2014-05-17 53 views
3

我在做一个方阵A的SVD分解,其中A = US Vdag,并且在Fortran代码,行读取gfortran错误:zgesvd在LAPACK

lwork = -1 

call zgesvd('A', 'A', A%d, A%d, A%m, A%d, S, U%m, U%d, Vdag%m, Vdag%d,work, lwork, rwork, info) 

lwork = int(work(1));deallocate(work); allocate(work(lwork)) 

call zgesvd('A', 'A', A%d, A%d, A%m, A%d, S, U%m, U%d, Vdag%m, Vdag%d,work, lwork, rwork, info) 

当我与gfortran编译,它没有错误或警告经历。然而,当我运行程序,它会显示错误与消息:

“**在进入ZGESVD参数号11有一个非法值”

我无法弄清楚什么地方出了错。

仅供参考,参数的定义:

type cmatrix 
    integer(4) d 
    complex(8), allocatable :: m(:,:) 
end type 

type (cmatrix) A,U,Vdag 

allocate(A%m(dim,dim),U%m(dim,dim),Vdag%m(dim,dim)) 

A%d = dim; U%m = dim; Vdag%d = dim 

real(8) S(dim) 

提前感谢! Xiaoyu

p.s.应该指出的是,这样的程序在使用ifort编译时运行平稳,但gfortran给出了上面显示的运行时错误

---问题解决了!

似乎问题在于ifortran和gfortran如何分配内存。我在代码USV类型的定义:

type USV 
    integer is_alloc 
    type (cmatrix) U,V 
    real(8), allocatable :: S(:) 
end USV 

当由

type(USV) Test_usv(:) 

allocate(Test_usv(3)), 

初始化is_alloc的值是使用英特尔Fortran编译0,而任意数量为gfortran。我需要使用此值作为分配U V矩阵的标准:

if (is_alloc.eq.0) then 

    allocate(U%m(dim,dim)) 

end if 
+2

第11个参数是'Vdag%d'。我建议在每次通话前打印其价值。尝试使用gfortran调试选项:'-fimplicit-none -Wall -Wline-truncation -Wcharacter-truncation -Wsprising -Waliasing -Wimplicit-interface -Wunused-parameter -fcheck = all -fbacktrace' –

+0

你能告诉我们'S '? –

+0

谢谢你们! @ M.S.B .:第11个说法确实无效。我发现这是一个问题,因为使用intel fortran和gfortran分配内存的初始化方案不同。 – Rain

回答

1

ifif和gfortran之间的根本问题不是区别。您的变量初始化方法无效Fortran。除非用声明,赋值语句等初始化变量,否则其值不确定。解决这个问题的方法之一将是一个默认初始化添加到类型定义:

type USV 
    integer is_alloc = 0 
    type (cmatrix) U,V 
    real(8), allocatable :: S(:) 
end USV 

另一种方法是不要自己跟踪分配情况和依靠的是Fortran语言为此提供了内在的功能:

if (.NOT. allocated (U%m)) allocate(U%m(dim,dim)) 

PS最佳做法是不要依赖具体的数值。种类值是任意的,并不一定是该类型的字节数。一些编译器使用字节数,其他编译器则不使用。指定的字节数,并具有移植的代码的一种方法是使用由ISO Fortran语言环境所提供的类型:

use, intrinsic :: ISO_FORTRAN_ENV 

integer(int32) :: d 
real(real64), allocatable :: S(:) 

该类型的位数命名。可用类型列表位于gfortran手册的“内部模块”一章中。