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:       MetaIterator
10 //- Description: Implementation code for the MetaIterator class
11 //- Owner:       Mike Eldred
12 //- Checked by:
13 
14 #include "MetaIterator.hpp"
15 #include "ProblemDescDB.hpp"
16 #include "ParallelLibrary.hpp"
17 
18 static const char rcsId[]="@(#) $Id: MetaIterator.cpp 6715 2010-04-02 21:58:15Z wjbohnh $";
19 
20 
21 namespace Dakota {
22 
MetaIterator(ProblemDescDB & problem_db)23 MetaIterator::MetaIterator(ProblemDescDB& problem_db):
24   Iterator(BaseConstructor(), problem_db),
25   iterSched(problem_db.parallel_library(),
26 	    false, // peers can manage local jobs (initial extracted from DB)
27 	    problem_db.get_int("method.iterator_servers"),
28 	    problem_db.get_int("method.processors_per_iterator"),
29 	    problem_db.get_short("method.iterator_scheduling"))
30 {
31   // historical default convergence tolerance
32   if (convergenceTol < 0.0) convergenceTol = 1.0e-4;
33 
34   if (!numFinalSolutions)  // default is zero
35     numFinalSolutions = 1; // for now...  (TO DO: hybrids, concurrent)
36 }
37 
38 
MetaIterator(ProblemDescDB & problem_db,Model & model)39 MetaIterator::MetaIterator(ProblemDescDB& problem_db, Model& model):
40   Iterator(BaseConstructor(), problem_db),
41   iterSched(problem_db.parallel_library(),
42 	    false, // peers can manage local jobs (initial extracted from DB)
43 	    problem_db.get_int("method.iterator_servers"),
44 	    problem_db.get_int("method.processors_per_iterator"),
45 	    problem_db.get_short("method.iterator_scheduling"))
46 {
47   iteratedModel = model;
48   //update_from_model(iteratedModel);
49 
50   // historical default convergence tolerance
51   if (convergenceTol < 0.0) convergenceTol = 1.0e-4;
52 
53   if (!numFinalSolutions)  // default is zero
54     numFinalSolutions = 1; // for now...  (TO DO: hybrids, concurrent)
55 }
56 
57 
~MetaIterator()58 MetaIterator::~MetaIterator()
59 { }
60 
61 
resize()62 bool MetaIterator::resize()
63 {
64   bool parent_reinit_comms = Iterator::resize();
65 
66   Cerr << "\nError: Resizing is not yet supported in method "
67        << method_enum_to_string(methodName) << "." << std::endl;
68   abort_handler(METHOD_ERROR);
69 
70   return parent_reinit_comms;
71 }
72 
73 
74 void MetaIterator::
check_model(const String & method_ptr,const String & model_ptr)75 check_model(const String& method_ptr, const String& model_ptr)
76 {
77   bool warn_flag = false;
78   if (!method_ptr.empty()) {
79     size_t restore_index = probDescDB.get_db_method_node(); // for restoration
80     probDescDB.set_db_method_node(method_ptr);
81     if (probDescDB.get_string("method.model_pointer") !=
82 	iteratedModel.model_id())
83       warn_flag = true;
84     probDescDB.set_db_method_node(restore_index);           // restore
85   }
86   else if (!model_ptr.empty() && model_ptr != iteratedModel.model_id())
87     warn_flag = true;
88 
89   if (warn_flag)
90     Cerr << "Warning: meta-iterator specification includes an inconsistent "
91 	 << "model_pointer.\n         Sub-iterator database initialization "
92 	 << "could be inconsistent with passed Model.\n" << std::endl;
93 }
94 
95 
96 void MetaIterator::
allocate_by_pointer(const String & method_ptr,Iterator & the_iterator,Model & the_model)97 allocate_by_pointer(const String& method_ptr, Iterator& the_iterator,
98 		    Model& the_model)
99 {
100   // store/restore the method/model indices separately (the current
101   // state of the iterator/model DB nodes may not be synched due to
102   // Model ctor recursions in process)
103   size_t method_index = probDescDB.get_db_method_node(),
104          model_index  = probDescDB.get_db_model_node(); // for restoration
105   probDescDB.set_db_list_nodes(method_ptr);
106 
107   if (the_model.is_null())
108     the_model = probDescDB.get_model();
109   iterSched.init_iterator(probDescDB, the_iterator, the_model);
110 
111   probDescDB.set_db_method_node(method_index);          // restore
112   probDescDB.set_db_model_nodes(model_index);           // restore
113 }
114 
115 
116 void MetaIterator::
allocate_by_name(const String & method_string,const String & model_ptr,Iterator & the_iterator,Model & the_model)117 allocate_by_name(const String& method_string, const String& model_ptr,
118 		 Iterator& the_iterator, Model& the_model)
119 {
120   // model instantiation is DB-based, iterator instantiation is not
121 
122   size_t model_index;
123   // if sub_model_ptr is defined, activate this model spec;
124   // if sub_model_ptr is empty, identify default model using empty string.
125   //bool set = !model_ptr.empty();
126   //if (set) {// && the_model.is_null())
127     model_index = probDescDB.get_db_model_node(); // for restoration
128     probDescDB.set_db_model_nodes(model_ptr);
129   //}
130 
131   if (the_model.is_null())
132     the_model = probDescDB.get_model();
133   iterSched.init_iterator(probDescDB, method_string, the_iterator, the_model);
134 
135   //if (set)
136     probDescDB.set_db_model_nodes(model_index);   // restore
137 }
138 
139 
140 IntIntPair MetaIterator::
estimate_by_pointer(const String & method_ptr,Iterator & the_iterator,Model & the_model)141 estimate_by_pointer(const String& method_ptr, Iterator& the_iterator,
142 		    Model& the_model)
143 {
144   // store/restore the method/model indices separately (the current
145   // state of the iterator/model DB nodes may not be synched due to
146   // Model ctor recursions in process)
147   size_t method_index = probDescDB.get_db_method_node(),
148          model_index  = probDescDB.get_db_model_node(); // for restoration
149   probDescDB.set_db_list_nodes(method_ptr);
150 
151   if (the_model.is_null())
152     the_model = probDescDB.get_model();
153   IntIntPair ppi_pr = iterSched.configure(probDescDB, the_iterator, the_model);
154 
155   probDescDB.set_db_method_node(method_index);          // restore
156   probDescDB.set_db_model_nodes(model_index);           // restore
157   return ppi_pr;
158 }
159 
160 
161 IntIntPair MetaIterator::
estimate_by_name(const String & method_string,const String & model_ptr,Iterator & the_iterator,Model & the_model)162 estimate_by_name(const String& method_string, const String& model_ptr,
163 		 Iterator& the_iterator, Model& the_model)
164 {
165   // model instantiation is DB-based, iterator instantiation is not
166 
167   size_t model_index;
168   // if sub_model_ptr is defined, activate this model spec;
169   // if sub_model_ptr is empty, identify default model using empty string.
170   //bool set = !model_ptr.empty();
171   //if (set) {// && the_model.is_null())
172     model_index = probDescDB.get_db_model_node(); // for restoration
173     probDescDB.set_db_model_nodes(model_ptr);
174   //}
175 
176   if (the_model.is_null())
177     the_model = probDescDB.get_model();
178 
179   IntIntPair ppi_pr
180     = iterSched.configure(probDescDB, method_string, the_iterator, the_model);
181 
182   //if (set)
183     probDescDB.set_db_model_nodes(model_index);   // restore
184   return ppi_pr;
185 }
186 
187 
post_run(std::ostream & s)188 void MetaIterator::post_run(std::ostream& s)
189 {
190   if (iterSched.lead_rank())
191     print_results(s);
192 }
193 
194 } // namespace Dakota
195