[pypy-commit] pypy refactor-signature: refactor up to a nice point of segmentation fault
fijal
noreply at buildbot.pypy.org
Wed Dec 14 12:22:59 CET 2011
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: refactor-signature
Changeset: r50496:8fc2393b390b
Date: 2011-12-14 13:22 +0200
http://bitbucket.org/pypy/pypy/changeset/8fc2393b390b/
Log: refactor up to a nice point of segmentation fault
diff --git a/pypy/module/micronumpy/interp_iter.py b/pypy/module/micronumpy/interp_iter.py
--- a/pypy/module/micronumpy/interp_iter.py
+++ b/pypy/module/micronumpy/interp_iter.py
@@ -2,13 +2,6 @@
from pypy.rlib import jit
from pypy.rlib.objectmodel import instantiate
-class NumpyEvalFrame(object):
- def __init__(self, iterators):
- self.iterators = iterators
-
- def next(self, shapelen):
- xxx
-
# Iterators for arrays
# --------------------
# all those iterators with the exception of BroadcastIterator iterate over the
@@ -159,38 +152,6 @@
def get_offset(self):
return self.offset
-class Call2Iterator(BaseIterator):
- def __init__(self, left, right):
- self.left = left
- self.right = right
-
- def next(self, shapelen):
- return Call2Iterator(self.left.next(shapelen),
- self.right.next(shapelen))
-
- def done(self):
- if isinstance(self.left, ConstantIterator):
- return self.right.done()
- return self.left.done()
-
- def get_offset(self):
- if isinstance(self.left, ConstantIterator):
- return self.right.get_offset()
- return self.left.get_offset()
-
-class Call1Iterator(BaseIterator):
- def __init__(self, child):
- self.child = child
-
- def next(self, shapelen):
- return Call1Iterator(self.child.next(shapelen))
-
- def done(self):
- return self.child.done()
-
- def get_offset(self):
- return self.child.get_offset()
-
class ConstantIterator(BaseIterator):
def next(self, shapelen):
return self
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
@@ -7,11 +7,12 @@
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 NumpyEvalFrame, ArrayIterator
+from pypy.module.micronumpy.interp_iter import ArrayIterator
numpy_driver = jit.JitDriver(
greens=['shapelen', 'signature'],
- reds=['result_size', 'i', 'ri', 'self', 'result']
+ virtualizables=['frame'],
+ reds=['result_size', 'frame', 'ri', 'self', 'result']
)
all_driver = jit.JitDriver(
greens=['shapelen', 'signature'],
@@ -759,9 +760,6 @@
def getitem(self, item):
raise NotImplementedError
- def eval(self, iter):
- return self.value
-
def to_str(self, space, comma, builder, indent=' ', use_ellipsis=False):
builder.append(self.dtype.itemtype.str_format(self.value))
@@ -790,20 +788,22 @@
raise NotImplementedError
def compute(self):
- i = 0
result_size = self.find_size()
result = W_NDimArray(result_size, self.shape, self.find_dtype())
shapelen = len(self.shape)
- xxx
- i = self.start_iter()
- ri = result.start_iter()
+ signature = self.find_sig()
+ frame = signature.create_frame(self)
+ ri = ArrayIterator(result)
while not ri.done():
numpy_driver.jit_merge_point(signature=signature,
shapelen=shapelen,
- result_size=result_size, i=i, ri=ri,
+ result_size=result_size,
+ frame=frame,
+ ri=ri,
self=self, result=result)
- result.dtype.setitem(result.storage, ri.offset, self.eval(i))
- i = i.next(shapelen)
+ result.dtype.setitem(result.storage, ri.offset,
+ signature.eval(frame, self))
+ frame.next(shapelen)
ri = ri.next(shapelen)
return result
@@ -816,11 +816,6 @@
self.force_if_needed()
return self.forced_result
- def eval(self, iter):
- if self.forced_result is not None:
- return self.forced_result.eval(iter)
- return self._eval(iter)
-
def getitem(self, item):
return self.get_concrete().getitem(item)
@@ -853,14 +848,9 @@
def _find_dtype(self):
return self.res_dtype
- def _eval(self, iter):
- assert isinstance(iter, Call1Iterator)
- val = self.values.eval(iter.child).convert_to(self.res_dtype)
- sig = jit.promote(self.signature)
- assert isinstance(sig, signature.Call1)
- return sig.unfunc(self.res_dtype, val)
-
def create_sig(self):
+ if self.forced_result is not None:
+ return self.forced_result.create_sig()
return signature.Call1(self.ufunc, self.values.create_sig())
class Call2(VirtualArray):
@@ -884,15 +874,9 @@
def _find_size(self):
return self.size
- def _eval(self, iter):
- assert isinstance(iter, Call2Iterator)
- lhs = self.left.eval(iter.left).convert_to(self.calc_dtype)
- rhs = self.right.eval(iter.right).convert_to(self.calc_dtype)
- sig = jit.promote(self.signature)
- assert isinstance(sig, signature.Call2)
- return sig.binfunc(self.calc_dtype, lhs, rhs)
-
def create_sig(self):
+ if self.forced_result is not None:
+ return self.forced_result.create_sig()
return signature.Call2(self.ufunc, self.left.create_sig(),
self.right.create_sig())
@@ -1048,9 +1032,6 @@
def getitem(self, item):
return self.dtype.getitem(self.storage, item)
- def eval(self, iter):
- return self.dtype.getitem(self.storage, iter.get_offset())
-
def copy(self):
array = W_NDimArray(self.size, self.shape[:], self.dtype, self.order)
rffi.c_memcpy(
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,8 +1,7 @@
-from pypy.rlib.objectmodel import r_dict, compute_identity_hash, compute_hash
-from pypy.rlib.rarithmetic import intmask
+from pypy.rlib.objectmodel import r_dict, compute_identity_hash
from pypy.module.micronumpy.interp_iter import ViewIterator, ArrayIterator, \
BroadcastIterator, OneDimIterator, ConstantIterator
-
+from pypy.rlib.jit import hint, unroll_safe
# def components_eq(lhs, rhs):
# if len(lhs) != len(rhs):
@@ -30,10 +29,19 @@
def find_sig(sig):
return known_sigs.setdefault(sig, sig)
+class NumpyEvalFrame(object):
+ _virtualizable2_ = ['iterators[*]']
+
+ def __init__(self, iterators):
+ self = hint(self, access_directly=True)
+ self.iterators = iterators
+
+ @unroll_safe
+ def next(self, shapelen):
+ for i in range(len(self.iterators)):
+ self.iterators[i] = self.iterators[i].next(shapelen)
+
class Signature(object):
- def create_iter(self, array, cache, res_shape=None):
- raise NotImplementedError
-
def invent_numbering(self):
cache = r_dict(sigeq, sighash)
self._invent_numbering(cache)
@@ -44,7 +52,12 @@
except KeyError:
no = len(cache)
cache[self] = no
- self.iter_no = no
+ self.iter_no = no
+
+ def create_frame(self, arr, res_shape=None):
+ iterlist = []
+ self._create_iter(iterlist, arr, res_shape)
+ return NumpyEvalFrame(iterlist)
class ConcreteSignature(Signature):
def __init__(self, dtype):
@@ -62,10 +75,27 @@
def debug_repr(self):
return 'Array'
+ def _create_iter(self, iterlist, arr, res_shape):
+ if self.iter_no >= len(iterlist):
+ iter = ArrayIterator(arr)
+ iterlist.append(iter)
+
+ def eval(self, frame, arr):
+ iter = frame.iterators[self.iter_no]
+ return arr.dtype.getitem(arr.storage, iter.offset)
+
class ScalarSignature(ConcreteSignature):
def debug_repr(self):
return 'Scalar'
+ def _create_iter(self, iterlist, arr, res_shape):
+ if self.iter_no >= len(iterlist):
+ iter = ConstantIterator()
+ iterlist.append(iter)
+
+ def eval(self, frame, arr):
+ return arr.value
+
class ViewSignature(Signature):
def __init__(self, child):
self.child = child
@@ -81,10 +111,18 @@
def debug_repr(self):
return 'Slice(%s)' % self.child.debug_repr()
+ def _create_iter(self, iterlist, arr, res_shape):
+ if self.iter_no >= len(iterlist):
+ iter = ViewIterator(arr)
+ iterlist.append(iter)
+
class FlatiterSignature(ViewSignature):
def debug_repr(self):
return 'FlatIter(%s)' % self.child.debug_repr()
+ def _create_iter(self, iterlist, arr, res_shape):
+ XXX
+
class Call1(Signature):
def __init__(self, func, child):
self.unfunc = func
@@ -105,6 +143,13 @@
def _invent_numbering(self, cache):
self.values._invent_numbering(cache)
+ def _create_iter(self, iterlist, arr, res_shape):
+ self.child._create_iter(iterlist, arr.values, res_shape)
+
+ def eval(self, frame, arr):
+ v = self.child.eval(frame, arr.values).convert_to(arr.res_dtype)
+ return self.unfunc(arr.res_dtype, v)
+
class Call2(Signature):
def __init__(self, func, left, right):
self.binfunc = func
@@ -125,6 +170,15 @@
self.left._invent_numbering(cache)
self.right._invent_numbering(cache)
+ def _create_iter(self, iterlist, arr, res_shape):
+ self.left._create_iter(iterlist, arr.left, res_shape)
+ self.right._create_iter(iterlist, arr.right, res_shape)
+
+ def eval(self, frame, arr):
+ lhs = self.left.eval(frame, arr.left).convert_to(arr.calc_dtype)
+ rhs = self.right.eval(frame, arr.right).convert_to(arr.calc_dtype)
+ return self.binfunc(arr.calc_dtype, lhs, rhs)
+
def debug_repr(self):
return 'Call2(%s, %s, %s)' % (self.name,
self.left.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
@@ -39,6 +39,8 @@
assert sig7.left.left.iter_no == sig7.right.left.iter_no
assert sig7.left.left.iter_no != sig7.right.right.iter_no
assert sig7.left.right.iter_no == sig7.right.right.iter_no
+ v1.forced_result = ar
+ assert v1.find_sig() is not sig1
def test_slice_signature(self, space):
float64_dtype = get_dtype_cache(space).w_float64dtype
More information about the pypy-commit
mailing list