訊息傳遞介面/MPI 函式參考
此頁面列出了 MPI 中使用的函式的簡要說明。
int MPI_Send( void *buf, int count, MPI_Datatype datatype, int dest,
int tag, MPI_Comm comm )
這將 buf 的內容傳送到秩為 dest 的目標,而接收端則呼叫 MPI_Recv。
int MPI_Recv( void *buf, int count, MPI_Datatype datatype, int source,
int tag, MPI_Comm comm, MPI_Status *status )
這將 buf 填充來自秩為 source 的源的資料,而傳送端則呼叫 MPI_Send。
int MPI_Bcast ( void *buffer, int count, MPI_Datatype datatype, int root,
MPI_Comm comm )
這將 buffer 中的內容在 root 上傳送到所有其他程序。因此,之後 buffer 的前 count 個元素在所有節點上都相同。 [1]
int MPI_Open_port(MPI_Info info, char *port_name)
這將建立一個埠,其他程序可以連線到該埠。作為 port_name 字串傳遞的緩衝區必須至少 MPI_MAX_PORT_NAME 長,並且將包含一個唯一的識別符號,其他程序需要知道該識別符號才能連線。
int MPI_Comm_accept(char *port_name, MPI_Info info, int root, MPI_Comm comm,
MPI_Comm *newcomm)
在呼叫 MPI_Open_port() 後,此函式將等待連線。
int MPI_Comm_connect(char *port_name, MPI_Info info, int root, MPI_Comm comm,
MPI_Comm *newcomm)
這將開啟到另一個程序的連線,該程序正在 MPI_Comm_accept() 上等待。port_name 引數必須與另一個程序的 port_name 相同,該 port_name 是從 MPI_Open_port 返回的。
以下函式透過應用簡單函式(例如求和)將跨處理器的陣列資料歸約為一個或多個處理器上的標量。
int MPI_Scan ( void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype,
MPI_Op op, MPI_Comm comm )
參見 [4].
int MPI_Allreduce ( void *sendbuf, void *recvbuf, int count,
MPI_Datatype datatype, MPI_Op op, MPI_Comm comm )
這將在所有節點上對每個節點的 sendbuf 執行由 MPI_Op 指定的操作。例如,如果節點 0 在其 sendbuf 中分別有 {0, 1, 2},而節點 1 有 {3, 4, 5},並且如果兩者都呼叫了 MPI_Allreduce(sendbuf, foo, 3, MPI_INT, MPI_SUM, world),則兩個節點上指向 foo 的緩衝區的內容將是
- {0+3, 1+4, 2+5} = {3, 5, 7}
對於 *P* 個程序的效能: 。 [5]
int MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *newcomm);
MPI_Comm_split() 在每個程序中建立一個新的通訊器。生成的通訊器對提供相同 color 引數的程序是通用的。程序可以透過提供 MPI_UNDEFINED 作為 color 來選擇不獲取通訊器,這將為該程序生成 MPI_COMM_NULL。
例如,以下程式碼將 MPI_COMM_WORLD 拆分為三個通訊器,分別“著色”為 0、1 和 2。
#include<iostream>
#include<mpi.h>
using namespace std;
int main(int argc, char** argv) {
MPI_Init(&argc, &argv);
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm comm;
MPI_Comm_split(MPI_COMM_WORLD, rank % 3, -rank*2, &comm); // The keys need not be positive or contiguous.
int rank2;
MPI_Comm_rank(comm, &rank2);
cout << "My rank was " << rank << " now " << rank2 << " color: " << rank % 3 << "\n";
MPI_Finalize();
}
使用八個程序執行,這將輸出以下內容(以不確定的順序)
My rank was 0 now 2 color: 0 My rank was 8 now 2 color: 1 My rank was 8 now 1 color: 2 My rank was 3 now 1 color: 0 My rank was 4 now 1 color: 1 My rank was 5 now 0 color: 2 My rank was 6 now 0 color: 0 My rank was 7 now 0 color: 1 My rank was 8 now 0 color: 1
以下函式協同工作,以允許程序之間進行非阻塞非同步通訊。 [6] 一個程序傳送,而另一個程序接收。傳送方必須在擦除緩衝區之前檢查操作是否已完成。MPI_Wait() 是一個阻塞等待,而 MPI_Test 是非阻塞的。
MPI_Isend() 和 MPI_Irecv() 呼叫不必按順序進行。也就是說,程序 42 可以呼叫 MPI_Irecv() 三次來開始從程序 37、38 和 39 接收,它們可以隨時傳送。
int MPI_Isend(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request);
---
int MPI_Irecv(void* buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Request recvtag, MPI_Comm comm, MPI_Status *status);
int MPI_Wait(MPI_Request *request, MPI_Status *status);
int MPI_Test(MPI_Request *request, int* flag, MPI_Status* status);
示例程式碼
#include<iostream>
#include<mpi.h>
using namespace std;
int main(int argc, char** argv) {
MPI_Init(&argc, &argv);
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm comm;
int sources[] = {3,4,5};
int dest = 1;
int tag =42;
if (rank == sources[0] || rank == sources[1] || rank == sources[2]) {
double x[] = { 1*rank, 2*rank, 3*rank};
MPI_Request r;
MPI_Isend(x, 3, MPI_DOUBLE, dest, tag, MPI_COMM_WORLD, &r);
cout << "Process " << rank << " waiting...\n";
MPI_Status status;
MPI_Wait(&r, &status);
cout << "Process " << rank << " sent\n";
} else if(rank == dest) {
double x[3][3];
MPI_Request r[3];
for (int i = 0; i !=3; ++i) {
MPI_Irecv(x[i], 3, MPI_DOUBLE, sources[i], tag, MPI_COMM_WORLD, &r[i]);
cout << "Process " << rank << " waiting for " << sources[i] << " on recv.\
\n";
}
for (int i = 0; i !=3; ++i) {
MPI_Status status;
MPI_Wait(&r[i], &status);
cout << "Process " << rank << " got " << x[i][0] << " " << x[i][1] << " " <\
< x[i][2] << ".\n";
}
}
MPI_Finalize();
}
| 讀者要求擴充套件此頁面以包含更多內容。 你可以透過新增新材料(瞭解如何操作)或在閱覽室中尋求幫助來提供幫助。 |
int MPI_Init(int *argc, char ***argv); int MPI_Finalize(void); int MPI_Comm_rank(MPI_Comm comm, int *rank); int MPI_Comm_size(MPI_Comm comm, int *size); int MPI_Get_count(MPI_Status *status, MPI_Datatype datatype, int *count); int MPI_Type_extent(MPI_Datatype datatype, MPI_Aint *extent); int MPI_Type_struct(int count, int *array_of_blocklengths, MPI_Aint *array_of_displacements, MPI_Datatype *array_of_types, MPI_Datatype *newtype); int MPI_Scatter(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount, MPI_Datatype recvcount, int root, MPI_Comm comm); Performance potential: As good as log_2 (N) as bad as N. http://www.pdc.kth.se/training/Talks/MPI/Collective.I/less.html#perf_scatter_image int MPI_Gather(void* sendbuf, int sendcount, MPI_Datatype sendype, void* recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm); -- [7]
- request);
int MPI_Sendrecv(void* sendbuf, int sendcount, MPI_Datatype datatype, int dest, int sendtag, void* recvbuf, int recvcount, MPI_Datatype recvtype, int source, int recvtag, MPI_Comm comm, MPI_Status *status); int MPI_Sendrecv_replace(void* buf, int count, MPI_Datatype datatype, int dest, int sendtag, int source, int int MPI_Request_free(MPI_Request *request); int MPI_Group_rank(MPI_Group group, int *rank); int MPI_Group_size(MPI_Group group, int *size); int MPI_Comm_group(MPI_Comm comm, MPI_Group *group); int MPI_Group_free(MPI_Group *group); int MPI_Group_incl(MPI_Group *group, int n, int *ranks, MPI_Group *newgroup); int MPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm *newgroup); int MPI_Wtime(void); int MPI_Get_processor_name(char *name, int *resultlen);
- 對 MPI 語義的出色解釋
- “集體通訊” 由 Dave Ennis 博士撰寫
| 此頁面或部分是一個未完成的草稿或提綱。 你可以幫助完成工作,或者你可以在專案室中尋求幫助。 |