QMCPACK
SlaterDetBuilder Class Reference

derived class from WaveFunctionComponentBuilder More...

+ Inheritance diagram for SlaterDetBuilder:
+ Collaboration diagram for SlaterDetBuilder:

Public Member Functions

 SlaterDetBuilder (Communicate *comm, SPOSetBuilderFactory &factory, ParticleSet &els, TrialWaveFunction &psi, const PSetMap &psets)
 constructor More...
 
std::unique_ptr< WaveFunctionComponentbuildComponent (xmlNodePtr cur) override
 initialize the Antisymmetric wave function for electrons More...
 
- Public Member Functions inherited from WaveFunctionComponentBuilder
 WaveFunctionComponentBuilder (Communicate *comm, ParticleSet &p)
 constructor More...
 
virtual ~WaveFunctionComponentBuilder ()=default
 
- Public Member Functions inherited from MPIObjectBase
 MPIObjectBase (Communicate *c)
 constructor with communicator More...
 
int rank () const
 return the rank of the communicator More...
 
int getGroupID () const
 return the group id of the communicator More...
 
CommunicategetCommunicator () const
 return myComm More...
 
CommunicategetCommRef () const
 return a TEMPORARY reference to Communicate More...
 
mpi_comm_type getMPI () const
 return MPI communicator if one wants to use MPI directly More...
 
bool is_manager () const
 return true if the rank == 0 More...
 
const std::string & getName () const
 return the name More...
 
void setName (const std::string &aname)
 

Private Member Functions

std::unique_ptr< DiracDeterminantBaseputDeterminant (xmlNodePtr cur, int spin_group, const std::unique_ptr< SPOSetBuilder > &legacy_input_sposet_builder, const std::unique_ptr< BackflowTransformation > &BFTrans)
 process a determinant element More...
 
std::unique_ptr< MultiSlaterDetTableMethodcreateMSDFast (xmlNodePtr cur, ParticleSet &target_ptcl, std::vector< std::unique_ptr< SPOSet >> &&spo_clones, const bool spinor, const bool use_precompute) const
 
bool readDetList (xmlNodePtr cur, std::vector< std::vector< ci_configuration >> &uniqueConfgs, std::vector< std::vector< size_t >> &C2nodes, std::vector< std::string > &CItags, std::vector< ValueType > &coeff, bool &optimizeCI, std::vector< int > &nptcls, std::unique_ptr< CSFData > &csf_data_ptr) const
 
bool readDetListH5 (xmlNodePtr cur, std::vector< std::vector< ci_configuration >> &uniqueConfgs, std::vector< std::vector< size_t >> &C2nodes, std::vector< std::string > &CItags, std::vector< ValueType > &coeff, bool &optimizeCI, 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>
void readCoeffs (hdf_archive &hin, std::vector< VT > &ci_coeff, size_t n_dets, int ext_level) const
 
template<typename VT >
void readCoeffs (hdf_archive &hin, std::vector< VT > &ci_coeff, size_t n_dets, int ext_level) const
 

Private Attributes

SPOSetBuilderFactorysposet_builder_factory_
 reference to the sposet_builder_factory, should be const once the legacy input style is removed More...
 
TrialWaveFunctiontargetPsi
 reference to TrialWaveFunction, should go away as the CUDA code. More...
 
const PSetMapptclPool
 reference to a PSetMap More...
 

Additional Inherited Members

- Public Types inherited from WaveFunctionComponentBuilder
using RealType = WaveFunctionComponent::RealType
 
using ValueType = WaveFunctionComponent::ValueType
 
using PosType = WaveFunctionComponent::PosType
 
using GradType = WaveFunctionComponent::GradType
 
using PSetMap = std::map< std::string, const std::unique_ptr< ParticleSet > >
 
- Public Types inherited from MPIObjectBase
using mpi_comm_type = Communicate::mpi_comm_type
 
- Static Public Attributes inherited from WaveFunctionComponentBuilder
static std::string wfs_tag = "wavefunction"
 reserved tags for the elements associated with the many-body wavefunctions More...
 
static std::string param_tag = "parameter"
 the element name for a parameter More...
 
static std::string dtable_tag = "distancetable"
 the element name for a distancetable More...
 
static std::string jastrow_tag = "jastrow"
 the element name for jatrow More...
 
static std::string detset_tag = "determinantset"
 the element name for a set of Slater determinants, contains 1..* Slater determinants More...
 
static std::string sd_tag = "slaterdeterminant"
 the element name for a Slater determinant, contains 1..* determinants More...
 
static std::string det_tag = "determinant"
 the element name for a determinant, may contain (0..*) orbital or parameter element More...
 
static std::string rn_tag = "determinant_rn"
 the element name for a released node determinant, may contain (0..*) orbital or parameter element More...
 
static std::string spo_tag = "psi"
 the element name for single-particle orbital More...
 
static std::string sposet_tag = "sposet"
 the element name for single-particle orbital set More...
 
static std::string ionorb_tag = "ionwf"
 the element name for an ion wavefunction More...
 
static std::string backflow_tag = "backflow"
 the element name for a backflow transformation More...
 
static std::string multisd_tag = "multideterminant"
 the element name for a multi slater determinant wavefunction More...
 
- Protected Attributes inherited from WaveFunctionComponentBuilder
ParticleSettargetPtcl
 reference to the particle set on which targetPsi is defined More...
 
xmlNodePtr myNode
 xmlNode operated by this object More...
 
- Protected Attributes inherited from MPIObjectBase
CommunicatemyComm
 pointer to Communicate More...
 
std::string ClassName
 class Name More...
 
std::string myName
 name of the object More...
 

Detailed Description

derived class from WaveFunctionComponentBuilder

Builder SlaterDeterminant with LCOrbitalSet

Definition at line 40 of file SlaterDetBuilder.h.

Constructor & Destructor Documentation

◆ SlaterDetBuilder()

SlaterDetBuilder ( Communicate comm,
SPOSetBuilderFactory factory,
ParticleSet els,
TrialWaveFunction psi,
const PSetMap psets 
)

constructor

Parameters
elsreference to the electrons
psireference to the wavefunction
ionsreference to the ions

Definition at line 42 of file SlaterDetBuilder.cpp.

References MPIObjectBase::ClassName.

48 {
49  ClassName = "SlaterDetBuilder";
50 }
WaveFunctionComponentBuilder(Communicate *comm, ParticleSet &p)
constructor
std::string ClassName
class Name
Definition: MPIObjectBase.h:65
SPOSetBuilderFactory & sposet_builder_factory_
reference to the sposet_builder_factory, should be const once the legacy input style is removed ...
const PSetMap & ptclPool
reference to a PSetMap
TrialWaveFunction & targetPsi
reference to TrialWaveFunction, should go away as the CUDA code.

Member Function Documentation

◆ buildComponent()

std::unique_ptr< WaveFunctionComponent > buildComponent ( xmlNodePtr  cur)
overridevirtual

initialize the Antisymmetric wave function for electrons

process <determinantset>

Parameters
curthe current xml node

determinantset

  • basiset 0..1
  • sposet 0..*
  • slaterdeterminant
    • determinant 0..*
  • ci

save the current node

Implements WaveFunctionComponentBuilder.

Definition at line 61 of file SlaterDetBuilder.cpp.

References OhmmsAttributeSet::add(), SPOSetBuilderFactory::addSPOSet(), qmcplusplus::app_log(), qmcplusplus::app_summary(), qmcplusplus::app_warning(), WaveFunctionComponentBuilder::backflow_tag, Communicate::barrier_and_abort(), BackflowBuilder::buildBackflowTransformation(), MPIObjectBase::ClassName, SlaterDetBuilder::createMSDFast(), SPOSetBuilderFactory::createSPOSetBuilder(), DELETED, qmcplusplus::det(), WaveFunctionComponentBuilder::det_tag, SPOSetBuilderFactory::empty(), ReportEngine::error(), getNodeName(), SPOSetBuilderFactory::getSPOSet(), ParticleSet::groups(), ParticleSet::isSpinor(), SPOSet::makeClone(), WaveFunctionComponentBuilder::multisd_tag, MPIObjectBase::myComm, SlaterDetBuilder::ptclPool, OhmmsAttributeSet::put(), SlaterDetBuilder::putDeterminant(), WaveFunctionComponentBuilder::rn_tag, WaveFunctionComponentBuilder::sd_tag, SlaterDetBuilder::sposet_builder_factory_, WaveFunctionComponentBuilder::sposet_tag, and WaveFunctionComponentBuilder::targetPtcl.

62 {
63  ReportEngine PRE(ClassName, "put(xmlNodePtr)");
64  ///save the current node
65  xmlNodePtr curRoot = cur;
66  bool multiDet = false;
67  std::string msd_algorithm;
68 
69  std::unique_ptr<WaveFunctionComponent> built_singledet_or_multidets;
70 
71  std::unique_ptr<SPOSetBuilder> legacy_input_sposet_builder;
72 
74  { //always create one, using singleton and just to access the member functions
75  app_warning() << "!!!!!!! Deprecated input style: creating SPO set inside determinantset. Support for this usage "
76  "will soon be removed. SPO sets should be built outside using sposet_collection."
77  << std::endl;
78  legacy_input_sposet_builder = sposet_builder_factory_.createSPOSetBuilder(curRoot);
79  }
80 
81  //check the basis set and backflow transformation
82  std::unique_ptr<BackflowTransformation> BFTrans;
83  cur = curRoot->children;
84  while (cur != NULL) //check the basis set
85  {
86  std::string cname(getNodeName(cur));
87  if (cname == sposet_tag)
88  {
89  app_warning() << "!!!!!!! Deprecated input style: creating SPO set inside determinantset. Support for this usage "
90  "will soon be removed. SPO sets should be built outside using sposet_collection."
91  << std::endl;
92  app_log() << "Creating SPOSet in SlaterDetBuilder::put(xmlNodePtr cur).\n";
93  assert(legacy_input_sposet_builder);
94  sposet_builder_factory_.addSPOSet(legacy_input_sposet_builder->createSPOSet(cur));
95  }
96  else if (cname == backflow_tag)
97  {
98  app_log() << "Creating Backflow transformation in SlaterDetBuilder::put(xmlNodePtr cur).\n";
99  // to simplify the logic inside DiracDeterminantWithBackflow,
100  // I'm requiring that only a single <backflow> block appears
101  // in the xml file
102  if (BFTrans)
103  myComm->barrier_and_abort("Only a single backflow block is allowed in the xml. "
104  "Please collect all transformations into a single block.");
105 
106  BackflowBuilder bfbuilder(targetPtcl, ptclPool);
107  BFTrans = bfbuilder.buildBackflowTransformation(cur);
108  }
109  cur = cur->next;
110  }
111 
112  cur = curRoot->children;
113  while (cur != NULL)
114  {
115  std::string cname(getNodeName(cur));
116  if (cname == sd_tag)
117  {
118  app_summary() << std::endl;
119  app_summary() << " Single Slater determinant" << std::endl;
120  app_summary() << " -------------------------" << std::endl;
121 
122  if (built_singledet_or_multidets)
123  myComm->barrier_and_abort("Only one slaterdeterminant or multideterminant entry allowed in XML");
124 
125  std::vector<std::unique_ptr<DiracDeterminantBase>> dirac_dets;
126  size_t spin_group = 0;
127  xmlNodePtr tcur = cur->children;
128  while (tcur != NULL)
129  {
130  std::string tname(getNodeName(tcur));
131  if (tname == det_tag || tname == rn_tag)
132  {
133  if (spin_group >= targetPtcl.groups())
134  {
135  std::ostringstream err_msg;
136  err_msg << "Need only " << targetPtcl.groups() << " determinant input elements. Found more." << std::endl;
137  throw std::runtime_error(err_msg.str());
138  }
139  dirac_dets.push_back(putDeterminant(tcur, spin_group, legacy_input_sposet_builder, BFTrans));
140  spin_group++;
141  }
142  tcur = tcur->next;
143  }
144  if (spin_group < targetPtcl.groups())
145  {
146  std::ostringstream err_msg;
147  err_msg << "Not enough determinant input elements. "
148  << "Need " << targetPtcl.groups() << " but only found " << spin_group << "." << std::endl;
149  throw std::runtime_error(err_msg.str());
150  }
151 
152  if (BFTrans)
153  {
154  app_summary() << " Using backflow transformation." << std::endl;
155  std::vector<std::unique_ptr<DiracDeterminantWithBackflow>> dirac_dets_bf;
156  for (auto& det : dirac_dets)
157  dirac_dets_bf.emplace_back(dynamic_cast<DiracDeterminantWithBackflow*>(det.release()));
158  auto single_det =
159  std::make_unique<SlaterDetWithBackflow>(targetPtcl, std::move(dirac_dets_bf), std::move(BFTrans));
160  built_singledet_or_multidets = std::move(single_det);
161  }
162  else
163  built_singledet_or_multidets = std::make_unique<SlaterDet>(targetPtcl, std::move(dirac_dets));
164  }
165  else if (cname == multisd_tag)
166  {
167  app_summary() << std::endl;
168  app_summary() << " Multi Slater determinants" << std::endl;
169  app_summary() << " -------------------------" << std::endl;
170  app_summary() << std::endl;
171 
172  if (built_singledet_or_multidets)
173  myComm->barrier_and_abort("Only one slaterdeterminant or multideterminant entry allowed in XML");
174 
175  const int nGroups = targetPtcl.groups();
176  std::vector<std::string> spoNames(nGroups);
177 
178  std::string fastAlg;
179  OhmmsAttributeSet spoAttrib;
180  for (int grp = 0; grp < nGroups; grp++)
181  spoAttrib.add(spoNames[grp], "spo_" + std::to_string(grp));
182  if (nGroups == 2)
183  { //for legacy
184  spoAttrib.add(spoNames[0], "spo_up");
185  spoAttrib.add(spoNames[1], "spo_dn");
186  }
187  spoAttrib.add(fastAlg, "Fast", {"", "yes", "no"}, TagStatus::DELETED);
188  spoAttrib.add(msd_algorithm, "algorithm", {"precomputed_table_method", "table_method"});
189  spoAttrib.put(cur);
190 
191  //new format
192  std::vector<std::unique_ptr<SPOSet>> spo_clones;
193 
194  for (int grp = 0; grp < nGroups; grp++)
195  {
196  const SPOSet* spo_tmp = sposet_builder_factory_.getSPOSet(spoNames[grp]);
197  if (spo_tmp == nullptr)
198  {
199  std::stringstream err_msg;
200  err_msg << "In SlaterDetBuilder: SPOSet \"" << spoNames[grp]
201  << "\" is not found. Expected for MultiSlaterDeterminant." << std::endl;
202  myComm->barrier_and_abort(err_msg.str());
203  }
204  spo_clones.emplace_back(spo_tmp->makeClone());
205  }
206 
207  app_summary() << " Using Bryan's table method." << std::endl;
208  if (BFTrans)
209  myComm->barrier_and_abort("Backflow is not supported by Multi-Slater determinants using the table method!");
210 
211  if (msd_algorithm == "precomputed_table_method")
212  app_summary() << " Using the table method with precomputing. Faster" << std::endl;
213  else
214  app_summary() << " Using the table method without precomputing. Slower." << std::endl;
215 
216  auto msd_fast = createMSDFast(cur, targetPtcl, std::move(spo_clones), targetPtcl.isSpinor(),
217  msd_algorithm == "precomputed_table_method");
218 
219  // The primary purpose of this function is to create all the optimizable orbital rotation parameters.
220  // But if orbital rotation parameters were supplied by the user it will also apply a unitary transformation
221  // and then remove the orbital rotation parameters
222  msd_fast->buildOptVariables();
223  built_singledet_or_multidets = std::move(msd_fast);
224  }
225  cur = cur->next;
226  }
227 
228  if (built_singledet_or_multidets)
229  return built_singledet_or_multidets;
230  else
231  {
232  //fatal
233  PRE.error("Failed to create a Single Slater determinant or Multi Slater determinants object.", true);
234  return nullptr;
235  }
236 }
static std::string det_tag
the element name for a determinant, may contain (0..*) orbital or parameter element ...
static std::string multisd_tag
the element name for a multi slater determinant wavefunction
std::ostream & app_warning()
Definition: OutputManager.h:69
std::unique_ptr< MultiSlaterDetTableMethod > createMSDFast(xmlNodePtr cur, ParticleSet &target_ptcl, std::vector< std::unique_ptr< SPOSet >> &&spo_clones, const bool spinor, const bool use_precompute) const
Tensor< T, D >::Type_t det(const Tensor< T, D > &a)
Definition: TensorOps.h:838
std::ostream & app_log()
Definition: OutputManager.h:65
std::ostream & app_summary()
Definition: OutputManager.h:63
bool put(xmlNodePtr cur)
assign attributes to the set
Definition: AttributeSet.h:55
std::unique_ptr< DiracDeterminantBase > putDeterminant(xmlNodePtr cur, int spin_group, const std::unique_ptr< SPOSetBuilder > &legacy_input_sposet_builder, const std::unique_ptr< BackflowTransformation > &BFTrans)
process a determinant element
const SPOSet * getSPOSet(const std::string &name) const
returns a named sposet from the pool only use in serial portion of execution ie during initialization...
static std::string rn_tag
the element name for a released node determinant, may contain (0..*) orbital or parameter element ...
ParticleSet & targetPtcl
reference to the particle set on which targetPsi is defined
int groups() const
return the number of groups
Definition: ParticleSet.h:511
void addSPOSet(std::unique_ptr< SPOSet >)
add an SPOSet to sposets map.
Communicate * myComm
pointer to Communicate
Definition: MPIObjectBase.h:62
class to handle a set of attributes of an xmlNode
Definition: AttributeSet.h:24
std::string ClassName
class Name
Definition: MPIObjectBase.h:65
static std::string sd_tag
the element name for a Slater determinant, contains 1..* determinants
static std::string backflow_tag
the element name for a backflow transformation
std::unique_ptr< SPOSetBuilder > createSPOSetBuilder(xmlNodePtr rootNode)
static std::string sposet_tag
the element name for single-particle orbital set
void barrier_and_abort(const std::string &msg) const
SPOSetBuilderFactory & sposet_builder_factory_
reference to the sposet_builder_factory, should be const once the legacy input style is removed ...
void add(PDT &aparam, const std::string &aname, std::vector< PDT > candidate_values={}, TagStatus status=TagStatus::OPTIONAL)
add a new attribute
Definition: AttributeSet.h:42
std::string getNodeName(xmlNodePtr cur)
Definition: libxmldefs.cpp:15
const PSetMap & ptclPool
reference to a PSetMap

◆ createMSDFast()

std::unique_ptr< MultiSlaterDetTableMethod > createMSDFast ( xmlNodePtr  cur,
ParticleSet target_ptcl,
std::vector< std::unique_ptr< SPOSet >> &&  spo_clones,
const bool  spinor,
const bool  use_precompute 
) const
private

Definition at line 466 of file SlaterDetBuilder.cpp.

References qmcplusplus::abs(), OhmmsAttributeSet::add(), APP_ABORT, qmcplusplus::app_log(), qmcplusplus::app_warning(), qmcplusplus::Units::charge::C, ParticleSet::first(), qmcplusplus::for(), getNodeName(), getXMLAttributeValue(), ParticleSet::groups(), ParticleSet::groupsize(), optimize::LINEAR_P, norm(), OhmmsAttributeSet::put(), SlaterDetBuilder::readDetList(), SlaterDetBuilder::readDetListH5(), and WaveFunctionComponentBuilder::targetPtcl.

Referenced by SlaterDetBuilder::buildComponent().

472 {
473  const size_t nGroups = targetPtcl.groups();
474 
475  std::vector<std::vector<size_t>> C2nodes(nGroups);
476  auto C2nodes_sorted_ptr = std::make_unique<std::vector<std::vector<size_t>>>(nGroups);
477  auto& C2nodes_sorted(*C2nodes_sorted_ptr);
478 
479  auto C_ptr = std::make_unique<std::vector<ValueType>>();
480  auto& C(*C_ptr);
481 
482  auto myVars_ptr = std::make_unique<opt_variables_type>();
483  auto& myVars(*myVars_ptr);
484 
485  bool Optimizable = false;
486  bool CI_Optimizable = false;
487 
488  bool optimizeCI;
489 
490  std::vector<int> nptcls(nGroups);
491  for (int grp = 0; grp < nGroups; grp++)
492  nptcls[grp] = targetPtcl.groupsize(grp);
493 
494  std::vector<std::vector<ci_configuration>> uniqueConfgs(nGroups);
495  std::vector<std::string> CItags;
496 
497  //Check id multideterminants are in HDF5
498 
499  xmlNodePtr curTemp = cur, DetListNode = nullptr;
500  curTemp = curTemp->children;
501  while (curTemp != NULL) //check the basis set
502  {
503  std::string cname(getNodeName(curTemp));
504  if (cname == "detlist")
505  DetListNode = curTemp;
506  curTemp = curTemp->next;
507  }
508 
509  std::unique_ptr<CSFData> csf_data_ptr;
510 
511  std::string HDF5Path(getXMLAttributeValue(DetListNode, "href"));
512  if (!HDF5Path.empty())
513  {
514  app_log() << "Found Multideterminants in H5 File" << std::endl;
515  readDetListH5(cur, uniqueConfgs, C2nodes, CItags, C, optimizeCI, nptcls);
516  }
517  else
518  readDetList(cur, uniqueConfgs, C2nodes, CItags, C, optimizeCI, nptcls, csf_data_ptr);
519 
520  const auto maxloc = std::max_element(C.begin(), C.end(), [](ValueType const& lhs, ValueType const& rhs) {
521  return std::norm(lhs) < std::norm(rhs);
522  });
523  const int refdet_id = std::distance(C.begin(), maxloc);
524  app_log() << "max CI coeff at det number " << refdet_id << " with value " << std::abs(C[refdet_id]) << std::endl;
525 
526  assert(nGroups == spo_clones.size());
527  std::vector<std::unique_ptr<MultiDiracDeterminant>> dets;
528  for (int grp = 0; grp < nGroups; grp++)
529  {
530  dets.emplace_back(std::make_unique<MultiDiracDeterminant>(std::move(spo_clones[grp]), spinor, targetPtcl.first(grp),
531  nptcls[grp]));
532  std::vector<ci_configuration2> list(uniqueConfgs[grp].size());
533  for (int i = 0; i < list.size(); i++)
534  {
535  list[i].occup.resize(nptcls[grp]);
536  int cnt = 0;
537  for (int k = 0; k < uniqueConfgs[grp][i].occup.size(); k++)
538  if (uniqueConfgs[grp][i].occup[k])
539  list[i].occup[cnt++] = k;
540  if (cnt != nptcls[grp])
541  {
542  APP_ABORT("Error in SlaterDetBuilder::createMSDFast for ptcl group "
543  << grp << ", problems with ci configuration list. \n");
544  }
545  }
546  // reorder unique determinants for a given spin based on the selected reference determinant
547  dets[grp]->createDetData(C2nodes[grp][refdet_id], list, C2nodes[grp], C2nodes_sorted[grp]);
548  }
549 
550  if (csf_data_ptr && csf_data_ptr->coeffs.size() == 1)
551  optimizeCI = false;
552 
553  if (optimizeCI)
554  {
555  app_log() << "CI coefficients are optimizable. \n";
556  std::string resetCI("no");
557  OhmmsAttributeSet spoAttrib;
558  spoAttrib.add(resetCI, "reset_coeff");
559  spoAttrib.put(cur);
560  if (resetCI == "yes")
561  {
562  if (csf_data_ptr)
563  for (int i = 1; i < csf_data_ptr->coeffs.size(); i++)
564  csf_data_ptr->coeffs[i] = 0;
565  else
566  for (int i = 1; i < C.size(); i++)
567  C[i] = 0;
568  app_log() << "CI coefficients are reset. \n";
569  }
570  Optimizable = CI_Optimizable = true;
571  if (csf_data_ptr)
572  for (int i = 1; i < csf_data_ptr->coeffs.size(); i++)
573  myVars.insert(CItags[i], std::real(csf_data_ptr->coeffs[i]), true, optimize::LINEAR_P);
574  else
575  for (int i = 1; i < C.size(); i++)
576  myVars.insert(CItags[i], std::real(C[i]), true, optimize::LINEAR_P);
577  }
578  else
579  {
580  app_log() << "CI coefficients are not optimizable. \n";
581  CI_Optimizable = false;
582  }
583 
584  bool any_optimizable = false;
585  for (int grp = 0; grp < nGroups; grp++)
586  {
587  if (dets[grp]->isOptimizable() == true)
588  {
589  any_optimizable = true;
590  break;
591  }
592  }
593  if (any_optimizable)
594  {
595  for (int grp = 0; grp < nGroups; grp++)
596  {
597  if (dets[grp]->isOptimizable() != true)
598  APP_ABORT("Optimizing the SPOSet of only only species is not supported!\n");
599  }
600  if (csf_data_ptr)
601  APP_ABORT("Currently, Using CSF is not available with MSJ Orbital Optimization!\n");
602 
603  for (int grp = 0; grp < nGroups; grp++)
604  {
605  for (int i = 0; i < nptcls[grp]; i++)
606  {
607  if (uniqueConfgs[grp][0].occup[i] != true)
608  APP_ABORT(
609  "The Hartee Fock Reference Determinant must be the first in the Multi-Slater expansion for the input!\n");
610  }
611  }
612  app_warning() << "Unrestricted Orbital Optimization will be performed. Spin symmetry is not guaranteed to be "
613  "preserved!\n";
614 
615  Optimizable = true;
616  }
617 
618  auto msd_fast = std::make_unique<MultiSlaterDetTableMethod>(targetPtcl, std::move(dets), use_precompute);
619  msd_fast->initialize(std::move(C2nodes_sorted_ptr), std::move(C_ptr), std::move(myVars_ptr), std::move(csf_data_ptr),
620  Optimizable, CI_Optimizable);
621 
622  return msd_fast;
623 }
std::ostream & app_warning()
Definition: OutputManager.h:69
QMCTraits::RealType real
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
std::ostream & app_log()
Definition: OutputManager.h:65
bool put(xmlNodePtr cur)
assign attributes to the set
Definition: AttributeSet.h:55
int first(int igroup) const
return the first index of a group i
Definition: ParticleSet.h:514
ParticleSet & targetPtcl
reference to the particle set on which targetPsi is defined
for(int i=0;i< size_test;++i) CHECK(Approx(gauss_random_vals[offset_for_rs+i])
int groups() const
return the number of groups
Definition: ParticleSet.h:511
double norm(const zVec &c)
Definition: VectorOps.h:118
class to handle a set of attributes of an xmlNode
Definition: AttributeSet.h:24
int groupsize(int igroup) const
return the size of a group
Definition: ParticleSet.h:527
#define APP_ABORT(msg)
Widely used but deprecated fatal error macros from legacy code.
Definition: AppAbort.h:27
std::string getXMLAttributeValue(const xmlNodePtr cur, const std::string_view name)
get the value string for attribute name if name is unfound in cur you get an empty string back this i...
bool readDetList(xmlNodePtr cur, std::vector< std::vector< ci_configuration >> &uniqueConfgs, std::vector< std::vector< size_t >> &C2nodes, std::vector< std::string > &CItags, std::vector< ValueType > &coeff, bool &optimizeCI, std::vector< int > &nptcls, std::unique_ptr< CSFData > &csf_data_ptr) const
bool readDetListH5(xmlNodePtr cur, std::vector< std::vector< ci_configuration >> &uniqueConfgs, std::vector< std::vector< size_t >> &C2nodes, std::vector< std::string > &CItags, std::vector< ValueType > &coeff, bool &optimizeCI, std::vector< int > &nptcls) const
void add(PDT &aparam, const std::string &aname, std::vector< PDT > candidate_values={}, TagStatus status=TagStatus::OPTIONAL)
add a new attribute
Definition: AttributeSet.h:42
std::string getNodeName(xmlNodePtr cur)
Definition: libxmldefs.cpp:15

◆ putDeterminant()

std::unique_ptr< DiracDeterminantBase > putDeterminant ( xmlNodePtr  cur,
int  spin_group,
const std::unique_ptr< SPOSetBuilder > &  legacy_input_sposet_builder,
const std::unique_ptr< BackflowTransformation > &  BFTrans 
)
private

process a determinant element

process determiment element

Parameters
curxml node
spin_groupthe spin group of the created determinant
Returns
legacy_input_sposet_builder an sposet builder to handle legacy input
BFTrans backflow transformations

determinant has

  • id unique name
  • sposet reference to the pre-defined sposet; when missing, use id
  • group electron species name, u or d magnetic system Extra attributes to handled the original released-node case

Definition at line 248 of file SlaterDetBuilder.cpp.

References qmcplusplus::ACCEL, OhmmsAttributeSet::add(), SPOSetBuilderFactory::addSPOSet(), APP_ABORT, qmcplusplus::app_log(), qmcplusplus::app_summary(), qmcplusplus::app_warning(), PlatformSelector< KIND >::candidate_values(), MPIObjectBase::ClassName, qmcplusplus::CPU, qmcplusplus::CUDA, SpeciesSet::findSpecies(), ParticleSet::first(), ParticleSet::getSpeciesSet(), SPOSetBuilderFactory::getSPOSet(), qmcplusplus::HOST, ParticleSet::last(), SPOSet::makeClone(), OhmmsAttributeSet::put(), PlatformSelector< KIND >::selectPlatform(), SpeciesSet::size(), SpeciesSet::speciesName, SlaterDetBuilder::sposet_builder_factory_, qmcplusplus::SYCL, and WaveFunctionComponentBuilder::targetPtcl.

Referenced by SlaterDetBuilder::buildComponent().

253 {
254  ReportEngine PRE(ClassName, "putDeterminant(xmlNodePtr,int)");
255 
256  const SpeciesSet& target_species = targetPtcl.getSpeciesSet();
257 
258  std::string spin_name = target_species.speciesName[spin_group];
259  std::string sposet_name;
260  std::string basisName("invalid");
261  std::string detname("0"), refname("0");
262  std::string s_detSize("0");
263 
264  OhmmsAttributeSet aAttrib;
265  aAttrib.add(basisName, "basisset");
266  aAttrib.add(detname, "id");
267  aAttrib.add(sposet_name, "sposet");
268  aAttrib.add(refname, "ref");
269  aAttrib.add(s_detSize, "DetSize");
270 
271  std::string s_cutoff("0.0");
272  std::string s_radius("0.0");
273  int s_smallnumber(-999999);
274  int rntype(0);
275  aAttrib.add(s_cutoff, "Cutoff");
276  aAttrib.add(s_radius, "Radius");
277  aAttrib.add(s_smallnumber, "smallnumber");
278  aAttrib.add(s_smallnumber, "eps");
279  aAttrib.add(rntype, "primary");
280  aAttrib.add(spin_name, "group");
281  aAttrib.put(cur);
282 
283  // whether to use an optimizable slater determinant
284  std::string optimize;
285  std::string matrix_inverter;
286  std::string use_batch;
287  std::string useGPU;
288  int delay_rank(0);
289 
290  OhmmsAttributeSet sdAttrib;
291  sdAttrib.add(delay_rank, "delay_rank");
292  sdAttrib.add(optimize, "optimize", {"no", "yes"});
293  sdAttrib.add(matrix_inverter, "matrix_inverter", {"gpu", "host"});
294 #if defined(ENABLE_OFFLOAD)
295  sdAttrib.add(use_batch, "batch", {"yes", "no"});
296 #else
297  sdAttrib.add(use_batch, "batch", {"no", "yes"});
298 #endif
299 #if defined(ENABLE_OFFLOAD)
300 #if defined(ENABLE_CUDA) || defined(ENABLE_SYCL)
301  sdAttrib.add(useGPU, "gpu", CPUOMPTargetVendorSelector::candidate_values);
302 #else
304 #endif
305 #endif
306  sdAttrib.put(cur->parent);
307 
308  { //check determinant@group
309  int spin_group_in = spin_group;
310  if (isdigit(spin_name[0]))
311  spin_group_in = atoi(spin_name.c_str());
312  else
313  spin_group_in = target_species.findSpecies(spin_name);
314  if (spin_group_in < target_species.size() && spin_group_in != spin_group)
315  {
316  spin_group = spin_group_in;
317  app_log() << " Overwrite group = " << spin_group << std::endl;
318  }
319  }
320 
321  //old input does not have sposet
322  if (sposet_name.empty())
323  sposet_name = detname;
324 
325  app_summary() << std::endl;
326  app_summary() << " Determinant" << std::endl;
327  app_summary() << " -----------" << std::endl;
328  app_summary() << " Name: " << detname << " Spin group: " << spin_group << " SPO name: " << sposet_name
329  << std::endl;
330  app_summary() << std::endl;
331 
332  const SPOSet* psi = sposet_builder_factory_.getSPOSet(sposet_name);
333  //check if the named sposet exists
334  if (psi == 0)
335  {
336  app_warning() << "!!!!!!! Deprecated input style: creating SPO set inside determinantset. Support for this usage "
337  "will soon be removed. SPO sets should be built outside using sposet_collection."
338  << std::endl;
339  app_log() << " Create a new SPO set " << sposet_name << std::endl;
340  assert(legacy_input_sposet_builder);
341  auto sposet = legacy_input_sposet_builder->createSPOSet(cur);
342  psi = sposet.get();
343  sposet_builder_factory_.addSPOSet(std::move(sposet));
344  }
345 
346  std::unique_ptr<SPOSet> psi_clone(psi->makeClone());
347  psi_clone->checkObject();
348 
349  const int firstIndex = targetPtcl.first(spin_group);
350  const int lastIndex = targetPtcl.last(spin_group);
351 
352  if (delay_rank < 0 || delay_rank > lastIndex - firstIndex)
353  {
354  std::ostringstream err_msg;
355  err_msg << "SlaterDetBuilder::putDeterminant delay_rank must be positive "
356  << "and no larger than the electron count within a determinant!\n"
357  << "Acceptable value [1," << lastIndex - firstIndex << "], "
358  << "user input " + std::to_string(delay_rank);
359  APP_ABORT(err_msg.str());
360  }
361  else if (delay_rank == 0)
362  {
363  if (lastIndex - firstIndex >= 192)
364  delay_rank = 32;
365  else
366  delay_rank = 1;
367  app_summary() << " Setting delay_rank to default value " << delay_rank << std::endl;
368  }
369 
370  if (delay_rank > 1)
371  app_summary() << " Using rank-" << delay_rank << " delayed update" << std::endl;
372  else
373  app_summary() << " Using rank-1 Sherman-Morrison Fahy update (SM1)" << std::endl;
374 
375  std::unique_ptr<DiracDeterminantBase> adet;
376 
377  if (BFTrans)
378  {
379  app_summary() << " Using backflow transformation." << std::endl;
380  adet = std::make_unique<DiracDeterminantWithBackflow>(std::move(psi_clone), *BFTrans, firstIndex, lastIndex);
381  }
382  else
383  {
384  const DetMatInvertor matrix_inverter_kind =
385  (matrix_inverter == "host") ? DetMatInvertor::HOST : DetMatInvertor::ACCEL;
386  if (matrix_inverter_kind == DetMatInvertor::HOST)
387  app_summary() << " Matrix inversion running on host." << std::endl;
388 
389  if (use_batch == "yes")
390  {
391  app_summary() << " Using walker batching." << std::endl;
392 
393 #if defined(ENABLE_CUDA) && defined(ENABLE_OFFLOAD)
395  {
396  app_summary() << " Running on a GPU via CUDA/HIP acceleration and OpenMP offload." << std::endl;
397  adet = std::make_unique<DiracDeterminantBatched<PlatformKind::CUDA, QMCTraits::ValueType, QMCTraits::QTFull::ValueType>>(std::move(psi_clone),
398  firstIndex, lastIndex,
399  delay_rank,
400  matrix_inverter_kind);
401  }
402  else
403 #endif
404 #if defined(ENABLE_SYCL) && defined(ENABLE_OFFLOAD)
406  {
407  app_summary() << " Running on a GPU via SYCL acceleration and OpenMP offload." << std::endl;
408  adet = std::make_unique<DiracDeterminantBatched<PlatformKind::SYCL, QMCTraits::ValueType, QMCTraits::QTFull::ValueType>>(std::move(psi_clone),
409  firstIndex, lastIndex,
410  delay_rank,
411  matrix_inverter_kind);
412  }
413  else
414 #endif
415  {
416 #if defined(ENABLE_OFFLOAD)
418  throw std::runtime_error("No pure CPU implementation of walker-batched Slater determinant.");
419  app_summary() << " Running OpenMP offload code path on a GPU. " << std::endl;
420 #else
421  app_summary() << " Running OpenMP offload code path on a CPU. " << std::endl;
422 #endif
423  adet = std::make_unique<DiracDeterminantBatched<PlatformKind::OMPTARGET, QMCTraits::ValueType, QMCTraits::QTFull::ValueType>>(std::move(psi_clone), firstIndex, lastIndex, delay_rank,
424  matrix_inverter_kind);
425  }
426  }
427  else
428  {
429  if (useGPU == "omptarget")
430  throw std::runtime_error("No OpenMP offload implementation of single-walker Slater determinant.");
431 #if defined(ENABLE_CUDA)
433  {
434  app_summary() << " Running on a GPU via CUDA/HIP acceleration." << std::endl;
435  adet = std::make_unique<
436  DiracDeterminant<DelayedUpdateCUDA<ValueType, QMCTraits::QTFull::ValueType>>>(std::move(psi_clone),
437  firstIndex, lastIndex,
438  delay_rank,
439  matrix_inverter_kind);
440  }
441 #elif defined(ENABLE_SYCL)
443  {
444  app_summary() << " Running on a GPU via SYCL acceleration." << std::endl;
445  adet = std::make_unique<
446  DiracDeterminant<DelayedUpdateSYCL<ValueType, QMCTraits::QTFull::ValueType>>>(std::move(psi_clone),
447  firstIndex, lastIndex,
448  delay_rank,
449  matrix_inverter_kind);
450  }
451 #endif
452  else
453  {
454  app_summary() << " Running on CPU." << std::endl;
455  adet = std::make_unique<DiracDeterminant<>>(std::move(psi_clone), firstIndex, lastIndex, delay_rank,
456  matrix_inverter_kind);
457  }
458  }
459  }
460 
461  app_log() << std::endl;
462  app_log().flush();
463  return adet;
464 }
std::ostream & app_warning()
Definition: OutputManager.h:69
std::ostream & app_log()
Definition: OutputManager.h:65
std::ostream & app_summary()
Definition: OutputManager.h:63
bool put(xmlNodePtr cur)
assign attributes to the set
Definition: AttributeSet.h:55
DetMatInvertor
determinant matrix inverter select
int first(int igroup) const
return the first index of a group i
Definition: ParticleSet.h:514
const SPOSet * getSPOSet(const std::string &name) const
returns a named sposet from the pool only use in serial portion of execution ie during initialization...
ParticleSet & targetPtcl
reference to the particle set on which targetPsi is defined
void addSPOSet(std::unique_ptr< SPOSet >)
add an SPOSet to sposets map.
class to handle a set of attributes of an xmlNode
Definition: AttributeSet.h:24
std::string ClassName
class Name
Definition: MPIObjectBase.h:65
#define APP_ABORT(msg)
Widely used but deprecated fatal error macros from legacy code.
Definition: AppAbort.h:27
int last(int igroup) const
return the last index of a group i
Definition: ParticleSet.h:517
static PlatformKind selectPlatform(std::string_view value)
SpeciesSet & getSpeciesSet()
retrun the SpeciesSet of this particle set
Definition: ParticleSet.h:231
std::vector< std::string > speciesName
Species name list.
Definition: SpeciesSet.h:44
SPOSetBuilderFactory & sposet_builder_factory_
reference to the sposet_builder_factory, should be const once the legacy input style is removed ...
void add(PDT &aparam, const std::string &aname, std::vector< PDT > candidate_values={}, TagStatus status=TagStatus::OPTIONAL)
add a new attribute
Definition: AttributeSet.h:42
const std::vector< std::string > candidate_values

◆ readCoeffs() [1/2]

void readCoeffs ( hdf_archive hin,
std::vector< VT > &  ci_coeff,
size_t  n_dets,
int  ext_level 
) const
inlineprivate

Determinant coeffs are stored in Coeff for the ground state and Coeff_N for the Nth excited state. The Ground State is always stored in Coeff Backward compatibility is insured

Definition at line 106 of file SlaterDetBuilder.h.

References hdf_archive::read().

Referenced by SlaterDetBuilder::readDetListH5().

107  {
108  ///Determinant coeffs are stored in Coeff for the ground state and Coeff_N
109  ///for the Nth excited state.
110  ///The Ground State is always stored in Coeff
111  ///Backward compatibility is insured
112  std::string extVar;
113  if (ext_level == 0)
114  extVar = "Coeff";
115  else
116  extVar = "Coeff_" + std::to_string(ext_level);
117 
118  hin.read(ci_coeff, extVar);
119  }

◆ readCoeffs() [2/2]

void readCoeffs ( hdf_archive hin,
std::vector< VT > &  ci_coeff,
size_t  n_dets,
int  ext_level 
) const
inlineprivate

Determinant coeffs are stored in Coeff_N where N is Nth excited state. The Ground State is always stored in Coeff. Backward compatibility is insured

Definition at line 125 of file SlaterDetBuilder.h.

References qmcplusplus::app_log(), hdf_archive::read(), and hdf_archive::readEntry().

126  {
127  std::string extVar;
128  std::vector<double> CIcoeff_real;
129  std::vector<double> CIcoeff_imag;
130  CIcoeff_imag.resize(n_dets);
131  CIcoeff_real.resize(n_dets);
132  fill(CIcoeff_imag.begin(), CIcoeff_imag.end(), 0.0);
133  ///Determinant coeffs are stored in Coeff_N where N is Nth excited state.
134  ///The Ground State is always stored in Coeff.
135  ///Backward compatibility is insured
136 
137  std::string ext_var;
138  if (ext_level == 0)
139  extVar = "Coeff";
140  else
141  extVar = "Coeff_" + std::to_string(ext_level);
142 
143 
144  hin.read(CIcoeff_real, extVar);
145 
146  extVar = extVar + "_imag";
147  if (!hin.readEntry(CIcoeff_imag, extVar))
148  app_log() << "Coeff_imag not found in h5. Set to zero." << std::endl;
149 
150  for (size_t i = 0; i < n_dets; i++)
151  ci_coeff[i] = VT(CIcoeff_real[i], CIcoeff_imag[i]);
152  }
std::ostream & app_log()
Definition: OutputManager.h:65

◆ readDetList()

bool readDetList ( xmlNodePtr  cur,
std::vector< std::vector< ci_configuration >> &  uniqueConfgs,
std::vector< std::vector< size_t >> &  C2nodes,
std::vector< std::string > &  CItags,
std::vector< ValueType > &  coeff,
bool &  optimizeCI,
std::vector< int > &  nptcls,
std::unique_ptr< CSFData > &  csf_data_ptr 
) const
private

Definition at line 625 of file SlaterDetBuilder.cpp.

References qmcplusplus::abs(), OhmmsAttributeSet::add(), APP_ABORT, qmcplusplus::app_log(), Communicate::barrier_and_abort(), getNodeName(), MPIObjectBase::myComm, and OhmmsAttributeSet::put().

Referenced by SlaterDetBuilder::createMSDFast().

633 {
634  bool success = true;
635 
636  const int nGroups = uniqueConfgs.size();
637  for (int grp = 0; grp < nGroups; grp++)
638  {
639  uniqueConfgs[grp].clear();
640  C2nodes[grp].clear();
641  }
642  CItags.clear();
643  coeff.clear();
644  std::vector<std::vector<ci_configuration>> confgLists(nGroups);
645  std::string optCI = "no";
646  RealType cutoff = 0.0;
647  RealType zero_cutoff = 0.0;
648  OhmmsAttributeSet ciAttrib;
649  ciAttrib.add(optCI, "optimize");
650  ciAttrib.add(optCI, "Optimize");
651  ciAttrib.put(cur);
652  optimizeCI = (optCI == "yes");
653  xmlNodePtr curRoot = cur, DetListNode = nullptr;
654  cur = curRoot->children;
655  while (cur != NULL) //check the basis set
656  {
657  std::string cname(getNodeName(cur));
658  if (cname == "detlist")
659  {
660  DetListNode = cur;
661  app_log() << "Found determinant list. \n";
662  }
663  cur = cur->next;
664  }
665 
666  std::vector<size_t> NCs(nGroups);
667  std::vector<size_t> NEs(nGroups);
668  size_t nstates = 0;
669  size_t ndets = 0;
670  size_t cnt0 = 0;
671  std::string Dettype = "DETS";
672  std::string CSFChoice = "qchem_coeff";
673  OhmmsAttributeSet spoAttrib;
674  for (int grp = 0; grp < nGroups; grp++)
675  {
676  spoAttrib.add(NCs[grp], "nc" + std::to_string(grp));
677  spoAttrib.add(NEs[grp], "ne" + std::to_string(grp));
678  }
679  if (nGroups == 2)
680  { //for legacy
681  spoAttrib.add(NCs[0], "nca");
682  spoAttrib.add(NCs[1], "ncb");
683  spoAttrib.add(NEs[0], "nea");
684  spoAttrib.add(NEs[1], "neb");
685  }
686  spoAttrib.add(ndets, "size");
687  spoAttrib.add(nstates, "nstates");
688  spoAttrib.add(Dettype, "type");
689  spoAttrib.add(cutoff, "cutoff");
690  spoAttrib.add(zero_cutoff, "zero_cutoff");
691  spoAttrib.add(zero_cutoff, "zerocutoff");
692  spoAttrib.add(CSFChoice, "sortby");
693  spoAttrib.put(DetListNode);
694 
695  if (ndets == 0)
696  {
697  APP_ABORT("size==0 in detlist is not allowed. Use slaterdeterminant in this case.\n");
698  }
699 
700  if (Dettype == "CSF")
701  csf_data_ptr = std::make_unique<CSFData>();
702  else if (Dettype != "DETS" && Dettype != "Determinants")
703  {
704  APP_ABORT("Only allowed type in detlist is DETS or CSF.\n");
705  }
706 
707  if (zero_cutoff > 0)
708  app_log() << " Initializing CI coeffs less than " << zero_cutoff << " to zero." << std::endl;
709 
710  for (int grp = 0; grp < nGroups; grp++)
711  {
712  if (NEs[grp] == 0)
713  NEs[grp] = nptcls[grp] - NCs[grp];
714  else if (NEs[grp] != nptcls[grp] - NCs[grp])
715  throw std::runtime_error("ne is not equal to n - nc for group " + std::to_string(grp));
716  }
717 
718  cur = DetListNode->children;
719  std::vector<ci_configuration> dummyCs(nGroups);
720  for (int grp = 0; grp < nGroups; grp++)
721  {
722  dummyCs[grp].occup.resize(NCs[grp] + nstates, false);
723  for (size_t i = 0; i < NCs[grp] + NEs[grp]; i++)
724  dummyCs[grp].occup[i] = true;
725  }
726  RealType sumsq_qc = 0.0;
727  RealType sumsq = 0.0;
728  if (csf_data_ptr)
729  {
730  auto& CSFcoeff = csf_data_ptr->coeffs;
731  auto& DetsPerCSF = csf_data_ptr->dets_per_csf;
732  auto& CSFexpansion = csf_data_ptr->expansion;
733 
734  app_log() << "Reading CSFs." << std::endl;
735  while (cur != NULL) //check the basis set
736  {
737  std::string cname(getNodeName(cur));
738  if (cname == "csf")
739  {
740  RealType exctLvl, qc_ci = 0.0;
741  OhmmsAttributeSet confAttrib;
742  std::string tag, OccString;
743  RealType ci_real = 0.0, ci_imag = 0.0;
744  confAttrib.add(ci_real, "coeff");
745  confAttrib.add(ci_real, "coeff_real");
746  confAttrib.add(ci_imag, "coeff_imag");
747  confAttrib.add(qc_ci, "qchem_coeff");
748  confAttrib.add(tag, "id");
749  confAttrib.add(OccString, "occ");
750  confAttrib.add(exctLvl, "exctLvl");
751  confAttrib.put(cur);
752 
753  if (qc_ci == 0.0)
754  qc_ci = ci_real;
755 
756  ValueType ci;
757 #ifdef QMC_COMPLEX
758  ci = ValueType(ci_real, ci_imag);
759 #else
760  if (ci_imag != RealType(0))
762  "SlaterDetBuilder::readDetList. Build with QMC_COMPLEX if using complex CI expansion coefficients.");
763  ci = ci_real;
764 #endif
765  //Can discriminate based on any of 3 criterion
766  if (((std::abs(qc_ci) < cutoff) && (CSFChoice == "qchem_coeff")) ||
767  ((CSFChoice == "exctLvl") && (exctLvl > cutoff)) || ((CSFChoice == "coeff") && (std::abs(ci) < cutoff)))
768  {
769  cur = cur->next;
770  cnt0++;
771  continue;
772  }
773  cnt0++;
774  if (std::abs(qc_ci) < zero_cutoff)
775  ci = 0.0;
776  CSFcoeff.push_back(ci);
777  sumsq_qc += qc_ci * qc_ci;
778  DetsPerCSF.push_back(0);
779  CItags.push_back(tag);
780  xmlNodePtr csf = cur->children;
781  while (csf != NULL)
782  {
783  std::string cname0(getNodeName(csf));
784  if (cname0 == "det")
785  {
786  std::vector<std::string> occs(nGroups);
787  std::string tag0;
788  RealType coef = 0.0;
789  OhmmsAttributeSet detAttrib;
790  detAttrib.add(tag0, "id");
791  detAttrib.add(coef, "coeff");
792  for (int grp = 0; grp < nGroups; grp++)
793  detAttrib.add(occs[grp], "occ" + std::to_string(grp));
794  if (nGroups == 2)
795  { //for legacy
796  detAttrib.add(occs[0], "alpha");
797  detAttrib.add(occs[1], "beta");
798  }
799  detAttrib.put(csf);
800  for (int grp = 0; grp < nGroups; grp++)
801  {
802  size_t nq = 0;
803  if (occs[grp].size() < nstates)
804  {
805  std::cerr << "occ" << grp << ": " << occs[grp] << std::endl;
806  APP_ABORT("Found incorrect group" + std::to_string(grp) + " determinant label. size < nc+nstates");
807  }
808  for (size_t i = 0; i < nstates; i++)
809  {
810  if (occs[grp][i] != '0' && occs[grp][i] != '1')
811  {
812  std::cerr << occs[grp] << std::endl;
813  APP_ABORT("Found incorrect determinant label.");
814  }
815  if (occs[grp][i] == '1')
816  nq++;
817  }
818  if (nq != NEs[grp])
819  {
820  std::cerr << "occ" << grp << ": " << occs[grp] << std::endl;
821  APP_ABORT("Found incorrect group" + std::to_string(grp) + " determinant label. nocc != nc+ne");
822  }
823  }
824  DetsPerCSF.back()++;
825  CSFexpansion.push_back(coef);
826  coeff.push_back(coef * ci);
827  for (int grp = 0; grp < nGroups; grp++)
828  {
829  confgLists[grp].push_back(dummyCs[grp]);
830  for (size_t i = 0; i < NCs[grp]; i++)
831  confgLists[grp].back().occup[i] = true;
832  for (size_t i = NCs[grp]; i < NCs[grp] + nstates; i++)
833  confgLists[grp].back().occup[i] = (occs[grp][i - NCs[grp]] == '1');
834  }
835  } // if(name=="det")
836  csf = csf->next;
837  } // csf loop
838  if (DetsPerCSF.back() == 0)
839  {
840  APP_ABORT("Found empty CSF (no det blocks).");
841  }
842  } // if (name == "csf")
843  cur = cur->next;
844  }
845  if (cnt0 != ndets)
846  {
847  std::cerr << "count, ndets: " << cnt0 << " " << ndets << std::endl;
848  APP_ABORT("Problems reading determinant ci_configurations. Found a number of determinants inconsistent with xml "
849  "file size parameter.\n");
850  }
851 
852  for (int grp = 0; grp < nGroups; grp++)
853  C2nodes[grp].resize(coeff.size());
854  app_log() << "Found " << coeff.size() << " terms in the MSD expansion.\n";
855  RealType sumsq = 0.0;
856  for (size_t i = 0; i < coeff.size(); i++)
857  sumsq += std::abs(coeff[i] * coeff[i]);
858  app_log() << "Norm of ci vector (sum of ci^2): " << sumsq << std::endl;
859  app_log() << "Norm of qchem ci vector (sum of qchem_ci^2): " << sumsq_qc << std::endl;
860  for (int grp = 0; grp < nGroups; grp++)
861  {
862  for (size_t i = 0; i < confgLists[grp].size(); i++)
863  {
864  bool found = false;
865  int k = -1;
866  for (size_t j = 0; j < uniqueConfgs[grp].size(); j++)
867  {
868  if (confgLists[grp][i] == uniqueConfgs[grp][j])
869  {
870  found = true;
871  k = j;
872  break;
873  }
874  }
875  if (found)
876  {
877  C2nodes[grp][i] = k;
878  }
879  else
880  {
881  uniqueConfgs[grp].push_back(confgLists[grp][i]);
882  C2nodes[grp][i] = uniqueConfgs[grp].size() - 1;
883  }
884  }
885  }
886  }
887  else
888  {
889  app_log() << "Reading CI expansion." << std::endl;
890 
891  std::vector<int> cnts(nGroups, 0);
892  std::vector<std::unordered_map<std::string, int>> MyMaps(nGroups);
893  while (cur != NULL) //check the basis set
894  {
895  std::string cname(getNodeName(cur));
896  if (cname == "configuration" || cname == "ci")
897  {
898  RealType qc_ci = 0.0;
899  std::vector<std::string> occs(nGroups);
900  std::string tag;
901  OhmmsAttributeSet confAttrib;
902  RealType ci_real = 0.0, ci_imag = 0.0;
903  confAttrib.add(ci_real, "coeff");
904  confAttrib.add(ci_real, "coeff_real");
905  confAttrib.add(ci_imag, "coeff_imag");
906  confAttrib.add(qc_ci, "qchem_coeff");
907  for (int grp = 0; grp < nGroups; grp++)
908  confAttrib.add(occs[grp], "occ" + std::to_string(grp));
909  if (nGroups == 2)
910  { //legacy
911  confAttrib.add(occs[0], "alpha");
912  confAttrib.add(occs[1], "beta");
913  }
914  confAttrib.add(tag, "id");
915  confAttrib.put(cur);
916 
917  ValueType ci;
918 #ifdef QMC_COMPLEX
919  ci = ValueType(ci_real, ci_imag);
920 #else
921  if (ci_imag != RealType(0))
923  "SlaterDetBuilder::readDetList. Build with QMC_COMPLEX if using complex CI expansion coefficients.");
924  ci = ci_real;
925 #endif
926 
927  //Will always loop through the whole determinant set as no assumption on the order of the determinant is made
928  if (std::abs(ci) < cutoff)
929  {
930  cur = cur->next;
931  continue;
932  }
933 
934  for (int grp = 0; grp < nGroups; grp++)
935  {
936  for (size_t i = 0; i < nstates; i++)
937  {
938  if (occs[grp][i] != '0' && occs[grp][i] != '1')
939  {
940  std::cerr << occs[grp] << std::endl;
941  APP_ABORT("Found incorrect determinant label for group " + std::to_string(grp));
942  }
943  }
944  if (occs[grp].size() < nstates)
945  {
946  std::cerr << "occ" << grp << ": " << occs[grp] << std::endl;
947  APP_ABORT("Found incorrect group" + std::to_string(grp) + " determinant label. size < nc+nstates");
948  }
949  }
950 
951  coeff.push_back(ci);
952  CItags.push_back(tag);
953 
954  for (int grp = 0; grp < nGroups; grp++)
955  {
956  std::unordered_map<std::string, int>::const_iterator got = MyMaps[grp].find(occs[grp]);
957  if (got == MyMaps[grp].end())
958  {
959  uniqueConfgs[grp].push_back(dummyCs[grp]);
960  uniqueConfgs[grp].back().add_occupation(occs[grp]);
961  C2nodes[grp].push_back(cnts[grp]);
962  MyMaps[grp].insert(std::pair<std::string, int>(occs[grp], cnts[grp]));
963  cnts[grp]++;
964  }
965  else
966  {
967  C2nodes[grp].push_back(got->second);
968  }
969  }
970 
971  cnt0++;
972  sumsq_qc += qc_ci * qc_ci;
973  sumsq += std::abs(ci * ci);
974  }
975  cur = cur->next;
976  }
977 
978  app_log() << "Found " << coeff.size() << " terms in the MSD expansion.\n";
979 
980  if (coeff.size() == 0)
981  throw std::runtime_error(
982  "MSD expansion is empty with either zero determinants input or remaining after cutoff applied.");
983 
984  app_log() << "Norm of ci vector (sum of ci^2): " << sumsq << std::endl;
985  app_log() << "Norm of qchem ci vector (sum of qchem_ci^2): " << sumsq_qc << std::endl;
986 
987  } //usingCSF
988 
989  for (auto grp = 0; grp < nGroups; grp++)
990  app_log() << "Found " << uniqueConfgs[grp].size() << " unique group " << grp << " determinants.\n";
991 
992  return success;
993 }
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
std::ostream & app_log()
Definition: OutputManager.h:65
bool put(xmlNodePtr cur)
assign attributes to the set
Definition: AttributeSet.h:55
Communicate * myComm
pointer to Communicate
Definition: MPIObjectBase.h:62
class to handle a set of attributes of an xmlNode
Definition: AttributeSet.h:24
#define APP_ABORT(msg)
Widely used but deprecated fatal error macros from legacy code.
Definition: AppAbort.h:27
QMCTraits::RealType RealType
void barrier_and_abort(const std::string &msg) const
void add(PDT &aparam, const std::string &aname, std::vector< PDT > candidate_values={}, TagStatus status=TagStatus::OPTIONAL)
add a new attribute
Definition: AttributeSet.h:42
std::string getNodeName(xmlNodePtr cur)
Definition: libxmldefs.cpp:15

◆ readDetListH5()

bool readDetListH5 ( xmlNodePtr  cur,
std::vector< std::vector< ci_configuration >> &  uniqueConfgs,
std::vector< std::vector< size_t >> &  C2nodes,
std::vector< std::string > &  CItags,
std::vector< ValueType > &  coeff,
bool &  optimizeCI,
std::vector< int > &  nptcls 
) const
private

64 bit fixed width integer

the number of 64 bit integers which represent the binary string for occupation

IF OPTIMIZED COEFFICIENTS ARE PRESENT IN opt_coeffs Path THEY ARE READ FROM DIFFERENT HDF5 the replace the previous coeff It is important to still read all old coeffs and only replace the optimized ones in order to keep coherence with the cutoff on the number of determinants REMEMBER!! FIRST COEFF IS FIXED. THEREFORE WE DO NOT REPLACE IT!!!
This loop will find all unique Determinants in and store them "unsorted" in a new container uniqueConfg_up and uniqueConfg_dn. The sorting is not done here

Definition at line 995 of file SlaterDetBuilder.cpp.

References qmcplusplus::abs(), OhmmsAttributeSet::add(), APP_ABORT, qmcplusplus::app_log(), hdf_archive::close(), getNodeName(), hdf_archive::is_dataset(), hdf_archive::is_dataset_of_type(), hdf_archive::open(), hdf_archive::push(), OhmmsAttributeSet::put(), hdf_archive::read(), SlaterDetBuilder::readCoeffs(), and hdf_archive::readEntry().

Referenced by SlaterDetBuilder::createMSDFast().

1002 {
1003  bool success = true;
1004  int extlevel(0);
1005  const int nGroups = uniqueConfgs.size();
1006  for (int grp = 0; grp < nGroups; grp++)
1007  {
1008  uniqueConfgs[grp].clear();
1009  C2nodes[grp].clear();
1010  }
1011  CItags.clear();
1012  coeff.clear();
1013  std::string CICoeffH5path("");
1014  std::vector<std::vector<ci_configuration>> confgLists(nGroups);
1015  std::vector<ValueType> CIcoeff;
1016  std::vector<std::string> ConfigTag;
1017  std::string optCI = "no";
1018  RealType cutoff = 0.0;
1019  OhmmsAttributeSet ciAttrib;
1020  ciAttrib.add(optCI, "optimize");
1021  ciAttrib.put(cur);
1022  optimizeCI = (optCI == "yes");
1023  xmlNodePtr curRoot = cur, DetListNode = nullptr;
1024  std::string multidetH5path;
1025  cur = curRoot->children;
1026  while (cur != NULL) //check the basis set
1027  {
1028  std::string cname(getNodeName(cur));
1029  if (cname == "detlist")
1030  {
1031  DetListNode = cur;
1032  app_log() << "Found determinant list. \n";
1033  }
1034  cur = cur->next;
1035  }
1036 
1037  app_log() << " H5 code path implicitly assumes NC0 = NC1 = ... = 0" << std::endl;
1038  for (int grp = 0; grp < nGroups; grp++)
1039  app_log() << "NE" << grp << " = " << nptcls[grp] << ", ";
1040  app_log() << std::endl;
1041  size_t nstates = 0;
1042  size_t ndets = 0;
1043  size_t H5_ndets, H5_nstates;
1044  /// 64 bit fixed width integer
1045  const unsigned bit_kind = 64;
1046  static_assert(bit_kind == sizeof(uint64_t) * 8, "Must be 64 bit fixed width integer");
1047  /// the number of 64 bit integers which represent the binary string for occupation
1048  int N_int;
1049  std::string Dettype = "DETS";
1050  ValueType sumsq = 0.0;
1051  OhmmsAttributeSet spoAttrib;
1052  spoAttrib.add(ndets, "size");
1053  spoAttrib.add(Dettype, "type");
1054  spoAttrib.add(nstates, "nstates");
1055  spoAttrib.add(extlevel, "ext_level");
1056  spoAttrib.add(cutoff, "cutoff");
1057  spoAttrib.add(multidetH5path, "href");
1058  spoAttrib.add(CICoeffH5path, "opt_coeffs");
1059  spoAttrib.put(DetListNode);
1060  if (ndets == 0)
1061  {
1062  APP_ABORT("size==0 in detlist is not allowed. Use slaterdeterminant in this case.\n");
1063  }
1064  if (Dettype != "DETS" && Dettype != "Determinants")
1065  APP_ABORT("Reading from HDF5 is only enabled for CI DETS. Must be accessed through (type=\"DETS\") or "
1066  "(type=\"Determinants\") .\n");
1067  app_log() << "Reading CI expansion from HDF5:" << multidetH5path << std::endl;
1068 
1069  hdf_archive hin;
1070  if (!hin.open(multidetH5path.c_str(), H5F_ACC_RDONLY))
1071  {
1072  std::cerr << "Could not open H5 file" << std::endl;
1073  abort();
1074  }
1075 
1076 
1077  hin.push("MultiDet", false);
1078 
1079  hin.read(H5_ndets, "NbDet");
1080  if (ndets != H5_ndets)
1081  {
1082  std::cerr << "Number of determinants in H5 file (" << H5_ndets << ") different from number of dets in XML ("
1083  << ndets << ")" << std::endl;
1084  abort();
1085  }
1086 
1087  hin.read(H5_nstates, "nstate");
1088  if (nstates == 0)
1089  nstates = H5_nstates;
1090  else if (nstates != H5_nstates)
1091  {
1092  std::cerr << "Number of states/orbitals in H5 file (" << H5_nstates
1093  << ") different from number of states/orbitals in XML (" << nstates << ")" << std::endl;
1094  abort();
1095  }
1096 
1097  hin.read(N_int, "Nbits");
1098  CIcoeff.resize(ndets);
1099  ConfigTag.resize(ndets);
1100 
1101  readCoeffs(hin, CIcoeff, ndets, extlevel);
1102 
1103  ///IF OPTIMIZED COEFFICIENTS ARE PRESENT IN opt_coeffs Path
1104  ///THEY ARE READ FROM DIFFERENT HDF5 the replace the previous coeff
1105  ///It is important to still read all old coeffs and only replace the optimized ones
1106  ///in order to keep coherence with the cutoff on the number of determinants
1107  ///REMEMBER!! FIRST COEFF IS FIXED. THEREFORE WE DO NOT REPLACE IT!!!
1108  if (CICoeffH5path != "")
1109  {
1110  int OptCiSize = 0;
1111  std::vector<ValueType> CIcoeffopt;
1112  hdf_archive coeffin;
1113  if (!coeffin.open(CICoeffH5path.c_str(), H5F_ACC_RDONLY))
1114  {
1115  std::cerr << "Could not open H5 file containing Optimized Coefficients" << std::endl;
1116  abort();
1117  }
1118 
1119  coeffin.push("MultiDet", false);
1120 
1121  coeffin.read(OptCiSize, "NbDet");
1122  CIcoeffopt.resize(OptCiSize);
1123 
1124  readCoeffs(coeffin, CIcoeffopt, ndets, extlevel);
1125 
1126  coeffin.close();
1127 
1128  for (int i = 0; i < OptCiSize; i++)
1129  CIcoeff[i + 1] = CIcoeffopt[i];
1130 
1131  app_log() << "The first " << OptCiSize
1132  << " Optimized coefficients were substituted to the original set of coefficients." << std::endl;
1133  }
1134 
1135  std::vector<Matrix<uint64_t>> temps;
1136  for (int grp = 0; grp < nGroups; grp++)
1137  {
1138  Matrix<uint64_t> tmp(ndets, N_int);
1139  temps.push_back(tmp);
1140  std::string ci_str;
1141 
1142  std::string ds_tag = "CI_" + std::to_string(grp);
1143  if (!hin.is_dataset(ds_tag))
1144  {
1145  //for backwards compatibility
1146  if (grp == 0)
1147  ds_tag = "CI_Alpha";
1148  else if (grp == 1)
1149  ds_tag = "CI_Beta";
1150  }
1151 
1152  if (!hin.is_dataset_of_type<uint64_t>(ds_tag))
1153  {
1154  if (hin.is_dataset_of_type<int64_t>(ds_tag))
1155  APP_ABORT(
1156  "QMCPACK expects the HDF5 CI vectors to be stored as unsigned 64 bit integers. This HDF5 uses signed 64 "
1157  "bit integers. The determinants_tools.py script can transform this file using the 'transform' flag.");
1158  APP_ABORT("Unknown HDF5 CI format");
1159  }
1160 
1161  if (!hin.readEntry(temps[grp], ds_tag))
1162  throw std::runtime_error("Unknown HDF5 CI format");
1163  }
1164 
1165  std::vector<std::string> MyCIs(nGroups);
1166  std::vector<ci_configuration> dummyCs(nGroups);
1167  for (int grp = 0; grp < nGroups; grp++)
1168  {
1169  MyCIs[grp].resize(nstates);
1170  dummyCs[grp].occup.resize(nstates, false);
1171  for (size_t i = 0; i < nstates; i++)
1172  dummyCs[grp].occup[i] = true;
1173  }
1174 
1175  hin.close();
1176  app_log() << " Done reading " << ndets << " CIs from H5!" << std::endl;
1177 
1178  std::vector<int> cnts(nGroups, 0);
1179  std::vector<std::unordered_map<std::string, int>> MyMaps(nGroups);
1180 
1181  app_log() << " Sorting unique CIs" << std::endl;
1182  ///This loop will find all unique Determinants in and store them "unsorted" in a new container uniqueConfg_up
1183  ///and uniqueConfg_dn. The sorting is not done here
1184  for (int ni = 0; ni < ndets; ni++)
1185  {
1186  if (std::abs(CIcoeff[ni]) < cutoff)
1187  continue;
1188 
1189  int j = 0;
1190  for (int k = 0; k < N_int; k++)
1191  {
1192  std::vector<std::bitset<bit_kind>> a2s(nGroups);
1193  for (int grp = 0; grp < nGroups; grp++)
1194  {
1195  uint64_t a = temps[grp][ni][k];
1196  a2s[grp] = a;
1197  }
1198 
1199  for (int i = 0; i < bit_kind; i++)
1200  {
1201  if (j < nstates)
1202  {
1203  for (int grp = 0; grp < nGroups; grp++)
1204  MyCIs[grp][j] = a2s[grp][i] ? '1' : '0';
1205  j++;
1206  }
1207  }
1208  }
1209  coeff.push_back(CIcoeff[ni]);
1210  std::ostringstream h5tag;
1211  h5tag << "CIcoeff_" << ni;
1212  CItags.push_back(h5tag.str());
1213 
1214  for (int grp = 0; grp < nGroups; grp++)
1215  {
1216  std::unordered_map<std::string, int>::const_iterator got = MyMaps[grp].find(MyCIs[grp]);
1217 
1218  if (got == MyMaps[grp].end())
1219  {
1220  uniqueConfgs[grp].push_back(dummyCs[grp]);
1221  uniqueConfgs[grp].back().add_occupation(MyCIs[grp]);
1222  C2nodes[grp].push_back(cnts[grp]);
1223  MyMaps[grp].insert(std::pair<std::string, int>(MyCIs[grp], cnts[grp]));
1224  cnts[grp]++;
1225  }
1226  else
1227  {
1228  C2nodes[grp].push_back(got->second);
1229  }
1230  }
1231  sumsq += CIcoeff[ni] * CIcoeff[ni];
1232  }
1233 
1234  app_log() << " Done Sorting unique CIs" << std::endl;
1235  app_log() << "Found " << coeff.size() << " terms in the MSD expansion.\n";
1236  if (coeff.size() == 0)
1237  throw std::runtime_error(
1238  "MSD expansion is empty with either zero determinants input or remaining after cutoff applied.");
1239 
1240  app_log() << "Norm of ci vector (sum of ci^2): " << sumsq << std::endl;
1241 
1242  for (auto grp = 0; grp < nGroups; grp++)
1243  app_log() << "Found " << uniqueConfgs[grp].size() << " unique group " << grp << " determinants.\n";
1244 
1245  return success;
1246 }
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
std::ostream & app_log()
Definition: OutputManager.h:65
bool put(xmlNodePtr cur)
assign attributes to the set
Definition: AttributeSet.h:55
class to handle a set of attributes of an xmlNode
Definition: AttributeSet.h:24
#define APP_ABORT(msg)
Widely used but deprecated fatal error macros from legacy code.
Definition: AppAbort.h:27
void readCoeffs(hdf_archive &hin, std::vector< VT > &ci_coeff, size_t n_dets, int ext_level) const
QMCTraits::RealType RealType
void add(PDT &aparam, const std::string &aname, std::vector< PDT > candidate_values={}, TagStatus status=TagStatus::OPTIONAL)
add a new attribute
Definition: AttributeSet.h:42
std::string getNodeName(xmlNodePtr cur)
Definition: libxmldefs.cpp:15

Member Data Documentation

◆ ptclPool

const PSetMap& ptclPool
private

reference to a PSetMap

Definition at line 66 of file SlaterDetBuilder.h.

Referenced by SlaterDetBuilder::buildComponent().

◆ sposet_builder_factory_

SPOSetBuilderFactory& sposet_builder_factory_
private

reference to the sposet_builder_factory, should be const once the legacy input style is removed

Definition at line 62 of file SlaterDetBuilder.h.

Referenced by SlaterDetBuilder::buildComponent(), and SlaterDetBuilder::putDeterminant().

◆ targetPsi

TrialWaveFunction& targetPsi
private

reference to TrialWaveFunction, should go away as the CUDA code.

Definition at line 64 of file SlaterDetBuilder.h.


The documentation for this class was generated from the following files: