3
$\begingroup$

First example: librarylink function return a list of two element

libsource = "#include \"WolframLibrary.h\"

  DLLEXPORT int returnlist(WolframLibraryData libData, mint Argc, \
MArgument *Args, MArgument Res) {
  mreal x;
  x = MArgument_getReal(Args[0]);

  MTensor out_MT;
  const mint out_dim[]={2};
  mint out_rank=1;
  int err = libData->MTensor_new(MType_Real, out_rank, out_dim, \
&out_MT);
  mreal *out_cpointer=libData->MTensor_getRealData(out_MT);

  out_cpointer[0]=x;
  out_cpointer[1]=x;

  MArgument_setMTensor(Res,out_MT);
  return LIBRARY_NO_ERROR;
  }";

load it with

Clear[lib]
lib = CreateLibrary[libsource, "returnlist", "Debug" -> True, 
   "CompileOptions" -> "-x c"];
returnlist = 
  LibraryFunctionLoad[lib, "returnlist", {Real}, {Real, 1}];

and now returnlist[2] gives {2.,2.}

Timing of sequential Table

Table[returnlist[i], {i, 1, 600000}]; // AbsoluteTiming
(*{0.642416, Null}*)

ParallelTable[returnlist[i], {i, 1, 600000}]; // AbsoluteTiming
(*{22.8262, Null}*)

If we look at the CPU load when evaluating ParallelTable, it shows that it only use one kernel

enter image description here

Second example, slight modification to the previous function to let it return only one number.

libsource = "#include \"WolframLibrary.h\"

  EXTERN_C DLLEXPORT int returnnum(WolframLibraryData libData, mint \
Argc, MArgument *Args, MArgument Res) {
  mreal x;
  x = MArgument_getReal(Args[0]);

  MTensor out_MT;
  const mint out_dim[]={2};
  mint out_rank=1;
  //-----------if tensor is real---------
  int err = libData->MTensor_new(MType_Real, out_rank, out_dim, \
&out_MT);
  mreal *out_cpointer=libData->MTensor_getRealData(out_MT);

  out_cpointer[0]=x;
  out_cpointer[1]=x;

  MArgument_setReal(Res,out_cpointer[0]);
  return LIBRARY_NO_ERROR;
  }";

load it with

LibraryFunctionUnload[returnnum]
Clear[lib];
lib = CreateLibrary[libsource, "returnnum", "Debug" -> True, 
   "CompileOptions" -> "-x c"];
returnnum = LibraryFunctionLoad[lib, "returnnum", {Real}, Real];

Now returnnum[2] gives 2..

Timing of Table

Table[returnnum[i], {i, 1, 6000000}]; // AbsoluteTiming
(*{6.23547,Null}*)

ParallelTable[returnnum[i], {i, 1, 6000000}]; // AbsoluteTiming
(*{7.46414,Null}*)

If we look at the CPU load when evaluating ParallelTable, it shows that it is parallelized now

enter image description here

Why is this? How to make librarylink function that return list be parallelized?

$\endgroup$
  • 3
    $\begingroup$ I haven't tested your code, but after a quick skim through the post it seems that the library function was only loaded on the main kernel. You must also load it explicitly (LibraryFunctionLoad) on each subkernel. Use ParalleEvaluate for this. I do use LibraryLink stuff with parallelization, but it usually is put in a Mathematica package (.m file) which has code for loading the library functions and which is read in using ParallelNeeds (in addition to standard Needs). $\endgroup$ – Szabolcs Jan 19 '16 at 9:32
  • $\begingroup$ @Szabolcs You mean like this ParallelEvaluate[ returnlist = LibraryFunctionLoad[lib, "returnlist", {Real}, {Real, 1}]]; ? But I got errors like "LibraryFunction::noopen: Cannot open lib." $\endgroup$ – matheorem Jan 19 '16 at 11:44
  • $\begingroup$ @Szabolcs Full path didn't work. What do you mean by using $LibraryPath? $\endgroup$ – matheorem Jan 19 '16 at 11:55
  • $\begingroup$ After looking more carefully: you must DistributeDefinitions[lib] before doing this. ParallelEvaluate does not automatically do it (like ParallelTable does). I deleted my previous comment. $\endgroup$ – Szabolcs Jan 19 '16 at 11:57
  • $\begingroup$ @Szabolcs Let me try it. But I am a question maybe not relevant. I often got errors like "CopyFile::filex: "Cannot overwrite existing file "C:......\\ Windows-x86-64\\ returnlist.dll"", and I tried to LibraryUnload[lib] and it will show "LibraryFunction::unloadlib: "The library \!(\"C:\\.....\\Windows-x86-64\\\\returnlist.dll\") cannot be unloaded. " What is wrong, How to avoid this? Currently, I have to restart Kernel to get the library create and load again correctly $\endgroup$ – matheorem Jan 19 '16 at 12:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.