Passing a set of NumPy arrays into C function for input and output

后端 未结 2 2193
[愿得一人]
[愿得一人] 2021-02-13 19:41

Let\'s assume we have a C function that takes a set of one or more input arrays, processes them, and writes its output into a set of output arrays. The signature looks as follow

2条回答
  •  甜味超标
    2021-02-13 19:54

    In C, float** points to first element in a table/array of float* pointers.

    Presumably each of those float* points to first element in a table/array of float values.

    Your function declaration has 1 count, however it's not clear what this count applies to:

    void compute (int count, float** input, float** output)
    
    • 2D matrix count x count in size?
    • count -sized array of float* each somehow terminated, e.g. with nan?
    • null-terminated array of float* each of count elements (reasonable assumption)?

    Please clarify your question and I will clarify my answer :-)

    Assuming the last API interpretation, here's my sample compute function:

    /* null-terminated array of float*, each points to count-sized array
    */
    extern void compute(int count, float** in, float** out)
    {
        while (*in)
        {
            for (int i=0; i

    Test code for the sample compute function:

    #include 
    extern void compute(int count, float** in, float** out);
    
    int main(int argc, char** argv)
    {
    #define COUNT 3
        float ina[COUNT] = { 1.5, 0.5, 3.0 };
        float inb[COUNT] = { 0.1, -0.2, -10.0 };
        float outa[COUNT];
        float outb[COUNT];
        float* in[] = {ina, inb, (float*)0};
        float* out[] = {outa, outb, (float*)0};
    
        compute(COUNT, in, out);
    
        for (int row=0; row<2; row++)
            for (int c=0; c

    And how you use same via ctypes in Python for count == 10 float subarrays and size 2 float* array, containing 1 real subarray and NULL terminator:

    import ctypes
    
    innertype = ctypes.ARRAY(ctypes.c_float, 10)
    outertype = ctypes.ARRAY(ctypes.POINTER(ctypes.c_float), 2)
    
    in1 = innertype(*range(10))
    in_ = outertype(in1, None)
    out1 = innertype(*range(10))
    out = outertype(out1, None)
    
    ctypes.CDLL("./compute.so").compute(10, in_, out)
    
    for i in range(10): print in_[0][i], out[0][i]
    

    Numpy interface to ctypes is covered here http://www.scipy.org/Cookbook/Ctypes#head-4ee0c35d45f89ef959a7d77b94c1c973101a562f, arr.ctypes.shape[:] arr.ctypes.strides[:] and arr.ctypes.data are what you need; you might be able to feed that directly to your compute.

    Here's an example:

    In [55]: a = numpy.array([[0.0]*10]*2, dtype=numpy.float32)
    
    In [56]: ctypes.cast(a.ctypes.data, ctypes.POINTER(ctypes.c_float))[0]
    Out[56]: 0.0
    
    In [57]: ctypes.cast(a.ctypes.data, ctypes.POINTER(ctypes.c_float))[0] = 1234
    
    In [58]: a
    Out[58]: 
    array([[ 1234.,     0.,     0.,     0.,     0.,     0.,     0.,     0.,
                0.,     0.],
           [    0.,     0.,     0.,     0.,     0.,     0.,     0.,     0.,
                0.,     0.]], dtype=float32)
    

提交回复
热议问题