Использование выровненной памяти для Fortran FFT (FFTW) без утечек памяти - PullRequest
1 голос
/ 27 марта 2019

Я хочу использовать современный интерфейс Fortran FFTW , но таким способом, который позволяет выполнять простые вызовы функций, такие как ifftshift (fft_c2c (vec) * exp (vec)) и так далее.Это мое понимание того, как это сделать (я также понимаю, что каждый новый звонок - это не самая эффективная вещь).В настоящее время этот код работает (возвращает правильные результаты);однако происходит утечка памяти, поэтому повторные вызовы приводят к потерям.Я не совсем уверен, где, хотя!Я надеялся, что ассоциация возвращаемой переменной `fft 'с единственной несвободной памятью не приведет к утечкам, но это, очевидно, неверно.Чего мне не хватает, и как мне лучше структурировать то, что я хочу сделать с правильным современным фортраном?Спасибо!

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 Ответ

1 голос
/ 27 марта 2019

Вы не можете сделать это легко. Вы заставляете свой notin на "modern" = "все является функцией" на Фортране, здесь это не подходит (или не подходит совсем).

Для утечек памяти правило простое - освободить все указатели. Использование их для переменной результата является гарантией утечки памяти. Если вам нужна локальная выделенная выровненная память, вам необходимо локально выделить ее, скопировать туда данные, скопировать данные и освободить их.

Каждому указателю в Фортране требуется явное освобождение, нет подсчета ссылок или сборки мусора, чтобы освободить их для вас.

Вы думаете только об использовании невыровненной памяти с соответствующими флагами и измеряете разницу, вам все равно кажется, что вы не заботитесь о максимальной производительности.

Наконец, выполнение FFTW_MEASURE перед каждым преобразованием - это не просто "не самая эффективная вещь", это катастрофа абсолютной производительности . Вы должны, по крайней мере, использовать FFTW_ESTIMATE, чтобы смягчить его.

...