I am working on a package to make it easier to write LibraryCode. I started this out of personal need, but I would like to make the package general enough to be of use to a broader audience. I found the barrier to writing LibraryLink extensions too high, especially when managed library expressions were involved. I tried to lower this by generating all the boilerplate code based on "templates" that describe the library interface.
This post is to request feedback on the package design. The packages is far from done yet, but it's complete enough to demonstrate the idea and to ask for guidance on how to proceed.
It can be downloaded from https://bitbucket.org/szhorvat/ltemplate/
Any feedback and constructive criticism is most welcome!
The following example shows how it can be used. While incomplete, I hope it conveys the main idea well.
Load package
<<LTemplate`
Write the code as a C++ class. For this short example I'm going to Export
the C++ source directly form Mathematica, but normally this would be written separately. The following class is for computing the mean and variance of an array in one go.
SetDirectory[$TemporaryDirectory]
code = "
class MeanVariance {
double m, v;
public:
void compute(mma::RealTensorRef vec) {
double sum = 0.0, sum2 = 0.0;
for (mint i=0; i < vec.length(); ++i) {
sum += vec[i];
sum2 += vec[i]*vec[i];
}
m = sum / vec.length();
v = sum2 / vec.length() - m*m;
}
double mean() { return m; }
double variance() { return v; }
};
";
Export["MeanVariance.h", code, "String"]
Define the interface to the class through a "template" definition:
template =
LClass["MeanVariance",
{
LFun["compute", {{Real, _, "Constant"}}, "Void"],
LFun["mean", {}, Real],
LFun["variance", {}, Real]
}
];
Compile & load:
CompileTemplate[template]
LoadTemplate[template]
Now the class can be instantiated as a managed library expressions using Make
. When an expression is no longer referenced from Mathematica, it is automatically freed.
meanVariance[arr_] :=
Module[{obj = Make[MeanVariance]},
obj@"compute"[arr];
{obj@"mean"[], obj@"variance"[]}
]
list = RandomReal[1, 100];
meanVariance[list]
{0.521816, 0.0888919}
This also provides a solution to the multiple return problem with LibraryLink (without having to resort to MathLink).
http://mathematica.stackexchange.com/questions/31545/returning-multiple-results-from-a-librarylink-function