【发布时间】:2015-01-02 01:44:21
【问题描述】:
我已经将一个从 C 语言改写为 Cython 的算法,这样我就可以利用融合类型并使其更容易从 python 调用。该算法可以使用多个数组以及其他一些参数来处理。数组被接受为指向指针的指针(例如 )。我想我会通过将多个数组作为 numpy 数组的元组提供来从 python 调用 cython 代码,但是这样做会使融合类型变得混乱。这是我现在如何工作的一个简单示例:
import numpy
cimport numpy
ctypedef fused test_dtype:
numpy.float32_t
numpy.float64_t
cdef int do_stuff(test_dtype **some_arrays):
if test_dtype is numpy.float32_t:
return 1
elif test_dtype is numpy.float64_t:
return 2
else:
return -1
def call_do_stuff(tuple some_arrays):
cdef unsigned int num_items = len(some_arrays)
cdef void **the_pointer = <void **>malloc(num_items * sizeof(void *))
if not the_pointer:
raise MemoryError("Could not allocate memory")
cdef unsigned int i
cdef numpy.ndarray[numpy.float32_t, ndim=2] tmp_arr32
cdef numpy.ndarray[numpy.float64_t, ndim=2] tmp_arr64
if some_arrays[0].dtype == numpy.float32:
for i in range(num_items):
tmp_arr32 = some_arrays[i]
the_pointer[i] = &tmp_arr32[0, 0]
return do_stuff(<numpy.float32_t **>the_pointer)
elif some_arrays[0].dtype == numpy.float64:
for i in range(num_items):
tmp_arr64 = some_arrays[i]
the_pointer[i] = &tmp_arr64[0, 0]
return do_stuff(<numpy.float64_t **>cols_pointer)
else:
raise ValueError("Array data type is unknown")
我意识到我可以在元组中指定类型,但如果我理解正确的话,没有比“对象”更复杂的了。有谁知道一种更清洁的方式来做我想做的事情?感谢您提供任何其他 cython 提示。
还有其他参数传递,包括与数组相同类型的fill_value 参数。如果 test_dtype 可以在调用时通过数组或填充参数确定,代码会变得更简单,但我找不到保证 C 将接收正确类型的值的好方法。例如,传递numpy.nan 或numpy.float64(numpy.nan) 并不能保证数据类型。
【问题讨论】: