Branch data Line data Source code
1 : : // *****************************************************************************
2 : : /*!
3 : : \file src/Inciter/Partitioner.hpp
4 : : \copyright 2012-2015 J. Bakosi,
5 : : 2016-2018 Los Alamos National Security, LLC.,
6 : : 2019-2021 Triad National Security, LLC.,
7 : : 2022-2024 J. Bakosi
8 : : All rights reserved. See the LICENSE file for details.
9 : : \brief Charm++ chare partitioner nodegroup used to perform mesh
10 : : partitioning
11 : : \details Charm++ chare partitioner nodegroup used to perform mesh read and
12 : : partitioning, one worker per compute node.
13 : : */
14 : : // *****************************************************************************
15 : : #ifndef Partitioner_h
16 : : #define Partitioner_h
17 : :
18 : : #include <array>
19 : : #include <stddef.h>
20 : :
21 : : #include "ContainerUtil.hpp"
22 : : #include "DerivedData.hpp"
23 : : #include "UnsMesh.hpp"
24 : : #include "Sorter.hpp"
25 : : #include "Refiner.hpp"
26 : : #include "Callback.hpp"
27 : :
28 : : #include "NoWarning/partitioner.decl.h"
29 : :
30 : : namespace inciter {
31 : :
32 : : //! Partitioner Charm++ chare nodegroup class
33 : : //! \details Instantiations of Partitioner comprise a processor aware Charm++
34 : : //! chare node group. When instantiated, a new object is created on each
35 : : //! compute node and not more (as opposed to individual chares or chare array
36 : : //! object elements). See also the Charm++ interface file partitioner.ci.
37 : : class Partitioner : public CBase_Partitioner {
38 : :
39 : : private:
40 : : //! \brief Mesh data used for categorizing mesh chunks assigned to chares
41 : : //! after mesh partitioning and before mesh distribution across chares
42 : : using MeshData =
43 : : std::tuple<
44 : : // Tetrahedron (domain element) connectivity
45 : : std::vector< std::size_t >,
46 : : // Boundary face connectivity for each side set
47 : : std::unordered_map< int, std::vector< std::size_t > >,
48 : : // Boundary node lists for each side set
49 : : std::unordered_map< int, std::vector< std::size_t > > >;
50 : :
51 : : public:
52 : : //! Constructor
53 : : Partitioner( std::size_t meshid,
54 : : const std::string& filename,
55 : : const tk::PartitionerCallback& cbp,
56 : : const tk::RefinerCallback& cbr,
57 : : const tk::SorterCallback& cbs,
58 : : const CProxy_Transporter& host,
59 : : const CProxy_Refiner& refiner,
60 : : const CProxy_Sorter& sorter,
61 : : const tk::CProxy_MeshWriter& meshwriter,
62 : : const CProxy_Discretization& discretization,
63 : : const CProxy_RieCG& riecg,
64 : : const CProxy_LaxCG& laxcg,
65 : : const CProxy_ZalCG& zalcg,
66 : : const CProxy_KozCG& kozcg,
67 : : const CProxy_ChoCG& chocg,
68 : : const CProxy_LohCG& lohcg,
69 : : const tk::CProxy_ConjugateGradients& cgpre,
70 : : const tk::CProxy_ConjugateGradients& cgmom,
71 : : const std::map< int, std::vector< std::size_t > >& bface,
72 : : const std::map< int, std::vector< std::size_t > >& faces,
73 : : const std::map< int, std::vector< std::size_t > >& bnode );
74 : :
75 : : #if defined(__clang__)
76 : : #pragma clang diagnostic push
77 : : #pragma clang diagnostic ignored "-Wundefined-func-template"
78 : : #endif
79 : : //! Migrate constructor
80 : : // cppcheck-suppress uninitMemberVar
81 [ + - ][ + - ]: 25 : explicit Partitioner( CkMigrateMessage* m ) : CBase_Partitioner( m ) {}
[ + - ]
82 : : #if defined(__clang__)
83 : : #pragma clang diagnostic pop
84 : : #endif
85 : :
86 : : //! Configure Charm++ reduction types
87 : : static void registerReducers();
88 : :
89 : : //! Reduction target to aggregate mesh graphs
90 : : void graph( CkReductionMsg* msg );
91 : :
92 : : //! Reduction target to aggregate mesh partition assginments
93 : : void parts( CkReductionMsg* msg );
94 : :
95 : : //! Partition the computational mesh into a number of chares
96 : : void partition( int nchare );
97 : :
98 : : //! Receive mesh associated to chares we own after refinement
99 : : void addMesh( int fromnode,
100 : : const std::unordered_map< int,
101 : : std::tuple<
102 : : std::vector< std::size_t >,
103 : : tk::UnsMesh::CoordMap,
104 : : std::unordered_map< int, std::vector< std::size_t > >,
105 : : std::unordered_map< int, std::vector< std::size_t > >
106 : : > >& chmesh );
107 : :
108 : : //! Acknowledge received mesh after initial mesh refinement
109 : : void recvMesh();
110 : :
111 : : //! Optionally start refining the mesh
112 : : void refine();
113 : :
114 : : /** @name Charm++ pack/unpack serializer member functions */
115 : : ///@{
116 : : //! \brief Pack/Unpack serialize member function
117 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference
118 : : //! \note This is a Charm++ nodegroup, pup() is thus only for
119 : : //! checkpoint/restart.
120 : 357 : void pup( PUP::er &p ) override {
121 : 357 : p | m_meshid;
122 : 357 : p | m_cbp;
123 : 357 : p | m_cbr;
124 : 357 : p | m_cbs;
125 : 357 : p | m_host;
126 : 357 : p | m_refiner;
127 : 357 : p | m_sorter;
128 : 357 : p | m_meshwriter;
129 : 357 : p | m_discretization;
130 : 357 : p | m_riecg;
131 : 357 : p | m_laxcg;
132 : 357 : p | m_zalcg;
133 : 357 : p | m_kozcg;
134 : 357 : p | m_chocg;
135 : 357 : p | m_lohcg;
136 : 357 : p | m_cgpre;
137 : 357 : p | m_cgmom;
138 : 357 : p | m_ginpoel;
139 : 357 : p | m_graph;
140 : 357 : p | m_coord;
141 : 357 : p | m_inpoel;
142 : 357 : p | m_lid;
143 : 357 : p | m_ndist;
144 : 357 : p | m_nchare;
145 : 357 : p | m_nface;
146 : 357 : p | m_nodech;
147 : 357 : p | m_linnodes;
148 : 357 : p | m_chinpoel;
149 : 357 : p | m_chcoordmap;
150 : 357 : p | m_chbface;
151 : 357 : p | m_chtriinpoel;
152 : 357 : p | m_chbnode;
153 : 357 : p | m_bnodechares;
154 : 357 : p | m_bface;
155 : 357 : p | m_triinpoel;
156 : 357 : p | m_bnode;
157 : 357 : }
158 : : //! \brief Pack/Unpack serialize operator|
159 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference
160 : : //! \param[in,out] i Partitioner object reference
161 : : friend void operator|( PUP::er& p, Partitioner& i ) { i.pup(p); }
162 : : //@}
163 : :
164 : : private:
165 : : //! Mesh ID
166 : : std::size_t m_meshid;
167 : : //! Charm++ callbacks associated to compile-time tags for partitioner
168 : : tk::PartitionerCallback m_cbp;
169 : : //! Charm++ callbacks associated to compile-time tags for refiner
170 : : tk::RefinerCallback m_cbr;
171 : : //! Charm++ callbacks associated to compile-time tags for sorter
172 : : tk::SorterCallback m_cbs;
173 : : //! Host proxy
174 : : CProxy_Transporter m_host;
175 : : //! Mesh refiner proxy
176 : : CProxy_Refiner m_refiner;
177 : : //! Mesh sorter proxy
178 : : CProxy_Sorter m_sorter;
179 : : //! Mesh writer proxy
180 : : tk::CProxy_MeshWriter m_meshwriter;
181 : : //! Discretization base proxy
182 : : CProxy_Discretization m_discretization;
183 : : //! Discretization scheme proxy
184 : : CProxy_RieCG m_riecg;
185 : : //! Discretization scheme proxy
186 : : CProxy_LaxCG m_laxcg;
187 : : //! Discretization scheme proxy
188 : : CProxy_ZalCG m_zalcg;
189 : : //! Discretization scheme proxy
190 : : CProxy_KozCG m_kozcg;
191 : : //! Discretization scheme proxy
192 : : CProxy_ChoCG m_chocg;
193 : : //! Discretization scheme proxy
194 : : CProxy_LohCG m_lohcg;
195 : : //! Conjugate Gradients Charm++ proxy for pressure solve
196 : : tk::CProxy_ConjugateGradients m_cgpre;
197 : : //! Conjugate Gradients Charm++ proxy for momentum solve
198 : : tk::CProxy_ConjugateGradients m_cgmom;
199 : : //! Element connectivity of this compute node's mesh chunk (global ids)
200 : : std::vector< std::size_t > m_ginpoel;
201 : : //! Aggregated mesh graph of owned nodes if graph-based partitioner is used
202 : : std::unordered_map< std::size_t, std::vector< std::size_t > > m_graph;
203 : : //! Coordinates of mesh nodes of this compute node's mesh chunk
204 : : tk::UnsMesh::Coords m_coord;
205 : : //! \brief Element connectivity with local node IDs of this compute node's
206 : : //! mesh chunk
207 : : std::vector< std::size_t > m_inpoel;
208 : : //! Global->local node IDs of elements of this compute node's mesh chunk
209 : : //! \details Key: global node id, value: local node id
210 : : std::unordered_map< std::size_t, std::size_t > m_lid;
211 : : //! Counter during mesh distribution
212 : : std::size_t m_ndist;
213 : : //! Total number of chares across all compute nodes
214 : : int m_nchare;
215 : : //! Counters (for each chare owned) for assigning face ids in parallel
216 : : std::unordered_map< int, std::size_t > m_nface;
217 : : //! Chare IDs (value) associated to global mesh node IDs (key)
218 : : //! \details Multiple chares can contribute to a single node, hence vector
219 : : //! for map value.
220 : : std::unordered_map< std::size_t, std::vector< int > > m_nodech;
221 : : //! \brief Map associating new node IDs (as in producing contiguous-row-id
222 : : //! linear system contributions) as map-values to old node IDs (as in
223 : : //! file) as map-keys
224 : : std::unordered_map< std::size_t, std::size_t > m_linnodes;
225 : : //! Mesh connectivity using global node IDs associated to chares owned
226 : : std::unordered_map< int, std::vector< std::size_t > > m_chinpoel;
227 : : //! Coordinates associated to global node IDs of our mesh chunk for chares
228 : : std::unordered_map< int, tk::UnsMesh::CoordMap > m_chcoordmap;
229 : : //! Side set id + boundary face id for each chare
230 : : std::unordered_map< int,
231 : : std::map< int, std::vector< std::size_t > > > m_chbface;
232 : : //! Boundary face connectivity for each chare
233 : : std::map< int, std::vector< std::size_t > > m_chtriinpoel;
234 : : //! Side set id + boundary nodes for each chare
235 : : std::unordered_map< int,
236 : : std::map< int, std::vector< std::size_t > > > m_chbnode;
237 : : //! \brief Map associating a list of chare IDs to old (as in file) global
238 : : //! mesh node IDs on the chare boundaries
239 : : //! \details Note that a single global mesh node ID can be associated to
240 : : //! multiple chare IDs as multiple chares can contribute to a single node.
241 : : std::unordered_map< std::size_t, std::vector< int > > m_bnodechares;
242 : : //! Boundary face IDs associated associated to side set IDs
243 : : std::map< int, std::vector< std::size_t > > m_bface;
244 : : //! Boundary face-node connectivity
245 : : std::vector< std::size_t > m_triinpoel;
246 : : //! List of boundary nodes associated to side-set IDs
247 : : std::map< int, std::vector< std::size_t > > m_bnode;
248 : :
249 : : //! Categorize mesh elements (given by their gobal node IDs) by target
250 : : std::unordered_map< int, MeshData >
251 : : categorize( const std::vector< std::size_t >& che ) const;
252 : :
253 : : //! Extract coordinates associated to global nodes of a mesh chunk
254 : : tk::UnsMesh::CoordMap coordmap( const std::vector< std::size_t >& inpoel );
255 : :
256 : : //! Distribute mesh to target compute nodes after mesh partitioning
257 : : void distribute( std::unordered_map< int, MeshData >&& mesh );
258 : :
259 : : //! Compute chare (partition) distribution across compute nodes
260 : : std::array< int, 2 > distribution( int npart ) const;
261 : :
262 : : //! Return nodegroup id for chare id
263 : : int node( int id ) const;
264 : :
265 : : //! Continue after partitioning finished
266 : : void partitioned( std::vector< std::size_t >&& che );
267 : : };
268 : :
269 : : } // inciter::
270 : :
271 : : #endif // Partitioner_h
|