当前位置: 首页 > 面试题库 >

如何将Numpy数组传递到cffi函数中以及如何将其取回?

姜钊
2023-03-14
问题内容

我正在使用Python和Numpy开发音频算法。现在,我想通过在C中实现一部分算法来加速该算法。在过去,我已经使用cython做到了这一点。现在,我想使用新的cffi做同样的事情。

为了进行测试,我编写了一个简单的C函数:

void copy(float *in, float *out, int len) {
    for (int i=0; i<len; i++) {
        out[i] = in[i];
    }
}

现在,我想创建两个numpy数组,并使用此函数对其进行处理。我想出了一种方法来做到这一点:

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)

但是,我想改进这段代码:

  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]但是不起作用。为什么不?

问题答案:

ctypesndarray的属性可以与ctypes模块交互,例如,ndarray.ctypes.data是数组的数据地址,可以将其强制转换为float *指针,然后将该指针传递给C函数。

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尝试将其转换为失败的浮点数。

我能想到的最佳解决方案是将其首先转换为列表:

float_in[0:16] = list(arr_in[0:16])


 类似资料:
  • 如何在不使其成为单独变量的情况下传递数组?例如,我知道这是有效的: 但我不想让数组成为变量,因为它只在这里使用。有没有办法做到这一点:

  • 问题内容: 我有一个一个的按钮在我的课,这是我的主要窗口类: 我有一个类就是主窗口的内容。 如何访问内容中的此按钮?有没有更好的方法来组织和控制器以促进此访问? 问题答案: 这样使用委托怎么样?本示例将更改按钮的标题。

  • 问题内容: 这似乎是一个愚蠢的问题,但是我是这个话题的新手。我正在致力于关于节点js的承诺。我想将参数传递给Promise函数。但是我不知道。 而功能类似于 问题答案: 将Promise包裹在一个函数中,否则它将立即开始工作。另外,您可以将参数传递给函数: 然后,使用它: ES6: 用:

  • 一个子:下拉组件 第二个子:播放列表组件

  • 问题内容: 我正在尝试向从创建的数组中添加一列。在这种情况下,它是一个数组:(行,列)。 我想添加第九列。空或零都无所谓。 问题答案: 我认为您的问题是您希望就地添加该列,但是由于存储的numpy数据的原因,它的作用是创建连接数组的副本 所以你需要保存输出: 替代方式: 我相信这三个函数(以及)之间的唯一区别是未指定when的默认行为: 假设 假设除非输入为1d,否则 如果输入为1d,则假定在添加

  • 问题内容: 好的,所以我想将一个非常基本的数组传递到jquery数据attrubute服务器端,如下所示: 然后像这样回撤: 为什么这似乎会警告’[‘而不是’a’(请参阅JSfiddle链接) JSFiddle链接: http : //jsfiddle.net/ktw4v/3/ 问题答案: 它将变量视为字符串,其第零个元素为。 发生这种情况是因为您的字符串不是有效的JSON,它应使用双引号而不是单