[pypy-commit] pypy numpy-dtype-alt: another shot at refactoring the world.

alex_gaynor noreply at buildbot.pypy.org
Mon Aug 15 17:47:48 CEST 2011


Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: numpy-dtype-alt
Changeset: r46523:f77427ecdc05
Date: 2011-08-15 10:51 -0500
http://bitbucket.org/pypy/pypy/changeset/f77427ecdc05/

Log:	another shot at refactoring the world.

diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py
--- a/pypy/module/micronumpy/interp_dtype.py
+++ b/pypy/module/micronumpy/interp_dtype.py
@@ -12,11 +12,10 @@
 
 
 SIGNEDLTR = "i"
+BOOLLTR = "b"
+FLOATINGLTR = "f"
 
 class W_Dtype(Wrappable):
-    aliases = []
-    applevel_types = []
-
     def __init__(self, space):
         pass
 
@@ -40,160 +39,17 @@
     def descr_str(self, space):
         return space.wrap(self.name)
 
-class LowLevelDtype(object):
-    _mixin_ = True
-
-    def erase(self, storage):
-        return rffi.cast(VOID_TP, storage)
-
-    def unerase(self, storage):
-        return rffi.cast(self.TP, storage)
-
-    def unwrap(self, space, w_item):
-        raise NotImplementedError
-
-    def malloc(self, size):
-        # XXX find out why test_zjit explodes with tracking of allocations
-        return self.erase(lltype.malloc(self.TP.TO, size,
-            zero=True, flavor="raw",
-            track_allocation=False, add_memory_pressure=True
-        ))
-
-    def getitem(self, storage, i):
-        return self.Box(self.unerase(storage)[i])
-
-    def setitem(self, storage, i, item):
-        assert isinstance(item, self.Box)
-        self.unerase(storage)[i] = item.val
-
-    def setitem_w(self, space, storage, i, w_item):
-        self.setitem(storage, i, self.unwrap(space, w_item))
-
-    @specialize.argtype(1)
-    def adapt_val(self, val):
-        return self.Box(rffi.cast(self.TP.TO.OF, val))
-
-    def str_format(self, item):
-        assert isinstance(item, self.Box)
-        return str(item.val)
-
-    # Operations.
-    def binop(func):
-        @functools.wraps(func)
-        def impl(self, v1, v2):
-            assert isinstance(v1, self.Box)
-            assert isinstance(v2, self.Box)
-            return self.Box(func(self, v1.val, v2.val))
-        return impl
-    def unaryop(func):
-        @functools.wraps(func)
-        def impl(self, v):
-            assert isinstance(v, self.Box)
-            return self.Box(func(self, v.val))
-        return impl
-
-    @binop
-    def add(self, v1, v2):
-        return v1 + v2
-    @binop
-    def sub(self, v1, v2):
-        return v1 - v2
-    @binop
-    def mul(self, v1, v2):
-        return v1 * v2
-    @binop
-    def div(self, v1, v2):
-        return v1 / v2
-    @binop
-    def mod(self, v1, v2):
-        return math.fmod(v1, v2)
-    @binop
-    def pow(self, v1, v2):
-        return math.pow(v1, v2)
-    @binop
-    def max(self, v1, v2):
-        return max(v1, v2)
-    @binop
-    def min(self, v1, v2):
-        return min(v1, v2)
-    @binop
-    def copysign(self, v1, v2):
-        return math.copysign(v1, v2)
-    @unaryop
-    def neg(self, v):
-        return -v
-    @unaryop
-    def pos(self, v):
-        return v
-    @unaryop
-    def abs(self, v):
-        return abs(v)
-    @unaryop
-    def sign(self, v):
-        if v == 0.0:
-            return 0.0
-        return rfloat.copysign(1.0, v)
-    @unaryop
-    def fabs(self, v):
-        return math.fabs(v)
-    @unaryop
-    def reciprocal(self, v):
-        if v == 0.0:
-            return rfloat.copysign(rfloat.INFINITY, v)
-        return 1.0 / v
-    @unaryop
-    def floor(self, v):
-        return math.floor(v)
-    @unaryop
-    def exp(self, v):
-        try:
-            return math.exp(v)
-        except OverflowError:
-            return rfloat.INFINITY
-    @unaryop
-    def sin(self, v):
-        return math.sin(v)
-    @unaryop
-    def cos(self, v):
-        return math.cos(v)
-    @unaryop
-    def tan(self, v):
-        return math.tan(v)
-    @unaryop
-    def arcsin(self, v):
-        if v < -1.0 or  v > 1.0:
-            return rfloat.NAN
-        return math.asin(v)
-    @unaryop
-    def arccos(self, v):
-        if v < -1.0 or v > 1.0:
-            return rfloat.NAN
-        return math.acos(v)
-    @unaryop
-    def arctan(self, v):
-        return math.atan(v)
-
-    # Comparisons, they return unwraped results (for now)
-    def ne(self, v1, v2):
-        assert isinstance(v1, self.Box)
-        assert isinstance(v2, self.Box)
-        return v1.val != v2.val
-    def bool(self, v):
-        assert isinstance(v, self.Box)
-        return bool(v.val)
-
-
-def make_array_ptr(T):
-    return lltype.Ptr(lltype.Array(T, hints={"nolength": True}))
 
 class BaseBox(object):
     pass
 
-def make_box(TP, valtype=None):
+VOID_TP = lltype.Ptr(lltype.Array(lltype.Void, hints={'nolength': True}))
+
+def create_low_level_dtype(num, kind, name, aliases, applevel_types, T, valtype=None):
     class Box(BaseBox):
         def __init__(self, val):
             if valtype is not None:
-                assert isinstance(val, valtype  )
+                assert isinstance(val, valtype)
             self.val = val
 
         def wrap(self, space):
@@ -201,62 +57,208 @@
 
         def convert_to(self, dtype):
             return dtype.adapt_val(self.val)
+    Box.__name__ = "%sBox" % T._name
 
-    Box.__name__ = "%sBox" % TP.TO.OF._name
-    return Box
+    TP = lltype.Ptr(lltype.Array(T, hints={'nolength': True}))
+    class W_LowLevelDtype(W_Dtype):
+        def erase(self, storage):
+            return rffi.cast(VOID_TP, storage)
 
-VOID_TP = make_array_ptr(lltype.Void)
+        def unerase(self, storage):
+            return rffi.cast(TP, storage)
 
-class W_BoolDtype(LowLevelDtype, W_Dtype):
-    num = 0
-    name = "bool"
-    aliases = ["?"]
-    applevel_types = ["bool"]
-    TP = make_array_ptr(lltype.Bool)
-    Box = make_box(TP, bool)
+        def box(self, value):
+            return Box(value)
 
+        def unwrap(self, space, w_item):
+            raise NotImplementedError
+
+        def malloc(self, size):
+            # XXX find out why test_zjit explodes with tracking of allocations
+            return self.erase(lltype.malloc(TP.TO, size,
+                zero=True, flavor="raw",
+                track_allocation=False, add_memory_pressure=True
+            ))
+
+        def getitem(self, storage, i):
+            return Box(self.unerase(storage)[i])
+
+        def setitem(self, storage, i, item):
+            assert isinstance(item, Box)
+            self.unerase(storage)[i] = item.val
+
+        def setitem_w(self, space, storage, i, w_item):
+            self.setitem(storage, i, self.unwrap(space, w_item))
+
+        @specialize.argtype(1)
+        def adapt_val(self, val):
+            return Box(rffi.cast(TP.TO.OF, val))
+
+        def str_format(self, item):
+            assert isinstance(item, Box)
+            return str(item.val)
+
+        # Operations.
+        def binop(func):
+            @functools.wraps(func)
+            def impl(self, v1, v2):
+                assert isinstance(v1, Box)
+                assert isinstance(v2, Box)
+                return Box(func(self, v1.val, v2.val))
+            return impl
+        def unaryop(func):
+            @functools.wraps(func)
+            def impl(self, v):
+                assert isinstance(v, Box)
+                return Box(func(self, v.val))
+            return impl
+
+        @binop
+        def add(self, v1, v2):
+            return v1 + v2
+        @binop
+        def sub(self, v1, v2):
+            return v1 - v2
+        @binop
+        def mul(self, v1, v2):
+            return v1 * v2
+        @binop
+        def div(self, v1, v2):
+            return v1 / v2
+        @binop
+        def mod(self, v1, v2):
+            return math.fmod(v1, v2)
+        @binop
+        def pow(self, v1, v2):
+            return math.pow(v1, v2)
+        @binop
+        def max(self, v1, v2):
+            return max(v1, v2)
+        @binop
+        def min(self, v1, v2):
+            return min(v1, v2)
+        @binop
+        def copysign(self, v1, v2):
+            return math.copysign(v1, v2)
+        @unaryop
+        def neg(self, v):
+            return -v
+        @unaryop
+        def pos(self, v):
+            return v
+        @unaryop
+        def abs(self, v):
+            return abs(v)
+        @unaryop
+        def sign(self, v):
+            if v == 0.0:
+                return 0.0
+            return rfloat.copysign(1.0, v)
+        @unaryop
+        def fabs(self, v):
+            return math.fabs(v)
+        @unaryop
+        def reciprocal(self, v):
+            if v == 0.0:
+                return rfloat.copysign(rfloat.INFINITY, v)
+            return 1.0 / v
+        @unaryop
+        def floor(self, v):
+            return math.floor(v)
+        @unaryop
+        def exp(self, v):
+            try:
+                return math.exp(v)
+            except OverflowError:
+                return rfloat.INFINITY
+        @unaryop
+        def sin(self, v):
+            return math.sin(v)
+        @unaryop
+        def cos(self, v):
+            return math.cos(v)
+        @unaryop
+        def tan(self, v):
+            return math.tan(v)
+        @unaryop
+        def arcsin(self, v):
+            if v < -1.0 or  v > 1.0:
+                return rfloat.NAN
+            return math.asin(v)
+        @unaryop
+        def arccos(self, v):
+            if v < -1.0 or v > 1.0:
+                return rfloat.NAN
+            return math.acos(v)
+        @unaryop
+        def arctan(self, v):
+            return math.atan(v)
+
+        # Comparisons, they return unwraped results (for now)
+        def ne(self, v1, v2):
+            assert isinstance(v1, Box)
+            assert isinstance(v2, Box)
+            return v1.val != v2.val
+        def bool(self, v):
+            assert isinstance(v, Box)
+            return bool(v.val)
+
+    W_LowLevelDtype.__name__ = "W_%sDtype" % name.capitalize()
+    W_LowLevelDtype.num = num
+    W_LowLevelDtype.kind = kind
+    W_LowLevelDtype.name = name
+    W_LowLevelDtype.aliases = aliases
+    W_LowLevelDtype.applevel_types = applevel_types
+    return W_LowLevelDtype
+
+
+W_BoolDtype = create_low_level_dtype(
+    num = 0, kind = BOOLLTR, name = "bool",
+    aliases = ["?"],
+    applevel_types = ["bool"],
+    T = lltype.Bool,
+)
+class W_BoolDtype(W_BoolDtype):
     def unwrap(self, space, w_item):
-        return self.Box(space.is_true(w_item))
+        return self.box(space.is_true(w_item))
 
-class W_Int8Dtype(LowLevelDtype, W_Dtype):
-    num = 1
-    kind = SIGNEDLTR
-    aliases = ["int8"]
-    TP = make_array_ptr(rffi.SIGNEDCHAR)
-    Box = make_box(TP)
+W_Int8Dtype = create_low_level_dtype(
+    num = 1, kind = SIGNEDLTR, name = "int8",
+    aliases = ["int8"],
+    applevel_types = [],
+    T = rffi.SIGNEDCHAR,
+)
+W_Int32Dtype = create_low_level_dtype(
+    num = 5, kind = SIGNEDLTR, name = "int32",
+    aliases = ["i"],
+    applevel_types = [],
+    T = rffi.INT,
+)
+W_LongDtype = create_low_level_dtype(
+    num = 7, kind = SIGNEDLTR, name = "???",
+    aliases = ["l"],
+    applevel_types = ["int"],
+    T = rffi.LONG
+)
+class W_LongDtype(W_LongDtype):
+    def unwrap(self, space, w_item):
+        return self.box(space.int_w(space.int(w_item)))
 
-class W_Int32Dtype(LowLevelDtype, W_Dtype):
-    num = 5
-    kind = SIGNEDLTR
-    aliases = ["i"]
-    TP = make_array_ptr(rffi.INT)
-    Box = make_box(TP)
-
-class W_LongDtype(LowLevelDtype, W_Dtype):
-    num = 7
-    kind = SIGNEDLTR
-    aliases = ["l"]
-    applevel_types = ["int"]
-    TP = make_array_ptr(rffi.LONG)
-    Box = make_box(TP)
-
+W_Int64Dtype = create_low_level_dtype(
+    num = 9, kind = SIGNEDLTR, name = "int64",
+    aliases = [],
+    applevel_types = ["long"],
+    T = rffi.LONGLONG
+)
+W_Float64Dtype = create_low_level_dtype(
+    num = 12, kind = FLOATINGLTR, name = "float64",
+    aliases = [],
+    applevel_types = ["float"],
+    T = lltype.Float,
+)
+class W_Float64Dtype(W_Float64Dtype):
     def unwrap(self, space, w_item):
-        return self.Box(space.int_w(space.int(w_item)))
-
-class W_Int64Dtype(LowLevelDtype, W_Dtype):
-    num = 9
-    applevel_types = ["long"]
-    TP = make_array_ptr(rffi.LONGLONG)
-    Box = make_box(TP)
-
-class W_Float64Dtype(LowLevelDtype, W_Dtype):
-    num = 12
-    applevel_types = ["float"]
-    TP = make_array_ptr(lltype.Float)
-    Box = make_box(TP)
-
-    def unwrap(self, space, w_item):
-        return self.Box(space.float_w(space.float(w_item)))
+        return self.box(space.float_w(space.float(w_item)))
 
     def str_format(self, item):
         return float2string(item.val, 'g', rfloat.DTSF_STR_PRECISION)
diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py
--- a/pypy/module/micronumpy/interp_numarray.py
+++ b/pypy/module/micronumpy/interp_numarray.py
@@ -96,7 +96,7 @@
             return result
 
         def impl(self, space):
-            result = space.fromcache(interp_dtype.W_Float64Dtype).Box(init).convert_to(self.find_dtype())
+            result = space.fromcache(interp_dtype.W_Float64Dtype).box(init).convert_to(self.find_dtype())
             return loop(self, self.find_dtype(), result, self.find_size()).wrap(space)
         return func_with_new_name(impl, "reduce_%s_impl" % op_name)
 
@@ -574,7 +574,7 @@
 def ones(space, size):
     dtype = space.fromcache(interp_dtype.W_Float64Dtype)
     arr = SingleDimArray(size, dtype=dtype)
-    one = dtype.Box(1.0)
+    one = dtype.box(1.0)
     for i in xrange(size):
         arr.dtype.setitem(arr.storage, i, one)
     return space.wrap(arr)
diff --git a/pypy/module/micronumpy/interp_support.py b/pypy/module/micronumpy/interp_support.py
--- a/pypy/module/micronumpy/interp_support.py
+++ b/pypy/module/micronumpy/interp_support.py
@@ -25,7 +25,7 @@
     i = 0
     while i < number:
         part = s[start:end]
-        a.dtype.setitem(a.storage, i, a.dtype.Box(runpack('d', part)))
+        a.dtype.setitem(a.storage, i, a.dtype.box(runpack('d', part)))
         i += 1
         start += FLOAT_SIZE
         end += FLOAT_SIZE


More information about the pypy-commit mailing list