Отправка кусков трехмерного массива с использованием подмассива MPI - PullRequest
0 голосов
/ 26 января 2019

Я новичок в MPI и пытаюсь научиться использовать MPI_Type_create_subarray, чтобы применять его в своих проектах.Я потратил много времени в поисках учебника, который мог бы удовлетворить мои потребности, но безуспешно.

Итак, я попытался обобщить концепцию в Как использовать MPI_Type_create_subarray для 3D-массивов, но что-то все еще отсутствует.

В частности, мой код возвращает Segmentation Fault error или показывает неверные данные, когда я пытаюсь увидеть результаты.Я не могу понять, где я допустил ошибку

Это мой код:

#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>

void printarr(int ***data, int nx, int ny, int nz, char *str);
int ***allocarray(int nx, int ny, int nz);

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

/* array sizes */
const int bigsize =10;
const int subsize_x =2;      const int subsize_y =2;     const int subsize_z =2;

/* communications parameters */
const int sender  =0;
const int receiver=1;
const int ourtag  =2;

int rank, size;

MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);

if (size < receiver+1) {
    if (rank == 0)
        fprintf(stderr,"%s: Needs at least %d  processors.\n", argv[0], receiver+1);
    MPI_Finalize();
    return 1;
}


MPI_Datatype mysubarray;

int starts[3] = {0,0,0};
int subsizes[3]  = {subsize_x,subsize_y,subsize_z};
int bigsizes[3]  = {bigsize, bigsize, 3};
MPI_Type_create_subarray(3, bigsizes, subsizes, starts, MPI_ORDER_C, MPI_INT, &mysubarray);
MPI_Type_commit(&mysubarray);

if (rank == sender) {
    int ***bigarray = allocarray(bigsize,bigsize,3);
    for (int k=0; k<3; k++)
        for (int j=0; j<bigsize; j++)
            for(int i=0; i< bigsize; i++) {
                bigarray[k][j][i] = k*(bigsize*bigsize)+j*bigsize+i;
            }

    printarr(bigarray, bigsize, bigsize, 3, " Sender: Big array ");

    MPI_Send(&(bigarray[0][0][0]), 1, mysubarray, receiver, ourtag, MPI_COMM_WORLD);
    MPI_Type_free(&mysubarray);

    free(bigarray);

} else if (rank == receiver) {

    int ***subarray = allocarray(subsize_x,subsize_y,subsize_z);
    MPI_Recv(&(subarray[0][0][0]), subsizes[0]*subsizes[1]*subsizes[2], MPI_INT, sender, ourtag, MPI_COMM_WORLD, MPI_STATUS_IGNORE);

    printarr(subarray, subsize_x, subsize_y, subsize_z, " Receiver: Subarray -- after receive");

    free(subarray);
}

MPI_Finalize();
return 0;
}

void printarr(int ***data, int nx, int ny, int nz, char *str) {
printf("-- %s --\n", str);
for(int k=0; k<nz; k++) {
    printf("\n\n-----%d------\n",k);
    for (int j=0; j<ny;j++) {
        for (int i=0; i<nx; i++) {
            printf("%3d ", data[k][j][i]);
        }
    printf("\n");
    }
}
}

int ***allocarray(int nx, int ny, int nz) {

int*** arr = (int***)malloc(sizeof(int**)*nz);
for(int k = 0; k < nz; k++) {
    arr[k]= (int**)malloc(sizeof(int*)*ny);
    for(int j = 0; j< ny; j++){
        arr[k][j] = (int*)malloc(sizeof(int)*nx);
        for(int i = 0; i < nx; i++){
            arr[k][j][i] = 0;
        }
    }
}
return arr;
}
...