Peano
Loading...
Searching...
No Matches
CPPPrinter.py
Go to the documentation of this file.
1import os
2import copy
3import exahype2.dslhype.SyntaxTree as SyntaxTree
4import exahype2.dslhype.Printer as Printer
5
7 def __init__(self, spaces_per_tab = 2):
8 self._spaces_per_tab = spaces_per_tab
9
10 def get_indent(self, indent_level: int) -> str:
11 return ' ' * indent_level * self._spaces_per_tab
12
13 def print_function_definition(self, function_definition: SyntaxTree.FunctionDefinition, indent_level = 0):
14 namespace_header = f"""namespace {"::".join(function_definition._namespaces)} {{"""
15 namespace_footer = "}"
16 template_string = ""
17 if function_definition._template is not None:
18 template_strings = [argument.print(self) for argument in function_definition._template]
19 template_string = "template <" + ",".join(template_strings) + ">\n"
20
21 current_indent = indent_level + 1 # Indentation increases inside namespace
22 statement_prints = [statement.print(self, current_indent + 1) for statement in function_definition._body]
23 argument_prints = [argument.print(self) for argument in function_definition._arguments]
24
25 return f"""{namespace_header}
26{template_string}{self.get_indent(indent_level)}{function_definition._return_type.print(self)} {function_definition.id}({', '.join(argument_prints)}) {{
27{os.linesep.join(statement_prints)}
28{self.get_indent(indent_level)}}}
29{namespace_footer}
30"""
31
32 def print_function_declaration(self, function_definition: SyntaxTree.FunctionDefinition, indent_level=0):
33 namespace_header = f"""namespace {"::".join(function_definition._namespaces)} {{"""
34 namespace_footer = "}"
35 template_string = ""
36 if function_definition._template is not None:
37 template_strings = [argument.print(self) for argument in function_definition._template]
38 template_string = "template <" + ",".join(template_strings) + ">\n"
39
40 current_indent = indent_level + 1 # Indentation increases inside namespace
41 argument_prints = [argument.print(self) for argument in function_definition._arguments]
42
43 return f"""{namespace_header}
44{template_string}{self.get_indent(indent_level)}{function_definition._return_type.print(self)} {function_definition.id}({', '.join(argument_prints)});
45{namespace_footer}
46"""
47
48 def print_function_definition_with_timer(self, function_definition: SyntaxTree.FunctionDefinition, indent_level=0):
49 namespace_header = f"""namespace {"::".join(function_definition._namespaces)} {{"""
50 namespace_footer = "}"
51 template_string = ""
52 function_call_string = function_definition.id
53 if function_definition._template is not None:
54 template_strings = [argument.print(self) for argument in function_definition._template]
55 template_string = "template <" + ",".join(template_strings) + ">\n"
56 function_call_string += "<" + ",".join([template.split(' ')[1] for template in template_strings]) + ">"
57
58 arguments = copy.deepcopy(function_definition._arguments)
59 arguments.append(SyntaxTree.Argument("measurement", SyntaxTree.TCustom("tarch::timing::Measurement&")))
60
61 current_indent = indent_level + 1 # Indentation increases inside namespace
62 argument_prints = [argument.print(self) for argument in arguments]
63
64 return f"""{namespace_header}
65{template_string}{self.get_indent(indent_level)}{function_definition._return_type.print(self)} {function_definition.id}({', '.join(argument_prints)}) {{
66tarch::timing::Watch watch("{"::".join(function_definition._namespaces)}", "{function_definition.id}", false, true);
67{function_call_string}({",".join([argument.print(self).split(' ')[-1] for argument in function_definition._arguments])});
68watch.stop();
69measurement.setValue(watch.getCalendarTime());
70{self.get_indent(indent_level)}}}
71{namespace_footer}
72"""
73
74 def print_function_declaration_with_timer(self, function_definition: SyntaxTree.FunctionDefinition, indent_level=0):
75 namespace_header = f"""namespace {"::".join(function_definition._namespaces)} {{"""
76 namespace_footer = "}"
77 template_string = ""
78 if function_definition._template is not None:
79 template_strings = [argument.print(self) for argument in function_definition._template]
80 template_string = "template <" + ",".join(template_strings) + ">\n"
81
82 arguments = copy.deepcopy(function_definition._arguments)
83 arguments.append(SyntaxTree.Argument("measurement", SyntaxTree.TCustom("tarch::timing::Measurement&")))
84
85 current_indent = indent_level + 1 # Indentation increases inside namespace
86 argument_prints = [argument.print(self) for argument in arguments]
87
88 return f"""{namespace_header}
89{template_string}{self.get_indent(indent_level)}{function_definition._return_type.print(self)} {function_definition.id}({', '.join(argument_prints)});
90{namespace_footer}
91"""
92
93 def print_argument(self, argument: SyntaxTree.Argument, indent_level=0):
94 return self.get_indent(indent_level) + argument._type.print(self) + " " + argument.id
95
96 def print_name(self, name: SyntaxTree.Name, indent_level=0):
97 return self.get_indent(indent_level) + name.id
98
99 def print_integer(self, integer: SyntaxTree.Integer, indent_level=0):
100 if integer._string is None:
101 return self.get_indent(indent_level) + str(integer._value)
102 else:
103 return self.get_indent(indent_level) + str(integer._string)
104
105 def print_if(self, if_statement: SyntaxTree.If, indent_level=0):
106 statement_prints = [statement.print(self, indent_level + 1) for statement in if_statement._statements]
107 return self.get_indent(indent_level) + f"""if constexpr ({if_statement._boolean.print(self)}) {{
108{os.linesep.join(statement_prints)}
109""" + self.get_indent(indent_level) + "}"
110
111 def print_for(self, for_statement: SyntaxTree.For, indent_level = 0):
112 statement_prints = [statement.print(self, indent_level + 1) for statement in for_statement._statements]
113 if for_statement._use_scheduler:
114 return self.get_indent(indent_level) + f"""parallelForWithSchedulerInstructions({for_statement._iteration_variable.print(self)}, {for_statement._iteration_range[1].print(self)}, loopParallelism) {{
115{os.linesep.join(statement_prints)}
116{self.get_indent(indent_level)}}}
117endParallelFor"""
118 else:
119 return self.get_indent(indent_level) + f"""for (int {for_statement._iteration_variable.print(self)} = {for_statement._iteration_range[0].print(self)}; {for_statement._iteration_variable.print(self)} < {for_statement._iteration_range[1].print(self)}; {for_statement._iteration_variable.print(self)}++) {{
120{os.linesep.join(statement_prints)}
121""" + self.get_indent(indent_level) + "}"
122
123 def print_comment(self, comment: SyntaxTree.Comment, indent_level=0):
124 return self.get_indent(indent_level) + "//" + comment._comment[1:]
125
126 def print_function_call(self, function_call: SyntaxTree.FunctionCall, indent_level=0):
127 argument_prints = [argument.print(self) for argument in function_call._arguments]
128 return f"""{self.get_indent(indent_level)}{function_call.id}({", ".join(argument_prints)});"""
129
130 def print_max(self, max: SyntaxTree.Max, indent_level=0):
131 return f"{self.get_indent(indent_level)}std::max({max._lhs.print(self)}, {max._rhs.print(self)});"
132
133 def print_memory_allocation(self, memory_allocation: SyntaxTree.MemoryAllocation, indent_level=0):
134 if len(memory_allocation._dimensions) == 1:
135 return self.get_indent(indent_level) + f"""{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)}];"""
136 else:
137 if SyntaxTree.Node.use_accelerator == False and type(SyntaxTree.Name.variables[memory_allocation._name.id]) is not SyntaxTree.FaceDataBlock:
138 return self.get_indent(indent_level) + f"""{memory_allocation._type.print(self)}** {memory_allocation._name.print(self)} = new {memory_allocation._type.print(self)}*[{memory_allocation._dimensions[-1].print(self)}];
139{memory_allocation._loop.print(self, indent_level)}"""
140 else:
141 return self.get_indent(indent_level) + f"""{memory_allocation._type.print(self)}* {memory_allocation._name.print(self)} = new {memory_allocation._type.print(self)}[{(memory_allocation._size * memory_allocation._dimensions[-1]).print(self)}];"""
142
143 def print_memory_deallocation(self, memory_deallocation: SyntaxTree.MemoryDeallocation, indent_level=0):
144 if len(memory_deallocation._dimensions) == 1:
145 return self.get_indent(indent_level) + f"""delete[] {memory_deallocation._name.print(self)};"""
146 else:
147 if SyntaxTree.Node.use_accelerator == False and type(SyntaxTree.Name.variables[memory_deallocation._name.id]) is not SyntaxTree.FaceDataBlock:
148 return f"""{memory_deallocation._loop.print(self, indent_level)}
149{self.get_indent(indent_level)}delete[] {memory_deallocation._name.print(self)};"""
150 else:
151 return f"""{self.get_indent(indent_level)}delete[] {memory_deallocation._name.print(self)};"""
152
153 def print_assignment(self, assignment: SyntaxTree.Assignment, indent_level = 0):
154 lhs_print = assignment._lhs.print(self)
155 rhs_print = assignment._rhs.print(self)
156 return f"{self.get_indent(indent_level)}{lhs_print} = {rhs_print};"
157
158 def print_construction(self, construction: SyntaxTree.Construction, indent_level=0):
159 return self.get_indent(indent_level) + f"{construction._name.get_type().print(self)} {construction._name.print(self)} = {construction._expression.print(self)};"
160
161 def print_data_block_construction_from_existing(self, construction: SyntaxTree.DataBlockConstructionFromExisting, indent_level=0):
162 type_print = construction._name.get_type().print(self)
163 if isinstance(construction._name.get_type(), SyntaxTree.TDiagonalMatrix) or construction._name.id[-2:] == "1d":
164 type_print = "const double*"
165 if len(construction._dataBlock._iteration_range) > 1 and SyntaxTree.Node.use_accelerator == False and type(construction._dataBlock) is not SyntaxTree.FaceDataBlock:
166 type_print += "*"
167 return self.get_indent(indent_level) + f"{type_print} {construction._name.print(self)} = {construction._dataBlock._internal.print(self)};"
168
169 def print_data_block_construction_from_operation(self, construction: SyntaxTree.DataBlockConstructionFromOperation, indent_level=0):
170 return f"""{construction.memoryAllocation.print(self, indent_level)}
171{construction.assignment.print(self, indent_level)}"""
172
173 def print_data_block_construction_from_function(self, construction: SyntaxTree.DataBlockConstructionFromFunction, indent_level=0):
174 return f"""{construction.memoryAllocation.print(self, indent_level)}
175{construction.initialisation.print(self, indent_level)}"""
176
177 def print_data_block_construction_from_matrix_vector_product(self, construction: SyntaxTree.DataBlockConstructionFromFunction, indent_level=0):
178 return f"""{construction.memoryAllocation.print(self, indent_level)}
179{construction.assignment.print(self, indent_level)}"""
180
181 def print_data_block_construction_from_dot_product(self, construction: SyntaxTree.DataBlockConstructionFromFunction, indent_level=0):
182 return f"""{construction.memoryAllocation.print(self, indent_level)}
183{construction.assignment.print(self, indent_level)}"""
184
185 def print_diagonal_matrix(self, construction: SyntaxTree.DataBlockConstructionFromFunction, indent_level=0):
186 if construction._id is not None:
187 return construction._id.print(self, indent_level)
188 else:
189 return construction._internal.print(self, indent_level)
190
191 def print_matrix(self, construction: SyntaxTree.DataBlockConstructionFromFunction, indent_level=0):
192 if construction._id is not None:
193 return construction._id.print(self, indent_level)
194 else:
195 return construction._internal.print(self, indent_level)
196
197 def print_diagonal_matrix_construction_from_kronecker_product(self, construction: SyntaxTree.DataBlockConstructionFromFunction, indent_level=0):
198 return f"""{construction._memory_allocation.print(self, indent_level)}
199{construction._assignment.print(self, indent_level)}"""
200
201 def print_diagonal_matrix_construction_from_value(self, construction: SyntaxTree.DataBlockConstructionFromFunction, indent_level=0):
202 return f"""{construction._memory_allocation.print(self, indent_level)}
203{construction._assignment.print(self, indent_level)}"""
204
205 def print_matrix_construction_from_kronecker_product(self, construction: SyntaxTree.DataBlockConstructionFromFunction, indent_level=0):
206 return f"""{construction._memory_allocation.print(self, indent_level)}
207{construction._initialisation.print(self, indent_level)}
208{construction._assignment.print(self, indent_level)}"""
209
210 def print_data_block_assignment(self, assignment: SyntaxTree.DataBlockAssignment, indent_level=0):
211 return assignment._loop.print(self, indent_level)
212
213 def print_boolean(self, boolean: SyntaxTree.Boolean, indent_level = 0):
214 return self.get_indent(indent_level) + str(boolean.value)
215
216 def print_string(self, string: SyntaxTree.String, indent_level = 0):
217 return self.get_indent(indent_level) + str(string._value)
218
219 def print_float(self, float: SyntaxTree.Float, indent_level = 0):
220 if float._string is None:
221 return self.get_indent(indent_level) + str(float._value)
222 else:
223 return self.get_indent(indent_level) + str(float._string)
224
225 def print_data_block(self, data_block: SyntaxTree.DataBlock, indent_level=0):
226 if data_block.id is None:
227 return self.get_indent(indent_level) + data_block._internal.print(self)
228 else:
229 return self.get_indent(indent_level) + data_block.id
230
231 def print_subscript(self, subscript: SyntaxTree.Subscript, indent_level=0):
232 return f"{self.get_indent(indent_level)}{subscript._value.print(self)}[{subscript._index.print(self)}]"
233
234 def print_reference(self, reference: SyntaxTree.Reference, indent_level=0):
235 return f"{self.get_indent(indent_level)}&{reference._expression.print(self)}"
236
237 def print_vector(self, vector: SyntaxTree.Vector, indent_level=0):
238 if vector._string is None:
239 element_prints = [element.print(self) for element in vector._elements]
240 return f"""{self.get_indent(indent_level)}tarch::la::Vector<{len(vector._elements)}, {vector._type.print(self)}>{{{", ".join(element_prints)}}}"""
241 return vector._string
242
243 def print_vector_index(self, vector_index: SyntaxTree.VectorIndex, indent_level=0):
244 return f"{self.get_indent(indent_level)}{vector_index._value.print(self)}({vector_index._index.print(self)})"
245
246 def print_comparison(self, comparison: SyntaxTree.Comparison, indent_level=0):
247 return f"{self.get_indent(indent_level)}({comparison._lhs.print(self)} {comparison._operation} {comparison._rhs.print(self)})"
248
249 def print_binary_operation(self, binary_operation: SyntaxTree.BinaryOperation, indent_level=0):
250 return f"{self.get_indent(indent_level)}({binary_operation._lhs.print(self)} {binary_operation._operation} {binary_operation._rhs.print(self)})"
251
252 def print_unary_operation(self, unary_operation: SyntaxTree.UnaryOperation, indent_level=0):
253 return f"{self.get_indent(indent_level)}({unary_operation._operation} {unary_operation._operand.print(self)})"
254
255 def print_data_block_unary_max(self, unary_max: SyntaxTree.DataBlockUnaryMax, indent_level=0):
256 return unary_max._loop.print(self, indent_level)
257
258 def print_custom_type(self, type: SyntaxTree.TCustom, indent_level=0):
259 return self.get_indent(indent_level) + type._type
260
261 def print_void_type(self, type: SyntaxTree.TVoid, indent_level=0):
262 return self.get_indent(indent_level) + "void"
263
264 def print_integer_type(self, type: SyntaxTree.TInteger, indent_level=0):
265 return self.get_indent(indent_level) + "int"
266
267 def print_long_type(self, type: SyntaxTree.TLong, indent_level=0):
268 return self.get_indent(indent_level) + "long"
269
270 def print_boolean_type(self, type: SyntaxTree.TBoolean, indent_level=0):
271 return self.get_indent(indent_level) + "bool"
272
273 def print_float_type(self, type: SyntaxTree.TFloat, indent_level=0):
274 return self.get_indent(indent_level) + "double" + ("&" if type._reference else "")
275
276 def print_string_type(self, type: SyntaxTree.TString, indent_level=0):
277 return self.get_indent(indent_level) + "const char*"
278
279 def print_data_block_type(self, type: SyntaxTree.TDataBlock, indent_level=0):
280 return self.get_indent(indent_level) + type._underlying_type.print(self) + "*"
281
282 def print_matrix_type(self, type: SyntaxTree.TMatrix, indent_level=0):
283 return self.get_indent(indent_level) + type._underlying_type.print(self) + "*"
284
285 def print_diagonal_matrix_type(self, type: SyntaxTree.TDiagonalMatrix, indent_level=0):
286 return self.get_indent(indent_level) + type._underlying_type.print(self) + "*"
287
288 def print_nested_memref_type(self, type: SyntaxTree.TNestedMemref, indent_level=0):
289 return self.get_indent(indent_level) + "double**"
290
291 def print_simple_memref_type(self, type: SyntaxTree.TSimpleMemref, indent_level=0):
292 return self.get_indent(indent_level) + "void*"
293
294 def print_function_type(self, type: SyntaxTree.TFunctionType, indent_level=0):
295 return self.get_indent(indent_level) + "void*"
__init__(self, spaces_per_tab=2)
Definition CPPPrinter.py:7
print_function_declaration(self, SyntaxTree.FunctionDefinition function_definition, indent_level=0)
Definition CPPPrinter.py:32
print_argument(self, SyntaxTree.Argument argument, indent_level=0)
Definition CPPPrinter.py:93
str get_indent(self, int indent_level)
Definition CPPPrinter.py:10
print_function_definition_with_timer(self, SyntaxTree.FunctionDefinition function_definition, indent_level=0)
Definition CPPPrinter.py:48
print_integer(self, SyntaxTree.Integer integer, indent_level=0)
Definition CPPPrinter.py:99
print_function_declaration_with_timer(self, SyntaxTree.FunctionDefinition function_definition, indent_level=0)
Definition CPPPrinter.py:74
print_function_definition(self, SyntaxTree.FunctionDefinition function_definition, indent_level=0)
Definition CPPPrinter.py:13
print_for(self, SyntaxTree.For for_statement, indent_level=0)
print_if(self, SyntaxTree.If if_statement, indent_level=0)
print_name(self, SyntaxTree.Name name, indent_level=0)
Definition CPPPrinter.py:96