【问题标题】:Repeatedly used 2D array in a Fortran 90 subroutineFortran 90 子程序中重复使用的二维数组
【发布时间】:2020-11-01 10:17:52
【问题描述】:

我有一个结构如下所示的 Fortran 90 程序。 subroutinne A 中的步骤 compute the 2D array myMatrix(1:N,1:N) 很昂贵。它只依赖于全局变量N,只需要计算一次;子程序中的“其他步骤”不会改变 myMatrix 的值。目前,每当调用子例程时都会计算myMatrix

有没有办法让二维数组myMatrix只计算一次?

module constants
    integer :: N
end module constans

module A_module
use constants
contains
    subroutine A
    ! compute the 2D real array myMatrix(1:N,1:N)
    ! other steps that use myMatrix
    end subroutine A
end module A_module

program main
    use constants
    use A_module
    integer :: k

    do  k = 1,10000
        call A 
    end do

end program main

【问题讨论】:

    标签: fortran fortran90


    【解决方案1】:

    当然。定义一个 init_a_matrix 子例程,用于在 do 循环之外初始化矩阵。

    subroutine init_a_matrix
       ! Do initialization here
    end subroutine init_a_matrix
    

    那么你有

    call init_a_matrix
    do  k = 1,10000
        call A 
    end do
    

    如果要消除子程序A中myMatrix的冗余初始化(由于只需要计算一次,在子程序的初始调用时),可以使用SAVE属性和@987654326 @ 旗帜。在子程序A 你做,

    logical :: init_flag = .false.
    real, save :: matrix_a(n,n)
    if (init_flag .eqv. .false.) then
       ! Initialize matrix_a on the first call to the subroutine and reset init_flag.
       init_flag = .true.
    end if
    

    【讨论】:

      【解决方案2】:

      如果myMatrix 是子例程A未保存本地 变量,则需要在子例程的每个条目上重新计算其值:当子例程完成执行时,未保存的局部变量变为未定义。

      但是,有许多方法可以重用变量:

      • 使其成为保存的局部变量:保存的局部变量保留其定义
      • 将其作为虚拟参数,而不是局部变量(参数关联):其定义来自调用者
      • 把它当作其他形式的非局部变量(其他forms of association):它的定义来自另一个地方

      如果它是一个已保存的变量,则在子例程的第一个条目上计算它,并在后续调用中保留其定义:

      subroutine A
        <declaration>, save :: mymatrix
        logical, save :: first_entry = .TRUE.
      
        if (first_entry) then
           ! set up mymatrix
           first_entry = .FALSE.
        end if
        ! ...
      end subroutine A
      

      您可以使用 mymatrix 一个模块/主机变量做很多相同的事情。您可以使用 first_entry 保存的指标或依赖用户(如在 evets's answer 中)有一个额外的设置步骤:

      module A_module
      use constants
      <declaration> myMatrix  ! Example with host association, automatically saved
      contains
          subroutine A
          ! myMatrix is reused, either set up by a distinct call or on first entry
          ! other steps that use myMatrix
          end subroutine A
      end module A_module
      

      或者您可以将变量作为虚拟参数:

      mymatrix_actual = ...
      do k = 1,10000
        call A(mymatrix_actual)  ! A now has the dummy variable
      end do
      

      【讨论】:

        猜你喜欢
        • 2013-08-13
        • 1970-01-01
        • 2015-03-22
        • 1970-01-01
        • 2020-03-19
        • 1970-01-01
        • 2012-12-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多