[pypy-commit] pypy numpy-single-jitdriver: some fixes
fijal
noreply at buildbot.pypy.org
Fri Feb 3 11:03:30 CET 2012
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: numpy-single-jitdriver
Changeset: r52050:16f093b4c8be
Date: 2012-02-03 12:03 +0200
http://bitbucket.org/pypy/pypy/changeset/16f093b4c8be/
Log: some fixes
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
@@ -3,7 +3,7 @@
from pypy.interpreter.gateway import interp2app, unwrap_spec
from pypy.interpreter.typedef import TypeDef, GetSetProperty
from pypy.module.micronumpy import (interp_ufuncs, interp_dtype, interp_boxes,
- signature, support)
+ signature, support, loop)
from pypy.module.micronumpy.strides import (calculate_slice_strides,
shape_agreement, find_shape_and_elems, get_shape_from_iterable,
calc_new_strides, to_coords)
@@ -17,20 +17,6 @@
from pypy.module.micronumpy.appbridge import get_appbridge_cache
-all_driver = jit.JitDriver(
- greens=['shapelen', 'sig'],
- virtualizables=['frame'],
- reds=['frame', 'self', 'dtype'],
- get_printable_location=signature.new_printable_location('all'),
- name='numpy_all',
-)
-any_driver = jit.JitDriver(
- greens=['shapelen', 'sig'],
- virtualizables=['frame'],
- reds=['frame', 'self', 'dtype'],
- get_printable_location=signature.new_printable_location('any'),
- name='numpy_any',
-)
slice_driver = jit.JitDriver(
greens=['shapelen', 'sig'],
virtualizables=['frame'],
@@ -166,6 +152,8 @@
descr_prod = _reduce_ufunc_impl("multiply", True)
descr_max = _reduce_ufunc_impl("maximum")
descr_min = _reduce_ufunc_impl("minimum")
+ descr_all = _reduce_ufunc_impl('logical_and')
+ descr_any = _reduce_ufunc_impl('logical_or')
def _reduce_argmax_argmin_impl(op_name):
reduce_driver = jit.JitDriver(
@@ -205,40 +193,6 @@
return space.wrap(loop(self))
return func_with_new_name(impl, "reduce_arg%s_impl" % op_name)
- def _all(self):
- dtype = self.find_dtype()
- sig = self.find_sig()
- frame = sig.create_frame(self)
- shapelen = len(self.shape)
- while not frame.done():
- all_driver.jit_merge_point(sig=sig,
- shapelen=shapelen, self=self,
- dtype=dtype, frame=frame)
- if not dtype.itemtype.bool(sig.eval(frame, self)):
- return False
- frame.next(shapelen)
- return True
-
- def descr_all(self, space):
- return space.wrap(self._all())
-
- def _any(self):
- dtype = self.find_dtype()
- sig = self.find_sig()
- frame = sig.create_frame(self)
- shapelen = len(self.shape)
- while not frame.done():
- any_driver.jit_merge_point(sig=sig, frame=frame,
- shapelen=shapelen, self=self,
- dtype=dtype)
- if dtype.itemtype.bool(sig.eval(frame, self)):
- return True
- frame.next(shapelen)
- return False
-
- def descr_any(self, space):
- return space.wrap(self._any())
-
descr_argmax = _reduce_argmax_argmin_impl("max")
descr_argmin = _reduce_argmax_argmin_impl("min")
@@ -746,7 +700,6 @@
raise NotImplementedError
def compute(self):
- from pypy.module.micronumpy import loop
ra = ResultArray(self, self.size, self.shape, self.res_dtype)
loop.compute(ra)
return ra.left
@@ -859,6 +812,12 @@
return signature.ResultSignature(self.res_dtype, self.left.create_sig(),
self.right.create_sig())
+def done_if_true(dtype, val):
+ return dtype.itemtype.bool(val)
+
+def done_if_false(dtype, val):
+ return not dtype.itemtype.bool(val)
+
class ReduceArray(Call2):
def __init__(self, func, name, identity, child, dtype):
self.identity = identity
@@ -874,9 +833,15 @@
frame.cur_value = self.identity.convert_to(self.calc_dtype)
def create_sig(self):
+ if self.name == 'logical_and':
+ done_func = done_if_false
+ elif self.name == 'logical_or':
+ done_func = done_if_true
+ else:
+ done_func = None
return signature.ReduceSignature(self.ufunc, self.name, self.res_dtype,
signature.ScalarSignature(self.res_dtype),
- self.right.create_sig())
+ self.right.create_sig(), done_func)
class AxisReduce(Call2):
_immutable_fields_ = ['left', 'right']
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
@@ -2,7 +2,7 @@
from pypy.interpreter.error import OperationError, operationerrfmt
from pypy.interpreter.gateway import interp2app, unwrap_spec, NoneNotWrapped
from pypy.interpreter.typedef import TypeDef, GetSetProperty, interp_attrproperty
-from pypy.module.micronumpy import interp_boxes, interp_dtype, support
+from pypy.module.micronumpy import interp_boxes, interp_dtype, support, loop
from pypy.rlib.rarithmetic import LONG_BIT
from pypy.tool.sourcetools import func_with_new_name
@@ -120,8 +120,6 @@
keepdims=False):
from pypy.module.micronumpy.interp_numarray import convert_to_array, \
Scalar, ReduceArray
- from pypy.module.micronumpy import loop
-
if self.argcount != 2:
raise OperationError(space.w_ValueError, space.wrap("reduce only "
"supported for binary functions"))
@@ -132,14 +130,16 @@
if isinstance(obj, Scalar):
raise OperationError(space.w_TypeError, space.wrap("cannot reduce "
"on a scalar"))
-
size = obj.size
- dtype = find_unaryop_result_dtype(
- space, obj.find_dtype(),
- promote_to_float=self.promote_to_float,
- promote_to_largest=promote_to_largest,
- promote_bools=True
- )
+ if self.comparison_func:
+ dtype = interp_dtype.get_dtype_cache(space).w_booldtype
+ else:
+ dtype = find_unaryop_result_dtype(
+ space, obj.find_dtype(),
+ promote_to_float=self.promote_to_float,
+ promote_to_largest=promote_to_largest,
+ promote_bools=True
+ )
shapelen = len(obj.shape)
if self.identity is None and size == 0:
raise operationerrfmt(space.w_ValueError, "zero-size array to "
@@ -152,8 +152,6 @@
def do_axis_reduce(self, obj, dtype, dim, keepdims):
from pypy.module.micronumpy.interp_numarray import AxisReduce,\
W_NDimArray
- from pypy.module.micronumpy import loop
-
if keepdims:
shape = obj.shape[:dim] + [1] + obj.shape[dim + 1:]
else:
@@ -234,7 +232,6 @@
w_lhs.value.convert_to(calc_dtype),
w_rhs.value.convert_to(calc_dtype)
))
-
new_shape = shape_agreement(space, w_lhs.shape, w_rhs.shape)
w_res = Call2(self.func, self.name,
new_shape, calc_dtype,
@@ -404,8 +401,10 @@
("isnan", "isnan", 1, {"bool_result": True}),
("isinf", "isinf", 1, {"bool_result": True}),
- ('logical_and', 'logical_and', 2, {'comparison_func': True}),
- ('logical_or', 'logical_or', 2, {'comparison_func': True}),
+ ('logical_and', 'logical_and', 2, {'comparison_func': True,
+ 'identity': 1}),
+ ('logical_or', 'logical_or', 2, {'comparison_func': True,
+ 'identity': 0}),
('logical_xor', 'logical_xor', 2, {'comparison_func': True}),
('logical_not', 'logical_not', 1, {'bool_result': True}),
diff --git a/pypy/module/micronumpy/loop.py b/pypy/module/micronumpy/loop.py
--- a/pypy/module/micronumpy/loop.py
+++ b/pypy/module/micronumpy/loop.py
@@ -4,7 +4,6 @@
"""
from pypy.rlib.jit import JitDriver, hint, unroll_safe, promote
-from pypy.module.micronumpy import signature
from pypy.module.micronumpy.interp_iter import ConstantIterator
class NumpyEvalFrame(object):
@@ -60,18 +59,25 @@
greens=['shapelen', 'sig'],
virtualizables=['frame'],
reds=['frame', 'arr'],
- get_printable_location=signature.new_printable_location('numpy'),
+ get_printable_location=get_printable_location,
name='numpy',
)
+class ComputationDone(Exception):
+ def __init__(self, value):
+ self.value = value
+
def compute(arr):
sig = arr.find_sig()
shapelen = len(arr.shape)
frame = sig.create_frame(arr)
- while not frame.done():
- numpy_driver.jit_merge_point(sig=sig,
- shapelen=shapelen,
- frame=frame, arr=arr)
- sig.eval(frame, arr)
- frame.next(shapelen)
- return frame.cur_value
+ try:
+ while not frame.done():
+ numpy_driver.jit_merge_point(sig=sig,
+ shapelen=shapelen,
+ frame=frame, arr=arr)
+ sig.eval(frame, arr)
+ frame.next(shapelen)
+ return frame.cur_value
+ except ComputationDone, e:
+ return e.value
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
@@ -3,6 +3,7 @@
from pypy.module.micronumpy.interp_iter import ConstantIterator, AxisIterator,\
ViewTransform, BroadcastTransform
from pypy.tool.pairtype import extendabletype
+from pypy.module.micronumpy.loop import ComputationDone
""" Signature specifies both the numpy expression that has been constructed
and the assembler to be compiled. This is a very important observation -
@@ -358,10 +359,20 @@
self.right._create_iter(iterlist, arraylist, arr.right, rtransforms)
class ReduceSignature(Call2):
+ _immutable_fields_ = ['binfunc', 'name', 'calc_dtype',
+ 'left', 'right', 'done_func']
+
+ def __init__(self, func, name, calc_dtype, left, right,
+ done_func):
+ Call2.__init__(self, func, name, calc_dtype, left, right)
+ self.done_func = done_func
+
def eval(self, frame, arr):
from pypy.module.micronumpy.interp_numarray import ReduceArray
assert isinstance(arr, ReduceArray)
rval = self.right.eval(frame, arr.right).convert_to(self.calc_dtype)
+ if self.done_func is not None and self.done_func(self.calc_dtype, rval):
+ raise ComputationDone(rval)
frame.cur_value = self.binfunc(self.calc_dtype, frame.cur_value, rval)
def debug_repr(self):
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
@@ -347,8 +347,9 @@
raises((ValueError, TypeError), add.reduce, 1)
def test_reduce_1d(self):
- from _numpypy import add, maximum
+ from _numpypy import add, maximum, less
+ assert less.reduce([5, 4, 3, 2, 1])
assert add.reduce([1, 2, 3]) == 6
assert maximum.reduce([1]) == 1
assert maximum.reduce([1, 2, 3]) == 3
More information about the pypy-commit
mailing list