1.一個簡單的hello world程序
mpi_hello.cpp
#include <iostream>
#include "mpi"
int main(int argv,char* argc[]){
MPI_Init(&argv,&argc);
cout<<"hello world"<<endl;
MPI_Finalize();
return0;
}
編譯:mpicxx -o mpi_hello mpi_hello.cpp
運行:mpirun -np 3 ./mpi_hello
2.幾個函數
(a)初始化MPI環境:int MPI_Init(int *argv,char **argc);
(b)結束MPI程序的運行:int MPI_Finalize(void);
這裏只是告知該MPI的並行代碼執行結束,而不是整個程序結束執行退出。在MPI_Finalize之後的代碼還是會繼續串行執行。例如:
#include "mpi.h"
#include <stdio.h>
#include <math.h>
#include <unistd.h>
#include <iostream>
using namespace std;
int main(int argc, char *argv[]){
int myid; // 當前進程的編號
int numprocs; // 當前進程的名稱
int namelen;
char processor_name[MPI_MAX_PROCESSOR_NAME];
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&myid);
MPI_Get_processor_name(processor_name,&namelen);
inti;
for(i=0; i<4; ++i){
cout<<"I'm"<<myid<<", sending "<<i<<endl;
sleep(1);
if(0 == myid && 0 == i){
MPI_Barrier(MPI_COMM_WORLD); //進程0將一直等待,直到其他並行進程執行結束
}
}
//MPI_Finalize(); //由於未執行MPI_Finalize,進程0無法感知到其他進程已退出
return0;
}
(c)獲取進程個數:intMPI_Comm_size(MPI_Comm comm, int *size);
(d)獲取當前進程編號rank,該值範圍[0,p-1],p爲並行進程個數:intMPI_Comm_rank(MPI_Comm comm, int *rank);
注:並不是編號爲0的進程就是主進程用於接收其他進程發送的消息,而是調用Recv函數的進程接收消息,調用Send函數的進行發送消息。
(e)通信域(通信空間):MPI_COMM_WORLD。一個通信空間是一個進程組和一個上下文的組合。上下文可看作爲組的超級標籤,用於區分不同的通信域。在執行函數MPI_Init之後,一個MPI程序的所有進程形成一個缺省的組,這個組的通信域即被寫作MPI_COMM_WORLD。該參數是MPI通信操作函數中必不可少的參數,用於限定參加通信的進程的範圍。這類似於namespace,但是通信域不僅包括了組的標示符,還包括組裏面的進程。
(f)發送消息:intMPI_Send(void* buf, int count, MPI_Datatype datatype, int dest,int tag, MPI_Comm comm);
IN buf 發送緩衝區的起始地址
IN count 要發送信息的元素個數(元素個數不一定等於字節個數,因爲一個元素可能包含多個字節)
IN datatype 發送信息的數據類型
IN dest 接收消息進程的rank值
IN tag 消息標籤(標識消息)
IN comm 通信域
(g)接收消息:intMPI_Recv(void* buf, int count, MPI_Datatype datatype, int source, inttag, MPI_Comm comm, MPI_Status *status);
OUT buf 接收緩衝區的起始地址,接收緩存應>=count*sizeof(datatype),否則將造成溢出
IN count 要接收信息的元素個數
IN datatype 接收信息的數據類型
IN source發送消息進程的rank值。使用MPI_ANY_SOURCE,可以接收來自任意進程的消息
IN tag 消息標籤(只接收與發送消息中tag值相同的消息)。使用MPI_ANY_TAG,可以接收任意標籤的消息
IN comm 通信域
OUTstatus status對象,包含實際接收到的消息的有關信息。可以通過status.MPI_SOURCE,status.MPI_TAG分別獲取發送消息的進程和消息標籤
(h)獲取實際接收到消息的長度:intMPI_Get_count(MPI_Status status, MPI_Datatype datatype,int* count);
INstatus 接收操作的返回值.
INdatatype 接收緩衝區中元素的數據類型.
OUTcount 接收消息中的元素個數.
(i)獲取指定通信域中的進程數:int MPI_Comm_size(MPI_Comm comm,int &size);
INcomm 通信域
OUTsize 通信域中的進程數
(j)MPI基本數據類型與C++類型的對應關係
MPI_BYTE |
|
MPI_CHAR |
signed char |
MPI_DOUBLE |
double |
MPI_FLOAT |
float |
MPI_INT |
int |
MPI_LONG |
long |
MPI_LONG_DOUBLE |
long double |
MPI_PACKED |
|
MPI_SHORT |
short |
MPI_UNSIGNED_CHAR |
unsigned char |
MPI_UNSIGNED |
unsigned int |
MPI_UNSIGNED_LONG |
unsigned long |
MPI_UNSIGNED_SHORT |
unsigned short |
|
|
Reference
1.MPI官方文檔