Branch data Line data Source code
1 : : // ***************************************************************************** 2 : : /*! 3 : : \file src/Inciter/DiagReducer.cpp 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 Custom Charm++ reducer for merging std::vectors across PEs 9 : : \details Custom Charm++ reducer for merging std::vectors across PEs. 10 : : */ 11 : : // ***************************************************************************** 12 : : 13 : : #include <stddef.h> 14 : : #include <type_traits> 15 : : #include <memory> 16 : : 17 : : #include "DiagReducer.hpp" 18 : : #include "Diagnostics.hpp" 19 : : #include "Exception.hpp" 20 : : 21 : : namespace inciter { 22 : : 23 : : std::pair< int, std::unique_ptr<char[]> > 24 : 34440 : serialize( std::size_t meshid, 25 : : std::size_t ncomp, 26 : : const std::vector< std::vector< tk::real > >& d ) 27 : : // ***************************************************************************** 28 : : // Serialize std::vectors to raw memory stream 29 : : //! \param[in] meshid Mesh ID 30 : : //! \param[in] ncomp Number of scalar components being solved 31 : : //! \param[in] d Diagnostics vector of vectors (of eq components) 32 : : //! \return Pair of the length and the raw stream containing the serialized 33 : : //! vectors 34 : : // ***************************************************************************** 35 : : { 36 : : // Prepare for serializing diagnostics to a raw binary stream, compute size 37 [ + - ]: 68880 : PUP::sizer sizer; 38 [ + - ]: 34440 : sizer | meshid; 39 [ + - ]: 34440 : sizer | ncomp; 40 [ + - ]: 34440 : sizer | const_cast< std::vector< std::vector< tk::real > >& >( d ); 41 : : 42 : : // Create raw character stream to store the serialized vectors 43 [ + - ]: 68880 : std::unique_ptr<char[]> flatData = std::make_unique<char[]>( sizer.size() ); 44 : : 45 : : // Serialize vector, each message will contain a vector 46 [ + - ]: 34440 : PUP::toMem packer( flatData.get() ); 47 [ + - ]: 34440 : packer | meshid; 48 [ + - ]: 34440 : packer | ncomp; 49 [ + - ]: 34440 : packer | const_cast< std::vector< std::vector< tk::real > >& >( d ); 50 : : 51 : : // Return size of and raw stream 52 : 68880 : return { sizer.size(), std::move(flatData) }; 53 : : } 54 : : 55 : : CkReductionMsg* 56 : 4982 : mergeDiag( int nmsg, CkReductionMsg **msgs ) 57 : : // ***************************************************************************** 58 : : // Charm++ custom reducer for merging diagnostics during reduction across PEs 59 : : //! \param[in] nmsg Number of messages in msgs 60 : : //! \param[in] msgs Charm++ reduction message containing the serialized 61 : : //! diagnostics 62 : : //! \return Aggregated diagnostics built for further aggregation if needed 63 : : // ***************************************************************************** 64 : : { 65 : : std::size_t meshid, ncomp; 66 : 9964 : std::vector< std::vector< tk::real > > v; 67 : : 68 : : // Create PUP deserializer based on message passed in 69 [ + - ]: 9964 : PUP::fromMem creator( msgs[0]->getData() ); 70 : : 71 : : // Deserialize vector from raw stream 72 [ + - ]: 4982 : creator | meshid; 73 [ + - ]: 4982 : creator | ncomp; 74 [ + - ]: 4982 : creator | v; 75 : : 76 [ + + ]: 31254 : for (int m=1; m<nmsg; ++m) { 77 : : // Unpack vector 78 : : std::size_t mid, nc; 79 : 52544 : std::vector< std::vector< tk::real > > w; 80 [ + - ]: 52544 : PUP::fromMem curCreator( msgs[m]->getData() ); 81 [ + - ]: 26272 : curCreator | mid; 82 [ + - ]: 26272 : curCreator | nc; 83 [ + - ]: 26272 : curCreator | w; 84 : : // Aggregate diagnostics vector 85 : 26272 : meshid = mid; 86 : 26272 : ncomp = nc; 87 [ - + ][ - - ]: 26272 : Assert( v.size() == w.size(), [ - - ][ - - ] 88 : : "Size mismatch during diagnostics aggregation" ); 89 [ - + ][ - - ]: 26272 : Assert( v.size() == inciter::NUMDIAG, [ - - ][ - - ] 90 : : "Size mismatch during diagnostics aggregation" ); 91 [ + + ]: 236448 : for (std::size_t i=0; i<v.size(); ++i) 92 [ - + ][ - - ]: 210176 : Assert( v[i].size() == w[i].size(), [ - - ][ - - ] 93 : : "Size mismatch during diagnostics aggregation" ); 94 : : // Apply diagnostics aggregation policy 95 : : // Sum for L2 normal of the numerical solution for all scalar components 96 [ + + ]: 104334 : for (std::size_t i=0; i<v[L2SOL].size(); ++i) v[L2SOL][i] += w[L2SOL][i]; 97 : : // Sum for the L2 norm of the numerical - analytical solution for all comps 98 [ + + ]: 104334 : for (std::size_t i=0; i<v[L2ERR].size(); ++i) v[L2ERR][i] += w[L2ERR][i]; 99 : : // Sum for the L2 norm of the residual of all components 100 [ + + ]: 104334 : for (std::size_t i=0; i<v[L2RES].size(); ++i) v[L2RES][i] += w[L2RES][i]; 101 : : // Max for the Linf norm of the numerical - analytical solution for all comp 102 [ + + ]: 104334 : for (std::size_t i=0; i<v[LINFERR].size(); ++i) 103 [ + + ]: 78062 : if (w[LINFERR][i] > v[LINFERR][i]) v[LINFERR][i] = w[LINFERR][i]; 104 : : // Sum of the total energy over the entire domain 105 : 26272 : v[TOTALSOL][0] += w[TOTALSOL][0]; 106 : : // Copy ITER, TIME, DT 107 [ + + ]: 105088 : for (std::size_t j=v.size()-3; j<v.size(); ++j) 108 [ + + ]: 313002 : for (std::size_t i=0; i<v[j].size(); ++i) 109 : 234186 : v[j][i] = w[j][i]; 110 : : } 111 : : 112 : : // Serialize concatenated diagnostics vector to raw stream 113 [ + - ]: 9964 : auto stream = serialize( meshid, ncomp, v ); 114 : : 115 : : // Forward serialized diagnostics 116 [ + - ]: 9964 : return CkReductionMsg::buildNew( stream.first, stream.second.get() ); 117 : : } 118 : : 119 : : } // inciter::