19#ifndef HEDGEHOG_CORE_STATE_MANAGER_H_
20#define HEDGEHOG_CORE_STATE_MANAGER_H_
25#include "../../tools/traits.h"
26#include "../../tools/concepts.h"
27#include "../../tools/meta_functions.h"
29#include "../abstractions/base/cleanable_abstraction.h"
30#include "../abstractions/base/copyable_abstraction.h"
31#include "../abstractions/base/can_terminate_abstraction.h"
32#include "../abstractions/node/task_inputs_management_abstraction.h"
33#include "../abstractions/node/task_outputs_management_abstraction.h"
34#include "../implementors/concrete_implementor/multi_queue_receivers.h"
35#include "../implementors/concrete_implementor/default_multi_executes.h"
36#include "../../behavior/input_output/state_sender.h"
41#ifndef DOXYGEN_SHOULD_SKIP_THIS
45template<
size_t Separator,
class ...AllTypes>
51template<
size_t Separator,
class ...AllTypes>
59template<
size_t Separator,
class ...AllTypes>
60using TIM = tool::TaskInputsManagementAbstractionTypeDeducer_t
64template<
size_t Separator,
class ...AllTypes>
65using TOM = tool::TaskOutputsManagementAbstractionTypeDeducer_t
71template<
size_t Separator,
class ...AllTypes>
78 public TIM<Separator, AllTypes...>,
79 public TOM<Separator, AllTypes...> {
96 :
CoreStateManager<Separator, AllTypes...>(stateManager, state,
"AbstractState Manager", false) {}
111 TIM<Separator, AllTypes...>(
113 std::make_shared<implementor::DefaultSlot>(),
114 std::make_shared<tool::MultiQueueReceiversTypeDeducer_t<tool::Inputs<Separator, AllTypes...>>>(),
115 std::make_shared<
hh::tool::DefaultMultiExecutesTypeDeducer_t<tool::Inputs<Separator, AllTypes...>>>(
119 TOM<Separator, AllTypes...>(),
137 template<
class ConcreteMultiReceivers,
class ConcreteMultiExecutes,
class ConcreteMultiSenders>
141 std::shared_ptr<implementor::ImplementorSlot>
const &concreteSlot,
142 std::shared_ptr<ConcreteMultiReceivers> concreteMultiReceivers,
143 std::shared_ptr<ConcreteMultiExecutes> concreteMultiExecutes,
144 std::shared_ptr<implementor::ImplementorNotifier>
const &concreteNotifier,
145 std::shared_ptr<ConcreteMultiSenders> concreteMultiSenders) :
150 TIM<Separator, AllTypes...>(this, concreteSlot, concreteMultiReceivers, concreteMultiExecutes),
151 TOM<Separator, AllTypes...>(concreteNotifier, concreteMultiSenders),
168 if (lock) { this->lockSlotMutex(); }
170 if (lock) { this->unlockSlotMutex(); }
185 [[nodiscard]] std::vector<std::pair<std::string const, std::string const>>
ids()
const override {
186 return {{this->
id(), this->
id()}};
226 using Indices = std::make_index_sequence<std::tuple_size_v<Outputs_t>>;
228 std::chrono::time_point<std::chrono::system_clock>
237 start = std::chrono::system_clock::now();
240 this->callAllExecuteWithNullptr();
241 emptyReadyLists<Outputs_t>(indices);
242 state_->stateManager(
nullptr);
244 finish = std::chrono::system_clock::now();
251 start = std::chrono::system_clock::now();
252 volatile bool canTerminate = this->
wait();
253 finish = std::chrono::system_clock::now();
257 if (canTerminate) {
break; }
260 start = std::chrono::system_clock::now();
263 this->operateReceivers();
264 emptyReadyLists<Outputs_t>(indices);
265 state_->stateManager(
nullptr);
267 finish = std::chrono::system_clock::now();
282 this->notifyAllTerminated();
298 [[nodiscard]] std::shared_ptr<AbstractMemoryManager>
memoryManager()
const override {
306 this->
nvtxProfiler()->startRangeWaiting(this->totalNumberElementsReceived());
307 std::unique_lock<std::mutex> lock(*(this->mutex()));
308 this->slotConditionVariable()->wait(
310 [
this]() {
return !this->receiversEmpty() || this->
callCanTerminate(
false); }
319 void gatherCleanable(std::unordered_set<hh::behavior::Cleanable *> &cleanableSet)
override {
320 CleanableAbstraction::gatherCleanable(cleanableSet);
327 template<
class Outputs_t,
size_t ...Indexes>
329 (emptyReadyLists<std::tuple_element_t<Indexes, Outputs_t>>(), ...);
334 template<
class Output>
336 auto &rdyList = std::static_pointer_cast<behavior::StateSender<Output>>(
state_)->readyList();
337 std::shared_ptr<Output> data =
nullptr;
338 while (!rdyList->empty()) {
339 data = rdyList->front();
341 this->sendAndNotify(data);
348 std::shared_ptr<abstraction::NodeAbstraction>
clone(
349 [[maybe_unused]] std::map<
NodeAbstraction *, std::shared_ptr<NodeAbstraction>> &correspondenceMap)
override {
352 return clone->core();
358 this->duplicateOutputEdges(mapping);
typename internals::Splitter< delta, Types... >::Inputs Inputs
Helper getting the input types from a list of template types (variadic)
typename internals::Splitter< delta, Types... >::Outputs Outputs
Helper getting the output types from a list of template types (variadic)
tool::TaskOutputsManagementAbstractionTypeDeducer_t< tool::Outputs< Separator, AllTypes... > > TOM
Type alias for an TaskOutputsManagementAbstraction from the list of template parameters.
tool::TaskInputsManagementAbstractionTypeDeducer_t< tool::Inputs< Separator, AllTypes... > > TIM
Type alias for an TaskInputsManagementAbstraction from the list of template parameters.
Printer abstraction to get a snapshot of the metrics of the Hedgehog graph.
bool registerNode(core::abstraction::NodeAbstraction const *nodeAbstraction)
Register a visited node.
virtual void printNodeInformation(core::abstraction::NodeAbstraction const *node)=0
Print node information.
virtual std::string extraPrintingInformation() const
Print extra information for the task.
virtual void initialize()
initialize step for the task
virtual void shutdown()
shutdown step for the task
std::shared_ptr< AbstractMemoryManager > const & memoryManager() const
Memory manager accessor.
Abstraction for core that present termination condition.
bool callNodeCanTerminate() const
Call user-definable termination.
CanTerminateAbstraction(behavior::CanTerminate *const canTerminateNode)
Constructor using behavior::CanTerminate node abstraction.
Abstraction for cleanable core.
CleanableAbstraction()=default
Constructor used by the CoreGraph to have the handles to clean inner cleanable nodes.
Core abstraction for clonable nodes, nodes duplicated by execution pipeline.
Core abstraction for copyable nodes.
CopyableAbstraction(CopyableNode *const copyableNode)
Constructor using a node abstraction.
std::shared_ptr< CopyableNode > callCopy()
Interface to call user-defined copy method.
virtual std::string id() const
Core's id ('x' + address of abstraction) as string.
NodeAbstraction(std::string name)
Core node constructor using the core's name.
void incrementExecutionDuration(std::chrono::nanoseconds const &exec)
Increment execution duration.
std::string const & name() const
Accessor to the core's name.
virtual int deviceId() const
Get the device identifier (got from belonging graph)
Task core abstraction used to define some method for task-like behaving cores like CoreExecutionPipel...
void incrementWaitDuration(std::chrono::nanoseconds const &wait)
Increment the wait duration.
void setInitialized()
Set the task as initialized.
TaskNodeAbstraction(std::string const &name, behavior::Node *node)
Create the abstraction with the node's name.
std::shared_ptr< NvtxProfiler > const & nvtxProfiler() const
Accessor to the NVTX profiler attached to the node.
bool isActive() const
Accessor to task status.
AbstractState manager core.
CoreStateManager(StateManager< Separator, AllTypes... > *const stateManager, std::shared_ptr< AbstractState< Separator, AllTypes... > > const &state, std::string const &name, bool const automaticStart, std::shared_ptr< implementor::ImplementorSlot > const &concreteSlot, std::shared_ptr< ConcreteMultiReceivers > concreteMultiReceivers, std::shared_ptr< ConcreteMultiExecutes > concreteMultiExecutes, std::shared_ptr< implementor::ImplementorNotifier > const &concreteNotifier, std::shared_ptr< ConcreteMultiSenders > concreteMultiSenders)
Construct a state manager from the state manager and its concrete abstraction's implementations.
void preRun() override
Initialize the state manager.
void duplicateEdge(std::map< NodeAbstraction *, std::shared_ptr< NodeAbstraction > > &mapping) override
Duplicate the state manager edge.
bool wait()
Wait statement when the node is alive and no input data are available.
bool hasMemoryManagerAttached() const override
Test if a memory manager is attached.
std::shared_ptr< AbstractMemoryManager > memoryManager() const override
Accessor to the memory manager.
bool automaticStart() const
Accessor to the automatic start flag.
bool const automaticStart_
Flag for automatic start.
void emptyReadyLists(std::index_sequence< Indexes... >)
Interface method to call emptyReadyLists for a type when decomposing types from a tuple.
void run() override
Main core state manager logic.
std::string extraPrintingInformation() const override
Accessor to user-defined extra information for the state-manager.
void visit(Printer *printer) override
Visit the state manager.
void postRun() override
Post run logic, shutdown the state manager, notify successor nodes of state manager termination.
std::shared_ptr< abstraction::NodeAbstraction > clone(std::map< NodeAbstraction *, std::shared_ptr< NodeAbstraction > > &correspondenceMap) override
Clone method, to duplicate a state manager when it is part of another graph in an execution pipeline.
~CoreStateManager() override=default
Default destructor.
StateManager< Separator, AllTypes... > *const stateManager_
User defined state manager.
bool callCanTerminate(bool lock) override
Call user-definable termination.
void gatherCleanable(std::unordered_set< hh::behavior::Cleanable * > &cleanableSet) override
Gather the state manager and the state into the cleanableSet.
void emptyReadyLists()
Empty the ready list for a type.
CoreStateManager(StateManager< Separator, AllTypes... > *const stateManager, std::shared_ptr< AbstractState< Separator, AllTypes... > > const &state)
Construct a state manager from the user state manager and its state.
std::shared_ptr< AbstractState< Separator, AllTypes... > > const state_
Managed state.
std::vector< std::pair< std::string const, std::string const > > ids() const override
Node ids [nodeId, nodeGroupId] accessor.
CoreStateManager(StateManager< Separator, AllTypes... > *const stateManager, std::shared_ptr< AbstractState< Separator, AllTypes... > > const &state, std::string const &name, bool const automaticStart)
Construct a state manager from the user state manager, its state, a name and the automatic start flag...