Author: Richard Plangger <r...@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] _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit