仅在根进程上声明的数组

3
在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声明需要在顶部。但我希望有一种方法可以解决这个问题?

这种方式,数组也不会占用我的“虚拟”内存,对吗?还是我理解错了什么?

2个回答

4
正如您指出的那样,在IF代码块或过程的声明块之后,您不能有声明语句。但是,将数组在所有进程上声明为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

这样,程序就不会占用其他进程的额外内存。

你确定没有其他程序占用了你的内存吗?我经常在某些进程上进行这种声明和分配,而没有出现问题。 - milancurcic
我认为不是这样的,因为我拥有的所有数组都是可分配的,即使在运行开始之前,“virt”值也很高,而我还没有分配任何数组(同时,“res”值几乎为零)。好吧,如果没有什么诀窍,我想我必须找到另一种解决方法。 - liskawc
1
@liskawc 我想知道你的代码是否在分配数组时保留了一些空间。也许你可以在从属进程上将其分配到一些小值,然后立即进行解除分配? - Kyle Kanos
@KyleKanos 我理解的对吗:allocate(array(2,2)), array=dcmplx(0.0d0,0.0d0), deallocate(array)? - liskawc
@liskawc:我认为甚至赋值都不是必要的,但这就是我所想的。 - Kyle Kanos
显示剩余2条评论

0

你是否需要在每个进程中都使用(完整的)数组?如果不需要,请尝试以块的形式分配:Proc0:1- 10,Proc1:11-20等。然后,每个进程只需要分配其块。您可能需要一种方法来映射全局索引(例如此示例中的1-20)和本地索引(每个进程的1-10)。

当然,您需要在某个时间点将所有进程的所有块收集到根进程中(例如I/O),但是您可能可以依次完成此操作而无需任何进一步的内存。


我分发其他数组(它们按预期工作),但在问题中提到的数组只会在主节点上声明。 - liskawc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接