I have a subroutine that builds sparse matrices, and I need to call it several times. However, it seems that if I call this subroutine a lot of times (and/or if the sparse matrices are very large), memory consumption in my machine starts to accumulate. Given that my matrices are quite large, repeated calls to the subroutine make the program crash eventually. It seems that Fortran is not flushing/freeing the allocated memory after completing each subroutine call.
I'm building these sparse matrices using the Sparse BLAS library that comes with oneAPI MKL, and using the ifort
compiler.
Below, I have an example where I build a small matrix with Sparse BLAS many times. Iterations do not change anything, but as I understand this, memory consumption shouldn't start increasing after each iteration. However, it does. If I were using regular (dense) matrices in this loop rather than using Sparse BLAS, memory consumption doesn't increase at all. For example, if I comment the last line in the loop where I call mkl_sparse_d_create_csr
, the program doesn't crash.
program test
use iso_c_binding
use mkl_spblas
implicit none
integer,parameter :: n = 5
integer :: iter,i,j,stat
real :: csr_ref(n,n)
integer :: count_row,count_nnz
integer :: jcol(1),irow(n+1)
real(C_DOUBLE) :: vals(1)
type(SPARSE_MATRIX_T) :: csr
! Dummy matrix
csr_ref = 0.0
csr_ref(1,1) = 1.0
! Iterating many times
do iter = 1,1000000000
! Builing CSR matrix
irow = 1
count_nnz = 0
do i = 1,n
count_row = 0
do j = 1,n
if (abs(csr_ref(i,j)) > 1e-4) then
count_row = count_row + 1
count_nnz = count_nnz + 1
vals(count_nnz) = csr_ref(i,j)
jcol(count_nnz) = j
end if
end do
irow(1+i) = count_row + irow(i)
end do
! Create sparse matrix
stat = mkl_sparse_d_create_csr(csr, SPARSE_INDEX_BASE_ONE, n, n, irow(1:n), irow(2:n+1), jcol, vals)
end do
end program test
What is the problem here?
The problem is that you are required to call mkl_sparse_destroy
to recover the memory allocated by mkl_sparse_?_create_csr
. This is explicitly stated in the online documentation for mkl_sparse_destroy
but unfortunately not in the online documentation for mkl_sparse_?_create_csr
.
References:
mkl_sparse_?_create_csr
: https://www.intel.com/content/www/us/en/docs/onemkl/developer-reference-fortran/2024-0/mkl-sparse-create-csr.htmlmkl_sparse_destroy
: https://www.intel.com/content/www/us/en/docs/onemkl/developer-reference-fortran/2024-0/mkl-sparse-destroy.html