Branch data Line data Source code
1 : : // *****************************************************************************
2 : : /*!
3 : : \file src/Inciter/Ghosts.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 Declarations file for generating ghost data structures
9 : : \details Declarations file for asynchronous distributed
10 : : ghost data structures using Charm++.
11 : :
12 : : There are a potentially large number of Ghosts Charm++ chares.
13 : : Each Ghosts chare gets a chunk of the full load, due to partiting the mesh.
14 : :
15 : : The implementation uses the Charm++ runtime system and is fully
16 : : asynchronous, overlapping computation and communication. The algorithm
17 : : utilizes the structured dagger (SDAG) Charm++ functionality.
18 : : */
19 : : // *****************************************************************************
20 : : #ifndef Ghosts_h
21 : : #define Ghosts_h
22 : :
23 : : #include "Fields.hpp"
24 : : #include "FaceData.hpp"
25 : : #include "Discretization.hpp"
26 : :
27 : : #include "NoWarning/ghosts.decl.h"
28 : :
29 : : namespace inciter {
30 : :
31 : : //! Ghosts Charm++ chare array used to determine ghost data structures
32 : : class Ghosts : public CBase_Ghosts {
33 : :
34 : : public:
35 : : #if defined(__clang__)
36 : : #pragma clang diagnostic push
37 : : #pragma clang diagnostic ignored "-Wunused-parameter"
38 : : #pragma clang diagnostic ignored "-Wdeprecated-declarations"
39 : : #elif defined(STRICT_GNUC)
40 : : #pragma GCC diagnostic push
41 : : #pragma GCC diagnostic ignored "-Wunused-parameter"
42 : : #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
43 : : #elif defined(__INTEL_COMPILER)
44 : : #pragma warning( push )
45 : : #pragma warning( disable: 1478 )
46 : : #endif
47 : : // Include Charm++ SDAG code. See http://charm.cs.illinois.edu/manuals/html/
48 : : // charm++/manual.html, Sec. "Structured Control Flow: Structured Dagger".
49 : : Ghosts_SDAG_CODE
50 : : #if defined(__clang__)
51 : : #pragma clang diagnostic pop
52 : : #elif defined(STRICT_GNUC)
53 : : #pragma GCC diagnostic pop
54 : : #elif defined(__INTEL_COMPILER)
55 : : #pragma warning( pop )
56 : : #endif
57 : :
58 : : //! Constructor
59 : : explicit
60 : : Ghosts( const CProxy_Discretization& disc,
61 : : const std::map< int, std::vector< std::size_t > >& bface,
62 : : const std::vector< std::size_t >& triinpoel,
63 : : std::size_t nunk,
64 : : CkCallback cbDone );
65 : :
66 : : #if defined(__clang__)
67 : : #pragma clang diagnostic push
68 : : #pragma clang diagnostic ignored "-Wundefined-func-template"
69 : : #endif
70 : : //! Migrate constructor
71 : : // cppcheck-suppress uninitMemberVar
72 : 5213 : explicit Ghosts( CkMigrateMessage* ) {}
73 : : #if defined(__clang__)
74 : : #pragma clang diagnostic pop
75 : : #endif
76 : :
77 : : //! Local face & tet IDs associated to 3 global node IDs
78 : : //! \details This map stores tetrahedron cell faces (map key) and their
79 : : //! associated local face ID and inner local tet id adjacent to the face
80 : : //! (map value). A face is given by 3 global node IDs.
81 : : using FaceMap =
82 : : std::unordered_map< tk::UnsMesh::Face, // 3 global node IDs
83 : : std::array< std::size_t, 2 >, // local face & tet ID
84 : : tk::UnsMesh::Hash<3>,
85 : : tk::UnsMesh::Eq<3> >;
86 : :
87 : : //! Storage type for refined mesh used for field output
88 : : struct OutMesh {
89 : : //! Element connectivity, local->global node ids, global->local nodes ids
90 : : tk::UnsMesh::Chunk chunk;
91 : : //! Node coordinates
92 : : tk::UnsMesh::Coords coord;
93 : : //! Triangle element connectivity
94 : : std::vector< std::size_t > triinpoel;
95 : : //! Boundary-face connectivity
96 : : std::map< int, std::vector< std::size_t > > bface;
97 : : //! Node communinaction map
98 : : tk::NodeCommMap nodeCommMap;
99 : : //! \brief Pack/Unpack serialize member function
100 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference
101 : 15812 : void pup( PUP::er& p ) {
102 : 31624 : p|chunk; p|coord; p|triinpoel; p|bface; p|nodeCommMap;
103 : 15812 : }
104 : : //! Destroyer
105 [ + + ]: 22536 : void destroy() {
106 : : tk::destroy( std::get<0>(chunk) );
107 : : tk::destroy( std::get<1>(chunk) );
108 : 22536 : tk::destroy( std::get<2>(chunk) );
109 : : tk::destroy( coord[0] );
110 : : tk::destroy( coord[1] );
111 : : tk::destroy( coord[2] );
112 : : tk::destroy( triinpoel );
113 : 22536 : tk::destroy( bface );
114 : 22536 : tk::destroy( nodeCommMap );
115 : 22536 : }
116 : : };
117 : :
118 : : //! Discretization proxy
119 : : CProxy_Discretization m_disc;
120 : : //! Counter for number of unknowns on this chare (including ghosts)
121 : : std::size_t m_nunk;
122 : : //! Mesh connectivity extended
123 : : std::vector< std::size_t > m_inpoel;
124 : : //! Node coordinates extended
125 : : tk::UnsMesh::Coords m_coord;
126 : : //! Face data
127 : : FaceData m_fd;
128 : : //! Face geometry
129 : : tk::Fields m_geoFace;
130 : : //! Element geometry
131 : : tk::Fields m_geoElem;
132 : : //! Counter for number of faces on this chare (including chare boundaries)
133 : : std::size_t m_nfac;
134 : : //! Face & tet IDs associated to global node IDs of the face for each chare
135 : : //! \details This map stores not only the unique faces associated to
136 : : //! fellow chares, but also a newly assigned local face ID and adjacent
137 : : //! local tet ID.
138 : : std::unordered_map< int, FaceMap > m_bndFace;
139 : : //! Elements which are ghosts for other chares associated to those chare IDs
140 : : std::unordered_map< int, std::unordered_set< std::size_t > > m_sendGhost;
141 : : //! Local element id associated to ghost remote id charewise
142 : : //! \details This map associates the local element id (inner map value) to
143 : : //! the (remote) element id of the ghost (inner map key) based on the
144 : : //! chare id (outer map key) this remote element lies in.
145 : : std::unordered_map< int,
146 : : std::unordered_map< std::size_t, std::size_t > > m_ghost;
147 : : //! Expected ghost tet ids (used only in DEBUG)
148 : : std::set< std::size_t > m_exptGhost;
149 : : //! Map local ghost tet ids (value) and zero-based boundary ids (key)
150 : : std::unordered_map< std::size_t, std::size_t > m_bid;
151 : : //! Elements (value) surrounding point (key) data-structure
152 : : std::map< std::size_t, std::vector< std::size_t > > m_esup;
153 : : //! 1 if starting time stepping, 0 if during time stepping
154 : : std::size_t m_initial;
155 : :
156 : : //1 Start setup of communication maps for cell-centered schemes
157 : : void startCommSetup();
158 : :
159 : : //! Start sizing communication buffers and setting up ghost data
160 : : void resizeComm();
161 : :
162 : : //! Receive unique set of faces we potentially share with/from another chare
163 : : void comfac( int fromch, const tk::UnsMesh::FaceSet& infaces );
164 : :
165 : : //! Receive ghost data on chare boundaries from fellow chare
166 : : void comGhost( int fromch, const GhostData& ghost );
167 : :
168 : : //! Receive requests for ghost data
169 : : void reqGhost();
170 : :
171 : : //! Send all of our ghost data to fellow chares
172 : : void sendGhost();
173 : :
174 : : //! Setup node-neighborhood (esup)
175 : : void nodeNeighSetup();
176 : :
177 : : //! Receive element-surr-points data on chare boundaries from fellow chare
178 : : void comEsup( int fromch,
179 : : const std::unordered_map< std::size_t, std::vector< std::size_t > >&
180 : : bndEsup,
181 : : const std::unordered_map< std::size_t, std::vector< tk::real > >&
182 : : nodeBndCells );
183 : :
184 : : /** @name Pack/unpack (Charm++ serialization) routines */
185 : : ///@{
186 : : //! \brief Pack/Unpack serialize member function
187 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference
188 : 16154 : void pup( PUP::er &p ) override {
189 : 16154 : p | m_disc;
190 : 16154 : p | m_nunk;
191 : 16154 : p | m_inpoel;
192 : : p | m_coord;
193 : : p | m_fd;
194 : 16154 : p | m_geoFace;
195 : 16154 : p | m_geoElem;
196 : 16154 : p | m_nfac;
197 : 16154 : p | m_bndFace;
198 : 16154 : p | m_sendGhost;
199 : 16154 : p | m_ghost;
200 : 16154 : p | m_exptGhost;
201 : 16154 : p | m_bid;
202 : 16154 : p | m_esup;
203 : 16154 : p | m_initial;
204 : 16154 : p | m_ncomfac;
205 : 16154 : p | m_nadj;
206 : 16154 : p | m_ncomEsup;
207 : 16154 : p | m_ipface;
208 : 16154 : p | m_ghostData;
209 : 16154 : p | m_ghostReq;
210 : 16154 : p | m_expChBndFace;
211 : 16154 : p | m_infaces;
212 : 16154 : p | m_esupc;
213 : 16154 : p | m_cbAfterDone;
214 : 16154 : }
215 : : //! \brief Pack/Unpack serialize operator|
216 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference
217 : : //! \param[in,out] a Ghosts object reference
218 : : friend void operator|( PUP::er& p, Ghosts& a ) { a.pup(p); }
219 : : ///@}
220 : :
221 : : private:
222 : : using ncomp_t = tk::ncomp_t;
223 : :
224 : : //! Counter for face adjacency communication map
225 : : std::size_t m_ncomfac;
226 : : //! Counter signaling that all ghost data have been received
227 : : std::size_t m_nadj;
228 : : //! Counter for element-surr-node adjacency communication map
229 : : std::size_t m_ncomEsup;
230 : : //! Internal + physical boundary faces (inverse of inpofa)
231 : : tk::UnsMesh::FaceSet m_ipface;
232 : : //! Ghost data associated to chare IDs we communicate with
233 : : std::unordered_map< int, GhostData > m_ghostData;
234 : : //! Number of chares requesting ghost data
235 : : std::size_t m_ghostReq;
236 : : //! Unique set of chare-boundary faces this chare is expected to receive
237 : : tk::UnsMesh::FaceSet m_expChBndFace;
238 : : //! Incoming communication buffer during chare-boundary face communication
239 : : std::unordered_map< int, tk::UnsMesh::FaceSet > m_infaces;
240 : : //! Communication buffer for esup data-structure
241 : : std::map< std::size_t, std::vector< std::size_t > > m_esupc;
242 : : //! Function call to continue with in Scheme when Ghosts is done
243 : : CkCallback m_cbAfterDone;
244 : :
245 : : //! Access bound Discretization class pointer
246 : 356334 : Discretization* Disc() const {
247 : : Assert( m_disc[ thisIndex ].ckLocal() != nullptr, "ckLocal() null" );
248 : 712668 : return m_disc[ thisIndex ].ckLocal();
249 : : }
250 : :
251 : : //! Compute chare-boundary faces
252 : : void bndFaces();
253 : :
254 : : //! Setup own ghost data on this chare
255 : : void setupGhost();
256 : :
257 : : //! Continue after face adjacency communication map completed on this chare
258 : : void faceAdj();
259 : :
260 : : //! Compute partial boundary surface integral and sum across all chares
261 : : void bndIntegral();
262 : :
263 : : //! Continue after node adjacency communication map completed on this chare
264 : : void adj();
265 : :
266 : : //! Perform leak-test on chare boundary faces
267 : : bool leakyAdjacency();
268 : :
269 : : //! Check if esuf of chare-boundary faces matches
270 : : bool faceMatch();
271 : :
272 : : //! Verify that all chare-boundary faces have been received
273 : : bool receivedChBndFaces();
274 : :
275 : : //! Find any chare for face (given by 3 global node IDs)
276 : : int findchare( const tk::UnsMesh::Face& t );
277 : :
278 : : //! Check if entries in inpoel, inpofa and node-triplet are consistent
279 : : std::size_t nodetripletMatch(
280 : : const std::array< std::size_t, 2 >& id,
281 : : const tk::UnsMesh::Face& t );
282 : :
283 : : //! Fill elements surrounding a face along chare boundary
284 : : void addEsuf(
285 : : const std::array< std::size_t, 2 >& id,
286 : : std::size_t ghostid );
287 : :
288 : : //! Fill elements surrounding a element along chare boundary
289 : : void addEsuel(
290 : : const std::array< std::size_t, 2 >& id,
291 : : std::size_t ghostid,
292 : : const tk::UnsMesh::Face& t );
293 : :
294 : : //! Fill face-geometry data along chare boundary
295 : : void addGeoFace(
296 : : const tk::UnsMesh::Face& t,
297 : : const std::array< std::size_t, 2 >& id );
298 : : };
299 : :
300 : : } // inciter::
301 : :
302 : : #endif // Ghosts_h
|