乗算ループで暗黙的な openMP ディレクティブを使用して、 CRSでスパース行列の単純な行列ベクトル乗算を実装しました。
完全なコードは GitHub にあります: https://github.com/torbjoernk/openMP-Examples/blob/icc_gcc_problem/matxvec_sparse/matxvec_sparse.cpp
注: 醜いです ;-)
プライベート メモリと共有メモリを制御するために、restrict ポインターを使用しています。64 ビット Linux で GCC 4.6.3 を使用してコンパイルすると、正常に動作します (コマンド内の%u
とに関する 2 つの警告を除いて、それは問題ではありません)。unsigned int
printf
ただし、64 ビット Linux で ICC 12.1.0 を使用してコンパイルすると、次のエラーで失敗します。
matxvec_sparse.cpp(79): error: "default_n_row" must be specified in a variable list at enclosing OpenMP parallel pragma
#pragma omp parallel \
^
問題の変数とポインタの定義で
int default_n_row = 4;
int *n_row = &default_n_row;
そして、次のように定義された openMP ディレクティブ
#pragma omp parallel \
default(none) \
shared(n_row, aval, acolind, arowpt, vval, yval) \
private(x, y)
{
#pragma omp for \
schedule(static)
for ( x = 0; x < *n_row; x++ ) {
yval[x] = 0;
for ( y = arowpt[x]; y < arowpt[x+1]; y++ ) {
yval[x] += aval[y] * vval[ acolind[y] ];
}
}
} /* end PARALLEL */
g++ でコンパイル:
c++ -fopenmp -O0 -g -std=c++0x -Wall -o matxvec_sparse matxvec_sparse.cpp
Icc でコンパイル:
icc -openmp -O0 -g -std=c++0x -Wall -restrict -o matxvec_sparse matxvec_sparse.cpp
- GCC/ICCの使い方の誤りでしょうか?
- これは私のコードの設計上の問題であり、未定義の動作を引き起こしていますか?
もしそうなら、どの行がそれを引き起こしていますか? - ICCとGCCの不一致ですか?
もしそうなら、コンパイラの独立性と互換性を達成するための良い方法は何でしょうか?