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: ParamResponsePair
10 //- Description: A container for a variables object, a response object,
11 //- and interface and evaluation ids.
12 //-
13 //- Owner: Mike Eldred
14 //- Version: $Id
15
16 #ifndef PARAM_RESPONSE_PAIR_H
17 #define PARAM_RESPONSE_PAIR_H
18
19 #include "dakota_data_types.hpp"
20 #include "dakota_data_io.hpp"
21 #include "DakotaVariables.hpp"
22 #include "DakotaResponse.hpp"
23
24 namespace Dakota {
25
26
27 /// Container class for a variables object, a response object, and an
28 /// evaluation id.
29
30 /** ParamResponsePair provides a container class for association of
31 the input for a particular function evaluation (a variables
32 object) with the output from this function evaluation (a response
33 object), along with an evaluation identifier. This container
34 defines the basic unit used in the data_pairs cache, in restart
35 file operations, and in a variety of scheduling algorithm queues.
36 With the advent of STL, replacement of arrays of this class with
37 map<> and pair<> template constructs may be possible (using
38 map<pair<int,String>, pair<Variables,Response> >, for example),
39 assuming that deep copies, I/O, alternate constructors, etc., can
40 be adequately addressed. Boost tuple<> may also be a candidate. */
41
42 class ParamResponsePair
43 {
44 //
45 //- Heading: Friends
46 //
47
48 /// equality operator
49 friend bool operator==(const ParamResponsePair& pair1,
50 const ParamResponsePair& pair2);
51 /// inequality operator
52 friend bool operator!=(const ParamResponsePair& pair1,
53 const ParamResponsePair& pair2);
54
55 /// allow boost access to serialize this class
56 friend class boost::serialization::access;
57
58 public:
59
60 //
61 //- Heading: Constructors, destructor, assignment operator
62 //
63
64 /// default constructor
65 ParamResponsePair();
66 /// alternate constructor for temporaries
67 ParamResponsePair(const Variables& vars, const String& interface_id,
68 const Response& response, bool deep_copy = false);
69 /// standard constructor for history uses
70 ParamResponsePair(const Variables& vars, const String& interface_id,
71 const Response& response, const int eval_id,
72 bool deep_copy = true);
73 /// copy constructor
74 ParamResponsePair(const ParamResponsePair& pair);
75
76 /// destructor
77 ~ParamResponsePair();
78
79 /// assignment operator
80 ParamResponsePair& operator=(const ParamResponsePair& pair);
81
82 //
83 //- Heading: Member functions
84 //
85
86 /// read a ParamResponsePair object from an std::istream
87 void read(std::istream& s);
88 /// write a ParamResponsePair object to an std::ostream
89 void write(std::ostream& s) const;
90
91 /// read a ParamResponsePair object in annotated format from an std::istream
92 void read_annotated(std::istream& s);
93 /// write a ParamResponsePair object in annotated format to an std::ostream
94 void write_annotated(std::ostream& s) const;
95
96 /// write a ParamResponsePair object in tabular format (all
97 /// variables active/inactive) to an std::ostream
98 void write_tabular(std::ostream& s, unsigned short tabular_format) const;
99
100 /// write PRP labels in tabular format to an std::ostream
101 void write_tabular_labels(std::ostream& s,
102 unsigned short tabular_format) const;
103
104 /// read a ParamResponsePair object from a packed MPI buffer
105 void read(MPIUnpackBuffer& s);
106 /// write a ParamResponsePair object to a packed MPI buffer
107 void write(MPIPackBuffer& s) const;
108
109 //
110 //- Heading: Set and Inquire functions
111 //
112
113 /// return the evaluation identifier
114 int eval_id() const;
115 /// set the evaluation identifier
116 void eval_id(int id);
117
118 /// return the interface identifier from evalInterfaceIds
119 const String& interface_id() const;
120 /// set the interface identifier within evalInterfaceIds
121 void interface_id(const String& id);
122
123 /// return the aggregate eval/interface identifier from the response object
124 const IntStringPair& eval_interface_ids() const;
125
126 /// return the parameters object
127 const Variables& variables() const;
128 /// return the parameters object
129 Variables& variables();
130 /// set the parameters object
131 void variables(const Variables& vars);
132
133 /// return the response object
134 const Response& response() const;
135 /// return the response object
136 Response& response();
137 /// set the response object
138 void response(const Response& resp);
139
140 /// return the active set object from the response object
141 const ActiveSet& active_set() const;
142 /// set the active set object within the response object
143 void active_set(const ActiveSet& set);
144
145 private:
146
147 /// serialize the PRP: write and read are symmetric for this class
148 template<class Archive>
149 void serialize(Archive& ar, const unsigned int version);
150
151 //
152 //- Heading: Data
153 //
154
155 /// the set of parameters for the function evaluation
156 Variables prpVariables;
157 /// the response set for the function evaluation
158 Response prpResponse;
159
160 /// the evalInterfaceIds aggregate
161 /** the function evaluation identifier (assigned from Interface::evalIdCntr)
162 is paired with the interface used to generate the response object. Used
163 in PRPCache id_vars_set_compare to prevent duplicate detection on results
164 from different interfaces. evalInterfaceIds belongs here rather than in
165 Response since some Response objects involve consolidation of several fn
166 evals (e.g., Model::synchronize_derivatives()) that are not, in total,
167 generated by a single interface. The prPair, on the other hand, is
168 used for storage of all low level fn evals that get evaluated in
169 ApplicationInterface::map(). */
170 IntStringPair evalInterfaceIds;
171 };
172
173
ParamResponsePair()174 inline ParamResponsePair::ParamResponsePair()
175 { }
176
177
178 /** Uses of this constructor often employ the standard Variables and
179 Response copy constructors to share representations since this
180 constructor is commonly used for search_pairs (which are local
181 instantiations that go out of scope prior to any changes to
182 values; i.e., they are not used for history). */
183 inline ParamResponsePair::
ParamResponsePair(const Variables & vars,const String & interface_id,const Response & response,bool deep_copy)184 ParamResponsePair(const Variables& vars, const String& interface_id,
185 const Response& response, bool deep_copy):
186 prpVariables( (deep_copy) ? vars.copy() : vars ),
187 prpResponse( (deep_copy) ? response.copy() : response ),
188 evalInterfaceIds(0, interface_id)
189 { }
190
191
192 /** Uses of this constructor often do not share representations since
193 deep copies are used when history mechanisms (e.g., data_pairs and
194 beforeSynchCorePRPQueue) are involved. */
195 inline ParamResponsePair::
ParamResponsePair(const Variables & vars,const String & interface_id,const Response & response,const int eval_id,bool deep_copy)196 ParamResponsePair(const Variables& vars, const String& interface_id,
197 const Response& response, const int eval_id, bool deep_copy):
198 prpVariables( (deep_copy) ? vars.copy() : vars ),
199 prpResponse( (deep_copy) ? response.copy() : response ),
200 evalInterfaceIds(eval_id, interface_id)
201 { }
202
203
ParamResponsePair(const ParamResponsePair & pair)204 inline ParamResponsePair::ParamResponsePair(const ParamResponsePair& pair):
205 prpVariables(pair.prpVariables), prpResponse(pair.prpResponse),
206 evalInterfaceIds(pair.evalInterfaceIds)
207 { }
208
209
210 inline ParamResponsePair&
operator =(const ParamResponsePair & pair)211 ParamResponsePair::operator=(const ParamResponsePair& pair)
212 {
213 prpVariables = pair.prpVariables;
214 prpResponse = pair.prpResponse;
215 evalInterfaceIds = pair.evalInterfaceIds;
216
217 return *this;
218 }
219
220
~ParamResponsePair()221 inline ParamResponsePair::~ParamResponsePair()
222 { }
223
224
eval_id() const225 inline int ParamResponsePair::eval_id() const
226 { return evalInterfaceIds.first; }
227
228
eval_id(int id)229 inline void ParamResponsePair::eval_id(int id)
230 { evalInterfaceIds.first = id; }
231
232
interface_id() const233 inline const String& ParamResponsePair::interface_id() const
234 { return evalInterfaceIds.second; }
235
236
interface_id(const String & id)237 inline void ParamResponsePair::interface_id(const String& id)
238 { evalInterfaceIds.second = id; }
239
240
eval_interface_ids() const241 inline const IntStringPair& ParamResponsePair::eval_interface_ids() const
242 { return evalInterfaceIds; }
243
244
variables() const245 inline const Variables& ParamResponsePair::variables() const
246 { return prpVariables; }
247
248
variables()249 inline Variables& ParamResponsePair::variables()
250 { return prpVariables; }
251
252
variables(const Variables & vars)253 inline void ParamResponsePair::variables(const Variables& vars)
254 { prpVariables = vars; }
255
256
response() const257 inline const Response& ParamResponsePair::response() const
258 { return prpResponse; }
259
260
response()261 inline Response& ParamResponsePair::response()
262 { return prpResponse; }
263
264
response(const Response & resp)265 inline void ParamResponsePair::response(const Response& resp)
266 { prpResponse = resp; }
267
268
active_set() const269 inline const ActiveSet& ParamResponsePair::active_set() const
270 { return prpResponse.active_set(); }
271
272
active_set(const ActiveSet & set)273 inline void ParamResponsePair::active_set(const ActiveSet& set)
274 { prpResponse.active_set(set); }
275
276
277 // The binary read and write operators are used to read from and write to the
278 // binary restart file and the ASCII write operator is used to echo a pair
279 // read from the restart file to cout (in manage_restart() in main.cpp). The
280 // ASCII read operator is not currently used. The MPIPackBuffer/MPIUnpackBuffer
281 // operators are used to pass a source point for the continuation algorithm.
read(std::istream & s)282 inline void ParamResponsePair::read(std::istream& s)
283 { s >> prpVariables >> prpResponse; }
284
285
write(std::ostream & s) const286 inline void ParamResponsePair::write(std::ostream& s) const
287 {
288 s << "Parameters:\n" << prpVariables;
289 if (!(evalInterfaceIds.second.empty() || evalInterfaceIds.second == "NO_ID"))
290 s << "\nInterface identifier = " << evalInterfaceIds.second << '\n';
291 s << "\nActive response data:\n"<< prpResponse << std::endl;
292 }
293
294
295 /// std::istream extraction operator for ParamResponsePair
operator >>(std::istream & s,ParamResponsePair & pair)296 inline std::istream& operator>>(std::istream& s, ParamResponsePair& pair)
297 { pair.read(s); return s; }
298
299
300 /// std::ostream insertion operator for ParamResponsePair
operator <<(std::ostream & s,const ParamResponsePair & pair)301 inline std::ostream& operator<<(std::ostream& s, const ParamResponsePair& pair)
302 { pair.write(s); return s; }
303
304
305 /** interfaceId is omitted since master processor retains interface
306 ids and communicates asv and response data only with slaves. */
read(MPIUnpackBuffer & s)307 inline void ParamResponsePair::read(MPIUnpackBuffer& s)
308 { s >> prpVariables >> prpResponse >> evalInterfaceIds.first; }
309
310
311 /** interfaceId is omitted since master processor retains interface
312 ids and communicates asv and response data only with slaves. */
write(MPIPackBuffer & s) const313 inline void ParamResponsePair::write(MPIPackBuffer& s) const
314 { s << prpVariables << prpResponse << evalInterfaceIds.first; }
315
316
317 /// MPIUnpackBuffer extraction operator for ParamResponsePair
operator >>(MPIUnpackBuffer & s,ParamResponsePair & pair)318 inline MPIUnpackBuffer& operator>>(MPIUnpackBuffer& s, ParamResponsePair& pair)
319 { pair.read(s); return s; }
320
321
322 /// MPIPackBuffer insertion operator for ParamResponsePair
operator <<(MPIPackBuffer & s,const ParamResponsePair & pair)323 inline MPIPackBuffer& operator<<(MPIPackBuffer& s,const ParamResponsePair& pair)
324 { pair.write(s); return s; }
325
326
327 /// equality operator for ParamResponsePair
operator ==(const ParamResponsePair & pair1,const ParamResponsePair & pair2)328 inline bool operator==(const ParamResponsePair& pair1,
329 const ParamResponsePair& pair2)
330 {
331 // equality check includes interfaceId; evalId need not match
332 return (pair1.prpVariables == pair2.prpVariables &&
333 pair1.evalInterfaceIds.second == pair2.evalInterfaceIds.second &&
334 pair1.prpResponse == pair2.prpResponse);
335 }
336
337
338 /// inequality operator for ParamResponsePair
operator !=(const ParamResponsePair & pair1,const ParamResponsePair & pair2)339 inline bool operator!=(const ParamResponsePair& pair1,
340 const ParamResponsePair& pair2)
341 { return !(pair1 == pair2); }
342
343 } // namespace Dakota
344
345
346 // Since we may serialize this class through a temporary, force
347 // serialization mode and no tracking
348 BOOST_CLASS_IMPLEMENTATION(Dakota::ParamResponsePair,
349 boost::serialization::object_serializable)
350 BOOST_CLASS_TRACKING(Dakota::ParamResponsePair,
351 boost::serialization::track_never)
352
353
354 #endif
355