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