gem5 [DEVELOP-FOR-25.1]
Loading...
Searching...
No Matches
hdf5.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2016-2019 Arm Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#include "base/stats/hdf5.hh"
39
40#include "base/logging.hh"
41#include "base/stats/info.hh"
42#include "base/trace.hh"
43#include "debug/Stats.hh"
44
45namespace gem5
46{
47
51template<typename T>
52bool emptyStrings(const T &labels)
53{
54 for (const auto &s : labels) {
55 if (!s.empty())
56 return false;
57 }
58 return true;
59}
60
61
62namespace statistics
63{
64
65Hdf5::Hdf5(const std::string &file, unsigned chunking,
66 bool desc, bool formulas)
67 : fname(file), timeChunk(chunking),
68 enableDescriptions(desc), enableFormula(formulas),
69 dumpCount(0)
70{
71 // Tell the library not to print exceptions by default. There are
72 // cases where we rely on exceptions to determine if we need to
73 // create a node or if we can just open it.
74 H5::Exception::dontPrint();
75}
76
78{
79}
80
81void
82Hdf5::begin(const std::string &message)
83{
84 // HDF5 format ignores the message parameter
85 // as it doesn't support text messages
86 h5File = H5::H5File(fname,
87 // Truncate the file if this is the first dump
88 dumpCount > 0 ? H5F_ACC_RDWR : H5F_ACC_TRUNC);
89 path.push(h5File.openGroup("/"));
90}
91
92void
94{
95 assert(valid());
96
97 dumpCount++;
98}
99
100bool
102{
103 return true;
104}
105
106
107void
109{
110 auto base = path.top();
111
112 // Try to open an existing stat group corresponding to the
113 // name. Create it if it doesn't exist.
114 H5::Group group;
115 try {
116 group = base.openGroup(name);
117 } catch (const H5::FileIException& e) {
118 group = base.createGroup(name);
119 } catch (const H5::GroupIException& e) {
120 group = base.createGroup(name);
121 }
122
123 path.push(group);
124}
125
126void
128{
129 assert(!path.empty());
130 path.pop();
131}
132
133void
135{
136 // Since this stat is a scalar, we need 1-dimensional value in the
137 // stat file. The Hdf5::appendStat helper will populate the size
138 // of the first dimension (time).
139 hsize_t fdims[1] = { 0, };
140 double data[1] = { info.result(), };
141
142 appendStat(info, 1, fdims, data);
143}
144
145void
147{
148 appendVectorInfo(info);
149}
150
151void
153{
154 warn_once("HDF5 stat files don't support distributions.\n");
155}
156
157void
159{
160 warn_once("HDF5 stat files don't support vector distributions.\n");
161}
162
163void
165{
166 // Request a 3-dimensional stat, the first dimension will be
167 // populated by the Hdf5::appendStat() helper. The remaining two
168 // dimensions correspond to the stat instance.
169 hsize_t fdims[3] = { 0, info.x, info.y };
170 H5::DataSet data_set = appendStat(info, 3, fdims, info.cvec.data());
171
172 if (dumpCount == 0) {
173 if (!info.subnames.empty() && !emptyStrings(info.subnames))
174 addMetaData(data_set, "subnames", info.subnames);
175
176 if (!info.y_subnames.empty() && !emptyStrings(info.y_subnames))
177 addMetaData(data_set, "y_subnames", info.y_subnames);
178
179 if (!info.subdescs.empty() && !emptyStrings(info.subdescs))
180 addMetaData(data_set, "subdescs", info.subdescs);
181 }
182}
183
184void
186{
187 if (!enableFormula)
188 return;
189
190 H5::DataSet data_set = appendVectorInfo(info);
191
192 if (dumpCount == 0)
193 addMetaData(data_set, "equation", info.str());
194}
195
196void
198{
199 warn_once("HDF5 stat files don't support sparse histograms.\n");
200}
201
202H5::DataSet
204{
205 const VResult &vr(info.result());
206 // Request a 2-dimensional stat, the first dimension will be
207 // populated by the Hdf5::appendStat() helper. The remaining
208 // dimension correspond to the stat instance.
209 hsize_t fdims[2] = { 0, vr.size() };
210 H5::DataSet data_set = appendStat(info, 2, fdims, vr.data());
211
212 if (dumpCount == 0) {
213 if (!info.subnames.empty() && !emptyStrings(info.subnames))
214 addMetaData(data_set, "subnames", info.subnames);
215
216 if (!info.subdescs.empty() && !emptyStrings(info.subdescs))
217 addMetaData(data_set, "subdescs", info.subdescs);
218 }
219
220 return data_set;
221}
222
223H5::DataSet
224Hdf5::appendStat(const Info &info, int rank, hsize_t *dims, const double *data)
225{
226 H5::Group group = path.top();
227 H5::DataSet data_set;
228 H5::DataSpace fspace;
229
230 dims[0] = dumpCount + 1;
231
232 if (dumpCount > 0) {
233 // Get the existing stat if we have already dumped this stat
234 // before.
235 data_set = group.openDataSet(info.name);
236 data_set.extend(dims);
237 fspace = data_set.getSpace();
238 } else {
239 // We don't have the stat already, create it.
240
241 H5::DSetCreatPropList props;
242
243 // Setup max dimensions based on the requested file dimensions
244 std::vector<hsize_t> max_dims(rank);
245 std::copy(dims, dims + rank, max_dims.begin());
246 max_dims[0] = H5S_UNLIMITED;
247
248 // Setup chunking
249 std::vector<hsize_t> chunk_dims(rank);
250 std::copy(dims, dims + rank, chunk_dims.begin());
251 chunk_dims[0] = timeChunk;
252 props.setChunk(rank, chunk_dims.data());
253
254 // Enable compression
255 props.setDeflate(1);
256
257 fspace = H5::DataSpace(rank, dims, max_dims.data());
258 try {
259 DPRINTF(Stats, "Creating dataset %s in group %s\n",
260 info.name, group.getObjnameByIdx(group.getId()));
261 data_set = group.createDataSet(info.name,
262 H5::PredType::NATIVE_DOUBLE, fspace, props);
263 } catch (const H5::Exception &e) {
264 std::string err = "Failed creating H5::DataSet " + info.name + "; ";
265 err += e.getDetailMsg() + " in " + e.getFuncName();
266 // Rethrow std exception so that it's passed on to the Python world
267 throw std::runtime_error(err);
268 }
269
270 if (enableDescriptions && !info.desc.empty()) {
271 addMetaData(data_set, "description", info.desc);
272 }
273 }
274
275 // The first dimension is time which isn't included in data.
276 dims[0] = 1;
277 H5::DataSpace mspace(rank, dims);
278 std::vector<hsize_t> foffset(rank, 0);
279 foffset[0] = dumpCount;
280
281 fspace.selectHyperslab(H5S_SELECT_SET, dims, foffset.data());
282 data_set.write(data, H5::PredType::NATIVE_DOUBLE, mspace, fspace);
283
284 return data_set;
285}
286
287void
288Hdf5::addMetaData(H5::DataSet &loc, const char *name,
289 const std::vector<const char *> &values)
290{
291 H5::StrType type(H5::PredType::C_S1, H5T_VARIABLE);
292 hsize_t dims[1] = { values.size(), };
293 H5::DataSpace space(1, dims);
294 H5::Attribute attribute = loc.createAttribute(name, type, space);
295 attribute.write(type, values.data());
296}
297
298void
299Hdf5::addMetaData(H5::DataSet &loc, const char *name,
300 const std::vector<std::string> &values)
301{
302 std::vector<const char *> cstrs(values.size());
303 for (int i = 0; i < values.size(); ++i)
304 cstrs[i] = values[i].c_str();
305
306 addMetaData(loc, name, cstrs);
307}
308
309void
310Hdf5::addMetaData(H5::DataSet &loc, const char *name,
311 const std::string &value)
312{
313 H5::StrType type(H5::PredType::C_S1, value.length() + 1);
314 hsize_t dims[1] = { 1, };
315 H5::DataSpace space(1, dims);
316 H5::Attribute attribute = loc.createAttribute(name, type, space);
317 attribute.write(type, value.c_str());
318}
319
320void
321Hdf5::addMetaData(H5::DataSet &loc, const char *name, double value)
322{
323 hsize_t dims[1] = { 1, };
324 H5::DataSpace space(1, dims);
325 H5::Attribute attribute = loc.createAttribute(
326 name, H5::PredType::NATIVE_DOUBLE, space);
327 attribute.write(H5::PredType::NATIVE_DOUBLE, &value);
328}
329
330
331std::unique_ptr<Output>
332initHDF5(const std::string &filename, unsigned chunking,
333 bool desc, bool formulas)
334{
335 return std::unique_ptr<Output>(
336 new Hdf5(simout.resolve(filename), chunking, desc, formulas));
337}
338
339}; // namespace statistics
340} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:209
const char data[]
virtual std::string str() const =0
H5::DataSet appendStat(const Info &info, int rank, hsize_t *dims, const double *data)
Helper function to append an n-dimensional double stat to the file.
Definition hdf5.cc:224
bool valid() const override
Definition hdf5.cc:101
const bool enableFormula
Definition hdf5.hh:148
const bool enableDescriptions
Definition hdf5.hh:147
const std::string fname
Definition hdf5.hh:145
void addMetaData(H5::DataSet &loc, const char *name, const std::vector< const char * > &values)
Helper function to add a string vector attribute to a stat.
Definition hdf5.cc:288
std::stack< H5::Group > path
Definition hdf5.hh:150
void end() override
Definition hdf5.cc:93
H5::H5File h5File
Definition hdf5.hh:153
H5::DataSet appendVectorInfo(const VectorInfo &info)
Helper function to append vector stats and set their metadata.
Definition hdf5.cc:203
void begin(const std::string &message="") override
Definition hdf5.cc:82
void endGroup() override
Definition hdf5.cc:127
void visit(const ScalarInfo &info) override
Definition hdf5.cc:134
const hsize_t timeChunk
Definition hdf5.hh:146
void beginGroup(const char *name) override
Definition hdf5.cc:108
std::string name
The name of the stat.
Definition info.hh:83
std::string desc
The description of the stat.
Definition info.hh:89
virtual Result result() const =0
std::vector< std::string > subdescs
Definition info.hh:230
std::vector< std::string > y_subnames
Definition info.hh:231
std::vector< std::string > subnames
Names and descriptions of subfields.
Definition info.hh:229
VCounter cvec
Local storage for the entry values, used for printing.
Definition info.hh:237
virtual const VResult & result() const =0
std::vector< std::string > subdescs
Definition info.hh:188
std::vector< std::string > subnames
Names and descriptions of subfields.
Definition info.hh:187
STL vector class.
Definition stl.hh:37
#define warn_once(...)
Definition logging.hh:292
Bitfield< 4 > s
Bitfield< 6 > err
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 9 > e
Definition misc_types.hh:65
std::vector< Result > VResult
vector of results.
Definition types.hh:57
std::unique_ptr< Output > initHDF5(const std::string &filename, unsigned chunking, bool desc, bool formulas)
Definition hdf5.cc:332
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36
bool emptyStrings(const T &labels)
Check if all strings in a container are empty.
Definition hdf5.cc:52
OutputDirectory simout
Definition output.cc:62
const std::string & name()
Definition trace.cc:48

Generated on Mon Oct 27 2025 04:13:00 for gem5 by doxygen 1.14.0