[pypy-commit] pypy numpy-refactor: beat it until getitem kinda works
fijal
noreply at buildbot.pypy.org
Thu Aug 30 15:25:12 CEST 2012
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: numpy-refactor
Changeset: r56933:b56af48f1efe
Date: 2012-08-30 15:19 +0200
http://bitbucket.org/pypy/pypy/changeset/b56af48f1efe/
Log: beat it until getitem kinda works
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
@@ -1,6 +1,8 @@
from pypy.module.micronumpy.arrayimpl import base
from pypy.module.micronumpy import support
+from pypy.interpreter.error import OperationError, operationerrfmt
+from pypy.rlib import jit
class ConcreteArrayIterator(base.BaseArrayIterator):
def __init__(self, array):
@@ -14,7 +16,7 @@
self.dtype.setitem(self.array, self.offset, elem)
def getitem(self):
- return self.dtype.getitem(self.array, self.offset)
+ return self.array.getitem(self.offset)
def next(self):
self.offset += self.element_size
@@ -38,7 +40,14 @@
backstrides.reverse()
return strides, backstrides
+def int_w(space, w_obj):
+ # a special version that respects both __index__ and __int__
+ # XXX add __index__ support
+ return space.int_w(space.int(w_obj))
+
class ConcreteArray(base.BaseArrayImplementation):
+ start = 0
+
def __init__(self, shape, dtype, order):
self.shape = shape
self.size = support.product(shape) * dtype.get_size()
@@ -52,3 +61,57 @@
def create_iter(self):
return ConcreteArrayIterator(self)
+
+ def getitem(self, index):
+ return self.dtype.getitem(self, index)
+
+ # -------------------- applevel get/setitem -----------------------
+
+ @jit.unroll_safe
+ def _lookup_by_index(self, space, view_w):
+ item = self.start
+ for i, w_index in enumerate(view_w):
+ if space.isinstance_w(w_index, space.w_slice):
+ raise IndexError
+ idx = int_w(space, w_index)
+ if idx < 0:
+ idx = self.shape[i] + id
+ if idx < 0 or idx >= self.shape[0]:
+ raise operationerrfmt(space.w_IndexError,
+ "index (%d) out of range (0<=index<%d", i, self.shape[i],
+ )
+ item += idx * self.strides[i]
+ return item
+
+ def _single_item_index(self, space, w_idx):
+ """ Return an index of single item if possible, otherwise raises
+ IndexError
+ """
+ if (space.isinstance_w(w_idx, space.w_str) or
+ space.isinstance_w(w_idx, space.w_slice) or
+ space.is_w(w_idx, space.w_None)):
+ raise IndexError
+ shape_len = len(self.shape)
+ if shape_len == 0:
+ raise OperationError(space.w_IndexError, space.wrap(
+ "0-d arrays can't be indexed"))
+ if space.isinstance_w(w_idx, space.w_tuple):
+ view_w = space.fixedview(w_idx)
+ if len(view_w) < shape_len:
+ raise IndexError
+ if len(view_w) > shape_len:
+ raise OperationError(space.w_IndexError,
+ space.wrap("invalid index"))
+ return self._lookup_by_index(space, view_w)
+ idx = int_w(space, w_idx)
+ return self._lookup_by_index(space, [space.wrap(idx)])
+
+ def descr_getitem(self, space, w_index):
+ try:
+ item = self._single_item_index(space, w_index)
+ return self.getitem(item)
+ except IndexError:
+ # not a single result
+ chunks = self._prepare_slice_args(space, w_index)
+ return chunks.apply(self)
+
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
@@ -6,9 +6,13 @@
def __init__(self, dtype):
self.value = None
+ self.dtype = dtype
def get_shape(self):
return []
def set_scalar_value(self, value):
self.value = value
+
+ def get_scalar_value(self):
+ return self.value
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
@@ -19,7 +19,7 @@
def scalar_w(space, dtype, w_object):
arr = W_NDimArray([], dtype)
- arr.implementation.set_scalar_value(w_object)
+ arr.implementation.set_scalar_value(dtype.coerce(space, w_object))
return arr
class W_NDimArray(Wrappable):
@@ -50,12 +50,21 @@
def descr_get_ndim(self, space):
return space.wrap(len(self.get_shape()))
+ def descr_getitem(self, space, w_idx):
+ if (isinstance(w_idx, W_NDimArray) and w_idx.get_shape() == self.get_shape() and
+ w_idx.get_dtype().is_bool_type()):
+ return self.getitem_filter(space, w_idx)
+ return self.implementation.descr_getitem(space, w_idx)
+
def create_iter(self):
return self.implementation.create_iter()
def is_scalar(self):
return self.implementation.is_scalar
+ def get_scalar_value(self):
+ return self.implementation.get_scalar_value()
+
def _binop_impl(ufunc_name):
def impl(self, space, w_other, w_out=None):
return getattr(interp_ufuncs.get(space), ufunc_name).call(space,
@@ -78,6 +87,8 @@
__add__ = interp2app(W_NDimArray.descr_add),
+ __getitem__ = interp2app(W_NDimArray.descr_getitem),
+
dtype = GetSetProperty(W_NDimArray.descr_get_dtype),
shape = GetSetProperty(W_NDimArray.descr_get_shape,
W_NDimArray.descr_set_shape),
@@ -94,7 +105,10 @@
def array(space, w_object, w_dtype=None, copy=True, w_order=None, subok=False,
ndmin=0):
if not space.issequence_w(w_object):
- dtype = decode_w_dtype(space, w_dtype)
+ if w_dtype is None or space.is_w(w_dtype, space.w_None):
+ w_dtype = interp_ufuncs.find_dtype_for_scalar(space, w_object)
+ dtype = space.interp_w(interp_dtype.W_Dtype,
+ space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype))
return scalar_w(space, dtype, w_object)
if w_order is None or space.is_w(w_order, space.w_None):
order = 'C'
@@ -130,8 +144,15 @@
arr_iter.next()
return arr
-def zeros(space):
- pass
+ at unwrap_spec(order=str)
+def zeros(space, w_shape, w_dtype=None, order='C'):
+ dtype = space.interp_w(interp_dtype.W_Dtype,
+ space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype)
+ )
+ shape = _find_shape(space, w_shape)
+ if not shape:
+ return scalar_w(space, dtype, space.wrap(0))
+ return space.wrap(W_NDimArray(shape, dtype=dtype, order=order))
def ones(space):
pass
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
@@ -323,13 +323,14 @@
res_dtype = calc_dtype
if w_lhs.is_scalar() and w_rhs.is_scalar():
arr = self.func(calc_dtype,
- w_lhs.value.convert_to(calc_dtype),
- w_rhs.value.convert_to(calc_dtype)
+ w_lhs.get_scalar_value().convert_to(calc_dtype),
+ w_rhs.get_scalar_value().convert_to(calc_dtype)
)
- if out.is_scalar():
- out.set_value(arr)
- elif isinstance(out, W_NDimArray):
- out.fill(space, arr)
+ if isinstance(out, W_NDimArray):
+ if out.is_scalar():
+ out.set_scalar_value(arr)
+ else:
+ out.fill(space, arr)
else:
out = arr
return space.wrap(out)
diff --git a/pypy/module/micronumpy/support.py b/pypy/module/micronumpy/support.py
--- a/pypy/module/micronumpy/support.py
+++ b/pypy/module/micronumpy/support.py
@@ -9,14 +9,16 @@
return i
def convert_to_array(space, w_obj):
- from pypy.module.micronumpy.interp_numarray import W_NDimArray, array
+ from pypy.module.micronumpy.interp_numarray import W_NDimArray, array,\
+ scalar_w
+ from pypy.module.micronumpy import interp_ufuncs
+
if isinstance(w_obj, W_NDimArray):
return w_obj
elif space.issequence_w(w_obj):
# Convert to array.
return array(space, w_obj, w_order=None)
else:
- xxxx
# If it's a scalar
dtype = interp_ufuncs.find_dtype_for_scalar(space, w_obj)
return scalar_w(space, dtype, w_obj)
More information about the pypy-commit
mailing list