gem5 v24.0.0.0
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
81
82void
84{
85 h5File = H5::H5File(fname,
86 // Truncate the file if this is the first dump
87 dumpCount > 0 ? H5F_ACC_RDWR : H5F_ACC_TRUNC);
88 path.push(h5File.openGroup("/"));
89}
90
91void
93{
94 assert(valid());
95
96 dumpCount++;
97}
98
99bool
101{
102 return true;
103}
104
105
106void
108{
109 auto base = path.top();
110
111 // Try to open an existing stat group corresponding to the
112 // name. Create it if it doesn't exist.
113 H5::Group group;
114 try {
115 group = base.openGroup(name);
116 } catch (const H5::FileIException& e) {
117 group = base.createGroup(name);
118 } catch (const H5::GroupIException& e) {
119 group = base.createGroup(name);
120 }
121
122 path.push(group);
123}
124
125void
127{
128 assert(!path.empty());
129 path.pop();
130}
131
132void
134{
135 // Since this stat is a scalar, we need 1-dimensional value in the
136 // stat file. The Hdf5::appendStat helper will populate the size
137 // of the first dimension (time).
138 hsize_t fdims[1] = { 0, };
139 double data[1] = { info.result(), };
140
141 appendStat(info, 1, fdims, data);
142}
143
144void
146{
147 appendVectorInfo(info);
148}
149
150void
152{
153 warn_once("HDF5 stat files don't support distributions.\n");
154}
155
156void
158{
159 warn_once("HDF5 stat files don't support vector distributions.\n");
160}
161
162void
164{
165 // Request a 3-dimensional stat, the first dimension will be
166 // populated by the Hdf5::appendStat() helper. The remaining two
167 // dimensions correspond to the stat instance.
168 hsize_t fdims[3] = { 0, info.x, info.y };
169 H5::DataSet data_set = appendStat(info, 3, fdims, info.cvec.data());
170
171 if (dumpCount == 0) {
172 if (!info.subnames.empty() && !emptyStrings(info.subnames))
173 addMetaData(data_set, "subnames", info.subnames);
174
175 if (!info.y_subnames.empty() && !emptyStrings(info.y_subnames))
176 addMetaData(data_set, "y_subnames", info.y_subnames);
177
178 if (!info.subdescs.empty() && !emptyStrings(info.subdescs))
179 addMetaData(data_set, "subdescs", info.subdescs);
180 }
181}
182
183void
185{
186 if (!enableFormula)
187 return;
188
189 H5::DataSet data_set = appendVectorInfo(info);
190
191 if (dumpCount == 0)
192 addMetaData(data_set, "equation", info.str());
193}
194
195void
197{
198 warn_once("HDF5 stat files don't support sparse histograms.\n");
199}
200
201H5::DataSet
203{
204 const VResult &vr(info.result());
205 // Request a 2-dimensional stat, the first dimension will be
206 // populated by the Hdf5::appendStat() helper. The remaining
207 // dimension correspond to the stat instance.
208 hsize_t fdims[2] = { 0, vr.size() };
209 H5::DataSet data_set = appendStat(info, 2, fdims, vr.data());
210
211 if (dumpCount == 0) {
212 if (!info.subnames.empty() && !emptyStrings(info.subnames))
213 addMetaData(data_set, "subnames", info.subnames);
214
215 if (!info.subdescs.empty() && !emptyStrings(info.subdescs))
216 addMetaData(data_set, "subdescs", info.subdescs);
217 }
218
219 return data_set;
220}
221
222H5::DataSet
223Hdf5::appendStat(const Info &info, int rank, hsize_t *dims, const double *data)
224{
225 H5::Group group = path.top();
226 H5::DataSet data_set;
227 H5::DataSpace fspace;
228
229 dims[0] = dumpCount + 1;
230
231 if (dumpCount > 0) {
232 // Get the existing stat if we have already dumped this stat
233 // before.
234 data_set = group.openDataSet(info.name);
235 data_set.extend(dims);
236 fspace = data_set.getSpace();
237 } else {
238 // We don't have the stat already, create it.
239
240 H5::DSetCreatPropList props;
241
242 // Setup max dimensions based on the requested file dimensions
243 std::vector<hsize_t> max_dims(rank);
244 std::copy(dims, dims + rank, max_dims.begin());
245 max_dims[0] = H5S_UNLIMITED;
246
247 // Setup chunking
248 std::vector<hsize_t> chunk_dims(rank);
249 std::copy(dims, dims + rank, chunk_dims.begin());
250 chunk_dims[0] = timeChunk;
251 props.setChunk(rank, chunk_dims.data());
252
253 // Enable compression
254 props.setDeflate(1);
255
256 fspace = H5::DataSpace(rank, dims, max_dims.data());
257 try {
258 DPRINTF(Stats, "Creating dataset %s in group %s\n",
259 info.name, group.getObjnameByIdx(group.getId()));
260 data_set = group.createDataSet(info.name,
261 H5::PredType::NATIVE_DOUBLE, fspace, props);
262 } catch (const H5::Exception &e) {
263 std::string err = "Failed creating H5::DataSet " + info.name + "; ";
264 err += e.getDetailMsg() + " in " + e.getFuncName();
265 // Rethrow std exception so that it's passed on to the Python world
266 throw std::runtime_error(err);
267 }
268
269 if (enableDescriptions && !info.desc.empty()) {
270 addMetaData(data_set, "description", info.desc);
271 }
272 }
273
274 // The first dimension is time which isn't included in data.
275 dims[0] = 1;
276 H5::DataSpace mspace(rank, dims);
277 std::vector<hsize_t> foffset(rank, 0);
278 foffset[0] = dumpCount;
279
280 fspace.selectHyperslab(H5S_SELECT_SET, dims, foffset.data());
281 data_set.write(data, H5::PredType::NATIVE_DOUBLE, mspace, fspace);
282
283 return data_set;
284}
285
286void
287Hdf5::addMetaData(H5::DataSet &loc, const char *name,
288 const std::vector<const char *> &values)
289{
290 H5::StrType type(H5::PredType::C_S1, H5T_VARIABLE);
291 hsize_t dims[1] = { values.size(), };
292 H5::DataSpace space(1, dims);
293 H5::Attribute attribute = loc.createAttribute(name, type, space);
294 attribute.write(type, values.data());
295}
296
297void
298Hdf5::addMetaData(H5::DataSet &loc, const char *name,
299 const std::vector<std::string> &values)
300{
301 std::vector<const char *> cstrs(values.size());
302 for (int i = 0; i < values.size(); ++i)
303 cstrs[i] = values[i].c_str();
304
305 addMetaData(loc, name, cstrs);
306}
307
308void
309Hdf5::addMetaData(H5::DataSet &loc, const char *name,
310 const std::string &value)
311{
312 H5::StrType type(H5::PredType::C_S1, value.length() + 1);
313 hsize_t dims[1] = { 1, };
314 H5::DataSpace space(1, dims);
315 H5::Attribute attribute = loc.createAttribute(name, type, space);
316 attribute.write(type, value.c_str());
317}
318
319void
320Hdf5::addMetaData(H5::DataSet &loc, const char *name, double value)
321{
322 hsize_t dims[1] = { 1, };
323 H5::DataSpace space(1, dims);
324 H5::Attribute attribute = loc.createAttribute(
325 name, H5::PredType::NATIVE_DOUBLE, space);
326 attribute.write(H5::PredType::NATIVE_DOUBLE, &value);
327}
328
329
330std::unique_ptr<Output>
331initHDF5(const std::string &filename, unsigned chunking,
332 bool desc, bool formulas)
333{
334 return std::unique_ptr<Output>(
335 new Hdf5(simout.resolve(filename), chunking, desc, formulas));
336}
337
338}; // namespace statistics
339} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:210
const char data[]
std::string resolve(const std::string &name) const
Returns relative file names prepended with name of this directory.
Definition output.cc:204
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:223
bool valid() const override
Definition hdf5.cc:100
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:287
std::stack< H5::Group > path
Definition hdf5.hh:150
void end() override
Definition hdf5.cc:92
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:202
void begin() override
Definition hdf5.cc:83
void endGroup() override
Definition hdf5.cc:126
void visit(const ScalarInfo &info) override
Definition hdf5.cc:133
const hsize_t timeChunk
Definition hdf5.hh:146
void beginGroup(const char *name) override
Definition hdf5.cc:107
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
#define warn_once(...)
Definition logging.hh:260
Bitfield< 4 > s
Bitfield< 6 > err
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 9 > e
Definition misc_types.hh:65
Bitfield< 51, 12 > base
Definition pagetable.hh:141
std::unique_ptr< Output > initHDF5(const std::string &filename, unsigned chunking, bool desc, bool formulas)
Definition hdf5.cc:331
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria 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 Tue Jun 18 2024 16:24:01 for gem5 by doxygen 1.11.0