Пример #1
0
void
unpackMetrics(Prof::CallPath::Profile& profile,
	      const ParallelAnalysis::PackedMetrics& packedMetrics)
{
  Prof::CCT::Tree& cct = *profile.cct();

  // 1. unpack 'packedMetrics' into temporary derived metrics [mBegId,
  //    mEndId) in 'profile'
  uint mBegId = packedMetrics.mBegId(), mEndId = packedMetrics.mEndId();

  DIAG_Assert(packedMetrics.numNodes() == cct.maxDenseId() + 1, "");
  DIAG_Assert(packedMetrics.numMetrics() == mEndId - mBegId, "");

  for (uint nodeId = 1; nodeId < packedMetrics.numNodes(); ++nodeId) {
    for (uint mId1 = 0, mId2 = mBegId; mId2 < mEndId; ++mId1, ++mId2) {
      Prof::CCT::ANode* n = cct.findNode(nodeId);
      n->demandMetric(mId2) = packedMetrics.idx(nodeId, mId1);
    }
  }

  // 2. update derived metrics [mDrvdBeg, mDrvdEnd) based on new
  //    values in [mBegId, mEndId)
  uint mDrvdBeg = packedMetrics.mDrvdBegId();
  uint mDrvdEnd = packedMetrics.mDrvdEndId();
  cct.root()->computeMetricsIncr(*profile.metricMgr(), mDrvdBeg, mDrvdEnd,
				 Prof::Metric::AExprIncr::FnCombine);
}
Пример #2
0
void
mergeNonLocal(std::pair<Prof::CallPath::Profile*,
	                ParallelAnalysis::PackedMetrics*> data,
	      int rank_x, int rank_y, int myRank, MPI_Comm comm)
{
  int tag = rank_y; // sender

  if (myRank == rank_x) {
    Prof::CallPath::Profile* profile_x = data.first;
    ParallelAnalysis::PackedMetrics* packedMetrics_x = data.second;

    // rank_x receives metric data from rank_y
    MPI_Status mpistat;
    MPI_Recv(packedMetrics_x->data(), packedMetrics_x->dataSize(),
	     MPI_DOUBLE, rank_y, tag, comm, &mpistat);
    DIAG_Assert(packedMetrics_x->verify(), DIAG_UnexpectedInput);
    
    unpackMetrics(*profile_x, *packedMetrics_x);
  }

  if (myRank == rank_y) {
    Prof::CallPath::Profile* profile_y = data.first;
    ParallelAnalysis::PackedMetrics* packedMetrics_y = data.second;

    packMetrics(*profile_y, *packedMetrics_y);
    
    // rank_y sends metric data to rank_x
    MPI_Send(packedMetrics_y->data(), packedMetrics_y->dataSize(),
	     MPI_DOUBLE, rank_x, tag, comm);
  }
}
Пример #3
0
void
broadcast(Prof::CallPath::Profile*& profile,
	  int myRank, int maxRank, MPI_Comm comm)
{
  if (myRank != RankTree::rootRank) {
    DIAG_Assert(!profile, "ParallelAnalysis::broadcast: " << DIAG_UnexpectedInput);
    profile = new Prof::CallPath::Profile("[ParallelAnalysis::broadcast]");
    profile->isMetricMgrVirtual(true);
  }
  
  int max_level = RankTree::level(maxRank);
  for (int level = 0; level < max_level; ++level) {
    int i_beg = RankTree::begNode(level);
    int i_end = std::min(maxRank, RankTree::endNode(level));
    
    for (int i = i_beg; i <= i_end; ++i) {
      // merge i into its left child (i_lchild)
      int i_lchild = RankTree::leftChild(i);
      if (i_lchild <= maxRank) {
	mergeNonLocal(profile, i_lchild, i, myRank);
      }

      // merge i into its right child (i_rchild)
      int i_rchild = RankTree::rightChild(i);
      if (i_rchild <= maxRank) {
	mergeNonLocal(profile, i_rchild, i, myRank);
      }
    }

    MPI_Barrier(comm);
  }
}
Пример #4
0
LoadMap::LoadMap(uint sz)
{
  m_lm_byId.reserve(sz);

  LM* nullLM = new LM(Prof::Struct::Tree::UnknownLMNm);
  lm_insert(nullLM);
  DIAG_Assert(nullLM->id() == LoadMap::LMId_NULL, "LoadMap::LoadMap");
}
Пример #5
0
// findGroup: see general comments in header.
//
// Currently assumes:
// 1. Metric groups in both x and y appear in sorted order and without
//    gaps.  This assumption is upheld because (a) groups are
//    distributed across processes in sorted order and (b) the
//    reduction tree always merges left before right children.
//
//    This means we should *never* see:
//      x: [2.a 2.b]  y: [1.a 1.b | 2.a 2.b]
//      x: [2.a 2.b]  y: [1.a 1.b | 3.a 3.b]
//
// 2. All profile files in a group have the same set of metrics.
// 
// While this simplifies things, because of groups, we still have to
// merge profiles where only a subgroup of y matches a group in x.
//   x: [1.a 1.b]  y: [1.a 1.b | 2.a 2.b]
// 
// 
// *** N.B.: *** Assumptions (1) and (2) imply that either (a) y's
// metrics fully match x's or (b) y's *first* metric subgroup fully
// matches x's metrics.  It also enables us to use a metric's unique
// name for a search.
// 
//
// TODO: Eventually, we cannot assume (2).  It will be possible for
// a group to have different sets of metrics, which could lead to
// merges like the following:
//
//    x: [1.a 1.b]            y: [1.a 1.b | 1.a 1.c]
//    x: [1.a 1.c]            y: [1.a 1.b | 1.a 1.c]
//    x: [1.a 1.c] [1.d 1.e]  y: [1.a 1.b | 1.a 1.c]
//
// This implies that *any* subgroup of y could match *any* subgroup of
// x.  It also implies that we cannot search by a metric's unique name
// because the unique name in y may be different than the unique name
// in x.
//
uint
Mgr::findGroup(const Mgr& y) const
{
  const Mgr* x = this;

  // -------------------------------------------------------
  // Based on observation above, we first try to match y's first
  // subgroup.
  // -------------------------------------------------------

  uint y_grp_sz = 0; // open end boundary
  if (y.size() > 0) {
    y_grp_sz = 1; // metric 0 is first entry in 'y_grp'
    const string& y_grp_pfx = y.metric(0)->namePfx();

    for (uint y_i = 1; y_i < y.size(); ++y_i) {
      const string& mPfx = y.metric(y_i)->namePfx();
      if (mPfx != y_grp_pfx) {
	break;
      }
      y_grp_sz++;
    }
  }

  bool found = true; // optimistic

  std::vector<uint> metricMap(y_grp_sz);
  
  for (uint y_i = 0; y_i < y_grp_sz; ++y_i) {
    const Metric::ADesc* y_m = y.metric(y_i);
    string mNm = y_m->name();
    const Metric::ADesc* x_m = x->metric(mNm);
    
    if (!x_m || (y_i > 0 && x_m->id() != (metricMap[y_i - 1] + 1))) {
      found = false;
      break;
    }
    
    metricMap[y_i] = x_m->id();
  }
  
  bool foundGrp = (found && !metricMap.empty());

  // -------------------------------------------------------
  // 
  // -------------------------------------------------------

  if (foundGrp) {
    // sanity check: either (x.size() == y_grp_sz) or the rest of x
    // matches the rest of y.
    for (uint x_i = metricMap[y_grp_sz - 1] + 1, y_i = y_grp_sz;
	 x_i < x->size() && y_i < y.size(); ++x_i, ++y_i) {
      DIAG_Assert(x->metric(x_i)->name() == y.metric(y_i)->name(), "");
    }
  }

  return (foundGrp) ? metricMap[0] : Mgr::npos;
}
Пример #6
0
void
LoadMap::lm_insert(LoadMap::LM* x)
{
  m_lm_byId.push_back(x);
  x->id(m_lm_byId.size() - 1); // id is the last slot used
 
  std::pair<LMSet_nm::iterator, bool> ret = m_lm_byName.insert(x);
  DIAG_Assert(ret.second, "LoadMap::lm_insert(): conflict inserting: "
	      << x->toString());
}
Пример #7
0
void
Mgr::computePartners()
{
  StringToADescMap metricsIncl;
  StringToADescMap metricsExcl;

  // -------------------------------------------------------
  // populate maps
  // -------------------------------------------------------
  for (uint i = 0; i < m_metrics.size(); ++i) {
    Metric::ADesc* m = m_metrics[i];
    string nm = m->namePfxBaseSfx();

    StringToADescMap* metricsMap = NULL;
    switch (m->type()) {
      case ADesc::TyIncl: metricsMap = &metricsIncl; break;
      case ADesc::TyExcl: metricsMap = &metricsExcl; break;
      default: break;
    }
    
    if (metricsMap) {
      DIAG_MsgIf(0, "Metric::Mgr::computePartners: insert: " << nm
		 << " [" << m->name() << "]");
      std::pair<StringToADescMap::iterator, bool> ret =
	metricsMap->insert(make_pair(nm, m));
      DIAG_Assert(ret.second, "Metric::Mgr::computePartners: Found duplicate entry inserting:\n\t" << m->toString() << "\nOther entry:\n\t" << ret.first->second->toString());
    }
  }

  // -------------------------------------------------------
  // find partners
  // -------------------------------------------------------
  for (uint i = 0; i < m_metrics.size(); ++i) {
    Metric::ADesc* m = m_metrics[i];
    string nm = m->namePfxBaseSfx();

    StringToADescMap* metricsMap = NULL;
    switch (m->type()) {
      case ADesc::TyIncl: metricsMap = &metricsExcl; break;
      case ADesc::TyExcl: metricsMap = &metricsIncl; break;
      default: break;
    }
    
    if (metricsMap) {
      StringToADescMap::iterator it = metricsMap->find(nm);
      if (it != metricsMap->end()) {
	Metric::ADesc* partner = it->second;
	m->partner(partner);
	DIAG_MsgIf(0, "Metric::Mgr::computePartners: found: "
		   << m->name() << " -> " << partner->name());
      }
    }
  }
}
Пример #8
0
void
packMetrics(const Prof::CallPath::Profile& profile,
	    ParallelAnalysis::PackedMetrics& packedMetrics)
{
  Prof::CCT::Tree& cct = *profile.cct();

  // pack derived metrics [mDrvdBeg, mDrvdEnd) from 'profile' into
  // 'packedMetrics'
  uint mDrvdBeg = packedMetrics.mDrvdBegId();
  uint mDrvdEnd = packedMetrics.mDrvdEndId();

  DIAG_Assert(packedMetrics.numNodes() == cct.maxDenseId() + 1, "");
  DIAG_Assert(packedMetrics.numMetrics() == mDrvdEnd - mDrvdBeg, "");

  for (Prof::CCT::ANodeIterator it(cct.root()); it.Current(); ++it) {
    Prof::CCT::ANode* n = it.current();
    for (uint mId1 = 0, mId2 = mDrvdBeg; mId2 < mDrvdEnd; ++mId1, ++mId2) {
      packedMetrics.idx(n->id(), mId1) = n->metric(mId2);
    }
  }
}
Пример #9
0
bool
Mgr::insertInMapsAndMakeUniqueName(Metric::ADesc* m)
{
  bool isChanged = false;

  // 1. metric name to Metric::ADescVec table
  string nm = m->name();
  StringToADescVecMap::iterator it = m_nuniqnmToMetricMap.find(nm);
  if (it != m_nuniqnmToMetricMap.end()) {
    Metric::ADescVec& mvec = it->second;

    // ensure uniqueness: qualifier is an integer >= 1
    int qualifier = mvec.size();
    const string& nm_sfx = m->nameSfx();
    string sfx_new = nm_sfx;
    if (!sfx_new.empty()) {
      sfx_new += ".";
    }
    sfx_new += StrUtil::toStr(qualifier);
    
    m->nameSfx(sfx_new);
    nm = m->name(); // update 'nm'
    isChanged = true;

    mvec.push_back(m);
  }
  else {
    m_nuniqnmToMetricMap.insert(make_pair(nm, Metric::ADescVec(1, m)));
  }

  // 2. unique name to Metric::ADesc table
  std::pair<StringToADescMap::iterator, bool> ret =
    m_uniqnmToMetricMap.insert(make_pair(nm, m));
  DIAG_Assert(ret.second, "Metric::Mgr::insertInMapsAndMakeUniqueName: Found duplicate entry inserting:\n\t" << m->toString() << "\nOther entry:\n\t" << ret.first->second->toString());

  
  // 3. profile file name to Metric::SampledDesc table
  Metric::SampledDesc* mSmpl = dynamic_cast<Metric::SampledDesc*>(m);
  if (mSmpl) {
    const string& fnm = mSmpl->profileName();
    StringToADescVecMap::iterator it1 = m_fnameToFMetricMap.find(fnm);
    if (it1 != m_fnameToFMetricMap.end()) {
      Metric::ADescVec& mvec = it1->second;
      mvec.push_back(mSmpl);
    }
    else {
      m_fnameToFMetricMap.insert(make_pair(fnm, Metric::ADescVec(1, mSmpl)));
    }
  }

  return isChanged;
}
Пример #10
0
void IteratorStack::InitTraversal(TraversalOrder torder, 
				  IterStackEnumType _enumType)
{
  clientTraversalOrder = torder;
  enumType = _enumType;
  if (enumType == ITER_STACK_ENUM_LEAVES_ONLY)
    traversalOrder = PostOrder;
  else if (torder == ReversePreOrder)
    traversalOrder = PreOrder;  // reversed by IteratorToPushIfAny
  else if (torder == ReversePostOrder)
    traversalOrder = PostOrder;  // reversed by IteratorToPushIfAny
//else if (torder == ReversePreAndPostOrder)
//  traversalOrder = PreAndPostOrder;  // reversed by IteratorToPushIfAny
  else {
    DIAG_Assert((torder == PreOrder) || (torder == PostOrder) || 
		(torder == PreAndPostOrder), "");
    traversalOrder = torder;
  }
}
Пример #11
0
double   
toDbl(const char* str, unsigned* endidx)
{
  double value = 0;
  DIAG_Assert((str && str[0] != '\0'), "StrUtil::toDbl: empty string!");
  
  errno = 0;
  char* endptr = NULL;
  value = strtod(str, &endptr);
  if (endidx) {
    *endidx = (endptr - str) / sizeof(char);
  }
  if (errno || (!endidx && endptr && strlen(endptr) > 0)) {
    string msg = "[StrUtil::toDbl] Cannot convert `" + string(str)
      + "' to real (double) value.";
    if (errno) { // not always set
      msg += string(" (") + strerror(errno) + string(")");
    }
    DIAG_Throw(msg);
  }
  return value;
}
Пример #12
0
uint64_t
toUInt64(const char* str, unsigned* endidx)
{
  uint64_t value = 0;
  DIAG_Assert((str && str[0] != '\0'), "StrUtil::toUInt64: empty string!");
  
  errno = 0;
  char* endptr = NULL;
  value = strtoull(str, &endptr, 0);
  if (endidx) {
    *endidx = (endptr - str) / sizeof(char);
  }
  if (errno || (!endidx && endptr && strlen(endptr) > 0)) {
    string msg = "[StrUtil::toUInt64] Cannot convert `" + string(str)
      + "' to integral (uint64_t) value";
    if (errno) { // not always set
      msg += string(" (") + strerror(errno) + string(")");
    }
    DIAG_Throw(msg);
  }
  return value;
}
Пример #13
0
 void InsertPC(VMA pc, ushort opIndex) {
   DIAG_Assert(pcset, "");
   VMA oppc = mset->GetISA()->convertVMAToOpVMA(pc, opIndex);
   pcset->insert(oppc); // do not add duplicates!
 }