作为共享库加载时,Fortran 模块可分配数组何时超出范围?

2023-12-31

我正在从 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)

动态加载的库超出了 Fortran 标准。整个“处理器”表示发生了什么,它是 Fortran 编译器、操作系统、链接器等的复合体。

在 Linux 和其他 POSIX 操作系统中,如果从内存中卸载库,它将超出范围。这个简单的测试用例表明:

module test_module

  double precision, allocatable, dimension(:,:) :: y

  contains

    subroutine init() bind(C, name = "init_")
      print *, "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

      if (.not. allocated(y) ) error stop("not allocated!")
      z = x + y(1,1)
      print*, "success"
    end subroutine eval

end module test_module

C 调用库:

#include <stdio.h>
#include <dlfcn.h>
#include <stdlib.h>

int main(){

  void *handle = dlopen("/home/lada/f/testy/stackoverflow/dltest.so",RTLD_NOW);

  void (*init_)() = (void (*)())dlsym(handle, "init_");
  init_();

  double x=0,y=0;
  void (*eval_)(double x, double z) = (void (*)())dlsym(handle, "eval_");      
  eval_(x, y);

  dlclose(handle);
  handle = dlopen("./dltest.so",RTLD_NOW);

  eval_ = (void (*)())dlsym(handle, "eval_");
  eval_(x, y);

  return 0;

}

And run:

> gfortran -shared -fPIC -o dltest.so dltest.f90
> gcc -ggdb  dltest.c -ldl
> ./a.out 
 init_
 success
ERROR STOP not allocated!

此后不再分配数组dlclose() and dlopen()。您必须确保 R 不会从内存中卸载该库。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

作为共享库加载时,Fortran 模块可分配数组何时超出范围? 的相关文章

  • 指定 R 中 hist() 中的 bin 数量?

    我尝试指定垃圾箱的数量hist R为10 如下 gt hist x breaks 10 但垃圾箱的数量并不完全是 10 我尝试了几个其他数量的垃圾箱 结果发生了同样的情况 hist says breaks可以指定 给出直方图单元格数量的单个
  • 如何调整ggplot直方图的时间刻度轴

    我正在使用一个数据框 其中一列包含POSIXct日期时间值 我正在尝试使用绘制这些时间戳的直方图ggplot2但我有两个问题 我不知道如何设置 binwidthgeom histogram 我想将每个垃圾箱设置为一天或一周 我尝试提供 di
  • 用于清除工作空间和转储存储的 R 全局函数

    我希望创建一个全局函数来清除我的工作区并转储我的内存 我将我的函数称为 cleaner 并希望它执行以下代码 remove list ls gc 我尝试在全局环境中创建该函数 但是当我运行它时 控制台仅打印该函数的文本 在我要获取的函数文件
  • Fortran 读取语句中的“end”是什么意思?

    什么是end 这段代码片段的意思是什么 read portNum 100 end 900 readline 附 我已经尝试用谷歌找到这个 但没有运气 用户3600286 直接引用自this pdf http www tomzap com n
  • 查找数据帧列表中同一列中的所有重复值并将其转换为 NULL

    我有一个清单BELGIAN COAST list包含数百个数据帧 df1 df2 15 列 X 1000 行 每个数据帧的最后一列称为Chemicals并包含一些字符 例如Sulfate or Ammonia 但是这一列有很多行Chemic
  • 如何获得属于五分位数的x?

    我正在大学学习使用 R 进行计量经济学项目 所以请原谅我的笨拙 基本上 使用并给出 一个矩阵 股票价格 行 天 列 公司股票价格 另一个矩阵 市值 行 天 列 公司市值 我必须收集第三个矩阵每天观察的属于市值分布第一五分位数的股票价格 然后
  • 从 R 环境中删除对象

    我正在阅读 Hadley 的 Advanced R 在第 8 章中 他说我们可以使用以下方法从环境中删除对象 rm 但是 移除该物体后我仍然可以看到该物体 这是我的代码 e lt new env e a lt 1 e b lt 2 e a
  • 将 VLMC 拟合到很长的序列

    我正在尝试将 VLMC 拟合到最长序列为 296 个状态的数据集 我这样做如下所示 Load libraries library PST library RCurl library TraMineR Load and transform d
  • 在另一个 Rmd 中运行选定的块

    我已经在源 Rmd 文件中运行了分析 并且希望仅使用few来自源的块 我已经看到了一些关于从源 Rmd 中提取所有块的答案来自另一个 Rmd 中的 Rmd 文件的源代码 https stackoverflow com questions 4
  • 将 sf voronoi 多边形裁剪到边界框时出错

    我正在尝试将 voronoi polygons 使用 sf package 创建 剪辑 到边界框 但它引发了我无法定义的错误 我对 R 的空间世界不太有经验 感谢所有帮助 样本数据 stations lt structure list ST
  • 如何在数据部分(RAM)中保留一定范围的内存并防止同一应用程序使用该内存的堆/堆栈?

    我想在 RAM 中保留 分配一定范围的内存 并且同一应用程序不应覆盖或使用该范围的内存进行堆 堆栈存储 如何在内存中分配一定范围的内存以防止堆栈 堆覆盖 我考虑过向应用程序本身添加 或分配 一个数组并保留内存 但它被编译器优化了 因为它在应
  • R 更改小数位且不四舍五入

    gt signif 1 89 digits 2 1 1 9 我想要1 8 这有点笨拙 但它会起作用并保持所有数字 x lt 1 829380 trunc dec lt function x n floor x 10 n 10 n Resul
  • 解析,用三点参数替换

    让我们考虑一个典型的deparse substitute R call f1 lt function u x y print deparse substitute x varU vu varX vx varY vy f1 u varU x
  • 比较 R 中的两个字符向量

    我有两个 ID 字符向量 我想比较这两个字符向量 特别是我对以下数字感兴趣 A和B各有多少个ID 有多少个ID在A中但不在B中 有多少个ID在B但不在A 我还想画维恩图 以下是一些可以尝试的基础知识 gt A c Dog Cat Mouse
  • r 中的 5 维图

    我正在尝试在 R 中绘制 5 维图 我目前正在使用rgl包以 4 个维度绘制数据 使用 3 个变量作为 x y z 坐标 另一个变量作为颜色 我想知道是否可以使用这个包添加第五个变量 例如空间中点的大小或形状 这是我的数据和当前代码的示例
  • 如何计算嵌套函数中的粘合表达式?

    我正在尝试嵌套一个函数 该函数将两个字符串粘合在一起 该函数使用组合字符串来命名数据帧的列 然而 问题似乎是粘合表达式没有足够早地评估为字符串 我可以 并且应该 强制在将表达式作为参数传递给另一个函数之前对其进行求值吗 library ti
  • 如何在R中同时对三个字段进行网络分析

    如何在 R 中同时对三个字段进行网络分析 下面是示例数据以及desired output在最后一栏中 df lt data frame stringsAsFactors FALSE id 1 c ABC ABC BCD CDE DEF EF
  • 16 位以上整数的计算

    我有两个大整数 两者都超过 16 位 确切地说是 20 位 而且我知道由于双精度浮点运算 我在使用这些数字进行计算甚至将它们存储在变量中 独立于编程语言 时受到限制 不过 我想也许gmp图书馆应该处理它们 但不幸的是它没有 可以计算更大的整
  • 使用自定义堆的类似 malloc 的函数

    如果我希望使用自定义预分配堆构造类似 malloc 的功能 那么 C 中最好的方法是什么 我的具体问题是 我有一个可映射 类似内存 的设备 已将其放入我的地址空间中 但我需要获得一种更灵活的方式来使用该内存来存储将随着时间的推移分配和释放的
  • 如何将 ggrough 图表另存为 .png

    说我正在使用R包裹ggrough https xvrdm github io ggrough https xvrdm github io ggrough 我有这个代码 取自该网页 library ggplot2 library ggroug

随机推荐