2011-07-06 2 views
1

다른 크기의 행렬의 고유 값과 고유 벡터를 계산하려고합니다. 아주 간단한 Fortran90 코드를 사용하고 있으며 우분투에서 실행되는 내 컴퓨터에서 사용할 수있는 인텔 MKL 패키지에 포함 된 적절한 Lapack 라이브러리에 링크하여 컴파일 중입니다. "matrix_diag_01.f90"코드는 메시지의 끝에 붙습니다. "random"모듈은 Numerical Recipes의 "ran"난수 생성기를 포함합니다. 코드가 잘 컴파일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 개의 매개 변수 만 있습니다. 둘째, 고유 벡터를 반환하지만 고유 값은 반환하지 않습니다. 나는 더 큰 메모리를 가진 다른 머신에서 컴파일을 체크했지만 결과는 같았다.

아무도 도와 줄 수 있습니까?

감사합니다. 당신은 당신이 호출하는 함수의 소스를 보면

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 오류에 대한 해결책이 없습니다. 반환하지 않는 고유치에 관해서는,'info' 인자로'ssyevd'를 호출 해 보았습니까? – 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

답변 해 주셔서 대단히 감사합니다. 그러나 함수를 호출하고 라이브러리 (즉 Fortran 95)를 연결하는 방법은 LWORK 매개 변수를 직접 제어 할 수 없습니다. http://software.intel.com/sites/products/documentation/hpc/mkl/mklman/lse/functn_syevd.htm – ricoamor

+0

예, 래퍼를 호출하기 때문입니다. 어쩌면 Fortran77 버전을 대신 사용해보십시오. 또한 한계에 대한 함수의 문서를보십시오. 전체 3000x3000 매트릭스가 상당히 큰 것처럼 보입니다. double을 사용하는 중에도 안정성 또는 반올림 오류에 문제가있을 수 있습니다. – whoplisp

+0

고맙습니다. 이것은 앞으로 나아갈 것 같습니다. 코드의 일부만 Fortran 77을 사용하고 래퍼는 잊어 버리십시오. 그것은 3000x3000 매트릭스와 함께 작동합니다. 감사! – ricoamor