如何将一个Numpy数组传递到cffi函数中,以及如何将其取回? [英] How to pass a Numpy array into a cffi function and how to get one back out?
问题描述
我正在使用Python和Numpy开发音频算法.现在,我想通过在C中实现一部分算法来加速该算法.过去,已经使用cython完成了此操作.现在,我想使用新的 cffi .
I am developing an audio algorithm using Python and Numpy. Now I want to speed up that algorithm by implementing a part of it in C. In the past, I have done this using cython. Now I want to do the same thing using the new cffi.
出于测试目的,我编写了一个简单的C函数:
For testing purposes, I wrote a trivial C function:
void copy(float *in, float *out, int len) {
for (int i=0; i<len; i++) {
out[i] = in[i];
}
}
现在,我想创建两个numpy数组,并使用此函数对其进行处理. 我想出了一种方法:
Now I want to create two numpy arrays and have those be processed by this function. I figured out a way to do that:
import numpy as np
from cffi import FFI
ffi = FFI()
ffi.cdef("void copy(float *in, float *out, int len);")
C = ffi.dlopen("/path/to/copy.dll")
float_in = ffi.new("float[16]")
float_out = ffi.new("float[16]")
arr_in = 42*np.ones(16, dtype=np.float32)
float_in[0:16] = arr_in[0:16]
C.copy(float_in, float_out, 16)
arr_out = np.frombuffer(ffi.buffer(float_out, 16*4), dtype=np.float32)
但是,我想改进这段代码:
However, I would like to improve this code:
- 有没有一种方法可以直接访问numpy数组的基础浮点缓冲区而不复制它们?
-
ffi.buffer
对于将C数组的内容快速转换为Numpy数组非常方便.有没有一种等效的方法可以将numpy数组快速转换为C数组而不复制单个元素? - 对于某些应用程序,
float_in[0:16] = arr_in[0:16]
是访问数据的便捷方法.相反,arr_out[0:16] = float_out[0:16]
不起作用.为什么不呢?
- Is there a way to directly access the underlying float buffers of the numpy arrays without copying them?
ffi.buffer
is very convenient for quickly converting to contents of a C array to a Numpy array. Is there an equivalent way for quickly converting a numpy array into a C array without copying the individual elements?- For some applications,
float_in[0:16] = arr_in[0:16]
is a convenient way of accessing data. The opposite,arr_out[0:16] = float_out[0:16]
does not work however. Why not?
推荐答案
ndarray的ctypes
属性可以与ctypes模块交互,例如,ndarray.ctypes.data
是数组的数据地址,可以将其强制转换为float *
指针,
然后将指针传递给C函数.
The ctypes
attribute of ndarray can interact with the ctypes module, for example, ndarray.ctypes.data
is the data address of the array, you can cast it to a float *
pointer,
and then pass the pointer to the C function.
import numpy as np
from cffi import FFI
ffi = FFI()
ffi.cdef("void copy(float *in, float *out, int len);")
C = ffi.dlopen("ccode.dll")
a = 42*np.ones(16, dtype=np.float32)
b = np.zeros_like(a)
pa = ffi.cast("float *", a.ctypes.data)
pb = ffi.cast("float *", b.ctypes.data)
C.copy(pa, pb, len(a))
print b
您的问题3:
我认为ffi数组无法提供numpy必要的信息来访问其内部缓冲区.因此numpy尝试将其转换为失败的浮点数.
I think ffi array doesn't provide numpy the necessary information to access it's inner buffer. So numpy try to convert it to a float number which failed.
我认为最好的解决方案是将其首先转换为列表:
The best solution I can thinks is convert it to list first:
float_in[0:16] = list(arr_in[0:16])
这篇关于如何将一个Numpy数组传递到cffi函数中,以及如何将其取回?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!