[pypy-svn] r76308 - in pypy/branch/micronumpy/pypy/module/micronumpy: . test

dan at codespeak.net dan at codespeak.net
Thu Jul 22 01:45:26 CEST 2010


Author: dan
Date: Thu Jul 22 01:45:25 2010
New Revision: 76308

Modified:
   pypy/branch/micronumpy/pypy/module/micronumpy/array.py
   pypy/branch/micronumpy/pypy/module/micronumpy/microarray.py
   pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py
   pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py
Log:
Cleaning up and adding tests.

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	Thu Jul 22 01:45:25 2010
@@ -4,16 +4,21 @@
 from pypy.interpreter.gateway import NoneNotWrapped
 from pypy.interpreter.gateway import interp2app
 
-def iterable_type(space, xs):
-    raise NotImplementedError("Stub")
-
-def get_dtype(space, t):
-    raise NotImplementedError("Stub")
-
-def retrieve_dtype(space, t):
-    raise NotImplementedError("Stub")
-
-from pypy.rpython.lltypesystem import lltype
+def stride_row(shape, i):
+    assert i >= 0
+    stride = 1
+    ndim = len(shape)
+    for s in shape[i + 1:]:
+        stride *= s
+    return stride
+
+def stride_column(shape, i):
+    i -= 1
+    stride = 1
+    while i >= 0:
+        stride *= shape[i]
+        i -= 1
+    return stride
 
 def validate_index(array, space, w_i):
     index_dimensionality = space.int_w(space.len(w_i))

Modified: pypy/branch/micronumpy/pypy/module/micronumpy/microarray.py
==============================================================================
--- pypy/branch/micronumpy/pypy/module/micronumpy/microarray.py	(original)
+++ pypy/branch/micronumpy/pypy/module/micronumpy/microarray.py	Thu Jul 22 01:45:25 2010
@@ -14,6 +14,8 @@
 from pypy.module.micronumpy.array import construct_array, infer_shape
 from pypy.module.micronumpy.dtype import null_data
 
+from pypy.module.micronumpy.array import stride_row, stride_column
+
 def size_from_shape(shape):
     size = 1
     for dimension in shape:
@@ -23,29 +25,11 @@
 def index_w(space, w_index):
     return space.int_w(space.index(w_index))
 
-def stride_row(shape, i):
-    assert i >= 0
-    stride = 1
-    ndim = len(shape)
-    for s in shape[i + 1:]:
-        stride *= s
-    return stride
-
-def stride_column(shape, i):
-    i -= 1
-    if i < 0:
-        return 1
-    elif i == 0:
-        return shape[0]
-    else:
-        stride = 1
-        for s in shape[:i]:
-            stride *= s
-        return stride
-
 class MicroIter(Wrappable):
+    _immutable_fields_ = ['array', 'stride']
     def __init__(self, array):
         self.array = array
+        self.stride = array.stride(0)
         self.i = 0
 
     def descr_iter(self, space):
@@ -53,14 +37,37 @@
     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
+        if self.i < self.array.opposite_stride(1): #will change for row/column
+            if len(self.array.shape) > 1:
+                ar = MicroArray(self.array.shape[1:], # ok for column major?
+                                self.array.dtype,
+                                self.array,
+                                offset = self.array.offset + self.i * self.stride)
+                self.i += 1
+                return space.wrap(ar)
+            elif len(self.array.shape) == 1:
+                next = self.array.getitem(space, self.i * self.stride)
+                self.i += 1
+                return next
+            else:
+                raise OperationError(space.w_ValueError,
+                       space.wrap("Something is horribly wrong with this array's shape. Has %d dimensions." % len(self.array.shape)))
         else:
             raise OperationError(space.w_StopIteration, space.wrap(""))
     descr_next.unwrap_spec = ['self', ObjSpace]
 
+    def __str__(self):
+        from pypy.rlib.rStringIO import RStringIO as StringIO
+        out = StringIO()
+        out.write('iterator(i=')
+        out.write(str(self.i))
+        out.write(', array=')
+        out.write(repr(self.array))
+        out.write(')')
+        result = out.getvalue()
+        out.close()
+        return result
+
 MicroIter.typedef = TypeDef('iterator',
                             __iter__ = interp2app(MicroIter.descr_iter),
                             next = interp2app(MicroIter.descr_next),
@@ -116,27 +123,29 @@
         for i in range(len(index)):
             if index[i] < 0:
                 index[i] = self.shape[i] + index[i]
-        return self.flatten_index(space, index) 
+        return self.flatten_index(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):
+    def flatten_index(self, index):
+        offset = 0
+        for i in range(len(index)):
+            stride = self.stride(i)
+            offset += index[i] * stride
+        return offset
+
+    def stride(self, i):
         if self.order == 'C':
-            return self.flatten_index_r(index) # row order for C
+            return stride_row(self.shape, i) # row order for C
         elif self.order == 'F':
-            return self.flatten_index_c(index) #
+            return stride_column(self.shape, i) #
+        else:
+            raise OperationError(space.w_NotImplementedError,
+                                 space.wrap("Unknown order: '%s'" % self.order))
+
+    def opposite_stride(self, i):
+        if self.order == 'C': # C for C not Column, but this is opposite
+            return stride_column(self.shape, i)
+        elif self.order == 'F':
+            return stride_row(self.shape, i)
         else:
             raise OperationError(space.w_NotImplementedError,
                                  space.wrap("Unknown order: '%s'" % self.order))
@@ -204,6 +213,11 @@
         return app_descr_repr(space, space.wrap(self))
     descr_repr.unwrap_spec = ['self', ObjSpace]
 
+    # FIXME: Can I use app_descr_str directly somehow?
+    def descr_str(self, space):
+        return app_descr_str(space, space.wrap(self))
+    descr_str.unwrap_spec = ['self', ObjSpace]
+
     def descr_iter(self, space):
         return space.wrap(MicroIter(self))
     descr_iter.unwrap_spec = ['self', ObjSpace]
@@ -217,13 +231,40 @@
 
 app_formatting = gateway.applevel("""
     from StringIO import StringIO
-    def stringify(out, array):
+    def stringify(out, array, prefix='', commas=False, first=False, last=False, depth=0):
+        if depth > 0 and not first:
+            out.write('\\n')
+            out.write(prefix) # indenting for array(
+            out.write(' ' * depth) 
+
         out.write("[")
         if len(array.shape) > 1:
-            out.write(',\\n'.join([str(x) for x in array]))
+            i = 1
+            for x in array:
+                if i == 1:
+                    stringify(out, x,
+                              first=True, commas=commas, prefix=prefix, depth=depth + 1)
+                elif i >= len(array):
+                    stringify(out, x,
+                              last=True, commas=commas, prefix=prefix, depth=depth + 1)
+                else:
+                    stringify(out, x,
+                              commas=commas, prefix=prefix, depth=depth + 1)
+
+                i += 1
+            out.write("]")
         else:
-            out.write(', '.join([str(x) for x in array]))
-        out.write("]")
+            if commas:
+                separator = ', '
+            else:
+                separator = ' '
+
+            out.write(separator.join([str(x) for x in array]))
+
+            if commas and not last:
+                out.write("],")
+            else:
+                out.write("]")
 
     def descr_str(self):
         out = StringIO()
@@ -235,7 +276,7 @@
     def descr_repr(self):
         out = StringIO()
         out.write("array(")
-        stringify(out, self)
+        stringify(out, self, commas=True, prefix='      ') 
         out.write(")")
         result = out.getvalue()
         out.close()
@@ -243,6 +284,7 @@
                        """)
 
 app_descr_repr = app_formatting.interphook('descr_repr')
+app_descr_str = app_formatting.interphook('descr_str')
 
 # Getters, strange GetSetProperty behavior
 # forced them out of the class
@@ -273,6 +315,7 @@
                              __setitem__ = interp2app(MicroArray.descr_setitem),
                              __len__ = interp2app(MicroArray.descr_len),
                              __repr__ = interp2app(MicroArray.descr_repr),
+                             __str__ = interp2app(MicroArray.descr_str),
                              __iter__ = interp2app(MicroArray.descr_iter),
                             )
 

Modified: pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py
==============================================================================
--- pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py	(original)
+++ pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py	Thu Jul 22 01:45:25 2010
@@ -5,10 +5,6 @@
 from pypy.interpreter.baseobjspace import ObjSpace, W_Root, Wrappable
 from pypy.rlib.debug import make_sure_not_resized
 
-from pypy.module.micronumpy.sdarray import sdresult
-
-from pypy.module.micronumpy.mdarray import mdresult
-
 def unpack_shape(space, w_shape):
     if space.is_true(space.isinstance(w_shape, space.w_int)):
         return [space.int_w(w_shape)]
@@ -18,82 +14,17 @@
 def infer_shape(space, w_values): 
     return [space.int_w(space.len(w_values))] #TODO: handle multi-dimensional arrays...
 
-class ndarray(Wrappable):
-    def __init__(self, space, w_values, w_shape=NoneNotWrapped, w_dtype=NoneNotWrapped):
-        self.array = None
-        self.space = space
-        if w_dtype is None and not space.is_w(w_values, space.w_None):
-            #TODO: infer type from w_values (better than this)
-            w_dtype = space.type(space.fixedview(w_values)[0]) #FIXME: Allocates an entire array and throws it away!
-
-        self.dtype = w_dtype
-        shape_w = None
-        if w_shape is None:
-            try:
-                shape_w = infer_shape(space, w_values)
-            except OperationError, e:
-                if e.match(space, space.w_TypeError): pass
-                else: raise
-        else:
-            shape_w = unpack_shape(space, w_shape)
-
-        if not shape_w is None and not w_dtype is None:
-            try:
-                if len(shape_w) == 1:
-                    length = shape_w[0]
-                    self.array = sdresult(space, w_dtype)(space, length)
-                else:
-                    self.array = mdresult(space, w_dtype)(space, shape_w)
-            except KeyError, e:
-                raise OperationError(space.w_NotImplementedError,
-                        space.wrap("Haven't implemented generic array yet!"))
-
-        if not w_values is None and not space.is_w(w_values, space.w_None):
-            self.array.load_iterable(w_values) #TODO: implement loading for multi-dimensional arrays
-
-    def validate_index(self, space, w_i):
-        try:
-            index_dimensionality = space.int_w(space.len(w_i))
-            array_dimensionality = len(self.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
-
-    # Math Operations
-    descr_mul = create_math_operation(mul_scalar)
-    descr_div = create_math_operation(div_scalar)
-    descr_add = create_math_operation(add_scalar)
-    descr_sub = create_math_operation(sub_scalar)
-
-    def descr_iter(self):
-        space = self.space
-        return space.wrap(ArrayIter(space, self, 0))
-    descr_iter.unwrap_spec = ['self']
+def validate_index(self, space, w_i):
+    try:
+        index_dimensionality = space.int_w(space.len(w_i))
+        array_dimensionality = len(self.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 descr_getitem(self, space, w_i):
-        self.validate_index(space, w_i)
-        return self.array.getitem(w_i)
-    descr_getitem.unwrap_spec = ['self', ObjSpace, W_Root]
-
-    def descr_setitem(self, space, w_i, w_x):
-        self.validate_index(space, w_i)
-        self.array.setitem(w_i, w_x)
-    descr_setitem.unwrap_spec = ['self', ObjSpace, W_Root, W_Root]
-
-    def descr_len(self, space):
-        return self.array.len()
-    descr_len.unwrap_spec = ['self', ObjSpace]
-
-    def descr_str(self, space):
-        return space.wrap("[%s]" % self.array.str())
-    descr_str.unwrap_spec = ['self', ObjSpace]
-
-    def descr_repr(self, space):
-        return space.wrap("array([%s])" % self.array.str())
-    descr_repr.unwrap_spec = ['self', ObjSpace]
 
 def descr_new(space, w_cls, w_shape,
               w_buffer=NoneNotWrapped, w_offset=NoneNotWrapped,
@@ -103,27 +34,3 @@
 descr_new.unwrap_spec = [ObjSpace, W_Root, W_Root,
                          W_Root, W_Root, 
                          W_Root, str]
-
-ndarray.typedef = TypeDef(
-    'ndarray',
-    #__init__ = interp2app(descr_init), #FIXME
-    __new__ = interp2app(descr_new),
-    __iter__ = interp2app(ndarray.descr_iter),
-    __mul__ = interp2app(ndarray.descr_mul),
-    __div__ = interp2app(ndarray.descr_div),
-    __add__ = interp2app(ndarray.descr_add),
-    __sub__ = interp2app(ndarray.descr_sub),
-    __str__ = interp2app(ndarray.descr_str),
-    __repr__ = interp2app(ndarray.descr_repr),
-    __getitem__ = interp2app(ndarray.descr_getitem),
-    __setitem__ = interp2app(ndarray.descr_setitem),
-    __len__     = interp2app(ndarray.descr_len),
-)
-
-def array(space, w_values, w_shape=NoneNotWrapped, w_dtype=NoneNotWrapped):
-    return ndarray(space, w_values, w_shape, w_dtype)
-array.unwrap_spec = [ObjSpace, W_Root, W_Root, W_Root]
-
-def zeros(space, w_shape, w_dtype=NoneNotWrapped):
-    return ndarray(space, None, w_shape, w_dtype)
-zeros.unwrap_spec = [ObjSpace, W_Root, W_Root]

Modified: pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py
==============================================================================
--- pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py	(original)
+++ pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py	Thu Jul 22 01:45:25 2010
@@ -411,6 +411,14 @@
         assert stride_column(shape, 0) == 1
         assert stride_column(shape, 1) == 2
 
+        shape = (5, 4, 3)
+        assert stride_row(shape, 0) == 12
+        assert stride_row(shape, 1) == 3
+        assert stride_row(shape, 2) == 1
+
+        assert stride_column(shape, 0) == 1
+        assert stride_column(shape, 1) == 5
+        assert stride_column(shape, 2) == 20
         # TODO: more, N-dimensional too
 
     def test_memory_layout(self, space):



More information about the Pypy-commit mailing list