Подтвердить что ты не робот

Массивы с переменными размерами в Fortran без выделения()

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

По существу, я ищу эквивалент Fortran следующего в 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 массивами до моей недавней встречи с проблемой в упомянутом выше вопросе. Если есть отрицательный ответ на этот вопрос, я очень ценю ссылку на источник.

Изменить: см. комментарии к M.S.B. ответ. Элегантный способ сделать это стал возможен только в Fortran 2008, и это делается в конструкции block.

4b9b3361

Ответ 1

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

subroutine MySub ( N )

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

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

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

Ответ 2

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

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

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