【问题标题】:Array declared only on root process仅在根进程上声明的数组
【发布时间】:2013-09-15 16:23:30
【问题描述】:

特别是在 Fortran 的 MPI 中,仅在根进程上定义一个数组是否可能并且是一个不错的选择?例如这样的:

program test
implicit none

include 'mpif.h'

all mpi_init(ierr)

call mpi_comm_rank(mpi_comm_world,myid,ierr)
call mpi_comm_size(mpi_comm_world,numproc,ierr) 

if (myid .eq. 0) then
    complex(8), dimension(:,:), allocatable :: array
end if

   ...

if (myid .eq. 0) then
    allocate(array(2,2))
end if

   ...

end program

您可以猜到,我已经尝试过了,但它不起作用,因为在 Fortran 中声明需要放在首位。但我希望有办法解决这个问题?

这样,数组也不会占用我的“虚拟”内存对吗?还是我误会了什么?

【问题讨论】:

    标签: arrays fortran mpi


    【解决方案1】:

    正如您所指出的,您不能在IF-blocks 或过程的声明块之后的任何地方有声明语句。但是,允许在所有进程上将数组声明为 ALLOCATABLE,并仅在其中一些进程上进行分配,我认为这是一个不错的选择。

    ! Declare as allocatable on all processes
    complex(8), dimension(:,:), allocatable :: array
    
       ...
    
    ! Allocate only on some
    if (myid .eq. 0) then
        allocate(array(2,2))
    end if
    

    这样,程序不会在其他进程上消耗任何额外的内存。

    【讨论】:

    • 有没有什么技巧?因为你的建议,我已经这样做了——但发现自己的虚拟内存消耗非常大(在 linux 中,我的“virt”比预期的要高得多”
    • 您确信其他东西没有吞噬您的记忆吗?我经常在选择进程上做这种声明和分配没有问题。
    • 我不相信,因为我拥有的所有数组都是可分配的,即使在运行开始时,“virt”值也很高,在我分配任何数组之前(同时“res " 值实际上为零)。好吧,如果没有技巧的话,我想我得另辟蹊径了。
    • @liskawc 我想知道您的代码是否占用了一些空间以防您分配数组。也许您可以 allocate 它在从属进程上设置一些小的值,然后立即 deallocate 它?
    • @KyleKanos 我理解正确吗: allocate(array(2,2)), array=dcmplx(0.0d0,0.0d0), deallocate(array)?
    【解决方案2】:

    每个进程都需要(完整)数组吗?如果没有,尝试分块分配:Proc0: 1--10, Proc1: 11--20 等。然后,每个进程只需要分配它的块。您可能需要一种在全局索引(本例中为 1--20)和本地索引(每个进程为 1--10)之间进行映射的方法。

    当然,您需要在某个时间点(例如 I/O)将所有进程的所有块收集到根进程,但您可以按顺序执行此操作而无需任何更多内存。

    【讨论】:

    • 我分发其他数组(它们按预期工作),但问题中提到的数组只会在 master 上声明。
    猜你喜欢
    • 2013-06-06
    • 1970-01-01
    • 2014-02-17
    • 2021-07-07
    • 1970-01-01
    • 1970-01-01
    • 2014-07-23
    • 2020-10-24
    • 2012-05-16
    相关资源
    最近更新 更多