Problem:
Using an explicit interface for Lapack (http://www.netlib.org/lapack/) routines simplifies coding. There is a problem with routines like SGELS (https://www.netlib.org/lapack/explore-3.1.1-html/sgels.f.html) which require a WORK (https://www.netlib.org/lapack/lug/node117.html) array of variable size. Fixing the size of the WORK array to a large number is successful, but defeats the economy of Lapack.
But I am unable to use an allocatable array for WORK.
The usual error message is something like
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Fortran query routines on the WORK array such as shape, size, is_contiguous and bounds checking are successful. But any attempt to print a value from the array produces a segmentation fault.
After several permutations, here is a minimal working example of the code.
Code
Main program
program mwe
use mLapackInterfaceSGELS, only : sgels
implicit none
integer, parameter :: n = 2
real, dimension ( : ), allocatable :: work
real, dimension ( : , : ), allocatable :: AstarA, Astarb
integer :: nrhs = 0, lda = 0, ldb = 0, lwork = 0, info = 0
lda = n
ldb = n
nrhs = 1
lwork = -1
allocate ( Astarb ( 1 : n, 1 : 1 ) )
allocate ( AstarA ( 1 : n, 1 : n ) )
allocate ( work ( 1 : 2 ) )
Astarb ( 1 : n, 1 ) = [ 466.7, 2898.]
AstarA ( 1 : n, 1 : n ) = reshape ( [ [ 9., 45. ], [ 45., 285.] ], [ n, n ] )
work ( 1 : 2 ) = 0.0
write ( * , * ) "work array before query = ", work
call sgels( trans = 'No transpose', m = n, n = n, nrhs = nrhs, A = AstarA, lda = lda, b = Astarb, ldb = ldb, &
work = work, lwork = -1, info = info )
write ( * , * ) "out: shape ( work ) = ", shape ( work )
write ( * , * ) "lbound ( work ) = ", lbound ( work )
write ( * , * ) "ubound ( work ) = ", ubound ( work )
write ( * , * ) "size ( work ) = ", size ( work )
write ( * , * ) "is_contiguous ( work ) = ", is_contiguous ( work )
write ( * , * ) "work array after query = ", work
stop
end program mwe
Interface module
(As seen in Numerical Methods with Modern Fortran, Richard Hanson, Tim Hopkins, Listing 2.5. (https://my.siam.org/Store/Product/viewproduct/?ProductId=24372445))
module mLapackInterfaceSGELS
implicit none
interface lapack_sgels
subroutine sgels ( trans, m, n, nrhs, A, lda, b, ldb, work, lwork, info )
integer, intent ( in ) :: m, n, nrhs, lda, ldb, lwork
integer, intent ( out ) :: info
real, allocatable, intent ( out ) :: work ( : )
real, intent ( inout ) :: A ( 1 : lda , 1 : n ), b ( 1 : ldb , 1 : nrhs )
character, intent ( in ) :: trans
end subroutine sgels
end interface lapack_sgels
end module mLapackInterfaceSGELS
Output from code
The line which causes the error is:
write ( * , * ) "work array after query = ", work
The output from the code is:
work array before query = 0.00000000 0.00000000
out: shape ( work ) = 2
lbound ( work ) = 1
ubound ( work ) = 2
size ( work ) = 2
is_contiguous ( work ) = T
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Compiler version
% gcc --version (1c01947)fortran-alpha
gcc (Spack GCC) 10.2.0
Compilation
gfortran -g -c -Og -pedantic -Wall -Warray-temporaries -Wextra -Waliasing -Wsurprising -Wimplicit-procedure -Wintrinsics-std -Wfunction-elimination -Wc-binding-type -Wrealloc-lhs-all -Wuse-without-only -Wconversion-extra -fno-realloc-lhs -ffpe-trap=denormal,invalid,zero -fbacktrace -fmax-errors=5 -fcheck=all -fcheck=do -fcheck=pointer -fno-protect-parens -faggressive-function-elimination -fdiagnostics-color=auto -finit-derived -o m-lapack-interface-sgels.o m-lapack-interface-sgels.f08
gfortran -g -c -Og -pedantic -Wall -Warray-temporaries -Wextra -Waliasing -Wsurprising -Wimplicit-procedure -Wintrinsics-std -Wfunction-elimination -Wc-binding-type -Wrealloc-lhs-all -Wuse-without-only -Wconversion-extra -fno-realloc-lhs -ffpe-trap=denormal,invalid,zero -fbacktrace -fmax-errors=5 -fcheck=all -fcheck=do -fcheck=pointer -fno-protect-parens -faggressive-function-elimination -fdiagnostics-color=auto -finit-derived -o mwe.o mwe.f08
Execution
Two different Lapack libraries were used. Both produced the same failure.
/usr/local/lib
gfortran -g -L/usr/local/lib -llapack -lblas -o mwe m-lapack-interface-sgels.o mwe.o
Apple Accelerate framework
gfortran -g -framework Accelerate -o mwe m-lapack-interface-sgels.o mwe.o
Tip: Consider redirecting the output to avoid overrunning the screen buffer:
./mwe 2>&1 | tee output.txt
Question
How do I fix the interface and the call to allow the use of an allocatable WORK array?
Parameter corruption when interfacing FORTRAN lapack routine
real, allocatable, intent(out) :: work(:)in the interface block toreal, intent(out) :: work(*), does the result change? (I think if you attachallocatablein the dummy argument, the compiler will try to pass the address of an "array descriptor (= some internal metadata)" rather than the address of the actual data in the array) - roygvibsgelsto have an allocatable dummy argument you must modify its definition not some arbitrary interface block. Your interface should describe what the procedure is, not what you want it to be, and this holds for argumentsAandBalso. - francescalus