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