python – 将Cython融合类型转换为C指针

python – 将Cython融合类型转换为C指针,第1张

概述这是一个关于从Cython融合类型转换为C类型的一般问题,我将用一个最小的例子来描述.考虑表面的C函数模板: template <typename T>void scale_impl(const T * x, T * y, const T a, const size_t N) { for (size_t n = 0; n < N; ++n) { y[n] = a*x[n] 这是一个关于从Cython融合类型转换为C类型的一般问题,我将用一个最小的例子来描述.考虑表面的C函数模板:

template <typename T>voID scale_impl(const T * x,T * y,const T a,const size_t N) {    for (size_t n = 0; n < N; ++n) {        y[n] = a*x[n];    }}

我希望能够在任何类型和形状的任何numpy ndarray上调用此函数.使用Cython,我们首先声明函数模板:

cdef extern:    voID scale_impl[T](const T * x,const size_t N)

然后声明我们希望 *** 作的有效标量类型:

ctypedef fused Scalar:    float    double    ...

最后实现实际的Cython垫片:

def scale(ndarray[Scalar] x,Scalar a):    """Scale an array x by the value a"""    cdef ndarray[Scalar] y = np.empty_like(x)    scale_impl(<Scalar *>x.data,<Scalar *>y.data,a,x.size)    return y

这不起作用有两个原因:

> x只能是1维,而不是任意(或至少很多)维
>施放到< Scalar *>抛出错误,因为Scalar实际上是一个Python对象

人们显然可以明确推断出这些专业化:

if Scalar is float:        scale_impl(<float *>x.data,<float *>y.data,x.size)    if Scalar is double:        scale_impl(<double *>x.data,<double *>y.data,x.size)    if Scalar is ...

但是这会产生一个组合数量的代码路径,我必须手工编写用于娱乐多个融合类型的函数,并创建了这种情况(我假设)引入融合类型以避免.

有没有办法将任意维度(在原因内)数组传递给Cython函数并让它推导出标量数据的指针类型?或者,处理此类功能的最合理的折衷方案是什么?

解决方法 (另请参阅 Using Cython to wrap a c++ template to accept any numpy array中给出的答案,这是一个非常类似的问题.)

使用表单& x [0]而不是尝试转换x.data解决了选择正确的模板专业化的问题. 2D阵列的问题有点复杂,因为不保证阵列是连续的或有序的.

我创建了一个在一维数组上执行实际工作的函数,并包装一个根据需要展平的简单函数:

def _scale_impl(Scalar[::1] x,Scalar a):  # the "::1" Syntax ensures the array is actually continuous  cdef np.ndarray[Scalar,ndim=1] y = np.empty_like(x)  cdef size_t N = x.shape[0] # this seems to be necessary to avoID throwing off Cython's template deduction  scale_impl(&x[0],&y[0],N)  return ydef scale(x,a):  """Scale an array x by the value a"""  y = _scale_impl(np.ravel(x),a)  return y.reshape(x.shape) # reshape needs to be kept out of Cython
总结

以上是内存溢出为你收集整理的python – 将Cython融合类型转换为C指针全部内容,希望文章能够帮你解决python – 将Cython融合类型转换为C指针所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1197231.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-03
下一篇 2022-06-03

发表评论

登录后才能评论

评论列表(0条)

保存