我需要做一些类似于MPI_Gather的事情,但我需要按照与流程等级不同的顺序存储收集的数据.我以为我可以这样做:
int i;
int gathervals[10];
int my_val, my_place_in_storage;
/* init MPI etc ... then ... */
my_val = some_fcn_of_rank(my_rank, ...)
my_place_in_storage = some_other_fcn(my_val, my_rank, ...)
if (my_rank == 0){
/* my_val on proc 0 does go in gathervals[0], which simplifies
things */
gathervals[0] = my_val;
for (i=1; i<num_procs; i++){
MPI_Recv(&gathervals[i], 1, MPI_INT, MPI_ANY_SOURCE,
i, MPI_COMM_WORLD, stat_mpi);
}
}else{
MPI_Send(&mv_val, 1, MPI_INT, 0, my_place_in_storage,
MPI_COMM_WORLD);
}
Run Code Online (Sandbox Code Playgroud)
我的想法是proc 0将启动循环并等待从proc的发布发送my_place_in_storage为1,然后proc 0将接收该消息并将值放入gathervals[1].然后它将迭代并等待,直到它看到来自proc的帖子my_place_in_storage为2,等等.
这有用吗?我在proc 0上遇到了一个段错误,我正试图找出原因.我认为这段代码可能有点不正统,可以从这里开始.我已经验证了所有my_place_in_storage值的正确性.
另一种选择是使用MPI_Comm_split创建一个包含所有相同的过程,但MPI_COMM_WORLD置换为基于"my_place_in_storage"新秩序新的传播者.你可以这样做,如果每个人都提供相同的"颜色"值,所以他们都属于同一个传播者,但使用"my_place_in_storage"作为"关键".
Communicator创建有一些开销,但如果使用相同的"my_place_in_storage"值多次执行此操作,这可能比使用两个收集更有效.请注意,在新的通信器中,您还可以使用也应该比gatherv更快的聚集.