The Sparta Modeling Framework
Loading...
Searching...
No Matches
IterableCollector.hpp
1// <IterableCollector.hpp> -*- C++ -*-
2
3/*
4 */
5
6#pragma once
7
8#include <memory>
9#include <sstream>
10#include <string>
11#include <vector>
12#include <iterator>
13#include <type_traits>
14#include "sparta/utils/Utils.hpp"
15#include "sparta/log/MessageSource.hpp"
20
21namespace sparta {
22namespace collection {
23
68template <typename IterableType, SchedulingPhase collection_phase = SchedulingPhase::Collection, bool sparse_array_type = false>
70{
71public:
72 typedef typename IterableType::size_type size_type;
73
85 const std::string & name,
86 const std::string & group,
87 const uint32_t index,
88 const std::string & desc,
89 const IterableType * iterable,
90 const size_type expected_capacity) :
91 CollectableTreeNode(parent, name, group, index, desc),
92 iterable_object_(iterable),
93 expected_capacity_(expected_capacity),
94 event_set_(this),
95 ev_close_record_(&event_set_, name + "_pipeline_collectable_close_event",
97 {
98 for (size_type i = 0; i < expected_capacity_; ++i)
99 {
100 std::stringstream name_str;
101 name_str << name << i;
102 positions_.emplace_back(new CollectableT(this, name_str.str(), group, i));
103 }
104 }
105
106
118 const std::string & name,
119 const std::string & group,
120 const uint32_t index,
121 const std::string & desc,
122 const IterableType & iterable,
123 const size_type expected_capacity) :
124 IterableCollector(parent, name, group, index, desc, &iterable, expected_capacity)
125 {}
126
136 const std::string & name,
137 const std::string & desc,
138 const IterableType * iterable,
139 const size_type expected_capacity) :
140 IterableCollector(parent, name, name, 0, desc, iterable, expected_capacity)
141 {}
142
152 const std::string & name,
153 const std::string & desc,
154 const IterableType & iterable,
155 const size_type expected_capacity) :
156 IterableCollector(parent, name, name, 0, desc, &iterable, expected_capacity)
157 {}
158
167 const std::string & name,
168 const IterableType * iterable,
169 const size_type expected_capacity) :
170 IterableCollector (parent, name, name + " Iterable Collector",
171 iterable, expected_capacity)
172 {
173 // Delegated constructor
174 }
175
184 const std::string & name,
185 const IterableType & iterable,
186 const size_type expected_capacity) :
187 IterableCollector (parent, name, name + " Iterable Collector",
188 &iterable, expected_capacity)
189 {
190 // Delegated constructor
191 }
192
200 const std::string & name,
201 const size_type expected_capacity) :
202 IterableCollector (parent, name, name + " Iterable Collector",
203 nullptr, expected_capacity)
204 {
205 // Can't auto collect without setting iterable_object_
207 }
208
213 void collect(const IterableType * iterable_object)
214 {
215 // If pointer has become nullified, close the records
216 if(nullptr == iterable_object) {
217 closeRecord();
218 }
220 {
221 if(SPARTA_EXPECT_FALSE(iterable_object->size() > expected_capacity_))
222 {
223 if(SPARTA_EXPECT_FALSE(warn_on_size_))
224 {
226 << "WARNING! The collected object '"
227 << getLocation() << "' has grown beyond the "
228 << "expected capacity (given at construction) for collection. "
229 << "Expected " << expected_capacity_ << " but grew to "
230 << iterable_object->size()
231 << " This is your first and last warning.";
232 warn_on_size_ = false;
233 }
234 }
235 collectImpl_(iterable_object, std::integral_constant<bool, sparse_array_type>());
236 }
237 }
238
240 void collect() override {
241 collect(iterable_object_);
242 }
243
247 void closeRecord(const bool & simulation_ending = false) override {
248 for (size_type i = 0; i < positions_.size(); ++i) {
249 positions_[i]->closeRecord(simulation_ending);
250 }
251 }
252
254 void scheduleCloseRecord(sparta::Clock::Cycle cycle) {
256 ev_close_record_.preparePayload(false)->schedule(cycle);
257 }
258 }
259
263 auto_collect_ = false;
264 }
265
268 void collectWithDuration(sparta::Clock::Cycle duration) {
270 collect();
271 if(duration != 0) {
272 ev_close_record_.preparePayload(false)->schedule(duration);
273 }
274 }
275 }
276
278 void reattach(const IterableType * obj) {
279 iterable_object_ = obj;
280 }
281
282private:
284 // Standard walk of iterable types
285 void collectImpl_(const IterableType * iterable_object, std::false_type)
286 {
287 sparta_assert(nullptr != iterable_object,
288 "Can't collect iterable_object because it's a nullptr! How did we get here?");
289 auto itr = iterable_object->begin();
290 auto eitr = iterable_object->end();
291 for (uint32_t i = 0; i < expected_capacity_; ++i)
292 {
293 if (itr != eitr) {
294 positions_[i]->collect(*itr);
295 ++itr;
296 } else {
297 positions_[i]->closeRecord();
298 }
299 }
300 }
301
302 // Full iteration walk, checking validity of the iterator. This
303 // is used for Pipe and Array where the iterator points to valid
304 // and not valid entries in the component
305 void collectImpl_(const IterableType * iterable_object, std::true_type)
306 {
307 sparta_assert(nullptr != iterable_object,
308 "Can't collect iterable_object because it's a nullptr! How did we get here?");
309 uint32_t s = 0;
310 auto itr = iterable_object->begin();
311 for (uint32_t i = 0; i < expected_capacity_; ++i, ++s)
312 {
313 if (itr.isValid()) {
314 positions_[i]->collect(*itr);
315 } else {
316 positions_[i]->closeRecord();
317 }
318 ++itr;
319 }
320 }
321
324 void setCollecting_(bool collect, Collector * collector) override
325 {
326 PipelineCollector * pipeline_col = dynamic_cast<PipelineCollector *>(collector);
327 sparta_assert(pipeline_col != nullptr);
328
329 if(collect && auto_collect_) {
330 // Add this Collectable to the PipelineCollector's
331 // list of objects requiring collection
332 pipeline_col->addToAutoCollection(this, collection_phase);
333 }
334 else {
335 closeRecord();
336 }
337 }
338
339 const IterableType * iterable_object_;
340 std::vector<std::unique_ptr<CollectableT>> positions_;
341 const size_type expected_capacity_ = 0;
342 bool auto_collect_ = true;
343 bool warn_on_size_ = true;
344
345 // For those folks that want a value to automatically
346 // disappear in the future
347 sparta::EventSet event_set_;
349
350};
351} // namespace collection
352} // namespace sparta
define a CollectableTreeNode type TreeNode.
Implementation of the Collectable class that allows a user to collect an object into an pipeViewer pi...
Class to facilitate pipeline collection operations.
File that defines the phases used in simulation.
#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 ...
Definition EventSet.hpp:26
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.
Node in a composite tree representing a sparta Tree item.
Definition TreeNode.hpp:205
std::string getLocation() const override final
An abstract type of TreeNode that has virtual calls to start collection on this node,...
bool isCollected() const
Determine whether or not this node has collection turned on or off.
Class used to either manually or auto-collect an Annotation String object in a pipeline database.
A collector of any iterable type (std::vector, std::list, sparta::Buffer, etc)
void reattach(const IterableType *obj)
Reattach to a new iterable object (used for moves)
void collect(const IterableType *iterable_object)
void setManualCollection()
Do not perform any automatic collection The SchedulingPhase is ignored.
void closeRecord(const bool &simulation_ending=false) override
void scheduleCloseRecord(sparta::Clock::Cycle cycle)
Schedule event to close all records for this iterable type.
IterableCollector(TreeNode *parent, const std::string &name, const std::string &desc, const IterableType &iterable, const size_type expected_capacity)
constructor
IterableCollector(TreeNode *parent, const std::string &name, const IterableType &iterable, const size_type expected_capacity)
constructor with no description
void collect() override
Collect the contents of the associated iterable object.
IterableCollector(TreeNode *parent, const std::string &name, const IterableType *iterable, const size_type expected_capacity)
constructor with no description
IterableCollector(TreeNode *parent, const std::string &name, const std::string &group, const uint32_t index, const std::string &desc, const IterableType *iterable, const size_type expected_capacity)
constructor
IterableCollector(TreeNode *parent, const std::string &name, const std::string &group, const uint32_t index, const std::string &desc, const IterableType &iterable, const size_type expected_capacity)
constructor
void collectWithDuration(sparta::Clock::Cycle duration)
Perform a collection, then close the records in the future.
IterableCollector(TreeNode *parent, const std::string &name, const size_type expected_capacity)
constructor with no iterable object associated
IterableCollector(TreeNode *parent, const std::string &name, const std::string &desc, const IterableType *iterable, const size_type expected_capacity)
constructor
static MessageSource & getGlobalWarn()
Gets the global warning logger. These messages can be picked up by placing a Tap on the sparta::TreeN...
Macros for handling exponential backoff.