mir-pybuffer 0.2.0

mir-numpy connection example


To use this package, put the following dependency into your project's dependencies section:

dub.json
dub.sdl

mir-pybuffer

Build Status pypi dub

mir-pybuffer provides simpler communication interface between C/D-language and python ndarrays (e.g., numpy, PIL) in Buffer Protocol.

installation

$ pip install pybuffer
$ dub fetch mir-pybuffer # for D (mir) extention

for C extention, you do not need anything but Python.h. you can see a read/write example in c-bp.c and run it by $ make test-c.

usage

python side

All you need to do is calling C/D dynamic library with pybuffer.CDLL.

import ctypes
import numpy
import pybuffer

# ndarrays
x = numpy.array([[0, 1, 2], [3, 4, 5]]).astype(numpy.float64)
y = numpy.array([0, 1, 2]).astype(numpy.float64)

# load dynamic library written in d or c
lib = pybuffer.CDLL("./libyour-dub-lib.so")
err = lib.func1(x, y, ctypes.c_double(2.0))
assert err == 0

D side

currently mir-pybuffer only supports ndslice functions that return void. To create dynamic library, you also need to add "targetType": "dynamicLibrary" in dub.json.

import mir.ndslice : Slice, Contiguous;
// NOTE: DO NOT import pybuffer without ": pybuffer, MixinPyBufferWrappers"
// because it fails to generate wrappers.
import pybuffer : pybuffer, MixinPyBufferWrappers;

@pybuffer
void func1(Slice!(double*, 2) mat, Slice!(double*, 1) vec, double a) {
  mat[0][] += vec;
  vec[] *= a;
}

mixin MixinPyBufferWrappers;

run this example by $ make test-mir.

detail

@pybuffer and mixin MixinPyBufferWrappers; will generate wrapper functions as follows:

pragma(mangle, __traits(identifier, pybuffer_func1))
extern(C) auto pybuffer_func1( ref Py_buffer a0 , ref Py_buffer a1 , double a2 ) {
  import mir.ndslice.connect.cpython;
  import std.stdio : writeln;
  Slice!(double*, 2) _a0;
  {
    auto err = fromPythonBuffer( _a0 , a0 );
    if (err != PythonBufferErrorCode.success) { writeln(err); return err; }
  }
  Slice!(double*, 1) _a1;
  {
    auto err = fromPythonBuffer( _a1 , a1 );
    if (err != PythonBufferErrorCode.success) { writeln(err); return err; }
  }
  func1( _a0 , _a1 , a2 );
  return PythonBufferErrorCode.success;
}

you can see the actual generated codes by lib.print_generated() in python. pybuffer.CDLL calls pybuffer_func1 instead of func1 with PyBuffer arguments and error code handling. see mir.ndslice.connect.cpython.PythonBufferErrorCode for error code definitions.

known issues

  • import pybuffer without : pybuffer, MixinPyBufferWrappers causes a empty generated string.
Authors:
  • karita
Dependencies:
mir-algorithm
Versions:
0.2.0 2018-Sep-10
0.1.7 2018-Apr-05
0.1.6 2018-Apr-03
0.1.5 2018-Apr-03
0.1.4 2018-Apr-02
Show all 8 versions
Download Stats:
  • 0 downloads today

  • 0 downloads this week

  • 0 downloads this month

  • 2 downloads total

Score:
0.7
Short URL:
mir-pybuffer.dub.pm