Sparse行列を解決するためにConjugate勾配法を並列化する作業を進めています。 CGメソッドはアルゴリズムの中で "matrixVectorProduct()"というサブルーチンを呼び出します。私はこのサブルーチンを具体的に並列化しようとしています。以下は、CSRフォーマットで格納されたSYMMETRIC行列のためのコードです。Open MP:Sparse行列の対称行列乗算
void matrixVectorProduct(MTX *MAT, double* inVec, double* outVec){
int i,j, ckey;
if((matcode[1] == 'X')&&(matcode[3] == 'S'))
{
//Initialize outVec to zeros
for(int j=0;j<MAT->nrows;j++)
outVec[j] = 0.0;
for(i=0;i<MAT->nrows;i++)
for(ckey=MAT->row_ptr[i];ckey<MAT->row_ptr[i+1];ckey++) {
j = MAT->JA[ckey];
outVec[i] = outVec[i] + MAT->val[ckey] * inVec[j];
}
for(int i=0;i<MAT->nrows;i++)
for(int ckey=MAT->row_ptr[i];ckey<MAT->row_ptr[i+1];ckey++) {
j = MAT->JA[ckey];
if(j!=i)
outVec[j] += MAT->val[ckey] * inVec[i];;
}
}
else
{
fprintf(stderr,"\n Not a symmetric Matrix. CG method not applicable\n");
exit(1);
}
return;}
並列後、マイコードである:
void matrixVectorProduct(MTX *MAT, double* inVec, double* outVec){
int i,j, ckey;
if((matcode[1] == 'X')&&(matcode[3] == 'S'))
{
//Initialize outVec to zeros
for(int j=0;j<MAT->nrows;j++)
outVec[j] = 0.0;
#pragma omp parallel
{
#pragma omp for private(ckey,j) schedule(static)
for(i=0;i<MAT->nrows;i++) {
double zi = 0.0;
for(ckey=MAT->row_ptr[i];ckey<MAT->row_ptr[i+1];ckey++) {
j = MAT->JA[ckey];
zi = zi + MAT->val[ckey] * inVec[j];
}
outVec[i] += zi;
}
}
#pragma omp parallel
{
#pragma omp for private(ckey,j) schedule(static)
for(int i=0;i<MAT->nrows;i++)
for(int ckey=MAT->row_ptr[i];ckey<MAT->row_ptr[i+1];ckey++) {
j = MAT->JA[ckey];
if(j!=i)
outVec[j] += MAT->val[ckey] * inVec[i];;
}
}
}
else
{
fprintf(stderr,"\n Not a symmetric Matrix. CG method not applicable\n");
exit(1);
}
return;
}
所望のように、第1 OMPプラグマループが動作しています。しかし、私は同様に2番目のループを並列化するときに問題があるようです。正しい出力が得られていません。
2番目のプラグマループで何が間違っているのか教えてもらえますか?私はマルチスレッドとオープンMPへの初心者です。
ありがとうございました。