使用对齐的内存进行Fortran FFT(FFTW),而不会发生内存泄漏

时间:2019-03-27 06:56:11

标签: memory-leaks fortran return-type fftw

我想使用FFTW的现代Fortran接口,但是要以允许简单的函数调用的方式使用,例如ifftshift(fft_c2c(vec)* exp(vec))等。这就是我对如何执行此操作的理解(我也了解,对每个呼叫进行新计划都不是最有效的方法)。目前,此代码可以正常使用(返回正确的结果);但是,存在内存泄漏,因此重复调用会导致丢失。我不太确定在哪里!我曾希望将返回变量'fft'与唯一未释放的内存相关联不会导致泄漏,但这显然是不正确的。我缺少什么,如何更好地构建我想要使用适当的现代fortran进行的工作?谢谢!

function fft_c2c(x) result(fft)                                               
integer :: N                                                                
type(C_PTR) :: plan                                                         
complex(C_DOUBLE_COMPLEX), pointer :: fft(:)                                
complex(C_DOUBLE_COMPLEX), dimension(:), intent(in) :: x                    

! Use an auxiliary array that is allocated with fftw_alloc_complex          
! to ensure memory alignment for performance, see FFTW docs                 
complex(C_DOUBLE_COMPLEX), pointer :: x_align(:)                            
type(C_PTR) :: p                                                            

N = size(x)                                                                 
p = fftw_alloc_complex(int(N, C_SIZE_T))                                    
call c_f_pointer(p, fft, [N]);                                              
p = fftw_alloc_complex(int(N, C_SIZE_T))                                    
call c_f_pointer(p, x_align, [N]);                                          

plan = fftw_plan_dft_1d(N, x_align, fft, FFTW_FORWARD, FFTW_MEASURE);       
! FFTW overwrites x_align and fft during planning process, so assign        
! data here                                                                 
x_align = x                                                                 
call fftw_execute_dft(plan, x_align, fft);                                  
call fftw_free(p);                                                          
end function fft_c2c                                                          

1 个答案:

答案 0 :(得分:1)

您不能轻易做到这一点。您正在Fortran上强制使用“ modern” =“ everything is a function”的符号,在此它不太适合(或根本不适合)。

对于内存泄漏,规则很简单-释放所有指针。将它们用于结果变量可确保内存泄漏。如果需要本地分配的对齐内存,则需要在本地分配,在其中复制数据,将数据复制出来并取消分配。

Fortran中的每个指针都需要显式释放,没有引用计数或垃圾回收来为您分配它们。

您考虑只将未对齐的内存与适当的标志一起使用并衡量差异,您似乎根本不在乎最佳性能。

最后,在每次转换之前进行FFTW_MEASURE不仅仅是“不是最有效的事情”,这是绝对性能的灾难。您至少应该使用FFTW_ESTIMATE来减轻它。