-
Notifications
You must be signed in to change notification settings - Fork 5
Home
Wolfram LibraryLink provides users a way to call external programs in Wolfram Language (Mathematica). The external binary codes are loaded into the Wolfram Kernel through dynamic libraries (.dll, .so). Therefore, compared to WSTP, the overhead of calling a function using LibraryLink is much lower, and argument passing is much more efficient. Wolfram LibraryLink User Guide gives a comprehend description of LibraryLink.
Although LibraryLink makes it possible to improve runtime efficiency, it comes at the cost of writing tedious boilerplate code, in addition to writing functions in C/C++. wll-interface is a header only library written in C++, which simplifies LibraryLink coding and make it less error-prone.
We start with a C++ function multiply
:
double multiply(double x, int y)
{
return x * y;
}
We use wll-interface to simplify the process of loading this function — just add two lines of code:
src = "
#include \"wll_interface.h\" // include the header file
double multiply(double x, int y)
{
return x * y;
}
DEFINE_WLL_FUNCTION(multiply) // defines wll_multiply
";
Now we create a shared library from the code. You need to replace <path-to-wll_interface.h>
below with the directory that contains the header file wll_interface.h
so that the compiler can find it.
Needs["CCompilerDriver`"];
mylib = CreateLibrary[src, "wll_multiply"(* name of the library, can be anything *),
"IncludeDirectories" -> {"<path-to-wll_interface.h>"},
Language -> "C++", "CompileOptions" -> "-std=c++17"]
Finally, we load the function into Mathematica, and use it. Note that the function we loaded is called wll_multiply
. wll-interface add wll_
in front of the C++ function and define the new function according to LibraryLink specifications.
multiply = LibraryFunctionLoad[mylib, "wll_multiply", {Real, Integer}, Real];
multiply[2.33, 5]
Calling external library often involves the representations of data structures. wll-interface abstracts the data structures in LibraryLink by classes or native types. See Type Specification for more information.
In this example, we are going to load std::sort
in C++ STL into Mathematica.
src = "
#include <algorithm>
#include "wll_interface.h"
wll::list<double> sort(wll::list<double> a)
{
std::sort(a.begin(), a.end());
return a;
}
DEFINE_WLL_FUNCTION(sort)
";
MTensor
in LibraryLink is represented in wll-interface as wll::tensor<Type, Rank>
, and wll::list<double>
is an alias for wll::tensor<double, 1>
. begin
and end
are member functions of wll::tensor
class that return iterators.
Then we create a library from the code
Needs["CCompilerDriver`"];
mylib = CreateLibrary[src, "wll_sort"(* name of the library, can be anything *),
"IncludeDirectories" -> {"<path-to-wll_interface.h>"},
Language -> "C++", "CompileOptions" -> "-std=c++17",
"Libraries" -> {},
"LibraryDirectories" -> {}
]
"Libraries"
and "LibraryDirectories"
can be used to specify dependencies on external libraries. Since std::sort
is compiled with the function sort
, we do not need to specify any dependency.
Finally, we load the function into Mathematica, and use it.
sort = LibraryFunctionLoad[mylib, "wll_sort", {{Real, 1}}, {Real, 1}];
sort[{5., 4., 3., 2., 1.}]