Author: Richard Plangger <r...@pasra.at> Branch: vecopt-merge Changeset: r79252:fc31b6dcacc8 Date: 2015-08-27 13:10 +0200 http://bitbucket.org/pypy/pypy/changeset/fc31b6dcacc8/
Log: extending test cases for memory references diff --git a/rpython/jit/metainterp/optimizeopt/dependency.py b/rpython/jit/metainterp/optimizeopt/dependency.py --- a/rpython/jit/metainterp/optimizeopt/dependency.py +++ b/rpython/jit/metainterp/optimizeopt/dependency.py @@ -934,11 +934,11 @@ """ IndexVar is an AbstractValue only to ensure that a box can be assigned to the same variable as an index var. """ - def __init__(self, var): + def __init__(self, var, coeff_mul=1, coeff_div=1, constant=0): self.var = var - self.coefficient_mul = 1 - self.coefficient_div = 1 - self.constant = 0 + self.coefficient_mul = coeff_mul + self.coefficient_div = coeff_div + self.constant = constant # saves the next modification that uses a variable self.next_nonconst = None self.current_end = None @@ -990,7 +990,7 @@ def same_variable(self, other): assert isinstance(other, IndexVar) - return other.var == self.var + return other.var is self.var def diff(self, other): """ calculates the difference as a second parameter """ @@ -1060,9 +1060,8 @@ if self.is_identity(): return 'IndexVar(%s+%s)' % (self.var, repr(self.next_nonconst)) - return 'IndexVar((%s*(%s/%s)+%s) + %s)' % (self.var, self.coefficient_mul, - self.coefficient_div, self.constant, - repr(self.next_nonconst)) + return 'IndexVar((%s*(%s/%s)+%s))' % (self.var, self.coefficient_mul, + self.coefficient_div, self.constant) class MemoryRef(object): """ a memory reference to an array object. IntegralForwardModification is able diff --git a/rpython/jit/metainterp/optimizeopt/test/test_dependency.py b/rpython/jit/metainterp/optimizeopt/test/test_dependency.py --- a/rpython/jit/metainterp/optimizeopt/test/test_dependency.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_dependency.py @@ -7,20 +7,11 @@ from rpython.jit.metainterp.optimizeopt.dependency import (DependencyGraph, Dependency, IndexVar, MemoryRef, Node) from rpython.jit.metainterp.resoperation import rop, ResOperation +from rpython.jit.backend.llgraph.runner import ArrayDescr +from rpython.rtyper.lltypesystem import rffi +from rpython.rtyper.lltypesystem import lltype from rpython.conftest import option -class FakeNode(Node): - def __init__(self, i): - Node.__init__(self, None, i) - pass - - def __repr__(self): - return "n%d" % self.opidx - -class FakeDependencyGraph(DependencyGraph): - def __init__(self): - pass - class DependencyBaseTest(BaseTest): def setup_method(self, method): @@ -138,6 +129,48 @@ return self.last_graph.memory_refs[node] class BaseTestDependencyGraph(DependencyBaseTest): + + def test_index_var_basic(self): + b = FakeBox() + i = IndexVar(b,1,1,0) + j = IndexVar(b,1,1,0) + assert i.is_identity() + assert not i.less(j) + assert i.same_variable(j) + assert i.diff(j) == 0 + + def test_index_var_diff(self): + b = FakeBox() + i = IndexVar(b,4,2,0) + j = IndexVar(b,1,1,1) + assert not i.is_identity() + assert not j.is_identity() + assert i.diff(j) == 1 + + def test_memoryref_basic(self): + i = FakeBox() + a = FakeBox() + m1 = memoryref(a, i, (1,1,0)) + m2 = memoryref(a, i, (1,1,0)) + assert m1.match(m2) + + @py.test.mark.parametrize('coeff1,coeff2,adja,alias', + [((1,1,0), (1,1,0), False, True), + ((4,2,0), (8,4,0), False, True), + ((4,2,0), (8,2,0), False, True), + ((4,2,1), (8,4,0), True, False), + ]) + def test_memoryref_adjacent_alias(self, coeff1, + coeff2, adja, + alias): + i = FakeBox() + a = FakeBox() + m1 = memoryref(a, i, coeff1) + m2 = memoryref(a, i, coeff2) + assert m1.is_adjacent_after(m2) == adja + assert m2.is_adjacent_after(m1) == adja + assert m1.indices_can_alias(m2) == alias + def test_dependency_empty(self): ops = """ [] # 0: 1 @@ -511,6 +544,49 @@ assert cycle is not None assert cycle == [n1,n3,n4] +class FakeMemoryRefResOp(object): + def __init__(self, array, descr): + self.array = array + self.descr = descr + def getarg(self, index): + return self.array + def getdescr(self): + return self.descr + +FLOAT = ArrayDescr(lltype.Float) +SFLOAT = ArrayDescr(lltype.SingleFloat) +CHAR = ArrayDescr(rffi.r_signedchar) +UCHAR = ArrayDescr(rffi.r_uchar) +SHORT = ArrayDescr(rffi.r_short) +USHORT = ArrayDescr(rffi.r_ushort) +INT = ArrayDescr(rffi.r_int) +UINT = ArrayDescr(rffi.r_uint) +LONG = ArrayDescr(rffi.r_longlong) +ULONG = ArrayDescr(rffi.r_ulonglong) + +def memoryref(array, var, mod=(1,1,0), descr=None, raw=False): + if descr is None: + descr = FLOAT + mul, div, off = mod + op = FakeMemoryRefResOp(array, descr) + return MemoryRef(op, + IndexVar(var, mul, div, off), + raw) + +class FakeBox(object): + pass + +class FakeNode(Node): + def __init__(self, i): + Node.__init__(self, None, i) + pass + + def __repr__(self): + return "n%d" % self.opidx + +class FakeDependencyGraph(DependencyGraph): + def __init__(self): + pass class TestLLtype(BaseTestDependencyGraph, LLtypeMixin): diff --git a/rpython/jit/metainterp/optimizeopt/vectorize.py b/rpython/jit/metainterp/optimizeopt/vectorize.py --- a/rpython/jit/metainterp/optimizeopt/vectorize.py +++ b/rpython/jit/metainterp/optimizeopt/vectorize.py @@ -326,6 +326,8 @@ if memref_a.is_adjacent_to(memref_b): pair = self.packset.can_be_packed(node_a, node_b, None, False) if pair: + if node_a.op.getopnum() == rop.GETARRAYITEM_RAW: + print "found", memref_a.index_var, memref_b.index_var self.packset.add_pack(pair) def extend_packset(self): diff --git a/rpython/jit/metainterp/test/test_vectorize.py b/rpython/jit/metainterp/test/test_vectorize.py --- a/rpython/jit/metainterp/test/test_vectorize.py +++ b/rpython/jit/metainterp/test/test_vectorize.py @@ -13,6 +13,11 @@ from rpython.rlib.rawstorage import (alloc_raw_storage, raw_storage_setitem, free_raw_storage, raw_storage_getitem) +def malloc(T,n): + return lltype.malloc(T, n, flavor='raw', zero=True) +def free(mem): + lltype.free(mem, flavor='raw') + class VectorizeTests: enable_opts = 'intbounds:rewrite:virtualize:string:earlyforce:pure:heap:unroll' @@ -289,8 +294,8 @@ myjitdriver = JitDriver(greens = [], reds = 'auto') def f(d, v1, v2): - a = [v1] * d - b = [v2] * d + a = [v1] * i + b = [v2] * i i = 0 while i < len(a): myjitdriver.jit_merge_point() @@ -305,6 +310,31 @@ # return 69.999 ... instead of 70, (v1+v2)*i == 70.0 assert res == f(i,v1,v2) == sum([v1+v2]*i) + @py.test.mark.parametrize('size',[12]) + def test_body_multiple_accesses(self, size): + myjitdriver = JitDriver(greens = [], reds = 'auto') + T = lltype.Array(rffi.CHAR, hints={'nolength': True}) + def f(size): + vector_a = malloc(T, size) + vector_b = malloc(T, size) + i = 0 + while i < size: + myjitdriver.jit_merge_point() + # should unroll and group them correctly + c1 = vector_a[i] + c2 = vector_a[i+1] + c3 = vector_a[i+2] + # + vector_b[i] = c1 + vector_b[i+1] = c2 + vector_b[i+2] = c3 + i += 3 + free(vector_a) + free(vector_b) + return 0 + res = self.meta_interp(f, [size], vec_all=True) + assert res == f(size) + class VectorizeLLtypeTests(VectorizeTests): pass _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit