繁体   English   中英

gfortran SIGABRT 错误:来自 lapack 的 zgesvd function

[英]gfortran SIGABRT error: the zgesvd function from lapack

我正在编写一个 fortran 90 子程序,它调用 lapack function zgesvd。 不幸的是,我收到了这个错误:

    malloc(): corrupted top size
    Program received signal SIGABRT: Process abort signal.
    Backtrace for this error:
    #0  0x7f338321cd21 in ???
    #1  0x7f338321bef5 in ???
    #2  0x7f3382f0120f in ???
    #3  0x7f3382f0118b in ???
    #4  0x7f3382ee0858 in ???
    #5  0x7f3382f4b3ed in ???
    #6  0x7f3382f5347b in ???
    #7  0x7f3382f56839 in ???
    #8  0x7f3382f58418 in ???
    #9  0x560e60a94daf in ???
    #10  0x560e60a94b75 in ???
    #11  0x560e60a94bae in ???
    #12  0x7f3382ee20b2 in ???
    #13  0x560e60a9420d in ???
    #14  0xffffffffffffffff in ???
    Aborted (core dumped)

包含子例程的最小代码如下所示。 由于 Lapack 调用相当详细,因此包含每个参数的详细信息必须有点冗长,对此我深表歉意:

module my_mod
    IMPLICIT NONE

    CONTAINS
    subroutine svd_gc(A,u,s,vt,info)
        integer, parameter :: pr = SELECTED_REAL_KIND(15,3)
        complex(pr), dimension (:,:), intent(in)  :: A
        integer :: M, N
        
        integer :: lda, ldu, ldvt

        real(pr), dimension (min(SIZE(A,1),SIZE(A,2))) :: s
        complex(pr), dimension (SIZE(A,1),SIZE(A,1)) :: u
        complex(pr), dimension (SIZE(A,2),SIZE(A,2)) :: vt
        integer lwork
        complex(pr), dimension (1) :: work1
        real, dimension (5*min(SIZE(A,1),SIZE(A,2))) :: rwork
        integer :: info
        complex(pr), allocatable, dimension(:) :: work2
        
        external zgesvd

        M = SIZE(A,1)
        N = SIZE(A,2)
        lda = M
        ldu = M
        ldvt = N

        ! initialization step
        call zgesvd('All', 'All', M, N, A, lda, s, u, ldu, vt, ldvt, work1, -1, rwork, info )
        lwork = min(1000, int( work1(1) ))
        allocate( work2(lwork) )

        call zgesvd('All', 'All', M, N, A, lda, s, u, ldu, vt, ldvt, work2, lwork, rwork, info )

    end subroutine svd_gc
end module my_mod

这里称为:

program main
    use my_mod

    implicit none
    
    integer, parameter :: pr = SELECTED_REAL_KIND(15,3)
    real(pr), dimension (5,3) :: MR, MI
    complex(pr), dimension (5,3) :: M

    complex(pr), dimension(5,5) :: u
    complex(pr), dimension(3,3) :: vt
    real(pr), dimension(3) :: s
    integer i, j, info
    
    call random_vec(5,3,MR) ! generates an array of real numbers
    call random_vec(5,3,MI)
    
    M = cmplx(MR,MI)
    
    call svd_gc(M,u,s,vt,info)

    do j=1,3
        print '("---------")'
        print*,s(j)
        
        do i=1,3
            print*,vt(i,j)
        end do
        
        print '(" ")'
    end do

end program main

我用 gfortran 编译...最终运行生成的文件

不幸的是,这个调用返回了一个 SIGABRT 错误,所以我找到了一个 zgesvd 调用的工作示例,我从英特尔网站上拿了一个: https://www.intel.com/content/www/us/en/develop/documentation/onemkl- lapack-examples/top/最小二乘和特征值问题/奇异值分解/gesvd-function/zgesvd-example/zgesvd-example-fortran.html

基本上你不需要work2,你将work1的大小设置为1000,然后调用:

    call zgesvd('All', 'All', M, N, A, lda, s, u, ldu, vt, ldvt, work1, -1, rwork, info )
    lwork = min(1000, int( work1(1) ))

    call zgesvd('All', 'All', M, N, A, lda, s, u, ldu, vt, ldvt, work1, lwork, rwork, info )

好的,谢谢英特尔!

但是现在,如果我敢在任何调用我的 zgesvd 子例程 (svd_gc) 的代码中使用“分配”命令,那么我会再次收到 SIGABRT 错误。 我想知道,我做错了什么? 还是 zgesvd function 仍然不稳定,可能是一些“free()”调用放错地方或定义不正确? 您是否看到任何更正或解决方法? 也许另一个 Fortran 库?

我看到了一个非常相似的线程: gfortran error: zgesvd in lapack然而,我没有使用这种“USV”类型定义,所以我认为它不相关

提前致谢!

编辑:在此编辑中,我确实将“双重”分配“REAL*8”更改为另一个我希望更干净的分配。 另外,我为调用子程序的主程序添加了最少的代码!

好的,由于 Ian Bush 对“rwork”变量的评论,我得到了错误。 'rwork' 必须是双精度的,因为它在此处的原型中说明: http://www.netlib.org/lapack/explore-html/d3/da8/group__complex16_g_esing_gad6f0c85f3cca2968e1ef901d2b6014ee.ZFC35FDC8EAD226C72639

因此,替换: real, dimension (5*min(SIZE(A,1),SIZE(A,2))):: rwork
by: real(pr), dimension (5*min(SIZE(A,1),SIZE(A,2))):: rwork
似乎解决了这个问题。 感谢您的建设性意见和批评,它有助于改进!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM