我有一些特殊问题:在一个简单的MPI_Send / MPI_Recv程序中,假设我们知道要发送的消息类型,但在接收端我们不知道我们将收到哪种类型的数据。
所以我尝试首先尝试如下:
#include "mpi.h"
#include <stdlib.h>
#include <stdio.h>
int main(int args, char** argv){
int rank, size;
MPI_Status status;
MPI_Init(&args,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);
if(rank==0){
int x = 10;
MPI_Send(&x,4,MPI_BYTE,1,0,MPI_COMM_WORLD);
}
if(rank==1){
void* datax;
int count = sizeof(int);
datax = malloc(count);
MPI_Recv(datax,count,MPI_BYTE,0,0,MPI_COMM_WORLD,&status);
//Now check if the value is received correctly
int z = (int) datax;
printf("RCV: %d \n",z);
}
MPI_Finalize();
return 0;
}
程序正确编译并运行,但收到的值是一些内存垃圾值不正确(在这种情况下为10)。
有什么建议吗?
感谢,
答案 0 :(得分:4)
虽然你的评论解决了编程错误,但在MPI中发送和接收未知类型(甚至是未知大小)的数据的方法要好得多。
区分不同消息类型的一种常用方法是为每种类型使用不同的标记号。在您的代码中,您在MPI_Send
电话中使用了标签号0。使用描述邮件类型的标记号,然后在MPI_Recv
调用之前使用MPI_Probe
找出您将要收到的邮件类型。例如,您的代码可以像这样修改:
if (rank == 0) {
MPI_Send(data_buf, data_size, MPI_BYTE, 1, tag_that_describes_message_type, MPI_COMM_WORLD)
} else if (rank == 1) {
MPI_Status status;
// Probe for a message coming from rank 0 with any tag.
MPI_Probe(0, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
// Find out what type of message is ready to be received by accessing the MPI_TAG variable in the status struct
if (status.MPI_TAG == 0) {
// Receive messages of this type. Maybe you sent an array of ints?
MPI_Recv(...)
} else if (status.MPI_TAG == 1) {
// Receive messages of this type. Maybe you sent an array of floats? Handle it here.
MPI_Recv(...)
} else if ...
MPI_Probe
也可用于在收到消息之前查找消息的大小,从而允许您动态接收几乎任何类型的消息。有关为此目的使用MPI_Probe
的更好解释和说明,请转到this tutorial。
如果您需要发送大量不同类型的数据(太多而无法使用标记号进行枚举),请将您的邮件打包到Google Protocol Buffer,然后将其作为MPI_BYTE
的数组接收(就像您一样)在您的示例中执行),然后在接收方将其解压缩。协议缓冲区的C实现是here。