Author: mattip <[email protected]>
Branch: numpypy.float16
Changeset: r58670:cf2ea494b4d0
Date: 2012-11-02 15:33 +0200
http://bitbucket.org/pypy/pypy/changeset/cf2ea494b4d0/

Log:    _write, _read works

diff --git a/pypy/module/micronumpy/halffloat.py 
b/pypy/module/micronumpy/halffloat.py
--- a/pypy/module/micronumpy/halffloat.py
+++ b/pypy/module/micronumpy/halffloat.py
@@ -1,31 +1,15 @@
 # Based on numpy's halffloat.c, this is an implementation of routines
 # for 16 bit float values.
+from pypy.rpython.lltypesystem import rffi
 
-#from pypy.rpython.lltypesystem import rffi
-#from rffi import USHORT as uint16
-#def tofloat(x):
-#    return rffi.cast(rffi.FLOAT, x)
 
-'''
-def half_to_float(x):
-    assert isinstance(x, float16)
-    xbits = x.view(uint16)
-    fbits = halffloatbits_to_floatbits(xbits)
-    return uint32(fbits).view(float32) 
-
-def float_to_half(f):
-    assert isinstance(f, (float32, float))
-    fbits = float32(f).view(uint32)
-    xbits = floatbits_to_halfbits(fbits)
-    return uint16(xbits).view(float16)
-'''
 def halfbits_to_floatbits(x):
     h_exp = x & 0x7c00
-    f_sign = (x & 0x8000) << 16
+    f_sgn = (x & 0x8000) << 16
     if h_exp == 0: #0 or subnormal
         h_sig = x & 0x03ff
         if h_sig == 0:
-            return f_sign
+            return f_sgn
         #Subnormal
         h_sig <<= 1;
         while (h_sig & 0x0400) == 0:
@@ -33,11 +17,11 @@
             h_exp += 1
         f_exp = 127 - 15 - h_exp << 23
         f_sig = h_sig & 0x03ff << 13
-        return f_sign & f_exp & f_sig
+        return f_sgn + f_exp + f_sig
     elif h_exp == 0x7c00: # inf or nan
-        return f_sign + 0x7f800000 + ((x & 0x03ff) << 13)
+        return f_sgn + 0x7f800000 + ((x & 0x03ff) << 13)
     # Just need to adjust the exponent and shift
-    return f_sign + (((x & 0x7fff) + 0x1c000) << 13)
+    return f_sgn +((rffi.cast(rffi.UINT,(x & 0x7fff)) + 0x1c000) << 13)
 
 
 def floatbits_to_halfbits(f):
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
@@ -228,7 +228,7 @@
             (numpy.int16, 5),
             (numpy.uint32, 7),
             (numpy.int64, 3),
-            (numpy.float16, 3.14156),
+            (numpy.float16, 10.),
             (numpy.float32, 2.0),
             (numpy.float64, 4.32),
         ]:
diff --git a/pypy/module/micronumpy/test/test_halffloat.py 
b/pypy/module/micronumpy/test/test_halffloat.py
--- a/pypy/module/micronumpy/test/test_halffloat.py
+++ b/pypy/module/micronumpy/test/test_halffloat.py
@@ -14,7 +14,8 @@
         # numpy.float16(v).view(uint16)
         cases = [[0., 0, 0], [10, 1092616192, 18688], [-10, 3240099840, 
51456], 
                  [10e3, 1176256512, 28898], [float('inf'), 2139095040, 31744], 
-                 [-float('inf'), 4286578688, 64512]]
+                 [-float('inf'), 4286578688, 64512],
+                 [5., 1084227584, 17664],]
         for v, fbits, hbits in cases:
             # No 'view' in numpypy yet
             # fbits = array(v, dtype='float32').view(uint32)
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
@@ -2038,7 +2038,7 @@
         BaseNumpyAppTest.setup_class.im_func(cls)
         cls.w_data = cls.space.wrap(struct.pack('dddd', 1, 2, 3, 4))
         cls.w_fdata = cls.space.wrap(struct.pack('f', 2.3))
-        cls.w_float16val = cls.space.wrap(struct.pack('e', 5.2))
+        cls.w_float16val = cls.space.wrap('\x00E') # 5.0 in float16 
         cls.w_float32val = cls.space.wrap(struct.pack('f', 5.2))
         cls.w_float64val = cls.space.wrap(struct.pack('d', 300.4))
         cls.w_ulongval = cls.space.wrap(struct.pack('L', 12))
@@ -2111,7 +2111,6 @@
     def test_fromstring_types(self):
         from _numpypy import (fromstring, int8, int16, int32, int64, uint8,
             uint16, uint32, float16, float32, float64)
-
         a = fromstring('\xFF', dtype=int8)
         assert a[0] == -1
         b = fromstring('\xFF', dtype=uint8)
@@ -2126,14 +2125,14 @@
         assert repr(f[0]) == '4294967295'
         g = fromstring('\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF', dtype=int64)
         assert g[0] == -1
-        h = fromstring(self.float16val, dtype=float16)
-        assert h[0] == float16(5.2)
         h = fromstring(self.float32val, dtype=float32)
         assert h[0] == float32(5.2)
         i = fromstring(self.float64val, dtype=float64)
         assert i[0] == float64(300.4)
         j = fromstring(self.ulongval, dtype='L')
         assert j[0] == 12
+        k = fromstring(self.float16val, dtype=float16)
+        assert k[0] == float16(5.)
 
     def test_fromstring_invalid(self):
         from _numpypy import fromstring, uint16, uint8, int32
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
@@ -14,6 +14,7 @@
 from pypy.rlib.rarithmetic import widen, byteswap
 from pypy.rpython.lltypesystem import lltype, rffi
 from pypy.rlib.rstruct.runpack import runpack
+from pypy.rlib.rstruct.ieee import float_pack, float_unpack
 from pypy.tool.sourcetools import func_with_new_name
 from pypy.rlib import jit
 from pypy.rlib.rstring import StringBuilder
@@ -180,7 +181,8 @@
             self._write(storage, i, offset, value)
 
     def runpack_str(self, s):
-        return self.box(runpack(self.format_code, s))
+        v = runpack(self.format_code, s)
+        return self.box(v)
 
     def pack_str(self, box):
         return struct.pack(self.format_code, self.unbox(box))
@@ -923,15 +925,22 @@
 class Float16(BaseType, Float):
     _attrs_ = ()
     T = rffi.USHORT
-    _COMPUTATION_T = rffi.FLOAT
+    _COMPUTATION_T = rffi.DOUBLE
 
     BoxType = interp_boxes.W_Float16Box
-    format_code = "e"
 
     def str_format(self, box):
         return float2string(self.for_computation(self.unbox(box)), "g",
                             rfloat.DTSF_STR_PRECISION)
 
+    def pack_str(self, box):
+        xxx
+
+    def runpack_str(self, s):
+        hbits = runpack('H', s)
+        fbits = halffloat.halfbits_to_floatbits(hbits)
+        return self.box(float_unpack(fbits, 4))
+
     def for_computation(self, v):
         return float(v)
 
@@ -945,24 +954,29 @@
 
     @specialize.argtype(1)
     def box(self, value):
-        return self.BoxType(rffi.cast(self._COMPUTATION_T, value))
+        ret_val =  self.BoxType(rffi.cast(self._COMPUTATION_T, value))
+        return ret_val
 
 
     def _read(self, storage, i, offset):
         byte_rep = raw_storage_getitem(self.T, storage, i + offset)
         fbits = halffloat.halfbits_to_floatbits(byte_rep)
-        return rffi.cast(rffi.FLOAT, fbits)
+        return float_unpack(fbits, 4)
 
     def read(self, arr, i, offset, dtype=None):
-        val = self._read(arr.storage, i, offset)
-        return self.BoxType(val)
+        value = self._read(arr.storage, i, offset)
+        ret_val =  self.BoxType(rffi.cast(self._COMPUTATION_T, value))
+        return ret_val
 
+    def _write(self, storage, i, offset, value):
+        fbits = float_pack(value,4)
+        hbits = halffloat.floatbits_to_halfbits(fbits)
+        raw_storage_setitem(storage, i + offset, rffi.cast(self.T, hbits))
 
 class NonNativeFloat16(BaseType, NonNativeFloat):
     _attrs_ = ()
 
     BoxType = interp_boxes.W_Float16Box
-    format_code = "e"
 
 class Float32(BaseType, Float):
     _attrs_ = ()
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to