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 : : 2022-2024 J. Bakosi 8 : : All rights reserved. See the LICENSE file for details. 9 : : \brief Custom Charm++ reducer for merging diagnostics across PEs 10 : : \details Custom Charm++ reducer for merging diagnostics across PEs. 11 : : */ 12 : : // ***************************************************************************** 13 : : 14 : : #include <stddef.h> 15 : : #include <type_traits> 16 : : #include <memory> 17 : : 18 : : #include "DiagReducer.hpp" 19 : : #include "Diagnostics.hpp" 20 : : #include "Exception.hpp" 21 : : 22 : : namespace inciter { 23 : : namespace diagnostics { 24 : : 25 : : std::pair< int, std::unique_ptr<char[]> > 26 [ + - ]: 44718 : serialize( std::size_t meshid, 27 : : std::size_t ncomp, 28 : : const std::vector< std::vector< tk::real > >& d ) 29 : : // ***************************************************************************** 30 : : // Serialize diagnostics to raw memory stream 31 : : //! \param[in] meshid Mesh ID 32 : : //! \param[in] ncomp Number of scalar components whose diagnostics are computed 33 : : //! \param[in] d Diagnostics vector of vectors (of eq components) 34 : : //! \return Pair of the length and the raw stream containing the serialized 35 : : //! vectors 36 : : // ***************************************************************************** 37 : : { 38 : : // Prepare for serializing diagnostics to a raw binary stream, compute size 39 : : PUP::sizer sizer; 40 : : sizer | meshid; 41 : : sizer | ncomp; 42 : : sizer | const_cast< std::vector< std::vector< tk::real > >& >( d ); 43 : : 44 : : // Create raw character stream to store the serialized vectors 45 : : std::unique_ptr<char[]> flatData = std::make_unique<char[]>( sizer.size() ); 46 : : 47 : : // Serialize vector, each message will contain a vector 48 : : PUP::toMem packer( flatData.get() ); 49 : : packer | meshid; 50 : : packer | ncomp; 51 : : packer | const_cast< std::vector< std::vector< tk::real > >& >( d ); 52 : : 53 : : // Return size of and raw stream 54 : 44718 : return { sizer.size(), std::move(flatData) }; 55 : : } 56 : : 57 : : CkReductionMsg* 58 [ + - ]: 7464 : mergeDiag( int nmsg, CkReductionMsg **msgs ) 59 : : // ***************************************************************************** 60 : : // Charm++ custom reducer for merging diagnostics during reduction across PEs 61 : : //! \param[in] nmsg Number of messages in msgs 62 : : //! \param[in] msgs Charm++ reduction message containing the serialized 63 : : //! diagnostics 64 : : //! \return Aggregated diagnostics built for further aggregation if needed 65 : : // ***************************************************************************** 66 : : { 67 : : using namespace diagnostics; 68 : : 69 : : // Will store deserialized diagnostics vector of vectors 70 : : std::size_t meshid; 71 : : std::size_t ncomp; 72 : : std::vector< std::vector< tk::real > > v; 73 : : 74 : : // Create PUP deserializer based on message passed in 75 [ + - ]: 7464 : PUP::fromMem creator( msgs[0]->getData() ); 76 : : 77 : : // Deserialize vector from raw stream 78 : : // cppcheck-suppress uninitvar 79 : : creator | meshid; 80 : : creator | ncomp; 81 : : creator | v; 82 : : 83 [ + + ]: 40740 : for (int m=1; m<nmsg; ++m) { 84 : : // Unpack vector 85 : : std::size_t mid; 86 : : std::size_t nc; 87 : : std::vector< std::vector< tk::real > > w; 88 [ + - ]: 33276 : PUP::fromMem curCreator( msgs[m]->getData() ); 89 : : // cppcheck-suppress uninitvar 90 : : curCreator | mid; 91 : : curCreator | nc; 92 : : curCreator | w; 93 : : // Aggregate diagnostics vector 94 : : // cppcheck-suppress uninitvar 95 : : // cppcheck-suppress unreadVariable 96 : 33276 : meshid = mid; 97 : 33276 : ncomp = nc; 98 : : Assert( v.size() == w.size(), 99 : : "Size mismatch during diagnostics aggregation" ); 100 : : Assert( v.size() == NUMDIAG, 101 : : "Size mismatch during diagnostics aggregation" ); 102 : : // cppcheck-suppress unsignedLessThanZero 103 [ + + ]: 299484 : for (std::size_t i=0; i<v.size(); ++i) 104 : : Assert( v[i].size() == w[i].size(), 105 : : "Size mismatch during diagnostics aggregation" ); 106 : : // Apply diagnostics aggregation policy 107 : : // Sum for L2 normal of the numerical solution for all scalar components 108 [ + + ]: 196071 : for (std::size_t i=0; i<v[L2SOL].size(); ++i) v[L2SOL][i] += w[L2SOL][i]; 109 : : // Sum for the L2 norm of the residual of all components 110 [ + + ]: 196071 : for (std::size_t i=0; i<v[L2RES].size(); ++i) v[L2RES][i] += w[L2RES][i]; 111 : : // Sum of the total energy over the entire domain 112 : 33276 : v[TOTALEN][0] += w[TOTALEN][0]; 113 : : // Sum for the L2 norm of the numerical - analytical solution for all comps 114 [ + + ]: 196071 : for (std::size_t i=0; i<v[L2ERR].size(); ++i) v[L2ERR][i] += w[L2ERR][i]; 115 : : // Sum for the L1 norm of the numerical - analytical solution for all comps 116 [ + + ]: 196071 : for (std::size_t i=0; i<v[L1ERR].size(); ++i) v[L1ERR][i] += w[L1ERR][i]; 117 : : // Copy ITER, TIME, DT 118 [ + + ]: 196071 : for (std::size_t i=0; i<v[ITER].size(); ++i) v[ITER][i] = w[ITER][i]; 119 [ + + ]: 196071 : for (std::size_t i=0; i<v[TIME].size(); ++i) v[TIME][i] = w[TIME][i]; 120 [ + + ]: 196071 : for (std::size_t i=0; i<v[DT].size(); ++i) v[DT][i] = w[DT][i]; 121 : 33276 : } 122 : : 123 : : // Serialize concatenated diagnostics vector to raw stream 124 [ + - ]: 7464 : auto stream = serialize( meshid, ncomp, v ); 125 : : 126 : : // Forward serialized diagnostics 127 [ + - ]: 14928 : return CkReductionMsg::buildNew( stream.first, stream.second.get() ); 128 : 7464 : } 129 : : 130 : : } // diagnostics:: 131 : : } // inciter::