2016-10-18 2 views
0

まず、の使用を示しているthis codeを参照として使用しています。これはMPI_Scatterを使用しないため、ここで達成しようとしています。私はこれについて長い間今働いており、問題を理解することはできません。このソベルエッジ検出アルゴリズムは、画像内のオブジェクトのアウトラインを強化します。MPIルートプロセスからの収集のみを集める

私は以下のコードを投稿します。あまり多くはありませんが、まずは簡単なコードの説明をします。

私は、逐次プログラムを並列プログラムに変換しようとしています。したがって、非MPIコードはすべて正しいです。

私のMPIコードのどこかに間違いがあります。

int main(int argc, char **argv) { 

    FILE *inFile, *oFile; 
    int grayImage[N][N], edgeImage[N][N]; 
    char type[2]; 
    int w, h, max; 
    int r, g, b, y, x, i, j, sum, sumx, sumy; 
    int tid; 

    int GX[3][3], GY[3][3]; 
    double elapsed_time; 
    struct timeval tv1, tv2; 
    int error = 0; 
    char buffer[BUFSIZ]; 
    int rank, NP; 

    // Code lies here for reading from the image file and storing into the grayImage array. 
    // This works so I saw no reason to include it 

    /* 3x3 Sobel masks. */ 
    GX[0][0] = -1; GX[0][1] = 0; GX[0][2] = 1; 
    GX[1][0] = -2; GX[1][1] = 0; GX[1][2] = 2; 
    GX[2][0] = -1; GX[2][1] = 0; GX[2][2] = 1; 

    GY[0][0] = 1; GY[0][1] = 2; GY[0][2] = 1; 
    GY[1][0] = 0; GY[1][1] = 0; GY[1][2] = 0; 
    GY[2][0] = -1; GY[2][1] = -2; GY[2][2] = -1; 



    MPI_Init(NULL, NULL); 

    MPI_Comm_size(MPI_COMM_WORLD, &NP); 
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 

    // This calculates the block size.MPI 
    // On 4 processors the block size for a 100x100 image would be 25x100 each 

    int blksz = (int)ceil((double)N/NP); 

    // This creates a local array for each processor, soon to be gathered 

    int tempEdge[blksz][N]; 

    // this line shows it's working correctly 

    printf("processor %d, width: %d, height: %d, blksz: %d, begin: %d, end: %d\n", rank, w, h, blksz, rank*blksz, (rank+1)*blksz); 

    for(x=rank*blksz; x < (rank+1)*blksz && x<h; x++){ 

     // Any code in this loop can be ignored as it works correctly. 

     for(y=0; y < w; ++y){ 

      sumx = 0; 
      sumy = 0; 
      // handle image boundaries 
      if(x==0 || x==(h-1) || y==0 || y==(w-1)) 
       sum = 0; 
      else{ 
       //x gradient approx 
       for(i=-1; i<=1; i++) { 
        for(j=-1; j<=1; j++){ 
         sumx += (grayImage[x+i][y+j] * GX[i+1][j+1]); 
        } 
       } 
       //y gradient approx 
       for(i=-1; i<=1; i++) { 
        for(j=-1; j<=1; j++){ 
         sumy += (grayImage[x+i][y+j] * GY[i+1][j+1]); 
        } 
       } 
       //gradient magnitude approx 
       sum = (abs(sumx) + abs(sumy)); 
      } 
      tempEdge[x][y] = clamp(sum); 
     } 
    } 

    // Here is the line I am guessing is causing the problem 

    MPI_Gather(&tempEdge, w*blksz, MPI_INT, 
       &edgeImage, w*blksz, MPI_INT, 0, 
       MPI_COMM_WORLD); 


    // Finally, I output edgeImage to a file here. 

    if(rank==0){ 

     // output edgeImage to File 

    } 

    MPI_Finalize(); 

    return 0;  
} 

は、私が使用していた入力画像はこれです:

enter image description here

しかし、出力はこれだけ与えている:あなたはそれを見ることができるように

enter image description here

のみです四半期(N/4)、またはblkszです。

これは、MPI_Gatherがランク0のプロセスからのみ収集されていることを意味しますか?

私はこれに多くの時間を費やしてきましたが、どんな助けも大変に感謝しています!

答えて

2

コードの残りの部分にバグがないかMPIコレクティブを責めないでください。実際には、コードがsegfaultingせずに壊れた画像を生成する奇跡です。

int tempEdge[blksz][N]; 
      ~~~~~ 

for(x = rank*blksz; x < (rank+1)*blksz && x<h; x++){ 
     ~~~~~~~~~~ 
    for(y = 0; y < w; ++y){ 
     ... 
     tempEdge[x][y] = clamp(sum); (1) 
       ~ 
    } 
} 

任意の順位> 0の場合、コードは配列の末尾を超えて書き込みます。また

tempEdge[x - rank*blksz][y] = clamp(sum); 

MPI_Gatherコールで&の削除:(1)読むことで文を修正

MPI_Gather(tempEdge, w*blksz, MPI_INT, 
      edgeImage, w*blksz, MPI_INT, 0, 
      MPI_COMM_WORLD); 

をそれはあまりにも&で動作しますが、それは技術的に間違っています。 番地のアドレスがであると主張する場合は、代わりに&tempEdge[0][0]&edgeImage[0][0]を使用してください。

+0

私は実際にそれを逃したと信じられない!今私はそれを投稿するために馬鹿に感じます。すべてのコードを見てくれてありがとう! –

+0

私は知っている、片手の指で使用可能な並列デバッガの数を数えることができ、それらのほとんどが商用であるので、MPIコードのデバッグは難しい。 –

関連する問題