mir-pybind ~master
mir and python connection library
To use this package, run the following command in your project's root directory:
Manual usage
Put the following dependency into your project's dependences section:
mir-pybind
Like pybind11 in C++, mir-pybind provides simplest communication interface between D-language (e.g., mir.ndslice) and python (e.g., numpy, PIL) by Buffer Protocol and PyObject based conversion. Unlike my previous project mir-pybuffer, this does not need python library because this is pure D project.
usage
python side
All you need is importing D dynamic library. Wrong arguments will raise TypeError, RuntimeError, etc from D library.
import numpy
import libtest_module
assert libtest_module.__doc__ == "this is D module"
assert libtest_module.foo(1) == 2.0
assert libtest_module.baz(1.5, "MB") == "1.5MB"
x = numpy.array([[0, 1, 2], [3, 4, 5]]).astype(numpy.float64)
y = numpy.array([0, 1, 2]).astype(numpy.float64)
mem = numpy.asarray(libtest_module.sum(x, y))
numpy.testing.assert_allclose(mem, x + y)
assert libtest_module.bar(1, 2.0, (True, y)) == (1, ((2.0, 1, True, 0.0),))
print("TEST OK")
D side
You need to implement funcitons and register them by mir.pybind.defModule
.
import std.stdio;
import mir.ndslice;
import mir.pybind : def, defModule;
double foo(long x) {
return x * 2;
}
string baz(double d, char[] s) {
import std.conv : to;
return d.to!string ~ s.to!string;
}
import std.typecons;
auto bar(long i, double d, Tuple!(bool, Slice!(double*, 1)) t) {
writeln(t[1]);
return tuple(i, tuple(tuple(d, i, t[0], t[1][0])));
}
// NOTE: returning slice is partially supported (need numpy.asarray in python)
Slice!(double*, 2) sum(Slice!(double*, 2) x, Slice!(double*, 1) y) {
auto z = x.slice; // copy
foreach (zi; z) {
zi[] += y;
}
return z;
}
mixin defModule!(
"libtest_module", // module name
"this is D module", // module doc
// register d-func and doc under the module
[def!(foo, typeof(foo).stringof),
def!(baz, "this is baz"),
def!(bar, "this is bar"),
def!(sum, "this is sum")]);
To create dynamic library, you also need to add "targetType": "dynamicLibrary"
in dub.json.
detail
The mixin in the last line generates following for example.
extern (C):
static PyModuleDef mod = {
PyModuleDef_HEAD_INIT,
"mod", // module name
"this is D language mod", // module doc
-1, // size of per-interpreter state of the module,
// or -1 if the module keeps state in global variables.
};
static methods = [
def!(foo, "this is foo"),
...
PyMethodDef_SENTINEL
];
auto PyInit_libtest_module() {
import core.runtime : rt_init;
rt_init();
Py_AtExit(&rtAtExit);
mod.m_methods = methods.ptr;
return PyModule_Create(&mod);
}
roadmap
- [DONE] support basic type argument and return: int, float, bool, str, tuple
- [DONE] support numpy/ndslice argument
- [DONE] support numpy/ndslice return (NOTE: need numpy.asarray for returned values)
- [TODO] user-defined class/struct support
- [TODO] keyword args for functions
- Registered by shigeki karita
- ~master released 5 years ago
- ShigekiKarita/mir-pybind
- BSL-1.0
- Copyright © 2018, karita
- Authors:
- Sub packages:
- mir-pybind:deimos-python
- Dependencies:
- mir-algorithm, mir-pybind:deimos-python
- Versions:
-
0.0.3 2019-Jul-31 0.0.2 2018-Nov-16 0.0.1 2018-Nov-14 ~master 2019-Jul-31 - Download Stats:
-
-
0 downloads today
-
0 downloads this week
-
0 downloads this month
-
18 downloads total
-
- Score:
- 0.6
- Short URL:
- mir-pybind.dub.pm