[pypy-commit] pypy default: merge unsigned-dtypes branch
justinpeel
noreply at buildbot.pypy.org
Mon Oct 3 21:44:35 CEST 2011
Author: Justin Peel <notmuchtotell at gmail.com>
Branch:
Changeset: r47805:1255f9205eda
Date: 2011-10-03 13:44 -0600
http://bitbucket.org/pypy/pypy/changeset/1255f9205eda/
Log: merge unsigned-dtypes branch
diff --git a/pypy/jit/codewriter/effectinfo.py b/pypy/jit/codewriter/effectinfo.py
--- a/pypy/jit/codewriter/effectinfo.py
+++ b/pypy/jit/codewriter/effectinfo.py
@@ -74,6 +74,7 @@
OS_LLONG_UGE = 91
OS_LLONG_URSHIFT = 92
OS_LLONG_FROM_UINT = 93
+ OS_LLONG_U_TO_FLOAT = 94
#
OS_MATH_SQRT = 100
diff --git a/pypy/jit/codewriter/jtransform.py b/pypy/jit/codewriter/jtransform.py
--- a/pypy/jit/codewriter/jtransform.py
+++ b/pypy/jit/codewriter/jtransform.py
@@ -440,6 +440,7 @@
rewrite_op_ullong_mod_zer = _do_builtin_call
rewrite_op_gc_identityhash = _do_builtin_call
rewrite_op_gc_id = _do_builtin_call
+ rewrite_op_uint_mod = _do_builtin_call
# ----------
# getfield/setfield/mallocs etc.
@@ -883,9 +884,15 @@
v = v_arg
oplist = []
if unsigned1:
- opname = 'cast_uint_to_longlong'
+ if unsigned2:
+ opname = 'cast_uint_to_ulonglong'
+ else:
+ opname = 'cast_uint_to_longlong'
else:
- opname = 'cast_int_to_longlong'
+ if unsigned2:
+ opname = 'cast_int_to_ulonglong'
+ else:
+ opname = 'cast_int_to_longlong'
op2 = self.rewrite_operation(
SpaceOperation(opname, [v], v_result)
)
@@ -995,6 +1002,21 @@
return op2
''' % (_op, _oopspec.lower(), _oopspec, _oopspec)).compile()
+ for _op, _oopspec in [('cast_int_to_ulonglong', 'FROM_INT'),
+ ('cast_uint_to_ulonglong', 'FROM_UINT'),
+ ('cast_float_to_ulonglong', 'FROM_FLOAT'),
+ ('cast_ulonglong_to_float', 'U_TO_FLOAT'),
+ ]:
+ exec py.code.Source('''
+ def rewrite_op_%s(self, op):
+ args = op.args
+ op1 = self.prepare_builtin_call(op, "ullong_%s", args)
+ op2 = self._handle_oopspec_call(op1, args,
+ EffectInfo.OS_LLONG_%s,
+ EffectInfo.EF_ELIDABLE_CANNOT_RAISE)
+ return op2
+ ''' % (_op, _oopspec.lower(), _oopspec)).compile()
+
def _normalize(self, oplist):
if isinstance(oplist, SpaceOperation):
return [oplist]
diff --git a/pypy/jit/codewriter/support.py b/pypy/jit/codewriter/support.py
--- a/pypy/jit/codewriter/support.py
+++ b/pypy/jit/codewriter/support.py
@@ -315,18 +315,30 @@
def _ll_1_llong_from_int(x):
return r_longlong(intmask(x))
+def _ll_1_ullong_from_int(x):
+ return r_ulonglong(intmask(x))
+
def _ll_1_llong_from_uint(x):
return r_longlong(r_uint(x))
+def _ll_1_ullong_from_uint(x):
+ return r_ulonglong(r_uint(x))
+
def _ll_1_llong_to_int(xll):
return intmask(xll)
def _ll_1_llong_from_float(xf):
return r_longlong(xf)
+def _ll_1_ullong_from_float(xf):
+ return r_ulonglong(xf)
+
def _ll_1_llong_to_float(xll):
return float(rffi.cast(lltype.SignedLongLong, xll))
+def _ll_1_ullong_u_to_float(xull):
+ return float(rffi.cast(lltype.UnsignedLongLong, xull))
+
def _ll_1_llong_abs(xll):
if xll < 0:
@@ -351,20 +363,23 @@
return llop.llong_mod(lltype.SignedLongLong, xll, yll)
def _ll_2_ullong_floordiv(xll, yll):
- return llop.ullong_floordiv(lltype.SignedLongLong, xll, yll)
+ return llop.ullong_floordiv(lltype.UnsignedLongLong, xll, yll)
def _ll_2_ullong_floordiv_zer(xll, yll):
if yll == 0:
raise ZeroDivisionError
- return llop.ullong_floordiv(lltype.SignedLongLong, xll, yll)
+ return llop.ullong_floordiv(lltype.UnsignedLongLong, xll, yll)
def _ll_2_ullong_mod(xll, yll):
- return llop.ullong_mod(lltype.SignedLongLong, xll, yll)
+ return llop.ullong_mod(lltype.UnsignedLongLong, xll, yll)
def _ll_2_ullong_mod_zer(xll, yll):
if yll == 0:
raise ZeroDivisionError
- return llop.ullong_mod(lltype.SignedLongLong, xll, yll)
+ return llop.ullong_mod(lltype.UnsignedLongLong, xll, yll)
+
+def _ll_2_uint_mod(xll, yll):
+ return llop.uint_mod(lltype.Unsigned, xll, yll)
# libffi support
diff --git a/pypy/jit/codewriter/test/test_flatten.py b/pypy/jit/codewriter/test/test_flatten.py
--- a/pypy/jit/codewriter/test/test_flatten.py
+++ b/pypy/jit/codewriter/test/test_flatten.py
@@ -829,14 +829,15 @@
self.encoding_test(f, [rffi.cast(FROM, 42)], expectedstr,
transform=True)
elif TO in (rffi.LONG, rffi.ULONG):
+ if rffi.cast(FROM, -1) < 0:
+ fnname = "llong_from_int"
+ else:
+ fnname = "llong_from_uint"
if TO == rffi.LONG:
TO = rffi.LONGLONG
else:
TO = rffi.ULONGLONG
- if rffi.cast(FROM, -1) < 0:
- fnname = "llong_from_int"
- else:
- fnname = "llong_from_uint"
+ fnname = "u" + fnname
expected.pop() # remove int_return
expected.append(
"residual_call_irf_f $<* fn %s>, <Descr>, I[%s], R[], F[] -> %%f0"
diff --git a/pypy/jit/codewriter/test/test_longlong.py b/pypy/jit/codewriter/test/test_longlong.py
--- a/pypy/jit/codewriter/test/test_longlong.py
+++ b/pypy/jit/codewriter/test/test_longlong.py
@@ -57,7 +57,8 @@
assert op1.opname == 'residual_call_irf_f'
else:
assert op1.opname == 'residual_call_irf_i'
- gotindex = getattr(EffectInfo, 'OS_' + op1.args[0].value.upper())
+ gotindex = getattr(EffectInfo,
+ 'OS_' + op1.args[0].value.upper().lstrip('U'))
assert gotindex == oopspecindex
assert op1.args[1] == 'calldescr-%d' % oopspecindex
assert list(op1.args[2]) == [v for v in vlist
@@ -192,8 +193,12 @@
[lltype.SignedLongLong], lltype.Signed)
self.do_check('cast_float_to_longlong', EffectInfo.OS_LLONG_FROM_FLOAT,
[lltype.Float], lltype.SignedLongLong)
+ self.do_check('cast_float_to_ulonglong', EffectInfo.OS_LLONG_FROM_FLOAT,
+ [lltype.Float], lltype.UnsignedLongLong)
self.do_check('cast_longlong_to_float', EffectInfo.OS_LLONG_TO_FLOAT,
[lltype.SignedLongLong], lltype.Float)
+ self.do_check('cast_ulonglong_to_float', EffectInfo.OS_LLONG_U_TO_FLOAT,
+ [lltype.UnsignedLongLong], lltype.Float)
for T1 in [lltype.SignedLongLong, lltype.UnsignedLongLong]:
for T2 in [lltype.Signed, lltype.Unsigned]:
self.do_check('cast_primitive', EffectInfo.OS_LLONG_TO_INT,
diff --git a/pypy/jit/metainterp/test/test_ajit.py b/pypy/jit/metainterp/test/test_ajit.py
--- a/pypy/jit/metainterp/test/test_ajit.py
+++ b/pypy/jit/metainterp/test/test_ajit.py
@@ -2956,6 +2956,18 @@
assert res == f(32)
self.check_loops(arraylen_gc=2)
+ def test_ulonglong_mod(self):
+ myjitdriver = JitDriver(greens = [], reds = ['n', 'sa', 'i'])
+ def f(n):
+ sa = i = rffi.cast(rffi.ULONGLONG, 1)
+ while i < rffi.cast(rffi.ULONGLONG, n):
+ myjitdriver.jit_merge_point(sa=sa, n=n, i=i)
+ sa += sa % i
+ i += 1
+ res = self.meta_interp(f, [32])
+ assert res == f(32)
+
+
class TestOOtype(BasicTests, OOJitMixin):
def test_oohash(self):
diff --git a/pypy/jit/metainterp/test/test_longlong.py b/pypy/jit/metainterp/test/test_longlong.py
--- a/pypy/jit/metainterp/test/test_longlong.py
+++ b/pypy/jit/metainterp/test/test_longlong.py
@@ -118,6 +118,26 @@
res = self.interp_operations(f, [1000000000])
assert res == 123500000000.0
+ def test_floats_negative(self):
+ def f(i):
+ # i == 1000000000
+ f = i * -123.5
+ n = r_longlong(f)
+ compare(n, -29, 1054051584)
+ return float(n)
+ res = self.interp_operations(f, [1000000000])
+ assert res == -123500000000.0
+
+ def test_floats_ulonglong(self):
+ def f(i):
+ # i == 1000000000
+ f = i * 12350000000.0
+ n = r_ulonglong(f)
+ compare(n, -1419508847, 538116096)
+ return float(n)
+ res = self.interp_operations(f, [1000000000])
+ assert res == 12350000000000000000.0
+
def test_unsigned_compare_ops(self):
def f(n1, n2):
# n == 30002000000000
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
@@ -7,13 +7,14 @@
from pypy.interpreter.typedef import TypeDef, interp_attrproperty, GetSetProperty
from pypy.module.micronumpy import signature
from pypy.objspace.std.floatobject import float2string
-from pypy.rlib import rfloat
-from pypy.rlib.rarithmetic import widen
+from pypy.rlib import rarithmetic, rfloat
+from pypy.rlib.rarithmetic import LONG_BIT, widen
from pypy.rlib.objectmodel import specialize, enforceargs
from pypy.rlib.unroll import unrolling_iterable
from pypy.rpython.lltypesystem import lltype, rffi
+UNSIGNEDLTR = "u"
SIGNEDLTR = "i"
BOOLLTR = "b"
FLOATINGLTR = "f"
@@ -61,7 +62,10 @@
self.val = val
def wrap(self, space):
- return space.wrap(self.val)
+ val = self.val
+ if valtype is rarithmetic.r_singlefloat:
+ val = float(val)
+ return space.wrap(val)
def convert_to(self, dtype):
return dtype.adapt_val(self.val)
@@ -145,7 +149,7 @@
return self.adapt_val(func(self, self.for_computation(self.unbox(v))))
return impl
-class ArithmaticTypeMixin(object):
+class ArithmeticTypeMixin(object):
_mixin_ = True
@binop
@@ -200,11 +204,17 @@
return v1 >= v2
-class FloatArithmeticDtype(ArithmaticTypeMixin):
+class FloatArithmeticDtype(ArithmeticTypeMixin):
_mixin_ = True
+ def unwrap(self, space, w_item):
+ return self.adapt_val(space.float_w(space.float(w_item)))
+
def for_computation(self, v):
- return v
+ return float(v)
+
+ def str_format(self, item):
+ return float2string(self.for_computation(self.unbox(item)), 'g', rfloat.DTSF_STR_PRECISION)
@binop
def mod(self, v1, v2):
@@ -265,7 +275,7 @@
def arcsinh(self, v):
return math.asinh(v)
-class IntegerArithmeticDtype(ArithmaticTypeMixin):
+class IntegerArithmeticDtype(ArithmeticTypeMixin):
_mixin_ = True
def unwrap(self, space, w_item):
@@ -274,10 +284,16 @@
def for_computation(self, v):
return widen(v)
+ def str_format(self, item):
+ return str(widen(self.unbox(item)))
+
@binop
def mod(self, v1, v2):
return v1 % v2
+class SignedIntegerArithmeticDtype(IntegerArithmeticDtype):
+ _mixin_ = True
+
@unaryop
def sign(self, v):
if v > 0:
@@ -288,17 +304,22 @@
assert v == 0
return 0
- def str_format(self, item):
- return str(widen(self.unbox(item)))
+class UnsignedIntegerArithmeticDtype(IntegerArithmeticDtype):
+ _mixin_ = True
+
+ @unaryop
+ def sign(self, v):
+ return int(v != 0)
+
W_BoolDtype = create_low_level_dtype(
num = 0, kind = BOOLLTR, name = "bool",
- aliases = ["?"],
+ aliases = ["?", "bool", "bool8"],
applevel_types = ["bool"],
T = lltype.Bool,
valtype = bool,
)
-class W_BoolDtype(IntegerArithmeticDtype, W_BoolDtype):
+class W_BoolDtype(SignedIntegerArithmeticDtype, W_BoolDtype):
def unwrap(self, space, w_item):
return self.adapt_val(space.is_true(w_item))
@@ -311,67 +332,139 @@
W_Int8Dtype = create_low_level_dtype(
num = 1, kind = SIGNEDLTR, name = "int8",
- aliases = ["int8"],
+ aliases = ["b", "int8", "i1"],
applevel_types = [],
T = rffi.SIGNEDCHAR,
valtype = rffi.SIGNEDCHAR._type,
expected_size = 1,
)
-class W_Int8Dtype(IntegerArithmeticDtype, W_Int8Dtype):
+class W_Int8Dtype(SignedIntegerArithmeticDtype, W_Int8Dtype):
+ pass
+
+W_UInt8Dtype = create_low_level_dtype(
+ num = 2, kind = UNSIGNEDLTR, name = "uint8",
+ aliases = ["B", "uint8", "I1"],
+ applevel_types = [],
+ T = rffi.UCHAR,
+ valtype = rffi.UCHAR._type,
+ expected_size = 1,
+)
+class W_UInt8Dtype(UnsignedIntegerArithmeticDtype, W_UInt8Dtype):
pass
W_Int16Dtype = create_low_level_dtype(
num = 3, kind = SIGNEDLTR, name = "int16",
- aliases = ["int16"],
+ aliases = ["h", "int16", "i2"],
applevel_types = [],
T = rffi.SHORT,
valtype = rffi.SHORT._type,
expected_size = 2,
)
-class W_Int16Dtype(IntegerArithmeticDtype, W_Int16Dtype):
+class W_Int16Dtype(SignedIntegerArithmeticDtype, W_Int16Dtype):
+ pass
+
+W_UInt16Dtype = create_low_level_dtype(
+ num = 4, kind = UNSIGNEDLTR, name = "uint16",
+ aliases = ["H", "uint16", "I2"],
+ applevel_types = [],
+ T = rffi.USHORT,
+ valtype = rffi.USHORT._type,
+ expected_size = 2,
+)
+class W_UInt16Dtype(UnsignedIntegerArithmeticDtype, W_UInt16Dtype):
pass
W_Int32Dtype = create_low_level_dtype(
num = 5, kind = SIGNEDLTR, name = "int32",
- aliases = ["i"],
+ aliases = ["i", "int32", "i4"],
applevel_types = [],
T = rffi.INT,
valtype = rffi.INT._type,
expected_size = 4,
)
-class W_Int32Dtype(IntegerArithmeticDtype, W_Int32Dtype):
+class W_Int32Dtype(SignedIntegerArithmeticDtype, W_Int32Dtype):
+ pass
+
+W_UInt32Dtype = create_low_level_dtype(
+ num = 6, kind = UNSIGNEDLTR, name = "uint32",
+ aliases = ["I", "uint32", "I4"],
+ applevel_types = [],
+ T = rffi.UINT,
+ valtype = rffi.UINT._type,
+ expected_size = 4,
+)
+class W_UInt32Dtype(UnsignedIntegerArithmeticDtype, W_UInt32Dtype):
pass
W_Int64Dtype = create_low_level_dtype(
num = 9, kind = SIGNEDLTR, name = "int64",
- aliases = [],
+ aliases = ["q", "int64", "i8"],
applevel_types = ["long"],
T = rffi.LONGLONG,
valtype = rffi.LONGLONG._type,
expected_size = 8,
)
-class W_Int64Dtype(IntegerArithmeticDtype, W_Int64Dtype):
+class W_Int64Dtype(SignedIntegerArithmeticDtype, W_Int64Dtype):
+ pass
+
+W_UInt64Dtype = create_low_level_dtype(
+ num = 10, kind = UNSIGNEDLTR, name = "uint64",
+ aliases = ["Q", "uint64", "I8"],
+ applevel_types = [],
+ T = rffi.ULONGLONG,
+ valtype = rffi.ULONGLONG._type,
+ expected_size = 8,
+)
+class W_UInt64Dtype(UnsignedIntegerArithmeticDtype, W_UInt64Dtype):
+ pass
+
+if LONG_BIT == 32:
+ class W_LongDtype(W_Int32Dtype):
+ pass
+
+ class W_ULongDtype(W_UInt32Dtype):
+ pass
+else:
+ class W_LongDtype(W_Int64Dtype):
+ pass
+
+ class W_ULongDtype(W_UInt64Dtype):
+ pass
+
+W_LongDtype.num = 7
+W_LongDtype.aliases = ["l"]
+W_LongDtype.applevel_types = ["int"]
+W_ULongDtype.num = 8
+W_ULongDtype.aliases = ["L"]
+
+W_Float32Dtype = create_low_level_dtype(
+ num = 11, kind = FLOATINGLTR, name = "float32",
+ aliases = ["f", "float32", "f4"],
+ applevel_types = [],
+ T = lltype.SingleFloat,
+ valtype = rarithmetic.r_singlefloat,
+ expected_size = 4,
+)
+class W_Float32Dtype(FloatArithmeticDtype, W_Float32Dtype):
pass
W_Float64Dtype = create_low_level_dtype(
num = 12, kind = FLOATINGLTR, name = "float64",
- aliases = [],
+ aliases = ["d", "float64", "f8"],
applevel_types = ["float"],
T = lltype.Float,
valtype = float,
expected_size = 8,
)
class W_Float64Dtype(FloatArithmeticDtype, W_Float64Dtype):
- def unwrap(self, space, w_item):
- return self.adapt_val(space.float_w(space.float(w_item)))
-
- def str_format(self, item):
- return float2string(self.unbox(item), 'g', rfloat.DTSF_STR_PRECISION)
+ pass
ALL_DTYPES = [
W_BoolDtype,
- W_Int8Dtype, W_Int16Dtype, W_Int32Dtype, W_Int64Dtype,
- W_Float64Dtype
+ W_Int8Dtype, W_UInt8Dtype, W_Int16Dtype, W_UInt16Dtype,
+ W_Int32Dtype, W_UInt32Dtype, W_LongDtype, W_ULongDtype,
+ W_Int64Dtype, W_UInt64Dtype,
+ W_Float32Dtype, W_Float64Dtype,
]
dtypes_by_alias = unrolling_iterable([
@@ -398,6 +491,7 @@
num = interp_attrproperty("num", cls=W_Dtype),
kind = interp_attrproperty("kind", cls=W_Dtype),
+ itemsize = interp_attrproperty("num_bytes", cls=W_Dtype),
shape = GetSetProperty(W_Dtype.descr_get_shape),
)
W_Dtype.typedef.acceptable_as_base_class = False
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
@@ -4,6 +4,7 @@
from pypy.interpreter.typedef import TypeDef, GetSetProperty, interp_attrproperty
from pypy.module.micronumpy import interp_dtype, signature
from pypy.rlib import jit
+from pypy.rlib.rarithmetic import LONG_BIT
from pypy.tool.sourcetools import func_with_new_name
@@ -180,23 +181,56 @@
# Everything promotes to float, and bool promotes to everything.
if dt2.kind == interp_dtype.FLOATINGLTR or dt1.kind == interp_dtype.BOOLLTR:
+ # Float32 + 8-bit int = Float64
+ if dt2.num == 11 and dt1.num_bytes >= 4:
+ return space.fromcache(interp_dtype.W_Float64Dtype)
return dt2
- assert False
+ # for now this means mixing signed and unsigned
+ if dt2.kind == interp_dtype.SIGNEDLTR:
+ # if dt2 has a greater number of bytes, then just go with it
+ if dt1.num_bytes < dt2.num_bytes:
+ return dt2
+ # we need to promote both dtypes
+ dtypenum = dt2.num + 2
+ else:
+ # increase to the next signed type (or to float)
+ dtypenum = dt2.num + 1
+ # UInt64 + signed = Float64
+ if dt2.num == 10:
+ dtypenum += 1
+ newdtype = interp_dtype.ALL_DTYPES[dtypenum]
+
+ if newdtype.num_bytes > dt2.num_bytes or newdtype.kind == interp_dtype.FLOATINGLTR:
+ return space.fromcache(newdtype)
+ else:
+ # we only promoted to long on 32-bit or to longlong on 64-bit
+ # this is really for dealing with the Long and Ulong dtypes
+ if LONG_BIT == 32:
+ dtypenum += 2
+ else:
+ dtypenum += 3
+ return space.fromcache(interp_dtype.ALL_DTYPES[dtypenum])
def find_unaryop_result_dtype(space, dt, promote_to_float=False,
promote_bools=False, promote_to_largest=False):
if promote_bools and (dt.kind == interp_dtype.BOOLLTR):
return space.fromcache(interp_dtype.W_Int8Dtype)
if promote_to_float:
+ if dt.kind == interp_dtype.FLOATINGLTR:
+ return dt
+ if dt.num >= 5:
+ return space.fromcache(interp_dtype.W_Float64Dtype)
for bytes, dtype in interp_dtype.dtypes_by_num_bytes:
- if dtype.kind == interp_dtype.FLOATINGLTR and dtype.num_bytes >= dt.num_bytes:
+ if dtype.kind == interp_dtype.FLOATINGLTR and dtype.num_bytes > dt.num_bytes:
return space.fromcache(dtype)
if promote_to_largest:
if dt.kind == interp_dtype.BOOLLTR or dt.kind == interp_dtype.SIGNEDLTR:
return space.fromcache(interp_dtype.W_Int64Dtype)
elif dt.kind == interp_dtype.FLOATINGLTR:
return space.fromcache(interp_dtype.W_Float64Dtype)
+ elif dt.kind == interp_dtype.UNSIGNEDLTR:
+ return space.fromcache(interp_dtype.W_UInt64Dtype)
else:
assert False
return dt
@@ -205,15 +239,23 @@
w_type = space.type(w_obj)
bool_dtype = space.fromcache(interp_dtype.W_BoolDtype)
+ long_dtype = space.fromcache(interp_dtype.W_LongDtype)
int64_dtype = space.fromcache(interp_dtype.W_Int64Dtype)
if space.is_w(w_type, space.w_bool):
- if current_guess is None:
+ if current_guess is None or current_guess is bool_dtype:
return bool_dtype
+ return current_guess
elif space.is_w(w_type, space.w_int):
if (current_guess is None or current_guess is bool_dtype or
- current_guess is int64_dtype):
+ current_guess is long_dtype):
+ return long_dtype
+ return current_guess
+ elif space.is_w(w_type, space.w_long):
+ if (current_guess is None or current_guess is bool_dtype or
+ current_guess is long_dtype or current_guess is int64_dtype):
return int64_dtype
+ return current_guess
return space.fromcache(interp_dtype.W_Float64Dtype)
@@ -225,7 +267,9 @@
def impl(res_dtype, lvalue, rvalue):
res = getattr(res_dtype, op_name)(lvalue, rvalue)
if comparison_func:
- res = space.fromcache(interp_dtype.W_BoolDtype).box(res)
+ booldtype = space.fromcache(interp_dtype.W_BoolDtype)
+ assert isinstance(booldtype, interp_dtype.W_BoolDtype)
+ res = booldtype.box(res)
return res
return func_with_new_name(impl, ufunc_name)
@@ -278,7 +322,7 @@
identity = extra_kwargs.get("identity")
if identity is not None:
- identity = space.fromcache(interp_dtype.W_Int64Dtype).adapt_val(identity)
+ identity = space.fromcache(interp_dtype.W_LongDtype).adapt_val(identity)
extra_kwargs["identity"] = identity
func = ufunc_dtype_caller(space, ufunc_name, op_name, argcount,
@@ -291,4 +335,4 @@
setattr(self, ufunc_name, ufunc)
def get(space):
- return space.fromcache(UfuncState)
\ No newline at end of file
+ return space.fromcache(UfuncState)
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
@@ -64,18 +64,46 @@
def test_unaryops(self, space):
bool_dtype = space.fromcache(interp_dtype.W_BoolDtype)
int8_dtype = space.fromcache(interp_dtype.W_Int8Dtype)
+ uint8_dtype = space.fromcache(interp_dtype.W_UInt8Dtype)
+ int16_dtype = space.fromcache(interp_dtype.W_Int16Dtype)
+ uint16_dtype = space.fromcache(interp_dtype.W_UInt16Dtype)
int32_dtype = space.fromcache(interp_dtype.W_Int32Dtype)
+ uint32_dtype = space.fromcache(interp_dtype.W_UInt32Dtype)
+ long_dtype = space.fromcache(interp_dtype.W_LongDtype)
+ ulong_dtype = space.fromcache(interp_dtype.W_ULongDtype)
+ int64_dtype = space.fromcache(interp_dtype.W_Int64Dtype)
+ uint64_dtype = space.fromcache(interp_dtype.W_UInt64Dtype)
+ float32_dtype = space.fromcache(interp_dtype.W_Float32Dtype)
float64_dtype = space.fromcache(interp_dtype.W_Float64Dtype)
- # Normal rules, everythign returns itself
+ # Normal rules, everything returns itself
assert find_unaryop_result_dtype(space, bool_dtype) is bool_dtype
assert find_unaryop_result_dtype(space, int8_dtype) is int8_dtype
+ assert find_unaryop_result_dtype(space, uint8_dtype) is uint8_dtype
+ assert find_unaryop_result_dtype(space, int16_dtype) is int16_dtype
+ assert find_unaryop_result_dtype(space, uint16_dtype) is uint16_dtype
assert find_unaryop_result_dtype(space, int32_dtype) is int32_dtype
+ assert find_unaryop_result_dtype(space, uint32_dtype) is uint32_dtype
+ assert find_unaryop_result_dtype(space, long_dtype) is long_dtype
+ assert find_unaryop_result_dtype(space, ulong_dtype) is ulong_dtype
+ assert find_unaryop_result_dtype(space, int64_dtype) is int64_dtype
+ assert find_unaryop_result_dtype(space, uint64_dtype) is uint64_dtype
+ assert find_unaryop_result_dtype(space, float32_dtype) is float32_dtype
assert find_unaryop_result_dtype(space, float64_dtype) is float64_dtype
# 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 float64_dtype
- assert find_unaryop_result_dtype(space, int8_dtype, promote_to_float=True) is float64_dtype
+ 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, 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
- assert find_unaryop_result_dtype(space, float64_dtype, promote_to_float=True) is float64_dtype
\ No newline at end of file
+ assert find_unaryop_result_dtype(space, uint32_dtype, promote_to_float=True) is float64_dtype
+ assert find_unaryop_result_dtype(space, int64_dtype, promote_to_float=True) is float64_dtype
+ assert find_unaryop_result_dtype(space, uint64_dtype, promote_to_float=True) is float64_dtype
+ assert find_unaryop_result_dtype(space, float32_dtype, promote_to_float=True) is float32_dtype
+ assert find_unaryop_result_dtype(space, float64_dtype, promote_to_float=True) is float64_dtype
+
+ # promote bools, happens with sign ufunc
+ assert find_unaryop_result_dtype(space, bool_dtype, promote_bools=True) is int8_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
@@ -17,6 +17,7 @@
from numpy import dtype
assert dtype(bool).num == 0
+ assert dtype(int).num == 7
assert dtype(long).num == 9
assert dtype(float).num == 12
@@ -81,6 +82,48 @@
assert isinstance(a[i], (int, long))
assert a[1] == 1
+ def test_overflow(self):
+ from numpy import array, dtype
+ assert array([128], 'b')[0] == -128
+ assert array([256], 'B')[0] == 0
+ assert array([32768], 'h')[0] == -32768
+ assert array([65536], 'H')[0] == 0
+ if dtype('l').itemsize == 4: # 32-bit
+ raises(OverflowError, "array([2**32/2], 'i')")
+ raises(OverflowError, "array([2**32], 'I')")
+ raises(OverflowError, "array([2**64/2], 'q')")
+ raises(OverflowError, "array([2**64], 'Q')")
+
+ def test_bool_binop_types(self):
+ from numpy import array, dtype
+ types = ('?','b','B','h','H','i','I','l','L','q','Q','f','d')
+ N = len(types)
+ a = array([True], '?')
+ for t in types:
+ assert (a + array([0], t)).dtype is dtype(t)
+
+ def test_binop_types(self):
+ from numpy import array, dtype
+ tests = [('b','B','h'), ('b','h','h'), ('b','H','i'), ('b','i','i'),
+ ('b','l','l'), ('b','q','q'), ('b','Q','d'), ('B','h','h'),
+ ('B','H','H'), ('B','i','i'), ('B','I','I'), ('B','l','l'),
+ ('B','L','L'), ('B','q','q'), ('B','Q','Q'), ('h','H','i'),
+ ('h','i','i'), ('h','l','l'), ('h','q','q'), ('h','Q','d'),
+ ('H','i','i'), ('H','I','I'), ('H','l','l'), ('H','L','L'),
+ ('H','q','q'), ('H','Q','Q'), ('i','l','l'), ('i','q','q'),
+ ('i','Q','d'), ('I','L','L'), ('I','q','q'), ('I','Q','Q'),
+ ('q','Q','d'), ('b','f','f'), ('B','f','f'), ('h','f','f'),
+ ('H','f','f'), ('i','f','d'), ('I','f','d'), ('l','f','d'),
+ ('L','f','d'), ('q','f','d'), ('Q','f','d'), ('q','d','d')]
+ if dtype('i').itemsize == dtype('l').itemsize: # 32-bit
+ tests.extend([('b','I','q'), ('b','L','q'), ('h','I','q'),
+ ('h','L','q'), ('i','I','q'), ('i','L','q')])
+ else:
+ 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)
+
def test_add_int8(self):
from numpy import array, dtype
@@ -99,6 +142,15 @@
for i in range(5):
assert b[i] == i * 2
+ def test_add_uint32(self):
+ from numpy import array, dtype
+
+ a = array(range(5), dtype="I")
+ b = a + a
+ assert b.dtype is dtype("I")
+ for i in range(5):
+ assert b[i] == i * 2
+
def test_shape(self):
from numpy import dtype
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
@@ -551,8 +551,10 @@
from numpy import array, dtype
assert array([True]).dtype is dtype(bool)
- assert array([True, 1]).dtype is dtype(long)
- assert array([1, 2, 3]).dtype is dtype(long)
+ assert array([True, False]).dtype is dtype(bool)
+ assert array([True, 1]).dtype is dtype(int)
+ assert array([1, 2, 3]).dtype is dtype(int)
+ assert array([1L, 2, 3]).dtype is dtype(long)
assert array([1.2, True]).dtype is dtype(float)
assert array([1.2, 5]).dtype is dtype(float)
assert array([]).dtype is dtype(float)
diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py
--- a/pypy/module/micronumpy/test/test_ufuncs.py
+++ b/pypy/module/micronumpy/test/test_ufuncs.py
@@ -234,7 +234,7 @@
assert b[i] == math.sin(a[i])
a = sin(array([True, False], dtype=bool))
- assert a[0] == sin(1)
+ assert abs(a[0] - sin(1)) < 1e-7 # a[0] will be less precise
assert a[1] == 0.0
def test_cos(self):
diff --git a/pypy/module/micronumpy/test/test_zjit.py b/pypy/module/micronumpy/test/test_zjit.py
--- a/pypy/module/micronumpy/test/test_zjit.py
+++ b/pypy/module/micronumpy/test/test_zjit.py
@@ -1,20 +1,24 @@
from pypy.jit.metainterp.test.support import LLJitMixin
from pypy.module.micronumpy import interp_ufuncs, signature
from pypy.module.micronumpy.compile import (numpy_compile, FakeSpace,
- FloatObject)
-from pypy.module.micronumpy.interp_dtype import W_Float64Dtype, W_Int64Dtype
+ FloatObject, IntObject)
+from pypy.module.micronumpy.interp_dtype import W_Int32Dtype, W_Float64Dtype, W_Int64Dtype, W_UInt64Dtype
from pypy.module.micronumpy.interp_numarray import (BaseArray, SingleDimArray,
SingleDimSlice, scalar_w)
from pypy.rlib.nonconst import NonConstant
from pypy.rpython.annlowlevel import llstr
from pypy.rpython.test.test_llinterp import interpret
+import py
+
class TestNumpyJIt(LLJitMixin):
def setup_class(cls):
cls.space = FakeSpace()
cls.float64_dtype = cls.space.fromcache(W_Float64Dtype)
cls.int64_dtype = cls.space.fromcache(W_Int64Dtype)
+ cls.uint64_dtype = cls.space.fromcache(W_UInt64Dtype)
+ cls.int32_dtype = cls.space.fromcache(W_Int32Dtype)
def test_add(self):
def f(i):
@@ -303,6 +307,31 @@
'int_lt': 1, 'guard_true': 1, 'jump': 1})
assert result == 11.0
+ def test_int32_sum(self):
+ py.test.skip("pypy/jit/backend/llimpl.py needs to be changed to "
+ "deal correctly with int dtypes for this test to "
+ "work. skip for now until someone feels up to the task")
+ space = self.space
+ float64_dtype = self.float64_dtype
+ int32_dtype = self.int32_dtype
+
+ def f(n):
+ if NonConstant(False):
+ dtype = float64_dtype
+ else:
+ dtype = int32_dtype
+ ar = SingleDimArray(n, dtype=dtype)
+ i = 0
+ while i < n:
+ ar.get_concrete().setitem(i, int32_dtype.box(7))
+ i += 1
+ v = ar.descr_add(space, ar).descr_sum(space)
+ assert isinstance(v, IntObject)
+ return v.intval
+
+ result = self.meta_interp(f, [5], listops=True, backendopt=True)
+ assert result == f(5)
+
class TestTranslation(object):
def test_compile(self):
x = numpy_compile('aa+f*f/a-', 10)
diff --git a/pypy/rpython/lltypesystem/opimpl.py b/pypy/rpython/lltypesystem/opimpl.py
--- a/pypy/rpython/lltypesystem/opimpl.py
+++ b/pypy/rpython/lltypesystem/opimpl.py
@@ -357,7 +357,7 @@
def op_cast_float_to_uint(f):
assert type(f) is float
- return r_uint(int(f))
+ return r_uint(long(f))
def op_cast_float_to_longlong(f):
assert type(f) is float
@@ -369,7 +369,7 @@
def op_cast_float_to_ulonglong(f):
assert type(f) is float
- return r_ulonglong(r_longlong(f))
+ return r_ulonglong(long(f))
def op_cast_char_to_int(b):
assert type(b) is str and len(b) == 1
diff --git a/pypy/rpython/lltypesystem/test/test_lloperation.py b/pypy/rpython/lltypesystem/test/test_lloperation.py
--- a/pypy/rpython/lltypesystem/test/test_lloperation.py
+++ b/pypy/rpython/lltypesystem/test/test_lloperation.py
@@ -5,6 +5,7 @@
from pypy.rpython.llinterp import LLFrame
from pypy.rpython.test.test_llinterp import interpret
from pypy.rpython import rclass
+from pypy.rlib.rarithmetic import LONGLONG_MASK, r_longlong, r_ulonglong
LL_INTERP_OPERATIONS = [name[3:] for name in LLFrame.__dict__.keys()
if name.startswith('op_')]
@@ -133,6 +134,14 @@
py.test.raises(TypeError, llop.getinteriorfield,
lltype.Signed, s3, 'y')
+def test_cast_float_to_ulonglong():
+ f = 12350000000000000000.0
+ py.test.raises(OverflowError, r_longlong, f)
+ r_longlong(f / 2) # does not raise OverflowError
+ #
+ x = llop.cast_float_to_ulonglong(lltype.UnsignedLongLong, f)
+ assert x == r_ulonglong(f)
+
# ___________________________________________________________________________
# This tests that the LLInterpreter and the LL_OPERATIONS tables are in sync.
More information about the pypy-commit
mailing list