LAPACK:ZHEEV常规失败的大型矩阵

时间:2018-03-30 22:54:48

标签: fortran fortran90 lapack intel-fortran intel-mkl

我有一个Fortran 90代码,它在块对角化后找到自旋链哈密顿量的特征值。我生成了每个块的对角化,这似乎工作得很好,直到块的大小变得太大,此时我得到了错误。

spinchain.exe中的0x05E8A247(mkl_avx2.dll)抛出异常:0xC0000005:访问冲突写入位置0x054E8000。

我在Visual Studio 2017中使用带有MKL库的Intel Fortran编译器。从我可以看出,当块矩阵的顺序大于60时,我得到此错误。在Release模式下运行(而不是Debug),代码将一直运行而没有任何抱怨,但我认为输出不正确。

我写了一个简短的代码来创建一个N x N埃尔米特矩阵并通过zheev例程运行它。为简单起见,我选择了所有1的矩阵,它具有N-1个零特征值和单个特征值N.我只是循环遍历N的值,生成矩阵并用zheev()对角化,打印N,最大特征值,以及所有特征值的总和。我发现一切都很好,直到N = 51,此时最大特征值返回52然后当我尝试使用错误Critical error detected c0000374解除分配数组时,我得到一个异常。

点击“继续”,异常变为

Eigtest.exe中0x77A5A879(ntdll.dll)的未处理异常:0xC0000374:堆已损坏(参数:0x77A95910)。

以下代码:

program Eigenvalues
    implicit none
    integer, parameter :: dp = kind(0.d0)
    integer :: N, lwork, info, i
    real(dp), allocatable :: lambda(:), work(:), rwork(:)
    complex(dp), allocatable :: H(:,:)

    do N = 1,70

        lwork = 3*N
        allocate(H(N,N))
        allocate(lambda(N))
        allocate(work(lwork))
        allocate(rwork(lwork))

        H = dcmplx(1.0_dp,0)

        call zheev('N','U',N,H,N,lambda,work,lwork,rwork,info)

        if (info == 0) then
                write(*,'(I5, F16.12, F16.12)'), N, lambda(N), sum(lambda)
        else
            print*, "diagonalization failed: info = ", info
            read*, i
            stop
        end if

        deallocate(H,lambda,work,rwork)

    end do

    read*, i

end program

我还编写了另一个版本的代码,我将N作为参数在开头修改并定义了没有allocatable的数组,它将在没有任何异常的情况下运行,但为N =提供了错误的特征值51和大多数值高于N = 51。

请原谅我,如果我的代码不好,我是物理学家,而不是程序员。意见或建议表示赞赏。

1 个答案:

答案 0 :(得分:1)

根据zheev的手册页,数组work预计为complex*16,因此我们可能需要类似

的内容
real(dp), allocatable :: lambda(:), rwork(:)
complex(dp), allocatable :: H(:,:), work(:)

(这似乎与我的电脑上的gfortran一起工​​作)。