Массивы с переменными размерами в 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
.
Ответы
Ответ 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.
Другие компиляторы могут иметь аналогичные варианты. Возможно, это делает то, что вы хотите.