3.3数据类型匹配和数据转换 BACKWARDFORWARD


3.3.1 类型匹配规则


我们能认为消息传送由下列三个阶段组成。   

在这三个阶段,没有看到类型匹配:在发送者缓存中的每个变量类型必须匹配该发送操作为输如指定的类型;由发送操作指定的类型必须匹配由接收操作指定的类型;在接收缓存中的每个变量的类型必须匹配由接收操作为指定的类型。不能观察到这三个规则的程序是错误的。   

为了更精确地定义,我们必须处理两个问题:宿主语言的类型和通信操作指定的类型匹配;发送者和接收者的类型匹配。   

如果发送和接收操作使用同一类型名字,那么这个发送和接收操作类型匹配(第二阶段)。即,MPI_INTEGER匹配MPI_INTEGER, MPI_REAL匹配MPI_REAL, 等等。对这个规则, 有一个例外, 将在3.13节中讨论, 类型MPI_PACKED能匹配任何其它类型。   

如果由通信操作所使用的数据类型名字相应于宿主程序变量的基本类型,那么宿主程序中该变量的类型匹配通信操作所指定的类型。例如,类型名为MPI_INTEGER的输入匹配Fortran的变量类型INTEGER。在3.2.2节给出Fortran和C的这种对照表。对最后这个规则,有两个例外:类型为名为MPI_BYTE或MPI_PACKED的一个输入能用于匹配任何存储字节(在一个字节地址的机器上), 不论包含这个字节的变量类型是什么。类型MPI_PACKED用于发送己显式打包的数据, 或接收将被显式拆包的数据,看3.13节。类型MPI_BYTE允许我们传送不变的存储中的一个字节的二进制值。   

总之,类型匹配规则分为下面三个部分。   .

下面的例子解释了前两种情况。

例子3.1 发送者和接收者指定匹配的类型。

CALL MPI_COMM_RANK(comm, rank, ierr)
IF(rank.EQ.0) THEN
@CALL MPI_SEND(a(1), 10, MPI_REAL, 1, TAG, comm, ierr)
ELSE
@CALL MPI_RECV(b(1), 15, MPI_REAL, 0, tag, comm, status, ierr)
END IF

如果a和b是尺寸大于等于10的实型数组,则这个程序是正确的。(在Fortran中,既使a或b的尺寸小于10, 使用这个程序可能是正确的: 例如, 当a(1)能等价于一个含10个元素的数组。)

例子3.2 发送者和接收者不指定匹配类型。

CALL MPI_COMM_RANK(comm, rank, ierr)
IF(rank.EQ.0) THEN
@CALL MPI_SEND(a(1), 10, MPI_REAL, 1, tag, comm, ierr)
ELSE
@CALL MPI_RECV(b(1), 40, MPI_BYTE, 0, tag, comm, status, ierr)
END IF

这个程序是错误的, 因为发送者和接收者没提供匹配的数据类型参数。

例子3.3 发送者和接收者指定无类型值的通信。

CALL MPI_COMM_RANK(comm, rank, ierr)
IF(rank.EQ.0) THEN
@CALL MPI_SEND(a(1), 40, MPI_BYTE, 1, tag, comm, ierr)
ELSE
@CALL MPI_RECV(b(1), 60, MPI_BYTE, 0, tag, comm, status, ierr)
END IF

无论a和b的尺寸和类型如何, 这个程序是正确的( 这个程序导致存储器存取越界)。

类型MPI_CHARACTER

类型MPI_CHARACTER匹配Fortran的类型为CHARACTER的一个变量中的一个字符,而不是存储在这个变量中的全部字符。类型为CHARACTER的Fortran得变量或子串好象字符数组一样被传送。在下面的例子中解释这个。

例子3.4 传送Fortran的CHARACTER类型

CHARACTER*10 a
CHARACTER*10 b

CALL MPI_COMM_RANK(comm, rank, ierr)
IF (rank.EQ.0) THEN
@CALL MPI_SEND(a, 5, MPI_CHARACTER, 1, tag, comm, ierr)
ELSE
@CALL MPI_RECV(b(6:10), 5, MPI_CHARACTER, 0, tag, comm, status, ierr)
END IF

进程1中的字符串b的最后五个字符被进程0中的字符串a的前五个字符替代。


Copyright: NPAC, PACT
BACKWARDFORWARD