3from .DaStGenToLegacyTool
import DaStGenToLegacyTool
17 Simple generator mapping a DaStGen2 object onto a plain C++ class
25 return "peano4::stacks::STDVectorStack< " + self.
_data.get_full_qualified_type() +
" >";
29 return "#include \"peano4/stacks/STDVectorStack.h\" \n \
30 #include \"" + self.
_data.namespace[-1] +
"/" + self.
_data.name +
".h\""
36 Finally construct the output
38 Pass in an instance of the output object. We use this output
39 object only to register the generated C++ file with the build
43 full_qualified_name =
""
44 for i
in self.
_data.namespace:
45 full_qualified_name += i
46 full_qualified_name +=
"::"
47 full_qualified_name += self.
_data.name
48 self.
_data.data.set_full_qualified_name(full_qualified_name)
50 self.
_data.data.write_header_file( self.
_data.subdirectory + self.
_data.namespace[-1] +
"/" + self.
_data.name +
".h" )
51 self.
_data.data.write_implementation_file( self.
_data.subdirectory + self.
_data.namespace[-1] +
"/" + self.
_data.name +
".cpp" )
52 output.makefile.add_cpp_file( self.
_data.subdirectory + self.
_data.namespace[-1] +
"/" + self.
_data.name +
".cpp", generated=
True )
59 Simple generator mapping a DaStGen2 object onto a plain C++ class
61 The generator is very similar to DaStGen2Generator, but it has to take
62 extra care as we assume that some objects host smart pointers. Therefore,
63 we do two things: We dump the smart pointer version, and we create a
64 flattene version, too.
72 return "peano4::stacks::STDVectorStackOverObjectsWithSmartPointers< " + self.
_data.get_full_qualified_type() +
" >";
76 return "#include \"peano4/stacks/STDVectorStackOverObjectsWithSmartPointers.h\" \n \
77 #include \"" + self.
_data.namespace[-1] +
"/" + self.
_data.name +
".h\""
83 Finally construct the output
85 Pass in an instance of the output object. We use this output
86 object only to register the generated C++ file with the build
87 environment. This part is exactly the same as for a plain 1:1
90 Further to the default generator, this routine does a little bit
93 - Make a deep copy of the data object and replace each instance of
94 a smart pointer with its plain counterpart. This new data object
95 is identified by the extension _Flattened.
96 - Make the new helper data structure include the original class with
98 - Declare this one as an embedded type via using.
99 - Add a new copy constructor/conversion routine which really just maps
100 the two data types onto each other by using the setters and getters.
103 full_qualified_name =
""
104 for i
in self.
_data.namespace:
105 full_qualified_name += i
106 full_qualified_name +=
"::"
107 full_qualified_name += self.
_data.name
110 flattened_data_object = copy.copy(self.
_data.data)
111 old_attributes = flattened_data_object._attributes
112 flattened_data_object._attributes = []
114 for attribute
in old_attributes:
117 cardinality = attribute._cardinality,
118 ifdefs = attribute.ifdefs
121 flattened_data_object._attributes.append( attribute )
122 if attribute.ifdefs==[]:
123 copy_statements +=
"""
124result.set{}( static_cast<decltype(result.get{}())>( copy.get{}() ) );
125""".format(attribute.get_accessor_name(),
126 attribute.get_accessor_name(),
127 attribute.get_accessor_name()
130 copy_statements +=
"""
132result.set{}( static_cast<decltype(result.get{}())>( copy.get{}() ) );
135 attribute.get_accessor_name(),
136 attribute.get_accessor_name(),
137 attribute.get_accessor_name(),
141 extension =
"_Flattened"
142 full_qualified_name_flattened = full_qualified_name + extension
143 full_qualified_file_without_extension_flattened = self.
_data.subdirectory + self.
_data.namespace[-1] +
"/" + self.
_data.name + extension
146 self.
_data.data.additional_includes +=
"""
147#include "{}_Flattened.h"
148""".format(self.
_data.name)
156 self._data.data.public_fields =
"""
157 using FlattenedType = {}_Flattened;
159 static {} flatten(const {}& copy) {{
166 static {} unflatten(const {}& copy) {{
173""".format(self._data.name,
175 self._data.name + extension,
177 self._data.name + extension,
181 self._data.name + extension,
186 self._data.data.set_full_qualified_name(full_qualified_name)
187 self._data.data.write_header_file( self._data.subdirectory + self._data.namespace[-1] +
"/" + self._data.name +
".h" )
188 self._data.data.write_implementation_file( self._data.subdirectory + self._data.namespace[-1] +
"/" + self._data.name +
".cpp" )
189 output.makefile.add_cpp_file( self._data.subdirectory + self._data.namespace[-1] +
"/" + self._data.name +
".cpp", generated=
True )
191 flattened_data_object.set_full_qualified_name(full_qualified_name_flattened)
192 flattened_data_object.write_header_file( full_qualified_file_without_extension_flattened +
".h" )
193 flattened_data_object.write_implementation_file( full_qualified_file_without_extension_flattened +
".cpp" )
194 output.makefile.add_cpp_file( full_qualified_file_without_extension_flattened +
".cpp", generated=
True )
200 Default superclass for any data model in Peano which is stored within the grid
202 A DaStGen2 data type generator. To add fields to this object, just
203 use the DaStGen2 instance data of this field, i.e. data.add_attribute().
208 data: dastgen2.DataModel
209 Add elements to this guy to enrich your data model.
211 peano4_mpi_and_storage_aspect: peano4.dastgen2.MPIAndStorageAspect
212 This aspect adds the Peano-specific MPI routines to the data type,
213 i.e. routines used for boundary and re-balancing exchange. Modify
214 this one if you want to control certain data exchange or merge
220 I can control when to store data through the peano4_mpi_and_storage_aspect.
225 If you want to add your own MPI merge implementation, you have to
226 alter the attribute peano4_mpi_and_storage_aspect.
238 readme_descriptor =
"""
242 readme_package_descriptor =
"""
243### Data structure modelling
245Peano models its data structures via a tool called DaStGen. The actual DaStGen
246version in use is the second generation of DaStGen which is integrated into
247LLVM, e.g. The first generation of DaStGen has been a stand-alone Java tool
248which serves as a precompiler. As DaStGen 2 is not published yet, we appreciate
249a citation of the two original DaStGen papers when you discuss the memory needs:
252 @InProceedings{Bungartz:2008:DaStGen,
253 author={Bungartz, Hans--Joachim and Eckhardt, Wolfgang and Mehl, Miriam and Weinzierl, Tobias}, "
254 editor={Bubak, Marian and van Albada, Geert Dick and Dongarra, Jack and Sloot, Peter M. A.},
255 title={DaStGen---A Data Structure Generator for Parallel C++ HPC Software},
256 booktitle={Computational Science -- ICCS 2008},
258 publisher={Springer Berlin Heidelberg},
259 address={Berlin, Heidelberg}, "
261 isbn={978-3-540-69389-5}
265 @article{Bungartz:2010:DaStGen,
266 title = {A precompiler to reduce the memory footprint of multiscale PDE solvers in C++},
267 journal = {Future Generation Computer Systems},"
273 doi = {https://doi.org/10.1016/j.future.2009.05.011},
274 url = {https://www.sciencedirect.com/science/article/pii/S0167739X09000673},
275 author = {H.-J. Bungartz and W. Eckhardt and T. Weinzierl and C. Zenger},
276 keywords = {Data compaction and compression, Code generation, Multigrid and multilevel methods},
277 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.}
285 Construct a DaStGen2 object
287 We hold the data model and a dedicated data generator. By default, the data
288 model is augmented with geometric debug information. Every Peano data
289 object has an MPI aspect, i.e. can, in principle, be sent and received
293 super(DaStGen2, self).
__init__(name)
308 def configure(self, namespace, association, subdirectory=""):
313 Configuring an output means setting the right output directory and
314 taking into account whether we are associated to a vertex, face or
317 I always need the MPI aspect, but I can't add the right one in the
318 constructor, as I don't know whether this DaStGen model is used for
319 vertices, faces or cells. Such context however is important to generate
320 the correct merge routines with the correct signature. Therefore, I
321 hook into this routine.
324 super(DaStGen2, self).
configure(namespace,association,subdirectory)
338 @additional_load_and_store_arguments.setter
341 for new_argument
in new_arguments:
343#include \"""" + new_argument[1].replace(
"::",
"/") +
""".h"
351 Does class host a smart pointer attribute
353 The context is important when we pick the data generator, as objects with
354 a smart poiner have to be handled differently compared to plain objects.
357 for attribute
in self.
data._attributes:
Represents on DaStGen2 object, i.e.
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.
construct_output(self, output)
Finally construct the output.
get_stack_container(self)
get_header_file_include(self)
Simple generator mapping a DaStGen2 object onto a plain C++ class.
get_header_file_include(self)
construct_output(self, output)
Finally construct the output.
get_stack_container(self)
Default superclass for any data model in Peano which is stored within the grid.
hosts_smart_pointer_attribute(self)
Does class host a smart pointer attribute.
__init__(self, name)
Construct a DaStGen2 object.
_additional_load_and_store_arguments
configure(self, namespace, association, subdirectory="")
Configure output.
peano4_mpi_and_storage_aspect
additional_load_and_store_arguments(self)
_additional_load_and_store_arguments
construct_ifdef_string(symbol_list)
Return empty string if symbol_list is empty.