[pypy-commit] pypy numpypy-remove-scalar: Remove scalar. It needs some new support in signatures though.
alex_gaynor
noreply at buildbot.pypy.org
Wed Jan 18 23:43:35 CET 2012
Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: numpypy-remove-scalar
Changeset: r51465:6cb068520d24
Date: 2012-01-18 16:40 -0600
http://bitbucket.org/pypy/pypy/changeset/6cb068520d24/
Log: Remove scalar. It needs some new support in signatures though.
diff --git a/pypy/module/micronumpy/compile.py b/pypy/module/micronumpy/compile.py
--- a/pypy/module/micronumpy/compile.py
+++ b/pypy/module/micronumpy/compile.py
@@ -6,11 +6,10 @@
import re
from pypy.interpreter.baseobjspace import InternalSpaceCache, W_Root
-from pypy.module.micronumpy import interp_boxes
+from pypy.module.micronumpy import interp_boxes, interp_ufuncs
from pypy.module.micronumpy.interp_dtype import get_dtype_cache
-from pypy.module.micronumpy.interp_numarray import (Scalar, BaseArray,
- scalar_w, W_NDimArray, array)
-from pypy.module.micronumpy import interp_ufuncs
+from pypy.module.micronumpy.interp_numarray import (BaseArray, W_NDimArray,
+ convert_to_array, array)
from pypy.rlib.objectmodel import specialize, instantiate
@@ -54,10 +53,10 @@
self.fromcache = InternalSpaceCache(self).getorbuild
def issequence_w(self, w_obj):
- return isinstance(w_obj, ListObject) or isinstance(w_obj, W_NDimArray)
+ return isinstance(w_obj, ListObject) or isinstance(w_obj, BaseArray)
def isinstance_w(self, w_obj, w_tp):
- return w_obj.tp == w_tp
+ return not isinstance(w_obj, BaseArray) and w_obj.tp == w_tp
def decode_index4(self, w_idx, size):
if isinstance(w_idx, IntObject):
@@ -260,8 +259,7 @@
w_rhs = self.rhs.execute(interp)
if not isinstance(w_lhs, BaseArray):
# scalar
- dtype = get_dtype_cache(interp.space).w_float64dtype
- w_lhs = scalar_w(interp.space, dtype, w_lhs)
+ w_lhs = convert_to_array(interp.space, w_lhs)
assert isinstance(w_lhs, BaseArray)
if self.name == '+':
w_res = w_lhs.descr_add(interp.space, w_rhs)
@@ -270,7 +268,6 @@
elif self.name == '-':
w_res = w_lhs.descr_sub(interp.space, w_rhs)
elif self.name == '->':
- assert not isinstance(w_rhs, Scalar)
if isinstance(w_rhs, FloatObject):
w_rhs = IntObject(int(w_rhs.floatval))
assert isinstance(w_lhs, BaseArray)
@@ -280,7 +277,7 @@
if (not isinstance(w_res, BaseArray) and
not isinstance(w_res, interp_boxes.W_GenericBox)):
dtype = get_dtype_cache(interp.space).w_float64dtype
- w_res = scalar_w(interp.space, dtype, w_res)
+ w_res = convert_to_array(interp.space, w_res, dtype=dtype)
return w_res
def __repr__(self):
@@ -398,17 +395,7 @@
w_res = neg.call(interp.space, [arr])
else:
assert False # unreachable code
- if isinstance(w_res, BaseArray):
- return w_res
- if isinstance(w_res, FloatObject):
- dtype = get_dtype_cache(interp.space).w_float64dtype
- elif isinstance(w_res, BoolObject):
- dtype = get_dtype_cache(interp.space).w_booldtype
- elif isinstance(w_res, interp_boxes.W_GenericBox):
- dtype = w_res.get_dtype(interp.space)
- else:
- dtype = None
- return scalar_w(interp.space, dtype, w_res)
+ return w_res
else:
raise WrongFunctionName
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
@@ -1,15 +1,16 @@
from pypy.interpreter.baseobjspace import Wrappable
from pypy.interpreter.error import OperationError, operationerrfmt
-from pypy.interpreter.gateway import interp2app, NoneNotWrapped
+from pypy.interpreter.gateway import interp2app, NoneNotWrapped, unwrap_spec
from pypy.interpreter.typedef import TypeDef, GetSetProperty
from pypy.module.micronumpy import interp_ufuncs, interp_dtype, signature
+from pypy.module.micronumpy.interp_iter import (ArrayIterator, OneDimIterator,
+ SkipLastAxisIterator)
from pypy.module.micronumpy.strides import calculate_slice_strides
from pypy.rlib import jit
+from pypy.rlib.rstring import StringBuilder
from pypy.rpython.lltypesystem import lltype, rffi
from pypy.tool.sourcetools import func_with_new_name
-from pypy.rlib.rstring import StringBuilder
-from pypy.module.micronumpy.interp_iter import ArrayIterator, OneDimIterator,\
- SkipLastAxisIterator
+
numpy_driver = jit.JitDriver(
greens=['shapelen', 'sig'],
@@ -272,10 +273,7 @@
def _binop_right_impl(ufunc_name):
def impl(self, space, w_other):
- w_other = scalar_w(space,
- interp_ufuncs.find_dtype_for_scalar(space, w_other, self.find_dtype()),
- w_other
- )
+ w_other = convert_to_array(space, w_other, dtype=self.find_dtype())
return getattr(interp_ufuncs.get(space), ufunc_name).call(space, [w_other, self])
return func_with_new_name(impl, "binop_right_%s_impl" % ufunc_name)
@@ -375,8 +373,7 @@
descr_argmin = _reduce_argmax_argmin_impl("min")
def descr_dot(self, space, w_other):
- w_other = convert_to_array(space, w_other)
- if isinstance(w_other, Scalar):
+ if is_scalar(space, w_other):
return self.descr_mul(space, w_other)
else:
w_res = self.descr_mul(space, w_other)
@@ -399,8 +396,6 @@
def descr_set_shape(self, space, w_iterable):
new_shape = get_shape_from_iterable(space,
self.size, w_iterable)
- if isinstance(self, Scalar):
- return
self.get_concrete().setshape(space, new_shape)
def descr_get_size(self, space):
@@ -560,8 +555,7 @@
def descr_tolist(self, space):
if len(self.shape) == 0:
- assert isinstance(self, Scalar)
- return self.value.descr_tolist(space)
+ return self.getitem(0).descr_tolist(space)
w_result = space.newlist([])
for i in range(self.shape[0]):
space.call_method(w_result, "append",
@@ -650,50 +644,23 @@
def supports_fast_slicing(self):
return False
-def convert_to_array(space, w_obj):
+def convert_to_array(space, w_obj, dtype=None):
if isinstance(w_obj, BaseArray):
+ assert dtype is None
return w_obj
elif space.issequence_w(w_obj):
# Convert to array.
- return array(space, w_obj, w_order=None)
+ return array(space, w_obj, w_order=None, w_dtype=dtype)
else:
# If it's a scalar
- dtype = interp_ufuncs.find_dtype_for_scalar(space, w_obj)
- return scalar_w(space, dtype, w_obj)
+ if dtype is None:
+ dtype = interp_ufuncs.find_dtype_for_scalar(space, w_obj)
+ arr = W_NDimArray(1, [], dtype)
+ arr.setitem(0, dtype.coerce(space, w_obj))
+ return arr
-def scalar_w(space, dtype, w_obj):
- return Scalar(dtype, dtype.coerce(space, w_obj))
-
-class Scalar(BaseArray):
- """
- Intermediate class representing a literal.
- """
- size = 1
- _attrs_ = ["dtype", "value", "shape"]
-
- def __init__(self, dtype, value):
- self.shape = []
- BaseArray.__init__(self, [])
- self.dtype = dtype
- self.value = value
-
- def find_dtype(self):
- return self.dtype
-
- def to_str(self, space, comma, builder, indent=' ', use_ellipsis=False):
- builder.append(self.dtype.itemtype.str_format(self.value))
-
- def copy(self, space):
- return Scalar(self.dtype, self.value)
-
- def fill(self, space, w_value):
- self.value = self.dtype.coerce(space, w_value)
-
- def create_sig(self):
- return signature.ScalarSignature(self.dtype)
-
- def get_concrete_or_scalar(self):
- return self
+def is_scalar(space, w_obj):
+ return not isinstance(w_obj, BaseArray) and not space.issequence_w(w_obj)
class VirtualArray(BaseArray):
@@ -884,7 +851,7 @@
return self
def supports_fast_slicing(self):
- return self.order == 'C' and self.strides[-1] == 1
+ return self.order == 'C' and bool(self.strides) and self.strides[-1] == 1
def find_dtype(self):
return self.dtype
@@ -1069,7 +1036,7 @@
return array
def fill(self, space, w_value):
- self.setslice(space, scalar_w(space, self.dtype, w_value))
+ self.setslice(space, convert_to_array(space, w_value))
class ViewArray(ConcreteArray):
@@ -1129,9 +1096,9 @@
""" A class representing contiguous array. We know that each iteration
by say ufunc will increase the data index by one
"""
- def setitem(self, item, value):
+ def setitem(self, idx, value):
self.invalidated()
- self.dtype.setitem(self.storage, item, value)
+ self.dtype.setitem(self.storage, idx, value)
def setshape(self, space, new_shape):
self.shape = new_shape
@@ -1165,7 +1132,7 @@
dtype = space.interp_w(interp_dtype.W_Dtype,
space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype)
)
- return scalar_w(space, dtype, w_item_or_iterable)
+ return convert_to_array(space, w_item_or_iterable, dtype=dtype)
if w_order is None:
order = 'C'
else:
@@ -1217,9 +1184,9 @@
return space.wrap(arr)
def dot(space, w_obj, w_obj2):
+ if is_scalar(space, w_obj):
+ return convert_to_array(space, w_obj2).descr_dot(space, w_obj)
w_arr = convert_to_array(space, w_obj)
- if isinstance(w_arr, Scalar):
- return convert_to_array(space, w_obj2).descr_dot(space, w_arr)
return w_arr.descr_dot(space, w_obj2)
BaseArray.typedef = TypeDef(
@@ -1307,6 +1274,9 @@
self.iter = OneDimIterator(arr.start, self.strides[0],
self.shape[0])
+ def descr_iter(self):
+ return self
+
def descr_next(self, space):
if self.iter.done():
raise OperationError(space.w_StopIteration, space.w_None)
@@ -1314,12 +1284,10 @@
self.iter = self.iter.next(self.shapelen)
return result
- def descr_iter(self):
- return self
W_FlatIterator.typedef = TypeDef(
'flatiter',
+ __iter__ = interp2app(W_FlatIterator.descr_iter),
next = interp2app(W_FlatIterator.descr_next),
- __iter__ = interp2app(W_FlatIterator.descr_iter),
)
W_FlatIterator.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
@@ -3,12 +3,13 @@
from pypy.interpreter.gateway import interp2app
from pypy.interpreter.typedef import TypeDef, GetSetProperty, interp_attrproperty
from pypy.module.micronumpy import interp_boxes, interp_dtype
-from pypy.module.micronumpy.signature import ReduceSignature,\
- find_sig, new_printable_location, AxisReduceSignature, ScalarSignature
+from pypy.module.micronumpy.signature import (ReduceSignature,
+ AxisReduceSignature, ScalarSignature, new_printable_location, find_sig)
from pypy.rlib import jit
from pypy.rlib.rarithmetic import LONG_BIT
from pypy.tool.sourcetools import func_with_new_name
+
reduce_driver = jit.JitDriver(
greens=['shapelen', "sig"],
virtualizables=["frame"],
@@ -114,8 +115,8 @@
return self.reduce(space, w_obj, False, False, w_dim)
def reduce(self, space, w_obj, multidim, promote_to_largest, w_dim):
- from pypy.module.micronumpy.interp_numarray import convert_to_array, \
- Scalar
+ from pypy.module.micronumpy.interp_numarray import convert_to_array
+
if self.argcount != 2:
raise OperationError(space.w_ValueError, space.wrap("reduce only "
"supported for binary functions"))
@@ -124,7 +125,7 @@
obj = convert_to_array(space, w_obj)
if dim >= len(obj.shape):
raise OperationError(space.w_ValueError, space.wrap("axis(=%d) out of bounds" % dim))
- if isinstance(obj, Scalar):
+ if not obj.shape:
raise OperationError(space.w_TypeError, space.wrap("cannot reduce "
"on a scalar"))
@@ -155,9 +156,9 @@
return self.reduce_loop(shapelen, sig, frame, value, obj, dtype)
def do_axis_reduce(self, obj, dtype, dim):
- from pypy.module.micronumpy.interp_numarray import AxisReduce,\
- W_NDimArray
-
+ from pypy.module.micronumpy.interp_numarray import (AxisReduce,
+ W_NDimArray)
+
shape = obj.shape[0:dim] + obj.shape[dim + 1:len(obj.shape)]
size = 1
for s in shape:
@@ -231,17 +232,22 @@
def call(self, space, args_w):
from pypy.module.micronumpy.interp_numarray import (Call1,
- convert_to_array, Scalar)
+ convert_to_array, is_scalar)
[w_obj] = args_w
- w_obj = convert_to_array(space, w_obj)
+ scalar = is_scalar(space, w_obj)
+ if scalar:
+ w_obj_dtype = find_dtype_for_scalar(space, w_obj)
+ else:
+ w_obj = convert_to_array(space, w_obj)
+ w_obj_dtype = w_obj.find_dtype()
res_dtype = find_unaryop_result_dtype(space,
- w_obj.find_dtype(),
+ w_obj_dtype,
promote_to_float=self.promote_to_float,
promote_bools=self.promote_bools,
)
- if isinstance(w_obj, Scalar):
- return self.func(res_dtype, w_obj.value.convert_to(res_dtype))
+ if scalar:
+ return self.func(res_dtype, res_dtype.coerce(space, w_obj))
w_res = Call1(self.func, self.name, w_obj.shape, res_dtype, w_obj)
w_obj.add_invalidates(w_res)
@@ -260,14 +266,22 @@
self.comparison_func = comparison_func
def call(self, space, args_w):
- from pypy.module.micronumpy.interp_numarray import (Call2,
- convert_to_array, Scalar, shape_agreement)
+ from pypy.module.micronumpy.interp_numarray import (BaseArray, Call2,
+ convert_to_array, is_scalar, shape_agreement)
[w_lhs, w_rhs] = args_w
- w_lhs = convert_to_array(space, w_lhs)
- w_rhs = convert_to_array(space, w_rhs)
+ scalar = is_scalar(space, w_lhs) and is_scalar(space, w_rhs)
+ if scalar:
+ w_lhs_dtype = find_dtype_for_scalar(space, w_lhs)
+ w_rhs_dtype = find_dtype_for_scalar(space, w_rhs)
+ else:
+ w_lhs = convert_to_array(space, w_lhs)
+ w_rhs = convert_to_array(space, w_rhs)
+ w_lhs_dtype = w_lhs.find_dtype()
+ w_rhs_dtype = w_rhs.find_dtype()
+
calc_dtype = find_binop_result_dtype(space,
- w_lhs.find_dtype(), w_rhs.find_dtype(),
+ w_lhs_dtype, w_rhs_dtype,
promote_to_float=self.promote_to_float,
promote_bools=self.promote_bools,
)
@@ -275,12 +289,14 @@
res_dtype = interp_dtype.get_dtype_cache(space).w_booldtype
else:
res_dtype = calc_dtype
- if isinstance(w_lhs, Scalar) and isinstance(w_rhs, Scalar):
+ if scalar:
return self.func(calc_dtype,
- w_lhs.value.convert_to(calc_dtype),
- w_rhs.value.convert_to(calc_dtype)
+ calc_dtype.coerce(space, w_lhs),
+ calc_dtype.coerce(space, w_rhs),
)
+ assert isinstance(w_lhs, BaseArray)
+ assert isinstance(w_rhs, BaseArray)
new_shape = shape_agreement(space, w_lhs.shape, w_rhs.shape)
w_res = Call2(self.func, self.name,
new_shape, calc_dtype,
diff --git a/pypy/module/micronumpy/signature.py b/pypy/module/micronumpy/signature.py
--- a/pypy/module/micronumpy/signature.py
+++ b/pypy/module/micronumpy/signature.py
@@ -195,11 +195,6 @@
iter = ConstantIterator()
iterlist.append(iter)
- def eval(self, frame, arr):
- from pypy.module.micronumpy.interp_numarray import Scalar
- assert isinstance(arr, Scalar)
- return arr.value
-
class ViewSignature(ArraySignature):
def debug_repr(self):
return 'Slice'
@@ -331,7 +326,7 @@
assert isinstance(arr, Call2)
lhs = self.left.eval(frame, arr.left).convert_to(self.calc_dtype)
rhs = self.right.eval(frame, arr.right).convert_to(self.calc_dtype)
-
+
return self.binfunc(self.calc_dtype, lhs, rhs)
def debug_repr(self):
@@ -342,7 +337,7 @@
def _invent_numbering(self, cache, allnumbers):
self.left._invent_numbering(new_cache(), allnumbers)
self.right._invent_numbering(cache, allnumbers)
-
+
def _create_iter(self, iterlist, arraylist, arr, transforms):
from pypy.module.micronumpy.interp_numarray import Call2
@@ -397,12 +392,12 @@
class SliceloopSignature(Call2):
def eval(self, frame, arr):
from pypy.module.micronumpy.interp_numarray import Call2
-
+
assert isinstance(arr, Call2)
ofs = frame.iterators[0].offset
arr.left.setitem(ofs, self.right.eval(frame, arr.right).convert_to(
self.calc_dtype))
-
+
def debug_repr(self):
return 'SliceLoop(%s, %s, %s)' % (self.name, self.left.debug_repr(),
self.right.debug_repr())
@@ -447,6 +442,6 @@
assert isinstance(arr, AxisReduce)
return self.right.eval(frame, arr.right).convert_to(self.calc_dtype)
-
+
def debug_repr(self):
return 'AxisReduceSig(%s, %s)' % (self.name, self.right.debug_repr())
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
@@ -1,6 +1,6 @@
from pypy.conftest import gettestobjspace
from pypy.module.micronumpy.interp_dtype import get_dtype_cache
-from pypy.module.micronumpy.interp_numarray import W_NDimArray, Scalar
+from pypy.module.micronumpy.interp_numarray import W_NDimArray
from pypy.module.micronumpy.interp_ufuncs import (find_binop_result_dtype,
find_unaryop_result_dtype)
@@ -16,7 +16,7 @@
ar = W_NDimArray(10, [10], dtype=float64_dtype)
ar2 = W_NDimArray(10, [10], dtype=float64_dtype)
v1 = ar.descr_add(space, ar)
- v2 = ar.descr_add(space, Scalar(float64_dtype, 2.0))
+ v2 = ar.descr_add(space, space.wrap(2.0))
sig1 = v1.find_sig()
sig2 = v2.find_sig()
assert v1 is not v2
@@ -26,7 +26,7 @@
sig1b = ar2.descr_add(space, ar).find_sig()
assert sig1b.left.array_no != sig1b.right.array_no
assert sig1b is not sig1
- v3 = ar.descr_add(space, Scalar(float64_dtype, 1.0))
+ v3 = ar.descr_add(space, space.wrap(1.0))
sig3 = v3.find_sig()
assert sig2 is sig3
v4 = ar.descr_add(space, ar)
diff --git a/pypy/module/micronumpy/test/test_compile.py b/pypy/module/micronumpy/test/test_compile.py
--- a/pypy/module/micronumpy/test/test_compile.py
+++ b/pypy/module/micronumpy/test/test_compile.py
@@ -135,7 +135,7 @@
r
"""
interp = self.run(code)
- assert interp.results[0].value.value == 15
+ assert interp.results[0].value == 15
def test_sum2(self):
code = """
@@ -144,8 +144,7 @@
sum(b)
"""
interp = self.run(code)
- assert interp.results[0].value.value == 30 * (30 - 1)
-
+ assert interp.results[0].value == 30 * (30 - 1)
def test_array_write(self):
code = """
@@ -163,7 +162,7 @@
b = a + a
min(b)
""")
- assert interp.results[0].value.value == -24
+ assert interp.results[0].value == -24
def test_max(self):
interp = self.run("""
@@ -172,7 +171,7 @@
b = a + a
max(b)
""")
- assert interp.results[0].value.value == 256
+ assert interp.results[0].value == 256
def test_slice(self):
interp = self.run("""
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
@@ -945,7 +945,7 @@
assert debug_repr(a) == 'Array'
assert debug_repr(a + a) == 'Call2(add, Array, Array)'
assert debug_repr(a[::2]) == 'Slice'
- assert debug_repr(a + 2) == 'Call2(add, Array, Scalar)'
+ assert debug_repr(a + 2) == 'Call2(add, Array, Array)'
assert debug_repr(a + a.flat) == 'Call2(add, Array, Slice)'
assert debug_repr(sin(a)) == 'Call1(sin, Array)'
More information about the pypy-commit
mailing list