diff --git a/src/QMCDrivers/CloneManager.cpp b/src/QMCDrivers/CloneManager.cpp index 02e01f1659..5f268bfe37 100644 --- a/src/QMCDrivers/CloneManager.cpp +++ b/src/QMCDrivers/CloneManager.cpp @@ -27,7 +27,6 @@ #else using TraceManager = int; #endif -#include "WalkerLogManager.h" //comment this out to use only method to clone #define ENABLE_CLONE_PSI_AND_H @@ -87,7 +86,6 @@ CloneManager::~CloneManager() #if !defined(REMOVE_TRACEMANAGER) delete_iter(traceClones.begin(), traceClones.end()); #endif - delete_iter(wlog_collectors.begin(), wlog_collectors.end()); } void CloneManager::makeClones(MCWalkerConfiguration& w, TrialWaveFunction& psi, QMCHamiltonian& ham) @@ -282,4 +280,12 @@ CloneManager::RealType CloneManager::acceptRatio() const return static_cast(nAcceptTot) / static_cast(nAcceptTot + nRejectTot); } +RefVector CloneManager::getWalkerLogCollectorRefs() +{ + RefVector refs; + for(int i = 0; i < wlog_collectors.size(); i++) + refs.push_back(*wlog_collectors[i]); + return refs; +} + } // namespace qmcplusplus diff --git a/src/QMCDrivers/CloneManager.h b/src/QMCDrivers/CloneManager.h index d8f41b962a..cdfb073c58 100644 --- a/src/QMCDrivers/CloneManager.h +++ b/src/QMCDrivers/CloneManager.h @@ -76,7 +76,7 @@ class CloneManager : public QMCTraits ///trace managers std::vector traceClones; ///trace collectors - std::vector wlog_collectors; + UPtrVector wlog_collectors; //for correlated sampling. static std::vector> WPoolClones_uptr; @@ -89,6 +89,8 @@ class CloneManager : public QMCTraits ///Walkers per MPI rank std::vector wPerRank; + + RefVector getWalkerLogCollectorRefs(); }; } // namespace qmcplusplus #endif diff --git a/src/QMCDrivers/Crowd.cpp b/src/QMCDrivers/Crowd.cpp index a00a458fa4..208fe1290e 100644 --- a/src/QMCDrivers/Crowd.cpp +++ b/src/QMCDrivers/Crowd.cpp @@ -19,7 +19,7 @@ Crowd::Crowd(EstimatorManagerNew& emb, const TrialWaveFunction& twf, const QMCHamiltonian& ham, const MultiWalkerDispatchers& dispatchers) - : dispatchers_(dispatchers), driverwalker_resource_collection_(driverwalker_res), estimator_manager_crowd_(emb) + : dispatchers_(dispatchers), driverwalker_resource_collection_(driverwalker_res), estimator_manager_crowd_(emb) { if (emb.areThereListeners()) { @@ -82,16 +82,34 @@ void Crowd::startBlock(int num_steps) // VMCBatched does no nonlocal moves n_nonlocal_accept_ = 0; estimator_manager_crowd_.startBlock(num_steps); - wlog_collector_.startBlock(); + if (wlog_collector_) + wlog_collector_->startBlock(); } void Crowd::stopBlock() { estimator_manager_crowd_.stopBlock(); } +void Crowd::setWalkerLogCollector(std::unique_ptr&& collector) +{ + wlog_collector_ = std::move(collector); +} + void Crowd::collectStepWalkerLog(int current_step) { + if (!wlog_collector_) + return; + for (int iw = 0; iw < size(); ++iw) - wlog_collector_.collect(mcp_walkers_[iw], walker_elecs_[iw], walker_twfs_[iw], walker_hamiltonians_[iw], current_step); + wlog_collector_->collect(mcp_walkers_[iw], walker_elecs_[iw], walker_twfs_[iw], walker_hamiltonians_[iw], + current_step); } +RefVector Crowd::getWalkerLogCollectorRefs(const UPtrVector& crowds) +{ + RefVector refs; + for (auto& crowd : crowds) + if (crowd && crowd->wlog_collector_) + refs.push_back(*crowd->wlog_collector_); + return refs; +} } // namespace qmcplusplus diff --git a/src/QMCDrivers/Crowd.h b/src/QMCDrivers/Crowd.h index ee468ce2b0..4127f7886b 100644 --- a/src/QMCDrivers/Crowd.h +++ b/src/QMCDrivers/Crowd.h @@ -16,7 +16,7 @@ #include "MultiWalkerDispatchers.h" #include "DriverWalkerTypes.h" #include "Estimators/EstimatorManagerCrowd.h" -#include "WalkerLogManager.h" +#include "WalkerLogCollector.h" namespace qmcplusplus { @@ -52,9 +52,9 @@ class Crowd */ Crowd(EstimatorManagerNew& emb, const DriverWalkerResourceCollection& driverwalker_res, - const ParticleSet& pset, + const ParticleSet& pset, const TrialWaveFunction& twf, - const QMCHamiltonian& hamiltonian_temp, + const QMCHamiltonian& hamiltonian_temp, const MultiWalkerDispatchers& dispatchers); ~Crowd(); /** Because so many vectors allocate them upfront. @@ -85,6 +85,8 @@ class Crowd estimator_manager_crowd_.accumulate(mcp_walkers_, walker_elecs_, walker_twfs_, walker_hamiltonians_, rng); } + /// activate the collector + void setWalkerLogCollector(std::unique_ptr&&); /// Collect walker log data void collectStepWalkerLog(int current_step); @@ -103,7 +105,6 @@ class Crowd const RefVector& get_walker_hamiltonians() const { return walker_hamiltonians_; } const EstimatorManagerCrowd& get_estimator_manager_crowd() const { return estimator_manager_crowd_; } - WalkerLogCollector& getWalkerLogCollector() { return wlog_collector_; } DriverWalkerResourceCollection& getSharedResource() { return driverwalker_resource_collection_; } @@ -118,6 +119,9 @@ class Crowd const MultiWalkerDispatchers& dispatchers_; + /// get refereces of active walker log collectors. If walker logging is disabled, the RefVector size can be zero. + static RefVector getWalkerLogCollectorRefs(const UPtrVector& crowds); + private: /** @name Walker Vectors * @@ -136,7 +140,7 @@ class Crowd /// per crowd estimator manager EstimatorManagerCrowd estimator_manager_crowd_; // collector for walker logs - WalkerLogCollector wlog_collector_; + std::unique_ptr wlog_collector_; /** @name Step State * diff --git a/src/QMCDrivers/DMC/DMC.cpp b/src/QMCDrivers/DMC/DMC.cpp index 46e705550e..fc7647001b 100644 --- a/src/QMCDrivers/DMC/DMC.cpp +++ b/src/QMCDrivers/DMC/DMC.cpp @@ -94,7 +94,7 @@ void DMC::resetUpdateEngines() Rng.resize(NumThreads); estimatorClones.resize(NumThreads, nullptr); traceClones.resize(NumThreads, nullptr); - wlog_collectors.resize(NumThreads, nullptr); + wlog_collectors.resize(NumThreads); FairDivideLow(W.getActiveWalkers(), NumThreads, wPerRank); { @@ -144,7 +144,7 @@ void DMC::resetUpdateEngines() Movers[ip]->setSpinMass(SpinMass); Movers[ip]->put(qmcNode); //Movers[ip]->resetRun(branchEngine.get(), estimatorClones[ip], traceClones[ip], DriftModifier); - Movers[ip]->resetRun2(branchEngine.get(), estimatorClones[ip], traceClones[ip], wlog_collectors[ip], DriftModifier); + Movers[ip]->resetRun2(branchEngine.get(), estimatorClones[ip], traceClones[ip], wlog_collectors[ip].get(), DriftModifier); Movers[ip]->initWalkersForPbyP(W.begin() + wPerRank[ip], W.begin() + wPerRank[ip + 1]); } else @@ -163,7 +163,7 @@ void DMC::resetUpdateEngines() Movers[ip]->put(qmcNode); //Movers[ip]->resetRun(branchEngine.get(), estimatorClones[ip], traceClones[ip], DriftModifier); - Movers[ip]->resetRun2(branchEngine.get(), estimatorClones[ip], traceClones[ip], wlog_collectors[ip], DriftModifier); + Movers[ip]->resetRun2(branchEngine.get(), estimatorClones[ip], traceClones[ip], wlog_collectors[ip].get(), DriftModifier); Movers[ip]->initWalkersForPbyP(W.begin() + wPerRank[ip], W.begin() + wPerRank[ip + 1]); } else @@ -174,7 +174,7 @@ void DMC::resetUpdateEngines() Movers[ip] = new DMCUpdateAllWithRejection(*wClones[ip], *psiClones[ip], *hClones[ip], *Rng[ip]); Movers[ip]->put(qmcNode); //Movers[ip]->resetRun(branchEngine.get(), estimatorClones[ip], traceClones[ip], DriftModifier); - Movers[ip]->resetRun2(branchEngine.get(), estimatorClones[ip], traceClones[ip], wlog_collectors[ip], DriftModifier); + Movers[ip]->resetRun2(branchEngine.get(), estimatorClones[ip], traceClones[ip], wlog_collectors[ip].get(), DriftModifier); Movers[ip]->initWalkers(W.begin() + wPerRank[ip], W.begin() + wPerRank[ip + 1]); } } @@ -239,7 +239,7 @@ bool DMC::run() #if !defined(REMOVE_TRACEMANAGER) Traces->startRun(nBlocks, traceClones); #endif - wlog_manager_->startRun(wlog_collectors); + wlog_manager_->startRun(getWalkerLogCollectorRefs()); IndexType block = 0; IndexType updatePeriod = (qmc_driver_mode[QMC_UPDATE_MODE]) ? Period4CheckProperties : (nBlocks + 1) * nSteps; int sample = 0; @@ -297,7 +297,7 @@ bool DMC::run() #if !defined(REMOVE_TRACEMANAGER) Traces->write_buffers(traceClones, block); #endif - wlog_manager_->writeBuffers(wlog_collectors); + wlog_manager_->writeBuffers(); block++; if (DumpConfig && block % Period4CheckPoint == 0) { diff --git a/src/QMCDrivers/DMC/DMCBatched.cpp b/src/QMCDrivers/DMC/DMCBatched.cpp index 4a8d97da6b..cc3ff53f68 100644 --- a/src/QMCDrivers/DMC/DMCBatched.cpp +++ b/src/QMCDrivers/DMC/DMCBatched.cpp @@ -28,6 +28,7 @@ #include "MemoryUsage.h" #include "QMCWaveFunctions/TWFGrads.hpp" #include "TauParams.hpp" +#include "WalkerLogManager.h" namespace qmcplusplus { @@ -433,12 +434,12 @@ bool DMCBatched::run() estimator_manager_->startDriverRun(); - //start walker log manager - wlog_manager_ = std::make_unique(walker_logs_input, allow_walker_logs, get_root_name(), myComm); - std::vector wlog_collectors; - for (auto& c: crowds_) - wlog_collectors.push_back(&c->getWalkerLogCollector()); - wlog_manager_->startRun(wlog_collectors); + //initialize WalkerLogManager and collectors + WalkerLogManager wlog_manager(walker_logs_input, allow_walker_logs, get_root_name(), myComm); + for (auto& crowd : crowds_) + crowd->setWalkerLogCollector(wlog_manager.makeCollector()); + //register walker log collectors into the manager + wlog_manager.startRun(Crowd::getWalkerLogCollectorRefs(crowds_)); StateForThread dmc_state(qmcdriver_input_, *drift_modifier_, *branch_engine_, population_, steps_per_block_); @@ -494,7 +495,7 @@ bool DMCBatched::run() for (UPtr& ham : population_.get_hamiltonians()) setNonLocalMoveHandler(*ham); - dmc_state.step = step; + dmc_state.step = step; dmc_state.global_step = global_step; crowd_task(crowds_.size(), runDMCStep, dmc_state, timers_, dmc_timers_, std::ref(step_contexts_), std::ref(crowds_)); @@ -513,7 +514,7 @@ bool DMCBatched::run() if (qmcdriver_input_.get_measure_imbalance()) measureImbalance("Block " + std::to_string(block)); endBlock(); - wlog_manager_->writeBuffers(wlog_collectors); + wlog_manager.writeBuffers(); recordBlock(block); } @@ -536,8 +537,8 @@ bool DMCBatched::run() print_mem("DMCBatched ends", app_log()); + wlog_manager.stopRun(); estimator_manager_->stopDriverRun(); - wlog_manager_->stopRun(); return finalize(num_blocks, true); } diff --git a/src/QMCDrivers/DMC/DMCBatched.h b/src/QMCDrivers/DMC/DMCBatched.h index fbb318ca7d..e334128de2 100644 --- a/src/QMCDrivers/DMC/DMCBatched.h +++ b/src/QMCDrivers/DMC/DMCBatched.h @@ -52,8 +52,8 @@ class DMCBatched : public QMCDriverNew SFNBranch& branch_engine; IndexType recalculate_properties_period; const size_t steps_per_block; - IndexType step = -1; - IndexType global_step = -1; + IndexType step = -1; + IndexType global_step = -1; bool is_recomputing_block = false; StateForThread(const QMCDriverInput& qmci, diff --git a/src/QMCDrivers/DMC/DMCUpdatePbyPFast.cpp b/src/QMCDrivers/DMC/DMCUpdatePbyPFast.cpp index e28f017980..5011676a23 100644 --- a/src/QMCDrivers/DMC/DMCUpdatePbyPFast.cpp +++ b/src/QMCDrivers/DMC/DMCUpdatePbyPFast.cpp @@ -24,7 +24,7 @@ #else using TraceManager = int; #endif -#include "WalkerLogManager.h" +#include "WalkerLogCollector.h" //#define TEST_INNERBRANCH diff --git a/src/QMCDrivers/QMCDriver.h b/src/QMCDrivers/QMCDriver.h index 0b62c24f29..c59b67ac8d 100644 --- a/src/QMCDrivers/QMCDriver.h +++ b/src/QMCDrivers/QMCDriver.h @@ -31,7 +31,6 @@ #include "QMCWaveFunctions/WaveFunctionPool.h" #include "QMCHamiltonians/QMCHamiltonian.h" #include "Estimators/EstimatorManagerBase.h" -#include "WalkerLogManager.h" #include "QMCDrivers/DriverTraits.h" #include "QMCDrivers/QMCDriverInterface.h" #include "QMCDrivers/GreenFunctionModifiers/DriftModifierBase.h" diff --git a/src/QMCDrivers/QMCDriverNew.cpp b/src/QMCDrivers/QMCDriverNew.cpp index ab37238376..5f407a85ce 100644 --- a/src/QMCDrivers/QMCDriverNew.cpp +++ b/src/QMCDrivers/QMCDriverNew.cpp @@ -33,7 +33,6 @@ #include "Utilities/Timer.h" #include "Message/UniformCommunicateError.h" #include "EstimatorInputDelegates.h" -#include "WalkerLogInput.h" #include "WalkerLogManager.h" diff --git a/src/QMCDrivers/QMCDriverNew.h b/src/QMCDrivers/QMCDriverNew.h index 68f5e0e67c..2661ffdf59 100644 --- a/src/QMCDrivers/QMCDriverNew.h +++ b/src/QMCDrivers/QMCDriverNew.h @@ -52,7 +52,6 @@ namespace qmcplusplus { //forward declarations: Do not include headers if not needed class TraceManager; -class WalkerLogManager; class EstimatorManagerNew; class TrialWaveFunction; class QMCHamiltonian; @@ -443,9 +442,6 @@ class QMCDriverNew : public QMCDriverInterface, public MPIObjectBase */ std::unique_ptr estimator_manager_; - /// walker log manager - std::unique_ptr wlog_manager_; - ///record engine for walkers std::unique_ptr wOut; diff --git a/src/QMCDrivers/QMCUpdateBase.cpp b/src/QMCDrivers/QMCUpdateBase.cpp index f23dd01bba..728a4a3c2d 100644 --- a/src/QMCDrivers/QMCUpdateBase.cpp +++ b/src/QMCDrivers/QMCUpdateBase.cpp @@ -26,7 +26,7 @@ #else using TraceManager = int; #endif -#include "WalkerLogManager.h" +#include "WalkerLogCollector.h" namespace qmcplusplus { diff --git a/src/QMCDrivers/QMCUpdateBase.h b/src/QMCDrivers/QMCUpdateBase.h index 237b7048b4..f5ae46b923 100644 --- a/src/QMCDrivers/QMCUpdateBase.h +++ b/src/QMCDrivers/QMCUpdateBase.h @@ -23,7 +23,6 @@ #include "QMCWaveFunctions/TrialWaveFunction.h" #include "QMCHamiltonians/QMCHamiltonian.h" #include "QMCHamiltonians/NonLocalTOperator.h" -#include "WalkerLogManager.h" #include "GreenFunctionModifiers/DriftModifierBase.h" #include "SimpleFixedNodeBranch.h" #include "DriverDebugChecks.h" diff --git a/src/QMCDrivers/VMC/VMC.cpp b/src/QMCDrivers/VMC/VMC.cpp index 508ae66561..17e66e1e0f 100644 --- a/src/QMCDrivers/VMC/VMC.cpp +++ b/src/QMCDrivers/VMC/VMC.cpp @@ -67,7 +67,7 @@ bool VMC::run() #if !defined(REMOVE_TRACEMANAGER) Traces->startRun(nBlocks, traceClones); #endif - wlog_manager_->startRun(wlog_collectors); + wlog_manager_->startRun(getWalkerLogCollectorRefs()); LoopTimer<> vmc_loop; RunTimeControl<> runtimeControl(run_time_manager, MaxCPUSecs, myComm->getName(), myComm->rank() == 0); @@ -111,7 +111,7 @@ bool VMC::run() #if !defined(REMOVE_TRACEMANAGER) Traces->write_buffers(traceClones, block); #endif - wlog_manager_->writeBuffers(wlog_collectors); + wlog_manager_->writeBuffers(); recordBlock(block); vmc_loop.stop(); @@ -169,7 +169,7 @@ void VMC::resetRun() Movers.resize(NumThreads, nullptr); estimatorClones.resize(NumThreads, nullptr); traceClones.resize(NumThreads, nullptr); - wlog_collectors.resize(NumThreads, nullptr); + wlog_collectors.resize(NumThreads); Rng.resize(NumThreads); // hdf_archive::hdf_archive() is not thread-safe @@ -267,7 +267,7 @@ void VMC::resetRun() //int ip=omp_get_thread_num(); Movers[ip]->put(qmcNode); //Movers[ip]->resetRun(branchEngine.get(), estimatorClones[ip], traceClones[ip], DriftModifier); - Movers[ip]->resetRun2(branchEngine.get(), estimatorClones[ip], traceClones[ip], wlog_collectors[ip], DriftModifier); + Movers[ip]->resetRun2(branchEngine.get(), estimatorClones[ip], traceClones[ip], wlog_collectors[ip].get(), DriftModifier); if (qmc_driver_mode[QMC_UPDATE_MODE]) Movers[ip]->initWalkersForPbyP(W.begin() + wPerRank[ip], W.begin() + wPerRank[ip + 1]); else diff --git a/src/QMCDrivers/VMC/VMCBatched.cpp b/src/QMCDrivers/VMC/VMCBatched.cpp index 094a8aca8f..a6344440b7 100644 --- a/src/QMCDrivers/VMC/VMCBatched.cpp +++ b/src/QMCDrivers/VMC/VMCBatched.cpp @@ -309,12 +309,13 @@ bool VMCBatched::run() IndexType num_blocks = qmcdriver_input_.get_max_blocks(); //start the main estimator estimator_manager_->startDriverRun(); - //start walker log manager - wlog_manager_ = std::make_unique(walker_logs_input, allow_walker_logs, get_root_name(), myComm); - std::vector wlog_collectors; - for (auto& c: crowds_) - wlog_collectors.push_back(&c->getWalkerLogCollector()); - wlog_manager_->startRun(wlog_collectors); + + //initialize WalkerLogManager and collectors + WalkerLogManager wlog_manager(walker_logs_input, allow_walker_logs, get_root_name(), myComm); + for (auto& crowd : crowds_) + crowd->setWalkerLogCollector(wlog_manager.makeCollector()); + //register walker log collectors into the manager + wlog_manager.startRun(Crowd::getWalkerLogCollectorRefs(crowds_)); StateForThread vmc_state(qmcdriver_input_, vmcdriver_input_, *drift_modifier_, population_, steps_per_block_); @@ -386,7 +387,7 @@ bool VMCBatched::run() for (int step = 0; step < steps_per_block_; ++step, ++global_step) { ScopedTimer local_timer(timers_.run_steps_timer); - vmc_state.step = step; + vmc_state.step = step; vmc_state.global_step = global_step; crowd_task(crowds_.size(), runVMCStep, vmc_state, timers_, std::ref(step_contexts_), std::ref(crowds_)); @@ -403,7 +404,7 @@ bool VMCBatched::run() if (qmcdriver_input_.get_measure_imbalance()) measureImbalance("Block " + std::to_string(block)); endBlock(); - wlog_manager_->writeBuffers(wlog_collectors); + wlog_manager.writeBuffers(); recordBlock(block); } @@ -449,8 +450,8 @@ bool VMCBatched::run() print_mem("VMCBatched ends", app_log()); + wlog_manager.stopRun(); estimator_manager_->stopDriverRun(); - wlog_manager_->stopRun(); return finalize(num_blocks, true); } @@ -459,7 +460,7 @@ void VMCBatched::enable_sample_collection() { assert(steps_per_block_ > 0 && "VMCBatched::enable_sample_collection steps_per_block_ must be positive!"); auto samples = compute_samples_per_rank(qmcdriver_input_.get_max_blocks(), steps_per_block_, - population_.get_num_local_walkers()); + population_.get_num_local_walkers()); samples_.setMaxSamples(samples, population_.get_num_ranks()); collect_samples_ = true; diff --git a/src/QMCDrivers/VMC/VMCBatched.h b/src/QMCDrivers/VMC/VMCBatched.h index 8c4cee5882..994b3d45c5 100644 --- a/src/QMCDrivers/VMC/VMCBatched.h +++ b/src/QMCDrivers/VMC/VMCBatched.h @@ -53,7 +53,7 @@ class VMCBatched : public QMCDriverNew IndexType recalculate_properties_period; const size_t steps_per_block; IndexType step = -1; - IndexType global_step = -1; + IndexType global_step = -1; bool is_recomputing_block = false; StateForThread(const QMCDriverInput& qmci, diff --git a/src/QMCDrivers/WalkerLogCollector.cpp b/src/QMCDrivers/WalkerLogCollector.cpp index c0297ded23..4be0e99057 100644 --- a/src/QMCDrivers/WalkerLogCollector.cpp +++ b/src/QMCDrivers/WalkerLogCollector.cpp @@ -23,25 +23,14 @@ namespace qmcplusplus using MCPWalker = Walker; - -WalkerLogCollector::WalkerLogCollector() -{ - init(); -} - - -WalkerLogCollector::WalkerLogCollector(const WalkerLogState& state_) -{ - init(); - state = state_; -} +WalkerLogCollector::WalkerLogCollector(const WalkerLogState& state) : state_(state) { init(); } void WalkerLogCollector::init() { properties_include = {"R2Accepted", "R2Proposed", "LocalEnergy", "LocalPotential", "Kinetic", - "ElecElec", "ElecIon", "LocalECP", "NonLocalECP"}; - energy_index = -1; + "ElecElec", "ElecIon", "LocalECP", "NonLocalECP"}; + energy_index = -1; // empty walker steps and energy vectors for the MC block steps.resize(0); energies.resize(0); @@ -54,9 +43,9 @@ void WalkerLogCollector::init() void WalkerLogCollector::startBlock() { - if (!state.logs_active) + if (!state_.logs_active) return; // no-op for driver if logs are inactive - if (state.verbose) + if (state_.verbose) app_log() << "WalkerLogCollector::startBlock " << std::endl; resetBuffers(); // resize buffers to zero rows } @@ -68,12 +57,12 @@ void WalkerLogCollector::collect(const MCPWalker& walker, const QMCHamiltonian& ham, int step) { - if (!state.logs_active) + if (!state_.logs_active) return; // no-op for driver if logs are inactive // only collect walker data at steps matching the period (default 1) int current_step = (step == -1) ? pset.current_step : step; - if (current_step % state.step_period != 0) + if (current_step % state_.step_period != 0) return; auto& bsi = walker_property_int_buffer; @@ -172,7 +161,7 @@ void WalkerLogCollector::collect(const MCPWalker& walker, void WalkerLogCollector::resetBuffers() { - if (state.verbose) + if (state_.verbose) app_log() << "WalkerLogCollector::reset_buffers" << std::endl; // resize all buffers to zero rows walker_property_int_buffer.resetBuffer(); @@ -186,7 +175,7 @@ void WalkerLogCollector::resetBuffers() void WalkerLogCollector::checkBuffers() { - if (state.verbose) + if (state_.verbose) app_log() << "WalkerLogCollector::checkBuffers" << std::endl; size_t nrows = walker_property_int_buffer.nrows(); auto prop_real_bad = walker_property_real_buffer.nrows() != nrows; diff --git a/src/QMCDrivers/WalkerLogCollector.h b/src/QMCDrivers/WalkerLogCollector.h index 73d92dbf24..b1a60b5ad0 100644 --- a/src/QMCDrivers/WalkerLogCollector.h +++ b/src/QMCDrivers/WalkerLogCollector.h @@ -67,9 +67,6 @@ class WalkerLogCollector /// location of LocalEnergy in ParticleSet::PropertyList int energy_index; - /// state data set by WalkerLogManager - WalkerLogState state; - private: // temporary (contiguous) storage for awful ParticleAttrib<> quantities /// tmp storage for walker positions @@ -80,11 +77,12 @@ class WalkerLogCollector Array Gtmp; /// tmp storage for walker wavefunciton laplacians Array Ltmp; + /// state data set by WalkerLogManager + const WalkerLogState& state_; public: - WalkerLogCollector(); - - WalkerLogCollector(const WalkerLogState& state_); + /// constructor. The state should be given by the manager. + WalkerLogCollector(const WalkerLogState& state); /// resize buffers to zero rows at beginning of each MC block void startBlock(); diff --git a/src/QMCDrivers/WalkerLogManager.cpp b/src/QMCDrivers/WalkerLogManager.cpp index b78d6eaf7a..cf1bf11dde 100644 --- a/src/QMCDrivers/WalkerLogManager.cpp +++ b/src/QMCDrivers/WalkerLogManager.cpp @@ -68,28 +68,27 @@ WalkerLogManager::WalkerLogManager(WalkerLogInput& inp, bool allow_logs, std::st } -WalkerLogCollector* WalkerLogManager::makeCollector() +std::unique_ptr WalkerLogManager::makeCollector() const { if (state.verbose) app_log() << "WalkerLogManager::makeCollector " << std::endl; - WalkerLogCollector* tc = new WalkerLogCollector(state); - return tc; + return std::make_unique(state); } -void WalkerLogManager::startRun(std::vector& collectors) +void WalkerLogManager::startRun(RefVector&& collectors) { + collectors_in_run_ = std::move(collectors); if (!state.logs_active) return; // no-op for driver if logs are inactive + if (collectors_in_run_.empty()) + throw std::runtime_error("BUG collectors are empty but walker logs are active"); if (state.verbose) app_log() << "WalkerLogManager::startRun " << std::endl; - // transfer step_period, verbosity, etc settings to log collectors - for (auto& tc : collectors) - tc->state = state; // check data size consistency among the log collector buffers - checkCollectors(collectors); + checkCollectors(collectors_in_run_); // open the logs file - openFile(collectors); + openFile(collectors_in_run_); } @@ -99,13 +98,15 @@ void WalkerLogManager::stopRun() return; // no-op for driver if logs are inactive if (state.verbose) app_log() << "WalkerLogManager::stopRun " << std::endl; + collectors_in_run_.clear(); // close the logs file closeFile(); } -void WalkerLogManager::writeBuffers(std::vector& collectors) +void WalkerLogManager::writeBuffers() { + const RefVector& collectors = collectors_in_run_; if (!state.logs_active) return; // no-op for driver if logs are inactive if (state.verbose) @@ -136,7 +137,7 @@ void WalkerLogManager::writeBuffers(std::vector& collectors // gather per energy and step data for all walker throughout the MC block for (size_t c = 0; c < collectors.size(); ++c) { - auto& tc = *collectors[c]; + WalkerLogCollector& tc = collectors[c]; tc.checkBuffers(); for (size_t r = 0; r < tc.energies.size(); ++r) energy_order.push_back(std::make_tuple(tc.steps[r], tc.energies[r], c, r)); @@ -169,27 +170,30 @@ void WalkerLogManager::writeBuffers(std::vector& collectors size_t c, r; if (write_min_data) { // cache data for minimum energy walker - c = std::get<2>(energy_order[nmin]); - r = std::get<3>(energy_order[nmin]); - wmin_property_int_buffer.addRow(collectors[c]->walker_property_int_buffer, r); - wmin_property_real_buffer.addRow(collectors[c]->walker_property_real_buffer, r); - wmin_particle_real_buffer.addRow(collectors[c]->walker_particle_real_buffer, r); + c = std::get<2>(energy_order[nmin]); + r = std::get<3>(energy_order[nmin]); + WalkerLogCollector& tc = collectors[c]; + wmin_property_int_buffer.addRow(tc.walker_property_int_buffer, r); + wmin_property_real_buffer.addRow(tc.walker_property_real_buffer, r); + wmin_particle_real_buffer.addRow(tc.walker_particle_real_buffer, r); } if (write_max_data) { // cache data for maximum energy walker - c = std::get<2>(energy_order[nmax]); - r = std::get<3>(energy_order[nmax]); - wmax_property_int_buffer.addRow(collectors[c]->walker_property_int_buffer, r); - wmax_property_real_buffer.addRow(collectors[c]->walker_property_real_buffer, r); - wmax_particle_real_buffer.addRow(collectors[c]->walker_particle_real_buffer, r); + c = std::get<2>(energy_order[nmax]); + r = std::get<3>(energy_order[nmax]); + WalkerLogCollector& tc = collectors[c]; + wmax_property_int_buffer.addRow(tc.walker_property_int_buffer, r); + wmax_property_real_buffer.addRow(tc.walker_property_real_buffer, r); + wmax_particle_real_buffer.addRow(tc.walker_particle_real_buffer, r); } if (write_med_data) { // cache data for median energy walker - c = std::get<2>(energy_order[nmed]); - r = std::get<3>(energy_order[nmed]); - wmed_property_int_buffer.addRow(collectors[c]->walker_property_int_buffer, r); - wmed_property_real_buffer.addRow(collectors[c]->walker_property_real_buffer, r); - wmed_particle_real_buffer.addRow(collectors[c]->walker_particle_real_buffer, r); + c = std::get<2>(energy_order[nmed]); + r = std::get<3>(energy_order[nmed]); + WalkerLogCollector& tc = collectors[c]; + wmed_property_int_buffer.addRow(tc.walker_property_int_buffer, r); + wmed_property_real_buffer.addRow(tc.walker_property_real_buffer, r); + wmed_particle_real_buffer.addRow(tc.walker_particle_real_buffer, r); } // reset pointers n1 = n; @@ -201,21 +205,21 @@ void WalkerLogManager::writeBuffers(std::vector& collectors } // write buffer data to file - writeBuffersHDF(collectors); + writeBuffersHDF(); } -void WalkerLogManager::checkCollectors(std::vector& collectors) +void WalkerLogManager::checkCollectors(const RefVector& collectors) const { if (state.verbose) app_log() << "WalkerLogManager::checkCollectors" << std::endl; if (collectors.size() > 0) { bool all_same = true; - WalkerLogCollector& ref = *collectors[0]; + WalkerLogCollector& ref = collectors[0]; for (int i = 0; i < collectors.size(); ++i) { - WalkerLogCollector& tc = *collectors[i]; + WalkerLogCollector& tc = collectors[i]; all_same &= tc.walker_property_int_buffer.sameAs(ref.walker_property_int_buffer); all_same &= tc.walker_property_real_buffer.sameAs(ref.walker_property_real_buffer); all_same &= tc.walker_particle_real_buffer.sameAs(ref.walker_particle_real_buffer); @@ -232,7 +236,7 @@ void WalkerLogManager::checkCollectors(std::vector& collect } -void WalkerLogManager::openFile(std::vector& collectors) +void WalkerLogManager::openFile(const RefVector& collectors) { if (state.verbose) app_log() << "WalkerLogManager::openFile " << std::endl; @@ -248,7 +252,7 @@ void WalkerLogManager::closeFile() } -void WalkerLogManager::openHDFFile(std::vector& collectors) +void WalkerLogManager::openHDFFile(const RefVector& collectors) { if (state.verbose) app_log() << "WalkerLogManager::openHDFFile " << std::endl; @@ -284,11 +288,12 @@ void WalkerLogManager::openHDFFile(std::vector& collectors) } -void WalkerLogManager::writeBuffersHDF(std::vector& collectors) +void WalkerLogManager::writeBuffersHDF() { + const RefVector& collectors = collectors_in_run_; if (state.verbose) app_log() << "WalkerLogManager::writeBuffersHDF " << std::endl; - WalkerLogCollector& tc_lead = *collectors[0]; + WalkerLogCollector& tc_lead = collectors[0]; if (!registered_hdf) { // write walker quantity information ("data_layout") for each buffer in the HDF file // create data_layout for all-walker buffers @@ -320,7 +325,7 @@ void WalkerLogManager::writeBuffersHDF(std::vector& collect // write data for all-walker buffers to HDF for (int ip = 0; ip < collectors.size(); ++ip) { - WalkerLogCollector& tc = *collectors[ip]; + WalkerLogCollector& tc = collectors[ip]; tc.walker_property_int_buffer.writeHDF(*hdf_file, tc_lead.walker_property_int_buffer.hdf_file_pointer); tc.walker_property_real_buffer.writeHDF(*hdf_file, tc_lead.walker_property_real_buffer.hdf_file_pointer); if (write_particle_data) diff --git a/src/QMCDrivers/WalkerLogManager.h b/src/QMCDrivers/WalkerLogManager.h index ff0aad250a..be00e1b5a5 100644 --- a/src/QMCDrivers/WalkerLogManager.h +++ b/src/QMCDrivers/WalkerLogManager.h @@ -14,7 +14,7 @@ #define QMCPLUSPLUS_WALKERLOGMANAGER_H #include "WalkerLogCollector.h" - +#include "type_traits/template_types.hpp" namespace qmcplusplus { @@ -43,13 +43,12 @@ struct WalkerLogInput; */ class WalkerLogManager { -public: - WalkerLogState state; - private: /// file prefix for the current driver std::string file_root; Communicate* communicator; + /// output state + WalkerLogState state; /// access to HDF file std::unique_ptr hdf_file; /// whether walker quantity data ("data_layout") has been recorded in HDF @@ -88,36 +87,38 @@ class WalkerLogManager /// buffer containing per-particle properties for the median energy walkers WalkerLogBuffer wmed_particle_real_buffer; + RefVector collectors_in_run_; + public: WalkerLogManager(WalkerLogInput& inp, bool allow_logs, std::string series_root, Communicate* comm = 0); - /// create a WalkerLogCollector (legacy drivers only, "cloning" style) - WalkerLogCollector* makeCollector(); + /// create a WalkerLogCollector + std::unique_ptr makeCollector() const; /// open the logs file and check consistency of the collectors at the start of a run - void startRun(std::vector& collectors); + void startRun(RefVector&& collectors); /// close the logs file at the end of a run void stopRun(); /// collect min/max/median walker data and write buffered walker log data to file - void writeBuffers(std::vector& collectors); + void writeBuffers(); private: /// check consistency of walker buffer row sizes - void checkCollectors(std::vector& collectors); + void checkCollectors(const RefVector& collectors) const; /// open the logs file - void openFile(std::vector& collectors); + void openFile(const RefVector& collectors); /// close the logs file void closeFile(); /// open the logs file (HDF format) - void openHDFFile(std::vector& collectors); + void openHDFFile(const RefVector& collectors); /// write data buffers to the logs file (HDF format) - void writeBuffersHDF(std::vector& collectors); + void writeBuffersHDF(); /// close the logs file (HDF format) void closeHDFFile(); diff --git a/src/QMCDrivers/tests/test_WalkerLogCollector.cpp b/src/QMCDrivers/tests/test_WalkerLogCollector.cpp index 6ee4a5e3ab..4d3e75c478 100644 --- a/src/QMCDrivers/tests/test_WalkerLogCollector.cpp +++ b/src/QMCDrivers/tests/test_WalkerLogCollector.cpp @@ -76,9 +76,8 @@ TEST_CASE("WalkerLogCollector::collect", "[estimators]") walker.DataSet.allocate(); } - WalkerLogCollector wlc; - wlc.state.logs_active = true; - wlc.state.step_period = 1; + WalkerLogState state{true, 1, false}; + WalkerLogCollector wlc(state); auto& bsi = wlc.walker_property_int_buffer; auto& bsr = wlc.walker_property_real_buffer;