提问人:shekhar 提问时间:8/15/2023 最后编辑:Anton Kesyshekhar 更新时间:8/18/2023 访问量:40
非阻塞发送接收:代码任意执行 OpenMPI C++
non blocking send receive: code executes arbitrarily openmpi c++
问:
我正在使用 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 中任意成功执行。有时,它不会引发错误,但发送和接收不会完成,代码会给出错误的结果。
我想知道是版本更改导致了问题,还是我的代码写得不好?
有没有更好的方法?
答: 暂无答案
评论