mirror of
https://github.com/RRZE-HPC/OSACA.git
synced 2026-01-05 02:30:08 +01:00
added tests for loop-carried deps and changed data structure of them to dict
This commit is contained in:
@@ -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']],
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user