HPCToolkit
CallPath-Profile.cpp
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 //************************* System Include Files ****************************
61 
62 #define __STDC_LIMIT_MACROS /* stdint; locate here for CentOS 5/gcc 4.1.2) */
63 
64 #include <iostream>
65 using std::hex;
66 using std::dec;
67 
68 #include <typeinfo>
69 
70 #include <string>
71 using std::string;
72 
73 #include <vector>
74 #include <map>
75 #include <algorithm>
76 #include <sstream>
77 
78 #include <cstdio>
79 #include <cstring> // strcmp
80 #include <cmath> // abs
81 
82 #include <stdint.h>
83 #include <unistd.h>
84 
85 #define __STDC_FORMAT_MACROS
86 #include <inttypes.h>
87 
88 #include <alloca.h>
89 #include <linux/limits.h>
90 
91 
92 
93 //*************************** User Include Files ****************************
94 
95 #include <include/gcc-attr.h>
96 #include <include/uint.h>
97 
98 #include "CallPath-Profile.hpp"
99 #include "FileError.hpp"
100 #include "NameMappings.hpp"
101 #include "Struct-Tree.hpp"
102 
103 #include <lib/xml/xml.hpp>
104 using namespace xml;
105 
106 
107 #include <lib/prof-lean/hpcfmt.h>
110 
111 #include <lib/support/diagnostics.h>
112 #include <lib/support/FileUtil.hpp>
113 #include <lib/support/Logic.hpp>
115 #include <lib/support/StrUtil.hpp>
116 
117 #include <lib/support/ExprEval.hpp>
118 #include <lib/support/VarMap.hpp>
119 
120 //*************************** Forward Declarations **************************
121 
122 // implementations of prof_abort will be separately defined for MPI and
123 // non-MPI contexts
124 extern void
126 (
127  int error_code
128 );
129 
130 
131 
132 //***************************************************************************
133 // macros
134 //***************************************************************************
135 
136 #define DBG 0
137 #define DBG_DATA 0
138 #define MAX_PREFIX_CHARS 64
139 
140 
141 
142 //***************************************************************************
143 // Profile
144 //***************************************************************************
145 
146 namespace Prof {
147 
148 // -------------------------------------------------------------------------
149 // special variables to store mapping between the original and unique ID
150 // this table is needed to avoid duplicate filenames that arise with alien
151 // and loop nodes.
152 // this variable will be used by getFileIdFromMap in CCT-Tree.cpp
153 // ---------------------------------------------------
154 std::map<uint, uint> m_mapFileIDs; // map between file IDs
155 std::map<uint, uint> m_mapProcIDs; // map between proc IDs
156 
157 // all fake load modules will be merged into one single load module
158 // whoever the first one arrive, will be the main fake load module
159 std::map<uint, uint> m_pairFakeLoadModule;
160 
161 namespace CallPath {
162 
163 
164 Profile::Profile(const std::string name)
165 {
166  m_name = name;
167  m_fmtVersion = 0.0;
168  m_flags.bits = 0;
169  m_measurementGranularity = 0;
170 
171  m_traceMinTime = UINT64_MAX;
172  m_traceMaxTime = 0;
173 
174  m_mMgr = new Metric::Mgr;
175  m_isMetricMgrVirtual = false;
176 
177  m_loadmap = new LoadMap;
178 
179  m_cct = new CCT::Tree(this);
180 
181  m_structure = NULL;
182 
183  canonicalize();
184 }
185 
186 
187 Profile::~Profile()
188 {
189  delete m_mMgr;
190  delete m_loadmap;
191  delete m_cct;
192  delete m_structure;
193 }
194 
195 
196 uint
197 Profile::merge(Profile& y, int mergeTy, uint mrgFlag)
198 {
199  Profile& x = (*this);
200 
201  DIAG_Assert(!y.m_structure, "Profile::merge: source profile should not have structure yet!");
202 
203  // -------------------------------------------------------
204  // merge name, flags, etc
205  // -------------------------------------------------------
206 
207  // Note: these values can be 'null' if the hpcrun-fmt data had no epochs
208  if (x.m_fmtVersion == 0.0) {
210  }
211  else if (y.m_fmtVersion == 0.0) {
213  }
214 
215  if (x.m_flags.bits == 0) {
216  x.m_flags.bits = y.m_flags.bits;
217  }
218  else if (y.m_flags.bits == 0) {
219  y.m_flags.bits = x.m_flags.bits;
220  }
221 
222  if (x.m_measurementGranularity == 0) {
224  }
225  else if (y.m_measurementGranularity == 0) {
227  }
228 
229  DIAG_WMsgIf(x.m_fmtVersion != y.m_fmtVersion,
230  "CallPath::Profile::merge(): ignoring incompatible versions: "
231  << x.m_fmtVersion << " vs. " << y.m_fmtVersion);
232  DIAG_WMsgIf(x.m_flags.bits != y.m_flags.bits,
233  "CallPath::Profile::merge(): ignoring incompatible flags: "
234  << x.m_flags.bits << " vs. " << y.m_flags.bits);
236  "CallPath::Profile::merge(): ignoring incompatible measurement-granularity: " << x.m_measurementGranularity << " vs. " << y.m_measurementGranularity);
237 
238  x.m_profileFileName = "";
239 
240  x.m_traceFileName = "";
241  x.m_traceFileNameSet.insert(y.m_traceFileNameSet.begin(),
242  y.m_traceFileNameSet.end());
243  x.m_traceMinTime = std::min(x.m_traceMinTime, y.m_traceMinTime);
244  x.m_traceMaxTime = std::max(x.m_traceMaxTime, y.m_traceMaxTime);
245 
246 
247  // -------------------------------------------------------
248  // merge metrics
249  // -------------------------------------------------------
250  uint x_newMetricBegIdx = 0;
251  uint firstMergedMetric = mergeMetrics(y, mergeTy, x_newMetricBegIdx);
252 
253  // -------------------------------------------------------
254  // merge LoadMaps
255  //
256  // Post-INVARIANT: y's cct refers to x's LoadMap
257  // -------------------------------------------------------
258  std::vector<LoadMap::MergeEffect>* mrgEffects1 =
259  x.m_loadmap->merge(*y.loadmap());
260  y.merge_fixCCT(mrgEffects1);
261  delete mrgEffects1;
262 
263  // -------------------------------------------------------
264  // merge CCTs
265  // -------------------------------------------------------
266 
267  if (mrgFlag & CCT::MrgFlg_NormalizeTraceFileY) {
268  mrgFlag |= CCT::MrgFlg_PropagateEffects;
269  }
270 
271  CCT::MergeEffectList* mrgEffects2 =
272  x.cct()->merge(y.cct(), x_newMetricBegIdx, mrgFlag);
273 
274  DIAG_Assert(Logic::implies(mrgEffects2 && !mrgEffects2->empty(),
276  "CallPath::Profile::merge: there should only be CCT::MergeEffects when MrgFlg_NormalizeTraceFileY is passed");
277 
278  y.merge_fixTrace(mrgEffects2);
279  delete mrgEffects2;
280 
281  return firstMergedMetric;
282 }
283 
284 
285 uint
286 Profile::mergeMetrics(Profile& y, int mergeTy, uint& x_newMetricBegIdx)
287 {
288  Profile& x = (*this);
289 
290  DIAG_Assert(x.m_isMetricMgrVirtual == y.m_isMetricMgrVirtual,
291  "CallPath::Profile::merge(): incompatible metrics");
292 
293  DIAG_MsgIf(0, "Profile::mergeMetrics: init\n"
294  << "x: " << x.metricMgr()->toString(" ")
295  << "y: " << y.metricMgr()->toString(" "));
296 
297  uint yBeg_mapsTo_xIdx = 0;
298 
299  x_newMetricBegIdx = 0; // first metric in y maps to (metricsMapTo)
300 
301  // -------------------------------------------------------
302  // Translate Merge_mergeMetricByName to a primitive merge type
303  // -------------------------------------------------------
304  if (mergeTy == Merge_MergeMetricByName) {
305  uint mapsTo = x.metricMgr()->findGroup(*y.metricMgr());
306  mergeTy = (mapsTo == Metric::Mgr::npos) ? Merge_CreateMetric : (int)mapsTo;
307  }
308 
309  // -------------------------------------------------------
310  // process primitive merge types
311  // -------------------------------------------------------
312  // the index, within y, of the first new metric to add to x
313  uint y_newMetricIdx = Metric::Mgr::npos;
314 
315  if (mergeTy == Merge_CreateMetric) {
316  yBeg_mapsTo_xIdx = x.metricMgr()->size();
317 
318  y_newMetricIdx = 0;
319  }
320  else if (mergeTy >= Merge_MergeMetricById) {
321  yBeg_mapsTo_xIdx = (uint)mergeTy; // [
322 
323  uint yEnd_mapsTo_xIdx = yBeg_mapsTo_xIdx + y.metricMgr()->size(); // )
324  if (! (x.metricMgr()->size() >= yEnd_mapsTo_xIdx) ) {
325  uint overlapSz = x.metricMgr()->size() - yBeg_mapsTo_xIdx;
326  y_newMetricIdx = overlapSz;
327  }
328  }
329  else {
331  }
332 
333  for (uint i = y_newMetricIdx; i < y.metricMgr()->size(); ++i) {
334  const Metric::ADesc* m = y.metricMgr()->metric(i);
335  x.metricMgr()->insert(m->clone());
336  }
337 
338  if (!isMetricMgrVirtual()) {
339  x_newMetricBegIdx = yBeg_mapsTo_xIdx;
340  }
341 
342  DIAG_MsgIf(0, "Profile::mergeMetrics: fini:\n" << m_mMgr->toString(" "));
343 
344  return yBeg_mapsTo_xIdx;
345 }
346 
347 
348 void
349 Profile::merge_fixCCT(const std::vector<LoadMap::MergeEffect>* mrgEffects)
350 {
351  // early exit for trivial case
352  if (!mrgEffects || mrgEffects->empty()) {
353  return;
354  }
355 
356  CCT::ANode* root = cct()->root();
357 
358  for (CCT::ANodeIterator it(root); it.Current(); ++it) {
359  CCT::ANode* n = it.current();
360 
361  CCT::ADynNode* n_dyn = dynamic_cast<CCT::ADynNode*>(n);
362  if (n_dyn) {
363  lush_lip_t* lip = n_dyn->lip();
364 
365  LoadMap::LMId_t lmId1, lmId2;
366  lmId1 = n_dyn->lmId_real();
367  lmId2 = (lip) ? lush_lip_getLMId(lip) : LoadMap::LMId_NULL;
368 
369  for (uint i = 0; i < mrgEffects->size(); ++i) {
370  const LoadMap::MergeEffect& chg = (*mrgEffects)[i];
371  if (chg.old_id == lmId1) {
372  n_dyn->lmId_real(chg.new_id);
373  if (lmId2 == LoadMap::LMId_NULL) {
374  break; // quick exit in the common case
375  }
376  }
377  if (chg.old_id == lmId2) {
378  lush_lip_setLMId(lip, (uint16_t) chg.new_id);
379  }
380  }
381  }
382  }
383 }
384 
385 
386 void
387 Profile::merge_fixTrace(const CCT::MergeEffectList* mrgEffects)
388 {
389  typedef std::map<uint, uint> UIntToUIntMap;
390 
391  // early exit for trivial case
392  if (m_traceFileName.empty()) {
393  return;
394  }
395  else if (!mrgEffects || mrgEffects->empty()) {
396  return; // rely on Analysis::Util::copyTraceFiles() to copy orig file
397  }
398 
399  // N.B.: We could build a map of old->new cpIds within
400  // Profile::merge(), but the list of effects is more general and
401  // extensible. There are no asymptotic problems with building the
402  // following map for local use.
403  UIntToUIntMap cpIdMap;
404  for (CCT::MergeEffectList::const_iterator it = mrgEffects->begin();
405  it != mrgEffects->end(); ++it) {
406  const CCT::MergeEffect& effct = *it;
407  cpIdMap.insert(std::make_pair(effct.old_cpId, effct.new_cpId));
408  }
409 
410  // ------------------------------------------------------------
411  // Rewrite trace file
412  // ------------------------------------------------------------
413  int ret;
414 
415  DIAG_MsgIf(0, "Profile::merge_fixTrace: " << m_traceFileName);
416 
417  string traceFileNameTmp = m_traceFileName + "." + HPCPROF_TmpFnmSfx;
418 
419  char* infsBuf = new char[HPCIO_RWBufferSz];
420  char* outfsBuf = new char[HPCIO_RWBufferSz];
421 
422  const string& inFnm = m_traceFileName;
423  FILE* infs = hpcio_fopen_r(inFnm.c_str());
424  if (!infs) {
425  std::string errorString;
426  hpcrun_getFileErrorString(inFnm, errorString);
427  DIAG_EMsg("failed to open trace file " << errorString << "; skip this one.");
428  return;
429  }
430 
431  ret = setvbuf(infs, infsBuf, _IOFBF, HPCIO_RWBufferSz);
432  DIAG_AssertWarn(ret == 0, inFnm << ": Profile::merge_fixTrace: setvbuf!");
433 
434  hpctrace_fmt_hdr_t hdr;
435  ret = hpctrace_fmt_hdr_fread(&hdr, infs);
436  if (ret == HPCFMT_ERR) {
437  std::string errorString;
438  hpcrun_getFileErrorString(inFnm, errorString);
439  DIAG_EMsg("failed reading header from trace measurement file " << errorString << "; skip this one.");
440  hpcio_fclose(infs);
441  return;
442  }
443 
444  const string& outFnm = traceFileNameTmp;
445  FILE* outfs = hpcio_fopen_w(outFnm.c_str(), 1/*overwrite*/);
446  if (!outfs) {
447  if (errno == EDQUOT) {
448  DIAG_EMsg("disk quota exceeded; unable to open trace result file " <<
449  outFnm << "; aborting.");
450  hpcio_fclose(infs);
451  prof_abort(-1);
452  } else {
453  std::string errorString;
454  hpcrun_getFileErrorString(outFnm, errorString);
455  DIAG_EMsg("failed opening trace result file " << errorString <<
456  "when processing trace measurement file " << inFnm << "; skip this one.");
457  hpcio_fclose(infs);
458  return;
459  }
460  }
461 
462  ret = setvbuf(outfs, outfsBuf, _IOFBF, HPCIO_RWBufferSz);
463  DIAG_AssertWarn(ret == 0, outFnm << ": Profile::merge_fixTrace: setvbuf!");
464 
465  ret = hpctrace_fmt_hdr_fwrite(hdr.flags, outfs);
466  if (ret == HPCFMT_ERR) goto badwrite;
467 
468  while ( !feof(infs) ) {
469  // 1. Read trace record (exit on EOF)
470  hpctrace_fmt_datum_t datum;
471  ret = hpctrace_fmt_datum_fread(&datum, hdr.flags, infs);
472  if (ret == HPCFMT_EOF) {
473  break;
474  } else if (ret == HPCFMT_ERR) {
475  DIAG_EMsg("failed reading a record from trace measurement file " << inFnm << "; skip this one.");
476  hpcio_fclose(infs);
477  hpcio_fclose(outfs);
478  unlink(outFnm.c_str()); // delete incomplete output file
479  return;
480  }
481 
482  // 2. Translate cct id
483  uint cctId_old = datum.cpId;
484  uint cctId_new = datum.cpId;
485  UIntToUIntMap::iterator it = cpIdMap.find(cctId_old);
486  if (it != cpIdMap.end()) {
487  cctId_new = it->second;
488  DIAG_MsgIf(0, " " << cctId_old << " -> " << cctId_new);
489  }
490  datum.cpId = cctId_new;
491 
492  // 3. Write new trace record
493  ret = hpctrace_fmt_datum_fwrite(&datum, hdr.flags, outfs);
494  if (ret == HPCFMT_ERR) goto badwrite;
495  }
496 
497  hpcio_fclose(infs);
498  hpcio_fclose(outfs);
499 
500  delete[] infsBuf;
501  delete[] outfsBuf;
502  return;
503 
504 badwrite:
505  {
506  std::string errorString;
507  hpcrun_getFileErrorString(outFnm, errorString);
508  DIAG_EMsg("failed writing trace result file " << errorString << "; aborting.");
509  hpcio_fclose(infs);
510  hpcio_fclose(outfs);
511  unlink(outFnm.c_str()); // delete incomplete output file
512  prof_abort(-1);
513  }
514 }
515 
516 
517 
518 // ---------------------------------------------------
519 // String comparison used for hash map
520 // ---------------------------------------------------
522 public:
523  bool operator()(const std::string n1, const std::string n2) const {
524  return n1.compare(n2)<0;
525  }
526 };
527 
528 // ---------------------------------------------------
529 // special variables to store mapping between filename and the ID
530 // this hack is needed to avoid duplicate filenames
531 // which occurs with alien nodes
532 // ---------------------------------------------------
533 static std::map<std::string, uint, StringCompare> m_mapFiles; // map the filenames and the ID
534 static std::map<std::string, uint, StringCompare> m_mapProcs; // map the procedure names and the ID
535 
536 // attempt to retrieve the filename of a node
537 // if the node is an alien or a loop or a file, then we are guaranteed to
538 // retrieve the current filename associated to the node.
539 //
540 // However, if the node is not of those types, we'll try to get
541 // the ancestor file of the node. This is not the proper way to get the
542 // filename, but it's the closest we can get (AFAIK).
543 static const char *
545 {
546  const char *nm = NULL;
547  if (strct)
548  {
549  const std::type_info &tid = typeid(*strct);
550 
551  if (tid == typeid(Struct::Alien)) {
552  nm = static_cast<Struct::Alien*>(strct)->fileName().c_str();
553  } else if (tid == typeid(Struct::Loop)) {
554  nm = static_cast<Struct::Loop*>(strct)->fileName().c_str();
555  } else if (tid == typeid(Struct::File)){
556  nm = static_cast<Struct::File*>(strct)->name().c_str();
557  } else {
558  Prof::Struct::File *file = strct->ancestorFile();
559  if (file) {
560  nm = file->name().c_str();
561  }
562  }
563  }
564  return nm;
565 }
566 
567 // writing XML dictionary in the header part of experiment.xml
568 static void
569 writeXML_help(std::ostream& os, const char* entry_nm,
570  Struct::Tree* structure, const Struct::ANodeFilter* filter,
571  int type, bool remove_redundancy)
572 {
573  Struct::ANode* root = structure ? structure->root() : NULL;
574  if (!root) {
575  return;
576  }
577 
578  for (Struct::ANodeIterator it(root, filter); it.Current(); ++it) {
579  Struct::ANode* strct = it.current();
580 
581  uint id = strct->id();
582  const char* nm = NULL;
583 
584  int fake_procedure = 0;
585 
586  if (type == 1) { // LoadModule
587  nm = static_cast<Prof::Struct::LM *> (strct)->pretty_name(); //strct->name().c_str();
589  if (sf) {
590  sf->id(id);
591  m_pairFakeLoadModule.insert(std::make_pair(id, sf->id()));
592 
593  nm = sf->unified_name();
594  }
595  }
596  else if (type == 2) { // File
597  nm = getFileName(strct);
598  // ---------------------------------------
599  // avoid redundancy in XML filename dictionary
600  // (exception for unknown-file)
601  // ---------------------------------------
602  Struct::LM *lm = strct->ancestorLM();
603  std::string lm_name;
604  if (lm) {
605  // use pretty_name for the key to unify different names of vmlinux
606  // i.e.: vmlinux.aaaaa = vmlinux.bbbbbb = vmlinux.ccccc = vmlinux
607  lm_name = lm->pretty_name();
608  }
609  std::string key = lm_name + ":" + nm;
610 
611  if (m_mapFiles.find(key) == m_mapFiles.end()) {
612  // the filename is not in the list. Add it.
613  m_mapFiles[key] = id;
614 
615  } else if ( nm != Prof::Struct::Tree::UnknownFileNm
616  && nm[0] != '\0' )
617  {
618  // WARNING: We do not allow redundancy unless for some specific files
619  // For "unknown-file" and empty file (alien case), we allow duplicates
620  // Otherwise we remove duplicate filename, and use the existing one.
621  uint id_orig = m_mapFiles[key];
622 
623  // remember that this ID needs redirection to the existing ID
624  Prof::m_mapFileIDs[id] = id_orig;
625  continue;
626  }
627  }
628  else if (type == 3) { // Proc
629  const char *proc_name = strct->name().c_str();
630  nm = normalize_name(proc_name, fake_procedure);
631 
632  if (remove_redundancy &&
634  {
635  // -------------------------------------------------------
636  // avoid redundancy in XML procedure dictionary
637  // a procedure can have the same name if they are from different
638  // file or different load module
639  // -------------------------------------------------------
640  std::string completProcName;
641 
642  Struct::File *file = strct->ancestorFile();
643  uint file_id = (file != NULL ? file->id() : 0);
644  Struct::LM *lm = strct->ancestorLM();
645  if (lm) {
646  uint lm_id = lm->id();
648  if (sf) {
649  lm_id = sf->id();
650 
651  // if we haven't set fake_file_id, we need to set it with
652  // the file id of this struct.
653  // otherwise, we just reuse the fake_file_id to make it consistent
654  // across different lm
655 
656  sf->fileId(file_id);
657  file_id = sf->fileId();
658  }
659 
660  char buffer[MAX_PREFIX_CHARS];
661  snprintf(buffer, MAX_PREFIX_CHARS, "lm_%d:", lm_id);
662  completProcName.append(buffer);
663  }
664 
665  // we need to allow the same function name from a different file
666  char buffer[MAX_PREFIX_CHARS];
667  snprintf(buffer, MAX_PREFIX_CHARS, "f_%d:", file_id);
668  completProcName.append(buffer);
669 
670  const char *lnm;
671 
672  // a procedure name within the same file has to be unique.
673  // However, for codes compiled with GCC, binutils (or parseAPI)
674  // it's better to compare internally with the mangled names
675  Struct::Proc *proc = dynamic_cast<Struct::Proc *>(strct);
676  if (proc)
677  {
678  if (proc->linkName().empty()) {
679  // the proc has no mangled name
680  lnm = proc_name;
681  } else
682  { // get the mangled name
683  lnm = proc->linkName().c_str();
684  }
685  } else
686  {
687  lnm = strct->name().c_str();
688  }
689  completProcName.append(lnm);
690  if (m_mapProcs.find(completProcName) == m_mapProcs.end())
691  {
692  // the proc is not in dictionary. Add it into the map.
693  m_mapProcs[completProcName] = id;
694  } else
695  {
696  // the same procedure name already exists, we need to reuse
697  // the previous ID instead of the original one.
698  uint id_orig = m_mapProcs[completProcName];
699 
700  // remember that this ID needs redirection to the existing ID
701  Prof::m_mapProcIDs[id] = id_orig;
702  continue;
703  }
704  }
705  } else {
707  }
708 
709  os << " <" << entry_nm << " i" << MakeAttrNum(id)
710  << " n" << MakeAttrStr(nm);
711 
712  if (fake_procedure > 0) {
713  os << " f" << MakeAttrNum(fake_procedure);
714  }
715 
716  os << "/>\n";
717  }
718 }
719 
720 
721 static bool
723 {
724  return (typeid(x) == typeid(Struct::File) || typeid(x) == typeid(Struct::Alien) ||
725  typeid(x) == typeid(Struct::Loop));
726 }
727 
728 
729 static bool
731 {
732  return (typeid(x) == typeid(Struct::Proc) || typeid(x) == typeid(Struct::Alien));
733 }
734 
735 
736 std::ostream&
737 Profile::writeXML_hdr(std::ostream& os, uint metricBeg, uint metricEnd,
738  uint oFlags, const char* GCC_ATTR_UNUSED pfx) const
739 {
740  typedef std::map<uint, string> UIntToStringMap;
741  UIntToStringMap metricIdToFormula;
742 
743  // -------------------------------------------------------
744  //
745  // -------------------------------------------------------
746  os << " <MetricTable>\n";
747  for (uint i = metricBeg; i < metricEnd; i++) {
748  const Metric::ADesc* m = m_mMgr->metric(i);
749 
750  bool isDrvd = false;
751  Metric::IDBExpr* mDrvdExpr = NULL;
752  if (typeid(*m) == typeid(Metric::DerivedDesc)) {
753  isDrvd = true;
754  mDrvdExpr = static_cast<const Metric::DerivedDesc*>(m)->expr();
755  }
756  else if (typeid(*m) == typeid(Metric::DerivedIncrDesc)) {
757  isDrvd = true;
758  mDrvdExpr = static_cast<const Metric::DerivedIncrDesc*>(m)->expr();
759  }
760 
761  // Metric
762  os << " <Metric i" << MakeAttrNum(i)
763  << " n" << MakeAttrStr(m->name())
764  << " v=\"" << m->toValueTyStringXML() << "\""
765  << " em=\"" << m->isMultiplexed() << "\""
766  << " es=\"" << m->num_samples() << "\""
767  << " ep=\"" << long(m->periodMean()) << "\""
768  << " t=\"" << Prof::Metric::ADesc::ADescTyToXMLString(m->type()) << "\"";
769  if (m->partner()) {
770  os << " partner" << MakeAttrNum(m->partner()->id());
771  }
772  os << " show=\"" << ((m->isVisible()) ? "1" : "0") << "\""
773  << " show-percent=\"" << ((m->doDispPercent()) ? "1" : "0") << "\""
774  << ">\n";
775 
776  // MetricFormula
777  if (isDrvd) {
778 
779  // 0. retrieve combine formula (each DerivedIncrDesc corresponds
780  // to an 'accumulator')
781  string combineFrm;
782  if (mDrvdExpr) {
783  combineFrm = mDrvdExpr->combineString1();
784 
785  for (uint k = 1; k < mDrvdExpr->numAccum(); ++k) {
786  uint mId = mDrvdExpr->accumId(k);
787  string frm = mDrvdExpr->combineString2();
788  metricIdToFormula.insert(std::make_pair(mId, frm));
789  }
790  }
791  else {
792  // must represent accumulator 2
793  uint mId = m->id();
794  UIntToStringMap::iterator it = metricIdToFormula.find(mId);
795  DIAG_Assert((it != metricIdToFormula.end()), DIAG_UnexpectedInput);
796  combineFrm = it->second;
797  }
798 
799  // 1. MetricFormula: combine
800  os << " <MetricFormula t=\"combine\""
801  << " frm=\"" << combineFrm << "\"/>\n";
802 
803  // 2. MetricFormula: finalize
804  if (mDrvdExpr) {
805  os << " <MetricFormula t=\"finalize\""
806  << " frm=\"" << mDrvdExpr->finalizeString() << "\"/>\n";
807  }
808  }
809 
810  // Info
811  os << " <Info>"
812  << "<NV n=\"units\" v=\"events\"/>"; // or "samples" m->isUnitsEvents()
813 
814  const Metric::SampledDesc* mSmpl =
815  dynamic_cast<const Metric::SampledDesc*>(m);
816  if (mSmpl) {
817  os << "<NV n=\"period\" v" << MakeAttrNum(mSmpl->period()) << "/>";
818  }
819  os << "</Info>\n";
820  os << " </Metric>\n";
821  }
822  os << " </MetricTable>\n";
823 
824  // -------------------------------------------------------
825  //
826  // -------------------------------------------------------
827  os << " <MetricDBTable>\n";
828  for (uint i = 0; i < m_mMgr->size(); i++) {
829  const Metric::ADesc* m = m_mMgr->metric(i);
830  if (m->hasDBInfo()) {
831  os << " <MetricDB i" << MakeAttrNum(i)
832  << " n" << MakeAttrStr(m->name())
833  << " t=\"" << Prof::Metric::ADesc::ADescTyToXMLString(m->type()) << "\"";
834  if (m->partner()) {
835  os << " partner" << MakeAttrNum(m->partner()->id());
836  }
837  os << " db-glob=\"" << m->dbFileGlob() << "\""
838  << " db-id=\"" << m->dbId() << "\""
839  << " db-num-metrics=\"" << m->dbNumMetrics() << "\""
840  << " db-header-sz=\"" << HPCMETRICDB_FMT_HeaderLen << "\""
841  << "/>\n";
842  }
843  }
844  os << " </MetricDBTable>\n";
845 
846  // -------------------------------------------------------
847  //
848  // -------------------------------------------------------
849  if (!traceFileNameSet().empty()) {
850  os << " <TraceDBTable>\n";
851  os << " <TraceDB i" << MakeAttrNum(0)
852  << " db-glob=\"" << "*." << HPCRUN_TraceFnmSfx << "\""
853  << " db-min-time=\"" << m_traceMinTime << "\""
854  << " db-max-time=\"" << m_traceMaxTime << "\""
855  << " db-header-sz=\"" << HPCTRACE_FMT_HeaderLen << "\""
856  << "/>\n";
857  os << " </TraceDBTable>\n";
858  }
859 
860  // -------------------------------------------------------
861  //
862  // -------------------------------------------------------
863  os << " <LoadModuleTable>\n";
864  writeXML_help(os, "LoadModule", m_structure,
865  &Struct::ANodeTyFilter[Struct::ANode::TyLM], 1,
866  m_remove_redundancy);
867  os << " </LoadModuleTable>\n";
868 
869  // -------------------------------------------------------
870  //
871  // -------------------------------------------------------
872  os << " <FileTable>\n";
873  Struct::ANodeFilter filt1(writeXML_FileFilter, "FileTable", 0);
874  writeXML_help(os, "File", m_structure, &filt1, 2, m_remove_redundancy);
875  os << " </FileTable>\n";
876 
877  // -------------------------------------------------------
878  //
879  // -------------------------------------------------------
880  if ( !(oFlags & CCT::Tree::OFlg_Debug) ) {
881  os << " <ProcedureTable>\n";
882  Struct::ANodeFilter filt2(writeXML_ProcFilter, "ProcTable", 0);
883  writeXML_help(os, "Procedure", m_structure, &filt2, 3, true /*m_remove_redundancy*/);
884  os << " </ProcedureTable>\n";
885  }
886 
887  return os;
888 }
889 
890 
891 std::ostream&
892 Profile::dump(std::ostream& os) const
893 {
894  os << m_name << std::endl;
895 
896  m_mMgr->dump(os);
897 
898  m_loadmap->dump(os);
899 
900  if (m_cct) {
901  m_cct->dump(m_mMgr, os, CCT::Tree::OFlg_DebugAll);
902  }
903  return os;
904 }
905 
906 
907 void
908 Profile::ddump() const
909 {
910  dump();
911 }
912 
913 
914 } // namespace CallPath
915 
916 } // namespace Prof
917 
918 
919 //***************************************************************************
920 //
921 //***************************************************************************
922 
923 static std::pair<Prof::CCT::ADynNode*, Prof::CCT::ADynNode*>
925  const hpcrun_fmt_cct_node_t& nodeFmt, uint rFlags,
926  const std::string& ctxtStr);
927 
928 static void
930  epoch_flags_t flags);
931 
932 
933 //***************************************************************************
934 
935 namespace Prof {
936 
937 namespace CallPath {
938 
939 const char* Profile::FmtEpoch_NV_virtualMetrics = "is-virtual-metrics";
940 
941 Profile*
942 Profile::make(uint rFlags)
943 {
944  Profile* prof = new Profile("[program-name]");
945 
946  if (rFlags & RFlg_VirtualMetrics) {
947  prof->isMetricMgrVirtual(true);
948  }
949  prof->canonicalize();
950 
951  return prof;
952 }
953 
954 
955 Profile*
956 Profile::make(const char* fnm, uint rFlags, FILE* outfs)
957 {
958  int ret;
959 
960  FILE* fs = hpcio_fopen_r(fnm);
961  if (!fs) {
962  if (errno == ENOENT)
963  fprintf(stderr, "ERROR: measurement file or directory '%s' does not exist\n",
964  fnm);
965  else if (errno == EACCES)
966  fprintf(stderr, "ERROR: failed to open file '%s': file access denied\n",
967  fnm);
968  else
969  fprintf(stderr, "ERROR: failed to open file '%s': system failure\n",
970  fnm);
971  prof_abort(-1);
972  }
973 
974  char* fsBuf = new char[HPCIO_RWBufferSz];
975  ret = setvbuf(fs, fsBuf, _IOFBF, HPCIO_RWBufferSz);
976  DIAG_AssertWarn(ret == 0, "Profile::make: setvbuf!");
977 
978  rFlags |= RFlg_HpcrunData; // TODO: for now assume an hpcrun file (verify!)
979 
980  Profile* prof = NULL;
981  ret = fmt_fread(prof, fs, rFlags, fnm, fnm, outfs);
982 
983  hpcio_fclose(fs);
984 
985  delete[] fsBuf;
986 
987  return prof;
988 }
989 
990 
991 int
992 Profile::fmt_fread(Profile* &prof, FILE* infs, uint rFlags,
993  std::string ctxtStr, const char* filename, FILE* outfs)
994 {
995  int ret;
996 
997  // ------------------------------------------------------------
998  // hdr
999  // ------------------------------------------------------------
1000  hpcrun_fmt_hdr_t hdr;
1001  ret = hpcrun_fmt_hdr_fread(&hdr, infs, malloc);
1002  if (ret != HPCFMT_OK) {
1003  fprintf(stderr, "ERROR: error reading 'fmt-hdr' in '%s': either the file "
1004  "is not a profile or it is corrupted\n", filename);
1005  prof_abort(-1);
1006  }
1007  if ( !(hdr.version >= HPCRUN_FMT_Version_20) ) {
1008  DIAG_Throw("unsupported file version '" << hdr.versionStr << "'");
1009  }
1010 
1011  if (outfs) {
1012  hpcrun_fmt_hdr_fprint(&hdr, outfs);
1013  }
1014 
1015 
1016  // ------------------------------------------------------------
1017  // epoch: Read each epoch and merge them to form one Profile
1018  // ------------------------------------------------------------
1019 
1020  prof = NULL;
1021 
1022  uint num_epochs = 0;
1023  while ( !feof(infs) ) {
1024 
1025  Profile* myprof = NULL;
1026 
1027  string myCtxtStr = "epoch " + StrUtil::toStr(num_epochs + 1);
1028  ctxtStr += ": " + myCtxtStr;
1029 
1030  try {
1031  ret = fmt_epoch_fread(myprof, infs, rFlags, hdr,
1032  ctxtStr, filename, outfs);
1033  if (ret == HPCFMT_EOF) {
1034  break;
1035  }
1036  }
1037  catch (const Diagnostics::Exception& x) {
1038  delete myprof;
1039  DIAG_Throw("error reading " << ctxtStr << ": " << x.what());
1040  }
1041 
1042  if (! prof) {
1043  prof = myprof;
1044  }
1045  else {
1046  prof->merge(*myprof, Profile::Merge_MergeMetricById);
1047  }
1048 
1049  num_epochs++;
1050  }
1051 
1052  if (!prof) {
1053  prof = make(rFlags); // make an empty profile
1054  }
1055 
1056  prof->canonicalize(rFlags);
1057  prof->metricMgr()->computePartners();
1058 
1059  // ------------------------------------------------------------
1060  //
1061  // ------------------------------------------------------------
1062 
1063  if (outfs) {
1064  fprintf(outfs, "\n[You look fine today! (num-epochs: %u)]\n", num_epochs);
1065  }
1066 
1067  hpcrun_fmt_hdr_free(&hdr, free);
1068 
1069  return HPCFMT_OK;
1070 }
1071 
1072 
1073 int
1074 Profile::fmt_epoch_fread(Profile* &prof, FILE* infs, uint rFlags,
1075  const hpcrun_fmt_hdr_t& hdr,
1076  std::string ctxtStr, const char* filename,
1077  FILE* outfs)
1078 {
1079  using namespace Prof;
1080 
1081  string profFileName = (filename) ? filename : "";
1082 
1083  int ret;
1084 
1085  // ------------------------------------------------------------
1086  // Read epoch data
1087  // ------------------------------------------------------------
1088 
1089  // ----------------------------------------
1090  // epoch-hdr
1091  // ----------------------------------------
1092  hpcrun_fmt_epochHdr_t ehdr;
1093  ret = hpcrun_fmt_epochHdr_fread(&ehdr, infs, malloc);
1094  if (ret == HPCFMT_EOF) {
1095  return HPCFMT_EOF;
1096  }
1097  if (ret != HPCFMT_OK) {
1098  DIAG_Throw("error reading 'epoch-hdr'");
1099  }
1100  if (outfs) {
1101  hpcrun_fmt_epochHdr_fprint(&ehdr, outfs);
1102  }
1103 
1104  // ----------------------------------------
1105  // metric-tbl
1106  // ----------------------------------------
1107  metric_tbl_t metricTbl;
1108  metric_aux_info_t *aux_info;
1109 
1110  ret = hpcrun_fmt_metricTbl_fread(&metricTbl, &aux_info, infs, hdr.version, malloc);
1111  if (ret != HPCFMT_OK) {
1112  DIAG_Throw("error reading 'metric-tbl'");
1113  }
1114  if (outfs) {
1115  hpcrun_fmt_metricTbl_fprint(&metricTbl, aux_info, outfs);
1116  }
1117 
1118  const uint numMetricsSrc = metricTbl.len;
1119 
1120  // ----------------------------------------
1121  // loadmap
1122  // ----------------------------------------
1123  loadmap_t loadmap_tbl;
1124  ret = hpcrun_fmt_loadmap_fread(&loadmap_tbl, infs, malloc);
1125  if (ret != HPCFMT_OK) {
1126  DIAG_Throw("error reading 'loadmap'");
1127  }
1128  if (outfs) {
1129  hpcrun_fmt_loadmap_fprint(&loadmap_tbl, outfs);
1130  }
1131 
1132  // ------------------------------------------------------------
1133  // Create Profile
1134  // ------------------------------------------------------------
1135 
1136  // ----------------------------------------
1137  // obtain meta information
1138  // ----------------------------------------
1139 
1140  const char* val;
1141 
1142  // -------------------------
1143  // program name
1144  // -------------------------
1145  string progNm;
1146  val = hpcfmt_nvpairList_search(&(hdr.nvps), HPCRUN_FMT_NV_prog);
1147  if (val && strlen(val) > 0) {
1148  progNm = val;
1149  }
1150 
1151  // -------------------------
1152  // environment
1153  // -------------------------
1154 
1155 #if 0
1156  string envPath;
1157  val = hpcfmt_nvpairList_search(&(hdr.nvps), HPCRUN_FMT_NV_envPath);
1158  if (val && strlen(val) > 0) {
1159  envPath = val;
1160  }
1161 #endif
1162 
1163  // -------------------------
1164  // parallelism context (mpi rank, thread id)
1165  // -------------------------
1166  string mpiRankStr, tidStr;
1167 
1168  // val = hpcfmt_nvpairList_search(&(hdr.nvps), HPCRUN_FMT_NV_jobId);
1169 
1170  val = hpcfmt_nvpairList_search(&(hdr.nvps), HPCRUN_FMT_NV_mpiRank);
1171  if (val) {
1172  mpiRankStr = val;
1173  }
1174 
1175  val = hpcfmt_nvpairList_search(&(hdr.nvps), HPCRUN_FMT_NV_tid);
1176  if (val) {
1177  tidStr = val;
1178  }
1179 
1180  // -------------------------
1181  // trace information
1182  // -------------------------
1183 
1184  bool haveTrace = false;
1185  string traceFileName;
1186 
1187  string traceMinTimeStr, traceMaxTimeStr;
1188  uint64_t traceMinTime = UINT64_MAX, traceMaxTime = 0;
1189 
1191  if (val) {
1192  traceMinTimeStr = val;
1193  if (val[0] != '\0') { traceMinTime = StrUtil::toUInt64(traceMinTimeStr); }
1194  }
1195 
1197  if (val) {
1198  traceMaxTimeStr = val;
1199  if (val[0] != '\0') { traceMaxTime = StrUtil::toUInt64(traceMaxTimeStr); }
1200  }
1201 
1202  haveTrace = (traceMinTime != 0 && traceMaxTime != 0);
1203 
1204  // Note: 'profFileName' can be empty when reading from a memory stream
1205  if (haveTrace && !profFileName.empty()) {
1206  // TODO: extract trace file name from profile
1207  static const string ext_prof = string(".") + HPCRUN_ProfileFnmSfx;
1208  static const string ext_trace = string(".") + HPCRUN_TraceFnmSfx;
1209 
1210  traceFileName = profFileName;
1211  size_t ext_pos = traceFileName.find(ext_prof);
1212  if (ext_pos != string::npos) {
1213  traceFileName.replace(traceFileName.begin() + ext_pos,
1214  traceFileName.end(), ext_trace);
1215  // DIAG_Assert(FileUtil::isReadable(traceFileName));
1216  }
1217  }
1218 
1219  // -------------------------
1220  //
1221  // -------------------------
1222 
1223  // N.B.: We currently assume FmtEpoch_NV_virtualMetrics is set iff
1224  // we read from a memory buffer. Possibly we need an explicit tag for this.
1225 
1226  bool isVirtualMetrics = false;
1227  val = hpcfmt_nvpairList_search(&(ehdr.nvps), FmtEpoch_NV_virtualMetrics);
1228  if (val && strcmp(val, "0") != 0) {
1229  isVirtualMetrics = true;
1230  rFlags |= RFlg_NoMetricValues;
1231  }
1232 
1233 
1234  // ----------------------------------------
1235  // make CallPath::Profile
1236  // ----------------------------------------
1237 
1238  prof = new Profile(progNm);
1239 
1240  prof->m_fmtVersion = hdr.version;
1241  prof->m_flags = ehdr.flags;
1243 
1244  prof->m_profileFileName = profFileName;
1245 
1246  if (haveTrace) {
1247  prof->m_traceFileName = traceFileName;
1248  if (!traceFileName.empty()) {
1249  prof->m_traceFileNameSet.insert(traceFileName);
1250  }
1251  prof->m_traceMinTime = traceMinTime;
1252  prof->m_traceMaxTime = traceMaxTime;
1253  }
1254 
1255 
1256  // ----------------------------------------
1257  // make metric table
1258  // ----------------------------------------
1259 
1260  string m_sfx;
1261  if (!mpiRankStr.empty() && !tidStr.empty()) {
1262  m_sfx = "[" + mpiRankStr + "," + tidStr + "]";
1263  }
1264  else if (!mpiRankStr.empty()) {
1265  m_sfx = "[" + mpiRankStr + "]";
1266  }
1267  else if (!tidStr.empty()) {
1268  m_sfx = "[" + tidStr + "]";
1269  }
1270 
1271  if (rFlags & RFlg_NoMetricSfx) {
1272  m_sfx = "";
1273  //if (!tidStr.empty()) { m_sfx = "[" + tidStr + "]"; } // TODO:threads
1274  }
1275 
1276  metric_desc_t* m_lst = metricTbl.lst;
1277  for (uint i = 0; i < numMetricsSrc; i++) {
1278  const metric_desc_t& mdesc = m_lst[i];
1279  const metric_aux_info_t &current_aux_info = aux_info[i];
1280 
1281  // ----------------------------------------
1282  //
1283  // ----------------------------------------
1284  string nm = mdesc.name;
1285  string desc = mdesc.description;
1286  string profRelId = StrUtil::toStr(i);
1287 
1288  bool doMakeInclExcl = (rFlags & RFlg_MakeInclExcl);
1289 
1290  // Certain metrics do not have both incl/excl values
1291  if (nm == HPCRUN_METRIC_RetCnt) {
1292  doMakeInclExcl = false;
1293  }
1294 
1295  DIAG_Assert(mdesc.flags.fields.ty == MetricFlags_Ty_Raw
1296  || mdesc.flags.fields.ty == MetricFlags_Ty_Final,
1297  "Prof::CallPath::Profile::fmt_epoch_fread: unexpected metric type '"
1298  << mdesc.flags.fields.ty << "'");
1299 
1300  DIAG_Assert(Logic::implies(mdesc.flags.fields.ty == MetricFlags_Ty_Final,
1301  !(rFlags & RFlg_MakeInclExcl)),
1303 
1304  // ----------------------------------------
1305  // 1. Make 'regular'/'inclusive' metric descriptor
1306  // ----------------------------------------
1307  Metric::SampledDesc* m =
1308  new Metric::SampledDesc(nm, desc, mdesc.period, true/*isUnitsEvents*/,
1309  profFileName, profRelId, "HPCRUN");
1310 
1311  // keep the show status consistent between hpcrun and experiment.xml
1312  m->isVisible(mdesc.flags.fields.show == 1);
1313  m->doDispPercent(mdesc.flags.fields.showPercent == 1);
1314 
1315  if (doMakeInclExcl) {
1316  m->type(Metric::ADesc::TyIncl);
1317  }
1318  else {
1319  if (nm == HPCRUN_METRIC_RetCnt) {
1320  m->type(Metric::ADesc::TyExcl);
1321  }
1322  else {
1323  m->type(Metric::ADesc::fromHPCRunMetricValTy(mdesc.flags.fields.valTy));
1324  }
1325  }
1326  if (!m_sfx.empty()) {
1327  m->nameSfx(m_sfx);
1328  }
1329  m->flags(mdesc.flags);
1330 
1331  // ----------------------------------------
1332  // 1b. Update the additional perf event attributes
1333  // ----------------------------------------
1334 
1335  Prof::Metric::SamplingType_t sampling_type = mdesc.is_frequency_metric ?
1337 
1338  m->sampling_type(sampling_type);
1339  m->isMultiplexed(current_aux_info.is_multiplexed);
1340  m->periodMean (current_aux_info.threshold_mean);
1341  m->num_samples (current_aux_info.num_samples);
1342 
1343  // ----------------------------------------
1344  // 1c. add to the list of metric
1345  // ----------------------------------------
1346 
1347  prof->metricMgr()->insert(m);
1348 
1349  // ----------------------------------------
1350  // 2. Make associated 'exclusive' descriptor, if applicable
1351  // ----------------------------------------
1352  if (doMakeInclExcl) {
1353  Metric::SampledDesc* mSmpl =
1354  new Metric::SampledDesc(nm, desc, mdesc.period,
1355  true/*isUnitsEvents*/,
1356  profFileName, profRelId, "HPCRUN");
1357  mSmpl->type(Metric::ADesc::TyExcl);
1358  if (!m_sfx.empty()) {
1359  mSmpl->nameSfx(m_sfx);
1360  }
1361  mSmpl->flags(mdesc.flags);
1362  mSmpl->isVisible(mdesc.flags.fields.show);
1363  mSmpl->doDispPercent(mdesc.flags.fields.showPercent);
1364 
1365  prof->metricMgr()->insert(mSmpl);
1366  }
1367  }
1368 
1369  if (isVirtualMetrics || (rFlags & RFlg_VirtualMetrics) ) {
1370  prof->isMetricMgrVirtual(true);
1371  }
1372 
1373 
1374  // ----------------------------------------
1375  // make metric DB info
1376  // ----------------------------------------
1377 
1378  // metric DB information:
1379  // 1. create when reading an actual data file
1380  // 2. preserve when reading a profile from a memory buffer
1381  if ( !isVirtualMetrics ) {
1382  // create metric db information
1383  Prof::Metric::Mgr* mMgr = prof->metricMgr();
1384  for (uint mId = 0; mId < mMgr->size(); ++mId) {
1385  Prof::Metric::ADesc* m = mMgr->metric(mId);
1386  m->dbId(mId);
1387  m->dbNumMetrics(mMgr->size());
1388  }
1389  }
1390 
1391  // ----------------------------------------
1392  // make loadmap
1393  // ----------------------------------------
1394 
1395  uint num_lm = loadmap_tbl.len;
1396 
1397  LoadMap loadmap(num_lm);
1398 
1399  for (uint i = 0; i < num_lm; ++i) {
1400  string nm = loadmap_tbl.lst[i].name;
1402 
1403  LoadMap::LM* lm = new LoadMap::LM(nm);
1404  loadmap.lm_insert(lm);
1405 
1406  DIAG_Assert(lm->id() == i + 1, "Profile::fmt_epoch_fread: Currently expect load module id's to be in dense ascending order.");
1407  }
1408 
1409  DIAG_MsgIf(DBG, loadmap.toString());
1410 
1411  std::vector<LoadMap::MergeEffect>* mrgEffect =
1412  prof->loadmap()->merge(loadmap);
1413  DIAG_Assert(mrgEffect->empty(), "Profile::fmt_epoch_fread: " << DIAG_UnexpectedInput);
1414 
1415  hpcrun_fmt_loadmap_free(&loadmap_tbl, free);
1416  delete mrgEffect;
1417 
1418 
1419  // ------------------------------------------------------------
1420  // cct
1421  // ------------------------------------------------------------
1422  fmt_cct_fread(*prof, infs, rFlags, metricTbl, ctxtStr, outfs);
1423 
1424 
1426  hpcrun_fmt_metricTbl_free(&metricTbl, free);
1427 
1428  return HPCFMT_OK;
1429 }
1430 
1431 
1432 int
1433 Profile::fmt_cct_fread(Profile& prof, FILE* infs, uint rFlags,
1434  const metric_tbl_t& metricTbl,
1435  std::string ctxtStr, FILE* outfs)
1436 {
1437  DIAG_Assert(infs, "Bad file descriptor!");
1438 
1439  CCTIdToCCTNodeMap cctNodeMap;
1440 
1441  int ret = HPCFMT_ERR;
1442 
1443  // ------------------------------------------------------------
1444  // Read number of cct nodes
1445  // ------------------------------------------------------------
1446  uint64_t numNodes = 0;
1447  hpcfmt_int8_fread(&numNodes, infs);
1448 
1449  // ------------------------------------------------------------
1450  // Read each CCT node
1451  // ------------------------------------------------------------
1452 
1453  if (outfs) {
1454  fprintf(outfs, "[cct: (num-nodes: %" PRIu64 ")\n", numNodes);
1455  }
1456 
1457  CCT::Tree* cct = prof.cct();
1458 
1459  if (numNodes > 0) {
1460  delete cct->root();
1461  cct->root(NULL);
1462  }
1463 
1464  // N.B.: numMetricsSrc <= [numMetricsDst = prof.metricMgr()->size()]
1465  uint numMetricsSrc = metricTbl.len;
1466 
1467  if (rFlags & RFlg_NoMetricValues) {
1468  numMetricsSrc = 0;
1469  }
1470 
1471  hpcrun_fmt_cct_node_t nodeFmt;
1472  nodeFmt.num_metrics = numMetricsSrc;
1473  nodeFmt.metrics = (numMetricsSrc > 0) ?
1474  (hpcrun_metricVal_t*)alloca(numMetricsSrc * sizeof(hpcrun_metricVal_t))
1475  : NULL;
1476 
1477  ExprEval eval;
1478  DIAG_DevMsgIf(DBG_DATA, ". read nodes: " << numNodes );
1479 
1480  for (uint i = 0; i < numNodes; ++i) {
1481  // ----------------------------------------------------------
1482  // Read the node
1483  // ----------------------------------------------------------
1484  ret = hpcrun_fmt_cct_node_fread(&nodeFmt, prof.m_flags, infs);
1485  if (ret != HPCFMT_OK) {
1486  DIAG_Throw("Error reading CCT node " << nodeFmt.id);
1487  }
1488  if (outfs) {
1489  hpcrun_fmt_cct_node_fprint(&nodeFmt, outfs, prof.m_flags,
1490  &metricTbl, " ");
1491  }
1492  // ------------------------------------------
1493  // check if the metric contains a formula
1494  // if this is the case, we'll compute the metric based on the formula
1495  // given by hpcrun.
1496  // FIXME: we don't check the validity of the formula (yet).
1497  // If hpcrun has incorrect formula, the result can be anything
1498  // ------------------------------------------
1499  metric_desc_t* m_lst = metricTbl.lst;
1500  VarMap var_map(nodeFmt.metrics, m_lst, numMetricsSrc);
1501 
1502  for (uint i = 0; i < numMetricsSrc; i++) {
1503  char *expr = (char*) m_lst[i].formula;
1504  if (expr == NULL || strlen(expr)==0) continue;
1505 
1506  double res = eval.Eval(expr, &var_map);
1507  if (eval.GetErr() == EEE_NO_ERROR) {
1508  // the formula syntax looks "correct". Update the the metric value
1509  hpcrun_fmt_metric_set_value(m_lst[i], &nodeFmt.metrics[i], res);
1510  }
1511  }
1512 
1513  int nodeId = (int)nodeFmt.id;
1514  int parentId = (int)nodeFmt.id_parent;
1515 
1516  // Find parent of node
1517  CCT::ANode* node_parent = NULL;
1518  if (parentId != HPCRUN_FMT_CCTNodeId_NULL) {
1519  CCTIdToCCTNodeMap::iterator it = cctNodeMap.find(parentId);
1520  if (it != cctNodeMap.end()) {
1521  node_parent = it->second;
1522  }
1523  else {
1524  DIAG_Throw("Cannot find parent for CCT node " << nodeId);
1525  }
1526  }
1527 
1528  // Disable the preorder id requirement for CCT nodes. It is hard
1529  // for Profile::fmt_cct_fwrite to guarantee preorder ids when it
1530  // is also forced to preserve some trace ids. This also makes it
1531  // easier for hpcrun to handle thread thread creation contexts.
1532 #if 0
1533  if (! (abs(parentId) < abs(nodeId))) {
1534  DIAG_Throw("CCT node " << nodeId << " has invalid parent (" << parentId << ")");
1535  }
1536 #endif
1537 
1538  // ----------------------------------------------------------
1539  // Create node and link to parent
1540  // ----------------------------------------------------------
1541 
1542  std::pair<CCT::ADynNode*, CCT::ADynNode*> n2 =
1543  cct_makeNode(prof, nodeFmt, rFlags, ctxtStr);
1544  CCT::ADynNode* node = n2.first;
1545  CCT::ADynNode* node_sib = n2.second;
1546 
1547  DIAG_DevMsgIf(0, "fmt_cct_fread: " << hex << node << " -> " << node_parent << dec);
1548 
1549  if (node_parent) {
1550  // If 'node' is not the secondary root, perform sanity check
1551  if (!node->isSecondarySynthRoot()) {
1552  if (node->lmId_real() == LoadMap::LMId_NULL) {
1553  DIAG_WMsg(2, ctxtStr << ": CCT (non-root) node " << nodeId << " has invalid normalized IP: " << node->nameDyn());
1554  }
1555  }
1556 
1557  node->link(node_parent);
1558  if (node_sib) {
1559  node_sib->link(node_parent);
1560  }
1561  }
1562  else {
1563  DIAG_AssertWarn(cct->empty(), ctxtStr << ": CCT must only have one root!");
1564  DIAG_AssertWarn(!node_sib, ctxtStr << ": CCT root cannot be split into interior and leaf!");
1565  cct->root(node);
1566  }
1567 
1568  cctNodeMap.insert(std::make_pair(nodeFmt.id, node));
1569 #if DBG_DATA
1570  if (node->hpcrun_node_type() > 20) {
1571  std::cerr << "Error id= " << node->id() << ": hpcrun node type invalid: " << node->hpcrun_node_type() << "\n" ;
1572  }
1573 #endif
1574  }
1575 
1576  if (outfs) {
1577  fprintf(outfs, "]\n");
1578  }
1579 
1580  return HPCFMT_OK;
1581 }
1582 
1583 
1584 //***************************************************************************
1585 
1586 int
1587 Profile::fmt_fwrite(const Profile& prof, FILE* fs, uint wFlags)
1588 {
1589  int ret;
1590 
1591  // ------------------------------------------------------------
1592  // header
1593  // ------------------------------------------------------------
1594 
1595  string traceMinTimeStr = StrUtil::toStr(prof.m_traceMinTime);
1596  string traceMaxTimeStr = StrUtil::toStr(prof.m_traceMaxTime);
1597 
1598  ret = hpcrun_fmt_hdr_fwrite(fs,
1599  "TODO:hdr-name","TODO:hdr-value",
1600  HPCRUN_FMT_NV_traceMinTime, traceMinTimeStr.c_str(),
1601  HPCRUN_FMT_NV_traceMaxTime, traceMaxTimeStr.c_str(),
1602  NULL);
1603  if (ret == HPCFMT_ERR) return HPCFMT_ERR;
1604 
1605  // ------------------------------------------------------------
1606  // epoch
1607  // ------------------------------------------------------------
1608  ret = fmt_epoch_fwrite(prof, fs, wFlags);
1609  if (ret == HPCFMT_ERR) return HPCFMT_ERR;
1610 
1611  return HPCFMT_OK;
1612 }
1613 
1614 
1615 int
1616 Profile::fmt_epoch_fwrite(const Profile& prof, FILE* fs, uint wFlags)
1617 {
1618  int ret;
1619 
1620  // ------------------------------------------------------------
1621  // epoch-hdr
1622  // ------------------------------------------------------------
1623  const char* virtualMetrics = "0";
1624  if (prof.isMetricMgrVirtual() || (wFlags & WFlg_VirtualMetrics) ) {
1625  virtualMetrics = "1";
1626  }
1627 
1628  ret = hpcrun_fmt_epochHdr_fwrite(fs, prof.m_flags,
1630  "TODO:epoch-name", "TODO:epoch-value",
1631  FmtEpoch_NV_virtualMetrics, virtualMetrics,
1632  NULL);
1633  if (ret == HPCFMT_ERR) return HPCFMT_ERR;
1634 
1635  // ------------------------------------------------------------
1636  // metric-tbl
1637  // ------------------------------------------------------------
1638 
1639  uint numMetrics = prof.metricMgr()->size();
1640 
1641  ret = hpcfmt_int4_fwrite(numMetrics, fs);
1642  if (ret == HPCFMT_ERR) return HPCFMT_ERR;
1643 
1644  for (uint i = 0; i < numMetrics; i++) {
1645  const Metric::ADesc* m = prof.metricMgr()->metric(i);
1646 
1647  string nmFmt = m->nameToFmt();
1648  const string& desc = m->description();
1649 
1652 
1653  mdesc.name = const_cast<char*>(nmFmt.c_str());
1654  mdesc.description = const_cast<char*>(desc.c_str());
1656  mdesc.flags.fields.valTy = Metric::ADesc::toHPCRunMetricValTy(m->type());
1658  mdesc.period = 1;
1659  mdesc.formula = NULL;
1660  mdesc.format = NULL;
1661  mdesc.is_frequency_metric = false;
1662 
1663  metric_aux_info_t aux_info;
1664  aux_info.is_multiplexed = m->isMultiplexed();
1665  aux_info.num_samples = m->num_samples();
1666  aux_info.threshold_mean = m->periodMean();
1667 
1668  ret = hpcrun_fmt_metricDesc_fwrite(&mdesc, &aux_info, fs);
1669  if (ret == HPCFMT_ERR) return HPCFMT_ERR;
1670  }
1671 
1672 
1673  // ------------------------------------------------------------
1674  // loadmap
1675  // ------------------------------------------------------------
1676 
1677  const LoadMap& loadmap = *(prof.loadmap());
1678 
1679  ret = hpcfmt_int4_fwrite(loadmap.size(), fs);
1680  if (ret == HPCFMT_ERR) return HPCFMT_ERR;
1681 
1682  for (LoadMap::LMId_t i = 1; i <= loadmap.size(); i++) {
1683  const LoadMap::LM* lm = loadmap.lm(i);
1684 
1685  loadmap_entry_t lm_entry;
1686  lm_entry.id = (uint16_t) lm->id();
1687  lm_entry.name = const_cast<char*>(lm->name().c_str());
1688  lm_entry.flags = 0; // TODO:flags
1689 
1690  ret = hpcrun_fmt_loadmapEntry_fwrite(&lm_entry, fs);
1691  if (ret == HPCFMT_ERR) return HPCFMT_ERR;
1692  }
1693 
1694  // ------------------------------------------------------------
1695  // cct
1696  // ------------------------------------------------------------
1697  ret = fmt_cct_fwrite(prof, fs, wFlags);
1698  if (ret == HPCFMT_ERR) return HPCFMT_ERR;
1699 
1700  return HPCFMT_OK;
1701 }
1702 
1703 
1704 int
1705 Profile::fmt_cct_fwrite(const Profile& prof, FILE* fs, uint wFlags)
1706 {
1707  int ret;
1708 
1709  // ------------------------------------------------------------
1710  // Ensure CCT node ids follow conventions
1711  // ------------------------------------------------------------
1712 
1713  // N.B.: This may not generate preorder ids because it is necessary
1714  // to retain certain trace ids.
1715  uint64_t numNodes = 0;
1716  uint nodeId_next = 2; // cf. s_nextUniqueId
1717  for (CCT::ANodeIterator it(prof.cct()->root()); it.Current(); ++it) {
1718  CCT::ANode* n = it.current();
1719  Prof::CCT::ADynNode* n_dyn = dynamic_cast<Prof::CCT::ADynNode*>(n);
1720 
1721  if (n_dyn && hpcrun_fmt_doRetainId(n_dyn->cpId())) {
1722  n->id(n_dyn->cpId());
1723  }
1724  else {
1725  n->id(nodeId_next);
1726  nodeId_next += 2;
1727  }
1728  numNodes++;
1729  }
1730 
1731  // ------------------------------------------------------------
1732  // Write number of cct nodes
1733  // ------------------------------------------------------------
1734 
1735  ret = hpcfmt_int8_fwrite(numNodes, fs);
1736  if (ret != HPCFMT_OK) return HPCFMT_ERR;
1737 
1738  DIAG_DevMsgIf(DBG_DATA, ". write nodes: " << numNodes );
1739 
1740  // ------------------------------------------------------------
1741  // Write each CCT node
1742  // ------------------------------------------------------------
1743 
1744  uint numMetrics = prof.metricMgr()->size();
1745  if (prof.isMetricMgrVirtual() || (wFlags & WFlg_VirtualMetrics) ) {
1746  numMetrics = 0;
1747  }
1748 
1749  hpcrun_fmt_cct_node_t nodeFmt;
1750  nodeFmt.num_metrics = numMetrics;
1751  nodeFmt.metrics =
1752  (hpcrun_metricVal_t*) alloca(numMetrics * sizeof(hpcrun_metricVal_t));
1753 
1754  for (CCT::ANodeIterator it(prof.cct()->root()); it.Current(); ++it) {
1755  CCT::ANode* n = it.current();
1756  fmt_cct_makeNode(nodeFmt, *n, prof.m_flags);
1757 
1758  ret = hpcrun_fmt_cct_node_fwrite(&nodeFmt, prof.m_flags, fs);
1759  if (ret != HPCFMT_OK) return HPCFMT_ERR;
1760  }
1761 
1762  //debug
1763  DIAG_DevMsgIf(DBG_DATA, "CallPath-Profile num nodes: " << numNodes << std::endl);
1764 
1765  return HPCFMT_OK;
1766 }
1767 
1768 
1769 //***************************************************************************
1770 
1771 // 1. Create a CCT::Root node for the CCT
1772 // 2. Normalize a CCT of the form [cf. CallPath::Profile::fmt_fwrite()]:
1773 //
1774 // PrimaryRoot --> monitor_main --> main --> ...
1775 // |
1776 // \--> [SecondaryRoot] --> ...
1777 //
1778 // into the following:
1779 //
1780 // CCT::Root --> main --> ...
1781 // |
1782 // \--> [CCT::Root] --> ...
1783 void
1784 Profile::canonicalize(uint rFlags)
1785 {
1786  using namespace Prof;
1787 
1788  CCT::ANode* root = m_cct->root();
1789  CCT::ADynNode* root_dyn = dynamic_cast<CCT::ADynNode*>(root);
1790 
1791  // ------------------------------------------------------------
1792  // idempotent
1793  // ------------------------------------------------------------
1794  if (root && typeid(*root) == typeid(CCT::Root)) {
1795  return;
1796  }
1797 
1798  // ------------------------------------------------------------
1799  // 1. Find secondary root (if it exists) and unlink it from CCT
1800  // ------------------------------------------------------------
1801 
1802  // INVARIANT: 'secondaryRoot' is one of the children of 'root'
1803  CCT::ADynNode* secondaryRoot = NULL;
1804 
1805  if (root_dyn && root_dyn->isPrimarySynthRoot()) {
1806  for (CCT::ANodeChildIterator it(root); it.Current(); ++it) {
1807  CCT::ANode* n = it.current();
1808  CCT::ADynNode* n_dyn = dynamic_cast<CCT::ADynNode*>(n);
1809  if (n_dyn && n_dyn->isSecondarySynthRoot()) {
1810  secondaryRoot = n_dyn;
1811  secondaryRoot->unlink();
1812  break;
1813  }
1814  }
1815  }
1816 
1817  // ------------------------------------------------------------
1818  // 2. Create new secondary root
1819  // ------------------------------------------------------------
1820 
1821  // CCT::ANode* secondaryRootNew = new CCT::Root(m_name);
1822  // copy all children of secondaryRoot to secondaryRootNew
1823 
1824  // ------------------------------------------------------------
1825  // 3. Find potential splice point
1826  // ------------------------------------------------------------
1827 
1828  // INVARIANT: 'splicePoint' is the innermost (closest to leaves)
1829  // node to be deleted.
1830  CCT::ANode* splicePoint = NULL;
1831 
1832  if (root_dyn && root_dyn->isPrimarySynthRoot()) {
1833  splicePoint = root;
1834 #if 0
1835  if (rFlags & RFlg_HpcrunData) {
1836  // hpcrun generates CCTs in the form diagrammed above
1837  if (splicePoint->childCount() == 1) {
1838  splicePoint = splicePoint->firstChild();
1839  }
1840  }
1841 #endif
1842  }
1843 
1844  // ------------------------------------------------------------
1845  // 4. Create new primary root
1846  // ------------------------------------------------------------
1847 
1848  CCT::ANode* rootNew = new CCT::Root(m_name);
1849 
1850  if (splicePoint) {
1851  for (CCT::ANodeChildIterator it(splicePoint); it.Current(); /* */) {
1852  CCT::ANode* n = it.current();
1853  it++; // advance iterator -- it is pointing at 'n'
1854  n->unlink();
1855  n->link(rootNew);
1856  }
1857 
1858  delete root; // N.B.: also deletes 'splicePoint'
1859  }
1860  else if (root) {
1861  root->link(rootNew);
1862  }
1863 
1864  m_cct->root(rootNew);
1865 
1866  // ------------------------------------------------------------
1867  // 5. Relink secondary root
1868  // ------------------------------------------------------------
1869 
1870  if (secondaryRoot) {
1871  secondaryRoot->link(rootNew);
1872  }
1873 }
1874 
1875 
1876 } // namespace CallPath
1877 
1878 } // namespace Prof
1879 
1880 
1881 //***************************************************************************
1882 
1883 static std::pair<Prof::CCT::ADynNode*, Prof::CCT::ADynNode*>
1885  const hpcrun_fmt_cct_node_t& nodeFmt, uint rFlags,
1886  const std::string& ctxtStr)
1887 {
1888  using namespace Prof;
1889 
1890  const LoadMap& loadmap = *(prof.loadmap());
1891 
1892  // ----------------------------------------------------------
1893  // Gather node parameters
1894  // ----------------------------------------------------------
1895  bool isLeaf = false;
1896 
1897  // ----------------------------------------
1898  // cpId
1899  // ----------------------------------------
1900  int nodeId = (int)nodeFmt.id;
1901  if (nodeId < 0) {
1902  isLeaf = true;
1903  nodeId = -nodeId;
1904  }
1905  // INVARIANT: nodeId > HPCRUN_FMT_CCTNodeId_NULL
1906 
1908  if (hpcrun_fmt_doRetainId(nodeFmt.id)) {
1909  cpId = nodeId;
1910  }
1911 
1912  LoadMap::LMId_t lmId = nodeFmt.lm_id;
1913 
1914  VMA lmIP = (VMA)nodeFmt.lm_ip; // FIXME:tallent: Use ISA::convertVMAToOpVMA
1915  ushort opIdx = 0;
1916  lush_lip_t* lip = NULL;
1917 
1918  // ----------------------------------------
1919  // normalized ip (lmId and lmIP)
1920  // ----------------------------------------
1921 
1922  if (! (lmId <= loadmap.size() /*1-based*/) ) {
1923  DIAG_WMsg(1, ctxtStr << ": CCT node " << nodeId
1924  << " has invalid load module: " << lmId);
1925  lmId = LoadMap::LMId_NULL;
1926  }
1927  loadmap.lm(lmId)->isUsed(true); // ok if LoadMap::LMId_NULL
1928 
1929  DIAG_MsgIf(0, "cct_makeNode(: "<< hex << lmIP << dec << ", " << lmId << ")");
1930 
1931  // ----------------------------------------
1932  // normalized lip
1933  // ----------------------------------------
1934  if (!lush_lip_eq(&nodeFmt.lip, &lush_lip_NULL)) {
1935  lip = CCT::ADynNode::clone_lip(&nodeFmt.lip);
1936  }
1937 
1938  if (lip) {
1939  LoadMap::LMId_t lip_lmId = lush_lip_getLMId(lip);
1940 
1941  if (! (lip_lmId <= loadmap.size() /*1-based*/) ) {
1942  DIAG_WMsg(1, ctxtStr << ": CCT node " << nodeId
1943  << " has invalid (logical) load module: " << lip_lmId);
1944  lip_lmId = LoadMap::LMId_NULL;
1945  }
1946  loadmap.lm(lip_lmId)->isUsed(true); // ok if LoadMap::LMId_NULL
1947  }
1948 
1949  // ----------------------------------------
1950  // metrics
1951  // ----------------------------------------
1952 
1953  bool doZeroMetrics = prof.isMetricMgrVirtual()
1955 
1956  bool hasMetrics = false;
1957 
1958  // [numMetricsSrc = nodeFmt.num_metrics] <= numMetricsDst
1959  uint numMetricsDst = prof.metricMgr()->size();
1961  numMetricsDst = 0;
1962  }
1963 
1964  Metric::IData metricData(numMetricsDst);
1965  for (uint i_dst = 0, i_src = 0; i_dst < numMetricsDst; i_dst++) {
1966  Metric::ADesc* adesc = prof.metricMgr()->metric(i_dst);
1967  Metric::SampledDesc* mdesc = dynamic_cast<Metric::SampledDesc*>(adesc);
1968  DIAG_Assert(mdesc, "inconsistency: no corresponding SampledDesc!");
1969 
1970  hpcrun_metricVal_t m = nodeFmt.metrics[i_src];
1971 
1972  if (mdesc->flags().fields.valFmt == MetricFlags_ValFmt_Address) {
1973  // special treatment for address-type metric
1974  // we don't want to convert to double and multiply by period
1975  metricData.metricObject(i_dst) = m;
1976 
1977  } else {
1978 
1979  double mval = 0;
1980  switch (mdesc->flags().fields.valFmt) {
1982  mval = (double)m.i; break;
1984  mval = m.r; break;
1985 
1986  default:
1988  }
1989  metricData.metric(i_dst) = mval * (double)mdesc->period();
1990  }
1991  if (!hpcrun_metricVal_isZero(m)) {
1992  hasMetrics = true;
1993  }
1994 
1996  if (adesc->type() == Prof::Metric::ADesc::TyNULL ||
1997  adesc->type() == Prof::Metric::ADesc::TyExcl) {
1998  i_src++;
1999  }
2000  // Prof::Metric::ADesc::TyIncl: reuse i_src
2001  }
2002  else {
2003  i_src++;
2004  }
2005  }
2006 
2007  if (doZeroMetrics) {
2008  metricData.clearMetrics();
2009  }
2010 
2011  // ----------------------------------------------------------
2012  // Create nodes.
2013  //
2014  // Note that it is possible for an interior node to have
2015  // a non-zero metric count. If this is the case, the node should be
2016  // split into two sibling nodes: 1) an interior node with metrics
2017  // == 0 (that has cpId == NULL *and* that is the primary return node);
2018  // and 2) a leaf node with the metrics and the cpId.
2019  // ----------------------------------------------------------
2021  Prof::CCT::ADynNode* n_leaf = NULL;
2022 
2023  if (hasMetrics || isLeaf) {
2024  n = new CCT::Stmt(NULL, cpId, nodeFmt, lmId, lmIP, opIdx, lip,
2025  metricData);
2026  }
2027 
2028  if (!isLeaf) {
2029  if (hasMetrics) {
2030  n_leaf = n;
2031 
2032  const uint cpId0 = HPCRUN_FMT_CCTNodeId_NULL;
2033 
2034  uint mSz = (doZeroMetrics) ? 0 : numMetricsDst;
2035  Metric::IData metricData0(mSz);
2036 
2037  lush_lip_t* lipCopy = CCT::ADynNode::clone_lip(lip);
2038 
2039  n = new CCT::Call(NULL, cpId0, nodeFmt, lmId, lmIP, opIdx,
2040  lipCopy, metricData0);
2041  }
2042  else {
2043  n = new CCT::Call(NULL, cpId, nodeFmt, lmId, lmIP, opIdx,
2044  lip, metricData);
2045  }
2046  }
2047 
2048  return std::make_pair(n, n_leaf);
2049 }
2050 
2051 
2052 static void
2054  epoch_flags_t flags)
2055 {
2056  n_fmt.id = (n.isLeaf()) ? -(n.id()) : n.id();
2057 
2058  n_fmt.id_parent = (n.parent()) ? n.parent()->id() : HPCRUN_FMT_CCTNodeId_NULL;
2059 
2060  const Prof::CCT::ADynNode* n_dyn_p =
2061  dynamic_cast<const Prof::CCT::ADynNode*>(&n);
2062 
2063  n_fmt.node_type = n.hpcrun_node_type();
2064 #if DBG_DATA
2065  if (n_fmt.node_type > 20) {
2066  std::cerr << "Error: invalid-node-type: " << n_fmt.node_type <<", id: " << n_fmt.id << "\n";
2067  }
2068 #endif
2069 
2070  if (typeid(n) == typeid(Prof::CCT::Root)) {
2071  n_fmt.as_info = lush_assoc_info_NULL;
2073  n_fmt.lm_ip = 0;
2074  lush_lip_init(&(n_fmt.lip));
2075  memset(n_fmt.metrics, 0, n_fmt.num_metrics * sizeof(hpcrun_metricVal_t));
2076  }
2077  else if (n_dyn_p) {
2078  const Prof::CCT::ADynNode& n_dyn = *n_dyn_p;
2079 
2080  if (flags.fields.isLogicalUnwind) {
2081  n_fmt.as_info = n_dyn.assocInfo();
2082  }
2083 
2084  n_fmt.lm_id = (uint16_t) n_dyn.lmId();
2085  n_fmt.lm_ip = n_dyn.Prof::CCT::ADynNode::lmIP();
2086 
2087  if (flags.fields.isLogicalUnwind) {
2088  lush_lip_init(&(n_fmt.lip));
2089  if (n_dyn.lip()) {
2090  memcpy(&n_fmt.lip, n_dyn.lip(), sizeof(lush_lip_t));
2091  }
2092  }
2093 
2094  // Note: use n_fmt.num_metrics rather than n_dyn.numMetrics() to
2095  // support skipping the writing of metrics.
2096  for (uint i = 0; i < n_fmt.num_metrics; ++i) {
2097  hpcrun_metricVal_t m; // C99: (hpcrun_metricVal_t){.r = n_dyn.metric(i)};
2098  m.r = n_dyn.metric(i);
2099  n_fmt.metrics[i] = m;
2100  }
2101  }
2102  else {
2103  DIAG_Die("fmt_cct_makeNode: unknown CCT node type");
2104  }
2105 }
2106 
void hpcrun_fmt_epochHdr_free(hpcrun_fmt_epochHdr_t *ehdr, hpcfmt_free_fn dealloc)
Definition: hpcrun-fmt.c:242
virtual void fileId(uint _id)=0
int hpcrun_fmt_hdr_fprint(hpcrun_fmt_hdr_t *hdr, FILE *fs)
Definition: hpcrun-fmt.c:144
bool is_frequency_metric
Definition: hpcrun-fmt.h:381
#define HPCRUN_FMT_NV_tid
Definition: hpcrun-fmt.h:158
static const char * getFileName(Struct::ANode *strct)
static void writeXML_help(std::ostream &os, const char *entry_nm, Struct::Tree *structure, const Struct::ANodeFilter *filter, int type, bool remove_redundancy)
#define MAX_PREFIX_CHARS
ADesc * partner() const
ANode * parent() const
Definition: CCT-Tree.hpp:434
bool hasDBInfo() const
static void lush_lip_setLMId(lush_lip_t *x, uint16_t lmId)
Definition: lush-support.h:374
bool insert(Metric::ADesc *m)
Definition: Metric-Mgr.cpp:460
int hpctrace_fmt_datum_fwrite(hpctrace_fmt_datum_t *x, hpctrace_hdr_flags_t flags, FILE *outfs)
Definition: hpcrun-fmt.c:965
const metric_desc_t metricDesc_NULL
Definition: hpcrun-fmt.c:254
void MONITOR_EXT_WRAP_NAME() free(void *ptr)
static const std::string UnknownFileNm
const std::string & nameSfx() const
virtual const char * unified_name()=0
bfd_vma VMA
Definition: ISATypes.hpp:79
void prof_abort(int error_code)
Definition: main.cpp:98
bool isVisible() const
hpcfmt_vma_t lm_ip
Definition: hpcrun-fmt.h:554
uint64_t toUInt64(const char *str, unsigned *endidx)
Definition: StrUtil.cpp:189
#define DIAG_EMsg(...)
Definition: diagnostics.h:251
string toStr(const int x, int base)
Definition: StrUtil.cpp:243
lush_lip_t * lip() const
Definition: CCT-Tree.hpp:879
static bool hpcrun_fmt_doRetainId(uint32_t id)
Definition: hpcrun-fmt.h:502
MetricFlags_Ty_t ty
Definition: hpcrun-fmt.h:261
MetricFlags_ValTy_t valTy
Definition: hpcrun-fmt.h:262
void isMultiplexed(bool isMultiplexedEvent)
virtual const std::string & what() const
Definition: Exception.hpp:126
MetricFlags_ValFmt_t valFmt
Definition: hpcrun-fmt.h:263
static const char * ADescTyToXMLString(ADescTy type)
hpcrun_metricVal_t & metricObject(size_t mId)
double Eval(EVAL_CHAR *expr, BaseVarMap *var_map)
Definition: ExprEval.cpp:134
std::list< MergeEffect > MergeEffectList
Definition: CCT-Merge.hpp:126
LM * lm(LMId_t id) const
Definition: LoadMap.hpp:230
ANode * root() const
Definition: CCT-Tree.hpp:160
bool empty() const
Definition: CCT-Tree.hpp:168
int hpcrun_fmt_metricTbl_fprint(metric_tbl_t *metric_tbl, metric_aux_info_t *aux_info, FILE *fs)
Definition: hpcrun-fmt.c:334
int hpcrun_fmt_cct_node_fprint(hpcrun_fmt_cct_node_t *x, FILE *fs, epoch_flags_t flags, const metric_tbl_t *metricTbl, const char *pre)
Definition: hpcrun-fmt.c:688
static uint16_t lush_lip_getLMId(const lush_lip_t *x)
Definition: lush-support.h:367
#define DBG
lush_assoc_info_t lush_assoc_info_NULL
Definition: lush-support.c:83
LoadMap::LMId_t lmId_real() const
Definition: CCT-Tree.hpp:830
double metric(size_t mId) const
std::string nameDyn() const
Definition: CCT-Tree.cpp:1181
cct_node_t * node
Definition: cct.c:128
const hpcrun_metricFlags_t hpcrun_metricFlags_NULL
Definition: hpcrun-fmt.c:265
std::string name() const
char versionStr[sizeof(HPCRUN_FMT_Version)]
Definition: hpcrun-fmt.h:128
epoch_flags_t flags
Definition: hpcrun-fmt.h:188
static const char HPCRUN_TraceFnmSfx[]
Definition: hpcrun-fmt.h:96
static RealPathMgr & singleton()
static bool writeXML_FileFilter(const Struct::ANode &x, long GCC_ATTR_UNUSED type)
static __thread u32 tid
virtual uint numAccum() const =0
virtual std::string combineString1() const =0
bool doDispPercent() const
bool isPrimarySynthRoot() const
Definition: CCT-Tree.hpp:906
virtual const std::string & name() const
static int hpcfmt_int4_fwrite(uint32_t val, FILE *outfs)
Definition: hpcfmt.h:217
static const std::string UnknownProcNm
const char * hpcfmt_nvpairList_search(const HPCFMT_List(hpcfmt_nvpair_t) *nvps, const char *name)
Definition: hpcfmt.c:263
static const char HPCRUN_ProfileFnmSfx[]
Definition: hpcrun-fmt.h:93
LMId_t id() const
Definition: LoadMap.hpp:123
std::string nameToFmt() const
ANode * firstChild() const
Definition: CCT-Tree.hpp:438
const std::string & linkName() const
Root * root() const
int hpcrun_fmt_cct_node_fread(hpcrun_fmt_cct_node_t *x, epoch_flags_t flags, FILE *fs)
Definition: hpcrun-fmt.c:631
std::string MakeAttrStr(const char *x, int flags=ESC_TRUE)
Definition: xml.hpp:216
int hpcrun_fmt_loadmap_fread(loadmap_t *loadmap, FILE *fs, hpcfmt_alloc_fn alloc)
Definition: hpcrun-fmt.c:531
#define DIAG_MsgIf(ifexpr,...)
Definition: diagnostics.h:236
std::string toString() const
Definition: LoadMap.cpp:163
int hpcrun_fmt_hdr_fwrite(FILE *fs,...)
Definition: hpcrun-fmt.c:126
uint size() const
Definition: Metric-Mgr.hpp:153
void sampling_type(SamplingType_t type)
const std::string & name() const
Definition: LoadMap.hpp:128
static std::pair< Prof::CCT::ADynNode *, Prof::CCT::ADynNode * > cct_makeNode(Prof::CallPath::Profile &prof, const hpcrun_fmt_cct_node_t &nodeFmt, uint rFlags, const std::string &ctxtStr)
hpcfmt_uint_t num_metrics
Definition: hpcrun-fmt.h:559
uint64_t num_samples
Definition: hpcfmt.h:349
Definition: xml.cpp:127
void hpcrun_fmt_metricTbl_free(metric_tbl_t *metric_tbl, hpcfmt_free_fn dealloc)
Definition: hpcrun-fmt.c:348
#define HPCRUN_FMT_NV_mpiRank
Definition: hpcrun-fmt.h:157
void hpcrun_fmt_loadmap_free(loadmap_t *loadmap, hpcfmt_free_fn dealloc)
Definition: hpcrun-fmt.c:575
void num_samples(const uint64_t samples)
char * description
Definition: hpcrun-fmt.h:370
int hpcrun_fmt_epochHdr_fprint(hpcrun_fmt_epochHdr_t *ehdr, FILE *fs)
Definition: hpcrun-fmt.c:227
const char * pretty_name() const
uint cpId() const
Definition: CCT-Tree.hpp:791
void lm_insert(LoadMap::LM *x)
Definition: LoadMap.cpp:107
unsigned short int ushort
Definition: uint.h:120
bool realpath(std::string &pathNm) const
std::string toString(const char *pfx="") const
Definition: Metric-Mgr.cpp:735
unsigned int uint
Definition: uint.h:124
MergeEffectList * merge(const Tree *y, uint x_newMetricBegIdx, uint mrgFlag=0, uint oFlag=0)
Definition: CCT-Tree.cpp:166
virtual std::string toValueTyStringXML() const
static std::map< std::string, uint, StringCompare > m_mapFiles
hpcrun_metricFlags_fields fields
Definition: hpcrun-fmt.h:276
uint16_t id
Definition: hpcrun-fmt.h:454
union lush_lip lush_lip_t
Definition: lush-support.h:305
char * format
Definition: hpcrun-fmt.h:379
int hpcrun_fmt_metricDesc_fwrite(metric_desc_t *x, metric_aux_info_t *aux_info, FILE *fs)
Definition: hpcrun-fmt.c:412
bool is_multiplexed
Definition: hpcfmt.h:346
Definition: hpcrun-fmt.h:452
lush_assoc_info_t as_info
Definition: hpcrun-fmt.h:545
double threshold_mean
Definition: hpcfmt.h:347
#define HPCRUN_METRIC_RetCnt
Definition: hpcrun-metric.h:82
static int hpcfmt_int8_fread(uint64_t *val, FILE *infs)
Definition: hpcfmt.h:172
void link(NonUniformDegreeTreeNode *parent)
static const LMId_t LMId_NULL
Definition: LoadMap.hpp:108
virtual const std::string & name() const
virtual std::string finalizeString() const =0
virtual const std::string & name() const
File * ancestorFile() const
LMId_t size() const
Definition: LoadMap.hpp:225
uint dbNumMetrics() const
uint merge(Profile &y, int mergeTy, uint mrgFlag=0)
static int hpcfmt_int8_fwrite(uint64_t val, FILE *outfs)
Definition: hpcfmt.h:227
const std::string dbFileGlob() const
const LoadMap * loadmap() const
std::map< int, Prof::CCT::ANode * > CCTIdToCCTNodeMap
static void lush_lip_init(lush_lip_t *x)
Definition: lush-support.h:319
SimpleSymbolsFactories simpleSymbolsFactories
virtual void id(uint _id)=0
epoch_flags_bitfield fields
Definition: hpcrun-fmt.h:181
uint64_t flags
Definition: hpcrun-fmt.h:456
static void fmt_cct_makeNode(hpcrun_fmt_cct_node_t &n_fmt, const Prof::CCT::ANode &n, epoch_flags_t flags)
uint64_t period
Definition: hpcrun-fmt.h:374
virtual ADesc * clone() const
#define HPCRUN_FMT_NV_traceMaxTime
Definition: hpcrun-fmt.h:163
SimpleSymbolsFactory * find(const char *pathname)
ADescTy type() const
LoadMap::LMId_t lmId() const
Definition: CCT-Tree.hpp:823
lush_assoc_info_t assocInfo() const
Definition: CCT-Tree.hpp:805
bool isSecondarySynthRoot() const
Definition: CCT-Tree.hpp:913
int hpcrun_fmt_loadmap_fprint(loadmap_t *loadmap, FILE *fs)
Definition: hpcrun-fmt.c:561
lush_lip_t lush_lip_NULL
Definition: lush-support.c:119
const Metric::Mgr * metricMgr() const
static const char HPCPROF_TmpFnmSfx[]
Definition: hpcrun-fmt.h:104
static bool lush_lip_eq(const lush_lip_t *x, const lush_lip_t *y)
Definition: lush-support.h:327
const char * DIAG_UnexpectedInput
uint64_t measurementGranularity
Definition: hpcrun-fmt.h:189
int hpcrun_fmt_hdr_fread(hpcrun_fmt_hdr_t *hdr, FILE *infs, hpcfmt_alloc_fn alloc)
Definition: hpcrun-fmt.c:93
static std::map< std::string, uint, StringCompare > m_mapProcs
std::map< uint, uint > m_mapProcIDs
char * formula
Definition: hpcrun-fmt.h:378
const char * normalize_name(const char *in, int &fake_procedure)
int hpcrun_fmt_cct_node_fwrite(hpcrun_fmt_cct_node_t *x, epoch_flags_t flags, FILE *fs)
Definition: hpcrun-fmt.c:660
#define HPCRUN_FMT_NV_envPath
Definition: hpcrun-fmt.h:155
void hpcrun_node_type(uint16_t type)
Definition: CCT-Tree.hpp:422
hpctrace_hdr_flags_t flags
Definition: hpcrun-fmt.h:668
uint64_t bits
Definition: hpcrun-fmt.h:182
void *MONITOR_EXT_WRAP_NAME() malloc(size_t bytes)
enum Prof::Metric::SamplingType_e SamplingType_t
void canonicalize(uint rFlags=0)
#define HPCRUN_FMT_NV_traceMinTime
Definition: hpcrun-fmt.h:162
int hpcrun_fmt_loadmapEntry_fwrite(loadmap_entry_t *x, FILE *fs)
Definition: hpcrun-fmt.c:600
bool isUsed() const
Definition: LoadMap.hpp:142
#define NULL
Definition: ElfHelper.cpp:85
#define DBG_DATA
FILE * hpcio_fopen_r(const char *fnm)
Definition: hpcio.c:134
std::string MakeAttrNum(int x)
Definition: xml.hpp:228
static const double HPCRUN_FMT_Version_20
Definition: hpcrun-fmt.h:123
std::vector< LoadMap::MergeEffect > * merge(const LoadMap &y)
Definition: LoadMap.cpp:130
int hpcrun_fmt_metricTbl_fread(metric_tbl_t *metric_tbl, metric_aux_info_t **aux_info, FILE *fs, double fmtVersion, hpcfmt_alloc_fn alloc)
Definition: hpcrun-fmt.c:283
static bool hpcrun_metricVal_isZero(hpcrun_metricVal_t x)
Definition: hpcrun-fmt.h:355
uint findGroup(const Mgr &y_mMgr) const
Definition: Metric-Mgr.cpp:586
Metric::ADesc * metric(uint i)
Definition: Metric-Mgr.hpp:131
const std::string & description() const
int hpcrun_fmt_epochHdr_fread(hpcrun_fmt_epochHdr_t *ehdr, FILE *fs, hpcfmt_alloc_fn alloc)
Definition: hpcrun-fmt.c:172
uint id() const
Definition: CCT-Tree.hpp:383
int hpctrace_fmt_hdr_fread(hpctrace_fmt_hdr_t *hdr, FILE *infs)
Definition: hpcrun-fmt.c:795
virtual NonUniformDegreeTreeNode * Current() const
LM * ancestorLM() const
int hpcio_fclose(FILE *fs)
Definition: hpcio.c:152
void hpcrun_fmt_hdr_free(hpcrun_fmt_hdr_t *hdr, hpcfmt_free_fn dealloc)
Definition: hpcrun-fmt.c:159
int hpctrace_fmt_datum_fread(hpctrace_fmt_datum_t *x, hpctrace_hdr_flags_t flags, FILE *fs)
Definition: hpcrun-fmt.c:901
hpcrun_metricFlags_t flags() const
EXPR_EVAL_ERR GetErr()
Definition: ExprEval.cpp:156
#define DIAG_Die(...)
Definition: diagnostics.h:267
#define GCC_ATTR_UNUSED
Definition: gcc-attr.h:80
static const int HPCTRACE_FMT_HeaderLen
Definition: hpcrun-fmt.h:654
bool implies(bool p, bool q)
Definition: Logic.hpp:114
void merge_fixCCT(const std::vector< LoadMap::MergeEffect > *mrgEffects)
int hpcrun_fmt_epochHdr_fwrite(FILE *fs, epoch_flags_t flags, uint64_t measurementGranularity,...)
Definition: hpcrun-fmt.c:201
<!-- ********************************************************************--> n<!-- HPCToolkit Experiment DTD --> n<!-- Version 2.1 --> n<!-- ********************************************************************--> n<!ELEMENT HPCToolkitExperiment(Header,(SecCallPathProfile|SecFlatProfile) *)> n<!ATTLIST HPCToolkitExperiment\n version CDATA #REQUIRED > n n<!-- ******************************************************************--> n n<!-- Info/NV:flexible name-value pairs:(n) ame;(t) ype;(v) alue --> n<!ELEMENT Info(NV *)> n<!ATTLIST Info\n n CDATA #IMPLIED > n<!ELEMENT NV EMPTY > n<!ATTLIST NV\n n CDATA #REQUIRED\n t CDATA #IMPLIED\n v CDATA #REQUIRED > n n<!-- ******************************************************************--> n<!-- Header --> n<!-- ******************************************************************--> n<!ELEMENT Header(Info *)> n<!ATTLIST Header\n n CDATA #REQUIRED > n n<!-- ******************************************************************--> n<!-- Section Header --> n<!-- ******************************************************************--> n<!ELEMENT SecHeader(MetricTable?, MetricDBTable?, TraceDBTable?, LoadModuleTable?, FileTable?, ProcedureTable?, Info *)> n n<!-- MetricTable:--> n<!ELEMENT MetricTable(Metric) * > n n<!-- Metric:(i) d;(n) ame --> n<!--(v) alue-type:transient type of values --> n<!--(t) ype:persistent type of metric --> n<!-- fmt:format;show;--> n<!ELEMENT Metric(MetricFormula *, Info?)> n<!ATTLIST Metric\n i CDATA #REQUIRED\n n CDATA #REQUIRED\n es CDATA #IMPLIED\n em CDATA #IMPLIED\n ep CDATA #IMPLIED\n v(raw|final|derived-incr|derived) \"raw\\ t (inclusive|exclusive|nil) \nil\\ partner CDATA #IMPLIED\ fmt CDATA #IMPLIED\ show (1|0) \1\\ show-percent (1|0) \1> n n<!-- MetricFormula represents derived metrics: (t)ype; (frm): formula --> n<!ELEMENT MetricFormula (Info?)> n<!ATTLIST MetricFormula\ t (combine|finalize) \finalize\\ i CDATA #IMPLIED\ frm CDATA #REQUIRED> n n<!-- Metric data, used in sections: (n)ame [from Metric]; (v)alue --> n<!ELEMENT M EMPTY> n<!ATTLIST M\ n CDATA #REQUIRED\ v CDATA #REQUIRED> n n<!-- MetricDBTable: --> n<!ELEMENT MetricDBTable (MetricDB)*> n n<!-- MetricDB: (i)d; (n)ame --> n<!-- (t)ype: persistent type of metric --> n<!-- db-glob: file glob describing files in metric db --> n<!-- db-id: id within metric db --> n<!-- db-num-metrics: number of metrics in db --> n<!-- db-header-sz: size (in bytes) of a db file header --> n<!ELEMENT MetricDB EMPTY> n<!ATTLIST MetricDB\ i CDATA #REQUIRED\ n CDATA #REQUIRED\ t (inclusive|exclusive|nil) \nil\\ partner CDATA #IMPLIED\ db-glob CDATA #IMPLIED\ db-id CDATA #IMPLIED\ db-num-metrics CDATA #IMPLIED\ db-header-sz CDATA #IMPLIED> n n<!-- TraceDBTable: --> n<!ELEMENT TraceDBTable (TraceDB)> n n<!-- TraceDB: (i)d --> n<!-- db-min-time: min beginning time stamp (global) --> n<!-- db-max-time: max ending time stamp (global) --> n<!ELEMENT TraceDB EMPTY> n<!ATTLIST TraceDB\ i CDATA #REQUIRED\ db-glob CDATA #IMPLIED\ db-min-time CDATA #IMPLIED\ db-max-time CDATA #IMPLIED\ db-header-sz CDATA #IMPLIED> n n<!-- LoadModuleTable assigns a short name to a load module --> n<!ELEMENT LoadModuleTable (LoadModule)*> n n<!ELEMENT LoadModule (Info?)> n<!ATTLIST LoadModule\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!-- FileTable assigns a short name to a file --> n<!ELEMENT FileTable (File)*> n n<!ELEMENT File (Info?)> n<!ATTLIST File\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!-- ProcedureTable assigns a short name to a procedure --> n<!ELEMENT ProcedureTable (Procedure)*> n n<!-- Info/NV: flexible name-value pairs: (n)ame; (t)ype; (v)alue --> n<!-- f: family of the procedure (fake, root, ...)--> n<!ELEMENT Procedure (Info?)> n<!ATTLIST Procedure\ i CDATA #REQUIRED\ n CDATA #REQUIRED\ f CDATA #IMPLIED> n n<!-- ****************************************************************** --> n<!-- Section: Call path profile --> n<!-- ****************************************************************** --> n<!ELEMENT SecCallPathProfile (SecHeader, SecCallPathProfileData)> n<!ATTLIST SecCallPathProfile\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!ELEMENT SecCallPathProfileData (PF|M)*> n<!-- Procedure frame --> n<!-- (i)d: unique identifier for cross referencing --> n<!-- (s)tatic scope id --> n<!-- (n)ame: a string or an id in ProcedureTable --> n<!-- (lm) load module: a string or an id in LoadModuleTable --> n<!-- (f)ile name: a string or an id in LoadModuleTable --> n<!-- (l)ine range: \beg-end\ (inclusive range) --> n<!-- (a)lien: whether frame is alien to enclosing P --> n<!-- (str)uct: hpcstruct node id --> n<!-- (t)ype: hpcrun node type: memory access, variable declaration, ... --> n<!-- (v)ma-range-set: \{[beg-end), [beg-end)...}\ --> n<!ELEMENT PF (PF|Pr|L|C|S|M)*> n<!ATTLIST PF\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ n CDATA #REQUIRED\ lm CDATA #IMPLIED\ f CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Procedure (static): GOAL: replace with 'P' --> n<!ELEMENT Pr (Pr|L|C|S|M)*> n<!ATTLIST Pr\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ n CDATA #REQUIRED\ lm CDATA #IMPLIED\ f CDATA #IMPLIED\ l CDATA #IMPLIED\ a (1|0) \0\\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Callsite (a special StatementRange) --> n<!ELEMENT C (PF|M)*> n<!ATTLIST C\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n n<!-- ****************************************************************** --> n<!-- Section: Flat profile --> n<!-- ****************************************************************** --> n<!ELEMENT SecFlatProfile (SecHeader, SecFlatProfileData)> n<!ATTLIST SecFlatProfile\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!ELEMENT SecFlatProfileData (LM|M)*> n<!-- Load module: (i)d; (n)ame; (v)ma-range-set --> n<!ELEMENT LM (F|P|M)*> n<!ATTLIST LM\ i CDATA #IMPLIED\ n CDATA #REQUIRED\ v CDATA #IMPLIED> n<!-- File --> n<!ELEMENT F (P|L|S|M)*> n<!ATTLIST F\ i CDATA #IMPLIED\ n CDATA #REQUIRED> n<!-- Procedure (Note 1) --> n<!ELEMENT P (P|A|L|S|C|M)*> n<!ATTLIST P\ i CDATA #IMPLIED\ n CDATA #REQUIRED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Alien (Note 1) --> n<!ELEMENT A (A|L|S|C|M)*> n<!ATTLIST A\ i CDATA #IMPLIED\ f CDATA #IMPLIED\ n CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Loop (Note 1,2) --> n<!ELEMENT L (A|Pr|L|S|C|M)*> n<!ATTLIST L\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ l CDATA #IMPLIED\ f CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Statement (Note 2) --> n<!-- (it): trace record identifier --> n<!ELEMENT S (S|M)*> n<!ATTLIST S\ i CDATA #IMPLIED\ it CDATA #IMPLIED\ s CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Note 1: Contained Cs may not contain PFs --> n<!-- Note 2: The 's' attribute is not used for flat profiles --> n
void merge_fixTrace(const CCT::MergeEffectList *mrgEffects)
char * name
Definition: hpcrun-fmt.h:455
const ANodeFilter ANodeTyFilter[ANode::TyNUMBER]
virtual std::string combineString2() const =0
void hpcrun_fmt_metric_set_value(metric_desc_t metric_desc, hpcrun_metricVal_t *metric, double value)
Definition: hpcrun-fmt.c:482
virtual NonUniformDegreeTreeNode * Current() const
hpcrun_metricFlags_t flags
Definition: hpcrun-fmt.h:372
void hpcrun_getFileErrorString(const std::string &fnm, std::string &errorString)
Definition: FileError.cpp:87
static const int HPCMETRICDB_FMT_HeaderLen
Definition: hpcrun-fmt.h:738
FILE * hpcio_fopen_w(const char *fnm, int overwrite)
Definition: hpcio.c:100
hpcrun_metricVal_t * metrics
Definition: hpcrun-fmt.h:560
#define HPCIO_RWBufferSz
Definition: hpcio.h:86
void periodMean(float periodMeanEvent)
Prof::Struct::Tree * m_structure
virtual uint accumId(int) const =0
bool operator()(const std::string n1, const std::string n2) const
#define HPCRUN_FMT_NV_prog
Definition: hpcrun-fmt.h:153
std::map< uint, uint > m_mapFileIDs
#define HPCRUN_FMT_CCTNodeId_NULL
Definition: hpcrun-fmt.h:497
std::map< uint, uint > m_pairFakeLoadModule
int hpctrace_fmt_hdr_fwrite(hpctrace_hdr_flags_t flags, FILE *fs)
Definition: hpcrun-fmt.c:862
CCT::Tree * cct() const
virtual NonUniformDegreeTreeNode * Current() const
static bool writeXML_ProcFilter(const Struct::ANode &x, long GCC_ATTR_UNUSED type)