Memory management 将OpenMP与Fortran一起使用时出现内存错误,运行FFTW

Memory management 将OpenMP与Fortran一起使用时出现内存错误,运行FFTW,memory-management,fortran,openmp,gfortran,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\u ff

我正在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\u fftw\u openmp.f90-I/usr/local/include-L/usr/lib/x86\u 64-linux-gnu-lfftw3\u 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\u fftw\u openmp.f90-I/usr/local/include-L/usr/lib/x86\u 64-linux-gnu-lfftw3\u omp-lfftw3-lm-fopenmp-fmax stack var size=65536编译时,我获得了成功

所以,我不明白: 1) 如果庞大的矩阵是一个共享变量,为什么会有内存分配问题? 2) 如果我有更大的矩阵变量,我找到的解决方案会起作用吗?例如,再使用3个矩阵
500 x 500 x 500
来存储计算结果。
3) 在我找到的提示中,人们说使用可分配数组/矩阵可以解决问题,但我使用的是没有任何区别的。我还需要做些什么吗?

两个具有500 x 500 x 500个元素的双复阵列需要4G内存。计算机中的可用内存量可能不足

如果只使用小窗口,则可以考虑在整个时间内不使用整个数组,而只考虑其中的一部分。或者使用MPI将计算分布到多台计算机上


或者只使用内存更大的计算机。

也许我错过了一些东西,但不是
500x500x2(复杂)x8(双)x2(num数组)=4e9
即4GB或3.73GB?(取决于您选择使用1000或1024进行计算)实际上,当
A3D
的非连续片被传递到没有显式接口的函数时,需要超过3.73 GiB,并且编译器正在为每次调用
dfftw\u execute\u dft
创建一个临时连续副本,所以临时数组没什么大不了的。@vladimir-f它在有12GB内存的PC上工作得很好(没有编译中的
-fmax stack var size=65536
标志)。现在我的问题是另一个与OpenMP计算有关的问题,我在另一个问题中发布。您使用64位编译器和操作系统吗?你有多少记性?大约需要4 GB的内存。再加上另一个可能的
重塑
的临时值,因此另一个可能的2 GB。使用
ulimit-a
检查进程资源限制。也许数据段大小或虚拟地址空间大小是有限的。我在一台有限的PC上测试,有4GB的RAM。我将尽快在一台12GB的主机上进行测试(完成后在这里进行更新)。关于
ulimit-a
堆栈大小为
8192kb
。抱歉@hristo iliev,但这8 Mb的限制到底是什么?@VictorXA hristo所说的不是堆栈大小,而是“数据段大小或虚拟地址空间大小”,这是非常不同的。有关堆栈,请参见和中的解释,但我认为这不是您的问题。你只需要在你的计算机中增加内存。@vladimir-f现在我有了!根据
ulimit-a
输出,您阐明的这些特性都是无限的。