【问题标题】:MPI-Ibcast usageMPI-Ibcast 使用
【发布时间】:2017-07-16 21:03:49
【问题描述】:

我试图了解 MPI_Ibcast 的工作原理。 我想出了一个测试来说明我需要什么。 它可能不正确,因为我可能不了解 Ibcast 的正确用法:

#include <iostream>
#include <mpi.h>
#include <string>
#include <vector>


using namespace std;

class A {
public:
        int a[3];
        MPI_Request request;
        int tag;
        A() {}
        int foo() {
                int rank;
                MPI_Comm_rank(MPI_COMM_WORLD, &rank);
                cout<<rank<<endl;
                if (rank == 0)
                        tag = 5;
                MPI_Ibcast(&tag, 1, MPI_INT, 0, MPI_COMM_WORLD, &request);
        }
};

int main(int argc, char* argv[]) {
        MPI_Init(&argc, &argv);
        int rank;
        MPI_Comm_rank(MPI_COMM_WORLD, &rank);
        MPI_Status* status = new MPI_Status[2];
        MPI_Request* request = new MPI_Request[2];
        A* a = new A[2];
        for (int i = 0; i < 2; i++) {
                a[i].request = request[i];
        }

        for (int i = 0; i < 2; i++) {
                if (i == 0 && rank == 0) {
                        a[0].foo();
                }else if ( i == 1 && rank == 1) {
                        a[1].foo();
                }
                int a;
                for (int i = 0; i < 1000; i++)
                        a+=i;
        }
        MPI_Waitall(2, request, status);
        cout <<a[1].tag<<" "<<a[1].tag<<" "<<a[1].tag<<endl;
        MPI_Finalize();
}

我想看看,如果 MPI_Ibcast 可以在第一次迭代的函数中调用,那么这个函数返回并且在另一个迭代中另一个进程也将调用 MPI_Ibcast 然后它全部完成(标签将被广播并设置为 5 in所有两个过程)。我在这里使用类的原因是我将它们放在原始程序中,在这里我尝试对一个小问题进行建模。

所以任务是:在不同的循环中,不同进程上的不同实例调用一个函数。其中一些被组织成组,在这个组内 Ibcast 广播标签。在这里,我有一个小组有两个班级。也许我应该以某种方式纠正这个例子?

【问题讨论】:

    标签: c++ mpi broadcast


    【解决方案1】:

    我不完全确定您想要做什么,但这是您示例的固定版本。我更正的主要内容是使用请求,因为您没有等待正确的请求...

    #include <iostream>
    #include <mpi.h>
    
    using namespace std;
    
    class A {
        public:
            MPI_Request request;
            int tag;
            A() : request(MPI_REQUEST_NULL), tag(-1){}
            int foo() {
                int rank;
                MPI_Comm_rank(MPI_COMM_WORLD, &rank);
                cout<<rank<<endl;
                if (rank == 0)
                    tag = 5;
                MPI_Ibcast(&tag, 1, MPI_INT, 0, MPI_COMM_WORLD, &request);
            }
    };
    
    int main(int argc, char* argv[]) {
        MPI_Init(&argc, &argv);
        int rank;
        MPI_Comm_rank(MPI_COMM_WORLD, &rank);
        A a[2];
    
        for (int i = 0; i < 2; i++) {
            if (i == 0 && rank == 0) {
                a[0].foo();
            }else if ( i == 1 && rank == 1) {
                a[1].foo();
            }
            int b = 0;
            for (int i = 0; i < 1000; i++)
                b+=i;
        }
        MPI_Wait(&a[rank].request, MPI_STATUS_IGNORE);
        cout <<a[1].tag<<" "<<a[1].tag<<" "<<a[1].tag<<endl;
        MPI_Finalize();
    }
    

    这是我在机器上使用两个进程编译和运行它时给出的结果:

    ~/tmp$ mpiicpc -O0 ibcst.cc 
    ~/tmp$ mpirun -n 2 ./a.out 
    1
    0
    5 5 5
    -1 -1 -1
    

    现在可以了,希望能达到您的预期。但是,您对进程组的描述使我相信您应该使用例如MPI_Comm_split() 创建几个子通信器,以允许在...内使用集体调用...

    【讨论】:

      猜你喜欢
      • 2021-03-16
      • 2011-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      • 2014-09-17
      • 2014-11-26
      • 2015-04-14
      相关资源
      最近更新 更多