GidLookupHelper<T, lno_t>::GidLookupHelper(
    const RCP<const Environment> &env, 
    const ArrayRCP<const T> &gidList):
    env_(env),
    gidList_(gidList), useHashTable_(false), indexMap_(), indexHash_()
{
  lno_t len = gidList_.size();

  if (len < 1)
    return;

  if (IdentifierTraits<T>::hasUniqueKey())
    useHashTable_ = true;

  const T *ids = gidList_.getRawPtr();

  if (!useHashTable_){
    try{
      for (lno_t i=0; i < gidList.size(); i++){
        typename map<T, lno_t>::iterator rec = indexMap_.find(*ids);
        if (rec == indexMap_.end())
          indexMap_[*ids] = i;
        ids++;
      }
    }
    catch (const std::exception &e){
      env_->localMemoryAssertion(__FILE__, __LINE__, len, false);
    }
  }
  else{
    typedef typename Teuchos::Hashtable<double, lno_t> id2index_hash_t;
    id2index_hash_t *p = NULL;
  
    try{
      p = new id2index_hash_t(len);
    }
    catch (const std::exception &e){
      env_->localMemoryAssertion(__FILE__, __LINE__, len, false);
    }
  
    for (lno_t i=0; i < len; i++){
      double key = IdentifierTraits<T>::key(*ids++);
      try{
        if (!p->containsKey(key))
          p->put(key, i);
      }
      Z2_THROW_OUTSIDE_ERROR(*env_);
    }

    indexHash_ = rcp<id2index_hash_t>(p);
  }
}
Example #2
0
  void globalSumsByPart( 
    const RCP<const Environment> &env,
    const RCP<const Comm<int> > &comm, 
    const ArrayView<const pnum_t> &part, 
    const ArrayView<StridedData<lno_t, scalar_t> > &vwgts,
    multiCriteriaNorm mcNorm,
    partId_t &numParts, 
    partId_t &numNonemptyParts,
    ArrayRCP<MetricValues<scalar_t> > &metrics,
    ArrayRCP<scalar_t> &globalSums)
{
  env->debug(DETAILED_STATUS, "Entering globalSumsByPart");
  //////////////////////////////////////////////////////////
  // Initialize return values

  numParts = numNonemptyParts = 0;

  int vwgtDim = vwgts.size();

  int numMetrics = 1;        // "object count"
  if (vwgts[0].size() > 0)
    numMetrics++;            // "normed weight" or "weight 1"
  if (vwgtDim > 1)
    numMetrics += vwgtDim;   // "weight n"

  typedef MetricValues<scalar_t> mv_t;
  mv_t *newMetrics = new mv_t [numMetrics];
  env->localMemoryAssertion(__FILE__, __LINE__, numMetrics, newMetrics); 
  ArrayRCP<mv_t> metricArray(newMetrics, 0, numMetrics, true);

  metrics = metricArray;

  //////////////////////////////////////////////////////////
  // Figure out the global number of parts in use.
  // Verify vertex weight dim is the same everywhere.

  lno_t localNumObj = part.size();
  partId_t localNum[2], globalNum[2];
  localNum[0] = static_cast<partId_t>(vwgtDim);  
  localNum[1] = 0;

  for (lno_t i=0; i < localNumObj; i++)
    if (part[i] > localNum[1]) localNum[1] = part[i];

  try{
    reduceAll<int, partId_t>(*comm, Teuchos::REDUCE_MAX, 2, 
      localNum, globalNum);
  }
  Z2_THROW_OUTSIDE_ERROR(*env)

  env->globalBugAssertion(__FILE__, __LINE__, "inconsistent vertex dimension",
    globalNum[0] > 0 && globalNum[0] == localNum[0], 
    DEBUG_MODE_ASSERTION, comm);

  partId_t nparts = globalNum[1] + 1;

  int globalSumSize = nparts * numMetrics;
  scalar_t * sumBuf = new scalar_t [globalSumSize];
  env->localMemoryAssertion(__FILE__, __LINE__, globalSumSize, sumBuf);
  globalSums = arcp(sumBuf, 0, globalSumSize);

  //////////////////////////////////////////////////////////
  // Calculate the local totals by part.

  scalar_t *localBuf = new scalar_t [globalSumSize];
  env->localMemoryAssertion(__FILE__, __LINE__, globalSumSize, localBuf);
  memset(localBuf, 0, sizeof(scalar_t) * globalSumSize);

  scalar_t *obj = localBuf;              // # of objects

  for (lno_t i=0; i < localNumObj; i++)
    obj[part[i]]++;

  if (numMetrics > 1){

    scalar_t *wgt = localBuf + nparts; // single normed weight
    try{
      normedPartWeights<scalar_t, pnum_t, lno_t>(env, nparts, 
        part, vwgts, mcNorm, wgt);
    }
    Z2_FORWARD_EXCEPTIONS
  
//KDDKDD TODO  This code assumes the solution has the part ordered the
//KDDKDD TODO  same way as the user input.  That assumption is not
//KDDKDD TODO  currently true, although we plan to make it true.
//KDDKDD TODO  As a results, currently the weight metrics may be wrong.
//KDDKDD TODO  See bug 5891.  April 5, 2013
    if (vwgtDim > 1){
      wgt += nparts;         // individual weights
      for (int vdim = 0; vdim < vwgtDim; vdim++){
        if (vwgts[vdim].size()){
         for (lno_t i=0; i < localNumObj; i++)
           wgt[part[i]] += vwgts[vdim][i];
        }
        else{  // uniform weights
          for (int p=0; p < nparts; p++)
            wgt[p] = obj[p];
        }
        wgt += nparts;
      }
    }
  }