The Sparta Modeling Framework
Loading...
Searching...
No Matches
ParameterSet.hpp
Go to the documentation of this file.
1// <ParameterSet> -*- C++ -*-
2
3#pragma once
4
5#include <iostream>
6#include <iomanip>
7#include <string>
8#include <ostream>
9#include <vector>
10#include <unordered_map>
11
12#include "sparta/utils/Utils.hpp"
15
21namespace sparta
22{
23 class ParameterTree;
24
64 class ParameterSet : public TreeNode
65 {
66 friend class ParameterBase;
67
68 public:
75
76 ParameterSet() = delete;
77 ParameterSet(const ParameterSet& rhp) = delete;
78 void operator=(const ParameterSet& rhp) = delete;
79
83 static constexpr char NODE_NAME[] = "params";
84
88 static constexpr char PARAMETER_SET_NODE_TAG[] = "SPARTA_ParameterSet";
89
91 typedef std::vector<sparta::ParameterBase*> ParameterVector;
92
94 typedef std::unordered_map<std::string, ParameterBase*> ParameterPairs;
95
106 "Parameter set"),
107 __this_ps(this)
108 {
109 addTag(PARAMETER_SET_NODE_TAG); // Tag for easier searching
110
111 if(parent){
112 // Do not inherit parent phase yet if finalizing
113 const bool inherit_phase = parent->getPhase() < TREE_FINALIZING;
114 parent->addChild(this, inherit_phase);
115 }
116 }
117
121 virtual ~ParameterSet() = default;
122
123 bool validateIndependently(std::string& err_names) const
124 {
125 bool success = true;
126 for(const ParameterPairs::value_type& p : keys_){
127 std::string temp;
128 if(!p.second->validateIndependently(temp)){
129 err_names += p.second->stringize();
130 err_names += ": ";
131 err_names += temp;
132 err_names += '\n';
133 success = false;
134 }
135 }
136 return success;
137 }
138
139 bool validateDependencies(const TreeNode* node, std::string& err_names) const
140 {
141 bool success = true;
142 for(const ParameterPairs::value_type& p : keys_){
143 std::string temp;
144 if(!p.second->validateDependencies(node, temp)){
145 err_names += p.second->stringize();
146 err_names += ": ";
147 err_names += temp;
148 err_names += '\n';
149 success = false;
150 }
151 }
152 return success;
153 }
154
159 for(ParameterPairs::value_type & pair : keys_) {
160 pair.second->resetReadCount_();
161 }
162 }
163
168 for(ParameterPairs::value_type & pair : keys_) {
169 pair.second->resetWriteCount_();
170 }
171 }
172
183 void verifyAllRead() const {
184 std::stringstream errors;
185 bool err = false;
186 for(const ParameterPairs::value_type& p : keys_){
187 if(not p.second->isReadOrIgnored()){
188 if(err){
189 errors << ", ";
190 }
191 errors << p.second->getName();
192 err = true;
193 }
194 }
195
196 if(err){
197 throw ParameterException("Some parameters in ParameterSet \"")
198 << getLocation() << "\" have not been read: " << errors.str()
199 << " . A sparta::Resource must read all of its parameters or explicitly "
200 ".ignore() them";
201 }
202 }
203
216 void ignoreAll() const {
217 for(const ParameterPairs::value_type& p : keys_){
218 p.second->ignore_();
219 }
220 }
221
223 virtual std::string dumpList() const {
224 std::stringstream ss;
225 ss << "Parameters for " << getLocation() << ":\n";
226
227 // Determine column sizes
230 uint32_t col_sizes[] = {0, 0, 0, 0, 0};
231 for(const ParameterPairs::value_type& p : keys_){
232 col_sizes[0] = std::max<uint32_t>(p.second->getTypeName().size(), col_sizes[0]);
233 col_sizes[1] = std::max<uint32_t>(p.second->getName().size(), col_sizes[1]);
234 col_sizes[2] = std::max<uint32_t>(p.second->getValueAsString().size(), col_sizes[2]);
235 col_sizes[3] = std::max<uint32_t>(p.second->getDefaultAsString().size(), col_sizes[3]);
236 col_sizes[4] = std::max<uint32_t>(numDecDigits(p.second->getReadCount()), col_sizes[4]);
237 }
238
239 // Render table with constant column size (type, key, value, default, read: num_reads)
240 for(const ParameterPairs::value_type& p : keys_){
241 const ParameterBase* pb = p.second;
242 if(!pb->isVisibilityAllowed()){
243 continue;
244 }
245 ss << " ";
246 ss << '('
247 << std::setiosflags(std::ios::left) << std::setw(col_sizes[0]) << pb->getTypeName() << " "
248 << std::setiosflags(std::ios::left) << std::setw(col_sizes[1]) << pb->getName() << " : "
249 << std::setiosflags(std::ios::left) << std::setw(col_sizes[2]) << pb->getValueAsString() << ", def="
250 << std::setiosflags(std::ios::left) << std::setw(col_sizes[3]) << pb->getDefaultAsString()
251 << " read: " << std::setiosflags(std::ios::left) << std::setw(col_sizes[4]) << pb->getReadCount()
252 << ')';
253
254 ss << '\n';
255 }
256
257 return ss.str();
258 }
259
260 // Overload of TreeNode::stringize
261 virtual std::string stringize(bool pretty=false) const override {
262 (void) pretty;
263 std::stringstream ss;
264 ss << '<' << getLocation() << ' ' << keys_.size() << " params>";
265 return ss.str();
266 }
267
285 template <class T>
286 const T getParameterValueAs(const std::string& name) const {
287 ParameterPairs::const_iterator itr = keys_.find(name);
288 if(keys_.end() == itr){
289 throw ParameterException("Could not get parameter by name \"")
290 << name << "\". No parameter by that name exists.";
291 }
292 ParameterBase* pb = itr->second;
293 sparta_assert(pb != nullptr);
294 return pb->getValueAs<T>();
295 }
296
314 template <class ContentT>
315 const Parameter<ContentT>& getParameterAs(const std::string& name) const {
316 const ParameterBase* pb = getParameter(name, true);
317 Parameter<ContentT>* p = dynamic_cast<const Parameter<ContentT>*>(pb);
318 if(!p){
319 throw SpartaException("Found parameter \"") << name << "\" in ParameterSet "
320 << getLocation() << " but Parameter was not of requested type \""
321 << demangle(typeid(ContentT).name()) << "\". Was instead \""
322 << pb->getTypeName() << "\". ";
323 }
324 return *p;
325 }
326
327 // Overload of getParameterAs for non-const access with a pointer ContentT type
328 template <class ContentT>
329 Parameter<ContentT>& getParameterAs(const std::string& name) {
330 ParameterBase* pb = getParameter(name, true);
331 Parameter<ContentT>* p = dynamic_cast<Parameter<ContentT>*>(pb);
332 if(!p){
333 throw SpartaException("Found parameter \"") << name << "\" in ParameterSet "
334 << getLocation() << " but Parameter was not of requested type \""
335 << demangle(typeid(ContentT).name()) << "\". Was instead \""
336 << pb->getTypeName() << "\". ";
337 }
338 return *p;
339 }
340
351 ParameterBase* getParameter(const std::string& name, bool must_exist=true) {
352 return getChildAs<ParameterBase>(name, must_exist);
353 }
354
358 const ParameterBase* getParameter(const std::string& name, bool must_exist=true) const {
359 return getChildAs<ParameterBase>(name, must_exist);
360 }
361
363 uint32_t findParameters(const std::string& name,
364 std::vector<ParameterBase*>& results) {
365 std::vector<TreeNode*> nodes;
366 TreeNode::findChildren(name, nodes);
367 uint32_t num_found = 0;
368 for(TreeNode* node : nodes){
369 ParameterBase* p = dynamic_cast<ParameterBase*>(node);
370 if(p != nullptr){
371 results.push_back(p);
372 ++num_found;
373 }else{
374 std::cerr << "Could not cast node " << node->getLocation() << " to ParameterBase*" << std::endl;
375 }
376 }
377 return num_found;
378 }
379
383 bool hasParameter(const std::string& name) const {
384 ParameterPairs::const_iterator itr = keys_.find(name);
385 return itr != keys_.end();
386 }
387
392 static inline uint32_t getNumBoundTypes() {
393 return (uint32_t)KeyValue::GBL_type_name_map.size();
394 }
395
404 bool hasModificationPermission(const ParameterBase * modifying_param,
405 std::vector<const ParameterBase *> params) const
406 {
407 for(const auto & param : params)
408 {
409 sparta_assert(param != modifying_param);
410
411 bool hit_modifier = false;
412 for(const auto & it : params_) {
413 if(it == param) {
414 sparta_assert(hit_modifier == true, "Parameter: '"
415 << it->getName() << "' cannot modifiy '" << param->getName()
416 << "' because '" << it->getName()
417 << "' does not come before '" << param->getName()
418 << "' in the parameter set");
419 return (hit_modifier == true);
420 }
421 if(it == modifying_param) {
422 hit_modifier = true;
423 }
424 }
425 }
426 return true;
427 }
428
437 if(locking_params_stack_.empty()) {
438 return true;
439 }
440 sparta_assert(locking_params_stack_.back() != modify_e,
441 "Parameter '" << locking_params_stack_.back()->getName()
442 << "' cannot modify itself in it's own callback!");
443 return hasModificationPermission(locking_params_stack_.back(), {modify_e});
444 }
445
450 void lock(const ParameterBase * lock_param);
451
456 bool isLocked() const {
457 return (locking_params_stack_.empty() == false);
458 }
459
465 void unlock(const ParameterBase * unlock_param);
466
475 template<typename T>
477 {
478 public:
480 keys_(0), key_iter_(ParameterPairs::iterator())
481 {
482 }
483
484 ParameterSetIterator(ParameterPairs const * keys, T const & itr) :
485 keys_(keys), key_iter_(itr)
486 {
487 sparta_assert(keys != 0); // Cannot create without a valid keys map
488 }
489
491 keys_(rhp.keys_), key_iter_(rhp.key_iter_)
492 {}
493
494 const ParameterSetIterator& operator=(const ParameterSetIterator& rhp)
495 {
496 keys_ = rhp.keys_;
497 key_iter_ = rhp.key_iter_;
498 return *this;
499 }
500
501 // Prefix
502 const ParameterSetIterator& operator++()
503 {
504 // There is a bug in boost that prevents gcc from compiling this
505 // with -Werror=sequence-point on.
506 ++key_iter_;
507 return *this;
508 }
509
510 // Postfix
511 const ParameterSetIterator operator++(int i)
512 {
513 (void) i;
514 ParameterSetIterator current = *this;
515 ++(*this);
516 return current;
517 }
518
519 ParameterBase* operator*(){
520 if(keys_ == 0){
521 throw ParameterException("Iterator has not been initialized");
522 }
523 if(key_iter_ == keys_->end()){
524 throw ParameterException("Iterator has reached end and is invalid");
525 }
526 return key_iter_->second;
527 }
528
529 const ParameterBase * operator*() const {
530 if(keys_ == 0){
531 throw ParameterException("Iterator has not been initialized");
532 }
533 if(key_iter_ == keys_->end()){
534 throw ParameterException("Iterator has reached end and is invalid");
535 }
536 return key_iter_->second;
537 }
538
539 bool operator==(const ParameterSetIterator& rhp) const {
540 return key_iter_ == rhp.key_iter_;
541 }
542
543 bool operator!=(const ParameterSetIterator& rhp) const {
544 return key_iter_ != rhp.key_iter_;
545 }
546
547 private:
548 ParameterPairs const * keys_;
549 T key_iter_;
550
551 };
552
555
558
559 // Returns a vector of names
560 std::vector<std::string> getNames() const {
561 std::vector<std::string> result;
562 for(ParameterPairs::value_type const & pair : keys_){
563 result.push_back(pair.first);
564 }
565 return result;
566 }
567
568 iterator begin() {
569 ParameterPairs::iterator itr = keys_.begin();
570 return iterator((const ParameterPairs*)&keys_, itr);
571 }
572
573 iterator end() {
574 ParameterPairs::iterator itr = keys_.end();
575 return iterator((const ParameterPairs*)&keys_, itr);
576 }
577
578 const_iterator begin() const {
579 ParameterPairs::const_iterator itr = keys_.begin();
580 return const_iterator((const ParameterPairs*)&keys_, itr);
581 }
582
583 const_iterator end() const {
584 ParameterPairs::const_iterator itr = keys_.end();
585 return const_iterator((const ParameterPairs*)&keys_, itr);
586 }
587
588 size_t getNumParameters() const {
589 return keys_.size();
590 }
591
604
620
621 protected:
622
630
639 virtual void onAddingChild_(TreeNode* child) override;
640
646 virtual void onAddedAsChild_() noexcept override;
647
656
665
671
689 const ParameterTree* pt,
691
696
701
702 private:
703
710 std::vector<const ParameterBase *> locking_params_stack_;
711
716 OneWayBool<false> populated_from_virtual_;
717
718 }; // class ParameterSet
719
720} // namespace sparta
721
741#define PARAMETER(type, name, def, doc) \
742 sparta::Parameter<type> name {#name, def, doc, __this_ps};
743
744#define LOCKED_PARAMETER(type, name, def, doc) \
745 sparta::Parameter<type> name {#name, def, doc, sparta::Parameter<type>::ParameterAttribute::LOCKED, __this_ps};
746
747#define VOLATILE_LOCKED_PARAMETER(type, name, def, doc) \
748 sparta::Parameter<type> name {#name, def, doc, sparta::Parameter<type>::ParameterAttribute::LOCKED, __this_ps, true};
749
750#define HIDDEN_PARAMETER(type, name, def, doc) \
751 sparta::Parameter<type> name {#name, def, doc, sparta::Parameter<type>::ParameterAttribute::HIDDEN, __this_ps};
752
753#define VOLATILE_HIDDEN_PARAMETER(type, name, def, doc) \
754 sparta::Parameter<type> name {#name, def, doc, sparta::Parameter<type>::ParameterAttribute::HIDDEN, __this_ps, true};
755
761#define VOLATILE_PARAMETER(type, name, def, doc) \
762 sparta::Parameter<type> name {#name, def, doc, __this_ps, true};
763
774#define PARAMETER_CTORDEFAULT(type, name, doc) \
775 class _Parameter_##name : public sparta::Parameter<type> \
776 { \
777 public: \
778 typedef type value_type; \
779 \
780 /* construction with no default is disallowed */ \
781 _Parameter_##name() = delete; \
782 \
783 /* construction with new default value */ \
784 _Parameter_##name(ParameterSet* ps, type default_value) : \
785 sparta::Parameter<type>(#name, default_value, doc) \
786 { \
787 sparta_assert(ps, "Must construct Parameter " #name " with valid ParameterSet"); \
788 this->addToSet_(ps); \
789 } \
790 \
791 void operator=(const value_type& v) { \
792 sparta::Parameter<value_type>::operator=(v); \
793 /*return *this;*/ \
794 } \
795 }; \
796 _Parameter_##name name; // No construction args suppled. Must be explicitly done by containing class
797
799inline std::ostream& operator<< (std::ostream& out, sparta::ParameterSet const & ps){
800 out << ps.stringize(true); // pretty
801 return out;
802}
803
804inline std::ostream& operator<< (std::ostream& out, sparta::ParameterSet const * ps){
805 out << ps->stringize(true); // pretty
806 return out;
807}
Individual Parameter interface base class, container class, and global helpers methods.
#define sparta_assert(...)
Simple variadic assertion that will throw a sparta_exception if the condition fails.
Basic Node framework in sparta device tree composite pattern.
static TypeToTypeNameMap GBL_type_name_map
Map of internal typeid names to C++ names.
Definition KeyValue.hpp:87
Boolean with a default capable of being changed to the opposite value only. it can never set to the d...
Definition Utils.hpp:355
Non-templated base class for generic parameter access and iteration.
const T getValueAs() const
Gets the value of this ParameterBase as a templated type T if this parameter actually contains a valu...
virtual bool isVisibilityAllowed() const =0
Query if this parameter is safe to be displayed via prints, dumps. A parameter should not be displaye...
virtual std::string getDefaultAsString() const =0
Gets the default value of this Parameter as a string.
uint32_t getReadCount() const
Number of times this Parameter has been read after initialization or after the last write (or explici...
virtual std::string getValueAsString() const =0
Gets the current value of this Parameter as a string.
virtual const std::string getTypeName() const =0
Gets the compiler-independent readable type string of the value currently held.
Exception indicating a misconfigured Parameter or invalid Parameter access.
Definition Parameter.hpp:58
Non-const iterator for ParameterSet.
Generic container of Parameters.
virtual void onAddedAsChild_() noexcept override
When added to the tree after construction, try and pull values for paraemters. Finalize the Parameter...
ParameterBase * getParameter(const std::string &name, bool must_exist=true)
Gets a TreeNode by exact path relative to this node.
ParameterSet()=delete
Default constructor disabled.
void readValuesFromVirtualTree_()
Read values for every parameter of possible from the virtual parameter tree if possible.
void lock(const ParameterBase *lock_param)
Lock the parameter set for parameter to parameter updates.
void resetWriteCounts()
Reset the write-count on all Parameters in this set.
std::unordered_map< std::string, ParameterBase * > ParameterPairs
Mapping of parameter names to parameters (for fast lookup by name)
static constexpr char PARAMETER_SET_NODE_TAG[]
Tag added to ParameterSet nodes.
const T getParameterValueAs(const std::string &name) const
Finds a parameter and gets its value as the templated type.
void addParameter_(sparta::ParameterBase *p)
Add a parameter to the parameter set. \temp This will be removed.
uint32_t readAllParamValuesFromVirtualTree()
Read values for all parameters from the virtual tree and re-write them to the parameters the way SPAR...
void operator=(const ParameterSet &rhp)=delete
Copying disabled. Do not override.
ParameterSetIterator< ParameterPairs::const_iterator > const_iterator
Const iterator.
bool readValueFromVirtualTree_(const ParameterTree *arch_pt, const ParameterTree *pt, sparta::ParameterBase *p)
Read a value for a single parameter from the virtual tree and write it to the selected parameter....
uint32_t readVolatileParamValuesFromVirtualTree()
Read values for each volatile parameter from the virtual tree and re-write them to the parameters the...
const ParameterBase * getParameter(const std::string &name, bool must_exist=true) const
Const qualified variant of getParameter.
static constexpr char NODE_NAME[]
Name of any ParameterSet TreeNode.
ParameterVector params_
Straight vector of registered parameters.
bool hasParameter(const std::string &name) const
Determines whether this ParameterSet has the parameter with the given name.
virtual std::string dumpList() const
Print out a friendly set of parameters.
bool canParameterBeModifiedByLockingParam(const ParameterBase *modify_e)
Determine if the given parameter can be modified by a parameter currently writing to the parameter se...
bool isLocked() const
Is the parameter set currently locked by another parameter.
bool hasModificationPermission(const ParameterBase *modifying_param, std::vector< const ParameterBase * > params) const
Determine if the given parameter can safely modify the given list of parameters.
const ParameterTree * getSimArchParameterTree_()
Find the virtual architectural parameter tree for this node's tree from its root.
uint32_t findParameters(const std::string &name, std::vector< ParameterBase * > &results)
virtual ~ParameterSet()=default
Destructor.
void ignoreAll() const
Increments the read count of each Parameter in this set.
ParameterPairs keys_
Map of name (key) to ParameterBase* instances.
ParameterSet(TreeNode *parent)
Constructor.
std::vector< sparta::ParameterBase * > ParameterVector
Vector of ParameterBase pointers.
const ParameterTree * getSimParameterTree_()
Find the virtual parameter tree for this node's tree from its root.
ParameterSet * __this_ps
Pointer to this ParameterSet accessible in class declaration scope. This is used By parameters to att...
ParameterSetIterator< ParameterPairs::iterator > iterator
Non-const iterator.
const Parameter< ContentT > & getParameterAs(const std::string &name) const
Retrieves a sparta::Parameter<ContentT> reference from this parameter set.
virtual std::string stringize(bool pretty=false) const override
Create a string representation of this node.
ParameterSet(const ParameterSet &rhp)=delete
Copying disabled. Do not override.
virtual void onAddingChild_(TreeNode *child) override
React to child registration.
static uint32_t getNumBoundTypes()
Gets the number of bound types.
void verifyAllRead() const
Checks the read-count on all Parameters. If any have no been read at least once since last write (sin...
void unlock(const ParameterBase *unlock_param)
Unlock the parameter set for parameter to parameter updates.
void resetReadCounts()
Reset the read-count on all Parameters in this set.
Virtual Parameter Tree. This represents a tree of parameters read from some source but does not neces...
Parameter instance, templated to contain only a specific type.
TreePhase getPhase() const
Gets the trees current phase.
@ TREE_FINALIZING
Tree is being finalized, but has not completed (maybe errors?)
Used to construct and throw a standard C++ exception. Inherits from std::exception.
Node in a composite tree representing a sparta Tree item.
Definition TreeNode.hpp:205
static const group_idx_type GROUP_IDX_NONE
GroupIndex indicating that a node has no group index because it belongs to no group.
Definition TreeNode.hpp:303
std::string getLocation() const override final
static constexpr char GROUP_NAME_BUILTIN[]
Reserved name for built-in nodes.
Definition TreeNode.hpp:370
void addChild(TreeNode *child, bool inherit_phase=true)
Adds a TreeNode to this node as a child.
const std::string & getName() const override
Gets the name of this node.
void addTag(const std::string &tag)
Adds single tag to this node.
uint32_t findChildren(const std::string &pattern, std::vector< TreeNode * > &results, std::vector< std::vector< std::string > > &replacements)
Finds all children starting at this node with a given pattern relative to this node by matching names...
Macros for handling exponential backoff.
uint32_t numDecDigits(uint32_t val)
Gets number of decimal digits in a uint32_t.
std::ostream & operator<<(std::ostream &o, const SimulationInfo &info)
ostream insertion operator for SimulationInfo
std::string demangle(const std::string &name) noexcept
Demangles a C++ symbol.
Definition Utils.hpp:203