[pypy-commit] pypy numpy-record-dtypes: non native dtypes

fijal noreply at buildbot.pypy.org
Tue Feb 7 11:04:18 CET 2012


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: numpy-record-dtypes
Changeset: r52158:b8341326183f
Date: 2012-02-07 12:03 +0200
http://bitbucket.org/pypy/pypy/changeset/b8341326183f/

Log:	non native dtypes

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
@@ -1,3 +1,5 @@
+
+import sys
 from pypy.interpreter.baseobjspace import Wrappable
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.gateway import interp2app
@@ -67,9 +69,10 @@
             return w_dtype
         elif space.isinstance_w(w_dtype, space.w_str):
             name = space.str_w(w_dtype)
-            for dtype in cache.builtin_dtypes:
-                if dtype.name == name or dtype.char == name or name in dtype.aliases:
-                    return dtype
+            try:
+                return cache.dtypes_by_name[name]
+            except KeyError:
+                pass
         elif space.isinstance_w(w_dtype, space.w_list):
             xxx
         else:
@@ -127,6 +130,13 @@
 )
 W_Dtype.typedef.acceptable_as_base_class = False
 
+if sys.byteorder == 'little':
+    byteorder_prefix = '<'
+    nonnative_byteorder_prefix = '>'
+else:
+    byteorder_prefix = '>'
+    nonnative_byteorder_prefix = '<'
+
 class DtypeCache(object):
     def __init__(self, space):
         self.w_booldtype = W_Dtype(
@@ -258,7 +268,6 @@
             char='Q',
             w_box_type = space.gettypefor(interp_boxes.W_ULongLongBox),
         )
-
         self.builtin_dtypes = [
             self.w_booldtype, self.w_int8dtype, self.w_uint8dtype,
             self.w_int16dtype, self.w_uint16dtype, self.w_int32dtype,
@@ -271,6 +280,20 @@
             (dtype.itemtype.get_element_size(), dtype)
             for dtype in self.builtin_dtypes
         )
+        self.dtypes_by_name = {}
+        for dtype in self.builtin_dtypes:
+            self.dtypes_by_name[dtype.name] = dtype
+            can_name = dtype.kind + str(dtype.itemtype.get_element_size())
+            self.dtypes_by_name[can_name] = dtype
+            self.dtypes_by_name[byteorder_prefix + can_name] = dtype
+            new_name = nonnative_byteorder_prefix + can_name
+            itemtypename = dtype.itemtype.__class__.__name__
+            self.dtypes_by_name[new_name] = W_Dtype(
+                getattr(types, 'NonNative' + itemtypename)(),
+                dtype.num, dtype.kind, new_name, dtype.char, dtype.w_box_type)
+            for alias in dtype.aliases:
+                self.dtypes_by_name[alias] = dtype
+            self.dtypes_by_name[dtype.char] = dtype
 
 def get_dtype_cache(space):
     return space.fromcache(DtypeCache)
diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py
--- a/pypy/module/micronumpy/test/test_dtypes.py
+++ b/pypy/module/micronumpy/test/test_dtypes.py
@@ -423,3 +423,8 @@
                                        numpy.generic, object)
         assert numpy.bool_.__mro__ == (numpy.bool_, numpy.generic, object)
         #assert numpy.str_.__mro__ == 
+
+    def test_alternate_constructs(self):
+        from _numpypy import dtype
+        assert dtype('i8') == dtype('<i8')# XXX should be equal == dtype(long)
+        assert dtype('>i8') != dtype('i8')
diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py
--- a/pypy/module/micronumpy/types.py
+++ b/pypy/module/micronumpy/types.py
@@ -6,7 +6,7 @@
 from pypy.objspace.std.floatobject import float2string
 from pypy.rlib import rfloat, libffi, clibffi
 from pypy.rlib.objectmodel import specialize
-from pypy.rlib.rarithmetic import LONG_BIT, widen
+from pypy.rlib.rarithmetic import LONG_BIT, widen, byteswap
 from pypy.rpython.lltypesystem import lltype, rffi
 from pypy.rlib.rstruct.runpack import runpack
 
@@ -99,28 +99,28 @@
     def default_fromstring(self, space):
         raise NotImplementedError
 
+    def _read(self, storage, width, i, offset):
+        return libffi.array_getitem(clibffi.cast_type_to_ffitype(self.T),
+                                    width, storage, i, offset)
+
     def read(self, storage, width, i, offset):
-        return self.box(libffi.array_getitem(clibffi.cast_type_to_ffitype(self.T),
-            width, storage, i, offset
-        ))
+        return self.box(self._read(storage, width, i, offset))
 
     def read_bool(self, storage, width, i, offset):
-        return bool(self.for_computation(
-            libffi.array_getitem(clibffi.cast_type_to_ffitype(self.T),
-                                 width, storage, i, offset)))
+        return bool(self.for_computation(self._read(storage, width, i, offset)))
+
+    def _write(self, storage, width, i, offset, value):
+        libffi.array_setitem(clibffi.cast_type_to_ffitype(self.T),
+                             width, storage, i, offset, value)
+        
 
     def store(self, storage, width, i, offset, box):
-        value = self.unbox(box)
-        libffi.array_setitem(clibffi.cast_type_to_ffitype(self.T),
-            width, storage, i, offset, value
-        )
+        self._write(storage, width, i, offset, self.unbox(box))
 
     def fill(self, storage, width, box, start, stop, offset):
         value = self.unbox(box)
         for i in xrange(start, stop):
-            libffi.array_setitem(clibffi.cast_type_to_ffitype(self.T),
-                width, storage, i, offset, value
-            )
+            self._write(storage, width, i, offset, value)
 
     def runpack_str(self, s):
         return self.box(runpack(self.format_code, s))
@@ -208,6 +208,14 @@
     def min(self, v1, v2):
         return min(v1, v2)
 
+class NonNativePrimitive(Primitive):
+    _mixin_ = True
+    
+    def _read(self, storage, width, i, offset):
+        return byteswap(Primitive._read(self, storage, width, i, offset))
+
+    def _write(self, storage, width, i, offset, value):
+        Primitive._write(self, storage, width, i, offset, byteswap(value))
 
 class Bool(BaseType, Primitive):
     T = lltype.Bool
@@ -523,3 +531,14 @@
         UIntP = tp
         break
 del tp
+
+def _setup():
+    for name, tp in globals().items():
+        if isinstance(tp, type):
+            class NonNative(NonNativePrimitive, tp):
+                pass
+            NonNative.__name__ = 'NonNative' + name
+            globals()[NonNative.__name__] = NonNative
+
+_setup()
+del _setup


More information about the pypy-commit mailing list