Arrays and Fortran routines (helper arrays)

I go through the Fortran code, and one bit is a bit puzzled.

There is a subroutine, say

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

which is called in another routine:

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

where W is the "working array". It seems like a certain value from W is passed to X, however X is measured as an array. What's happening?

+4
source share
3 answers

This is an abnormal idiom for a routine to work on a subset (rectangular in N dimensions) of the original array.

All parameters in Fortran (at least until Fortran 90) are passed by reference, so the actual argument of the array is resolved as a location in memory. Select a location inside the space allocated for the entire array, and the routine only controls part of the array.

The biggest problem: you need to know how the array fits in memory and how Fortran works with the array indexing scheme. Fortran uses the ordering of basic column arrays, which is the opposite of c. Consider an array of size 5x5 (and index both directions from 0 to simplify comparison with c). In both languages, 0.0 is the first element in memory. In c, the next element in memory is [0][1] , but in Fortran it is (1,0) . This affects what indexes you throw when choosing a subspace: if the original array is A (i, j, k, l), and the subroutine works on a three-dimensional subspace (as in your example), in c it works on Aprime[i=constant][j][k][l] , but in Fortran, works on Aprime(i,j,k,l=constant) .

Another risk turns around. The dimensions of the array (sub) in the subroutine must match the sizes in the calling procedure, or strange, strange things (think about it). Therefore, if A is declared the size (0: 4.0: 5.0: 6.0: 7), and we call it with the element A(0,1,0,1) , the receiving procedure can trigger the index of each measurement, where he ever likes, but has to make dimensions (4,5,6) or otherwise; but that means the last element in the j direction is really wrapping! The fact is, do not use the last element. To make sure that this happens is the work of programmers and the pain in the butt. Take care of yourself. A lot of care.

+7
source

in fortran, variables are passed to the address. So W(0,1,0,1) is the value and address. so basically you go through Subarray starting with W(0,1,0,1) .

+2
source

This is called a "sequence association." In this case, what seems to be scalable, the array element (the actual argument in the calling object) is associated with the array (implicitly the first element), the dummy argument in the subroutine. After that, the elements of the arrays are connected by the storage order, known as the "sequence". This was done in Fortran 77 and earlier for various reasons, here, apparently, for an array of the workspace - perhaps the programmer was engaged in his own memory management. This is saved in Fortran> = 90 for backward compatibility, but IMO is not included in the new code.

+2
source

Source: https://habr.com/ru/post/1304794/


All Articles