Peano
Loading...
Searching...
No Matches
SYCLPrinter.py
Go to the documentation of this file.
1import exahype2.dslhype.printers.CPPPrinter as CPPPrinter
2import exahype2.dslhype.SyntaxTree as SyntaxTree
3import os
4import copy
5
6class SYCLPrinter(CPPPrinter):
7 def print_function_definition(self, function_definition: SyntaxTree.FunctionDefinition, indent_level = 0):
8 namespace_header = f"""namespace {"::".join(function_definition._namespaces)}::sycl {{"""
9 namespace_footer = "}"
10 template_string = ""
11 if function_definition._template is not None:
12 template_strings = [argument.print(self) for argument in function_definition._template]
13 template_string = "template <" + ",".join(template_strings) + ">\n"
14
15 current_indent = indent_level + 1 # Indentation increases inside namespace
16 statement_prints = [statement.print(self, current_indent + 1) for statement in function_definition._body]
17 argument_prints = [argument.print(self) for argument in function_definition._arguments]
18 statement_prints.insert(0, "::sycl::queue& queue = tarch::accelerator::getSYCLQueue(targetDevice);")
19 statement_prints.insert(1, "size_t range0, range1, range2;")
20
21 data_copy_prints = []
22 for dataBlockCreation in SyntaxTree.FunctionDefinition._syclDataToCopy:
23 if len(dataBlockCreation._dataBlock._iteration_range) > 1:
24 step_size = SyntaxTree.Integer(1)
25 for d in dataBlockCreation._dataBlock._iteration_range[0:-1]:
26 step_size = step_size * (d[1] - d[0])
27 size = step_size * (dataBlockCreation._dataBlock._iteration_range[-1][1] - dataBlockCreation._dataBlock._iteration_range[-1][0])
28
29 return f"""{namespace_header}
30{template_string}{self.get_indent(indent_level)}{function_definition._return_type.print(self)} {function_definition.id}({', '.join(argument_prints)}) {{
31{os.linesep.join(statement_prints)}
32{self.get_indent(indent_level)}}}
33{namespace_footer}
34"""
35
36 def print_function_declaration(self, function_definition: SyntaxTree.FunctionDefinition, indent_level=0):
37 namespace_header = f"""namespace {"::".join(function_definition._namespaces)}::sycl {{"""
38 namespace_footer = "}"
39 template_string = ""
40 if function_definition._template is not None:
41 template_strings = [argument.print(self) for argument in function_definition._template]
42 template_string = "template <" + ",".join(template_strings) + ">\n"
43
44 current_indent = indent_level + 1 # Indentation increases inside namespace
45 argument_prints = [argument.print(self) for argument in function_definition._arguments]
46
47 return f"""{namespace_header}
48{template_string}{self.get_indent(indent_level)}{function_definition._return_type.print(self)} {function_definition.id}({', '.join(argument_prints)});
49{namespace_footer}
50"""
51
52 def print_function_definition_with_timer(self, function_definition: SyntaxTree.FunctionDefinition, indent_level=0):
53 namespace_header = f"""namespace {"::".join(function_definition._namespaces)}::sycl {{"""
54 namespace_footer = "}"
55 template_string = ""
56 function_call_string = function_definition.id
57 if function_definition._template is not None:
58 template_strings = [argument.print(self) for argument in function_definition._template]
59 template_string = "template <" + ",".join(template_strings) + ">\n"
60 function_call_string += "<" + ",".join([template.split(' ')[1] for template in template_strings]) + ">"
61
62 arguments = copy.deepcopy(function_definition._arguments)
63 arguments.append(SyntaxTree.Argument("measurement", SyntaxTree.TCustom("tarch::timing::Measurement&")))
64
65 current_indent = indent_level + 1 # Indentation increases inside namespace
66 argument_prints = [argument.print(self) for argument in arguments]
67
68 return f"""{namespace_header}
69{template_string}{self.get_indent(indent_level)}{function_definition._return_type.print(self)} {function_definition.id}({', '.join(argument_prints)}) {{
70tarch::timing::Watch watch("{"::".join(function_definition._namespaces)}", "{function_definition.id}", false, true);
71{function_call_string}({",".join([argument.print(self).split(' ')[-1] for argument in function_definition._arguments])});
72watch.stop();
73measurement.setValue(watch.getCalendarTime());
74{self.get_indent(indent_level)}}}
75{namespace_footer}
76"""
77
78 def print_function_declaration_with_timer(self, function_definition: SyntaxTree.FunctionDefinition, indent_level=0):
79 namespace_header = f"""namespace {"::".join(function_definition._namespaces)}::sycl {{"""
80 namespace_footer = "}"
81 template_string = ""
82 if function_definition._template is not None:
83 template_strings = [argument.print(self) for argument in function_definition._template]
84 template_string = "template <" + ",".join(template_strings) + ">\n"
85
86 arguments = copy.deepcopy(function_definition._arguments)
87 arguments.append(SyntaxTree.Argument("measurement", SyntaxTree.TCustom("tarch::timing::Measurement&")))
88
89 current_indent = indent_level + 1 # Indentation increases inside namespace
90 argument_prints = [argument.print(self) for argument in arguments]
91
92 return f"""{namespace_header}
93{template_string}{self.get_indent(indent_level)}{function_definition._return_type.print(self)} {function_definition.id}({', '.join(argument_prints)});
94{namespace_footer}
95"""
96
97 def print_memory_allocation(self, memory_allocation: SyntaxTree.MemoryAllocation, indent_level=0):
98 if len(memory_allocation._dimensions) == 1:
99 return f"""{self.get_indent(indent_level)}{memory_allocation._type.print(self) + "* " if memory_allocation._specify_type else ""}{memory_allocation._name.print(self)} = new {memory_allocation._type.print(self)}[{memory_allocation._dimensions[0].print(self)}];"""
100 else:
101 return f"""{self.get_indent(indent_level)}{memory_allocation._type.print(self)}** {memory_allocation._name.print(self)} = new {memory_allocation._type.print(self)}*[{memory_allocation._dimensions[-1].print(self)}];
102{memory_allocation._loop.print(self, indent_level)}"""
103
104 def print_memory_deallocation(self, memory_deallocation: SyntaxTree.MemoryDeallocation, indent_level=0):
105 return f"""{self.get_indent(indent_level)}::sycl::free({memory_deallocation._name.print(self)}, queue);"""
106
107 def print_data_block_unary_max(self, unary_max: SyntaxTree.DataBlockUnaryMax, indent_level=0):
108 ranges = [f"range{i} = {loop.get_interval_size().print(self)};" for i, loop in enumerate(unary_max._loops[0:3])]
109 indexing = [f"int {loop.get_iteration_variable().print(self)} = index[{i}];" for i, loop in enumerate(unary_max._loops[0:3])]
110 statement_prints = [statement.print(self, indent_level + 1) for statement in unary_max._loops[2]._statements]
111 return os.linesep.join(ranges) + "\n" + self.get_indent(indent_level) + f"""queue.submit([&](::sycl::handler& handler) {{handler.memset({unary_max._outputVariable.print(self)}, 0, sizeof(double) * {unary_max._loop.get_interval_size().print(self)}); }}).wait();
112{self.get_indent(indent_level)}queue.submit([&](::sycl::handler& handler) {{
113{self.get_indent(indent_level)}handler.parallel_for(::sycl::range<3>{{range0, range1, range2}}, [=](::sycl::item<3> index) {{
114{os.linesep.join(indexing)}
115{unary_max._loops[3].print(self, indent_level + 1)}
116{self.get_indent(indent_level + 1)}}});
117{self.get_indent(indent_level)}}}).wait();"""
118
119 def print_max(self, max: SyntaxTree.Max, indent_level=0):
120 return f"{self.get_indent(indent_level)}sycl::max({max._lhs.print(self)}, {max._rhs.print(self)});"
121
122 def print_data_block_construction_from_function(self, construction: SyntaxTree.DataBlockConstructionFromFunction, indent_level=0):
123 ranges = [f"range{i} = {loop.get_interval_size().print(self)};" for i, loop in enumerate(construction._loops[0:3])]
124 indexing = [f"int {loop.get_iteration_variable().print(self)} = index[{i}];" for i, loop in enumerate(construction._loops[0:3])]
125 statement_prints = [statement.print(self, indent_level + 1) for statement in construction._loops[2]._statements]
126 return construction.memoryAllocation.print(self, indent_level) + os.linesep.join(ranges) + "\n" + self.get_indent(indent_level) + f"""queue.submit([&](::sycl::handler& handler) {{
127{self.get_indent(indent_level)}handler.parallel_for(::sycl::range<3>{{range0, range1, range2}}, [=](::sycl::item<3> index) {{
128{os.linesep.join(indexing)}
129{os.linesep.join(statement_prints)}
130{self.get_indent(indent_level + 1)}}});
131{self.get_indent(indent_level)}}}).wait();"""
132
133 def print_data_block_assignment(self, assignment: SyntaxTree.DataBlockAssignment, indent_level=0):
134 ranges = [f"range{i} = {loop.get_interval_size().print(self)};" for i, loop in enumerate(assignment._loops[0:3])]
135 indexing = [f"int {loop.get_iteration_variable().print(self)} = index[{i}];" for i, loop in enumerate(assignment._loops[0:3])]
136 statement_prints = [statement.print(self, indent_level + 1) for statement in assignment._loops[2]._statements]
137 return os.linesep.join(ranges) + "\n" + self.get_indent(indent_level) + f"""queue.submit([&](::sycl::handler& handler) {{
138{self.get_indent(indent_level)}handler.parallel_for(::sycl::range<3>{{range0, range1, range2}}, [=](::sycl::item<3> index) {{
139{os.linesep.join(indexing)}
140{os.linesep.join(statement_prints)}
141{self.get_indent(indent_level + 1)}}});
142{self.get_indent(indent_level)}}}).wait();"""
print_max(self, SyntaxTree.Max max, indent_level=0)
print_function_definition(self, SyntaxTree.FunctionDefinition function_definition, indent_level=0)
Definition SYCLPrinter.py:7
print_data_block_construction_from_function(self, SyntaxTree.DataBlockConstructionFromFunction construction, indent_level=0)
print_function_declaration(self, SyntaxTree.FunctionDefinition function_definition, indent_level=0)
print_data_block_assignment(self, SyntaxTree.DataBlockAssignment assignment, indent_level=0)
print_function_declaration_with_timer(self, SyntaxTree.FunctionDefinition function_definition, indent_level=0)
print_data_block_unary_max(self, SyntaxTree.DataBlockUnaryMax unary_max, indent_level=0)
print_function_definition_with_timer(self, SyntaxTree.FunctionDefinition function_definition, indent_level=0)
print_memory_deallocation(self, SyntaxTree.MemoryDeallocation memory_deallocation, indent_level=0)
print_memory_allocation(self, SyntaxTree.MemoryAllocation memory_allocation, indent_level=0)