一對進程之間的數據轉換,也就是說一邊發送數據另一邊接收數據,點到點通信是MPI通信機制的基礎,它分爲同步通信和異步通信二種機制。
阻塞式函數
1. int MPI_send(void *buf,int count,MPI_Datatype datatype,int dest,int tag,MPI_Comm comm)
IN buf 所要發送消息數據的首地址
IN count 發送消息數組元素的個數
IN datatype 發送消息的數據類型
IN dest 接收消息的進程編號
IN tag 消息標籤
IN comm 通信子
2. int MPI_Recv(void *buf,int count,MPI_Datatype datatype,int source,int tag,MPI_Comm comm,MPI_Status *status)
OUT buf 接收消息數據的首地址
IN Count 接收消息數組元素的最大個數
IN datatype 接收消息的數據類型
IN source 發送消息的進程編號
IN tag 消息標籤
IN comm 通信子
OUT status 接收消息時返回的狀態
3. int MPI_Get_Count(MPI_Status status,MPI_Datatype datatype,int *count)
IN status 接收消息時返回的狀態
IN datatype 接收消息時返回的類型
OUT Count 接收消息時數組元素的個數
4. int MPI_Sendrecv(void *sendbuf,int sendcount,MPI_Datatype sendtype,int dest,int sendtag,void *recvbuf,int recvcount,MPI_Datatype recvtype,int source,int recvtag,MPI_Comm comm,MPI_Status *status)
IN sendbuf 所要發送消息數據的首地址
IN sendcount 發送消息數組元素的個數
IN sendtype 發送消息的數據類型
IN dest 接收消息的進程編號
IN sendtag 發送消息標籤
OUT recvbuf 接收消息數據的首地址
IN recvcount 接收消息數組元素的最大個數
IN recvtype 接收消息的數據類型
IN Source 發送消息的進程編號
IN recvtag 接收消息標籤
IN comm 通信子
OUT status 接收消息時返回的狀態
5. int MPI_Sendrecv_replace(void *sendbuf,int count,MPI_Datatype datatype,int dest,int sendtag,int source,int recving,MPI_Comm comm,MPI_Status *status)
OUT buf 發送和接收消息數據的首地址
IN Count 發送和接收消息數組元素的個數
IN dest 接收消息的進程編號
IN sendtag 發送消息標籤
IN source 發送消息的進程編號
IN recvtag 接收消息標籤
IN comm 通信子
OUT status 接收消息時返回的狀態
6. int MPI_probe(int source,int tag,MPI_Comm comm,MPI_Status *status)
IN source 發送消息進程的編號
IN tag 接收消息的標籤
IN comm 通信子
OUT status 返回到消息的狀態
7. int MPI_Iprobe(int source,int tag,MPI_Comm comm,int *flag,MPI_Status *status)
IN source 發送消息進程的編號
IN tag 接收消息的標籤
IN comm 通信子
OUT flag 如果指定消息已經到達,flag返回值爲true
OUT status 返回到達消息的狀態
非阻塞式函數
非阻塞式通信函數是指在通信過程中,不需要等待通信結束就返回,通常這種通信過程交由計算機的後臺來處理,如果計算機系統提供硬件支持非阻塞式通信函數,就可以使計算與通信在時間上的重疊,從而提高並行計算的效率。
1. int MPI_Isend(void *buf,int count,MPI_Datatype datatype,int dest,int tag,MPI_Comm comm,MPI_Request *request)
IN buf 所要發送消息數據的首地址
IN count 發送消息數組元素的個數
IN datatype 發送消息的數據類型
IN dest 接收消息的進程編號
IN tag 消息標籤
IN comm 通信子
OUT request 請求句柄一杯將來查詢
2. int MPI_Irecv(void *buf,int count,MPI_Datatype datatype,int source,int tag,MPI_Comm comm,MPI_Request *request)
OUT buf 接收消息數據的首地址
IN Count 接收消息數組元素的個數
IN datatype 接收消息的數據類型
IN source 發送消息的進程編號
IN tag 消息標籤
IN comm 通信子
OUT request 請求句柄以北將來查詢
MPI_Isend和MPI_Irecv不需要等待發送或接收消息完成就可以執行其他任務
3. Int MPI_wait(MPI_Request *request,MPI_Status *status)
INOUT request 請求句柄
OUT status 發送或接收消息的狀態
如果request所指的操作已經完成,MPI_Wait將結束等待狀態
4. Int MPI_Test(MPI_Request *request,int *flag,MPI_Status *status)
INOUT request 請求句柄
OUT flag request所指的操作已經完成返回值爲true
OUT status 發送或接收消息的狀態
5. Int MPI_Request_free(MPI_Request *request)
INOUT request 請求句柄,返回值爲MPI_Request_null
對單個request進行查詢
6. Int MPI_Waitany(int count,MPI_Request *array_of_requests,int *index,MPI_Status *status)
IN count 請求句柄的個數
INOUT array_of_requests 請求句柄數組
OUT index 已經完成通信操作的句柄指標
OUT status 消息的狀態
當所有請求句柄中至少有一個已經完成通信操作,就返回,如果有多於一個請求句柄已經完成,MPI_waitany將隨機選擇其中的一個並立即返回
7. Int MPI_Testany(int Count,MPI_Request *array)
IN count 請求句柄個數
INOUT array_of_requests 請求句柄數組
OUT index 已經完成通信操作的句柄指標
OUT flag 如果有一個已經完成,則flag=true
OUT status 消息的狀態
無論有沒有通信操作完成都將立即返回
8. Int MPI_Waitall(int Count,MPI_Request *array_of_requests)
IN count 請求句柄的個數
INOUT array_of_requests 請求句柄數組
INOUT array_of_status 所有消息的狀態數組
所有通信操作完成之後才返回,否則將一直等待
9. Int MPI_Testall(int Count,MPI_Request *array_of_requests,int *flag,MPI_Status *array_of_status)
IN count 請求句柄的個數
INOUT array_of_requests 請求句柄數組
OUT flag 如果有一個沒完成,則flag=false
INOUT array_of_status 所有消息的狀態數組
無論所有通信操作是否完成都立即返回
10. Int MPI_Cancel(MPI_Request *request)
INOUT request 請求句柄
取消一個發送或接收操作
11. Int MPI_Test_cancelled(MPI_Status *status,int *flag)
IN status 消息的狀態
OUT flag 如果已經取消,則flag=true
最後附上一個測試的例子:
#include "mpi.h"
#include <stdio.h>
#include <math.h>
#include <malloc.h>
void main(int argc,char **argv){
int rank,bsize,*buf,recv;
MPI_Comm comm=MPI_COMM_WORLD;
MPI_Status status;
int nums[4]={0,1,2,3};
MPI_Init(&argc,&argv);
MPI_Comm_rank(comm,&rank);
if(rank==0){
MPI_Send(&nums[rank],1,MPI_INT,4,0,comm);
}
else if(rank==1){
MPI_Pack_size(1,MPI_INT,comm,&bsize);
bsize+=2*MPI_BSEND_OVERHEAD;
buf=(int *)malloc(bsize);
MPI_Buffer_attach(buf,bsize+MPI_BSEND_OVERHEAD);
MPI_Bsend(&nums[rank],1,MPI_INT,5,0,comm);
MPI_Buffer_detach(&buf,&bsize);
free(buf);
}else if(rank==2){
MPI_Rsend(&nums[rank],1,MPI_INT,6,0,comm);
}else if(rank==3){
MPI_Ssend(&nums[rank],1,MPI_INT,7,0,comm);
}else if(rank==4){
MPI_Recv(&recv,1,MPI_INT,0,0,comm,&status);
printf("Process %d Recv Mes from process %d: %d\n",rank,status.MPI_SOURCE,recv);
}else if(rank==5){
MPI_Recv(&recv,1,MPI_INT,1,0,comm,&status);
printf("Process %d Recv Mes from process %d: %d\n",rank,status.MPI_SOURCE,recv);
}else if(rank==6){
MPI_Recv(&recv,1,MPI_INT,2,0,comm,&status);
printf("Process %d Recv Mes from process %d: %d\n",rank,status.MPI_SOURCE,recv);
}else if(rank==7){
MPI_Recv(&recv,1,MPI_INT,3,0,comm,&status);
printf("Process %d Recv Mes from process %d: %d\n",rank,status.MPI_SOURCE,recv);
}
MPI_Finalize();
}
輸出結果如下:
Process 4 Recv Mes from process 0: 0
Process 6 Recv Mes from process 2: 2
Process 5 Recv Mes from process 1: 1
Process 7 Recv Mes from process 3: 3