web-dev-qa-db-ja.com

clangでOpenMPを使用する

Clang(3.6および3.8 ToTの両方)を使用してOpenMPコードをコンパイルする際に問題があります。

このブログ投稿 http://blog.llvm.org/2015/05/openmp-support_22.html に従いましたが、問題はコンパイルされたプログラムが1つのスレッドでのみ実行されることです。私はubuntu 15.04 x64を使用しています。libgompとlibiopmpの両方がインストールされており、次のコマンドでコードをコンパイルします。

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

代わりにgccを使用すると、すべて正常に動作します:gcc test.c -o test -fopenmp

また、export LD_LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/5.1.1:$LD_LIBRARY_PATHしかし、助けにはなりませんでした。 `

助言がありますか?

18
kuhar

更新

LLVM/Clangの最新トランク(clang-3.8)の構築、libiomp5のインストール、およびgomp ompヘッダーファイルの場所の指定が機能しました。 libiomp5のUbuntuパッケージはまったく正しくないため、/ usr/libに/usr/lib/libiomp5.soから/usr/lib/libiomp5.so.5へのシンボリックリンクを追加する必要があることに注意してください。

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

Linux Mint 17.2(本質的にUbuntu trusty)でg ++-5.1およびclang ++-3.6を使用していますが、次のコードでも同じ結果が得られます。

#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;
    }
}

これをltraceで実行すると、問題が明らかになります。

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

問題をすぐに確認できます。clang++はGOMP_parallelを呼び出さないため、常に1つのスレッドを取得します。これは、clang側の異常な動作です。 cspecの「特別な」 OpenMPバージョン をビルドして使用しようとしましたか?

9
Tim

追加のコメント:

1)-fopenmp = libompを使用してclangでOpenMPを有効にする必要があります。 -fopenmpはlibgompをリンクするだけですが、すべてのプラグマを無視します。奇妙な、私は知っている-とすぐにトランクで変更されます。

2)3.7はOpenMPをサポートする最初のバージョンです。 3.6ではありません。

3)clangはlibompでのみ機能します。 libgomp(ヘッダーまたはライブラリ)をlibompのように配置しないでください! clangはlibgompでサポートされていないIntel APIを使用します。 -fopenmp = libompは正しいライブラリをリンクする必要があります。

あなたのもの、

アンドレイ・ボカンコ

ソフトウェアエンジニアIntel

17
Andrey Bokhanko

Linux Mint 17.2で動作するようにしました。 (基本的にUbuntu 14.04)と:

パッケージ:libiomp-dev clang-3.8

コンパイルフラグ:-fopenmp

リンカーフラグ:-fopenmp=libiomp5

現在では、複数のスレッドをコンパイルして使用しています。

変更された FindOpenMP.cmake

6
veio

OMP_NUM_THREADS環境変数はおそらくあなたが望むものです。プログラムで設定することもできます。

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

そして、clangについても同じです。

0
Jack Wasey