[英]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.