From 0a7ced5b0472b32f6c1fa8ba17bc45a42409a392 Mon Sep 17 00:00:00 2001 From: Ye Luo Date: Thu, 11 Aug 2022 00:48:53 -0500 Subject: [PATCH 1/5] Support multi-step WFOpt --- src/QMCDrivers/WFOpt/QMCCostFunctionBase.cpp | 4 +- .../Fermion/MultiSlaterDetTableMethod.cpp | 5 +- src/QMCWaveFunctions/Jastrow/BsplineFunctor.h | 1 + .../Jastrow/PolynomialFunctor3D.h | 16 +++- src/QMCWaveFunctions/VariableSet.cpp | 4 +- src/QMCWaveFunctions/VariableSet.h | 15 ++- tests/molecules/H4_ae/CMakeLists.txt | 22 ++++- tests/molecules/H4_ae/H4.wfs_j123.xml | 71 ++++++++++++++ .../H4_ae/optm-OneShiftOnly-multistep.xml | 92 +++++++++++++++++++ 9 files changed, 211 insertions(+), 19 deletions(-) create mode 100644 tests/molecules/H4_ae/H4.wfs_j123.xml create mode 100644 tests/molecules/H4_ae/optm-OneShiftOnly-multistep.xml diff --git a/src/QMCDrivers/WFOpt/QMCCostFunctionBase.cpp b/src/QMCDrivers/WFOpt/QMCCostFunctionBase.cpp index 9f47967f21..6026bd3973 100644 --- a/src/QMCDrivers/WFOpt/QMCCostFunctionBase.cpp +++ b/src/QMCDrivers/WFOpt/QMCCostFunctionBase.cpp @@ -414,7 +414,7 @@ bool QMCCostFunctionBase::put(xmlNodePtr q) if (obj.isOptimized()) obj.checkInVariablesExclusive(OptVariablesForPsi); OptVariablesForPsi.resetIndex(); - app_log() << "Totally " << OptVariablesForPsi.size() << " parameters being optimzied." << std::endl; + app_log() << " Selected " << OptVariablesForPsi.size() << " variational parameters." << std::endl; //synchronize OptVariables and OptVariablesForPsi OptVariables = OptVariablesForPsi; @@ -482,6 +482,8 @@ bool QMCCostFunctionBase::put(xmlNodePtr q) { APP_ABORT("QMCCostFunctionBase::put No valid optimizable variables are found."); } + else + app_log() << " Totally " << NumOptimizables << " parameters being optimized after applying constraints." << std::endl; // app_log() << " " << std::endl; // OptVariables.print(app_log()); // app_log() << "" << std::endl; diff --git a/src/QMCWaveFunctions/Fermion/MultiSlaterDetTableMethod.cpp b/src/QMCWaveFunctions/Fermion/MultiSlaterDetTableMethod.cpp index cb3f1cc940..e090c496c9 100644 --- a/src/QMCWaveFunctions/Fermion/MultiSlaterDetTableMethod.cpp +++ b/src/QMCWaveFunctions/Fermion/MultiSlaterDetTableMethod.cpp @@ -35,7 +35,7 @@ MultiSlaterDetTableMethod::MultiSlaterDetTableMethod(ParticleSet& targetPtcl, CI_Optimizable(false), use_pre_computing_(use_pre_computing) { - Dets = std::move(dets); + Dets = std::move(dets); C_otherDs.resize(Dets.size()); int NP = targetPtcl.getTotalNum(); myG.resize(NP); @@ -735,7 +735,10 @@ void MultiSlaterDetTableMethod::extractOptimizableObjectRefs(UniqueOptObjRefs& o void MultiSlaterDetTableMethod::checkInVariablesExclusive(opt_variables_type& active) { if (CI_Optimizable && myVars->size()) + { + myVars->setIndexDefault(); active.insertFrom(*myVars); + } } void MultiSlaterDetTableMethod::checkInVariables(opt_variables_type& active) diff --git a/src/QMCWaveFunctions/Jastrow/BsplineFunctor.h b/src/QMCWaveFunctions/Jastrow/BsplineFunctor.h index 76da6b7f0f..8dacfb64cf 100644 --- a/src/QMCWaveFunctions/Jastrow/BsplineFunctor.h +++ b/src/QMCWaveFunctions/Jastrow/BsplineFunctor.h @@ -682,6 +682,7 @@ struct BsplineFunctor : public OptimizableFunctorBase { if (notOpt) return; + myVars.setIndexDefault(); active.insertFrom(myVars); } diff --git a/src/QMCWaveFunctions/Jastrow/PolynomialFunctor3D.h b/src/QMCWaveFunctions/Jastrow/PolynomialFunctor3D.h index 4b4b4bcc72..cb3acc928e 100644 --- a/src/QMCWaveFunctions/Jastrow/PolynomialFunctor3D.h +++ b/src/QMCWaveFunctions/Jastrow/PolynomialFunctor3D.h @@ -990,9 +990,21 @@ struct PolynomialFunctor3D : public OptimizableFunctorBase reset_gamma(); } - void checkInVariables(opt_variables_type& active) override { active.insertFrom(myVars); } + void checkInVariables(opt_variables_type& active) override + { + if (notOpt) + return; + + myVars.setIndexDefault(); + active.insertFrom(myVars); + } - void checkOutVariables(const opt_variables_type& active) override { myVars.getIndex(active); } + void checkOutVariables(const opt_variables_type& active) override + { + if (notOpt) + return; + myVars.getIndex(active); + } void print(std::ostream& os) { diff --git a/src/QMCWaveFunctions/VariableSet.cpp b/src/QMCWaveFunctions/VariableSet.cpp index 7170eefbf9..50757fa9fe 100644 --- a/src/QMCWaveFunctions/VariableSet.cpp +++ b/src/QMCWaveFunctions/VariableSet.cpp @@ -173,10 +173,10 @@ void VariableSet::getIndex(const VariableSet& selected) } } -void VariableSet::setDefaults(bool optimize_all) +void VariableSet::setIndexDefault() { for (int i = 0; i < Index.size(); ++i) - Index[i] = optimize_all ? i : -1; + Index[i] = i; } void VariableSet::print(std::ostream& os, int leftPadSpaces, bool printHeader) const diff --git a/src/QMCWaveFunctions/VariableSet.h b/src/QMCWaveFunctions/VariableSet.h index 5a6cb770b0..f9c9f674d6 100644 --- a/src/QMCWaveFunctions/VariableSet.h +++ b/src/QMCWaveFunctions/VariableSet.h @@ -46,11 +46,11 @@ struct VariableSet using value_type = qmcplusplus::QMCTraits::ValueType; using real_type = qmcplusplus::QMCTraits::RealType; - using pair_type = std::pair; - using index_pair_type = std::pair; - using iterator = std::vector::iterator; - using const_iterator = std::vector::const_iterator; - using size_type = std::vector::size_type; + using pair_type = std::pair; + using index_pair_type = std::pair; + using iterator = std::vector::iterator; + using const_iterator = std::vector::const_iterator; + using size_type = std::vector::size_type; ///number of active variables int num_active_vars; @@ -327,10 +327,9 @@ struct VariableSet */ void getIndex(const VariableSet& selected); - /** set default Indices - * @param optimize_all if true, all the variables are active + /** set default Indices, namely all the variables are active */ - void setDefaults(bool optimize_all); + void setIndexDefault(); void print(std::ostream& os, int leftPadSpaces = 0, bool printHeader = false) const; diff --git a/tests/molecules/H4_ae/CMakeLists.txt b/tests/molecules/H4_ae/CMakeLists.txt index 90c096ea87..fc9905ed6e 100644 --- a/tests/molecules/H4_ae/CMakeLists.txt +++ b/tests/molecules/H4_ae/CMakeLists.txt @@ -289,6 +289,19 @@ if(NOT QMC_CUDA) H4_OPT_SCALARS # OPT step 5 ) + list(APPEND H4_OPT_SCALARS_ONLY_JAS "totenergy" "-2.066504 0.0009") # total energy + qmc_run_and_check( + short-H4-opt-OneShiftOnly-onlyjas + "${qmcpack_SOURCE_DIR}/tests/molecules/H4_ae" + H4-OneShiftOnly + optm-OneShiftOnly-onlyjas.xml + 1 + 16 + ${SUCCESS_STATUS_MP} + 5 + H4_OPT_SCALARS_ONLY_JAS # OPT step 5 + ) + list(APPEND H4_OPT_SCALARS_ONLY_MSD "totenergy" "-2.138635 0.0009") # total energy qmc_run_and_check( short-H4-opt-OneShiftOnly-onlymsd @@ -302,17 +315,16 @@ if(NOT QMC_CUDA) H4_OPT_SCALARS_ONLY_MSD # OPT step 5 ) - list(APPEND H4_OPT_SCALARS_ONLY_JAS "totenergy" "-2.066504 0.0009") # total energy qmc_run_and_check( - short-H4-opt-OneShiftOnly-onlyjas + short-H4-optbatch-OneShiftOnly-multistep "${qmcpack_SOURCE_DIR}/tests/molecules/H4_ae" H4-OneShiftOnly - optm-OneShiftOnly-onlyjas.xml + optm-OneShiftOnly-multistep.xml 1 16 ${SUCCESS_STATUS_MP} - 5 - H4_OPT_SCALARS_ONLY_JAS # OPT step 5 + 11 + H4_OPT_SCALARS_ONLY_MSD # OPT step 011 ) else() message(VERBOSE diff --git a/tests/molecules/H4_ae/H4.wfs_j123.xml b/tests/molecules/H4_ae/H4.wfs_j123.xml new file mode 100644 index 0000000000..df4d2d1692 --- /dev/null +++ b/tests/molecules/H4_ae/H4.wfs_j123.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + 5.04668000000000e-01 4.50114000000000e-01 3.58423000000000e-01 1.26449000000000e-01 + -2.40452000000000e-01 -3.20413000000000e-01 4.66777000000000e-01 7.03549000000000e-01 + 8.80080000000000e-02 -5.04842000000000e-01 8.07522000000000e-01 -7.19301000000000e-01 + 1.03323500000000e+00 -8.77213000000000e-01 -3.90492000000000e-01 2.12318000000000e-01 + + + + + + 5.04668000000000e-01 4.50114000000000e-01 3.58423000000000e-01 1.26449000000000e-01 + -2.40452000000000e-01 -3.20413000000000e-01 4.66777000000000e-01 7.03549000000000e-01 + 8.80080000000000e-02 -5.04842000000000e-01 8.07522000000000e-01 -7.19301000000000e-01 + 1.03323500000000e+00 -8.77213000000000e-01 -3.90492000000000e-01 2.12318000000000e-01 + + + + + + + + + + + + + + + + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + + + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + + + + + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + + + + + + + + + + + + diff --git a/tests/molecules/H4_ae/optm-OneShiftOnly-multistep.xml b/tests/molecules/H4_ae/optm-OneShiftOnly-multistep.xml new file mode 100644 index 0000000000..8b748256be --- /dev/null +++ b/tests/molecules/H4_ae/optm-OneShiftOnly-multistep.xml @@ -0,0 +1,92 @@ + + + + batch + + + + + + + + + + + + + + 16 + 128 + 5 + 128 + 5 + 0.5 + yes + 262144 + 1.00 + 0.00 + 0.00 + + OneShiftOnly + uu ud + + + + + + 16 + 128 + 5 + 128 + 5 + 0.5 + yes + 262144 + 1.00 + 0.00 + 0.00 + + OneShiftOnly + uu ud eH + + + + + + 16 + 128 + 5 + 128 + 5 + 0.5 + yes + 262144 + 1.00 + 0.00 + 0.00 + + OneShiftOnly + uu ud eH CI + + + + + + 16 + 128 + 5 + 128 + 5 + 0.5 + yes + 262144 + 1.00 + 0.00 + 0.00 + + OneShiftOnly + uu ud eH uuH udH + + + + From 50f6a029f533f39d734048dd5fa4615d3bab0990 Mon Sep 17 00:00:00 2001 From: Ye Luo Date: Wed, 17 Aug 2022 15:58:19 -0500 Subject: [PATCH 2/5] Add WFopt variational_subset parameter to manual. --- docs/methods.rst | 25 +++++++++++++++++++++++++ docs/running_docker.rst | 0 2 files changed, 25 insertions(+) mode change 100755 => 100644 docs/running_docker.rst diff --git a/docs/methods.rst b/docs/methods.rst index b810d9a28f..25ad760e70 100644 --- a/docs/methods.rst +++ b/docs/methods.rst @@ -551,6 +551,31 @@ The cost function consists of three components: energy, unreweighted variance, a 0.00 0.05 +Varational paramemter selection +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The predominant way of selecting varational paramemters is via ```` input. +```` entries support ``optimize="yes"/"no"`` to enable/disable variational parameters in the wavefunction optimization. +The secondary way of selecting varational paramemters is via ``variational_subset`` parameter in the ```` driver input. +It allows controlling optimization granularity at each optimization step. +If ``variational_subset`` is not provided or empty, all the varational paramemters are selected. +If variational paramemters are set as not optimizable in the predominant way, the secondary way won't be able to set them optimizable even they are selected. + +The following example shows optimizing subsets of parameters in stages in a single QMCPACK run. + +:: + + ... + uu ud + + + ... + uu ud eH + + + ... + uu ud eH CI + + Optimizers ~~~~~~~~~~ diff --git a/docs/running_docker.rst b/docs/running_docker.rst old mode 100755 new mode 100644 From 7dfc92a4934135692ab559b5c9923b3f7e652ced Mon Sep 17 00:00:00 2001 From: Ye Luo Date: Wed, 17 Aug 2022 16:17:34 -0500 Subject: [PATCH 3/5] Correct typo. --- docs/methods.rst | 4 ++-- src/QMCDrivers/WFOpt/QMCCostFunctionBase.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/methods.rst b/docs/methods.rst index 25ad760e70..d04fb956c4 100644 --- a/docs/methods.rst +++ b/docs/methods.rst @@ -551,8 +551,8 @@ The cost function consists of three components: energy, unreweighted variance, a 0.00 0.05 -Varational paramemter selection -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Varational parameter selection +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The predominant way of selecting varational paramemters is via ```` input. ```` entries support ``optimize="yes"/"no"`` to enable/disable variational parameters in the wavefunction optimization. The secondary way of selecting varational paramemters is via ``variational_subset`` parameter in the ```` driver input. diff --git a/src/QMCDrivers/WFOpt/QMCCostFunctionBase.cpp b/src/QMCDrivers/WFOpt/QMCCostFunctionBase.cpp index 43511dd9d0..110e790d90 100644 --- a/src/QMCDrivers/WFOpt/QMCCostFunctionBase.cpp +++ b/src/QMCDrivers/WFOpt/QMCCostFunctionBase.cpp @@ -414,7 +414,7 @@ bool QMCCostFunctionBase::put(xmlNodePtr q) if (obj.isOptimized()) obj.checkInVariablesExclusive(OptVariablesForPsi); OptVariablesForPsi.resetIndex(); - app_log() << "In total " << OptVariablesForPsi.size() << " parameters being optimzied." << std::endl; + app_log() << " Variational subset selects " << OptVariablesForPsi.size() << " parameters." << std::endl; //synchronize OptVariables and OptVariablesForPsi OptVariables = OptVariablesForPsi; @@ -483,7 +483,7 @@ bool QMCCostFunctionBase::put(xmlNodePtr q) APP_ABORT("QMCCostFunctionBase::put No valid optimizable variables are found."); } else - app_log() << " Totally " << NumOptimizables << " parameters being optimized after applying constraints." << std::endl; + app_log() << " In total " << NumOptimizables << " parameters being optimized after applying constraints." << std::endl; // app_log() << " " << std::endl; // OptVariables.print(app_log()); // app_log() << "" << std::endl; From 62ffa57bedc73b903742c1828cd3eee9da129154 Mon Sep 17 00:00:00 2001 From: Ye Luo Date: Thu, 18 Aug 2022 19:38:16 -0500 Subject: [PATCH 4/5] Trap invalid variational_subset entries. --- src/QMCDrivers/WFOpt/QMCCostFunctionBase.cpp | 23 +++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/QMCDrivers/WFOpt/QMCCostFunctionBase.cpp b/src/QMCDrivers/WFOpt/QMCCostFunctionBase.cpp index 110e790d90..723f3e860d 100644 --- a/src/QMCDrivers/WFOpt/QMCCostFunctionBase.cpp +++ b/src/QMCDrivers/WFOpt/QMCCostFunctionBase.cpp @@ -21,7 +21,7 @@ #include "OhmmsData/ParameterSet.h" #include "OhmmsData/XMLParsingString.h" #include "Message/CommOperators.h" -#include +#include "Message/UniformCommunicateError.h" //#define QMCCOSTFUNCTION_DEBUG @@ -483,7 +483,8 @@ bool QMCCostFunctionBase::put(xmlNodePtr q) APP_ABORT("QMCCostFunctionBase::put No valid optimizable variables are found."); } else - app_log() << " In total " << NumOptimizables << " parameters being optimized after applying constraints." << std::endl; + app_log() << " In total " << NumOptimizables << " parameters being optimized after applying constraints." + << std::endl; // app_log() << " " << std::endl; // OptVariables.print(app_log()); // app_log() << "" << std::endl; @@ -1068,8 +1069,21 @@ bool QMCCostFunctionBase::isEffectiveWeightValid(EffectiveWeight effective_weigh UniqueOptObjRefs QMCCostFunctionBase::extractOptimizableObjects(TrialWaveFunction& psi) const { const auto& names(variational_subset_names); - /// survey all the optimizable objects + // survey all the optimizable objects const auto opt_obj_refs = psi.extractOptimizableObjectRefs(); + // check if input names are valid + for (auto& name : names) + if (std::find_if(opt_obj_refs.begin(), opt_obj_refs.end(), + [&name](const OptimizableObject& obj) { return name == obj.getName(); }) == opt_obj_refs.end()) + { + std::ostringstream msg; + msg << "Variational subset entry " << name << " doesn't exist in the trial wavefunction which contains :"; + for (OptimizableObject& obj : opt_obj_refs) + msg << " '" << obj.getName() << "'"; + msg << "." << std::endl; + throw UniformCommunicateError(msg.str()); + } + for (OptimizableObject& obj : opt_obj_refs) obj.setOptimization(names.empty() || std::find_if(names.begin(), names.end(), [&obj](const std::string& name) { return name == obj.getName(); @@ -1077,8 +1091,7 @@ UniqueOptObjRefs QMCCostFunctionBase::extractOptimizableObjects(TrialWaveFunctio return opt_obj_refs; } -void QMCCostFunctionBase::resetOptimizableObjects(TrialWaveFunction& psi, - const opt_variables_type& opt_variables) const +void QMCCostFunctionBase::resetOptimizableObjects(TrialWaveFunction& psi, const opt_variables_type& opt_variables) const { const auto opt_obj_refs = extractOptimizableObjects(psi); for (OptimizableObject& obj : opt_obj_refs) From 18b771b98aa97620087d43879ebc714d111509bf Mon Sep 17 00:00:00 2001 From: Ye Luo Date: Fri, 19 Aug 2022 08:51:36 -0500 Subject: [PATCH 5/5] Add a test for invalid variatioal_subset. --- src/QMCDrivers/WFOpt/QMCCostFunctionBase.cpp | 2 +- tests/molecules/H4_ae/CMakeLists.txt | 10 ++++++ .../det-input-check-optm-invalid-subset.xml | 35 +++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 tests/molecules/H4_ae/det-input-check-optm-invalid-subset.xml diff --git a/src/QMCDrivers/WFOpt/QMCCostFunctionBase.cpp b/src/QMCDrivers/WFOpt/QMCCostFunctionBase.cpp index 723f3e860d..8552d2bdf2 100644 --- a/src/QMCDrivers/WFOpt/QMCCostFunctionBase.cpp +++ b/src/QMCDrivers/WFOpt/QMCCostFunctionBase.cpp @@ -1077,7 +1077,7 @@ UniqueOptObjRefs QMCCostFunctionBase::extractOptimizableObjects(TrialWaveFunctio [&name](const OptimizableObject& obj) { return name == obj.getName(); }) == opt_obj_refs.end()) { std::ostringstream msg; - msg << "Variational subset entry " << name << " doesn't exist in the trial wavefunction which contains :"; + msg << "Variational subset entry '" << name << "' doesn't exist in the trial wavefunction which contains"; for (OptimizableObject& obj : opt_obj_refs) msg << " '" << obj.getName() << "'"; msg << "." << std::endl; diff --git a/tests/molecules/H4_ae/CMakeLists.txt b/tests/molecules/H4_ae/CMakeLists.txt index 96744ed08b..5e1934cc2b 100644 --- a/tests/molecules/H4_ae/CMakeLists.txt +++ b/tests/molecules/H4_ae/CMakeLists.txt @@ -352,6 +352,16 @@ if(NOT QMC_CUDA) 11 H4_OPT_SCALARS_ONLY_MSD # OPT step 011 ) + + qmc_run_and_check( + deterministic-input_check-invalid_variational_subset + "${qmcpack_SOURCE_DIR}/tests/molecules/H4_ae" + H4-OneShiftOnly + det-input-check-optm-invalid-subset.xml + 2 + 1 + FALSE + ) else() message(VERBOSE "Skipping H4_ae tests because gaussian basis sets are not supported by complex build (QMC_COMPLEX=1)") diff --git a/tests/molecules/H4_ae/det-input-check-optm-invalid-subset.xml b/tests/molecules/H4_ae/det-input-check-optm-invalid-subset.xml new file mode 100644 index 0000000000..470caa5a09 --- /dev/null +++ b/tests/molecules/H4_ae/det-input-check-optm-invalid-subset.xml @@ -0,0 +1,35 @@ + + + + batch + + + + + + + + + + + + + + 16 + 128 + 5 + 128 + 5 + 0.5 + yes + 262144 + 1.00 + 0.00 + 0.00 + + OneShiftOnly + uu ee + + + +