HPCToolkit
CallPath-Profile.hpp
Go to the documentation of this file.
1 // -*-Mode: C++;-*-
2 
3 // * BeginRiceCopyright *****************************************************
4 //
5 // $HeadURL$
6 // $Id$
7 //
8 // --------------------------------------------------------------------------
9 // Part of HPCToolkit (hpctoolkit.org)
10 //
11 // Information about sources of support for research and development of
12 // HPCToolkit is at 'hpctoolkit.org' and in 'README.Acknowledgments'.
13 // --------------------------------------------------------------------------
14 //
15 // Copyright ((c)) 2002-2019, Rice University
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are
20 // met:
21 //
22 // * Redistributions of source code must retain the above copyright
23 // notice, this list of conditions and the following disclaimer.
24 //
25 // * Redistributions in binary form must reproduce the above copyright
26 // notice, this list of conditions and the following disclaimer in the
27 // documentation and/or other materials provided with the distribution.
28 //
29 // * Neither the name of Rice University (RICE) nor the names of its
30 // contributors may be used to endorse or promote products derived from
31 // this software without specific prior written permission.
32 //
33 // This software is provided by RICE and contributors "as is" and any
34 // express or implied warranties, including, but not limited to, the
35 // implied warranties of merchantability and fitness for a particular
36 // purpose are disclaimed. In no event shall RICE or contributors be
37 // liable for any direct, indirect, incidental, special, exemplary, or
38 // consequential damages (including, but not limited to, procurement of
39 // substitute goods or services; loss of use, data, or profits; or
40 // business interruption) however caused and on any theory of liability,
41 // whether in contract, strict liability, or tort (including negligence
42 // or otherwise) arising in any way out of the use of this software, even
43 // if advised of the possibility of such damage.
44 //
45 // ******************************************************* EndRiceCopyright *
46 
47 //***************************************************************************
48 //
49 // File:
50 // $HeadURL$
51 //
52 // Purpose:
53 // [The purpose of this file]
54 //
55 // Description:
56 // [The set of functions, macros, etc. defined in the file]
57 //
58 //***************************************************************************
59 
60 #ifndef prof_Prof_CallPath_Profile_hpp
61 #define prof_Prof_CallPath_Profile_hpp
62 
63 //************************* System Include Files ****************************
64 
65 #include <iostream>
66 #include <cstdio>
67 
68 #include <vector>
69 #include <map>
70 #include <set>
71 #include <string>
72 
73 
74 //*************************** User Include Files ****************************
75 
76 #include <include/uint.h>
77 
78 #include "Metric-Mgr.hpp"
79 #include "LoadMap.hpp"
80 #include "CCT-Tree.hpp"
81 #include "StringSet.hpp"
82 
83 #include <lib/support/FileUtil.hpp> // dirname
84 
85 #include "../binutils/SimpleSymbolsFactories.hpp"
86 
87 
88 //*************************** Forward Declarations ***************************
89 
90 typedef std::map<int, Prof::CCT::ANode*> CCTIdToCCTNodeMap;
91 
92 
93 //*************************** Forward Declarations ***************************
94 
95 //***************************************************************************
96 // Profile
97 //***************************************************************************
98 
99 namespace Prof {
100 
101 namespace CallPath {
102 
103 
104 class Profile
105  : public Unique // non copyable
106 {
107 public:
108  Profile(const std::string name);
109  virtual ~Profile();
110 
111  // -------------------------------------------------------
112  // meta data
113  // -------------------------------------------------------
114  const std::string&
115  name() const
116  { return m_name; }
117 
118  void
119  name(const std::string& x)
120  { m_name = x; }
121 
122  void
123  name(const char* x)
124  { m_name = (x) ? x : ""; }
125 
126 
127  double
128  fmtVersion() const
129  { return m_fmtVersion; }
130 
131 
132  const StringSet&
134  { return m_traceFileNameSet; }
135 
136 
137  StringSet&
139  { return m_traceFileNameSet; }
140 
141  // enable/disable redundancy of procedure names
142  // @param flag: true -- redundancy is eliminated
143  // false -- redundancy is allowed
144  void disable_redundancy(bool flag) {
145  m_remove_redundancy = flag;
146  }
147 
148  void
149  addDirectory(std::string filename) {
150  std::string directory = FileUtil::dirname(filename);
151  if (!directory.empty()) {
152  m_directorySet.insert(directory);
153  }
154  }
155 
156  void
157  copyDirectory(const StringSet &rhs) {
158  m_directorySet += rhs;
159  }
160 
161  StringSet&
163  return m_directorySet;
164  }
165 
166  // -------------------------------------------------------
167  // MetricMgr
168  // -------------------------------------------------------
169 
170  const Metric::Mgr*
171  metricMgr() const
172  { return m_mMgr; }
173 
174  Metric::Mgr*
176  { return m_mMgr; }
177 
178  void
180  { m_mMgr = mMgr; }
181 
182 
183  // isMetricMgrVirtual: It is sometimes useful for the metric manager
184  // to contain descriptions of metrics for which there are no
185  // corresponding values. We call this a virtual metric manager.
186  // The main use of this is when profiles are read with the
187  // RFlg_VirtualMetrics flag.
188  //
189  // NOTE: alternatively, we could have the metric manager read just
190  // enough of each file to pull out the metric descriptors (just as
191  // it does for flat information).
192  bool
194  { return m_isMetricMgrVirtual; }
195 
196  void
198  { m_isMetricMgrVirtual = x; }
199 
200  // -------------------------------------------------------
201  // LoadMap
202  // -------------------------------------------------------
203  const LoadMap*
204  loadmap() const
205  { return m_loadmap; }
206 
207  LoadMap*
209  { return m_loadmap; }
210 
211 
212  // -------------------------------------------------------
213  // CCT
214  // -------------------------------------------------------
215  CCT::Tree*
216  cct() const
217  { return m_cct; }
218 
219 
220  // -------------------------------------------------------
221  // Static structure
222  // -------------------------------------------------------
224  structure() const
225  { return m_structure; }
226 
227  void
229  { m_structure = x; }
230 
231 
232  // -------------------------------------------------------
233  //
234  // -------------------------------------------------------
235  enum {
236  // merge y's metrics into x's by name: the group of names in y
237  // are merged with a matching group of names in x or are created
239 
240  // for each metric in y, create a corresponding metric in x
242 
243  // merge y's metrics into x's by id: first metric in y maps to
244  // given metric id in x (assumes complete overlap)
245  Merge_MergeMetricById = 0 // or >= 0
246  };
247 
248 
249  // merge: Given a Profile y, merge y into x = 'this'. The 'mergeTy'
250  // parameter indicates how to merge y's metrics into x. Returns
251  // the index of the first merged metric in x.
252  // ASSUMES: both x and y are in canonical form (canonicalize())
253  // WARNING: the merge may change/destroy y
254  uint
255  merge(Profile& y, int mergeTy, uint mrgFlag = 0);
256 
257  // -------------------------------------------------------
258  //
259  // -------------------------------------------------------
260  enum {
261  // only read metric table, even if CCT nodes have metrics
263 
264  // do not add suffixes to metric descriptors
265  RFlg_NoMetricSfx = (1 << 1),
266 
267  // make inclusive/exclusive descriptors and (if non-virtual)
268  // corresponding space within CCT nodes
269  RFlg_MakeInclExcl = (1 << 2),
270 
271  // *private*: CCT nodes have no metrics, even if metric table is
272  // non-empty. (E.g.: When reading a profile that has been written
273  // with WFlg_virtualMetrics, there is a non-empty metric table but
274  // no metric values attached to nodes.)
276 
277  // *private*: Data generated by hpcrun as opposed to hpcprof. This
278  // affects the normalizations applied to obtain a canonical CCT.
279  RFlg_HpcrunData = (1 << 4),
280 
281  // only write metric descriptors, even if CCT nodes have metrics
283  };
284 
285  // if non-zero, indicates that CCT nodes do not have metric values
286  // even if the metric table is non-empty
287  static const char* FmtEpoch_NV_virtualMetrics;
288 
289 
290  // make: build an empty Profile or build one from profile file 'fnm'
291  static Profile*
292  make(uint rFlags);
293 
294  static Profile*
295  make(const char* fnm, uint rFlags, FILE* outfs);
296 
297 
298  // fmt_*_fread(): Reads the appropriate hpcrun_fmt object from the
299  // file stream 'infs', checking for errors, and constructs
300  // appropriate Prof::Profile::CallPath objects. If 'outfs' is
301  // non-null, a textual form of the data is echoed to 'outfs' for
302  // human inspection.
303 
304  static int
305  fmt_fread(Profile* &prof, FILE* infs, uint rFlags,
306  std::string ctxtStr, const char* filename, FILE* outfs);
307 
308  static int
309  fmt_epoch_fread(Profile* &prof, FILE* infs, uint rFlags,
310  const hpcrun_fmt_hdr_t& hdr,
311  std::string ctxtStr, const char* filename, FILE* outfs);
312 
313  static int
314  fmt_cct_fread(Profile& prof, FILE* infs, uint rFlags,
315  const metric_tbl_t& metricTbl,
316  std::string ctxtStr, FILE* outfs);
317 
318 
319  // fmt_*_fwrite(): Write the appropriate object as hpcrun_fmt to the
320  // file stream 'outfs', checking for errors.
321  //
322  // N.B.: hpcrun-fmt cannot represent static structure. Therefore,
323  // fmt_cct_fwrite() only writes out nodes of type CCT::ADynNode.
324 
325  static int
326  fmt_fwrite(const Profile& prof, FILE* outfs, uint wFlags);
327 
328  static int
329  fmt_epoch_fwrite(const Profile& prof, FILE* outfs, uint wFlags);
330 
331  static int
332  fmt_cct_fwrite(const Profile& prof, FILE* fs, uint wFlags);
333 
334  // -------------------------------------------------------
335  // Output
336  // -------------------------------------------------------
337 
338  std::ostream&
339  writeXML_hdr(std::ostream& os, uint metricBeg, uint metricEnd,
340  uint oFlags, const char* pfx = "") const;
341 
342  std::ostream&
343  writeXML_hdr(std::ostream& os, uint oFlags = 0, const char* pfx = "") const
344  { return writeXML_hdr(os, 0, m_mMgr->size(), oFlags, pfx); }
345 
346 
347  // TODO: move Analysis::CallPath::write() here?
348  //std::ostream& writeXML_cct(...) const;
349 
350  std::ostream&
351  dump(std::ostream& os = std::cerr) const;
352 
353  void
354  ddump() const;
355 
356  static const int StructMetricIdFlg = 0;
357 
358 private:
359  void
360  canonicalize(uint rFlags = 0);
361 
362  uint
363  mergeMetrics(Profile& y, int mergeTy, uint& x_newMetricBegIdx);
364 
365  // apply MergeEffects after merging two profiles
366  void
367  merge_fixCCT(const std::vector<LoadMap::MergeEffect>* mrgEffects);
368 
369  void
370  merge_fixTrace(const CCT::MergeEffectList* mrgEffects);
371 
372 private:
373  std::string m_name;
374  double m_fmtVersion;
377 
378  std::string m_profileFileName; // non-empty, if relevant
379  StringSet m_directorySet; // set of directories containing profiles
380 
381  std::string m_traceFileName; // non-empty, if relevant
384 
385  //typedef std::map<std::string, std::string> StrToStrMap;
386  //StrToStrMap m_nvPairMap;
387 
390 
392 
394  CCT::Tree* m_cct_annex; // additional root (like datacentric, resource-centric, ...etc)
395 
397 
399 };
400 
401 } // namespace CallPath
402 
403 } // namespace Prof
404 
405 
406 //***************************************************************************
407 
408 
409 //***************************************************************************
410 
411 #endif /* prof_Prof_CallPath_Profile_hpp */
412 
void copyDirectory(const StringSet &rhs)
static int fmt_cct_fwrite(const Profile &prof, FILE *fs, uint wFlags)
void structure(Prof::Struct::Tree *x)
static const char * FmtEpoch_NV_virtualMetrics
Profile(const std::string name)
static int fmt_epoch_fread(Profile *&prof, FILE *infs, uint rFlags, const hpcrun_fmt_hdr_t &hdr, std::string ctxtStr, const char *filename, FILE *outfs)
static int fmt_cct_fread(Profile &prof, FILE *infs, uint rFlags, const metric_tbl_t &metricTbl, std::string ctxtStr, FILE *outfs)
std::list< MergeEffect > MergeEffectList
Definition: CCT-Merge.hpp:126
string dirname(const char *fName)
Definition: FileUtil.cpp:134
const StringSet & traceFileNameSet() const
std::ostream & dump(std::ostream &os=std::cerr) const
std::ostream & writeXML_hdr(std::ostream &os, uint metricBeg, uint metricEnd, uint oFlags, const char *pfx="") const
uint size() const
Definition: Metric-Mgr.hpp:153
void name(const char *x)
unsigned int uint
Definition: uint.h:124
static int fmt_epoch_fwrite(const Profile &prof, FILE *outfs, uint wFlags)
uint merge(Profile &y, int mergeTy, uint mrgFlag=0)
const LoadMap * loadmap() const
std::map< int, Prof::CCT::ANode * > CCTIdToCCTNodeMap
void name(const std::string &x)
static int fmt_fwrite(const Profile &prof, FILE *outfs, uint wFlags)
static const int StructMetricIdFlg
const Metric::Mgr * metricMgr() const
void disable_redundancy(bool flag)
Prof::Struct::Tree * structure() const
void metricMgr(Metric::Mgr *mMgr)
static Profile * make(uint rFlags)
uint mergeMetrics(Profile &y, int mergeTy, uint &x_newMetricBegIdx)
std::ostream & writeXML_hdr(std::ostream &os, uint oFlags=0, const char *pfx="") const
void canonicalize(uint rFlags=0)
void addDirectory(std::string filename)
static int fmt_fread(Profile *&prof, FILE *infs, uint rFlags, std::string ctxtStr, const char *filename, FILE *outfs)
void merge_fixCCT(const std::vector< LoadMap::MergeEffect > *mrgEffects)
void merge_fixTrace(const CCT::MergeEffectList *mrgEffects)
const std::string & name() const
Prof::Struct::Tree * m_structure
CCT::Tree * cct() const