【问题标题】:Trouble with Intel MKL libraries: segfault / unresolved external symbol英特尔 MKL 库的问题:segfault / unresolved external symbol
【发布时间】:2019-07-19 11:21:41
【问题描述】:

我正在编译一些尝试使用英特尔 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 例程。根据文档,我应该用heev 替换zheev。所以我试过了,但后来我得到了错误

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

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

【问题讨论】:

  • 您是否指定了任何额外的链接库,或者您只是使用/mkl
  • @francescalus,我只是在项目属性中启用了“使用 MKL 库”选项,这是我使用 VSL 和 DFT 例程时所必需的。
  • 你用的是什么编译器?

标签: fortran intel-fortran intel-mkl


【解决方案1】:

解决方案是显式链接 Lapack95 库,它不是简单地与 -mkl 标志链接。例如,在使用英特尔 Fortran 编译器编译的 4 字节整数的 64 位 Windows 上,使用

ifort /Qmkl heev_test.f90 mkl_lapack95_lp64.lib

至于 seg 故障,我错误地调用了 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 库,上面的子程序本质上相当于方阵的 f95 接口并且可以很容易地修改。有关变量的定义,请参阅文档。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-22
    • 1970-01-01
    • 2018-02-21
    • 2016-09-26
    • 2019-11-19
    • 2022-07-06
    • 2017-03-30
    • 2017-10-20
    相关资源
    最近更新 更多