2014-05-17 62 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手冊的「內部模塊」一章中。