20 #include <type_traits> 22 #include <unordered_map> 65 xmlNodePtr curRoot = cur;
66 bool multiDet =
false;
67 std::string msd_algorithm;
69 std::unique_ptr<WaveFunctionComponent> built_singledet_or_multidets;
71 std::unique_ptr<SPOSetBuilder> legacy_input_sposet_builder;
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." 82 std::unique_ptr<BackflowTransformation> BFTrans;
83 cur = curRoot->children;
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." 92 app_log() <<
"Creating SPOSet in SlaterDetBuilder::put(xmlNodePtr cur).\n";
93 assert(legacy_input_sposet_builder);
98 app_log() <<
"Creating Backflow transformation in SlaterDetBuilder::put(xmlNodePtr cur).\n";
104 "Please collect all transformations into a single block.");
112 cur = curRoot->children;
119 app_summary() <<
" Single Slater determinant" << std::endl;
120 app_summary() <<
" -------------------------" << std::endl;
122 if (built_singledet_or_multidets)
125 std::vector<std::unique_ptr<DiracDeterminantBase>> dirac_dets;
126 size_t spin_group = 0;
127 xmlNodePtr tcur = cur->children;
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());
139 dirac_dets.push_back(
putDeterminant(tcur, spin_group, legacy_input_sposet_builder, BFTrans));
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());
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()));
159 std::make_unique<SlaterDetWithBackflow>(
targetPtcl, std::move(dirac_dets_bf), std::move(BFTrans));
160 built_singledet_or_multidets = std::move(single_det);
163 built_singledet_or_multidets = std::make_unique<SlaterDet>(
targetPtcl, std::move(dirac_dets));
168 app_summary() <<
" Multi Slater determinants" << std::endl;
169 app_summary() <<
" -------------------------" << std::endl;
172 if (built_singledet_or_multidets)
176 std::vector<std::string> spoNames(nGroups);
180 for (
int grp = 0; grp < nGroups; grp++)
181 spoAttrib.
add(spoNames[grp],
"spo_" + std::to_string(grp));
184 spoAttrib.
add(spoNames[0],
"spo_up");
185 spoAttrib.
add(spoNames[1],
"spo_dn");
188 spoAttrib.
add(msd_algorithm,
"algorithm", {
"precomputed_table_method",
"table_method"});
192 std::vector<std::unique_ptr<SPOSet>> spo_clones;
194 for (
int grp = 0; grp < nGroups; grp++)
197 if (spo_tmp ==
nullptr)
199 std::stringstream err_msg;
200 err_msg <<
"In SlaterDetBuilder: SPOSet \"" << spoNames[grp]
201 <<
"\" is not found. Expected for MultiSlaterDeterminant." << std::endl;
204 spo_clones.emplace_back(spo_tmp->
makeClone());
207 app_summary() <<
" Using Bryan's table method." << std::endl;
211 if (msd_algorithm ==
"precomputed_table_method")
212 app_summary() <<
" Using the table method with precomputing. Faster" << std::endl;
214 app_summary() <<
" Using the table method without precomputing. Slower." << std::endl;
217 msd_algorithm ==
"precomputed_table_method");
222 msd_fast->buildOptVariables();
223 built_singledet_or_multidets = std::move(msd_fast);
228 if (built_singledet_or_multidets)
229 return built_singledet_or_multidets;
233 PRE.
error(
"Failed to create a Single Slater determinant or Multi Slater determinants object.",
true);
251 const std::unique_ptr<SPOSetBuilder>& legacy_input_sposet_builder,
252 const std::unique_ptr<BackflowTransformation>& BFTrans)
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");
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");
271 std::string s_cutoff(
"0.0");
272 std::string s_radius(
"0.0");
273 int s_smallnumber(-999999);
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");
285 std::string matrix_inverter;
286 std::string use_batch;
291 sdAttrib.
add(delay_rank,
"delay_rank");
293 sdAttrib.
add(matrix_inverter,
"matrix_inverter", {
"gpu",
"host"});
294 #if defined(ENABLE_OFFLOAD) 295 sdAttrib.
add(use_batch,
"batch", {
"yes",
"no"});
297 sdAttrib.
add(use_batch,
"batch", {
"no",
"yes"});
299 #if defined(ENABLE_OFFLOAD) 300 #if defined(ENABLE_CUDA) || defined(ENABLE_SYCL) 306 sdAttrib.
put(cur->parent);
309 int spin_group_in = spin_group;
310 if (isdigit(spin_name[0]))
311 spin_group_in = atoi(spin_name.c_str());
313 spin_group_in = target_species.
findSpecies(spin_name);
314 if (spin_group_in < target_species.
size() && spin_group_in != spin_group)
316 spin_group = spin_group_in;
317 app_log() <<
" Overwrite group = " << spin_group << std::endl;
322 if (sposet_name.empty())
323 sposet_name = detname;
328 app_summary() <<
" Name: " << detname <<
" Spin group: " << spin_group <<
" SPO name: " << sposet_name
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." 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);
346 std::unique_ptr<SPOSet> psi_clone(psi->
makeClone());
347 psi_clone->checkObject();
352 if (delay_rank < 0 || delay_rank > lastIndex - firstIndex)
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);
361 else if (delay_rank == 0)
363 if (lastIndex - firstIndex >= 192)
367 app_summary() <<
" Setting delay_rank to default value " << delay_rank << std::endl;
371 app_summary() <<
" Using rank-" << delay_rank <<
" delayed update" << std::endl;
373 app_summary() <<
" Using rank-1 Sherman-Morrison Fahy update (SM1)" << std::endl;
375 std::unique_ptr<DiracDeterminantBase> adet;
379 app_summary() <<
" Using backflow transformation." << std::endl;
380 adet = std::make_unique<DiracDeterminantWithBackflow>(std::move(psi_clone), *BFTrans, firstIndex, lastIndex);
387 app_summary() <<
" Matrix inversion running on host." << std::endl;
389 if (use_batch ==
"yes")
391 app_summary() <<
" Using walker batching." << std::endl;
393 #if defined(ENABLE_CUDA) && defined(ENABLE_OFFLOAD) 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,
400 matrix_inverter_kind);
404 #if defined(ENABLE_SYCL) && defined(ENABLE_OFFLOAD) 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,
411 matrix_inverter_kind);
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;
421 app_summary() <<
" Running OpenMP offload code path on a CPU. " << std::endl;
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);
429 if (useGPU ==
"omptarget")
430 throw std::runtime_error(
"No OpenMP offload implementation of single-walker Slater determinant.");
431 #if defined(ENABLE_CUDA) 434 app_summary() <<
" Running on a GPU via CUDA/HIP acceleration." << std::endl;
435 adet = std::make_unique<
437 firstIndex, lastIndex,
439 matrix_inverter_kind);
441 #elif defined(ENABLE_SYCL) 444 app_summary() <<
" Running on a GPU via SYCL acceleration." << std::endl;
445 adet = std::make_unique<
447 firstIndex, lastIndex,
449 matrix_inverter_kind);
455 adet = std::make_unique<DiracDeterminant<>>(std::move(psi_clone), firstIndex, lastIndex, delay_rank,
456 matrix_inverter_kind);
469 std::vector<std::unique_ptr<SPOSet>>&& spo_clones,
471 const bool use_precompute)
const 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);
479 auto C_ptr = std::make_unique<std::vector<ValueType>>();
482 auto myVars_ptr = std::make_unique<opt_variables_type>();
483 auto& myVars(*myVars_ptr);
485 bool Optimizable =
false;
486 bool CI_Optimizable =
false;
490 std::vector<int> nptcls(nGroups);
491 for (
int grp = 0; grp < nGroups; grp++)
494 std::vector<std::vector<ci_configuration>> uniqueConfgs(nGroups);
495 std::vector<std::string> CItags;
499 xmlNodePtr curTemp = cur, DetListNode =
nullptr;
500 curTemp = curTemp->children;
501 while (curTemp != NULL)
504 if (cname ==
"detlist")
505 DetListNode = curTemp;
506 curTemp = curTemp->next;
509 std::unique_ptr<CSFData> csf_data_ptr;
512 if (!HDF5Path.empty())
514 app_log() <<
"Found Multideterminants in H5 File" << std::endl;
515 readDetListH5(cur, uniqueConfgs, C2nodes, CItags,
C, optimizeCI, nptcls);
518 readDetList(cur, uniqueConfgs, C2nodes, CItags,
C, optimizeCI, nptcls, csf_data_ptr);
520 const auto maxloc = std::max_element(
C.begin(),
C.end(), [](
ValueType const& lhs,
ValueType const& rhs) {
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;
526 assert(nGroups == spo_clones.size());
527 std::vector<std::unique_ptr<MultiDiracDeterminant>> dets;
528 for (
int grp = 0; grp < nGroups; grp++)
530 dets.emplace_back(std::make_unique<MultiDiracDeterminant>(std::move(spo_clones[grp]), spinor,
targetPtcl.
first(grp),
532 std::vector<ci_configuration2> list(uniqueConfgs[grp].size());
533 for (
int i = 0; i < list.size(); i++)
535 list[i].occup.resize(nptcls[grp]);
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])
542 APP_ABORT(
"Error in SlaterDetBuilder::createMSDFast for ptcl group " 543 << grp <<
", problems with ci configuration list. \n");
547 dets[grp]->createDetData(C2nodes[grp][refdet_id], list, C2nodes[grp], C2nodes_sorted[grp]);
550 if (csf_data_ptr && csf_data_ptr->coeffs.size() == 1)
555 app_log() <<
"CI coefficients are optimizable. \n";
556 std::string resetCI(
"no");
558 spoAttrib.
add(resetCI,
"reset_coeff");
560 if (resetCI ==
"yes")
563 for (
int i = 1; i < csf_data_ptr->coeffs.size(); i++)
564 csf_data_ptr->coeffs[i] = 0;
566 for (
int i = 1; i <
C.size(); i++)
568 app_log() <<
"CI coefficients are reset. \n";
570 Optimizable = CI_Optimizable =
true;
572 for (
int i = 1; i < csf_data_ptr->coeffs.size(); i++)
575 for (
int i = 1; i <
C.size(); i++)
580 app_log() <<
"CI coefficients are not optimizable. \n";
581 CI_Optimizable =
false;
584 bool any_optimizable =
false;
585 for (
int grp = 0; grp < nGroups; grp++)
587 if (dets[grp]->isOptimizable() ==
true)
589 any_optimizable =
true;
595 for (
int grp = 0; grp < nGroups; grp++)
597 if (dets[grp]->isOptimizable() !=
true)
598 APP_ABORT(
"Optimizing the SPOSet of only only species is not supported!\n");
601 APP_ABORT(
"Currently, Using CSF is not available with MSJ Orbital Optimization!\n");
603 for (
int grp = 0; grp < nGroups; grp++)
605 for (
int i = 0; i < nptcls[grp]; i++)
607 if (uniqueConfgs[grp][0].occup[i] !=
true)
609 "The Hartee Fock Reference Determinant must be the first in the Multi-Slater expansion for the input!\n");
612 app_warning() <<
"Unrestricted Orbital Optimization will be performed. Spin symmetry is not guaranteed to be " 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);
626 std::vector<std::vector<ci_configuration>>& uniqueConfgs,
627 std::vector<std::vector<size_t>>& C2nodes,
628 std::vector<std::string>& CItags,
629 std::vector<ValueType>& coeff,
631 std::vector<int>& nptcls,
632 std::unique_ptr<CSFData>& csf_data_ptr)
const 636 const int nGroups = uniqueConfgs.size();
637 for (
int grp = 0; grp < nGroups; grp++)
639 uniqueConfgs[grp].clear();
640 C2nodes[grp].clear();
644 std::vector<std::vector<ci_configuration>> confgLists(nGroups);
645 std::string optCI =
"no";
649 ciAttrib.
add(optCI,
"optimize");
650 ciAttrib.
add(optCI,
"Optimize");
652 optimizeCI = (optCI ==
"yes");
653 xmlNodePtr curRoot = cur, DetListNode =
nullptr;
654 cur = curRoot->children;
658 if (cname ==
"detlist")
661 app_log() <<
"Found determinant list. \n";
666 std::vector<size_t> NCs(nGroups);
667 std::vector<size_t> NEs(nGroups);
671 std::string Dettype =
"DETS";
672 std::string CSFChoice =
"qchem_coeff";
674 for (
int grp = 0; grp < nGroups; grp++)
676 spoAttrib.
add(NCs[grp],
"nc" + std::to_string(grp));
677 spoAttrib.
add(NEs[grp],
"ne" + std::to_string(grp));
681 spoAttrib.
add(NCs[0],
"nca");
682 spoAttrib.
add(NCs[1],
"ncb");
683 spoAttrib.
add(NEs[0],
"nea");
684 spoAttrib.
add(NEs[1],
"neb");
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);
697 APP_ABORT(
"size==0 in detlist is not allowed. Use slaterdeterminant in this case.\n");
700 if (Dettype ==
"CSF")
701 csf_data_ptr = std::make_unique<CSFData>();
702 else if (Dettype !=
"DETS" && Dettype !=
"Determinants")
704 APP_ABORT(
"Only allowed type in detlist is DETS or CSF.\n");
708 app_log() <<
" Initializing CI coeffs less than " << zero_cutoff <<
" to zero." << std::endl;
710 for (
int grp = 0; grp < nGroups; grp++)
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));
718 cur = DetListNode->children;
719 std::vector<ci_configuration> dummyCs(nGroups);
720 for (
int grp = 0; grp < nGroups; grp++)
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;
730 auto& CSFcoeff = csf_data_ptr->coeffs;
731 auto& DetsPerCSF = csf_data_ptr->dets_per_csf;
732 auto& CSFexpansion = csf_data_ptr->expansion;
734 app_log() <<
"Reading CSFs." << std::endl;
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");
762 "SlaterDetBuilder::readDetList. Build with QMC_COMPLEX if using complex CI expansion coefficients.");
766 if (((
std::abs(qc_ci) < cutoff) && (CSFChoice ==
"qchem_coeff")) ||
767 ((CSFChoice ==
"exctLvl") && (exctLvl > cutoff)) || ((CSFChoice ==
"coeff") && (
std::abs(ci) < cutoff)))
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;
786 std::vector<std::string> occs(nGroups);
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));
796 detAttrib.
add(occs[0],
"alpha");
797 detAttrib.
add(occs[1],
"beta");
800 for (
int grp = 0; grp < nGroups; grp++)
803 if (occs[grp].size() < nstates)
805 std::cerr <<
"occ" << grp <<
": " << occs[grp] << std::endl;
806 APP_ABORT(
"Found incorrect group" + std::to_string(grp) +
" determinant label. size < nc+nstates");
808 for (
size_t i = 0; i < nstates; i++)
810 if (occs[grp][i] !=
'0' && occs[grp][i] !=
'1')
812 std::cerr << occs[grp] << std::endl;
813 APP_ABORT(
"Found incorrect determinant label.");
815 if (occs[grp][i] ==
'1')
820 std::cerr <<
"occ" << grp <<
": " << occs[grp] << std::endl;
821 APP_ABORT(
"Found incorrect group" + std::to_string(grp) +
" determinant label. nocc != nc+ne");
825 CSFexpansion.push_back(coef);
826 coeff.push_back(coef * ci);
827 for (
int grp = 0; grp < nGroups; grp++)
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');
838 if (DetsPerCSF.back() == 0)
840 APP_ABORT(
"Found empty CSF (no det blocks).");
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");
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";
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++)
862 for (
size_t i = 0; i < confgLists[grp].size(); i++)
866 for (
size_t j = 0; j < uniqueConfgs[grp].size(); j++)
868 if (confgLists[grp][i] == uniqueConfgs[grp][j])
881 uniqueConfgs[grp].push_back(confgLists[grp][i]);
882 C2nodes[grp][i] = uniqueConfgs[grp].size() - 1;
889 app_log() <<
"Reading CI expansion." << std::endl;
891 std::vector<int> cnts(nGroups, 0);
892 std::vector<std::unordered_map<std::string, int>> MyMaps(nGroups);
896 if (cname ==
"configuration" || cname ==
"ci")
899 std::vector<std::string> occs(nGroups);
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));
911 confAttrib.
add(occs[0],
"alpha");
912 confAttrib.
add(occs[1],
"beta");
914 confAttrib.
add(tag,
"id");
923 "SlaterDetBuilder::readDetList. Build with QMC_COMPLEX if using complex CI expansion coefficients.");
934 for (
int grp = 0; grp < nGroups; grp++)
936 for (
size_t i = 0; i < nstates; i++)
938 if (occs[grp][i] !=
'0' && occs[grp][i] !=
'1')
940 std::cerr << occs[grp] << std::endl;
941 APP_ABORT(
"Found incorrect determinant label for group " + std::to_string(grp));
944 if (occs[grp].size() < nstates)
946 std::cerr <<
"occ" << grp <<
": " << occs[grp] << std::endl;
947 APP_ABORT(
"Found incorrect group" + std::to_string(grp) +
" determinant label. size < nc+nstates");
952 CItags.push_back(tag);
954 for (
int grp = 0; grp < nGroups; grp++)
956 std::unordered_map<std::string, int>::const_iterator got = MyMaps[grp].find(occs[grp]);
957 if (got == MyMaps[grp].end())
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]));
967 C2nodes[grp].push_back(got->second);
972 sumsq_qc += qc_ci * qc_ci;
978 app_log() <<
"Found " << coeff.size() <<
" terms in the MSD expansion.\n";
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.");
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;
989 for (
auto grp = 0; grp < nGroups; grp++)
990 app_log() <<
"Found " << uniqueConfgs[grp].size() <<
" unique group " << grp <<
" determinants.\n";
996 std::vector<std::vector<ci_configuration>>& uniqueConfgs,
997 std::vector<std::vector<size_t>>& C2nodes,
998 std::vector<std::string>& CItags,
999 std::vector<ValueType>& coeff,
1001 std::vector<int>& nptcls)
const 1003 bool success =
true;
1005 const int nGroups = uniqueConfgs.size();
1006 for (
int grp = 0; grp < nGroups; grp++)
1008 uniqueConfgs[grp].clear();
1009 C2nodes[grp].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";
1020 ciAttrib.
add(optCI,
"optimize");
1022 optimizeCI = (optCI ==
"yes");
1023 xmlNodePtr curRoot = cur, DetListNode =
nullptr;
1024 std::string multidetH5path;
1025 cur = curRoot->children;
1029 if (cname ==
"detlist")
1032 app_log() <<
"Found determinant list. \n";
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] <<
", ";
1043 size_t H5_ndets, H5_nstates;
1045 const unsigned bit_kind = 64;
1046 static_assert(bit_kind ==
sizeof(uint64_t) * 8,
"Must be 64 bit fixed width integer");
1049 std::string Dettype =
"DETS";
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);
1062 APP_ABORT(
"size==0 in detlist is not allowed. Use slaterdeterminant in this case.\n");
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;
1070 if (!hin.
open(multidetH5path.c_str(), H5F_ACC_RDONLY))
1072 std::cerr <<
"Could not open H5 file" << std::endl;
1077 hin.
push(
"MultiDet",
false);
1079 hin.
read(H5_ndets,
"NbDet");
1080 if (ndets != H5_ndets)
1082 std::cerr <<
"Number of determinants in H5 file (" << H5_ndets <<
") different from number of dets in XML (" 1083 << ndets <<
")" << std::endl;
1087 hin.
read(H5_nstates,
"nstate");
1089 nstates = H5_nstates;
1090 else if (nstates != H5_nstates)
1092 std::cerr <<
"Number of states/orbitals in H5 file (" << H5_nstates
1093 <<
") different from number of states/orbitals in XML (" << nstates <<
")" << std::endl;
1097 hin.
read(N_int,
"Nbits");
1098 CIcoeff.resize(ndets);
1099 ConfigTag.resize(ndets);
1108 if (CICoeffH5path !=
"")
1111 std::vector<ValueType> CIcoeffopt;
1113 if (!coeffin.
open(CICoeffH5path.c_str(), H5F_ACC_RDONLY))
1115 std::cerr <<
"Could not open H5 file containing Optimized Coefficients" << std::endl;
1119 coeffin.
push(
"MultiDet",
false);
1121 coeffin.
read(OptCiSize,
"NbDet");
1122 CIcoeffopt.resize(OptCiSize);
1124 readCoeffs(coeffin, CIcoeffopt, ndets, extlevel);
1128 for (
int i = 0; i < OptCiSize; i++)
1129 CIcoeff[i + 1] = CIcoeffopt[i];
1131 app_log() <<
"The first " << OptCiSize
1132 <<
" Optimized coefficients were substituted to the original set of coefficients." << std::endl;
1135 std::vector<Matrix<uint64_t>> temps;
1136 for (
int grp = 0; grp < nGroups; grp++)
1139 temps.push_back(tmp);
1142 std::string ds_tag =
"CI_" + std::to_string(grp);
1147 ds_tag =
"CI_Alpha";
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.");
1162 throw std::runtime_error(
"Unknown HDF5 CI format");
1165 std::vector<std::string> MyCIs(nGroups);
1166 std::vector<ci_configuration> dummyCs(nGroups);
1167 for (
int grp = 0; grp < nGroups; grp++)
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;
1176 app_log() <<
" Done reading " << ndets <<
" CIs from H5!" << std::endl;
1178 std::vector<int> cnts(nGroups, 0);
1179 std::vector<std::unordered_map<std::string, int>> MyMaps(nGroups);
1181 app_log() <<
" Sorting unique CIs" << std::endl;
1184 for (
int ni = 0; ni < ndets; ni++)
1186 if (
std::abs(CIcoeff[ni]) < cutoff)
1190 for (
int k = 0; k < N_int; k++)
1192 std::vector<std::bitset<bit_kind>> a2s(nGroups);
1193 for (
int grp = 0; grp < nGroups; grp++)
1195 uint64_t a = temps[grp][ni][k];
1199 for (
int i = 0; i < bit_kind; i++)
1203 for (
int grp = 0; grp < nGroups; grp++)
1204 MyCIs[grp][j] = a2s[grp][i] ?
'1' :
'0';
1209 coeff.push_back(CIcoeff[ni]);
1210 std::ostringstream h5tag;
1211 h5tag <<
"CIcoeff_" << ni;
1212 CItags.push_back(h5tag.str());
1214 for (
int grp = 0; grp < nGroups; grp++)
1216 std::unordered_map<std::string, int>::const_iterator got = MyMaps[grp].find(MyCIs[grp]);
1218 if (got == MyMaps[grp].end())
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]));
1228 C2nodes[grp].push_back(got->second);
1231 sumsq += CIcoeff[ni] * CIcoeff[ni];
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.");
1240 app_log() <<
"Norm of ci vector (sum of ci^2): " << sumsq << std::endl;
1242 for (
auto grp = 0; grp < nGroups; grp++)
1243 app_log() <<
"Found " << uniqueConfgs[grp].size() <<
" unique group " << grp <<
" determinants.\n";
base class for Single-particle orbital sets
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()
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
std::unique_ptr< WaveFunctionComponent > buildComponent(xmlNodePtr cur) override
initialize the Antisymmetric wave function for electrons
bool open(const std::filesystem::path &fname, unsigned flags=H5F_ACC_RDWR)
open a file
helper functions for EinsplineSetBuilder
An abstract class for wave function builders.
Tensor< T, D >::Type_t det(const Tensor< T, D > &a)
virtual std::unique_ptr< SPOSet > makeClone() const
make a clone of itself every derived class must implement this to have threading working correctly...
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
std::ostream & app_summary()
bool put(xmlNodePtr cur)
assign attributes to the set
DetMatInvertor
determinant matrix inverter select
void close()
close all the open groups and file
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
int first(int igroup) const
return the first index of a group i
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 ...
bool is_dataset_of_type(const std::string &aname)
check if aname is a dataset of type T
int size() const
return the number of species
std::map< std::string, const std::unique_ptr< ParticleSet > > PSetMap
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])
Wrapping information on parallelism.
int groups() const
return the number of groups
void addSPOSet(std::unique_ptr< SPOSet >)
add an SPOSet to sposets map.
Specialized paritlce class for atomistic simulations.
WaveFunctionComponent::ValueType ValueType
double norm(const zVec &c)
Final class and should not be derived.
Communicate * myComm
pointer to Communicate
class to handle a set of attributes of an xmlNode
declaration of ProgressReportEngine
bool is_dataset(const std::string &aname)
check if aname is a dataset
int groupsize(int igroup) const
return the size of a group
std::string ClassName
class Name
#define APP_ABORT(msg)
Widely used but deprecated fatal error macros from legacy code.
int last(int igroup) const
return the last index of a group i
static PlatformKind selectPlatform(std::string_view value)
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...
WaveFunctionComponent::RealType RealType
SlaterDetBuilder(Communicate *comm, SPOSetBuilderFactory &factory, ParticleSet &els, TrialWaveFunction &psi, const PSetMap &psets)
constructor
static std::string sd_tag
the element name for a Slater determinant, contains 1..* determinants
std::unique_ptr< BackflowTransformation > buildBackflowTransformation(xmlNodePtr cur)
SpeciesSet & getSpeciesSet()
retrun the SpeciesSet of this particle set
void push(const std::string &gname, bool createit=true)
push a group to the group stack
std::vector< std::string > speciesName
Species name list.
void readCoeffs(hdf_archive &hin, std::vector< VT > &ci_coeff, size_t n_dets, int ext_level) const
Declaration of DiracDeterminantBatched with a S(ingle)P(article)O(rbital)Set.
Class to represent a many-body trial wave function.
void error(const std::string &msg, bool fatal=false)
static std::string backflow_tag
the element name for a backflow transformation
void read(T &data, const std::string &aname)
read the data from the group aname and check status runtime error is issued on I/O error ...
Declaration of DiracDeterminant with a S(ingle)P(article)O(rbital)Set.
std::unique_ptr< SPOSetBuilder > createSPOSetBuilder(xmlNodePtr rootNode)
static std::string sposet_tag
the element name for single-particle orbital set
Custom container for set of attributes for a set of species.
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
int findSpecies(const std::string &name) const
if the input species is not found, add a new species
void barrier_and_abort(const std::string &msg) const
bool readEntry(T &data, const std::string &aname)
read the data from the group aname and return status use read() for inbuilt error checking ...
Declaration of DiracDeterminantWithBackflow with a S(ingle)P(article)O(rbital)Set.
SPOSetBuilderFactory & sposet_builder_factory_
reference to the sposet_builder_factory, should be const once the legacy input style is removed ...
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
std::string getNodeName(xmlNodePtr cur)
const PSetMap & ptclPool
reference to a PSetMap
const std::vector< std::string > candidate_values