使用“MPI_Gatherv”沿第 n 维堆叠数组

Posted

技术标签:

【中文标题】使用“MPI_Gatherv”沿第 n 维堆叠数组【英文标题】:Stack arrays along nth dimension with `MPI_Gatherv` 【发布时间】:2020-09-06 23:45:57 【问题描述】:

我正在处理使用 MPI 并行化的 Fortran 代码。我在每个处理器上定义了一组 5 维数组:

real(DP) :: Qs(5, 5, 1, 1, ncell)

其中ncell 是每个处理器的不同编号。我想将所有数组收集到一个数组 Qs_glob 在处理器 0 处定义为:

real(DP) :: Qs_glob(5, 5, 1, 1, ncellglob)

其中ncellglob 等于不同处理器的所有ncell 值的总和。因此,我想沿第五维堆叠Qs 数组。我认为这可以使用mpi_gatherv 来完成,但是,我一直在努力在网络上找到一个可行的示例。任何人都可以帮忙吗?

编辑:

变量ncell 仅在本地为每个处理器所知。但是,这些变量可以通过mpi_gather 轻松发送到处理器 0。所有处理器都知道变量ncellglob。处理器总数nproc 也是所有处理器都知道的。

我的问题是找出mpi_gatherv 中的位移索引,因此数组最终会沿第 5 维堆叠。

【问题讨论】:

网上有很多例子。它应该很简单,每个进程的 n 只是数组的本地大小。如果您包含一些尝试并解释您的问题,这将是一个更好的问题。我们不知道您了解什么,不了解什么,所以这不是寻求教程的好地方。为了对您真正有用,我们必须知道您在每个流程中存储了什么样的信息,因此您需要显示更多代码。每个进程对其他进程了解多少(尤其是关于ncell)?这些信息是如何存储的? @VladimirF 好的,我想我明白了。位移索引每次都需要移动所有维度上的索引总和。我将编辑问题,也许还会发布我自己的答案。 我想你 (OP) 知道你在用那些伪装成 rank-5 数组的 rank-3 数组做什么。外部观察者可能会认为单例维度只是为了让索引更令人费解:-) @HighPerformanceMark 哈哈,是的,它们是 5 维的,但在这种情况下,两个维度的大小恰好是 1。 【参考方案1】:

我想我现在有了解决方案。操作方法如下:

subroutine gather_arrays()

use vars ! module defining Qs and ncell
use mpi_mod ! module defining nproc and rank

implicit none

! define the global array
real(DP) :: Q_glob(5, 5, 1, 1, ncellglob)

! define arrays containing the size and displacement index for each local array Qs
integer :: ncells(nproc), displacements(nproc), i 

! send array sizes to processor 0
call mpi_gather(ncell, 1, mpi_integer, ncells, 1, mpi_integer, 0, mpi_comm_world, ierr)

! calculate displacement indices
if (rank == 0) then
   displacements(1) = 0
   do i=2, nproc
      displacements(i) = displacements(i-1) + 5*5*1*1*ncells(i-1)
   end do
end if

! finally, gather all arrays in Q_glob
call mpi_gatherv(Qs, 5*5*1*1*ncell, MPI_DOUBLE_PRECISION, Q_glob, 5*5*1*1*ncells, displacements, MPI_DOUBLE_PRECISION, 0, mpi_comm_world, ierr)

end subroutine

【讨论】:

以上是关于使用“MPI_Gatherv”沿第 n 维堆叠数组的主要内容,如果未能解决你的问题,请参考以下文章

理解 numpy 的 dstack 函数

MPI_GATHERV 覆盖命令中未引用的数组

使用 mpi_f08 模块时调用 mpi_gatherv 后数组的 Lbound 发生变化

通过沿一个轴堆叠将两个 numpy 视图组合成一个视图

MPI_GATHERV (Fortran) 从二维子矩阵创建一个新的二维矩阵

沿第二轴连接 2 个 1D `numpy` 数组