【问题标题】:Gathering in MPI, but not with MPI_Gather在 MPI 中收集,但不使用 MPI_Gather
【发布时间】:2016-10-23 14:26:47
【问题描述】:

我需要执行 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);
}

我的想法是 proc 0 将启动循环并等到从 my_place_in_storage 为 1 的 proc 发布发送,然后 proc 0 将接收该消息并将值放入 gathervals[1]。然后它将迭代并等待,直到它看到来自 proc 的 my_place_in_storage 为 2 的帖子,等等。

这应该有效吗?我在 proc 0 上遇到了段错误,我试图找出原因。我认为这个可能有点不正统的代码块将是开始的地方。我已经验证了所有my_place_in_storage 值的正确性。

【问题讨论】:

标签: c mpi


【解决方案1】:

另一个选项是使用 MPI_Comm_split 创建一个新的通信器,它包含与 MPI_COMM_WORLD 相同的所有进程,但根据“my_place_in_storage”排列成新的顺序。如果每个人都提供相同的“颜色”值,那么您就可以这样做,因此他们都属于同一个通信器,但使用“my_place_in_storage”作为“键”。

Communicator 创建有一些开销,但如果您使用相同的“my_place_in_storage”值多次执行此操作,这可能比使用两个收集更有效。请注意,在新的通信器中,您也可以只使用 gather,它也应该比gatherv 更快。

【讨论】:

  • 有趣。我不会想到的。谢谢!
【解决方案2】:

是的,这应该可以,但是您有更好的选择。使用MPI_Gather 收集my_place_in_storage 并将其用作MPI_Gatherv 的位移数组。类似的东西:

 if (my_rank == 0) {
     int displacements[10];
     int recvcounts[10] = {1,1,1,1,1,1,1,1,1,1};
     MPI_Gather(&my_place_in_storage, 1, MPI_INT,
                displacements, 1, MPI_INT, 0, MPI_COMM_WORLD); 
     MPI_Gatherv(&my_val, 1, MPI_INT, gathervals, recvcounts,
                 displacements, MPI_INT, 0, MPI_COMM_WORLD);
 } else {
     MPI_Gather(&my_place_in_storage, 1, MPI_INT,
                NULL, 1, MPI_INT, 0, MPI_COMM_WORLD); 
     MPI_Gatherv(&my_val, 1, MPI_INT, NULL, 1, NULL,
                 MPI_INT, 0, MPI_COMM_WORLD);
 }

一般来说,最好使用一个集合而不是多个点对点消息。这更具可扩展性,并允许 MPI 实现进行更多优化。

【讨论】:

  • 第一次调用MPI_Gatherv时的recvcounts参数应该是recvcounts,而不是1
猜你喜欢
  • 2017-07-03
  • 2021-02-01
  • 2016-04-28
  • 1970-01-01
  • 2014-01-22
  • 1970-01-01
  • 2011-12-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多