[pypy-svn] r70470 - pypy/branch/micronumpy/pypy/module/micronumpy

dan at codespeak.net dan at codespeak.net
Sat Jan 9 20:17:20 CET 2010


Author: dan
Date: Sat Jan  9 20:17:18 2010
New Revision: 70470

Modified:
   pypy/branch/micronumpy/pypy/module/micronumpy/__init__.py
   pypy/branch/micronumpy/pypy/module/micronumpy/array.py
   pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py
   pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py
   pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py
   pypy/branch/micronumpy/pypy/module/micronumpy/ufunc.py
Log:
Refactored to remove ndarray.py as it was becomming a thinner and thinner wrapper around sdarray and mdarray.

Modified: pypy/branch/micronumpy/pypy/module/micronumpy/__init__.py
==============================================================================
--- pypy/branch/micronumpy/pypy/module/micronumpy/__init__.py	(original)
+++ pypy/branch/micronumpy/pypy/module/micronumpy/__init__.py	Sat Jan  9 20:17:18 2010
@@ -7,9 +7,9 @@
     appleveldefs = {}
     
     interpleveldefs = {
-        'array'    : 'ndarray.array',
-        'ndarray'  : 'ndarray.ndarray',
-        'zeros'    : 'ndarray.zeros',
+        'array'    : 'array.array',
+        'ndarray'  : 'array.ndarray',
+        'zeros'    : 'array.zeros',
         'minimum'  : 'ufunc.minimum',
         }
 

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	Sat Jan  9 20:17:18 2010
@@ -1,12 +1,25 @@
-class BaseNumArray(object):
+from pypy.interpreter.baseobjspace import ObjSpace, W_Root, Wrappable
+from pypy.interpreter.error import OperationError
+from pypy.interpreter.typedef import TypeDef
+from pypy.interpreter.gateway import NoneNotWrapped
+from pypy.interpreter.gateway import interp2app, NoneNotWrapped
+
+from pypy.module.micronumpy.dtype import iterable_type
+
+class BaseNumArray(Wrappable):
     pass
 
-def iterable_type(space, w_xs):
-    xs = space.fixedview(w_xs)
-    type = int
-    for i in range(len(xs)):
-        type = result_types[type, xs[i]]
-    return type
+def validate_index(array, space, w_i):
+    try:
+        index_dimensionality = space.int_w(space.len(w_i))
+        array_dimensionality = len(array.shape)
+        if index_dimensionality > array_dimensionality:
+            raise OperationError(space.w_IndexError,
+                    space.wrap("Index dimensionality (%d) greater than array dimensionality (%d)." % (index_dimensionality, array_dimensionality)))
+    except OperationError, e:
+        if e.match(space, space.w_TypeError): pass
+        else: raise
+
 
 def mul_operation():
     def mul(x, y): return x * y
@@ -47,3 +60,62 @@
     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): 
+    return [space.int_w(space.len(w_values))] #TODO: handle multi-dimensional arrays...
+
+def construct_array(space, shape, w_dtype):
+    from pypy.module.micronumpy.sdarray import sdresult
+    from pypy.module.micronumpy.mdarray import mdresult
+    try:
+        if len(shape) == 1:
+            length = shape[0]
+            return sdresult(space, w_dtype)(space, length, w_dtype)
+        else:
+            return mdresult(space, w_dtype)(space, shape)
+    except KeyError, e:
+        raise OperationError(space.w_NotImplementedError,
+                space.wrap("Haven't implemented generic array yet!"))
+
+def descr_new(space, w_cls, w_shape, w_dtype=NoneNotWrapped,
+              w_buffer=NoneNotWrapped, w_offset=NoneNotWrapped,
+              w_strides=NoneNotWrapped, order='C'):
+    shape_w = unpack_shape(space, w_shape)
+    result = construct_array(space, shape_w, w_dtype)
+    #TODO: load from buffer?
+    return space.wrap(result)
+descr_new.unwrap_spec = [ObjSpace, W_Root, W_Root, W_Root,
+                         W_Root, W_Root,
+                         W_Root, str]
+
+BaseNumArray.typedef = TypeDef("ndarray",
+                       __new__ = interp2app(descr_new),
+                      )
+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:
+        w_dtype = iterable_type(space, w_values)
+    result = construct_array(space, shape, w_dtype)
+    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)
+    result = construct_array(space, shape_w, w_dtype)
+    return space.wrap(result)
+zeros.unwrap_spec = [ObjSpace, W_Root, W_Root, str]

Modified: pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py
==============================================================================
--- pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py	(original)
+++ pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py	Sat Jan  9 20:17:18 2010
@@ -13,3 +13,19 @@
     return float32(space.float_w(w_x))
 def coerce_float32(space, w_x):
     return unwrap_float32(space, space.float(w_x))
+
+def result_mapping(space, w_types):
+    types = {
+            (space.w_int, space.w_int): space.w_int,
+            (space.w_int, space.w_float): space.w_float,
+            (space.w_float, space.w_int): space.w_float,
+            (space.w_float, space.w_float): space.w_float
+            }
+    return types[w_types]
+
+def iterable_type(space, w_xs):
+    xs = space.fixedview(w_xs)
+    result_type = space.w_int
+    for i in range(len(xs)):
+        result_type = result_mapping(space, (result_type, space.type(xs[i])))
+    return result_type

Modified: pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py
==============================================================================
--- pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py	(original)
+++ pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py	Sat Jan  9 20:17:18 2010
@@ -5,6 +5,7 @@
 from pypy.rlib.debug import make_sure_not_resized
 
 from pypy.module.micronumpy.array import BaseNumArray
+from pypy.module.micronumpy.array import base_typedef
 
 from pypy.module.micronumpy.dtype import unwrap_int, coerce_int
 from pypy.module.micronumpy.dtype import unwrap_float, coerce_float
@@ -37,6 +38,18 @@
             self.storage = [data_type(0.0)] * size
             make_sure_not_resized(self.storage)
 
+        def load_iterable(self, w_xs):
+            self._internal_load(w_xs, self.shape)
+
+        def _internal_load(self, w_xs, shape):
+            space = self.space
+            length = shape[0]
+            xs = space.fixedview(w_xs, length)
+
+            #FIXME: brain no work, do later
+            #for x in xs:
+                #self
+
         def _unpack_indexes(self, space, w_index):
             indexes = [space.int_w(w_i) for w_i in space.fixedview(w_index)]
             if len(indexes) != len(self.shape):
@@ -44,17 +57,19 @@
                     'Wrong index'))
             return indexes
 
-        def getitem(self, w_index):
+        def descr_getitem(self, w_index):
             space = self.space
             indexes = self._unpack_indexes(space, w_index)
             pos = compute_pos(space, indexes, self.shape)
             return space.wrap(self.storage[pos])
+        descr_getitem.unwrap_spec = ['self', W_Root]
 
-        def setitem(self, w_index, w_value):
+        def descr_setitem(self, w_index, w_value):
             space = self.space
             indexes = self._unpack_indexes(space, w_index)
             pos = compute_pos(space, indexes, self.shape)
             self.storage[pos] = coerce(space, w_value)
+        descr_setitem.unwrap_spec = ['self', W_Root, W_Root]
 
         def load_iterable(self, w_xs):
             space = self.space
@@ -62,13 +77,21 @@
                                        space.wrap("Haven't implemented iterable loading yet!"))
 
         def len(self):
+            return self.shape[0]
+
+        def descr_len(self):
             space = self.space
-            return space.wrap(self.shape[0])
+            return space.wrap(self.len())
+        descr_len.unwrap_spec = ['self']
 
+    MultiDimArray.typedef = TypeDef('ndarray', base_typedef,
+                                    __len__ = interp2app(MultiDimArray.descr_len),
+                                    __getitem__ = interp2app(MultiDimArray.descr_getitem),
+                                    __setitem__ = interp2app(MultiDimArray.descr_setitem),
+                                   )
     return MultiDimArray
 
 MultiDimIntArray = create_mdarray(int, unwrap_int, coerce_int)
-MultiDimArray = MultiDimIntArray #XXX: compatibility
 MultiDimFloatArray = create_mdarray(float, unwrap_float, coerce_float)
 
 class ResultFactory(object):

Modified: pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py
==============================================================================
--- pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py	(original)
+++ pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py	Sat Jan  9 20:17:18 2010
@@ -3,49 +3,69 @@
 from pypy.interpreter.typedef import TypeDef
 from pypy.interpreter.gateway import interp2app, NoneNotWrapped
 from pypy.rlib.debug import make_sure_not_resized
-from pypy.objspace.std.typeobject import W_TypeObject
 
 from pypy.module.micronumpy.array import BaseNumArray
+from pypy.module.micronumpy.array import base_typedef
 from pypy.module.micronumpy.array import mul_operation, div_operation, add_operation, sub_operation
 from pypy.module.micronumpy.array import copy_operation
+
 from pypy.module.micronumpy.dtype import unwrap_int, coerce_int
 from pypy.module.micronumpy.dtype import unwrap_float, coerce_float
 from pypy.module.micronumpy.dtype import unwrap_float32, coerce_float32, float32
+from pypy.module.micronumpy.dtype import result_mapping
 
 # from pypy.interpreter.gateway import unwrap_spec #TODO: merge unwrap_spec decorator
 
 class BaseSingleDimArray(BaseNumArray): pass
 
 def create_sdarray(data_type, unwrap, coerce):
+    class SingleDimIterator(Wrappable):
+        def __init__(self, space, array, i):
+            self.space = space
+            self.array = array
+            self.i = i
+
+        def descr_iter(self):
+            self.space = space
+            return space.wrap(self)
+        descr_iter.unwrap_spec = ['self']
+
+        def descr_next(self):
+            space = self.space
+            try:
+                result = self.array.storage[self.i]
+                self.i += 1
+                return space.wrap(result)
+            except IndexError, e:
+                raise OperationError(space.w_StopIteration, space.wrap(""))
+        descr_iter.unwrap_spec = ['self']
+
+    SingleDimIterator.typedef = TypeDef('iterator',
+                                __iter__ = interp2app(SingleDimIterator.descr_iter),
+                                next = interp2app(SingleDimIterator.descr_next)
+                                )
+
+    mul = mul_operation()
+    div = div_operation()
+    add = add_operation()
+    sub = sub_operation()
+    copy = copy_operation()
+
     class NumArray(BaseSingleDimArray):
-        def __init__(self, space, length):
-            self.shape = (1,)
-            self.length = length
+        def __init__(self, space, length, dtype):
+            self.shape = (length,)
             self.space = space
-            self.storage = [data_type(0.0)] * length
+            self.storage = [data_type()] * length
+            self.dtype = dtype
             make_sure_not_resized(self.storage)
 
-        mul = mul_operation()
-        div = div_operation()
-        add = add_operation()
-        sub = sub_operation()
-        copy = copy_operation()
-
-        def create_scalar_op(f):
-            def scalar_operation(self, source, w_x):
-                space = self.space
+        def create_math_operation(f):
+            def scalar_operation(result, source, w_x):
+                space = result.space
                 x = coerce(space, w_x)
-                for i in range(source.length):
-                    self.storage[i] = f(data_type(source.storage[i]), x)
-            return scalar_operation
-
-        mul_scalar = create_scalar_op(mul)
-        div_scalar = create_scalar_op(div)
-        add_scalar = create_scalar_op(add)
-        sub_scalar = create_scalar_op(sub)
+                for i in range(len(source.storage)):
+                    result.storage[i] = f(data_type(source.storage[i]), x)
 
-        #TODO: wrap up fixedview and scalar together
-        def create_fixedview_op(f):
             def fixedview_operation(self, w_xs):
                 space = self.space
                 try:
@@ -60,47 +80,100 @@
                     self.storage[i] = f(source.storage[i], self.coerce(w_x)) #TODO: probably shouldn't coerce
                     i += 1
                 return result
-            return fixedview_operation
 
-        copy_iterable = create_fixedview_op(copy)
+            def math_operation(self, w_x):
+                space = self.space
+                if space.type(w_x) in (space.w_list, space.w_tuple):
+                    raise OperationError(space.w_NotImplementedError,
+                                         space.wrap("Haven't implemented array * iterable yet!"))
+                else:
+                    result_t = result_mapping(space, (space.type(w_x), self.dtype))
+                    result = sdresult(space, result_t)(space, self.len(), self.dtype)
+                    scalar_operation(result, self, w_x)
+
+                    w_result = space.wrap(result)
+                return w_result
+            math_operation.unwrap_spec = ['self', W_Root]
+            return math_operation
+
+        descr_mul = create_math_operation(mul)
+        descr_mul.__name__ = 'descr_mul'
+
+        descr_div = create_math_operation(div)
+        descr_div.__name__ = 'descr_div'
+
+        descr_add = create_math_operation(add)
+        descr_add.__name__ = 'descr_add'
+
+        descr_sub = create_math_operation(sub)
+        descr_sub.__name__ = 'descr_sub'
 
-        def load_iterable(self, w_values): #FIXME: less than ideal
+        def load_iterable(self, w_values):
             space = self.space
             i = 0
-            for x in space.fixedview(w_values, self.length):
-                self.storage[i] = unwrap(space, x)
+            for x in space.fixedview(w_values, self.len()):
+                self.storage[i] = coerce(space, x)
                 i += 1
 
-        def getitem(self, w_index):
+        def descr_iter(self):
+            return space.wrap(SingleDimIterator(space, self, 0))
+        descr_iter.unwrap_spec = ['self']
+
+        def descr_getitem(self, index):
             space = self.space
-            index = space.int_w(w_index)
             try:
                 return space.wrap(self.storage[index])
             except IndexError:
                 raise OperationError(space.w_IndexError,
                                      space.wrap("list index out of range"))
+        descr_getitem.unwrap_spec = ['self', int]
 
-        def setitem(self, w_index, w_value):
+        def descr_setitem(self, index, w_value):
             space = self.space
-            index = space.int_w(w_index)
             try:
                 self.storage[index] = coerce(space, w_value)
             except IndexError:
                 raise OperationError(space.w_IndexError,
                                      space.wrap("list index out of range"))
             return space.w_None
+        descr_setitem.unwrap_spec = ['self', int, W_Root]
 
         def len(self):
+            return len(self.storage)
+
+        def descr_len(self):
             space = self.space
-            return space.wrap(len(self.storage))
+            return space.wrap(self.len())
+        descr_len.unwrap_spec = ['self']
 
         def str(self):
             return ', '.join([str(x) for x in self.storage])
 
+        def descr_str(self):
+            space = self.space
+            return space.wrap("[%s]" % self.str())
+        descr_str.unwrap_spec = ['self']
+
+        def descr_repr(self):
+            space = self.space
+            return space.wrap("array([%s])" % self.str())
+        descr_repr.unwrap_spec = ['self']
+
+    NumArray.typedef = TypeDef('ndarray', base_typedef,
+                               __mul__ = interp2app(NumArray.descr_mul),
+                               __div__ = interp2app(NumArray.descr_div),
+                               __add__ = interp2app(NumArray.descr_add),
+                               __sub__ = interp2app(NumArray.descr_sub),
+                               __getitem__ = interp2app(NumArray.descr_getitem),
+                               __setitem__ = interp2app(NumArray.descr_setitem),
+                               __len__ = interp2app(NumArray.descr_len),
+                               __str__ = interp2app(NumArray.descr_str),
+                               __repr__ = interp2app(NumArray.descr_repr),
+                              )
+
     return NumArray
 
 IntArray = create_sdarray(int, unwrap_int, coerce_int)
-NumArray = IntArray # FIXME: compatibility for now
 FloatArray = create_sdarray(float, unwrap_float, coerce_float)
 Float32Array = create_sdarray(float32, unwrap_float32, coerce_float32)
 GenericArray = None

Modified: pypy/branch/micronumpy/pypy/module/micronumpy/ufunc.py
==============================================================================
--- pypy/branch/micronumpy/pypy/module/micronumpy/ufunc.py	(original)
+++ pypy/branch/micronumpy/pypy/module/micronumpy/ufunc.py	Sat Jan  9 20:17:18 2010
@@ -1,4 +1,4 @@
-from pypy.module.micronumpy.ndarray import array, zeros, ndarray
+from pypy.module.micronumpy.array import array, zeros, ndarray
 from pypy.interpreter.baseobjspace import ObjSpace, W_Root
 from pypy.interpreter.error import OperationError
 
@@ -6,16 +6,16 @@
     if not isinstance(w_a, ndarray) or not isinstance(w_b, ndarray):
         raise OperationError(space.w_TypeError,
                              space.wrap("expecting ndarray object"))
-    if w_a.array.length != w_b.array.length:
+    if w_a.len()!= w_b.len():
         raise OperationError(space.w_ValueError,
                              space.wrap("minimum of arrays of different length"))
-    res = zeros(space, space.wrap(w_a.array.length), w_a.dtype)
-    for i in range(len(w_a.array.storage)):
-        one = w_a.array.storage[i]
-        two = w_b.array.storage[i]
+    res = zeros(space, space.wrap(w_a.len()), w_a.dtype)
+    for i in range(len(w_a.storage)):
+        one = w_a.storage[i]
+        two = w_b.storage[i]
         if one < two:
-            res.array.storage[i] = one
+            res.storage[i] = one
         else:
-            res.array.storage[i] = two
+            res.storage[i] = two
     return space.wrap(res)
 minimum.unwrap_spec = [ObjSpace, W_Root, W_Root]



More information about the Pypy-commit mailing list