Fortran 中不带 Allocate() 的可变大小数组

发布于 2024-11-19 03:31:18 字数 820 浏览 5 评论 0原文

有没有办法在 Fortran 中在堆栈上创建可变大小的数组? Allocate() 对我不起作用,因为它将数组放在堆上。这可能会导致并行化问题(请参阅我的其他问题: OpenMP:堆数组的性能较差(堆栈数组可以工作)很好))。当然,一些智能内存管理可以解决这个问题,但 Fortran 中的内存管理听起来很愚蠢。

本质上,我正在寻找与 C 中的以下内容等效的 Fortran:

scanf("%d", N);
int myarray[N];

重申一下:我不想要,

Integer, PARAMETER :: N=100
Integer, Dimension(N) :: myarray

因为这决定了编译时的数组大小。我也不想要,

Integer, Dimension(:), Allocatable :: myarray
read(*,*) N
Allocate(myarray(1:N))

因为它将数组放在堆上。

非常感谢帮助。我对可分配数组非常满意,直到最近遇到上面引用的问题中的问题。如果这个问题的答案是否定的,我将非常感谢源链接。

编辑:请参阅 MSB 答案的评论。一种优雅的方法只有在 Fortran 2008 中才成为可能,并且是在 block 构造中完成的。

Is there a way to create variable size arrays in Fortran on the stack? Allocate() does not work for me, because it places the array on the heap. This may lead to problems with parallelization (see my other question:
OpenMP: poor performance of heap arrays (stack arrays work fine) ). Of course, some smart memory management would give a way around that problem, but memory management in Fortran sounds silly.

Essentially, I am looking for a Fortran equivalent of the following in C:

scanf("%d", N);
int myarray[N];

To re-iterate: I do NOT want

Integer, PARAMETER :: N=100
Integer, Dimension(N) :: myarray

because this determines the array size at compile time. Neither do I want

Integer, Dimension(:), Allocatable :: myarray
read(*,*) N
Allocate(myarray(1:N))

because it places the array on the heap.

Help very much appreciated. I was very happy with Allocatable arrays until my recent encounter with the problem in the question cited above. If there is a negative answer to this question, I would very much appreciate a link to the source.

Edit: see comments to M.S.B.'s answer. An elegant way of doing this only became possible in Fortran 2008, and it is done in a block construct.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一城柳絮吹成雪 2024-11-26 03:31:18

Fortran 可以自动创建数组,只需在子例程的入口处进行声明,只要在运行时已知维度...这不需要将维度声明为参数属性,它们可以是参数,例如,

subroutine MySub ( N )

integer, intent (in) :: N
real, dimension (N) :: array

是否有效。那么为什么不在主程序或某个子程序中决定你的大小“N”,然后调用另一个子程序继续。通过这种方法,数组可能会位于堆栈上。正如 @eriktous 所写,Fortran 语言标准没有指定这种行为。一些编译器将本地数组切换到超过一定大小的堆。一些编译器提供了控制此行为的选项。将大型数组放在堆上可能会被递归或 OpenMP 覆盖。

您还可以将可分配数组作为实际参数传递给子例程,而无需将子例程的虚拟参数声明为可分配。这可能对您的担忧没有帮助,因为原始数组仍然可能位于堆上。

Fortran can automatically create arrays just with declarations on entry to subroutines, as long as the the dimensions are known at run time ... this doesn't require the dimensions to be declared parameter attribute, they can be arguments, e.g.,

subroutine MySub ( N )

integer, intent (in) :: N
real, dimension (N) :: array

is valid. So why not decide your size "N" in the main program, or some subroutine, then call another subroutine to continue. Likely with this approach the array will be on the stack. As @eriktous wrote, the Fortran language standard doesn't specify this behavior. Some compilers switch local arrays to the heap past a certain size. Some compilers provide options to control this behavior. Placing large arrays on the heap would probably be overridden with recursive or OpenMP.

You can also pass an allocatable array as an actual argument to a subroutine without the dummy argument of the subroutine being declared as allocatable. Which may not help with your concern because the original array will still likely be on the heap.

尘世孤行 2024-11-26 03:31:18

Fortran 标准没有堆栈和堆的概念,因此这将取决于实现(即编译器)。查看例如 gfortran 的文档,它有一个选项

-frecursive
    Allow indirect recursion by forcing all local arrays to be allocated on the stack.

其他编译器可能有类似的选项。也许这就是你想要的。

The Fortran standard has no concept of stack and heap, so this will be implementation (i.e. compiler) dependent. Looking at the docs for e.g. gfortran, it has an option

-frecursive
    Allow indirect recursion by forcing all local arrays to be allocated on the stack.

Other compilers may have similar options. Perhaps this does what you want.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文