MPI_Waitall() 给定 MPI_Request 数组的行为可能具有用于异步 send/recv 的未初始化插槽
MPI_Waitall() behavior given MPI_Request array with possibly uninitialized slots for asynchronous send/recv
我遇到过这样一种情况,我需要分配一个 MPI_Request 类型的静态数组来跟踪异步发送和接收 MPI 操作。我总共有 8 个 Isend 和 Irecv 操作——其中 4 个是 Isend,其余是 Irecv。但是,我不会一次调用这 8 个函数。根据传入的数据,这些函数成对调用,这意味着我可以调用一对 1 send/receive 或 2 send/receive 或 3 send/receive 或一次全部。他们将成对被召唤这一事实是肯定的,但他们中有多少人会被召唤并不确定。下面是一个伪代码:
MPI_Request reqs[8];
MPI_Status stats[8];
if (Rank A exists){
//The process have to send data to A and receive data from A
MPI_Isend(A, ..., &reqs[0]);
MPI_Irecv(A, ..., &reqs[1]);
}
if(Rank B exists){
//The process have to send data to B and receive data from B
MPI_Isend(B, ..., &reqs[2]);
MPI_Irecv(B, ..., &reqs[3]);
}
if(Rank C exists){
//The process have to send data to C and receive data from C
MPI_Isend(C, ..., &reqs[4]);
MPI_Irecv(C, ..., &reqs[5]);
}
if(Rank D exists){
//The process have to send data to D and receive data from D
MPI_Isend(D, ..., &reqs[6]);
MPI_Irecv(D, ..., &reqs[7]);
}
//Wait for asynchronous operations to complete
MPI_Waitall(8, reqs, stats);
现在,我不确定程序的行为是什么。总共有 8 个不同的异步发送和接收函数调用,每个调用在 MPI_reqs[8]
中每个函数都有一个槽,但并非所有函数都将始终被使用。当其中一些未被调用时,MPI_reqs[8]
中的一些槽将未被初始化。但是,我需要 MPI_Waitall(8, reqs, stats)
到 return,不管 MPI_reqs[8]
中的所有插槽是否都已初始化。
有人可以解释程序在这种特定情况下的行为方式吗?
您可以使用 MPI_REQUEST_NULL
设置/初始化那些丢失的请求。也就是说,为什么不只是
int count = 0;
...
Isend(A, &reqs[count++]);
...
MPI_Waitall(count, reqs, stats);
当然,让值未初始化并将其提供给从中读取的某个函数并不是一个好主意。
我遇到过这样一种情况,我需要分配一个 MPI_Request 类型的静态数组来跟踪异步发送和接收 MPI 操作。我总共有 8 个 Isend 和 Irecv 操作——其中 4 个是 Isend,其余是 Irecv。但是,我不会一次调用这 8 个函数。根据传入的数据,这些函数成对调用,这意味着我可以调用一对 1 send/receive 或 2 send/receive 或 3 send/receive 或一次全部。他们将成对被召唤这一事实是肯定的,但他们中有多少人会被召唤并不确定。下面是一个伪代码:
MPI_Request reqs[8];
MPI_Status stats[8];
if (Rank A exists){
//The process have to send data to A and receive data from A
MPI_Isend(A, ..., &reqs[0]);
MPI_Irecv(A, ..., &reqs[1]);
}
if(Rank B exists){
//The process have to send data to B and receive data from B
MPI_Isend(B, ..., &reqs[2]);
MPI_Irecv(B, ..., &reqs[3]);
}
if(Rank C exists){
//The process have to send data to C and receive data from C
MPI_Isend(C, ..., &reqs[4]);
MPI_Irecv(C, ..., &reqs[5]);
}
if(Rank D exists){
//The process have to send data to D and receive data from D
MPI_Isend(D, ..., &reqs[6]);
MPI_Irecv(D, ..., &reqs[7]);
}
//Wait for asynchronous operations to complete
MPI_Waitall(8, reqs, stats);
现在,我不确定程序的行为是什么。总共有 8 个不同的异步发送和接收函数调用,每个调用在 MPI_reqs[8]
中每个函数都有一个槽,但并非所有函数都将始终被使用。当其中一些未被调用时,MPI_reqs[8]
中的一些槽将未被初始化。但是,我需要 MPI_Waitall(8, reqs, stats)
到 return,不管 MPI_reqs[8]
中的所有插槽是否都已初始化。
有人可以解释程序在这种特定情况下的行为方式吗?
您可以使用 MPI_REQUEST_NULL
设置/初始化那些丢失的请求。也就是说,为什么不只是
int count = 0;
...
Isend(A, &reqs[count++]);
...
MPI_Waitall(count, reqs, stats);
当然,让值未初始化并将其提供给从中读取的某个函数并不是一个好主意。