Skip to content

Commit

Permalink
Merge pull request #5077 from ye-luo/more-guards
Browse files Browse the repository at this point in the history
Check SPOSet size against SD/MSD needs
  • Loading branch information
prckent authored Jul 4, 2024
2 parents 9c1bbf4 + fd50e32 commit 4cbe8ff
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 47 deletions.
8 changes: 0 additions & 8 deletions src/QMCWaveFunctions/Fermion/DiracDeterminant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,6 @@ DiracDeterminant<DU_TYPE>::DiracDeterminant(std::unique_ptr<SPOSet>&& spos,
RotatedSPOs* rot_spo = dynamic_cast<RotatedSPOs*>(Phi.get());
if (rot_spo)
rot_spo->buildOptVariables(NumPtcls);

if (Phi->getOrbitalSetSize() < NumPtcls)
{
std::ostringstream err_msg;
err_msg << "The SPOSet " << Phi->getName() << " only has " << Phi->getOrbitalSetSize() << " orbitals "
<< "but this determinant needs at least " << NumPtcls << std::endl;
throw std::runtime_error(err_msg.str());
}
}

template<typename DU_TYPE>
Expand Down
97 changes: 60 additions & 37 deletions src/QMCWaveFunctions/Fermion/SlaterDetBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,14 @@ std::unique_ptr<DiracDeterminantBase> SlaterDetBuilder::putDeterminant(
std::unique_ptr<SPOSet> psi_clone(psi->makeClone());
psi_clone->checkObject();

if (const auto nptcl_group = targetPtcl.groupsize(spin_group); psi_clone->getOrbitalSetSize() < nptcl_group)
{
std::ostringstream err_msg;
err_msg << "The SPOSet " << psi_clone->getName() << " only has " << psi_clone->getOrbitalSetSize() << " orbitals "
<< "but this determinant needs at least " << nptcl_group << std::endl;
myComm->barrier_and_abort(err_msg.str());
}

const int firstIndex = targetPtcl.first(spin_group);
const int lastIndex = targetPtcl.last(spin_group);

Expand All @@ -356,7 +364,7 @@ std::unique_ptr<DiracDeterminantBase> SlaterDetBuilder::putDeterminant(
<< "and no larger than the electron count within a determinant!\n"
<< "Acceptable value [1," << lastIndex - firstIndex << "], "
<< "user input " + std::to_string(delay_rank);
APP_ABORT(err_msg.str());
myComm->barrier_and_abort(err_msg.str());
}
else if (delay_rank == 0)
{
Expand Down Expand Up @@ -394,21 +402,21 @@ std::unique_ptr<DiracDeterminantBase> SlaterDetBuilder::putDeterminant(
if (CPUOMPTargetVendorSelector::selectPlatform(useGPU) == PlatformKind::CUDA)
{
app_summary() << " Running on a GPU via CUDA/HIP acceleration and OpenMP offload." << std::endl;
adet = std::make_unique<DiracDeterminantBatched<PlatformKind::CUDA, QMCTraits::ValueType, QMCTraits::QTFull::ValueType>>(std::move(psi_clone),
firstIndex, lastIndex,
delay_rank,
matrix_inverter_kind);
adet = std::make_unique<DiracDeterminantBatched<PlatformKind::CUDA, QMCTraits::ValueType,
QMCTraits::QTFull::ValueType>>(std::move(psi_clone), firstIndex,
lastIndex, delay_rank,
matrix_inverter_kind);
}
else
#endif
#if defined(ENABLE_SYCL) && defined(ENABLE_OFFLOAD)
if (CPUOMPTargetVendorSelector::selectPlatform(useGPU) == PlatformKind::SYCL)
if (CPUOMPTargetVendorSelector::selectPlatform(useGPU) == PlatformKind::SYCL)
{
app_summary() << " Running on a GPU via SYCL acceleration and OpenMP offload." << std::endl;
adet = std::make_unique<DiracDeterminantBatched<PlatformKind::SYCL, QMCTraits::ValueType, QMCTraits::QTFull::ValueType>>(std::move(psi_clone),
firstIndex, lastIndex,
delay_rank,
matrix_inverter_kind);
adet = std::make_unique<DiracDeterminantBatched<PlatformKind::SYCL, QMCTraits::ValueType,
QMCTraits::QTFull::ValueType>>(std::move(psi_clone), firstIndex,
lastIndex, delay_rank,
matrix_inverter_kind);
}
else
#endif
Expand All @@ -420,8 +428,10 @@ std::unique_ptr<DiracDeterminantBase> SlaterDetBuilder::putDeterminant(
#else
app_summary() << " Running OpenMP offload code path on a CPU. " << std::endl;
#endif
adet = std::make_unique<DiracDeterminantBatched<PlatformKind::OMPTARGET, QMCTraits::ValueType, QMCTraits::QTFull::ValueType>>(std::move(psi_clone), firstIndex, lastIndex, delay_rank,
matrix_inverter_kind);
adet = std::make_unique<DiracDeterminantBatched<PlatformKind::OMPTARGET, QMCTraits::ValueType,
QMCTraits::QTFull::ValueType>>(std::move(psi_clone), firstIndex,
lastIndex, delay_rank,
matrix_inverter_kind);
}
}
else
Expand Down Expand Up @@ -487,10 +497,6 @@ std::unique_ptr<MultiSlaterDetTableMethod> SlaterDetBuilder::createMSDFast(

bool optimizeCI;

std::vector<int> nptcls(nGroups);
for (int grp = 0; grp < nGroups; grp++)
nptcls[grp] = targetPtcl.groupsize(grp);

std::vector<std::vector<ci_configuration>> uniqueConfgs(nGroups);
std::vector<std::string> CItags;

Expand All @@ -508,14 +514,20 @@ std::unique_ptr<MultiSlaterDetTableMethod> SlaterDetBuilder::createMSDFast(

std::unique_ptr<CSFData> csf_data_ptr;

std::string HDF5Path(getXMLAttributeValue(DetListNode, "href"));
if (!HDF5Path.empty())
{
app_log() << "Found Multideterminants in H5 File" << std::endl;
readDetListH5(cur, uniqueConfgs, C2nodes, CItags, C, optimizeCI, nptcls);
std::vector<int> nptcls(nGroups);
for (int grp = 0; grp < nGroups; grp++)
nptcls[grp] = targetPtcl.groupsize(grp);

std::string HDF5Path(getXMLAttributeValue(DetListNode, "href"));
if (!HDF5Path.empty())
{
app_log() << "Found Multideterminants in H5 File" << std::endl;
readDetListH5(cur, uniqueConfgs, C2nodes, CItags, C, optimizeCI, nptcls);
}
else
readDetList(cur, uniqueConfgs, C2nodes, CItags, C, optimizeCI, nptcls, csf_data_ptr);
}
else
readDetList(cur, uniqueConfgs, C2nodes, CItags, C, optimizeCI, nptcls, csf_data_ptr);

const auto maxloc = std::max_element(C.begin(), C.end(), [](ValueType const& lhs, ValueType const& rhs) {
return std::norm(lhs) < std::norm(rhs);
Expand All @@ -527,22 +539,35 @@ std::unique_ptr<MultiSlaterDetTableMethod> SlaterDetBuilder::createMSDFast(
std::vector<std::unique_ptr<MultiDiracDeterminant>> dets;
for (int grp = 0; grp < nGroups; grp++)
{
dets.emplace_back(std::make_unique<MultiDiracDeterminant>(std::move(spo_clones[grp]), spinor, targetPtcl.first(grp),
nptcls[grp]));
const auto nptcl_group = targetPtcl.groupsize(grp);
// convert ci_configuration to ci_configuration2
std::vector<ci_configuration2> list(uniqueConfgs[grp].size());
for (int i = 0; i < list.size(); i++)
{
list[i].occup.resize(nptcls[grp]);
int cnt = 0;
for (int k = 0; k < uniqueConfgs[grp][i].occup.size(); k++)
if (uniqueConfgs[grp][i].occup[k])
list[i].occup[cnt++] = k;
if (cnt != nptcls[grp])
std::ostringstream err_msg;
if (const auto orb_space_size = uniqueConfgs[grp][i].occup.size();
orb_space_size > spo_clones[grp]->getOrbitalSetSize())
err_msg << "The unique determinant " << i << " needs at least " << orb_space_size
<< " occupied and unoccupied single particle orbitals but SPOSet '" << spo_clones[grp]->getName()
<< "' only contains " << spo_clones[grp]->getOrbitalSetSize() << "." << std::endl;
else
{
APP_ABORT("Error in SlaterDetBuilder::createMSDFast for ptcl group "
<< grp << ", problems with ci configuration list. \n");
list[i].occup.resize(nptcl_group);
int cnt = 0;
for (int k = 0; k < orb_space_size; k++)
if (uniqueConfgs[grp][i].occup[k])
list[i].occup[cnt++] = k;
if (cnt != nptcl_group)
err_msg << "The unique determinant configuration " << i << " contains " << cnt
<< " occupied orbitals not matching " << nptcl_group << " particles." << std::endl;
}
if (const std::string msg = err_msg.str(); msg.length())
myComm->barrier_and_abort("SlaterDetBuilder::createMSDFast Issues found in the particle group " + std::to_string(grp) + " :\n" + msg);
}

dets.emplace_back(std::make_unique<MultiDiracDeterminant>(std::move(spo_clones[grp]), spinor, targetPtcl.first(grp),
nptcl_group));

// reorder unique determinants for a given spin based on the selected reference determinant
dets[grp]->createDetData(C2nodes[grp][refdet_id], list, C2nodes[grp], C2nodes_sorted[grp]);
}
Expand Down Expand Up @@ -601,14 +626,12 @@ std::unique_ptr<MultiSlaterDetTableMethod> SlaterDetBuilder::createMSDFast(
APP_ABORT("Currently, Using CSF is not available with MSJ Orbital Optimization!\n");

for (int grp = 0; grp < nGroups; grp++)
{
for (int i = 0; i < nptcls[grp]; i++)
for (int i = 0; i < targetPtcl.groupsize(grp); i++)
{
if (uniqueConfgs[grp][0].occup[i] != true)
APP_ABORT(
"The Hartee Fock Reference Determinant must be the first in the Multi-Slater expansion for the input!\n");
}
}
app_warning() << "Unrestricted Orbital Optimization will be performed. Spin symmetry is not guaranteed to be "
"preserved!\n";

Expand All @@ -628,7 +651,7 @@ bool SlaterDetBuilder::readDetList(xmlNodePtr cur,
std::vector<std::string>& CItags,
std::vector<ValueType>& coeff,
bool& optimizeCI,
std::vector<int>& nptcls,
const std::vector<int>& nptcls,
std::unique_ptr<CSFData>& csf_data_ptr) const
{
bool success = true;
Expand Down Expand Up @@ -998,7 +1021,7 @@ bool SlaterDetBuilder::readDetListH5(xmlNodePtr cur,
std::vector<std::string>& CItags,
std::vector<ValueType>& coeff,
bool& optimizeCI,
std::vector<int>& nptcls) const
const std::vector<int>& nptcls) const
{
bool success = true;
int extlevel(0);
Expand Down
4 changes: 2 additions & 2 deletions src/QMCWaveFunctions/Fermion/SlaterDetBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class SlaterDetBuilder : public WaveFunctionComponentBuilder
std::vector<std::string>& CItags,
std::vector<ValueType>& coeff,
bool& optimizeCI,
std::vector<int>& nptcls,
const std::vector<int>& nptcls,
std::unique_ptr<CSFData>& csf_data_ptr) const;

bool readDetListH5(xmlNodePtr cur,
Expand All @@ -99,7 +99,7 @@ class SlaterDetBuilder : public WaveFunctionComponentBuilder
std::vector<std::string>& CItags,
std::vector<ValueType>& coeff,
bool& optimizeCI,
std::vector<int>& nptcls) const;
const std::vector<int>& nptcls) const;

template<typename VT,
std::enable_if_t<(std::is_same<VT, ValueType>::value) && (std::is_floating_point<VT>::value), int> = 0>
Expand Down

0 comments on commit 4cbe8ff

Please sign in to comment.