问题
为Lapack添加外部接口后,代码在与消息链接时失败
Undefined symbols for architecture x86_64:
"___msolutionsvd_MOD_dgesvd", referenced from:
___msolutionsvd_MOD_svd_pseudoinverse_solve_sub in m-solution-svd.o
链接器似乎正在查找一个DGESVD.mod
文件,该文件未包含在我的openblas
安装中。
代码
这是有效的
模块module mSolutionSVD
使用声明
external DGESVD
指向BLAS例程和contains
subroutine svd_pseudoinverse_solve_sub
其调用CCD_ 7。
此操作失败
声明已替换为显式接口
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
背景
种类声明来源于具有以下声明的例程:
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 )
问题
我们可以在不重新编译Lapack的情况下为Lapack使用外部接口吗?
您的代码有三个问题,其中两个与您的问题无关。
首先,数据类型的定义应该是
use, intrinsic :: iso_fortran_env, only : INT64, REAL64
integer, parameter :: kindA = kind ( 'A' )
integer, parameter :: rp = REAL64
integer, parameter :: ip = INT64
这是因为预定义的常数INT64
和REAL64
已经表示秩,而辅助函数selected_*_kind
期望给定有效小数位数。
其次,您的接口没有指定参数LDVT
。
第三,也是最重要的一点,您将DGESVD
声明为module subroutine
,这样您就可以说子例程位于当前模块中。但事实并非如此。Lapack子程序不在任何模块中。因此,您需要从接口定义中省略module
关键字。
注意:如果数据类型kindA
、rp
和ip
是在同一个模块中定义的,那么在从接口声明中删除module
关键字后,您还需要添加行
import kindA, ip, rp
就在原型线subroutine DGESVD (...
下方