[pypy-svn] r46178 - in pypy/dist/pypy/rpython/numpy: . test
simonb at codespeak.net
simonb at codespeak.net
Thu Aug 30 02:59:56 CEST 2007
Author: simonb
Date: Thu Aug 30 02:59:54 2007
New Revision: 46178
Modified:
pypy/dist/pypy/rpython/numpy/aarray.py
pypy/dist/pypy/rpython/numpy/rarray.py
pypy/dist/pypy/rpython/numpy/test/test_array.py
Log:
numpy: progress with indexing, iterators dissapear with malloc removal
Modified: pypy/dist/pypy/rpython/numpy/aarray.py
==============================================================================
--- pypy/dist/pypy/rpython/numpy/aarray.py (original)
+++ pypy/dist/pypy/rpython/numpy/aarray.py Thu Aug 30 02:59:54 2007
@@ -72,20 +72,6 @@
add = sub = mul = div = truediv = union
-class __extend__(pairtype(SomeArray, SomeInteger)):
- def setitem((s_array, s_index), s_value):
- if s_array.ndim == 0:
- raise AnnotatorError()
- if isinstance(s_value, SomeArray):
- assert s_array.ndim == s_value.ndim + 1
-
- def getitem((s_array, s_index)):
- if s_array.ndim == 0:
- raise AnnotatorError()
- if s_array.ndim > 1:
- return SomeArray(s_array.typecode, s_array.ndim-1)
- return s_array.get_item_type()
-
class __extend__(pairtype(SomeArray, SomeTuple)):
def get_leftover_dim((s_array, s_index)):
ndim = s_array.ndim
@@ -100,8 +86,10 @@
def setitem((s_array, s_index), s_value):
ndim = pair(s_array, s_index).get_leftover_dim()
+ if len(s_index.items)>s_array.ndim:
+ raise AnnotatorError("invalid index")
if isinstance(s_value, SomeArray):
- if s_value.ndim + ndim != s_array.ndim:
+ if s_value.ndim != ndim:
# XX allow broadcasting..
raise AnnotatorError("shape mismatch")
elif ndim > 0:
@@ -109,12 +97,33 @@
def getitem((s_array, s_index)):
ndim = pair(s_array, s_index).get_leftover_dim()
+ if len(s_index.items)>s_array.ndim:
+ raise AnnotatorError("invalid index")
if s_array.ndim == 0 and len(s_index.items):
raise AnnotatorError("indexing rank zero array with nonempty tuple")
if ndim > 0:
return SomeArray(s_array.typecode, ndim)
return s_array.get_item_type()
+# These two up-cast the index to SomeTuple and call above.
+class __extend__(pairtype(SomeArray, SomeSlice)):
+ def setitem((s_array, s_index), s_value):
+ s_tuple = SomeTuple([s_index])
+ return pair(s_array, s_tuple).setitem(s_value)
+
+ def getitem((s_array, s_index)):
+ s_tuple = SomeTuple([s_index])
+ return pair(s_array, s_tuple).getitem()
+
+class __extend__(pairtype(SomeArray, SomeInteger)):
+ def setitem((s_array, s_index), s_value):
+ s_tuple = SomeTuple([s_index])
+ return pair(s_array, s_tuple).setitem(s_value)
+
+ def getitem((s_array, s_index)):
+ s_tuple = SomeTuple([s_index])
+ return pair(s_array, s_tuple).getitem()
+
numpy_typedict = {
(SomeInteger, rffi.r_signedchar) : 'b',
(SomeInteger, rffi.r_short) : 'h',
@@ -159,9 +168,9 @@
raise AnnotatorError("List item type not supported")
return SomeArray(typecode, ndim)
- def specialize_call(self, hop):
+ def specialize_call(self, hop, i_dtype=None):
r_array = hop.r_result
- [v_lst] = hop.inputargs(r_array) # coerce list arg to array arg
+ v_lst = hop.inputarg(r_array, 0) # coerce list arg to array arg
v_result = r_array.build_from_array(hop.llops, v_lst)
return v_result
@@ -197,10 +206,10 @@
# v_result = r_array.build_from_shape(hop.llops, r_lst, v_lst)
# return v_result
- def specialize_call(self, hop):
+ def specialize_call(self, hop, i_dtype=None):
r_tpl = hop.args_r[0]
# XX also call with single int arg
- [v_tpl] = hop.inputargs(r_tpl)
+ v_tpl = hop.inputarg(r_tpl, 0)
r_array = hop.r_result
v_result = r_array.build_from_shape(hop.llops, r_tpl, v_tpl)
return v_result
Modified: pypy/dist/pypy/rpython/numpy/rarray.py
==============================================================================
--- pypy/dist/pypy/rpython/numpy/rarray.py (original)
+++ pypy/dist/pypy/rpython/numpy/rarray.py Thu Aug 30 02:59:54 2007
@@ -2,14 +2,18 @@
from pypy.rpython.rrange import AbstractRangeRepr
from pypy.rpython.rint import IntegerRepr
from pypy.rpython.rlist import AbstractBaseListRepr
+from pypy.rpython.rtuple import AbstractTupleRepr
from pypy.rpython.error import TyperError
from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.rpython.lltypesystem.rtupletype import TUPLE_TYPE
+from pypy.rpython.rslice import AbstractSliceRepr
from pypy.rpython.lltypesystem.lltype import \
- GcArray, GcStruct, Signed, Ptr, Unsigned, malloc, Void
+ GcArray, GcStruct, Signed, Ptr, Unsigned, Void, FixedSizeArray, Bool,\
+ malloc, direct_arrayitems, direct_ptradd
+from pypy.rpython.lltypesystem.rtuple import TupleRepr
from pypy.annotation.model import SomeObject, SomeInteger
from pypy.rpython.numpy.aarray import SomeArray
-from pypy.annotation.pairtype import pairtype
+from pypy.annotation.pairtype import pairtype, pair
from pypy.rlib.unroll import unrolling_iterable
from pypy.annotation import listdef
from pypy.rpython.memory.lltypelayout import sizeof
@@ -40,47 +44,110 @@
return shape
return ll_get_shape
+NPY_INTP = Signed # index type (see Py_intptr_t)
+def ARRAY_ITER(ARRAY, INDEXARRAY):
+ ITER = Ptr(
+ GcStruct("array_iter",
+ ("nd_m1", Signed), # number of dimensions - 1
+ ("index", NPY_INTP),
+ ("size", NPY_INTP),
+ ("coordinates", INDEXARRAY),
+ ("dims_m1", INDEXARRAY),
+ ("strides", INDEXARRAY),
+ ("backstrides", INDEXARRAY),
+ #("factors", INDEXARRAY),
+ ("ao", ARRAY),
+ ("dataptr", Ptr(FixedSizeArray(ARRAY.TO.data.TO.OF, 1))), # pointer to current item
+ #("contiguous", Bool),
+ ))
+ return ITER
+
+def ll_mul_list(items, n):
+ result = 1
+ while n:
+ result *= items[n-1]
+ n -= 1
+ return result
+
+def gen_iter_funcs(ndim):
+ unroll_ndim = unrolling_iterable(range(ndim))
+ unroll_ndim_rev = unrolling_iterable(reversed(range(ndim)))
+
+ def ll_iter_reset(it):
+ it.index = 0
+ it.dataptr = direct_arrayitems(it.ao.data)
+ for i in unroll_ndim:
+ it.coordinates[i] = 0
+
+ def ll_iter_new(ITER, ao):
+ it = malloc(ITER)
+ it.nd_m1 = ndim - 1
+ it.size = ll_mul_list(ao.shape, ndim)
+ it.ao = ao
+ #it.factors[nd-1] = 1
+ for i in unroll_ndim:
+ it.dims_m1[i] = ao.shape[i]-1
+ it.strides[i] = ao.strides[i]
+ it.backstrides[i] = it.strides[i] * it.dims_m1[i]
+ #if i > 0:
+ #it.factors[nd-i-1] = it.factors[nd]*ao.shape[nd-i]
+ # ll_iter_reset(it)
+ it.index = 0
+ it.dataptr = direct_arrayitems(it.ao.data)
+ for i in unroll_ndim:
+ it.coordinates[i] = 0
+ return it
+ ll_iter_new._always_inline_ = True
+
+ def ll_iter_next(it):
+ it.index += 1
+ for i in unroll_ndim_rev:
+ if it.coordinates[i] < it.dims_m1[i]:
+ it.coordinates[i] += 1
+ it.dataptr = direct_ptradd(it.dataptr, it.strides[i])
+ break
+ it.coordinates[i] = 0
+ it.dataptr = direct_ptradd(it.dataptr, -it.backstrides[i])
+ i -= 1
+ ll_iter_next._always_inline_ = True
+
+ return ll_iter_new, ll_iter_next
+
+def ll_setitem_from_array(iter_new0, iter_next0, ITER0, array0,
+ slice,
+ iter_new1, iter_next1, ITER1, array1):
+ it0 = iter_new0(ITER0, array0)
+ it1 = iter_new1(ITER1, array1)
+ while it0.index < it0.size:
+ it0.dataptr[0] = it1.dataptr[0]
+ iter_next0(it0)
+ iter_next1(it1)
class ArrayRepr(Repr):
def __init__(self, rtyper, s_array):
self.s_array = s_array
self.s_value = s_array.get_item_type()
- self.item_repr = rtyper.getrepr(self.s_value)
- ITEM = self.item_repr.lowleveltype
- ITEMARRAY = GcArray(ITEM, hints={'nolength':True})
- SIZEARRAY = GcArray(Signed, hints={'nolength':True})
- self.PTR_SIZEARRAY = Ptr(SIZEARRAY)
- self.itemsize = sizeof(ITEM)
self.ndim = s_array.ndim
+ self.item_repr = rtyper.getrepr(self.s_value)
+ self.ITEM = self.item_repr.lowleveltype
+ ITEMARRAY = GcArray(self.ITEM, hints={'nolength':True})
+ self.INDEXARRAY = FixedSizeArray(NPY_INTP, self.ndim)
+ self.itemsize = sizeof(self.ITEM)
self.ARRAY = Ptr(
GcStruct("array",
("data", Ptr(ITEMARRAY)), # pointer to raw data buffer
- ("ndim", Signed), # number of dimensions
- ("shape", self.PTR_SIZEARRAY), # size in each dimension
- ("strides", self.PTR_SIZEARRAY), # bytes (?) to jump to get to the
+ ("ndim", Signed), # number of dimensions (do we need this ?)
+ ("shape", self.INDEXARRAY), # size in each dimension
+ ("strides", self.INDEXARRAY), # elements to jump to get to the
# next element in each dimension
))
self.lowleveltype = self.ARRAY
+ self.ITER = ARRAY_ITER(self.ARRAY, self.INDEXARRAY)
def build_from_array(self, llops, v_array):
cARRAY = inputconst(lltype.Void, self.lowleveltype.TO)
return llops.gendirectcall(ll_build_alias, cARRAY, v_array)
-# def build_from_shape(self, llops, r_tuple, v_tuple):
-# cARRAY = inputconst(lltype.Void, self.lowleveltype.TO)
-# cTUPLE = inputconst(lltype.Void, r_tuple.lowleveltype.TO)
-# ndim = self.ndim
-# c_ndim = inputconst(lltype.Signed, ndim)
-# assert ndim == len(r_tuple.items_r)
-# v_array = llops.gendirectcall(ll_allocate, cARRAY, c_ndim)
-# c_attr = inputconst(lltype.Void, 'shape')
-# v_shape = llops.genop('getfield', [v_array, c_attr], self.PTR_SIZEARRAY)
-# for i in range(ndim):
-# v_size = r_tuple.getitem_internal(llops, v_tuple, i)
-# v_i = inputconst(lltype.Signed, i)
-# llops.genop('setarrayitem', [v_shape, v_i, v_size])
-# return v_array
-
def build_from_shape(self, llops, r_tuple, v_tuple):
cARRAY = inputconst(lltype.Void, self.lowleveltype.TO)
cTUPLE = inputconst(lltype.Void, r_tuple.lowleveltype.TO)
@@ -130,21 +197,57 @@
class __extend__(pairtype(ArrayRepr, ArrayRepr)):
- def rtype_add((r_arr1,r_arr2), hop):
+ def rtype_add((r_arr1, r_arr2), hop):
v_arr1, v_arr2 = hop.inputargs(r_arr1, r_arr2)
cARRAY = hop.inputconst(Void, hop.r_result.ARRAY.TO)
return hop.gendirectcall(ll_add, cARRAY, v_arr1, v_arr2)
class __extend__(pairtype(ArrayRepr, IntegerRepr)):
- def rtype_setitem((r_arr,r_int), hop):
+ def rtype_setitem((r_arr, r_int), hop):
v_array, v_index, v_item = hop.inputargs(r_arr, Signed, r_arr.item_repr)
return hop.gendirectcall(ll_setitem, v_array, v_index, v_item)
- def rtype_getitem((r_arr,r_int), hop):
+ def rtype_getitem((r_arr, r_int), hop):
v_array, v_index = hop.inputargs(r_arr, Signed)
return hop.gendirectcall(ll_getitem, v_array, v_index)
+#class __extend__(pairtype(ArrayRepr, AbstractTupleRepr)):
+# def rtype_setitem((r_arr, r_tpl), hop):
+# v_array, v_tuple, v_item = hop.inputargs(r_arr, r_tpl, r_arr)
+# return hop.gendirectcall(ll_setitem_from_array, v_array, v_tuple, v_item)
+#
+# def rtype_getitem((r_arr, r_tpl), hop):
+# return NotImplemented
+
+
+class __extend__(pairtype(ArrayRepr, AbstractSliceRepr)):
+ def rtype_setitem((r_arr, r_slc), hop):
+ r_item = hop.args_r[2]
+ v_array, v_slc, v_item = hop.inputargs(r_arr, r_slc, r_item)
+ cITER0 = hop.inputconst(Void, r_arr.ITER.TO)
+ cITER1 = hop.inputconst(Void, r_item.ITER.TO)
+ iter_new0, iter_next0 = gen_iter_funcs(r_arr.ndim)
+ iter_new1, iter_next1 = gen_iter_funcs(r_item.ndim)
+ cnew0 = hop.inputconst(Void, iter_new0)
+ cnext0 = hop.inputconst(Void, iter_next0)
+ cnew1 = hop.inputconst(Void, iter_new1)
+ cnext1 = hop.inputconst(Void, iter_next1)
+# return hop.gendirectcall(ll_setitem_from_array, cnext, cITER0, v_array, v_slc, cITER1, v_item)
+ return hop.gendirectcall(ll_setitem_from_array,
+ cnew0, cnext0, cITER0, v_array, v_slc, cnew1, cnext1, cITER1, v_item)
+
+
+#class __extend__(pairtype(ArrayRepr, AbstractSliceRepr)):
+# # promote and delegate XX doesn't work
+# def rtype_setitem((r_arr, r_slc), hop):
+# r_tpl = TupleRepr(hop.rtyper, [r_slc])
+# return pair(r_arr, r_tpl).rtype_setitem(hop)
+#
+# def rtype_getitem((r_arr, r_slc), hop):
+# r_tpl = TupleRepr(hop.rtyper, [r_slc])
+# return pair(r_arr, r_tpl).rtype_getitem(hop)
+
class __extend__(pairtype(AbstractBaseListRepr, ArrayRepr)):
def convert_from_to((r_lst, r_arr), v, llops):
if r_lst.listitem is None:
@@ -163,8 +266,8 @@
def ll_allocate(ARRAY, ndim):
array = malloc(ARRAY)
array.ndim = ndim
- array.shape = malloc(ARRAY.shape.TO, array.ndim)
- array.strides = malloc(ARRAY.strides.TO, array.ndim)
+ #array.shape = malloc(ARRAY.shape.TO, array.ndim)
+ #array.strides = malloc(ARRAY.strides.TO, array.ndim)
return array
def ll_build_from_list(ARRAY, lst):
Modified: pypy/dist/pypy/rpython/numpy/test/test_array.py
==============================================================================
--- pypy/dist/pypy/rpython/numpy/test/test_array.py (original)
+++ pypy/dist/pypy/rpython/numpy/test/test_array.py Thu Aug 30 02:59:54 2007
@@ -86,7 +86,10 @@
a = numpy.zeros((3,4,5))
b = a[0]
a[0,1,2] = 1.
- b[0,1] = a[2]
+ b[0,1] = 2.
+ b[:] = a[1]
+ b[:,:] = a[1]
+ b[0,:] = a[1,2]
return b
t = TranslationContext()
@@ -180,7 +183,7 @@
def test_specialize_array_access(self):
def access_with_variable():
- my_array = numpy.array(range(10))
+ my_array = numpy.array(range(10), dtype='i')
my_array[2] = 2
sum = 0
for idx in range(10):
@@ -238,14 +241,41 @@
assert res.data[0] == 1
assert res.data[1] == 2
- def X_test_specialize_view(self):
+ def test_specialize_indexing(self):
+ def f():
+ a = numpy.zeros((3,), dtype='i')
+ b = numpy.array([5,55,555])
+ a[:] = b
+ return a
+ #self.specialize_view(f)
+ res = interpret(f, [])
+ assert res.data[0] == 5
+ assert res.data[1] == 55
+ assert res.data[2] == 555
+
+ def specialize_view(self, f, args=[]):
t = TranslationContext()
a = t.buildannotator()
- a = a.build_types(f, [])
+ a = a.build_types(f, args)
r = t.buildrtyper()
r.specialize()
+ from pypy.translator.backendopt.all import backend_optimizations
+ backend_optimizations(t, inline=True)
t.view()
+#from pypy.rlib.unroll import unrolling_iterable, unrolling_zero
+#unroller = unrolling_iterable((1,2,3))
+#def deep_f(result, i):
+# result += 1
+# if i<5:
+# result *= deep_f(result, i+1)
+# return result
+#
+#def deep_unroll():
+## i = unrolling_zero
+# i = 0
+# return deep_f(0, i)
+
class Test_compile:
def setup_class(self):
if not test_c_compile:
@@ -265,6 +295,7 @@
assert fn(1) == 99
def test_compile_2d(self):
+ py.test.skip()
def access_array(index):
a = numpy.zeros((5,6))
a[0,0] = 2
More information about the Pypy-commit
mailing list