HPCToolkit
Metric-Mgr.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 //************************ System Include Files ******************************
48 
49 #include <iostream>
50 
51 #include <string>
52 using std::string;
53 
54 #include <map>
55 using std::map;
56 
57 #include <vector>
58 using std::vector;
59 
60 #include <typeinfo>
61 
62 //************************* User Include Files *******************************
63 
64 #include "Metric-Mgr.hpp"
65 
66 #include "Flat-ProfileData.hpp"
67 
69 #include <lib/support/StrUtil.hpp>
70 
71 
72 //************************ Forward Declarations ******************************
73 
74 
75 namespace Prof {
76 
77 namespace Metric {
78 
79 //****************************************************************************
80 //
81 //****************************************************************************
82 
84 {
85 }
86 
87 
89 {
90  for (uint i = 0; i < m_metrics.size(); ++i) {
91  delete m_metrics[i];
92  }
93 }
94 
95 //****************************************************************************
96 
97 void
98 Mgr::makeRawMetrics(const std::vector<std::string>& profileFiles,
99  bool isUnitsEvents, bool doDispPercent)
100 {
101  // ------------------------------------------------------------
102  // Create a Metric::SampledDesc for each event within each profile
103  // ------------------------------------------------------------
104  for (uint i = 0; i < profileFiles.size(); ++i) {
105  const string& proffnm = profileFiles[i];
106 
108  try {
109  prof.open(proffnm.c_str());
110  }
111  catch (...) {
112  DIAG_EMsg("While reading '" << proffnm << "'");
113  throw;
114  }
115 
116  const Metric::SampledDescVec& mdescs = prof.mdescs();
117  for (uint j = 0; j < mdescs.size(); ++j) {
118  const Metric::SampledDesc& mSmpl = *mdescs[j];
119 
120  bool isSortKey = (empty());
121 
123  m->isSortKey(isSortKey);
124  m->doDispPercent(doDispPercent);
125  m->isUnitsEvents(isUnitsEvents);
126  m->zeroDBInfo();
127 
128  insert(m);
129  }
130  }
131 }
132 
133 
134 uint
135 Mgr::makeSummaryMetrics(bool needAllStats, bool needMultiOccurance,
136  uint srcBegId, uint srcEndId)
137 {
138  StringToADescVecMap nmToMetricMap;
139 
140  std::vector<Metric::ADescVec*> metricGroups;
141 
142  if (srcBegId == Mgr::npos) {
143  srcBegId = 0;
144  }
145  if (srcEndId == Mgr::npos) {
146  srcEndId = m_metrics.size();
147  }
148 
149  uint threshold = (needMultiOccurance) ? 2 : 1;
150 
151  // -------------------------------------------------------
152  // collect like metrics
153  // -------------------------------------------------------
154  for (uint i = srcBegId; i < srcEndId; ++i) {
155  Metric::ADesc* m = m_metrics[i];
156  string nm = m->nameGeneric();
157 
158  StringToADescVecMap::iterator it = nmToMetricMap.find(nm);
159  if (it != nmToMetricMap.end()) {
160  Metric::ADescVec& mvec = it->second;
161  mvec.push_back(m);
162  }
163  else {
164  std::pair<StringToADescVecMap::iterator, bool> ret =
165  nmToMetricMap.insert(make_pair(nm, Metric::ADescVec(1, m)));
166  Metric::ADescVec* grp = &(ret.first->second);
167  metricGroups.push_back(grp);
168  }
169  }
170 
171  // -------------------------------------------------------
172  // create summary metrics
173  // -------------------------------------------------------
174  uint firstId = Mgr::npos;
175 
176  for (uint i = 0; i < metricGroups.size(); ++i) {
177  const Metric::ADescVec& mVec = *(metricGroups[i]);
178  if (mVec.size() >= threshold) {
179  Metric::ADesc* m = mVec[0];
180 
181  Metric::ADesc* mNew = makeSummaryMetric("Sum", m, mVec);
182 
183  if (needAllStats) {
184  makeSummaryMetric("Mean", m, mVec);
185  makeSummaryMetric("StdDev", m, mVec);
186  makeSummaryMetric("CfVar", m, mVec);
187  makeSummaryMetric("Min", m, mVec);
188  makeSummaryMetric("Max", m, mVec);
189  }
190 
191  if (firstId == Mgr::npos) {
192  firstId = mNew->id();
193  }
194  }
195  }
196 
197  computePartners();
198 
199  return firstId;
200 }
201 
202 void
204 {
205 
206 
207  for (uint i=0; i<source->size(); i++) {
208 
209  Prof::Metric::ADesc *m = metric(i);
210 
211  uint64_t samples = m->num_samples() +
212  source->metric(i)->num_samples();
213  uint64_t period = m->periodMean() +
214  source->metric(i)->periodMean();
215 
216  m->num_samples(samples);
217  m->periodMean (period);
218  }
219 }
220 
221 void
223 {
224  for (uint i=0; i<m_metrics.size(); i++) {
225  Prof::Metric::ADesc *m = metric(i);
226 
227  float period = m->periodMean();
228  float mean = period / num_profiles;
229 
230  m->periodMean(mean);
231  }
232 }
233 
234 uint
235 Mgr::makeSummaryMetricsIncr(bool needAllStats, uint srcBegId, uint srcEndId)
236 {
237  if (srcBegId == Mgr::npos) {
238  srcBegId = 0;
239  }
240  if (srcEndId == Mgr::npos) {
241  srcEndId = m_metrics.size();
242  }
243 
244  uint firstId = Mgr::npos;
245 
246  for (uint i = srcBegId; i < srcEndId; ++i) {
247  Metric::ADesc* m = m_metrics[i];
248 
249  Metric::ADesc* mNew =
250  makeSummaryMetricIncr("Sum", m);
251 
252  if (needAllStats) {
253  makeSummaryMetricIncr("Mean", m);
254  makeSummaryMetricIncr("StdDev", m);
255  makeSummaryMetricIncr("CfVar", m);
256  makeSummaryMetricIncr("Min", m);
257  makeSummaryMetricIncr("Max", m);
258  }
259 
260  if (firstId == Mgr::npos) {
261  firstId = mNew->id();
262  }
263  }
264 
265  computePartners();
266 
267  return firstId;
268 }
269 
270 
272 Mgr::makeSummaryMetric(const string mDrvdTy, const Metric::ADesc* mSrc,
273  const Metric::ADescVec& mOpands)
274 {
275  Metric::AExpr** opands = new Metric::AExpr*[mOpands.size()];
276  for (uint i = 0; i < mOpands.size(); ++i) {
277  Metric::ADesc* m = mOpands[i];
278  opands[i] = new Metric::Var(m->name(), m->id());
279  }
280 
281  // This is a cheesy way of creating the metrics, but it is good
282  // enough for now.
283 
284  Metric::AExpr* expr = NULL;
285  if (mDrvdTy.find("Sum", 0) == 0) {
286  expr = new Metric::Plus(opands, mOpands.size());
287  }
288  else if (mDrvdTy.find("Mean", 0) == 0) {
289  expr = new Metric::Mean(opands, mOpands.size());
290  }
291  else if (mDrvdTy.find("StdDev", 0) == 0) {
292  expr = new Metric::StdDev(opands, mOpands.size());
293  }
294  else if (mDrvdTy.find("CfVar", 0) == 0) {
295  expr = new Metric::CoefVar(opands, mOpands.size());
296  }
297  else if (mDrvdTy.find("%CfVar", 0) == 0) {
298  expr = new Metric::RStdDev(opands, mOpands.size());
299  }
300  else if (mDrvdTy.find("Min", 0) == 0) {
301  expr = new Metric::Min(opands, mOpands.size());
302  }
303  else if (mDrvdTy.find("Max", 0) == 0) {
304  expr = new Metric::Max(opands, mOpands.size());
305  }
306  else {
308  }
309 
310  string mNmFmt = mSrc->nameToFmt();
311  string mNmBase = mSrc->nameBase() + ":" + mDrvdTy;
312  const string& mDesc = mSrc->description();
313 
314  DerivedDesc* m =
315  new DerivedDesc(mNmFmt, mDesc, expr, mSrc->isVisible(), true/*isSortKey*/,
316  mSrc->doDispPercent(), mSrc->isPercent());
317  m->nameBase(mNmBase);
318  m->nameSfx(""); // clear; cf. Prof::CallPath::Profile::RFlg_NoMetricSfx
319  m->zeroDBInfo(); // clear
320 
321  // copy some attributes from the source
322  m->periodMean (mSrc->periodMean());
323  m->sampling_type(mSrc->sampling_type());
324  m->num_samples (mSrc->num_samples());
325  m->isMultiplexed(mSrc->isMultiplexed());
326 
327  insert(m);
328  expr->accumId(0, m->id());
329 
330  for (uint k = 1; k < expr->numAccum(); ++k) {
331  string m2NmBase = mNmBase + ":accum" + StrUtil::toStr(k+1);
332  DerivedDesc* m2 =
333  new DerivedDesc(mNmFmt, mDesc, NULL/*expr*/, false/*isVisible*/,
334  false/*isSortKey*/, false/*doDispPercent*/,
335  false/*isPercent*/);
336  m2->nameBase(m2NmBase);
337  m2->nameSfx(""); // clear; cf. Prof::CallPath::Profile::RFlg_NoMetricSfx
338  m2->zeroDBInfo(); // clear
339  insert(m2);
340 
341  expr->accumId(k, m2->id());
342  }
343 
344  if (expr->hasNumSrcVar()) {
345  string m3NmBase = mNmBase + ":num-src";
346  Metric::NumSource* m3Expr = new Metric::NumSource(mOpands.size());
347  DerivedDesc* m3 =
348  new DerivedDesc(mNmFmt, mDesc, m3Expr, false/*isVisible*/,
349  false/*isSortKey*/, false/*doDispPercent*/,
350  false/*isPercent*/);
351  m3->nameBase(m3NmBase);
352  m3->nameSfx(""); // clear; cf. Prof::CallPath::Profile::RFlg_NoMetricSfx
353  m3->zeroDBInfo(); // clear
354  insert(m3);
355  m3Expr->accumId(0, m3->id());
356 
357  expr->numSrcVarId(m3->id());
358  }
359 
360  return m;
361 }
362 
363 
365 Mgr::makeSummaryMetricIncr(const string mDrvdTy, const Metric::ADesc* mSrc)
366 {
367  bool doDispPercent = mSrc->doDispPercent();
368  bool isVisible = mSrc->isVisible();
369  bool isPercent = false;
370 
371  // This is a cheesy way of creating the metrics, but it is good
372  // enough for now.
373 
374  Metric::AExprIncr* expr = NULL;
375  if (mDrvdTy.find("Sum", 0) == 0) {
376  expr = new Metric::SumIncr(Metric::IData::npos, mSrc->id());
377  }
378  else if (mDrvdTy.find("Mean", 0) == 0) {
379  expr = new Metric::MeanIncr(Metric::IData::npos, mSrc->id());
380  doDispPercent = false;
381  }
382  else if (mDrvdTy.find("StdDev", 0) == 0) {
383  expr = new Metric::StdDevIncr(Metric::IData::npos, 0, mSrc->id());
384  doDispPercent = false;
385  }
386  else if (mDrvdTy.find("CfVar", 0) == 0) {
387  expr = new Metric::CoefVarIncr(Metric::IData::npos, 0, mSrc->id());
388  doDispPercent = false;
389  }
390  else if (mDrvdTy.find("%CfVar", 0) == 0) {
391  expr = new Metric::RStdDevIncr(Metric::IData::npos, 0, mSrc->id());
392  isPercent = true;
393  }
394  else if (mDrvdTy.find("Min", 0) == 0) {
395  expr = new Metric::MinIncr(Metric::IData::npos, mSrc->id());
396  doDispPercent = false;
397  }
398  else if (mDrvdTy.find("Max", 0) == 0) {
399  expr = new Metric::MaxIncr(Metric::IData::npos, mSrc->id());
400  doDispPercent = false;
401  }
402  else {
404  }
405 
406  string mNmFmt = mSrc->nameToFmt();
407  string mNmBase = mSrc->nameBase() + ":" + mDrvdTy;
408  const string& mDesc = mSrc->description();
409 
410  DerivedIncrDesc* m =
411  new DerivedIncrDesc(mNmFmt, mDesc, expr, isVisible,
412  true/*isSortKey*/, doDispPercent, isPercent);
413  m->nameBase(mNmBase);
414  m->zeroDBInfo(); // clear
415 
416  // copy some attributes from the source
417  m->periodMean (mSrc->periodMean());
418  m->sampling_type(mSrc->sampling_type());
419  m->num_samples (mSrc->num_samples());
420  m->isMultiplexed(mSrc->isMultiplexed());
421 
422  insert(m);
423  expr->accumId(0, m->id());
424 
425  for (uint k = 1; k < expr->numAccum(); ++k) {
426  string m2NmBase = mNmBase + ":accum" + StrUtil::toStr(k+1);
427  DerivedIncrDesc* m2 =
428  new DerivedIncrDesc(mNmFmt, mDesc, NULL/*expr*/, false/*isVisible*/,
429  false/*isSortKey*/, false/*doDispPercent*/,
430  false/*isPercent*/);
431  m2->nameBase(m2NmBase);
432  m2->zeroDBInfo(); // clear
433  insert(m2);
434 
435  expr->accumId(k, m2->id());
436  }
437 
438  if (expr->hasNumSrcVar()) {
439  string m3NmBase = mNmBase + ":num-src";
440  Metric::NumSourceIncr* m3Expr = new Metric::NumSourceIncr(0, mSrc->id());
441  DerivedIncrDesc* m3 =
442  new DerivedIncrDesc(mNmFmt, mDesc, m3Expr, false/*isVisible*/,
443  false/*isSortKey*/, false/*doDispPercent*/,
444  false/*isPercent*/);
445  m3->nameBase(m3NmBase);
446  m3->zeroDBInfo(); // clear
447  insert(m3);
448  m3Expr->accumId(0, m3->id());
449 
450  expr->numSrcVarId(m3->id());
451  }
452 
453  return m;
454 }
455 
456 
457 //****************************************************************************
458 
459 bool
461 {
462  // 1. metric table
463  uint id = m_metrics.size();
464  m_metrics.push_back(m);
465  m->id(id);
466 
467  // 2. insert in maps and ensure name is unique
468  bool changed = insertInMapsAndMakeUniqueName(m);
469  return changed;
470 }
471 
472 
473 bool
475 {
476  string nm = m->name();
477  if (metric(nm)) {
478  return false; // already exists
479  }
480 
481  insert(m);
482  return true;
483 }
484 
485 
488 {
490  for (uint i = 0; i < m_metrics.size(); ++i) {
491  Metric::ADesc* m = m_metrics[i];
492  if (m->isSortKey()) {
493  found = m;
494  break;
495  }
496  }
497  return found;
498 }
499 
500 
503 {
505  for (uint i = 0; i < m_metrics.size(); ++i) {
506  Metric::ADesc* m = m_metrics[i];
507  if (m->isVisible()) {
508  found = m;
509  break;
510  }
511  }
512  return found;
513 }
514 
515 
518 {
520  for (int i = m_metrics.size() - 1; i >= 0; --i) { // i may be < 0
521  Metric::ADesc* m = m_metrics[i];
522  if (m->isVisible()) {
523  found = m;
524  break;
525  }
526  }
527  return found;
528 }
529 
530 
531 bool
533 {
534  for (uint i = 0; i < m_metrics.size(); ++i) {
535  Metric::ADesc* m = m_metrics[i];
536  if (typeid(*m) == typeid(Prof::Metric::DerivedDesc) ||
537  typeid(*m) == typeid(Prof::Metric::DerivedIncrDesc)) {
538  return true;
539  }
540  }
541  return false;
542 }
543 
544 
545 //****************************************************************************
546 
547 // findGroup: see general comments in header.
548 //
549 // Currently assumes:
550 // 1. Metric groups in both x and y appear in sorted order and without
551 // gaps. This assumption is upheld because (a) groups are
552 // distributed across processes in sorted order and (b) the
553 // reduction tree always merges left before right children.
554 //
555 // This means we should *never* see:
556 // x: [2.a 2.b] y: [1.a 1.b | 2.a 2.b]
557 // x: [2.a 2.b] y: [1.a 1.b | 3.a 3.b]
558 //
559 // 2. All profile files in a group have the same set of metrics.
560 //
561 // While this simplifies things, because of groups, we still have to
562 // merge profiles where only a subgroup of y matches a group in x.
563 // x: [1.a 1.b] y: [1.a 1.b | 2.a 2.b]
564 //
565 //
566 // *** N.B.: *** Assumptions (1) and (2) imply that either (a) y's
567 // metrics fully match x's or (b) y's *first* metric subgroup fully
568 // matches x's metrics. It also enables us to use a metric's unique
569 // name for a search.
570 //
571 //
572 // TODO: Eventually, we cannot assume (2). It will be possible for
573 // a group to have different sets of metrics, which could lead to
574 // merges like the following:
575 //
576 // x: [1.a 1.b] y: [1.a 1.b | 1.a 1.c]
577 // x: [1.a 1.c] y: [1.a 1.b | 1.a 1.c]
578 // x: [1.a 1.c] [1.d 1.e] y: [1.a 1.b | 1.a 1.c]
579 //
580 // This implies that *any* subgroup of y could match *any* subgroup of
581 // x. It also implies that we cannot search by a metric's unique name
582 // because the unique name in y may be different than the unique name
583 // in x.
584 //
585 uint
586 Mgr::findGroup(const Mgr& y) const
587 {
588  const Mgr* x = this;
589 
590  // -------------------------------------------------------
591  // Based on observation above, we first try to match y's first
592  // subgroup.
593  // -------------------------------------------------------
594 
595  uint y_grp_sz = 0; // open end boundary
596  if (y.size() > 0) {
597  y_grp_sz = 1; // metric 0 is first entry in 'y_grp'
598  const string& y_grp_pfx = y.metric(0)->namePfx();
599 
600  for (uint y_i = 1; y_i < y.size(); ++y_i) {
601  const string& mPfx = y.metric(y_i)->namePfx();
602  if (mPfx != y_grp_pfx) {
603  break;
604  }
605  y_grp_sz++;
606  }
607  }
608 
609  bool found = true; // optimistic
610 
611  std::vector<uint> metricMap(y_grp_sz);
612 
613  for (uint y_i = 0; y_i < y_grp_sz; ++y_i) {
614  const Metric::ADesc* y_m = y.metric(y_i);
615  string mNm = y_m->name();
616  const Metric::ADesc* x_m = x->metric(mNm);
617 
618  if (!x_m || (y_i > 0 && x_m->id() != (metricMap[y_i - 1] + 1))) {
619  found = false;
620  break;
621  }
622 
623  metricMap[y_i] = x_m->id();
624  }
625 
626  bool foundGrp = (found && !metricMap.empty());
627 
628  // -------------------------------------------------------
629  //
630  // -------------------------------------------------------
631 
632  if (foundGrp) {
633  // sanity check: either (x.size() == y_grp_sz) or the rest of x
634  // matches the rest of y.
635  for (uint x_i = metricMap[y_grp_sz - 1] + 1, y_i = y_grp_sz;
636  x_i < x->size() && y_i < y.size(); ++x_i, ++y_i) {
637  DIAG_Assert(x->metric(x_i)->name() == y.metric(y_i)->name(), "");
638  }
639  }
640 
641  return (foundGrp) ? metricMap[0] : Mgr::npos;
642 }
643 
644 
645 //****************************************************************************
646 
647 void
649 {
650  // clear maps
651  m_nuniqnmToMetricMap.clear();
652  m_uniqnmToMetricMap.clear();
653  m_fnameToFMetricMap.clear();
654 
655  for (uint i = 0; i < m_metrics.size(); ++i) {
656  Metric::ADesc* m = m_metrics[i];
658  }
659 }
660 
661 
662 void
664 {
665  StringToADescMap metricsIncl;
666  StringToADescMap metricsExcl;
667 
668  // -------------------------------------------------------
669  // populate maps
670  // -------------------------------------------------------
671  for (uint i = 0; i < m_metrics.size(); ++i) {
672  Metric::ADesc* m = m_metrics[i];
673  string nm = m->namePfxBaseSfx();
674 
675  StringToADescMap* metricsMap = NULL;
676  switch (m->type()) {
677  case ADesc::TyIncl: metricsMap = &metricsIncl; break;
678  case ADesc::TyExcl: metricsMap = &metricsExcl; break;
679  default: break;
680  }
681 
682  if (metricsMap) {
683  DIAG_MsgIf(0, "Metric::Mgr::computePartners: insert: " << nm
684  << " [" << m->name() << "]");
685  std::pair<StringToADescMap::iterator, bool> ret =
686  metricsMap->insert(make_pair(nm, m));
687  DIAG_Assert(ret.second, "Metric::Mgr::computePartners: Found duplicate entry inserting:\n\t" << m->toString() << "\nOther entry:\n\t" << ret.first->second->toString());
688  }
689  }
690 
691  // -------------------------------------------------------
692  // find partners
693  // -------------------------------------------------------
694  for (uint i = 0; i < m_metrics.size(); ++i) {
695  Metric::ADesc* m = m_metrics[i];
696  string nm = m->namePfxBaseSfx();
697 
698  StringToADescMap* metricsMap = NULL;
699  switch (m->type()) {
700  case ADesc::TyIncl: metricsMap = &metricsExcl; break;
701  case ADesc::TyExcl: metricsMap = &metricsIncl; break;
702  default: break;
703  }
704 
705  if (metricsMap) {
706  StringToADescMap::iterator it = metricsMap->find(nm);
707  if (it != metricsMap->end()) {
708  Metric::ADesc* partner = it->second;
709  m->partner(partner);
710  DIAG_MsgIf(0, "Metric::Mgr::computePartners: found: "
711  << m->name() << " -> " << partner->name());
712  }
713  }
714  }
715 }
716 
717 
718 //****************************************************************************
719 
720 void
722 {
723  for (uint i = 0; i < m_metrics.size(); ++i) {
724  Metric::ADesc* m = m_metrics[i];
725  if (m->hasDBInfo()) {
726  m->zeroDBInfo();
727  }
728  }
729 }
730 
731 
732 //****************************************************************************
733 
734 string
735 Mgr::toString(const char* pfx) const
736 {
737  std::ostringstream os;
738  dump(os, pfx);
739  return os.str();
740 }
741 
742 
743 std::ostream&
744 Mgr::dump(std::ostream& os, const char* pfx) const
745 {
746  os << pfx << "[ metric table:" << std::endl;
747  for (uint i = 0; i < m_metrics.size(); i++) {
748  Metric::ADesc* m = m_metrics[i];
749  os << pfx << " " << m->id() << ": " << m->toString() << std::endl;
750  }
751  os << pfx << "]" << std::endl;
752 
753  os << pfx << "[ unique-name-to-metric:" << std::endl;
754  for (StringToADescMap::const_iterator it = m_uniqnmToMetricMap.begin();
755  it != m_uniqnmToMetricMap.end(); ++it) {
756  const string& nm = it->first;
757  Metric::ADesc* m = it->second;
758  os << pfx << " " << nm << " -> " << m->toString() << std::endl;
759  }
760  os << pfx << "]" << std::endl;
761 
762  return os;
763 }
764 
765 
766 void
767 Mgr::ddump() const
768 {
769  dump(std::cerr);
770  std::cerr.flush();
771 }
772 
773 
774 //****************************************************************************
775 //
776 //****************************************************************************
777 
778 bool
780 {
781  bool isChanged = false;
782 
783  // 1. metric name to Metric::ADescVec table
784  string nm = m->name();
785  StringToADescVecMap::iterator it = m_nuniqnmToMetricMap.find(nm);
786  if (it != m_nuniqnmToMetricMap.end()) {
787  Metric::ADescVec& mvec = it->second;
788 
789  // ensure uniqueness: qualifier is an integer >= 1
790  int qualifier = mvec.size();
791  const string& nm_sfx = m->nameSfx();
792  string sfx_new = nm_sfx;
793  if (!sfx_new.empty()) {
794  sfx_new += ".";
795  }
796  sfx_new += StrUtil::toStr(qualifier);
797 
798  m->nameSfx(sfx_new);
799  nm = m->name(); // update 'nm'
800  isChanged = true;
801 
802  mvec.push_back(m);
803  }
804  else {
805  m_nuniqnmToMetricMap.insert(make_pair(nm, Metric::ADescVec(1, m)));
806  }
807 
808  // 2. unique name to Metric::ADesc table
809  std::pair<StringToADescMap::iterator, bool> ret =
810  m_uniqnmToMetricMap.insert(make_pair(nm, m));
811  DIAG_Assert(ret.second, "Metric::Mgr::insertInMapsAndMakeUniqueName: Found duplicate entry inserting:\n\t" << m->toString() << "\nOther entry:\n\t" << ret.first->second->toString());
812 
813 
814  // 3. profile file name to Metric::SampledDesc table
815  Metric::SampledDesc* mSmpl = dynamic_cast<Metric::SampledDesc*>(m);
816  if (mSmpl) {
817  const string& fnm = mSmpl->profileName();
818  StringToADescVecMap::iterator it1 = m_fnameToFMetricMap.find(fnm);
819  if (it1 != m_fnameToFMetricMap.end()) {
820  Metric::ADescVec& mvec = it1->second;
821  mvec.push_back(mSmpl);
822  }
823  else {
824  m_fnameToFMetricMap.insert(make_pair(fnm, Metric::ADescVec(1, mSmpl)));
825  }
826  }
827 
828  return isChanged;
829 }
830 
831 
832 //****************************************************************************
833 
834 } // namespace Metric
835 
836 } // namespace Prof
const std::string & profileName() const
void makeRawMetrics(const std::vector< std::string > &profileFiles, bool isUnitsEvents=true, bool doDispPercent=true)
Definition: Metric-Mgr.cpp:98
bool insertInMapsAndMakeUniqueName(Metric::ADesc *m)
Definition: Metric-Mgr.cpp:779
bool insertIf(Metric::ADesc *m)
Definition: Metric-Mgr.cpp:474
ADesc * partner() const
bool isPercent() const
bool hasDBInfo() const
bool insert(Metric::ADesc *m)
Definition: Metric-Mgr.cpp:460
const std::string & nameSfx() const
std::string namePfxBaseSfx() const
bool isVisible() const
StringToADescVecMap m_nuniqnmToMetricMap
Definition: Metric-Mgr.hpp:277
bool hasDerived() const
Definition: Metric-Mgr.cpp:532
#define DIAG_EMsg(...)
Definition: diagnostics.h:251
void mergePerfEventStatistics(Mgr *source)
Definition: Metric-Mgr.cpp:203
string toStr(const int x, int base)
Definition: StrUtil.cpp:243
void ddump() const
Definition: Metric-Mgr.cpp:767
void isMultiplexed(bool isMultiplexedEvent)
virtual uint accumId(int i) const
virtual std::string toString() const
const Metric::SampledDescVec & mdescs()
std::vector< ADesc * > ADescVec
Metric::ADesc * findSortKey() const
Definition: Metric-Mgr.cpp:487
std::ostream & dump(std::ostream &os=std::cerr, const char *pfx="") const
Definition: Metric-Mgr.cpp:744
void zeroDBInfo() const
Definition: Metric-Mgr.cpp:721
std::string name() const
StringToADescVecMap m_fnameToFMetricMap
Definition: Metric-Mgr.hpp:283
bool empty() const
Definition: Metric-Mgr.hpp:157
uint makeSummaryMetricsIncr(bool needAllStats, uint srcBegId=Mgr::npos, uint srcEndId=Mgr::npos)
Definition: Metric-Mgr.cpp:235
void mergePerfEventStatistics_finalize(int num_profiles)
Definition: Metric-Mgr.cpp:222
bool doDispPercent() const
std::string nameToFmt() const
#define DIAG_MsgIf(ifexpr,...)
Definition: diagnostics.h:236
uint size() const
Definition: Metric-Mgr.hpp:153
void sampling_type(SamplingType_t type)
void num_samples(const uint64_t samples)
uint makeSummaryMetrics(bool needAllStats, bool needMultiOccurance, uint srcBegId=Mgr::npos, uint srcEndId=Mgr::npos)
Definition: Metric-Mgr.cpp:135
virtual bool hasNumSrcVar() const
const std::string & nameBase() const
std::string nameGeneric() const
std::string toString(const char *pfx="") const
Definition: Metric-Mgr.cpp:735
unsigned int uint
Definition: uint.h:124
static const uint npos
Definition: Metric-Mgr.hpp:202
Metric::DerivedIncrDesc * makeSummaryMetricIncr(const std::string mDrvdTy, const Metric::ADesc *mSrc)
Definition: Metric-Mgr.cpp:365
std::map< std::string, Metric::ADescVec > StringToADescVecMap
Definition: Metric-Mgr.hpp:81
Metric::DerivedDesc * makeSummaryMetric(const std::string mDrvdTy, const Metric::ADesc *mSrc, const Metric::ADescVec &mOpands)
Definition: Metric-Mgr.cpp:272
virtual uint numSrcVarId() const
Metric::ADesc * findFirstVisible() const
Definition: Metric-Mgr.cpp:502
bool isSortKey() const
Metric::ADescVec m_metrics
Definition: Metric-Mgr.hpp:273
ADescTy type() const
const char * DIAG_UnexpectedInput
bool found
Definition: cct.c:129
virtual uint accumId(int i) const
#define NULL
Definition: ElfHelper.cpp:85
const std::string & namePfx() const
std::map< std::string, Metric::ADesc * > StringToADescMap
Definition: Metric-Mgr.hpp:80
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
static int const threshold
void open(const char *filename=NULL)
#define DIAG_Die(...)
Definition: diagnostics.h:267
Metric::ADesc * findLastVisible() const
Definition: Metric-Mgr.cpp:517
StringToADescMap m_uniqnmToMetricMap
Definition: Metric-Mgr.hpp:280
void periodMean(float periodMeanEvent)
static long period
Definition: itimer.c:194
virtual uint numAccum() const
static const uint npos