2016-01-29 2 views
3

Привет Я пытаюсь послать ребра 2-мерного массива по коммутации точка-точка с MPI.Отправка массива через связь между точками MPI

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

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

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

Каждый узел имеет свое собственное изображение (та же ширина и высота) и границы, в которых должны быть получены обмененные данные. Каждый узел allready знает, куда отправлять/получать данные. Буферы приема (верхний, бот, левый, правый) уже выделены. Что не работает, так это то, что во время процесса обмена я всегда получаю ошибку сегментации.

Вот мой критический метод:

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

Не зная, где именно происходит segfault, я просто догадываюсь, где ошибка. Однако каждый раз, когда кто-то задает такой вопрос, это потому, что они построили 2D-массив, используя двойные указатели, и у них нет плотно упакованной матрицы. 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 вам либо нужно выделить их как одномерные массивы, либо выполнить дополнительную математику, либо отправить каждую строку по отдельности.

Смежные вопросы