0

乗算ループで暗黙的な 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 intprintf

ただし、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の不一致ですか?
    もしそうなら、コンパイラの独立性と互換性を達成するための良い方法は何でしょうか?
4

1 に答える 1

1

は。コードを見ると、icpc が問題を認識していることは明らかですが、g++ と icpc のどちらのコンパイラが正しいことを行っているかは、仕様を確認しないとわかりません。

問題はrestrictキーワードではありません。それらをすべて-restrict取り除いて icpc のオプションを失った場合、問題は残ります。問題は、その並列セクションにあることですがdefault(none) shared(n_row...)n_rowプログラムの開始時には、へのポインターdefault_n_rowです。そして、icpc は、その omp 並列セクションでdefault_n_rowも共有 (または、少なくとも何か) する必要があります。

于 2012-04-11T13:37:04.063 に答える