1 /*  _______________________________________________________________________
2 
3     DAKOTA: Design Analysis Kit for Optimization and Terascale Applications
4     Copyright 2014-2020 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
5     This software is distributed under the GNU Lesser General Public License.
6     For more information, see the README file in the top Dakota directory.
7     _______________________________________________________________________ */
8 
9 //- Class:       EmbedHybridMetaIterator
10 //- Description: A meta-iterator for tightly-coupled global-local hybrids
11 //- Owner:       Mike Eldred
12 //- Checked by:
13 //- Version: $Id: EmbedHybridMetaIterator.hpp 6492 2009-12-19 00:04:28Z briadam $
14 
15 #ifndef EMBED_HYBRID_META_ITERATOR_H
16 #define EMBED_HYBRID_META_ITERATOR_H
17 
18 #include "MetaIterator.hpp"
19 
20 
21 namespace Dakota {
22 
23 
24 /// Meta-iterator for closely-coupled hybrid iteration, typically
25 /// involving the embedding of local search methods within global
26 /// search methods.
27 
28 /** This meta-iterator uses multiple methods in close coordination,
29     generally using a local search minimizer repeatedly within a
30     global minimizer (the local search minimizer refines candidate
31     minima which are fed back to the global minimizer). */
32 
33 class EmbedHybridMetaIterator: public MetaIterator
34 {
35 public:
36 
37   //
38   //- Heading: Constructors and destructor
39   //
40 
41   /// standard constructor
42   EmbedHybridMetaIterator(ProblemDescDB& problem_db);
43   /// alternate constructor
44   EmbedHybridMetaIterator(ProblemDescDB& problem_db, Model& model);
45   /// destructor
46   ~EmbedHybridMetaIterator();
47 
48 protected:
49 
50   //
51   //- Heading: Member functions
52   //
53 
54   /// Performs the hybrid iteration by executing global and local
55   /// iterators, using a set of models that may vary in fidelity
56   void core_run();
57 
58   void derived_init_communicators(ParLevLIter pl_iter);
59   void derived_set_communicators(ParLevLIter pl_iter);
60   void derived_free_communicators(ParLevLIter pl_iter);
61 
62   IntIntPair estimate_partition_bounds();
63 
64   /// return the final solution from the embedded hybrid (variables)
65   const Variables& variables_results() const;
66   /// return the final solution from the embedded hybrid (response)
67   const Response&  response_results() const;
68 
69 private:
70 
71   //
72   //- Heading: Data members
73   //
74 
75   /// the top-level outer iterator (e.g., global minimizer)
76   Iterator globalIterator;
77   /// the model employed by the top-level outer iterator
78   Model globalModel;
79 
80   /// the inner iterator (e.g., local minimizer)
81   Iterator localIterator;
82   /// the model employed by the inner iterator
83   Model localModel;
84 
85   /// use of constructor that enforces use of a single passed Model
86   bool singlePassedModel;
87 
88   /// the probability of running a local search refinement within
89   /// phases of the global minimization for tightly-coupled hybrids
90   Real localSearchProb;
91 };
92 
93 
estimate_partition_bounds()94 inline IntIntPair EmbedHybridMetaIterator::estimate_partition_bounds()
95 {
96   // Note: EmbedHybridMetaIterator::derived_init_communicators() calls
97   // IteratorScheduler::configure() to estimate_partition_bounds() on the
98   // subIterator, not the MetaIterator.  When EmbedHybridMetaIterator is a
99   // sub-iterator, we augment the subIterator concurrency with the MetaIterator
100   // concurrency.  [Thus, this is not redundant with configure().]
101 
102   const String& global_method_ptr
103     = probDescDB.get_string("method.hybrid.global_method_pointer");
104   const String& global_model_ptr
105     = probDescDB.get_string("method.hybrid.global_model_pointer");
106   const String& local_method_ptr
107     = probDescDB.get_string("method.hybrid.local_method_pointer");
108   const String& local_model_ptr
109     = probDescDB.get_string("method.hybrid.local_model_pointer");
110 
111   Model& global_model = (singlePassedModel) ? iteratedModel : globalModel;
112   Model& local_model  = (singlePassedModel) ? iteratedModel :  localModel;
113 
114   iterSched.construct_sub_iterator(probDescDB, globalIterator, global_model,
115     global_method_ptr,probDescDB.get_string("method.hybrid.global_method_name"),
116     global_model_ptr);
117   iterSched.construct_sub_iterator(probDescDB, localIterator, local_model,
118     local_method_ptr, probDescDB.get_string("method.hybrid.local_method_name"),
119     local_model_ptr);
120 
121   IntIntPair global_min_max = globalIterator.estimate_partition_bounds(),
122     local_min_max = localIterator.estimate_partition_bounds(), min_max;
123   int min_procs = std::min(global_min_max.first,  local_min_max.first),
124       max_procs = std::max(global_min_max.second, local_min_max.second);
125 
126   // now apply scheduling data for this level (recursion is complete)
127   min_max.first  = ProblemDescDB::min_procs_per_level(min_procs,
128     iterSched.procsPerIterator,	iterSched.numIteratorServers);
129   min_max.second = ProblemDescDB::max_procs_per_level(max_procs,
130     iterSched.procsPerIterator, iterSched.numIteratorServers,
131     iterSched.iteratorScheduling, 1, false, maxIteratorConcurrency);
132   return min_max;
133 }
134 
135 
variables_results() const136 inline const Variables& EmbedHybridMetaIterator::variables_results() const
137 { return globalIterator.variables_results(); }
138 
139 
response_results() const140 inline const Response& EmbedHybridMetaIterator::response_results() const
141 { return globalIterator.response_results(); }
142 
143 } // namespace Dakota
144 
145 #endif
146