it-swarm.com.de

Verwenden von OpenMP mit Clang

Ich habe Probleme beim Kompilieren von OpenMP-Code unter Verwendung von clang (sowohl 3.6 als auch 3.8 ToT).

Ich folgte diesem Blogbeitrag http://blog.llvm.org/2015/05/openmp-support_22.html , aber das Problem ist, dass das kompilierte Programm nur auf einem einzigen Thread ausgeführt wird. m mit Ubuntu 15.04 x64 habe ich sowohl libgomp als auch libiopmp installiert und 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 benutze, funktioniert alles gut: 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 half nicht . `

Irgendwelche Vorschläge?

16
kuhar

Update

Erstellen Sie den neuesten Stamm von LLVM/Clang (clang-3.8), installieren Sie libiomp5 und geben Sie den Speicherort der gomp omp-Headerdateien an. Beachten Sie, dass das Ubuntu-Paket für libiomp5 nicht ganz korrekt ist. Daher müssen Sie in/usr/lib einen Symlink 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 trusty) und 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 deutlich:

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) +++

klirren

$ 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 können das Problem sofort sehen: clang ++ ruft niemals GOMP_parallel auf, so dass Sie immer einen Thread erhalten. Das ist ein verrücktes Verhalten von Clang. Haben Sie versucht, die "spezielle" OpenMP-Version von clang zu erstellen und zu verwenden?

8
Tim

Einige zusätzliche Kommentare:

1) Sie müssen -fopenmp = libomp verwenden, um OpenMP in clang zu aktivieren. -fopenmp verknüpft nur libgomp, ignoriert jedoch alle Pragmas. Seltsam, ich weiß - und wird bald im Kofferraum gewechselt.

2) 3.7 ist die erste Version, die OpenMP unterstützt. 3.6 nicht.

3) clang kann nur mit libomp arbeiten. Setzen Sie libgomp (Header oder die Bibliothek) nicht in den Weg von libomp! clang verwendet die Intel API, die von libgomp nicht unterstützt wird. -fopenmp = libomp sollte die richtige Bibliothek verknüpfen.

Deine,

Andrey Bokhanko

Software-IngenieurIntel

14
Andrey Bokhanko

Ich habe es mit Linux Mint 17.2 zum Laufen gebracht. (im Wesentlichen Ubuntu 14.04) mit:

pakete: libiomp-dev clang-3.8

Kompilierflag: -fopenmp

Linker-Flag: -fopenmp=libiomp5

Jetzt kompiliert und verwendet mehrere Threads.

Hier ist der modifizierte FindOpenMP.cmake

6
veio

Die Umgebungsvariable OMP_NUM_THREADS ist wahrscheinlich das, was Sie wollen. Sie können es auch programmgesteuert einstellen.

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

Und das Gleiche für das Klirren.

0
Jack Wasey