コード例 #1
0
 //NOTE: weights are not handled nicely.
 //weight should be done carefully, not valid for DMC
 //will add a function to MCWalkerConfiguration to track total weight
 void EstimatorManager::accumulate(MCWalkerConfiguration& W)
 {
   BlockWeight += W.getActiveWalkers();
   RealType norm=1.0/W.getGlobalNumWalkers();
   for(int i=0; i< Estimators.size(); i++) 
     Estimators[i]->accumulate(W,W.begin(),W.end(),norm);
 }
コード例 #2
0
  int WalkerControlBase::branch(int iter, MCWalkerConfiguration& W, RealType trigger) {

    int prefill_numwalkers = sortWalkers(W);

    measureProperties(iter);
    W.EnsembleProperty=EnsembleProperty;

    //un-biased variance but we use the saimple one
    //W.EnsembleProperty.Variance=(e2sum*wsum-esum*esum)/(wsum*wsum-w2sum);

    ////add to the accumData for block average: REMOVE THIS
    //accumData[ENERGY_INDEX]     += curData[ENERGY_INDEX]*wgtInv;
    //accumData[ENERGY_SQ_INDEX]  += curData[ENERGY_SQ_INDEX]*wgtInv;
    //accumData[WALKERSIZE_INDEX] += curData[WALKERSIZE_INDEX];
    //accumData[WEIGHT_INDEX]     += curData[WEIGHT_INDEX];

    int nw_tot = copyWalkers(W);

    //set Weight and Multiplicity to default values
    MCWalkerConfiguration::iterator it(W.begin()),it_end(W.end());
    while(it != it_end) {
      (*it)->Weight= 1.0;
      (*it)->Multiplicity=1.0;
      ++it;
    }

    //set the global number of walkers
    W.setGlobalNumWalkers(nw_tot);

    return prefill_numwalkers;
  }
コード例 #3
0
/** accumulate Local energies and collectables
 * @param W ensemble
 */
void EstimatorManager::accumulate(MCWalkerConfiguration& W)
{
  BlockWeight += W.getActiveWalkers();
  RealType norm=1.0/W.getGlobalNumWalkers();
  for(int i=0; i< Estimators.size(); i++)
    Estimators[i]->accumulate(W,W.begin(),W.end(),norm);
  if(Collectables)//collectables are normalized by QMC drivers
    Collectables->accumulate_all(W.Collectables,1.0);
}
コード例 #4
0
/**  Write the set of walker configurations to the HDF5 file.  
 *@param W set of walker configurations
 *@param ic the number of frames
 *
 * \if ic==-1
 *  use only the last frame for a restart
 * \else if ic>=0
 *  use ic frames from the file for opitimizations
 */
bool  
HDFWalkerInput0::put(MCWalkerConfiguration& W, int ic){

  if(Counter<0) return false;

  int selected = ic;
  if(ic<0) {
    XMLReport("Will use the last set from " << NumSets << " of configurations.")
    selected = NumSets-1;
  }

  typedef MCWalkerConfiguration::PosType PosType;
  typedef MCWalkerConfiguration::PropertyContainer_t ProtertyContainer_t;

  typedef Matrix<PosType>  PosContainer_t;

  int nwt = 0;
  int npt = 0;
  //2D array of PosTypes (x,y,z) indexed by (walker,particle)
  PosContainer_t Pos_temp;

  //open the group
  char GrpName[128];
  sprintf(GrpName,"config%04d",selected);
  hid_t group_id = H5Gopen(h_config,GrpName);
    
  HDFAttribIO<PosContainer_t> Pos_in(Pos_temp);
  //read the dataset
  Pos_in.read(group_id,"coord");
  //close the group
  H5Gclose(group_id);

  /*check to see if the number of walkers and particles is  consistent with W */
  int nptcl = Pos_temp.cols();
  nwt = Pos_temp.rows();

  int curWalker = W.getActiveWalkers();
  if(curWalker) {
    LOGMSG("Adding " << nwt << " walkers to " << curWalker)
    W.createWalkers(nwt);
  } else {
    W.resize(nwt,nptcl); 
  }

  //assign configurations to W
  int iw=0;
  MCWalkerConfiguration::iterator it = W.begin()+curWalker; 
  MCWalkerConfiguration::iterator it_end = W.end(); 
  while(it != it_end) {
    std::copy(Pos_temp[iw],Pos_temp[iw+1], (*it)->R.begin());
    ++it;++iw;
  }

  return true;
}
コード例 #5
0
int 
WalkerControlMPI::branch(int iter, MCWalkerConfiguration& W, RealType trigger) {

  std::fill(curData.begin(),curData.end(),0);
  //std::fill(NumPerNode.begin(),NumPerNode.end(),0);
  sortWalkers(W);

  //update the number of walkers for this node
  curData[LE_MAX+MyContext]=NumWalkers;

  int nw = copyWalkers(W);

  myComm->allreduce(curData);

  RealType wgtInv(1.0/curData[WEIGHT_INDEX]);
  accumData[ENERGY_INDEX]     += curData[ENERGY_INDEX]*wgtInv;
  accumData[ENERGY_SQ_INDEX]  += curData[ENERGY_SQ_INDEX]*wgtInv;
  accumData[WALKERSIZE_INDEX] += curData[WALKERSIZE_INDEX];
  accumData[WEIGHT_INDEX]     += curData[WEIGHT_INDEX];

  Cur_pop=0;
  for(int i=0, j=LE_MAX; i<NumContexts; i++,j++) {
    Cur_pop+= NumPerNode[i]=static_cast<int>(curData[j]);
  }

  swapWalkersSimple(W); 

  //Do not need to use a trigger.
  //Cur_min=Nmax; 
  //Cur_max=0; 
  //Cur_pop=0;
  //for(int i=0, j=LE_MAX; i<NumContexts; i++,j++) {
  //  Cur_pop+= NumPerNode[i]=static_cast<int>(curData[j]);
  //  Cur_min = std::min(Cur_min,NumPerNode[i]);
  //  Cur_max = std::max(Cur_max,NumPerNode[i]);
  //}
  //int max_diff = std::max(Cur_max*NumContexts-Cur_pop,Cur_pop-Cur_min*NumContexts);
  //double diff_pop = static_cast<double>(max_diff)/static_cast<double>(Cur_pop);
  //if(diff_pop > trigger) { 
  //  swapWalkersSimple(W); 
  //  //swapWalkersMap(W); 
  //}

  //set Weight and Multiplicity to default values
  MCWalkerConfiguration::iterator it(W.begin()),it_end(W.end());
  while(it != it_end) {
    (*it)->Weight= 1.0;
    (*it)->Multiplicity=1.0;
    ++it;
  }

  //update the global number of walkers
  W.setGlobalNumWalkers(Cur_pop);
  return Cur_pop;
}
コード例 #6
0
/**
   @brief accumulate data for all the estimators
*/
void 
ScalarEstimatorManager::accumulate(const MCWalkerConfiguration& W) {

  for(MCWalkerConfiguration::const_iterator it = W.begin(); 
      it != W.end(); it++){    
    RealType wgt = (*it)->Properties(WEIGHT);
    WeightSum += wgt;
    for(int i=0; i< Estimators.size(); i++) 
      Estimators[i]->accumulate(**it,wgt);
  }
}
コード例 #7
0
 void WalkerControlBase::setWalkerID(MCWalkerConfiguration& walkers)
 {
   start(); //do the normal start
   MCWalkerConfiguration::iterator wit(walkers.begin());
   MCWalkerConfiguration::iterator wit_end(walkers.end());
   for(; wit != wit_end; ++wit)
   {
     if((*wit)->ID==0) 
     {
       (*wit)->ID=(++NumWalkersCreated)*NumContexts+MyContext;
       (*wit)->ParentID=(*wit)->ID;
     }
   }
 }
コード例 #8
0
/** accumulate data for all the estimators
 */
void 
ScalarEstimatorManager::accumulate(const MCWalkerConfiguration& W) {

  RealType wgt_sum=0;
  MCWalkerConfiguration::const_iterator it(W.begin()),it_end(W.end());
  while(it != it_end) {
    RealType wgt = (*it)->Weight;
    wgt_sum+= wgt;
    for(int i=0; i< Estimators.size(); i++) Estimators[i]->accumulate(**it,wgt);
    ++it;
  }

  MyData[WEIGHT_INDEX]+=wgt_sum;
}
コード例 #9
0
 void EstimatorManager::getCurrentStatistics(MCWalkerConfiguration& W
     , RealType& eavg, RealType& var)
 {
   LocalEnergyOnlyEstimator energynow;
   energynow.clear();
   energynow.accumulate(W,W.begin(),W.end(),1.0);
   vector<RealType> tmp(3);
   tmp[0]= energynow.scalars[0].result();
   tmp[1]= energynow.scalars[0].result2();
   tmp[2]= energynow.scalars[0].count();
   myComm->allreduce(tmp);
   eavg=tmp[0]/tmp[2];
   var=tmp[1]/tmp[2]-eavg*eavg;
 }
コード例 #10
0
 void Write2XYZ(MCWalkerConfiguration& W)
 {
   ofstream fout("bad.xyz");
   MCWalkerConfiguration::iterator it(W.begin());
   MCWalkerConfiguration::iterator it_end(W.end());
   int nptcls(W.getTotalNum());
   while(it != it_end) {
     fout << nptcls << endl 
       << "# E = " << (*it)->Properties(LOCALENERGY) 
       << " Wgt= " << (*it)->Weight << endl;
     for(int i=0; i<nptcls; i++)
       fout << "H " << (*it)->R[i] << endl;
     ++it;
   }
 }
コード例 #11
0
int WalkerControlBase::doNotBranch(int iter, MCWalkerConfiguration& W)
{
    MCWalkerConfiguration::iterator it(W.begin());
    MCWalkerConfiguration::iterator it_end(W.end());
    RealType esum=0.0,e2sum=0.0,wsum=0.0,ecum=0.0, w2sum=0.0;
    RealType r2_accepted=0.0,r2_proposed=0.0;
    for(; it!=it_end; ++it)
    {
        r2_accepted+=(*it)->Properties(R2ACCEPTED);
        r2_proposed+=(*it)->Properties(R2PROPOSED);
        RealType e((*it)->Properties(LOCALENERGY));
        int nc= std::min(static_cast<int>((*it)->Multiplicity),MaxCopy);
        RealType wgt((*it)->Weight);
        esum += wgt*e;
        e2sum += wgt*e*e;
        wsum += wgt;
        w2sum += wgt*wgt;
        ecum += e;
    }

    //temp is an array to perform reduction operations
    std::fill(curData.begin(),curData.end(),0);

    curData[ENERGY_INDEX]=esum;
    curData[ENERGY_SQ_INDEX]=e2sum;
    curData[WALKERSIZE_INDEX]=W.getActiveWalkers();
    curData[WEIGHT_INDEX]=wsum;
    curData[EREF_INDEX]=ecum;
    curData[R2ACCEPTED_INDEX]=r2_accepted;
    curData[R2PROPOSED_INDEX]=r2_proposed;

    myComm->allreduce(curData);

    measureProperties(iter);
    trialEnergy=EnsembleProperty.Energy;
    W.EnsembleProperty=EnsembleProperty;

    //return the current data
    return W.getGlobalNumWalkers();
}
コード例 #12
0
int 
WalkerReconfigurationMPI::branch(int iter, MCWalkerConfiguration& W, RealType trigger) {

  int nwkept = swapWalkers(W);

  RealType wgtInv(1.0/curData[WEIGHT_INDEX]);
  accumData[ENERGY_INDEX]     += curData[ENERGY_INDEX]*wgtInv;
  accumData[ENERGY_SQ_INDEX]  += curData[ENERGY_SQ_INDEX]*wgtInv;
  accumData[WALKERSIZE_INDEX] += nwkept;
  //accumData[WALKERSIZE_INDEX] += curData[WALKERSIZE_INDEX];
  accumData[WEIGHT_INDEX]     += curData[WEIGHT_INDEX];

  //set Weight and Multiplicity to default values
  MCWalkerConfiguration::iterator it(W.begin()),it_end(W.end());
  while(it != it_end) {
    (*it)->Weight= 1.0;
    (*it)->Multiplicity=1.0;
    ++it;
  }

  return nwkept;
}
コード例 #13
0
int 
GlobalWalkerControl::branch(int iter, MCWalkerConfiguration& W, RealType trigger) {

  std::fill(NumPerNode.begin(),NumPerNode.end(),0);

  sortWalkers(W);

  NumPerNode[MyContext] = NumWalkers;

  int nw = copyWalkers(W);

  //wait until everynode comes here
  OHMMS::Controller->barrier();
  gsum(NumPerNode,0);

  Cur_min=Nmax; Cur_max=0; Cur_pop=0;
  for(int i=0; i<NumContexts; i++) {
    Cur_pop+= NumPerNode[i];
    Cur_min = std::min(Cur_min,NumPerNode[i]);
    Cur_max = std::max(Cur_max,NumPerNode[i]);
  }

  int max_diff = std::max(Cur_max*NumContexts-Cur_pop,Cur_pop-Cur_min*NumContexts);
  double diff_pop = static_cast<double>(max_diff)/static_cast<double>(Cur_pop);

  if(diff_pop > trigger) { swapWalkersMap(W); }

  //set Weight and Multiplicity to default values
  MCWalkerConfiguration::iterator it(W.begin()),it_end(W.end());
  while(it != it_end) {
    (*it)->Weight= 1.0;
    (*it)->Multiplicity=1.0;
    ++it;
  }

  return Cur_pop;
}
コード例 #14
0
  /** evaluate curData and mark the bad/good walkers
   */
  int WalkerControlBase::sortWalkers(MCWalkerConfiguration& W) {

    MCWalkerConfiguration::iterator it(W.begin());

    vector<Walker_t*> bad,good_rn;
    vector<int> ncopy_rn;
    NumWalkers=0;
    MCWalkerConfiguration::iterator it_end(W.end());
    RealType esum=0.0,e2sum=0.0,wsum=0.0,ecum=0.0, w2sum=0.0, besum=0.0, bwgtsum=0.0;
    RealType r2_accepted=0.0,r2_proposed=0.0;
    int nrn(0),ncr(0);
    while(it != it_end) 
    {
      bool inFN=(((*it)->ReleasedNodeAge)==0);
      if ((*it)->ReleasedNodeAge==1) ncr+=1;
      int nc= std::min(static_cast<int>((*it)->Multiplicity),MaxCopy);
      r2_accepted+=(*it)->Properties(R2ACCEPTED);
      r2_proposed+=(*it)->Properties(R2PROPOSED);
      RealType e((*it)->Properties(LOCALENERGY));
      RealType bfe((*it)->Properties(ALTERNATEENERGY));
      RealType rnwgt(0.0);
      if (inFN)
        rnwgt=((*it)->Properties(SIGN));
      
//       RealType wgt((*it)->Weight);
      RealType wgt(0.0);
      if (inFN)
        wgt=((*it)->Weight); 
      
      esum += wgt*e;
      e2sum += wgt*e*e;
      wsum += wgt;
      w2sum += wgt*wgt;
      ecum += e;
      besum += bfe*rnwgt*wgt;
      bwgtsum += rnwgt*wgt;

      if((nc) && (inFN))
      {
        NumWalkers += nc;
        good_w.push_back(*it);
        ncopy_w.push_back(nc-1);
      }
      else if (nc)
      {
        NumWalkers += nc;
        nrn+=nc;
        good_rn.push_back(*it);
        ncopy_rn.push_back(nc-1);
      }
      else
      {
        bad.push_back(*it);
      }
      ++it;
    }

    //temp is an array to perform reduction operations
    std::fill(curData.begin(),curData.end(),0);

    //update curData
    curData[ENERGY_INDEX]=esum;
    curData[ENERGY_SQ_INDEX]=e2sum;
    curData[WALKERSIZE_INDEX]=W.getActiveWalkers();
    curData[WEIGHT_INDEX]=wsum;
    curData[EREF_INDEX]=ecum;
    curData[R2ACCEPTED_INDEX]=r2_accepted;
    curData[R2PROPOSED_INDEX]=r2_proposed;
    curData[FNSIZE_INDEX]=static_cast<RealType>(good_w.size());
    curData[RNONESIZE_INDEX]=static_cast<RealType>(ncr);
    curData[RNSIZE_INDEX]=nrn;
    curData[B_ENERGY_INDEX]=besum;
    curData[B_WGT_INDEX]=bwgtsum;
    
    ////this should be move
    //W.EnsembleProperty.NumSamples=curData[WALKERSIZE_INDEX];
    //W.EnsembleProperty.Weight=curData[WEIGHT_INDEX];
    //W.EnsembleProperty.Energy=(esum/=wsum);
    //W.EnsembleProperty.Variance=(e2sum/wsum-esum*esum);
    //W.EnsembleProperty.Variance=(e2sum*wsum-esum*esum)/(wsum*wsum-w2sum);

    //remove bad walkers empty the container
    for(int i=0; i<bad.size(); i++) delete bad[i];
    if (!WriteRN)
    {
     if(good_w.empty()) {
      app_error() << "All the walkers have died. Abort. " << endl;
      APP_ABORT("WalkerControlBase::sortWalkers");
     }

     int sizeofgood = good_w.size();
     //check if the projected number of walkers is too small or too large
     if(NumWalkers>Nmax) {
      int nsub=0;
      int nsub_target=(NumWalkers-nrn)-static_cast<int>(0.9*Nmax);
      int i=0;
      while(i< sizeofgood && nsub<nsub_target) {
        if(ncopy_w[i]) {ncopy_w[i]--; nsub++;}
        ++i;
      }
      NumWalkers -= nsub;
     } else  if(NumWalkers < Nmin) {
      int nadd=0;
      int nadd_target = static_cast<int>(Nmin*1.1)-(NumWalkers-nrn);
      if(nadd_target> sizeofgood) {
        app_warning() << "The number of walkers is running low. Requested walkers " 
          << nadd_target << " good walkers = " << sizeofgood << endl;
      }
      int i=0;
      while(i< sizeofgood && nadd<nadd_target) {
        ncopy_w[i]++; ++nadd;++i;
      }
      NumWalkers +=  nadd;
     }
    }
    else
    {
    it=good_rn.begin(); it_end=good_rn.end();
    int indy(0);
    while(it!=it_end) {
      good_w.push_back(*it);
      ncopy_w.push_back(ncopy_rn[indy]);
      it++,indy++;
    }
    }
    return NumWalkers;
  }
コード例 #15
0
  int WalkerControlBase::doNotBranch(int iter, MCWalkerConfiguration& W)
  {
    MCWalkerConfiguration::iterator it(W.begin());
    MCWalkerConfiguration::iterator it_end(W.end());
    RealType esum=0.0,e2sum=0.0,wsum=0.0,ecum=0.0, w2sum=0.0, besum=0.0, bwgtsum=0.0;
    RealType r2_accepted=0.0,r2_proposed=0.0;
    int nrn(0),ncr(0),nfn(0),ngoodfn(0);
    for(; it!=it_end;++it)
    {
      bool inFN=(((*it)->ReleasedNodeAge)==0);
      int nc= std::min(static_cast<int>((*it)->Multiplicity),MaxCopy);
      
      if ((*it)->ReleasedNodeAge==1) ncr+=1;
      else if ((*it)->ReleasedNodeAge==0) 
      {
        nfn+=1;
        ngoodfn+=nc;
      }
      
      r2_accepted+=(*it)->Properties(R2ACCEPTED);
      r2_proposed+=(*it)->Properties(R2PROPOSED);
      RealType e((*it)->Properties(LOCALENERGY));
      RealType bfe((*it)->Properties(ALTERNATEENERGY));
      RealType rnwgt(0.0);
      if (inFN)
        rnwgt=((*it)->Properties(SIGN));
      else
        nrn+=nc;
      //       RealType wgt((*it)->Weight);
      RealType wgt(0.0);
      if (inFN)
        wgt=((*it)->Weight); 
      
      esum += wgt*e;
      e2sum += wgt*e*e;
      wsum += wgt;
      w2sum += wgt*wgt;
      ecum += e;
      besum += bfe*rnwgt*wgt;
      bwgtsum += rnwgt*wgt;
    }

    //temp is an array to perform reduction operations
    std::fill(curData.begin(),curData.end(),0);

    curData[ENERGY_INDEX]=esum;
    curData[ENERGY_SQ_INDEX]=e2sum;
    curData[WALKERSIZE_INDEX]=W.getActiveWalkers();
    curData[WEIGHT_INDEX]=wsum;
    curData[EREF_INDEX]=ecum;
    curData[R2ACCEPTED_INDEX]=r2_accepted;
    curData[R2PROPOSED_INDEX]=r2_proposed;
    curData[FNSIZE_INDEX]=static_cast<RealType>(nfn);
    curData[RNONESIZE_INDEX]=static_cast<RealType>(ncr);
    curData[RNSIZE_INDEX]=nrn;
    curData[B_ENERGY_INDEX]=besum;
    curData[B_WGT_INDEX]=bwgtsum;

    myComm->allreduce(curData);

    measureProperties(iter);
    trialEnergy=EnsembleProperty.Energy;
    W.EnsembleProperty=EnsembleProperty;

    return W.getActiveWalkers();
  }
コード例 #16
0
/** evaluate curData and mark the bad/good walkers
 */
void WalkerControlBase::sortWalkers(MCWalkerConfiguration& W) {

    MCWalkerConfiguration::iterator it(W.begin());

    vector<Walker_t*> bad;
    NumWalkers=0;
    MCWalkerConfiguration::iterator it_end(W.end());
    RealType esum=0.0,e2sum=0.0,wsum=0.0,ecum=0.0, w2sum=0.0;
    RealType r2_accepted=0.0,r2_proposed=0.0;
    //RealType sigma=std::max(5.0*targetVar,targetEnergyBound);
    //RealType ebar= targetAvg;
    while(it != it_end)
    {
        r2_accepted+=(*it)->Properties(R2ACCEPTED);
        r2_proposed+=(*it)->Properties(R2PROPOSED);
        RealType e((*it)->Properties(LOCALENERGY));
        int nc= std::min(static_cast<int>((*it)->Multiplicity),MaxCopy);
        /// HACK HACK HACK
        //RealType wgt((*it)->Weight);
        RealType wgt = (RealType)nc;

        esum += wgt*e;
        e2sum += wgt*e*e;
        wsum += wgt;
        w2sum += wgt*wgt;
        ecum += e;

        if(nc)
        {
            NumWalkers += nc;
            good_w.push_back(*it);
            ncopy_w.push_back(nc-1);
        } else {
            bad.push_back(*it);
        }
        ++it;
    }

    //temp is an array to perform reduction operations
    std::fill(curData.begin(),curData.end(),0);

    //evaluate variance of this block
    //curVar=(e2sum-esum*esum/wsum)/wsum;
    //THIS IS NOT USED ANYMORE:BELOW
    //if(curVar>sigma) {
    //  app_error() << "Unphysical block variance is detected. Stop simulations." << endl;
    //  Write2XYZ(W);
    //  //Does not work some reason
    //  //OHMMS::Controller->abort();
    //#if defined(HAVE_MPI)
    //      OOMPI_COMM_WORLD.Abort();
    //#else
    //      abort();
    //#endif
    //    }
    //THIS IS NOT USED ANYMORE:ABOVE

    //update curData
    curData[ENERGY_INDEX]=esum;
    curData[ENERGY_SQ_INDEX]=e2sum;
    curData[WALKERSIZE_INDEX]=W.getActiveWalkers();
    curData[WEIGHT_INDEX]=wsum;
    curData[EREF_INDEX]=ecum;
    curData[R2ACCEPTED_INDEX]=r2_accepted;
    curData[R2PROPOSED_INDEX]=r2_proposed;

    ////this should be move
    //W.EnsembleProperty.NumSamples=curData[WALKERSIZE_INDEX];
    //W.EnsembleProperty.Weight=curData[WEIGHT_INDEX];
    //W.EnsembleProperty.Energy=(esum/=wsum);
    //W.EnsembleProperty.Variance=(e2sum/wsum-esum*esum);
    //W.EnsembleProperty.Variance=(e2sum*wsum-esum*esum)/(wsum*wsum-w2sum);

    //remove bad walkers empty the container
    for(int i=0; i<bad.size(); i++) delete bad[i];

    if(good_w.empty()) {
        app_error() << "All the walkers have died. Abort. " << endl;
        APP_ABORT("WalkerControlBase::sortWalkers");
    }

    int sizeofgood = good_w.size();

    //check if the projected number of walkers is too small or too
    //large
    if(NumWalkers>Nmax) {
        int nsub=0;
        int nsub_target=NumWalkers-static_cast<int>(0.9*Nmax);
        int i=0;
        while(i< sizeofgood && nsub<nsub_target) {
            if(ncopy_w[i]) {
                ncopy_w[i]--;
                nsub++;
            }
            ++i;
        }
        NumWalkers -= nsub;
    } else  if(NumWalkers < Nmin) {
        int nadd=0;
        int nadd_target = static_cast<int>(Nmin*1.1)-NumWalkers;
        if(nadd_target> sizeofgood) {
            app_warning() << "The number of walkers is running low. Requested walkers "
                          << nadd_target << " good walkers = " << sizeofgood << endl;
        }
        int i=0;
        while(i< sizeofgood && nadd<nadd_target) {
            ncopy_w[i]++;
            ++nadd;
            ++i;
        }
        NumWalkers +=  nadd;
    }
}
コード例 #17
0
 /** accumulate data over walkers
  * @param W MCWalkerConfiguration
  * @param wgt weight
  */
 void CompositeEstimatorSet::accumulate(MCWalkerConfiguration& W, RealType wgtnorm) 
 {
   accumulate(W,W.begin(),W.end(),wgtnorm);
 }
コード例 #18
0
/** swap Walkers with Recv/Send 
 *
 * The algorithm ensures that the load per node can differ only by one walker.
 * The communication is one-dimensional. 
 */
void GlobalWalkerControl::swapWalkersBlocked(MCWalkerConfiguration& W) {
  NumSwaps++;

  OffSet[0]=0;
  for(int i=0; i<NumContexts; i++) OffSet[i+1]=OffSet[i]+NumPerNode[i];
  FairPartition(Cur_pop,NumContexts,FairOffSet);

  int toLeft=FairOffSet[MyContext]-OffSet[MyContext];
  int toRight=FairOffSet[MyContext+1]-OffSet[MyContext+1];

  Walker_t& wRef(*W[0]);

  vector<Walker_t*> newW;

  int num_deleted=0;
  int last=NumPerNode[MyContext]-1;
  //scehdule irecv
  if(toLeft<0) { // recv from node-1 
    int dn=-toLeft;
    OOMPI_Packed recvBuffer(dn*wRef.byteSize(),OOMPI_COMM_WORLD);
    OOMPI_COMM_WORLD[MyContext-1].Recv(recvBuffer);
    while(dn) {
      Walker_t *awalker= new Walker_t(wRef);
      awalker->getMessage(recvBuffer);
      newW.push_back(awalker);
      --dn;
    }
  } else if(toLeft>0) { //send to node-1
    int dn=toLeft;
    num_deleted+=dn;
    OOMPI_Packed sendBuffer(dn*wRef.byteSize(),OOMPI_COMM_WORLD);
    while(dn) {
      W[last]->putMessage(sendBuffer); --dn; --last;
    }
    OOMPI_COMM_WORLD[MyContext-1].Send(sendBuffer);
  }

  if(toRight<0) { // send to node+1
    int dn=-toRight;
    num_deleted+=dn;
    OOMPI_Packed sendBuffer(dn*wRef.byteSize(),OOMPI_COMM_WORLD);
    while(dn) {
      W[last]->putMessage(sendBuffer); --dn; --last;
    }
    OOMPI_COMM_WORLD[MyContext+1].Send(sendBuffer);
  } else if(toRight>0) { //recv from node+1
    OOMPI_Packed recvBuffer(toRight*wRef.byteSize(),OOMPI_COMM_WORLD);
    OOMPI_COMM_WORLD[MyContext+1].Recv(recvBuffer);
    int dn=toRight;
    while(dn) {
      Walker_t *awalker= new Walker_t(wRef);
      awalker->getMessage(recvBuffer);
      newW.push_back(awalker);
      --dn;
    }
  }

  while(num_deleted>0) {
    W.pop_back(); --num_deleted;
  }

  if(newW.size()) W.insert(W.end(),newW.begin(),newW.end());
}
コード例 #19
0
int WalkerReconfigurationMPI::swapWalkers(MCWalkerConfiguration& W) {
  //ostringstream o;
  //o << "check." << MyContext << ".dat";
  //ofstream fout(o.str().c_str(),ios::app);

  int nw=W.getActiveWalkers();
  if(TotalWalkers ==0) {
    FirstWalker=nw*MyContext;
    LastWalker=FirstWalker+nw;
    TotalWalkers = nw*NumContexts;
    nwInv = 1.0/static_cast<RealType>(TotalWalkers);
    DeltaStep = UnitZeta*nwInv;

    ncopy_w.resize(nw);
    wConf.resize(nw);
    //wSum.resize(NumContexts);
    wOffset.resize(NumContexts+1);
    dN.resize(NumContexts+1);
  }

  //std::fill(wSum.begin(),wSum.end(),0.0);

  MCWalkerConfiguration::iterator it(W.begin()), it_end(W.end());
  int iw=0;
  RealType esum=0.0,e2sum=0.0,wtot=0.0,ecum=0.0;
  while(it != it_end) {
    RealType wgt((*it)->Weight);
    RealType e((*it)->Properties(LOCALENERGY));
    esum += wgt*e;
    e2sum += wgt*e*e;
    wtot += wgt;
    ecum += e;
    wConf[iw++]=wgt;
    ++it;
  }
  //wSum[MyContext]=wtot;
  curData[ENERGY_INDEX]=esum;
  curData[ENERGY_SQ_INDEX]=e2sum;
  curData[WALKERSIZE_INDEX]=nw;
  curData[WEIGHT_INDEX]=wtot;
  curData[EREF_INDEX]=ecum;
  std::fill(curData.begin()+LE_MAX,curData.end(),0.0);
  curData[LE_MAX+MyContext]=wtot;

  //collect everything
  myComm->allreduce(curData);

  //wOffset[ip] is the partial sum update to ip
  wOffset[0]=0;
  //for(int ip=0; ip<NumContexts; ip++) wOffset[ip+1]=wOffset[ip]+wSum[ip];
  for(int ip=0,jp=LE_MAX; ip<NumContexts; ip++,jp++) 
    wOffset[ip+1]=wOffset[ip]+curData[jp];

  wtot=wOffset[NumContexts]; //wtot is the total weight

  //find the lower and upper bound of index
  int minIndex=static_cast<int>((wOffset[MyContext]/wtot-DeltaStep)*static_cast<RealType>(TotalWalkers))-1;
  int maxIndex=static_cast<int>((wOffset[MyContext+1]/wtot-DeltaStep)*static_cast<RealType>(TotalWalkers))+1;
  int nb=maxIndex-minIndex+1;
  vector<RealType> Zeta(nb);

  for(int i=minIndex, ii=0; i<maxIndex; i++,ii++) {
    Zeta[ii]= wtot*(DeltaStep+static_cast<RealType>(i)*nwInv);
  }

  RealType wCur=wOffset[MyContext];
  int ind=0;
  while(Zeta[ind]<wCur) {ind++;} 

  //surviving walkers
  int icdiff=0;
  for(iw=0; iw<nw; iw++) {
    RealType tryp=wCur+abs(wConf[iw]);
    int ni=0;
    while(Zeta[ind]<tryp && Zeta[ind] >= wCur) {
      ind++;
      ni++;
    }
    wCur+=abs(wConf[iw]);
    if(ni) {
      icdiff++;
    } 
    ncopy_w[iw]=ni;
  }

  vector<int> plus, minus;
  for(iw=0;iw<nw; iw++) {
    int m=ncopy_w[iw];
    if(m>1) {// add the index of this walker to plus, duplicate m-1 times
      plus.insert(plus.end(),m-1,iw);
    } else if(m==0) { // add the walker index to be killed/overwritten
      minus.push_back(iw);
    }
  }

  //copy within the local node
  int lower=std::min(plus.size(),minus.size()); 
  while(lower>0) {
    --lower;
    W[minus[lower]]->assign(*(W[plus[lower]]));
    minus.pop_back();
    plus.pop_back();
  }


  //dN[ip] extra/missing walkers
  //dN[NumContexts] contains the number of surviving walkers
  std::fill(dN.begin(),dN.end(),0);
  dN[NumContexts]=icdiff;
  if(plus.size()) { dN[MyContext]=plus.size();}
  if(minus.size()) { dN[MyContext]=-minus.size();}

  //collect the data
  myComm->allreduce(dN);

  if(plus.size()) sendWalkers(W,plus);
  if(minus.size()) recvWalkers(W,minus);

  //vector<int> minusN, plusN;
  //bool tosend=false, torecv=false;
  //for(int ip=0; ip<NumContexts; ip++) {
  //  if(dN[ip]>0) {
  //    plusN.insert(plusN.end(),dN[ip],ip);
  //    tosend=true;
  //  } else if(dN[ip]<0) {
  //    minusN.insert(minusN.end(),-dN[ip],ip);
  //    torecv=true;
  //  }
  //}

  //int wbuffer_size=W[0]->byteSize();

  //int nswap=plusN.size();
  //int last = abs(dN[MyContext])-1;
  //int ic=0;
  //while(ic<nswap && last>=0) {
  //  if(plusN[ic]==MyContext) {
  //    OOMPI_Packed sendBuffer(wbuffer_size,OOMPI_COMM_WORLD);
  //    W[plus[last]]->putMessage(sendBuffer);
  //    OOMPI_COMM_WORLD[minusN[ic]].Send(sendBuffer);
  //    --last; 
  //  } 
  //  if(minusN[ic]==MyContext) {
  //    OOMPI_Packed recvBuffer(wbuffer_size,OOMPI_COMM_WORLD);
  //    OOMPI_COMM_WORLD[plusN[ic]].Recv(recvBuffer);
  //    W[minus[last]]->getMessage(recvBuffer);
  //    --last;
  //  }
  //  ++ic;
  //}

  //collect surviving walkers
  return dN[NumContexts];
}
コード例 #20
0
/** swap Walkers with Recv/Send 
 *
 * The algorithm ensures that the load per node can differ only by one walker.
 * The communication is one-dimensional. 
 */
void WalkerControlMPI::swapWalkersSimple(MCWalkerConfiguration& W) {

  NumSwaps++;
  FairDivideLow(Cur_pop,NumContexts,FairOffSet);
  vector<int> minus, plus;
  int deltaN;
  for(int ip=0; ip<NumContexts; ip++) {
    int dn=NumPerNode[ip]-(FairOffSet[ip+1]-FairOffSet[ip]);
    if(ip == MyContext) deltaN=dn;
    if(dn>0) {
      plus.insert(plus.end(),dn,ip); 
    } else if(dn<0){
      minus.insert(minus.end(),-dn,ip); 
    }
  }

  Walker_t& wRef(*W[0]);
  vector<Walker_t*> newW;
  vector<Walker_t*> oldW; 

#ifdef MCWALKERSET_MPI_DEBUG
  char fname[128];
  sprintf(fname,"test.%d",MyContext);
  ofstream fout(fname, ios::app);
  //fout << NumSwaps << " " << Cur_pop << " ";
  //for(int ic=0; ic<NumContexts; ic++) fout << NumPerNode[ic] << " ";
  //fout << " | ";
  //for(int ic=0; ic<NumContexts; ic++) fout << FairOffSet[ic+1]-FairOffSet[ic] << " ";
  //fout << " | ";
  for(int ic=0; ic<plus.size(); ic++) {
    fout << plus[ic] << " ";
  }
  fout << " | ";
  for(int ic=0; ic<minus.size(); ic++) {
    fout << minus[ic] << " ";
  }
  fout << endl;
#endif

  int nswap=std::min(plus.size(), minus.size());
  int last=W.getActiveWalkers()-1;
  int nsend=0;
  for(int ic=0; ic<nswap; ic++) {
    if(plus[ic]==MyContext) {
      //OOMPI_Packed sendBuffer(wRef.byteSize(),OOMPI_COMM_WORLD);
      OOMPI_Packed sendBuffer(wRef.byteSize(),myComm->getComm());
      W[last]->putMessage(sendBuffer);
      //OOMPI_COMM_WORLD[minus[ic]].Send(sendBuffer);
      myComm->getComm()[minus[ic]].Send(sendBuffer);
      --last; ++nsend;
    }
    if(minus[ic]==MyContext) {
      //OOMPI_Packed recvBuffer(wRef.byteSize(),OOMPI_COMM_WORLD);
      OOMPI_Packed recvBuffer(wRef.byteSize(),myComm->getComm());
      //OOMPI_COMM_WORLD[plus[ic]].Recv(recvBuffer);
      myComm->getComm()[plus[ic]].Recv(recvBuffer);
      Walker_t *awalker= new Walker_t(wRef);
      awalker->getMessage(recvBuffer);
      newW.push_back(awalker);
    }
  }

  if(nsend) {
    nsend=NumPerNode[MyContext]-nsend;
    W.destroyWalkers(W.begin()+nsend, W.end());
  }

  //add walkers from other node
  if(newW.size()) W.insert(W.end(),newW.begin(),newW.end());
}
コード例 #21
0
  // old ones
  void 
    RQMCEstimator
    ::initialize(MCWalkerConfiguration& W, 
        vector<QMCHamiltonian*>& h, 
        vector<TrialWaveFunction*>& psi,
        RealType tau,vector<RealType>& Norm,
        bool require_register) {

      NumWalkers = W.getActiveWalkers();
      //allocate UmbrellaEnergy
      int numPtcls(W.getTotalNum());
      RatioIJ.resize(NumWalkers,NumCopies*(NumCopies-1)/2);

      MCWalkerConfiguration::iterator it(W.begin()); 
      MCWalkerConfiguration::iterator it_end(W.end()); 

      vector<RealType> sumratio(NumCopies), logpsi(NumCopies);
      int iw(0);
      int DataSetSize((*it)->DataSet.size());
      while(it != it_end) {

        Walker_t& thisWalker(**it);
        (*it)->DataSet.rewind();

        if(require_register) {
          W.registerData(thisWalker,(*it)->DataSet);
        } else {
          W.R = thisWalker.R;
          W.update();
          if(DataSetSize) W.updateBuffer((*it)->DataSet);
        }

        //evalaute the wavefunction and hamiltonian
        for(int ipsi=0; ipsi< NumCopies;ipsi++) {
          psi[ipsi]->G.resize(numPtcls);
          psi[ipsi]->L.resize(numPtcls);
          //Need to modify the return value of OrbitalBase::registerData
          if(require_register) {
            logpsi[ipsi]=psi[ipsi]->registerData(W,(*it)->DataSet);
          } else {
            if(DataSetSize)logpsi[ipsi]=psi[ipsi]->updateBuffer(W,(*it)->DataSet);
            else logpsi[ipsi]=psi[ipsi]->evaluateLog(W); 		 
          }
          psi[ipsi]->G=W.G;
          thisWalker.Properties(ipsi,LOGPSI)=logpsi[ipsi];
          thisWalker.Properties(ipsi,LOCALENERGY)=h[ipsi]->evaluate(W);
          h[ipsi]->saveProperty(thisWalker.getPropertyBase(ipsi));
          sumratio[ipsi]=1.0;
        } 							

        //Check SIMONE's note
        //Compute the sum over j of Psi^2[j]/Psi^2[i] for each i
        int indexij(0);
        RealType *rPtr=RatioIJ[iw];
        for(int ipsi=0; ipsi< NumCopies-1; ipsi++) {			  
          for(int jpsi=ipsi+1; jpsi< NumCopies; jpsi++){     		 
            RealType r= std::exp(2.0*(logpsi[jpsi]-logpsi[ipsi])); 
            rPtr[indexij++]=r*Norm[ipsi]/Norm[jpsi];
            sumratio[ipsi] += r;                            
            sumratio[jpsi] += 1.0/r;		
          }                                              
        }                                               

        //Re-use Multiplicity as the sumratio
        thisWalker.Multiplicity=sumratio[0];
        //DON't forget DRIFT!!!
        thisWalker.Drift=0.0;

        for(int ipsi=0; ipsi< NumCopies; ipsi++) {
          RealType wgt=1.0/sumratio[ipsi];
          thisWalker.Properties(ipsi,UMBRELLAWEIGHT)=wgt;

          //thisWalker.Drift += wgt*psi[ipsi]->G;
          PAOps<RealType,DIM>::axpy(wgt,psi[ipsi]->G,thisWalker.Drift);
        }
        thisWalker.Drift *= tau;
        ++it;++iw;
      }
    }
コード例 #22
0
  void 
    RQMCEstimator
    ::initialize(MCWalkerConfiguration& W, vector<ParticleSet*>& WW,
        SpaceWarp& Warp,
        vector<QMCHamiltonian*>& h, 
        vector<TrialWaveFunction*>& psi,
        RealType tau,vector<RealType>& Norm,
        bool require_register) {

      NumWalkers = W.getActiveWalkers();

      int numPtcls(W.getTotalNum());

      RatioIJ.resize(NumWalkers,NumCopies*(NumCopies-1)/2);

      vector<RealType> invsumratio(NumCopies);
      MCWalkerConfiguration::ParticlePos_t drift(numPtcls);

      MCWalkerConfiguration::iterator it(W.begin()); 
      MCWalkerConfiguration::iterator it_end(W.end()); 

      vector<RealType> sumratio(NumCopies), logpsi(NumCopies);
      vector<RealType> Jacobian(NumCopies);

      int jindex=W.addProperty("Jacobian");
      int iw(0);
      int DataSetSize((*it)->DataSet.size());
      while(it != it_end) {
        Walker_t& thisWalker(**it);
        (*it)->DataSet.rewind();

        //NECESSARY SINCE THE DISTANCE TABLE OF W ARE USED TO WARP
        if(require_register) {
          W.registerData(thisWalker,(*it)->DataSet);
        } else {
          W.R = thisWalker.R;
          W.update();
          if(DataSetSize) W.updateBuffer((*it)->DataSet);
        }

        for(int ipsi=0; ipsi<NumCopies; ipsi++) Jacobian[ipsi]=1.e0;
        for(int iptcl=0; iptcl< numPtcls; iptcl++){
          Warp.warp_one(iptcl,0);
          for(int ipsi=0; ipsi<NumCopies; ipsi++){
            WW[ipsi]->R[iptcl]=W.R[iptcl]+Warp.get_displacement(iptcl,ipsi);
            Jacobian[ipsi]*=Warp.get_Jacobian(iptcl,ipsi);
          }
          if(require_register || DataSetSize) Warp.update_one_ptcl_Jacob(iptcl);
        }

        for(int ipsi=0; ipsi<NumCopies; ipsi++){
          thisWalker.Properties(ipsi,jindex)=Jacobian[ipsi];
        }

        //update distance table and bufferize it if necessary
        if(require_register) {
          for(int ipsi=0; ipsi<NumCopies; ipsi++){ 
            WW[ipsi]->registerData((*it)->DataSet);
          }
          Warp.registerData(WW,(*it)->DataSet);
        } else {
          for(int ipsi=0; ipsi<NumCopies; ipsi++){
            WW[ipsi]->update();
            if(DataSetSize) WW[ipsi]->updateBuffer((*it)->DataSet);
          }
          if(DataSetSize) Warp.updateBuffer((*it)->DataSet);
        }



        //evalaute the wavefunction and hamiltonian
        for(int ipsi=0; ipsi< NumCopies;ipsi++) {			  
          psi[ipsi]->G.resize(numPtcls);
          psi[ipsi]->L.resize(numPtcls);
          //Need to modify the return value of OrbitalBase::registerData
          if(require_register) {
            logpsi[ipsi]=psi[ipsi]->registerData(*WW[ipsi],(*it)->DataSet);
          }else{
            if(DataSetSize)logpsi[ipsi]=psi[ipsi]->updateBuffer(*WW[ipsi],(*it)->DataSet);
            else logpsi[ipsi]=psi[ipsi]->evaluateLog(*WW[ipsi]); 		 
          }
          psi[ipsi]->G=WW[ipsi]->G;
          thisWalker.Properties(ipsi,LOGPSI)=logpsi[ipsi];
          thisWalker.Properties(ipsi,LOCALENERGY)=h[ipsi]->evaluate(*WW[ipsi]);
          h[ipsi]->saveProperty(thisWalker.getPropertyBase(ipsi));
          sumratio[ipsi]=1.0;
        } 							

        //Check SIMONE's note
        //Compute the sum over j of Psi^2[j]/Psi^2[i] for each i
        int indexij(0);
        RealType *rPtr=RatioIJ[iw];
        for(int ipsi=0; ipsi< NumCopies-1; ipsi++) {			  
          for(int jpsi=ipsi+1; jpsi< NumCopies; jpsi++){     		 
            RealType r= std::exp(2.0*(logpsi[jpsi]-logpsi[ipsi]))*Norm[ipsi]/Norm[jpsi];
            //BEWARE: RatioIJ DOES NOT INCLUDE THE JACOBIANS!
            rPtr[indexij++]=r;
            r*=(Jacobian[jpsi]/Jacobian[ipsi]);
            sumratio[ipsi] += r;                            
            sumratio[jpsi] += 1.0/r;		
          }                                              
        }                                               

        //Re-use Multiplicity as the sumratio
        thisWalker.Multiplicity=sumratio[0];

        /*START COMMENT
          QMCTraits::PosType WarpDrift;
          RealType denom(0.e0),wgtpsi;
          thisWalker.Drift=0.e0; 
          for(int ipsi=0; ipsi< NumCopies; ipsi++) {
          wgtpsi=1.e0/sumratio[ipsi];
          thisWalker.Properties(ipsi,UMBRELLAWEIGHT)=wgtpsi;
          denom += wgtpsi;
          for(int iptcl=0; iptcl< numPtcls; iptcl++){
          WarpDrift=dot( psi[ipsi]->G[iptcl], Warp.get_Jacob_matrix(iptcl,ipsi)  )
          +5.0e-1*Warp.get_grad_ln_Jacob(iptcl,ipsi) ;
          thisWalker.Drift[iptcl] += (wgtpsi*WarpDrift);
          }
          }
        //Drift = denom*Drift;
        thisWalker.Drift *= (tau/denom);
        END COMMENT*/
        for(int ipsi=0; ipsi< NumCopies ;ipsi++){
          invsumratio[ipsi]=1.0/sumratio[ipsi];
          thisWalker.Properties(ipsi,UMBRELLAWEIGHT)=invsumratio[ipsi];
        }
        setScaledDrift(tau,psi[0]->G,drift);
        thisWalker.Drift=invsumratio[0]*drift;
        for(int ipsi=1; ipsi< NumCopies ;ipsi++) {               		
          setScaledDrift(tau,psi[ipsi]->G,drift);
          thisWalker.Drift += (invsumratio[ipsi]*drift);
        }
        ++it;++iw;
      }
    }
コード例 #23
0
/** swap walkers using (low,high) ordered pairs
 *
 * The communication occur only between the (low,high) pairs.
 * This does not guarantee a perfect balance swapWalkersBlocked and swapWalkersAsync
 * try to achieve. However, the number of messages and their sizes are less than
 * other methods.
 */
void GlobalWalkerControl::swapWalkersMap(MCWalkerConfiguration& W) {

  NumSwaps++;
  multimap<int,int> nw_map;
  for(int i=0; i<NumContexts; i++) {
    nw_map.insert(pair<int,int>(NumPerNode[i],i));
  }
  // multimap key is sorted with ascending order 
  multimap<int,int>::iterator it(nw_map.begin());
  multimap<int,int>::reverse_iterator it_b(nw_map.end());
  bool notpaired=true;
  int target_context=-1;
  int half=NumContexts/2;
  int item=0;
  bool minorcontext;
  while(notpaired &&item<half) {
    int i=(*it).second;
    int j=(*it_b).second;
    if(i == MyContext) {
      target_context=j;
      notpaired=false;
      minorcontext=true;
    } else if(j == MyContext) {
      target_context= i;
      notpaired=false;
      minorcontext=false;
    } 
    ++it; ++it_b; ++item;
  }

  int nw_tot=NumPerNode[MyContext]+NumPerNode[target_context];
  int nw_L=nw_tot/2;
  int nw_R=nw_tot-nw_L;
  int dnw(0);
  if(minorcontext) {
    dnw=nw_L-NumPerNode[MyContext];//how many to get
  } else {
    dnw=NumPerNode[MyContext]-nw_R;//how many to send
  }

  if(dnw) {//something to swap
    if(minorcontext) {//open recv buffer
      Walker_t& wRef(*W[0]);
      OOMPI_Packed recvBuffer(dnw*wRef.byteSize(),OOMPI_COMM_WORLD);
      OOMPI_COMM_WORLD[target_context].Recv(recvBuffer);
      //create walkers
      int last = W.getActiveWalkers();
      while(dnw) {
        Walker_t *awalker= new Walker_t(wRef);
        awalker->getMessage(recvBuffer);
        W.push_back(awalker);
        --dnw; ++last;
      }
    } else {
      Walker_t& wRef(*W[0]);
      OOMPI_Packed sendBuffer(dnw*wRef.byteSize(),OOMPI_COMM_WORLD);
      int last=W.getActiveWalkers()-1;
      while(dnw) {
        W[last]->putMessage(sendBuffer);
        --dnw; --last;
      }
      OOMPI_COMM_WORLD[target_context].Send(sendBuffer);
      //last=WalkerList.size()-1;
      //while(dnw_save) {
      //  delete WalkerList[last]; 
      //  WalkerList.pop_back();
      //  --dnw_save; --last;
      //}
      //destroyWalkers(WalkerList.begin()+nsub[MyContext], WalkerList.end());
      W.destroyWalkers(W.begin()+nw_R, W.end());
    }
  }

  /* not used yet
  struct lessNode {
    inline bool operator()(const pair<int,int>& a,
        const pair<int,int>& b) const {
      return a.second < b.second;
    }
  };
  //typedef pair<int,int> mytype;
  //vector<mytype> id2n(NumContexts);
  //for(int i=0; i<NumContexts; i++) {
  //  id2n=pair<int,int>(i,NumPerNode[i]);
  //}
  //
  //std::sort(id2n.begin(),id2n.end(),lessNode);
  */
}