Permalink
Browse files

Allow strided memoryviews to be copied to contiguous memoryviews

  • Loading branch information...
1 parent 9536b62 commit 148c2904f7ccffab7feaff01c1ee2248eb705b24 @markflorisson committed May 28, 2012
Showing with 15 additions and 6 deletions.
  1. +6 −1 Cython/Compiler/ExprNodes.py
  2. +1 −3 Cython/Compiler/Nodes.py
  3. +3 −2 Cython/Compiler/PyrexTypes.py
  4. +5 −0 tests/compile/memoryview.pyx
@@ -220,6 +220,7 @@ class ExprNode(Node):
is_memview_index = False
is_memview_slice = False
is_memview_broadcast = False
+ is_memview_copy_assignment = False
is_slice = False
@@ -664,7 +665,8 @@ def coerce_to(self, dst_type, env):
"Cannot convert '%s' to memoryviewslice" %
(src_type,))
elif not src.type.conforms_to(dst_type,
- broadcast=self.is_memview_broadcast):
+ broadcast=self.is_memview_broadcast,
+ copying=self.is_memview_copy_assignment):
if src.type.dtype.same_as(dst_type.dtype):
msg = "Memoryview '%s' not conformable to memoryview '%s'."
tup = src.type, dst_type
@@ -2778,6 +2780,8 @@ def analyse_as_memview_scalar_assignment(self, rhs):
if lhs:
self.type = lhs.type
self.replacement_node = lhs
+ self.is_memview_copy_assignment = lhs.is_memview_copy_assignment
+ rhs.is_memview_copy_assignment = lhs.is_memview_copy_assignment
def wrap_in_nonecheck_node(self, env, getting):
if not env.directives['nonecheck'] or not self.base.may_be_none():
@@ -3420,6 +3424,7 @@ class MemoryCopySlice(MemoryCopyNode):
memslice1[:] = memslice2
"""
+ is_memview_copy_assignment = True
copy_slice_cname = "__pyx_memoryview_copy_contents"
def _generate_assignment_code(self, src, code):
View
@@ -4359,11 +4359,9 @@ def analyse_types(self, env, use_temp = 0):
is_index_node = isinstance(self.lhs, ExprNodes.IndexNode)
if is_index_node:
self.lhs.analyse_broadcast_operation(self.rhs)
-
self.lhs.analyse_as_memview_scalar_assignment(self.rhs)
- dtype = self.lhs.type
- self.rhs = self.rhs.coerce_to(dtype, env)
+ self.rhs = self.rhs.coerce_to(self.lhs.type, env)
if use_temp:
self.rhs = self.rhs.coerce_to_temp(env)
@@ -617,7 +617,7 @@ def get_entry(self, node, cname=None, type=None):
entry = Symtab.Entry(cname, cname, type, node.pos)
return MemoryView.MemoryViewSliceBufferEntry(entry)
- def conforms_to(self, dst, broadcast=False):
+ def conforms_to(self, dst, broadcast=False, copying=False):
'''
returns True if src conforms to dst, False otherwise.
@@ -647,7 +647,8 @@ def conforms_to(self, dst, broadcast=False):
dst_access, dst_packing = dst_spec
if src_access != dst_access and dst_access != 'full':
return False
- if src_packing != dst_packing and dst_packing != 'strided':
+ if (src_packing != dst_packing and
+ dst_packing != 'strided' and not copying):
return False
return True
@@ -0,0 +1,5 @@
+# mode: cmpile
+
+cdef double[::1] contig
+# see if we can assign a strided value to a contiguous one
+contig[:] = contig[::2]

0 comments on commit 148c290

Please sign in to comment.