Массивы переменного размера в Fortran без Allocate () - PullRequest
12 голосов
/ 08 июля 2011

Есть ли способ создать массивы переменного размера в Fortran в стеке ? Allocate () не работает для меня, потому что он помещает массив в кучу. Это может привести к проблемам с распараллеливанием (см. Мой другой вопрос: OpenMP: низкая производительность массивов кучи (массивы стека работают нормально) ). Конечно, некоторое умное управление памятью могло бы обойти эту проблему, но управление памятью в Фортране звучит глупо.

По сути, я ищу фортрановский эквивалент следующего в C:

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

Чтобы повторить: я не хочу

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

потому что это определяет размер массива во время компиляции. Я тоже не хочу

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

потому что он помещает массив в кучу.

Помощь очень ценится. Я был очень счастлив с Allocatable массивами до моей недавней встречи с проблемой в вопросе, упомянутом выше. Если на этот вопрос будет отрицательный ответ, я был бы очень признателен за ссылку на источник.

Редактировать: см. Комментарии к ответу М.С.Б. Элегантный способ сделать это стало возможным только в Fortran 2008, и это сделано в конструкции block.

Ответы [ 2 ]

12 голосов
/ 08 июля 2011

Fortran может автоматически создавать массивы только с объявлениями о входе в подпрограммы, если измерения известны во время выполнения ... это не требует, чтобы измерения объявлялись как атрибут параметра, они могут быть аргументами, например,

subroutine MySub ( N )

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

действительно.Так почему бы не определить свой размер «N» в основной программе или какой-либо подпрограмме, а затем вызвать другую подпрограмму, чтобы продолжить.Вероятно, при таком подходе массив будет в стеке.Как писал @eriktous, стандарт языка Фортран не определяет это поведение.Некоторые компиляторы переключают локальные массивы в кучу после определенного размера.Некоторые компиляторы предоставляют опции для управления этим поведением.Размещение больших массивов в куче, вероятно, будет переопределено с помощью рекурсии или OpenMP.

Вы также можете передать выделяемый массив в качестве фактического аргумента подпрограмме без фиктивного аргумента подпрограммы, объявленной как выделяемая.Что может не помочь вам, потому что исходный массив все еще будет в куче.

6 голосов
/ 08 июля 2011

Стандарт Fortran не имеет понятия стека и кучи, поэтому это будет зависеть от реализации (то есть компилятора). Глядя на документы, например, гфортран, есть опция

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

Другие компиляторы могут иметь аналогичные параметры. Возможно, это делает то, что вы хотите.

...