[pypy-commit] pypy numpy-back-to-applevel: shuffle stuff around

fijal noreply at buildbot.pypy.org
Sat Jan 21 17:03:23 CET 2012


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: numpy-back-to-applevel
Changeset: r51582:b31c0d563d03
Date: 2012-01-21 18:02 +0200
http://bitbucket.org/pypy/pypy/changeset/b31c0d563d03/

Log:	shuffle stuff around

diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py
--- a/pypy/module/micronumpy/interp_numarray.py
+++ b/pypy/module/micronumpy/interp_numarray.py
@@ -1,10 +1,11 @@
 from pypy.interpreter.baseobjspace import Wrappable
 from pypy.interpreter.error import OperationError, operationerrfmt
-from pypy.interpreter.gateway import interp2app, NoneNotWrapped, unwrap_spec
+from pypy.interpreter.gateway import interp2app, unwrap_spec
 from pypy.interpreter.typedef import TypeDef, GetSetProperty
-from pypy.module.micronumpy import interp_ufuncs, interp_dtype, signature,\
-     interp_boxes
-from pypy.module.micronumpy.strides import calculate_slice_strides
+from pypy.module.micronumpy import interp_ufuncs, interp_dtype, signature
+from pypy.module.micronumpy.strides import calculate_slice_strides,\
+     shape_agreement, find_shape_and_elems, get_shape_from_iterable,\
+     calc_new_strides
 from pypy.rlib import jit
 from pypy.rpython.lltypesystem import lltype, rffi
 from pypy.tool.sourcetools import func_with_new_name
@@ -60,176 +61,6 @@
     name='numpy_filterset',
 )
 
-def _find_shape_and_elems(space, w_iterable):
-    shape = [space.len_w(w_iterable)]
-    batch = space.listview(w_iterable)
-    while True:
-        new_batch = []
-        if not batch:
-            return shape, []
-        if not space.issequence_w(batch[0]):
-            for elem in batch:
-                if space.issequence_w(elem):
-                    raise OperationError(space.w_ValueError, space.wrap(
-                        "setting an array element with a sequence"))
-            return shape, batch
-        size = space.len_w(batch[0])
-        for w_elem in batch:
-            if not space.issequence_w(w_elem) or space.len_w(w_elem) != size:
-                raise OperationError(space.w_ValueError, space.wrap(
-                    "setting an array element with a sequence"))
-            new_batch += space.listview(w_elem)
-        shape.append(size)
-        batch = new_batch
-
-def shape_agreement(space, shape1, shape2):
-    ret = _shape_agreement(shape1, shape2)
-    if len(ret) < max(len(shape1), len(shape2)):
-        raise OperationError(space.w_ValueError,
-            space.wrap("operands could not be broadcast together with shapes (%s) (%s)" % (
-                ",".join([str(x) for x in shape1]),
-                ",".join([str(x) for x in shape2]),
-            ))
-        )
-    return ret
-
-def _shape_agreement(shape1, shape2):
-    """ Checks agreement about two shapes with respect to broadcasting. Returns
-    the resulting shape.
-    """
-    lshift = 0
-    rshift = 0
-    if len(shape1) > len(shape2):
-        m = len(shape1)
-        n = len(shape2)
-        rshift = len(shape2) - len(shape1)
-        remainder = shape1
-    else:
-        m = len(shape2)
-        n = len(shape1)
-        lshift = len(shape1) - len(shape2)
-        remainder = shape2
-    endshape = [0] * m
-    indices1 = [True] * m
-    indices2 = [True] * m
-    for i in range(m - 1, m - n - 1, -1):
-        left = shape1[i + lshift]
-        right = shape2[i + rshift]
-        if left == right:
-            endshape[i] = left
-        elif left == 1:
-            endshape[i] = right
-            indices1[i + lshift] = False
-        elif right == 1:
-            endshape[i] = left
-            indices2[i + rshift] = False
-        else:
-            return []
-            #raise OperationError(space.w_ValueError, space.wrap(
-            #    "frames are not aligned"))
-    for i in range(m - n):
-        endshape[i] = remainder[i]
-    return endshape
-
-def get_shape_from_iterable(space, old_size, w_iterable):
-    new_size = 0
-    new_shape = []
-    if space.isinstance_w(w_iterable, space.w_int):
-        new_size = space.int_w(w_iterable)
-        if new_size < 0:
-            new_size = old_size
-        new_shape = [new_size]
-    else:
-        neg_dim = -1
-        batch = space.listview(w_iterable)
-        new_size = 1
-        if len(batch) < 1:
-            if old_size == 1:
-                # Scalars can have an empty size.
-                new_size = 1
-            else:
-                new_size = 0
-        new_shape = []
-        i = 0
-        for elem in batch:
-            s = space.int_w(elem)
-            if s < 0:
-                if neg_dim >= 0:
-                    raise OperationError(space.w_ValueError, space.wrap(
-                             "can only specify one unknown dimension"))
-                s = 1
-                neg_dim = i
-            new_size *= s
-            new_shape.append(s)
-            i += 1
-        if neg_dim >= 0:
-            new_shape[neg_dim] = old_size / new_size
-            new_size *= new_shape[neg_dim]
-    if new_size != old_size:
-        raise OperationError(space.w_ValueError,
-                space.wrap("total size of new array must be unchanged"))
-    return new_shape
-
-# Recalculating strides. Find the steps that the iteration does for each
-# dimension, given the stride and shape. Then try to create a new stride that
-# fits the new shape, using those steps. If there is a shape/step mismatch
-# (meaning that the realignment of elements crosses from one step into another)
-# return None so that the caller can raise an exception.
-def calc_new_strides(new_shape, old_shape, old_strides):
-    # Assumes that prod(old_shape) == prod(new_shape), len(old_shape) > 1, and
-    # len(new_shape) > 0
-    steps = []
-    last_step = 1
-    oldI = 0
-    new_strides = []
-    if old_strides[0] < old_strides[-1]:
-        #Start at old_shape[0], old_stides[0]
-        for i in range(len(old_shape)):
-            steps.append(old_strides[i] / last_step)
-            last_step *= old_shape[i]
-        cur_step = steps[0]
-        n_new_elems_used = 1
-        n_old_elems_to_use = old_shape[0]
-        for s in new_shape:
-            new_strides.append(cur_step * n_new_elems_used)
-            n_new_elems_used *= s
-            while n_new_elems_used > n_old_elems_to_use:
-                oldI += 1
-                if steps[oldI] != steps[oldI - 1]:
-                    return None
-                n_old_elems_to_use *= old_shape[oldI]
-            if n_new_elems_used == n_old_elems_to_use:
-                oldI += 1
-                if oldI >= len(old_shape):
-                    continue
-                cur_step = steps[oldI]
-                n_old_elems_to_use *= old_shape[oldI]
-    else:
-        #Start at old_shape[-1], old_strides[-1]
-        for i in range(len(old_shape) - 1, -1, -1):
-            steps.insert(0, old_strides[i] / last_step)
-            last_step *= old_shape[i]
-        cur_step = steps[-1]
-        n_new_elems_used = 1
-        oldI = -1
-        n_old_elems_to_use = old_shape[-1]
-        for i in range(len(new_shape) - 1, -1, -1):
-            s = new_shape[i]
-            new_strides.insert(0, cur_step * n_new_elems_used)
-            n_new_elems_used *= s
-            while n_new_elems_used > n_old_elems_to_use:
-                oldI -= 1
-                if steps[oldI] != steps[oldI + 1]:
-                    return None
-                n_old_elems_to_use *= old_shape[oldI]
-            if n_new_elems_used == n_old_elems_to_use:
-                oldI -= 1
-                if oldI < -len(old_shape):
-                    continue
-                cur_step = steps[oldI]
-                n_old_elems_to_use *= old_shape[oldI]
-    return new_strides
-
 class BaseArray(Wrappable):
     _attrs_ = ["invalidates", "shape", 'size']
 
@@ -1264,7 +1095,7 @@
         if order != 'C':  # or order != 'F':
             raise operationerrfmt(space.w_ValueError, "Unknown order: %s",
                                   order)
-    shape, elems_w = _find_shape_and_elems(space, w_item_or_iterable)
+    shape, elems_w = find_shape_and_elems(space, w_item_or_iterable)
     # they come back in C order
     size = len(elems_w)
     if space.is_w(w_dtype, space.w_None):
diff --git a/pypy/module/micronumpy/strides.py b/pypy/module/micronumpy/strides.py
--- a/pypy/module/micronumpy/strides.py
+++ b/pypy/module/micronumpy/strides.py
@@ -37,3 +37,174 @@
     rstrides = [0] * (len(res_shape) - len(orig_shape)) + rstrides
     rbackstrides = [0] * (len(res_shape) - len(orig_shape)) + rbackstrides
     return rstrides, rbackstrides
+
+
+def find_shape_and_elems(space, w_iterable):
+    shape = [space.len_w(w_iterable)]
+    batch = space.listview(w_iterable)
+    while True:
+        new_batch = []
+        if not batch:
+            return shape, []
+        if not space.issequence_w(batch[0]):
+            for elem in batch:
+                if space.issequence_w(elem):
+                    raise OperationError(space.w_ValueError, space.wrap(
+                        "setting an array element with a sequence"))
+            return shape, batch
+        size = space.len_w(batch[0])
+        for w_elem in batch:
+            if not space.issequence_w(w_elem) or space.len_w(w_elem) != size:
+                raise OperationError(space.w_ValueError, space.wrap(
+                    "setting an array element with a sequence"))
+            new_batch += space.listview(w_elem)
+        shape.append(size)
+        batch = new_batch
+
+def shape_agreement(space, shape1, shape2):
+    ret = _shape_agreement(shape1, shape2)
+    if len(ret) < max(len(shape1), len(shape2)):
+        raise OperationError(space.w_ValueError,
+            space.wrap("operands could not be broadcast together with shapes (%s) (%s)" % (
+                ",".join([str(x) for x in shape1]),
+                ",".join([str(x) for x in shape2]),
+            ))
+        )
+    return ret
+
+def _shape_agreement(shape1, shape2):
+    """ Checks agreement about two shapes with respect to broadcasting. Returns
+    the resulting shape.
+    """
+    lshift = 0
+    rshift = 0
+    if len(shape1) > len(shape2):
+        m = len(shape1)
+        n = len(shape2)
+        rshift = len(shape2) - len(shape1)
+        remainder = shape1
+    else:
+        m = len(shape2)
+        n = len(shape1)
+        lshift = len(shape1) - len(shape2)
+        remainder = shape2
+    endshape = [0] * m
+    indices1 = [True] * m
+    indices2 = [True] * m
+    for i in range(m - 1, m - n - 1, -1):
+        left = shape1[i + lshift]
+        right = shape2[i + rshift]
+        if left == right:
+            endshape[i] = left
+        elif left == 1:
+            endshape[i] = right
+            indices1[i + lshift] = False
+        elif right == 1:
+            endshape[i] = left
+            indices2[i + rshift] = False
+        else:
+            return []
+            #raise OperationError(space.w_ValueError, space.wrap(
+            #    "frames are not aligned"))
+    for i in range(m - n):
+        endshape[i] = remainder[i]
+    return endshape
+
+def get_shape_from_iterable(space, old_size, w_iterable):
+    new_size = 0
+    new_shape = []
+    if space.isinstance_w(w_iterable, space.w_int):
+        new_size = space.int_w(w_iterable)
+        if new_size < 0:
+            new_size = old_size
+        new_shape = [new_size]
+    else:
+        neg_dim = -1
+        batch = space.listview(w_iterable)
+        new_size = 1
+        if len(batch) < 1:
+            if old_size == 1:
+                # Scalars can have an empty size.
+                new_size = 1
+            else:
+                new_size = 0
+        new_shape = []
+        i = 0
+        for elem in batch:
+            s = space.int_w(elem)
+            if s < 0:
+                if neg_dim >= 0:
+                    raise OperationError(space.w_ValueError, space.wrap(
+                             "can only specify one unknown dimension"))
+                s = 1
+                neg_dim = i
+            new_size *= s
+            new_shape.append(s)
+            i += 1
+        if neg_dim >= 0:
+            new_shape[neg_dim] = old_size / new_size
+            new_size *= new_shape[neg_dim]
+    if new_size != old_size:
+        raise OperationError(space.w_ValueError,
+                space.wrap("total size of new array must be unchanged"))
+    return new_shape
+
+# Recalculating strides. Find the steps that the iteration does for each
+# dimension, given the stride and shape. Then try to create a new stride that
+# fits the new shape, using those steps. If there is a shape/step mismatch
+# (meaning that the realignment of elements crosses from one step into another)
+# return None so that the caller can raise an exception.
+def calc_new_strides(new_shape, old_shape, old_strides):
+    # Assumes that prod(old_shape) == prod(new_shape), len(old_shape) > 1, and
+    # len(new_shape) > 0
+    steps = []
+    last_step = 1
+    oldI = 0
+    new_strides = []
+    if old_strides[0] < old_strides[-1]:
+        #Start at old_shape[0], old_stides[0]
+        for i in range(len(old_shape)):
+            steps.append(old_strides[i] / last_step)
+            last_step *= old_shape[i]
+        cur_step = steps[0]
+        n_new_elems_used = 1
+        n_old_elems_to_use = old_shape[0]
+        for s in new_shape:
+            new_strides.append(cur_step * n_new_elems_used)
+            n_new_elems_used *= s
+            while n_new_elems_used > n_old_elems_to_use:
+                oldI += 1
+                if steps[oldI] != steps[oldI - 1]:
+                    return None
+                n_old_elems_to_use *= old_shape[oldI]
+            if n_new_elems_used == n_old_elems_to_use:
+                oldI += 1
+                if oldI >= len(old_shape):
+                    continue
+                cur_step = steps[oldI]
+                n_old_elems_to_use *= old_shape[oldI]
+    else:
+        #Start at old_shape[-1], old_strides[-1]
+        for i in range(len(old_shape) - 1, -1, -1):
+            steps.insert(0, old_strides[i] / last_step)
+            last_step *= old_shape[i]
+        cur_step = steps[-1]
+        n_new_elems_used = 1
+        oldI = -1
+        n_old_elems_to_use = old_shape[-1]
+        for i in range(len(new_shape) - 1, -1, -1):
+            s = new_shape[i]
+            new_strides.insert(0, cur_step * n_new_elems_used)
+            n_new_elems_used *= s
+            while n_new_elems_used > n_old_elems_to_use:
+                oldI -= 1
+                if steps[oldI] != steps[oldI + 1]:
+                    return None
+                n_old_elems_to_use *= old_shape[oldI]
+            if n_new_elems_used == n_old_elems_to_use:
+                oldI -= 1
+                if oldI < -len(old_shape):
+                    continue
+                cur_step = steps[oldI]
+                n_old_elems_to_use *= old_shape[oldI]
+    return new_strides


More information about the pypy-commit mailing list