MPI入門實例講解

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); 

Image

注:並不是編號爲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        通信域中的進程數 

jMPI基本數據類型與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官方文檔 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章