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