MPI_IRecv / MPI_ISend应该具有相同的`count`吗?

时间:2017-05-03 15:04:40

标签: parallel-processing mpi

一对MPI_IRecv/MPI_ISend是否应该获得相同的count

 int MPI_Irecv(void *buf, int count, MPI_Datatype datatype, int source,
           int tag, MPI_Comm comm, MPI_Request *request)
 ...
  count
    number of elements in receive buffer (integer)

documentation似乎表明不应该这样做,但我对措辞感到困惑,它与MPI_Recv略有不同。我附上了一个例子,如果我通过不同的count,我会期待。

生成文件

 cc=mpicc

 isend :  isend.c; $(cc) $< -o $@
 run: isend
 run:; mpiexec -np 2 ./isend

 clean:; rm -f isend
 .PHONY: clean run

isend.c

/* Usage: make run */
#include <stdio.h>
#include <mpi.h>  
#define send_cnt  1
#define recv_cnt 10    
#define SEND 0 /* who sends and who receives? */
#define RECV 1    
#define TAG 0
#define COMM MPI_COMM_WORLD  

MPI_Status  status;
MPI_Request request;

void send() {
  int dest = RECV;
  int buf[] = {42};
  MPI_Isend(buf, send_cnt, MPI_INT, dest, TAG, COMM, &request);
  MPI_Wait(&request, &status);
}

void recv() {
  int dest = SEND;
  int buf[123];
  MPI_Irecv(buf, recv_cnt, MPI_INT, dest, TAG, COMM, &request);
  MPI_Wait(&request, &status);
  printf("recv: %d\n", buf[0]);
}

int main(int argc, char *argv[]) {
  int rank;
  MPI_Init(&argc, &argv);
  MPI_Comm_rank(COMM, &rank);    
  if (rank == SEND) send();
  else              recv();    
  MPI_Finalize();
  return 0;
}

1 个答案:

答案 0 :(得分:2)

MPI_RecvMPI_Irecv都将允许写入缓冲区的最大数据元素量作为参数。此数字不一定必须等于传递给MPI_Send的数量 - 它可能更大或更小。当接收缓冲区中没有足够的空间容纳消息时,MPI将发出截断错误信号。当空间大于消息大小时,只会写入缓冲区的一部分。在后一种情况下,可以使用MPI_Get_count来检查MPI_Recv / MPI_Test* / MPI_Wait*返回的MPI状态对象。

传递给MPI_(I)Recv的计数小于传递给MPI_Send的计数的合法情况 - 不同的数据类型。例如,可以发送10个MPI_INT并接收由10 MPI_INT组成的连续数据类型的单个元素。在您的情况下,发送和接收操作都使用相同的数据类型,因此接收计数必须至少与发送计数一样大。

顺便说一句,你的代码缺少一个等待/测试MPI_Isend创建的请求的调用,这是错误的。