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

dan at codespeak.net dan at codespeak.net
Wed Jul 14 10:46:17 CEST 2010


Author: dan
Date: Wed Jul 14 10:46:16 2010
New Revision: 76192

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/sdarray.py
   pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py
   pypy/branch/micronumpy/pypy/module/micronumpy/ufunc.py
Log:
Initial commit for GSoC changes, lots of skipped tests, needs lots of cleanup, needs more tests.

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	Wed Jul 14 10:46:16 2010
@@ -1,15 +1,21 @@
 
 from pypy.interpreter.mixedmodule import MixedModule 
+import dtype
 
 class Module(MixedModule):
+    def __init__(self, space, w_name):
+        super(Module, self).__init__(space, w_name) 
+        from pypy.module.micronumpy import dtype
+        dtype.w_int_descr.w_native_type = space.w_int
+        dtype.w_float_descr.w_native_type = space.w_float
 
-    applevel_name = 'numpy'
+    applevel_name = 'micronumpy'
     appleveldefs = {}
     
     interpleveldefs = {
-        'array'    : 'array.array',
+        'array'    : 'microarray.array',
+        'zeros'    : 'microarray.zeros',
         'ndarray'  : 'array.ndarray',
-        'zeros'    : 'array.zeros',
         'minimum'  : 'ufunc.minimum',
         'dot'      : 'ufunc.dot',
         }

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:46:16 2010
@@ -4,14 +4,20 @@
 from pypy.interpreter.gateway import NoneNotWrapped
 from pypy.interpreter.gateway import interp2app
 
-from pypy.module.micronumpy.dtype import iterable_type
+def iterable_type(space, xs):
+    raise NotImplementedError("Stub")
 
-from pypy.module.micronumpy.dtype import get_dtype
-from pypy.module.micronumpy.dtype import retrieve_dtype #FIXME: ambiguous name?
+def get_dtype(space, t):
+    raise NotImplementedError("Stub")
+
+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):
     index_dimensionality = space.int_w(space.len(w_i))
     array_dimensionality = len(array.shape)
@@ -90,14 +96,10 @@
     return shape
 
 def construct_array(space, shape, w_dtype):
-    from pypy.module.micronumpy.sdarray import sdresult
-    from pypy.module.micronumpy.mdarray import mdresult
+    from pypy.module.micronumpy.microarray import MicroArray
     try:
-        if len(shape) == 1:
-            length = shape[0]
-            return sdresult(w_dtype.code)(space, length, w_dtype)
-        else:
-            return mdresult(w_dtype.code)(space, shape, w_dtype)
+        array = MicroArray(shape, w_dtype)
+        return space.wrap(array)
     except KeyError, e:
         raise OperationError(space.w_NotImplementedError,
                 space.wrap("Haven't implemented generic array yet!"))

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	Wed Jul 14 10:46:16 2010
@@ -1,139 +1,210 @@
 from pypy.interpreter.baseobjspace import ObjSpace, W_Root, Wrappable
 from pypy.interpreter.error import OperationError
-from pypy.interpreter.typedef import TypeDef
+from pypy.interpreter.typedef import TypeDef, GetSetProperty
 from pypy.interpreter.gateway import interp2app
+from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.lltypesystem import rffi
 
-def unwrap_int(space, w_x):
-    return space.int_w(w_x)
-def coerce_int(space, w_x):
-    return unwrap_int(space, space.int(w_x))
-
-def unwrap_float(space, w_x):
-    return space.float_w(w_x)
-def coerce_float(space, w_x):
-    return unwrap_float(space, space.float(w_x))
-
-from pypy.rlib.rarithmetic import r_singlefloat as float32
-
-def unwrap_float32(space, w_x):
-    return float32(space.float_w(w_x))
-def coerce_float32(space, w_x):
-    return unwrap_float32(space, space.float(w_x))
-
-def create_factory(result_factory):
-    def factory(t):
-        return result_factory[t]
-    return factory
-
-class DynamicType(Wrappable):
-    def __init__(self, code, name, applevel_type):
-        self.code = code
+class TypeDescr(Wrappable):
+    def __init__(self, dtype, name):
+        self.dtype = dtype
         self.name = name
-        self.applevel_type = applevel_type
+        self.w_native_type = None
 
-    def descr_eq(self, space, w_x):
-        if space.abstract_isinstance_w(w_x, space.w_type):
-            return space.eq(self.applevel_type, w_x) #FIXME: correct comparison?
-        else:
-            try:
-                code = space.str_w(w_x)
-                if self.code == code:
-                    return space.w_True
-                elif self.name == code:
-                    return space.w_True
-                else:
-                    raise OperationError(space.w_TypeError, space.wrap("data type not understood"))
-            except OperationError, e:
-                raise OperationError(space.w_TypeError, space.wrap("data type not understood"))
-    descr_eq.unwrap_spec = ['self', ObjSpace, W_Root]
-DynamicType.typedef = TypeDef('dtype',
-                              __eq__ = interp2app(DynamicType.descr_eq),
-                             )
-
-class DynamicTypes(object):
-    result_types = {
-                    ('i', 'i'): 'i',
-                    ('i', 'd'): 'd',
-                    ('d', 'i'): 'd',
-                    ('d', 'd'): 'd',
-                   }
-
-    def __init__(self):
-        self.dtypes = {}
+    def descr_eq(self, space, w_type):
+        if space.eq_w(self.w_native_type, w_type):
+            return space.w_True
 
-    def typecode(self, space, w_type):
         try:
-            assert isinstance(w_type, DynamicType)
-            return w_type.code
-        except AssertionError, e: pass
+            typestr = space.str_w(w_type)
+            if self.dtype.typecode == typestr: return space.w_True
+            elif self.name == typestr: return space.w_True
+            else: return space.w_False
+        except OperationError, e:
+            if e.match(space, space.w_TypeError): pass
+            else: raise
+
+        return space.w_False
+    descr_eq.unwrap_spec = ['self', ObjSpace, W_Root]
+
+    def descr_itemsize(self, space):
+        return space.wrap(self.dtype.itemsize())
+    descr_itemsize.unwrap_spec = ['self', ObjSpace]
+
+    def descr_repr(self, space):
+        return space.wrap("dtype('%s')" % self.name)
+    descr_repr.unwrap_spec = ['self', ObjSpace]
+
+    def result(self, other):
+        a = self.dtype.typeid
+        b = other.dtype.typeid
+        c = _result_types[(a, b)]
+        return _descriptors[c].wrappable_dtype()
+
+TypeDescr.typedef = TypeDef('dtype',
+                            itemsize = GetSetProperty(TypeDescr.descr_itemsize),
+                            __eq__ = interp2app(TypeDescr.descr_eq),
+                            __repr__ = interp2app(TypeDescr.descr_repr),
+                           )
+                            
+class DescrBase(object): pass
+
+_typeindex = {}
+_descriptors = []
+_w_descriptors = []
+def descriptor(code, name, ll_type):
+    arraytype = lltype.Array(ll_type)
+    class DescrImpl(DescrBase):
+        def __init__(self):
+            self.typeid = 0
+            self.typecode = code
+
+        def wrap(self, space, value):
+            return space.wrap(value)
+
+        def w_getitem(self, space, data, index):
+            return space.wrap(self.getitem(data, index))
+
+        def w_setitem(self, space, data, index, w_value):
+            value = self.unwrap(space, w_value)
+            self.setitem(data, index, value)
+
+        def itemsize(self):
+            return rffi.sizeof(ll_type)
+
+        def getitem(self, data, index):
+            array = rffi.cast(lltype.Ptr(arraytype), data)
+            return array[index]
+
+        def setitem(self, data, index, value):
+            array = rffi.cast(lltype.Ptr(arraytype), data)
+            #array[index] = rffi.cast(ll_type, value)
+            array[index] = value # XXX: let's see if this works
+
+        def alloc(self, count):
+            return lltype.malloc(arraytype, count, flavor='raw')
+
+        def free(self, data):
+            lltype.free(data, flavor='raw')
+
+        def wrappable_dtype(self):
+            assert _w_descriptors[self.typeid].dtype is self, "This better be true."
+            return _w_descriptors[self.typeid]
+
+    for type in [lltype.Signed, lltype.Float]:
+        def get_type(self, data, index):
+            value = self.getitem(data, index)
+            return rffi.cast(type, value)
+        get_type.__name__ = 'get_%s' % type
+        setattr(DescrImpl, 'get_%s' % type, get_type)
+
+        def set_type(self, data, index, value):
+            value = rffi.cast(ll_type, value)
+            self.setitem(data, index, value)
+        set_type.__name__ = 'set_%s' % type
+        setattr(DescrImpl, 'set_%s' % type, set_type)
+
+    DescrImpl.__name__ = 'Descr_%s' % name # XXX
+                                
+    typeid = len(_descriptors)
+
+    _typeindex[code] = typeid
+    descriptor = DescrImpl()
+    descriptor.typeid = typeid
+
+    _descriptors.append(descriptor)
+
+    w_descriptor = TypeDescr(descriptor, name)
+    _w_descriptors.append(w_descriptor)
+
+    return descriptor
+
+_typestring = {}
+# int, int32 is l
+# i is ??
+
+int_descr = descriptor('i', 'int32', lltype.Signed)
+type(int_descr).unwrap = lambda self, space, value: space.int_w(value)
+_int_index = _typeindex['i']
+_typestring['int32'] = _int_index
+w_int_descr = _w_descriptors[_int_index]
+
+float_descr = descriptor('d', 'float64', lltype.Float)
+type(float_descr).unwrap = lambda self, space, value: space.float_w(value)
+_float_index = _typeindex['d']
+_typestring['float64'] = _float_index
+w_float_descr = _w_descriptors[_float_index]
+
+_result_types = {(_int_index, _int_index): _int_index,
+                 (_int_index, _float_index): _float_index,
+                 (_float_index, _int_index): _float_index,
+                 (_float_index, _float_index): _float_index,
+                }
+
+def from_typecode(s):
+    index = _typeindex[s]
+    return _descriptors[index]
+
+def from_typestring(s):
+    index = _typestring[s]
+    return _descriptors[index]
+
+def from_wrapped_type(space, w_type):
+    if w_type is space.w_int:
+        return int_descr
+    else:
+        return float_descr #XXX: only handles two types!
+
+def get(space, w_dtype):
+    try:
+        s = space.str_w(w_dtype)
 
         try:
-            return space.str_w(w_type)
-        except OperationError, e:
-            typecode_mapping = {
-                                space.w_int: 'i',
-                                space.w_float: 'd',
-                               }
+            return from_typecode(s)
+        except KeyError, e:
+            return from_typestring(s)
+
+    except KeyError, e:
+        raise OperationError(space.w_TypeError,
+                             space.wrap("data type not understood")
+                            )
+
+    except OperationError, e:
+        if e.match(space, space.w_TypeError): pass # XXX: ValueError?
+
+    try:
+        i = space.int_w(w_dtype)
+        return _descriptors[i]
+    except OperationError, e:
+        if e.match(space, space.w_TypeError): pass 
+        else: raise
+
+    return from_wrapped_type(space, w_dtype)
+
+# FIXME: watch for wrapped typedescrs!
+def infer_from_iterable(space, w_xs):
+    highest_type = None
+    dtype = None
+    w_i = space.iter(w_xs)
+    try:
+        while True:
+            w_element = space.next(w_i)      
             try:
-                return typecode_mapping[w_type]
-            except IndexError, e:
-                raise OperationError(space.w_TypeError,
-                        space.wrap("Can't understand type."))
-
-    def result_mapping(self, space, types):
-        types = (self.typecode(space, types[0]),
-                 self.typecode(space, types[1]))
-        return self.result_types[types]
-
-    def iterable_type(self, space, w_xs):
-        xs = space.fixedview(w_xs)
-        result_type = 'i'
-        for i in range(len(xs)):
-            try:
-                atype = self.iterable_type(space, xs[i])
+                dtype = infer_from_iterable(space, w_element)
             except OperationError, e:
-                if not e.match(space, space.w_TypeError):
-                    raise
-                atype = self.typecode(space, space.type(xs[i]))
-            result_type = self.result_types[(result_type, atype)]
-        return result_type
-
-    def verify_dtype_dict(self, space):
-        if not self.dtypes:
-            self.dtypes.update(
-                               {
-                                'i': DynamicType('i', 'int32', space.w_int),
-                                'd': DynamicType('d', 'float64', space.w_float),
-                               }
-                              )
-
-    def retrieve_dtype(self, space, t):
-        self.verify_dtype_dict(space)
-        return self.dtypes[t]
-
-    def get_dtype(self, space, w_type):
-        try:
-            t = space.str_w(w_type)
-        except OperationError, e:
-            if e.match(space, space.w_TypeError):
-                t = self.typecode(space, w_type)
+                if e.match(space, space.w_TypeError): # not iterable?
+                    w_type = space.type(w_element)
+                    dtype = from_wrapped_type(space, w_type)
+                else: raise
+
+            if highest_type is not None:
+                a = highest_type.typeid   
+                b = dtype.typeid
+                highest_typeid = _result_types[(a, b)]
+                highest_type = _descriptors[highest_typeid]
             else:
-                raise
-        return self.retrieve_dtype(space, t)
-
-    def sdarray(self, space, length, w_dtype):
-        from pypy.module.micronumpy.sdarray import sdresult
-        return sdresult(self.typecode(space, w_dtype))(space, length, w_dtype)
-
-    def mdarray(self, space, shape, w_dtype):
-        from pypy.module.micronumpy.mdarray import mdresult
-        return mdresult(self.typecode(space, w_dtype))(space, shape, w_dtype)
-
-dtypes = DynamicTypes()
-iterable_type = dtypes.iterable_type
-typecode = dtypes.typecode
-result_mapping = dtypes.result_mapping
-get_dtype = dtypes.get_dtype
-retrieve_dtype = dtypes.retrieve_dtype
-sdarray = dtypes.sdarray
-mdarray = dtypes.mdarray
+                highest_type = dtype
+    except OperationError, e:
+        if e.match(space, space.w_StopIteration):
+            return highest_type
+    else: raise

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	Wed Jul 14 10:46:16 2010
@@ -12,16 +12,6 @@
 from pypy.module.micronumpy.array import \
         mul_operation, div_operation, add_operation, sub_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 result_mapping, iterable_type
-
-from pypy.module.micronumpy.dtype import create_factory
-
-from pypy.module.micronumpy.dtype import get_dtype
-from pypy.module.micronumpy.dtype import retrieve_dtype #FIXME: ambiguously named?
-from pypy.module.micronumpy.dtype import DynamicType
-
 #TODO: merge unwrap_spec decorator
 # from pypy.interpreter.gateway import unwrap_spec
 
@@ -60,6 +50,15 @@
                         next = interp2app(SingleDimIterator.descr_next)
                         )
 
+    def operation_name(type, operand_type, opname):
+        return '_'.join([type, operand_type, opname])
+
+    def fixedview_operation(opname, self, source, x):
+        return getattr(self, operation_name('client', 'fixedview', opname))(source, x)
+
+    def client_operation(opname, self, source, x):
+        return getattr(self, operation_name('client', 'scalar', opname))(source, x)
+
     def create_client_math_operation(f):
         def scalar_operation(self, source, x, inverse):
             for i in range(len(source.storage)):
@@ -274,22 +273,22 @@
             maxlen = max([len(x) for x in strings])
             return strings, maxlen
 
-        def descr_str(self):
+        def descr_str(self, space):
             space = self.space
             #beautiful, as in numpy
             strings, maxlen = self.str()
             return space.wrap(
                     "[%s]" % ' '.join(["%-*s"%(maxlen, s) for s in strings]) 
                     )
-        descr_str.unwrap_spec = ['self']
+        descr_str.unwrap_spec = ['self', ObjSpace]
 
-        def descr_repr(self):
+        def descr_repr(self, space):
             space = self.space
             strings, maxlen = self.str()
             return space.wrap(
                     "array([%s])" % ', '.join(["%-*s"%(maxlen, s) for s in strings]) 
                     )
-        descr_repr.unwrap_spec = ['self']
+        descr_repr.unwrap_spec = ['self', ObjSpace]
 
     NumArray.typedef = TypeDef('ndarray', base_typedef,
                                __mul__ = interp2app(NumArray.descr_mul),
@@ -315,8 +314,3 @@
                               )
 
     return NumArray
-
-IntArray = create_sdarray(int, unwrap_int, coerce_int)
-FloatArray = create_sdarray(float, unwrap_float, coerce_float)
-
-sdresult = create_factory({'i': IntArray, 'd': FloatArray})

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	Wed Jul 14 10:46:16 2010
@@ -1,8 +1,11 @@
 
+import py
+
 from pypy.conftest import gettestobjspace
 
 class TestSDArray(object):
     def test_unwrap(self, space):
+        skip("Irrelevant interplevel test")
         w_int = space.wrap(1)
         w_float = space.wrap(1.0)
 
@@ -27,6 +30,7 @@
         #interp_raises((space.w_TypeError,), unwrap_float, space, w_int) #er, shouldn't this raise?
 
     def test_coerce(self, space):
+        skip("Irrelevant interplevel test")
         w_int = space.wrap(1)
         w_float = space.wrap(1.0)
 
@@ -54,14 +58,15 @@
 
     def test_type_array(self):
         compare = self.compare
-        from numpy import array
+        from micronumpy import array
         for data_type in (int, float):
             data = [data_type(x) for x in xrange(4)] 
             ar = array(data)
             assert compare(ar, data)
 
+    @py.test.mark.xfail
     def test_sdarray_operators(self):
-        from numpy import array
+        from micronumpy import array
         from operator import mul, div, add, sub
         compare = self.compare
         d = range(1, self.length)
@@ -76,9 +81,10 @@
                     assert compare(operator(value, ar2), [operator(value, x) for x in data])
                 assert compare(operator(ar, ar2), [operator(x, y) for (x, y) in zip(ar, ar2)])
 
+    @py.test.mark.xfail
     def test_operator_result_types(self):
         from operator import mul, div, add, sub
-        from numpy import array
+        from micronumpy import array
         types = {
                  (int, int): int,
                  (int, float): float,
@@ -116,7 +122,7 @@
                 test_type(f.dtype, result_type)
 
     def test_iter(self):
-        from numpy import array
+        from micronumpy import array
         for iterable_type in (list, tuple):
             for data_type in (int, float):
                 data = iterable_type([data_type(x) for x in xrange(self.length)])
@@ -126,19 +132,20 @@
 
     def test_iterable_construction(self):
         compare = self.compare
-        from numpy import array
+        from micronumpy import array
         ar = array(xrange(4))
 
         assert compare(ar, xrange(4))
 
     def test_zeroes(self):
-        from numpy import zeros
+        from micronumpy import zeros
         for data_type in (int, float):
             ar = zeros(3, dtype=int)
             assert ar[0] == data_type(0.0)
     
+    @py.test.mark.xfail
     def test_setitem_getitem(self):
-        from numpy import zeros
+        from micronumpy import zeros
         compare = self.compare
 
         ar = zeros(8, dtype=int)
@@ -166,8 +173,9 @@
         raises(ValueError, ar.__setitem__, 0, 'f')
         raises(ValueError, ar.__setitem__, slice(2, 3), [4, 5, 6])
 
+    @py.test.mark.xfail
     def test_minimum(self):
-        from numpy import zeros, minimum
+        from micronumpy import zeros, minimum
         ar = zeros(5, dtype=int)
         ar2 = zeros(5, dtype=int)
         ar[0] = 3
@@ -184,9 +192,9 @@
         assert len(x) == 5
         raises(ValueError, minimum, ar, zeros(3, dtype=int))
 
+    @py.test.mark.xfail
     def test_str(self):
-        skip("Perfect string formatting is going to be tough.")
-        from numpy import zeros, array
+        from micronumpy import zeros, array
 
         z = zeros(shape=(3,))
         assert str(z) == '[ 0.  0.  0.]'
@@ -228,14 +236,15 @@
            return compare""")
 
     def test_multidim(self):
-        from numpy import zeros
+        from micronumpy import zeros
         ar = zeros((3, 3), dtype=int)
         assert ar[0, 2] == 0
         raises(IndexError, ar.__getitem__, (3, 0))
         assert ar[-2, 1] == 0
 
+    @py.test.mark.xfail
     def test_construction(self):
-        from numpy import array
+        from micronumpy import array
         gen_array = self.gen_array
 
         #3x3
@@ -248,7 +257,7 @@
         assert ar.shape == (2, 3)
 
         #3x2
-        ar = array(gen_array((3,2)))
+        ar = array(gen_array((3,2))) # XXX: here's the problem
         assert len(ar) == 3
         assert ar.shape == (3, 2)
 
@@ -256,7 +265,7 @@
         raises(ValueError, array, [2, [3, 4]])
 
     def test_getset(self):
-        from numpy import zeros
+        from micronumpy import zeros
         ar = zeros((3, 3, 3), dtype=int)
         ar[1, 2, 1] = 3
         assert ar[1, 2, 1] == 3
@@ -265,11 +274,11 @@
         assert ar[-2, 2, -2] == 3
 
     def test_len(self):
-        from numpy import zeros
+        from micronumpy import zeros
         assert len(zeros((3, 2, 1), dtype=int)) == 3
 
     def test_shape_detect(self):
-        from numpy import array
+        from micronumpy import array
         ar = array([range(i*3, i*3+3) for i in range(3)])
         assert len(ar) == 3
         assert ar.shape == (3, 3)
@@ -277,8 +286,9 @@
             for j in range(3):
                 assert ar[i, j] == i*3+j
     
+    @py.test.mark.xfail
     def test_get_set_slices(self):
-        from numpy import array
+        from micronumpy import array
         gen_array = self.gen_array
         compare = self.compare
 
@@ -327,18 +337,20 @@
         ar3[1:3] = [[0, 1, 2], [3, 4, 5]]
         assert compare(ar3[1, 2], [2, 2, 2])
 
+    @py.test.mark.xfail
     def test_newaxis(self):
-        from numpy import array
+        from micronumpy import array
         gen_array = self.gen_array
         compare = self.compare
 
         ar = array(gen_array((3, 3)))
 
         assert compare(ar[[1, 2], 0], ar[1:3, 0])
-        assert compare(ar[ [[1, 2], [0, 1]] ] [1, 0], ar[0])
+        assert compare(ar[ [[1, 2], [0, 1]] ] [1, 0], ar[0]) # zip iterables into coordinates
 
+    @py.test.mark.xfail
     def test_mdarray_operators(self):
-        from numpy import array
+        from micronumpy import array
         import operator
         compare = self.compare
 
@@ -377,9 +389,10 @@
 class AppTestDType(object):
     def setup_class(cls):
         cls.space = gettestobjspace(usemodules=('micronumpy',))
-    #FIXME: need DynamicType.__new__/__init__ to best test this
+
+    @py.test.mark.xfail
     def test_eq(self):
-        from numpy import zeros
+        from micronumpy import zeros
 
         a = zeros((4,), dtype=int)
         assert a.dtype == int
@@ -397,6 +410,7 @@
 
 class TestDType(object):
     def test_lookups(self, space):
+        skip("Depends on interplevel stuff that doesn't exist really anymore.")
         from pypy.module.micronumpy.dtype import retrieve_dtype
         from pypy.module.micronumpy.dtype import get_dtype
         a = get_dtype(space, space.wrap('i'))
@@ -406,6 +420,7 @@
         assert b == retrieve_dtype(space, 'd')
 
     def test_result_types(self, space):
+        skip("Depends on interplevel stuff that doesn't exist really anymore.")
         from pypy.module.micronumpy.dtype import get_dtype
         from pypy.module.micronumpy.dtype import result_mapping
         w_typecode_a = space.wrap('i')
@@ -419,9 +434,7 @@
         assert 'd' == result_mapping(space, (w_typecode_b, w_typecode_b))
 
     def test_iterable_type(self, space):
-        from pypy.module.micronumpy.dtype import iterable_type
-        w_int = space.wrap(1)
-        w_float = space.wrap(2.0)
+        from pypy.module.micronumpy.dtype import infer_from_iterable
 
         data = [(space.wrap([1, 2, 3, 4, 5]), 'i'),
                 (space.wrap([1, 2, 3.0, 4, 5]), 'd'),
@@ -431,4 +444,44 @@
                 (space.wrap([1.0, 2, 3, 4, 5.0]), 'd')]
 
         for w_xs, typecode in data:
-            assert typecode == iterable_type(space, w_xs)
+            assert typecode == infer_from_iterable(space, w_xs).typecode
+
+class TestMicroArray(object):
+    def test_strides(self, space):
+        from pypy.module.micronumpy.microarray import stride_row, stride_column
+
+        shape = (2, 3)
+        assert stride_row(shape, 0) == 3
+        assert stride_row(shape, 1) == 1
+
+        assert stride_column(shape, 0) == 1
+        assert stride_column(shape, 1) == 2
+
+        # TODO: more, N-dimensional too
+
+    def test_memory_layout(self, space):
+        from pypy.module.micronumpy.microarray import MicroArray
+        from pypy.module.micronumpy.microarray import array
+        from pypy.module.micronumpy.dtype import w_int_descr
+
+        data = [[1, 2, 3],
+                [4, 5, 6]]
+
+        w_data = space.wrap(data)
+        column_major = [1, 4, 2, 5, 3, 6]
+        row_major = [1, 2, 3, 4, 5, 6]
+
+        assert len(column_major) == len(row_major)
+        memlen = len(column_major)
+
+        ar = array(space, w_data, w_dtype=w_int_descr, order='C') #C for C not column
+        
+        for i in range(memlen):
+            array_element = space.unwrap(ar.getitem(space, i)) # ugly, but encapsulates everything
+            assert array_element == row_major[i]
+
+        ar = array(space, w_data, w_dtype=w_int_descr, order='F')
+        for i in range(memlen):
+            array_element = space.unwrap(ar.getitem(space, i)) # ugly, but encapsulates everything
+            assert array_element == column_major[i]
+

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	Wed Jul 14 10:46:16 2010
@@ -1,32 +1,34 @@
 from pypy.module.micronumpy.array import array, zeros, ndarray
 from pypy.module.micronumpy.array import construct_array
-from pypy.module.micronumpy.dtype import result_mapping
-from pypy.module.micronumpy.sdarray import sdresult
-from pypy.module.micronumpy.mdarray import mdresult, compute_pos
-
-from pypy.module.micronumpy.dtype import retrieve_dtype
 
 from pypy.interpreter.baseobjspace import ObjSpace, W_Root
 from pypy.interpreter.error import OperationError
 from pypy.rlib.debug import make_sure_not_resized
 
+from pypy.module.micronumpy.microarray import MicroArray, size_from_shape
+
 def minimum(space, w_a, w_b):
-    if not isinstance(w_a, ndarray) or not isinstance(w_b, ndarray):
+    if not isinstance(w_a, MicroArray) or not isinstance(w_b, MicroArray):
         raise OperationError(space.w_TypeError,
                              space.wrap("expecting ndarray object"))
-    if w_a.len()!= w_b.len():
+    if w_a.shape != w_b.shape:
         raise OperationError(space.w_ValueError,
                              space.wrap("minimum of arrays of different length"))
-    dtype = result_mapping(space, (w_a.dtype, w_b.dtype))
-    res = construct_array(space, w_a.shape, retrieve_dtype(space, dtype))
-    for i in range(len(w_a.storage)):
-        one = w_a.storage[i]
-        two = w_b.storage[i]
+
+    result_type = w_a.dtype.result(w_b.dtype)
+
+    result = MicroArray(w_a.shape, result_type)
+
+    size = size_from_shape(w_a.shape)
+
+    for i in range(size): # FIXME: specialized paths for Signed and Float ? wraps right now...
+        one = w_a.getitem(space, i)
+        two = w_b.getitem(space, i)
         if one < two:
-            res.storage[i] = one
+            result.setitem(space, i, one)
         else:
-            res.storage[i] = two
-    return space.wrap(res)
+            result.setitem(space, i, two)
+    return space.wrap(result)
 minimum.unwrap_spec = [ObjSpace, W_Root, W_Root]
 
 def dot(space, w_a, w_b):



More information about the Pypy-commit mailing list