0

プログラムを書いています。プログラムは行列を解きます。行列は、ユーザーがコマンド ライン引数で指定した大きさです。プログラムで非常に大きな行列を解決したいので、umfpack、lapack、suitespares、arpack を含むすべての線形代数を使い終わったときに、未使用の配列を削除してメモリ領域を解放しようとしました。私は、マトリックスの解決に関する他の問題をデバッグするためにのみ使用された、3 つの完全に未使用の配列を見つけました。

宣言と割り当てから変数を削除すると、プログラムは異なる動作を開始しました。マトリックスのソリューションは現在間違っています。バックアップファイルに戻りましたが、まだ正常に動作しています。未使用の配列の宣言と割り当てを削除すると、プログラムが正しい解決策を見つけることができなくなっていると確信しています。

私は数日間この問題をいじっています。未使用の配列を削除すると、プログラムの実行がどのように変化するか、本当に想像できません。どんな助けでも大歓迎です。

 program HHSolver
    use MathOperations
    integer :: O, NEV, i, j, k, a, col, row
    integer :: coeff, p, b, NTerms, NextCoeff
    integer :: m, n, symbolic, numeric
    integer :: TermIndex, ido, NCV,LDV, LWorkL, info2,ierr
    double precision :: x, y, sigmai, sigmar
    Character(128) :: String, term, factor
    character(1) :: bmat
    character(2) :: which
    double precision, dimension(:, :), allocatable :: polynomial        !this stores the polynomial boundary equation      
    double precision, dimension(:, :), allocatable :: lap           !this stores the polynomial boundary equation      
    double precision, dimension(:, :), allocatable :: temp          !this stores the polynomial boundary equation      
    double precision, dimension(:, :), allocatable :: R         !this stores the polynomial boundary equation           
    double precision, dimension(:, :), allocatable :: vec           !this stores the polynomial boundary equation           
    double precision, dimension(:, :), allocatable :: lwork         !this stores the polynomial boundary equation           
    double precision, dimension(:), allocatable :: alphar, beta 
    double precision, dimension(:), allocatable :: alphai, work 
    double precision, dimension(1, 1) :: dummy
    double precision, dimension(:), allocatable :: RESID        
    double precision, dimension(:, :), allocatable :: V, z
    double precision, dimension(:), allocatable :: workd, workl
    double precision, dimension(:), allocatable :: workev
    double precision, dimension(:), allocatable :: Ax, DI, DR
    integer, dimension(:), allocatable :: Ap, Ai
    integer, dimension(11) :: IPARAM
    integer, dimension(14) :: IPNTR     
    integer, dimension(1) :: h
    double precision :: control(20), info(90), tol
    logical, dimension(:), allocatable :: select
    logical :: rvec(1)
    double precision, dimension(:), allocatable :: tempvec

    external daxpy, dnrm2, dpttrf, dpttrs, dlapy2
    intrinsic abs

    call get_command_argument(1, String)
    read(String, '(i10)') O
    call get_command_argument(2, String)
    read(String, '(i10)') NEV
    call get_command_argument(3, String)

    write(*, *) 'try to allocate enough memory for full matrices'

    !this is wh the matrix is created
    allocate(lap((O + 1)**2, (O + 1)**2)) !this stores the polynomial boundary equation             
    allocate(temp((O + 1)**2, (O + 1)**2)) !this stores the polynomial boundary equation            
    allocate(R((O + 1)**2, (O + 1)**2)) !this stores the polynomial boundary equation           
    allocate(alphar((O+1)**2)) !this stores the polynomial boundary equation            
    allocate(alphai((O+1)**2)) !this stores the polynomial boundary equation            
    allocate(beta((O+1)**2)) !this stores the polynomial boundary equation              
    allocate(vec((O + 1)**2, (O + 1)**2)) !this stores the polynomial boundary equation             
    allocate(work(8*((O+1)**2))) !this stores the polynomial boundary equation              
    allocate(lwork(2*((O+1)**2), 2*((O+1)**2))) !this stores the polynomial boundary equation           
    allocate(RESID((O+1)**2)) !this stores the initial and last eigenvector
    allocate(V((O+1)**2,20+NEV)) !this stores the eigenvectors
    allocate(workd(3*((O+1)**2))) !this stores the eigenvectors             
    allocate(workl(30*(20+NEV)**2 + 60*(20+NEV))) !this stores the eigenvectors             
    allocate(workev(3*(20+NEV))) !this stores the eigenvectors              
    allocate(tempvec((O+1)**2)) !this stores the eigenvectors               
    allocate(DI(NEV+1)) !this stores the eigenvectors               
    allocate(DR(NEV+1)) !this stores the eigenvectors               
    allocate(select(20+NEV)) !this stores the eigenvectors              
    allocate(z((O+1)**2,1+NEV)) !this stores the eigenvectors

    write(*, *) 'memory for matrices allocated'     

            !create the matrix to be solved
            !solver the matrix

    write(*, '(25F20.5)') DI   !these are the real and imaginary part of solution
    write(*, '(25F20.5)') DR
  end program

alphai、alphar、lwork を削除しようとすると、すべてがバラバラになります。それらは使用さえされていません。

4

1 に答える 1

2

あなたが説明した:未使用の配列。削除すると、プログラムが間違った答えを返します。1 つの可能性は、使用されている他のいくつかの配列が小さすぎると宣言されていることです。使用された配列を削除した後、これらの配列はメモリ内で重複しており、重複のために誤って変更されています。以前は、追加のアレイがある場合、幸運にも、小さすぎるアレイに追加のストレージを提供していました。

未使用の配列を初期化し、プログラムの最後でそれらの値が変更されたかどうかを確認することで、これをテストできます。

すべての配列の次元を確認できます。

すべてのプロシージャ (サブルーチンと関数) をモジュールに配置して、それらのインターフェイスがコンパイラに認識されるようにすると、コンパイラは、それらが呼び出される実際の引数とそれらの仮引数の間の整合性をチェックできます。このexternalステートメントは、Fortran >=90 が提供するこのヘルプを利用していないことを示唆しています。

実行時の添え字チェックを含む、コンパイラのすべてのエラーおよび警告オプションを使用すると、問題が明らかになる場合があります。配列がその次元に関する情報が失われるような方法でサブルーチンに渡された場合、これは役に立たないかもしれません。gfortran を使用して、次のことを試してください。-fimplicit-none -Wall -Wline-truncation -Wcharacter-truncation -Wsurprising -Waliasing -Wimplicit-interface -Wunused-parameter -fwhole-file -fcheck=all -fbacktrace

于 2013-07-01T22:02:53.930 に答える