[pypy-commit] pypy refactor-signature: Refactor a bit - now ConcreteArray is something with strides, everything
fijal
noreply at buildbot.pypy.org
Fri Dec 16 12:35:47 CET 2011
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: refactor-signature
Changeset: r50603:8ac7503b0bf3
Date: 2011-12-16 13:34 +0200
http://bitbucket.org/pypy/pypy/changeset/8ac7503b0bf3/
Log: Refactor a bit - now ConcreteArray is something with strides,
everything else has no strides
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
@@ -203,37 +203,16 @@
return new_strides
class BaseArray(Wrappable):
- _attrs_ = ["invalidates", "shape", "strides", "backstrides",
- "start", 'order']
+ _attrs_ = ["invalidates", "shape"]
- _immutable_fields_ = ['start', "order"]
+ _immutable_fields_ = []
strides = None
start = 0
- def __init__(self, shape, order):
+ def __init__(self, shape):
self.invalidates = []
self.shape = shape
- self.order = order
- if self.strides is None:
- self.calc_strides(shape)
-
- def calc_strides(self, shape):
- strides = []
- backstrides = []
- s = 1
- shape_rev = shape[:]
- if self.order == 'C':
- shape_rev.reverse()
- for sh in shape_rev:
- strides.append(s)
- backstrides.append(s * (sh - 1))
- s *= sh
- if self.order == 'C':
- strides.reverse()
- backstrides.reverse()
- self.strides = strides[:]
- self.backstrides = backstrides[:]
def invalidated(self):
if self.invalidates:
@@ -403,7 +382,10 @@
concrete = self.get_concrete()
new_shape = get_shape_from_iterable(space,
concrete.find_size(), w_iterable)
- concrete.setshape(space, new_shape)
+ if isinstance(self, ConcreteArray):
+ # scalars don't have to do anything, just check if the shape
+ # is still empty
+ concrete.setshape(space, new_shape)
def descr_get_size(self, space):
return space.wrap(self.find_size())
@@ -556,10 +538,8 @@
"""
shape_len = len(self.shape)
if shape_len == 0:
- if not space.isinstance_w(w_idx, space.w_int):
- raise OperationError(space.w_IndexError, space.wrap(
- "wrong index"))
- return True
+ raise OperationError(space.w_IndexError, space.wrap(
+ "0-d arrays can't be indexed"))
if shape_len == 1:
if space.isinstance_w(w_idx, space.w_int):
return True
@@ -590,6 +570,7 @@
def descr_getitem(self, space, w_idx):
if self._single_item_result(space, w_idx):
concrete = self.get_concrete()
+ assert isinstance(concrete, ConcreteArray)
if len(concrete.shape) < 1:
raise OperationError(space.w_IndexError, space.wrap(
"0-d arrays can't be indexed"))
@@ -602,6 +583,7 @@
self.invalidated()
if self._single_item_result(space, w_idx):
concrete = self.get_concrete()
+ assert isinstance(concrete, ConcreteArray)
if len(concrete.shape) < 1:
raise OperationError(space.w_IndexError, space.wrap(
"0-d arrays can't be indexed"))
@@ -616,37 +598,39 @@
@jit.unroll_safe
def create_slice(self, space, chunks):
+ concr = self.get_concrete()
+ assert isinstance(concr, ConcreteArray)
if len(chunks) == 1:
start, stop, step, lgt = chunks[0]
if step == 0:
shape = self.shape[1:]
- strides = self.strides[1:]
- backstrides = self.backstrides[1:]
+ strides = concr.strides[1:]
+ backstrides = concr.backstrides[1:]
else:
shape = [lgt] + self.shape[1:]
- strides = [self.strides[0] * step] + self.strides[1:]
- backstrides = [(lgt - 1) * self.strides[0] * step] + self.backstrides[1:]
- start *= self.strides[0]
- start += self.start
+ strides = [concr.strides[0] * step] + concr.strides[1:]
+ backstrides = [(lgt - 1) * concr.strides[0] * step] + concr.backstrides[1:]
+ start *= concr.strides[0]
+ start += concr.start
else:
shape = []
strides = []
backstrides = []
- start = self.start
+ start = concr.start
i = -1
for i, (start_, stop, step, lgt) in enumerate(chunks):
if step != 0:
shape.append(lgt)
- strides.append(self.strides[i] * step)
- backstrides.append(self.strides[i] * (lgt - 1) * step)
- start += self.strides[i] * start_
+ strides.append(concr.strides[i] * step)
+ backstrides.append(concr.strides[i] * (lgt - 1) * step)
+ start += concr.strides[i] * start_
# add a reminder
s = i + 1
assert s >= 0
- shape += self.shape[s:]
- strides += self.strides[s:]
- backstrides += self.backstrides[s:]
- return W_NDimSlice(self, start, strides[:], backstrides[:],
+ shape += concr.shape[s:]
+ strides += concr.strides[s:]
+ backstrides += concr.backstrides[s:]
+ return W_NDimSlice(concr, start, strides[:], backstrides[:],
shape[:])
def descr_reshape(self, space, args_w):
@@ -747,8 +731,8 @@
_attrs_ = ["dtype", "value", "shape"]
def __init__(self, dtype, value):
- self.shape = self.strides = []
- BaseArray.__init__(self, [], 'C')
+ self.shape = []
+ BaseArray.__init__(self, [])
self.dtype = dtype
self.value = value
@@ -782,8 +766,8 @@
"""
Class for representing virtual arrays, such as binary ops or ufuncs
"""
- def __init__(self, name, shape, res_dtype, order):
- BaseArray.__init__(self, shape, order)
+ def __init__(self, name, shape, res_dtype):
+ BaseArray.__init__(self, shape)
self.forced_result = None
self.res_dtype = res_dtype
self.name = name
@@ -838,9 +822,8 @@
class Call1(VirtualArray):
- def __init__(self, ufunc, name, shape, res_dtype, values, order):
- VirtualArray.__init__(self, name, shape, res_dtype,
- values.order)
+ def __init__(self, ufunc, name, shape, res_dtype, values):
+ VirtualArray.__init__(self, name, shape, res_dtype)
self.values = values
self.ufunc = ufunc
@@ -863,7 +846,7 @@
Intermediate class for performing binary operations.
"""
def __init__(self, ufunc, name, shape, calc_dtype, res_dtype, left, right):
- VirtualArray.__init__(self, name, shape, res_dtype, left.order)
+ VirtualArray.__init__(self, name, shape, res_dtype)
self.ufunc = ufunc
self.left = left
self.right = right
@@ -886,7 +869,34 @@
self.left.create_sig(),
self.right.create_sig())
-class ViewArray(BaseArray):
+class ConcreteArray(BaseArray):
+ """ An array that have actual storage, whether owned or not
+ """
+ def __init__(self, shape, order):
+ self.order = order
+ if self.strides is None:
+ self.calc_strides(shape)
+ BaseArray.__init__(self, shape)
+
+ def calc_strides(self, shape):
+ strides = []
+ backstrides = []
+ s = 1
+ shape_rev = shape[:]
+ if self.order == 'C':
+ shape_rev.reverse()
+ for sh in shape_rev:
+ strides.append(s)
+ backstrides.append(s * (sh - 1))
+ s *= sh
+ if self.order == 'C':
+ strides.reverse()
+ backstrides.reverse()
+ self.strides = strides[:]
+ self.backstrides = backstrides[:]
+
+
+class ConcreteViewArray(ConcreteArray):
"""
Class for representing views of arrays, they will reflect changes of parent
arrays. Example: slices
@@ -894,13 +904,14 @@
def __init__(self, parent, strides, backstrides, shape):
self.strides = strides
self.backstrides = backstrides
- BaseArray.__init__(self, shape, parent.order)
+ ConcreteArray.__init__(self, shape, parent.order)
assert isinstance(parent, W_NDimArray)
self.parent = parent
self.invalidates = parent.invalidates
def get_concrete(self):
- # in fact, ViewArray never gets "concrete" as it never stores data.
+ # in fact, ConcreteViewArray never gets "concrete" as it never
+ # stores data.
# This implementation is needed for BaseArray getitem/setitem to work,
# can be refactored.
self.parent.get_concrete()
@@ -959,7 +970,7 @@
self.backstrides = new_backstrides[:]
self.shape = new_shape[:]
-class W_NDimSlice(ViewArray):
+class W_NDimSlice(ConcreteViewArray):
def __init__(self, parent, start, strides, backstrides, shape):
if isinstance(parent, W_NDimSlice):
parent = parent.parent
@@ -967,7 +978,7 @@
# XXX this should not force the array, but it did before the
# refactoring anyway, just in a more obscure way
parent = parent.get_concrete()
- ViewArray.__init__(self, parent, strides, backstrides, shape)
+ ConcreteViewArray.__init__(self, parent, strides, backstrides, shape)
self.start = start
self.size = 1
for sh in shape:
@@ -1015,14 +1026,14 @@
def create_sig(self):
return signature.ViewSignature(self.parent.create_sig())
-class W_NDimArray(BaseArray):
+class W_NDimArray(ConcreteArray):
""" A class representing contiguous array. We know that each iteration
by say ufunc will increase the data index by one
"""
_immutable_fields_ = ['storage']
def __init__(self, size, shape, dtype, order='C'):
- BaseArray.__init__(self, shape, order)
+ ConcreteArray.__init__(self, shape, order)
self.size = size
self.dtype = dtype
self.storage = dtype.malloc(size)
@@ -1213,15 +1224,15 @@
)
-class W_FlatIterator(ViewArray):
+class W_FlatIterator(ConcreteViewArray):
@jit.unroll_safe
def __init__(self, arr):
size = 1
for sh in arr.shape:
size *= sh
- ViewArray.__init__(self, arr.get_concrete(), [arr.strides[-1]],
- [arr.backstrides[-1]], [size])
+ ConcreteViewArray.__init__(self, arr.get_concrete(), [arr.strides[-1]],
+ [arr.backstrides[-1]], [size])
self.shapelen = len(arr.shape)
self.arr = arr
self.iter = OneDimIterator(self.arr.start, self.strides[0],
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,8 +121,7 @@
if isinstance(w_obj, Scalar):
return self.func(res_dtype, w_obj.value.convert_to(res_dtype))
- w_res = Call1(self.func, self.name, w_obj.shape, res_dtype, w_obj,
- w_obj.order)
+ w_res = Call1(self.func, self.name, w_obj.shape, res_dtype, w_obj)
w_obj.add_invalidates(w_res)
return w_res
diff --git a/pypy/module/micronumpy/signature.py b/pypy/module/micronumpy/signature.py
--- a/pypy/module/micronumpy/signature.py
+++ b/pypy/module/micronumpy/signature.py
@@ -1,4 +1,5 @@
from pypy.rlib.objectmodel import r_dict, compute_identity_hash, compute_hash
+from pypy.rlib.rarithmetic import intmask
from pypy.module.micronumpy.interp_iter import ViewIterator, ArrayIterator, \
BroadcastIterator, OneDimIterator, ConstantIterator
from pypy.rlib.jit import hint, unroll_safe, promote
@@ -63,7 +64,7 @@
class Signature(object):
_attrs_ = ['iter_no']
_immutable_fields_ = ['iter_no']
-
+
def invent_numbering(self):
cache = r_dict(sigeq, sighash)
allnumbers = []
@@ -171,6 +172,9 @@
self.iter_no = no
def _create_iter(self, iterlist, arr):
+ from pypy.module.micronumpy.interp_numarray import ConcreteViewArray
+
+ assert isinstance(arr, ConcreteViewArray)
if self.iter_no >= len(iterlist):
iterlist.append(ViewIterator(arr))
@@ -197,7 +201,7 @@
self.name = name
def hash(self):
- return compute_hash(self.name) ^ self.child.hash() << 1
+ return compute_hash(self.name) ^ intmask(self.child.hash() << 1)
def eq(self, other):
if type(self) is not type(other):
@@ -233,8 +237,8 @@
self.calc_dtype = calc_dtype
def hash(self):
- return (compute_hash(self.name) ^ (self.left.hash() << 1) ^
- (self.right.hash() << 2))
+ return (compute_hash(self.name) ^ intmask(self.left.hash() << 1) ^
+ intmask(self.right.hash() << 2))
def eq(self, other):
if type(self) is not type(other):
More information about the pypy-commit
mailing list