天天看點

MPI進階

mpi tutorial 介紹基本的mpi函數,源碼位址

      0, 基本概念

     buffer, data count, data type, destination, source, tag。下述的mli函數的參數,都包括這些名詞。其中buffer,就是發送/接收的變量名。c/c++中,參數按引用傳遞。

     mpi是spmd模型,适合粗粒度并行。各節點的資料,除了通信溝通外,互相獨立。

     mpi_wtime(), 類似 omp_get_wtime(void)

     MPI_Init() , 在mpi-2中,參數可以為null; mpi-1中,必須與main的參數一緻。   

       一, 點對點通信

      1.1 靜态資料傳輸

MPI_Send(void* data, int count, MPI_Datatype datatype, int destination,
         int tag, MPI_Comm communicator)
      
MPI_Recv(void* data, int count, MPI_Datatype datatype, int source,
         int tag, MPI_Comm communicator, MPI_Status* status)      

      1.2 動态資料傳輸

MPI_Get_count(MPI_Status* status, MPI_Datatype datatype, int* count)      
MPI_Probe(int source, int tag, MPI_Comm comm, MPI_Status* status)      

 mpi_probe,傳回status的屬性值,e.g. status.size, mpi_get_count 是通路status.size的函數

       1.3 舉例:随機遊走

   mpi政策分析:

      1  域分解, 每個子域内的遊走由一個mpi節點完成

      2 每個子域内walker數列初始化:初始位置和總步數(随機生成)

      3 每個子域内walker遊走規則:所有walker均沿一個方向。當其超過子域的邊界,将該walker加入 out_going_walker數列,其将與鄰接的子域通信。 

      4  mpi通信規則: send_outgoing_walk, 将目前cpu中 outgoing_walker數列發送到下一個子域; receive_incoming_walk,接收前一個子域送來的walker資料

      5  避免死鎖:如果所有節點上的walkers都同步--即先send,後receive. 而network buffer不大,send資料都沒法被線程接收。采用:偶數節點先發送,後接收;奇數節點,先接收後發送。如此避免死鎖。

      6  程式終止:給定最大步數,可以得到每個walker最大跨越的子域個數。完成這些跨越,該walker就終止了。

      二, 集合通信

MPI_bcast(void* send_data, int send_count, MPI_Datatype send_datatype,
            void* recv_data, int recv_count, MPI_Datatype recv_datatype,
            int root, MPI_Comm communicator)      
send_data 是master程序上的數組A0,send_count表示發送給每個slave程序的單元數目。比如 send_count =1 ,則 0号程序将得A0[0], 1号程序得到A0[1],依次。      
MPI_Scatter(void* send_data, int send_count, MPI_Datatype send_datatype,
            void* recv_data, int recv_count, MPI_Datatype recv_datatype,
            int root, MPI_Comm communicator)      
MPI_Gather(void* send_data, int send_count, MPI_Datatype send_datatype,
           void* recv_data, int recv_count, MPI_Datatype recv_datatype,
           int root, MPI_Comm communicator)      
MPI進階
MPI進階

     2.2  舉例:計算平均值

     1 master程序,生成随機數組, scatter到slave程序。注意各slave程序裡要先開辟一個buffer,用來接收 scatter過來的 随機數組片段; 

      2 master程序,gather 各salve上的平均值,同樣需要先開辟一個buffer,用來存儲各slave平均值;

      3 通信結束後,可釋放上述各開辟的buffer  

     2.3 reduce

MPI_Reduce(void* send_data, void* recv_data, int count,
           MPI_Datatype datatype, MPI_Op op, int root,
           MPI_Comm communicator)      

 send_data, 是各slave程序中要拿來reduce的對象;recv_data是master程序中存 reduced結果的變量, count是對象/變量的長度(count =1,即一個變量;count=2,即一個長度為2的數組)

reduce 比  scatter + gather 要簡潔些。

    總結

mpi 算是底層的通信協定,這篇文章主要是了解下這些通信方式,當然還有很多複雜的通信模型allgather等等。mpi 在計算仿真領域的應用開發,都或多或少提供了更高層次的封裝。比如petsc,以及進一步基于petsc的各類cfd/fea求解器開發,則是更上層。

根據課程進度,今後估計還有一些介紹矩陣計算,當然後期的重點是跟幾個開源。barba group github

繼續閱讀