并行算法讲义 联系客服

发布时间 : 星期二 文章并行算法讲义更新完毕开始阅读d6ac36768e9951e79b8927da

INTEGER ARRAY_OF_STATUSES(MPI_STATUS_SIZE,*) LOGICAL FLAG

当函数返回值等于 MPI_ERR_IN_STATUS 时表明部分通信请求的处理出错,此时用户应检查array_of_statuses 的每个元素中 MPI_ERROR 域的值来得到这些通信请求的错误码。 §3.4.3.4 等待、 检测一组通信器请求中一部分的完成 C

int MPI_Waitsome(int incount, MPI_Request *array_of_requests, int outcount, int *array_of_indices, MPI_Status *array_of_statuses) int MPI_Testsome(int incount, MPI_Request *array_of_requests, int outcount, int *array_of_indices, MPI_Status *array_of_statuses)

Fortran 77

MPI_WAITSOME(INCOUNT, ARRAY_OF_REQUESTS, OUTCOUNT, + ARRAY_OF_INDICES, ARRAY_OF_STATUSES, IERR)

INTEGER INCOUNT, ARRAY_OF_REQUESTS(*), OUTCOUNT, + ARRAY_OF_INDICES(*), IERR

INTEGER ARRAY_OF_STATUSES(MPI_STATUS_SIZE,*)

MPI_TESTSOME(INCOUNT, ARRAY_OF_REQUESTS, OUTCOUNT, + ARRAY_OF_INDICES, ARRAY_OF_STATUSES, IERR)

INTEGER INCOUNT, ARRAY_OF_REQUESTS(*), OUTCOUNT, + ARRAY_OF_INDICES(*), IERR

INTEGER ARRAY_OF_STATUSES(MPI_STATUS_SIZE,*)

outcount中返回的是成功完成的通信请求个数。array_of_indices的前 outcount 个元素给出已完成的通信请求在数组 array_of_requests中的位置。当指定的通信请求中至少有一个已完成时,或发生错误时 MPI_Waitsome才返回,而 MPI_Testsome当所有指定的通信请求都未完成时在outcount中返回 0。

当函数返回值等于 MPI_ERR_IN_STATUS时表明部分通信请求的处理出错,此时用户应检查array_of_statuses的每个元素中 MPI_ERROR 域的值来得到这些通信请求的错误码。 §3.4.4 通信请求的释放 C

int MPI_Request_free(MPI_Request *request)

Fortran 77

MPI_REQUEST_FREE(REQUEST, IERR) INTEGER REQUEST, IERR

MPI_Request_free 释放指定的通信请求 (及所占用的内存)。如果与该通信请求相关联的通信尚未完成,则 MPI_Request_free 会等待通信的完成。函数成功返回后 request的值将被置成MPI_REQUEST_NULL。

例 3.7 非阻塞消息传递: 【 03-ex7.f 】 §3.5 消息探测与通信请求的取消 §3.5.1 消息探测 C

int MPI_Probe(int source, int tag, MPI_Comm comm, MPI_Status status)

Fortran 77

MPI_PROBE(SOURCE, TAG, COMM, STATUS, IERR) INTEGER SOURCE, TAG, COMM, IERR INTEGER STATUS(MPI_STATUS_SIZE)

25

例:在接收未知长度的消息时,可先用 M PI_Probe 和 MPI_Get_count得到消息的长度。 MPI_Probe 属于阻塞型函数,它等待直到一个符合条件的消息到达后才返回。 对应的非阻塞函数为 MPI_Iprobe,它不论是否有符合条件的消息都立即返回。如果探测到符合条件的消息flag = true,否则 flag = false。 C

int MPI_Iprobe(int source, int tag, MPI_Comm comm, int *flag, MPI_Status *status)

Fortran 77

MPI_IPROBE(SOURCE, TAG, COMM, FLAG, STATUS, IERR) INTEGER SOURCE, TAG, COMM, IERR INTEGER STATUS(MPI_STATUS_SIZE) LOGICAL FLAG

§3.5.2 通信请求的取消 C

int MPI_Cancel(MPI_Request *request)

int MPI_Test_cancelled(MPI_Status *status, int *flag)

Fortran 77

MPI_CANCEL(REQUEST, IERR) INTEGER REQUEST, IERR

MPI_TEST_CANCELLED(STATUS, FLAG, IERR) INTEGER STATUS(MPI_STATUS_SIZE), IERR LOGICAL FLAG

MPI_Cancel用于取消一个尚未完成的通信请求,它在 MPI 系统中设置一个取消该通信请求的标志然后立即返回,具体的取消操作由 MPI系统在后台完成。调用 MPI_Cancel后,仍需调用MPI_Wait, MPI_Test,或 MPI_Request_free 等函数来完成并释放该通信请求。 MPI_Test_cancelled 可用来检测一个通信请求是否已被取消,返回 flag = true 如果该

通信请求已被取消。

26 §3.6 点对点通信函数汇总 函数类型 消息发送函数 消息接收函数 消息检测函数 等待/查询函数 释放通信请求 取消通信 通信模式 标准模式 缓冲模式 同步模式 就绪模式 阻塞型 MPI_Send MPI_Bsend MPI_Ssend MPI_Rsend MPI_Recv MPI_Probe MPI_Wait MPI_Waitall MPI_Waitany MPI_Waitsome MPI_Request_free 非阻塞型 MPI_Isend MPI_Ibsend MPI_Issend MPI_Irsend MPI_Irecv MPI_Iprobe MPI_Test MPI_Testall MPI_Testany MPI_Testsome MPI_Cancel MPI_Test_cancelled §3.7 持久通信请求

持久通信请求 (persistent communication request) 可用于以完全相同的方式 (相同的通信器、 收发缓冲区 、 数据类型与长度、 源/目的地址和消息标签) 重复收发的消息。目的是减少处理消息的开销及简化 MPI 程序。 §3.7.1 创建持久消息发送请求 C

int MPI_Send_init(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request)

Fortran 77

MPI_SEND_INIT(BUF, COUNT, DATATYPE, DEST, TAG, COMM, + REQUEST, IERR) BUF(*)

INTEGER REQUEST, COUNT, DATATYPE, DEST, TAG, COMM, + REQUEST, IERR

创建一个持久消息发送请求,该函数并不开始实际消息的发送,而只是创建一个请求句柄并返回给用户程序,留待以后实际消息发送时用。

MPI_Send_init 对应于标准模式的非阻塞发送。相应地还有三个函数

MPI_Bsend_init,MPI_Ssend_init 和MPI_Rsend_init分别对应于缓冲模式、同步模式和就绪模式的非阻塞发送,我们不在此介绍。 27 §3.7.2 创建持久消息接收请求 C

int MPI_Recv_init(void *buf, int count, MPI_Datatype datatype, int source, int tag,

MPI_Comm comm, MPI_Request *request)

Fortran 77

MPI_RECV_INIT(BUF, COUNT, DATATYPE, SOURCE, TAG, COMM, REQUEST, IERR) BUF(*)

INTEGER COUNT, DATATYPE, SOURCE, TAG, COMM, REQUEST, + IERR

创建一个持久消息接收请求,该函数并不开始实际消息的接收,而只是创建一个请求句柄并返回给用户程序,留待以后实际消息接收时用。 §3.7.3 开始基于持久通信请求的通信 C

int MPI_Start(MPI_Request *request) int MPI_Startall(int count,

MPI_Request *array_of_requests)

Fortran 77

MPI_START(REQUEST, IERR) INTEGER REQUEST, IERR

MPI_STARTALL(COUNT, ARRAY_OF_REQUESTS, IERR) INTEGER COUNT, ARRAY_OF_REQUESTS(*), IERR

每次调用 MPI_Start 相当于调用一次与 MPI_xxxx_init 相对应的非阻塞型通信函数 ( 如MPI_Isend, MPI_Irecv 等) MPI_Startall 的作用与 MPI_Start 类似,但它可一次启动多个通信。用一个 MPI_xxxx_init 创建的持久通信请求可反复调用 MPI_Start 或 M PI_Startall来完成多次通信。 §3.7.4 持久通信请求的完成与释放

与普通非阻塞型通信函数一样,通过持久通信请求启动的通信也需要调用 §3.4.3, §3.5.2 等节中介绍的函数来等待或检测通信的完成情况或取消通信,或用 MPI_Request_free 来释放一个持久通信请求。

例 3.8 使用持久通信器函数: 【 03_ex8.f 】

28

第四章 派生数据类型

MPI 的消息收发函数只能处理连续存储的同一类型的数据。当需要在一个消息中发送或接收具有复杂结构的数据时,可以通过定义派生数据类型 (derived datatype) 来实现。数据类型是 MPI 的一个重要特征,它的使用可有效地减少消息传递的次数,增大通信粒度,并且在收/发消息时避免或减少数据在内存中的拷贝 、 复制等操作。

§4.1 与数据类型有关的一些定义 §4.1.1 数据类型定义