SST  14.1.0
StructuralSimulationToolkit
params.h
1 // Copyright 2009-2024 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-2024, 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  /** Return a string version of all key/value parameter pairs */
779  std::string toString(const std::string& prefix = "") const;
780 
781  /**
782  * Add a key/value pair into the param object.
783  *
784  * @param key key to add to the map
785  *
786  * @param value value to add to the map
787  *
788  * @param overwrite controls whether the key/value pair will
789  * overwrite an existing pair in the set
790  */
791  void insert(const std::string& key, const std::string& value, bool overwrite = true);
792 
793  /**
794  * Add contents of input Params object to current Params object.
795  * This will also add any pointers to global param sets after the
796  * existing pointers to global param sets in this object.
797  *
798  * @param params Params object that should added to current object
799  */
800  void insert(const Params& params);
801 
802  /**
803  Get all the keys contained in the Params object. This will
804  give both local and global params.
805  */
806  std::set<std::string> getKeys() const;
807 
808  /**
809  * Returns a new parameter object with parameters that match the
810  * specified scoped prefix (scopes are separated with "." The
811  * keys will be stripped of the "scope." prefix.
812  *
813  * Function will search both local and global params, but all
814  * params will be copied into the local space of the new Params
815  * object.
816  *
817  * @param scope Scope to search (anything prefixed with "scope."
818  * will be included in the return Params object
819  *
820  * @return New Params object with the found scoped params.
821  */
822  Params get_scoped_params(const std::string& scope) const;
823 
824  /**
825  * Search the container for a particular key. This will search
826  * both local and global params.
827  *
828  * @param k Key to search for
829  * @return True if the params contains the key, false otherwise
830  */
831  bool contains(const key_type& k) const;
832 
833  /**
834  * @param keys Set of keys to consider valid to add to the stack
835  * of legal keys
836  */
837  void pushAllowedKeys(const KeySet_t& keys);
838 
839  /**
840  * Removes the most recent set of keys considered allowed
841  */
842  void popAllowedKeys();
843 
844  void serialize_order(SST::Core::Serialization::serializer& ser) override;
845  ImplementSerializable(SST::Params)
846 
847 private:
848  //// Functions used by model descriptions and config graph
849  //// outputters (classes that use it are friended below)
850  friend class SST::ConfigGraph;
851  friend class SST::ConfigComponent;
852  friend class SST::Core::ConfigGraphOutput;
853  friend class SST::SSTModelDescription;
854 
855  /**
856  * @param k Key to check for validity
857  * @return True if the key is considered allowed
858  */
859  void verifyParam(const key_type& k) const;
860 
861  /**
862  * Adds a global param set to be looked at in this Params object
863  * if the key isn't found locally. It will search the global sets
864  * in the order they were inserted and return immediately after
865  * finding the key in one of the sets.
866  *
867  * @param set set to add to the search list for this object
868  */
869  void addGlobalParamSet(const std::string& set);
870 
871  /**
872  * Adds a key/value pair to the specified global set
873  *
874  * @param set global set to add the key/value pair to
875  *
876  * @param key key to add to the map
877  *
878  * @param value value to add to the map
879  *
880  * @param overwrite controls whether the key/value pair will
881  * overwrite an existing pair in the set
882  */
883  static void
884  insert_global(const std::string& set, const key_type& key, const key_type& value, bool overwrite = true);
885 
886  /**
887  * Get a named global parameter set.
888  *
889  * @param name Name of the set to get
890  *
891  * @return returns a copy of the reqeusted global param set
892  *
893  */
894  static std::map<std::string, std::string> getGlobalParamSet(const std::string& name);
895 
896  /**
897  * Get a vector of the names of available global parameter sets.
898  *
899  * @return returns a vector of the names of available global param
900  * sets
901  *
902  */
903  static std::vector<std::string> getGlobalParamSetNames();
904 
905  /**
906  * Get a vector of the local keys
907  *
908  * @return returns a vector of the local keys in this Params
909  * object
910  *
911  */
912  std::vector<std::string> getLocalKeys() const;
913 
914  /**
915  * Get a vector of the global param sets this Params object is
916  * subscribed to
917  *
918  * @return returns a vector of the global param sets his Params
919  * object is subscribed to
920  *
921  */
922  std::vector<std::string> getSubscribedGlobalParamSets() const;
923 
924 
925  // Private functions used by Params
926  /**
927  * @param k Key to check for validity
928  * @return True if the key is considered allowed
929  */
930  void verifyKey(const key_type& k) const;
931 
932 
933  // Private data
934  std::map<uint32_t, std::string> my_data;
935  std::vector<std::map<uint32_t, std::string>*> data;
936  std::vector<KeySet_t> allowedKeys;
937  bool verify_enabled;
938  static bool g_verify_enabled;
939 
940  static uint32_t getKey(const std::string& str);
941 
942  /**
943  * Given a Parameter Key ID, return the Name of the matching parameter
944  * @param id Key ID to look up
945  * @return String name of the parameter
946  */
947  static const std::string& getParamName(uint32_t id);
948 
949  /* Friend main() because it broadcasts the maps */
950  friend int ::main(int argc, char* argv[]);
951  /* Friend simulation because it checkpoints the maps */
952  friend class Simulation_impl;
953 
954  static std::map<std::string, uint32_t> keyMap;
955  static std::vector<std::string> keyMapReverse;
956  static SST::Core::ThreadSafe::Spinlock keyLock;
957  static SST::Core::ThreadSafe::Spinlock globalLock;
958  static uint32_t nextKeyID;
959 
960  static std::map<std::string, std::map<uint32_t, std::string>> global_params;
961 };
962 
963 #if 0
964  class UnitAlgebra;
965 
966 #define SST_PARAMS_DECLARE_TEMPLATE_SPECIALIZATION(type) \
967  template <> \
968  type Params::find(const std::string& k, type default_value, bool& found) const; \
969  template <> \
970  type Params::find(const std::string& k, const std::string& default_value, bool& found) const; \
971  template <> \
972  type Params::find(const std::string& k, type default_value) const; \
973  template <> \
974  type Params::find(const std::string& k, const std::string& default_value) const; \
975  template <> \
976  type Params::find(const std::string& k) const;
977 
978 
979  SST_PARAMS_DECLARE_TEMPLATE_SPECIALIZATION(int32_t)
980  SST_PARAMS_DECLARE_TEMPLATE_SPECIALIZATION(uint32_t)
981  SST_PARAMS_DECLARE_TEMPLATE_SPECIALIZATION(int64_t)
982  SST_PARAMS_DECLARE_TEMPLATE_SPECIALIZATION(uint64_t)
983  SST_PARAMS_DECLARE_TEMPLATE_SPECIALIZATION(bool)
984  SST_PARAMS_DECLARE_TEMPLATE_SPECIALIZATION(float)
985  SST_PARAMS_DECLARE_TEMPLATE_SPECIALIZATION(double)
986  SST_PARAMS_DECLARE_TEMPLATE_SPECIALIZATION(UnitAlgebra)
987 
988  // std::string has to be special cased because of signature conflicts
989  // SST_PARAMS_DECLARE_TEMPLATE_SPECIALIZATION(std::string)
990  template<>
991  std::string Params::find<std::string>(const std::string& k, const std::string& default_value, bool &found) const;
992 #endif
993 
994 } // namespace SST
995 
996 #endif // SST_CORE_PARAMS_H
Output object provides consistent method for outputting data to stdout, stderr and/or sst debug file...
Definition: output.h:53
This class is basically a wrapper for objects to declare the order in which their members should be s...
Definition: serializer.h:43
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::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, T default_value) const
Find a Parameter value in the set, and return its value as a type T.
Definition: params.h:369
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
Outputs configuration data to a specified file path.
Definition: configGraphOutput.h:54
Represents the configuration of a generic component.
Definition: configGraph.h:217
void pushAllowedKeys(const KeySet_t &keys)
Definition: params.cc:226
A Configuration Graph A graph representing Components and Links.
Definition: configGraph.h:389
Definition: action.cc:18
static void enableVerify()
Enable, on a global scale, parameter verification.
Definition: params.h:254
bool contains(const key_type &k) const
Search the container for a particular key.
Definition: params.cc:217
Definition: serializable.h:24
static const std::string & getParamName(uint32_t id)
Given a Parameter Key ID, return the Name of the matching parameter.
Definition: params.cc:263
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&#39;s.
Definition: params.h:504
void clear()
Erases all elements, including deleting reference to global param sets.
Definition: params.cc:81
std::vector< std::string > getLocalKeys() const
Get a vector of the local keys.
Definition: params.cc:447
Params()
Create a new, empty Params.
Definition: params.cc:55
std::vector< std::string > getSubscribedGlobalParamSets() const
Get a vector of the global param sets this Params object is subscribed to.
Definition: params.cc:459
bool enableVerify(bool enable)
Enable or disable parameter verification on an instance of Params.
Definition: params.h:242
Main control class for a SST Simulation.
Definition: simulation_impl.h:76
static std::vector< std::string > getGlobalParamSetNames()
Get a vector of the names of available global parameter sets.
Definition: params.cc:435
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 toString(const std::string &prefix="") const
Return a string version of all key/value parameter pairs.
Definition: params.cc:140
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:198
std::set< std::string > getKeys() const
Get all the keys contained in the Params object.
Definition: params.cc:186
Definition: threadsafe.h:121
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&#39;s.
Definition: params.h:599
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
Parameter store.
Definition: params.h:55
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:319
void popAllowedKeys()
Removes the most recent set of keys considered allowed.
Definition: params.cc:232
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 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
Base class for Model Generation.
Definition: sstmodel.h:25
std::set< key_type, KeyCompare > KeySet_t
Definition: params.h:233
std::string key_type
Definition: params.h:232
size_t count(const key_type &k) const
Finds the number of elements with given key.
Definition: params.cc:89
bool empty() const
Returns true if the Params is empty.
Definition: params.cc:50
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
void verifyKey(const key_type &k) const
Definition: params.cc:241
void addGlobalParamSet(const std::string &set)
Adds a global param set to be looked at in this Params object if the key isn&#39;t found locally...
Definition: params.cc:310
size_t size() const
Returns the size of the Params.
Definition: params.cc:44
Params & operator=(const Params &old)
Assignment operator.
Definition: params.cc:70
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
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:163
void verifyParam(const key_type &k) const
Definition: params.cc:257
static std::map< std::string, std::string > getGlobalParamSet(const std::string &name)
Get a named global parameter set.
Definition: params.cc:422
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