SST 12.1.0
Structural Simulation Toolkit
params.h
1// Copyright 2009-2022 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-2022, 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
31int main(int argc, char* argv[]);
32
33namespace SST {
34
35class ConfigGraph;
36class ConfigComponent;
37class SSTModelDescription;
38
39namespace Core {
40class 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{
57private:
58 struct KeyCompare : std::binary_function<std::string, std::string, bool>
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);
87NO_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
231public:
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
845private:
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::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
std::enable_if< notstd::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
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) 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
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
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
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
std::enable_if< notstd::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
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
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
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