예제 #1
0
static void
makeDerivedMetrics(Prof::Metric::Mgr& metricMgr,
		   uint /*Analysis::Args::MetricFlg*/ metrics)
{
  if (Analysis::Args::MetricFlg_isSum(metrics)) {
    bool needAllStats =
      Analysis::Args::MetricFlg_isSet(metrics,
				      Analysis::Args::MetricFlg_StatsAll);
    bool needMultiOccurance = Analysis::Args::MetricFlg_isThread(metrics);
    metricMgr.makeSummaryMetrics(needAllStats, needMultiOccurance);
  }
  
  if (!Analysis::Args::MetricFlg_isThread(metrics)) {
    using namespace Prof;

    for (uint i = 0; i < metricMgr.size(); i++) {
      Metric::ADesc* m = metricMgr.metric(i);
      Metric::SampledDesc* mm = dynamic_cast<Metric::SampledDesc*>(m);
      if (mm) {
	mm->isVisible(false);
	mm->isSortKey(false);
      }
    }

    for (uint i = 0; i < metricMgr.size(); i++) {
      Metric::ADesc* m = metricMgr.metric(i);
      Metric::DerivedDesc* mm = dynamic_cast<Metric::DerivedDesc*>(m);
      if (mm) {
	mm->isSortKey(true);
	break;
      }
    }
  }
}
예제 #2
0
Prof::CallPath::Profile*
read(const char* prof_fnm, uint groupId, uint rFlags)
{
  // -------------------------------------------------------
  // 
  // -------------------------------------------------------

  Prof::CallPath::Profile* prof = NULL;
  try {
    DIAG_MsgIf(0, "Reading: '" << prof_fnm << "'");
    prof = Prof::CallPath::Profile::make(prof_fnm, rFlags, /*outfs*/ NULL);
  }
  catch (...) {
    DIAG_EMsg("While reading profile '" << prof_fnm << "'...");
    throw;
  }

  // -------------------------------------------------------
  // Potentially update the profile's metrics
  // -------------------------------------------------------

  if (groupId > 0) {
    Prof::Metric::Mgr* metricMgr = prof->metricMgr();
    for (uint i = 0; i < metricMgr->size(); ++i) {
      Prof::Metric::ADesc* m = metricMgr->metric(i);
      m->namePfx(StrUtil::toStr(groupId));
    }
    metricMgr->recomputeMaps();
  }

  return prof;
}
예제 #3
0
MetricCursor::MetricCursor(const Prof::Metric::Mgr& metricMgr,
			   const Prof::Flat::LM& proflm, 
			   const BinUtil::LM& lm)
{
  m_loadAddr = (VMA)proflm.load_addr();
  m_doUnrelocate = lm.doUnrelocate(m_loadAddr);
  
  // --------------------------------------------------------
  // Find all metrics for load module and compute totals for each metric
  // For now we have one metric per sampled event.
  // --------------------------------------------------------

  // NOTE: only handles raw events

  for (uint i = 0; i < metricMgr.size(); ++i) {
    const Prof::Metric::ADesc* m = metricMgr.metric(i);
    const Prof::Metric::SampledDesc* mm =
      dynamic_cast<const Prof::Metric::SampledDesc*>(m);
    if (mm) {
      uint mIdx = (uint)StrUtil::toUInt64(mm->profileRelId());
      const Prof::Flat::EventData& profevent = proflm.event(mIdx);
      m_metricDescs.push_back(&profevent);
    }
  }

  m_metricTots.resize(m_metricDescs.size());
  for (uint i = 0; i < m_metricDescs.size(); ++i) {
    const Prof::Flat::EventData& profevent = *(m_metricDescs[i]);
    uint64_t& metricTotal = m_metricTots[i];
    metricTotal = 0;

    for (uint j = 0; j < profevent.num_data(); ++j) {
      const Prof::Flat::Datum& evdat = profevent.datum(j);
      uint32_t count = evdat.second;
      metricTotal += count;
    }
  }

  m_curMetricIdx.resize(m_metricDescs.size());
  for (uint i = 0; i < m_curMetricIdx.size(); ++i) {
    m_curMetricIdx[i] = 0;
  }

  m_metricValAtVMA.resize(m_metricDescs.size());
}
예제 #4
0
// makeReturnCountMetric: A return count refers to the number of times
// a given CCT node is called by its parent context.  However, when
// hpcrun records return counts, there is no structure (e.g. procedure
// frames) in the CCT.  An an example, in the CCT fragment below, the
// return count [3] at 0xc means that 0xc returned to 0xbeef 3 times.
// Simlarly, 0xbeef returned to its caller 5 times.
//
//              |               |
//       ip: 0xbeef [5]         |
//       /      |      \        |
//   0xa [1]  0xb [2]  0xc [3]  |
//      |       |       |       |
//
// To be able to say procedure F is called by procedure G x times
// within this context, it is necessary to aggregate these counts at
// the newly added procedure frames (Struct::ProcFrm).
static void
makeReturnCountMetric(Prof::CallPath::Profile& prof)
{
  std::vector<uint> retCntId;

  // -------------------------------------------------------
  // find return count metrics, if any
  // -------------------------------------------------------
  Prof::Metric::Mgr* metricMgr = prof.metricMgr();
  for (uint i = 0; i < metricMgr->size(); ++i) {
    Prof::Metric::ADesc* m = metricMgr->metric(i);
    if (m->nameBase().find(HPCRUN_METRIC_RetCnt) != string::npos) {
      retCntId.push_back(m->id());
      m->computedType(Prof::Metric::ADesc::ComputedTy_Final);
      m->type(Prof::Metric::ADesc::TyExcl);
    }
  }

  if (retCntId.empty()) {
    return;
  }

  // -------------------------------------------------------
  // propagate and aggregate return counts
  // -------------------------------------------------------
  Prof::CCT::ANode* cct_root = prof.cct()->root();
  Prof::CCT::ANodeIterator it(cct_root, NULL/*filter*/, false/*leavesOnly*/,
			      IteratorStack::PostOrder);
  for (Prof::CCT::ANode* n = NULL; (n = it.current()); ++it) {
    if (typeid(*n) != typeid(Prof::CCT::ProcFrm) && n != cct_root) {
      Prof::CCT::ANode* n_parent = n->parent();
      for (uint i = 0; i < retCntId.size(); ++i) {
	uint mId = retCntId[i];
	n_parent->demandMetric(mId) += n->demandMetric(mId);
	n->metric(mId) = 0.0;
      }
    }
  }
}
예제 #5
0
static void 
ProcessMETRIC(DOMNode *node, Analysis::Args& args, Prof::Metric::Mgr& mMgr)
{
  static XMLCh* FILE = XMLString::transcode("FILE");
  static XMLCh* COMPUTE = XMLString::transcode("COMPUTE");
  static XMLCh* NAMEATTR = XMLString::transcode("name");
  static XMLCh* DISPLAYATTR = XMLString::transcode("display");
  static XMLCh* PERCENTATTR = XMLString::transcode("percent");
  //static XMLCh* PROPAGATEATTR = XMLString::transcode("propagate");
  static XMLCh* DISPLAYNAMEATTR = XMLString::transcode("displayName");
  static XMLCh* SORTBYATTR = XMLString::transcode("sortBy");

  // get metric attributes
  string metricNm = getAttr(node, NAMEATTR); 
  string metricDispNm = getAttr(node, DISPLAYNAMEATTR); 
  bool metricDoDisp = (getAttr(node, DISPLAYATTR) == "true"); 
  bool metricDoPercent = (getAttr(node,PERCENTATTR) == "true"); 
  bool metricDoSortBy = (getAttr(node,SORTBYATTR) == "true"); 

  if (metricNm.empty()) {
    ConfigParser_Throw("METRIC: Invalid name: '" << metricNm << "'.");
  }
  else if (mMgr.metric(metricNm) != NULL) {
    ConfigParser_Throw("METRIC: Metric name '" << metricNm << "' was previously defined.");
  }

  if (metricDispNm.empty()) {
    ConfigParser_Throw("METRIC: Invalid displayName: '" << metricDispNm << "'.");
  }
    
  DIAG_DevMsgIf(DBG, "CONFIG: " << "METRIC: name=" << metricNm
		<< " display=" <<  ((metricDoDisp) ? "true" : "false")
		<< " doPercent=" <<  ((metricDoPercent) ? "true" : "false")
		<< " sortBy=" <<  ((metricDoSortBy) ? "true" : "false")
		<< " metricDispNm=" << metricDispNm);
		
  // should have exactly one child
  DOMNode* metricImpl = node->getFirstChild();

  for ( ; metricImpl != NULL; metricImpl = metricImpl->getNextSibling()) {

    if (metricImpl->getNodeType() == DOMNode::TEXT_NODE) {
      // DTD ensures this can't contain anything but white space
      continue;
    }
    else if (metricImpl->getNodeType() == DOMNode::COMMENT_NODE) {
      continue;
    }
    
    const XMLCh* metricType = metricImpl->getNodeName();

    if (XMLString::equals(metricType, FILE)) {

      ProcessFILE(metricImpl, args, mMgr, metricNm, 
		  metricDoDisp, metricDoPercent, metricDoSortBy, 
		  metricDispNm);
    }
    else if (XMLString::equals(metricType,COMPUTE)) {

      //bool propagateComputed = false; // tallent
      // (getAttr(metricImpl, PROPAGATEATTR) == "computed"); 

      DOMNode* child = metricImpl->getFirstChild();
      for (; child != NULL; child = child->getNextSibling()) {
	if (child->getNodeType() == DOMNode::TEXT_NODE) {
	  // DTD ensures this can't contain anything but white space
	  continue;
	}
	else if (child->getNodeType() == DOMNode::COMMENT_NODE) {
	  continue;
	}

	using namespace Prof;
	Metric::AExpr* expr = makeMathMLExpr(metricNm.c_str(), child, mMgr);
	mMgr.insert(new Metric::DerivedDesc(metricNm, metricNm, expr,
					    metricDoDisp, metricDoSortBy,
					    metricDoPercent, 
					    false/*isPercent*/));
      }
    } 
    else {
      ConfigParser_Throw("Unexpected METRIC type '" << XMLString::transcode(metricType) << "'.");
    }
  }
}