通过MPI发送c结构部分失败
我正在使用通过MPI发送c结构部分失败,c,struct,mpi,C,Struct,Mpi,我正在使用MPI\u Type\u create\u struct()发送一个(粒子)结构,如已完成或详细说明。 我正在收集所有要进入特定进程的粒子,memcpy()将它们收集到发送缓冲区中,然后MPI\u Isend()将它们收集起来 到目前为止,一切顺利MPI_Iprob()'ing为消息提供正确的发送粒子数。 因此,我MPI_Recv()缓冲区并提取数据(现在甚至通过逐个复制结构)。无论我发送多少粒子,只有第一个粒子的数据是正确的 有三种可能的错误: MPI\u Type\u create
MPI\u Type\u create\u struct()
发送一个(粒子)结构,如已完成或详细说明。
我正在收集所有要进入特定进程的粒子,memcpy()
将它们收集到发送缓冲区中,然后MPI\u Isend()
将它们收集起来
到目前为止,一切顺利MPI_Iprob()
'ing为消息提供正确的发送粒子数。
因此,我MPI_Recv()
缓冲区并提取数据(现在甚至通过逐个复制结构)。无论我发送多少粒子,只有第一个粒子的数据是正确的
有三种可能的错误:
MPI\u Type\u create\u struct()
无法创建我的结构的正确映射,因为我在第一个链接中使用了offset of()
。可能我的结构包含一个不可见的填充,如第二个链接中所述typedef结构{
int-ID;
双x[DIM];
}p相粒子;
const int items=2;
int block_length[2]={1,DIM};
MPI_数据类型MPI_类型[2]={MPI_INT,MPI_DOUBLE};
MPI_Aint偏移量[2];
偏移量[0]=偏移量(pchase\u particle\u t,ID);
偏移量[1]=偏移量(pchase\u particle\u t,x);
MPI\u类型\u创建\u结构(项目、块长度、偏移、MPI\u类型,&W->MPI\u粒子);
MPI_类型_提交(&W->MPI_粒子);
派遣
/*处理所有mpi发送/接收状态数据*/
MPI_请求*发送_请求=P4EST_ALLOC(MPI_请求,W->P4EST->mpisize);
MPI_状态*recv_状态=P4EST_ALLOC(MPI_状态,W->P4EST->mpisize);
/*设置发送/接收缓冲区*/
pchase\u particle\u t**recv\u buf=P4EST\u ALLOC(pchase\u particle\u t*,数量发送器);
pchase\u particle\u t**send\u buf=P4EST\u ALLOC(pchase\u particle\u t*,num\u receiver);
int recv_count=0,recv_长度,标志,j;
/*将所有粒子发送到它们所属的进程*/
对于(i=0;iparticles_to,receivers[i]);
Phase_particle_t*tmpParticle;
int send_count=0;
/*为要发送的粒子获取空间*/
send_buf[i]=P4EST_ALLOC(pchase_particle,tmpList->elem_count);
/*将所有粒子复制到发送缓冲区,并从此过程中移除它们*/
while(tmpList->first!=NULL){
tmpParticle=sc_list_pop(tmpList);
memcpy(send_buf[i]+send_count*sizeof(pchase_particle_t)、tmpParticle、sizeof(pchase_particle_t));
/*自由粒子*/
P4EST_FREE(tmpParticle);
/*更新粒子计数器*/
发送_计数++;
}
/*打印发送缓冲区*/
对于(j=0;jp4est->mpirank,tmpParticle->ID,tmpParticle->x[0],tmpParticle->x[1]);
}
printf(“[pchase%i sending]粒子数:%i\n”,W->p4est->mpirank,send\u count);
/*将粒子发送给右所有者*/
mpiret=MPI Isend(发送buf[i],发送计数,W->MPI\u粒子,接收器[i],13,W->p4est->mpicomm,&send\u请求[i]);
SC检查MPI(mpiret);
}
还有接球
recv_count=0;
/*在所有邮件到达之前检查邮件*/
while(recv_countp4est->mpicomm,
&标志和记录状态[i];
国际单项体育联合会(旗){
/*解析接收到的粒子数*/
MPI_获取_计数(&recv_状态[i],W->MPI_粒子和&recv_长度);
printf(“[pchase%i receiving message]%i粒子从发件人%i到达,标记为%i\n”,
W->p4est->mpirank,recv_长度,recv_状态[i]。MPI_源,recv_状态[i]。MPI_标记);
/*为要发送的粒子获取空间*/
recv_buf[recv_count]=P4EST_ALLOC(pchase_particle_t,recv_length);
/*接收包含recv_长度粒子的列表*/
mpiret=MPI\u Recv(Recv\u buf[Recv\u count],Recv\u长度,W->MPI\u粒子,Recv\u状态[i]。MPI\u源,
recv_status[i].MPI_标记,W->p4est->mpicomm,&recv_status[i]);
SC检查MPI(mpiret);
/*
*将所有接收到的粒子插入到
*推送列表
*/
Phase_particle_t*tmpParticle;
对于(j=0;jID=tmpParticle->ID;
addParticle->x[0]=tmpParticle->x[0];
addParticle->x[1]=tmpParticle->x[1];
printf(“[pchase%i接收]粒子[%i](%lf,%lf)\n”,
W->p4est->mpirank,addParticle->ID,addParticle->x[0],addParticle->x[1]);
/*将接收到的粒子推送到推送列表并更新世界计数器*/
sc\u list\u append(W->particle\u push\u list,addParticle);
W->n_粒子++;
}
/*我们收到了另一个粒子列表*/
recv_count++;
}
}
}
编辑:重新凹入。。
编辑:只有第一个粒子的数据是正确的,这意味着它的所有属性(ID和坐标)都与发送的粒子的属性相同。然而,其他的用零初始化,即ID=0,x[0]=0.0,x[1]=0.0。也许这是解决问题的一个暗示 指针中有错误
/* handle all mpi send/recv status data */
MPI_Request *send_request = P4EST_ALLOC(MPI_Request, W->p4est->mpisize);
MPI_Status *recv_status = P4EST_ALLOC(MPI_Status, W->p4est->mpisize);
/* setup send/recv buffers */
pchase_particle_t **recv_buf = P4EST_ALLOC(pchase_particle_t *, num_senders);
pchase_particle_t **send_buf = P4EST_ALLOC(pchase_particle_t *, num_receivers);
int recv_count = 0, recv_length, flag, j;
/* send all particles to their belonging procs */
for (i = 0; i < num_receivers; i++) {
/* resolve particle list for proc i */
sc_list_t *tmpList = *((sc_list_t **) sc_array_index(W->particles_to, receivers[i]));
pchase_particle_t * tmpParticle;
int send_count = 0;
/* get space for the particles to be sent */
send_buf[i] = P4EST_ALLOC(pchase_particle_t, tmpList->elem_count);
/* copy all particles into the send buffer and remove them from this proc */
while(tmpList->first != NULL){
tmpParticle = sc_list_pop(tmpList);
memcpy(send_buf[i] + send_count * sizeof(pchase_particle_t), tmpParticle, sizeof(pchase_particle_t));
/* free particle */
P4EST_FREE(tmpParticle);
/* update particle counter */
send_count++;
}
/* print send buffer */
for (j = 0; j < send_count; j++) {
pchase_particle_t *tmpParticle = send_buf[i] + j * sizeof(pchase_particle_t);
printf("[pchase %i sending] particle[%i](%lf,%lf)\n", W->p4est->mpirank, tmpParticle->ID, tmpParticle->x[0], tmpParticle->x[1]);
}
printf("[pchase %i sending] particle count: %i\n", W->p4est->mpirank, send_count);
/* send particles to right owner */
mpiret = MPI_Isend(send_buf[i], send_count, W->MPI_Particle, receivers[i], 13, W->p4est->mpicomm, &send_request[i]);
SC_CHECK_MPI(mpiret);
}