//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); }
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; }
/** 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); }
/** 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; }
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; }
/** @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); } }
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; } } }
/** 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; }
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; }
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; } }
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(); }
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; }
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; }
/** 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; }
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(); }
/** 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; } }
/** accumulate data over walkers * @param W MCWalkerConfiguration * @param wgt weight */ void CompositeEstimatorSet::accumulate(MCWalkerConfiguration& W, RealType wgtnorm) { accumulate(W,W.begin(),W.end(),wgtnorm); }
/** 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()); }
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]; }
/** 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()); }
// 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; } }
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; } }
/** 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); */ }