我在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
解决此问题(提示here和here}但没有成功。
我用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)在我发现的提示中,人们说使用可分配的数组/矩阵会解决,但我使用没有任何区别。还有什么我需要做的吗?
答案 0 :(得分:0)
两个500 x 500 x 500元素的双复杂数组需要4千兆字节的内存。计算机中的可用内存量可能不足。
如果您只使用小窗口,您可能会考虑不是一直使用整个阵列,而只是使用整个阵列的一部分。或者使用MPI在多台计算机上分配计算。
或者只使用内存较大的电脑。