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 [ + - ]: 54271 : serialize( std::size_t meshid, const std::vector< std::vector< tk::real > >& d ) 25 : : // ***************************************************************************** 26 : : // Serialize std::vectors to raw memory stream 27 : : //! \param[in] meshid Mesh ID 28 : : //! \param[in] d Diagnostics vector of vectors (of eq components) 29 : : //! \return Pair of the length and the raw stream containing the serialized 30 : : //! vectors 31 : : // ***************************************************************************** 32 : : { 33 : : // Prepare for serializing diagnostics to a raw binary stream, compute size 34 : : PUP::sizer sizer; 35 : : sizer | meshid; 36 : : sizer | const_cast< std::vector< std::vector< tk::real > >& >( d ); 37 : : 38 : : // Create raw character stream to store the serialized vectors 39 : : std::unique_ptr<char[]> flatData = std::make_unique<char[]>( sizer.size() ); 40 : : 41 : : // Serialize vector, each message will contain a vector 42 : : PUP::toMem packer( flatData.get() ); 43 : : packer | meshid; 44 : : packer | const_cast< std::vector< std::vector< tk::real > >& >( d ); 45 : : 46 : : // Return size of and raw stream 47 : 54271 : return { sizer.size(), std::move(flatData) }; 48 : : } 49 : : 50 : : CkReductionMsg* 51 [ + - ]: 8356 : mergeDiag( int nmsg, CkReductionMsg **msgs ) 52 : : // ***************************************************************************** 53 : : // Charm++ custom reducer for merging diagnostics during reduction across PEs 54 : : //! \param[in] nmsg Number of messages in msgs 55 : : //! \param[in] msgs Charm++ reduction message containing the serialized 56 : : //! diagnostics 57 : : //! \return Aggregated diagnostics built for further aggregation if needed 58 : : // ***************************************************************************** 59 : : { 60 : : // Will store deserialized diagnostics vector of vectors 61 : : std::size_t meshid; 62 : 8356 : std::vector< std::vector< tk::real > > v; 63 : : 64 : : // Create PUP deserializer based on message passed in 65 [ + - ]: 8356 : PUP::fromMem creator( msgs[0]->getData() ); 66 : : 67 : : // Deserialize vector from raw stream 68 : : creator | meshid; 69 : : creator | v; 70 : : 71 [ + + ]: 49230 : for (int m=1; m<nmsg; ++m) { 72 : : // Unpack vector 73 : : std::size_t mid; 74 : 40874 : std::vector< std::vector< tk::real > > w; 75 [ + - ]: 40874 : PUP::fromMem curCreator( msgs[m]->getData() ); 76 : : curCreator | mid; 77 : : curCreator | w; 78 : : // Aggregate diagnostics vector 79 : 40874 : meshid = mid; 80 : : Assert( v.size() == w.size(), 81 : : "Size mismatch during diagnostics aggregation" ); 82 : : Assert( v.size() == inciter::NUMDIAG, 83 : : "Size mismatch during diagnostics aggregation" ); 84 [ + + ]: 367866 : for (std::size_t i=0; i<v.size(); ++i) 85 : : Assert( v[i].size() == w[i].size(), 86 : : "Size mismatch during diagnostics aggregation" ); 87 : : // Apply diagnostics aggregation policy 88 : : // Sum for L2 normal of the numerical solution for all scalar components 89 [ + + ]: 170742 : for (std::size_t i=0; i<v[L2SOL].size(); ++i) v[L2SOL][i] += w[L2SOL][i]; 90 : : // Sum for the L2 norm of the numerical - analytical solution for all comps 91 [ + + ]: 170742 : for (std::size_t i=0; i<v[L2ERR].size(); ++i) v[L2ERR][i] += w[L2ERR][i]; 92 : : // Sum for the L2 norm of the residual of all components 93 [ + + ]: 170742 : for (std::size_t i=0; i<v[L2RES].size(); ++i) v[L2RES][i] += w[L2RES][i]; 94 : : // Max for the Linf norm of the numerical - analytical solution for all comp 95 [ + + ]: 170742 : for (std::size_t i=0; i<v[LINFERR].size(); ++i) 96 [ + + ]: 129868 : if (w[LINFERR][i] > v[LINFERR][i]) v[LINFERR][i] = w[LINFERR][i]; 97 : : // Sum of the total energy over the entire domain 98 : 40874 : v[TOTALSOL][0] += w[TOTALSOL][0]; 99 : : // Copy ITER, TIME, DT 100 [ + + ]: 163496 : for (std::size_t j=v.size()-3; j<v.size(); ++j) 101 [ + + ]: 512226 : for (std::size_t i=0; i<v[j].size(); ++i) 102 : 389604 : v[j][i] = w[j][i]; 103 : : } 104 : : 105 : : // Serialize concatenated diagnostics vector to raw stream 106 [ + - ]: 8356 : auto stream = serialize( meshid, v ); 107 : : 108 : : // Forward serialized diagnostics 109 [ + - ]: 16712 : return CkReductionMsg::buildNew( stream.first, stream.second.get() ); 110 : : } 111 : : 112 : : } // inciter::