Author: Armin Rigo <[email protected]>
Branch:
Changeset: r58813:817f45e732ef
Date: 2012-11-09 16:29 +0100
http://bitbucket.org/pypy/pypy/changeset/817f45e732ef/
Log: merge heads
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -15,6 +15,8 @@
See doc/cppyy.rst for full details and functionality.
.. branch: nupypy-axis-arg-check
Check that axis arg is valid in _numpypy
+.. branch:less-gettestobjspace
+.. branch: move-apptest-support
.. branch: iterator-in-rpython
.. branch: numpypy_count_nonzero
@@ -42,6 +44,8 @@
Complex dtype support for numpy
.. branch: numpypy-problems
Improve dtypes intp, uintp, void, string and record
+.. branch: numpypy.float16
+Add float16 numpy dtype
.. branch: kill-someobject
major cleanups including killing some object support
.. branch: cpyext-PyThreadState_New
diff --git a/pypy/module/micronumpy/__init__.py
b/pypy/module/micronumpy/__init__.py
--- a/pypy/module/micronumpy/__init__.py
+++ b/pypy/module/micronumpy/__init__.py
@@ -55,6 +55,7 @@
'inexact': 'interp_boxes.W_InexactBox',
'floating': 'interp_boxes.W_FloatingBox',
'float_': 'interp_boxes.W_Float64Box',
+ 'float16': 'interp_boxes.W_Float16Box',
'float32': 'interp_boxes.W_Float32Box',
'float64': 'interp_boxes.W_Float64Box',
'intp': 'types.IntP.BoxType',
diff --git a/pypy/module/micronumpy/interp_boxes.py
b/pypy/module/micronumpy/interp_boxes.py
--- a/pypy/module/micronumpy/interp_boxes.py
+++ b/pypy/module/micronumpy/interp_boxes.py
@@ -217,6 +217,9 @@
class W_FloatingBox(W_InexactBox):
_attrs_ = ()
+class W_Float16Box(W_FloatingBox, PrimitiveBox):
+ descr__new__, _get_dtype = new_dtype_getter("float16")
+
class W_Float32Box(W_FloatingBox, PrimitiveBox):
descr__new__, _get_dtype = new_dtype_getter("float32")
@@ -458,6 +461,12 @@
__module__ = "numpypy",
)
+W_Float16Box.typedef = TypeDef("float16", W_FloatingBox.typedef,
+ __module__ = "numpypy",
+
+ __new__ = interp2app(W_Float16Box.descr__new__.im_func),
+)
+
W_Float32Box.typedef = TypeDef("float32", W_FloatingBox.typedef,
__module__ = "numpypy",
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
@@ -465,6 +465,14 @@
#alternate_constructors=[space.w_buffer],
# XXX no buffer in space
)
+ self.w_float16dtype = W_Dtype(
+ types.Float16(),
+ num=23,
+ kind=FLOATINGLTR,
+ name="float16",
+ char="e",
+ w_box_type=space.gettypefor(interp_boxes.W_Float16Box),
+ )
ptr_size = rffi.sizeof(rffi.CCHARP)
if ptr_size == 4:
intp_box = interp_boxes.W_Int32Box
@@ -499,14 +507,14 @@
self.w_int16dtype, self.w_uint16dtype, self.w_int32dtype,
self.w_uint32dtype, self.w_longdtype, self.w_ulongdtype,
self.w_int64dtype, self.w_uint64dtype,
- self.w_float32dtype, self.w_float64dtype, self.w_complex64dtype,
+ self.w_float16dtype, self.w_float32dtype, self.w_float64dtype,
self.w_complex64dtype,
self.w_complex128dtype,
self.w_stringdtype, self.w_unicodedtype,
self.w_voiddtype, self.w_intpdtype, self.w_uintpdtype,
]
self.float_dtypes_by_num_bytes = sorted(
(dtype.itemtype.get_element_size(), dtype)
- for dtype in [self.w_float32dtype, self.w_float64dtype]
+ for dtype in [self.w_float16dtype, self.w_float32dtype,
self.w_float64dtype]
)
self.dtypes_by_name = {}
# we reverse, so the stuff with lower numbers override stuff with
diff --git a/pypy/module/micronumpy/interp_ufuncs.py
b/pypy/module/micronumpy/interp_ufuncs.py
--- a/pypy/module/micronumpy/interp_ufuncs.py
+++ b/pypy/module/micronumpy/interp_ufuncs.py
@@ -407,7 +407,7 @@
dtypenum = dt2.num + 1
# UInt64 + signed = Float64
if dt2.num == 10:
- dtypenum += 1
+ dtypenum += 2
newdtype = interp_dtype.get_dtype_cache(space).builtin_dtypes[dtypenum]
if (newdtype.itemtype.get_element_size() > dt2.itemtype.get_element_size()
or
@@ -419,7 +419,7 @@
if LONG_BIT == 32:
dtypenum += 2
else:
- dtypenum += 3
+ dtypenum += 4
return interp_dtype.get_dtype_cache(space).builtin_dtypes[dtypenum]
diff --git a/pypy/module/micronumpy/test/test_base.py
b/pypy/module/micronumpy/test/test_base.py
--- a/pypy/module/micronumpy/test/test_base.py
+++ b/pypy/module/micronumpy/test/test_base.py
@@ -53,6 +53,7 @@
ulong_dtype = get_dtype_cache(space).w_ulongdtype
int64_dtype = get_dtype_cache(space).w_int64dtype
uint64_dtype = get_dtype_cache(space).w_uint64dtype
+ float16_dtype = get_dtype_cache(space).w_float16dtype
float32_dtype = get_dtype_cache(space).w_float32dtype
float64_dtype = get_dtype_cache(space).w_float64dtype
@@ -73,9 +74,9 @@
# Coerce to floats, some of these will eventually be float16, or
# whatever our smallest float type is.
- assert find_unaryop_result_dtype(space, bool_dtype,
promote_to_float=True) is float32_dtype # will be float16 if we ever put that in
- assert find_unaryop_result_dtype(space, int8_dtype,
promote_to_float=True) is float32_dtype # will be float16 if we ever put that in
- assert find_unaryop_result_dtype(space, uint8_dtype,
promote_to_float=True) is float32_dtype # will be float16 if we ever put that in
+ assert find_unaryop_result_dtype(space, bool_dtype,
promote_to_float=True) is float16_dtype
+ assert find_unaryop_result_dtype(space, int8_dtype,
promote_to_float=True) is float16_dtype
+ assert find_unaryop_result_dtype(space, uint8_dtype,
promote_to_float=True) is float16_dtype
assert find_unaryop_result_dtype(space, int16_dtype,
promote_to_float=True) is float32_dtype
assert find_unaryop_result_dtype(space, uint16_dtype,
promote_to_float=True) is float32_dtype
assert find_unaryop_result_dtype(space, int32_dtype,
promote_to_float=True) is float64_dtype
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
@@ -116,7 +116,7 @@
def test_bool_binop_types(self):
from _numpypy import array, dtype
types = [
- '?', 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q', 'f', 'd'
+ '?', 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q', 'f', 'd',
'e',
]
a = array([True], '?')
for t in types:
@@ -142,7 +142,9 @@
tests.extend([('b','I','l'), ('b','L','d'), ('h','I','l'),
('h','L','d'), ('i','I','l'), ('i','L','d')])
for d1, d2, dout in tests:
- assert (array([1], d1) + array([1], d2)).dtype is dtype(dout)
+ # make a failed test print helpful info
+ d3 = (array([1], d1) + array([1], d2)).dtype
+ assert (d1, d2, repr(d3)) == (d1, d2, repr(dtype(dout)))
def test_add_int8(self):
from _numpypy import array, dtype
@@ -228,6 +230,7 @@
(numpy.int16, 5),
(numpy.uint32, 7),
(numpy.int64, 3),
+ (numpy.float16, 10.),
(numpy.float32, 2.0),
(numpy.float64, 4.32),
]:
@@ -427,6 +430,17 @@
assert numpy.uint64(18446744073709551615) == 18446744073709551615
raises(OverflowError, numpy.uint64(18446744073709551616))
+ def test_float16(self):
+ import _numpypy as numpy
+ assert numpy.float16.mro() == [numpy.float16, numpy.floating,
+ numpy.inexact, numpy.number,
+ numpy.generic, object]
+
+ assert numpy.float16(12) == numpy.float64(12)
+ assert numpy.float16('23.4') == numpy.float16(23.4)
+ raises(ValueError, numpy.float16, '23.2df')
+
+
def test_float32(self):
import _numpypy as numpy
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,6 +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('\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))
@@ -2109,8 +2110,7 @@
def test_fromstring_types(self):
from _numpypy import (fromstring, int8, int16, int32, int64, uint8,
- uint16, uint32, float32, float64)
-
+ uint16, uint32, float16, float32, float64)
a = fromstring('\xFF', dtype=int8)
assert a[0] == -1
b = fromstring('\xFF', dtype=uint8)
@@ -2131,6 +2131,8 @@
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
@@ -1,6 +1,5 @@
import functools
import math
-import struct
from pypy.interpreter.error import OperationError
from pypy.module.micronumpy import interp_boxes
@@ -11,14 +10,15 @@
from pypy.rlib.rawstorage import (alloc_raw_storage, raw_storage_setitem,
raw_storage_getitem)
from pypy.rlib.objectmodel import specialize
-from pypy.rlib.rarithmetic import widen, byteswap
+from pypy.rlib.rarithmetic import widen, byteswap, r_ulonglong
from pypy.rpython.lltypesystem import lltype, rffi
from pypy.rlib.rstruct.runpack import runpack
+from pypy.rlib.rstruct.nativefmttable import native_is_bigendian
+from pypy.rlib.rstruct.ieee import float_pack, float_unpack, unpack_float
from pypy.tool.sourcetools import func_with_new_name
from pypy.rlib import jit
from pypy.rlib.rstring import StringBuilder
-
degToRad = math.pi / 180.0
log2 = math.log(2)
log2e = 1. / log2
@@ -179,10 +179,8 @@
self._write(storage, i, offset, value)
def runpack_str(self, s):
- return self.box(runpack(self.format_code, s))
-
- def pack_str(self, box):
- return struct.pack(self.format_code, self.unbox(box))
+ v = runpack(self.format_code, s)
+ return self.box(v)
@simple_binary_op
def add(self, v1, v2):
@@ -298,9 +296,6 @@
value = byteswap(value)
raw_storage_setitem(storage, i + offset, value)
- def pack_str(self, box):
- return struct.pack(self.format_code, byteswap(self.unbox(box)))
-
class Bool(BaseType, Primitive):
_attrs_ = ()
@@ -914,10 +909,49 @@
#value = byteswap(value) XXX
raw_storage_setitem(storage, i + offset, value)
- def pack_str(self, box):
- # XXX byteswap
- return struct.pack(self.format_code, self.unbox(box))
+class Float16(BaseType, Float):
+ _attrs_ = ()
+ _STORAGE_T = rffi.USHORT
+ T = rffi.DOUBLE
+
+ BoxType = interp_boxes.W_Float16Box
+
+ def get_element_size(self):
+ return rffi.sizeof(self._STORAGE_T)
+
+ def runpack_str(self, s):
+ assert len(s) == 2
+ fval = unpack_float(s, native_is_bigendian)
+ return self.box(fval)
+
+ def for_computation(self, v):
+ return float(v)
+
+ def default_fromstring(self, space):
+ return self.box(-1.0)
+
+ def _read(self, storage, i, offset):
+ hbits = raw_storage_getitem(self._STORAGE_T, storage, i + offset)
+ return float_unpack(r_ulonglong(hbits), 2)
+
+ def _write(self, storage, i, offset, value):
+ hbits = float_pack(value,2)
+ raw_storage_setitem(storage, i + offset,
+ rffi.cast(self._STORAGE_T, hbits))
+
+class NonNativeFloat16(Float16):
+ _attrs_ = ()
+ BoxType = interp_boxes.W_Float16Box
+
+ def _read(self, storage, i, offset):
+ res = Float16._read(self, storage, i, offset)
+ #return byteswap(res) XXX
+ return res
+
+ def _write(self, storage, i, offset, value):
+ #value = byteswap(value) XXX
+ Float16._write(self, storage, i, offset, value)
class Float32(BaseType, Float):
_attrs_ = ()
diff --git a/pypy/module/posix/app_posix.py b/pypy/module/posix/app_posix.py
--- a/pypy/module/posix/app_posix.py
+++ b/pypy/module/posix/app_posix.py
@@ -311,6 +311,13 @@
self._stream.close()
return self._proc.wait() or None # 0 => None
__del__ = close
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, *k):
+ self.close()
+
def __getattr__(self, name):
return getattr(self._stream, name)
def __iter__(self):
diff --git a/pypy/module/posix/test/test_posix2.py
b/pypy/module/posix/test/test_posix2.py
--- a/pypy/module/posix/test/test_posix2.py
+++ b/pypy/module/posix/test/test_posix2.py
@@ -501,6 +501,13 @@
assert res == '1\n'
assert stream.close() is None
+ def test_popen_with(self):
+ os = self.posix
+ stream = os.popen('echo 1')
+ with stream as fp:
+ res = fp.read()
+ assert res == '1\n'
+
if hasattr(__import__(os.name), '_getfullpathname'):
def test__getfullpathname(self):
# nt specific
diff --git a/pypy/rlib/rstruct/ieee.py b/pypy/rlib/rstruct/ieee.py
--- a/pypy/rlib/rstruct/ieee.py
+++ b/pypy/rlib/rstruct/ieee.py
@@ -15,7 +15,7 @@
- return an int, not a float
- do round-half-to-even, not round-half-away-from-zero.
- We assume that x is finite and nonnegative; except wrong results
+ We assume that x is finite and nonnegative; expect wrong results
if you use this for negative x.
"""
@@ -27,7 +27,7 @@
def float_unpack(Q, size):
- """Convert a 32-bit or 64-bit integer created
+ """Convert a 16-bit, 32-bit or 64-bit integer created
by float_pack into a Python float."""
if size == 8:
@@ -40,6 +40,11 @@
MAX_EXP = 128 # FLT_MAX_EXP
MANT_DIG = 24 # FLT_MANT_DIG
BITS = 32
+ elif size == 2:
+ MIN_EXP = -13
+ MAX_EXP = 16
+ MANT_DIG = 11
+ BITS = 16
else:
raise ValueError("invalid size value")
@@ -83,6 +88,11 @@
MAX_EXP = 128 # FLT_MAX_EXP
MANT_DIG = 24 # FLT_MANT_DIG
BITS = 32
+ elif size == 2:
+ MIN_EXP = -13
+ MAX_EXP = 16
+ MANT_DIG = 11
+ BITS = 16
else:
raise ValueError("invalid size value")
diff --git a/pypy/rlib/rstruct/test/test_ieee.py
b/pypy/rlib/rstruct/test/test_ieee.py
--- a/pypy/rlib/rstruct/test/test_ieee.py
+++ b/pypy/rlib/rstruct/test/test_ieee.py
@@ -110,3 +110,35 @@
if isnan(x):
continue
self.check_float(x)
+
+ def test_halffloat_exact(self):
+ #testcases generated from numpy.float16(x).view('uint16')
+ cases = [[0, 0], [10, 18688], [-10, 51456], [10e3, 28898],
+ [float('inf'), 31744], [-float('inf'), 64512]]
+ for c,h in cases:
+ hbit = float_pack(c, 2)
+ assert hbit == h
+ assert c == float_unpack(h, 2)
+
+ def test_halffloat_inexact(self):
+ #testcases generated from numpy.float16(x).view('uint16')
+ cases = [[10.001, 18688, 10.], [-10.001, 51456, -10],
+ [0.027588, 10000, 0.027587890625],
+ [22001, 30047, 22000]]
+ for c,h,f in cases:
+ hbit = float_pack(c, 2)
+ assert hbit == h
+ assert f == float_unpack(h, 2)
+
+ def test_halffloat_overunderflow(self):
+ import math
+ cases = [[670000, float('inf')], [-67000, -float('inf')],
+ [1e-08, 0], [-1e-8, -0.]]
+ for f1, f2 in cases:
+ try:
+ f_out = float_unpack(float_pack(f1, 2), 2)
+ except OverflowError:
+ f_out = math.copysign(float('inf'), f1)
+ assert f_out == f2
+ assert math.copysign(1., f_out) == math.copysign(1., f2)
+
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit