Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move NonLocalTOperator objects from Hamiltonian to Drivers #5137

Merged
merged 13 commits into from
Aug 22, 2024
Merged
1 change: 0 additions & 1 deletion src/QMCDrivers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ set(QMCDRIVERS
WaveFunctionTester.cpp
WalkerControlBase.cpp
CloneManager.cpp
ContextForSteps.cpp
Crowd.cpp
QMCUpdateBase.cpp
GreenFunctionModifiers/DriftModifierBuilder.cpp
Expand Down
21 changes: 0 additions & 21 deletions src/QMCDrivers/ContextForSteps.cpp

This file was deleted.

43 changes: 0 additions & 43 deletions src/QMCDrivers/ContextForSteps.h

This file was deleted.

66 changes: 39 additions & 27 deletions src/QMCDrivers/DMC/DMCBatched.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,25 @@
#include "TauParams.hpp"
#include "WalkerLogManager.h"
#include "CPU/math.hpp"
#include "QMCHamiltonians/NonLocalTOperator.h"

namespace qmcplusplus
{
using std::placeholders::_1;
using WP = WalkerProperties::Indexes;
using PsiValue = TrialWaveFunction::PsiValue;

class DMCBatched::DMCContextForSteps : public ContextForSteps
{
public:
DMCContextForSteps(RandomBase<FullPrecRealType>& random_gen, const NonLocalTOperator& non_local_ops)
: ContextForSteps(random_gen), non_local_ops(non_local_ops)
{}

///non local operator
NonLocalTOperator non_local_ops;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be protected or private?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ContextForSteps and its derived class are intended to be just a struct. Marking it private and adding an access function are unnecessary.

};

/** Constructor maintains proper ownership of input parameters
*
* Note you must call the Base constructor before the derived class sets QMCType
Expand Down Expand Up @@ -67,18 +79,12 @@ DMCBatched::DMCBatched(const ProjectData& project_data,

DMCBatched::~DMCBatched() = default;

void DMCBatched::setNonLocalMoveHandler(QMCHamiltonian& hamiltonian)
{
hamiltonian.setNonLocalMoves(dmcdriver_input_.get_non_local_move(), qmcdriver_input_.get_tau(),
dmcdriver_input_.get_alpha(), dmcdriver_input_.get_gamma());
}

template<CoordsType CT>
void DMCBatched::advanceWalkers(const StateForThread& sft,
Crowd& crowd,
DriverTimers& timers,
DMCTimers& dmc_timers,
ContextForSteps& step_context,
DMCContextForSteps& step_context,
bool recompute,
bool accumulate_this_step)
{
Expand Down Expand Up @@ -258,7 +264,9 @@ void DMCBatched::advanceWalkers(const StateForThread& sft,
ScopedTimer ham_local(timers.hamiltonian_timer);

std::vector<QMCHamiltonian::FullPrecRealType> new_energies(
ham_dispatcher.flex_evaluateWithToperator(walker_hamiltonians, walker_twfs, walker_elecs));
step_context.non_local_ops.getMoveKind() == TmoveKind::OFF
? ham_dispatcher.flex_evaluate(walker_hamiltonians, walker_twfs, walker_elecs)
: ham_dispatcher.flex_evaluateWithToperator(walker_hamiltonians, walker_twfs, walker_elecs));

auto resetSigNLocalEnergy = [](MCPWalker& walker, TrialWaveFunction& twf, auto local_energy, auto rr_acc,
auto rr_prop) {
Expand Down Expand Up @@ -312,7 +320,8 @@ void DMCBatched::advanceWalkers(const StateForThread& sft,

for (int iw = 0; iw < walkers.size(); ++iw)
{
walker_non_local_moves_accepted[iw] = walker_hamiltonians[iw].makeNonLocalMoves(walker_elecs[iw]);
walker_non_local_moves_accepted[iw] =
walker_hamiltonians[iw].makeNonLocalMoves(walker_elecs[iw], step_context.non_local_ops);

if (walker_non_local_moves_accepted[iw] > 0)
{
Expand All @@ -337,23 +346,23 @@ template void DMCBatched::advanceWalkers<CoordsType::POS>(const StateForThread&
Crowd& crowd,
DriverTimers& timers,
DMCTimers& dmc_timers,
ContextForSteps& step_context,
DMCContextForSteps& step_context,
bool recompute,
bool accumulate_this_step);

template void DMCBatched::advanceWalkers<CoordsType::POS_SPIN>(const StateForThread& sft,
Crowd& crowd,
DriverTimers& timers,
DMCTimers& dmc_timers,
ContextForSteps& step_context,
DMCContextForSteps& step_context,
bool recompute,
bool accumulate_this_step);

void DMCBatched::runDMCStep(int crowd_id,
const StateForThread& sft,
DriverTimers& timers,
DMCTimers& dmc_timers,
UPtrVector<ContextForSteps>& context_for_steps,
UPtrVector<DMCContextForSteps>& context_for_steps,
UPtrVector<Crowd>& crowds)
{
Crowd& crowd = *(crowds[crowd_id]);
Expand Down Expand Up @@ -394,7 +403,7 @@ void DMCBatched::process(xmlNodePtr node)
qmcdriver_input_.get_requested_steps(), qmcdriver_input_.get_max_blocks());

initPopulationAndCrowds(awc);
createRngsStepContexts(crowds_.size());
createStepContexts(crowds_.size());
}
catch (const UniformCommunicateError& ue)
{
Expand Down Expand Up @@ -463,7 +472,8 @@ bool DMCBatched::run()
{ // walker initialization
ScopedTimer local_timer(timers_.init_walkers_timer);
ParallelExecutor<> section_start_task;
section_start_task(crowds_.size(), initialLogEvaluation, std::ref(crowds_), std::ref(step_contexts_),
auto step_contexts_refs = getContextForStepsRefs();
section_start_task(crowds_.size(), initialLogEvaluation, std::ref(crowds_), std::ref(step_contexts_refs),
serializing_crowd_walkers_);

FullPrecRealType energy, variance;
Expand Down Expand Up @@ -504,11 +514,6 @@ bool DMCBatched::run()
{
ScopedTimer local_timer(timers_.run_steps_timer);

// ensure all the live walkers carry the up-to-date T-move settings.
// Such info should be removed from each NLPP eventually and be kept in the driver.
for (UPtr<QMCHamiltonian>& ham : population_.get_hamiltonians())
setNonLocalMoveHandler(*ham);

dmc_state.step = step;
dmc_state.global_step = global_step;
crowd_task(crowds_.size(), runDMCStep, dmc_state, timers_, dmc_timers_, std::ref(step_contexts_),
Expand Down Expand Up @@ -559,18 +564,25 @@ bool DMCBatched::run()
return finalize(num_blocks, true);
}

/** Creates Random Number generators for crowds and step contexts
*
* This is quite dangerous in that number of crowds can be > omp_get_max_threads()
* This is used instead of actually passing number of threads/crowds
* controlling threads all over RandomNumberControl.
*/
void DMCBatched::createRngsStepContexts(int num_crowds)
RefVector<QMCDriverNew::ContextForSteps> DMCBatched::getContextForStepsRefs() const
{
RefVector<ContextForSteps> refs;
refs.reserve(step_contexts_.size());
for (auto& one_context : step_contexts_)
refs.push_back(*one_context);
return refs;
}

void DMCBatched::createStepContexts(int num_crowds)
{
assert(num_crowds <= rngs_.size());
step_contexts_.resize(num_crowds);
NonLocalTOperator non_local_ops;
if (population_.get_golden_hamiltonian().hasPhysicalNLPP())
non_local_ops.thingsThatShouldBeInMyConstructor(dmcdriver_input_.get_non_local_move(), qmcdriver_input_.get_tau(),
dmcdriver_input_.get_alpha(), dmcdriver_input_.get_gamma());
for (int i = 0; i < num_crowds; ++i)
step_contexts_[i] = std::make_unique<ContextForSteps>(rngs_[i]);
step_contexts_[i] = std::make_unique<DMCContextForSteps>(rngs_[i], non_local_ops);
}

} // namespace qmcplusplus
34 changes: 17 additions & 17 deletions src/QMCDrivers/DMC/DMCBatched.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#include "QMCDrivers/QMCDriverNew.h"
#include "QMCDrivers/DMC/DMCDriverInput.h"
#include "QMCDrivers/MCPopulation.h"
#include "QMCDrivers/ContextForSteps.h"
#include "Particle/MCCoords.hpp"

namespace qmcplusplus
Expand Down Expand Up @@ -118,25 +117,17 @@ class DMCBatched : public QMCDriverNew

bool run() override;

// This is the task body executed at crowd scope
// it does not have access to object members by design
static void runDMCStep(int crowd_id,
const StateForThread& sft,
DriverTimers& timers,
DMCTimers& dmc_timers,
UPtrVector<ContextForSteps>& move_context,
UPtrVector<Crowd>& crowds);


QMCRunType getRunType() override { return QMCRunType::DMC_BATCH; }

void setNonLocalMoveHandler(QMCHamiltonian& hamiltonian);

private:
/// forward declaration. DMC specialized ContextForSteps
class DMCContextForSteps;

const DMCDriverInput dmcdriver_input_;
/// Per crowd, driver-specific move contexts
UPtrVector<ContextForSteps> step_contexts_;

UPtrVector<DMCContextForSteps> step_contexts_;
/// obtain reference vector of step contexts
RefVector<ContextForSteps> getContextForStepsRefs() const;
/** I think its better if these have there own type and variable name
*/
DMCTimers dmc_timers_;
Expand All @@ -148,14 +139,23 @@ class DMCBatched : public QMCDriverNew
std::unique_ptr<WalkerControl> walker_controller_;

// create Rngs and StepContests
void createRngsStepContexts(int num_crowds);
void createStepContexts(int num_crowds);

// This is the task body executed at crowd scope
// it does not have access to object members by design
static void runDMCStep(int crowd_id,
const StateForThread& sft,
DriverTimers& timers,
DMCTimers& dmc_timers,
UPtrVector<DMCContextForSteps>& move_context,
UPtrVector<Crowd>& crowds);

template<CoordsType CT>
static void advanceWalkers(const StateForThread& sft,
Crowd& crowd,
DriverTimers& timers,
DMCTimers& dmc_timers,
ContextForSteps& move_context,
DMCContextForSteps& move_context,
bool recompute,
bool accumulate_this_step);

Expand Down
4 changes: 2 additions & 2 deletions src/QMCDrivers/DMC/DMCUpdateAll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
}

// evaluate Hamiltonian
enew = H.evaluateWithToperator(W);
enew = non_local_ops_.getMoveKind() == TmoveKind::OFF ? H.evaluate(W) : H.evaluateWithToperator(W);
H.auxHevaluate(W, thisWalker);
H.saveProperty(thisWalker.getPropertyBase());

Expand All @@ -106,7 +106,7 @@
thisWalker.Properties(WP::R2PROPOSED) = rr_proposed;
}

const int NonLocalMoveAcceptedTemp = H.makeNonLocalMoves(W);
const int NonLocalMoveAcceptedTemp = H.makeNonLocalMoves(W, non_local_ops_);

Check warning on line 109 in src/QMCDrivers/DMC/DMCUpdateAll.cpp

View check run for this annotation

Codecov / codecov/patch

src/QMCDrivers/DMC/DMCUpdateAll.cpp#L109

Added line #L109 was not covered by tests
if (NonLocalMoveAcceptedTemp > 0)
{
W.saveWalker(thisWalker);
Expand Down
8 changes: 4 additions & 4 deletions src/QMCDrivers/DMC/DMCUpdatePbyPFast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ void DMCUpdatePbyPWithRejectionFast::advanceWalker(Walker_t& thisWalker, bool re
}
{
ScopedTimer local_timer(myTimers[DMC_hamiltonian]);
enew = H.evaluateWithToperator(W);
enew = non_local_ops_.getMoveKind() == TmoveKind::OFF ? H.evaluate(W) : H.evaluateWithToperator(W);
}
thisWalker.resetProperty(logpsi, Psi.getPhase(), enew, rr_accepted, rr_proposed, 1.0);
thisWalker.Weight *= branchEngine->branchWeight(enew, eold);
Expand Down Expand Up @@ -171,11 +171,11 @@ void DMCUpdatePbyPWithRejectionFast::advanceWalker(Walker_t& thisWalker, bool re
#if !defined(REMOVE_TRACEMANAGER)
Traces->buffer_sample(W.current_step);
#endif
if(wlog_collector)
wlog_collector->collect(thisWalker,W,Psi,H);
if (wlog_collector)
wlog_collector->collect(thisWalker, W, Psi, H);
{
ScopedTimer local_timer(myTimers[DMC_tmoves]);
const int NonLocalMoveAcceptedTemp = H.makeNonLocalMoves(W);
const int NonLocalMoveAcceptedTemp = H.makeNonLocalMoves(W, non_local_ops_);
if (NonLocalMoveAcceptedTemp > 0)
{
RealType logpsi = Psi.updateBuffer(W, w_buffer, false);
Expand Down
4 changes: 2 additions & 2 deletions src/QMCDrivers/DMC/DMCUpdatePbyPL2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ void DMCUpdatePbyPL2::advanceWalker(Walker_t& thisWalker, bool recompute)
}
{
ScopedTimer local_timer(myTimers[DMC_hamiltonian]);
enew = H.evaluateWithToperator(W);
enew = non_local_ops_.getMoveKind() == TmoveKind::OFF ? H.evaluate(W) : H.evaluateWithToperator(W);
}
thisWalker.resetProperty(logpsi, Psi.getPhase(), enew, rr_accepted, rr_proposed, 1.0);
thisWalker.Weight *= branchEngine->branchWeight(enew, eold);
Expand Down Expand Up @@ -241,7 +241,7 @@ void DMCUpdatePbyPL2::advanceWalker(Walker_t& thisWalker, bool recompute)
#endif
{
ScopedTimer local_timer(myTimers[DMC_tmoves]);
const int NonLocalMoveAcceptedTemp = H.makeNonLocalMoves(W);
const int NonLocalMoveAcceptedTemp = H.makeNonLocalMoves(W, non_local_ops_);
if (NonLocalMoveAcceptedTemp > 0)
{
RealType logpsi = Psi.updateBuffer(W, w_buffer, false);
Expand Down
4 changes: 2 additions & 2 deletions src/QMCDrivers/DMC/SODMCUpdatePbyPFast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ void SODMCUpdatePbyPWithRejectionFast::advanceWalker(Walker_t& thisWalker, bool
}
{
ScopedTimer local_timer(myTimers[SODMC_hamiltonian]);
enew = H.evaluateWithToperator(W);
enew = non_local_ops_.getMoveKind() == TmoveKind::OFF ? H.evaluate(W) : H.evaluateWithToperator(W);
}
thisWalker.resetProperty(logpsi, Psi.getPhase(), enew, rr_accepted, rr_proposed, 1.0);
thisWalker.Weight *= branchEngine->branchWeight(enew, eold);
Expand Down Expand Up @@ -181,7 +181,7 @@ void SODMCUpdatePbyPWithRejectionFast::advanceWalker(Walker_t& thisWalker, bool
#endif
{
ScopedTimer local_timer(myTimers[SODMC_tmoves]);
const int NonLocalMoveAcceptedTemp = H.makeNonLocalMoves(W);
const int NonLocalMoveAcceptedTemp = H.makeNonLocalMoves(W, non_local_ops_);
if (NonLocalMoveAcceptedTemp > 0)
{
RealType logpsi = Psi.updateBuffer(W, w_buffer, false);
Expand Down
5 changes: 3 additions & 2 deletions src/QMCDrivers/QMCDriverNew.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,14 +256,15 @@ void QMCDriverNew::makeLocalWalkers(IndexType nwalkers, RealType reserve)

void QMCDriverNew::initialLogEvaluation(int crowd_id,
UPtrVector<Crowd>& crowds,
UPtrVector<ContextForSteps>& context_for_steps,
const RefVector<ContextForSteps>& context_for_steps,
const bool serializing_crowd_walkers)
{
Crowd& crowd = *(crowds[crowd_id]);
if (crowd.size() == 0)
return;

crowd.setRNGForHamiltonian(context_for_steps[crowd_id]->get_random_gen());
ContextForSteps& my_context(context_for_steps[crowd_id]);
crowd.setRNGForHamiltonian(my_context.get_random_gen());
const PSdispatcher ps_dispatcher(!serializing_crowd_walkers);
const TWFdispatcher twf_dispatcher(!serializing_crowd_walkers);
const Hdispatcher ham_dispatcher(!serializing_crowd_walkers);
Expand Down
Loading
Loading