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

add batched evaluateVGLWithSpin to SpinorSet #3730

Merged
merged 8 commits into from
Jan 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 28 additions & 15 deletions src/QMCWaveFunctions/SPOSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ void SPOSet::evaluateVGL_spin(const ParticleSet& P,
ValueVector_t& d2psi,
ValueVector_t& dspin)
{
APP_ABORT("Need specialization of SPOSet::evaluateVGL_spin");
throw std::runtime_error("Need specialization of SPOSet::evaluateVGL_spin");
}

void SPOSet::mw_evaluateVGL(const RefVectorWithLeader<SPOSet>& spo_list,
Expand All @@ -83,6 +83,20 @@ void SPOSet::mw_evaluateVGL(const RefVectorWithLeader<SPOSet>& spo_list,
spo_list[iw].evaluateVGL(P_list[iw], iat, psi_v_list[iw], dpsi_v_list[iw], d2psi_v_list[iw]);
}

void SPOSet::mw_evaluateVGLWithSpin(const RefVectorWithLeader<SPOSet>& spo_list,
const RefVectorWithLeader<ParticleSet>& P_list,
int iat,
const RefVector<ValueVector_t>& psi_v_list,
const RefVector<GradVector_t>& dpsi_v_list,
const RefVector<ValueVector_t>& d2psi_v_list,
const RefVector<ValueVector_t>& dspin_v_list) const
{
assert(this == &spo_list.getLeader());
#pragma omp parallel for
for (int iw = 0; iw < spo_list.size(); iw++)
spo_list[iw].evaluateVGL_spin(P_list[iw], iat, psi_v_list[iw], dpsi_v_list[iw], d2psi_v_list[iw], dspin_v_list[iw]);
}

void SPOSet::mw_evaluateVGLandDetRatioGrads(const RefVectorWithLeader<SPOSet>& spo_list,
const RefVectorWithLeader<ParticleSet>& P_list,
int iat,
Expand All @@ -109,7 +123,7 @@ void SPOSet::mw_evaluateVGLandDetRatioGrads(const RefVectorWithLeader<SPOSet>& s

void SPOSet::evaluateThirdDeriv(const ParticleSet& P, int first, int last, GGGMatrix_t& grad_grad_grad_logdet)
{
APP_ABORT("Need specialization of SPOSet::evaluateThirdDeriv(). \n");
throw std::runtime_error("Need specialization of SPOSet::evaluateThirdDeriv(). \n");
}

void SPOSet::evaluate_notranspose_spin(const ParticleSet& P,
Expand All @@ -120,7 +134,8 @@ void SPOSet::evaluate_notranspose_spin(const ParticleSet& P,
ValueMatrix_t& d2logdet,
ValueMatrix_t& dspinlogdet)
{
APP_ABORT("Need specialization of " + className + "::evaluate_notranspose_spin(P,iat,psi,dpsi,d2logdet, dspin_logdet) (vector quantities)\n");
throw std::runtime_error("Need specialization of " + className +
"::evaluate_notranspose_spin(P,iat,psi,dpsi,d2logdet, dspin_logdet) (vector quantities)\n");
}

void SPOSet::mw_evaluate_notranspose(const RefVectorWithLeader<SPOSet>& spo_list,
Expand All @@ -144,7 +159,7 @@ void SPOSet::evaluate_notranspose(const ParticleSet& P,
GradMatrix_t& dlogdet,
HessMatrix_t& grad_grad_logdet)
{
APP_ABORT("Need specialization of SPOSet::evaluate_notranspose() for grad_grad_logdet. \n");
throw std::runtime_error("Need specialization of SPOSet::evaluate_notranspose() for grad_grad_logdet. \n");
}

void SPOSet::evaluate_notranspose(const ParticleSet& P,
Expand All @@ -155,13 +170,13 @@ void SPOSet::evaluate_notranspose(const ParticleSet& P,
HessMatrix_t& grad_grad_logdet,
GGGMatrix_t& grad_grad_grad_logdet)
{
APP_ABORT("Need specialization of SPOSet::evaluate_notranspose() for grad_grad_grad_logdet. \n");
throw std::runtime_error("Need specialization of SPOSet::evaluate_notranspose() for grad_grad_grad_logdet. \n");
}


std::unique_ptr<SPOSet> SPOSet::makeClone() const
{
APP_ABORT("Missing SPOSet::makeClone for " + className);
throw std::runtime_error("Missing SPOSet::makeClone for " + className);
return std::unique_ptr<SPOSet>();
}

Expand All @@ -179,7 +194,7 @@ void SPOSet::evaluateVGH(const ParticleSet& P,
GradVector_t& dpsi,
HessVector_t& grad_grad_psi)
{
APP_ABORT("Need specialization of " + className + "::evaluate(P,iat,psi,dpsi,dhpsi) (vector quantities)\n");
throw std::runtime_error("Need specialization of " + className + "::evaluate(P,iat,psi,dpsi,dhpsi) (vector quantities)\n");
}

void SPOSet::evaluateVGHGH(const ParticleSet& P,
Expand All @@ -189,7 +204,7 @@ void SPOSet::evaluateVGHGH(const ParticleSet& P,
HessVector_t& grad_grad_psi,
GGGVector_t& grad_grad_grad_psi)
{
APP_ABORT("Need specialization of " + className + "::evaluate(P,iat,psi,dpsi,dhpsi,dghpsi) (vector quantities)\n");
throw std::runtime_error("Need specialization of " + className + "::evaluate(P,iat,psi,dpsi,dhpsi,dghpsi) (vector quantities)\n");
}

void SPOSet::evaluateGradSource(const ParticleSet& P,
Expand All @@ -199,7 +214,7 @@ void SPOSet::evaluateGradSource(const ParticleSet& P,
int iat_src,
GradMatrix_t& gradphi)
{
APP_ABORT("SPOSetBase::evalGradSource is not implemented");
throw std::runtime_error("SPOSetBase::evalGradSource is not implemented");
}

void SPOSet::evaluateGradSource(const ParticleSet& P,
Expand All @@ -211,24 +226,22 @@ void SPOSet::evaluateGradSource(const ParticleSet& P,
HessMatrix_t& grad_grad_phi,
GradMatrix_t& grad_lapl_phi)
{
APP_ABORT("SPOSetBase::evalGradSource is not implemented");
throw std::runtime_error("SPOSetBase::evalGradSource is not implemented");
}

void SPOSet::evaluate_spin(const ParticleSet& P, int iat, ValueVector_t& psi, ValueVector_t& dpsi)
{
APP_ABORT("Need specialization of " + className + "::evaluate_spin(P,iat,psi,dpsi) (vector quantities)\n");
throw std::runtime_error("Need specialization of " + className + "::evaluate_spin(P,iat,psi,dpsi) (vector quantities)\n");
}

#ifdef QMC_CUDA

void SPOSet::evaluate(const ParticleSet& P, PosType& r, ValueVector_t& psi)
{
APP_ABORT("Need specialization for SPOSet::evaluate(const ParticleSet& P, PosType &r)\n");
throw std::runtime_error("Need specialization for SPOSet::evaluate(const ParticleSet& P, PosType &r)\n");
}

void SPOSet::evaluate(std::vector<Walker_t*>& walkers,
int iat,
gpu::device_vector<CTS::ValueType*>& phi)
void SPOSet::evaluate(std::vector<Walker_t*>& walkers, int iat, gpu::device_vector<CTS::ValueType*>& phi)
{
app_error() << "Need specialization of vectorized evaluate in SPOSet.\n";
app_error() << "Required CUDA functionality not implemented. Contact developers.\n";
Expand Down
21 changes: 18 additions & 3 deletions src/QMCWaveFunctions/SPOSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,23 @@ class SPOSet : public QMCTraits
const RefVector<GradVector_t>& dpsi_v_list,
const RefVector<ValueVector_t>& d2psi_v_list) const;

/** evaluate the values, gradients and laplacians and spin gradient of this single-particle orbital sets of multiple walkers
* @param spo_list the list of SPOSet pointers in a walker batch
* @param P_list the list of ParticleSet pointers in a walker batch
* @param iat active particle
* @param psi_v_list the list of value vector pointers in a walker batch
* @param dpsi_v_list the list of gradient vector pointers in a walker batch
* @param d2psi_v_list the list of laplacian vector pointers in a walker batch
* @param dspin_v_list the list of spin gradients vector pointers in a walker batch
*/
virtual void mw_evaluateVGLWithSpin(const RefVectorWithLeader<SPOSet>& spo_list,
const RefVectorWithLeader<ParticleSet>& P_list,
int iat,
const RefVector<ValueVector_t>& psi_v_list,
const RefVector<GradVector_t>& dpsi_v_list,
const RefVector<ValueVector_t>& d2psi_v_list,
const RefVector<ValueVector_t>& dspin_v_list) const;

/** evaluate the values, gradients and laplacians of this single-particle orbital sets
* and determinant ratio and grads of multiple walkers
* @param spo_list the list of SPOSet pointers in a walker batch
Expand Down Expand Up @@ -486,9 +503,7 @@ class SPOSet : public QMCTraits
//////////////////////////////////////////
virtual void reserve(PointerPool<gpu::device_vector<CTS::ValueType>>& pool) {}

virtual void evaluate(std::vector<Walker_t*>& walkers,
int iat,
gpu::device_vector<CTS::ValueType*>& phi);
virtual void evaluate(std::vector<Walker_t*>& walkers, int iat, gpu::device_vector<CTS::ValueType*>& phi);

virtual void evaluate(std::vector<Walker_t*>& walkers,
std::vector<PosType>& new_pos,
Expand Down
88 changes: 87 additions & 1 deletion src/QMCWaveFunctions/SpinorSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
// This file is distributed under the University of Illinois/NCSA Open Source License.
// See LICENSE file in top directory for details.
//
// Copyright (c) 2016 Jeongnim Kim and QMCPACK developers.
// Copyright (c) 2022 QMCPACK developers
//
// File developed by: Raymond Clay III, [email protected], Sandia National Laboratories
// Cody A. Melton, [email protected], Sandia National Laboratories
//
// File created by: Raymond Clay III, [email protected], Sandia National Laboratories
//////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -135,6 +136,91 @@ void SpinorSet::evaluateVGL_spin(const ParticleSet& P,
dspin = eye * (eis * psi_work_up - emis * psi_work_down);
}

void SpinorSet::mw_evaluateVGLWithSpin(const RefVectorWithLeader<SPOSet>& spo_list,
const RefVectorWithLeader<ParticleSet>& P_list,
int iat,
const RefVector<ValueVector_t>& psi_v_list,
const RefVector<GradVector_t>& dpsi_v_list,
const RefVector<ValueVector_t>& d2psi_v_list,
const RefVector<ValueVector_t>& dspin_v_list) const
{
auto& spo_leader = spo_list.getCastedLeader<SpinorSet>();
auto& P_leader = P_list.getLeader();
assert(this == &spo_leader);

IndexType nw = spo_list.size();
SPOSet& up_spo_leader = *(spo_leader.spo_up);
SPOSet& dn_spo_leader = *(spo_leader.spo_dn);
RefVectorWithLeader<SPOSet> up_spo_list(up_spo_leader);
RefVectorWithLeader<SPOSet> dn_spo_list(dn_spo_leader);
up_spo_list.reserve(nw);
dn_spo_list.reserve(nw);

std::vector<ValueVector_t> mw_up_psi_work, mw_dn_psi_work;
std::vector<GradVector_t> mw_up_dpsi_work, mw_dn_dpsi_work;
std::vector<ValueVector_t> mw_up_d2psi_work, mw_dn_d2psi_work;
mw_up_psi_work.reserve(nw);
mw_up_dpsi_work.reserve(nw);
mw_up_d2psi_work.reserve(nw);
mw_dn_psi_work.reserve(nw);
mw_dn_dpsi_work.reserve(nw);
mw_dn_d2psi_work.reserve(nw);

RefVector<ValueVector_t> up_psi_v_list, dn_psi_v_list;
RefVector<GradVector_t> up_dpsi_v_list, dn_dpsi_v_list;
RefVector<ValueVector_t> up_d2psi_v_list, dn_d2psi_v_list;
up_psi_v_list.reserve(nw);
up_dpsi_v_list.reserve(nw);
up_d2psi_v_list.reserve(nw);
dn_psi_v_list.reserve(nw);
dn_dpsi_v_list.reserve(nw);
dn_d2psi_v_list.reserve(nw);

ValueVector_t tmp_val_vec(OrbitalSetSize);
GradVector_t tmp_grad_vec(OrbitalSetSize);
for (int iw = 0; iw < nw; iw++)
{
SpinorSet& spinor = spo_list.getCastedElement<SpinorSet>(iw);
up_spo_list.emplace_back(*(spinor.spo_up));
dn_spo_list.emplace_back(*(spinor.spo_dn));

mw_up_psi_work.emplace_back(tmp_val_vec);
up_psi_v_list.emplace_back(mw_up_psi_work.back());
mw_dn_psi_work.emplace_back(tmp_val_vec);
dn_psi_v_list.emplace_back(mw_dn_psi_work.back());

mw_up_dpsi_work.emplace_back(tmp_grad_vec);
up_dpsi_v_list.emplace_back(mw_up_dpsi_work.back());
mw_dn_dpsi_work.emplace_back(tmp_grad_vec);
dn_dpsi_v_list.emplace_back(mw_dn_dpsi_work.back());

mw_up_d2psi_work.emplace_back(tmp_val_vec);
up_d2psi_v_list.emplace_back(mw_up_d2psi_work.back());
mw_dn_d2psi_work.emplace_back(tmp_val_vec);
dn_d2psi_v_list.emplace_back(mw_dn_d2psi_work.back());
}

up_spo_leader.mw_evaluateVGL(up_spo_list, P_list, iat, up_psi_v_list, up_dpsi_v_list, up_d2psi_v_list);
dn_spo_leader.mw_evaluateVGL(dn_spo_list, P_list, iat, dn_psi_v_list, dn_dpsi_v_list, dn_d2psi_v_list);

#pragma omp parallel for
for (int iw = 0; iw < nw; iw++)
{
ParticleSet::Scalar_t s = P_list[iw].activeSpin(iat);
RealType coss = std::cos(s);
RealType sins = std::sin(s);

ValueType eis(coss, sins);
ValueType emis(coss, -sins);
ValueType eye(0, 1.0);

psi_v_list[iw].get() = eis * up_psi_v_list[iw].get() + emis * dn_psi_v_list[iw].get();
dpsi_v_list[iw].get() = eis * up_dpsi_v_list[iw].get() + emis * dn_dpsi_v_list[iw].get();
d2psi_v_list[iw].get() = eis * up_d2psi_v_list[iw].get() + emis * dn_d2psi_v_list[iw].get();
dspin_v_list[iw].get() = eye * (eis * up_psi_v_list[iw].get() - emis * dn_psi_v_list[iw].get());
}
}

void SpinorSet::evaluate_notranspose(const ParticleSet& P,
int first,
int last,
Expand Down
20 changes: 19 additions & 1 deletion src/QMCWaveFunctions/SpinorSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
// This file is distributed under the University of Illinois/NCSA Open Source License.
// See LICENSE file in top directory for details.
//
// Copyright (c) 2016 Jeongnim Kim and QMCPACK developers.
// Copyright (c) 2022 QMCPACK developers
//
// File developed by: Raymond Clay III, [email protected], Sandia National Laboratories
// Cody A. Melton, [email protected], Sandia National Laboratories
//
// File created by: Raymond Clay III, [email protected], Sandia National Laboratories
//////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -79,6 +80,23 @@ class SpinorSet : public SPOSet
ValueVector_t& d2psi,
ValueVector_t& dspin) override;

/** evaluate the values, gradients and laplacians and spin gradient of this single-particle orbital sets of multiple walkers
* @param spo_list the list of SPOSet pointers in a walker batch
* @param P_list the list of ParticleSet pointers in a walker batch
* @param iat active particle
* @param psi_v_list the list of value vector pointers in a walker batch
* @param dpsi_v_list the list of gradient vector pointers in a walker batch
* @param d2psi_v_list the list of laplacian vector pointers in a walker batch
* @param dspin_v_list the list of spin gradients vector pointers in a walker batch
*/
void mw_evaluateVGLWithSpin(const RefVectorWithLeader<SPOSet>& spo_list,
const RefVectorWithLeader<ParticleSet>& P_list,
int iat,
const RefVector<ValueVector_t>& psi_v_list,
const RefVector<GradVector_t>& dpsi_v_list,
const RefVector<ValueVector_t>& d2psi_v_list,
const RefVector<ValueVector_t>& dspin_v_list) const override;

/** evaluate the values, gradients and laplacians of this single-particle orbital for [first,last) particles
* @param P current ParticleSet
* @param first starting index of the particles
Expand Down
2 changes: 1 addition & 1 deletion src/QMCWaveFunctions/WaveFunctionComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ class WaveFunctionComponent : public QMCTraits
std::vector<ComplexType>& spingrad_new) const
{
mw_ratioGrad(wfc_list, p_list, iat, ratios, grad_new);
};
}

/** a move for iat-th particle is accepted. Update the current content.
* @param P target ParticleSet
Expand Down
Binary file modified src/QMCWaveFunctions/tests/lcao_spinor.h5
Binary file not shown.
23 changes: 17 additions & 6 deletions src/QMCWaveFunctions/tests/lcao_spinor_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,13 @@ def val(self,pos):
norm = self.norm()
Copy link
Contributor

Choose a reason for hiding this comment

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

I saw above an h5 file was removed. No more needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the file wasn't removed, it just got overwritten. The lcao_spinor_test.py writes the h5 file that is read by SPOSetBuilder in the test_MO_spinor.py. When I reran it to add new reference values, it just overwrote that file

return norm *pos[0]**self.i * pos[1]**self.j * pos[2]**self.k * np.exp(-self.expt * r * r)

def get_reference_values():
pos = np.array([0.1,-0.3, 1.7])
s = 0.6

def get_reference_values(pos, s):
cs = np.cos(s)
ss = np.sin(s)

print("Position: {}".format(pos))
print("Spin: {}".format(s))

#gaussian basis function values
g = cartGauss(2.5,0,0,0,0) #s function
dr = 1e-6
Expand Down Expand Up @@ -215,5 +215,16 @@ def get_reference_values():
print(" Lap : {}".format(splap))
print(" SpinGrad: {}".format(spds))

write_h5_file()
get_reference_values()
print()
print()

if __name__ == "__main__":
write_h5_file()

pos = np.array([0.1,-0.3, 1.7])
s = 0.6
get_reference_values(pos,s)

pos = np.array([-0.4,1.5,-0.2])
s = -1.3
get_reference_values(pos,s)
Loading