使用subroutinization在fortran程序之间交换数据

时间:2012-12-11 19:52:22

标签: performance fortran subroutine

我有两个独立的(和大的)fortran程序,我需要在它们之间来回交换数据。它们是环境模拟器(让我们称之为A和B),每个时间步都需要交换一些数组的数据,直到模拟完成。我想出的解决方案是将B转换为一个子程序,每个时间步都由A调用,数据通过参数传递。因为B太大了,所以每次步骤初始化都很慢。

有没有办法将B保留在内存中,以便A每次都没有将所有内容加载到内存中?还有其他方法可以使子程序调用不那么慢吗?

是否有一种更有效的方式在同步方式之间以独立的Fortran程序交换数据而无需进行子机构化?

1 个答案:

答案 0 :(得分:0)

除了MPI方法之外,您还可以设计一个对象(派生类型),它包含程序B需要知道的所有变量,以便记住它在调用之间的状态。然后你应该将程序B的功能分成三个例程:

  • 初始化例程(在A中第一个时间步之前调用)
  • 主程序(在A中的每个时间步调用)
  • 可选:销毁(在A的最后一步后调用)。

每次从程序A中调用这些例程时,都会使用变量传递派生类型。在第一次调用中,它们被初始化,在随后的调用中使用它们。

所以程序A看起来像:

type(bdata) :: myb
...
call initialize_b(myb)
do ii = 1, ntimesteps
  ...
  call main_b(myb, data)
  ...
end do
call destruct_b(myb)

类型bdata必须包含程序B需要记住的所有内容,例如:

type :: bdata
  integer, allocatable :: whatever(:)
  ...
end type bdata

模块中具有程序B功能的例程如下:

!> First initialization of B (slow).
subroutine initialize_b(myb)
  type(bdata), intent(out) :: myb
  ...
end subroutine initialize_b


!> Process data comming from program A.
subroutine main_b(myb, data)
  type(bdata), intent(inout) :: myb
  ...
end subroutine main_b

如果只需要程序B的一个实例,则可以通过将程序B转换为模块变量来控制其状态(而不是派生类型的字段)来执行相同的操作。但无论解决方案如何,你必须以某种方式分离初始化部分,以确保它只执行一次。