Peano
Loading...
Searching...
No Matches
MPIForSmartPointers.py
Go to the documentation of this file.
1# This file is part of the DaStGen2 project. For conditions of distribution and
2# use, please see the copyright notice at www.peano-framework.org
3from .Aspect import Aspect
4#import dastgen2
5
6from dastgen2.Utils import construct_ifdef_string
7
8from .MPI import MPI
9
10
12 """!
13
14 Represents the MPI aspect injected into a DaStGen model.
15
16 This object replaces the MPI aspect when we stream a DaStGen object onto
17 disk. The aspect makes the object behave like a non-persistent wrapper:
18 The very moment we issue a send or a receive, we start to hold an instance
19 of the flattened object to which we delegate all function calls.
20
21 The routine replacing the generic MPI aspect with this one is typically
22 peano4.api.datamodel.DaStGen2GeneratorForObjectsWithSmartPointers.
23
24 """
25
26 def __init__(self, data_model):
27 """!
28
29 This constructor has to know the underlying data model. So you have
30 to tell it to which object you attach the aspect to.
31
32 If we replace an existing MPI aspect with an instance of this object,
33 we can pass in aspect._data_model as argument. For peano4.api.datamodel.DaStGen2,
34 this reads as
35
36 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
37 for aspect in old_aspects:
38 if isinstance(aspect,dastgen2.aspects.MPI):
39 self._data.data._aspects.append( dastgen2.aspects.MPIForSmartPointers(aspect._data_model) )
40 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
41
42
43 """
44 self._data_model_data_model = data_model
45 pass
46
47 def get_include(self):
48 return """
49#ifdef Parallel
50 #include <mpi.h>
51 #include <functional>
52#endif
53
54#include "{}_Flattened.h"
55""".format( self._data_model_data_model.name )
56
57
58 def get_attributes(self):
59 return """
60 #ifdef Parallel
61 private:
62 int _senderDestinationRank;
63 #endif
64"""
65
66 def get_method_declarations(self, full_qualified_name):
67 return """
68 using SmartType = {};
69 using FlattenedType = {}_Flattened;
70
71 #ifdef Parallel
72 /**
73 * Hands out MPI datatype if we work without the LLVM MPI extension.
74 * If we work with this additional feature, this is the routine where
75 * the lazy initialisation is done and the datatype is also cached.
76 */
77 static MPI_Datatype getForkDatatype();
78
79 static MPI_Datatype getJoinDatatype();
80
81 static MPI_Datatype getBoundaryExchangeDatatype();
82
83 static MPI_Datatype getMultiscaleDataExchangeDatatype();
84
85 static MPI_Datatype getGlobalCommunciationDatatype();
86
87 static void freeForkDatatype();
88
89 static void freeJoinDatatype();
90
91 static void freeBoundaryExchangeDatatype();
92
93 static void freeMultiscaleDataExchangeDatatype();
94
95 static void freeGlobalCommunciationDatatype();
96
97 int getSenderRank() const;
98
99 static void initDatatype();
100
101 static void shutdownDatatype();
102
103 static void send(const SmartType& buffer, int destination, int tag, MPI_Comm communicator );
104 static void receive(SmartType& buffer, int source, int tag, MPI_Comm communicator );
105
106 static void send(const SmartType& buffer, int destination, int tag, std::function<void()> startCommunicationFunctor, std::function<void()> waitFunctor, MPI_Comm communicator );
107 static void receive(SmartType& buffer, int source, int tag, std::function<void()> startCommunicationFunctor, std::function<void()> waitFunctor, MPI_Comm communicator );
108 #endif
109
110 static FlattenedType flatten(const SmartType& copy);
111 static SmartType unflatten(const FlattenedType& copy);
112""".format(full_qualified_name,
113 full_qualified_name)
114
115
116 def get_implementation(self, full_qualified_name):
117 copy_statements = ""
118 for attribute in self._data_model_data_model._attributes:
119 if attribute.ifdefs==[]:
120 copy_statements += """
121result.set{}( static_cast<decltype(result.get{}())>( copy.get{}() ) );
122""".format(attribute.get_accessor_name(),
123 attribute.get_accessor_name(),
124 attribute.get_accessor_name()
125 )
126 else:
127 copy_statements += """
128{}
129result.set{}( static_cast<decltype(result.get{}())>( copy.get{}() ) );
130#endif
131""".format(construct_ifdef_string(attribute.ifdefs),
132 attribute.get_accessor_name(),
133 attribute.get_accessor_name(),
134 attribute.get_accessor_name(),
135 )
136
137 return """
138#ifdef Parallel
139void """ + full_qualified_name + """::freeForkDatatype() {
140 FlattenedType::freeForkDatatype();
141}
142
143void """ + full_qualified_name + """::freeGlobalCommunciationDatatype() {
144 FlattenedType::freeGlobalCommunciationDatatype();
145}
146
147void """ + full_qualified_name + """::freeJoinDatatype() {
148 FlattenedType::freeJoinDatatype();
149}
150
151void """ + full_qualified_name + """::freeBoundaryExchangeDatatype() {
152 FlattenedType::freeBoundaryExchangeDatatype();
153}
154
155void """ + full_qualified_name + """::freeMultiscaleDataExchangeDatatype() {
156 FlattenedType::freeMultiscaleDataExchangeDatatype();
157}
158
159int """ + full_qualified_name + """::getSenderRank() const {
160 return _senderDestinationRank;
161}
162
163void """ + full_qualified_name + """::initDatatype() {
164 FlattenedType::initDatatype();
165}
166
167void """ + full_qualified_name + """::shutdownDatatype() {
168 FlattenedType::shutdownDatatype();
169}
170
171void """ + full_qualified_name + """::send(const SmartType& buffer, int destination, int tag, MPI_Comm communicator ) {
172 FlattenedType sendReceiveObject( flatten(buffer) );
173 FlattenedType::send( sendReceiveObject, destination, tag, communicator );
174}
175
176void """ + full_qualified_name + """::receive(SmartType& buffer, int source, int tag, MPI_Comm communicator ) {
177 FlattenedType sendReceiveObject;
178 FlattenedType::receive(sendReceiveObject, source, tag, communicator);
179 buffer = unflatten( sendReceiveObject );
180 buffer._senderDestinationRank = sendReceiveObject.getSenderRank();
181}
182
183void """ + full_qualified_name + """::send(
184 const SmartType& buffer,
185 int destination,
186 int tag,
187 std::function<void()> startCommunicationFunctor,
188 std::function<void()> waitFunctor,
189 MPI_Comm communicator
190) {
191 FlattenedType sendReceiveObject( flatten(buffer) );
192 FlattenedType::send( sendReceiveObject, destination, tag, startCommunicationFunctor, waitFunctor, communicator );
193}
194
195void """ + full_qualified_name + """::receive(
196 SmartType& buffer,
197 int source,
198 int tag,
199 std::function<void()> startCommunicationFunctor,
200 std::function<void()> waitFunctor,
201 MPI_Comm communicator
202) {
203 FlattenedType sendReceiveObject;
204 FlattenedType::receive(sendReceiveObject, source, tag, startCommunicationFunctor, waitFunctor, communicator);
205 buffer = unflatten( sendReceiveObject );
206 buffer._senderDestinationRank = sendReceiveObject.getSenderRank();
207}
208#endif
209
210""" + full_qualified_name + """::FlattenedType """ + full_qualified_name + """::flatten(const SmartType& copy ) {
211 FlattenedType result;
212 """ + copy_statements + """
213 return result;
214}
215
216""" + full_qualified_name + """::SmartType """ + full_qualified_name + """::unflatten(const FlattenedType& copy ) {
217 SmartType result;
218 """ + copy_statements + """
219 return result;
220}
221"""
Superclass of each and every MPI aspect in Peano 4.
Definition Aspect.py:6
Represents the MPI aspect injected into a DaStGen model.
__init__(self, data_model)
This constructor has to know the underlying data model.