缓冲区类型仅允许用作函数局部变量,但这就是我正在做的 [英] Buffer types only allowed as function local variables, but that's what I'm doing

查看:104
本文介绍了缓冲区类型仅允许用作函数局部变量,但这就是我正在做的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Cython不喜欢闭包中的numpy数组吗?

Cython doesn't like numpy arrays in closures?

%%cython
import numpy as np
cimport numpy as np

def f(np.ndarray[double, ndim=1] a):
    def g (double b):
        return a+b

    return g(1)

使用稳定版0.24,我得到:

Using the stable version 0.24, I get:

Error compiling Cython file:
------------------------------------------------------------
...
import numpy as np
cimport numpy as np

def f(np.ndarray[double, ndim=1] a):
     ^
------------------------------------------------------------

cython_magic.pyx:4:6: Buffer types only allowed as function local variables

如果我摆脱了 g 的定义,它可以编译/正常运行。

If I get rid of the definition of g, it compiles/works fine.

推荐答案

有一些工作回合:


  1. 仅分配内部函数中变量的类型:

  1. Only assign the type to the variable within the inner function:

def f(a):
    def g (double b):
        cdef np.ndarray[double, ndim=1] a_typed = a
        return a_typed+b

    return g(1)

与每次检查 g 的类型有关,这花费很小,其重要性取决于您正在做的其他工作在 g 中执行。

This has a small cost associated with checking the type on each call of g, the significance of which depends on how much other work you're doing in g.

使用内存视图和无类型变量的组合。

Use a mixture of memoryviews and untyped variables.

def f(a):
   cdef double[:] memview_of_a = a

   def g(double b):
       memview_of_a[0] = 0 # example of indexing operation
       return a+b

   return g(1)

这里要记住的是 memview_of_a a 查看相同的数据,因此您可以通过两种不同的方式访问它。使用memoryview可以快速建立数组索引。数组上的标量运算之类的操作实际上不受类型信息的影响,因此实际上没有理由将其强制为特定类型。

The thing to remember here is that memview_of_a and a look at the same data, so you can access it in two different ways. Array indexing is quick with the memoryview. Things like scalar operations on arrays aren't actually affected by the type information so there's really no reason to force it to be a specific type.

总的来说,这是一个限制,但是有一些工作回合(尽管它们不是很整齐)。

In summary, it's a limitation, but there are workrounds (although they aren't very neat).

这篇关于缓冲区类型仅允许用作函数局部变量,但这就是我正在做的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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