У меня есть многопоточная программа на C, использующая OpenMP. Внутри параллельного раздела кода для системного вызова делается скрипт Python, который отображает данные, сгенерированные в этой конкретной итерации цикла. У меня есть проблема, когда программа внезапно останавливается в той же точке после тысяч итераций и часов работы. После запуска ps -A
, чтобы увидеть, какие процессы выполнялись в стойле, я заметил n-много экземпляров python (где n = количество потоков), что привело меня к мысли, что что-то происходит со скриптом python. Я переключился с системного вызова на сценарий python на встроенный python, надеясь, что это решит проблему. Теперь я вижу, что запуск сценария python выдает предупреждение:
OpenBLAS Warning : Detect OpenMP Loop and this application may hang. Please rebuild the library with USE_OPENMP=1 option.
Я не использую ничего, связанного с BLAS, в моем коде, но после проб и ошибок я обнаружил, что это производится matplotlib, который зависит от numpy, который, в свою очередь, я полагаю, использует OpenBLAS. Я подозреваю, что это может быть виновником возможного срыва, но я не уверен, как это исправить. Я попытался установить OpenBLAS со страницы GitHub и сделать это с флагом USE_OPENMP=1
, как показано здесь:
Как заставить openBLAS работать с openMP?
Это, я полагаю, неудивительно, не решило проблему. Я подозреваю, что мне придется переделать любой источник BLAS, который использует matplotlib? В любом случае я привел минимальный пример, который воспроизводит нежелательное поведение. Код OpenMP C находится здесь:
#include <sys/wait.h>
#include <python2.7/Python.h>
#include "omp.h"
int NUM_THREADS = 8; // Default number of threads for OpenMP
int main(int argc, char * argv[])
{
# ifdef _OPENMP
printf("Compiled by an OpenMP-compliant implementation.\n");
# endif
omp_set_dynamic(0);
omp_set_num_threads(NUM_THREADS);
int nThreads = 0;
#pragma omp parallel
{
#pragma omp master
nThreads = omp_get_num_threads();
#pragma omp for
for (int i = 0; i < 8; i++) // Loop through number of samples
{
// Create directories to store and run the python script
char system_buffer[300] = "\0";
snprintf(system_buffer, sizeof(system_buffer), "mkdir -p %d", i+1);
int systemRet = system(system_buffer);
if(systemRet == -1)
{
// The system method failed
}
// Copy the Python Script to the working directory
char system_buffer_py[300] = "\0";
snprintf(system_buffer_py, sizeof(system_buffer_py), "cp test.py %d", i+1);
int systemRet_py = system(system_buffer_py);
if(systemRet_py == -1)
{
// The system method failed
}
int pid;
// Child
if ((pid = fork()) == 0)
{
int argc = 0;
char* argv[1];
argv[0] = NULL;
char python_script[300] = "\0";
snprintf(python_script, sizeof(python_script), "%d/test.py", i+1);
FILE *stream = fopen(python_script, "r");
Py_SetProgramName(argv[0]);
Py_Initialize();
PySys_SetArgv(argc, argv);
PyRun_AnyFile(stream, python_script);
Py_Finalize();
fclose(stream);
exit(0);
}
// Parent
else
{
int status;
waitpid(pid, &status, 0);
}
}
}//end of: pragma omp parallel
if (nThreads == NUM_THREADS)
{
printf("The expected number of threads, %d, were used.\n", NUM_THREADS);
}
else
{
printf("Expected %d OpenMP threads, but %d were used.\n", NUM_THREADS, nThreads);
}
return(0);
}
Это можно скомпилировать с помощью:
gcc -Wall -O3 -fopenmp test.c -o test -L/usr/lib/python2.7/config-x86_64-linux-gnu -L/usr/lib -lpython2.7 -ldl -export-dynamic -lm
Сценарий python находится здесь и должен находиться в том же каталоге, что и код C:
import os
import matplotlib.pyplot as plt
plot_name = os.path.dirname(__file__) + '/test.png'
plt.plot([1, 2, 3, 4])
plt.ylabel('some numbers')
plt.savefig(plot_name)
Выход от запуска кода C:
Compiled by an OpenMP-compliant implementation.
OpenBLAS Warning : Detect OpenMP Loop and this application may hang. Please rebuild the library with USE_OPENMP=1 option.
OpenBLAS Warning : Detect OpenMP Loop and this application may hang. Please rebuild the library with USE_OPENMP=1 option.
OpenBLAS Warning : Detect OpenMP Loop and this application may hang. Please rebuild the library with USE_OPENMP=1 option.
OpenBLAS Warning : Detect OpenMP Loop and this application may hang. Please rebuild the library with USE_OPENMP=1 option.
OpenBLAS Warning : Detect OpenMP Loop and this application may hang. Please rebuild the library with USE_OPENMP=1 option.
OpenBLAS Warning : Detect OpenMP Loop and this application may hang. Please rebuild the library with USE_OPENMP=1 option.
OpenBLAS Warning : Detect OpenMP Loop and this application may hang. Please rebuild the library with USE_OPENMP=1 option.
OpenBLAS Warning : Detect OpenMP Loop and this application may hang. Please rebuild the library with USE_OPENMP=1 option.
OpenBLAS Warning : Detect OpenMP Loop and this application may hang. Please rebuild the library with USE_OPENMP=1 option.
OpenBLAS Warning : Detect OpenMP Loop and this application may hang. Please rebuild the library with USE_OPENMP=1 option.
OpenBLAS Warning : Detect OpenMP Loop and this application may hang. Please rebuild the library with USE_OPENMP=1 option.
OpenBLAS Warning : Detect OpenMP Loop and this application may hang. Please rebuild the library with USE_OPENMP=1 option.
OpenBLAS Warning : Detect OpenMP Loop and this application may hang. Please rebuild the library with USE_OPENMP=1 option.
OpenBLAS Warning : Detect OpenMP Loop and this application may hang. Please rebuild the library with USE_OPENMP=1 option.
OpenBLAS Warning : Detect OpenMP Loop and this application may hang. Please rebuild the library with USE_OPENMP=1 option.
OpenBLAS Warning : Detect OpenMP Loop and this application may hang. Please rebuild the library with USE_OPENMP=1 option.
OpenBLAS Warning : Detect OpenMP Loop and this application may hang. Please rebuild the library with USE_OPENMP=1 option.
OpenBLAS Warning : Detect OpenMP Loop and this application may hang. Please rebuild the library with USE_OPENMP=1 option.
OpenBLAS Warning : Detect OpenMP Loop and this application may hang. Please rebuild the library with USE_OPENMP=1 option.
OpenBLAS Warning : Detect OpenMP Loop and this application may hang. Please rebuild the library with USE_OPENMP=1 option.
OpenBLAS Warning : Detect OpenMP Loop and this application may hang. Please rebuild the library with USE_OPENMP=1 option.
OpenBLAS Warning : Detect OpenMP Loop and this application may hang. Please rebuild the library with USE_OPENMP=1 option.
OpenBLAS Warning : Detect OpenMP Loop and this application may hang. Please rebuild the library with USE_OPENMP=1 option.
OpenBLAS Warning : Detect OpenMP Loop and this application may hang. Please rebuild the library with USE_OPENMP=1 option.
The expected number of threads, 8, were used.
Похоже, это предупреждение генерируется 3 раза для каждого потока (используя 8 потоков). Будем весьма благодарны за любые предложения по решению этой проблемы.