三、MPI实现
4.集合通信
(1)广播: MPI_Bcast函数
函数原型:
int MPI_Bcast(
void* data_buf_p,
int count,
MPI_Datatype datatype,
int source,
MPI_Comm communicator){...}
参数解释:
①void* data_buf_p
要广播的信息的存放地
②int count
要广播的信息的大小
③MPI_Datatype datatype
MPI数据类型
④int source
广播者的进程号
⑤MPI_Comm communicator
通信子名。
⑥返回值:
错误码。
函数作用:
名为communicator
通信子中序号为source
的进程向通信子中所有的进程传递消息,此消息是存放放在source
进程的data_buf_p
所指向的内存空间,且消息大小为count
,消息类型为datatype
;接受广播的其余所有进程便会将此条消息存放在本地的·data_buf_p·所指向的内存空间中。
注意事项:
这里发送与接收的消息均为各个进程中自己的data_buf_p所指向的内存空间,所以在调用此函数之前,要确保通信子中的每一个进程都有适配的data_buf_p所指向的内存空间。
(2)均匀分发(均匀散射): MPI_Scatter函数
函数原型:
int MPI_Scatter(
void* send_buf_p,
int send_count,
MPI_Datatype send_type,
void* recv_buf_p,
int recv_count,
MPI_Datatype recv_type,
int source,
MPI_Comm communicator){...}
参数解释:
①void* send_buf_p
要分发的数据的存放地
②int send_count
要分发给每个进程的数据的大小,也就是总大小除以comm_size
③MPI_Datatype datatype
MPI数据类型
④void* recv_buf_p
指向数据接收的内存空间
⑤inte recv_cound
接收的数据大小。注意,由于此函数是均匀分发,所以其实此参数的值应该为recv_count = send_count
⑥MPI_Datatype recv_type
接收的数据类型。显然,recvtype应该与send_type一致
⑦int source
分发数据的源进程的序号,即是此进程将会分发send_buf_p指向的数据
⑧MPI_Comm communicator
老朋友了,通信子的名字
函数作用:
将名为Communicator
通信子中的序号为source
的进程的send_buf_p
所指向的内存空间中的send_type
类型且大小为send_count
的数据,平均分发给communicator
通信子中的每一个进程(包括分发源进程),同时每一个进程将接收到的数据存入recv_buf_p
所指向的内存空间中,这些数据大小为recv_count
,类型为recv_type
。
注意事项:
由于含有接收参数,所以在调用此函数时,必须确保每一个进程都能调用到该函数,所有进程应该调用参数一模一样的该函数以确保不会报错。
(3)均匀聚集: MPI_Gather函数
函数原型:
int MPI_Gather(
void* send_buf_p,
int send_count,
MPI_Datatype send_type,
void* recv_buf_p,
int recv_count,
MPI_Datatype recv_type,
int dest,
MPI_Comm communicator){...}
参数解释:
①void* send_buf_p
要聚集的数据的存放地
②int send_count
要聚集的数据的大小
③MPI_Datatype datatype
MPI数据类型
④void* recv_buf_p
指向数据接收的内存空间
⑤inte recv_cound
接收的数据大小。注意,由于此函数是均匀聚集,所以其实此参数的值应该为recv_count = send_count
⑥MPI_Datatype recv_type
接收的数据类型。显然,recvtype应该与send_type一致
⑦int dest
聚集数据的目的地进程的序号,即是要将各个进程的数据向此进程的汇聚
⑧MPI_Comm communicator
老朋友了,通信子的名字
函数作用:
将名为communicator
通信子中每一个进程(包括聚集目的地进程)的send_buf_p
所指向的内存空间中send_type
类型大小为send_count
的数据向dest
号进程汇聚,dest
号进程将收到数据按发送方的进程号作为偏移量,存储在recv_buf_p
指向的recv_type
类型且大小为recv_count
大小的内存空间中。
注意事项:
与MPI_Scatter函数一样,此均匀聚集函数也必须确保每一个进程能调用到一模一样的MPI_Gather函数。
(4)进阶 MPI_Scatterv与MPI_Gatherv函数(非均匀分发与非均匀聚集)
这两个函数是均匀分发与均匀聚集函数的更一般形式,均匀分发与聚集函数是系统设置固定偏移量,而MPI_Scatterv与MPI_Gatherv函数多了一个displs数组参数,用来设置偏移量。由于此函数使用频率较低,性质与MPI_Scantter和MPI_Gather函数高度相似,故不在此赘述。