Using OpenMP with clang

41,472

Solution 1

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?

Solution 2

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.

Solution 3

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

Share:
41,472

Related videos on Youtube

kuhar
Author by

kuhar

Updated on July 09, 2022

Comments

  • kuhar
    kuhar almost 2 years

    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?

  • kuhar
    kuhar over 8 years
    Setting it pragmatically doesn't work - my program doesn't crash in any way and continues to execute on one thread.
  • kuhar
    kuhar over 8 years
    Clang-omp seems to be discontinued - last changes are from over a year ago.
  • kuhar
    kuhar over 8 years
    When you look at the generated IR (-S -emit-llvm) you can clearly see that only omp-specific function calls are being generated - parallel code corresponding to openmp's pragmas is nowhere to be found.
  • kuhar
    kuhar over 8 years
    This doesn't work since clang doesn't emit any code for omp pragmas.
  • kuhar
    kuhar over 8 years
    Thanks, you were right about using ToT clang and specifying omp library different than libgomp. In fact I've also got it working on my raspberry pi 2, using self-build libomp: openmp.llvm.org.
  • Mark Setchell
    Mark Setchell almost 8 years
    Can you clarify what is the correct way, under the current OSX version, to compile a C++-11 compliant program, called say demo.cpp using OpenMP please? I mean the full command-line please?
  • sjoelund.se
    sjoelund.se over 7 years
    "Note that the Ubuntu package for libiomp5 isn't quite correct" seems to be wrong. You should install the libiomp-dev package if you want the headers and ability to link against the library
  • David Doria
    David Doria over 7 years
    @Andrey Bokhanko I am trying with clang 4.0 and CMake 3.7 with SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11 -fopenmp=libomp") find_package(OpenMP REQUIRED) but still getting "Could NOT find OpenMP"
  • veio
    veio over 7 years
    I have the same problem with clang 3.8. Did anybody find a solution for this?
  • Nil
    Nil almost 7 years
    On Mint 18.1, I confirm that's it's working with clang 3.8 and libiomp-dev. I didn't use any flag.
  • Henry Schreiner
    Henry Schreiner over 6 years
    Use CMake 3.9 and checkout the docs. It should work correctly with Clang if you use the OpenMP::OpenMP_CXX target. You can't use Apple Clang, though, as of High Sierra / Xcode 9.0. You have to use brew install llvm and set up the environment for that compiler.
  • Royi
    Royi about 5 years
    What about Windows and clang-cl?
  • Henke
    Henke over 3 years
    Using clang++ version 6.0, libomp-dev version 5.0.1, and linker flag -fopenmp, my program ran just fine. However, when adding -fopenmp as compiler flag, it failed miserably.(!)