[pypy-commit] pypy default: fix numpy complex types with non-native byteorder

bdkearns noreply at buildbot.pypy.org
Fri Feb 21 01:20:09 CET 2014


Author: Brian Kearns <bdkearns at gmail.com>
Branch: 
Changeset: r69227:fb089d6960ac
Date: 2014-02-20 18:42 -0500
http://bitbucket.org/pypy/pypy/changeset/fb089d6960ac/

Log:	fix numpy complex types with non-native byteorder

diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py
--- a/pypy/module/micronumpy/arrayimpl/concrete.py
+++ b/pypy/module/micronumpy/arrayimpl/concrete.py
@@ -86,25 +86,25 @@
         return SliceArray(self.start, strides, backstrides, new_shape,
                           self, orig_array, dtype=dtype)
 
-    def get_real(self, orig_array):
+    def get_real(self, space, orig_array):
         strides = self.get_strides()
         backstrides = self.get_backstrides()
         if self.dtype.is_complex_type():
-            dtype =  self.dtype.float_type
+            dtype = self.dtype.get_float_dtype(space)
             return SliceArray(self.start, strides, backstrides,
                           self.get_shape(), self, orig_array, dtype=dtype)
         return SliceArray(self.start, strides, backstrides,
                           self.get_shape(), self, orig_array)
 
     def set_real(self, space, orig_array, w_value):
-        tmp = self.get_real(orig_array)
+        tmp = self.get_real(space, orig_array)
         tmp.setslice(space, convert_to_array(space, w_value))
 
     def get_imag(self, space, orig_array):
         strides = self.get_strides()
         backstrides = self.get_backstrides()
         if self.dtype.is_complex_type():
-            dtype =  self.dtype.float_type
+            dtype = self.dtype.get_float_dtype(space)
             return SliceArray(self.start + dtype.get_size(), strides,
                     backstrides, self.get_shape(), self, orig_array, dtype=dtype)
         impl = NonWritableArray(self.get_shape(), self.dtype, self.order, strides,
diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py
--- a/pypy/module/micronumpy/arrayimpl/scalar.py
+++ b/pypy/module/micronumpy/arrayimpl/scalar.py
@@ -78,22 +78,22 @@
             scalar.value = dtype.itemtype.runpack_str(space, self.value.raw_str())
         return scalar
 
-    def get_real(self, orig_array):
+    def get_real(self, space, orig_array):
         if self.dtype.is_complex_type():
-            scalar = Scalar(self.dtype.float_type)
+            scalar = Scalar(self.dtype.get_float_dtype(space))
             scalar.value = self.value.convert_real_to(scalar.dtype)
             return scalar
         return self
 
     def set_real(self, space, orig_array, w_val):
         w_arr = convert_to_array(space, w_val)
-        dtype = self.dtype.float_type or self.dtype
         if len(w_arr.get_shape()) > 0:
             raise OperationError(space.w_ValueError, space.wrap(
                 "could not broadcast input array from shape " +
                 "(%s) into shape ()" % (
                     ','.join([str(x) for x in w_arr.get_shape()],))))
         if self.dtype.is_complex_type():
+            dtype = self.dtype.get_float_dtype(space)
             self.value = self.dtype.itemtype.composite(
                                w_arr.get_scalar_value().convert_to(space, dtype),
                                self.value.convert_imag_to(dtype))
@@ -102,7 +102,7 @@
 
     def get_imag(self, space, orig_array):
         if self.dtype.is_complex_type():
-            scalar = Scalar(self.dtype.float_type)
+            scalar = Scalar(self.dtype.get_float_dtype(space))
             scalar.value = self.value.convert_imag_to(scalar.dtype)
             return scalar
         scalar = Scalar(self.dtype)
@@ -116,16 +116,15 @@
         #Only called on complex dtype
         assert self.dtype.is_complex_type()
         w_arr = convert_to_array(space, w_val)
-        dtype = self.dtype.float_type
         if len(w_arr.get_shape()) > 0:
             raise OperationError(space.w_ValueError, space.wrap(
                 "could not broadcast input array from shape " +
                 "(%s) into shape ()" % (
                     ','.join([str(x) for x in w_arr.get_shape()],))))
+        dtype = self.dtype.get_float_dtype(space)
         self.value = self.dtype.itemtype.composite(
                             self.value.convert_real_to(dtype),
-                            w_arr.get_scalar_value().convert_to(space, dtype),
-                            )
+                            w_arr.get_scalar_value().convert_to(space, dtype))
 
     def descr_getitem(self, space, _, w_idx):
         if space.isinstance_w(w_idx, space.w_tuple):
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
@@ -123,6 +123,11 @@
             return '|S' + str(self.get_size())
         return self.name
 
+    def get_float_dtype(self, space):
+        assert self.kind == NPY_COMPLEXLTR
+        assert self.float_type is not None
+        return get_dtype_cache(space).dtypes_by_name[self.byteorder + self.float_type]
+
     def descr_str(self, space):
         return space.wrap(self.get_name())
 
@@ -697,7 +702,7 @@
             char=NPY_CFLOATLTR,
             w_box_type = space.gettypefor(interp_boxes.W_Complex64Box),
             aliases=['csingle'],
-            float_type = self.w_float32dtype,
+            float_type=NPY_FLOATLTR,
         )
         self.w_complex128dtype = W_Dtype(
             types.Complex128(),
@@ -709,7 +714,7 @@
             alternate_constructors=[space.w_complex,
                                     space.gettypefor(interp_boxes.W_ComplexFloatingBox)],
             aliases=["complex", 'cfloat', 'cdouble'],
-            float_type = self.w_float64dtype,
+            float_type=NPY_DOUBLELTR,
         )
         self.w_complexlongdtype = W_Dtype(
             types.ComplexLong(),
@@ -719,7 +724,7 @@
             char=NPY_CLONGDOUBLELTR,
             w_box_type = space.gettypefor(interp_boxes.W_ComplexLongBox),
             aliases=["clongdouble", "clongfloat"],
-            float_type = self.w_floatlongdtype,
+            float_type=NPY_LONGDOUBLELTR,
         )
         self.w_stringdtype = W_Dtype(
             types.StringType(),
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
@@ -323,8 +323,8 @@
         return wrap_impl(space, w_subtype, self, copy)
 
     def descr_get_real(self, space):
-        return wrap_impl(space, space.type(self), self,
-                         self.implementation.get_real(self))
+        ret = self.implementation.get_real(space, self)
+        return wrap_impl(space, space.type(self), self, ret)
 
     def descr_get_imag(self, space):
         ret = self.implementation.get_imag(space, self)
diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py
--- a/pypy/module/micronumpy/test/test_numarray.py
+++ b/pypy/module/micronumpy/test/test_numarray.py
@@ -3028,6 +3028,20 @@
         v = fromstring("abcd", dtype="|S2")
         assert v[0] == "ab"
         assert v[1] == "cd"
+        v = fromstring('@\x01\x99\x99\x99\x99\x99\x9a\xbf\xf1\x99\x99\x99\x99\x99\x9a',
+                       dtype=dtype('>c16'))
+        assert v.tostring() == \
+            '@\x01\x99\x99\x99\x99\x99\x9a\xbf\xf1\x99\x99\x99\x99\x99\x9a'
+        assert v[0] == 2.2-1.1j
+        assert v.real == 2.2
+        assert v.imag == -1.1
+        v = fromstring('\x9a\x99\x99\x99\x99\x99\x01@\x9a\x99\x99\x99\x99\x99\xf1\xbf',
+                       dtype=dtype('<c16'))
+        assert v.tostring() == \
+            '\x9a\x99\x99\x99\x99\x99\x01@\x9a\x99\x99\x99\x99\x99\xf1\xbf'
+        assert v[0] == 2.2-1.1j
+        assert v.real == 2.2
+        assert v.imag == -1.1
 
     def test_fromstring_types(self):
         from numpypy import fromstring, array, dtype
@@ -3092,6 +3106,10 @@
                 raises(NotImplementedError, a.tostring, order)
             else:
                 assert a.tostring(order) == '\x01\x03\x02\x04'
+        assert array(2.2-1.1j, dtype='>c16').tostring() == \
+            '@\x01\x99\x99\x99\x99\x99\x9a\xbf\xf1\x99\x99\x99\x99\x99\x9a'
+        assert array(2.2-1.1j, dtype='<c16').tostring() == \
+            '\x9a\x99\x99\x99\x99\x99\x01@\x9a\x99\x99\x99\x99\x99\xf1\xbf'
 
 
 class AppTestRepr(BaseNumpyAppTest):
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
@@ -1061,6 +1061,9 @@
         l = len(s) // 2
         real = comp.runpack_str(space, s[:l])
         imag = comp.runpack_str(space, s[l:])
+        if not self.native:
+            real = comp.byteswap(real)
+            imag = comp.byteswap(imag)
         return self.composite(real, imag)
 
     @staticmethod
@@ -1121,6 +1124,9 @@
     def _read(self, storage, i, offset):
         real = raw_storage_getitem(self.T, storage, i + offset)
         imag = raw_storage_getitem(self.T, storage, i + offset + rffi.sizeof(self.T))
+        if not self.native:
+            real = byteswap(real)
+            imag = byteswap(imag)
         return real, imag
 
     def read(self, arr, i, offset, dtype=None):
@@ -1128,8 +1134,12 @@
         return self.box_complex(real, imag)
 
     def _write(self, storage, i, offset, value):
-        raw_storage_setitem(storage, i + offset, value[0])
-        raw_storage_setitem(storage, i + offset + rffi.sizeof(self.T), value[1])
+        real, imag = value
+        if not self.native:
+            real = byteswap(real)
+            imag = byteswap(imag)
+        raw_storage_setitem(storage, i + offset, real)
+        raw_storage_setitem(storage, i + offset + rffi.sizeof(self.T), imag)
 
     def store(self, arr, i, offset, box):
         self._write(arr.storage, i, offset, self.unbox(box))


More information about the pypy-commit mailing list