Commit 1c2c325a authored by Mark Florisson's avatar Mark Florisson

Fix utility code error & memslice acquisition count temporary bug

parent 4f929eef
...@@ -71,7 +71,7 @@ class UtilityCodeBase(object): ...@@ -71,7 +71,7 @@ class UtilityCodeBase(object):
""" """
is_cython_utility = False is_cython_utility = False
requires = None
_utility_cache = {} _utility_cache = {}
@classmethod @classmethod
...@@ -252,6 +252,8 @@ class UtilityCodeBase(object): ...@@ -252,6 +252,8 @@ class UtilityCodeBase(object):
def __str__(self): def __str__(self):
return "<%s(%s)" % (type(self).__name__, self.name) return "<%s(%s)" % (type(self).__name__, self.name)
def get_tree(self):
pass
class UtilityCode(UtilityCodeBase): class UtilityCode(UtilityCodeBase):
""" """
...@@ -299,9 +301,6 @@ class UtilityCode(UtilityCodeBase): ...@@ -299,9 +301,6 @@ class UtilityCode(UtilityCodeBase):
other_proto = getattr(other, 'proto', None) other_proto = getattr(other, 'proto', None)
return (self_proto, self.impl) == (other_proto, other.impl) return (self_proto, self.impl) == (other_proto, other.impl)
def get_tree(self):
pass
def none_or_sub(self, s, context): def none_or_sub(self, s, context):
""" """
Format a string in this utility code with context. If None, do nothing. Format a string in this utility code with context. If None, do nothing.
......
...@@ -2468,7 +2468,7 @@ class IndexNode(ExprNode): ...@@ -2468,7 +2468,7 @@ class IndexNode(ExprNode):
self.is_buffer_access = False self.is_buffer_access = False
# a[...] = b # a[...] = b
self.is_memoryviewslice_access = False self.is_memslice_copy = False
# incomplete indexing, Ellipsis indexing or slicing # incomplete indexing, Ellipsis indexing or slicing
self.memslice_slice = False self.memslice_slice = False
# integer indexing # integer indexing
...@@ -2498,7 +2498,6 @@ class IndexNode(ExprNode): ...@@ -2498,7 +2498,6 @@ class IndexNode(ExprNode):
skip_child_analysis = False skip_child_analysis = False
buffer_access = False buffer_access = False
memoryviewslice_access = False
if self.indices: if self.indices:
indices = self.indices indices = self.indices
...@@ -2510,7 +2509,7 @@ class IndexNode(ExprNode): ...@@ -2510,7 +2509,7 @@ class IndexNode(ExprNode):
if (is_memslice and not self.indices and if (is_memslice and not self.indices and
isinstance(self.index, EllipsisNode)): isinstance(self.index, EllipsisNode)):
# Memoryviewslice copying # Memoryviewslice copying
memoryviewslice_access = True self.is_memslice_copy = True
elif is_memslice: elif is_memslice:
# memoryviewslice indexing or slicing # memoryviewslice indexing or slicing
...@@ -2615,13 +2614,11 @@ class IndexNode(ExprNode): ...@@ -2615,13 +2614,11 @@ class IndexNode(ExprNode):
if self.base.type.is_buffer: if self.base.type.is_buffer:
self.base.entry.buffer_aux.writable_needed = True self.base.entry.buffer_aux.writable_needed = True
elif memoryviewslice_access: elif self.is_memslice_copy:
self.type = self.base.type self.type = self.base.type
self.is_memoryviewslice_access = True
if getting: if getting:
self.memslice_ellipsis_noop = True self.memslice_ellipsis_noop = True
else: else:
self.is_memslice_copy = True
self.memslice_broadcast = True self.memslice_broadcast = True
elif self.memslice_slice: elif self.memslice_slice:
...@@ -2630,6 +2627,12 @@ class IndexNode(ExprNode): ...@@ -2630,6 +2627,12 @@ class IndexNode(ExprNode):
self.use_managed_ref = True self.use_managed_ref = True
self.type = PyrexTypes.MemoryViewSliceType( self.type = PyrexTypes.MemoryViewSliceType(
self.base.type.dtype, axes) self.base.type.dtype, axes)
if (self.base.type.is_memoryviewslice and not
self.base.is_name and not
self.base.result_in_temp()):
self.base = self.base.coerce_to_temp(env)
if setting: if setting:
self.memslice_broadcast = True self.memslice_broadcast = True
...@@ -2987,23 +2990,32 @@ class IndexNode(ExprNode): ...@@ -2987,23 +2990,32 @@ class IndexNode(ExprNode):
code.putln("*%s %s= %s;" % (ptrexpr, op, rhs.result())) code.putln("*%s %s= %s;" % (ptrexpr, op, rhs.result()))
def generate_assignment_code(self, rhs, code): def generate_assignment_code(self, rhs, code):
generate_evaluation_code = (self.is_memslice_scalar_assignment or
self.memslice_slice)
if generate_evaluation_code:
self.generate_evaluation_code(code)
else:
self.generate_subexpr_evaluation_code(code) self.generate_subexpr_evaluation_code(code)
if self.is_buffer_access or self.memslice_index: if self.is_buffer_access or self.memslice_index:
self.generate_buffer_setitem_code(rhs, code) self.generate_buffer_setitem_code(rhs, code)
elif self.is_memslice_scalar_assignment: elif self.is_memslice_scalar_assignment:
self.generate_memoryviewslice_assign_scalar_code(rhs, code) self.generate_memoryviewslice_assign_scalar_code(rhs, code)
elif self.memslice_slice: elif self.memslice_slice or self.is_memslice_copy:
self.generate_memoryviewslice_setslice_code(rhs, code) self.generate_memoryviewslice_setslice_code(rhs, code)
elif self.is_memoryviewslice_access:
self.generate_memoryviewslice_copy_code(rhs, code)
elif self.type.is_pyobject: elif self.type.is_pyobject:
self.generate_setitem_code(rhs.py_result(), code) self.generate_setitem_code(rhs.py_result(), code)
else: else:
code.putln( code.putln(
"%s = %s;" % ( "%s = %s;" % (
self.result(), rhs.result())) self.result(), rhs.result()))
if generate_evaluation_code:
self.generate_disposal_code(code)
else:
self.generate_subexpr_disposal_code(code) self.generate_subexpr_disposal_code(code)
self.free_subexpr_temps(code) self.free_subexpr_temps(code)
rhs.generate_disposal_code(code) rhs.generate_disposal_code(code)
rhs.free_temps(code) rhs.free_temps(code)
...@@ -3108,20 +3120,13 @@ class IndexNode(ExprNode): ...@@ -3108,20 +3120,13 @@ class IndexNode(ExprNode):
have_slices=have_slices) have_slices=have_slices)
def generate_memoryviewslice_setslice_code(self, rhs, code): def generate_memoryviewslice_setslice_code(self, rhs, code):
"memslice1[:] = memslice2" "memslice1[...] = memslice2 or memslice1[:] = memslice2"
import MemoryView
self.generate_evaluation_code(code)
MemoryView.copy_broadcast_memview_src_to_dst(rhs, self, code)
def generate_memoryviewslice_copy_code(self, rhs, code):
"memslice1[...] = memslice2"
import MemoryView import MemoryView
MemoryView.copy_broadcast_memview_src_to_dst(rhs, self, code) MemoryView.copy_broadcast_memview_src_to_dst(rhs, self, code)
def generate_memoryviewslice_assign_scalar_code(self, rhs, code): def generate_memoryviewslice_assign_scalar_code(self, rhs, code):
"memslice1[...] = 0.0 or memslice1[:] = 0.0" "memslice1[...] = 0.0 or memslice1[:] = 0.0"
import MemoryView import MemoryView
self.generate_evaluation_code(code)
MemoryView.assign_scalar(self, rhs, code) MemoryView.assign_scalar(self, rhs, code)
def put_nonecheck(self, code): def put_nonecheck(self, code):
...@@ -4515,7 +4520,8 @@ class AttributeNode(ExprNode): ...@@ -4515,7 +4520,8 @@ class AttributeNode(ExprNode):
return return
code.putln("%s = %s;" % (self.result(), self.obj.result())) code.putln("%s = %s;" % (self.result(), self.obj.result()))
if self.obj.is_name or self.obj.is_attribute and self.obj.is_memslice_transpose: if self.obj.is_name or (self.obj.is_attribute and
self.obj.is_memslice_transpose):
code.put_incref_memoryviewslice(self.result(), have_gil=True) code.put_incref_memoryviewslice(self.result(), have_gil=True)
T = "__pyx_memslice_transpose(&%s) == 0" T = "__pyx_memslice_transpose(&%s) == 0"
...@@ -9107,8 +9113,12 @@ class CoerceToTempNode(CoercionNode): ...@@ -9107,8 +9113,12 @@ class CoerceToTempNode(CoercionNode):
# by generic generate_subexpr_evaluation_code! # by generic generate_subexpr_evaluation_code!
code.putln("%s = %s;" % ( code.putln("%s = %s;" % (
self.result(), self.arg.result_as(self.ctype()))) self.result(), self.arg.result_as(self.ctype())))
if self.type.is_pyobject and self.use_managed_ref: if self.use_managed_ref:
if self.type.is_pyobject:
code.put_incref(self.result(), self.ctype()) code.put_incref(self.result(), self.ctype())
elif self.type.is_memoryviewslice:
code.put_incref_memoryviewslice(self.result(),
not self.in_nogil_context)
class CloneNode(CoercionNode): class CloneNode(CoercionNode):
......
...@@ -60,6 +60,73 @@ cdef cdg(): ...@@ -60,6 +60,73 @@ cdef cdg():
cdef double[::1] dmv = array((10,), itemsize=sizeof(double), format='d') cdef double[::1] dmv = array((10,), itemsize=sizeof(double), format='d')
dmv = array((10,), itemsize=sizeof(double), format='d') dmv = array((10,), itemsize=sizeof(double), format='d')
cdef class TestExcClassExternalDtype(object):
cdef ext_dtype[:, :] arr_float
cdef td_h_double[:, :] arr_double
def __init__(self):
self.arr_float = cython.array((10, 10), itemsize=sizeof(ext_dtype), format='f')
self.arr_float[:] = 0.0
self.arr_float[4, 4] = 2.0
self.arr_double = cython.array((10, 10), itemsize=sizeof(td_h_double), format='d')
self.arr_double[:] = 0.0
self.arr_double[4, 4] = 2.0
def test_external_dtype():
"""
>>> test_external_dtype()
2.0
2.0
"""
cdef TestExcClassExternalDtype obj = TestExcClassExternalDtype()
print obj.arr_float[4, 4]
print obj.arr_double[4, 4]
cdef class ExtClassMockedAttr(object):
cdef int[:, :] arr
def __init__(self):
self.arr = IntMockBuffer("self.arr", range(100), (10, 8))
self.arr[:] = 0
self.arr[4, 4] = 2
cdef int[:, :] _coerce_to_temp():
cdef ExtClassMockedAttr obj = ExtClassMockedAttr()
return obj.arr
def test_coerce_to_temp():
"""
>>> test_coerce_to_temp()
acquired self.arr
released self.arr
<BLANKLINE>
acquired self.arr
released self.arr
<BLANKLINE>
acquired self.arr
released self.arr
2
<BLANKLINE>
acquired self.arr
released self.arr
2
<BLANKLINE>
acquired self.arr
released self.arr
2
"""
_coerce_to_temp()[:] = 0
print
_coerce_to_temp()[...] = 0
print
print _coerce_to_temp()[4, 4]
print
print _coerce_to_temp()[..., 4][4]
print
print _coerce_to_temp()[4][4]
cdef float[:,::1] global_mv = array((10,10), itemsize=sizeof(float), format='f') cdef float[:,::1] global_mv = array((10,10), itemsize=sizeof(float), format='f')
global_mv = array((10,10), itemsize=sizeof(float), format='f') global_mv = array((10,10), itemsize=sizeof(float), format='f')
cdef object global_obj cdef object global_obj
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment