[pypy-commit] pypy numpy-refactor: axis reduce, not working yet
fijal
noreply at buildbot.pypy.org
Wed Sep 5 12:53:23 CEST 2012
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: numpy-refactor
Changeset: r57143:e6845da36040
Date: 2012-09-05 12:52 +0200
http://bitbucket.org/pypy/pypy/changeset/e6845da36040/
Log: axis reduce, not working yet
diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py
--- a/pypy/module/micronumpy/arrayimpl/concrete.py
+++ b/pypy/module/micronumpy/arrayimpl/concrete.py
@@ -74,6 +74,47 @@
def done(self):
return self._done
+class AxisIterator(base.BaseArrayIterator):
+ def __init__(self, array, shape, dim):
+ self.shape = shape
+ strides = array.strides
+ backstrides = array.backstrides
+ if len(shape) == len(strides):
+ # keepdims = True
+ self.strides = strides[:dim] + [0] + strides[dim + 1:]
+ self.backstrides = backstrides[:dim] + [0] + backstrides[dim + 1:]
+ else:
+ self.strides = strides[:dim] + [0] + strides[dim:]
+ self.backstrides = backstrides[:dim] + [0] + backstrides[dim:]
+ self.first_line = True
+ self.indices = [0] * len(shape)
+ self._done = False
+ self.offset = array.start
+ self.dim = dim
+ self.array = array
+
+ def setitem(self, elem):
+ self.array.setitem(self.offset, elem)
+
+ def getitem(self):
+ return self.array.getitem(self.offset)
+
+ @jit.unroll_safe
+ def next(self):
+ for i in range(len(self.shape) - 1, -1, -1):
+ if self.indices[i] < self.shape[i] - 1:
+ if i == self.dim:
+ self.first_line = False
+ self.indices[i] += 1
+ self.offset += self.strides[i]
+ break
+ else:
+ if i == self.dim:
+ self.first_line = True
+ self.indices[i] = 0
+ self.offset -= self.backstrides[i]
+ else:
+ self._done = True
def int_w(space, w_obj):
# a special version that respects both __index__ and __int__
@@ -238,6 +279,9 @@
backstrides)
return loop.setslice(self.shape, impl, self)
+ def create_axis_iter(self, shape, dim):
+ return AxisIterator(self, shape, dim)
+
class ConcreteArray(BaseConcreteArray):
def __init__(self, shape, dtype, order, strides, backstrides):
self.shape = shape
diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py
--- a/pypy/module/micronumpy/arrayimpl/scalar.py
+++ b/pypy/module/micronumpy/arrayimpl/scalar.py
@@ -70,3 +70,5 @@
def reshape(self, space, new_shape):
return self.set_shape(space, new_shape)
+ def create_axis_iter(self, shape, dim):
+ raise Exception("axis iter should not happen on scalar")
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
@@ -90,6 +90,9 @@
def create_iter(self, shape):
return self.implementation.create_iter(shape)
+ def create_axis_iter(self, shape, dim):
+ return self.implementation.create_axis_iter(shape, dim)
+
def is_scalar(self):
return self.implementation.is_scalar()
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
@@ -171,7 +171,9 @@
else:
shape = obj_shape[:axis] + obj_shape[axis + 1:]
if out:
- #Test for shape agreement
+ # Test for shape agreement
+ # XXX maybe we need to do broadcasting here, although I must
+ # say I don't understand the details for axis reduce
if len(out.get_shape()) > len(shape):
raise operationerrfmt(space.w_ValueError,
'output parameter for reduction operation %s' +
@@ -187,14 +189,11 @@
",".join([str(x) for x in shape]),
",".join([str(x) for x in out.get_shape()]),
)
- #Test for dtype agreement, perhaps create an itermediate
- #if out.dtype != dtype:
- # raise OperationError(space.w_TypeError, space.wrap(
- # "mismatched dtypes"))
- return self.do_axis_reduce(obj, out.find_dtype(), axis, out)
+ dtype = out.get_dtype()
else:
- result = W_NDimArray.from_shape(shape, dtype)
- return self.do_axis_reduce(obj, dtype, axis, result)
+ out = W_NDimArray.from_shape(shape, dtype)
+ return loop.do_axis_reduce(shape, self.func, obj, dtype, axis, out,
+ self.identity)
if out:
if len(out.get_shape())>0:
raise operationerrfmt(space.w_ValueError, "output parameter "
@@ -208,14 +207,6 @@
return out
return res
- def do_axis_reduce(self, obj, dtype, axis, result):
- xxx
- from pypy.module.micronumpy.interp_numarray import AxisReduce
- arr = AxisReduce(self.func, self.name, self.identity, obj.shape, dtype,
- result, obj, axis)
- loop.compute(arr)
- return arr.left
-
class W_Ufunc1(W_Ufunc):
argcount = 1
diff --git a/pypy/module/micronumpy/loop.py b/pypy/module/micronumpy/loop.py
--- a/pypy/module/micronumpy/loop.py
+++ b/pypy/module/micronumpy/loop.py
@@ -21,7 +21,7 @@
out_iter.next()
return out
-def call1(shape, func, name , calc_dtype, res_dtype, w_obj, out):
+def call1(shape, func, name, calc_dtype, res_dtype, w_obj, out):
if out is None:
out = W_NDimArray.from_shape(shape, res_dtype)
obj_iter = w_obj.create_iter(shape)
@@ -82,3 +82,23 @@
x_iter.next()
y_iter.next()
return out
+
+def do_axis_reduce(shape, func, arr, dtype, axis, out, identity):
+ import pdb
+ pdb.set_trace()
+ out_iter = out.create_iter(shape)
+ arr_iter = arr.create_axis_iter(shape, axis)
+ if identity is not None:
+ identity = identity.convert_to(dtype)
+ while not out_iter.done():
+ w_val = arr_iter.getitem().convert_to(dtype)
+ if arr_iter.first_line:
+ if identity is not None:
+ w_val = func(dtype, identity, w_val)
+ else:
+ cur = out_iter.getitem()
+ w_val = func(dtype, cur, w_val)
+ out_iter.setitem(w_val)
+ arr_iter.next()
+ out_iter.next()
+ return out
diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py
--- a/pypy/module/micronumpy/test/test_numarray.py
+++ b/pypy/module/micronumpy/test/test_numarray.py
@@ -2,7 +2,6 @@
import py, sys
from pypy.conftest import option
-from pypy.interpreter.error import OperationError
from pypy.module.micronumpy.appbridge import get_appbridge_cache
from pypy.module.micronumpy.iter import Chunk, Chunks
from pypy.module.micronumpy.interp_numarray import W_NDimArray
@@ -1083,7 +1082,7 @@
assert a[:4].mean() == 1.5
a = array(range(105)).reshape(3, 5, 7)
b = a.mean(axis=0)
- b[0, 0]==35.
+ assert b[0, 0] == 35.
assert a.mean(axis=0)[0, 0] == 35
assert (b == array(range(35, 70), dtype=float).reshape(5, 7)).all()
assert (a.mean(2) == array(range(0, 15), dtype=float).reshape(3, 5) * 7 + 3).all()
More information about the pypy-commit
mailing list