假设我们有一个C函数,它接受一组或多个输入数组,对它们进行处理,并将其输出写入一组输出数组中。签名如下(其中count
表示要处理的数组元素的数量):
void compute (int count, float** input, float** output)
我想通过ctypes从Python调用这个函数,并使用它对一组NumPy数组应用转换。对于定义为
^{pr2}$以下工作:
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)
但是,我不知道如何为多个输入(和/或输出)创建相应的指针数组。有什么想法吗?在
编辑:因此人们一直想知道compute
如何知道预期的数组指针数量(因为count
表示每个数组的元素数)。事实上,这是硬编码的;给定的compute
精确地知道需要多少输入和输出。调用者的工作是验证input
和{compute
获取2个输入并写入1个输出数组:
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数组的指针数组)中生成适当的数据结构。在
在C中,
float**
指向float*
指针的表/数组中的第一个元素。在假设这些
float*
中的每一个都指向float
值的表/数组中的第一个元素。在您的函数声明有1个计数,但不清楚此计数适用于什么:
count
xcount
大小?在count
-大小为float*
的数组,每个数组都以某种方式终止,例如用nan
?在float*
每个count
元素(合理假设)?在请澄清您的问题,我将澄清我的答案:-)
假设最后一个API解释,下面是我的计算函数示例:
^{pr2}$示例计算函数的测试代码:
以及如何通过Python中的ctypes为
count
==10float
子数组和大小2
float*
数组使用相同的方法,其中包含1个实子数组和NULL终止符:这里介绍ctypes的Numpy接口http://www.scipy.org/Cookbook/Ctypes#head-4ee0c35d45f89ef959a7d77b94c1c973101a562f,arr.ctypes.shape形状[:] 前进的步伐[:]和arr.ctypes.data公司是您所需要的;您可以将其直接提供给您的
compute
。在下面是一个例子:
要特别针对Numpy数组执行此操作,可以使用:
其中C端可能看起来像:
^{pr2}$相关问题 更多 >
编程相关推荐