使用MPI,可以使用从相同基本类型派生并具有相同总长度的不同MPI_Datatype来发送和接收数据吗?
考虑两个MPI流程 A 和 B 。 A 有一个数组double a[n]
而 B 有一个数组double b[m]
。这两个流程都知道 A 想要发送 B k
双打,这些双打以某种方式分发在a
中(仅 A 具有关于这种分布的知识)。 B (且只有 B )知道如何在k
中排列b
双打。因此,两者都创建(通过MPI_Type_indexed
和MPI_Type_commit
)数据类型, A 对应于要从a
发送的元素和 B < / strong>对应于要将这些元素保存到b
中的位置。 A 调用MPI_Isend(a, 1, A_datatype, ...)
和 B 调用MPI_Irecv(b, 1, B_datatype, ...)
。
这有用吗?如果是,这是解决手头问题的标准方法吗?如果不是,这种数据交换通常如何进行?
答案 0 :(得分:3)
是的,它有效,而且这是一种非常标准的解决方法。
数据类型只是关于如何在发送方打包数据的指令,以及关于如何在接收方解压缩的指令。
这是一个非常有用且非常标准的MPI-IO方法。
答案 1 :(得分:2)
匹配发送和接收操作中的MPI类型必须是全等。一致性是一种较弱的等价形式。这意味着两种数据类型可能不相等,但它们的类型签名必须匹配。
每个MPI数据类型都是(offset[i], basic_type[i])
形式的元组列表,其中offset[i]
是i
项的偏移量,以字节为单位,从数据缓冲区开始(可能也是负数)而basic_type[i]
是项目的语言数据类型。这些元组的列表称为类型映射。仅基本类型列表称为类型的签名。
假设您声明了一个索引数据类型,其中包含5个块,每个块包含一个元素:
// Data type 1
MPI_Datatype type1;
int b_lens[5] = { 1, 1, 1, 1, 1 };
int b_offs[5] = { 1, 2, 3, 5, 7 };
MPI_Type_indexed(5, b_lens, b_offs, MPI_DOUBLE, &type1);
type1
具有以下类型映射: {(8,double),(16,double),(24,double),(40,double),(56,double)} 和 {double,double,double,double,double} 的类型签名。
现在使用相同数量的基本元素创建不同的连续类型:
// Data type 2
MPI_Datatype type2;
MPI_Type_contiguous(5, MPI_DOUBLE, &type2);
type2
具有以下类型映射: {(0,double),(8,double),(16,double),(24,double),(32,double)} 。此类型映射显然与type1
的映射不同,因为偏移量不同。但类型签名是相同的: {double,double,double,double,double} 。因此,type1
和type2
被认为是一致的。
以下代码是完全有效的MPI程序:
double array1[10];
double array2[5];
double array3[10];
if (rank == rank_sender)
{
MPI_Send(array1, 1, type1, rank_receiver, 0, MPI_COMM_WORLD);
MPI_Send(array1, 1, type1, rank_receiver, 0, MPI_COMM_WORLD);
}
else if (rank == rank_receiver)
{
MPI_Status status;
int num_elems;
MPI_Recv(array2, 1, type2, rank_sender, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
MPI_Recv(array3, 10, MPI_DOUBLE, rank_sender, 0, MPI_COMM_WORLD, &status);
MPI_Get_count(&status, MPI_DOUBLE, &num_elems); // num_elems will be set to 5
}
MPI_Send
来电将在发件人和array1
选择MPI_Recv
的第1,第2,第3,第5和第7个元素call将把它们放在接收器的连续5元素数组array2
中。原始数据类型MPI_DOUBLE
的10元素接收与发送消息的数据类型一致,但只填充缓冲区的前5个元素。使用数据类型调用MPI_Get_count
然后MPI_DOUBLE
会返回5
。
基本上,两种类型的一致性意味着相同基本类型和相同顺序的相同数量的数据项被打包到消息中然后解压缩。
MPI标准要求在正确的应用中具有一致性。但实际上,许多MPI实现不会在消息中传输类型签名,因此从不强制执行一致性。例如,Open MPI和MPICH都允许您在发送方使用MPI_DOUBLE
,在接收方使用MPI_LONG
(假设LP64系统)。这两种数据类型的大小相同(以字节为单位),但将double
转换为long
是没有意义的。有一些运行时MPI正确性检查工具,如MUST,可以检测代码中的此类问题。