结构数组上 MPI send/recv 的正确方法

Correct method of MPI send/recv on an array of structs

我一直在用树莓派建立一个四节点的 mpi 集群。据我所知,我要解决最后一个主要问题,那就是如何将一组结构从每个工人发送到经理。我已将代码裁剪到下面,但这可能需要尝试几次,因为我可能裁剪得太多了。尽管如此,我仍然遇到同样的错误(一个段错误,说地址未映射),但是如果有一点倒退和第四次,我很抱歉。


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

struct ticknrank
{
    char * ticker;
    int errors;
    int rank;
};

int main() //Designed for one master, three slaves
{

// i am under the impression the problem lies somewhere in this beginning section, before the commit.
    int my_id;
    MPI_Init(NULL,NULL);
    MPI_Comm_rank(MPI_COMM_WORLD, &my_id);
    MPI_Status status;

    MPI_Datatype types[3] = {MPI_CHAR,MPI_INT,MPI_INT};
    MPI_Datatype MPI_ticknrank, MPI_tmp;
    int blocklengths[3] ={8,1,1};
    MPI_Aint offsets[3];
    offsets[0] = offsetof(struct ticknrank,ticker);
    offsets[1] = offsetof(struct ticknrank,errors);
    offsets[2]= offsetof(struct ticknrank,rank);
    MPI_Aint lb, extent;
    MPI_Type_create_struct(3,blocklengths, offsets, types, &MPI_tmp);
    MPI_Type_get_extent(MPI_tmp, &lb, &extent);
    MPI_Type_create_resized(MPI_tmp, lb, extent, &MPI_ticknrank);
    MPI_Type_commit(&MPI_ticknrank);

//  NOTE: sizeof(ticknrank) = 12, while MPI_Type_size(ticknrank) = 16. Not sure what to do about that.

    if(my_id == 0) // meaning this process is a host job
    {
        //NOTE: NodethrRes and fou can be ommitted, I was just lazy and didn't wanna delete them
        //on my cluster.
        int length = 2;
        struct ticknrank * NodeTwoRes = (struct ticknrank *)malloc(length * sizeof(struct ticknrank));
        struct ticknrank * NodeThrRes = (struct ticknrank *)malloc(length * sizeof(struct ticknrank));
        struct ticknrank * NodeFouRes = (struct ticknrank *)malloc(length * sizeof(struct ticknrank));


        MPI_Recv(NodeTwoRes, length, MPI_ticknrank,1,MPI_ANY_TAG, MPI_COMM_WORLD, &status);
        MPI_Recv(NodeThrRes, length, MPI_ticknrank,2,MPI_ANY_TAG, MPI_COMM_WORLD, &status);
        MPI_Recv(NodeFouRes, length, MPI_ticknrank,3,MPI_ANY_TAG, MPI_COMM_WORLD, &status);

        printf("%s\n", NodeTwoRes[0].ticker);
        
    }
    else
    {
        int myLen = 2;
        struct ticknrank * results = malloc(myLen * sizeof(struct ticknrank));
        results[0].ticker = strdup("FIRST");
        results[0].rank = 4;
        results[0].errors = 7;
        results[1].ticker = strdup("SECON");
        results[1].rank = 3;
        results[1].errors = 15;
        MPI_Send(results,myLen,MPI_ticknrank,0,1,MPI_COMM_WORLD);
    }

    MPI_Type_free(&MPI_ticknrank);
    MPI_Finalize();

    return 0;
}


C 结构是一个 char * ticker(如果你是 运行 32 位,它是 4 个字节),但是派生的数据类型是 char ticker[8],它是确实是 8 个字节。

如果要一次发送多个struct ticknrank,那么数据应该在连续的内存中,这意味着从char * ticker移动到char ticker[8],并替换strdup()strcpy()(由您来确保没有缓冲区溢出)。