Peano
Loading...
Searching...
No Matches
DaStGen2.py
Go to the documentation of this file.
1# This file is part of the Peano project. For conditions of distribution and
2# use, please see the copyright notice at www.peano-framework.org
3from .DaStGenToLegacyTool import DaStGenToLegacyTool
4from .DoF import DoF
5
6import dastgen2
7
10
11#import peano4
14
15import copy
16
17
18
19class DaStGen2Generator(object):
20 """!
21
22 Simple generator mapping a DaStGen2 object onto a plain C++ class
23
24 """
25 def __init__(self,data):
26 self._data = data
27
28
30 return "peano4::stacks::STDVectorStack< " + self._data.get_full_qualified_type() + " >";
31
32
34 return "#include \"peano4/stacks/STDVectorStack.h\" \n \
35 #include \"" + self._data.namespace[-1] + "/" + self._data.name + ".h\""
36
37
38 def construct_output(self,output):
39 """!
40
41 Finally construct the output
42
43 Pass in an instance of the output object. We use this output
44 object only to register the generated C++ file with the build
45 environment.
46
47 """
48 full_qualified_name = ""
49 for i in self._data.namespace:
50 full_qualified_name += i
51 full_qualified_name += "::"
52 full_qualified_name += self._data.name
53 self._data.data.set_full_qualified_name(full_qualified_name)
54
55 self._data.data.write_header_file( self._data.subdirectory + self._data.namespace[-1] + "/" + self._data.name + ".h" )
56 self._data.data.write_implementation_file( self._data.subdirectory + self._data.namespace[-1] + "/" + self._data.name + ".cpp" )
57 output.makefile.add_cpp_file( self._data.subdirectory + self._data.namespace[-1] + "/" + self._data.name + ".cpp", generated=True )
58
59
60
62 """!
63
64 Simple generator mapping a DaStGen2 object onto a plain C++ class
65
66 The generator is very similar to DaStGen2Generator, but it has to take
67 extra care as we assume that some objects host smart pointers. Therefore,
68 we do two things: We dump the smart pointer version, and we create a
69 flattene version, too.
70
71 """
72 def __init__(self,data):
73 self._data = data
74
75
77 return "peano4::stacks::STDVectorStackOverObjectsWithSmartPointers< " + self._data.get_full_qualified_type() + " >";
78
79
81 return "#include \"peano4/stacks/STDVectorStackOverObjectsWithSmartPointers.h\" \n \
82 #include \"" + self._data.namespace[-1] + "/" + self._data.name + ".h\""
83
84
85 def construct_output(self,output):
86 """!
87
88 Finally construct the output
89
90 Pass in an instance of the output object. We use this output
91 object only to register the generated C++ file with the build
92 environment. This part is exactly the same as for a plain 1:1
93 translation.
94
95 Further to the default generator, this routine does a little bit
96 more:
97
98 - Make a deep copy of the data object and replace each instance of
99 a smart pointer with its plain counterpart. This new data object
100 is identified by the extension _Flattened.
101 - Make the new helper data structure include the original class with
102 the smart pointers.
103 - Declare this one as an embedded type via using.
104 - Add a new copy constructor/conversion routine which really just maps
105 the two data types onto each other by using the setters and getters.
106 - Replace the MPI aspect in the original object with an with the
107 variant for smart pointers
108
109 """
110 full_qualified_name = ""
111 for i in self._data.namespace:
112 full_qualified_name += i
113 full_qualified_name += "::"
114 full_qualified_name += self._data.name
115
116 print( "No of aspects for {}: {}".format( full_qualified_name, len(self._data.data._aspects) ))
117
118 # flattened_data_object is of type dastgen2.DataModel
119 flattened_data_object = copy.copy(self._data.data)
120 old_attributes = self._data.data._attributes
121 old_aspects = flattened_data_object._aspects
122 flattened_data_object._attributes = []
123 self._data.data._aspects = []
124 for attribute in old_attributes:
125 if isinstance(attribute,peano4.dastgen2.Peano4SmartPointerDoubleArray):
126 flattened_data_object._attributes.append( peano4.dastgen2.Peano4DoubleArray( name = attribute._name,
127 cardinality = attribute._cardinality,
128 ifdefs = attribute.ifdefs
129 ))
130 else:
131 flattened_data_object._attributes.append( attribute )
132
133 for aspect in old_aspects:
134 if isinstance(aspect,dastgen2.aspects.MPI):
135 self._data.data._aspects.append( dastgen2.aspects.MPIForSmartPointers(aspect._data_model) )
136 elif isinstance(aspect,peano4.dastgen2.MPIAndStorageAspect):
137 self._data.peano4_mpi_and_storage_aspect = aspect
138 self._data.data._aspects.append( self._data.peano4_mpi_and_storage_aspect )
139 else:
140 self._data.data._aspects.append( aspect )
141
142 extension = "_Flattened"
143 full_qualified_name_flattened = full_qualified_name + extension
144 full_qualified_file_without_extension_flattened = self._data.subdirectory + self._data.namespace[-1] + "/" + self._data.name + extension
145
146 self._data.data.set_full_qualified_name(full_qualified_name)
147 self._data.data.write_header_file( self._data.subdirectory + self._data.namespace[-1] + "/" + self._data.name + ".h" )
148 self._data.data.write_implementation_file( self._data.subdirectory + self._data.namespace[-1] + "/" + self._data.name + ".cpp" )
149 output.makefile.add_cpp_file( self._data.subdirectory + self._data.namespace[-1] + "/" + self._data.name + ".cpp", generated=True )
150
151 flattened_data_object.set_full_qualified_name(full_qualified_name_flattened)
152 flattened_data_object.write_header_file( full_qualified_file_without_extension_flattened + ".h" )
153 flattened_data_object.write_implementation_file( full_qualified_file_without_extension_flattened + ".cpp" )
154 output.makefile.add_cpp_file( full_qualified_file_without_extension_flattened + ".cpp", generated=True )
155
156
158 """!
159
160 Default superclass for any data model in Peano which is stored within the grid
161
162 A DaStGen2 data type generator. To add fields to this object, just
163 use the DaStGen2 instance data of this field, i.e. data.add_attribute().
164
165 @image html dof-class-diagram.png
166
167 By default, we add x and h to the attributes. The DataModel object also can
168 host aspects, i.e. classes which inject technical code snippets into each
169 and every instance. By default, we add peano4.dastgen2.MPIAndStorageAspect
170 and dastgen2.aspect.MPI, but yuo might want to add further ones.
171
172 The actual dump into a C++ file is not done by the DaStGen2 object.
173 Instead, we hold a generator object which does this translation. In that
174 sense, the DaStGen2 object is almost an empty wrapper which tailors the
175 underlying data model, but adds no further specific behaviour.
176
177 There are two code generations: The default one, and then one that we have
178 to employ if the underlying data object hosts a smart pointer.
179
180
181 ## Attributes
182
183 data: dastgen2.DataModel
184 Add elements to this guy to enrich your data model.
185
186 peano4_mpi_and_storage_aspect: peano4.dastgen2.MPIAndStorageAspect
187 This aspect adds the Peano-specific MPI routines to the data type,
188 i.e. routines used for boundary and re-balancing exchange. Modify
189 this one if you want to control certain data exchange or merge
190 patterns.
191
192
193 ## Data storage
194
195 I can control when to store data through the peano4_mpi_and_storage_aspect.
196
197
198 ## MPI
199
200 If you want to add your own MPI merge implementation, you have to
201 alter the attribute peano4_mpi_and_storage_aspect.
202
203 ## Arguments
204
205 name: String
206 Name (unqualified)
207
208
209
210 """
211
212
213 readme_descriptor = """
214"""
215
216
217 readme_package_descriptor = """
218### Data structure modelling
219
220Peano models its data structures via a tool called DaStGen. The actual DaStGen
221version in use is the second generation of DaStGen which is integrated into
222LLVM, e.g. The first generation of DaStGen has been a stand-alone Java tool
223which serves as a precompiler. As DaStGen 2 is not published yet, we appreciate
224a citation of the two original DaStGen papers when you discuss the memory needs:
225
226
227 @InProceedings{Bungartz:2008:DaStGen,
228 author={Bungartz, Hans--Joachim and Eckhardt, Wolfgang and Mehl, Miriam and Weinzierl, Tobias}, "
229 editor={Bubak, Marian and van Albada, Geert Dick and Dongarra, Jack and Sloot, Peter M. A.},
230 title={DaStGen---A Data Structure Generator for Parallel C++ HPC Software},
231 booktitle={Computational Science -- ICCS 2008},
232 year=2008,
233 publisher={Springer Berlin Heidelberg},
234 address={Berlin, Heidelberg}, "
235 pages={213--222},
236 isbn={978-3-540-69389-5}
237 }
238
239
240 @article{Bungartz:2010:DaStGen,
241 title = {A precompiler to reduce the memory footprint of multiscale PDE solvers in C++},
242 journal = {Future Generation Computer Systems},"
243 volume = {26},
244 number = {1},
245 pages = {175-182},
246 year = {2010},
247 issn = {0167-739X},
248 doi = {https://doi.org/10.1016/j.future.2009.05.011},
249 url = {https://www.sciencedirect.com/science/article/pii/S0167739X09000673},
250 author = {H.-J. Bungartz and W. Eckhardt and T. Weinzierl and C. Zenger},
251 keywords = {Data compaction and compression, Code generation, Multigrid and multilevel methods},
252 abstract = {A PDE solver's value is increasingly co-determined by its memory footprint, as the increase of computational multicore power overtakes the memory access speed, and as memory restricts the maximum experiment size. Tailoring a code to require less memory is technical challenging, error-prone, and hardware-dependent. Object-oriented code typically consumes much memory, though developers favour such high-level languages offering meaningful models and good maintainability. We augment the language C++ with new keywords branding records to be memory-critical. Our precompiler DaStGen then transforms this augmented specification into plain C++ optimised for low memory requirements. Hereby, it encodes multiple attributes with fixed range within one variable, and it reduces the number of bits per floating point value. The tool also generates one user-defined MPI data type per class and, thus, facilitates the construction of parallel codes with small messages.}
253 }
254"""
255
256
257 def __init__(self, name):
258 """!
259
260 Construct a DaStGen2 object
261
262 We hold the data model and a dedicated data generator. By default, the data
263 model is augmented with geometric debug information. Every Peano data
264 object has an MPI aspect, i.e. can, in principle, be sent and received
265 through MPI.
266
267 By default, each Peano dat model also realises the MPIAndStorageAspect
268 which requires special treatment:
269
270 ## MPI and storage aspect
271
272 Normally, we just hold all the aspects in a long list and generate them one
273 by one. The MPI and storage aspect is a little bit different: If we add the
274 Peano-specific one, we still want later to modify parts of it. That is, we
275 would have to run through all the aspects one by one, pick out the MPI and
276 storage one, and then alter this one. So what we do instead is that we hold
277 it as a dedicated attribute and also add it to the list.
278
279 """
280 super(DaStGen2, self).__init__(name)
281
282 # is set by configure() lazily
283 self.generator = None
284
286
287 self.data.add_attribute( peano4.dastgen2.Peano4DoubleArray( "debugX", "Dimensions", ifdefs=["PeanoDebug>0"] ) )
288 self.data.add_attribute( peano4.dastgen2.Peano4DoubleArray( "debugH", "Dimensions", ifdefs=["PeanoDebug>0"] ) )
289
290 self.peano4_mpi_and_storage_aspect = peano4.dastgen2.MPIAndStorageAspect(peano4.datamodel.DoFAssociation.Undef)
291
292 self.data.add_aspect( self.peano4_mpi_and_storage_aspect )
293 self.data.add_aspect( dastgen2.aspects.MPI() )
294
295
296 def configure(self, namespace, association, subdirectory=""):
297 """!
298
299 Configure output
300
301 Configuring an output means setting the right output directory and
302 taking into account whether we are associated to a vertex, face or
303 cell.
304
305 I always need the MPI aspect, but I can't add the right one in the
306 constructor, as I don't know whether this DaStGen model is used for
307 vertices, faces or cells. Such context however is important to generate
308 the correct merge routines with the correct signature. Therefore, I
309 hook into this routine.
310
311 """
312 super(DaStGen2, self).configure(namespace,association,subdirectory)
313 self.peano4_mpi_and_storage_aspect.dof_association = association
314
317 else:
318 self.generator = DaStGen2Generator(self)
319
320
321 @property
326 @additional_load_and_store_arguments.setter
327 def additional_load_and_store_arguments(self,new_arguments):
328 self.peano4_mpi_and_storage_aspect.additional_load_and_store_arguments = [ (x[1],x[2]) for x in new_arguments]
329 for new_argument in new_arguments:
330 self.peano4_mpi_and_storage_aspect.includes.append( """
331#include \"""" + new_argument[1].replace("::","/") + """.h"
332""")
334
335
337 """!
338
339 Does class host a smart pointer attribute
340
341 The context is important when we pick the data generator, as objects with
342 a smart poiner have to be handled differently compared to plain objects.
343
344 """
345 for attribute in self.data._attributes:
346 if isinstance(attribute,peano4.dastgen2.Peano4SmartPointerDoubleArray):
347 return True
348 return False
349
Represents on DaStGen2 object, i.e.
Definition DataModel.py:8
Represents the MPI aspect injected into a DaStGen model.
Represents the MPI aspect injected into a DaStGen model.
Definition MPI.py:9
Represents Peano's MPI and storage aspect injected into a DaStGen model.
Specialisation of array using Peano's tarch.
Specialisation of array using Peano's tarch with a smart pointer.
Simple generator mapping a DaStGen2 object onto a plain C++ class.
Definition DaStGen2.py:61
construct_output(self, output)
Finally construct the output.
Definition DaStGen2.py:85
Simple generator mapping a DaStGen2 object onto a plain C++ class.
Definition DaStGen2.py:19
construct_output(self, output)
Finally construct the output.
Definition DaStGen2.py:38
Default superclass for any data model in Peano which is stored within the grid.
Definition DaStGen2.py:157
hosts_smart_pointer_attribute(self)
Does class host a smart pointer attribute.
Definition DaStGen2.py:336
__init__(self, name)
Construct a DaStGen2 object.
Definition DaStGen2.py:257
configure(self, namespace, association, subdirectory="")
Configure output.
Definition DaStGen2.py:296
Base class for any degree of freedom object.
Definition DoF.py:56