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?