Nektar++
AssemblyCommDG.h
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File AssemblyCommDG.h
4 //
5 // For more information, please see: http://www.nektar.info
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10 // Department of Aeronautics, Imperial College London (UK), and Scientific
11 // Computing and Imaging Institute, University of Utah (USA).
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining a
14 // copy of this software and associated documentation files (the "Software"),
15 // to deal in the Software without restriction, including without limitation
16 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 // and/or sell copies of the Software, and to permit persons to whom the
18 // Software is furnished to do so, subject to the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be included
21 // in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 // DEALINGS IN THE SOFTWARE.
30 //
31 // Description: Parallel communication methods for DG with MPI, header file
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 
35 #ifndef MULTIREGIONS_ASSEMBLY_COMM_DG_H
36 #define MULTIREGIONS_ASSEMBLY_COMM_DG_H
37 
39 #include <MultiRegions/ExpList.h>
40 
41 namespace Nektar
42 {
43 namespace MultiRegions
44 {
45 
46 /**
47  * The ExchangeMethod classes contain the required structure to distribute the
48  * Fwd trace of partition edges to the matching locations in the Bwd trace in
49  * the corresponding adjacent partitions. This allows for communication between
50  * neighbouring partitions in the physical mesh by exchanging quadrature point
51  * values.
52  */
54 {
55 public:
56  /// Default constructor
58 
59  /// Default destructor
61 
62  /**
63  * Perform MPI comm exchange taking the Fwd trace and
64  * sending partition edge trace values to the matching locations in the
65  * Bwd trace of corresponding adjacent partitions.
66  *
67  * @param[in] testFwd The values to send to adjacent partitions
68  * @param[out] testBwd The values received from adjacent partitions
69  */
71  const Array<OneD, NekDouble> &testFwd,
72  Array<OneD, NekDouble> &testBwd) = 0;
73 };
74 
75 typedef std::shared_ptr<ExchangeMethod> ExchangeMethodSharedPtr;
76 
77 /**
78  * If parallel operation is not indicated then use the Serial subclass which
79  * does not perform any exchange.
80  */
81 class Serial final : public ExchangeMethod
82 {
83 public:
84  /// Default constructor
86 
88  const Array<OneD, NekDouble> &testFwd,
89  Array<OneD, NekDouble> &testBwd) final
90  {
91  boost::ignore_unused(testFwd, testBwd);
92  }
93 };
94 
95 /**
96  * Uses the MPI_AllToAll collective operation to perform the exchange of
97  * quadrature values. This does not allow for varying exchange array sizes so
98  * padding is used to ensure all partitions send/receive the same length array.
99  * All ranks communicate full array sizes to all other ranks. One collective
100  * operation is posted on each rank which requires communication.
101  */
102 class AllToAll final : public ExchangeMethod
103 {
104 public:
105  /// Default constructor.
107  const LibUtilities::CommSharedPtr &comm, const int &maxQuad,
108  const int &nRanks,
109  const std::map<int, std::vector<int>> &rankSharedEdges,
110  const std::map<int, std::vector<int>> &edgeToTrace);
111 
113  const Array<OneD, NekDouble> &testFwd,
114  Array<OneD, NekDouble> &testBwd) final;
115 
116 private:
117  /// Communicator
119  /// Max number of quadrature points in an element
120  int m_maxQuad = 0;
121  /// Number of ranks/processes/partitions
122  int m_nRanks = 0;
123  /// List of trace map indices of the quad points to exchange
124  std::vector<int> m_allEdgeIndex;
125  /// Largest shared partition edge
126  int m_maxCount = 0;
127 };
128 
129 /**
130  * Uses the MPI_AllToAllV collective operation to perform the exchange of
131  * quadrature values. This allows for varying exchange array sizes to minimise
132  * communication data size. All ranks communicate to all other ranks, however
133  * the array size can be 0 to avoid unnecessary data transfer. One collective
134  * peration is posted on each rank which requires communication.
135  */
136 class AllToAllV final : public ExchangeMethod
137 {
138 public:
139  /// Default constructor.
141  const LibUtilities::CommSharedPtr &comm,
142  const std::map<int, std::vector<int>> &rankSharedEdges,
143  const std::map<int, std::vector<int>> &edgeToTrace, const int &nRanks);
144 
146  const Array<OneD, NekDouble> &testFwd,
147  Array<OneD, NekDouble> &testBwd) final;
148 
149 private:
150  /// Communicator
152  /// List of trace map indices of the quad points to exchange
153  std::vector<int> m_allVEdgeIndex;
154  /// List of counts for MPI_alltoallv
156  /// List of displacements for MPI_alltoallv
158 };
159 
160 /**
161  * Uses the MPI_NeighborAllToAllV collective operation to perform the exchange
162  * of quadrature values. This allows for varying exchange array sizes to
163  * minimise communication data size. Ranks only communicate with ranks with
164  * which they need to exchange data, i.e. are adjacent in the mesh or share a
165  * periodic boundary condition, this further minimises unnecessary data transfer
166  * over just reducing array sizes to 0 such as in MPI_AllToAllV. One collective
167  * operation is posted on each rank which requires communication.
168  */
169 class NeighborAllToAllV final : public ExchangeMethod
170 {
171 public:
172  /// Default constructor.
174  const LibUtilities::CommSharedPtr &comm,
175  const std::map<int, std::vector<int>> &rankSharedEdges,
176  const std::map<int, std::vector<int>> &edgeToTrace);
177 
179  const Array<OneD, NekDouble> &testFwd,
180  Array<OneD, NekDouble> &testBwd) final;
181 
182 private:
183  /// Communicator
185  /// List of displacements
187  /// List of trace map indices of the quad points to exchange
188  std::vector<int> m_edgeTraceIndex;
189  /// List of counts
191 };
192 
193 /**
194  * Uses persistent MPI_Irecv and MPI_Isend operations to perform the exchange of
195  * quadrature values. This allows for varying exchange array sizes to minimise
196  * communication data size. Ranks only communicate with ranks with which they
197  * need to exchange data, i.e. are adjacent in the mesh or share a periodic
198  * boundary condition. On each rank there are 'n' receives and 'n' sends posted
199  * where 'n' is the number of other ranks with which communication is needed.
200  * We use persistent communication methods to reduce overhead.
201  */
202 class Pairwise final : public ExchangeMethod
203 {
204 public:
206  const LibUtilities::CommSharedPtr &comm,
207  const std::map<int, std::vector<int>> &rankSharedEdges,
208  const std::map<int, std::vector<int>> &edgeToTrace);
209 
211  const Array<OneD, NekDouble> &testFwd,
212  Array<OneD, NekDouble> &testBwd) final;
213 
214 private:
215  /// Communicator
217  /// List of partition to trace map indices of the quad points to exchange
218  std::vector<std::pair<int, std::vector<int>>> m_vecPairPartitionTrace;
219  /// List of displacements
221  /// Receive buffer for exchange
223  /// Send buffer for exchange
225  /// List of receive requests
227  /// List of send requests
229 };
230 
231 /**
232  * @brief Implements communication for populating forward and backwards spaces
233  * across processors in the discontinuous Galerkin routines.
234  *
235  * The AssemblyCommDG class constructs various exchange methods for performing
236  * the action of communicating trace data from the forwards space of one
237  * processor to the backwards space of the corresponding neighbour element, and
238  * vice versa.
239  *
240  * This class initialises the structure for all exchange methods and then times
241  * to determine the fastest method for the particular system configuration, if
242  * running in serial configuration it assigns the #Serial exchange method. It
243  * then acts as a pass through to the chosen exchange method for the
244  * #PerformExchange function.
245  */
247 {
248 public:
249  /// Default destructor
251 
252  // Constructor for MPI communication methods
254  const ExpList &locExp, const ExpListSharedPtr &trace,
256  &elmtToTrace,
257  const Array<OneD, const ExpListSharedPtr> &bndCondExp,
259  &bndCond,
260  const PeriodicMap &perMap);
261 
262  /**
263  * @brief Perform the trace exchange between processors, given the forwards
264  * and backwards spaces.
265  *
266  * @param testFwd Local forwards space of the trace (which will be sent)
267  * @param testBwd Local bacwards space of the trace (which will receive
268  * contributions)
269  */
271  const Array<OneD, NekDouble> &testFwd, Array<OneD, NekDouble> &testBwd)
272  {
273  m_exchange->PerformExchange(testFwd, testBwd);
274  }
275 
276 private:
277  /// Chosen exchange method (either fastest parallel or serial)
279  /// Max number of quadrature points in an element
280  int m_maxQuad = 0;
281  /// Number of ranks/processes/partitions
282  int m_nRanks = 0;
283  /// Map of process to shared edge IDs
284  std::map<int, std::vector<int>> m_rankSharedEdges;
285  /// Map of edge ID to quad point trace indices
286  std::map<int, std::vector<int>> m_edgeToTrace;
287 
288  /// Initalises the structure for the MPI communication
289  void InitialiseStructure(
290  const ExpList &locExp, const ExpListSharedPtr &trace,
292  &elmtToTrace,
293  const Array<OneD, const ExpListSharedPtr> &bndCondExp,
295  &bndCond,
296  const PeriodicMap &perMap, const LibUtilities::CommSharedPtr &comm);
297 
298  /// Timing of the MPI exchange method.
299  static std::tuple<NekDouble, NekDouble, NekDouble> Timing(
300  const LibUtilities::CommSharedPtr &comm, const int &count,
301  const int &num, const ExchangeMethodSharedPtr& f);
302 };
303 
304 typedef std::shared_ptr<AssemblyCommDG> AssemblyCommDGSharedPtr;
305 
306 } // namespace MultiRegions
307 } // namespace Nektar
308 
309 #endif
#define MULTI_REGIONS_EXPORT
LibUtilities::CommSharedPtr m_comm
Communicator.
std::vector< int > m_allEdgeIndex
List of trace map indices of the quad points to exchange.
AllToAll(const LibUtilities::CommSharedPtr &comm, const int &maxQuad, const int &nRanks, const std::map< int, std::vector< int >> &rankSharedEdges, const std::map< int, std::vector< int >> &edgeToTrace)
Default constructor.
int m_nRanks
Number of ranks/processes/partitions.
int m_maxQuad
Max number of quadrature points in an element.
void PerformExchange(const Array< OneD, NekDouble > &testFwd, Array< OneD, NekDouble > &testBwd) final
int m_maxCount
Largest shared partition edge.
std::vector< int > m_allVEdgeIndex
List of trace map indices of the quad points to exchange.
void PerformExchange(const Array< OneD, NekDouble > &testFwd, Array< OneD, NekDouble > &testBwd) final
AllToAllV(const LibUtilities::CommSharedPtr &comm, const std::map< int, std::vector< int >> &rankSharedEdges, const std::map< int, std::vector< int >> &edgeToTrace, const int &nRanks)
Default constructor.
LibUtilities::CommSharedPtr m_comm
Communicator.
Array< OneD, int > m_allVSendCount
List of counts for MPI_alltoallv.
Array< OneD, int > m_allVSendDisp
List of displacements for MPI_alltoallv.
Implements communication for populating forward and backwards spaces across processors in the discont...
void PerformExchange(const Array< OneD, NekDouble > &testFwd, Array< OneD, NekDouble > &testBwd)
Perform the trace exchange between processors, given the forwards and backwards spaces.
void InitialiseStructure(const ExpList &locExp, const ExpListSharedPtr &trace, const Array< OneD, Array< OneD, LocalRegions::ExpansionSharedPtr >> &elmtToTrace, const Array< OneD, const ExpListSharedPtr > &bndCondExp, const Array< OneD, const SpatialDomains::BoundaryConditionShPtr > &bndCond, const PeriodicMap &perMap, const LibUtilities::CommSharedPtr &comm)
Initalises the structure for the MPI communication.
int m_maxQuad
Max number of quadrature points in an element.
std::map< int, std::vector< int > > m_edgeToTrace
Map of edge ID to quad point trace indices.
int m_nRanks
Number of ranks/processes/partitions.
~AssemblyCommDG()=default
Default destructor.
static std::tuple< NekDouble, NekDouble, NekDouble > Timing(const LibUtilities::CommSharedPtr &comm, const int &count, const int &num, const ExchangeMethodSharedPtr &f)
Timing of the MPI exchange method.
AssemblyCommDG(const ExpList &locExp, const ExpListSharedPtr &trace, const Array< OneD, Array< OneD, LocalRegions::ExpansionSharedPtr >> &elmtToTrace, const Array< OneD, const ExpListSharedPtr > &bndCondExp, const Array< OneD, const SpatialDomains::BoundaryConditionShPtr > &bndCond, const PeriodicMap &perMap)
std::map< int, std::vector< int > > m_rankSharedEdges
Map of process to shared edge IDs.
ExchangeMethodSharedPtr m_exchange
Chosen exchange method (either fastest parallel or serial)
ExchangeMethod()=default
Default constructor.
virtual ~ExchangeMethod()=default
Default destructor.
virtual void PerformExchange(const Array< OneD, NekDouble > &testFwd, Array< OneD, NekDouble > &testBwd)=0
Base class for all multi-elemental spectral/hp expansions.
Definition: ExpList.h:107
NeighborAllToAllV(const LibUtilities::CommSharedPtr &comm, const std::map< int, std::vector< int >> &rankSharedEdges, const std::map< int, std::vector< int >> &edgeToTrace)
Default constructor.
void PerformExchange(const Array< OneD, NekDouble > &testFwd, Array< OneD, NekDouble > &testBwd) final
std::vector< int > m_edgeTraceIndex
List of trace map indices of the quad points to exchange.
Array< OneD, int > m_sendDisp
List of displacements.
LibUtilities::CommSharedPtr m_comm
Communicator.
Array< OneD, int > m_sendCount
List of counts.
LibUtilities::CommRequestSharedPtr m_sendRequest
List of send requests.
Array< OneD, NekDouble > m_sendBuff
Send buffer for exchange.
Array< OneD, NekDouble > m_recvBuff
Receive buffer for exchange.
LibUtilities::CommRequestSharedPtr m_recvRequest
List of receive requests.
Array< OneD, int > m_sendDisp
List of displacements.
std::vector< std::pair< int, std::vector< int > > > m_vecPairPartitionTrace
List of partition to trace map indices of the quad points to exchange.
Pairwise(const LibUtilities::CommSharedPtr &comm, const std::map< int, std::vector< int >> &rankSharedEdges, const std::map< int, std::vector< int >> &edgeToTrace)
void PerformExchange(const Array< OneD, NekDouble > &testFwd, Array< OneD, NekDouble > &testBwd) final
LibUtilities::CommSharedPtr m_comm
Communicator.
void PerformExchange(const Array< OneD, NekDouble > &testFwd, Array< OneD, NekDouble > &testBwd) final
Serial()=default
Default constructor.
std::shared_ptr< CommRequest > CommRequestSharedPtr
Definition: Comm.h:86
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition: Comm.h:54
std::shared_ptr< AssemblyCommDG > AssemblyCommDGSharedPtr
std::shared_ptr< ExchangeMethod > ExchangeMethodSharedPtr
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
std::map< int, std::vector< PeriodicEntity > > PeriodicMap
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:1