英特尔MKL库问题:segfault /未解析的外部符号

时间:2019-07-16 21:49:46

标签: fortran intel-fortran intel-mkl

我正在编译一些代码,以尝试使用英特尔MKL库特征解析器。我已经在使用VSL RNG和DFT库了,没有问题。我正在安装Intel Parallel Studio XE的情况下在Visual Studio中编译和运行所有内容。我确保在项目属性中启用了mkl标志。

include 'lapack.f90'
program heev_test
    use lapack95
    implicit none
    integer , parameter :: dp = kind(0.0d0)
    complex(dp) :: matrix(4,4)
    real(dp) :: eigs(4)
    matrix = (1.0_dp,0.0_dp)
    call zheev(matrix, eigs)
    print*, eigs
    read(*,*)
    stop  
end program

运行此代码会在我到目前为止已对其进行测试的两台计算机上产生段错误。我认为问题在于正在调用F77例程,该例程需要更多的参数(文档here)。我想使用简单得多的F95例程。根据文档,我应该将zheev替换为heev。所以我尝试了,但是然后我得到了错误

fatal error LNK1120: 1 unresolved externals 
error LNK2019: unresolved external symbol _ZHEEV_F95 referenced in function _MAIN__         

ZHEEV_F95具有在lapack.f90文件中定义的接口。

我现在唯一的另一件事是文档说我也应该包含mkl.fi,但是这样做会出现以下编译错误

Error       error #6218: This statement is positioned incorrectly and/or has syntax errors.     C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2018\windows\\mkl\include\lapack.f90    21  
Error       error #6790: This is an invalid statement; an END [PROGRAM]  statement is required.     C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2018\windows\\mkl\include\lapack.f90    24  
Error       error #6785: This name does not match the unit name.   [F95_PRECISION]      C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2018\windows\\mkl\include\lapack.f90    24  
Error       Compilation Aborted (code 1)        
Warning     warning #5427: Program may contain only one main entry routine

参考lapack.f90文件中的这些行:

21  MODULE F95_PRECISION
22      INTEGER, PARAMETER :: SP = KIND(1.0E0)
23      INTEGER, PARAMETER :: DP = KIND(1.0D0)
24  END MODULE F95_PRECISION

1 个答案:

答案 0 :(得分:0)

解决方案是显式链接Lapack95库,而不仅仅是与-mkl标志链接。例如,在使用Intel Fortran编译器编译的具有4个字节整数的Windows 64位上,使用

ifort /Qmkl heev_test.f90 mkl_lapack95_lp64.lib

对于段错误,我不正确地调用了F77例程。由于我没有为这些例程提供接口,因此编译器没有抱怨,当我调用它们时,由于没有正确输入参数而导致了分段错误。

这是可以正确调用两个例程的代码,可以进行验证以产生相同的结果。

include 'lapack.f90'
program heev_test
    use lapack95
    implicit none
    integer , parameter :: dp = kind(0.0d0)
    complex(dp) :: matrix(4,4)
    real(dp) :: eigs(4)
    matrix = (1.0_dp,0.0_dp)
    print*, "checking eigenvalues using zheevr"
    call eigenvalues(matrix,eigs)
    print*, eigs
    matrix = (1.0_dp,0.0_dp)
    print*, "checking eigenvalues using heevr"
    call heevr(matrix,eigs)
    print*, eigs
    read(*,*)
    stop  

contains

    subroutine eigenvalues(a,w)
        complex(dp) :: a(:,:)
        real(dp)    :: w(:)
        character*1 :: jobz, range, uplo
        integer     :: n, m, lda, il, iu, ldz
        real(dp)    :: vl, vu, abstol
        integer     :: info
        integer     :: lwork, liwork, lrwork
        complex(dp) , allocatable :: z(:,:)
        complex(dp) , allocatable :: work(:)
        real(dp)    , allocatable :: rwork(:)
        integer     , allocatable :: iwork(:)
        integer     , allocatable :: isuppz(:)

        jobz  = 'N'
        range = 'A'
        uplo  = 'U'
        n = size(a,dim=1)
        lda = max(1,n)
        vl = -huge(vl)
        vu = +huge(vl)
        il = 1
        iu = n
        abstol = 0.0_dp
        ldz = max(1,n)
        lwork = max(1,2*n)
        lrwork = max(1,24*n)
        liwork = max(1,10*n)
        allocate(work(lwork))
        allocate(rwork(lrwork))
        allocate(iwork(liwork))
        allocate(z(ldz,max(1,n)))
        allocate(isuppz(2*max(1,n)))
        lwork = -1
        liwork = -1
        lrwork = -1     

        call zheevr(jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, &
            &       z, ldz, isuppz, work, lwork, rwork, lrwork, iwork, liwork, info) 

        lwork = work(1)
        liwork = iwork(1)
        lrwork = rwork(1)
        deallocate(work,iwork,rwork)        
        allocate(work(lwork))
        allocate(iwork(liwork))
        allocate(rwork(lrwork))

        call zheevr(jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, &
            &       z, ldz, isuppz, work, lwork, rwork, lrwork, iwork, liwork, info)  

        deallocate(work,iwork,rwork)

        if (info /= 0) then
            print*, "diagonalization failed, info = ", info
            read(*,*)
            stop
        end if

    end subroutine
end program

就我而言,f95库未安装在目标计算机(远程集群)上,因此我不得不依靠f77库,对于上面的子例程,f77库基本上等效于方阵的f95接口并且可以轻松修改。有关变量的定义,请参见文档。

请注意,根据文档,heevr / zheevr是比heev / zheev更有效的例程,因此我将它们切换了。