ctypedef N.ndarray[ N.long_t, ndim = 1 ] vector_long_t
ctypedef N.ndarray[ N.float64_t, ndim = 1 ] vector_float_t
cdef fused vector_t:
vector_long_t
vector_float_t
cdef fused vector_t:
N.ndarray[ N.long_t, ndim = 1 ]
N.ndarray[ N.float64_t, ndim = 1 ]
cdef class MaxHeap( object ):
cdef struct heap_long_t:
ulong capacity
long *data
cdef struct heap_double_t:
ulong capacity
double *data
cdef fused heap_t:
heap_long_t
heap_double_t
Then the following two "work" -- the question is how to fuse the ndarray types, so I can have just one routine?
@cython.boundscheck( False )
cdef void heap_copy_to_long_vector(
heap_long_t heap, N.ndarray[ N.long_t, ndim = 1 ] vector
):
'''
copy elements from long heap to vector
.. note: problem with fused version because of ndarray
'''
for i in range( heap.capacity ):
vector[ i ] = heap.data[ i ]
@cython.boundscheck( False )
cdef void heap_copy_to_double_vector(
heap_double_t heap, N.ndarray[ N.float64_t, ndim = 1 ] vector
):
'''
copy elements from long heap to vector
.. note: problem with fused version because of ndarray
'''
for i in range( heap.capacity ):
vector[ i ] = heap.data[ i ]
cdef struct pair_double_ulong_t:
double key
ulong value
ctypedef N.long_t[ : ] h_vector_long_t
ctypedef N.float64_t[ : ] h_vector_double_t
ctypedef pair_double_ulong_t[ : ] h_vector_pair_double_ulong_t
cdef fused h_vector_t:
h_vector_long_t
h_vector_double_t
h_vector_pair_double_ulong_t
cdef struct heap_long_t:
ulong capacity
long *data
cdef struct heap_double_t:
ulong capacity
double *data
cdef struct heap_pair_double_ulong_t:
ulong capacity
pair_double_ulong_t *data
cdef fused heap_t:
heap_long_t
heap_double_t
heap_pair_double_ulong_t
@cython.boundscheck( False )
cdef void heap_copy_to_vector( heap_t heap, h_vector_t vector ) nogil:
cdef unsigned long i
if ( heap_t is heap_long_t and h_vector_t is not h_vector_long_t
or heap_t is heap_double_t and h_vector_t is not h_vector_double_t
or heap_t is heap_pair_double_ulong_t and h_vector_t is not h_vector_pair_double_ulong_t ):
with gil:
raise TypeError( 'element must be same type as heap' )
else:
for i in range( heap.capacity ):
vector[ i ] = heap.data[ i ]
-----
gives:
Error compiling Cython file:
------------------------------------------------------------
...
@cython.boundscheck( False )
cdef void heap_copy_to_vector( heap_t heap, h_vector_t vector ) nogil:
cdef unsigned long i
if ( heap_t is heap_long_t and h_vector_t is not h_vector_long_t
or heap_t is heap_double_t and h_vector_t is not h_vector_double_t
or heap_t is heap_pair_double_ulong_t and h_vector_t is not h_vector_pair_double_ulong_t ):
^
------------------------------------------------------------
/Users/shauncutts/src/python/factfiber/stat/pmodel/c/max_heap.pyx:134:65: Compiler crash in ReplaceFusedTypeChecks
CFuncDefNode.body = StatListNode(max_heap.pyx:131:4)
StatListNode.stats[1] = IfStatNode(max_heap.pyx:132:4)
IfStatNode.if_clauses[0] = IfClauseNode(max_heap.pyx:132:7)
IfClauseNode.condition = BoolBinopNode(max_heap.pyx:133:12,
operator = u'or',
result_is_used = True,
use_managed_ref = True)
BoolBinopNode.operand2 = BoolBinopNode(max_heap.pyx:134:12,
operator = u'or',
result_is_used = True,
use_managed_ref = True)
BoolBinopNode.operand2 = BoolBinopNode(max_heap.pyx:134:50,
operator = u'and',
result_is_used = True,
use_managed_ref = True)
BoolBinopNode.operand2 = PrimaryCmpNode(max_heap.pyx:134:65,
operator = u'is_not',
result_is_used = True,
use_managed_ref = True)
Compiler crash traceback from this point on:
File "Visitor.py", line 176, in Cython.Compiler.Visitor.TreeVisitor._visitchild (/Users/x/src/entropy-git/src/entropy/analyze/monitor/build/cython/Cython/Compiler/Visitor.c:3766)
File "/Library/Python/2.7/site-packages/Cython/Compiler/ParseTreeTransforms.py", line 2580, in visit_PrimaryCmpNode
is_same = type1.same_as(type2)
File "/Library/Python/2.7/site-packages/Cython/Compiler/PyrexTypes.py", line 214, in same_as
return self.same_as_resolved_type(other_type.resolve(), **kwds)
AttributeError: 'NoneType' object has no attribute 'resolve'