【问题标题】:How to initialize/declare a large array that occupies more memory than Master process has access to when parallelizing a code using MPI使用 MPI 并行化代码时,如何初始化/声明占用的内存比主进程访问更多内存的大型数组
【发布时间】:2018-05-03 01:07:45
【问题描述】:

我正在尝试并行化一个数学 fortran 代码,该代码迭代地求解 3D 晶格上的一组偏微分方程。我想做的是声明一个大数组并将其分布在不同的处理器之间以进行迭代计算。我真正感到困惑的是如何初始化这个数组,如果它占用的内存超过一个进程可以访问的内存。例如,如果我的大阵列占用 5 GB 内存,而主处理器只能访问 2 GB 内存,我如何初始化/声明它而不崩溃?有没有办法声明一个大型“分布式”数组。

另外,如果这是不可能的,我应该如何在多个处理器上将我的大数组分成多个较小的数组。在操作上,我要问的是,如果我如下声明我的大数组“f”,

        integer ierr, taskid, numtasks
        real*8 f
        dimension f(-nx:nx,-ny:ny,-nz:nz)
        call MPI_INIT( ierr )
        call MPI_COMM_RANK( MPI_COMM_WORLD, taskid, ierr )
        call MPI_COMM_SIZE( MPI_COMM_WORLD, numtasks, ierr )

    if(taskid==0) then
         DO 10, i = -nx, nx
             DO 20, j = -ny, ny
                Do 30, k = -nz, nz 

                f(i,j,k) = 0.0

    30       CONTINUE
    20    CONTINUE
    10 CONTINUE

    else

c Do something else !

    call MPI_Finalize(ierr)

当 nx、ny 和 nz 很大时,主处理器将耗尽内存并崩溃。那么,处理这种情况的最佳方法是什么。我在谷歌上搜索了很多,我找不到一个例子来解释在这种情况下该怎么做。我是初学者,所以请原谅我在这里没有得到任何东西。

【问题讨论】:

  • 这是大多数高性能计算的主要问题。通常,需要考虑要解决的系统的细节。例如,在我的领域中,PDE 是双曲线的,因此域被分解为每个处理器的不同分区。
  • 感谢您的及时回复。我知道我们需要分解我们的域。但是我不确定如何初始化这样一组分布式数组。如何确保特定处理器仅访问我要分配的数据(应该是什么语法?)。谢谢。
  • 向后嵌套下标是有问题的。在 64 位操作系统上,如果数组是可分配的,则应该没有问题。
  • 没有特定的语法。每个进程只声明数组(例如从1local_nx,或类似的东西。你确定你了解分布式进程吗?它们是完全独立的,它们不知道彼此的内部结构,它们只是交换一些消息. 而且,如果你正在学习,请学习 END DO 和其他现代 Fortran 功能。不要像 1970 年代那样编程。
  • 你的问题很奇怪。每个进程都有一个本地数组。它无法访问其他任何东西。根本不行(好吧,可以,但是太高级了)。它只是传递和接收消息。

标签: arrays parallel-processing fortran mpi distributed-computing


【解决方案1】:

您可能想澄清分布式数组的工作原理。有一个很大的全局数组。但它在任何地方都不存在!这只是一个概念。每个进程都有这个数组的一小部分。

有多种分解数组的方法,但请考虑对一维数组进行简单的一维分解。

在串行程序中,它将是一个数组:

real A(1:global_n)

有坐标

real x(1:global_n)

例如,这些坐标是

x = [( x0 + hx * i, i = 1, global_n )]

但在并行程序中,每个进程都有一个小数组。一种可能性是:

real A(1:local_n)

有坐标

real x(1:local_n)

每个进程都从local_x0开始

x = [( local_x0 + hx * i, i = 1, local_n )]

然后你可以简单地使用坐标来初始化数组

do i = 1, local_n
  A(i) = function_of_x(x(i))
end do

例如,如果您有一个 1..30 的数组,坐标从 0.1 到 3,并且有 3 个进程,那么您将拥有

local_n = 10

在每个过程中。

那么你将拥有进程 0

local_x0 = 0.1

对于进程 1

local_x0 = 1.1

对于进程 2

local_x0 = 2.1

【讨论】:

    猜你喜欢
    • 2017-11-25
    • 1970-01-01
    • 2021-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-20
    • 2015-01-01
    相关资源
    最近更新 更多