你的程序在多个层面上是错误的。首先,有在有条件的错误:
if(comm_rank=root){
这并不比comm_rank
到root
而是分配root
到comm_rank
,然后循环只会执行,如果root
是非零和除它以外将由所有级别执行。
二,根过程不需要将数据发送到本身,因为数据已经存在。即使您想要发送和接收,您应该注意到MPI_Send
和MPI_Recv
都仔细阅读了相同的缓冲区空间,这是不正确的。某些MPI实现使用直接存储器副本进行自我交互,即库可能使用memcpy()
来传输消息。使用memcpy()
与重叠的缓冲区(包括使用相同的缓冲区)会导致未定义的行为。
实现线性广播正确的方法是:
void My_MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm)
{
int comm_rank, comm_size, i;
MPI_Comm_rank(comm, &comm_rank);
MPI_Comm_size(comm, &comm_size);
if (comm_rank == root)
{
for (i = 0; i < comm_size; i++)
{
if (i != comm_rank)
MPI_Send(buffer, count, datatype, i, 0, comm);
}
}
else
MPI_Recv(buffer, count, datatype, root, 0, comm, MPI_STATUS_IGNORE);
}
一个进程与自身没有锁死通常的方式是:
- 使用
MPI_Isend
和MPI_Recv
或组合的组合MPI_Send
和MPI_Irecv
;
- 使用缓冲发送
MPI_Bsend
;使用MPI_Sendrecv
或MPI_Sendrecv_replace
。
的MPI_Irecv
和MPI_Send
作品以及在多发案件的组合在你们这样一个循环完成。例如:
MPI_Request req;
// Start a non-blocking receive
MPI_Irecv(buff2, count, datatype, root, 0, comm, &req);
// Send to everyone
for (i = 0; i < comm_size; i++)
MPI_Send(buff1, count, datatype, i, 0, comm);
// Complete the non-blocking receive
MPI_Wait(&req, MPI_STATUS_IGNORE);
请注意使用单独的缓冲区进行发送和接收。可能是唯一允许使用同一缓冲区发送和接收的点对点MPI通信呼叫是MPI_Sendrecv_replace
以及集体MPI呼叫的就地模式。但是这些内部实现方式使得在任何时候都不会使用相同的存储区域来发送和接收。
在我的电脑上正常工作。你确定你没有混合指针/地址? – Sleepyhead
@Sleepyhead,用大号“count”来试试。较小的消息通常被缓存或使用渴望的协议发送。 –