在Fortran中为Lapack使用显式接口:链接在查找模块文件时失败



问题

为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例程和containssubroutine 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

这是因为预定义的常数INT64REAL64已经表示秩,而辅助函数selected_*_kind期望给定有效小数位数。

其次,您的接口没有指定参数LDVT

第三,也是最重要的一点,您将DGESVD声明为module subroutine,这样您就可以说子例程位于当前模块中。但事实并非如此。Lapack子程序不在任何模块中。因此,您需要从接口定义中省略module关键字。

注意:如果数据类型kindArpip是在同一个模块中定义的,那么在从接口声明中删除module关键字后,您还需要添加行

import kindA, ip, rp

就在原型线subroutine DGESVD (...下方

最新更新