12#ifndef SST_CORE_SERIALIZATION_OBJECTMAP_H
13#define SST_CORE_SERIALIZATION_OBJECTMAP_H
15#include "sst/core/from_string.h"
16#include "sst/core/warnmacros.h"
43namespace SST::Core::Serialization {
49 bool operator()(
const std::string& a,
const std::string& b)
const
54 if ( isdigit(a[0]) && isdigit(b[0]) ) {
57 unsigned long long na = strtoull(a.c_str(), &ea, 10);
58 if ( *ea ==
'\0' && errno == 0 ) {
60 unsigned long long nb = strtoull(b.c_str(), &eb, 10);
61 if ( *eb ==
'\0' && errno == 0 )
return na < nb;
64 return std::less<>()(a, b);
72using ObjectMultimap = std::multimap<std::string, ObjectMap*, ObjectMultimapCmp>;
117class ObjectMapComparison
120 enum class Op : std::uint8_t { LT, LTE, GT, GTE, EQ, NEQ, CHANGED, INVALID };
122 static Op getOperationFromString(
const std::string& op)
124 if ( op ==
"<" )
return Op::LT;
125 if ( op ==
"<=" )
return Op::LTE;
126 if ( op ==
">" )
return Op::GT;
127 if ( op ==
">=" )
return Op::GTE;
128 if ( op ==
"==" )
return Op::EQ;
129 if ( op ==
"!=" )
return Op::NEQ;
130 if ( op ==
"changed" )
return Op::CHANGED;
134 static std::string getStringFromOp(Op op)
158 ObjectMapComparison() =
default;
160 explicit ObjectMapComparison(
const std::string& name) :
164 ObjectMapComparison(
const std::string& name,
ObjectMap* obj) :
169 virtual ~ObjectMapComparison() =
default;
170 virtual bool compare() = 0;
171 virtual std::string getCurrentValue()
const = 0;
172 virtual void print(std::ostream& stream)
const = 0;
173 virtual void* getVar()
const = 0;
174 const std::string& getName()
const {
return name_; }
177 std::string name_ =
"";
211 ObjectCategory category_ = ObjectCategory::Generic;
225 virtual void set_impl(
const std::string& UNUSED(value)) {}
246 size_t refCount_ = 1;
276 virtual bool checkValue(
const std::string& UNUSED(value))
const {
return false; }
328 static ObjectMultimap emptyVars;
348 if ( !--refCount_ )
delete this;
358 ObjectCategory getCategory()
const {
return category_; }
359 void setCategory(ObjectCategory cat) { category_ = cat; }
366 const std::string& UNUSED(name), ObjectMapComparison::Op UNUSED(op),
const std::string& UNUSED(value))
const
371 virtual ObjectMapComparison* getComparisonVar(
const std::string& UNUSED(name), ObjectMapComparison::Op UNUSED(op),
372 const std::string& UNUSED(name2),
ObjectMap* UNUSED(var2))
const
374 printf(
"In virtual ObjectMapComparison\n");
378 virtual ObjectBuffer* getObjectBuffer(
const std::string& UNUSED(name),
size_t UNUSED(sz)) {
return nullptr; }
433 virtual std::string
get()
const {
return ""; }
447 void set(
const std::string& value)
463 virtual std::string
get(
const std::string& var);
483 virtual void set(
const std::string& var,
const std::string& value,
bool& found,
bool& read_only);
540 virtual std::string
listVariable(std::string name,
bool& found,
int recurse = 0);
553 virtual std::string
list(
int recurse = 0);
589 void activate(
ObjectMap* parent,
const std::string& name)
615 std::string listRecursive(
const std::string& name,
int level,
int recurse);
621std::ostream& dumpObjectMap(std::ostream& os,
const ObjectMap& obj,
size_t indent = 0);
624operator<<(std::ostream& os,
const ObjectMap& obj)
626 return dumpObjectMap(os, obj);
655 for (
const auto& [name, child] :
variables_ )
656 if ( child !=
nullptr ) child->decRefCount();
697 for (
const auto& [name, child] :
variables_ )
698 if ( child !=
nullptr ) child->refresh();
731 std::string
getType()
const override {
return ""; }
739 void*
getAddr()
const override {
return nullptr; }
812template <
class T1,
class T2,
class =
void>
813constexpr bool have_common_type_v =
false;
815template <
class T1,
class T2>
816constexpr bool have_common_type_v<T1, T2, std::void_t<std::common_type_t<T1, T2>>> =
true;
819template <
class T,
class =
void>
820constexpr bool is_ordered_v =
false;
823constexpr bool is_ordered_v<T, std::void_t<
decltype(T {} < T {})>> =
true;
827template <
typename T1,
typename T2>
828std::enable_if_t<have_common_type_v<T1, T2>,
bool>
829cmp(T1 t1, ObjectMapComparison::Op op, T2 t2)
831 using T = std::common_type_t<T1, T2>;
833 case ObjectMapComparison::Op::LT:
834 if constexpr ( is_ordered_v<T> )
835 return static_cast<T
>(t1) <
static_cast<T
>(t2);
838 case ObjectMapComparison::Op::LTE:
839 if constexpr ( is_ordered_v<T> )
840 return static_cast<T
>(t1) <=
static_cast<T
>(t2);
843 case ObjectMapComparison::Op::GT:
844 if constexpr ( is_ordered_v<T> )
845 return static_cast<T
>(t1) >
static_cast<T
>(t2);
848 case ObjectMapComparison::Op::GTE:
849 if constexpr ( is_ordered_v<T> )
850 return static_cast<T
>(t1) >=
static_cast<T
>(t2);
853 case ObjectMapComparison::Op::EQ:
854 return static_cast<T
>(t1) ==
static_cast<T
>(t2);
855 case ObjectMapComparison::Op::NEQ:
856 case ObjectMapComparison::Op::CHANGED:
857 return static_cast<T
>(t1) !=
static_cast<T
>(t2);
859 std::cout <<
"Invalid comparison operator\n";
865template <
typename T1,
typename T2>
866std::enable_if_t<!have_common_type_v<T1, T2>,
bool>
867cmp(T1 UNUSED(t1), ObjectMapComparison::Op UNUSED(op), T2 UNUSED(t2))
870 printf(
"ERROR: cmp() does not support comparison of two types without a std::common_type\n");
877template <
typename T,
typename REF = T>
878class ObjectMapComparison_impl :
public ObjectMapComparison
881 ObjectMapComparison_impl(
const std::string& name, REF* var, Op op,
const std::string& value) :
882 ObjectMapComparison(name),
886 if ( op_ == Op::CHANGED ) {
888 comp_value_ =
static_cast<T
>(*var_);
892 comp_value_ = SST::Core::from_string<T>(value);
896 bool compare()
override
899 bool ret = cmp(*var_, op_, comp_value_);
902 if ( op_ == Op::CHANGED ) comp_value_ =
static_cast<T
>(*var_);
907 std::string getCurrentValue()
const override {
return SST::Core::to_string(*var_); }
909 void* getVar()
const override {
return var_; }
911 void print(std::ostream& stream)
const override
913 stream << name_ <<
" " << getStringFromOp(op_);
914 if ( op_ == Op::CHANGED )
917 stream <<
" " << SST::Core::to_string(comp_value_) <<
" ";
929template <
typename T1,
typename T2>
930class ObjectMapComparison_var :
public ObjectMapComparison
933 ObjectMapComparison_var(
const std::string& name1, T1* var1, Op op,
const std::string& name2, T2* var2) :
934 ObjectMapComparison(name1),
941 bool compare()
override
945 return cmp(v1, op_, v2);
948 std::string getCurrentValue()
const override
950 return SST::Core::to_string(*var1_) +
" " + SST::Core::to_string(*var2_);
953 void* getVar()
const override {
return var1_; }
955 void print(std::ostream& stream)
const override
957 stream << name_ <<
" " << getStringFromOp(op_);
958 if ( op_ == Op::CHANGED )
961 stream <<
" " << name2_ <<
" ";
965 std::string
const name2_;
974 ObjectBuffer(
const std::string& name,
size_t sz) :
979 virtual ~ObjectBuffer() =
default;
981 virtual void sample(
size_t index,
bool trigger) = 0;
982 virtual std::string get(
size_t index)
const = 0;
983 virtual std::string getTriggerVal()
const = 0;
985 std::string getName()
const {
return name_; }
986 size_t getBufSize()
const {
return bufSize_; }
993template <
typename T,
typename REF = T>
994class ObjectBuffer_impl :
public ObjectBuffer
997 ObjectBuffer_impl(
const std::string& name, REF* varPtr,
size_t sz) :
998 ObjectBuffer(name, sz),
1001 objectBuffer_.resize(sz);
1004 void sample(
size_t index,
bool trigger)
override
1006 objectBuffer_[index] = *varPtr_;
1007 if ( trigger ) triggerVal = *varPtr_;
1010 std::string get(
size_t index)
const override {
return SST::Core::to_string(objectBuffer_.at(index)); }
1012 std::string getTriggerVal()
const override {
return SST::Core::to_string(triggerVal); }
1016 std::vector<T> objectBuffer_;
1029 tagBuffer_.resize(bufSize_);
1030 cycleBuffer_.resize(bufSize_);
1031 handlerBuffer_.resize(bufSize_);
1034 virtual ~TraceBuffer() =
default;
1036 void setBufferReset() { reset_ =
true; }
1038 void resetTraceBuffer()
1050 size_t getBufferSize() {
return bufSize_; }
1054 objBuffers_.push_back(vb);
1058 enum BufferState :
int {
1065 const std::map<BufferState, char> state2char { { CLEAR,
'-' }, { TRIGGER,
'!' }, { POSTTRIGGER,
'+' },
1068 bool sampleT(
bool trigger, uint64_t cycle,
const std::string& handler)
1070 size_t start_state = state_;
1071 bool invokeAction =
false;
1075 if ( start_state == CLEAR ) {
1082 if ( start_state == TRIGGER || start_state == POSTTRIGGER ) {
1083 state_ = POSTTRIGGER;
1087 if ( !(state_ == POSTTRIGGER && postCount_ >= postDelay_) ) {
1089#ifdef _OBJMAP_DEBUG_
1090 std::cout <<
" Sample:" << handler <<
": numRecs:" << numRecs_ <<
" first:" << first_ <<
" cur:" << cur_
1091 <<
" state:" << state2char.at(state_) <<
" isOverrun:" << isOverrun_
1092 <<
" samplesLost:" << samplesLost_ << std::endl;
1094 cycleBuffer_[cur_] = cycle;
1095 handlerBuffer_[cur_] = handler;
1097 triggerCycle = cycle;
1102 for (
size_t obj = 0; obj < numObjects; obj++ ) {
1103 varBuffer_ = objBuffers_[obj];
1104 varBuffer_->sample(cur_, trigger);
1107 if ( numRecs_ < bufSize_ ) {
1108 tagBuffer_[cur_] = state_;
1110 cur_ = (cur_ + 1) % bufSize_;
1111 if ( cur_ == 0 ) first_ = 0;
1115 if ( tagBuffer_[cur_] == TRIGGER ) {
1119 tagBuffer_[cur_] = state_;
1121 cur_ = (cur_ + 1) % bufSize_;
1130 if ( (state_ == TRIGGER) && (postDelay_ == 0) ) {
1131 invokeAction =
true;
1134 if ( state_ == POSTTRIGGER ) {
1136 if ( postCount_ >= postDelay_ ) {
1137 invokeAction =
true;
1141 return invokeAction;
1144 void dumpTraceBufferT()
1146 if ( numRecs_ == 0 )
return;
1160 for (
int j = start;; j++ ) {
1161 size_t i = j % bufSize_;
1163 std::cout <<
"buf[" << i <<
"] " << handlerBuffer_.at(i) <<
" @" << cycleBuffer_.at(i) <<
" ("
1164 << state2char.at(tagBuffer_.at(i)) <<
") ";
1166 for (
size_t obj = 0; obj < numObjects; obj++ ) {
1168 std::cout << SST::Core::to_string(varBuffer_->getName()) <<
"=" << varBuffer_->get(i) <<
" ";
1178 void dumpTriggerRecord()
1180 std::stringstream ss;
1181 if ( numRecs_ == 0 ) {
1182 std::cout <<
"No trace samples in current buffer" << std::endl;
1185 if ( state_ != CLEAR ) {
1186 ss <<
"LastTriggerRecord:@cycle" << triggerCycle <<
": SamplesLost=" << samplesLost_ <<
": ";
1187 for (
size_t obj = 0; obj < numObjects; obj++ ) {
1189 ss << SST::Core::to_string(varBuffer_->getName()) <<
"=" << varBuffer_->getTriggerVal() <<
" ";
1192 std::cout << ss.str();
1196 void printVars(std::stringstream& ss)
1198 for (
size_t obj = 0; obj < numObjects; obj++ ) {
1200 ss << SST::Core::to_string(varBuffer_->getName()) <<
" ";
1204 void printConfig(std::stringstream& ss)
1206 ss <<
"bufsize = " << bufSize_ <<
" postDelay = " << postDelay_ <<
" : ";
1212 size_t bufSize_ = 64;
1213 size_t postDelay_ = 8;
1214 size_t postCount_ = 0;
1217 size_t numRecs_ = 0;
1218 bool isOverrun_ =
false;
1219 size_t samplesLost_ = 0;
1220 bool reset_ =
false;
1221 BufferState state_ = CLEAR;
1223 size_t numObjects = 0;
1224 std::vector<BufferState> tagBuffer_;
1225 std::vector<std::string> handlerBuffer_;
1226 std::vector<ObjectBuffer*> objBuffers_;
1227 std::vector<uint64_t> cycleBuffer_;
1228 uint64_t triggerCycle;
1245template <
typename T,
typename REF = T>
1261 virtual void set_impl(
const std::string& value)
override
1264 *
addr_ = SST::Core::from_string<T>(value);
1266 catch (
const std::exception& e ) {
1267 std::cerr << e.what() <<
": " << value << std::endl;
1271 bool checkValue(
const std::string& value)
const override
1275 T v = SST::Core::from_string<T>(value);
1278 catch (
const std::exception& e ) {
1279 std::cerr << e.what() <<
": " << value << std::endl;
1287 std::string
get()
const override {
return addr_ ? SST::Core::to_string(
static_cast<T
>(*
addr_)) :
"nullptr"; }
1320 ObjectMapFundamental& operator=(
const ObjectMapFundamental&) =
delete;
1331 const std::string& name, ObjectMapComparison::Op op,
const std::string& value)
const override
1336 ObjectMapComparison* getComparisonVar(
const std::string& name, ObjectMapComparison::Op UNUSED(op),
1337 const std::string& name2,
ObjectMap* var2)
const override
1341 printf(
"Triggers can only use fundamental types; %s is not fundamental\n", name2.c_str());
1345 std::string type = var2->
getType();
1347 std::cout <<
"In ObjectMapComparison_var: " << name <<
" " << name2 << std::endl;
1349 std::string type1 =
getType();
1350 std::cout <<
"getType(v1): " << type1 << std::endl;
1351 std::cout <<
"getType(v2): " << type << std::endl;
1356 if constexpr ( std::is_arithmetic_v<T> ) {
1421 std::cout <<
"Invalid type for comparison: " << name2 <<
"(" << type <<
")\n";
1425 ObjectBuffer* getObjectBuffer(
const std::string& name,
size_t sz)
override
1427 return new ObjectBuffer_impl<T, REF>(name,
addr_, sz);
1432template <
typename T>
1433ObjectMap* ObjectMapSerialization(T&& obj);
1445 explicit ObjectMapContainer(T* addr) :
1454 for (
const auto& [name, child] :
variables_ )
1455 if ( child !=
nullptr ) child->decRefCount();
1461 variables_ = std::move(
dynamic_cast<ObjectMapContainer&
>(*ObjectMapSerialization(*addr_)).
variables_);
1473template <
typename T,
typename REF,
typename PTYPE = T>
1474class ObjectMapFundamentalReference :
public ObjectMapFundamental<T, REF>
1478 static_assert(std::is_copy_constructible_v<REF> && std::is_convertible_v<REF, T> && std::is_assignable_v<REF, T>,
1479 "ObjectMapFundamentalReference<T, REF, PTYPE>: REF must be copyable, implicitly convertible to T, and "
1480 "assignable from T.");
1484 explicit ObjectMapFundamentalReference(
const REF& ref) :
1485 ObjectMapFundamental<T, REF>(std::addressof(this->ref)),
1496 ObjTreeCont* buildTreeNode(
const std::string& name)
override;
1502#include "sst/core/serialization/objectMapTreeBuilder.h"
Main component object for the simulation.
Definition component.h:32
The Object Tree (ObjTree) is intended to be a developer friendly interface to SST’s existing serializ...
Definition ObjTreeLeaves.h:41
Definition objectMap.h:972
void * getAddr() const override
Get the address of the represented object.
Definition objectMap.h:806
std::string type_
Type of the variable as given by the demangled version of typeid(T).name() for the type.
Definition objectMap.h:753
ObjectMapClass(const ObjectMapClass &)=delete
Disallow copying and assignment.
std::string getType() const override
Get the type of the represented object.
Definition objectMap.h:799
ObjectMapClass(void *addr, const std::string &type)
Constructor.
Definition objectMap.h:780
void * addr_
Address of the variable for reading and writing.
Definition objectMap.h:758
~ObjectMapClass() override=default
Destructor.
ObjectMapClass()=default
Default constructor.
Template implementation of ObjectMapComparison for <op> .
Definition objectMap.h:879
Template implementation of ObjectMapComparison for <op> .
Definition objectMap.h:931
Base class for interacting with data from ObjectMap.
Definition objectMap.h:118
Class used to map containers.
Definition objectMap.h:1440
void refresh() override
Refresh the ObjectMap, reconstructing children.
Definition objectMap.h:1451
std::string getType() const override
Get the type of the variable represented by the ObjectMap.
Definition objectMap.h:1449
bool isContainer() const final override
Check to see if this ObjectMap represents a container.
Definition objectMap.h:1448
void * getAddr() const override
Get the address of the variable represented by the ObjectMap.
Definition objectMap.h:1450
Definition objectMap.h:1475
std::string getType() const override
Return the type represented by this ObjectMap as given by the demangled version of typeid(T)....
Definition objectMap.h:1490
ObjectMap representing fundamental types, and classes treated as fundamental types.
Definition objectMap.h:1247
std::string getType() const override
Return the type represented by this ObjectMap as given by the demangled version of typeid(T)....
Definition objectMap.h:1328
REF * addr_
Address of the variable for reading and writing.
Definition objectMap.h:1252
void * getAddr() const override
Get the address of the variable represented by the ObjectMap.
Definition objectMap.h:1301
std::string get() const override
Get the value of the object as a string.
Definition objectMap.h:1287
virtual void set_impl(const std::string &value) override
Set the value of the object represented as a string.
Definition objectMap.h:1261
bool isFundamental() const final override
Returns true as object is a fundamental.
Definition objectMap.h:1294
ObjectMapFundamental(const ObjectMapFundamental &)=delete
Disallow copying and assignment.
~ObjectMapFundamental() override=default
Destructor.
ObjectMapHierarchyOnly()=default
Default constructor.
~ObjectMapHierarchyOnly() override=default
Destructor.
std::string getType() const override
Returns empty string since there is no underlying object being represented.
Definition objectMap.h:731
void * getAddr() const override
Returns nullptr since there is no underlying object being represented.
Definition objectMap.h:739
const ObjectMultimap & getVariables() const final override
Get the list of child variables contained in this ObjectMap.
Definition objectMap.h:689
ObjectMapWithChildren()=default
Default constructor.
~ObjectMapWithChildren() override
Destructor.
Definition objectMap.h:653
void addVariable(const std::string &name, ObjectMap *obj) final override
Adds a variable to this ObjectMap.
Definition objectMap.h:673
void refresh() override
Refresh the children.
Definition objectMap.h:695
void removeVariable(const std::string &name) final override
Removes a variable from this ObjectMap.
Definition objectMap.h:680
ObjectMultimap variables_
Map that child ObjectMaps are stored in.
Definition objectMap.h:639
ObjectMapWithChildren(const ObjectMapWithChildren &)=delete
Disallow copying and assignment.
Base class for objects created by the serializer mapping mode used to map the variables for objects.
Definition objectMap.h:189
ObjectMap()=default
Default constructor primarily used for the "top" object in the hierarchy.
bool isReadOnly() const
Check to see if this object is read-only.
Definition objectMap.h:259
virtual std::string get() const
Get the value of the variable as a string.
Definition objectMap.h:433
virtual void removeVariable(const std::string &UNUSED(name))
Removes a variable from this ObjectMap.
Definition objectMap.h:421
size_t getRefCount() const
Get the current reference count.
Definition objectMap.h:356
virtual const ObjectMultimap & getVariables() const
Get the list of child variables contained in this ObjectMap.
Definition objectMap.h:320
bool read_only_
Indicates whether or not the variable is read-only.
Definition objectMap.h:217
virtual std::string listVariable(std::string name, bool &found, int recurse=0)
Create a string that lists information for the specified variable.
Definition objectMap.cc:168
std::string getFullName() const
Get the full hierarchical name of the variable represented by this ObjectMap, based on the path taken...
Definition objectMap.cc:23
virtual SST::Core::Serialization::ObjTreeCont * buildTreeNode(const std::string &UNUSED(name))
Helper function to build an ObjTreeCont representation of this ObjectMap, if the subclass has type-sp...
Definition objectMap.h:578
ObjectMap(const ObjectMap &)=delete
Disallow copying and assignment.
std::string getName() const
Get the name of the variable represented by this ObjectMap.
Definition objectMap.h:286
virtual std::string list(int recurse=0)
Create a string that lists information for the current object.
Definition objectMap.cc:192
virtual ObjectMapComparison * getComparison(const std::string &UNUSED(name), ObjectMapComparison::Op UNUSED(op), const std::string &UNUSED(value)) const
Get a watch point for this object.
Definition objectMap.h:365
virtual std::string getType() const =0
Get the type of the variable represented by the ObjectMap.
ObjectMap * selectVariable(std::string name, bool &loop_detected, bool confirm=false)
Get the ObjectMap for the specified variable.
Definition objectMap.cc:50
virtual void addVariable(const std::string &UNUSED(name), ObjectMap *UNUSED(obj))
Adds a variable to this ObjectMap.
Definition objectMap.h:412
virtual ~ObjectMap()=default
Destructor.
void incRefCount()
Increment the reference counter for this ObjectMap.
Definition objectMap.h:338
virtual bool checkValue(const std::string &UNUSED(value)) const
Check if value string is valid for this type.
Definition objectMap.h:276
virtual bool isContainer() const
Check to see if this ObjectMap represents a container.
Definition objectMap.h:500
void set(const std::string &value)
Sets the value of the variable represented by the ObjectMap to the specified value,...
Definition objectMap.h:447
virtual void refresh()
Refresh the ObjectMap, reconstructing children.
Definition objectMap.h:569
ObjectMap * findVariable(const std::string &name, bool confirm=false) const
Find a variable in this object map.
Definition objectMap.cc:228
virtual void deactivate_callback()
Function that will get called when this object is deactivated (i.e selectParent() is called).
Definition objectMap.h:236
virtual bool isFundamental() const
Check to see if this ObjectMap represents a fundamental or a class treated as a fundamental.
Definition objectMap.h:492
virtual void set_impl(const std::string &UNUSED(value))
Function implemented by derived classes to implement set().
Definition objectMap.h:225
virtual void activate_callback()
Function that will get called when this object is selected.
Definition objectMap.h:230
static std::string demangle_name(const char *name)
Static function to demangle type names returned from typeid(T).name().
Definition objectMap.cc:152
void decRefCount()
Decrement the reference counter for this ObjectMap.
Definition objectMap.h:346
ObjectMap * selectParent()
Get the parent for this ObjectMap.
Definition objectMap.cc:38
void setReadOnly(bool state=true)
Set the read-only state of the object.
Definition objectMap.h:269
virtual void * getAddr() const =0
Get the address of the variable represented by the ObjectMap.
ObjectMapMetaData * mdata_
Metadata object for walking the object hierarchy.
Definition objectMap.h:210
Definition objectMap.h:1021
Module is a tag class used with the loadModule function.
Definition module.h:26
SubComponent is a class loadable through the factory which allows dynamic functionality to be added t...
Definition subcomponent.h:29
Definition objectMap.h:48