4

This is the continued problem of the LibraryLink memory usage question here and here.

In the following code, there is a 2X performance difference with only the change of ";".

MMASrc = "
  #include <WolframLibrary.h>
  #include <WolframCompileLibrary.h>

  DLLEXPORT mint WolframLibrary_getVersion(){
    return WolframLibraryVersion;
  }
  DLLEXPORT int WolframLibrary_initialize(WolframLibraryData \
libData){
    return 0;
  }

  EXTERN_C void zspsv_(char* UPLO, const mint* N, mint* NRHS, \
mcomplex* A, mint* IPIV, mcomplex* B, mint* LDB, mint* INFO);


  EXTERN_C DLLEXPORT int lpkSolveAXBS(WolframLibraryData libData, \
mint Argc, MArgument *Args, MArgument Res){

    MTensor ta=MArgument_getMTensor(Args[0]);
    MTensor tb=MArgument_getMTensor(Args[1]);
    mint N=*MTensor_getDimensionsMacro(tb);
    mcomplex* A=MTensor_getComplexDataMacro(ta);
    mcomplex* B=MTensor_getComplexDataMacro(tb);

    MTensor tclone=0;

    char U='U';
    mint IPIV[N];
    mint NRHS=1;
    mint LDA=N,LDB=N;
    mint INFO;
    mint i,j;

    mcomplex AP[N*(N+1)/2];

    for(j=0;j<N;j++)
      for(i=0;i<=j;i++)
        AP[i + (j+1)*j/2] = A[i*N+j];

    zspsv_(&U,&N,&NRHS,AP,IPIV,B,&LDB,&INFO);

    libData->MTensor_clone(tb,&tclone);

    MArgument_setMTensor(Res,tclone);
    return LIBRARY_NO_ERROR;
  }
  ";
Needs["CCompilerDriver`"];

CreateLibrary[MMASrc, "lpk", "Debug" -> True, 
  "TargetDirectory" -> "/tmp", "CompileOptions" -> "-llapack"];

A = {{1. + 0. I, 0. + 0. I, 0. - 6.94908*^-13 I, 
    0. - 6.94908*^-13 I}, {0. + 0. I, 1. + 0.0352595 I, 
    0. - 4.51893*^-11 I, 0. - 4.51893*^-11 I}, {0. - 6.94908*^-13 I, 
    0. - 4.51893*^-11 I, 1. + 0.0376938 I, 
    0. + 0. I}, {0. - 6.94908*^-13 I, 0. - 4.51893*^-11 I, 0. + 0. I, 
    1. + 0.0378932 I}};

B = {1. + 0. I, 0. + 0. I, 0. + 6.94908*^-13 I, 0. + 6.94908*^-13 I}; 

lpkSolve = LibraryFunctionLoad["/tmp/lpk.dylib", "lpkSolveAXBS", {{Complex, 2}, {Complex, 1}}, {Complex, 1}];

Now test the performance and the memory usage:

MemoryInUse[]/1024.^2
Table[LinearSolve[A, B], {40000}]; // AbsoluteTiming

MemoryInUse[]/1024.^2
Table[lpkSolve[A, B], {40000}]; // AbsoluteTiming

MemoryInUse[]/1024.^2
Table[lpkSolve[A, B], {40000}]; // AbsoluteTiming

MemoryInUse[]/1024.^2

(*
32.2057
{0.560369,Null}
32.2242
{0.115091,Null}
37.1101
{0.121534,Null}
41.995
*)

Note that there seems to be a memory leaking problem, and it is identified as a bug by ruebenko. The work around suggested also by ruebenko is to use ";" at the end of each call to the LibraryLink function. While this solves the memory leak, the performance seems decreaed:

MemoryInUse[]/1024.^2
Table[LinearSolve[A,B];,{40000}];//AbsoluteTiming

MemoryInUse[]/1024.^2
Table[lpkSolve[A,B];,{40000}];//AbsoluteTiming

MemoryInUse[]/1024.^2
Table[lpkSolve[A,B];,{40000}];//AbsoluteTiming

MemoryInUse[]/1024.^2

(*
42.0031
{0.675034,Null}
42.0002
{0.241069,Null}
42.0022
{0.232982,Null}
42.0026
*)

using Do instead of Table doesn't solve the problem:

MemoryInUse[]/1024.^2
Do[LinearSolve[A,B],{40000}];//AbsoluteTiming

MemoryInUse[]/1024.^2
Do[lpkSolve[A,B],{40000}];//AbsoluteTiming

MemoryInUse[]/1024.^2
Do[lpkSolve[A,B],{40000}];//AbsoluteTiming

MemoryInUse[]/1024.^2

(*
42.0102
{0.595506,Null}
42.012
{0.221176,Null}
42.0138
{0.213203,Null}
42.0154
*)

So why there is a 2X performance difference just by adding ";" at the end of function call, or replace Do with Table? And how to fix it?

xslittlegrass
  • 27,549
  • 9
  • 97
  • 186

0 Answers0