中科大 MPI编程指南(一)

https://wenku.baidu.com/view/3318805b69eae009581bec35.html

 

4.2 6个基本函数组成的mpi子集

#include "mpi.h" /* 提供mpi函数和数据类型定义 */


int main(int argc, char** argv) {

    int rank,size,tag =1;
    //senddata, recvdata 是int型
    int senddata, recvdata;
    
    //消息状态
    MPI_Status status;
    //初始化
    MPI_Init(&argc, &argv);
    
    //MPI_COMM_WORLD 全局——所有进程集合
    // MPI_Comm comm 当前
    
    //获取当前进程在指定通信域(MPI_COMM_WORLD)中的编号 -> 区分自身和其他程序
    int MPI_Comm_rank(MPI_Comm comm,int *rank);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    //获取指定通信域的进程数 -> 确定完成比例
    int MPI_Comm_size(MPI_Comm comm,int *size);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    
    if(rank==0){
        senddata=9999;
        
        /* 消息缓冲 即信内容
             * *buf     起始地址 
             * count    数据个数
             * datatype 数据类型
             
            消息封装 即信封
             * dest/source 目标/源进程编号 
             * tag      消息标签
             * comm     通信域
         */
         
        int MPI_send(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm);
        //发送数据到进程1
                //第四个参数即目的地进程编号
        MPI_send(&senddata, 1, MPI_INT, 1, tag, MPI_COMM_WORLD);
    }
    
    if(rank==1){
        int MPI_Recv(void*buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status);
        //从进程0接收数据
        MPI_Recv(&recvdata, 1, MPI_INT, 0 , tag, MPI_COMM_WORLD);
    }

    int MPI_Finalize(void);
    MPI_Finalize();
    return 0;
}

 

4.3 MPI消息

 

4.3.1数据类型(略)

Load elements -> load datatype2MPI_Datatype

 

4.3.2 消息标签

为什么需要消息标签?

区分相同类型的消息传输

//假设没有tag
        //Process P
        MPI_send(A,32,std::string,Q);
        MPI_send(B,16,std::string,Q);

        //Process Q
        MPI_Recv(X,32,std::string,P);
        MPI_Recv(Y,16,std::string,P);

        /*
        传送A的前32个字节给X;
        传送B的前16个字节给Y;

        尽管消息B后发送 但可能更快地到达进程Q 就被第一个recv接收到了x里,所以我们得加上标签
        */

    //有tag
        int tag1 = 1;
        int tag2 = 2;
        //Process P
        MPI_send(A,32,std::string,Q,tag1);
        MPI_send(B,16,std::string,Q,tag2);

        //Process Q
        MPI_Recv(X,32,std::string,P,tag1);
        MPI_Recv(Y,16,std::string,P,tag2);

 

 

4.3.3 通信域

1.进程组:进程的有限有序集 

一个进程用它在通信域里的编号来标识

//获取组大小
MPI_Comm_size(communicator, &group_size);
//获取进程编号
MPI_Comm_rank(communicator, &my_rank);

2.通信上下文:非显式

两部分来描述进程间的通信关系

// 一般size = rank + 1
        int my_rank = 9;
        int group_size = 10;

        int color = my_rank %3;
        int key = my_rank/3;

        MPI_Comm MyWorld,SplitWorld;
        int MPI_Comm_split(MyWorld,color,key,&SplitWorld);
        // my_rank = global_shard_id
        // color = mpi_rank();
        // 3 = mpi_size() 
        // key = local_shard_id
    
    
        //color = my_rank %3 = global_shard_id%mpi_size() = mpi_rank()
        //key = my_rank/3 =  global_shard_id/mpi_size() = local_shard_id

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值