Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Cython to wrap a c++ template to accept any numpy array

I'm trying to wrap a parallel sort written in c++ as a template, to use it with numpy arrays of any numeric type. I'm trying to use Cython to do this.

My problem is that I don't know how to pass a pointer to the numpy array data (of a correct type) to a c++ template. I believe I should use fused dtypes for this, but I don't quite understand how.

The code in .pyx file is below

# importing c++ template
cdef extern from "test.cpp":
    void inPlaceParallelSort[T](T* arrayPointer,int arrayLength)

def sortNumpyArray(np.ndarray a):
    # This obviously will not work, but I don't know how to make it work. 
    inPlaceParallelSort(a.data, len(a))

In the past I did similar tasks with ugly for-loops over all possible dtypes, but I believe there should be a better way to do this.

like image 569
Maxim Imakaev Avatar asked Feb 20 '15 20:02

Maxim Imakaev


People also ask

Is Cython compatible with NumPy?

You can use NumPy from Cython exactly the same as in regular Python, but by doing so you are losing potentially high speedups because Cython has support for fast access to NumPy arrays.

Why is Numba faster than Cython?

Numba compiled algorithms may make the runtime of the Python codes up to a million times faster and thus may reach the speed of C. In addition, with the increasing number of operations, the computation time is usually significantly faster than Cython, the other compiler used for faster processing.

Does Cython use C or C++?

Cython is a programming language that blends Python with the static type system of C and C++. cython is a compiler that translates Cython source code into efficient C or C++ source code. This source can then be compiled into a Python extension module or a standalone executable.


1 Answers

Yes, you want to use a fused type to have Cython call the sorting template for the appropriate specialization of the template. Here's a working example for all non-complex data types that does this with std::sort.

# cython: wraparound = False
# cython: boundscheck = False

cimport cython

cdef extern from "<algorithm>" namespace "std":
    cdef void sort[T](T first, T last) nogil

ctypedef fused real:
    cython.char
    cython.uchar
    cython.short
    cython.ushort
    cython.int
    cython.uint
    cython.long
    cython.ulong
    cython.longlong
    cython.ulonglong
    cython.float
    cython.double

cpdef void npy_sort(real[:] a) nogil:
    sort(&a[0], &a[a.shape[0]-1])
like image 130
IanH Avatar answered Oct 02 '22 00:10

IanH