[pypy-commit] pypy numpy-indexing-by-arrays-2: a branch to work on indexing by arrays - start by introducing new way of
fijal
noreply at buildbot.pypy.org
Sun Jan 15 13:40:32 CET 2012
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: numpy-indexing-by-arrays-2
Changeset: r51335:ad840d9d2a35
Date: 2012-01-15 14:36 +0200
http://bitbucket.org/pypy/pypy/changeset/ad840d9d2a35/
Log: a branch to work on indexing by arrays - start by introducing new
way of describing shapes
diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py
--- a/pypy/module/micronumpy/interp_dtype.py
+++ b/pypy/module/micronumpy/interp_dtype.py
@@ -84,6 +84,12 @@
def descr_get_shape(self, space):
return space.newtuple([])
+ def is_int_type(self):
+ return self.kind == SIGNEDLTR or self.kind == UNSIGNEDLTR
+
+ def is_bool_type(self):
+ return self.kind == BOOLLTR
+
W_Dtype.typedef = TypeDef("dtype",
__module__ = "numpypy",
__new__ = interp2app(W_Dtype.descr__new__.im_func),
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
@@ -4,6 +4,30 @@
from pypy.module.micronumpy.strides import calculate_broadcast_strides,\
calculate_slice_strides
+# structures to describe slicing
+
+class BaseChunk(object):
+ pass
+
+class Chunk(BaseChunk):
+ def __init__(self, start, stop, step, lgt):
+ self.start = start
+ self.stop = stop
+ self.step = step
+ self.lgt = lgt
+
+ def extend_shape(self, shape):
+ if self.step != 0:
+ shape.append(self.lgt)
+
+class IntArrayChunk(BaseChunk):
+ def __init__(self, arr):
+ self.arr = arr.get_concrete()
+
+class BoolArrayChunk(BaseChunk):
+ def __init__(self, arr):
+ self.arr = arr.get_concrete()
+
class BaseTransform(object):
pass
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
@@ -2,14 +2,15 @@
from pypy.interpreter.error import OperationError, operationerrfmt
from pypy.interpreter.gateway import interp2app, NoneNotWrapped
from pypy.interpreter.typedef import TypeDef, GetSetProperty
-from pypy.module.micronumpy import interp_ufuncs, interp_dtype, signature
+from pypy.module.micronumpy import interp_ufuncs, interp_dtype, signature,\
+ interp_boxes
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, OneDimIterator,\
- SkipLastAxisIterator
+ SkipLastAxisIterator, Chunk
numpy_driver = jit.JitDriver(
greens=['shapelen', 'sig'],
@@ -40,7 +41,6 @@
name='numpy_slice',
)
-
def _find_shape_and_elems(space, w_iterable):
shape = [space.len_w(w_iterable)]
batch = space.listview(w_iterable)
@@ -479,8 +479,8 @@
def _prepare_slice_args(self, space, w_idx):
if (space.isinstance_w(w_idx, space.w_int) or
space.isinstance_w(w_idx, space.w_slice)):
- return [space.decode_index4(w_idx, self.shape[0])]
- return [space.decode_index4(w_item, self.shape[i]) for i, w_item in
+ return [Chunk(*space.decode_index4(w_idx, self.shape[0]))]
+ return [Chunk(*space.decode_index4(w_item, self.shape[i])) for i, w_item in
enumerate(space.fixedview(w_idx))]
def descr_getitem(self, space, w_idx):
@@ -509,9 +509,8 @@
def create_slice(self, chunks):
shape = []
i = -1
- for i, (start_, stop, step, lgt) in enumerate(chunks):
- if step != 0:
- shape.append(lgt)
+ for i, chunk in enumerate(chunks):
+ chunk.extend_shape(shape)
s = i + 1
assert s >= 0
shape += self.shape[s:]
@@ -938,7 +937,7 @@
builder.append('\n' + indent)
else:
builder.append(indent)
- view = self.create_slice([(i, 0, 0, 1)]).get_concrete()
+ view = self.create_slice([Chunk(i, 0, 0, 1)]).get_concrete()
view.to_str(space, comma, builder, indent=indent + ' ',
use_ellipsis=use_ellipsis)
if i < self.shape[0] - 1:
@@ -955,7 +954,7 @@
builder.append(indent)
# create_slice requires len(chunks) > 1 in order to reduce
# shape
- view = self.create_slice([(i, 0, 0, 1)]).get_concrete()
+ view = self.create_slice([Chunk(i, 0, 0, 1)]).get_concrete()
view.to_str(space, comma, builder, indent=indent + ' ',
use_ellipsis=use_ellipsis)
i += 1
diff --git a/pypy/module/micronumpy/strides.py b/pypy/module/micronumpy/strides.py
--- a/pypy/module/micronumpy/strides.py
+++ b/pypy/module/micronumpy/strides.py
@@ -10,12 +10,12 @@
rstart = start
rshape = []
i = -1
- for i, (start_, stop, step, lgt) in enumerate(chunks):
- if step != 0:
- rstrides.append(strides[i] * step)
- rbackstrides.append(strides[i] * (lgt - 1) * step)
- rshape.append(lgt)
- rstart += strides[i] * start_
+ for i, chunk in enumerate(chunks):
+ if chunk.step != 0:
+ rstrides.append(strides[i] * chunk.step)
+ rbackstrides.append(strides[i] * (chunk.lgt - 1) * chunk.step)
+ rshape.append(chunk.lgt)
+ rstart += strides[i] * chunk.start
# add a reminder
s = i + 1
assert s >= 0
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
@@ -2,6 +2,7 @@
import py
from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest
from pypy.module.micronumpy.interp_numarray import W_NDimArray, shape_agreement
+from pypy.module.micronumpy.interp_iter import Chunk
from pypy.module.micronumpy import signature
from pypy.interpreter.error import OperationError
from pypy.conftest import gettestobjspace
@@ -37,53 +38,54 @@
def test_create_slice_f(self):
a = W_NDimArray(10 * 5 * 3, [10, 5, 3], MockDtype(), 'F')
- s = a.create_slice([(3, 0, 0, 1)])
+ s = a.create_slice([Chunk(3, 0, 0, 1)])
assert s.start == 3
assert s.strides == [10, 50]
assert s.backstrides == [40, 100]
- s = a.create_slice([(1, 9, 2, 4)])
+ s = a.create_slice([Chunk(1, 9, 2, 4)])
assert s.start == 1
assert s.strides == [2, 10, 50]
assert s.backstrides == [6, 40, 100]
- s = a.create_slice([(1, 5, 3, 2), (1, 2, 1, 1), (1, 0, 0, 1)])
+ s = a.create_slice([Chunk(1, 5, 3, 2), Chunk(1, 2, 1, 1), Chunk(1, 0, 0, 1)])
assert s.shape == [2, 1]
assert s.strides == [3, 10]
assert s.backstrides == [3, 0]
- s = a.create_slice([(0, 10, 1, 10), (2, 0, 0, 1)])
+ s = a.create_slice([Chunk(0, 10, 1, 10), Chunk(2, 0, 0, 1)])
assert s.start == 20
assert s.shape == [10, 3]
def test_create_slice_c(self):
a = W_NDimArray(10 * 5 * 3, [10, 5, 3], MockDtype(), 'C')
- s = a.create_slice([(3, 0, 0, 1)])
+ s = a.create_slice([Chunk(3, 0, 0, 1)])
assert s.start == 45
assert s.strides == [3, 1]
assert s.backstrides == [12, 2]
- s = a.create_slice([(1, 9, 2, 4)])
+ s = a.create_slice([Chunk(1, 9, 2, 4)])
assert s.start == 15
assert s.strides == [30, 3, 1]
assert s.backstrides == [90, 12, 2]
- s = a.create_slice([(1, 5, 3, 2), (1, 2, 1, 1), (1, 0, 0, 1)])
+ s = a.create_slice([Chunk(1, 5, 3, 2), Chunk(1, 2, 1, 1),
+ Chunk(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([(0, 10, 1, 10), (2, 0, 0, 1)])
+ s = a.create_slice([Chunk(0, 10, 1, 10), Chunk(2, 0, 0, 1)])
assert s.start == 6
assert s.shape == [10, 3]
def test_slice_of_slice_f(self):
a = W_NDimArray(10 * 5 * 3, [10, 5, 3], MockDtype(), 'F')
- s = a.create_slice([(5, 0, 0, 1)])
+ s = a.create_slice([Chunk(5, 0, 0, 1)])
assert s.start == 5
- s2 = s.create_slice([(3, 0, 0, 1)])
+ s2 = s.create_slice([Chunk(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([(1, 5, 3, 2)])
- s2 = s.create_slice([(0, 2, 1, 2), (2, 0, 0, 1)])
+ s = a.create_slice([Chunk(1, 5, 3, 2)])
+ s2 = s.create_slice([Chunk(0, 2, 1, 2), Chunk(2, 0, 0, 1)])
assert s2.shape == [2, 3]
assert s2.strides == [3, 50]
assert s2.backstrides == [3, 100]
@@ -91,16 +93,16 @@
def test_slice_of_slice_c(self):
a = W_NDimArray(10 * 5 * 3, [10, 5, 3], MockDtype(), order='C')
- s = a.create_slice([(5, 0, 0, 1)])
+ s = a.create_slice([Chunk(5, 0, 0, 1)])
assert s.start == 15 * 5
- s2 = s.create_slice([(3, 0, 0, 1)])
+ s2 = s.create_slice([Chunk(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([(1, 5, 3, 2)])
- s2 = s.create_slice([(0, 2, 1, 2), (2, 0, 0, 1)])
+ s = a.create_slice([Chunk(1, 5, 3, 2)])
+ s2 = s.create_slice([Chunk(0, 2, 1, 2), Chunk(2, 0, 0, 1)])
assert s2.shape == [2, 3]
assert s2.strides == [45, 1]
assert s2.backstrides == [45, 2]
@@ -108,14 +110,14 @@
def test_negative_step_f(self):
a = W_NDimArray(10 * 5 * 3, [10, 5, 3], MockDtype(), 'F')
- s = a.create_slice([(9, -1, -2, 5)])
+ s = a.create_slice([Chunk(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):
a = W_NDimArray(10 * 5 * 3, [10, 5, 3], MockDtype(), order='C')
- s = a.create_slice([(9, -1, -2, 5)])
+ s = a.create_slice([Chunk(9, -1, -2, 5)])
assert s.start == 135
assert s.strides == [-30, 3, 1]
assert s.backstrides == [-120, 12, 2]
@@ -124,7 +126,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([(0, 10, 1, 10), (2, 0, 0, 1)])
+ s = a.create_slice([Chunk(0, 10, 1, 10), Chunk(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))
@@ -134,7 +136,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([(0, 10, 1, 10), (2, 0, 0, 1)])
+ s = a.create_slice([Chunk(0, 10, 1, 10), Chunk(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))
@@ -1298,6 +1300,17 @@
assert isinstance(i['data'][0], int)
raises(TypeError, getattr, array(3), '__array_interface__')
+ def test_array_indexing_one_elem(self):
+ skip("not yet")
+ from _numpypy import array, arange
+ raises(IndexError, 'arange(3)[array([3.5])]')
+ a = arange(3)[array([1])]
+ assert a == 1
+ assert a[0] == 1
+ raises(IndexError,'arange(3)[array([15])]')
+ assert arange(3)[array([-3])] == 0
+ raises(IndexError,'arange(3)[array([-15])]')
+ assert arange(3)[array(1)] == 1
class AppTestSupport(BaseNumpyAppTest):
def setup_class(cls):
More information about the pypy-commit
mailing list