天天看点

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

继续阅读