我不清楚如何在 MPI 中正确使用非阻塞集合,特别是MPI_Ireduce()
在这种情况下:
假设我想从根等级收集总和:
int local_cnt;
int total_cnt;
MPI_Request request;
MPI_Ireduce(&local_cnt, &total_cnt, 1, MPI_INT, MPI_SUM, 0, MPI_WORLD_COMM, &request);
/* now I want to check if the reduce is finished */
if (rank == 0) {
int flag = 0;
MPI_Status status;
MPI_Test(&request, &flag, &status);
if (flag) {
/* reduce is finished? */
}
}
这是检查非阻塞减少是否完成的正确方法吗?我的困惑来自两个方面:一,可以还是应该只使用 root 进程检查它,MPI_Test()
因为这仅对 root 有意义?第二,既然MPI_Test()
是local op,这个local op怎么知道操作完成了?它确实需要完成所有过程,对吗?
您必须检查所有参与等级的完成情况,而不仅仅是根。
从用户的角度来看,您需要了解通信的完成情况,因为您不得对提供给非阻塞操作的内存进行任何操作。即,如果您发送一个局部作用域变量,如local_cnt
,则在确认操作完成之前,您不能写入它或离开它的作用域。
确保完成的一种选择是调用MPI_Test
直到它最终返回flag==true
。仅当您可以在调用之间做一些有用的事情时才使用它MPI_Test
:
{
int local_cnt;
int total_cnt;
// fill local_cnt on all ranks
MPI_Request request;
MPI_Ireduce(&local_cnt, &total_cnt, 1, MPI_INT, MPI_SUM, 0, MPI_WORLD_COMM, &request);
int flag;
do {
// perform some useful computation
MPI_Status status;
MPI_Test(&request, &flag, &status);
} while (!flag)
}
MPI_Test
如果在调用之间没有任何有用的事情可做,请不要循环调用。而是使用MPI_Wait
, 阻塞直到完成。
{
int local_cnt;
int total_cnt;
// fill local_cnt on all ranks
MPI_Request request;
MPI_Ireduce(&local_cnt, &total_cnt, 1, MPI_INT, MPI_SUM, 0, MPI_WORLD_COMM, &request);
// perform some useful computation
MPI_Status status;
MPI_Wait(&request, &status);
}
请记住,如果您根本没有有用的计算,并且由于死锁原因不需要非阻塞,请首先使用阻塞通信。如果您有多个正在进行的非阻塞通信,有MPI_Waitany
,MPI_Waitsome
,MPI_Waitall
和他们的测试变种的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句