20#include "sparta/collection/BitBucket.hpp"
21#include "sparta/pipeViewer/transaction_structures.hpp"
25#include "sparta/pairs/SpartaKeyPairs.hpp"
26#include "sparta/utils/Utils.hpp"
27#include "sparta/utils/MetaStructs.hpp"
29#include "boost/numeric/conversion/converter.hpp"
36 std::true_type derives_from_pair_definition_(
const sparta::PairDefinition<U>*);
37 std::false_type derives_from_pair_definition_(...);
41 typename T::SpartaPairDefinitionType;
42 requires decltype(derives_from_pair_definition_(
43 std::declval<typename T::SpartaPairDefinitionType*>()))::value;
48 std::is_trivial_v<T> &&
49 std::is_standard_layout_v<T> &&
54 std::is_same_v<std::decay_t<T>,
const char*>;
58 simdb::type_traits::is_pod_convertible_v<T> &&
72 template <
typename DataT, SchedulingPhase collection_phase = SchedulingPhase::Collection>
76 using ValueType = MetaStruct::remove_any_pointer_t<DataT>;
86 const std::string& name,
87 const std::string& group,
89 uint64_t parentid = 0,
90 const std::string & desc =
"Collectable <manual, no desc>") :
93 ev_close_record_(&
event_set_, name +
"_pipeline_collectable_close_event",
107 const std::string& name,
108 const DataT * collected_object,
109 uint64_t parentid = 0,
110 const std::string & desc =
"Collectable <no desc>") :
120 if(collected_object) {
133 const std::string& name,
134 uint64_t parentid = 0,
135 const std::string & desc =
"Collectable <manual, no desc>") :
154 template <
typename T>
155 requires MetaStruct::is_any_pointer_v<T>
171 template <
typename T>
172 requires MetaStruct::is_any_pointer_v<T>
201 template <
typename T>
202 requires MetaStruct::is_any_pointer_v<T>
255 entry_point_ = argos_collector->createScalarCollector(loc, clk_name, type);
257 auto tiny_strings = argos_collector->getTinyStrings();
258 auto enum_inspector = argos_collector->getEnumInspector();
259 auto bit_bucket = std::make_shared<CollectableBitBucket>(tiny_strings, enum_inspector);
264 virtual void setBitBucket(
const std::shared_ptr<BitBucket>& bit_bucket) {
289 "Collectables can only added to PipelineCollectors... for now");
335 #define INHERIT_COMMON_INTERFACE \
336 using ValueType = typename CollectableCommon<DataT, collection_phase>::ValueType; \
337 using CollectableCommon<DataT, collection_phase>::CollectableCommon; \
338 using CollectableCommon<DataT, collection_phase>::initialize; \
339 using CollectableCommon<DataT, collection_phase>::collect; \
340 using CollectableCommon<DataT, collection_phase>::collectWithDuration; \
341 using CollectableCommon<DataT, collection_phase>::closeRecord; \
342 using CollectableCommon<DataT, collection_phase>::setManualCollection; \
343 using CollectableCommon<DataT, collection_phase>::getEventSet_; \
344 using CollectableCommon<DataT, collection_phase>::bit_bucket_; \
345 using CollectableCommon<DataT, collection_phase>::entry_point_;
349 template<
typename DataT, SchedulingPhase collection_phase = SchedulingPhase::Collection,
typename =
void>
353 INHERIT_COMMON_INTERFACE
360 void performCollection_(
const ValueType &)
override final {
366 template<
typename DataT, SchedulingPhase collection_phase>
367 requires use_raw_type<MetaStruct::remove_any_pointer_t<DataT>>
368 class Collectable<DataT, collection_phase, void>
369 :
public CollectableCommon<DataT, collection_phase>
372 INHERIT_COMMON_INTERFACE
375 auto type = simdb::demangle_type<ValueType>();
376 if constexpr (std::is_enum_v<ValueType>) {
377 if (human_readable) {
378 using underlying_t = std::underlying_type_t<ValueType>;
379 type +=
" (enum: " + simdb::demangle_type<underlying_t>() +
")";
386 void performCollection_(
const ValueType & val)
override final {
387 constexpr auto dummy_field_id = 0u;
398 template<
typename DataT, SchedulingPhase collection_phase>
399 requires use_tiny_strings<MetaStruct::remove_any_pointer_t<DataT>>
400 class Collectable<DataT, collection_phase, void>
401 :
public CollectableCommon<DataT, collection_phase>
404 INHERIT_COMMON_INTERFACE
411 void performCollection_(
const ValueType & val)
override final {
412 constexpr auto dummy_field_id = 0u;
423 template<
typename DataT, SchedulingPhase collection_phase>
424 requires use_cast_operator<MetaStruct::remove_any_pointer_t<DataT>>
425 class Collectable<DataT, collection_phase, void>
426 :
public CollectableCommon<DataT, collection_phase>
429 INHERIT_COMMON_INTERFACE
432 using converted_t = simdb::type_traits::pod_convertible_t<ValueType>;
433 auto type = simdb::demangle_type<converted_t>();
434 if (human_readable) {
435 type +=
" (built-in type using cast operator)";
441 void performCollection_(
const ValueType & val)
override final {
442 constexpr auto dummy_field_id = 0u;
443 using converted_t = simdb::type_traits::pod_convertible_t<ValueType>;
444 auto converted_val =
static_cast<converted_t
>(val);
445 bit_bucket_->writeField(converted_val, dummy_field_id);
456 template<
typename DataT, SchedulingPhase collection_phase>
457 requires use_dynamic_fields<MetaStruct::remove_any_pointer_t<DataT>>
458 class Collectable<DataT, collection_phase, void>
459 :
public CollectableCommon<DataT, collection_phase>
462 INHERIT_COMMON_INTERFACE
465 auto type = std::string(
"dynamic");
466 if (human_readable) {
467 type +=
" (" + simdb::demangle_type<ValueType>() +
")";
473 std::ostringstream oss;
474 oss <<
"Collecting non-trivial classes using operator<< only is not supported for now. Use PairDefinition.\n";
476 oss <<
" - type: " << simdb::demangle_type<MetaStruct::remove_any_pointer_t<DataT>>() <<
" (scalar)";
477 argos_collector->postNotif(oss.str(), simdb::argos::NotifType::WARNING);
484 void performCollection_(
const ValueType &)
override final {
489 template<
typename DataT, SchedulingPhase collection_phase>
490 requires use_pair_definition<MetaStruct::remove_any_pointer_t<DataT>>
493 ,
public PairCollector<typename MetaStruct::remove_any_pointer_t<DataT>::SpartaPairDefinitionType>
496 INHERIT_COMMON_INTERFACE
499 auto type = simdb::demangle_type<ValueType>();
500 if (human_readable) {
501 type +=
" (using PairDefinition)";
509 simdb::DatabaseManager* db_mgr,
510 std::set<std::string>& serialized_types)
override final
513 if(serialized_types.count(root_dtype)) {
517 const int32_t schema_id =
518 db_mgr->INSERT(SQL_TABLE(
"DataTypeSchemas"), SQL_VALUES(root_dtype))->getId();
520 using PairDef =
typename ValueType::SpartaPairDefinitionType;
522 sparta::PairCache pair_cache;
523 pair_def.finalizeKeys(&pair_cache);
525 const auto & names = pair_cache.getNameStrings();
526 const auto & dtypes = pair_def.getLeafArgosDtypeStrings();
527 const auto & formatters = pair_cache.getFormatVector();
531 std::vector<std::string> format_strings;
532 for(
size_t i = 0; i < formatters.size(); ++i) {
534 switch(formatters[i]) {
535 case PairFormatter::HEX:
536 fmt_str =
"HEX";
break;
537 case PairFormatter::OCTAL:
538 fmt_str =
"OCT";
break;
541 format_strings.push_back(fmt_str);
544 bool verbose =
false;
546 verbose = sim->getSimulationConfiguration()->simdb_config.verboseMode();
550 std::cout <<
"\nSerializing PairDefinition to database for '" << root_dtype <<
"'...\n";
552 for(
size_t i = 0; i < names.size(); ++i) {
554 std::cout <<
"\t" << names[i] <<
", " << dtypes[i];
555 if (!format_strings[i].empty()) {
556 std::cout <<
" (" << format_strings[i] <<
")";
561 db_mgr->INSERT(SQL_TABLE(
"DataTypeNodes"),
562 SQL_VALUES(schema_id,
567 serialized_types.insert(root_dtype);
570 void setBitBucket(
const std::shared_ptr<BitBucket>& bit_bucket)
override final {
572 setBitBucket_(bit_bucket);
582 std::ostringstream ss;
583 for(
const auto & pairs : this->getPEventLogVector()){
584 ss << pairs.first <<
"(" << pairs.second <<
") ";
590 typedef typename ValueType::SpartaPairDefinitionType PairDef_t;
591 using PairCollector<PairDef_t>::collect_;
592 using PairCollector<PairDef_t>::setBitBucket_;
594 void performCollection_(
const ValueType & val)
override final {
605 void generateCollectionString_()
override {}
File that defines the EventSet class.
File that defines the PayloadEvent class.
Class to facilitate pipeline collection operations.
File that defines the phases used in simulation.
Simulation setup base class.
#define sparta_assert(...)
Simple variadic assertion that will throw a sparta_exception if the condition fails.
#define SPARTA_EXPECT_FALSE(x)
A macro for hinting to the compiler a particular condition should be considered most likely false.
#define CREATE_SPARTA_HANDLER_WITH_DATA(clname, meth, dataT)
Set of Events that a unit (or sparta::TreeNode, sparta::Resource) contains and are visible through a ...
Class to schedule a Scheduleable in the future with a payload, typed on both the data type and the sc...
ScheduleableHandle preparePayload(const DataT &payload)
Prepare a Scheduleable Payload for scheduling either now or later.
void schedule()
Schedule this event with its pre-set delay using the pre-set Clock.
Used to construct and throw a standard C++ exception. Inherits from std::exception.
Node in a composite tree representing a sparta Tree item.
app::Simulation * getSimulation() const
Gets the simulation (if any) associated with this tree.
static const group_idx_type GROUP_IDX_NONE
GroupIndex indicating that a node has no group index because it belongs to no group.
std::string getLocation() const override final
static constexpr char GROUP_NAME_NONE[]
Group name indicating that a node belongs to no group.
const Clock * getClock() override
Walks up parents (starting with self) until a parent with an associated local clock is found,...
BitBucket implementation for Collectable objects (whether "standalone" or inside an IterableCollector...
void writeTo(simdb::argos::EntryPoint *entry_point) override final
Called when using a standalone Collectable.
Common code for all Collectable implementations below.
void setCollecting_(bool collect, Collector *collector) override
std::vector< char > initial_bytes_
void createSimDbEntryPoint(simdb::argos::ArgosCollector *argos_collector) override
Collectable classes must be able to register themselves with the ArgosCollector.
void collect() override final
CollectableCommon(sparta::TreeNode *parent, const std::string &name, const std::string &group, uint32_t index, uint64_t parentid=0, const std::string &desc="Collectable <manual, no desc>")
Construct the Collectable, no data object associated, part of a group.
bool auto_collect_
Should we auto-collect?
const DataT * collected_object_
The annotation object to be collected.
CollectableCommon(sparta::TreeNode *parent, const std::string &name, const DataT *collected_object, uint64_t parentid=0, const std::string &desc="Collectable <no desc>")
Construct the Collectable.
std::shared_ptr< BitBucket > bit_bucket_
CollectableCommon(sparta::TreeNode *parent, const std::string &name, uint64_t parentid=0, const std::string &desc="Collectable <manual, no desc>")
Construct the Collectable, no data object associated.
sparta::EventSet event_set_
virtual void setBitBucket(const std::shared_ptr< BitBucket > &bit_bucket)
Set the BitBucket (byte buffers for SimDB EntryPoint)
void setManualCollection()
Do not perform any automatic collection The SchedulingPhase is ignored.
void collectWithDuration(const ValueType &val, sparta::Clock::Cycle duration)
Explicitly collect a value for the given duration.
PipelineCollector * pipeline_col_
Ze Collec-tor.
EventSet & getEventSet_()
Get a reference to the internal event set.
void collect(const ValueType &val)
virtual void performCollection_(const ValueType &val)=0
Subclasses are responsible for collecting values and writing the bytes.
virtual ~CollectableCommon()
Virtual destructor – does nothing.
void collectWithDuration(sparta::Clock::Cycle duration)
Calls collectWithDuration using the internal collected_object_ specified at construction.
void initialize(const ValueType &val)
For manual collection, provide an initial value.
void closeRecord(const bool &=false) override final
An abstract type of TreeNode that has virtual calls to start collection on this node,...
virtual std::string encodeCollectedType(bool human_readable=false) const =0
Encode the collected data type in a way Argos python deserializers will understand:
simdb::argos::EntryPoint * entry_point_
Entry point into the SimDB collection system.
bool isCollected() const
Determine whether or not this node has collection turned on or off.
bool isIterableCollectorBin() const
Check if this CollectableTreeNode is a Collectable inside an IterableCollector.
void setBitBucket(const std::shared_ptr< BitBucket > &bit_bucket) override final
Set the BitBucket (byte buffers for SimDB EntryPoint)
void createSimDbEntryPoint(simdb::argos::ArgosCollector *argos_collector) override final
Collectable classes must be able to register themselves with the ArgosCollector.
std::string dumpNameValuePairs(const DataT &val)
Strictly a Debug/Testing API. Never to be called in real modeler's code.
void serializeStructSchema(simdb::DatabaseManager *db_mgr, std::set< std::string > &serialized_types) override final
INHERIT_COMMON_INTERFACE std::string encodeCollectedType(bool human_readable=false) const override final
Encode the collected data type in a way Argos python deserializers will understand:
INHERIT_COMMON_INTERFACE std::string encodeCollectedType(bool=false) const override final
Encode the collected data type in a way Argos python deserializers will understand:
INHERIT_COMMON_INTERFACE std::string encodeCollectedType(bool=false) const override final
Encode the collected data type in a way Argos python deserializers will understand:
A non-templated base class that all Collectors should inherit from.
A class that facilitates all universal pipeline collection operations such as outputting finalized re...
void removeFromAutoCollection(CollectableTreeNode *ctn)
Remove the given CollectableTreeNode from collection.
void addToAutoCollection(CollectableTreeNode *ctn, SchedulingPhase collection_phase=SchedulingPhase::Tick)
Add the CollectableTreeNode to auto collection.
Macros for handling exponential backoff.
T * notNull(T *p)
Ensures that a pointer is not null.
static constexpr bool value
Test to see what happens when we invoke.