[pypy-commit] pypy default: merge numpy-refactor
bdkearns
noreply at buildbot.pypy.org
Thu Feb 27 13:17:41 CET 2014
Author: Brian Kearns <bdkearns at 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)
-
More information about the pypy-commit
mailing list