c++ - sierra - Usando OpenMP con clang
openmp high sierra (4)
Tengo problemas para compilar el código OpenMP usando clang (tanto 3.6 como 3.8 ToT).
Seguí esta publicación del blog http://blog.llvm.org/2015/05/openmp-support_22.html , pero el problema es que el programa compilado se ejecuta en un solo hilo. Estoy usando ubuntu 15.04 x64, tengo ambos libgomp y libiopmp instalados y compilo mi código con el siguiente comando:
clang test.c -o test -fopenmp -L/usr/lib/gcc/x86_64-linux-gnu/5.1.1
Cuando uso gcc, todo funciona bien: gcc test.c -o test -fopenmp
También intenté ejecutar la export LD_LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/5.1.1:$LD_LIBRARY_PATH
pero no ayudó. `
¿Alguna sugerencia?
Algunos comentarios adicionales:
1) Necesitas usar -fopenmp = libomp para habilitar OpenMP en clang. -fopenmp simplemente vincula libgomp pero ignora todos los pragmas. Raro, lo sé, y será cambiado en el baúl pronto.
2) 3.7 es la primera versión que soporta OpenMP. 3.6 no lo hace.
3) clang solo puede trabajar con libomp. ¡No ponga libgomp (los encabezados o la biblioteca) en el camino de libomp! clang usa la API de Intel, no es compatible con libgomp. -fopenmp = libomp debería enlazar la librería correcta.
Tuyo,
Andrey bokhanko
Ingeniero de Software Intel
La variable de entorno OMP_NUM_THREADS es probablemente lo que quieres. También puedes configurarlo programáticamente.
https://gcc.gnu.org/onlinedocs/libgomp/Environment-Variables.html
Y lo mismo para el clang.
Lo hice funcionar en Linux Mint 17.2. (esencialmente Ubuntu 14.04) con:
paquetes: libiomp-dev clang-3.8
Bandera de compilación: -fopenmp
Bandera del enlazador: -fopenmp=libiomp5
Ahora compila y utiliza múltiples hilos.
Aquí está el FindOpenMP.cmake modificado
Actualizar
Construyendo el último troncal de LLVM / Clang (clang-3.8), instalando libiomp5 y especificando la ubicación de los archivos de encabezado de gomp omp trabajados. Tenga en cuenta que el paquete de Ubuntu para libiomp5 no es del todo correcto, por lo que deberá agregar un enlace simbólico en / usr / lib desde /usr/lib/libiomp5.so a /usr/lib/libiomp5.so.5.
./clang++ -I/usr/lib/gcc/x86_64-linux-gnu/4.9/include -fopenmp=libiomp5 -o test test.cpp
Estoy usando g ++ - 5.1 y clang ++ - 3.6 en Linux Mint 17.2 (esencialmente Ubuntu trusty) y veo los mismos resultados con el siguiente código.
#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;
}
}
Ejecutar esto bajo ltrace revela el problema:
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) +++
sonido metálico
$ 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) +++
Inmediatamente puede ver el problema: clang ++ nunca llama a GOMP_parallel, por lo que siempre obtiene un hilo. Este es un comportamiento loco por parte de clang. ¿Has intentado construir y usar la versión "especial" de OpenMP de clang?