使用MPI实现broadcast、scatter、gather操作

1.MPI_Bcast:广播消息

MPI_Bcast用于将一个进程的buffer中的数据广播到其他进程的相同buffer变量中。
在这里插入图片描述

#include "stdio.h"  
#include "mpi.h"  
#include "stdlib.h"  
#define N 10
int main(int argc, char** argv)
{
    int rank, data[10];
    MPI_Init(0, 0);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    if (rank == 0)
    {
        for (int i = 0; i < 10; ++i)
        {
            data[i] = i + 1;
        }
    }
    //进程0广播数据给所有进程
    MPI_Bcast(&data, 10, MPI_INT, 0, MPI_COMM_WORLD);
    //printf("process %d send data\n", rank);

    //每个进程该变量都被置为一样的值
    printf("process %d receive data:", rank);
    for (int i = 0; i < 10; ++i)
    {
        printf("%d ", data[i]);
    }

    MPI_Finalize();

    return 0;
}

运行VS中的代码:
右击
在这里插入图片描述
复制完整路径
在这里插入图片描述
在这里插入图片描述
删除\Project1.sln点击回车
在这里插入图片描述
打开X64–>Debug
在这里插入图片描述
在路径处输入cmd
在命令窗口输入 -n 是端口数量 Project1.exe为路径下的exe文件
mpiexec -n 4 Project1.exe

2. MPI_Gather:收集消息

MPI_Gather用于将所有进程的某个变量值发送给某一个进程,并按照进程rank值排序。
可以看到各进程的data都发送到进程0,并在收集数据buf中按照进程rank排序,其他进程收集数据buf是随机值。

#include "stdio.h"  
#include "mpi.h"  
#include "stdlib.h"  
#define N 10
int main(int argc, char** argv)
{
    int rank, data = 0;
    int size;
    MPI_Init(0, 0);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    //每个进程分别对data赋不同的值
    for (int i = 0; i < size; ++i)
    {
        if (i == rank)
        {
            data = i + 1;
        }
    }
    int receiveRank = 0; //收集消息的进程rank
    int* rbuf = new int[size];
    //进程0收集其他所有进程的数据
    MPI_Gather(&data, 1, MPI_INT, rbuf, 1, MPI_INT, receiveRank, MPI_COMM_WORLD);
    //只有进程0的数据是收集所有进程的值 其他进程全是随机值
    printf("process %d receive data:", rank);
    for (int i = 0; i < size; ++i)
    {
        printf("%d ", rbuf[i]);
    }

    MPI_Finalize();


    return 0;
}

3. MPI_Scatter:散播消息

MPI_Scatter用于将某个进程的数据分配/散播给所有进程,发送的部分数据按照进程rank值依次发送给各进程

#include "stdio.h"  
#include "mpi.h"  
#include "stdlib.h"  
#define N 10
int main(int argc, char** argv)
{
    int rank, data;
    int* sendBuf;
    int size;
    MPI_Init(0, 0);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    sendBuf = new int[size];
    for (int i = 0; i < size; ++i)
    {
        sendBuf[i] = i + 1;
    }
    //发送消息的进程rank
    int sendRank = 0;
    //进程0散播(分配)数据到各进程
    MPI_Scatter(sendBuf, 1, MPI_INT, &data, 1, MPI_INT, sendRank, MPI_COMM_WORLD);
    //每个进程的data按照rank顺序依次被散播为不同数据
    printf("process %d receive data %d", rank, data);
    MPI_Finalize();


    return 0;
}

Logo

汇聚原天河团队并行计算工程师、中科院计算所专家以及头部AI名企HPC专家,助力解决“卡脖子”问题

更多推荐