MPI仅从SELECT处理器收集

时间:2013-08-08 02:21:03

标签: c parallel-processing mpi

我在MPI中寻找类似于allgather的函数,除了它只收集来自所有处理器的某个子集的数据。

此外,我想按照不依赖于处理器等级的顺序组合数据。

有这样的功能吗?如果没有,怎么能有效地实现这个?

谢谢!

2 个答案:

答案 0 :(得分:1)

我认为没有办法改变MPI调用本身的顺序(如果你愿意的话,你可以随后自己重新排序),但解决第一个问题相对容易。

在MPI中,并不要求所有集合调用都发生在MPI_COMM_WORLD(其中包含在执行开始时启动的所有进程)。您可以创建包含您喜欢的原始进程组的任何子集的新通信器。执行此操作的调用是MPI_COMM_CREATE。

要使用MPI_COMM_CREATE,您需要使用适当的函数(MPI_GROUP_EXCL,MPI_GROUP_INCL,MPI_GROUP_INTERSECTION等)操作要放入新通信器的进程的MPI_Group。网上通常有很多教程,如果不是很明显的话,你可以找到如何做这些事情。

答案 1 :(得分:1)

基本上,您的问题有两种解决方案。第一个解决方案是创建一个通信器,在那里放置必须发送数据的节点;但是,这不允许您对收集的数据进行随机播放。第二种解决方案是使用MPI_Gatherv而不是MPI_Gather。

MPI_Gatherv与MPI_Gather的作用相同,但您指定从每个处理器收集的元素数量以及放置它们的位置。考虑例如您可能希望收集流程0的2个值,流程1的3个值,流程2中的值和流程3中的1个值。

然后你必须用以下参数调用MPI_Gatherv(我把数组放在方括号中,所以这不是有效的代码; mycount是当前进程必须发送的元素数,因此对于进程0它将是2 ,3为进程1,......):

MPI_Gatherv(sendbuffer, mycount, type,
    recvbuffer, [2, 3, 0, 1], [0, 2, 5, 5], type,
    root, comm)

请注意,参数“displs”的第二个数组指定recvbuffer中的偏移量,其中将保存从相应进程接收的元素:

ProcID    Portion    Size
  0       [0, 2)      2
  1       [2, 5)      3
  2       [5, 5)      0
  3       [5, 6)      1

如果您愿意,例如以过程反转顺序存储值,从过程3的值开始到最后的过程0,你应该这样做:

MPI_Gatherv(sendbuffer, mycount, type,
    recvbuffer, [2, 3, 0, 1], [4, 1, 1, 0], type,
    root, comm)

这样“职业计划”看起来像:

ProcID    Portion    Size
  0       [4, 6)      2
  1       [1, 4)      3
  2       [1, 1)      0
  3       [0, 1)      1

如果你想要一个随机分布,你将“只是”必须随机生成一个数组“displ”,付出(很多)注意力使其保持一致。

作为两个最后的评论,请注意两个数组recvcounts和displ仅与root相关;在其他节点上传递空指针是安全的。另一个注意事项是你必须在不发送数据的节点中调用MPI_Gatherv:在这些情况下,mycount必须设置为0;如果你想避免在没有值发送的节点上调用MPI_Gatherv,你必须设置一个不同的通信器,然后调用MPI_Gatherv。