2011-07-06 44 views
1

異なるサイズの行列の固有値と固有ベクトルを計算しようとしています。私は非常に単純なFortran90コードを使用しています。私はUbuntuで動作する私のマシンで利用可能なIntel MKLパッケージに含まれている適切なLapackライブラリにリンクしてコンパイルしています。コード "matrix_diag_01.f90"は、メッセージの最後に添付されています。 「ランダム」モジュールには、数値レシピからの乱数ジェネレータが含まれています。コードはうまくコンパイルしますFortranでmkl lapackライブラリを使用した固有値と固有ベクトル

ifort -I $(MKLPATH) -o matrix_diag_01 matrix_diag_01.f90 
     random.f90 $(MKLPATH)libmkl_lapack95.a -Wl,--start-group 
     $(MKLPATH)libmkl_intel_lp64.a $(MKLPATH)libmkl_lapack.a 
     $(MKLPATH)libmkl_intel_thread.a $(MKLPATH)libmkl_core.a 
     -Wl,--end-group -lguide -lpthread 

実行可能ファイルは、小さな行列が与えられたときにうまく動作します。しかし、サイズが3000x3000の行列の場合、奇妙な振る舞いをします。最初にこのエラーが発生します。

MKL ERROR : Parameter 8 was incorrect on entry to SSYEVD 

ただし、SSYEVDの呼び出しには3つのパラメータしかありません。第2に、固有ベクトルを返しますが、固有値は返しません。私は大きなメモリを持つ別のマシンでコンパイルすることでチェックしましたが、結果は同じでした。

誰でもお手伝いできますか?

ありがとうございます!あなたが呼び出している関数のソースを見れば

PROGRAM matrix_diag_01 

USE random 

IMPLICIT NONE 

INTERFACE 
    SUBROUTINE diag(mat,n) 
     INTEGER n 
     REAL,DIMENSION(n,n) :: mat 
    END SUBROUTINE 
END INTERFACE 

INTEGER n,i,j,iseed 
REAL, DIMENSION(:), ALLOCATABLE :: w 
REAL, DIMENSION(:,:), ALLOCATABLE :: mat 

write (*,*) ' Please enter size of matrix' 
read (*,*) n 
write (*,*) ' Please type seed' 
read (*,*) iseed 

allocate (mat(n,n)) 

do i = 1,n 
    do j = 1,n 
     mat(i,j) = ran(iseed) 
    end do 
end do 

call diag(mat,n) 

stop 
END 
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
SUBROUTINE diag(mat,n) 

    USE mkl95_lapack 
    USE mkl95_precision 

    IMPLICIT NONE 

    CHARACTER(len=1) :: jobz = 'V' 

    INTEGER n,i 

    REAL,DIMENSION(n,n) :: mat 
    REAL,DIMENSION(:,:),ALLOCATABLE :: matt,a 
    REAL,DIMENSION(:),ALLOCATABLE :: w 

    allocate (matt(n,n),a(n,n),w(n)) 

    matt = mat*transpose(mat) 
    a = sqrt(matt) 
    open (unit=7,file="matrix.dat",status="unknown") 
    do i = 1,n 
    write (7,100) a(i,:) 
    end do 
    close (unit=7) 

    call syevd(a,w,jobz) 

    open (unit=8,file="eig_val.dat",status="unknown") 
    do i = 1,n 
    write (8,100) w(i) 
    end do 
    close (unit=8) 

    open (unit=9,file="eig_vec.dat",status="unknown") 
    do i = 1,n 
    write (9,100) a(i,:) 
    end do 
    close (unit=9) 

    return 
100 format(5000f16.5) 
end 
+0

私はMKLエラーの解決策はありませんが、十分なメモリが不足しているとは聞こえません。返されない固有値に関しては、 'ssyevd'を' info'引数で呼び出すことを試みましたか? – eriktous

答えて

2

は、それ自体が次の呼び出しを発行します。 http://software.intel.com/sites/products/documentation/hpc/mkl/lapack/mkl_lapack_examples/ssyevd_ex.f.htm

LWORK = MIN(LWMAX, INT(WORK(1))) 

CALL SSYEVD('Vectors', 'Upper', N, A, LDA, W, WORK, LWORK, 
     $    IWORK, LIWORK, INFO) 

おそらくパラメータlworkの値が間違っています。

+0

あなたの答え、whoplispに感謝しますが、関数を呼び出してライブラリ(Fortran 95)をリンクする方法は、LWORKパラメータを直接制御することはできません。 http://software.intel.com/sites/products/documentation/hpc/mkl/mklman/lse/functn_syevd.htm – ricoamor

+0

ラッパーを呼び出しているので、はい。たぶんFortran77のバージョンを呼び出すようにしてください。また、制限に関する関数のドキュメントを見てください。完全な3000x3000のマトリックスはかなり大きいようです。たぶん、二重使用中でも安定性や丸め誤差に問題があるかもしれません。 – whoplisp

+0

ありがとうございました。これは先を行く方法です。コードのその部分にFortran 77を使用して、ラッパーについて忘れてください。それは3000x3000マトリックスで動作します。ありがとう! – ricoamor

関連する問題