[pypy-commit] pypy vecopt2: added failing test case for extending pack sets
plan_rich
noreply at buildbot.pypy.org
Tue May 5 09:45:37 CEST 2015
Author: Richard Plangger <rich at pasra.at>
Branch: vecopt2
Changeset: r77088:a51be5e7791d
Date: 2015-03-25 08:44 +0100
http://bitbucket.org/pypy/pypy/changeset/a51be5e7791d/
Log: added failing test case for extending pack sets
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_vectorize.py b/rpython/jit/metainterp/optimizeopt/test/test_vectorize.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_vectorize.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_vectorize.py
@@ -65,6 +65,13 @@
opt.find_adjacent_memory_refs()
return opt
+ def extend_pack_set(self, loop, unroll_factor = -1):
+ opt = self.vec_optimizer_unrolled(loop, unroll_factor)
+ opt.build_dependency_graph()
+ opt.find_adjacent_memory_refs()
+ opt.extend_pack_set()
+ return opt
+
def assert_unroll_loop_equals(self, loop, expected_loop, \
unroll_factor = -1):
vec_optimizer = self.vec_optimizer_unrolled(loop, unroll_factor)
@@ -84,6 +91,14 @@
for i,op in enumerate(loop.operations):
print(i,op)
+ def assert_packset_contains(self, packset, x, y):
+ for pack in packset.packs:
+ if pack.left.op_idx == x and \
+ pack.right.op_idx == y:
+ break
+ else:
+ pytest.fail("must find a pack set for {x},{y}".format(x=x,y=y))
+
def assert_edges(self, graph, edge_list):
""" Check if all dependencies are met. for complex cases
adding None instead of a list of integers skips the test.
@@ -554,6 +569,32 @@
assert len(vopt.vec_info.memory_refs) == 2
assert len(vopt.pack_set.packs) == 1
+ def test_packset_init_raw_load_not_adjacent_and_adjacent(self):
+ ops = """
+ [p0,i0]
+ i3 = raw_load(p0, i0, descr=floatarraydescr)
+ jump(p0,i0)
+ """
+ loop = self.parse_loop(ops)
+ vopt = self.init_pack_set(loop,3)
+ assert len(vopt.vec_info.memory_refs) == 4
+ assert len(vopt.pack_set.packs) == 0
+ ops = """
+ [p0,i0]
+ i2 = int_add(i0,1)
+ raw_load(p0, i2, descr=floatarraydescr)
+ jump(p0,i2)
+ """
+ loop = self.parse_loop(ops)
+ vopt = self.init_pack_set(loop,3)
+ assert len(vopt.vec_info.memory_refs) == 4
+ assert len(vopt.pack_set.packs) == 3
+ for i in range(3):
+ x = (i+1)*2
+ y = x + 2
+ assert vopt.dependency_graph.independant(x,y)
+ self.assert_packset_contains(vopt.pack_set, x,y)
+
def test_packset_init_2(self):
ops = """
[p0,i0]
@@ -565,22 +606,27 @@
"""
loop = self.parse_loop(ops)
vopt = self.init_pack_set(loop,15)
- self.debug_print_operations(loop)
assert len(vopt.vec_info.memory_refs) == 16
assert len(vopt.pack_set.packs) == 15
+ # assure that memory refs are not adjacent for all
+ for i in range(15):
+ for j in range(15):
+ try:
+ if i-4 == j or i+4 == j:
+ mref1 = vopt.vec_info.memory_refs[i]
+ mref2 = vopt.vec_info.memory_refs[j]
+ assert mref1.is_adjacent_to(mref2)
+ else:
+ mref1 = vopt.vec_info.memory_refs[i]
+ mref2 = vopt.vec_info.memory_refs[j]
+ assert not mref1.is_adjacent_to(mref2)
+ except KeyError:
+ pass
for i in range(15):
x = (i+1)*4
y = x + 4
assert vopt.dependency_graph.independant(x,y)
- mref1 = vopt.vec_info.memory_refs[x]
- mref2 = vopt.vec_info.memory_refs[y]
- assert mref1.is_adjacent_to(mref2)
- for pack in vopt.pack_set.packs:
- if pack.left.op_idx == (i+1)*4 and \
- pack.right.op_idx == (i+1)*4 + 4:
- break
- else:
- pytest.fail("must find a pack set for {x},{y}".format(x=x,y=y))
+ self.assert_packset_contains(vopt.pack_set, x, y)
def test_isomorphic_operations(self):
ops_src = """
@@ -604,5 +650,23 @@
assert not isomorphic(ops[4], ops[6])
assert not isomorphic(ops[1], ops[6])
+ def test_packset_extend_simple(self):
+ ops = """
+ [p0,i0,i10]
+ i1 = int_add(i0, 1)
+ i2 = int_le(i1, 16)
+ guard_true(i2) [p0, i0]
+ i3 = getarrayitem_gc(p0, i1, descr=chararraydescr)
+ i4 = int_add(i10, i3)
+ jump(p0,i1, i4)
+ """
+ loop = self.parse_loop(ops)
+ vopt = self.extend_pack_set(loop,1)
+ assert len(vopt.vec_info.memory_refs) == 2
+ assert len(vopt.pack_set.packs) == 2
+ assert vopt.dependency_graph.independant(5,10)
+ self.assert_packset_contains(vopt.pack_set, 5, 10)
+
+
class TestLLtype(BaseTestVectorize, LLtypeMixin):
pass
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
@@ -226,22 +226,12 @@
if self.pack_set.can_be_packed(a_memref, b_memref):
self.pack_set.packs.append(Pair(a_memref, b_memref))
- def vectorize_trace(self, loop):
- """ Implementation of the algorithm introduced by Larsen. Refer to
- '''Exploiting Superword Level Parallelism
- with Multimedia Instruction Sets'''
- for more details.
- """
+ def extend_pack_set(self):
+ for p in self.pack_set.packs:
+ self.follow_def_uses(p)
- for i,operation in enumerate(loop.operations):
-
- if operation.getopnum() == rop.RAW_LOAD:
- # TODO while the loop is unrolled, build memory accesses
- pass
-
-
- # was not able to vectorize
- return False
+ def follow_def_uses(self, pack):
+ pass
def isomorphic(l_op, r_op):
""" Described in the paper ``Instruction-Isomorphism in Program Execution''.
@@ -270,6 +260,9 @@
self.dependency_graph = dependency_graph
self.operations = operations
+ def pack_count(self):
+ return len(self.packs)
+
def can_be_packed(self, lh_ref, rh_ref):
l_op = self.operations[lh_ref.op_idx]
r_op = self.operations[lh_ref.op_idx]
More information about the pypy-commit
mailing list