After adding an external interface for Lapack, the code fails during linking with the message
Undefined symbols for architecture x86_64:
"___msolutionsvd_MOD_dgesvd", referenced from:
___msolutionsvd_MOD_svd_pseudoinverse_solve_sub in m-solution-svd.o
It seems that the linker is looking for a DGESVD.mod file which is not included with my openblas installation.
The module module mSolutionSVD used the declaration
external DGESVD
to point to the BLAS routine and contains subroutine svd_pseudoinverse_solve_sub
which calls DGESVD.
The declaration was replaced with the explicit interface
interface lapack
module subroutine DGESVD ( JOBU, JOBVT, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK, LWORK, INFO )
character ( kind = kindA, len = 1 ), intent ( in ) :: JOBU, JOBVT
integer ( kind = ip ), intent ( in ) :: M, N, LDA, LDU, LWORK
integer ( kind = ip ), intent ( out ) :: INFO
real ( kind = rp ), intent ( out ) :: S ( : ), U ( : , : ), VT ( : , : ), WORK ( : )
real ( kind = rp ), intent ( inout ) :: A ( : , : )
end subroutine DGESVD
end interface lapack
The kind statements are sourced from a routine with these statements:
use, intrinsic :: iso_fortran_env, only : INT8, REAL64
integer, parameter :: kindA = kind ( 'A' )
integer, parameter :: rp = selected_real_kind ( REAL64 )
integer, parameter :: ip = selected_int_kind ( INT64 )
Can we use an external interface for Lapack without having to recompile Lapack?
There are three problems with your code, two of them not related to your question.
First, the definition of the data types should be
use, intrinsic :: iso_fortran_env, only : INT64, REAL64
integer, parameter :: kindA = kind ( 'A' )
integer, parameter :: rp = REAL64
integer, parameter :: ip = INT64
This is because the predefined constants INT64 and REAL64 already represent the ranks, while the auxiliary functions selected_*_kind expect to be given the number of valid decimal places.
Second, your interface does not specify the parameter LDVT.
Third, and most importantly, you declare DGESVD as a module subroutine, by which you say that the subroutine is located in the present module. But it is not. Lapack subroutines are not in any modules. So, you need to omit the module keyword from your interface definition.
Note: If the data types kindA, rp and ip are defined in the same module, then after removing the module keyword from the interface declaration you will also need to add the line
import kindA, ip, rp
just below the prototype line subroutine DGESVD (...