Utiliser OpenMP avec Clang

J’ai des problèmes pour comstackr le code OpenMP avec Clang (3.6 et 3.8 ToT).

J’ai suivi cet article de blog http://blog.llvm.org/2015/05/openmp-support_22.html , mais le problème est que le programme compilé est exécuté sur un seul thread. J’utilise Ubuntu 15.04 x64, libgomp et libiopmp sont installés et je comstack mon code à l’aide de la commande suivante:

clang test.c -o test -fopenmp -L/usr/lib/gcc/x86_64-linux-gnu/5.1.1 

Quand j’utilise gcc à la place, tout fonctionne gcc test.c -o test -fopenmp : gcc test.c -o test -fopenmp

J’ai également essayé d’exécuter l’ export LD_LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/5.1.1:$LD_LIBRARY_PATH mais cela n’a pas aidé. `

Aucune suggestion?

Mettre à jour

Construire la dernière version de LLVM / Clang (clang-3.8), installer libiomp5 et spécifier l’emplacement des fichiers d’en-tête gomp omp a fonctionné. Notez que le paquet Ubuntu pour libiomp5 n’est pas tout à fait correct. Vous devrez donc append un lien symbolique dans / usr / lib à partir de /usr/lib/libiomp5.so à /usr/lib/libiomp5.so.5.

 ./clang++ -I/usr/lib/gcc/x86_64-linux-gnu/4.9/include -fopenmp=libiomp5 -o test test.cpp 

J’utilise g ++ – 5.1 et clang ++ – 3.6 sur Linux Mint 17.2 (essentiellement Ubuntu fidèle) et je vois les mêmes résultats avec le code suivant.

 #include  #include  int main() { #pragma omp parallel num_threads(4) { #pragma omp critical std::cout << "tid = " << omp_get_thread_num() << std::endl; } } 

L'exécution de cette sous-trace révèle le problème:

g ++

 $ g++ -fopenmp -o test test.cpp $ ./test tid = 0 tid = 3 tid = 2 tid = 1 $ ltrace ./test __libc_start_main(0x400af6, 1, 0x7ffc937b8198, 0x400bc0  _ZNSt8ios_base4InitC1Ev(0x6021b1, 0xffff, 0x7ffc937b81a8, 5) = 0 __cxa_atexit(0x4009f0, 0x6021b1, 0x602090, 0x7ffc937b7f70) = 0 GOMP_parallel(0x400b6d, 0, 4, 0  GOMP_critical_start(0, 128, 0, 0) = 0 tid = 3 tid = 2 omp_get_thread_num(0x7f9fe13894a8, 1, 0, 0x493e0) = 0 _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(0x6020a0, 0x400c44, 0, 0x493e0) = 0x6020a0 _ZNSolsEi(0x6020a0, 0, 0x7f9fe1a03988, 0x203d2064) = 0x6020a0 _ZNSolsEPFRSoS_E(0x6020a0, 0x400920, 0x7f9fe1a03988, 0  _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_(0x6020a0, 0x400920, 0x7f9fe1a03988, 0) = 0x6020a0 <... _ZNSolsEPFRSoS_E resumed> ) = 0x6020a0 GOMP_critical_end(0x7f9fe0d2d400, 0x7f9fe0d2e9e0, 0, -1) = 0 tid = 1 tid = 0 <... GOMP_parallel resumed> ) = 0 _ZNSt8ios_base4InitD1Ev(0x6021b1, 0, 224, 0x7f9fe0d2df50) = 0x7f9fe1a08940 +++ exited (status 0) +++ 

bruit

 $ clang++ -fopenmp -o test test.cpp $ ./test tid = 0 $ ltrace ./test __libc_start_main(0x4009a0, 1, 0x7ffde4782538, 0x400a00  _ZNSt8ios_base4InitC1Ev(0x6013f4, 0x7ffde4782538, 0x7ffde4782548, 5) = 0 __cxa_atexit(0x400830, 0x6013f4, 0x6012c8, 0x7ffde4782310) = 0 _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(0x6012e0, 0x400a84, 0x7ffde4782548, 6) = 0x6012e0 omp_get_thread_num(0x7f3e4698c006, 0x7f3e4698c000, 0x7f3e46764988, 1024) = 0 _ZNSolsEi(0x6012e0, 0, 0x7f3e46764988, 1024) = 0x6012e0 _ZNSolsEPFRSoS_E(0x6012e0, 0x4007a0, 0x7f3e46764988, 0  _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_(0x6012e0, 0x4007a0, 0x7f3e46764988, 0) = 0x6012e0 tid = 0 <... _ZNSolsEPFRSoS_E resumed> ) = 0x6012e0 _ZNSt8ios_base4InitD1Ev(0x6013f4, 0, 224, 0x7f3e45886f50) = 0x7f3e46769940 +++ exited (status 0) +++ 

Vous pouvez immédiatement voir le problème: clang ++ n'appelle jamais GOMP_parallel, vous obtenez donc toujours un thread. C'est un comportement fou de la part de Clang. Avez-vous essayé de construire et d’utiliser la version "spéciale" OpenMP de clang?

Quelques commentaires supplémentaires:

1) Vous devez utiliser -fopenmp = libomp pour activer OpenMP dans Clang. -fopenmp lie simplement libgomp mais ignore tous les pragmas. Bizarre, je sais – et sera bientôt changé dans le coffre.

2) 3.7 est la première version qui prend en charge OpenMP. 3,6 pas.

3) Clang est seulement capable de travailler avec libomp. Ne mettez pas libgomp (en-têtes ou la bibliothèque) dans le chemin de libomp! Clang utilise l’API Intel, non prise en charge par libgomp. -fopenmp = libomp doit lier la bonne bibliothèque.

Le tiens,

Andrey Bokhanko

Ingénieur logiciel Intel

Je l’ai fait fonctionner sur Linux Mint 17.2. (essentiellement Ubuntu 14.04) avec:

les paquets: libiomp-dev clang-3.8

Indicateur de compilation: -fopenmp

Drapeau de l’ -fopenmp=libiomp5 : -fopenmp=libiomp5

Maintenant, il comstack et utilise plusieurs threads.

Voici le FindOpenMP.cmake modifié

La variable d’environnement OMP_NUM_THREADS est probablement ce que vous voulez. Vous pouvez également le définir par programme.

https://gcc.gnu.org/onlinedocs/libgomp/Environment-Variables.html

Et pareil pour Clang.