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 : : int nchare ); 76 : : 77 : : #if defined(__clang__) 78 : : #pragma clang diagnostic push 79 : : #pragma clang diagnostic ignored "-Wundefined-func-template" 80 : : #endif 81 : : //! Migrate constructor 82 : : // cppcheck-suppress uninitMemberVarPrivate 83 : 8987 : explicit Sorter( CkMigrateMessage* ) {} 84 : : #if defined(__clang__) 85 : : #pragma clang diagnostic pop 86 : : #endif 87 : : 88 : : //! Configure Charm++ reduction types 89 : : static void registerReducers(); 90 : : 91 : : //! Setup chare mesh boundary node communication map 92 : : void setup( std::size_t npoin ); 93 : : //! \brief Incoming query for a list mesh nodes for which this chare 94 : : //! compiles communication maps 95 : : void query( int fromch, const tk::AllCommMaps& bnd ); 96 : : //! Report receipt of boundary node lists 97 : : void recvquery(); 98 : : //! Respond to boundary node list queries 99 : : void response(); 100 : : //! Receive boundary node communication maps for our mesh chunk 101 : : void bnd( int fromch, const tk::CommMaps& msum ); 102 : : //! Receive receipt of boundary node communication map 103 : : void recvbnd(); 104 : : 105 : : //! Start reordering (if user enabled it) 106 : : void start(); 107 : : 108 : : //! \brief Receive number of uniquely assigned global mesh node IDs from 109 : : //! chares with lower indices 110 : : void offset( int c, std::size_t u ); 111 : : 112 : : //! Request new global node IDs for old node IDs 113 : : void request( int c, const std::unordered_set< std::size_t >& nd ); 114 : : 115 : : //! Receive lower bound of node IDs our PE operates on after reordering 116 : : void lower( std::size_t low ); 117 : : 118 : : //! Receive new (reordered) global node IDs and coordinates 119 : : void neworder( const std::unordered_map< std::size_t, 120 : : std::tuple< std::size_t, tk::UnsMesh::Coord > >& nodes ); 121 : : 122 : : //! Create worker chare array elements on this PE 123 : : void createWorkers(); 124 : : 125 : : //! Update mesh data we hold for whoever calls this function 126 : : void mesh( std::vector< std::size_t >& ginpoel, 127 : : tk::UnsMesh::CoordMap& coordmap, 128 : : std::vector< std::size_t >& triinpoel, 129 : : std::map< int, std::vector< std::size_t > >& bnode ); 130 : : 131 : : /** @name Charm++ pack/unpack serializer member functions */ 132 : : ///@{ 133 : : //! \brief Pack/Unpack serialize member function 134 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 135 : 26961 : void pup( PUP::er &p ) override { 136 : 26961 : p | m_meshid; 137 : : p | m_host; 138 : : p | m_meshwriter; 139 : : p | m_cbs; 140 : 26961 : p | m_scheme; 141 : 26961 : p | m_reorderRefiner; 142 : 26961 : p | m_ginpoel; 143 : 26961 : p | m_coordmap; 144 : 26961 : p | m_el; 145 : 26961 : p | m_nbnd; 146 : 26961 : p | m_bface; 147 : 26961 : p | m_triinpoel; 148 : 26961 : p | m_bnode; 149 : 26961 : p | m_nchare; 150 : 26961 : p | m_nodeset; 151 : 26961 : p | m_noffset; 152 : 26961 : p | m_nodech; 153 : 26961 : p | m_chnode; 154 : 26961 : p | m_edgech; 155 : 26961 : p | m_chedge; 156 : 26961 : p | m_msum; 157 : 26961 : p | m_reordcomm; 158 : 26961 : p | m_start; 159 : 26961 : p | m_newnodes; 160 : 26961 : p | m_newcoordmap; 161 : 26961 : p | m_reqnodes; 162 : 26961 : p | m_lower; 163 : 26961 : p | m_upper; 164 : 26961 : } 165 : : //! \brief Pack/Unpack serialize operator| 166 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference 167 : : //! \param[in,out] s Sorter object reference 168 : : friend void operator|( PUP::er& p, Sorter& s ) { s.pup(p); } 169 : : //@} 170 : : 171 : : private: 172 : : //! Mesh ID 173 : : std::size_t m_meshid; 174 : : //! Host proxy 175 : : CProxy_Transporter m_host; 176 : : //! MeshWriter proxy 177 : : tk::CProxy_MeshWriter m_meshwriter; 178 : : //! Charm++ callbacks associated to compile-time tags for sorter 179 : : tk::SorterCallback m_cbs; 180 : : //! Discretization schemes (one per mesh) 181 : : std::vector< Scheme > m_scheme; 182 : : //! Callback to use to send reordered mesh to Refiner 183 : : CkCallback m_reorderRefiner; 184 : : //! Tetrtahedron element connectivity of our chunk of the mesh (global ids) 185 : : std::vector< std::size_t > m_ginpoel; 186 : : //! Coordinates associated to global node IDs of our mesh chunk 187 : : tk::UnsMesh::CoordMap m_coordmap; 188 : : //! Elements of the mesh chunk we operate on 189 : : tk::UnsMesh::Chunk m_el; 190 : : //! Counter for number of chares contributing to chare boundary nodes 191 : : std::size_t m_nbnd; 192 : : //! List of boundary faces associated to side-set IDs 193 : : std::map< int, std::vector< std::size_t > > m_bface; 194 : : //! Boundary face-node connectivity 195 : : std::vector< std::size_t > m_triinpoel; 196 : : //! List of boundary nodes associated to side-set IDs 197 : : std::map< int, std::vector< std::size_t > > m_bnode; 198 : : //! Total number of sorter chares 199 : : int m_nchare; 200 : : //! Unique global node IDs chares on our PE will contribute to 201 : : std::set< std::size_t > m_nodeset; 202 : : //! \brief Counter for the number of chares from which this chare has 203 : : //! received node reordering offsets from 204 : : int m_noffset; 205 : : //! Node->chare map used to build boundary node communication maps 206 : : std::unordered_map< std::size_t, std::vector< int > > m_nodech; 207 : : //! Chare->node map used to build boundary node communication maps 208 : : tk::NodeCommMap m_chnode; 209 : : //! Edge->chare map used to build boundary edge communication maps 210 : : std::unordered_map< tk::UnsMesh::Edge, std::vector< int >, 211 : : tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> > m_edgech; 212 : : //! Chare->edge map used to build boundary edge communication maps 213 : : tk::EdgeCommMap m_chedge; 214 : : //! Communication maps associated to chare IDs 215 : : tk::CommMaps m_msum; 216 : : //! \brief Communication map used for distributed mesh node reordering 217 : : //! \details This map associates the list of global mesh point 218 : : //! indices to fellow chare IDs from which this chare receives new node 219 : : //! IDs during reordering. Only data that will be received from chares 220 : : //! with a lower index are stored, thus this is an asymmetric 221 : : //! communication map. 222 : : std::unordered_map< int, std::unordered_set< std::size_t > > m_reordcomm; 223 : : //! \brief Starting global mesh node ID for node reordering on this chare 224 : : //! during mesh node reordering 225 : : std::size_t m_start; 226 : : //! Map associating new node IDs (value) to old node IDs (key) 227 : : std::unordered_map< std::size_t, std::size_t > m_newnodes; 228 : : //! Coordinates associated to global (new) node IDs during reordering 229 : : tk::UnsMesh::CoordMap m_newcoordmap; 230 : : //! Queue of requested node IDs from chares 231 : : std::vector< std::pair< int, std::unordered_set<std::size_t> > > m_reqnodes; 232 : : //! Lower bound of node IDs this chare contributes to in a linear system 233 : : std::size_t m_lower; 234 : : //! Upper bound of node IDs this chare contributes to in a linear system 235 : : std::size_t m_upper; 236 : : 237 : : //! Start preparing for mesh node reordering in parallel 238 : : void mask(); 239 : : 240 : : //! Reorder global mesh node IDs 241 : : void reorder(); 242 : : 243 : : //! Associate new node IDs to old ones and return them to the requestor(s) 244 : : void prepare(); 245 : : 246 : : //! Compute final result of reordering 247 : : void finish(); 248 : : 249 : : //! Create Discretization chare array elements on this PE 250 : : void createDiscWorkers(); 251 : : }; 252 : : 253 : : } // inciter:: 254 : : 255 : : #endif // Sorter_h