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