Best/Preferred way to pass arrays in (modern) Fortran
by mostlyharmless from LinuxQuestions.org on (#5DHEG)
So, Lapack guidelines (http://www.netlib.org/lapack-dev/lap...e.html#fortran) say the following
Code:Do not use assumed-shape arrays in interfaces
Assumed-shape argument arrays, those defined like
REAL A(:,:)
add information to the low-level arguments passed into the routine, complicating language interoperability. Additionally, passing arrays as assumed-shape arguments may impose performance and memory costs. The F95 wrappers may use assumed arrays in the style of LAPACK95 [lapack95], as opposed to LAPACK3E [lapack3e].On the other hand, https://www.fortran90.org/src/best-practices.html (sounds reputable right?) states this:
Code:
When passing arrays in and out of a subroutine/function, use the following pattern for 1D arrays (it is called assumed-shape):
subroutine f(r)
real(dp), intent(out) :: r(:)
integer :: n, i
n = size(r)
do i = 1, n
r(i) = 1.0_dp / i**2
enddo
end subroutine
2D arrays:
subroutine g(A)
real(dp), intent(in) :: A(:, :)
...
end subroutine
and call it like this:
real(dp) :: r(5)
call f(r)
No array copying is done above. It has the following advantages:
the shape and size of the array is passed in automatically
the shape is checked at compile time, the size optionally at runtime
allows to use strides and all kinds of array arithmetic without actually copying any data.
This should always be your default way of passing arrays in and out of subroutines. However in the following cases one can (or has to) use explicit-shape arrays:
returning an array from a function
interfacing with C code or legacy Fortran (like Lapack)
operating on arbitrary shape array with the given function (however there are also other ways to do that, see Element-wise Operations on Arrays Using Subroutines/Functions for more information)Two questions arise to me:
(1) Is the Sca/Lapack program style old fashioned or actually more efficient? Or am I entirely missing the point?
(2) Does anyone (else) have an opinion on the Preferred Way?
I'm partial to the Sca/Lapack guidelines. I'd like my code to be efficient without extra copying of arrays, naturally I'd like to use lapack&blas as needed - why re-invent the wheel?- and it seems interfacing with other languages (eg C) might be useful occasionally too. I've got nothing against assumed shape arrays, slices and even allocatable arrays: they're great, but not for argument passing according to lapack guidelines.
I guess it comes down to the validity, or lack thereof, of this sentence:
Quote:
If so, why does fortran90.org recommend that as the default?


Code:Do not use assumed-shape arrays in interfaces
Assumed-shape argument arrays, those defined like
REAL A(:,:)
add information to the low-level arguments passed into the routine, complicating language interoperability. Additionally, passing arrays as assumed-shape arguments may impose performance and memory costs. The F95 wrappers may use assumed arrays in the style of LAPACK95 [lapack95], as opposed to LAPACK3E [lapack3e].On the other hand, https://www.fortran90.org/src/best-practices.html (sounds reputable right?) states this:
Code:
When passing arrays in and out of a subroutine/function, use the following pattern for 1D arrays (it is called assumed-shape):
subroutine f(r)
real(dp), intent(out) :: r(:)
integer :: n, i
n = size(r)
do i = 1, n
r(i) = 1.0_dp / i**2
enddo
end subroutine
2D arrays:
subroutine g(A)
real(dp), intent(in) :: A(:, :)
...
end subroutine
and call it like this:
real(dp) :: r(5)
call f(r)
No array copying is done above. It has the following advantages:
the shape and size of the array is passed in automatically
the shape is checked at compile time, the size optionally at runtime
allows to use strides and all kinds of array arithmetic without actually copying any data.
This should always be your default way of passing arrays in and out of subroutines. However in the following cases one can (or has to) use explicit-shape arrays:
returning an array from a function
interfacing with C code or legacy Fortran (like Lapack)
operating on arbitrary shape array with the given function (however there are also other ways to do that, see Element-wise Operations on Arrays Using Subroutines/Functions for more information)Two questions arise to me:
(1) Is the Sca/Lapack program style old fashioned or actually more efficient? Or am I entirely missing the point?
(2) Does anyone (else) have an opinion on the Preferred Way?
I'm partial to the Sca/Lapack guidelines. I'd like my code to be efficient without extra copying of arrays, naturally I'd like to use lapack&blas as needed - why re-invent the wheel?- and it seems interfacing with other languages (eg C) might be useful occasionally too. I've got nothing against assumed shape arrays, slices and even allocatable arrays: they're great, but not for argument passing according to lapack guidelines.
I guess it comes down to the validity, or lack thereof, of this sentence:
Quote:
Additionally, passing arrays as assumed-shape arguments may impose performance and memory costs |