MPI Отправить и получить указатель в MPI_Type_struct - PullRequest
1 голос
/ 24 апреля 2019

Я хочу отправить набор данных с помощью MPI_Type_struct, и один из них - указатель на массив (потому что матрицы, которые я собираюсь использовать, будут очень большими, и мне нужно сделать malloc).Проблема, которую я вижу, состоит в том, что все данные передаются правильно, кроме матрицы.Я знаю, что можно передать матрицу через указатель, поскольку, если я отправляю только указатель матрицы, наблюдаются правильные результаты.

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

void main(int argc, char *argv[])
{

    MPI_Init(&argc, &argv);
    int size, rank;
    int m,n;
    m=n=2;

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

    typedef struct estruct
    {
        float *array;
        int sizeM, sizeK, sizeN, rank_or;
    } ;

    struct estruct kernel, server;

    MPI_Datatype types[5] = {MPI_FLOAT, MPI_INT,MPI_INT,MPI_INT,MPI_INT};
    MPI_Datatype newtype;
    int lengths[5] = {n*m,1,1,1,1};
    MPI_Aint displacements[5];
    displacements[0] = (size_t) & (kernel.array[0]) - (size_t)&kernel;
    displacements[1] = (size_t) & (kernel.sizeM) - (size_t)&kernel;
    displacements[2] = (size_t) & (kernel.sizeK) - (size_t)&kernel;
    displacements[3] = (size_t) & (kernel.sizeN) - (size_t)&kernel;
    displacements[4] = (size_t) & (kernel.rank_or) - (size_t)&kernel;


    MPI_Type_struct(5, lengths, displacements, types, &newtype);
    MPI_Type_commit(&newtype);

    if (rank == 0)
    {
        kernel.array  = (float *)malloc(m * n * sizeof(float));
        for(int i = 0; i < m*n; i++) kernel.array[i] = i;
        kernel.sizeM = 5;
        kernel.sizeK = 5;
        kernel.sizeN = 5;
        kernel.rank_or = 5;
        MPI_Send(&kernel, 1, newtype, 1, 0, MPI_COMM_WORLD);
    }
    else
    {
        server.array  = (float *)malloc(m * n * sizeof(float));
        MPI_Recv(&server, 1, newtype, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);

        printf("%i \n", server.sizeM);
        printf("%i \n", server.sizeK);
        printf("%i \n", server.sizeN);
        printf("%i \n", server.rank_or);
        for(int i = 0; i < m*n; i++) printf("%f\n",server.array[i]);
    }

    MPI_Finalize();
}

Если предположить, что выполняются только два процесса, я ожидаю, что этот процессс рангом = 1 получить и отобразить правильные элементы матрицы на экране (другие элементы хорошо приняты), но фактический результат:

5
5
5
5
0.065004
0.000000
0.000000
0.000000

===================================================================================
=   BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
=   PID 26206 RUNNING AT pmul
=   EXIT CODE: 11
=   CLEANING UP REMAINING PROCESSES
=   YOU CAN IGNORE THE BELOW CLEANUP MESSAGES
===================================================================================
YOUR APPLICATION TERMINATED WITH THE EXIT STRING: Segmentation fault (signal 11)
This typically refers to a problem with your application.
Please see the FAQ page for debugging suggestions

Я надеюсь, что кто-то может мне помочь.

...