非阻塞发送接收:代码任意执行 OpenMPI C++

non blocking send receive: code executes arbitrarily openmpi c++

提问人:shekhar 提问时间:8/15/2023 最后编辑:Anton Kesyshekhar 更新时间:8/18/2023 访问量:40

问:

我正在使用 openMPI 构建求解欧拉方程的代码。为此,我需要跨不同进程发送一个属性数组(cols= 保守属性,rows= 节点号)。我发送和接收的代码片段如下

// SEND
for (int proc = 0; proc < numtasks; proc++) {
    if (proc != taskid) {
        size = send * 11; // typical size may be of the order of 10^3
        source = proc;
        p = &array2D[0][0];
        MPI_Send(&size, 1, MPI_INT, source, taskid, MPI_COMM_WORLD);
        MPI_Send(p, size, MPI_DOUBLE, source, taskid, MPI_COMM_WORLD);
  }
}

// RECEIVE
offset = 0;
for (int proc = 0; proc < numtasks; proc++) {
    if (proc != taskid) {
        source = proc;
        p = &array2D[offset][0];
        MPI_Recv(&recv_size[proc][0], 1, MPI_INT, source, source, MPI_COMM_WORLD,
                 &status); // recv_size is vector with rows equal to no of
                       // processors since a given process has to receive from
                       // multiple processes
        MPI_Recv(p, recv_size[proc][0], MPI_DOUBLE, source, source, MPI_COMM_WORLD,
             &status);
        offset = offset + recv_size[proc][0] / (11);
    }
}

当此代码在 openmpiV3 中执行时,它运行良好。但是,当我在 openmpiV1 中执行相同的操作时,它只是在此块之前停止(没有抛出错误)并且不会进一步执行。(在 V1 中,它对于较小的数据大小运行良好)

我阅读了一些关于阻止和非阻止发送和接收的帖子。所以我将代码修改为

// SEND
MPI_Request sendrequest, recvrequest;
for (int proc = 0; proc < numtasks; proc++) {
    if (proc != taskid) {
        size = send * 11; // typical size may be of the order of 10^3
        source = proc;
        p = &array2D[0][0];
        MPI_Send(&size, 1, MPI_INT, source, taskid, MPI_COMM_WORLD);
        MPI_Isend(p, size, MPI_DOUBLE, source, taskid, MPI_COMM_WORLD,
                  &sendrequest);
    }
}
// RECIEVE
MPI_Status status1, offset = 0;
for (int proc = 0; proc < numtasks; proc++) {
    if (proc != taskid) {
        source = proc;
        p = &array2D[offset][0];
        MPI_Recv(&recv_size[proc][0], 1, MPI_INT, source, source, MPI_COMM_WORLD,
                 &status);
        MPI_Irecv(p, recv_size[proc][0], MPI_DOUBLE, source, source, MPI_COMM_WORLD,
                  &recvrequest);
        offset = offset + recv_size[proc][0] / (11);
    }
}
MPI_Wait(&recvrequest, &status1);
    

修改后的代码在 openmpiV1 中任意成功执行。有时,它不会引发错误,但发送和接收不会完成,代码会给出错误的结果。

我想知道是版本更改导致了问题,还是我的代码写得不好?

有没有更好的方法?

C++ 发送 非阻塞 OpenMPI

评论


答: 暂无答案