gpt4 book ai didi

c - C 中的 Mpi_allgather 和 mpi_pack

转载 作者:行者123 更新时间:2023-12-04 05:52:44 26 4
gpt4 key购买 nike

我有一个带有mpi和MPI_Allgather和MPI_pack的problem。
我有结构:

typedef struct{
float a;
int b;
int c[];
}struc_t;

我初始化我的结构:
  struc_t* test=(struc_t*)malloc(sizeof(struc_t)+200*sizeof(int));

我想用 MPI_Allgather 发送我的结构数组:
int sizeSend,sizeRcv;
char *bufferSend,*bufferRecv;
int positionSend,PositionRecv;
MPI_Pack_size(10, MPI_MYTYPE , MPI_COMM_WORLD , &sizeSend);
MPI_Pack_size(10*nbProc, MPI_MYTYPE , MPI_COMM_WORLD , &sizeRcv);
MPI_Status statut;

MPI_MYTYPE 的代码:
MPI_Aint offsets[3],extent;
int blockcounts[3];
MPI_Datatype oldtypes[3];
MPI_Datatype TAB;
MPI_Type_contiguous(nb,MPI_INT,&TAB);
MPI_Type_commit(&TAB);

offsets[0]=0;
oldtypes[0] = MPI_FLOAT;
blockcounts[0] = 1;


MPI_Type_extent(MPI_FLOAT, &extent);
offsets[1]=extent;
oldtypes[1] = MPI_INT;
blockcounts[1] = 1;

MPI_Type_extent(MPI_INT, &extent);
offsets[2]=extent + offsets[1];
oldtypes[2] = TAB;
blockcounts[2] =1;

MPI_Type_struct(3, blockcounts, offsets, oldtypes, dptr);
MPI_Type_commit(MPI_MYTYPE);

我创建我的包:
positionSend=0;
positionRcv=0;
bufferSend = (char*) malloc(sizeSend);
bufferRecv = (char*) malloc(sizeRcv);

for(i=0;i<10;i++){
struc_t *elm = getElement(i);
MPI_Pack(&elm->a,1,MPI_FLOAT,bufferSend,sizeSend,&positionSend,MPI_COMM_WORLD);
MPI_Pack(&elm->b,1,MPI_INT,bufferSend,sizeSend,&positionSend,MPI_COMM_WORLD);
MPI_Pack(elm->c,200,MPI_INT,bufferSend,sizeSend,&positionSend,MPI_COMM_WORLD);
}

和接待:
MPI_Allgather(bufferSend,1, MPI_PACKED, bufferRecv,1,MPI_PACKED, MPI_COMM_WORLD);

for(i=0;i<10*nbProc;i++){

struc_t* recvStruc=(struc_t*)malloc(sizeof(struc_t)+200*sizeof(int));
MPI_Unpack(bufferRecv, sizeRcv, &positionRcv,&recvStruc->a,1, MPI_FLOAT,MPI_COMM_WORLD);
MPI_Unpack(bufferRecv, sizeRcv, &positionRcv,&recvStruc->b,1, MPI_INT,MPI_COMM_WORLD);
MPI_Unpack(bufferRecv, sizeRcv, &positionRcv,recvStruc->c,200, MPI_INT,MPI_COMM_WORLD);
}

但是 recvStruc 的结果是 0 :( 问题出在哪里?如果你帮助我,我就称你为上帝,哈哈。

谢谢

最佳答案

为什么要打包你的结构?如果它们的长度是可变的,这可能是有意义的,但是在这里您无论如何都要传输 200 个整数。更好的解决方案是仅使用 MPI 数据类型。这样你就有机会避免内存复制,如果 MPI 库确实需要在幕后打包你的数据,它可以自动完成。

这是一个工作示例:

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

typedef struct{
float a;
int b;
int c[];
} struc_t;

int main (int argc, char **argv)
{
MPI_Init(&argc, &argv);

int nproc;
MPI_Comm_size(MPI_COMM_WORLD, &nproc);

struc_t *test;

MPI_Aint struc_t_size;
MPI_Datatype struc_t_type;
{
int blocklen[] = {1, 1, 200};
MPI_Aint addr[4];
MPI_Address(test, &addr[0]);
MPI_Address(&test->a, &addr[1]);
MPI_Address(&test->b, &addr[2]);
MPI_Address(&test->c, &addr[3]);
MPI_Aint disp[] = { addr[1] - addr[0],
addr[2] - addr[0],
addr[3] - addr[0] };
MPI_Datatype types[] = {MPI_FLOAT, MPI_INT, MPI_INT};
MPI_Type_create_struct(3, blocklen, disp, types, &struc_t_type);
MPI_Type_commit(&struc_t_type);
}
MPI_Type_extent(struc_t_type, &struc_t_size);

test = malloc(struc_t_size);

// Put our rank in b to verify operation
MPI_Comm_rank(MPI_COMM_WORLD, &test->b);

void *buf = malloc(struc_t_size * nproc);

MPI_Allgather(test, 1, struc_t_type, buf, 1, struc_t_type, MPI_COMM_WORLD);

MPI_Type_free(&struc_t_type);

{
int i;
struc_t *p;
// Verify that everything was received correctly
for (i = 0; i < nproc; i++) {
p = buf + struc_t_size * i;
printf("%d %d\n", i, p->b);
}
}

MPI_Finalize();
return 0;
}

关于c - C 中的 Mpi_allgather 和 mpi_pack,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9879355/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com