Tuesday, 21 February 2023

How do I import a Cython function with array arguments to Numba?

The Numba documentation describes how to import a Cython function by creating a ctypes.CFUNCTYPE. However, the Cython function in the example only takes a scalar argument. I have a Cython function that takes arrays. How do I initialize the corresponding ctypes.CFUNCTYPE object?

Cython function:

cimport numpy as np


ctypedef np.float64_t FLOAT64


cdef api void generate_options(
        FLOAT64 [:] y_error,
        ...
    ):
    ...

The Numba documentation describes how to create array types. However, using these in ctypes.CFUNCTYPE raises TypeError: item 1 in _argtypes_ has no from_param method, so I assume they are not intended to be used as argtypes.


Edit:

The solution suggested in the comments calls the function from Numba, but produces a segmentation error when I try to take a slice. If I comment out the last line before return then there is no error. Am I doing something wrong with the c types?

Cython:

ctypedef np.int8_t INT8
ctypedef np.int64_t INT64
ctypedef np.float64_t FLOAT64


cdef api void generate_options(
        FLOAT64 [:] y_error,
        FLOAT64 [:,:] x,
        FLOAT64 [:] x_pads,
        INT8 [:] x_active,
        INT64 [:,:] indexes,
        long i_start,
        INT64 [:] i_start_by_x,
        INT64 [:] i_stop_by_x,
        int error,
        double delta,
        # buffers
        FLOAT64 [:,:] new_error,
        INT8 [:,:] new_sign,
    ):
    cdef:
        size_t n_stims = new_error.shape[0]
        size_t i_stim
        FLOAT64 [:] x_stim

    for i_stim in range(n_stims):
        if x_active[i_stim] == 0:
            continue
        x_stim = x[i_stim]
    return

Python:

addr = ...
functype = ctypes.CFUNCTYPE(
    None,
    ctypes.POINTER(ctypes.c_double),
    ctypes.POINTER(ctypes.c_double),
    ctypes.POINTER(ctypes.c_double),
    ctypes.POINTER(ctypes.c_int8),
    ctypes.POINTER(ctypes.c_int64),
    ctypes.c_int64,
    ctypes.POINTER(ctypes.c_int64),
    ctypes.POINTER(ctypes.c_int64),
    ctypes.c_int,
    ctypes.c_double,
    ctypes.POINTER(ctypes.c_double),
    ctypes.POINTER(ctypes.c_int8),
)
opt_generate_options = functype(addr)


from How do I import a Cython function with array arguments to Numba?

No comments:

Post a Comment