使用oneAPI MKL Sparse BLAS的Fortran程序内存泄漏问题排查
问题原因与修复方案
核心原因
每次调用mkl_sparse_d_create_csr创建的SPARSE_MATRIX_T类型对象csr未被销毁,导致内存泄漏。MKL在创建稀疏矩阵句柄时,会在堆上分配内部内存存储矩阵元数据和结构信息,循环中只创建不释放,内存会持续累积直至耗尽,最终引发程序崩溃。
修复方法
在每次循环创建矩阵后,调用MKL提供的mkl_sparse_destroy函数释放对象占用的内存。修改后的循环代码如下:
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) ! 销毁稀疏矩阵对象,释放内部内存 stat = mkl_sparse_destroy(csr) end do
优化建议
由于你的示例中csr_ref矩阵是固定不变的,完全可以将稀疏矩阵的创建逻辑移到循环外部,只创建一次即可重复使用,避免反复创建销毁的性能开销:
! 提前创建稀疏矩阵,仅执行一次 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 stat = mkl_sparse_d_create_csr(csr, SPARSE_INDEX_BASE_ONE, n, n, irow(1:n), irow(2:n+1), jcol, vals) ! 循环中直接复用已创建的稀疏矩阵 do iter = 1,1000000000 ! 这里执行需要使用稀疏矩阵的操作 end do ! 程序结束前销毁矩阵 stat = mkl_sparse_destroy(csr)
内容的提问来源于stack exchange,提问作者Looper
相关产品推荐
相关产品推荐

