MPI参考手册

附录3:MPI参考手册
本附录给出主要MPI函数的参考手册。为了节省篇幅,这里仅列出MPI函数的C接口,Fortran 接口子程序的参数与C 接口函数的参数完全类似。除MPI_Wtime和MPI_Wtick外,Fortran接口子程序比C接口函数在最后多出一个整型参数,用于返回错误码。
所列出的MPI 函数和变量是按照它们的类别组织的。为方便查找特定的函数,附3.1 中给出了一个MPI 的函数、变量名称按字母顺序排列的索引。
本附录的内容主要参考文献[8, 9] 以及MPICH的部分在线手册编写而成。

附3.1 MPI 函数、变量速查表
本节中出现在变量或函数名后边的页码代表它们在参考手册中所在页号,主要为了方便它们的查找,没有其他含义。

MPI_2INT 37
MPI_Abort 40
MPI_Address 46
MPI_Aint 38
MPI_Allgather 47
MPI_Allgatherv 48
MPI_Allreduce 49
MPI_Alltoall 48
MPI_Alltoallv 48
MPI_ANY_SOURCE 39
MPI_ANY_TAG 39
MPI_Attr_delete 52
MPI_Attr_get 52
MPI_Attr_put 52
MPI_BAND 38
MPI_Barrier 47
MPI_Bcast 47
MPI_BOR 38
MPI_BOTTO 39
MPI_Bsend 42
MPI_Bsend_init 44
MPI_BSEND_OVERHEAD 39
MPI_Buffer_attach 42
MPI_Buffer_detach 42
MPI_BXOR 38
MPI_BYTE 37
MPI_Cancel 44
MPI_CART 39
MPI_Cart_coords 53
MPI_Cart_create 52
MPI_Cart_get 53
MPI_Cart_map 53
MPI_Cart_rank 53
MPI_Cart_shift 53
MPI_Cart_sub 53
MPI_Cartdim_get 53
MPI_CHAR 37
MPI_Comm 38
MPI_Comm_compare 51
MPI_Comm_create 51
MPI_Comm_dup 51
MPI_Comm_free 52
MPI_Comm_group 51
MPI_COMM_NULL 38
MPI_Comm_rank 51
MPI_Comm_remote_group 54
MPI_Comm_remote_size 54
MPI_COMM_SELF 37
MPI_Comm_size 51
MPI_Comm_split 51
MPI_Comm_test_inter 54
MPI_COMM_WORLD 37
MPI_CONGRUENT 37
MPI_Copy_function 38
MPI_Datatype 38
MPI_DATATYPE_NULL 38
MPI_Delete_function 38
MPI_Dims_create 52
MPI_DOUBLE 37
MPI_DOUBLE_INT 37
MPI_DUP_FN 38
MPI_ERR_ARG 40
MPI_ERR_BUFFER 39
MPI_ERR_COMM 39
MPI_ERR_COUNT 39
MPI_ERR_DIMS 40
MPI_ERR_GROUP 40
MPI_ERR_IN_STATUS 40
MPI_ERR_INTERN 40
MPI_ERR_LASTCODE 40
MPI_ERR_OP 40
MPI_ERR_OTHER 40
MPI_ERR_PENDING 40
MPI_ERR_RANK 39
MPI_ERR_REQUEST 40
MPI_ERR_ROOT 39
MPI_ERR_TAG 39
MPI_ERR_TOPOLOGY 40
MPI_ERR_TRUNCATE 40
MPI_ERR_TYPE 39
MPI_ERR_UNKNOWN 40
MPI_Errhandler 38
MPI_Errhandler_create 40
MPI_Errhandler_free 41
MPI_Errhandler_get 41
MPI_ERRHANDLER_NULL 38
MPI_Errhandler_set 41
MPI_Error_class 41
MPI_Error_string 41
MPI_ERRORS_ARE_FATAL 38
MPI_ERRORS_RETURN 38
MPI_Finalize 40
MPI_FLOAT 37
MPI_FLOAT_INT 37
MPI_Gather 47
MPI_Gatherv 48
MPI_Get_count 47
MPI_Get_elements 47
MPI_Get_processor_name 40
MPI_GRAPH 39
MPI_Graph_create 54
MPI_Graph_get 54
MPI_Graph_map 54
MPI_Graph_neighbors 54
MPI_Graph_neighbors_count 54
MPI_Graphdims_get 54
MPI_Group 38
MPI_Group_compare 50
MPI_Group_difference 50
MPI_GROUP_EMPTY 37
MPI_Group_excl 50
MPI_Group_free 51
MPI_Group_incl 50
MPI_Group_intersection 50
MPI_GROUP_NULL 38
MPI_Group_range_excl 50
MPI_Group_range_incl 50
MPI_Group_rank 50
MPI_Group_size 50
MPI_Group_translate_ranks 51
MPI_Group_union 51
MPI_Handler_function 38
MPI_HOST 39
MPI_Ibsend 42
MPI_IDENT 37
MPI_Init 40
MPI_Initialized 40
MPI_INT 37
MPI_Intercomm_create 54
MPI_Intercomm_merge 54
MPI_IO 39
MPI_Iprobe 44
MPI_Irecv 42
MPI_Irsend 42
MPI_Isend 42
MPI_Issend 43
MPI_Keyval_create 52
MPI_Keyval_free 52
MPI_KEYVAL_INVALID 39
MPI_LAND 38
MPI_LB 37
MPI_LONG 37
MPI_LONG_DOUBLE 37
MPI_LONG_DOUBLE_INT 37
MPI_LONG_INT 37
MPI_LONG_LONG_INT 37
MPI_LOR 38
MPI_LXOR 38
MPI_MAX 38
MPI_MAX_ERROR_STRING 39
MPI_MAX_PROCESSOR_NAME 39
MPI_MAXLOC 38
MPI_MIN 38
MPI_MINLOC 38
MPI_NULL_COPY_FN 38
MPI_NULL_DELETE_FN 38
MPI_Op 38
MPI_Op_create 49
MPI_Op_free 50
MPI_OP_NULL 38
MPI_Pack 46
MPI_Pack_size 46
MPI_PACKED 37
MPI_Probe 42
MPI_PROC_NULL 39
MPI_PROD 38
MPI_Recv 41
MPI_Recv_init 44
MPI_Reduce 48
MPI_Reduce_scatter 49
MPI_Request 38
MPI_Request_free 44
MPI_REQUEST_NULL 38
MPI_Rsend 42
MPI_Rsend_init 45
MPI_Scan 49
MPI_Scatter 48
MPI_Scatterv 48
MPI_Send 41
MPI_Send_init 44
MPI_Sendrecv 41
MPI_Sendrecv_replace 42
MPI_SHORT 37
MPI_SHORT_INT 37
MPI_SIMILAR 37
MPI_Ssend 42
MPI_Ssend_init 45
MPI_Start 44
MPI_Startall 44
MPI_Status 38
MPI_SUCCESS 39
MPI_SUM 38
MPI_TAG_UB 39
MPI_Test 43
MPI_Test_cancelled 43
MPI_Testall 43
MPI_Testany 43
MPI_Testsome 43
MPI_Topo_test 52
MPI_Type_commit 46
MPI_Type_contiguous 45
MPI_Type_dup 47
MPI_Type_extent 47
MPI_Type_free 46
MPI_Type_hindexed 45
MPI_Type_hvector 45
MPI_Type_indexed 45
MPI_Type_lb 47
MPI_Type_size 47
MPI_Type_struct 46
MPI_Type_ub 47
MPI_Type_vector 45
MPI_UB 37
MPI_UNDEFINED 39
MPI_UNDEFINED_RANK 39
MPI_UNEQUAL 37
MPI_Unpack 46
MPI_UNSIGNED 37
MPI_UNSIGNED_CHAR 37
MPI_UNSIGNED_LONG 37
MPI_UNSIGNED_SHORT 37
MPI_User_function 38
MPI_Wait 43
MPI_Waitall 43
MPI_Waitany 43
MPI_Waitsome 44
MPI_Wtick 55
MPI_Wtime 55
MPI_WTIME_IS_GLOBAL 39

附3.2 MPI 预定义的变量及类型
附3.2.1 C语言MPI原始数据类型
C语言中表示MPI数据类型的变量类型是MPI_Datatype。

  1. 基本数据类型
    MPI_CHAR 对应于char。
    MPI_BYTE 对应于unsigned char。
    MPI_SHORT 对应于short。
    MPI_INT 对应于int。
    MPI_LONG 对应于long。
    MPI_FLOAT 对应于float。
    MPI_DOUBLE 对应于double。
    MPI_UNSIGNED_CHAR 对应于unsigned char。
    MPI_UNSIGNED_SHORT 对应于unsigned short。
    MPI_UNSIGNED 对应于unsigned int。
    MPI_UNSIGNED_LONG 对应于unsigned long。
    MPI_LONG_DOUBLE 对应于long double (有的系统不支持)。
    MPI_LONG_LONG_INT 对应于long long (有的系统不支持)。

  2. 特殊数据类型
    MPI_PACKED MPI_Pack和MPI_Unpack函数用的打包类型。
    MPI_UB 用于在MPI_Type_struct函数中设定数据类型的上界。
    MPI_LB 用于在MPI_Type_struct函数中设定数据类型的下界。

  3. MPI MAXLOC 和MPI MINLOC 中使用的数据类型
    MPI_FLOAT_INT 对应于struct {float,int}。
    MPI_LONG_INT 对应于struct {long,int}。
    MPI_DOUBLE_INT 对应于struct {double,int}。
    MPI_SHORT_INT 对应于struct {short,int}。
    MPI_2INT 对应于struct {int,int}。
    MPI_LONG_DOUBLE_INT 对应于struct {long double,int}。

附3.2.2 预定义的通信器与进程组
MPI的通信器和进程组在C语言中的变量类型分别为MPI_Comm和MPI_Group,它们在Fortran语言中都用INTEGER表示。
MPI_COMM_WORLD 包含所有进程的通信器。
MPI_COMM_SELF 只包含本进程的通信器。
MPI_GROUP_EMPTY 空进程组(不包含任何进程)。

通信器或进程组的比较结果
MPI_IDENT 表示两个通信器或进程组完全一样。
MPI_CONGRUENT 表示两个通信器包含的进程组一样(参看MPI_Comm_compare)。
MPI_SIMILAR 表示两个通信器或进程组中的进程集合一样,但进程排序不同。
MPI_UNEQUAL 表示两个通信器或进程组不相同。

附3.2.3 用于归约函数的预定义的二目运算
MPI用于进行归约运算的函数有MPI_Reduce、MPI_Allreduce、MPI_Reduce_scatter和MPI_Scan,它们所使用的二目运算在C中的类型为MPI_Op,在Fortran中的类型为INTEGER。
MPI_MAX 两个操作数中较大的一个。
MPI_MIN 两个操作数中较小的一个。
MPI_SUM 两个操作数之和。
MPI_PROD 两个操作数之积。
MPI_LAND 两个操作数的逻辑与(logical and)。
MPI_BAND 两个操作数的按位与(bitwise and)。
MPI_LOR 两个操作数的逻辑或(logical or)。
MPI_BOR 两个操作数的按位或(bitwise or)。
MPI_LXOR 两个操作数的逻辑异或(logical xor)。
MPI_BXOR 两个操作数的按位异或(bitwise xor)。
MPI_MINLOC 两对操作数中较小一个的值和位置。
MPI_MAXLOC 两对操作数中较大一个的值和位置。

附3.2.4 C变量类型及预定义函数
MPI_Status 存储通信状态的变量(参看3.2.8)。
MPI_Aint 存放地址或位移的变量。
MPI_Datatype 数据类型变量。
MPI_Request 通信请求变量。
MPI_Comm 通信器变量。
MPI_Group 进程组变量。
MPI_Op 归约操作的二目运算操作句柄。
MPI_User_function 聚合通信中的自定义函数(参看MPI_Op_create)。
MPI_Copy_function 通信器属性复制函数(参看MPI_Keyval_create)。
MPI_Delete_function 通信器属性删除函数(参看MPI_Keyval_create)。
MPI_NULL_COPY_FN 预定义的属性拷贝函数。
MPI_NULL_DELETE_FN 预定义的属性删除函数。
MPI_DUP_FN 预定义的属性复制函数。
MPI_Errhandler 错误处理函数句柄。
MPI_Handler_function 错误处理函数(参看MPI_Errhandler_create)。
MPI_ERRORS_ARE_FATAL 预定义的错误处理函数:发生错误则立即退出(默认行为)。
MPI_ERRORS_RETURN 预定义的错误处理函数:发生错误时返回错误码,程序继续运行。

附3.2.5 空对象
MPI_COMM_NULL 空通信器。
MPI_OP_NULL 空操作。
MPI_GROUP_NULL 空进程组。
MPI_DATATYPE_NULL 空数据类型。
MPI_REQUEST_NULL 空请求(空回执)。
MPI_ERRHANDLER_NULL 空错误处理过程。

附3.2.6 MPI 常量
MPI_TAG_UB 最大标签值(不小于216 -1)。
MPI_HOST 该变量给出主机所在的进程号(如果有主机的话)。
MPI_IO 具有输入、输出能力的进程号。
MPI_WTIME_IS_GLOBAL 代表MPI_Wtime函数返回的时间是否是全局同步的。
MPI_MAX_PROCESSOR_NAME 给出MPI_Get_processor_name返回的处理器名称最大长度。
MPI_MAX_ERROR_STRING 给出MPI_Error_string返回的错误信息的最大长度。
MPI_UNDEFINED 被许多MPI函数用于表示未知或未定义的
整数值。
MPI_UNDEFINED_RANK 未定义的进程号。
MPI_KEYVAL_INVALID 用于表示非法或未定义的keyvalue。
MPI_BSEND_OVERHEAD 给出MPI_Bsend附加的额外数据长度。
MPI_PROC_NULL 空进程,与空进程进行通信相当于空操作。
MPI_ANY_SOURCE 接收操作中用于表示从任何源地址接收。
MPI_ANY_TAG 接收操作中用于表示接收任何标签的消息。MPI_BOTTO 表示MPI 地址空间的基底地址
(参看MPI_Address)。
附3.2.7 进程拓扑结构
MPI_GRAPH 图结构。
MPI_CART 笛卡尔结构。
附3.2.8 通信状态信息
C语言中,MPI利用结构MPI_Status来返回消息传递的完成情况。该结构中包含下述成员可供调用程序查询:

附3.2.9 错误码
MPI_SUCCESS 操作成功。
MPI_ERR_BUFFER 非法缓冲区指针。
MPI_ERR_COUNT 非法个数。
MPI_ERR_TYPE 非法数据类型。
MPI_ERR_TAG 非法消息标签。
MPI_ERR_COMM 非法通信器。
MPI_ERR_RANK 非法进程号。
MPI_ERR_ROOT 非法根进程。
MPI_ERR_GROUP 非法进程组。
MPI_ERR_OP 非法归约运算操作。
MPI_ERR_TOPOLOGY 非法进程拓扑结构。
MPI_ERR_DIMS 非法维数。
MPI_ERR_ARG 非法参数。
MPI_ERR_UNKNOWN 未知错误。
MPI_ERR_TRUNCATE 接收数据时消息被截断。
MPI_ERR_OTHER 其他错误,错误信息可通过MPI_Error_string获得。
MPI_ERR_INTERN 内部错误。
MPI_ERR_IN_STATUS 错误码在状态变量的MPI_ERROR元素中
(参看MPI_Status)。
MPI_ERR_PENDING 有尚未完成的请求。
MPI_ERR_REQUEST 非法请求(MPI_Request)。
MPI_ERR_LASTCODE 该值位于错误码列表的最后。

附3.3 初始化、退出与错误处理函数
int MPI_Init(int *argc, char ***argv)

初始化MPI系统。通常它应该是第一个被调用的MPI函数。除MPI_Initialized外,其他所有MPI函数仅在调用了该函数后才可以被调用。argc和argv分别是命令行参数的个数和参数数组的指针(通过C的main函数得到),必须将它们如实传递给MPI系统。MPI系统通过它们得到所需的参数,并且会将MPI系统专用的参数删除而仅留下供用户程序使用的参数。
参看MPI_Initialized,MPI_Finalize,MPI_Abort。
int MPI_Initialized(int *flag)

用于检查MPI系统是否已经初始化。如果已经调用过MPI_Init则返回值flag != 0,否则返回值flag == 0。这是唯一可以在MPI_Init之前调用的函数。
参看MPI_Init。
int MPI_Finalize(void)

退出MPI系统。所有MPI进程在正常退出前都必须调用该函数。它是MPI程序中最后一个被调用的MPI函数。调用MPI_Finalize后不允许再调用任何MPI函数。调用该函数前应该确认所有的(非阻塞型) 通信均已完成。
参看MPI_Init,MPI_Initialized,MPI_Abort。
int MPI_Abort(MPI_Comm comm, int errorcode)

调用该函数时表明因为出现了某种致命错误而希望立即终止MPI程序的执行。MPI系统会尽量设法终止通信器comm中的所有进程。在UNIX系统环境中,errorcode被作为进程的退出码(exit code) 返回给操作系统。
参看MPI_Init 和MPI_Finalize。
int MPI_Get_processor_name(char *name, int *resultlen)

该函数返回运行本进程的处理器名称。参数name应该提供不少于MPI_MAX_PROCESSOR_NAME个字节的存储空间用于存放处理器名称。
int MPI_Errhandler_create(MPI_Handler_function *function,MPI_Errhandler *errhandler)

注册异常处理函数。参数function为异常处理函数,errhandler返回一个可用于MPI_Errhandler_set的句柄。function 应该是一个如下形式的C函数:
void function(MPI_Comm *comm, int *errcode, …)
其中comm是与之相关联的通信器,errcode为错误码(它们都是输入参数,使用地址是为了方便编写Fortran异常处理函数)。其余参数与MPI的具体实现有关。
参看MPI_Errhandler_free和MPI_Errhandler_set等。
int MPI_Errhandler_free(MPI_Errhandler *errhandler)

释放一个已注册的异常处理函数。
参看MPI_Errhandler_create和MPI_Errhandler_set等。
int MPI_Errhandler_set(MPI_Comm comm,MPI_Errhandler errhandler)

为通信器comm指定异常处理函数。其中,参数errhandler给出异常处理函数,它可以是通过MPI_Errhandler_create注册的自定义异常处理函数,也可以是MPI预定义的异常处理函数。MPI预定义的异常处理函数有:MPI_ERRORS_ARE_FATAL和MPI_ERRORS_RETURN。
参看MPI_Errhandler_create和MPI_Errhandler_free等。
int MPI_Errhandler_get(MPI_Comm comm,MPI_Errhandler *errhandler)

获取通信器comm的异常处理函数, errhandler返回异常处理函数的句柄。
参看MPI_Errhandler_create和MPI_Errhandler_free等。
int MPI_Error_string(int errorcode, char *string,int *resultlen)

获取指定错误码的错误信息(字符串)。string的长度必须不小于
MPI_MAX_ERROR_STRING。
int MPI_Error_class(int errorcode, int *errorclass)

获取指定错误码的错误类。

附3.4 点对点通信函数
附3.4.1 阻塞型通信函数
int MPI_Send(void *buf, int count, MPI_Datatype datatype,int dest, int tag,
MPI_Comm comm)
阻塞型消息发送。参数buf为发送缓冲区;count为发送的数据个数;datatype为发送的数据类型;dest为消息的目的地址(进程号),其取值范围为0到np-1间的整数(np代表通信器comm中的进程数) 或MPI_PROC_NULL;tag为消息标签,其取值范围为0到MPI_TAG_UB间的整数;comm为通信器。
int MPI_Recv(void *buf, int count, MPI_Datatype datatype,int source, int tag,
MPI_Comm comm,MPI_Status *status)
阻塞型消息接收。参数buf为接收缓冲区;count为数据个数,它是接收数据长度的上限,具体接收到的数据长度可通过调用MPI_Get_count函数得到;datatype为接收的数据类型;source为消息源地址(进程号),其取值范围为0到np-1 间的整数(np代表通信器comm 中的进程数),或MPI_ANY_SOURCE,或MPI_PROC_NULL;tag为消息标签,其取值范围为0到MPI_TAG_UB间的整数或MPI_ANY_TAG;comm为通信器;status返回接收状态,参看MPI_Status。
int MPI_Sendrecv(void *sendbuf, int sendcnt,MPI_Datatype sendtype, int dest,int sendtag,
void *recvbuf, int recvcnt,MPI_Datatype recvtype, int source,int recvtag,
MPI_Comm comm,MPI_Status *status)
该函数将一次发送调用和一次接收调用合并进行,它使得MPI程序更为简洁。更重要的是,它能够避免阻塞型通信函数由于消息收发配对不好而引起的程序死锁。使用该函数的一个限制是sendbuf和recvbuf必须指向不同的缓冲区。各参数与MPI_Send和MPI_Recv中的参数相对应。
int MPI_Sendrecv_replace(void *buf, int count,MPI_Datatype datatype, int dest,int sendtag,
int source,int recvtag, MPI_Comm comm,MPI_Status *status)
该函数的功能与MPI_Sendrecv类似,但收发使用同一缓冲区。
int MPI_Bsend(void *buf, int count, MPI_Datatype datatype,int dest, int tag,
MPI_Comm comm)
阻塞型缓冲模式消息发送,各参数的含义与MPI_Send同。该函数将buf中的数据拷贝到事先指定的缓冲区中然后立即返回,实际发送由MPI系统在后台进行。在调用该函数前必须调用MPI_Buffer_attach函数来指定发送缓冲区。各参数的含义与MPI_Send函数相同。
int MPI_Buffer_attach(void *buffer, int size)

指定buffer做为MPI_Bsend使用的缓冲区,缓冲区的最大长度为size字节。MPI只允许提交一个供MPI_Bsend使用的缓冲区,应该保证该缓冲区足够容下用MPI_Bsend发送的消息(每个消息所需的缓冲区长度通常等于消息中数据的长度加上一个常量,可以调用函数MPI_Type_size来查询一个消息实际需要的缓冲区长度)。
int MPI_Buffer_detach(void *bufferptr, int *size)

撤销在此之前通过MPI_Buffer_attach函数提交的缓冲区。在调用MPI_Buffer_detach前不应该修改缓冲区中的内容,以免破坏正在发送的消息。该函数的返回表明所有缓冲模式的消息发送均已完成。注意该函数中bufferptr和size均为输出参数。其中bufferptr返回所撤销的缓冲区的地址,而size则返回所撤销的缓冲区的长度。
int MPI_Probe(int source, int tag, MPI_Comm comm,MPI_Status *status)

该函数等待一个符合条件的消息到达然后返回。参数source、tag和comm的含义与MPI_Recv函数相同,status返回所到达的消息的有关信息。
int MPI_Ssend(void *buf, int count, MPI_Datatype datatype,int dest, int tag,
MPI_Comm comm)
略。
int MPI_Rsend(void *buf, int count, MPI_Datatype datatype,int dest, int tag, MPI_Comm comm)
略。
附3.4.2 非阻塞型通信函数
int MPI_Isend(void *buf, int count, MPI_Datatype datatype,int dest, int tag,
MPI_Comm comm,MPI_Request *request)
非阻塞型消息发送函数。该函数递交一个消息发送请求,要求MPI系统在后台完成消息的发送。MPI系统为该发送创建一个请求并将请求的句柄通过request变量返回给调用它的进程,供随后查询/等待消息发送完成时用。其余参数的含义与MPI_Send函数相同。
int MPI_Irecv(void *buf, int count, MPI_Datatype datatype,int source, int tag,
MPI_Comm comm,MPI_Request *request)
非阻塞型消息接收函数。该函数递交一个消息接收请求,要求MPI系统在后台完成消息的接收。MPI系统为该接收创建一个请求并将请求的句柄通过request变量返回给调用它的进程,供随后查询/等待消息接收的完成时用。其余参数的含义与MPI_Recv函数相同。
int MPI_Ibsend(void *buf, int count,MPI_Datatype datatype, int dest, int tag,
MPI_Comm comm, MPI_Request *request)
略。
int MPI_Irsend(void *buf, int count,MPI_Datatype datatype, int dest, int tag,
MPI_Comm comm, MPI_Request *request)
略。
int MPI_Issend(void *buf, int count,MPI_Datatype datatype, int dest, int tag,
MPI_Comm comm, MPI_Request *request)
略。
int MPI_Test(MPI_Request *request, int *flag,MPI_Status *status)

检测指定的通信请求,不论通信是否完成都立即返回。如果通信已经完成则在flag中返回!0,(此时status中包含关于所完成的通信的信息,对于接收请求,status返回的内容与MPI_Recv返回的一样;对于发送请求,status返回的内容不确定),相应的通信请求被释放,request被置成MPI_REQUEST_NULL。如果通信尚未完成则在flag中返回0。
int MPI_Testall(int count,MPI_Request array_of_requests[],int *flag,
MPI_Status array_of_statuses[])
检测数组array_of_requests中的count个请求是否已全部完成。
如果已经全部完成则在flag中返回!0,否则在flag中返回0。当函数返回值等于MPI_ERR_IN_STATUS时表明部分通信请求处理出错,此时调
用程序可检查array_of_statuses中每个元素的MPI_ERROR成员的值来得到出错的通信请求的错误码。
int MPI_Testany(int count,MPI_Request array_of_requests[],int *index, int *flag,
MPI_Status *status)
检测数组array_of_requests中的count个请求中任何一个的完成。返回时,index包含已完成的通信请求在数组array_of_requests中的位置,其他参数的含义与MPI_Wait和MPI_Test函数相同。
int MPI_Testsome(int incount,MPI_Request array_of_requests[],int *outcount,
int array_of_indices[],MPI_Status array_of_statuses[])
检测数组array_of_requests中的incount个请求中是否已经部分完成。outcount中返回的是成功完成的通信请求个数(返回0表示所有通信请求都尚未完成),array_of_indices的前outcount个元素给出已完成的通信请求在数组array_of_requests及array_of_statuses中的位置。当函数返回值等于MPI_ERR_IN_STATUS时表明部分通信请求处理出错,此时调用程序可检查array_of_statuses中每个元素的MPI_ERROR成员的值来得到出错的通信请求的错误码。
int MPI_Test_cancelled(MPI_Status *status, int *flag)

检测一个通信请求是否已被取消,如果该通信请求已被取消,则flag中返回的值不等于0,否则返回0。
int MPI_Wait(MPI_Request *request, MPI_Status *status)

该函数等待指定的通信请求完成然后返回。成功返回时,status中包含关于所完成的通信的信息(对于接收请求,status返回的内容与MPI_Recv返回的一样;对于发送请求,status的返回的值不确定),相应的通信请求被释放,request被置成MPI_REQUEST_NULL。
int MPI_Waitall(int count,MPI_Request array_of_requests[],
MPI_Status array_of_statuses[])
等待数组array_of_requests中的count个请求全部完成然后返回。当函数返回值等于MPI_ERR_IN_STATUS时表明部分通信请求处理出错,此时调用程序可检查array_of_statuses中每个元素的MPI_ERROR成员的值来得到出错的通信请求的错误码。
int MPI_Waitany(int count,MPI_Request array_of_requests[],int *index,
MPI_Status *status)
等待数组array_of_requests中的count个请求中任何一个的完成,然后返回。成功返回时,参数index 中包含已经完成的通信请求在数组array_of_requests中的位置。
int MPI_Waitsome(int incount,MPI_Request array_of_requests[],int *outcount,
int array_of_indices[],MPI_Status array_of_statuses[])
等待数组array_of_requests中的incount个请求中部分请求的完成然后返回。outcount返回成功完成的通信请求个数(返回0表示所有通信请求都尚未完成),array_of_indices的前outcount个元素给出已完成的通信请求在数组array_of_requests及array_of_statuses中的位置。当函数返回值等于MPI_ERR_IN_STATUS时表明部分通信请求处理出错,此时调用程序可检查array_of_statuses中每个元素的MPI_ERROR成员的值来得到出错的通信请求的错误码。
int MPI_Iprobe(int source, int tag, MPI_Comm comm,int *flag, MPI_Status *status)

该函数用于探测符合条件的消息是否已经到达。如果有符合条件的消息到达则flag中返回!0,否则flag中返回0。当有符合条件的消息时,status中包含关于该消息的信息。参数tag和source的含义与MPI_Recv函数相同。
int MPI_Cancel(MPI_Request *request)

取消一个尚未完成的通信请求,它在MPI系统中设置一个取消该通信请求的标志然后立即返回,实际取消操作由MPI系统在后台完成。调用MPI_Cancel后,仍需调用MPI_Wait,MPI_Test,或MPI_Request_free等函数来完成并释放该通信请求。
int MPI_Request_free(MPI_Request *request)

该函数释放指定的通信请求及所占用的资源。如果与该通信请求相关联的通信尚未完成,则它会先等待通信的完成。若操作成功则request的值被置成MPI_REQUEST_NULL。
附3.4.3 持久通信函数
int MPI_Send_init(void *buf, int count,MPI_Datatype datatype, int dest,int tag,
MPI_Comm comm,MPI_Request *request)
创建一个非阻塞型持久消息发送请求。该函数并不开始实际消息的发送,而只是创建一个请求句柄,通过request参数返回给调用程序,留待以后实际消息发送时用。用MPI_Send_init创建的持久通信请求可通过反复调用MPI_Start或MPI_Startall来完成多次消息发送。其余参数的含义与MPI_Send函数相同。
int MPI_Recv_init(void *buf, int count,MPI_Datatype datatype, int source,int tag,
MPI_Comm comm,MPI_Request *request)
创建一个非阻塞型持久消息接收请求。该函数并不开始实际消息的接收,而只是创建一个请求句柄,通过request参数返回给调用程序,留待以后实际消息接收时用。用MPI_Recv_init创建的持久接收可通过反复调用MPI_Start或MPI_Startall来完成多次消息接收。其余参数的含义与MPI_Recv函数相同。
int MPI_Start(MPI_Request *request)

启动基于持久通信请求的通信。每次调用MPI_Start相当于调用一次相应的非阻塞型通信函数(MPI_Isend和MPI_Irecv)。随后调用程序还需要调用MPI_Wait函数来等待通信的完成。
int MPI_Startall(int count,MPI_Request array_of_requests[])

MPI_Startall的作用与MPI_Start类似,但它可以一次启动由数组array_of_requests指定的count个通信。
int MPI_Bsend_init(void *buf, int count,MPI_Datatype datatype, int dest,int tag,
MPI_Comm comm,MPI_Request *request)
创建一个缓冲式持久消息发送请求。该函数并不开始实际消息的发送,而只是创建一个请求句柄并返回给调用程序,留待以后实际消息发送时用。用MPI_Bsend_init创建的持久通信请求可通过反复调用MPI_Start或MPI_Startall来完成多次消息发送。
参看MPI_Send_init。
int MPI_Rsend_init(void *buf, int count,MPI_Datatype datatype, int dest,int tag,
MPI_Comm comm,MPI_Request *request)
创建一个就绪式持久消息发送请求,该函数并不开始实际消息的发送,而只是创建一个请求句柄并返回给调用程序,留待以后实际消息发送时用。用MPI_Rsend_init创建的持久通信请求可通过反复调用MPI_Start或MPI_Startall来完成多次消息发送。
参看MPI_Send_init。
int MPI_Ssend_init(void *buf, int count,MPI_Datatype datatype, int dest,int tag,
MPI_Comm comm,MPI_Request *request)
创建一个同步式持久消息发送请求,该函数并不开始实际消息的发送,而只是创建一个请求句柄并返回给调用程序,留待以后实际消息发送时用。用MPI_Ssend_init创建的持久通信请求可通过反复调用MPI_Start或MPI_Startall来完成多次消息发送。
参看MPI_Send_init。

附3.5 数据类型与打包函数
int MPI_Type_contiguous(int count, MPI_Datatype oldtype,MPI_Datatype *newtype)

数据类型创建函数:新数据类型newtype由count个老数据类型oldtype按域(extent) 连续存放构成。
参看MPI_Type_commit和MPI_Type_free。
int MPI_Type_vector(int count, int blocklen, int stride,MPI_Datatype oldtype,
MPI_Datatype *newtype)
数据类型创建函数:新数据类型newtype由count个数据块构成,每个数据块由blocklen个连续存放、类型为oldtype的数据构成,相邻两个数据块的位移相差stride extentpoldtypeq个字节。
参看MPI_Type_commit和MPI_Type_free。
int MPI_Type_hvector(int count, int blocklen,MPI_Aint stride,
MPI_Datatype oldtype,MPI_Datatype *newtype)
数据类型创建函数:新数据类型newtype由count个数据块构成,每个数据块由blocklen个连续存放、类型为oldtype的数据构成,相邻两个数据块的位移相差stride个字节。该函数与MPI_Type_vector的区别在于:stride在后者中以oldtype的域为单位,而在前者中以字节为单位。
参看MPI_Type_commit和MPI_Type_free。
int MPI_Type_indexed(int count, int blocklens[],int indices[],
MPI_Datatype oldtype,MPI_Datatype *newtype)
数据类型创建函数:新数据类型newtype由count个数据块构成,数据块i由blocklens[i] 个连续存放、类型为oldtype的数据构成,其字节位移为indices[i] extentpoldtypeq。该函数与MPI_Type_vector的区别是数据块的长度可以不同,数据块间还可以不等距。
参看MPI_Type_commit和MPI_Type_free。
int MPI_Type_hindexed(int count, int blocklens[],MPI_Aint indices[],
MPI_Datatype oldtype,MPI_Datatype *newtype)
数据类型创建函数:新数据类型newtype由count个数据块构成,数据块i由blocklens[i]个连续存放、类型为oldtype的数据构成,其字节位移为indices[i]。该函数与MPI_Type_indexed的区别在于indices在前者中以字节为单位,而在后者中以老数据类型的域为单位。
参看MPI_Type_commit和MPI_Type_free。
int MPI_Type_struct(int count, int blocklens[],MPI_Aint indices[],
MPI_Datatype oldtypes[],MPI_Datatype *newtype)
数据类型创建函数:新数据类型newtype由count个数据块构成,数据块i 由blocklens[i]个连续存放、类型为oldtypes[i]的数据构成,其字节位移为indices[i]。
这是MPI 中最一般的类型构造函数。它与MPI_Type_hindexed的区别在于各数据块可以由不同的数据类型构成。
参看MPI_Type_commit和MPI_Type_free。
int MPI_Type_commit(MPI_Datatype *datatype)

提交数据类型。所有新创建的数据类型在首次用于消息传递前必须进行提交。新数据类型提交后就可以和MPI原始数据类型完全一样地在消息传递中使用。如果一个数据类型仅被用于创建其他数据类型的中间步骤而并不直接在消息传递中使用,则不必将它提交,一旦基于它的其他数据类型创建完毕即可立即将其释放。
int MPI_Type_free(MPI_Datatype *datatype)

释放指定的数据类型。当一个数据类型不再需要时应该将它释放以便释放其所占用的内存。函数返回时将datatype置成MPI_DATATYPE_NULL。释放一个数据类型不会影响正在进行的使用该数据类型的通信,也不会影响基于它创建的其他数据类型。
int MPI_Pack(void *inbuf, int incount,MPI_Datatype datatype, void *outbuf,int outsize,
int *position, MPI_Comm comm)
该函数将缓冲区inbuf中的incount个类型为datatype的数据进行打包,打包后的数据放在缓冲区outbuf中,outsize给出的是outbuf的总长度(字节数,供函数检查打包缓冲区是否越界用),comm是发送打包数据将使用的通信器,position用于保存打包缓冲区的当前位置,第一次调用MPI_Pack前调用程序应将position置为0,随后MPI_Pack将自动修改它,使得它总是指向打包缓冲区中尚未使用部分的起始位置,每次调用MPI_Pack后position的值实际上就是已打包的数据的总长度。
参看MPI_Unpack和MPI_Pack_size。
int MPI_Unpack(void *inbuf, int insize, int *position,void *outbuf,
int outcount,MPI_Datatype datatype, MPI_Comm comm)
该函数进行数据拆包操作,它正好是MPI_Pack的逆操作,用打包方式发送的消息接收方必须进行拆包。该函数从inbuf中拆包outcount个类型为datatype的数据到outbuf中。函数中各参数的含义与MPI_Pack类似,只不过这里的inbuf和insize对应于MPI_Pack中的outbuf和outsize,而outbuf和outcount则对应于MPI_Pack中的inbuf和incount。
参看MPI_Pack和MPI_Pack_size。
int MPI_Pack_size(int incount, MPI_Datatype datatype,MPI_Comm comm, int *size)

由于MPI打包时会在用户数据中加入一些附加信息,因此打包后的数据大小不等于用户数据的实际大小。该函数用于计算数据打包后的大小,通常用于估计所需的打包缓冲区长度,它在size中返回incount个类型为datatype的数据在通信器comm中打包后的数据长度。
参看MPI_Pack和MPI_Unpack。
int MPI_Address(void *location, MPI_Aint *address)

返回指定变量的“绝对”地址,可在构造数据类型时用于计算位移。该函数在Fortran 77中特别有用,因为Fortran 77没有提供通用的获取变量地址的手段。为便于Fortran 77代码使用MPI_Address函数返回的地址,MPI定义了一个常量MPI_BOTTOM,相当于绝对地址0,因此,调用CALL MPI_Address(BUFF,ADDRESS,IERR)后,MPI_BOTTOM(ADDRESS)与BUFF代表着同一个内存地址。
参看MPI_BOTTOM。
int MPI_Type_size(MPI_Datatype datatype, int *size)

返回指定数据类型的大小,即其中所包含的实际数据的字节数。
参看MPI_Type_extent,MPI_Type_lb,MPI_Type_ub。
int MPI_Type_extent(MPI_Datatype datatype,MPI_Aint *extent)

返回指定数据类型的域。
参看MPI_Type_size,MPI_Type_lb,MPI_Type_ub。
int MPI_Type_lb(MPI_Datatype datatype,MPI_Aint *displacement)

返回指定数据类型的下界。
参看MPI_Type_size,MPI_Type_extent,MPI_Type_ub。
int MPI_Type_ub(MPI_Datatype datatype,MPI_Aint *displacement)

返回指定数据类型的上界。
参看MPI_Type_size,MPI_Type_extent,MPI_Type_lb。
int MPI_Get_count(MPI_Status *status,MPI_Datatype datatype, int *count)

该函数在count中返回消息中实际数据的长度(数据类型个数)。
int MPI_Get_elements(MPI_Status *status,MPI_Datatype datatype, int *elements)

该函数与MPI_Get_count类似,但它返回消息中所包含的MPI原始数据类型个数。所返回的count值如果不等于MPI_UNDEFINED的话,则应该是函数MPI_Get_count所返回的count值的倍数。
int MPI_Type_dup(MPI_Datatype type, MPI_Datatype *newtype)

(MPI–2 函数) 复制数据类型。

附3.6 同步与聚合通信函数
int MPI_Barrier(MPI_Comm comm)

该函数用于进程的同步。调用该函数后进程将等待直到通信器comm中的所有进程都调用了该函数才返回。
int MPI_Bcast(void *buffer, int count,MPI_Datatype datatype, int root,MPI_Comm comm)

广播。通信器comm中进程号为root的进程(称为根进程) 将自己buffer中的内容发送给通信器中所有其他进程。参数buffer、count和datatype的含义与点对点通信函数(如MPI_Send和MPI_Recv)相同。
int MPI_Gather(void *sendbuf, int sendcnt,MPI_Datatype sendtype, void *recvbuf,
int recvcnt, MPI_Datatype recvtype,int root, MPI_Comm comm)
收集相同长度的数据块。以root为根进程,所有进程(包括根进程自己) 将sendbuf中的数据块发送给根进程,根进程将这些数据块按进程号的顺序依次放到recvbuf中。发送和接收的数据类型与长度必须相配,即发送和接收使用的数据类型必须具有相同的类型序列。参数recvbuf,recvcnt 和recvtype仅对根进程有意义。
需要特别注意的是,在根进程中,参数recvcnt指分别从每个进程接收的数据长度,而不是从所有进程接收的数据长度之和。因此,当sendtype等于recvtype时,sendcnt应该等于recvcnt。
int MPI_Allgather(void *sendbuf, int sendcnt,MPI_Datatype sendtype, void *recvbuf,
int recvcnt, MPI_Datatype recvtype,MPI_Comm comm)
MPI_Allgather与MPI_Gather类似,区别是所有进程同时将数据收集到recvbuf中,因此称为数据全收集。MPI_Allgather相当于依次以comm中的每个进程为根进程调用普通数据收集函数MPI_Gather,或者以任一进程为根进程调用一次普通收集,紧接着再对收集到的数据进行一次广播。
int MPI_Gatherv(void *sendbuf, int sendcnt,MPI_Datatype sendtype, void *recvbuf,
int *recvcnts, int *displs,MPI_Datatype recvtype,
int root,MPI_Comm comm)
收集不同长度的数据块。与MPI_Gather类似,但允许每个进程发送的数据块长度不同,并且根进程可以任意排放数据块在recvbuf中的位置。recvbuf,recvtype,recvcnts和displs仅对根进程有意义。数组recvcnts和displs的元素个数等于进程数,用于指定从每个进程接收的数据块长度和它们在recvbuf中的位移,均以recvtype为单位。
int MPI_Allgatherv(void *sendbuf, int sendcnt,MPI_Datatype sendtype, void *recvbuf,
int *recvcnts, int *displs,MPI_Datatype recvtype, MPI_Comm comm)
不同长度数据块的全收集。参数与MPI_Gatherv类似。它等价于依次以comm中的每个进程为根进程调用MPI_Gatherv,或是以任一进程为根进程调用一次普通收集,紧接着再对收集到的数据进行一次广播。
int MPI_Scatter(void *sendbuf, int sendcnt,MPI_Datatype sendtype, void *recvbuf,
int recvcnt, MPI_Datatype recvtype,int root, MPI_Comm comm)
散发相同长度数据块。根进程root将自己的sendbuf中的np个连续存放的数据块按进程号的顺序依次分发到comm的各个进程(包括根进程自己) 的recvbuf中,这里np代表comm中的进程数。sendcnt和sendtype 给出sendbuf中每个数据块的大小和类型,recvcnt和recvtype给出recvbuf的大小和类型,其中参数sendbuf、sendcnt 和sendtype仅对根进程有意义。
需要特别注意的是,在根进程中,参数sendcnt指分别发送给每个进程的数据长度,而不是发送给所有进程的数据长度之和。因此,当recvtype等于sendtype时,recvcnt应该等于sendcnt。
int MPI_Scatterv(void *sendbuf, int *sendcnts,int *displs, MPI_Datatype sendtype,
void *recvbuf, int recvcnt,MPI_Datatype recvtype, int root,
MPI_Comm comm)
散发不同长度的数据块。与MPI_Scatter类似,但允许sendbuf中每个数据块的长度不同并且可以按任意的顺序排放。sendbuf、sendtype、sendcnts和displs仅对根进程有意义。数组sendcnts和displs的元素个数等于comm中的进程数,它们分别给出发送给每个进程的数据长度和位移,均以sendtype为单位。
int MPI_Alltoall(void *sendbuf, int sendcnt,MPI_Datatype sendtype, void *recvbuf,
int recvcnt, MPI_Datatype recvtype,MPI_Comm comm)
相同长度数据块的全收集散发:进程i将sendbuf中的第j块数据发送到进程j的recvbuf中的第i个位置,i, j =0, … , np-1 (np代表comm 中的进程数)。sendbuf 和recvbuf 均由np个连续的数据块构成,每个数据块的长度/类型分别为sendcnt/sendtype和recvcnt/recvtype。
该操作相当于将数据在进程间进行一次转置。例如,假设一个二维数组按行分块存储在各进程中,则调用该函数可很容易地将它变成按列分块存储在各进程中。
int MPI_Alltoallv(void *sendbuf, int *sendcnts,int *sdispls, MPI_Datatype sendtype,
void *recvbuf, int *recvcnts,int *rdispls,
MPI_Datatype recvtype,MPI_Comm comm)
不同长度数据块的全收集散发。与MPI_Alltoall类似,但每个数据块的长度可以不等,并且不要求连续存放。各个参数的含义可参考函数MPI_Alltoall,MPI_Scatterv和MPI_Gatherv。
int MPI_Reduce(void *sendbuf, void *recvbuf, int count,MPI_Datatype datatype,
MPI_Op op, int root,MPI_Comm comm)
归约操作。假设comm中的进程数为np,则该函数相当于在根进程(root)中计算:
for (k = 0; k < count; k++) {
recvbuf[k] = 0;
for (i = 0; i < np; i++) {
recvbuf[k] = recvbuf[k] op (sendbuf[k] of process i)
}
}
这里op 是归约操作的二目运算。
参看附3.2.3 中的MPI_Op_create,MPI_Op_free。
int MPI_Allreduce(void *sendbuf, void *recvbuf, int count,MPI_Datatype datatype,
MPI_Op op,MPI_Comm comm)
全归约。它与普通归约函数MPI_Reduce 的操作类似,但所有进程将同时获得归约运算的结果。它除了比MPI_Reduce少一个root参数外,其余参数及含义与后者一样。MPI_Allreduce相当于在MPI_Reduce后马上再调用MPI_Bcast广播归约结果。
参看附3.2.3 中的MPI_Reduce 和MPI_Op_create。
int MPI_Reduce_scatter(void *sendbuf, void *recvbuf,int *recvcnts,MPI_Datatype datatype,
MPI_Op op,MPI_Comm comm)
归约散发。该函数的作用相当于首先进行一次

的归约操作,然后再对归约结果进行散发操作,散发给第i 个进程的数据块长度为recvcnts[i],这里np代表comm中的进程数。其他参数的含义与MPI_Reduce一样。
参看附3.2.3 和MPI_Reduce。
int MPI_Scan(void *sendbuf, void *recvbuf, int count,MPI_Datatype datatype,
MPI_Op op,MPI_Comm comm)
前缀归约(或扫描归约)。与普通全归约MPI_Allreduce类似,但各进程依次得到部分归约的结果。确切地,进程i的recvbuf中包含前i+1个进程的归约运算结果,i=0, … , np-1,np代表comm中的进程数。各参数的含义与MPI_Allreduce一样。
参看附3.2.3 和MPI_Reduce。
int MPI_Op_create(MPI_User_function *func, int commute,MPI_Op *op)

创建自定义的用于归约操作的二目运算。func参数是用于完成该运算的函数的指针,commute说明所定义的运算是否满足交换律(commute为非0表示满足交换律)。op返回所创建的二目运算的指针,类型为MPI_Op。
一个运算创建后便和MPI预定义的运算一样,可以用在所有归约(包括前缀归约) 函数中。负责完成二目运算的函数func应该具有如下形式的接口:
void func(void *invec, void *inoutvec, int *len, MPI_Datatype *datatype);
其中invec和inoutvec指向参与运算的操作数(operand),函数返回时inoutvec中应该包含运算的结果;len给出invec和inoutvec中的元素个数,它对应于函数MPI_Reduce中的count;datatype给出操作数的数据类型,它对应于函数MPI_Reduce中的datatype。直观地说,函数func必须负责完成如下操作:
for (i = 0; i < *len; i++) {
inoutvec[i] = invec[i] op inoutvec[i]
}
参看附3.2.3 中的MPI_Reduce和MPI_Op_free。
int MPI_Op_free(MPI_Op *op)

释放自定义的归约操作二目运算。

附3.7 进程组与通信器操作
附3.7.1 进程组操作
int MPI_Group_size(MPI_Group group, int *size)

返回指定进程组的大小(包含的进程个数)。与MPI_Comm_size函数类似。
int MPI_Group_rank(MPI_Group group, int *rank)

返回进程在指定进程组中的进程号。与MPI_Comm_rank函数类似。
int MPI_Group_compare(MPI_Group group1, MPI_Group group2,int *result)

比较两个进程组并在result中返回比较结果。如果两个进程组包含的进程一样、各进程的进程号也一样则结果为MPI_IDENT,如果两个进程组包含的进程一样但进程号不同则结果为MPI_SIMILAR,否则结果为MPI_UNEQUAL。
int MPI_Group_difference(MPI_Group group1,MPI_Group group2,
MPI_Group *group_out)
group_out中返回的新进程组由属于group1但不属于group2的进程构成,进程号按group1中的顺序进行编排。
int MPI_Group_intersection(MPI_Group group1,MPI_Group group2,
MPI_Group *group_out)
group_out中返回由group1与group2中的进程的交集构成的进程组。新进程组中进程号按group1中的顺序进行编排。
int MPI_Group_incl(MPI_Group group, int n, int *ranks,MPI_Group *group_out)

新进程组group_out由老进程组group中的部分进程构成,这些进程的进程号由数组ranks给出,n是数组ranks的元素个数。新进程组中的进程号亦由进程在ranks数组中的顺序决定,即进程组group_out中进程号为i的进程在老进程组group中的进程号为ranks[i]。该函数也可用来对进程组中的进程进行重新排序。当参数n=0时将创建一个空进程组MPI_GROUP_EMPTY。
int MPI_Group_excl(MPI_Group group, int n, int *ranks,MPI_Group *newgroup)

该函数将进程组group的进程集合减去一个子集而得到一个新进程组newgroup,减去的进程的进程号由数组ranks给出,n是ranks中的进程数。新进程组的进程号保持进程在老进程组中顺序。
int MPI_Group_range_incl(MPI_Group group, int n,int ranges[][3],MPI_Group *newgroup)

将由一组进程号范围给出的进程集合组成一个新进程组。每个进程号范围通过一个三元数对(起始进程号,终止进程号步长)描述,n为进程号范围的个数。确切地说,构成新进程组的进程集合由老进程组中进程号属于下述集合的进程组成:
上式中所有计算出的r必须互不相同,否则调用出错。新进程组中进程号按上式中先k再i的顺序编排。
int MPI_Group_range_excl(MPI_Group group, int n,int ranges[][3],MPI_Group *newgroup)

从老进程组中减去由一组进程号范围指定的进程而得到一个新进程组。该函数的结果正好是函数MPI_Group_range_incl的补集。各项参数的含义与MPI_Group_range_incl相同。
int MPI_Group_translate_ranks(MPI_Group group_a, int n,int *ranks_a,
MPI_Group group_b,int *ranks_b)
返回进程组group_a中的一组进程在进程组group_b中的进程号。数组ranks_a列出group_a中的进程号,而数组ranks_b则给出相应的进程在group_b中的进程号,n为数组ranks_a和ranks_b中的进程个数。
int MPI_Group_union(MPI_Group group1, MPI_Group group2,MPI_Group *group_out)

group_out中返回由group1与group2的并集构成的进程组。新进程组中进程号的分配原则是先对属于group1的进程按group1中的顺序编号,再对属于group2但不属于group1的进程按group2中的顺序编号。
int MPI_Comm_group(MPI_Comm comm, MPI_Group *group)

在group参数中返回指定通信器包含的进程组。
int MPI_Group_free(MPI_Group *group)

释放指定的进程组。函数返回时会将group置成MPI_GROUP_NULL以防止释放后被误用。实际上,该函数只是将该进程组加上释放标志。只有基于该进程组的所有通信器均被释放后才会实际将其释放。

附3.7.2 域内通信器操作
int MPI_Comm_size(MPI_Comm comm, int *size)

在size中返回指定通信器中的进程数。
int MPI_Comm_rank(MPI_Comm comm, int *rank)

在rank中返回本进程在指定通信器中的进程号。
int MPI_Comm_compare(MPI_Comm comm1, MPI_Comm comm2,int *result)

比较两个(域内) 通信器并在result中返回比较结果。如果两个通信器代表同一个通信域,则结果为MPI_IDENT,表示它们实际上是同一个通信器;如果两个通信器不代表同一通信域,但它们的进程组相同,即它们包含的进程相同并且进程号也相同,则结果为MPI_CONGRUENT;如果两个通信器包含的进程相同但进程号不同,则结果为MPI_SIMILAR;否则结果为MPI_UNEQUAL。
int MPI_Comm_create(MPI_Comm comm, MPI_Group group,MPI_Comm *comm_out)

创建一个包含指定进程组group的新通信器comm_out。这个函数并不将comm的属性传递给comm_out,而是为comm_out建立一个新的上下文。返回时,属于进程组group的进程中comm_out等于新通信器的句柄,而不属于进程组group的进程中comm_out则等于MPI_COMM_NULL。
int MPI_Comm_dup(MPI_Comm comm, MPI_Comm *comm_out)

生成一个与comm具有完全相同属性的新通信器comm_out。注意,新通信器comm_out与老通信器comm代表着不同的通信域,因此在它们之间不能进行通信操作,即用comm发送的消息不能用comm_out来接收,反之亦然。该函数通常用在并行库中:在库函数的开头将调用程序提供的通信器参数复制产生一个新通信器,库函数中使用新通信器进行通信,而在库函数返回前将新通信器释放,这样可以确保库函数中的通信不会与程序的其他通信相互干扰。
int MPI_Comm_split(MPI_Comm comm, int color, int key,MPI_Comm *comm_out)

该函数按照由参数color给出的颜色将通信器中的进程分组,所有具有相同颜色的进程构成一个新通信器。新通信器中进程号按参数key值的大小排序,两个进程的key值相同时则按它们在老通信器comm中的进程号排序。返回时,comm_out等于进程所属的新通信器的句柄。color必须是非负整数或MPI_UNDEFINED。如果color=MPI_UNDEFINED,则表示进程不属于任何新通信器,返回时comm_out=MPI_COMM_NULL。
int MPI_Comm_free(MPI_Comm *comm)

释放指定的通信器。函数返回时会将comm置成MPI_COMM_NULL以防止释放后被误用。实际上该函数只是将通信器加上释放标志。当所有引用该通信的操作全部完成后才会实际将其释放。
int MPI_Keyval_create(MPI_Copy_function *copy_fn,MPI_Delete_function *delete_fn,
int *keyval, void *extra_state)
创建新的通信器属性(attribute key) (略)。
int MPI_Keyval_free(int *keyval)

释放通信器属性(略)。
int MPI_Attr_delete(MPI_Comm comm, int keyval)

删除通信器中的指定属性(略)。
int MPI_Attr_get(MPI_Comm comm, int keyval,void *attr_value, int *flag)

获取通信器的指定属性的值(略)。
int MPI_Attr_put(MPI_Comm comm, int keyval,void *attr_value)

设定通信器的指定属性的值(略)。
附3.7.3 进程拓扑结构
int MPI_Topo_test(MPI_Comm comm, int *top_type)

查询拓扑结构类型。如果comm具有笛卡尔拓扑结构,则在top_type中返回MPI_CART,如果comm具有图拓扑结构,则在top_type中返回MPI_GRAPH,否则在top_type中返回MPI_UNDEFINED。
1. 笛卡尔拓扑结构
int MPI_Cart_create(MPI_Comm comm_old, int ndims,int *dims, int *periods,
int reorder,MPI_Comm *comm_cart)
该函数从通信器comm_old出发创建一个具有笛卡尔拓扑结构的新通信器comm_cart。ndims给出进程网格的维数;数组dims给出每维中的进程数;数组periods则说明进程在各个维上的联接是否具有周期性,即该维中第一个进程与最后一个进程是否相联,周期的笛卡尔拓扑结构也称为环面(torus)结构,periods[i] 0表明第i维是周期的,否则则是非周期的;reorder指明是否允许在新通信器comm_cart中对进程进行重新排序,在某些并行计算机上,根据处理机的物理联接方式及所要求的进程拓扑结构对进程重新排序有助于提高并行程序的性能。comm_cart中各维进程数之积必须不大于comm_old中的进程数,即 ,这里np代表comm_old中的进程数。如果 ,则一些进程将不属于comm_cart,这些进程的comm_cart参数返回MPI_COMM_NULL。
参看MPI_Dims_create。
int MPI_Dims_create(int nnodes, int ndims, int *dims)

(辅助函数) 该函数当给定总进程数及维数时自动计算各维的进程数,使得它们的乘积等于总进程数,并且各维上的进程数尽量接近。确切地说,给定nnodes和ndims,函数计算正整数dims[i],i =0, … , ndims-1,使得 并且dims[i]的值尽量接近。该函数要求输入时dims中元素的值为非负整数,并且它仅修改dims中输入值为0的元素。因此调用程序可以指定一些维上的进程数而仅要求计算其他维上的进程数。
这个函数的局限是没有考虑实际数据在各维上的大小。例如在二维区域分解计算中,假如进程数为4,计算网络为100*400,则理想的进程拓扑结构应为1* 4,而用该函数计算出的结果是2 *2。
参看MPI_Cart_create。
int MPI_Cart_map(MPI_Comm comm_old, int ndims, int *dims,int *periods, int *newrank)

该函数在newrank中返回给定笛卡尔拓扑结构下当前进程的建议编号。参数ndims,dims和periods的含义与函数MPI_Cart_create中相同。
参看MPI_Cart_create。
int MPI_Cartdim_get(MPI_Comm comm, int *ndims)

在ndims中返回通信器comm的笛卡尔拓扑结构的维数。
int MPI_Cart_rank(MPI_Comm comm, int *coords, int *rank)

给定一个进程在通信器comm中的笛卡尔坐标coords,该函数在rank中返回进程在comm中的进程号。对于具有周期性的维,coords中对应的坐标值允许“越界”,即小于0或大于等于相应维上的进程数。
int MPI_Cart_coords(MPI_Comm comm, int rank, int maxdims,int *coords)

给定一个进程在通信器comm中的进程号rank,该函数在coords中返回进程在comm中的笛卡尔坐标;maxdims给出数组coords的最大长度。
int MPI_Cart_get(MPI_Comm comm, int maxdims, int *dims,int *periods, int *coords)

返回通信器comm的笛卡尔拓扑结构的详细信息。数组dims、periods和coords分别返回各维的进程数、是否周期及当前进程的笛卡尔坐标;
参数maxdims给出数组dims、periods 和coords的最大长度。
int MPI_Cart_shift(MPI_Comm comm, int direction,int displ, int *source, int *dest)

计算在具有笛卡尔拓扑结构的通信器comm一个给定维上进行数据平移(如用MPI_Sendrecv将一块数据发送给该维上后面一个进程,同时接收从该维上前面一个进程发送来的数据) 的目的地址和源地址。输入参数direction是进行数据平移的维号 ;disp给出数据移动的“步长”(绝对值) 和“方向”(正负号);输出参数rank_source和rank_dest分别是平移操作的源地址和目的地址。
假设指定的维上的进程数为d,当前进程在该维上的坐标为i,源进程rank_source在该维上的坐标为is,目的进程rank_dest在该维上的坐标为id,如果该维是周期的,则:

否则:

int MPI_Cart_sub(MPI_Comm comm, int *remain_dims,MPI_Comm *comm_new)

该函数将一个具有笛卡尔拓扑结构的通信器comm指定的维抽取出来,构成一个具有低维笛卡尔结构的新通信器comm_new。数组remain_dims的元素用来指定哪些维被包含在新通信器中,remain_dims[i] 0 表示新通信器包含第i维,否则表示新通信器不包含第i维。
2. 图拓扑结构
int MPI_Graph_create(MPI_Comm comm_old, int nnodes,int *index, int *edges,
int reorder,MPI_Comm *comm_graph)
从通信器comm_old出发,创建一个具有指定图拓扑结构的新通信器comm_graph。新通信器的拓扑结构图通过参数nnodes、index 和edges描述:nnodes是图的结点数(如果nnodes小于通信器comm_old的进程数,则一些进程将不属于新通信器comm_graph,这些进程中参数comm_graph的返回值将为MPI_COMM_NULL),index[i] (i = 0, … , nnodes -1) 给出结点0, … , i的邻居数之和,edges则顺序给出所有结点的邻居的进程号。
如果用Neighborpiq表示第i个结点的邻居的进程号集合,则:

参数reorder指示是否允许在新通信器中对进程进行重新编号(与函数MPI_Cart_create类似)。
int MPI_Graphdims_get(MPI_Comm comm, int *nnodes,int *nedges)

该函数在参数nnodes中返回通信器comm的拓扑结构图的结点数(等于comm中的进程数),在参数nedges中返回通信器comm的拓扑结构图的边数。
int MPI_Graph_get(MPI_Comm comm, int maxindex,int maxedges, int *index, int *edges)

该函数返回通信器comm的拓扑结构图中的index和edges数组。
参数maxindex和maxedges分别限定数组index和edges的最大长度。
参看MPI_Graph_create。
int MPI_Graph_map(MPI_Comm comm_old, int nnodes,int *index, int *edges,
int *newrank)
该函数在newrank中返回给定图结构下当前进程的建议编号。参数nnodes、index和edges的含义与函数MPI_Graph_create中相同。
参看MPI_Graph_create。
int MPI_Graph_neighbors(MPI_Comm comm, int rank,int maxneighbors, int *neighbors)

在数组neighbors中返回与通信器comm中的进程rank相邻的进程的进程号,maxneighbors限定数组neighbors的最大长度。
int MPI_Graph_neighbors_count(MPI_Comm comm, int rank,int *nneighbors)

返回指定进程的邻居数。
附3.7.4 域间通信器操作
int MPI_Comm_remote_group(MPI_Comm comm, MPI_Group *group)

略。
int MPI_Comm_remote_size(MPI_Comm comm, int *size)

略。
int MPI_Comm_test_inter(MPI_Comm comm, int *flag)

略。
int MPI_Intercomm_create(MPI_Comm local_comm,int local_leader,
MPI_Comm peer_comm,int remote_leader, int tag,
MPI_Comm *comm_out)
略。
int MPI_Intercomm_merge(MPI_Comm comm, int high,MPI_Comm *comm_out)

略。

附3.8 时间函数
double MPI_Wtime(void)

返回当前墙钟时间,以从某一固定时刻算起的秒数为单位。时钟精度可通过函数MPI_Wtick查询。在C接口中,这是唯一两个返回双精度值而非整型错误码的MPI函数之一。在Fortran 77接口中,这是唯一两个FUNCTION形式而非SUBROUTINE形式的MPI Fortran接口之一。
参看MPI_Wtick。
double MPI_Wtick(void)

该函数给出MPI_Wtime函数的时钟精度,以秒为单位。例如,假设MPI_Wtime使用的硬件时钟频率为1/1000秒,则MPI_Wtick的返回值为10-3,表示用函数MPI_Wtime得到的时间精度为千分之一秒。在C中,这是唯一两个返回双精度值而非整型错误码的MPI函数之一。在Fortran 77中,这是唯一两个FUNCTION形式而非SUBROUTINE形式的MPI Fortran接口之一。
参看MPI_Wtime。

参考文献
[1] 张林波,迟学斌,莫则尧,李若.并行计算导论.北京:清华大学出版社.2006
[2] 张武生,薛巍,李建江,李纬民.MPI并行程序设计实例教程.北京:清华大学出版社.2009
[3] 敖富江 译.并行编程模式.北京:清华大学出版社.2005
[4] 莫则尧.实用的并行程序性能分析方法.数值计算与计算机应用,2000,21(4):266–275
[5] 陈文光,武永卫 等译.MPI与OpenMP并行程序设计.北京:清华大学出版社.2004
[6] 莫则尧. 实用的并行程序性能分析方法. 数值计算与计算机应用, 2000, 21(4):266–275
[7] Sun X H, D T Rover. Scalability of Parallel Algorithm-machine Combinations.IEEE Trans. on Parallel and Distributed Systems, 1994,5(6):599-613
[8] MPI: A Message-Passing Interface Standard.
http://www.mpi-forum.org/docs/mpi-11-html/mpi-report.html
[9] MPI–2: Extensions to the Message-Passing Interface.
http://www.mpi-forum.org/docs/mpi-20-html/mpi2-report.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值