我正在从 R 调用 fortran 子例程,作为更复杂的优化问题的一部分。目前,该子例程是独立的——具有当前参数值的输入和函数评估和梯度项的输出。我现在希望将可分配数组初始化为共享模块变量(在优化之前),该变量将在优化期间由子例程使用(但不修改)。
在这种情况下,共享可分配数组何时会超出范围或被删除?
幼稚的阅读内存管理 https://en.wikibooks.org/wiki/Fortran/memory_managementFortran wikibook 的部分建议模块变量应该持续存在(甚至可能在程序执行后)。
一些sources http://www.fortran90.org/src/best-practices.html#allocatable-arrays我读过表明可分配数组在超出范围时将自动释放。模块变量也会发生这种情况吗?什么时候会发生?
我找到了一个number https://stackoverflow.com/questions/16278866/fortran-allocatable-variables-in-modules of related https://stackoverflow.com/questions/11837616/fortran-allocatable-array-lifetime 问题 https://stackoverflow.com/questions/13844426/when-does-a-module-go-out-of-scope-in-fortran-90-95但我无法将它们放在模块变量和共享库加载的上下文中。
Edit:
Fortran 模块的最小示例。分配的数组按 Fortran 程序中的预期工作。在实践中,两者init()
and eval()
将被 R 函数包装(init_wrap()
and eval_wrap()
)并从 R 调用。我想确认分配的变量y
保证不会超出范围或被删除test_module
作为共享库加载。
module test_module
double precision, allocatable, dimension(:,:) :: y
contains
subroutine init() bind(C, name = "init_")
if (.not. allocated(y) ) then
allocate(y(1,1))
end if
y = 1
end subroutine init
subroutine eval(x, z) bind(C, name = "eval_")
double precision, intent(in) :: x
double precision, intent(out) :: z
z = x + y(1,1)
end subroutine eval
end module test_module
! Program added for testing purposes only,
! module is used as shared library
program test_program
use test_module
double precision :: x, z
! Initialize allocatable array
call init()
! Use allocatable array during optimization
x = 1
call eval(x, z)
x = 2
call eval(x, z)
print *, z
end program test_program
Edit 2:
我在 github 上创建了一个框架包,它模拟了我如何使用 Fortran 代码:https://github.com/ssokolen/fortran.test https://github.com/ssokolen/fortran.test
下面的 R 代码可以按照我的需要工作(分配的数组将其值保留在eval_wrap()
调用),但我仍然希望得到关于分配的模块变量在作为共享库加载时何时超出范围的明确答案(或者表明没有一般行为的答案)。
library(devtools)
install_github('ssokolen/fortran.test')
library(fortran.test)
init_wrap()
eval_wrap(1)
eval_wrap(2)