Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using OpenMP with clang

Tags:

c++

c

clang

openmp

I have problems compiling OpenMP code using clang (both 3.6 and 3.8 ToT).

I followed this blog post http://blog.llvm.org/2015/05/openmp-support_22.html , but the problem is that the compiled program is executed on a one thread only. I'm using ubuntu 15.04 x64, I have both libgomp and libiopmp installed and I compile my code with the following command:

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

When I use gcc instead, everything works fine: gcc test.c -o test -fopenmp

I also tried running export LD_LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/5.1.1:$LD_LIBRARY_PATH but it didn't help. `

Any suggestions?

like image 981
kuhar Avatar asked Oct 26 '15 22:10

kuhar


People also ask

Does clang support OpenMP?

Clang fully supports OpenMP 4.5. Clang supports offloading to X86_64, AArch64, PPC64[LE] and has basic support for Cuda devices.

What is LLVM OpenMP?

llvm-openmp/12.0. 1 The OpenMP (Open Multi-Processing) specification is a standard for a set of compiler directives\, library routines\, and environment variables that can be used to specify shared memory parallelism in Fortran and C/C++ programs. This is the LLVM implementation.

Can you use OpenMP in C++?

OpenMP in a nutshell. OpenMP is a library for parallel programming in the SMP (symmetric multi-processors, or shared-memory processors) model. When programming with OpenMP, all threads share memory and data. OpenMP supports C, C++ and Fortran.


3 Answers

Some additional comments:

1) You need to use -fopenmp=libomp to enable OpenMP in clang. -fopenmp just links libgomp but ignores all the pragmas. Weird, I know -- and will be changed in the trunk soon.

2) 3.7 is the first version that supports OpenMP. 3.6 doesn't.

3) clang is only able to work with libomp. Don't put libgomp (headers or the library) in the way of libomp! clang uses Intel API, not supported by libgomp. -fopenmp=libomp should link correct library.

like image 78
Andrey Bokhanko Avatar answered Oct 23 '22 02:10

Andrey Bokhanko


Update

Building the latest trunk of LLVM/Clang (clang-3.8), installing libiomp5, and specifying the location of the gomp omp header files worked. Note that the Ubuntu package for libiomp5 isn't quite correct, so you will need to add a symlink in /usr/lib from /usr/lib/libiomp5.so to /usr/lib/libiomp5.so.5.

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

I'm using g++-5.1 and clang++-3.6 on Linux Mint 17.2 (essentially Ubuntu trusty) and I see the same results with the following 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;
    }
}

Running this under ltrace reveals the issue:

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

clang

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

You can immediately see the problem: clang++ never calls GOMP_parallel, so you always get one thread. This is crazy behavior on the part of clang. Have you tried building and using the "special" OpenMP version of clang?

like image 29
Tim Avatar answered Oct 23 '22 03:10

Tim


I made it work on Linux Mint 17.2. (essentially Ubuntu 14.04) with:

packages: libiomp-dev clang-3.8

Compile flag: -fopenmp

Linker flag: -fopenmp=libiomp5

Now it compiles and uses multiple threads.

Here is the modified FindOpenMP.cmake

like image 10
veio Avatar answered Oct 23 '22 03:10

veio