将一组NumPy数组传递到C函数中以进行输入和输出 [英] Passing a set of NumPy arrays into C function for input and output
问题描述
让我们假设我们有一个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
确切知道期望多少输入和输出.验证input
和output
指向正确数量的输入和输出是调用者的工作.以下是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屋!