[pypy-svn] r76193 - pypy/branch/micronumpy/pypy/module/micronumpy
dan at codespeak.net
dan at codespeak.net
Wed Jul 14 10:51:24 CEST 2010
Author: dan
Date: Wed Jul 14 10:51:23 2010
New Revision: 76193
Added:
pypy/branch/micronumpy/pypy/module/micronumpy/microarray.py
Modified:
pypy/branch/micronumpy/pypy/module/micronumpy/array.py
Log:
That's an important file...
Modified: pypy/branch/micronumpy/pypy/module/micronumpy/array.py
==============================================================================
--- pypy/branch/micronumpy/pypy/module/micronumpy/array.py (original)
+++ pypy/branch/micronumpy/pypy/module/micronumpy/array.py Wed Jul 14 10:51:23 2010
@@ -13,9 +13,6 @@
def retrieve_dtype(space, t):
raise NotImplementedError("Stub")
-class BaseNumArray(Wrappable):
- pass
-
from pypy.rpython.lltypesystem import lltype
def validate_index(array, space, w_i):
@@ -33,52 +30,6 @@
raise OperationError(space.w_IndexError,
space.wrap("invalid index")) # all as in numpy
-def mul_operation():
- def mul(x, y): return x * y
- return mul
-
-def div_operation():
- def div(x, y): return x / y
- return div
-
-def add_operation():
- def add(x, y): return x + y
- return add
-
-def sub_operation():
- def sub(x, y): return x - y
- return sub
-
-def copy_operation():
- def copy(x, y): return x #XXX: I sure hope GCC can optimize this
- return copy
-
-def app_mul_operation():
- def mul(space, x, y):
- return space.mul(x, y)
- return mul
-
-def app_div_operation():
- def div(space, x, y):
- return space.div(x, y)
- return div
-
-def app_add_operation():
- def add(space, x, y):
- return space.add(x, y)
- return add
-
-def app_sub_operation():
- def sub(space, x, y):
- return space.sub(x, y)
- return sub
-
-def unpack_shape(space, w_shape):
- if space.is_true(space.isinstance(w_shape, space.w_int)):
- return [space.int_w(w_shape)]
- shape_w = space.fixedview(w_shape)
- return [space.int_w(w_i) for w_i in shape_w]
-
def infer_shape(space, w_values):
shape = []
while True:
@@ -104,6 +55,9 @@
raise OperationError(space.w_NotImplementedError,
space.wrap("Haven't implemented generic array yet!"))
+class BaseNumArray(Wrappable):
+ pass
+
def descr_new(space, w_cls, w_shape, w_dtype=NoneNotWrapped,
w_buffer=NoneNotWrapped, w_offset=NoneNotWrapped,
w_strides=NoneNotWrapped, order='C'):
@@ -121,29 +75,3 @@
)
base_typedef = BaseNumArray.typedef
ndarray = BaseNumArray
-
-def array(space, w_values, w_dtype=NoneNotWrapped,
- copy=True, order='C',
- subok=False, ndim=1):
- shape = infer_shape(space, w_values)
-
- if w_dtype is None:
- dtype_w = retrieve_dtype(space, iterable_type(space, w_values))
- else:
- dtype_w = get_dtype(space, w_dtype)
- result = construct_array(space, shape, dtype_w)
- result.load_iterable(w_values)
- return space.wrap(result)
-array.unwrap_spec = [ObjSpace, W_Root, W_Root,
- bool, str,
- bool, int]
-
-def zeros(space, w_shape, w_dtype=NoneNotWrapped, order='C'):
- shape_w = unpack_shape(space, w_shape)
- if w_dtype is None:
- dtype_w = retrieve_dtype(space, 'd')
- else:
- dtype_w = get_dtype(space, w_dtype)
- result = construct_array(space, shape_w, dtype_w)
- return space.wrap(result)
-zeros.unwrap_spec = [ObjSpace, W_Root, W_Root, str]
Added: pypy/branch/micronumpy/pypy/module/micronumpy/microarray.py
==============================================================================
--- (empty file)
+++ pypy/branch/micronumpy/pypy/module/micronumpy/microarray.py Wed Jul 14 10:51:23 2010
@@ -0,0 +1,354 @@
+from pypy.interpreter.baseobjspace import ObjSpace
+from pypy.interpreter.error import OperationError
+from pypy.interpreter.typedef import TypeDef, GetSetProperty
+from pypy.interpreter.gateway import interp2app
+from pypy.interpreter.gateway import NoneNotWrapped
+
+from pypy.interpreter.baseobjspace import Wrappable
+from pypy.interpreter.baseobjspace import W_Root, UnpackValueError
+from pypy.objspace.std.sliceobject import W_SliceObject
+from pypy.objspace.std.listobject import W_ListObject
+from pypy.objspace.std.tupleobject import W_TupleObject
+from pypy.rlib.debug import make_sure_not_resized
+
+from pypy.module import micronumpy
+from pypy.module.micronumpy.array import BaseNumArray
+from pypy.module.micronumpy.array import base_typedef
+from pypy.module.micronumpy.array import construct_array, infer_shape
+from pypy.module.micronumpy.array import validate_index
+
+def size_from_shape(shape):
+ size = 1
+ for dimension in shape:
+ size *= dimension
+ return size
+
+def index_w(space, w_index):
+ return space.int_w(space.index(w_index))
+
+def stride_row(shape, i):
+ stride = 1
+ ndim = len(shape)
+ for s in shape[i + 1:]:
+ stride *= s
+ return stride
+
+def stride_column(shape, i):
+ if i < 1: return 1
+ elif i == 1:
+ return shape[0]
+ stride = 1
+ for s in shape[:i-1]:
+ stride *= s
+ return stride
+
+class MicroIter(Wrappable):
+ def __init__(self, array):
+ self.array = array
+ self.i = 0
+
+ def descr_iter(self, space):
+ return space.wrap(self)
+ descr_iter.unwrap_spec = ['self', ObjSpace]
+
+ def descr_next(self, space):
+ if self.i < space.int_w(space.len(self.array)):
+ next = self.array.getitem(space, self.i) # FIXME: wrong for multi dimensional! (would be easy applevel)
+ self.i += 1
+ return next
+ else:
+ raise OperationError(space.w_StopIteration, space.wrap(""))
+ descr_next.unwrap_spec = ['self', ObjSpace]
+
+MicroIter.typedef = TypeDef('iterator',
+ __iter__ = interp2app(MicroIter.descr_iter),
+ next = interp2app(MicroIter.descr_next),
+ )
+
+class MicroArray(BaseNumArray):
+ def __init__(self, shape, dtype, parent=None, offset = 0):
+ self.shape = shape
+ self.dtype = dtype
+ self.parent = parent
+ self.offset = offset
+ self.order = 'C' #XXX: more forgiving to give it valid default
+
+ assert self.dtype is not None
+ dtype = dtype.dtype #XXX: ugly
+
+ size = size_from_shape(shape)
+
+ if size > 0 and parent is None:
+ self.data = dtype.alloc(size)
+ elif parent is not None:
+ self.data = parent.data
+ else:
+ self.data = None
+
+ def descr_len(self, space):
+ return space.wrap(self.shape[0])
+ descr_len.unwrap_spec = ['self', ObjSpace]
+
+ def getitem(self, space, index):
+ try:
+ dtype = self.dtype.dtype #XXX: kinda ugly
+ return dtype.w_getitem(space, self.data, self.offset + index)
+ except IndexError, e:
+ raise OperationError(space.w_IndexError,
+ space.wrap("index out of bounds"))
+
+ def setitem(self, space, index, w_value):
+ dtype = self.dtype.dtype #XXX: kinda ugly
+ dtype.w_setitem(space, self.data, self.offset + index, w_value) #maybe hang onto w_dtype separately?
+
+ def flatten_applevel_index(self, space, w_index):
+ try:
+ index = space.int_w(w_index)
+ return index
+ except OperationError, e:
+ if not e.match(space, space.w_TypeError):
+ raise
+
+ index = space.fixedview(w_index)
+ index = [index_w(space, w_x) for w_x in index]
+ # XXX: normalize
+ for i in range(len(index)):
+ if index[i] < 0:
+ index[i] = self.shape[i] + index[i]
+ return self.flatten_index(space, index)
+
+ def create_flatten_index(stride_function):
+ def flatten_index(self, index):
+ offset = 0
+ for i in range(len(index)):
+ stride = stride_function(self.shape, i)
+ offset += index[i] * stride
+ return offset
+ return flatten_index
+
+ flatten_index_r = create_flatten_index(stride_row)
+ flatten_index_c = create_flatten_index(stride_column)
+
+ # FIXME: when different types are supported
+ # this function will change
+ def flatten_index(self, space, index):
+ if self.order == 'C':
+ return self.flatten_index_r(index) # row order for C
+ elif self.order == 'F':
+ return self.flatten_index_c(index) #
+ else:
+ raise OperationError(space.w_NotImplementedError,
+ space.wrap("Unknown order: '%s'" % self.order))
+
+ def descr_getitem(self, space, w_index):
+ try:
+ index = self.flatten_applevel_index(space, w_index)
+
+ try:
+ #w_iter = space.iter(w_index) # XXX: I guess len() should throw TypeError
+ # FIXME: what about slices?
+ index_dimension = space.int_w(space.len(w_index))
+ except OperationError, e:
+ if e.match(space, space.w_TypeError):
+ index_dimension = 1
+ else: raise
+
+ if index_dimension == len(self.shape):
+ return self.getitem(space, index)
+ elif index_dimension < len(self.shape):
+ array = MicroArray(self.shape[index_dimension:], self.dtype,
+ parent=self, offset=self.offset + index)
+ return space.wrap(array)
+ else:
+ raise OperationError(space.w_IndexError,
+ space.wrap("invalid index"))
+
+ except OperationError, e:
+ if e.match(space, space.w_TypeError): pass # is there any way this can be caught here?
+ else: raise
+
+ # XXX: here be demons
+
+ try:
+ indices = []
+ index = space.fixedview(w_index)
+ if len(index) > len(self.shape):
+ raise OperationError(space.w_ValueError,
+ space.wrap("Index has more dimensions (%d) than array (%d)" % (len(index), len(self.shape))))
+
+ for i in range(len(index)):
+ indices.append([])
+
+ for subindex in index:
+ try:
+ raise OperationError(space.w_NotImplementedError,
+ space.wrap("Haven't implemented newaxis."))
+ except OperationError, e:
+ pass
+
+ except OperationError, e:
+ if e.match(space, space.w_StopIteration): pass
+ else: raise
+
+
+ descr_getitem.unwrap_spec = ['self', ObjSpace, W_Root]
+
+ def descr_setitem(self, space, w_index, w_value):
+ index = self.flatten_applevel_index(space, w_index)
+ self.setitem(space, index, w_value)
+ descr_setitem.unwrap_spec = ['self', ObjSpace, W_Root, W_Root]
+
+ def descr_repr(self, space):
+ return space.wrap("<MicroArray Object>")
+ descr_repr.unwrap_spec = ['self', ObjSpace]
+
+ def descr_iter(self, space):
+ return space.wrap(MicroIter(self))
+ descr_iter.unwrap_spec = ['self', ObjSpace]
+
+ def __del__(self):
+ if self.parent is None and self.data is not None:
+ dtype = self.dtype.dtype
+ dtype.free(self.data)
+
+from pypy.interpreter import gateway
+
+app_formatting = gateway.applevel("""
+ from StringIO import StringIO
+ def str(out, array):
+ out.write("[")
+ if len(array.shape) > 1:
+ out.write(',\\n'.join([str(x) for x in array]))
+ else:
+ out.write(', '.join([str(x) for x in array]))
+ out.write("]")
+
+ def descr_str(self):
+ out = StringIO()
+ str(out, self)
+ result = out.getvalue()
+ out.close()
+ return result
+
+ def descr_repr(self):
+ out = StringIO()
+ out.write("array(")
+ str(out, self)
+ out.write(")")
+ result = out.getvalue()
+ out.close()
+ return result
+ """)
+
+app_descr_repr = app_formatting.interphook('descr_repr')
+
+def microarray_descr_repr(self, space):
+ return app_descr_repr(space, space.wrap(self))
+microarray_descr_repr.unwrap_spec = ['self', ObjSpace]
+
+# Getters, strange GetSetProperty behavior
+# forced them out of the class
+def descr_get_dtype(space, self):
+ return space.wrap(self.dtype)
+
+def descr_get_shape(space, self):
+ return space.newtuple([space.wrap(x) for x in self.shape])
+
+MicroArray.typedef = TypeDef('uarray',
+ dtype = GetSetProperty(descr_get_dtype, cls=MicroArray),
+ shape = GetSetProperty(descr_get_shape, cls=MicroArray),
+ __getitem__ = interp2app(MicroArray.descr_getitem),
+ __setitem__ = interp2app(MicroArray.descr_setitem),
+ __len__ = interp2app(MicroArray.descr_len),
+ __repr__ = microarray_descr_repr,
+ __iter__ = interp2app(MicroArray.descr_iter),
+ )
+
+def reconcile_shapes(space, a, b):
+ assert a == b, "Invalid assertion I think" # FIXME
+ return a
+
+#def infer_shape(space, w_xs):
+def infer_shape_slow(space, w_xs): # gonna kill this after it's been svn for one revision
+ length = 0
+ shape = []
+ old = None
+ try:
+ w_i = space.iter(w_xs)
+ while True:
+ element = space.next(w_i)
+ try:
+ shape = infer_shape(space, element)
+ except OperationError, e:
+ if e.match(space, space.w_TypeError): pass
+ else: raise
+
+ if old is not None:
+ shape = reconcile_shapes(space, old, shape) # use to process jagged arrays, if Numpy even allows them
+
+ length += 1
+ old = shape
+ except OperationError, e:
+ if e.match(space, space.w_StopIteration):
+ return [length] + shape
+ else:
+ raise
+
+#XXX: don't like having to pass around setitem
+app_fill_array = gateway.applevel("""
+ def fill_array(start, a, b):
+ i = 0
+ for x in b:
+ print i
+ try:
+ fill_array(start + [i], a, x)
+ except TypeError, e:
+ a[start + [i]] = x
+ i += 1
+ """)
+
+fill_array = app_fill_array.interphook('fill_array')
+
+def array(space, w_xs, w_dtype=NoneNotWrapped, copy=True, order='C', subok=False, w_ndim=NoneNotWrapped):
+ if w_dtype is None:
+ dtype = micronumpy.dtype.infer_from_iterable(space, w_xs)
+ else:
+ dtype = micronumpy.dtype.get(space, w_dtype)
+
+ assert dtype is not None
+ wrappable_dtype = dtype.wrappable_dtype()
+
+ shape = infer_shape(space, w_xs)
+
+ ar = MicroArray(shape, wrappable_dtype)
+ ar.order = order
+ w_ar = space.wrap(ar)
+
+ fill_array(space,
+ space.wrap([]), w_ar, w_xs)
+
+ return w_ar
+array.unwrap_spec = [ObjSpace, W_Root, W_Root, bool, str, bool, W_Root]
+
+def zeros(space, w_shape, w_dtype=NoneNotWrapped, order='C'):
+ try:
+ shape_w = space.fixedview(w_shape)
+ shape = [space.int_w(x) for x in shape_w]
+ except OperationError, e:
+ if e.match(space, space.w_TypeError):
+ shape = [space.int_w(w_shape)]
+ else: raise
+
+ if w_dtype:
+ dtype = micronumpy.dtype.get(space, w_dtype)
+ else:
+ dtype = micronumpy.dtype.int_descr
+
+ ar = MicroArray(shape, dtype.wrappable_dtype())
+ ar.order = order
+
+ for i in range(size_from_shape(shape)):
+ ar.setitem(space, i, space.wrap(0))
+
+ return space.wrap(ar)
+zeros.unwrap_spec = [ObjSpace, W_Root, W_Root]
More information about the Pypy-commit
mailing list