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