2016-01-29 35 views
3

嗨我想通過MPI點對點通信發送2-dim數組的邊緣。通過MPI點對點通信發送數組

struct image { 
    /* image data block */ 
    double **data; //2dim array 

    /* boundaries */ 
    double *top; 
    double *bot; 
    double *left; 
    double *right; 

    /* dimensions */ 
    int width; 
    int height; 
}; 

每個節點都有它自己的圖像(相同的寬度和高度)以及應該接收交換數據的邊界。每個節點都已知道發送/接收數據的位置。接收緩衝區(top,bot,left,right)已被分配。 什麼不起作用的是我在交換過程中總是遇到分段錯誤。

這裏是我的關鍵方法:

void MPI_stencil_p_to_p(struct image *img, int *neighbours, MPI_Comm comm) 
{ 
    int count = 0; 

    for (int i = 0; i < 4; ++i) 
    { 
     if (neighbours[i] != MPI_PROC_NULL){ 
      count+=2; 
     } 
    } 
    MPI_Status status[count]; 
    MPI_Request req[count]; 
    int count_tmp = count; 
    for (int i = 0; i < 4; ++i) 
    { 
     if (neighbours[i] != MPI_PROC_NULL){ 
      count_tmp--; 
      if (i == 0) 
      { 
       printf("%d: %d\n", ra, neighbours[i]); 
       printf("works %d\n", ra); 
       MPI_Isend(img->data[0], img->width, MPI_DOUBLE, neighbours[i], TAG, comm, &req[count_tmp]); 
       count_tmp--; 
       MPI_Irecv(&img->top, img->width, MPI_DOUBLE, neighbours[i], TAG, comm, &req[count_tmp]); 
       continue; 
      } else if (i == 2) 
      { 
       printf("%d: %d\n", ra, neighbours[i]); 
       int len = img->height-1; 
       MPI_Isend(img->data[len], img->width, MPI_DOUBLE, neighbours[i], TAG, comm, &req[count_tmp]); 
       count_tmp--; 
       MPI_Irecv(&img->bot, img->width, MPI_DOUBLE, neighbours[i], TAG, comm, &req[count_tmp]); 
       continue; 
      } 

      MPI_Datatype col; 
      MPI_Type_vector(img->height, 1, img->width, MPI_DOUBLE, &col); 
      MPI_Type_commit(&col); 

      if (i == 1) 
      { 
       printf("%d: %d\n", ra, neighbours[i]); 
       MPI_Isend(&img->data[0][0], 1, col, neighbours[i], TAG, comm, &req[count_tmp]); 
       count_tmp--; 
       MPI_Irecv(&img->right, img->height, MPI_DOUBLE, neighbours[i], TAG, comm, &req[count_tmp]); 
      } else 
      { 
       printf("%d: %d\n", ra, neighbours[i]); 
       int len = img->width-1; 
       MPI_Isend(&img->data[0][len], 1, col, neighbours[i], TAG, comm, &req[count_tmp]); 
       count_tmp--; 
       MPI_Irecv(&img->left, img->height, MPI_DOUBLE, neighbours[i], TAG, comm, &req[count_tmp]); 
      } 
      MPI_Type_free(&col); 
     } 
    } 
    if (MPI_Waitall(count, req, status) != MPI_SUCCESS) 
     error_exit(EXIT_FAILURE, "MPI_Waitall"); 
} 

感謝的幫助我出去!

回答

1

如果不知道節點發生的確切位置,我只是猜測錯誤在哪裏。然而,每當有人問這樣的問題時,這是因爲他們已經使用雙指針構造了二維數組,並且它們沒有密集的矩陣。 MPI預計發送/接收連續的數據,因此,如果您嘗試發送分配這樣一個矩陣的多行:

double **data; 
data = malloc(sizeof(double) * n); 
for (i = 0; i < n; i++) data[i] = malloc(sizeof(double) * m); 

你會碰到一個問題,因爲data[0][m-1]data[1][0]不一定是在內存中連續的位置。

相反,在MPI中發送矩陣時,您需要將它們分配爲一維數組,並執行額外的數學運算或單獨發送每行。