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

dan at codespeak.net dan at codespeak.net
Tue Mar 2 06:52:53 CET 2010


Author: dan
Date: Tue Mar  2 06:52:52 2010
New Revision: 71611

Modified:
   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/ndarray.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:
Added DynamicType object implementing (somewhat) the functionality of NumPy's dtype objects, did a bit of housekeeping.

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	Tue Mar  2 06:52:52 2010
@@ -6,6 +6,9 @@
 
 from pypy.module.micronumpy.dtype import iterable_type
 
+from pypy.module.micronumpy.dtype import get_dtype
+from pypy.module.micronumpy.dtype import retrieve_dtype #FIXME: ambiguous name?
+
 class BaseNumArray(Wrappable):
     pass
 
@@ -22,7 +25,6 @@
         if e.match(space, space.w_TypeError): pass
         else: raise
 
-
 def mul_operation():
     def mul(x, y): return x * y
     return mul
@@ -91,9 +93,9 @@
     try:
         if len(shape) == 1:
             length = shape[0]
-            return sdresult(space, w_dtype)(space, length, w_dtype)
+            return sdresult(w_dtype.code)(space, length, w_dtype)
         else:
-            return mdresult(space, w_dtype)(space, shape, w_dtype)
+            return mdresult(w_dtype.code)(space, shape, w_dtype)
     except KeyError, e:
         raise OperationError(space.w_NotImplementedError,
                 space.wrap("Haven't implemented generic array yet!"))
@@ -102,7 +104,8 @@
               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)
+    dtype_w = get_dtype(space, w_dtype)
+    result = construct_array(space, shape_w, dtype_w)
     #TODO: load from buffer?
     return space.wrap(result)
 descr_new.unwrap_spec = [ObjSpace, W_Root, W_Root, W_Root,
@@ -121,8 +124,10 @@
     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)
+        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,
@@ -131,6 +136,10 @@
 
 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)
+    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]

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	Tue Mar  2 06:52:52 2010
@@ -1,4 +1,8 @@
-from pypy.interpreter.error import OperationError
+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 interp2app
+
 def unwrap_int(space, w_x):
     return space.int_w(w_x)
 def coerce_int(space, w_x):
@@ -15,34 +19,108 @@
 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 typecode(space, w_type):
+    try:
+        assert isinstance(w_type, DynamicType)
+        return w_type.code
+    except AssertionError, e: pass
+
+    try:
+        return space.str_w(w_type)
+    except OperationError, e:
+        typecode_mapping = {
+                            space.w_int: 'i',
+                            space.w_float: 'd',
+                           }
+        try:
+            return typecode_mapping[w_type]
+        except IndexError, e:
+            raise OperationError(space.w_TypeError,
+                    space.wrap("Can't understand type."))
+
+result_types = {
+                ('i', 'i'): 'i',
+                ('i', 'd'): 'd',
+                ('d', 'i'): 'd',
+                ('d', 'd'): 'd',
+               }
+
+def result_mapping(space, types):
+    types = (typecode(space, types[0]),
+             typecode(space, types[1]))
+    return result_types[types]
 
 def iterable_type(space, w_xs):
     xs = space.fixedview(w_xs)
-    result_type = space.w_int
+    result_type = 'i'
     for i in range(len(xs)):
         try:
-            space.iter(xs[i])
+            atype = iterable_type(space, xs[i])
         except OperationError, e:
             if not e.match(space, space.w_TypeError):
                 raise
-            atype = space.type(xs[i])
-        else:
-            atype = iterable_type(space, xs[i])
-        result_type = result_mapping(space, (result_type, atype))
+            atype = typecode(space, space.type(xs[i]))
+        result_type = result_types[(result_type, atype)]
     return result_type
 
-def create_factory(dict_filler):
-    result_factory = {}
-    def result(space, t):
-        if not result_factory:
-            result_factory.update(dict_filler(space))
+def create_factory(result_factory):
+    def factory(t):
         return result_factory[t]
-    return result
+    return factory
+
+class DynamicType(Wrappable):
+    def __init__(self, code, name, applevel_type):
+        self.code = code
+        self.name = name
+        self.applevel_type = applevel_type
+
+    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.wrap(True)
+                elif self.name == code:
+                    return space.wrap(True)
+                else:
+                    return space.wrap(False)
+            except OperationError, e:
+                return space.wrap(False)
+            except TypeError, e:
+                return space.wrap(False) #FIXME: need to throw applevel type error
+    descr_eq.unwrap_spec = ['self', ObjSpace, W_Root]
+DynamicType.typedef = TypeDef('dtype',
+                              __eq__ = interp2app(DynamicType.descr_eq),
+                             )
+
+class DynamicTypes(object):
+    def __init__(self):
+        self.dtypes = {}
+    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 = typecode(space, w_type)
+            else:
+                raise
+        return self.retrieve_dtype(space, t)
+
+dtypes = DynamicTypes()
+get_dtype = dtypes.get_dtype
+retrieve_dtype = dtypes.retrieve_dtype

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	Tue Mar  2 06:52:52 2010
@@ -365,4 +365,4 @@
 MultiDimIntArray = create_mdarray(int, unwrap_int, coerce_int)
 MultiDimFloatArray = create_mdarray(float, unwrap_float, coerce_float)
 
-mdresult = create_factory(lambda space: {space.w_int: MultiDimIntArray, space.w_float: MultiDimFloatArray})
+mdresult = create_factory({'i': MultiDimIntArray, 'd': MultiDimFloatArray})

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	Tue Mar  2 06:52:52 2010
@@ -10,15 +10,6 @@
 
 from pypy.module.micronumpy.mdarray import mdresult
 
-def result_type(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 unpack_shape(space, w_shape):
     if space.is_true(space.isinstance(w_shape, space.w_int)):
         return [space.int_w(w_shape)]

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	Tue Mar  2 06:52:52 2010
@@ -1,5 +1,4 @@
 from pypy.interpreter.baseobjspace import W_Root, Wrappable
-from pypy.objspace.std.sliceobject import W_SliceObject
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.typedef import TypeDef, GetSetProperty
 from pypy.interpreter.gateway import interp2app
@@ -9,7 +8,6 @@
 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
@@ -19,63 +17,22 @@
 
 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
 
-
 class BaseSingleDimArray(BaseNumArray): pass
 
 def descr_dtype(space, self):
-    return self.dtype
+    return space.wrap(self.dtype)
 
 def descr_shape(space, self):
     return space.newtuple([space.wrap(self.len())])
 
-
-
-MUL = mul_operation()
-DIV = div_operation()
-ADD = add_operation()
-SUB = sub_operation()
-COPY = copy_operation()
-
 def create_sdarray(data_type, unwrap, coerce):
-
-    def create_math_operation(f):
-        opname = f.__name__
-        def math_operation(self, w_x):
-            space = self.space
-            try:
-                space.iter(w_x)
-            except OperationError, e:
-                if not e.match(space, space.w_TypeError):
-                    raise
-                result_t = result_mapping(space,
-                                            (space.type(w_x), self.dtype))
-                op2 = coerce(space, w_x)
-                result = sdresult(space, result_t)(space, self.len(), result_t)
-                operation = result.__class__.client_scalar[opname]
-            else:
-                lop = space.int_w(space.len(w_x))
-                if lop != self.len():
-                    raise OperationError(space.w_ValueError,
-                            space.wrap("shape mismatch: objects cannot be"
-                                         " broadcast to the same shape"))
-                dtype = iterable_type(space, w_x)
-                result_t = result_mapping(space, (dtype, self.dtype))
-                op2 = sdresult(space, dtype)(space, lop, dtype)
-                op2.load_iterable(w_x)
-                result = sdresult(space, result_t)(space, self.len(), result_t)
-                operation = result.__class__.client_fixedview[opname]
-
-            operation(result, self, op2)
-
-            w_result = space.wrap(result)
-            return w_result
-        math_operation.unwrap_spec = ['self', W_Root]
-        math_operation.__name__ = 'descr_'+opname
-        return math_operation
-
     class SingleDimIterator(Wrappable):
         def __init__(self, space, array, i):
             self.space = space
@@ -105,39 +62,78 @@
     def create_client_math_operation(f):
         def scalar_operation(self, source, x):
             for i in range(len(source.storage)):
-                self.storage[i] = data_type(f(source.storage[i], x))
+                self.storage[i] = f(source.storage[i], x)
 
-        def fixedview_operation(self, source1, source2):
+        def fixedview_operation(self, a, b):
             for i in range(self.len()):
-                self.storage[i] = \
-                    data_type(f(source1.storage[i], source2.storage[i]))
+                self.storage[i] = f(a.storage[i], b.storage[i])
         return scalar_operation, fixedview_operation
 
+    def create_math_operation(f):
+        opname = f.__name__
+        def math_operation(self, w_x):
+            space = self.space
+            try:
+                space.iter(w_x)
+            except OperationError, e:
+                if not e.match(space, space.w_TypeError):
+                    raise
+                result_t = result_mapping(space,
+                                          (space.type(w_x), self.dtype))
+                x = coerce(space, w_x)
+                result = sdresult(result_t)(space,
+                                            self.len(), retrieve_dtype(space, result_t)
+                                           )
+                client_scalar[opname](result, self, x)
+            else:
+                operand_length = space.int_w(space.len(w_x))
+                if operand_length != self.len():
+                    raise OperationError(space.w_ValueError,
+                            space.wrap("shape mismatch: objects cannot be"
+                                       " broadcast to the same shape"))
+                dtype_w = retrieve_dtype(space, iterable_type(space, w_x))
+                result_t = result_mapping(space, (dtype_w, self.dtype))
+                xs = sdresult(dtype_w.code)(space, operand_length, dtype_w)
+                xs.load_iterable(w_x)
+                result = sdresult(result_t)(
+                                            space, self.len(), retrieve_dtype(space, result_t)
+                                           )
+                client_fixedview[opname](result, self, xs)
+
+            return space.wrap(result)
+        math_operation.unwrap_spec = ['self', W_Root]
+        math_operation.__name__ = "%s_descr_%s" % (str(data_type), opname)
+        return math_operation
+
+    client_scalar = {}
+    client_fixedview = {}
+
+    mul = mul_operation()
+    client_scalar['mul'], client_fixedview['mul'] = \
+                                        create_client_math_operation(mul)
+    div = div_operation()
+    client_scalar['div'], client_fixedview['div'] = \
+                                        create_client_math_operation(div)
+    add = add_operation()
+    client_scalar['add'], client_fixedview['add'] = \
+                                        create_client_math_operation(add)
+    sub = sub_operation()
+    client_scalar['sub'], client_fixedview['sub'] = \
+                                        create_client_math_operation(sub)
+
     class NumArray(BaseSingleDimArray):
         def __init__(self, space, length, dtype):
             self.shape = (length,)
             self.space = space
-            self.storage = make_sure_not_resized([data_type(0.0)] * length)
+            self.storage = [data_type(0.0)] * length
+            assert isinstance(dtype, DynamicType)
             self.dtype = dtype
+            make_sure_not_resized(self.storage)
 
-        
-        client_scalar = {}
-        client_fixedview = {}
-
-        client_scalar['mul'], client_fixedview['mul'] = \
-                                            create_client_math_operation(MUL)
-        client_scalar['div'], client_fixedview['div'] = \
-                                            create_client_math_operation(DIV)
-        client_scalar['add'], client_fixedview['add'] = \
-                                            create_client_math_operation(ADD)
-        client_scalar['sub'], client_fixedview['sub'] = \
-                                            create_client_math_operation(SUB)
-
-
-        descr_mul = create_math_operation(MUL)
-        descr_div = create_math_operation(DIV)
-        descr_add = create_math_operation(ADD)
-        descr_sub = create_math_operation(SUB)
+        descr_mul = create_math_operation(mul)
+        descr_div = create_math_operation(div)
+        descr_add = create_math_operation(add)
+        descr_sub = create_math_operation(sub)
 
         def load_iterable(self, w_values):
             space = self.space
@@ -161,9 +157,9 @@
 
         def descr_getitem(self, w_index):
             space = self.space
-            if isinstance(w_index, W_SliceObject):
+            if space.is_true(space.isinstance(w_index, space.w_slice)):
                 start, stop, step, slen = w_index.indices4(space, self.len())
-                res = sdresult(space, self.dtype)(space, slen, self.dtype)
+                res = sdresult(self.dtype.code)(space, slen, self.dtype)
                 if step == 1:
                     res.storage[:] = self.storage[start:stop]
                 else:
@@ -186,7 +182,7 @@
 
         def descr_setitem(self, w_index, w_value):
             space = self.space
-            if isinstance(w_index, W_SliceObject):
+            if space.is_true(space.isinstance(w_index, space.w_slice)):
                 start, stop, step, slen = w_index.indices4(space, self.len())
                 try:
                     space.iter(w_value)
@@ -260,12 +256,15 @@
                                __div__ = interp2app(NumArray.descr_div),
                                __add__ = interp2app(NumArray.descr_add),
                                __sub__ = interp2app(NumArray.descr_sub),
+
                                __rmul__ = interp2app(NumArray.descr_mul),
                                __rdiv__ = interp2app(NumArray.descr_div),
                                __radd__ = interp2app(NumArray.descr_add),
                                __rsub__ = 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),
@@ -282,4 +281,4 @@
 Float32Array = create_sdarray(float32, unwrap_float32, coerce_float32)
 GenericArray = None
 
-sdresult = create_factory(lambda space: {space.w_int: IntArray, space.w_float: FloatArray})
+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	Tue Mar  2 06:52:52 2010
@@ -49,6 +49,17 @@
                  (float, float): float
                 }
 
+        typecodes = {int: 'i',
+                     float: 'd'}
+
+        typestrings = {int: 'int32',
+                       float: 'float64'}
+
+        def test_type(dtype, expected_type):
+            assert dtype == expected_type
+            assert dtype == typecodes[expected_type]
+            assert dtype == typestrings[expected_type]
+
         for operand_types, result_type in types.iteritems():
             for operator in (mul, div, add, sub):
                 a_type, b_type = operand_types
@@ -56,16 +67,16 @@
                 b = array(xrange(1, self.length + 1), dtype=b_type)
 
                 c = operator(a, b)
-                assert c.dtype == result_type
+                test_type(c.dtype, result_type)
 
                 d = operator(b, a)
-                assert d.dtype == result_type
+                test_type(d.dtype, result_type)
 
                 e = operator(a, b_type(self.value))
-                assert e.dtype == result_type
+                test_type(e.dtype, result_type)
 
                 f = operator(a_type(self.value), b)
-                assert f.dtype == result_type
+                test_type(f.dtype, result_type)
 
     def test_iter(self):
         from numpy import array

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	Tue Mar  2 06:52:52 2010
@@ -3,6 +3,9 @@
 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
@@ -15,7 +18,7 @@
         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, 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]
@@ -74,7 +77,7 @@
 
     dtype = result_mapping(space, (w_a.dtype, w_b.dtype))
 
-    res = construct_array(space, shape, dtype)
+    res = construct_array(space, shape, retrieve_dtype(space, dtype))
     res.storage[:] = data
     return space.wrap(res)
 dot.unwrap_spec = [ObjSpace, W_Root, W_Root]



More information about the Pypy-commit mailing list