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-2025 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 [ + - ]: 47136 : 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 : 47136 : return { sizer.size(), std::move(flatData) };
55 : : }
56 : :
57 : : CkReductionMsg*
58 [ + - ]: 7806 : 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 [ + - ]: 7806 : 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 [ + + ]: 42970 : 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 [ + - ]: 35164 : 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 : 35164 : meshid = mid;
97 : 35164 : 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 [ + + ]: 316476 : 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 [ + + ]: 207381 : 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 [ + + ]: 207381 : 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 : 35164 : v[TOTALEN][0] += w[TOTALEN][0];
113 : : // Sum for the L2 norm of the numerical - analytical solution for all comps
114 [ + + ]: 207381 : 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 [ + + ]: 207381 : for (std::size_t i=0; i<v[L1ERR].size(); ++i) v[L1ERR][i] += w[L1ERR][i];
117 : : // Copy ITER, TIME, DT
118 [ + + ]: 207381 : for (std::size_t i=0; i<v[ITER].size(); ++i) v[ITER][i] = w[ITER][i];
119 [ + + ]: 207381 : for (std::size_t i=0; i<v[TIME].size(); ++i) v[TIME][i] = w[TIME][i];
120 [ + + ]: 207381 : for (std::size_t i=0; i<v[DT].size(); ++i) v[DT][i] = w[DT][i];
121 : 35164 : }
122 : :
123 : : // Serialize concatenated diagnostics vector to raw stream
124 [ + - ]: 7806 : auto stream = serialize( meshid, ncomp, v );
125 : :
126 : : // Forward serialized diagnostics
127 [ + - ]: 15612 : return CkReductionMsg::buildNew( stream.first, stream.second.get() );
128 : 7806 : }
129 : :
130 : : } // diagnostics::
131 : : } // inciter::
|