将一组NumPy数组传递到C函数中以进行输入和输出 [英] Passing a set of NumPy arrays into C function for input and output

查看:136
本文介绍了将一组NumPy数组传递到C函数中以进行输入和输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们假设我们有一个C函数,该函数接受一组一个或多个输入数组,对其进行处理,然后将其输出写入一组输出数组.签名如下所示(count代表要处理的数组元素的数量):

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 follows (with count representing the number of array elements to be processed):

void compute (int count, float** input, float** output)

我想通过ctypes从Python调用此函数,并使用它对一组NumPy数组进行转换.对于定义为的一输入一输出功能

I want to call this function from Python via ctypes and use it to apply a transformation to a set of NumPy arrays. For a one-input/one-output function defined as

void compute (int count, float* input, float* output)

以下作品:

import ctypes
import numpy

from numpy.ctypeslib import ndpointer

lib = ctypes.cdll.LoadLibrary('./block.so')
fun = lib.compute
fun.restype = None
fun.argtypes = [ctypes.c_int,
                ndpointer(ctypes.c_float),
                ndpointer(ctypes.c_float)]

data = numpy.ones(1000).astype(numpy.float32)
output = numpy.zeros(1000).astype(numpy.float32)
fun(1000, data, output)

但是,我不知道如何为多个输入(和/或输出)创建相应的指针数组.有什么想法吗?

However, I have no clue how to create the corresponding pointer array for multiple inputs (and/or outputs). Any ideas?

编辑:所以人们一直想知道compute如何知道期望多少个数组指针(因为count是指每个数组中的元素数).实际上,这是硬编码的;给定的compute确切知道期望多少输入和输出.验证inputoutput指向正确数量的输入和输出是调用者的工作.以下是compute的示例,该示例接受2个输入并写入1个输出数组:

Edit: So people have been wondering how compute knows how many array pointers to expect (as count refers to the number of elements per array). This is, in fact, hard-coded; a given compute knows precisely how many inputs and outputs to expect. It's the caller's job to verify that input and output point to the right number of inputs and outputs. Here's an example compute taking 2 inputs and writing to 1 output array:

virtual void compute (int count, float** input, float** output) {
    float* input0 = input[0];
    float* input1 = input[1];
    float* output0 = output[0];
    for (int i=0; i<count; i++) {
        float fTemp0 = (float)input1[i];
        fRec0[0] = ((0.09090909090909091f * fTemp0) + (0.9090909090909091f * fRec0[1]));
        float fTemp1 = (float)input0[i];
        fRec1[0] = ((0.09090909090909091f * fTemp1) + (0.9090909090909091f * fRec1[1]));
        output0[i] = (float)((fTemp0 * fRec1[0]) - (fTemp1 * fRec0[0]));
        // post processing
        fRec1[1] = fRec1[0];
        fRec0[1] = fRec0[0];
    }
}

我无法影响compute的签名和实现.我可以验证(从Python!)需要多少个输入和输出.关键问题是如何为函数提供正确的argtypes,以及如何在NumPy(指向NumPy数组的指针的数组)中产生适当的数据结构.

I have no way of influencing the signature and implementation of compute. I can verify (from Python!) how many inputs and outputs are required. Key problem is how to give the correct argtypes for the function, and how to produce appropriate data structures in NumPy (an array of pointers to NumPy arrays).

推荐答案

要专门针对Numpy数组执行此操作,可以使用:

To do this specifically with Numpy arrays, you could use:

import numpy as np
import ctypes

count = 5
size = 1000

#create some arrays
arrays = [np.arange(size,dtype="float32") for ii in range(count)] 

#get ctypes handles
ctypes_arrays = [np.ctypeslib.as_ctypes(array) for array in arrays]

#Pack into pointer array
pointer_ar = (ctypes.POINTER(C.c_float) * count)(*ctypes_arrays)

ctypes.CDLL("./libfoo.so").foo(ctypes.c_int(count), pointer_ar, ctypes.c_int(size))

事物的C面可能看起来像这样:

Where the C side of things might look like:

# function to multiply all arrays by 2
void foo(int count, float** array, int size)
{
   int ii,jj;
   for (ii=0;ii<count;ii++){
      for (jj=0;jj<size;jj++)
         array[ii][jj] *= 2;    
   }

}

这篇关于将一组NumPy数组传递到C函数中以进行输入和输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆