Verwenden von OpenMP mit Clang

Verwenden von OpenMP mit Clang


Ich habe Probleme beim Kompilieren von OpenMP-Code mit Clang (sowohl 3.6 als auch 3.8 ToT).


Ich bin diesem Blogbeitrag http://blog.llvm.org/2015/05/openmp-support_22.html gefolgt, aber das Problem ist, dass das kompilierte Programm nur auf einem Thread ausgeführt wird.
Ich verwende Ubuntu 15.04 x64, ich habe sowohl libgomp als auch libiopmp installiert und ich kompiliere meinen Code mit dem folgenden Befehl:


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

Wenn ich stattdessen gcc verwende, funktioniert alles einwandfrei:gcc test.c -o test -fopenmp


Ich habe auch versucht, export LD_LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/5.1.1:$LD_LIBRARY_PATH auszuführen aber es hat nicht geholfen.
`


Irgendwelche Vorschläge?


Antworten:


Aktualisieren


Das Erstellen des neuesten Trunks von LLVM/Clang (clang-3.8), das Installieren von libiomp5 und das Angeben des Speicherorts der gomp-omp-Header-Dateien funktionierte. Beachten Sie, dass das Ubuntu-Paket für libiomp5 nicht ganz korrekt ist, daher müssen Sie einen symbolischen Link in /usr/lib von /usr/lib/libiomp5.so zu /usr/lib/libiomp5.so.5 hinzufügen.


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


Ich verwende g++-5.1 und clang++-3.6 unter Linux Mint 17.2 (im Wesentlichen Ubuntu vertrauenswürdig) und ich sehe die gleichen Ergebnisse mit dem folgenden Code.


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

Wenn Sie dies unter ltrace ausführen, wird das Problem angezeigt:


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 <unfinished ...>
_ZNSt8ios_base4InitC1Ev(0x6021b1, 0xffff, 0x7ffc937b81a8, 5) = 0
__cxa_atexit(0x4009f0, 0x6021b1, 0x602090, 0x7ffc937b7f70) = 0
GOMP_parallel(0x400b6d, 0, 4, 0 <unfinished ...>
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 <unfinished ...>
_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) +++

Klang


$ clang++ -fopenmp -o test test.cpp
$ ./test
tid = 0
$ ltrace ./test
__libc_start_main(0x4009a0, 1, 0x7ffde4782538, 0x400a00 <unfinished ...>
_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 <unfinished ...>
_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) +++

Sie sehen sofort das Problem:clang++ ruft niemals GOMP_parallel auf, Sie erhalten also immer einen Thread. Das ist ein verrücktes Verhalten von clang. Haben Sie versucht, die "spezielle" OpenMP-Version von Clang zu erstellen und zu verwenden?