[pypy-commit] pypy numpy-single-jitdriver: shuffle stuff around so reduce does not need it's own jitdriver. 16 LOC removed
fijal
noreply at buildbot.pypy.org
Thu Feb 2 17:40:45 CET 2012
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: numpy-single-jitdriver
Changeset: r52035:ef9343793d60
Date: 2012-02-02 18:40 +0200
http://bitbucket.org/pypy/pypy/changeset/ef9343793d60/
Log: shuffle stuff around so reduce does not need it's own jitdriver. 16
LOC removed WIN!
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
@@ -17,13 +17,6 @@
from pypy.module.micronumpy.appbridge import get_appbridge_cache
-numpy_driver = jit.JitDriver(
- greens=['shapelen', 'sig'],
- virtualizables=['frame'],
- reds=['result_size', 'frame', 'ri', 'self', 'result'],
- get_printable_location=signature.new_printable_location('numpy'),
- name='numpy',
-)
all_driver = jit.JitDriver(
greens=['shapelen', 'sig'],
virtualizables=['frame'],
@@ -685,6 +678,9 @@
raise OperationError(space.w_NotImplementedError, space.wrap(
"non-int arg not supported"))
+ def compute_first_step(self, sig, frame):
+ pass
+
def convert_to_array(space, w_obj):
if isinstance(w_obj, BaseArray):
return w_obj
@@ -811,7 +807,8 @@
def create_sig(self):
if self.forced_result is not None:
return self.forced_result.create_sig()
- return signature.Call1(self.ufunc, self.name, self.values.create_sig())
+ return signature.Call1(self.ufunc, self.name, self.calc_dtype,
+ self.values.create_sig())
class Call2(VirtualArray):
"""
@@ -852,10 +849,6 @@
return signature.Call2(self.ufunc, self.name, self.calc_dtype,
self.left.create_sig(), self.right.create_sig())
-class ComputationArray(BaseArray):
- """ A base class for all objects that describe operations for computation
- """
-
class ResultArray(Call2):
def __init__(self, child, size, shape, dtype, res=None, order='C'):
if res is None:
@@ -866,12 +859,25 @@
return signature.ResultSignature(self.res_dtype, self.left.create_sig(),
self.right.create_sig())
-class Reduce(ComputationArray):
- def __init__(self):
- pass
+class ReduceArray(Call2):
+ def __init__(self, func, name, identity, child, dtype):
+ self.identity = identity
+ Call2.__init__(self, func, name, [1], dtype, dtype, None, child)
+
+ def compute_first_step(self, sig, frame):
+ assert isinstance(sig, signature.ReduceSignature)
+ if self.identity is None:
+ frame.cur_value = sig.right.eval(frame, self).convert_to(
+ self.calc_dtype)
+ frame.next(len(self.right.shape))
+ else:
+ frame.cur_value = self.identity.convert_to(self.calc_dtype)
+
def create_sig(self):
- return signature.ReduceSignature(self.func)
+ return signature.ReduceSignature(self.ufunc, self.name, self.res_dtype,
+ signature.ScalarSignature(self.res_dtype),
+ self.right.create_sig())
class SliceArray(Call2):
def __init__(self, shape, dtype, left, right, no_broadcast=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,21 +3,13 @@
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.signature import (ReduceSignature, find_sig,
+from pypy.module.micronumpy.signature import (find_sig,
new_printable_location, AxisReduceSignature, ScalarSignature)
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"],
- reds=["frame", "self", "dtype", "value", "obj"],
- get_printable_location=new_printable_location('reduce'),
- name='numpy_reduce',
-)
-
axisreduce_driver = jit.JitDriver(
greens=['shapelen', 'sig'],
virtualizables=['frame'],
@@ -140,7 +132,9 @@
def reduce(self, space, w_obj, multidim, promote_to_largest, dim,
keepdims=False):
from pypy.module.micronumpy.interp_numarray import convert_to_array, \
- Scalar
+ 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"))
@@ -166,17 +160,8 @@
if shapelen > 1 and dim >= 0:
res = self.do_axis_reduce(obj, dtype, dim, keepdims)
return space.wrap(res)
- scalarsig = ScalarSignature(dtype)
- sig = find_sig(ReduceSignature(self.func, self.name, dtype,
- scalarsig,
- obj.create_sig()), obj)
- frame = sig.create_frame(obj)
- if self.identity is None:
- value = sig.eval(frame, obj).convert_to(dtype)
- frame.next(shapelen)
- else:
- value = self.identity.convert_to(dtype)
- return self.reduce_loop(shapelen, sig, frame, value, obj, dtype)
+ arr = ReduceArray(self.func, self.name, self.identity, obj, dtype)
+ return loop.compute(arr)
def do_axis_reduce(self, obj, dtype, dim, keepdims):
from pypy.module.micronumpy.interp_numarray import AxisReduce,\
@@ -229,19 +214,6 @@
arr.left.setitem(iterator.offset, value)
frame.next(shapelen)
- def reduce_loop(self, shapelen, sig, frame, value, obj, dtype):
- while not frame.done():
- reduce_driver.jit_merge_point(sig=sig,
- shapelen=shapelen, self=self,
- value=value, obj=obj, frame=frame,
- dtype=dtype)
- assert isinstance(sig, ReduceSignature)
- value = sig.binfunc(dtype, value,
- sig.eval(frame, obj).convert_to(dtype))
- frame.next(shapelen)
- return value
-
-
class W_Ufunc1(W_Ufunc):
argcount = 1
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
@@ -3,8 +3,55 @@
signatures
"""
-from pypy.rlib.jit import JitDriver
+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):
+ _virtualizable2_ = ['iterators[*]', 'final_iter', 'arraylist[*]',
+ 'value', 'identity', 'cur_value']
+
+ @unroll_safe
+ def __init__(self, iterators, arrays, identity=None):
+ self = hint(self, access_directly=True, fresh_virtualizable=True)
+ self.iterators = iterators[:]
+ self.arrays = arrays[:]
+ for i in range(len(self.iterators)):
+ iter = self.iterators[i]
+ if not isinstance(iter, ConstantIterator):
+ self.final_iter = i
+ break
+ else:
+ self.final_iter = -1
+ self.cur_value = None
+ self.identity = identity
+
+ def done(self):
+ final_iter = promote(self.final_iter)
+ if final_iter < 0:
+ assert False
+ return self.iterators[final_iter].done()
+
+ @unroll_safe
+ def next(self, shapelen):
+ for i in range(len(self.iterators)):
+ self.iterators[i] = self.iterators[i].next(shapelen)
+
+ @unroll_safe
+ def next_from_second(self, shapelen):
+ """ Don't increase the first iterator
+ """
+ for i in range(1, len(self.iterators)):
+ self.iterators[i] = self.iterators[i].next(shapelen)
+
+ def next_first(self, shapelen):
+ self.iterators[0] = self.iterators[0].next(shapelen)
+
+ def get_final_iter(self):
+ final_iter = promote(self.final_iter)
+ if final_iter < 0:
+ assert False
+ return self.iterators[final_iter]
def get_printable_location(shapelen, sig):
return 'numpy ' + sig.debug_repr() + ' [%d dims]' % (shapelen,)
@@ -27,4 +74,4 @@
frame=frame, arr=arr)
sig.eval(frame, arr)
frame.next(shapelen)
-
+ return frame.cur_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
@@ -1,9 +1,7 @@
from pypy.rlib.objectmodel import r_dict, compute_identity_hash, compute_hash
from pypy.rlib.rarithmetic import intmask
-from pypy.module.micronumpy.interp_iter import ViewIterator, ArrayIterator, \
- ConstantIterator, AxisIterator, ViewTransform,\
- BroadcastTransform
-from pypy.rlib.jit import hint, unroll_safe, promote
+from pypy.module.micronumpy.interp_iter import ConstantIterator, AxisIterator,\
+ ViewTransform, BroadcastTransform
from pypy.tool.pairtype import extendabletype
""" Signature specifies both the numpy expression that has been constructed
@@ -55,50 +53,6 @@
known_sigs[sig] = sig
return sig
-class NumpyEvalFrame(object):
- _virtualizable2_ = ['iterators[*]', 'final_iter', 'arraylist[*]',
- 'value', 'identity']
-
- @unroll_safe
- def __init__(self, iterators, arrays):
- self = hint(self, access_directly=True, fresh_virtualizable=True)
- self.iterators = iterators[:]
- self.arrays = arrays[:]
- for i in range(len(self.iterators)):
- iter = self.iterators[i]
- if not isinstance(iter, ConstantIterator):
- self.final_iter = i
- break
- else:
- self.final_iter = -1
-
- def done(self):
- final_iter = promote(self.final_iter)
- if final_iter < 0:
- assert False
- return self.iterators[final_iter].done()
-
- @unroll_safe
- def next(self, shapelen):
- for i in range(len(self.iterators)):
- self.iterators[i] = self.iterators[i].next(shapelen)
-
- @unroll_safe
- def next_from_second(self, shapelen):
- """ Don't increase the first iterator
- """
- for i in range(1, len(self.iterators)):
- self.iterators[i] = self.iterators[i].next(shapelen)
-
- def next_first(self, shapelen):
- self.iterators[0] = self.iterators[0].next(shapelen)
-
- def get_final_iter(self):
- final_iter = promote(self.final_iter)
- if final_iter < 0:
- assert False
- return self.iterators[final_iter]
-
def _add_ptr_to_cache(ptr, cache):
i = 0
for p in cache:
@@ -141,10 +95,20 @@
self.iter_no = no
def create_frame(self, arr):
+ from pypy.module.micronumpy.loop import NumpyEvalFrame
+ from pypy.module.micronumpy.interp_numarray import ReduceArray
+
iterlist = []
arraylist = []
self._create_iter(iterlist, arraylist, arr, [])
- return NumpyEvalFrame(iterlist, arraylist)
+ if isinstance(arr, ReduceArray):
+ identity = arr.identity
+ else:
+ identity = None
+ f = NumpyEvalFrame(iterlist, arraylist, identity)
+ # hook for cur_value being used by reduce
+ arr.compute_first_step(self, f)
+ return f
class ConcreteSignature(Signature):
_immutable_fields_ = ['dtype']
@@ -256,12 +220,13 @@
return self.child.eval(frame, arr.child)
class Call1(Signature):
- _immutable_fields_ = ['unfunc', 'name', 'child']
+ _immutable_fields_ = ['unfunc', 'name', 'child', 'dtype']
- def __init__(self, func, name, child):
+ def __init__(self, func, name, dtype, child):
self.unfunc = func
self.child = child
self.name = name
+ self.dtype = dtype
def hash(self):
return compute_hash(self.name) ^ intmask(self.child.hash() << 1)
@@ -398,20 +363,14 @@
self.right._create_iter(iterlist, arraylist, arr.right, rtransforms)
class ReduceSignature(Call2):
- def _create_iter(self, iterlist, arraylist, arr, transforms):
- self.right._create_iter(iterlist, arraylist, arr, transforms)
-
- def _invent_numbering(self, cache, allnumbers):
- self.right._invent_numbering(cache, allnumbers)
-
- def _invent_array_numbering(self, arr, cache):
- self.right._invent_array_numbering(arr, cache)
-
def eval(self, frame, arr):
- return self.right.eval(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)
+ frame.cur_value = self.binfunc(self.calc_dtype, frame.cur_value, rval)
def debug_repr(self):
- return 'ReduceSig(%s, %s)' % (self.name, self.right.debug_repr())
+ return 'ReduceSig(%s)' % (self.name, self.right.debug_repr())
class SliceloopSignature(Call2):
def eval(self, frame, arr):
More information about the pypy-commit
mailing list