Branch data Line data Source code
1 : : // ***************************************************************************** 2 : : /*! 3 : : \file src/Inciter/Sorter.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 Mesh sorter for global distributed mesh reordering 9 : : \details Mesh sorter is Charm++ chare array and is used to do global 10 : : distributed mesh node reordering that yields consecutive unique global node 11 : : IDs with increasing PE IDs in asynchronous distributed-memory parallel 12 : : fashion. 13 : : */ 14 : : // ***************************************************************************** 15 : : #ifndef Sorter_h 16 : : #define Sorter_h 17 : : 18 : : #include <vector> 19 : : #include <map> 20 : : #include <unordered_map> 21 : : 22 : : #include "TaggedTuple.hpp" 23 : : #include "Tags.hpp" 24 : : #include "Callback.hpp" 25 : : #include "UnsMesh.hpp" 26 : : #include "UnsMesh.hpp" 27 : : #include "Scheme.hpp" 28 : : #include "CommMap.hpp" 29 : : 30 : : #include "NoWarning/transporter.decl.h" 31 : : #include "NoWarning/sorter.decl.h" 32 : : 33 : : namespace inciter { 34 : : 35 : : //! Mesh sorter for global distributed mesh node reordering 36 : : class Sorter : public CBase_Sorter { 37 : : 38 : : #if defined(__clang__) 39 : : #pragma clang diagnostic push 40 : : #pragma clang diagnostic ignored "-Wunused-parameter" 41 : : #pragma clang diagnostic ignored "-Wdeprecated-declarations" 42 : : #elif defined(STRICT_GNUC) 43 : : #pragma GCC diagnostic push 44 : : #pragma GCC diagnostic ignored "-Wunused-parameter" 45 : : #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 46 : : #elif defined(__INTEL_COMPILER) 47 : : #pragma warning( push ) 48 : : #pragma warning( disable: 1478 ) 49 : : #endif 50 : : // Include Charm++ SDAG code. See http://charm.cs.illinois.edu/manuals/html/ 51 : : // charm++/manual.html, Sec. "Structured Control Flow: Structured Dagger". 52 : : Sorter_SDAG_CODE 53 : : #if defined(__clang__) 54 : : #pragma clang diagnostic pop 55 : : #elif defined(STRICT_GNUC) 56 : : #pragma GCC diagnostic pop 57 : : #elif defined(__INTEL_COMPILER) 58 : : #pragma warning( pop ) 59 : : #endif 60 : : 61 : : public: 62 : : //! Constructor 63 : : explicit Sorter( std::size_t meshid, 64 : : const CProxy_Transporter& transporter, 65 : : const tk::CProxy_MeshWriter& meshwriter, 66 : : const tk::SorterCallback& cbs, 67 : : const std::vector< Scheme >& scheme, 68 : : CkCallback reorderRefiner, 69 : : const std::vector< std::size_t >& ginpoel, 70 : : const tk::UnsMesh::CoordMap& coordmap, 71 : : const tk::UnsMesh::Chunk& el, 72 : : const std::map< int, std::vector< std::size_t > >& bface, 73 : : const std::vector< std::size_t >& triinpoel, 74 : : const std::map< int, std::vector< std::size_t > >& bnode, 75 : : const std::unordered_map< std::size_t, std::set< std::size_t > >& 76 : : elemblockid, 77 : : int nchare ); 78 : : 79 : : #if defined(__clang__) 80 : : #pragma clang diagnostic push 81 : : #pragma clang diagnostic ignored "-Wundefined-func-template" 82 : : #endif 83 : : //! Migrate constructor 84 : : // cppcheck-suppress uninitMemberVarPrivate 85 : 7785 : explicit Sorter( CkMigrateMessage* ) {} 86 : : #if defined(__clang__) 87 : : #pragma clang diagnostic pop 88 : : #endif 89 : : 90 : : //! Configure Charm++ reduction types 91 : : static void registerReducers(); 92 : : 93 : : //! Setup chare mesh boundary node communication map 94 : : void setup( std::size_t npoin ); 95 : : //! \brief Incoming query for a list mesh nodes for which this chare 96 : : //! compiles communication maps 97 : : void query( int fromch, const tk::AllCommMaps& bnd ); 98 : : //! Report receipt of boundary node lists 99 : : void recvquery(); 100 : : //! Respond to boundary node list queries 101 : : void response(); 102 : : //! Receive boundary node communication maps for our mesh chunk 103 : : void bnd( int fromch, const tk::CommMaps& msum ); 104 : : //! Receive receipt of boundary node communication map 105 : : void recvbnd(); 106 : : 107 : : //! Start reordering (if user enabled it) 108 : : void start(); 109 : : 110 : : //! \brief Receive number of uniquely assigned global mesh node IDs from 111 : : //! chares with lower indices 112 : : void offset( int c, std::size_t u ); 113 : : 114 : : //! Request new global node IDs for old node IDs 115 : : void request( int c, const std::unordered_set< std::size_t >& nd ); 116 : : 117 : : //! Receive lower bound of node IDs our PE operates on after reordering 118 : : void lower( std::size_t low ); 119 : : 120 : : //! Receive new (reordered) global node IDs and coordinates 121 : : void neworder( const std::unordered_map< std::size_t, 122 : : std::tuple< std::size_t, tk::UnsMesh::Coord > >& nodes ); 123 : : 124 : : //! Create worker chare array elements on this PE 125 : : void createWorkers(); 126 : : 127 : : //! Update mesh data we hold for whoever calls this function 128 : : void mesh( std::vector< std::size_t >& ginpoel, 129 : : tk::UnsMesh::CoordMap& coordmap, 130 : : std::vector< std::size_t >& triinpoel, 131 : : std::map< int, std::vector< std::size_t > >& bnode ); 132 : : 133 : : /** @name Charm++ pack/unpack serializer member functions */ 134 : : ///@{ 135 : : //! \brief Pack/Unpack serialize member function 136 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 137 : 24125 : void pup( PUP::er &p ) override { 138 : 24125 : p | m_meshid; 139 : 24125 : p | m_host; 140 : 24125 : p | m_meshwriter; 141 : : p | m_cbs; 142 : 24125 : p | m_scheme; 143 : 24125 : p | m_reorderRefiner; 144 : 24125 : p | m_ginpoel; 145 : 24125 : p | m_coordmap; 146 : 24125 : p | m_el; 147 : 24125 : p | m_nbnd; 148 : 24125 : p | m_bface; 149 : 24125 : p | m_triinpoel; 150 : 24125 : p | m_bnode; 151 : 24125 : p | m_elemblockid; 152 : 24125 : p | m_nchare; 153 : 24125 : p | m_nodeset; 154 : 24125 : p | m_noffset; 155 : 24125 : p | m_nodech; 156 : 24125 : p | m_chnode; 157 : 24125 : p | m_edgech; 158 : 24125 : p | m_chedge; 159 : 24125 : p | m_msum; 160 : 24125 : p | m_reordcomm; 161 : 24125 : p | m_start; 162 : 24125 : p | m_newnodes; 163 : 24125 : p | m_newcoordmap; 164 : 24125 : p | m_reqnodes; 165 : 24125 : p | m_lower; 166 : 24125 : p | m_upper; 167 : 24125 : } 168 : : //! \brief Pack/Unpack serialize operator| 169 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 170 : : //! \param[in,out] s Sorter object reference 171 : : friend void operator|( PUP::er& p, Sorter& s ) { s.pup(p); } 172 : : //@} 173 : : 174 : : private: 175 : : //! Mesh ID 176 : : std::size_t m_meshid; 177 : : //! Host proxy 178 : : CProxy_Transporter m_host; 179 : : //! MeshWriter proxy 180 : : tk::CProxy_MeshWriter m_meshwriter; 181 : : //! Charm++ callbacks associated to compile-time tags for sorter 182 : : tk::SorterCallback m_cbs; 183 : : //! Discretization schemes (one per mesh) 184 : : std::vector< Scheme > m_scheme; 185 : : //! Callback to use to send reordered mesh to Refiner 186 : : CkCallback m_reorderRefiner; 187 : : //! Tetrtahedron element connectivity of our chunk of the mesh (global ids) 188 : : std::vector< std::size_t > m_ginpoel; 189 : : //! Coordinates associated to global node IDs of our mesh chunk 190 : : tk::UnsMesh::CoordMap m_coordmap; 191 : : //! Elements of the mesh chunk we operate on 192 : : tk::UnsMesh::Chunk m_el; 193 : : //! Counter for number of chares contributing to chare boundary nodes 194 : : std::size_t m_nbnd; 195 : : //! List of boundary faces associated to side-set IDs 196 : : std::map< int, std::vector< std::size_t > > m_bface; 197 : : //! Boundary face-node connectivity 198 : : std::vector< std::size_t > m_triinpoel; 199 : : //! List of boundary nodes associated to side-set IDs 200 : : std::map< int, std::vector< std::size_t > > m_bnode; 201 : : //! Local tet ids associated with mesh block ids 202 : : std::unordered_map< std::size_t, std::set< std::size_t > > m_elemblockid; 203 : : //! Total number of sorter chares 204 : : int m_nchare; 205 : : //! Unique global node IDs chares on our PE will contribute to 206 : : std::set< std::size_t > m_nodeset; 207 : : //! \brief Counter for the number of chares from which this chare has 208 : : //! received node reordering offsets from 209 : : int m_noffset; 210 : : //! Node->chare map used to build boundary node communication maps 211 : : std::unordered_map< std::size_t, std::vector< int > > m_nodech; 212 : : //! Chare->node map used to build boundary node communication maps 213 : : tk::NodeCommMap m_chnode; 214 : : //! Edge->chare map used to build boundary edge communication maps 215 : : std::unordered_map< tk::UnsMesh::Edge, std::vector< int >, 216 : : tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> > m_edgech; 217 : : //! Chare->edge map used to build boundary edge communication maps 218 : : tk::EdgeCommMap m_chedge; 219 : : //! Communication maps associated to chare IDs 220 : : tk::CommMaps m_msum; 221 : : //! \brief Communication map used for distributed mesh node reordering 222 : : //! \details This map associates the list of global mesh point 223 : : //! indices to fellow chare IDs from which this chare receives new node 224 : : //! IDs during reordering. Only data that will be received from chares 225 : : //! with a lower index are stored, thus this is an asymmetric 226 : : //! communication map. 227 : : std::unordered_map< int, std::unordered_set< std::size_t > > m_reordcomm; 228 : : //! \brief Starting global mesh node ID for node reordering on this chare 229 : : //! during mesh node reordering 230 : : std::size_t m_start; 231 : : //! Map associating new node IDs (value) to old node IDs (key) 232 : : std::unordered_map< std::size_t, std::size_t > m_newnodes; 233 : : //! Coordinates associated to global (new) node IDs during reordering 234 : : tk::UnsMesh::CoordMap m_newcoordmap; 235 : : //! Queue of requested node IDs from chares 236 : : std::vector< std::pair< int, std::unordered_set<std::size_t> > > m_reqnodes; 237 : : //! Lower bound of node IDs this chare contributes to in a linear system 238 : : std::size_t m_lower; 239 : : //! Upper bound of node IDs this chare contributes to in a linear system 240 : : std::size_t m_upper; 241 : : 242 : : //! Start preparing for mesh node reordering in parallel 243 : : void mask(); 244 : : 245 : : //! Reorder global mesh node IDs 246 : : void reorder(); 247 : : 248 : : //! Associate new node IDs to old ones and return them to the requestor(s) 249 : : void prepare(); 250 : : 251 : : //! Compute final result of reordering 252 : : void finish(); 253 : : 254 : : //! Create Discretization chare array elements on this PE 255 : : void createDiscWorkers(); 256 : : }; 257 : : 258 : : } // inciter:: 259 : : 260 : : #endif // Sorter_h