对于函数局部变量的缓冲区类型意外抛出 Cython 错误
Cython error thrown unexpectedly for buffer types which ARE function local variables
刚学Cython,运行报了一个我不明白的错误,好吧我不明白为什么会在下面的函数中抛出。纯 Python 版本按预期工作。
import numpy as np
cimport numpy as np
ctypedef np.int8_t DTYPE_int8
ctypedef np.int64_t DTYPE_int64
cdef int fitness(np.ndarray[DTYPE_int8, ndim=1] c):
cdef np.ndarray[DTYPE_int8, ndim=1] a
cdef np.ndarray[DTYPE_int8, ndim=1] d1_cnts
cdef np.ndarray[DTYPE_int8, ndim=1] d2_cnts
a = np.arange(N, dtype=np.int8)
d1_cnts = np.unique(c - a, return_counts=True)[1]
d2_cnts = np.unique(c + a, return_counts=True)[1]
d1_cnts = sum(sum(range(n)) for n in d1_cnts)
d2_cnts = sum(sum(range(n)) for n in d2_cnts)
return d1_cnts + d2_cnts
pop = np.arange(N, dtype=np.int8)
print(fitness(pop))
我收到 d1_cnts 和 d2_cnts 的错误“缓冲区类型只允许作为函数局部变量”。这两个变量都是函数局部变量(对吧?),那么为什么会出现这个错误?
它们被捕获在生成器表达式中:
(sum(range(n)) for n in d1_cnts)
在这种情况下,生成器表达式立即被 sum
使用,但 Cython 担心您可能 return 生成器表达式(带有捕获的变量)的一般情况。
您的两个选择是:
- 使用限制较少的类型化内存视图
- 切换到不捕获变量的列表理解求和。
我认为 Cython 最终应该相当有效地优化生成器表达式,但错误消息出现在更早的阶段,在它意识到这是一个选项之前。
另外 sum(range(n))
应该可以用三角数公式替换((n-1)*n/2
我认为),但这是一个单独的优化
刚学Cython,运行报了一个我不明白的错误,好吧我不明白为什么会在下面的函数中抛出。纯 Python 版本按预期工作。
import numpy as np
cimport numpy as np
ctypedef np.int8_t DTYPE_int8
ctypedef np.int64_t DTYPE_int64
cdef int fitness(np.ndarray[DTYPE_int8, ndim=1] c):
cdef np.ndarray[DTYPE_int8, ndim=1] a
cdef np.ndarray[DTYPE_int8, ndim=1] d1_cnts
cdef np.ndarray[DTYPE_int8, ndim=1] d2_cnts
a = np.arange(N, dtype=np.int8)
d1_cnts = np.unique(c - a, return_counts=True)[1]
d2_cnts = np.unique(c + a, return_counts=True)[1]
d1_cnts = sum(sum(range(n)) for n in d1_cnts)
d2_cnts = sum(sum(range(n)) for n in d2_cnts)
return d1_cnts + d2_cnts
pop = np.arange(N, dtype=np.int8)
print(fitness(pop))
我收到 d1_cnts 和 d2_cnts 的错误“缓冲区类型只允许作为函数局部变量”。这两个变量都是函数局部变量(对吧?),那么为什么会出现这个错误?
它们被捕获在生成器表达式中:
(sum(range(n)) for n in d1_cnts)
在这种情况下,生成器表达式立即被 sum
使用,但 Cython 担心您可能 return 生成器表达式(带有捕获的变量)的一般情况。
您的两个选择是:
- 使用限制较少的类型化内存视图
- 切换到不捕获变量的列表理解求和。
我认为 Cython 最终应该相当有效地优化生成器表达式,但错误消息出现在更早的阶段,在它意识到这是一个选项之前。
另外 sum(range(n))
应该可以用三角数公式替换((n-1)*n/2
我认为),但这是一个单独的优化