发送/接收的MPI数据类型是否必须匹配?
我正在尝试确定发送操作和接收操作的哪些参数必须匹配要传递的消息。
我知道接收操作必须匹配(或包含)消息的来源,标签和通信器。 但是,数据类型是否需要匹配?
我可以匹配0级的发送:
MPI_Send (send_buffer, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
在1级接收操作:
MPI_Recv (recv_buffer, 4, MPI_BYTE, 0, 0, MPI_COMM_WORLD, status);
特别是因为发送’计数’小于接收计数,我知道它对MPI有效。
谢谢。
简短的回答是肯定的,数据类型必须匹配,但有一些警告。
使用原始MPI数据类型(如MPI_FLOAT
和MPI_FLOAT
,类型必须相同。 唯一的例外是MPI_PACKED
,它可以匹配任何其他类型。
使用派生数据类型(也称为用户定义的数据类型)时,事情会变得稍微复杂一些。 一般的MPI数据类型由两部分组成: 类型签名 ,它定义构成派生数据类型的基本语言数据类型,以及一系列字节位移 ,它们定义这些基本元素在内存中的位置。 两个序列的组合称为数据类型的类型映射 。 原始MPI数据类型是此类通用数据类型的特殊情况,在类型签名中具有单个基本数据类型,位移为0,例如, MPI_INT
具有以下类型映射: { (int, 0) }
。 要匹配发送和接收操作,两侧的类型签名必须相同,但位移可能会有所不同。 例如,发送方可以发送由3个MPI_FLOAT
组成的单个MPI_Type_contiguous
对象,但是接收方可以将其作为具有任意位移的3个MPI_FLOAT
的MPI_Type_indexed
类型接收。 发送方还可以提供3个MPI_FLOAT
元素的数组,例如MPI_Send(buf, 3, MPI_FLOAT, ...)
,这仍然会产生相同的类型签名。
我应该强调,类型签名仅包含基本数据类型。 用户定义的数据类型是直接从原始MPI类型还是其他用户定义的数据类型(或其混合)创建的,这是无关紧要的。
示例:发送MPI_Type_struct
包含3个MPI_FLOAT
和2个MPI_FLOAT
。 接收器定义MPI_Type_contiguous
包括3个MPI_Type_contiguous
(让我们称之为A
),另一个MPI_Type_contiguous
为2个MPI_FLOAT
(类型B
),然后是由1个A
和MPI_Type_struct
组成的MPI_Type_struct
。 这两种数据类型将匹配,因为最终它们都是3个int
然后是2个float
。