SST  13.1.0
Structural Simulation Toolkit
params.h
1 // Copyright 2009-2023 NTESS. Under the terms
2 // of Contract DE-NA0003525 with NTESS, the U.S.
3 // Government retains certain rights in this software.
4 //
5 // Copyright (c) 2009-2023, NTESS
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/from_string.h"
16 #include "sst/core/output.h"
17 #include "sst/core/serialization/serializable.h"
18 #include "sst/core/serialization/serializer.h"
19 #include "sst/core/threadsafe.h"
20 
21 #include <cassert>
22 #include <inttypes.h>
23 #include <iostream>
24 #include <map>
25 #include <sstream>
26 #include <stack>
27 #include <stdexcept>
28 #include <stdlib.h>
29 #include <utility>
30 
31 int main(int argc, char* argv[]);
32 
33 namespace SST {
34 
35 class ConfigGraph;
36 class ConfigComponent;
37 class SSTModelDescription;
38 
39 namespace Core {
40 class ConfigGraphOutput;
41 } // namespace Core
42 
43 /**
44  * Parameter store.
45  *
46  * Stores key-value pairs as std::strings and provides
47  * a templated find method for finding values and converting
48  * them to arbitrary types (@see find()).
49  *
50  * NOTE: Params objects should only be used for simulation
51  * initialization, a Params object should not be used as part of an
52  * event, as serialization of Params objects only works correctly as
53  * part of ConfigGraph serialization.
54  */
56 {
57 private:
58  struct KeyCompare
59  {
60  bool operator()(const std::string& X, const std::string& Y) const
61  {
62  const char* x = X.c_str();
63  const char* y = Y.c_str();
64 
65 #define EAT_VAR(A, B) \
66  do { \
67  if ( *x == '%' && (*(x + 1) == '(' || *(x + 1) == 'd') ) { \
68  /* We need to eat off some tokens */ \
69  ++x; \
70  if ( *x == '(' ) { \
71  do { \
72  x++; \
73  } while ( *x && *x != ')' ); \
74  x++; /* *x should now == 'd' */ \
75  } \
76  if ( *x != 'd' ) goto NO_VARIABLE; \
77  x++; /* Finish eating the variable */ \
78  /* Now, eat of digits of Y */ \
79  while ( *y && isdigit(*y) ) \
80  y++; \
81  } \
82  } while ( 0 )
83 
84  do {
85  EAT_VAR(x, y);
86  EAT_VAR(y, x);
87 NO_VARIABLE:
88  if ( *x == *y ) {
89  if ( '\0' == *x ) return false;
90  x++;
91  y++;
92  }
93  else {
94  if ( *x < *y ) return true;
95  return false;
96  }
97  } while ( *x && *y );
98  if ( !(*x) && (*y) ) return true;
99  return false;
100 
101 #undef EAT_VAR
102  }
103  };
104 
105  /** Private utility function to convert a value to the specified
106  * type and check for errors. Key is passed only in case an error
107  * message needs to be generated.
108  *
109  * Type T must be either a basic numeric type (including bool) ,
110  * a std::string, or a class that has a constructor with a std::string
111  * as its only parameter. This class uses SST::Core::from_string to
112  * do the conversion.
113  * @param k - Parameter name
114  * @throw std::invalid_argument If value in (key, value) can't be
115  * converted to type T, an invalid_argument exception is thrown.
116  */
117  template <class T>
118  inline T convert_value(const std::string& key, const std::string& val) const
119  {
120  try {
121  return SST::Core::from_string<T>(val);
122  }
123  catch ( const std::invalid_argument& e ) {
124  std::string msg = "Params::find(): No conversion for value: key = " + key + ", value = " + val +
125  ". Original error: " + e.what();
126  std::invalid_argument t(msg);
127  throw t;
128  }
129  }
130 
131  /** Private utility function to find a Parameter value in the set,
132  * and return its value as a type T.
133  *
134  * Type T must be either a basic numeric type (including bool) ,
135  * a std::string, or a class that has a constructor with a std::string
136  * as its only parameter. This class uses SST::Core::from_string to
137  * do the conversion.
138  * @param k - Parameter name
139  * @param default_value - Default value to return if parameter isn't found
140  * @param found - set to true if the the parameter was found
141  * @throw std::invalid_argument If value in (key, value) can't be
142  * converted to type T, an invalid_argument exception is thrown.
143  */
144  template <class T>
145  inline T find_impl(const std::string& k, T default_value, bool& found) const
146  {
147  verifyKey(k);
148  // const_iterator i = data.find(getKey(k));
149  const std::string& value = getString(k, found);
150  if ( !found ) { return default_value; }
151  else {
152  return convert_value<T>(k, value);
153  }
154  }
155 
156  /** Find a Parameter value in the set, and return its value as a type T.
157  * Type T must be either a basic numeric type (including bool) ,
158  * a std::string, or a class that has a constructor with a std::string
159  * as its only parameter. This class uses SST::Core::from_string to
160  * do the conversion.
161  * @param k - Parameter name
162  * @param default_value - Default value to return if parameter isn't found,
163  * specified as a string
164  * @param found - set to true if the the parameter was found
165  */
166  template <class T>
167  inline T find_impl(const std::string& k, const std::string& default_value, bool& found) const
168  {
169  verifyKey(k);
170  const std::string& value = getString(k, found);
171  if ( !found ) {
172  try {
173  return SST::Core::from_string<T>(default_value);
174  }
175  catch ( const std::invalid_argument& e ) {
176  std::string msg = "Params::find(): Invalid default value specified: key = " + k +
177  ", value = " + default_value + ". Original error: " + e.what();
178  std::invalid_argument t(msg);
179  throw t;
180  }
181  }
182  else {
183  found = true;
184  try {
185  return SST::Core::from_string<T>(value);
186  }
187  catch ( const std::invalid_argument& e ) {
188  std::string msg = "Params::find(): No conversion for value: key = " + k + ", value = " + value +
189  ". Original error: " + e.what();
190  std::invalid_argument t(msg);
191  throw t;
192  }
193  }
194  }
195 
196  typedef std::map<uint32_t, std::string>::const_iterator const_iterator; /*!< Const Iterator type */
197 
198  const std::string& getString(const std::string& name, bool& found) const;
199 
200  /**
201  Private function to clean up a token. It will remove leading
202  and trailing whitespace, leading and trailing quotes (single or
203  double), and the backslash (\‍) character before escaped quotes
204  of the same type as a leading quote.
205 
206  The format of the items depends on where they came from. The
207  string for the items are generated by calling the repr()
208  function on them. For strings, this means they will typically
209  be enclosed in single quotes. It is possible that they end up
210  enclosed in double quotes if the string itself contains a
211  single quote. For strings which contain both single and double
212  quotes, the repr() will create a single quoted string with all
213  internal single quotes escaped with '\'. Also, any string that
214  starts with a quote character, must end with the same quote
215  character.
216 
217  Examples of strings using double and/or single quotes:
218  'This is "a" test' -> This is "a" test
219  "This is 'a' test" -> This is 'a' test
220  'This "is \'a\'" test' -> This "is 'a'" test
221  'This "is \"a\"" test' -> This "is \"a\"" test
222  */
223  void cleanToken(std::string& token) const;
224 
225  /**
226  Private function for creating tokens from a delimited list.
227  Delimiters inside of quotes (single or double) are ignored.
228  */
229  void getDelimitedTokens(const std::string& value, char delim, std::vector<std::string>& tokens) const;
230 
231 public:
232  typedef std::string key_type; /*!< Type of key (string) */
233  typedef std::set<key_type, KeyCompare> KeySet_t; /*!< Type of a set of keys */
234 
235  /**
236  * Enable or disable parameter verification on an instance
237  * of Params. Useful when generating a new set of Params to
238  * pass off to a module.
239  *
240  * @return returns the previous state of the flag
241  */
242  bool enableVerify(bool enable)
243  {
244  bool old = verify_enabled;
245  verify_enabled = enable;
246  return old;
247  }
248 
249  /**
250  * Enable, on a global scale, parameter verification. Used
251  * after construction of the config graph so that warnings are
252  * not generated during construction.
253  */
254  static void enableVerify() { g_verify_enabled = true; };
255 
256  /**
257  * Returns the size of the Params. This will count both local and
258  * global params.
259  *
260  * @return number of key/value pairs in this Params object
261  */
262  size_t size() const;
263  /**
264  * Returns true if the Params is empty. Checks both local and
265  * global param sets.
266  *
267  * @return true if this Params object is empty, false otherwise
268  */
269  bool empty() const;
270 
271  /** Create a new, empty Params */
272  Params();
273 
274  /** Create a copy of a Params object */
275  Params(const Params& old);
276 
277  virtual ~Params() {}
278 
279  /**
280  * @brief Assignment operator.
281  * @param old Param to be copied
282  *
283  * All the elements of old are copied, This will also copy
284  * over any references to global param sets
285  */
286  Params& operator=(const Params& old);
287 
288  /**
289  * Erases all elements, including deleting reference to global
290  * param sets.
291  */
292  void clear();
293 
294  /**
295  * @brief Finds the number of elements with given key.
296  *
297  * The call will check both local and global params, but will
298  * still only report one instance if the given key is found in
299  * both the local and global param sets.
300  *
301  * @param k Key of (key, value) pairs to be located.
302  * @return Number of elements with specified key
303  * (either 1 or 0).
304  *
305  */
306  size_t count(const key_type& k) const;
307 
308  /** Find a Parameter value in the set, and return its value as a type T.
309  * Type T must be either a basic numeric type (including bool) ,
310  * a std::string, or a class that has a constructor with a std::string
311  * as its only parameter. This class uses SST::Core::from_string to
312  * do the conversion.
313  * @param k - Parameter name
314  * @param default_value - Default value to return if parameter isn't found
315  * @param found - set to true if the the parameter was found
316  * @throw std::invalid_argument If value in (key, value) can't be
317  * converted to type T, an invalid_argument exception is thrown.
318  */
319  template <class T>
320  typename std::enable_if<not std::is_same<std::string, T>::value, T>::type
321  find(const std::string& k, T default_value, bool& found) const
322  {
323  return find_impl<T>(k, default_value, found);
324  }
325 
326  /** Find a Parameter value in the set, and return its value as a type T.
327  * Type T must be either a basic numeric type (including bool) ,
328  * a std::string, or a class that has a constructor with a std::string
329  * as its only parameter. This class uses SST::Core::from_string to
330  * do the conversion.
331  * @param k - Parameter name
332  * @param default_value - Default value to return if parameter isn't found,
333  * specified as a string
334  * @param found - set to true if the the parameter was found
335  */
336  template <class T>
337  T find(const std::string& k, const std::string& default_value, bool& found) const
338  {
339  return find_impl<T>(k, default_value, found);
340  }
341 
342  /** Find a Parameter value in the set, and return its value as a type T.
343  * This version of find is only enabled for bool. This
344  * is required because a string literal will be preferentially
345  * cast to a bool rather than a string. This ensures that
346  * find<bool> works correctly for string literals. This class uses
347  * SST::Core::from_string to do the conversion.
348  * @param k - Parameter name
349  * @param default_value - Default value to return if parameter isn't found,
350  * specified as a string literal
351  */
352  template <class T>
353  typename std::enable_if<std::is_same<bool, T>::value, T>::type
354  find(const std::string& k, const char* default_value, bool& found) const
355  {
356  if ( nullptr == default_value ) { return find_impl<T>(k, static_cast<T>(0), found); }
357  return find_impl<T>(k, std::string(default_value), found);
358  }
359 
360  /** Find a Parameter value in the set, and return its value as a type T.
361  * Type T must be either a basic numeric type (including bool),
362  * a std::string, or a class that has a constructor with a std::string
363  * as its only parameter. This class uses SST::Core::from_string to
364  * do the conversion.
365  * @param k - Parameter name
366  * @param default_value - Default value to return if parameter isn't found
367  */
368  template <class T>
369  T find(const std::string& k, T default_value) const
370  {
371  bool tmp;
372  return find_impl<T>(k, default_value, tmp);
373  }
374 
375  /** Find a Parameter value in the set, and return its value as a type T.
376  * Type T must be either a basic numeric type (including bool) ,
377  * a std::string, or a class that has a constructor with a std::string
378  * as its only parameter. This class uses SST::Core::from_string to
379  * do the conversion.
380  * @param k - Parameter name
381  * @param default_value - Default value to return if parameter isn't found,
382  * specified as a string
383  */
384  template <class T>
385  T find(const std::string& k, const std::string& default_value) const
386  {
387  bool tmp;
388  return find_impl<T>(k, default_value, tmp);
389  }
390 
391  /** Find a Parameter value in the set, and return its value as a type T.
392  * This version of find is only enabled for bool. This
393  * is required because a string literal will be preferentially
394  * cast to a bool rather than a string. This ensures that
395  * find<bool> works correctly for string literals.This class uses
396  * SST::Core::from_string to do the conversion.
397  * @param k - Parameter name
398  * @param default_value - Default value to return if parameter isn't found,
399  * specified as a string literal
400  */
401  template <class T>
402  typename std::enable_if<std::is_same<bool, T>::value, T>::type
403  find(const std::string& k, const char* default_value) const
404  {
405  bool tmp;
406  if ( nullptr == default_value ) { return find_impl<T>(k, static_cast<T>(0), tmp); }
407  return find_impl<T>(k, std::string(default_value), tmp);
408  }
409 
410  /** Find a Parameter value in the set, and return its value as a type T.
411  * Type T must be either a basic numeric type (including bool) ,
412  * a std::string, or a class that has a constructor with a std::string
413  * as its only parameter. This class uses SST::Core::from_string to
414  * do the conversion.
415  * @param k - Parameter name
416  */
417  template <class T>
418  T find(const std::string& k) const
419  {
420  bool tmp;
421  T default_value = T();
422  return find_impl<T>(k, default_value, tmp);
423  }
424 
425  /** Find a Parameter value in the set, and return its value as a
426  * type T. Type T must be either a basic numeric type , a
427  * std::string, or a class that has a constructor with a
428  * std::string as its only parameter. This version of find is not
429  * enabled for bool as it conflicts with find<bool>(string key, bool
430  * default_value). This class uses SST::Core::from_string to do
431  * the conversion.
432  * @param k - Parameter name
433  * @param found - set to true if the the parameter was found
434  */
435  template <class T>
436  typename std::enable_if<not std::is_same<bool, T>::value, T>::type find(const std::string& k, bool& found) const
437  {
438  T default_value = T();
439  return find_impl<T>(k, default_value, found);
440  }
441 
442  /** Find a Parameter value in the set, and return its value as a
443  * vector of T's. The array will be appended to
444  * the end of the vector.
445  *
446  * Type T must be either a basic numeric type (including bool) , a
447  * std::string, or a class that has a constructor with a
448  * std::string as its only parameter. This class uses
449  * SST::Core::from_string to do the conversion. The values in the
450  * array must be enclosed in square brackets ( [] ), and be comma
451  * separated (commas in double or single quotes will not be
452  * considered a delimiter). If there are no square brackets, the
453  * entire string will be considered one value and a single item
454  * will be added to the vector.
455  *
456  * More details about parsing the values out of the string:
457  *
458  * Parses a string representing an array of tokens. It is
459  * tailored to the types strings you get when passing a python
460  * list as the param string. When you call addParam() on a python
461  * list in the input file, it will call the str() function on the
462  * list, which creates a string with the following format:
463  * [item1, item2, item3]
464  *
465  * The format of the items depends on where they came from. The
466  * string for the items are generated by calling the repr()
467  * function on them. For strings, this means they will typically
468  * be enclosed in single quotes. It is possible that they end up
469  * enclosed in double quotes if the string itself contains a
470  * single quote. For strings which contain both single and double
471  * quotes, the repr() will create a single quoted string with all
472  * internal single quotes escaped with '\'. Most other items used
473  * in SST do not enclose the string in quotes, though any string
474  * that contains a comma would need to be enclosed in quotes,
475  * since the comma is the delimiter character used. This is not
476  * done automatically, so if you have something that generates a
477  * commma in the string created by repr(), you may need to create
478  * an array string manually. Also, any string that starts with a
479  * quote character, must end with the same quote character.
480  *
481  * Tokens are generated by splitting the string on commas that are
482  * not within quotes (double or single). All whitespace at the
483  * beginning and end of a token is ignored (unless inside quotes).
484  * Once the tokens are generated, any quoted string will have the
485  * front and back quotes removed. The '\' for any escaped quote
486  * of the same type as the front and back is also removed.
487  *
488  * Examples:
489  *
490  * These will produce the same results:
491  * [1, 2, 3, 4, 5]
492  * ['1', '2', '3', '4', '5']
493  *
494  * Examples of strings using double and/or single quotes:
495  * 'This is "a" test' -> This is "a" test
496  * "This is 'a' test" -> This is 'a' test
497  * 'This "is \'a\'" test' -> This "is 'a'" test
498  * 'This "is \"a\"" test' -> This "is \"a\"" test
499  *
500  * @param k - Parameter name
501  * @param vec - vector to append array items to
502  */
503  template <class T>
504  void find_array(const key_type& k, std::vector<T>& vec) const
505  {
506  verifyKey(k);
507 
508  bool found = false;
509  std::string value = getString(k, found);
510  if ( !found ) return;
511  // If string starts with [ and ends with ], it is considered
512  // an array. Otherwise, it is considered a single
513  // value.
514  if ( value.front() != '[' || value.back() != ']' ) {
515  vec.push_back(convert_value<T>(k, value));
516  return;
517  }
518 
519  value = value.substr(1, value.size() - 2);
520 
521  // Get the tokens for the array
522  std::vector<std::string> tokens;
523  getDelimitedTokens(value, ',', tokens);
524 
525  // Clean up the tokens
526  for ( auto& str : tokens ) {
527  cleanToken(str);
528  }
529 
530  // Convert each token into the proper type and put in output
531  // vector
532  for ( auto& val : tokens ) {
533  vec.push_back(convert_value<T>(k, val));
534  }
535  }
536 
537  /** Find a Parameter value in the set, and return its value as a
538  * set of T's. The items will be added to the passed in set.
539  *
540  * Type T must be either a basic numeric type (including bool), a
541  * std::string, or a class that has a constructor with a
542  * std::string as its only parameter. This class uses
543  * SST::Core::from_string to do the conversion. The values in the
544  * set must be enclosed in curly braces ( {} ), and be comma
545  * separated (commas in double or single quotes will not be
546  * considered a delimiter). If there are no curly braces, the
547  * entire string will be considered one value and a single item
548  * will be added to the set.
549  *
550  * More details about parsing the values out of the string:
551  *
552  * Parses a string representing a set of tokens. It is
553  * tailored to the types strings you get when passing a python
554  * set as the param string. When you call addParam() on a python
555  * set in the input file, it will call the str() function on the
556  * set, which creates a string with the following format:
557  * {item1, item2, item3}
558  *
559  * The format of the items depends on where they came from. The
560  * string for the items are generated by calling the repr()
561  * function on them. For strings, this means they will typically
562  * be enclosed in single quotes. It is possible that they end up
563  * enclosed in double quotes if the string itself contains a
564  * single quote. For strings which contain both single and double
565  * quotes, the repr() will create a single quoted string with all
566  * internal single quotes escaped with '\'. Most other items used
567  * in SST do not enclose the string in quotes, though any string
568  * that contains a comma would need to be enclosed in quotes,
569  * since the comma is the delimiter character used. This is not
570  * done automatically, so if you have something that generates a
571  * commma in the string created by repr(), you may need to create
572  * an array string manually. Also, any string that starts with a
573  * quote character, must end with the same quote character.
574  *
575  * Tokens are generated by splitting the string on commas that are
576  * not within quotes (double or single). All whitespace at the
577  * beginning and end of a token is ignored (unless inside quotes).
578  * Once the tokens are generated, any quoted string will have the
579  * front and back quotes removed. The '\' for any escaped quote
580  * of the same type as the front and back is also removed.
581  *
582  * Examples:
583  *
584  * These will produce the same results:
585  * {1, 2, 3, 4, 5}
586  * {'1', '2', '3', '4', '5'}
587  *
588  * Examples of strings using double and/or single quotes:
589  * 'This is "a" test' -> This is "a" test
590  * "This is 'a' test" -> This is 'a' test
591  * 'This "is \'a\'" test' -> This "is 'a'" test
592  * 'This "is \"a\"" test' -> This "is \"a\"" test
593  *
594  * @param k - Parameter name
595  * @param set - set to add items to (new items will overwrite old
596  * items)
597  */
598  template <class T>
599  void find_set(const key_type& k, std::set<T>& set) const
600  {
601  verifyKey(k);
602 
603  bool found = false;
604  std::string value = getString(k, found);
605  if ( !found ) return;
606 
607  // Python 2 seems to have a slightly different format when
608  // str() is called on sets: set([a, b, c]). We need to change
609  // this to the expected format.
610  if ( value.find("set([") == 0 ) {
611  // Need to convert formats
612 
613  // take a substring with space at beginning and end to add
614  // {}
615  value = value.substr(4, value.length() - 5);
616  value[0] = '{';
617  value[value.length() - 1] = '}';
618  }
619 
620  // If string starts with { and ends with }, it is considered
621  // a set. Otherwise, it is considered a single
622  // value.
623  if ( value.front() != '{' || value.back() != '}' ) {
624  set.insert(convert_value<T>(k, value));
625  return;
626  }
627 
628  value = value.substr(1, value.size() - 2);
629 
630  // Get the tokens for the array
631  std::vector<std::string> tokens;
632  getDelimitedTokens(value, ',', tokens);
633 
634  // Clean up the tokens
635  for ( auto& str : tokens ) {
636  cleanToken(str);
637  }
638 
639  // Convert each token into the proper type and put in output
640  // vector
641  for ( auto& val : tokens ) {
642  set.insert(convert_value<T>(k, val));
643  }
644  }
645 
646  /** Find a Parameter value in the set, and return its value as a
647  * map<keyT,valT>. The items will be added to the passed in map.
648  *
649  * Types keyT and valT must be either a basic numeric type
650  * (including bool), a std::string, or a class that has a
651  * constructor with a std::string as its only parameter. This
652  * class uses SST::Core::from_string to do the conversion. The
653  * values in the map must be enclosed in curly braces ( {} ), the
654  * key/value pairs must be comma separated (commas in double or
655  * single quotes will not be considered a delimiter) and the key
656  * and value in the pairs must be separated by a colon (colons in
657  * double or single quotes will not be considered a delimiter).
658  * If there are no curly braces, the function will throw an
659  * std::invalid_argument exception without adding anything to the
660  * map.
661  *
662  * More details about parsing the values out of the string:
663  *
664  * Parses a string representing a set of tokens. It is
665  * tailored to the types strings you get when passing a python
666  * set as the param string. When you call addParam() on a python
667  * set in the input file, it will call the str() function on the
668  * set, which creates a string with the following format:
669  * {key1 : value1, key2 : value2, key3 : value3}
670  *
671  * The format of each item depends on where it came from. The
672  * string for the items are generated by calling the repr()
673  * function on them. For strings, this means they will typically
674  * be enclosed in single quotes. It is possible that they end up
675  * enclosed in double quotes if the string itself contains a
676  * single quote. For strings which contain both single and double
677  * quotes, the repr() will create a single quoted string with all
678  * internal single quotes escaped with '\'. Most other items used
679  * in SST do not enclose the string in quotes, though any string
680  * that contains a comma would need to be enclosed in quotes,
681  * since the comma is the delimiter character used. This is not
682  * done automatically, so if you have something that generates a
683  * commma in the string created by repr(), you may need to create
684  * an array string manually. Also, any string that starts with a
685  * quote character, must end with the same quote character.
686  *
687  * Tokens are generated by splitting the string on commas that are
688  * not within quotes (double or single). All whitespace at the
689  * beginning and end of a token is ignored (unless inside quotes).
690  * Once the tokens are generated, any quoted string will have the
691  * front and back quotes removed. The '\' for any escaped quote
692  * of the same type as the front and back is also removed.
693  *
694  * Examples:
695  *
696  * These will produce the same results:
697  * {"one" : 1, "two" : 2, "three" : 3, "Four" : 4}
698  * {"one" :'1', "two" : '2', "three" : '3', "four" : '4'}
699  *
700  * Examples of strings using double and/or single quotes:
701  * 'This is "a" test' -> This is "a" test
702  * "This is 'a' test" -> This is 'a' test
703  * 'This "is \'a\'" test' -> This "is 'a'" test
704  * 'This "is \"a\"" test' -> This "is \"a\"" test
705  *
706  * @param k - Parameter name
707  * @param map - map to add items to (new items will overwrite old
708  * items)
709  */
710  template <class keyT, class valT>
711  void find_map(const key_type& k, std::map<keyT, valT>& map) const
712  {
713  verifyKey(k);
714 
715  bool found = false;
716  std::string value = getString(k, found);
717  if ( !found ) return;
718  // If string starts with { and ends with }, it is considered
719  // a map. Otherwise, we will throw an exception.
720  if ( value.front() != '{' || value.back() != '}' ) {
721  std::string msg = "Invalid format for parameter to be parsed as a map: " + value;
722 
723  // Throw exception
724  throw std::invalid_argument(msg);
725  }
726 
727  value = value.substr(1, value.size() - 2);
728 
729  // Get the tokens
730  std::vector<std::string> tokens;
731  getDelimitedTokens(value, ',', tokens);
732 
733  // Now, we need to convert each of these to a key/value pair
734  // separated by a colon
735  std::vector<std::string> kvpair;
736  for ( auto& x : tokens ) {
737  kvpair.clear();
738  getDelimitedTokens(x, ':', kvpair);
739 
740  if ( kvpair.size() != 2 ) {
741  std::string msg = "Invalid format for map key/value pair: " + x;
742 
743  // throw exception
744  throw std::invalid_argument(msg);
745  }
746 
747  // Clean up the tokens
748  cleanToken(kvpair[0]);
749  cleanToken(kvpair[1]);
750 
751  // Insert into map, overwriting what might already be there
752  map[convert_value<keyT>(k, kvpair[0])] = convert_value<valT>(k, kvpair[1]);
753  }
754  }
755 
756  /** Checks to see if the value associated with the given key is
757  * considered to be an array. A value is considered to be an
758  * array if it is enclosed in square brackets ([]). No whitespace
759  * before or after the brackets is allowed.
760  *
761  * @param k - Parameter name
762  * @return true if value is an array as described above, false otherwise.
763  */
764  bool is_value_array(const key_type& k) const
765  {
766  bool found = false;
767  std::string value = getString(k, found);
768  if ( !found ) return false;
769  // String should start with [ and end with ]
770  if ( (value.find("[") == std::string::npos) || (value.find("]") == std::string::npos) ) { return false; }
771  return true;
772  }
773 
774  /** Print all key/value parameter pairs to specified ostream */
775  void print_all_params(std::ostream& os, const std::string& prefix = "") const;
776  /** Print all key/value parameter pairs to specified ostream */
777  void print_all_params(Output& out, const std::string& prefix = "") const;
778 
779  /**
780  * Add a key/value pair into the param object.
781  *
782  * @param key key to add to the map
783  *
784  * @param value value to add to the map
785  *
786  * @param overwrite controls whether the key/value pair will
787  * overwrite an existing pair in the set
788  */
789  void insert(const std::string& key, const std::string& value, bool overwrite = true);
790 
791  /**
792  * Add contents of input Params object to current Params object.
793  * This will also add any pointers to global param sets after the
794  * existing pointers to global param sets in this object.
795  *
796  * @param params Params object that should added to current object
797  */
798  void insert(const Params& params);
799 
800  /**
801  Get all the keys contained in the Params object. This will
802  give both local and global params.
803  */
804  std::set<std::string> getKeys() const;
805 
806  /**
807  * Returns a new parameter object with parameters that match the
808  * specified scoped prefix (scopes are separated with "." The
809  * keys will be stripped of the "scope." prefix.
810  *
811  * Function will search both local and global params, but all
812  * params will be copied into the local space of the new Params
813  * object.
814  *
815  * @param scope Scope to search (anything prefixed with "scope."
816  * will be included in the return Params object
817  *
818  * @return New Params object with the found scoped params.
819  */
820  Params get_scoped_params(const std::string& scope) const;
821 
822  /**
823  * Search the container for a particular key. This will search
824  * both local and global params.
825  *
826  * @param k Key to search for
827  * @return True if the params contains the key, false otherwise
828  */
829  bool contains(const key_type& k) const;
830 
831  /**
832  * @param keys Set of keys to consider valid to add to the stack
833  * of legal keys
834  */
835  void pushAllowedKeys(const KeySet_t& keys);
836 
837  /**
838  * Removes the most recent set of keys considered allowed
839  */
840  void popAllowedKeys();
841 
842  void serialize_order(SST::Core::Serialization::serializer& ser) override;
843  ImplementSerializable(SST::Params)
844 
845 private:
846  //// Functions used by model descriptions and config graph
847  //// outputters (classes that use it are friended below)
848  friend class SST::ConfigGraph;
849  friend class SST::ConfigComponent;
850  friend class SST::Core::ConfigGraphOutput;
851  friend class SST::SSTModelDescription;
852 
853  /**
854  * @param k Key to check for validity
855  * @return True if the key is considered allowed
856  */
857  void verifyParam(const key_type& k) const;
858 
859  /**
860  * Adds a global param set to be looked at in this Params object
861  * if the key isn't found locally. It will search the global sets
862  * in the order they were inserted and return immediately after
863  * finding the key in one of the sets.
864  *
865  * @param set set to add to the search list for this object
866  */
867  void addGlobalParamSet(const std::string& set);
868 
869  /**
870  * Adds a key/value pair to the specified global set
871  *
872  * @param set global set to add the key/value pair to
873  *
874  * @param key key to add to the map
875  *
876  * @param value value to add to the map
877  *
878  * @param overwrite controls whether the key/value pair will
879  * overwrite an existing pair in the set
880  */
881  static void
882  insert_global(const std::string& set, const key_type& key, const key_type& value, bool overwrite = true);
883 
884  /**
885  * Get a named global parameter set.
886  *
887  * @param name Name of the set to get
888  *
889  * @return returns a copy of the reqeusted global param set
890  *
891  */
892  static std::map<std::string, std::string> getGlobalParamSet(const std::string& name);
893 
894  /**
895  * Get a vector of the names of available global parameter sets.
896  *
897  * @return returns a vector of the names of available global param
898  * sets
899  *
900  */
901  static std::vector<std::string> getGlobalParamSetNames();
902 
903  /**
904  * Get a vector of the local keys
905  *
906  * @return returns a vector of the local keys in this Params
907  * object
908  *
909  */
910  std::vector<std::string> getLocalKeys() const;
911 
912  /**
913  * Get a vector of the global param sets this Params object is
914  * subscribed to
915  *
916  * @return returns a vector of the global param sets his Params
917  * object is subscribed to
918  *
919  */
920  std::vector<std::string> getSubscribedGlobalParamSets() const;
921 
922 
923  // Private functions used by Params
924  /**
925  * @param k Key to check for validity
926  * @return True if the key is considered allowed
927  */
928  void verifyKey(const key_type& k) const;
929 
930 
931  // Private data
932  std::map<uint32_t, std::string> my_data;
933  std::vector<std::map<uint32_t, std::string>*> data;
934  std::vector<KeySet_t> allowedKeys;
935  bool verify_enabled;
936  static bool g_verify_enabled;
937 
938  static uint32_t getKey(const std::string& str);
939 
940  /**
941  * Given a Parameter Key ID, return the Name of the matching parameter
942  * @param id Key ID to look up
943  * @return String name of the parameter
944  */
945  static const std::string& getParamName(uint32_t id);
946 
947  /* Friend main() because it broadcasts the maps */
948  friend int ::main(int argc, char* argv[]);
949 
950  static std::map<std::string, uint32_t> keyMap;
951  static std::vector<std::string> keyMapReverse;
952  static SST::Core::ThreadSafe::Spinlock keyLock;
953  static SST::Core::ThreadSafe::Spinlock globalLock;
954  static uint32_t nextKeyID;
955 
956  static std::map<std::string, std::map<uint32_t, std::string>> global_params;
957 };
958 
959 #if 0
960  class UnitAlgebra;
961 
962 #define SST_PARAMS_DECLARE_TEMPLATE_SPECIALIZATION(type) \
963  template <> \
964  type Params::find(const std::string& k, type default_value, bool& found) const; \
965  template <> \
966  type Params::find(const std::string& k, const std::string& default_value, bool& found) const; \
967  template <> \
968  type Params::find(const std::string& k, type default_value) const; \
969  template <> \
970  type Params::find(const std::string& k, const std::string& default_value) const; \
971  template <> \
972  type Params::find(const std::string& k) const;
973 
974 
975  SST_PARAMS_DECLARE_TEMPLATE_SPECIALIZATION(int32_t)
976  SST_PARAMS_DECLARE_TEMPLATE_SPECIALIZATION(uint32_t)
977  SST_PARAMS_DECLARE_TEMPLATE_SPECIALIZATION(int64_t)
978  SST_PARAMS_DECLARE_TEMPLATE_SPECIALIZATION(uint64_t)
979  SST_PARAMS_DECLARE_TEMPLATE_SPECIALIZATION(bool)
980  SST_PARAMS_DECLARE_TEMPLATE_SPECIALIZATION(float)
981  SST_PARAMS_DECLARE_TEMPLATE_SPECIALIZATION(double)
982  SST_PARAMS_DECLARE_TEMPLATE_SPECIALIZATION(UnitAlgebra)
983 
984  // std::string has to be special cased because of signature conflicts
985  // SST_PARAMS_DECLARE_TEMPLATE_SPECIALIZATION(std::string)
986  template<>
987  std::string Params::find<std::string>(const std::string& k, const std::string& default_value, bool &found) const;
988 #endif
989 
990 } // namespace SST
991 
992 #endif // SST_CORE_PARAMS_H
Represents the configuration of a generic component.
Definition: configGraph.h:218
A Configuration Graph A graph representing Components and Links.
Definition: configGraph.h:390
Definition: configGraphOutput.h:42
Definition: serializable.h:119
This class is basically a wrapper for objects to declare the order in which their members should be s...
Definition: serializer.h:35
Definition: threadsafe.h:122
Output object provides consistent method for outputting data to stdout, stderr and/or sst debug file.
Definition: output.h:52
Parameter store.
Definition: params.h:56
void popAllowedKeys()
Removes the most recent set of keys considered allowed.
Definition: params.cc:209
static std::map< std::string, std::string > getGlobalParamSet(const std::string &name)
Get a named global parameter set.
Definition: params.cc:396
void verifyKey(const key_type &k) const
Definition: params.cc:218
std::enable_if< not std::is_same< bool, T >::value, T >::type 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:436
std::string key_type
Definition: params.h:232
void addGlobalParamSet(const std::string &set)
Adds a global param set to be looked at in this Params object if the key isn't found locally.
Definition: params.cc:284
std::vector< std::string > getSubscribedGlobalParamSets() const
Get a vector of the global param sets this Params object is subscribed to.
Definition: params.cc:433
std::vector< std::string > getLocalKeys() const
Get a vector of the local keys.
Definition: params.cc:421
void clear()
Erases all elements, including deleting reference to global param sets.
Definition: params.cc:81
void print_all_params(std::ostream &os, const std::string &prefix="") const
Print all key/value parameter pairs to specified ostream.
Definition: params.cc:100
std::set< std::string > getKeys() const
Get all the keys contained in the Params object.
Definition: params.cc:163
static std::vector< std::string > getGlobalParamSetNames()
Get a vector of the names of available global parameter sets.
Definition: params.cc:409
Params()
Create a new, empty Params.
Definition: params.cc:55
std::enable_if< std::is_same< bool, T >::value, T >::type find(const std::string &k, const char *default_value, bool &found) const
Find a Parameter value in the set, and return its value as a type T.
Definition: params.h:354
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:418
bool contains(const key_type &k) const
Search the container for a particular key.
Definition: params.cc:194
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:504
bool enableVerify(bool enable)
Enable or disable parameter verification on an instance of Params.
Definition: params.h:242
Params & operator=(const Params &old)
Assignment operator.
Definition: params.cc:70
Params get_scoped_params(const std::string &scope) const
Returns a new parameter object with parameters that match the specified scoped prefix (scopes are sep...
Definition: params.cc:175
static const std::string & getParamName(uint32_t id)
Given a Parameter Key ID, return the Name of the matching parameter.
Definition: params.cc:240
void verifyParam(const key_type &k) const
Definition: params.cc:234
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:369
void pushAllowedKeys(const KeySet_t &keys)
Definition: params.cc:203
static void enableVerify()
Enable, on a global scale, parameter verification.
Definition: params.h:254
T find(const std::string &k, const std::string &default_value) const
Find a Parameter value in the set, and return its value as a type T.
Definition: params.h:385
void find_map(const key_type &k, std::map< keyT, valT > &map) const
Find a Parameter value in the set, and return its value as a map<keyT,valT>.
Definition: params.h:711
bool empty() const
Returns true if the Params is empty.
Definition: params.cc:50
static void insert_global(const std::string &set, const key_type &key, const key_type &value, bool overwrite=true)
Adds a key/value pair to the specified global set.
Definition: params.cc:293
std::enable_if< not std::is_same< std::string, T >::value, T >::type 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:321
size_t size() const
Returns the size of the Params.
Definition: params.cc:44
size_t count(const key_type &k) const
Finds the number of elements with given key.
Definition: params.cc:89
std::set< key_type, KeyCompare > KeySet_t
Definition: params.h:233
void find_set(const key_type &k, std::set< T > &set) const
Find a Parameter value in the set, and return its value as a set of T's.
Definition: params.h:599
bool is_value_array(const key_type &k) const
Checks to see if the value associated with the given key is considered to be an array.
Definition: params.h:764
std::enable_if< std::is_same< bool, T >::value, T >::type find(const std::string &k, const char *default_value) const
Find a Parameter value in the set, and return its value as a type T.
Definition: params.h:403
T find(const std::string &k, const std::string &default_value, bool &found) const
Find a Parameter value in the set, and return its value as a type T.
Definition: params.h:337
void insert(const std::string &key, const std::string &value, bool overwrite=true)
Add a key/value pair into the param object.
Definition: params.cc:140
Base class for Model Generation.
Definition: sstmodel.h:26