Author: Brian Kearns <bdkea...@gmail.com> Branch: Changeset: r69512:ec929caa596e Date: 2014-02-27 07:15 -0500 http://bitbucket.org/pypy/pypy/changeset/ec929caa596e/
Log: merge numpy-refactor diff --git a/pypy/module/micronumpy/arrayops.py b/pypy/module/micronumpy/arrayops.py --- a/pypy/module/micronumpy/arrayops.py +++ b/pypy/module/micronumpy/arrayops.py @@ -8,6 +8,7 @@ shape_agreement_multiple + def where(space, w_arr, w_x=None, w_y=None): """where(condition, [x, y]) @@ -91,6 +92,7 @@ out = W_NDimArray.from_shape(space, shape, dtype) return loop.where(space, out, shape, arr, x, y, dtype) + def dot(space, w_obj1, w_obj2, w_out=None): w_arr = convert_to_array(space, w_obj1) if w_arr.is_scalar(): @@ -162,6 +164,7 @@ axis_start += arr.get_shape()[axis] return res + @unwrap_spec(repeats=int) def repeat(space, w_arr, repeats, w_axis): arr = convert_to_array(space, w_arr) @@ -186,9 +189,11 @@ Chunks(chunks).apply(space, w_res).implementation.setslice(space, arr) return w_res + def count_nonzero(space, w_obj): return space.wrap(loop.count_all_true(convert_to_array(space, w_obj))) + def choose(space, w_arr, w_choices, w_out, w_mode): arr = convert_to_array(space, w_arr) choices = [convert_to_array(space, w_item) for w_item @@ -208,6 +213,7 @@ loop.choose(space, arr, choices, shape, dtype, out, mode) return out + def put(space, w_arr, w_indices, w_values, w_mode): arr = convert_to_array(space, w_arr) mode = clipmode_converter(space, w_mode) @@ -256,6 +262,7 @@ arr.setitem(space, [index], dtype.coerce(space, value)) + def diagonal(space, arr, offset, axis1, axis2): shape = arr.get_shape() shapelen = len(shape) diff --git a/pypy/module/micronumpy/boxes.py b/pypy/module/micronumpy/boxes.py --- a/pypy/module/micronumpy/boxes.py +++ b/pypy/module/micronumpy/boxes.py @@ -69,6 +69,7 @@ ret = space.newtuple([scalar, space.newtuple([space.wrap(self._get_dtype(space)), space.wrap(self.raw_str())])]) return ret + class PrimitiveBox(Box): _mixin_ = True _immutable_fields_ = ['value'] @@ -93,6 +94,7 @@ lltype.free(value, flavor="raw") return ret + class ComplexBox(Box): _mixin_ = True _immutable_fields_ = ['real', 'imag'] @@ -360,6 +362,7 @@ return self.get_dtype(space).itemtype.imag(self) w_flags = None + def descr_get_flags(self, space): if self.w_flags is None: self.w_flags = W_FlagsObject(self) diff --git a/pypy/module/micronumpy/concrete.py b/pypy/module/micronumpy/concrete.py --- a/pypy/module/micronumpy/concrete.py +++ b/pypy/module/micronumpy/concrete.py @@ -276,6 +276,17 @@ backstrides) return loop.setslice(space, self.get_shape(), impl, self) + def create_iter(self, shape=None, backward_broadcast=False): + if shape is not None and \ + support.product(shape) > support.product(self.get_shape()): + r = calculate_broadcast_strides(self.get_strides(), + self.get_backstrides(), + self.get_shape(), shape, + backward_broadcast) + return iter.MultiDimViewIterator(self, self.start, + r[0], r[1], shape) + return iter.ArrayIterator(self) + def create_axis_iter(self, shape, dim, cum): return iter.AxisIterator(self, shape, dim, cum) @@ -335,26 +346,6 @@ self.backstrides = backstrides self.storage = storage - def create_iter(self, shape=None, backward_broadcast=False, require_index=False): - if shape is not None and \ - support.product(shape) > support.product(self.get_shape()): - r = calculate_broadcast_strides(self.get_strides(), - self.get_backstrides(), - self.get_shape(), shape, - backward_broadcast) - return iter.MultiDimViewIterator(self, self.start, - r[0], r[1], shape) - if not require_index: - return iter.ConcreteArrayIterator(self) - if len(self.get_shape()) <= 1: - return iter.OneDimViewIterator(self, self.start, - self.get_strides(), - self.get_shape()) - return iter.MultiDimViewIterator(self, self.start, - self.get_strides(), - self.get_backstrides(), - self.get_shape()) - def fill(self, space, box): self.dtype.itemtype.fill(self.storage, self.dtype.elsize, box, 0, self.size, 0) @@ -440,24 +431,6 @@ def fill(self, space, box): loop.fill(self, box.convert_to(space, self.dtype)) - def create_iter(self, shape=None, backward_broadcast=False, require_index=False): - if shape is not None and \ - support.product(shape) > support.product(self.get_shape()): - r = calculate_broadcast_strides(self.get_strides(), - self.get_backstrides(), - self.get_shape(), shape, - backward_broadcast) - return iter.MultiDimViewIterator(self, self.start, - r[0], r[1], shape) - if len(self.get_shape()) <= 1: - return iter.OneDimViewIterator(self, self.start, - self.get_strides(), - self.get_shape()) - return iter.MultiDimViewIterator(self, self.start, - self.get_strides(), - self.get_backstrides(), - self.get_shape()) - def set_shape(self, space, orig_array, new_shape): if len(self.get_shape()) < 2 or self.size == 0: # TODO: this code could be refactored into calc_strides diff --git a/pypy/module/micronumpy/constants.py b/pypy/module/micronumpy/constants.py --- a/pypy/module/micronumpy/constants.py +++ b/pypy/module/micronumpy/constants.py @@ -57,7 +57,7 @@ INTPLTR = 'p' UINTPLTR = 'P' -GENBOOLLTR ='b' +GENBOOLLTR = 'b' SIGNEDLTR = 'i' UNSIGNEDLTR = 'u' FLOATINGLTR = 'f' diff --git a/pypy/module/micronumpy/flagsobj.py b/pypy/module/micronumpy/flagsobj.py --- a/pypy/module/micronumpy/flagsobj.py +++ b/pypy/module/micronumpy/flagsobj.py @@ -6,9 +6,13 @@ class W_FlagsObject(W_Root): def __init__(self, arr): - self.arr = arr self.flags = 0 + def descr__new__(space, w_subtype): + self = space.allocate_instance(W_FlagsObject, w_subtype) + W_FlagsObject.__init__(self, None) + return self + def descr_get_contiguous(self, space): return space.w_True @@ -60,6 +64,8 @@ W_FlagsObject.typedef = TypeDef("flagsobj", __module__ = "numpy", + __new__ = interp2app(W_FlagsObject.descr__new__.im_func), + __getitem__ = interp2app(W_FlagsObject.descr_getitem), __setitem__ = interp2app(W_FlagsObject.descr_setitem), __eq__ = interp2app(W_FlagsObject.descr_eq), diff --git a/pypy/module/micronumpy/flatiter.py b/pypy/module/micronumpy/flatiter.py --- a/pypy/module/micronumpy/flatiter.py +++ b/pypy/module/micronumpy/flatiter.py @@ -19,7 +19,7 @@ def get_shape(self): return self.shape - def create_iter(self, shape=None, backward_broadcast=False, require_index=False): + def create_iter(self, shape=None, backward_broadcast=False): assert isinstance(self.base(), W_NDimArray) return self.base().create_iter() @@ -33,7 +33,6 @@ def reset(self): self.iter = self.base.create_iter() - self.index = 0 def descr_len(self, space): return space.wrap(self.base.get_size()) @@ -43,14 +42,13 @@ raise OperationError(space.w_StopIteration, space.w_None) w_res = self.iter.getitem() self.iter.next() - self.index += 1 return w_res def descr_index(self, space): - return space.wrap(self.index) + return space.wrap(self.iter.index) def descr_coords(self, space): - coords = self.base.to_coords(space, space.wrap(self.index)) + coords = self.base.to_coords(space, space.wrap(self.iter.index)) return space.newtuple([space.wrap(c) for c in coords]) def descr_getitem(self, space, w_idx): diff --git a/pypy/module/micronumpy/iter.py b/pypy/module/micronumpy/iter.py --- a/pypy/module/micronumpy/iter.py +++ b/pypy/module/micronumpy/iter.py @@ -37,7 +37,7 @@ All the calculations happen in next() next_skip_x(steps) tries to do the iteration for a number of steps at once, -but then we cannot gaurentee that we only overflow one single shape +but then we cannot guarantee that we only overflow one single shape dimension, perhaps we could overflow times in one big step. """ from rpython.rlib import jit @@ -78,28 +78,41 @@ return [space.wrap(self.indexes[i]) for i in range(shapelen)] -class BaseArrayIterator(object): - def next(self): - raise NotImplementedError # purely abstract base class - - def setitem(self, elem): - raise NotImplementedError - - def set_scalar_object(self, value): - raise NotImplementedError # works only on scalars - - -class ConcreteArrayIterator(BaseArrayIterator): - _immutable_fields_ = ['array', 'skip', 'size'] - +class ArrayIterator(object): def __init__(self, array): self.array = array - self.offset = 0 - self.skip = array.dtype.elsize - self.size = array.size + self.start = array.start + self.size = array.get_size() + self.ndim_m1 = len(array.shape) - 1 + self.shape_m1 = [s - 1 for s in array.shape] + self.strides = array.strides[:] + self.backstrides = array.backstrides[:] + self.reset() - def setitem(self, elem): - self.array.setitem(self.offset, elem) + def reset(self): + self.index = 0 + self.indices = [0] * (self.ndim_m1 + 1) + self.offset = self.start + + @jit.unroll_safe + def next(self): + self.index += 1 + for i in xrange(self.ndim_m1, -1, -1): + if self.indices[i] < self.shape_m1[i]: + self.indices[i] += 1 + self.offset += self.strides[i] + break + else: + self.indices[i] = 0 + self.offset -= self.backstrides[i] + + def next_skip_x(self, step): + # XXX implement + for _ in range(step): + self.next() + + def done(self): + return self.index >= self.size def getitem(self): return self.array.getitem(self.offset) @@ -107,52 +120,11 @@ def getitem_bool(self): return self.array.getitem_bool(self.offset) - def next(self): - self.offset += self.skip + def setitem(self, elem): + self.array.setitem(self.offset, elem) - def next_skip_x(self, x): - self.offset += self.skip * x - def done(self): - return self.offset >= self.size - - def reset(self): - self.offset %= self.size - - -class OneDimViewIterator(ConcreteArrayIterator): - def __init__(self, array, start, strides, shape): - self.array = array - self.offset = start - self.index = 0 - assert len(strides) == len(shape) - if len(shape) == 0: - self.skip = array.dtype.elsize - self.size = 1 - else: - assert len(shape) == 1 - self.skip = strides[0] - self.size = shape[0] - - def next(self): - self.offset += self.skip - self.index += 1 - - def next_skip_x(self, x): - self.offset += self.skip * x - self.index += x - - def done(self): - return self.index >= self.size - - def reset(self): - self.offset %= self.size - - def get_index(self, d): - return self.index - - -class MultiDimViewIterator(ConcreteArrayIterator): +class MultiDimViewIterator(ArrayIterator): def __init__(self, array, start, strides, backstrides, shape): self.indexes = [0] * len(shape) self.array = array @@ -201,11 +173,8 @@ def reset(self): self.offset %= self.size - def get_index(self, d): - return self.indexes[d] - -class AxisIterator(BaseArrayIterator): +class AxisIterator(ArrayIterator): def __init__(self, array, shape, dim, cumulative): self.shape = shape strides = array.get_strides() @@ -227,12 +196,6 @@ 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): 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 @@ -331,7 +331,7 @@ def nonzero(res, arr, box): res_iter = res.create_iter() - arr_iter = arr.create_iter(require_index=True) + arr_iter = arr.create_iter() shapelen = len(arr.shape) dtype = arr.dtype dims = range(shapelen) @@ -339,7 +339,7 @@ nonzero_driver.jit_merge_point(shapelen=shapelen, dims=dims, dtype=dtype) if arr_iter.getitem_bool(): for d in dims: - res_iter.setitem(box(arr_iter.get_index(d))) + res_iter.setitem(box(arr_iter.indices[d])) res_iter.next() arr_iter.next() return res @@ -435,8 +435,6 @@ arr_iter.next_skip_x(step) length -= 1 val_iter.next() - # WTF numpy? - val_iter.reset() fromstring_driver = jit.JitDriver(name = 'numpy_fromstring', greens = ['itemsize', 'dtype'], diff --git a/pypy/module/micronumpy/ndarray.py b/pypy/module/micronumpy/ndarray.py --- a/pypy/module/micronumpy/ndarray.py +++ b/pypy/module/micronumpy/ndarray.py @@ -44,6 +44,7 @@ "objects are not aligned")) return out_shape, right_critical_dim + class __extend__(W_NDimArray): @jit.unroll_safe def descr_get_shape(self, space): @@ -280,11 +281,10 @@ s.append(suffix) return s.build() - def create_iter(self, shape=None, backward_broadcast=False, require_index=False): + def create_iter(self, shape=None, backward_broadcast=False): assert isinstance(self.implementation, BaseConcreteArray) return self.implementation.create_iter( - shape=shape, backward_broadcast=backward_broadcast, - require_index=require_index) + shape=shape, backward_broadcast=backward_broadcast) def create_axis_iter(self, shape, dim, cum): return self.implementation.create_axis_iter(shape, dim, cum) @@ -1126,6 +1126,7 @@ return w_obj pass + @unwrap_spec(offset=int) def descr_new_array(space, w_subtype, w_shape, w_dtype=None, w_buffer=None, offset=0, w_strides=None, w_order=None): @@ -1176,6 +1177,7 @@ space.wrap('__array_finalize__')), w_subtype) return w_ret + @unwrap_spec(addr=int) def descr__from_shape_and_storage(space, w_cls, w_shape, addr, w_dtype, w_subtype=None): """ diff --git a/pypy/module/micronumpy/test/test_flagsobj.py b/pypy/module/micronumpy/test/test_flagsobj.py --- a/pypy/module/micronumpy/test/test_flagsobj.py +++ b/pypy/module/micronumpy/test/test_flagsobj.py @@ -2,6 +2,14 @@ class AppTestFlagsObj(BaseNumpyAppTest): + def test_init(self): + import numpy as np + a = np.array([1,2,3]) + assert a.flags['C'] is True + b = type(a.flags)() + assert b is not a.flags + assert b['C'] is True + def test_repr(self): import numpy as np a = np.array([1,2,3]) diff --git a/pypy/module/micronumpy/ufuncs.py b/pypy/module/micronumpy/ufuncs.py --- a/pypy/module/micronumpy/ufuncs.py +++ b/pypy/module/micronumpy/ufuncs.py @@ -9,9 +9,11 @@ from pypy.module.micronumpy.base import convert_to_array, W_NDimArray from pypy.module.micronumpy.strides import shape_agreement + def done_if_true(dtype, val): return dtype.itemtype.bool(val) + def done_if_false(dtype, val): return not dtype.itemtype.bool(val) @@ -544,6 +546,7 @@ dtypenum += 2 return descriptor.get_dtype_cache(space).dtypes_by_num[dtypenum] + @jit.unroll_safe def find_unaryop_result_dtype(space, dt, promote_to_float=False, promote_bools=False, promote_to_largest=False): @@ -570,6 +573,7 @@ return dtype return dt + def find_dtype_for_scalar(space, w_obj, current_guess=None): bool_dtype = descriptor.get_dtype_cache(space).w_booldtype long_dtype = descriptor.get_dtype_cache(space).w_longdtype @@ -611,9 +615,9 @@ 'unable to create dtype from objects, "%T" instance not ' 'supported', w_obj) + def ufunc_dtype_caller(space, ufunc_name, op_name, argcount, comparison_func, bool_result): - dtype_cache = descriptor.get_dtype_cache(space) def get_op(dtype): try: return getattr(dtype.itemtype, op_name) @@ -621,6 +625,7 @@ raise oefmt(space.w_NotImplementedError, "%s not implemented for %s", ufunc_name, dtype.get_name()) + dtype_cache = descriptor.get_dtype_cache(space) if argcount == 1: def impl(res_dtype, value): res = get_op(res_dtype)(value) @@ -762,6 +767,6 @@ ufunc = W_Ufunc2(func, ufunc_name, **extra_kwargs) setattr(self, ufunc_name, ufunc) + def get(space): return space.fromcache(UfuncState) - _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit