使用OpenMP与Fortran运行FFTW

时间:2017-05-22 21:05:03

标签: memory-management fortran openmp gfortran

我在fortran程序中测试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解决此问题(提示herehere}但没有成功。 我用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 个答案:

答案 0 :(得分:0)

两个500 x 500 x 500元素的双复杂数组需要4千兆字节的内存。计算机中的可用内存量可能不足。

如果您只使用小窗口,您可能会考虑不是一直使用整个阵列,而只是使用整个阵列的一部分。或者使用MPI在多台计算机上分配计算。

或者只使用内存较大的电脑。