0

Problem

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.

Code

This works

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.

This fails

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

Background

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 )

Question

Can we use an external interface for Lapack without having to recompile Lapack?

dantopa
  • 616
  • 7
  • 19

1 Answers1

1

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 (...

jacob
  • 1,535
  • 1
  • 11
  • 26