如何将一个Numpy数组传递到cffi函数中,以及如何将其取回? [英] How to pass a Numpy array into a cffi function and how to get one back out?

查看:168
本文介绍了如何将一个Numpy数组传递到cffi函数中,以及如何将其取回?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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:

  1. 有没有一种方法可以直接访问numpy数组的基础浮点缓冲区而不复制它们?
  2. ffi.buffer对于将C数组的内容快速转换为Numpy数组非常方便.有没有一种等效的方法可以将numpy数组快速转换为C数组而不复制单个元素?
  3. 对于某些应用程序,float_in[0:16] = arr_in[0:16]是访问数据的便捷方法.相反,arr_out[0:16] = float_out[0:16]不起作用.为什么不呢?
  1. Is there a way to directly access the underlying float buffers of the numpy arrays without copying them?
  2. 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?
  3. 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屋!

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