Массивы и подпрограммы Фортрана (подмассивы) - PullRequest
4 голосов
/ 22 марта 2010

Я прохожу код на Фортране, и меня немного озадачило.

Есть подпрограмма, скажем

SUBROUTINE SSUB(X,...)
REAL*8 X(0:N1,1:N2,0:N3-1),...
...
RETURN 
END

Который вызывается в другой подпрограмме:

CALL SSUB(W(0,1,0,1),...)

где W - «рабочий массив». Похоже, что конкретное значение из W передается X, однако X измеряется как массив. Что происходит?

Ответы [ 3 ]

7 голосов
/ 22 марта 2010

Это необычная идиома для получения подпрограммы для работы с (прямоугольником в N-измерениях) исходного массива.

Все параметры в Fortran (по крайней мере, до Fortran 90) передаются по ссылке, поэтому фактический аргумент массива разрешается как место в памяти. Выберите местоположение внутри пространства, выделенного для всего массива, и подпрограмма обрабатывает только часть массива.

Самая большая проблема: Вы должны знать, как массив размещается в памяти и как работает схема индексации массивов Фортрана. Fortran использует упорядочение основного массива столбцов, которое противоположно c. Рассмотрим массив размером 5x5 (и индексируйте в обоих направлениях от 0, чтобы упростить сравнение с c). В обоих языках 0,0 является первым элементом в памяти. В c следующим элементом в памяти является [0][1], но в Фортране это (1,0). Это влияет на то, какие индексы вы отбрасываете при выборе подпространства: если исходный массив A (i, j, k, l), а подпрограмма работает в трехмерном подпространстве (как в вашем примере), в c она работает на Aprime[i=constant][j][k][l], но в Фортране работает на Aprime(i,j,k,l=constant).

Другой риск заключается в обертывании. Размеры (под) массива в подпрограмме должны совпадать с размерами в вызывающей подпрограмме, иначе произойдут странные, странные вещи (подумайте об этом). Так что, если A объявлен с размером (0: 4,0: 5,0: 6,0: 7), и мы вызываем с элементом A(0,1,0,1), подпрограмма получения может свободно запускать индекс каждого измерения там, где ему нравится , но должны сделать размеры (4,5,6) или иначе; но это означает, что последний элемент в направлении j фактически оборачивается! Что нужно сделать, это , а не использовать последний элемент. Убедиться в том, что это произойдет, - дело программистов, и это неприятно. Береги себя. Много забот.

2 голосов
/ 23 марта 2010

Это называется "связью последовательности". В этом случае то, что кажется масштабатором, элементом массива (фактический аргумент в вызывающей стороне) связан с массивом (неявно первым элементом), фиктивным аргументом в подпрограмме. После этого элементы массивов связываются по порядку хранения, известному как «последовательность». Это было сделано в Fortran 77 и ранее по разным причинам, здесь, по-видимому, для массива рабочей области - возможно, программист делал свое собственное управление памятью. Это сохраняется в Fortran> = 90 для обратной совместимости, но IMO не входит в новый код.

2 голосов
/ 22 марта 2010

в фортране переменные передаются по адресу. Так что W(0,1,0,1) - это значение и адрес. так что в основном вы передаете subarray начиная с W(0,1,0,1).

...