Удаление выделения массива Fortran теперь неверное решение

Я пишу программу. Программа решает матрицы. Размер матриц определяется пользователем в аргументах командной строки. Я хочу, чтобы программа решала очень большие матрицы, поэтому, когда я закончил со всеми вещами линейной алгебры, включая 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. Их даже не используют.


person user2540350    schedule 01.07.2013    source источник
comment
Пожалуйста, предоставьте нам какой-нибудь код для начала, будет намного проще понять, в чем проблема.   -  person Jk1    schedule 02.07.2013
comment
Это не позволяло мне. Не понравилось форматирование. Я не меняю форматирование 1000 строк кода.   -  person user2540350    schedule 02.07.2013
comment
Что произойдет, если вы поместите оператор implicit none в строку 3?   -  person milancurcic    schedule 02.07.2013


Ответы (1)


Вы описали: неиспользуемые массивы, которые если убрать, то ваша программа дает неправильные ответы. Одна из возможностей состоит в том, что некоторые другие используемые массивы объявлены слишком маленькими. Что после удаления используемых массивов эти массивы перекрываются в памяти и из-за перекрытия изменяются некорректно. Раньше, когда у вас были дополнительные массивы, к счастью, они предоставляли дополнительное хранилище для массива или массивов, которые были слишком малы.

Вы можете проверить это, инициализировав неиспользуемые массивы, а затем в конце программы проверив, изменилось ли какое-либо из их значений.

Вы можете просмотреть размеры всех массивов.

Наличие всех процедур (подпрограмм и функций) в модулях, так что их интерфейсы известны компилятору, позволит компилятору проверить согласованность между фактическими аргументами, с которыми они вызываются, и их фиктивными аргументами. Оператор external предполагает, что вы не используете эту помощь, предоставляемую Fortran >=90.

Использование всех параметров ошибок и предупреждений вашего компилятора, включая проверку индексов во время выполнения, может выявить проблему. Если массив был передан подпрограмме таким образом, что информация о его размерах потеряна, это может не помочь. С помощью gfortran попробуйте: -fimplicit-none -Wall -Wline-truncation -Wcharacter-truncation -Wsurprising -Waliasing -Wimplicit-interface -Wunused-parameter -fwhole-file -fcheck=all -fbacktrace

person M. S. B.    schedule 01.07.2013
comment
Это мое умозрительное объяснение. Неиспользуемые массивы фактически создают буфер, и одна из функций превышает границу граничного массива. Я бы подумал, что это вызовет ошибку времени выполнения. Кажется странным, что я мог выделить (a (10)), выделить (b (10)) и сохранить что-то в a (11) = b (1) без каких-либо ошибок. - person user2540350; 02.07.2013
comment
По умолчанию не проверяется правильность использования индекса. Эта проверка требует дополнительных инструкций, которые требуют времени выполнения. С помощью gfortran вы можете добавить эту проверку с помощью -fcheck=all (включая -fcheck=bounds). Он может найти или не найти ошибку нижнего индекса, в зависимости от того, как вы передаете массивы подпрограммам. - person M. S. B.; 02.07.2013