added tests for loop-carried deps and changed data structure of them to dict

This commit is contained in:
JanLJL
2019-08-30 10:11:51 +02:00
parent ae69950e11
commit de1964a654
3 changed files with 51 additions and 27 deletions

View File

@@ -149,26 +149,26 @@ class Frontend(object):
)
)
def print_loopcarried_dependencies(self, dep_tuplelist, separator='|'):
def print_loopcarried_dependencies(self, dep_dict, separator='|'):
print(
'\n\nLoop-Carried Dependencies Analysis Report\n'
+ '-----------------------------------------'
)
for tup in dep_tuplelist:
for dep in dep_dict:
print(
'{:4d} {} {:4.1f} {} {:36}{} {}'.format(
tup[0]['line_number'],
dep,
separator,
sum(
[
instr_form['latency'] if instr_form['latency'] is not None else 0
for instr_form in tup[1]
for instr_form in dep_dict[dep]['dependencies']
]
),
separator,
tup[0]['line'],
dep_dict[dep]['root']['line'],
separator,
[node['line_number'] for node in tup[1]],
[node['line_number'] for node in dep_dict[dep]['dependencies']],
)
)

View File

@@ -17,6 +17,24 @@ class KernelDG(nx.DiGraph):
self.dg = self.create_DG(self.kernel)
self.loopcarried_deps = self.check_for_loopcarried_dep(self.kernel)
def create_DG(self, kernel):
# 1. go through kernel instruction forms (as vertices)
# 2. find edges (to dependend further instruction)
# 3. get LT value and set as edge weight
# 4. add instr forms as node attribute
dg = nx.DiGraph()
for i, instruction_form in enumerate(kernel):
dg.add_node(instruction_form['line_number'])
dg.nodes[instruction_form['line_number']]['instruction_form'] = instruction_form
for dep in self.find_depending(instruction_form, kernel[i + 1:]):
dg.add_edge(
instruction_form['line_number'],
dep['line_number'],
latency=instruction_form['latency'],
)
dg.nodes[dep['line_number']]['instruction_form'] = dep
return dg
def check_for_loopcarried_dep(self, kernel):
multiplier = len(kernel) + 1
# increase line number for second kernel loop
@@ -43,34 +61,20 @@ class KernelDG(nx.DiGraph):
)
# adjust line numbers
# and add reference to kernel again
for i, dep in enumerate(loopcarried_deps):
loopcarried_deps_dict = {}
for dep in loopcarried_deps:
nodes = [int(n / multiplier) for n in dep[1] if n >= first_line_no * multiplier]
nodes = [self._get_node_by_lineno(x) for x in nodes]
loopcarried_deps[i] = (self._get_node_by_lineno(dep[0]), nodes)
loopcarried_deps_dict[dep[0]] = {
'root': self._get_node_by_lineno(dep[0]),
'dependencies': nodes,
}
return loopcarried_deps
return loopcarried_deps_dict
def _get_node_by_lineno(self, lineno):
return [instr for instr in self.kernel if instr.line_number == lineno][0]
def create_DG(self, kernel):
# 1. go through kernel instruction forms (as vertices)
# 2. find edges (to dependend further instruction)
# 3. get LT value and set as edge weight
# 4. add instr forms as node attribute
dg = nx.DiGraph()
for i, instruction_form in enumerate(kernel):
dg.add_node(instruction_form['line_number'])
for dep in self.find_depending(instruction_form, kernel[i + 1:]):
dg.add_edge(
instruction_form['line_number'],
dep['line_number'],
latency=instruction_form['latency'],
)
dg.nodes[instruction_form['line_number']]['instruction_form'] = instruction_form
dg.nodes[dep['line_number']]['instruction_form'] = dep
return dg
def get_critical_path(self):
if nx.algorithms.dag.is_directed_acyclic_graph(self.dg):
longest_path = nx.algorithms.dag.dag_longest_path(self.dg, weight='latency')

View File

@@ -150,6 +150,26 @@ class TestSemanticTools(unittest.TestCase):
self.assertEqual(len(list(dg.get_dependent_instruction_forms(line_number=20))), 0)
self.assertEqual(len(list(dg.get_dependent_instruction_forms(line_number=21))), 0)
def test_cyclic_dag(self):
dg = KernelDG(self.kernel_x86, self.parser_x86, self.machine_model_csx)
dg.dg.add_edge(100, 101, latency=1.0)
dg.dg.add_edge(101, 102, latency=2.0)
dg.dg.add_edge(102, 100, latency=3.0)
with self.assertRaises(NotImplementedError):
dg.get_critical_path()
with self.assertRaises(NotImplementedError):
dg.get_loopcarried_dependencies()
def test_loop_carried_dependency_x86(self):
dg = KernelDG(self.kernel_x86, self.parser_x86, self.machine_model_csx)
lc_deps = dg.get_loopcarried_dependencies()
self.assertEqual(len(lc_deps), 1)
self.assertEqual(lc_deps[7]['root'], dg.dg.nodes(data=True)[7]['instruction_form'])
self.assertEqual(len(lc_deps[7]['dependencies']), 1)
self.assertEqual(
lc_deps[7]['dependencies'][0], dg.dg.nodes(data=True)[7]['instruction_form']
)
def test_is_read_is_written_x86(self):
# independent form HW model
dag = KernelDG(self.kernel_x86, self.parser_x86, None)