Ошибка памяти при использовании OpenMP с Fortran, работающим FFTW
Я тестирую FFTW в программе на Фортране, потому что мне нужно ее использовать. Поскольку я работаю с огромными матрицами, мое первое решение - использовать OpenMP. Когда моя матрица имеет размерность 500 x 500 x 500
возникает следующая ошибка:
Operating system error:
Program aborted. Backtrace:
Cannot allocate memory
Allocation would exceed memory limit
Я скомпилировал код, используя следующее: gfortran -o test teste_fftw_openmp.f90 -I/usr/local/include -L/usr/lib/x86_64-linux-gnu -lfftw3_omp -lfftw3 -lm -fopenmp
PROGRAM test_fftw
USE omp_lib
USE, intrinsic:: iso_c_binding
IMPLICIT NONE
INCLUDE 'fftw3.f'
INTEGER::i, DD=500
DOUBLE COMPLEX:: OUTPUT_FFTW(3,3,3)
DOUBLE COMPLEX, ALLOCATABLE:: A3D(:,:,:), FINAL_OUTPUT(:,:,:)
integer*8:: plan
integer::iret, nthreads
INTEGER:: indiceX, indiceY, indiceZ, window=2
!! TESTING 3D FFTW with OPENMP
ALLOCATE(A3D(DD,DD,DD))
ALLOCATE(FINAL_OUTPUT(DD-2,DD-2,DD-2))
write(*,*) '---------------'
write(*,*) '------------TEST 3D FFTW WITH OPENMP----------'
A3D = reshape((/(i, i=1,DD*DD*DD)/),shape(A3D))
CALL dfftw_init_threads(iret)
CALL dfftw_plan_with_nthreads(nthreads)
CALL dfftw_plan_dft_3d(plan, 3,3,3, OUTPUT_FFTW, OUTPUT_FFTW, FFTW_FORWARD, FFTW_ESTIMATE)
FINAL_OUTPUT=0.
!$OMP PARALLEL DO DEFAULT(SHARED) SHARED(A3D,plan,window) &
!$OMP PRIVATE(indiceX, indiceY, indiceZ, OUTPUT_FFTW, FINAL_OUTPUT)
DO indiceZ=1,10!500-window
write(*,*) 'INDICE Z=', indiceZ
DO indiceY=1,10!500-window
DO indiceX=1,10!500-window
CALL dfftw_execute_dft(plan, A3D(indiceX:indiceX+window,indiceY:indiceY+window, indiceZ:indiceZ+window), OUTPUT_FFTW)
FINAL_OUTPUT(indiceX,indiceY,indiceZ)=SUM(ABS(OUTPUT_FFTW))
ENDDO
ENDDO
ENDDO
!$OMP END PARALLEL DO
call dfftw_destroy_plan(plan)
CALL dfftw_cleanup_threads()
DEALLOCATE(A3D,FINAL_OUTPUT)
END PROGRAM test_fftw
Обратите внимание, эта ошибка возникает, когда я просто использую огромную матрицу (A3D
) без запуска цикла во всех значениях этой матрицы (для запуска во всех значениях я должен иметь пределы трех (вложенных) циклов как 500-window
, Я пытался решить эту проблему (советы здесь и здесь) с -mcmodel=medium
в сборнике без успеха. У меня был успех, когда я собрал с gfortran -o test teste_fftw_openmp.f90 -I/usr/local/include -L/usr/lib/x86_64-linux-gnu -lfftw3_omp -lfftw3 -lm -fopenmp -fmax-stack-var-size=65536
Итак, я не понимаю:
1) Почему существует проблема выделения памяти, если огромная матрица является общей переменной?
2) Решение, которое я нашел, сработает, если у меня будет больше матричных переменных? Например, еще 3 матрицы 500 x 500 x 500
хранить результаты расчетов.
3) В советах, которые я нашел, люди говорили, что использование размещаемых массивов / матриц решит проблему, но я использовал без разницы. Есть ли что-нибудь еще, что мне нужно сделать для этого?
1 ответ
Два двойных комплексных массива с 500 x 500 x 500 элементами требуют 4 гигабайта памяти. Вполне вероятно, что объем доступной памяти на вашем компьютере недостаточно.
Если вы работаете только с небольшими окнами, вы можете рассмотреть не весь массив в целом, а только его части. Или распределите вычисления по нескольким компьютерам, используя MPI.
Или просто используйте компьютер с большей оперативной памятью.