【发布时间】:2012-12-29 18:38:28
【问题描述】:
假设我们有一个 C 函数,它接受一组一个或多个输入数组,处理它们,并将其输出写入一组输出数组。签名如下(count代表要处理的数组元素个数):
void compute (int count, float** input, float** output)
我想通过 ctypes 从 Python 调用此函数,并使用它对一组 NumPy 数组应用转换。对于定义为的单输入/单输出函数
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)
但是,我不知道如何为 多个 输入(和/或输出)创建相应的指针数组。有什么想法吗?
编辑:所以人们一直想知道compute 是如何知道需要多少个数组指针(因为count 指的是每个数组的元素数)。事实上,这是硬编码的;给定的compute 准确地知道预期有多少输入和输出。调用者的工作是验证input 和output 是否指向正确数量的输入和输出。这是一个示例 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 数组的指针数组)。
【问题讨论】:
-
this question 有帮助吗?
-
不幸的是,没有。它更特定于 NumPy 和 ctypes。不过,谢谢。
-
可能你需要重写
compute来存储数据。 -
compute函数是自动生成的,所以我对签名和实现的影响很小。 -
你怎么知道在自动生成的函数中,插入了多少个数组?