QMCPACK
HybridEngine.cpp
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source License.
3 // See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2019 QMCPACK developers.
6 //
7 // File developed by: Leon Otis, leon_otis@berkeley.edu University, University of California Berkeley
8 // Ye Luo, yeluo@anl.gov, Argonne National Laboratory
9 //
10 // File created by: Leon Otis, leon_otis@berkeley.edu University, University of California Berkeley
11 //////////////////////////////////////////////////////////////////////////////////////
12 
13 #include <vector>
14 #include <string>
15 #include <numeric>
16 #include "HybridEngine.h"
17 #include "OhmmsData/ParameterSet.h"
18 #include "Message/CommOperators.h"
20 
21 
22 namespace qmcplusplus
23 {
24 HybridEngine::HybridEngine(Communicate* comm, const xmlNodePtr cur) : myComm(comm)
25 {
26  step_num_ = -1;
27  processXML(cur);
28 }
29 
30 //Hybrid Engine processes xml input to determine which optimizations are being used and for how many iterations
31 bool HybridEngine::processXML(const xmlNodePtr opt_xml)
32 {
33  opt_methods_.clear();
34  saved_xml_opt_methods_.clear();
36 
37  xmlNodePtr cur = opt_xml->children;
38  while (cur != NULL)
39  {
40  std::string cname((const char*)(cur->name));
41  if (cname == "optimizer")
42  {
43  std::string children_MinMethod;
44  ParameterSet m_param;
45  m_param.add(children_MinMethod, "MinMethod");
46  m_param.put(cur);
47 
48  if (children_MinMethod.empty())
49  throw std::runtime_error("MinMethod must be given!\n");
50  std::string updates_string(getXMLAttributeValue(cur, "num_updates"));
51  app_log() << "HybridEngine saved MinMethod " << children_MinMethod << " num_updates = " << updates_string << '\n';
52  auto iter = OptimizerNames.find(children_MinMethod);
53  if (iter == OptimizerNames.end())
54  throw std::runtime_error("Unknown MinMethod!\n");
55  opt_methods_.push_back(iter->second);
56  saved_xml_opt_methods_.push_back(cur);
57  num_updates_opt_methods_.push_back(std::stoi(updates_string));
58  }
59  cur = cur->next;
60  }
61 
62  if (saved_xml_opt_methods_.size() != 2)
63  throw std::runtime_error("MinMethod hybrid needs two optimizer input blocks!\n");
64 
65  return true;
66 }
67 
68 //Retrieves the appropriate XML input for the current optimization method
70 {
72 }
73 
74 //Queries whether information from one optimization method(currently needs to be descent) should be stored.
75 bool HybridEngine::queryStore(int store_num, const OptimizerType method) const
76 {
77  bool store = false;
78 
79  int idx = 0;
80 
81  auto iter = std::find(opt_methods_.begin(), opt_methods_.end(), method);
82  if (iter == opt_methods_.end())
83  throw std::runtime_error("Unknown MinMethod!\n");
84  else
85  idx = std::distance(opt_methods_.begin(), iter);
86 
87 
88  const int tot_micro_it = std::accumulate(num_updates_opt_methods_.begin(), num_updates_opt_methods_.end(), 0);
89  const int pos = step_num_ % tot_micro_it;
90  //interval is the number of steps between stores based on the number of stores desired
91  int interval = num_updates_opt_methods_[idx] / store_num;
92 
93  if (interval == 0)
94  {
95  app_log()
96  << "Requested Number of Stored Vectors greater than number of descent steps. Storing a vector on each step."
97  << std::endl;
98  interval = 1;
99  }
100  if ((pos + 1) % interval == 0)
101  {
102  store = true;
103  }
104 
105  return store;
106 }
107 
108 //Determines what the current optimization method is based on the current step number and returns the associated index
110 {
111  const int tot_micro_it = std::accumulate(num_updates_opt_methods_.begin(), num_updates_opt_methods_.end(), 0);
112  const int pos = step_num_ % tot_micro_it;
113 
114  int run_sum = 0;
115  int select_idx = 0;
116 
117  //Compare pos to running sum of microiterations of different methods to determine which method is being used
118  for (int i = 0; i < num_updates_opt_methods_.size(); i++)
119  {
120  run_sum += num_updates_opt_methods_[i];
121  if (run_sum > pos)
122  {
123  select_idx = i;
124  break;
125  }
126  }
127 
128  return select_idx;
129 }
130 
131 } // namespace qmcplusplus
std::vector< xmlNodePtr > saved_xml_opt_methods_
xml saved node
Definition: HybridEngine.h:47
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
const std::map< std::string, OptimizerType > OptimizerNames
std::ostream & app_log()
Definition: OutputManager.h:65
std::vector< int > num_updates_opt_methods_
Definition: HybridEngine.h:50
bool put(std::istream &is) override
read from std::istream
Definition: ParameterSet.h:42
int step_num_
number of optimization steps taken
Definition: HybridEngine.h:38
Wrapping information on parallelism.
Definition: Communicate.h:68
class to handle a set of parameters
Definition: ParameterSet.h:27
XMLNodeString convert xmlNode contents into a std::string XMLAttrString convert one xmlNode attribute...
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...
void add(PDT &aparam, const std::string &aname_in, std::vector< PDT > candidate_values={}, TagStatus status=TagStatus::OPTIONAL)
add a new parameter corresponding to an xmlNode <parameter>
std::vector< OptimizerType > opt_methods_
list of methods known by hybrid
Definition: HybridEngine.h:44
bool processXML(const xmlNodePtr cur)
process xml node
bool queryStore(int store_num, OptimizerType method_type) const