SST  6.0.0
StructuralSimulationToolkit
params.h
1 // Copyright 2009-2016 Sandia Corporation. Under the terms
2 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S.
3 // Government retains certain rights in this software.
4 //
5 // Copyright (c) 2009-2016, Sandia Corporation
6 // All rights reserved.
7 //
8 // This file is part of the SST software package. For license
9 // information, see the LICENSE file in the top level directory of the
10 // distribution.
11 
12 #ifndef SST_CORE_PARAM_H
13 #define SST_CORE_PARAM_H
14 
15 #include <sst/core/output.h>
16 #include <sst/core/from_string.h>
17 
18 #include <cassert>
19 #include <inttypes.h>
20 #include <iostream>
21 #include <sstream>
22 #include <map>
23 #include <stack>
24 #include <stdlib.h>
25 #include <utility>
26 #include <sst/core/threadsafe.h>
27 
28 #include <sst/core/serialization/serializable.h>
29 #include <sst/core/serialization/serializer.h>
30 
31 int main(int argc, char *argv[]);
32 
33 namespace SST {
34 
35 class ConfigGraph;
36 
37 /**
38  * Parameter store
39  *
40  * Meets the requirements of a <a href="tables.html#65">container</a>, a
41  * <a href="tables.html#66">reversible container</a>, and an
42  * <a href="tables.html#69">associative container</a> (using unique keys).
43  * For a @c map<Key,T> the key_type is Key, the mapped_type is T, and the
44  * value_type is std::pair<const Key,T>.
45  */
47 private:
48  struct KeyCompare : std::binary_function<std::string, std::string, bool>
49  {
50  bool operator()(const std::string& X, const std::string& Y) const
51  {
52  const char *x = X.c_str();
53  const char *y = Y.c_str();
54 
55 #define EAT_VAR(A, B) \
56  do { \
57  if ( *x == '%' && (*(x+1) == '(' || *(x+1) == 'd')) { \
58  /* We need to eat off some tokens */ \
59  ++x; \
60  if ( *x == '(' ) { \
61  do { x++; } while ( *x && *x != ')' ); \
62  x++; /* *x should now == 'd' */ \
63  } \
64  if ( *x != 'd' ) goto NO_VARIABLE; \
65  x++; /* Finish eating the variable */ \
66  /* Now, eat of digits of Y */ \
67  while ( *y && isdigit(*y) ) y++; \
68  } \
69  } while(0)
70 
71  do {
72  EAT_VAR(x, y);
73  EAT_VAR(y, x);
74 NO_VARIABLE:
75  if ( *x == *y ) {
76  if ( '\0' == *x ) return false;
77  x++;
78  y++;
79  } else {
80  if ( *x < *y ) return true;
81  return false;
82  }
83  } while ( *x && *y );
84  if ( !(*x) && (*y) ) return true;
85  return false;
86 
87 #undef EAT_VAR
88  }
89  };
90 
91  typedef std::map<uint32_t, std::string>::const_iterator const_iterator; /*!< Const Iterator type */
92 
93 public:
94  typedef std::string key_type; /*!< Type of key (string) */
95  typedef std::set<key_type, KeyCompare> KeySet_t; /*!< Type of a set of keys */
96 
97  /**
98  * Enable or disable parameter verification on an instance
99  * of Params. Useful when generating a new set of Params to
100  * pass off to a module.
101  */
102  bool enableVerify(bool enable) { bool old = verify_enabled; verify_enabled = enable; return old; }
103 
104  /**
105  * Enable, on a global scale, parameter verification. Used
106  * after construction of the config graph so that warnings are
107  * not generated during construction.
108  */
109  static void enableVerify() { g_verify_enabled = true; };
110 
111  /** Returns the size of the Params. */
112  size_t size() const { return data.size(); }
113  /** Returns true if the Params is empty. (Thus begin() would equal end().) */
114  bool empty() const { return data.empty(); }
115 
116 
117  /** Create a new, empty Params */
118  Params() : data(), verify_enabled(true) { }
119 
120  /** Create a copy of a Params object */
121  Params(const Params& old) : data(old.data), allowedKeys(old.allowedKeys), verify_enabled(old.verify_enabled) { }
122 
123  virtual ~Params() { }
124 
125  /**
126  * @brief Map assignment operator.
127  * @param old A %map of identical element and allocator types.
128  *
129  * All the elements of @a x are copied, but unlike the copy constructor,
130  * the allocator object is not copied.
131  */
132  Params& operator=(const Params& old) {
133  data = old.data;
134  verify_enabled = old.verify_enabled;
135  allowedKeys = old.allowedKeys;
136  return *this;
137  }
138 
139  /**
140  * Erases all elements in a %map. Note that this function only
141  * erases the elements, and that if the elements themselves are
142  * pointers, the pointed-to memory is not touched in any way.
143  * Managing the pointer is the user's responsibilty.
144  */
145  void clear() { data.clear(); }
146 
147 
148  /**
149  * @brief Finds the number of elements with given key.
150  * @param k Key of (key, value) pairs to be located.
151  * @return Number of elements with specified key.
152  *
153  * This function only makes sense for multimaps; for map the result will
154  * either be 0 (not present) or 1 (present).
155  */
156  size_t count(const key_type& k) { return data.count(getKey(k)); }
157 
158  /** Find a Parameter value in the set, and return its value as a type T
159  * @param k - Parameter name
160  * @param default_value - Default value to return if parameter isn't found
161  * @param found - set to true if the the parameter was found
162  */
163  template <class T>
164  T find(const std::string &k, T default_value, bool &found) const {
165  verifyParam(k);
166  const_iterator i = data.find(getKey(k));
167  if (i == data.end()) {
168  found = false;
169  return default_value;
170  } else {
171  found = true;
172  try {
173  return SST::Core::from_string<T>(i->second);
174  }
175  catch ( const std::invalid_argument& e ) {
176  std::string msg = "Params::find(): No conversion for value: key = " + k + ", value = " + i->second +
177  ". Oringal error: " + e.what();
178  std::invalid_argument t(msg);
179  throw t;
180  }
181  }
182  }
183 
184  /** Find a Parameter value in the set, and return its value as a type T
185  * @param k - Parameter name
186  * @param default_value - Default value to return if parameter isn't found
187  */
188  template <class T>
189  T find(const std::string &k, T default_value ) const {
190  bool tmp;
191  return find(k, default_value, tmp);
192  }
193 
194  /** Find a Parameter value in the set, and return its value as a type T
195  * @param k - Parameter name
196  */
197  template <class T>
198  T find(const std::string &k) const {
199  bool tmp;
200  T default_value = T();
201  return find(k, default_value, tmp);
202  }
203 
204  /** Find a Parameter value in the set, and return its value as a type T
205  * @param k - Parameter name
206  * @param found - set to true if the the parameter was found
207  */
208  template <class T>
209  T find(const std::string &k, bool &found) const {
210  T default_value = T();
211  return find(k, default_value, found);
212  }
213 
214  /** Find a Parameter value in the set, and return its value as a
215  * vector of T's. The array will be appended to
216  * the end of the vector.
217  *
218  * @param k - Parameter name
219  * @param vec - vector to append array items to
220  */
221  template <class T>
222  void find_array(const key_type &k, std::vector<T>& vec) const {
223  verifyParam(k);
224  const_iterator i = data.find(getKey(k));
225  if ( i == data.end()) {
226  return;
227  }
228  std::string value = i->second;
229  // String should start with [ and end with ], we need to cut
230  // these out
231  value = value.substr(0,value.size()-1);
232  value = value.substr(1);
233 
234  std::stringstream ss(value);
235 
236  while( ss.good() ) {
237  std::string substr;
238  getline( ss, substr, ',' );
239  // vec.push_back(strtol(substr.c_str(), NULL, 0));
240  try {
241  vec.push_back(SST::Core::from_string<T>(substr));
242  }
243  catch ( const std::invalid_argument& e ) {
244  std::string msg = "Params::find(): No conversion for value: key = " + k + ", value = " + substr +
245  ". Oringal error: " + e.what();
246  std::invalid_argument t(msg);
247  throw t;
248  }
249  }
250  }
251 
252  /** Find a Parameter value in the set, and return its value as an integer
253  * @param k - Parameter name
254  * @param default_value - Default value to return if parameter isn't found
255  * @param found - set to true if the the parameter was found
256  */
257  __attribute__ ((deprecated))
258  int64_t find_integer(const key_type &k, long default_value, bool &found) const {
259  return find<int64_t>(k,default_value,found);
260  }
261 
262  /** Find a Parameter value in the set, and return its value as an integer
263  * @param k - Parameter name
264  * @param default_value - Default value to return if parameter isn't found
265  */
266  __attribute__ ((deprecated))
267  int64_t find_integer(const key_type &k, long default_value = -1) const {
268  return find<int64_t>(k,default_value);
269  }
270 
271  /** Find a Parameter value in the set, and return its value as a
272  * vector of integers. The array of integers will be appended to
273  * the end of the vector.
274  *
275  * @param k - Parameter name
276  * @param vec - vector to append array items to
277  */
278  __attribute__ ((deprecated))
279  void find_integer_array(const key_type &k, std::vector<int64_t>& vec) const {
280  find_array<int64_t>(k,vec);
281  }
282 
283  /** Find a Parameter value in the set, and return its value as a double
284  * @param k - Parameter name
285  * @param default_value - Default value to return if parameter isn't found
286  * @param found - set to true if the the parameter was found
287  */
288  __attribute__ ((deprecated))
289  double find_floating(const key_type& k, double default_value, bool &found) const {
290  return find<double>(k,default_value,found);
291  }
292 
293  /** Find a Parameter value in the set, and return its value as a double
294  * @param k - Parameter name
295  * @param default_value - Default value to return if parameter isn't found
296  */
297  __attribute__ ((deprecated))
298  double find_floating(const key_type& k, double default_value = -1.0) const {
299  return find<double>(k,default_value);
300  }
301 
302  /** Find a Parameter value in the set, and return its value as a
303  * vector of floats. The array of floats will be appended to
304  * the end of the vector.
305  *
306  * @param k - Parameter name
307  * @param vec - vector to append array items to
308  */
309  __attribute__ ((deprecated))
310  void find_floating_array(const key_type &k, std::vector<double>& vec) const {
311  find_array<double>(k,vec);
312  }
313 
314  /** Find a Parameter value in the set, and return its value
315  * @param k - Parameter name
316  * @param default_value - Default value to return if parameter isn't found
317  * @param found - set to true if the the parameter was found
318  */
319  __attribute__ ((deprecated))
320  std::string find_string(const key_type &k, std::string default_value, bool &found) const {
321  return find<std::string>(k,default_value,found);
322  }
323 
324  /** Find a Parameter value in the set, and return its value
325  * @param k - Parameter name
326  * @param default_value - Default value to return if parameter isn't found
327  */
328  __attribute__ ((deprecated))
329  std::string find_string(const key_type &k, std::string default_value = "") const {
330  return find<std::string>(k,default_value);
331  }
332 
333  /** Find a Parameter value in the set, and return its value as a
334  * vector of strings. The array of strings will be appended to
335  * the end of the vector.
336  *
337  * @param k - Parameter name
338  * @param vec - vector to append array items to
339  */
340  __attribute__ ((deprecated))
341  void find_string_array(const key_type &k, std::vector<std::string>& vec) const {
342  find_array<std::string>(k,vec);
343  }
344 
345  /** Print all key/value parameter pairs to specified ostream */
346  void print_all_params(std::ostream &os, std::string prefix = "") const {
347  for (const_iterator i = data.begin() ; i != data.end() ; ++i) {
348  os << prefix << "key=" << keyMapReverse[i->first] << ", value=" << i->second << std::endl;
349  }
350  }
351 
352 
353 
354  /** Add a key value pair into the param object.
355  */
356  void insert(std::string key, std::string value, bool overwrite = true) {
357  if ( overwrite ) {
358  data[getKey(key)] = value;
359  }
360  else {
361  uint32_t id = getKey(key);
362  data.insert(std::make_pair(id, value));
363  }
364  }
365 
366  void insert(const Params& params) {
367  data.insert(params.data.begin(), params.data.end());
368  }
369 
370  std::set<std::string> getKeys() const {
371  std::set<std::string> ret;
372  for (const_iterator i = data.begin() ; i != data.end() ; ++i) {
373  ret.insert(keyMapReverse[i->first]);
374  }
375  return ret;
376  }
377 
378  /** Returns a new parameter object with parameters that match
379  * the specified prefix.
380  */
381  Params find_prefix_params(std::string prefix) const {
382  Params ret;
383  ret.enableVerify(false);
384  for (const_iterator i = data.begin() ; i != data.end() ; ++i) {
385  std::string key = keyMapReverse[i->first].substr(0, prefix.length());
386  if (key == prefix) {
387  ret.insert(keyMapReverse[i->first].substr(prefix.length()), i->second);
388  }
389  }
390  ret.allowedKeys = allowedKeys;
391  ret.enableVerify(verify_enabled);
392 
393  return ret;
394  }
395 
396 
397  /**
398  * @param k Key to search for
399  * @return True if the params contains the key, false otherwise
400  */
401  bool contains(const key_type &k) {
402  return data.find(getKey(k)) != data.end();
403  }
404 
405  /**
406  * @param keys Set of keys to consider valid to add to the stack
407  * of legal keys
408  */
409  void pushAllowedKeys(const KeySet_t &keys) {
410  allowedKeys.push_back(keys);
411  }
412 
413  /**
414  * Removes the most recent set of keys considered allowed
415  */
416  void popAllowedKeys() {
417  allowedKeys.pop_back();
418  }
419 
420  /**
421  * @param k Key to check for validity
422  * @return True if the key is considered allowed
423  */
424  void verifyParam(const key_type &k) const {
425  if ( !g_verify_enabled || !verify_enabled ) return;
426 
427  for ( std::vector<KeySet_t>::const_reverse_iterator ri = allowedKeys.rbegin() ; ri != allowedKeys.rend() ; ++ri ) {
428  if ( ri->find(k) != ri->end() ) return;
429  }
430 
431 #ifdef USE_PARAM_WARNINGS
432  SST::Output outXX("ParamWarning: ", 0, 0, Output::STDERR);
433  outXX.output(CALL_INFO, "Warning: Parameter \"%s\" is undocumented.\n", k.c_str());
434 #endif
435  }
436 
437 
438  /**
439  * Given a Parameter Key ID, return the Name of the matching parameter
440  * @param id Key ID to look up
441  * @return String name of the parameter
442  */
443  static const std::string& getParamName(uint32_t id)
444  {
445  return keyMapReverse[id];
446  }
447 
448 
449  void serialize_order(SST::Core::Serialization::serializer &ser) {
450  ser & data;
451  }
452 
453  ImplementSerializable(SST::Params)
454 
455 private:
456  std::map<uint32_t, std::string> data;
457  std::vector<KeySet_t> allowedKeys;
458  bool verify_enabled;
459  static bool g_verify_enabled;
460 
461  uint32_t getKey(const std::string &str) const
462  {
463  std::lock_guard<SST::Core::ThreadSafe::Spinlock> lock(keyLock);
464  std::map<std::string, uint32_t>::iterator i = keyMap.find(str);
465  if ( i == keyMap.end() ) {
466  return (uint32_t)-1;
467  }
468  return i->second;
469  }
470 
471  uint32_t getKey(const std::string &str)
472  {
473  std::lock_guard<SST::Core::ThreadSafe::Spinlock> lock(keyLock);
474  std::map<std::string, uint32_t>::iterator i = keyMap.find(str);
475  if ( i == keyMap.end() ) {
476  uint32_t id = nextKeyID++;
477  keyMap.insert(std::make_pair(str, id));
478  keyMapReverse.push_back(str);
479  assert(keyMapReverse.size() == nextKeyID);
480  return id;
481  }
482  return i->second;
483  }
484 
485  /* Friend main() because it broadcasts the maps */
486  friend int ::main(int argc, char *argv[]);
487 
488  static std::map<std::string, uint32_t> keyMap;
489  static std::vector<std::string> keyMapReverse;
490  static SST::Core::ThreadSafe::Spinlock keyLock;
491  static uint32_t nextKeyID;
492 
493 
494 };
495 
496 } //namespace SST
497 
498 #endif //SST_CORE_PARAMS_H
Output object provides consistant method for outputing data to stdout, stderr and/or sst debug file...
Definition: output.h:54
Params(const Params &old)
Create a copy of a Params object.
Definition: params.h:121
This class is basically a wrapper for objects to declare the order in which their members should be s...
Definition: serializer.h:35
void find_array(const key_type &k, std::vector< T > &vec) const
Find a Parameter value in the set, and return its value as a vector of T's.
Definition: params.h:222
T find(const std::string &k, T default_value) const
Find a Parameter value in the set, and return its value as a type T.
Definition: params.h:189
void pushAllowedKeys(const KeySet_t &keys)
Definition: params.h:409
bool contains(const key_type &k)
Definition: params.h:401
Params find_prefix_params(std::string prefix) const
Returns a new parameter object with parameters that match the specified prefix.
Definition: params.h:381
std::string find_string(const key_type &k, std::string default_value, bool &found) const
Find a Parameter value in the set, and return its value.
Definition: params.h:320
void find_integer_array(const key_type &k, std::vector< int64_t > &vec) const
Find a Parameter value in the set, and return its value as a vector of integers.
Definition: params.h:279
void insert(std::string key, std::string value, bool overwrite=true)
Add a key value pair into the param object.
Definition: params.h:356
Params & operator=(const Params &old)
Map assignment operator.
Definition: params.h:132
T find(const std::string &k) const
Find a Parameter value in the set, and return its value as a type T.
Definition: params.h:198
Definition: action.cc:17
static void enableVerify()
Enable, on a global scale, parameter verification.
Definition: params.h:109
void print_all_params(std::ostream &os, std::string prefix="") const
Print all key/value parameter pairs to specified ostream.
Definition: params.h:346
size_t count(const key_type &k)
Finds the number of elements with given key.
Definition: params.h:156
Definition: serializable.h:108
bool empty() const
Returns true if the Params is empty.
Definition: params.h:114
int64_t find_integer(const key_type &k, long default_value, bool &found) const
Find a Parameter value in the set, and return its value as an integer.
Definition: params.h:258
void clear()
Erases all elements in a map.
Definition: params.h:145
void find_string_array(const key_type &k, std::vector< std::string > &vec) const
Find a Parameter value in the set, and return its value as a vector of strings.
Definition: params.h:341
static const std::string & getParamName(uint32_t id)
Given a Parameter Key ID, return the Name of the matching parameter.
Definition: params.h:443
void find_floating_array(const key_type &k, std::vector< double > &vec) const
Find a Parameter value in the set, and return its value as a vector of floats.
Definition: params.h:310
Params()
Create a new, empty Params.
Definition: params.h:118
T find(const std::string &k, T default_value, bool &found) const
Find a Parameter value in the set, and return its value as a type T.
Definition: params.h:164
bool enableVerify(bool enable)
Enable or disable parameter verification on an instance of Params.
Definition: params.h:102
void output(uint32_t line, const char *file, const char *func, const char *format,...) const
Output the message with formatting as specified by the format parameter.
Definition: output.h:184
Definition: output.h:62
double find_floating(const key_type &k, double default_value, bool &found) const
Find a Parameter value in the set, and return its value as a double.
Definition: params.h:289
Definition: threadsafe.h:101
size_t size() const
Returns the size of the Params.
Definition: params.h:112
T find(const std::string &k, bool &found) const
Find a Parameter value in the set, and return its value as a type T.
Definition: params.h:209
Parameter store.
Definition: params.h:46
void popAllowedKeys()
Removes the most recent set of keys considered allowed.
Definition: params.h:416
std::set< key_type, KeyCompare > KeySet_t
Definition: params.h:95
std::string key_type
Definition: params.h:94
void verifyParam(const key_type &k) const
Definition: params.h:424