Search code examples
eclipsememorymemory-leaksvalgrindintel-mkl

Insight as to why Valgrind shows memory leak for Intel's MKL LAPACKE


This is the first time I've ever used Intel's MKL LAPACKE and Valgrind. Unfortunately, I get an error with something I have little to no experience with. I could use some advice on how to cure a potential memory leak. I'm using Intel's MKL library, so I highly assume this issue is my fault, but I'm not exactly sure what to look for or how to debug the issue.

Here is the example file I'm testing from the MKL installation

/*******************************************************************************
* Copyright 2010-2016 Intel Corporation All Rights Reserved.
*
* The source code,  information  and material  ("Material") contained  herein is
* owned by Intel Corporation or its  suppliers or licensors,  and  title to such
* Material remains with Intel  Corporation or its  suppliers or  licensors.  The
* Material  contains  proprietary  information  of  Intel or  its suppliers  and
* licensors.  The Material is protected by  worldwide copyright  laws and treaty
* provisions.  No part  of  the  Material   may  be  used,  copied,  reproduced,
* modified, published,  uploaded, posted, transmitted,  distributed or disclosed
* in any way without Intel's prior express written permission.  No license under
* any patent,  copyright or other  intellectual property rights  in the Material
* is granted to  or  conferred  upon  you,  either   expressly,  by implication,
* inducement,  estoppel  or  otherwise.  Any  license   under such  intellectual
* property rights must be express and approved by Intel in writing.
*
* Unless otherwise agreed by Intel in writing,  you may not remove or alter this
* notice or  any  other  notice   embedded  in  Materials  by  Intel  or Intel's
* suppliers or licensors in any way.
*******************************************************************************/
/*
   LAPACKE_chesv Example.
   ======================
   The program computes the solution to the system of linear equations
   with a Hermitian matrix A and multiple right-hand sides B,
   where A is the coefficient matrix:
   ( -2.90,  0.00) (  0.31,  4.46) (  9.66, -5.66) ( -2.28,  2.14)
   (  0.31, -4.46) ( -7.93,  0.00) (  9.55, -4.62) ( -3.51,  3.11)
   (  9.66,  5.66) (  9.55,  4.62) (  0.30,  0.00) (  9.33, -9.66)
   ( -2.28, -2.14) ( -3.51, -3.11) (  9.33,  9.66) (  2.40,  0.00)
   and B is the right-hand side matrix:
   ( -5.69, -8.21) ( -2.83,  6.46)
   ( -3.57,  1.99) ( -7.64,  1.10)
   (  8.42, -9.83) ( -2.33, -4.23)
   ( -5.00,  3.85) (  6.48, -3.81)
   Description.
   ============
   The routine solves for X the complex system of linear equations A*X = B,
   where A is an n-by-n Hermitian matrix, the columns of matrix B are
   individual right-hand sides, and the columns of X are the corresponding
   solutions.
   The diagonal pivoting method is used to factor A as A = U*D*UH or
   A = L*D*LH, where U (or L) is a product of permutation and unit upper
   (lower) triangular matrices, and D is Hermitian and block diagonal with
   1-by-1 and 2-by-2 diagonal blocks.
   The factored form of A is then used to solve the system of equations A*X = B.
   Example Program Results.
   ========================
 LAPACKE_chesv (row-major, high-level) Example Program Results
 Solution
 (  0.22, -0.95) ( -1.13,  0.18)
 ( -1.42, -1.30) (  0.70,  1.13)
 ( -0.65, -0.40) (  0.04,  0.07)
 ( -0.48,  1.35) (  1.15, -0.27)
 Details of factorization
 (  3.17,  0.00) (  7.32,  3.28) ( -0.36,  0.06) (  0.20, -0.82)
 (  0.00,  0.00) (  0.03,  0.00) ( -0.48,  0.03) (  0.25, -0.76)
 (  0.00,  0.00) (  0.00,  0.00) (  0.30,  0.00) (  9.33, -9.66)
 (  0.00,  0.00) (  0.00,  0.00) (  0.00,  0.00) (  2.40,  0.00)
 Pivot indices
     -1     -1     -3     -3
*/
#include <stdlib.h>
#include <stdio.h>
#include "mkl_lapacke.h"
/* Auxiliary routines prototypes */
extern void print_matrix( char* desc, MKL_INT m, MKL_INT n, MKL_Complex8* a, MKL_INT lda );
extern void print_int_vector( char* desc, MKL_INT n, MKL_INT* a );
/* Parameters */
#define N 4
#define NRHS 2
#define LDA N
#define LDB NRHS
/* Main program */
int main() {
    /* Locals */
    MKL_INT n = N, nrhs = NRHS, lda = LDA, ldb = LDB, info;
    /* Local arrays */
    MKL_INT ipiv[N];
    MKL_Complex8 a[LDA*N] = {
       {-2.90f,  0.00f}, { 0.31f,  4.46f}, { 9.66f, -5.66f}, {-2.28f,  2.14f},
       { 0.00f,  0.00f}, {-7.93f,  0.00f}, { 9.55f, -4.62f}, {-3.51f,  3.11f},
       { 0.00f,  0.00f}, { 0.00f,  0.00f}, { 0.30f,  0.00f}, { 9.33f, -9.66f},
       { 0.00f,  0.00f}, { 0.00f,  0.00f}, { 0.00f,  0.00f}, { 2.40f,  0.00f}
    };
    MKL_Complex8 b[LDB*N] = {
       {-5.69f, -8.21f}, {-2.83f,  6.46f},
       {-3.57f,  1.99f}, {-7.64f,  1.10f},
       { 8.42f, -9.83f}, {-2.33f, -4.23f},
       {-5.00f,  3.85f}, { 6.48f, -3.81f}
    };
    /* Executable statements */
    printf( "LAPACKE_chesv (row-major, high-level) Example Program Results\n" );
    /* Solve the equations A*X = B */
    info = LAPACKE_chesv( LAPACK_ROW_MAJOR, 'U', n, nrhs, a, lda, ipiv,
            b, ldb );
    /* Check for the exact singularity */
    if( info > 0 ) {
        printf( "The element of the diagonal factor " );
        printf( "D(%i,%i) is zero, so that D is singular;\n", info, info );
        printf( "the solution could not be computed.\n" );
        exit( 1 );
    }
    /* Print solution */
    print_matrix( "Solution", n, nrhs, b, ldb );
    /* Print details of factorization */
    print_matrix( "Details of factorization", n, n, a, lda );
    /* Print pivot indices */
    print_int_vector( "Pivot indices", n, ipiv );
    exit( 0 );
} /* End of LAPACKE_chesv Example */
/* Auxiliary routine: printing a matrix */
void print_matrix( char* desc, MKL_INT m, MKL_INT n, MKL_Complex8* a, MKL_INT lda ) {
    MKL_INT i, j;
    printf( "\n %s\n", desc );
    for( i = 0; i < m; i++ ) {
        for( j = 0; j < n; j++ )
            printf( " (%6.2f,%6.2f)", a[i*lda+j].real, a[i*lda+j].imag );
        printf( "\n" );
    }
}
/* Auxiliary routine: printing a vector of integers */
void print_int_vector( char* desc, MKL_INT n, MKL_INT* a ) {
    MKL_INT j;
    printf( "\n %s\n", desc );
    for( j = 0; j < n; j++ ) printf( " %6i", a[j] );
    printf( "\n" );
}

Valgrind output at the following line info = LAPACKE_chesv( LAPACK_ROW_MAJOR, 'U', n, nrhs, a, lda, ipiv, b, ldb );

Multiple markers at this line
    - 69,664 bytes in 1 blocks are possibly lost in loss record 11 of 11 [PID:
     5535]
    - 288 bytes in 1 blocks are possibly lost in loss record 9 of 11 [PID: 5535]
    - 192 bytes in 1 blocks are possibly lost in loss record 6 of 11 [PID: 5535]
    - 192 bytes in 1 blocks are possibly lost in loss record 5 of 11 [PID: 5535]
    - 256 bytes in 1 blocks are possibly lost in loss record 8 of 11 [PID: 5535]
    - 224 bytes in 1 blocks are possibly lost in loss record 7 of 11 [PID: 5535]

I did not alter the example file from Intel in anyway. I simply built it and ran it. Here are the details from the Valgrind log file:

==5535== 192 bytes in 1 blocks are possibly lost in loss record 5 of 11
==5535==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5535==    by 0x5898A3D: mkl_serv_allocate (in /usr/local/INTEL/compilers_and_libraries_2016.2.181/linux/mkl/lib/intel64_lin/libmkl_core.so)
==5535==    by 0x51C3192: LAPACKE_chesv (in /usr/local/INTEL/compilers_and_libraries_2016.2.181/linux/mkl/lib/intel64_lin/libmkl_intel_lp64.so)
==5535==    by 0x400A59: main (/home/troy/Eclipse_INTEL/mkl_lapacke_gcc/Debug/../chesv_row.c:112)
==5535==
==5535== 192 bytes in 1 blocks are possibly lost in loss record 6 of 11
==5535==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5535==    by 0x5898A3D: mkl_serv_allocate (in /usr/local/INTEL/compilers_and_libraries_2016.2.181/linux/mkl/lib/intel64_lin/libmkl_core.so)
==5535==    by 0x5074A1E: CHESV (in /usr/local/INTEL/compilers_and_libraries_2016.2.181/linux/mkl/lib/intel64_lin/libmkl_intel_lp64.so)
==5535==    by 0x51C3491: LAPACKE_chesv_work (in /usr/local/INTEL/compilers_and_libraries_2016.2.181/linux/mkl/lib/intel64_lin/libmkl_intel_lp64.so)
==5535==    by 0x51C31F2: LAPACKE_chesv (in /usr/local/INTEL/compilers_and_libraries_2016.2.181/linux/mkl/lib/intel64_lin/libmkl_intel_lp64.so)
==5535==    by 0x400A59: main (/home/troy/Eclipse_INTEL/mkl_lapacke_gcc/Debug/../chesv_row.c:112)
==5535==
==5535== 224 bytes in 1 blocks are possibly lost in loss record 7 of 11
==5535==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5535==    by 0x5898A3D: mkl_serv_allocate (in /usr/local/INTEL/compilers_and_libraries_2016.2.181/linux/mkl/lib/intel64_lin/libmkl_core.so)
==5535==    by 0x51C33D9: LAPACKE_chesv_work (in /usr/local/INTEL/compilers_and_libraries_2016.2.181/linux/mkl/lib/intel64_lin/libmkl_intel_lp64.so)
==5535==    by 0x51C31F2: LAPACKE_chesv (in /usr/local/INTEL/compilers_and_libraries_2016.2.181/linux/mkl/lib/intel64_lin/libmkl_intel_lp64.so)
==5535==    by 0x400A59: main (/home/troy/Eclipse_INTEL/mkl_lapacke_gcc/Debug/../chesv_row.c:112)
==5535==
==5535== 256 bytes in 1 blocks are possibly lost in loss record 8 of 11
==5535==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5535==    by 0x5899F49: mm_account_ptr_by_tid..0 (in /usr/local/INTEL/compilers_and_libraries_2016.2.181/linux/mkl/lib/intel64_lin/libmkl_core.so)
==5535==    by 0x5898399: mkl_serv_allocate (in /usr/local/INTEL/compilers_and_libraries_2016.2.181/linux/mkl/lib/intel64_lin/libmkl_core.so)
==5535==    by 0x51C3192: LAPACKE_chesv (in /usr/local/INTEL/compilers_and_libraries_2016.2.181/linux/mkl/lib/intel64_lin/libmkl_intel_lp64.so)
==5535==    by 0x400A59: main (/home/troy/Eclipse_INTEL/mkl_lapacke_gcc/Debug/../chesv_row.c:112)
==5535==
==5535== 288 bytes in 1 blocks are possibly lost in loss record 9 of 11
==5535==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5535==    by 0x5898A3D: mkl_serv_allocate (in /usr/local/INTEL/compilers_and_libraries_2016.2.181/linux/mkl/lib/intel64_lin/libmkl_core.so)
==5535==    by 0x51C338A: LAPACKE_chesv_work (in /usr/local/INTEL/compilers_and_libraries_2016.2.181/linux/mkl/lib/intel64_lin/libmkl_intel_lp64.so)
==5535==    by 0x51C31F2: LAPACKE_chesv (in /usr/local/INTEL/compilers_and_libraries_2016.2.181/linux/mkl/lib/intel64_lin/libmkl_intel_lp64.so)
==5535==    by 0x400A59: main (/home/troy/Eclipse_INTEL/mkl_lapacke_gcc/Debug/../chesv_row.c:112)
==5535==
==5535== 69,664 bytes in 1 blocks are possibly lost in loss record 11 of 11
==5535==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5535==    by 0x589A184: mm_account_ptr_by_tid..0 (in /usr/local/INTEL/compilers_and_libraries_2016.2.181/linux/mkl/lib/intel64_lin/libmkl_core.so)
==5535==    by 0x5898399: mkl_serv_allocate (in /usr/local/INTEL/compilers_and_libraries_2016.2.181/linux/mkl/lib/intel64_lin/libmkl_core.so)
==5535==    by 0x51C3192: LAPACKE_chesv (in /usr/local/INTEL/compilers_and_libraries_2016.2.181/linux/mkl/lib/intel64_lin/libmkl_intel_lp64.so)
==5535==    by 0x400A59: main (/home/troy/Eclipse_INTEL/mkl_lapacke_gcc/Debug/../chesv_row.c:112)
==5535==

I should add that I'm using eclipse to run my software. Is there a special way to setup the MKL libraries with eclipse? I believe this is where my potential error is. The program gives me an answer, and everything "seems" to be correct, but after running Valgrind for the first time and I got the errors listed above. Can someone provide instructions on how to setup the MKL libraries in eclipse (paths and libraries)? Thanks.

UPDATE: I've tried these tools and sites, but still, I get the memory feedback from Valgrind. At this point, unless someone offers something helpful, I'll have to assume it's only a "potential" leak and not a "definite" one.


Solution

  • After getting in touch with someone at Intel, I was advised to read the section of the user guide pointed to in the quote below, and checked this link on further usage of "mkl_free_buffers". In the end, adding "mkl_free_buffers();" to the end of program fixed the issue. Valgrind "found no problems to report".

    Avoiding Memory Leaks in Intel MKL

    When running, Intel MKL allocates and deallocates internal buffers to facilitate better performance. However,
    in some cases this behavior may result in memory leaks.
    To avoid memory leaks, you can do either of the following:
    • Set the
      MKL_DISABLE_FAST_MM
      environment variable to 1 or call the
      mkl_disable_fast_mm()
      function.
    Be aware that this change may negatively impact performance of some Intel MKL functions, especially for small problem sizes.
    • Call the
      mkl_free_buffers()
      function or the
      mkl_thread_free_buffers()
      function in the current
      thread.
    For the descriptions of the memory functions, see the Intel MKL Reference Manual, available in the Intel
    Software Documentation Library.