[pypy-commit] pypy numpypy-axisops: fix test_axis_iterator, start to see some results

mattip noreply at buildbot.pypy.org
Wed Dec 28 02:59:43 CET 2011


Author: mattip
Branch: numpypy-axisops
Changeset: r50917:4e517ebe55c0
Date: 2011-12-28 02:31 +0200
http://bitbucket.org/pypy/pypy/changeset/4e517ebe55c0/

Log:	fix test_axis_iterator, start to see some results

diff --git a/pypy/module/micronumpy/interp_iter.py b/pypy/module/micronumpy/interp_iter.py
--- a/pypy/module/micronumpy/interp_iter.py
+++ b/pypy/module/micronumpy/interp_iter.py
@@ -113,6 +113,7 @@
     """
     def __init__(self, arr_start, strides, backstrides, shape, dim=-1, slice_start=[]):
         self.shape = shape
+        self.shapelen = len(shape)
         self.indices = [0] * len(shape)
         self.done = False
         self.offset = arr_start
@@ -125,11 +126,12 @@
             for i in range(len(slice_start)):
                 self.offset += strides[i] * slice_start[i]
     def next(self, shapelen):
+        #shapelen will always be one less than self.shapelen
         offset = self.offset
-        indices = [0] * shapelen
-        for i in range(shapelen):
+        indices = [0] * self.shapelen
+        for i in range(self.shapelen):
             indices[i] = self.indices[i]
-        for i in range(shapelen - 1, -1, -1):
+        for i in range(self.shapelen - 1, -1, -1):
             if i == self.dim:
                 continue
             if indices[i] < self.shape[i] - 1:
@@ -147,6 +149,7 @@
         res.strides = self.strides
         res.backstrides = self.backstrides
         res.shape = self.shape
+        res.shapelen = self.shapelen
         res.dim = self.dim
         res.done = self.done
         return res
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
@@ -734,7 +734,7 @@
         self.child = None
 
 class Reduce(VirtualArray):
-    def __init__(self, ufunc, name, dim, res_dtype, values):
+    def __init__(self, ufunc, name, dim, res_dtype, values, identity=None):
         shape=values.shape[0:dim] + values.shape[dim+1:len(values.shape)]
         VirtualArray.__init__(self, name, shape, res_dtype)
         self.values = values
@@ -742,9 +742,11 @@
         self.ufunc = ufunc
         self.res_dtype = res_dtype
         self.dim = dim
+        self.identity = identity
 
     def _del_sources(self):
         self.values = None
+        pass
 
     def create_sig(self, res_shape):
         if self.forced_result is not None:
@@ -754,21 +756,37 @@
                            self.values.create_sig(res_shape))
 
     def compute(self):
-        result = W_NDimArray(self.size, self.shape, self.find_dtype())
+        dtype = self.res_dtype
+        result = W_NDimArray(self.size, self.shape, dtype)
         shapelen = len(result.shape)
+        objlen = len(self.values.shape)
+        target_len = self.values.shape[self.dim]
         #sig = self.find_sig(result.shape) ##Don't do this, it causes an infinite recursion
         sig = self.create_sig(result.shape)
         ri = ArrayIterator(self.size)
         si = axis_iter_from_arr(self.values, self.dim)
         while not ri.done():
-            #frame = sig.create_frame(self.values, chunks = [si.indices])
-            #Frame should be returning self.func applied to the axis starting at si.offset
-            frame = sig.create_frame(self.values, chunks = [])
-            val = sig.eval(frame, self.values).convert_to( self.find_dtype())
-            result.dtype.setitem(result.storage, ri.offset, val)
+            chunks = []
+            for i in range(objlen - 1, -1, -1):
+                if i==self.dim:
+                    chunks.append((0, target_len, 1, target_len))
+                else:
+                    chunks.append((si.indices[i], 0, 0, 1))
+            frame = sig.create_frame(self.values, 
+                         res_shape = [target_len], chunks = [chunks,])
+            if self.identity is None:
+                value = sig.eval(frame, self.values).convert_to(dtype)
+                frame.next(shapelen)
+            else:
+                value = self.identity.convert_to(dtype)
+            while not frame.done():
+                assert isinstance(sig, signature.ReduceSignature)
+                nextval = sig.eval(frame, self.values).convert_to(dtype)
+                value = sig.binfunc(dtype, value, nextval)
+                frame.next(shapelen)
+            result.dtype.setitem(result.storage, ri.offset, value)
             ri = ri.next(shapelen)
             si = si.next(shapelen)
-            frame = frame.next
         return result
 
 
diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py
--- a/pypy/module/micronumpy/interp_ufuncs.py
+++ b/pypy/module/micronumpy/interp_ufuncs.py
@@ -121,20 +121,20 @@
         size = obj.size
         dtype = find_unaryop_result_dtype(
             space, obj.find_dtype(),
-            promote_to_largest=True
+            promote_to_float=self.promote_to_float
         )
         shapelen = len(obj.shape)
+        if self.identity is None and size == 0:
+            raise operationerrfmt(space.w_ValueError, "zero-size array to "
+                    "%s.reduce without identity", self.name)
         if shapelen>1 and dim>=0:
             from pypy.module.micronumpy.interp_numarray import Reduce
-            return Reduce(self.func, self.name, dim, dtype, obj)
+            return Reduce(self.func, self.name, dim, dtype, obj, self.identity)
         sig = find_sig(ReduceSignature(self.func, self.name, dtype,
                                        ScalarSignature(dtype),
                                        obj.create_sig(obj.shape)), obj)
         frame = sig.create_frame(obj)
         if self.identity is None:
-            if size == 0:
-                raise operationerrfmt(space.w_ValueError, "zero-size array to "
-                    "%s.reduce without identity", self.name)
             value = sig.eval(frame, obj).convert_to(dtype)
             frame.next(shapelen)
         else:
diff --git a/pypy/module/micronumpy/test/test_iterators.py b/pypy/module/micronumpy/test/test_iterators.py
--- a/pypy/module/micronumpy/test/test_iterators.py
+++ b/pypy/module/micronumpy/test/test_iterators.py
@@ -1,5 +1,5 @@
 
-from pypy.module.micronumpy.interp_iter import AxisIterator
+from pypy.module.micronumpy.interp_iter import axis_iter_from_arr
 from pypy.module.micronumpy.interp_numarray import W_NDimArray
 
 class MockDtype(object):
@@ -9,50 +9,50 @@
 class TestAxisIteratorDirect(object):
     def test_axis_iterator(self):
         a = W_NDimArray(5*3, [5, 3], MockDtype(), 'C')
-        i = AxisIterator(a)
+        i = axis_iter_from_arr(a)
         ret = []
         while not i.done:
             ret.append(i.offset)
-            i = i.next()
+            i = i.next(1)
         assert ret == [0, 3, 6, 9, 12]
         a = W_NDimArray(7*5*3, [7, 5, 3], MockDtype(), 'C')
-        i = AxisIterator(a)
+        i = axis_iter_from_arr(a)
         ret = []
         while not i.done:
             ret.append(i.offset)
-            i = i.next()
+            i = i.next(1)
         assert ret == [3*v for v in range(7*5)]
-        i = AxisIterator(a,2)
+        i = axis_iter_from_arr(a,2)
         ret = []
         while not i.done:
             ret.append(i.offset)
-            i = i.next()
+            i = i.next(1)
         assert ret == [3*v for v in range(7*5)]
-        i = AxisIterator(a,1)
+        i = axis_iter_from_arr(a,1)
         ret = []
         while not i.done:
             ret.append(i.offset)
-            i = i.next()
+            i = i.next(1)
         assert ret == [ 0,  1,  2, 15, 16, 17, 30, 31, 32, 45, 46, 47,
                        60, 61, 62, 75, 76, 77, 90, 91, 92] 
     def test_axis_iterator_with_start(self):
         a = W_NDimArray(7*5*3, [7, 5, 3], MockDtype(), 'C')
-        i = AxisIterator(a, start=[0, 0, 0])
+        i = axis_iter_from_arr(a, start=[0, 0, 0])
         ret = []
         while not i.done:
             ret.append(i.offset)
-            i = i.next()
+            i = i.next(2)
         assert ret == [3*v for v in range(7*5)]
-        i = AxisIterator(a, start=[1, 1, 0])
+        i = axis_iter_from_arr(a, start=[1, 1, 0])
         ret = []
         while not i.done:
             ret.append(i.offset)
-            i = i.next()
+            i = i.next(2)
         assert ret == [3*v+18 for v in range(7*5)]
-        i = AxisIterator(a, 1, [2, 0, 2])
+        i = axis_iter_from_arr(a, 1, [2, 0, 2])
         ret = []
         while not i.done:
             ret.append(i.offset)
-            i = i.next()
+            i = i.next(2)
         assert ret == [v + 32 for v in [ 0,  1,  2, 15, 16, 17, 30, 31, 32,
                             45, 46, 47, 60, 61, 62, 75, 76, 77, 90, 91, 92]]
diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py
--- a/pypy/module/micronumpy/test/test_ufuncs.py
+++ b/pypy/module/micronumpy/test/test_ufuncs.py
@@ -348,9 +348,8 @@
     def test_reduceND(self):
         from numpypy import add, arange
         a = arange(12).reshape(3, 4)
-        assert add.reduce(a,1)[0] ==6
-        assert (add.reduce(a, 1) == [ 6, 22, 38]).all()
-        assert (add.reduce(a, 0) == add.reduce(a)).all()
+        assert (add.reduce(a, 0) == [12, 15, 18, 21]).all()
+        assert (add.reduce(a, 1) == [6.0, 22.0, 38.0]).all()
 
     def test_comparisons(self):
         import operator


More information about the pypy-commit mailing list