NOMAD Source  Version 4.0.0 Beta
MadsInitialization.cpp
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------------*/
2 /* NOMAD - Nonlinear Optimization by Mesh Adaptive Direct Search - */
3 /* */
4 /* NOMAD - Version 4.0.0 has been created by */
5 /* Viviane Rochon Montplaisir - Polytechnique Montreal */
6 /* Christophe Tribes - Polytechnique Montreal */
7 /* */
8 /* The copyright of NOMAD - version 4.0.0 is owned by */
9 /* Charles Audet - Polytechnique Montreal */
10 /* Sebastien Le Digabel - Polytechnique Montreal */
11 /* Viviane Rochon Montplaisir - Polytechnique Montreal */
12 /* Christophe Tribes - Polytechnique Montreal */
13 /* */
14 /* NOMAD v4 has been funded by Rio Tinto, Hydro-Québec, NSERC (Natural */
15 /* Sciences and Engineering Research Council of Canada), InnovÉÉ (Innovation */
16 /* en Énergie Électrique) and IVADO (The Institute for Data Valorization) */
17 /* */
18 /* NOMAD v3 was created and developed by Charles Audet, Sebastien Le Digabel, */
19 /* Christophe Tribes and Viviane Rochon Montplaisir and was funded by AFOSR */
20 /* and Exxon Mobil. */
21 /* */
22 /* NOMAD v1 and v2 were created and developed by Mark Abramson, Charles Audet, */
23 /* Gilles Couture, and John E. Dennis Jr., and were funded by AFOSR and */
24 /* Exxon Mobil. */
25 /* */
26 /* Contact information: */
27 /* Polytechnique Montreal - GERAD */
28 /* C.P. 6079, Succ. Centre-ville, Montreal (Quebec) H3C 3A7 Canada */
29 /* e-mail: nomad@gerad.ca */
30 /* */
31 /* This program is free software: you can redistribute it and/or modify it */
32 /* under the terms of the GNU Lesser General Public License as published by */
33 /* the Free Software Foundation, either version 3 of the License, or (at your */
34 /* option) any later version. */
35 /* */
36 /* This program is distributed in the hope that it will be useful, but WITHOUT */
37 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
38 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License */
39 /* for more details. */
40 /* */
41 /* You should have received a copy of the GNU Lesser General Public License */
42 /* along with this program. If not, see <http://www.gnu.org/licenses/>. */
43 /* */
44 /* You can find information on the NOMAD software at www.gerad.ca/nomad */
45 /*---------------------------------------------------------------------------------*/
46 
47 #include "../../Algos/AlgoStopReasons.hpp"
48 #include "../../Algos/CacheInterface.hpp"
49 #include "../../Algos/EvcInterface.hpp"
50 #include "../../Algos/SubproblemManager.hpp"
51 #include "../../Algos/Mads/GMesh.hpp"
52 #include "../../Algos/Mads/MadsInitialization.hpp"
53 #include "../../Cache/CacheBase.hpp"
54 #include "../../Output/OutputQueue.hpp"
55 
56 #include <unistd.h> // For usleep
57 
58 void NOMAD::MadsInitialization::init()
59 {
60  _name = NOMAD::Initialization::getName();
61 }
62 
63 
64 bool NOMAD::MadsInitialization::runImp()
65 {
66  _initialMesh = std::make_shared<NOMAD::GMesh>(_pbParams);
67 
68  bool doContinue = ! _stopReasons->checkTerminate();
69 
70  if (doContinue)
71  {
72  eval_x0s();
73  doContinue = ! _stopReasons->checkTerminate();
74  }
75  return doContinue;
76 }
77 
78 
79 void NOMAD::MadsInitialization::validateX0s() const
80 {
81  auto x0s = _pbParams->getAttributeValue<NOMAD::ArrayOfPoint>("X0");
82  size_t n = _pbParams->getAttributeValue<size_t>("DIMENSION");
83  bool validX0available = false;
84  std::string err;
85 
86  for (size_t x0index = 0; x0index < x0s.size(); x0index++)
87  {
88  auto x0 = x0s[x0index];
89  if (!x0.isComplete() || x0.size() != n)
90  {
91  err += "Initialization: eval_x0s: Invalid X0 " + x0.display() + ".";
92  }
93  else
94  {
95  validX0available = true;
96  }
97  }
98  if (validX0available)
99  {
100  if (!err.empty())
101  {
102  // Show invalid X0s
103  AddOutputWarning(err);
104  }
105  }
106  else
107  {
108  // No valid X0 available. Throw exception.
109  size_t cacheSize = NOMAD::CacheBase::getInstance()->size();
110  if (cacheSize > 0)
111  {
112  err += " Hint: Try not setting X0 so that the cache is used (";
113  err += std::to_string(cacheSize) + " points)";
114  }
115  else
116  {
117  err += ". Cache is empty.";
118  }
119  throw NOMAD::Exception(__FILE__, __LINE__, err);
120  }
121 
122 }
123 
124 
125 bool NOMAD::MadsInitialization::eval_x0s()
126 {
127  bool evalOk = false;
128  std::string s;
129 
130  auto x0s = _pbParams->getAttributeValue<NOMAD::ArrayOfPoint>("X0");
131 
132  validateX0s();
133 
134  // Add X0s that need evaluation to eval queue
135  NOMAD::CacheInterface cacheInterface(this);
136  NOMAD::EvcInterface evcInterface(this);
137  auto evc = evcInterface.getEvaluatorControl();
138  auto evalType = evc->getEvalType();
139  evc->lockQueue();
140 
141  NOMAD::EvalPointSet evalPointSet;
142  for (size_t x0index = 0; x0index < x0s.size(); x0index++)
143  {
144  auto x0 = x0s[x0index];
145  NOMAD::EvalPoint evalPointX0(x0);
146  evalPointSet.insert(evalPointX0);
147  }
148 
149  // Add points to the eval queue.
150  // Convert to full dimension if needed.
151  // Note: Queue is already locked - it needs to be locked to add points.
152  evcInterface.keepPointsThatNeedEval(evalPointSet, false); // false: no mesh
153 
154  // Enforce no opportunism.
155  auto previousOpportunism = evc->getOpportunisticEval();
156  evc->setOpportunisticEval(false);
157  evc->unlockQueue(false); // false: do not sort eval queue
158 
159  // Evaluate all x0s. Ignore returned success type.
160  // Note: EvaluatorControl would not be able to compare/compute success since there is no barrier.
161  evcInterface.startEvaluation();
162 
163  // Reset opportunism to previous values.
164  evc->setOpportunisticEval(previousOpportunism);
165 
166  bool x0Failed = true;
167 
168  // Construct barrier using points evaluated by this step.
169  // The points are cleared from the EvaluatorControl.
170  auto evaluatedPoints = evcInterface.retrieveAllEvaluatedPoints();
171  std::vector<NOMAD::EvalPoint> evalPointX0s;
172 
173  if (_stopReasons->checkTerminate())
174  {
175  return false;
176  }
177 
178  for (auto x0 : x0s)
179  {
180  NOMAD::EvalPoint evalPointX0(x0);
181 
182  // Look for x0 in freshly evaluated points
183  bool x0Found = findInList(x0, evaluatedPoints, evalPointX0);
184 
185  if (!x0Found)
186  {
187  // Look for x0 in EvaluatorControl barrier
188  x0Found = evcInterface.findInBarrier(x0, evalPointX0);
189  if (!x0Found)
190  {
191  // Look for x0 in cache
192  // Note: Even if we are not currently using cache in this sub-algorithm,
193  // we may have interesting points in the global cache.
194  if (evc->getUseCache())
195  {
196  // If status of point in cache is IN_PROGRESS, wait for evaluation to be completed.
197  x0Found = (cacheInterface.find(x0, evalPointX0, evalType) > 0);
198  }
199  else
200  {
201  // Look for X0 in cache, but do not wait for evaluation.
202  x0Found = (cacheInterface.find(x0, evalPointX0) > 0);
203  }
204  }
205  }
206 
207  if (x0Found && evalPointX0.isEvalOk(evalType))
208  {
209  // evalOk is true if at least one evaluation is Ok
210  evalOk = true;
211  evalPointX0s.push_back(evalPointX0);
212 
213  x0Failed = false; // At least one good X0.
214  }
215  }
216 
217  if (x0Failed)
218  {
219  // All x0s failed. Show an error.
220  auto madsStopReason = NOMAD::AlgoStopReasons<NOMAD::MadsStopType>::get(_stopReasons);
221  madsStopReason->set(NOMAD::MadsStopType::X0_FAIL);
222 
223  for (auto x0 : x0s)
224  {
225  auto x0Full = x0.makeFullSpacePointFromFixed(NOMAD::SubproblemManager::getSubFixedVariable(this));
226  AddOutputError("X0 evaluation failed for X0 = " + x0Full.display());
227  }
228  }
229  else
230  {
232  for (auto evalPointX0 : evalPointX0s)
233  {
234  s = "Using X0: ";
235  // BB: Simple display. SGTE: Full display.
236  s += (NOMAD::EvalType::BB == evalType) ? evalPointX0.display() : evalPointX0.displayAll();
237  }
238  AddOutputInfo(s);
240 
241  // Construct barrier using x0s
242  auto hMax = _runParams->getAttributeValue<NOMAD::Double>("H_MAX_0");
243  _barrier = std::make_shared<NOMAD::Barrier>(hMax, NOMAD::SubproblemManager::getSubFixedVariable(this), evalType, evalPointX0s);
244  }
245 
246  NOMAD::OutputQueue::Flush();
247 
248  return evalOk;
249 }
ArrayOfPoint
std::vector< Point > ArrayOfPoint
Type definition for the representation of a vector of points.
Definition: ArrayOfPoint.hpp:63
findInList
bool findInList(const Point &point, const std::vector< EvalPoint > &evalPointList, EvalPoint &foundEvalPoint)
Utility to find Point in EvalPoint vector.
EvalPointSet
std::set< EvalPoint, EvalPointCompare > EvalPointSet
Definition for EvalPointSet.
Definition: EvalPoint.hpp:371
OUTPUT_INFO_END
#define OUTPUT_INFO_END
Definition: OutputQueue.hpp:151
OUTPUT_INFO_START
#define OUTPUT_INFO_START
Definition: OutputQueue.hpp:148