Author: Maciej Fijalkowski <[email protected]>
Branch: refactor-signature
Changeset: r50719:2ab09b67b929
Date: 2011-12-19 22:51 +0200
http://bitbucket.org/pypy/pypy/changeset/2ab09b67b929/
Log: implement virtualviews
diff --git a/pypy/module/micronumpy/interp_iter.py
b/pypy/module/micronumpy/interp_iter.py
--- a/pypy/module/micronumpy/interp_iter.py
+++ b/pypy/module/micronumpy/interp_iter.py
@@ -1,6 +1,7 @@
from pypy.rlib import jit
from pypy.rlib.objectmodel import instantiate
+from pypy.module.micronumpy.strides import calculate_broadcast_strides
# Iterators for arrays
# --------------------
@@ -60,30 +61,24 @@
def get_offset(self):
return self.offset
+def view_iter_from_arr(arr):
+ return ViewIterator(arr.start, arr.strides, arr.backstrides, arr.shape)
+
class ViewIterator(BaseIterator):
- def __init__(self, arr, res_shape=None):
- self.offset = arr.start
+ def __init__(self, start, strides, backstrides, shape, res_shape=None):
+ self.offset = start
self._done = False
- if res_shape is not None and res_shape != arr.shape:
- self.strides = []
- self.backstrides = []
- for i in range(len(arr.shape)):
- if arr.shape[i] == 1:
- self.strides.append(0)
- self.backstrides.append(0)
- else:
- self.strides.append(arr.strides[i])
- self.backstrides.append(arr.backstrides[i])
- self.strides = [0] * (len(res_shape) - len(arr.shape)) +
self.strides
- self.backstrides = [0] * (len(res_shape) - len(arr.shape)) +
self.backstrides
+ if res_shape is not None and res_shape != shape:
+ r = calculate_broadcast_strides(strides, backstrides,
+ shape, res_shape)
+ self.strides, self.backstrides = r
self.res_shape = res_shape
else:
- self.strides = arr.strides
- self.backstrides = arr.backstrides
- self.res_shape = arr.shape
+ self.strides = strides
+ self.backstrides = backstrides
+ self.res_shape = shape
self.indices = [0] * len(self.res_shape)
-
@jit.unroll_safe
def next(self, shapelen):
offset = self.offset
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
@@ -3,12 +3,13 @@
from pypy.interpreter.gateway import interp2app, unwrap_spec, NoneNotWrapped
from pypy.interpreter.typedef import TypeDef, GetSetProperty
from pypy.module.micronumpy import interp_ufuncs, interp_dtype, signature
+from pypy.module.micronumpy.strides import calculate_slice_strides
from pypy.rlib import jit
from pypy.rpython.lltypesystem import lltype, rffi
from pypy.tool.sourcetools import func_with_new_name
from pypy.rlib.rstring import StringBuilder
-from pypy.module.micronumpy.interp_iter import ArrayIterator, ViewIterator,\
- OneDimIterator
+from pypy.module.micronumpy.interp_iter import ArrayIterator,\
+ view_iter_from_arr, OneDimIterator
numpy_driver = jit.JitDriver(
greens=['shapelen', 'sig'],
@@ -203,7 +204,7 @@
return new_strides
class BaseArray(Wrappable):
- _attrs_ = ["invalidates", "shape"]
+ _attrs_ = ["invalidates", "shape", 'size']
_immutable_fields_ = []
@@ -316,8 +317,7 @@
idx += 1
return result
def impl(self, space):
- size = self.find_size()
- if size == 0:
+ if self.size == 0:
raise OperationError(space.w_ValueError,
space.wrap("Can't call %s on zero-size arrays" % op_name))
return space.wrap(loop(self))
@@ -380,13 +380,13 @@
def descr_set_shape(self, space, w_iterable):
new_shape = get_shape_from_iterable(space,
- self.find_size(), w_iterable)
+ self.size, w_iterable)
if isinstance(self, Scalar):
return
self.get_concrete().setshape(space, new_shape)
def descr_get_size(self, space):
- return space.wrap(self.find_size())
+ return space.wrap(self.size)
def descr_copy(self, space):
return self.copy()
@@ -405,7 +405,7 @@
res.append("array(")
concrete = self.get_concrete()
dtype = concrete.find_dtype()
- if not concrete.find_size():
+ if not concrete.size:
res.append('[]')
if len(self.shape) > 1:
# An empty slice reports its shape
@@ -417,7 +417,7 @@
concrete.to_str(space, 1, res, indent=' ')
if (dtype is not interp_dtype.get_dtype_cache(space).w_float64dtype and
dtype is not interp_dtype.get_dtype_cache(space).w_int64dtype) or \
- not self.find_size():
+ not self.size:
res.append(", dtype=" + dtype.name)
res.append(")")
return space.wrap(res.build())
@@ -428,7 +428,7 @@
Multidimensional arrays/slices will span a number of lines,
each line will begin with indent.
'''
- size = self.find_size()
+ size = self.size
if size < 1:
builder.append('[]')
return
@@ -454,7 +454,7 @@
builder.append(indent)
# create_slice requires len(chunks) > 1 in order to reduce
# shape
- view = self.create_slice(space, [(i, 0, 0, 1), (0,
self.shape[1], 1, self.shape[1])])
+ view = self.create_slice([(i, 0, 0, 1), (0, self.shape[1],
1, self.shape[1])])
view.to_str(space, comma, builder, indent=indent + ' ',
use_ellipsis=use_ellipsis)
builder.append('\n' + indent + '..., ')
i = self.shape[0] - 3
@@ -469,7 +469,7 @@
builder.append(indent)
# create_slice requires len(chunks) > 1 in order to reduce
# shape
- view = self.create_slice(space, [(i, 0, 0, 1), (0,
self.shape[1], 1, self.shape[1])])
+ view = self.create_slice([(i, 0, 0, 1), (0, self.shape[1], 1,
self.shape[1])])
view.to_str(space, comma, builder, indent=indent + ' ',
use_ellipsis=use_ellipsis)
i += 1
elif ndims == 1:
@@ -581,7 +581,7 @@
item = concrete._index_of_single_item(space, w_idx)
return concrete.getitem(item)
chunks = self._prepare_slice_args(space, w_idx)
- return space.wrap(self.create_slice(space, chunks))
+ return space.wrap(self.create_slice(chunks))
def descr_setitem(self, space, w_idx, w_value):
self.invalidated()
@@ -597,31 +597,24 @@
if not isinstance(w_value, BaseArray):
w_value = convert_to_array(space, w_value)
chunks = self._prepare_slice_args(space, w_idx)
- view = self.create_slice(space, chunks)
+ view = self.create_slice(chunks).get_concrete()
view.setslice(space, w_value)
@jit.unroll_safe
- def create_slice(self, space, chunks):
- #if not isinstance(self, ConcreteArray):
- # return VirtualSlice(self, chunks)
- self = self.get_concrete()
+ def create_slice(self, chunks):
shape = []
- strides = []
- backstrides = []
- start = self.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_
- # add a reminder
s = i + 1
assert s >= 0
shape += self.shape[s:]
- strides += self.strides[s:]
- backstrides += self.backstrides[s:]
+ if not isinstance(self, ConcreteArray):
+ return VirtualSlice(self, chunks, shape)
+ r = calculate_slice_strides(self.start, self.strides, self.backstrides,
+ chunks)
+ start, strides, backstrides = r
return W_NDimSlice(start, strides[:], backstrides[:],
shape[:], self)
@@ -642,8 +635,7 @@
else:
w_shape = space.newtuple(args_w)
concrete = self.get_concrete()
- new_shape = get_shape_from_iterable(space,
- concrete.find_size(), w_shape)
+ new_shape = get_shape_from_iterable(space, concrete.size, w_shape)
# Since we got to here, prod(new_shape) == self.size
new_strides = calc_new_strides(new_shape,
concrete.shape, concrete.strides)
@@ -662,10 +654,10 @@
return arr
def descr_mean(self, space):
- return space.div(self.descr_sum(space), space.wrap(self.find_size()))
+ return space.div(self.descr_sum(space), space.wrap(self.size))
def descr_nonzero(self, space):
- if self.find_size() > 1:
+ if self.size > 1:
raise OperationError(space.w_ValueError, space.wrap(
"The truth value of an array with more than one element is
ambiguous. Use a.any() or a.all()"))
concr = self.get_concrete_or_scalar()
@@ -725,6 +717,7 @@
"""
Intermediate class representing a literal.
"""
+ size = 1
_attrs_ = ["dtype", "value", "shape"]
def __init__(self, dtype, value):
@@ -733,9 +726,6 @@
self.dtype = dtype
self.value = value
- def find_size(self):
- return 1
-
def find_dtype(self):
return self.dtype
@@ -770,16 +760,15 @@
raise NotImplementedError
def compute(self):
- result_size = self.find_size()
- result = W_NDimArray(result_size, self.shape, self.find_dtype())
+ result = W_NDimArray(self.size, self.shape, self.find_dtype())
shapelen = len(self.shape)
sig = self.find_sig()
frame = sig.create_frame(self)
- ri = ArrayIterator(result_size)
+ ri = ArrayIterator(self.size)
while not ri.done():
numpy_driver.jit_merge_point(sig=sig,
shapelen=shapelen,
- result_size=result_size,
+ result_size=self.size,
frame=frame,
ri=ri,
self=self, result=result)
@@ -804,33 +793,43 @@
def setitem(self, item, value):
return self.get_concrete().setitem(item, value)
- def find_size(self):
- if self.forced_result is not None:
- # The result has been computed and sources may be unavailable
- return self.forced_result.find_size()
- return self._find_size()
-
def find_dtype(self):
return self.res_dtype
class VirtualSlice(VirtualArray):
- def __init__(self, parent, chunks):
- self.parent = parent
+ def __init__(self, child, chunks, shape):
+ size = 1
+ for sh in shape:
+ size *= sh
+ self.child = child
self.chunks = chunks
- VirtualArray.__init__(self, 'slice', parent.shape, parent.find_dtype())
+ self.size = size
+ VirtualArray.__init__(self, 'slice', shape, child.find_dtype())
+
+ def create_sig(self, res_shape):
+ if self.forced_result is not None:
+ return self.forced_result.create_sig(res_shape)
+ return signature.VirtualSliceSignature(
+ self.child.create_sig(res_shape))
+
+ def force_if_needed(self):
+ if self.forced_result is None:
+ concr = self.child.get_concrete()
+ self.forced_result = concr.create_slice(self.chunks)
+
+ def _del_sources(self):
+ self.child = None
class Call1(VirtualArray):
def __init__(self, ufunc, name, shape, res_dtype, values):
VirtualArray.__init__(self, name, shape, res_dtype)
self.values = values
+ self.size = values.size
self.ufunc = ufunc
def _del_sources(self):
self.values = None
- def _find_size(self):
- return self.values.find_size()
-
def _find_dtype(self):
return self.res_dtype
@@ -858,9 +857,6 @@
self.left = None
self.right = None
- def _find_size(self):
- return self.size
-
def create_sig(self, res_shape):
if self.forced_result is not None:
return self.forced_result.array_sig(res_shape)
@@ -891,9 +887,6 @@
def get_concrete(self):
return self
- def find_size(self):
- return self.size
-
def find_dtype(self):
return self.dtype
@@ -933,7 +926,7 @@
class ViewArray(ConcreteArray):
def copy(self):
array = W_NDimArray(self.size, self.shape[:], self.find_dtype())
- iter = ViewIterator(self)
+ iter = view_iter_from_arr(self)
a_iter = ArrayIterator(array.size)
while not iter.done():
array.setitem(a_iter.offset, self.getitem(iter.offset))
@@ -965,7 +958,7 @@
def _sliceloop(self, source, res_shape):
sig = source.find_sig(res_shape)
frame = sig.create_frame(source, res_shape)
- res_iter = ViewIterator(self)
+ res_iter = view_iter_from_arr(self)
shapelen = len(res_shape)
while not res_iter.done():
slice_driver.jit_merge_point(sig=sig,
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
@@ -62,7 +62,7 @@
raise OperationError(space.w_TypeError, space.wrap("cannot reduce "
"on a scalar"))
- size = obj.find_size()
+ size = obj.size
dtype = find_unaryop_result_dtype(
space, obj.find_dtype(),
promote_to_largest=True
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
@@ -2,7 +2,7 @@
from pypy.rlib.rarithmetic import intmask
from pypy.module.micronumpy.interp_iter import ViewIterator, ArrayIterator, \
OneDimIterator, ConstantIterator
-from pypy.rpython.lltypesystem.llmemory import cast_ptr_to_adr
+from pypy.module.micronumpy.strides import calculate_slice_strides
from pypy.rlib.jit import hint, unroll_safe, promote
def sigeq(one, two):
@@ -92,7 +92,7 @@
res_shape = res_shape or arr.shape
iterlist = []
arraylist = []
- self._create_iter(iterlist, arraylist, arr, res_shape)
+ self._create_iter(iterlist, arraylist, arr, res_shape, [])
return NumpyEvalFrame(iterlist, arraylist)
class ConcreteSignature(Signature):
@@ -113,23 +113,39 @@
def hash(self):
return compute_identity_hash(self.dtype)
+ def allocate_view_iter(self, arr, res_shape, chunklist):
+ r = arr.start, arr.strides, arr.backstrides
+ if chunklist:
+ for chunkelem in chunklist:
+ r = calculate_slice_strides(r[0], r[1], r[2], chunkelem)
+ start, strides, backstrides = r
+ if len(res_shape) == 1:
+ return OneDimIterator(start, strides[0], res_shape[0])
+ return ViewIterator(start, strides, backstrides, arr.shape, res_shape)
+
class ArraySignature(ConcreteSignature):
def debug_repr(self):
return 'Array'
def _invent_array_numbering(self, arr, cache):
- storage = arr.get_concrete().storage
- self.array_no = _add_ptr_to_cache(storage, cache)
+ from pypy.module.micronumpy.interp_numarray import ConcreteArray
+ concr = arr.get_concrete()
+ assert isinstance(concr, ConcreteArray)
+ self.array_no = _add_ptr_to_cache(concr.storage, cache)
- def _create_iter(self, iterlist, arraylist, arr, res_shape):
+ def _create_iter(self, iterlist, arraylist, arr, res_shape, chunklist):
+ from pypy.module.micronumpy.interp_numarray import ConcreteArray
concr = arr.get_concrete()
+ assert isinstance(concr, ConcreteArray)
storage = concr.storage
if self.iter_no >= len(iterlist):
- iterlist.append(self.allocate_iter(concr, res_shape))
+ iterlist.append(self.allocate_iter(concr, res_shape, chunklist))
if self.array_no >= len(arraylist):
arraylist.append(storage)
- def allocate_iter(self, arr, res_shape):
+ def allocate_iter(self, arr, res_shape, chunklist):
+ if chunklist:
+ return self.allocate_view_iter(arr, res_shape, chunklist)
return ArrayIterator(arr.size)
def eval(self, frame, arr):
@@ -143,7 +159,7 @@
def _invent_array_numbering(self, arr, cache):
pass
- def _create_iter(self, iterlist, arraylist, arr, res_shape):
+ def _create_iter(self, iterlist, arraylist, arr, res_shape, chunklist):
if self.iter_no >= len(iterlist):
iter = ConstantIterator()
iterlist.append(iter)
@@ -163,17 +179,38 @@
allnumbers.append(no)
self.iter_no = no
- def allocate_iter(self, arr, res_shape):
- if len(res_shape) == 1:
- return OneDimIterator(arr.start, arr.strides[0], res_shape[0])
- return ViewIterator(arr, res_shape)
+ def allocate_iter(self, arr, res_shape, chunklist):
+ return self.allocate_view_iter(arr, res_shape, chunklist)
-class FlatiterSignature(ViewSignature):
- def debug_repr(self):
- return 'FlatIter(%s)' % self.child.debug_repr()
+class VirtualSliceSignature(Signature):
+ def __init__(self, child):
+ self.child = child
- def _create_iter(self, iterlist, arraylist, arr, res_shape):
- raise NotImplementedError
+ def _invent_array_numbering(self, arr, cache):
+ from pypy.module.micronumpy.interp_numarray import VirtualSlice
+ assert isinstance(arr, VirtualSlice)
+ self.child._invent_array_numbering(arr.child, cache)
+
+ def hash(self):
+ return intmask(self.child.hash() ^ 1234)
+
+ def eq(self, other, compare_array_no=True):
+ if type(self) is not type(other):
+ return False
+ assert isinstance(other, VirtualSliceSignature)
+ return self.child.eq(other.child, compare_array_no)
+
+ def _create_iter(self, iterlist, arraylist, arr, res_shape, chunklist):
+ from pypy.module.micronumpy.interp_numarray import VirtualSlice
+ assert isinstance(arr, VirtualSlice)
+ chunklist.append(arr.chunks)
+ self.child._create_iter(iterlist, arraylist, arr.child, res_shape,
+ chunklist)
+
+ def eval(self, frame, arr):
+ from pypy.module.micronumpy.interp_numarray import VirtualSlice
+ assert isinstance(arr, VirtualSlice)
+ return self.child.eval(frame, arr.child)
class Call1(Signature):
_immutable_fields_ = ['unfunc', 'name', 'child']
@@ -204,10 +241,11 @@
assert isinstance(arr, Call1)
self.child._invent_array_numbering(arr.values, cache)
- def _create_iter(self, iterlist, arraylist, arr, res_shape):
+ def _create_iter(self, iterlist, arraylist, arr, res_shape, chunklist):
from pypy.module.micronumpy.interp_numarray import Call1
assert isinstance(arr, Call1)
- self.child._create_iter(iterlist, arraylist, arr.values, res_shape)
+ self.child._create_iter(iterlist, arraylist, arr.values, res_shape,
+ chunklist)
def eval(self, frame, arr):
from pypy.module.micronumpy.interp_numarray import Call1
@@ -248,12 +286,14 @@
self.left._invent_numbering(cache, allnumbers)
self.right._invent_numbering(cache, allnumbers)
- def _create_iter(self, iterlist, arraylist, arr, res_shape):
+ def _create_iter(self, iterlist, arraylist, arr, res_shape, chunklist):
from pypy.module.micronumpy.interp_numarray import Call2
assert isinstance(arr, Call2)
- self.left._create_iter(iterlist, arraylist, arr.left, res_shape)
- self.right._create_iter(iterlist, arraylist, arr.right, res_shape)
+ self.left._create_iter(iterlist, arraylist, arr.left, res_shape,
+ chunklist)
+ self.right._create_iter(iterlist, arraylist, arr.right, res_shape,
+ chunklist)
def eval(self, frame, arr):
from pypy.module.micronumpy.interp_numarray import Call2
@@ -267,8 +307,8 @@
self.right.debug_repr())
class ReduceSignature(Call2):
- def _create_iter(self, iterlist, arraylist, arr, res_shape):
- self.right._create_iter(iterlist, arraylist, arr, res_shape)
+ def _create_iter(self, iterlist, arraylist, arr, res_shape, chunklist):
+ self.right._create_iter(iterlist, arraylist, arr, res_shape, chunklist)
def _invent_numbering(self, cache, allnumbers):
self.right._invent_numbering(cache, allnumbers)
diff --git a/pypy/module/micronumpy/test/test_base.py
b/pypy/module/micronumpy/test/test_base.py
--- a/pypy/module/micronumpy/test/test_base.py
+++ b/pypy/module/micronumpy/test/test_base.py
@@ -57,6 +57,9 @@
v3 = v2.descr_add(space, v1)
v4 = v1.descr_add(space, v2)
assert v3.find_sig() is v4.find_sig()
+ v5 = ar.descr_add(space, ar).descr_getitem(space, space.wrap(slice(1,
3, 1)))
+ v6 = ar.descr_add(space, ar).descr_getitem(space, space.wrap(slice(1,
4, 1)))
+ assert v5.find_sig() is v6.find_sig()
class TestUfuncCoerscion(object):
def test_binops(self, space):
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
@@ -36,92 +36,86 @@
assert a.backstrides == [135, 12, 2]
def test_create_slice_f(self):
- space = self.space
a = W_NDimArray(10 * 5 * 3, [10, 5, 3], MockDtype(), 'F')
- s = a.create_slice(space, [(3, 0, 0, 1)])
+ s = a.create_slice([(3, 0, 0, 1)])
assert s.start == 3
assert s.strides == [10, 50]
assert s.backstrides == [40, 100]
- s = a.create_slice(space, [(1, 9, 2, 4)])
+ s = a.create_slice([(1, 9, 2, 4)])
assert s.start == 1
assert s.strides == [2, 10, 50]
assert s.backstrides == [6, 40, 100]
- s = a.create_slice(space, [(1, 5, 3, 2), (1, 2, 1, 1), (1, 0, 0, 1)])
+ s = a.create_slice([(1, 5, 3, 2), (1, 2, 1, 1), (1, 0, 0, 1)])
assert s.shape == [2, 1]
assert s.strides == [3, 10]
assert s.backstrides == [3, 0]
- s = a.create_slice(space, [(0, 10, 1, 10), (2, 0, 0, 1)])
+ s = a.create_slice([(0, 10, 1, 10), (2, 0, 0, 1)])
assert s.start == 20
assert s.shape == [10, 3]
def test_create_slice_c(self):
- space = self.space
a = W_NDimArray(10 * 5 * 3, [10, 5, 3], MockDtype(), 'C')
- s = a.create_slice(space, [(3, 0, 0, 1)])
+ s = a.create_slice([(3, 0, 0, 1)])
assert s.start == 45
assert s.strides == [3, 1]
assert s.backstrides == [12, 2]
- s = a.create_slice(space, [(1, 9, 2, 4)])
+ s = a.create_slice([(1, 9, 2, 4)])
assert s.start == 15
assert s.strides == [30, 3, 1]
assert s.backstrides == [90, 12, 2]
- s = a.create_slice(space, [(1, 5, 3, 2), (1, 2, 1, 1), (1, 0, 0, 1)])
+ s = a.create_slice([(1, 5, 3, 2), (1, 2, 1, 1), (1, 0, 0, 1)])
assert s.start == 19
assert s.shape == [2, 1]
assert s.strides == [45, 3]
assert s.backstrides == [45, 0]
- s = a.create_slice(space, [(0, 10, 1, 10), (2, 0, 0, 1)])
+ s = a.create_slice([(0, 10, 1, 10), (2, 0, 0, 1)])
assert s.start == 6
assert s.shape == [10, 3]
def test_slice_of_slice_f(self):
- space = self.space
a = W_NDimArray(10 * 5 * 3, [10, 5, 3], MockDtype(), 'F')
- s = a.create_slice(space, [(5, 0, 0, 1)])
+ s = a.create_slice([(5, 0, 0, 1)])
assert s.start == 5
- s2 = s.create_slice(space, [(3, 0, 0, 1)])
+ s2 = s.create_slice([(3, 0, 0, 1)])
assert s2.shape == [3]
assert s2.strides == [50]
assert s2.parent is a
assert s2.backstrides == [100]
assert s2.start == 35
- s = a.create_slice(space, [(1, 5, 3, 2)])
- s2 = s.create_slice(space, [(0, 2, 1, 2), (2, 0, 0, 1)])
+ s = a.create_slice([(1, 5, 3, 2)])
+ s2 = s.create_slice([(0, 2, 1, 2), (2, 0, 0, 1)])
assert s2.shape == [2, 3]
assert s2.strides == [3, 50]
assert s2.backstrides == [3, 100]
assert s2.start == 1 * 15 + 2 * 3
def test_slice_of_slice_c(self):
- space = self.space
a = W_NDimArray(10 * 5 * 3, [10, 5, 3], MockDtype(), order='C')
- s = a.create_slice(space, [(5, 0, 0, 1)])
+ s = a.create_slice([(5, 0, 0, 1)])
assert s.start == 15 * 5
- s2 = s.create_slice(space, [(3, 0, 0, 1)])
+ s2 = s.create_slice([(3, 0, 0, 1)])
assert s2.shape == [3]
assert s2.strides == [1]
assert s2.parent is a
assert s2.backstrides == [2]
assert s2.start == 5 * 15 + 3 * 3
- s = a.create_slice(space, [(1, 5, 3, 2)])
- s2 = s.create_slice(space, [(0, 2, 1, 2), (2, 0, 0, 1)])
+ s = a.create_slice([(1, 5, 3, 2)])
+ s2 = s.create_slice([(0, 2, 1, 2), (2, 0, 0, 1)])
assert s2.shape == [2, 3]
assert s2.strides == [45, 1]
assert s2.backstrides == [45, 2]
assert s2.start == 1 * 15 + 2 * 3
def test_negative_step_f(self):
- space = self.space
a = W_NDimArray(10 * 5 * 3, [10, 5, 3], MockDtype(), 'F')
- s = a.create_slice(space, [(9, -1, -2, 5)])
+ s = a.create_slice([(9, -1, -2, 5)])
assert s.start == 9
assert s.strides == [-2, 10, 50]
assert s.backstrides == [-8, 40, 100]
def test_negative_step_c(self):
- space = self.space
a = W_NDimArray(10 * 5 * 3, [10, 5, 3], MockDtype(), order='C')
- s = a.create_slice(space, [(9, -1, -2, 5)])
+ s = a.create_slice([(9, -1, -2, 5)])
assert s.start == 135
assert s.strides == [-30, 3, 1]
assert s.backstrides == [-120, 12, 2]
@@ -130,7 +124,7 @@
a = W_NDimArray(10 * 5 * 3, [10, 5, 3], MockDtype(), 'F')
r = a._index_of_single_item(self.space, self.newtuple(1, 2, 2))
assert r == 1 + 2 * 10 + 2 * 50
- s = a.create_slice(self.space, [(0, 10, 1, 10), (2, 0, 0, 1)])
+ s = a.create_slice([(0, 10, 1, 10), (2, 0, 0, 1)])
r = s._index_of_single_item(self.space, self.newtuple(1, 0))
assert r == a._index_of_single_item(self.space, self.newtuple(1, 2, 0))
r = s._index_of_single_item(self.space, self.newtuple(1, 1))
@@ -140,7 +134,7 @@
a = W_NDimArray(10 * 5 * 3, [10, 5, 3], MockDtype(), 'C')
r = a._index_of_single_item(self.space, self.newtuple(1, 2, 2))
assert r == 1 * 3 * 5 + 2 * 3 + 2
- s = a.create_slice(self.space, [(0, 10, 1, 10), (2, 0, 0, 1)])
+ s = a.create_slice([(0, 10, 1, 10), (2, 0, 0, 1)])
r = s._index_of_single_item(self.space, self.newtuple(1, 0))
assert r == a._index_of_single_item(self.space, self.newtuple(1, 2, 0))
r = s._index_of_single_item(self.space, self.newtuple(1, 1))
diff --git a/pypy/module/micronumpy/test/test_zjit.py
b/pypy/module/micronumpy/test/test_zjit.py
--- a/pypy/module/micronumpy/test/test_zjit.py
+++ b/pypy/module/micronumpy/test/test_zjit.py
@@ -193,7 +193,7 @@
# This is the sum of the ops for both loops, however if you remove the
# optimization then you end up with 2 float_adds, so we can still be
# sure it was optimized correctly.
- self.check_resops({'setinteriorfield_raw': 4, 'getfield_gc': 20,
+ self.check_resops({'setinteriorfield_raw': 4, 'getfield_gc': 22,
'getarrayitem_gc_pure': 2,
'getfield_gc_pure': 4,
'guard_class': 8, 'int_add': 8, 'float_mul': 2,
@@ -342,7 +342,24 @@
self.check_simple_loop({'getinteriorfield_raw': 2, 'float_add' : 1,
'setinteriorfield_raw': 1, 'int_add': 3,
'int_lt': 1, 'guard_true': 1, 'jump': 1,
- 'arraylen_gc': 2})
+ 'arraylen_gc': 3})
+
+ def define_virtual_slice():
+ return """
+ a = |30|
+ c = a + a
+ d = c -> 1:20
+ d -> 1
+ """
+
+ def test_virtual_slice(self):
+ result = self.run("virtual_slice")
+ assert result == 4
+ self.check_loop_count(1)
+ self.check_simple_loop({'getinteriorfield_raw': 2, 'float_add' : 1,
+ 'setinteriorfield_raw': 1, 'int_add': 2,
+ 'int_ge': 1, 'guard_false': 1, 'jump': 1,
+ 'arraylen_gc': 1})
class TestNumpyOld(LLJitMixin):
def setup_class(cls):
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit