31#ifndef DW_FRAMEWORK_SIMPLENODE_HPP_
32#define DW_FRAMEWORK_SIMPLENODE_HPP_
34#include <dw/core/base/Types.h>
46#include <dwshared/dwfoundation/dw/core/container/BaseString.hpp>
47#include <dwshared/dwfoundation/dw/core/container/HashContainer.hpp>
48#include <dwshared/dwfoundation/dw/core/container/VectorFixed.hpp>
49#include <dwshared/dwfoundation/dw/core/language/Function.hpp>
63 size_t maxInputPortCount_,
64 size_t maxOutputPortCount_,
76template <
typename NodeT>
81 portSize<NodeT, PortDirection::INPUT>(),
82 portSize<NodeT, PortDirection::OUTPUT>(),
95 throw ExceptionWithStatus(DW_NOT_IMPLEMENTED,
"SimpleNode::reset() not implemented");
118 throw ExceptionWithStatus(DW_NOT_IMPLEMENTED,
"SimpleNode::validate() not implemented");
134 dwStatus
getPasses(VectorFixed<
Pass*>& passList, dwProcessorType processorType) override;
150 template <typename Func, typename PortList>
153 for (
auto& elem : portList)
159 template <
typename Func>
163 if (elem.second.get() ==
nullptr)
165 const char* nodeName{nullptr};
166 this->getName(&nodeName);
167 throw ExceptionWithStatus(DW_NOT_INITIALIZED,
"SimpleNode: input port not initialized, node ", nodeName,
", port id ", elem.first);
173 template <
typename Func>
176 iteratePorts(m_outputPorts, [&func,
this](
decltype(m_outputPorts)::TElement& elem) {
177 if (elem.second.get() ==
nullptr)
179 const char* nodeName{nullptr};
180 this->getName(&nodeName);
181 throw ExceptionWithStatus(DW_NOT_INITIALIZED,
"SimpleNode: output port not initialized, node ", nodeName,
", port id ", elem.first);
187 template <
typename ModuleHandle_t>
190 dwModuleHandle_t moduleHandle;
192 if (DW_NULL_HANDLE == handle)
194 return DW_INVALID_ARGUMENT;
197 dwStatus ret{getModuleHandle(&moduleHandle, handle, context)};
198 if (DW_SUCCESS != ret)
203 return setObjectHandle(moduleHandle);
215 dwStatus
getModuleHandle(dwModuleHandle_t* moduleHandle,
void* handle, dwContextHandle_t context);
225 typename NodeT,
size_t PassIndex,
typename PassFunctionT>
226 void registerPass(PassFunctionT func, std::initializer_list<std::pair<dwStatus, uint32_t>>
const& returnMapping = {})
229 if (!isValidPass<NodeT>(PassIndex))
231 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"registerPass called with an invalid pass id: ", PassIndex);
234 if (m_passList.size() == 0U || m_passList.size() - 1U < PassIndex)
237 m_passList.resize(PassIndex + 1U);
240 if (m_passList[PassIndex] !=
nullptr)
242 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"registerPass called with a pass id which has been added before: ", PassIndex);
244 dwProcessorType processorType{passProcessorType<NodeT, PassIndex>()};
246 m_passList[PassIndex] = std::make_unique<PassImpl<PassFunctionT>>(*
this, passName<NodeT, PassIndex>(), func, processorType, returnMapping);
254 typename NodeT,
size_t PassIndex,
typename PassFunctionT>
255 void registerPass(PassFunctionT func, cudaStream_t
const cudaStream, std::initializer_list<std::pair<dwStatus, uint32_t>>
const& returnMapping = {})
257 static_assert(passProcessorType<NodeT, PassIndex>() == DW_PROCESSOR_TYPE_GPU,
"The processor type of a pass with a cuda stream must be GPU");
258 registerPass<NodeT, PassIndex>(func, returnMapping);
259 m_passList[PassIndex]->m_cudaStream =
cudaStream;
293 return m_healthSignal;
297 VectorFixed<std::unique_ptr<Pass>> m_passList;
298 FixedString<MAX_NAME_LEN> m_name;
299 bool m_setupTeardownCreated;
305 dwModuleHandle_t m_object;
306 uint32_t m_iterationCount{};
307 uint32_t m_nodePeriod{};
314 template <
typename NodeT,
size_t PortIndex,
typename... Args>
317 static_assert(PortIndex < portSize<NodeT, PortDirection::INPUT>(),
"Invalid port index");
318 using DataType =
decltype(portType<NodeT, PortDirection::INPUT, PortIndex>());
319 auto port = std::make_shared<ManagedPortInput<DataType>>(portName<NodeT, PortDirection::INPUT, PortIndex>(), std::forward<Args>(args)...);
320 if (m_inputPorts.find(PortIndex) != m_inputPorts.end())
322 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"Input port with the following id registered multiple times: ", PortIndex);
324 m_inputPorts[PortIndex] = port;
334 template <
typename NodeT,
size_t PortIndex,
typename... Args>
337 static_assert(PortIndex < portSize<NodeT, PortDirection::INPUT>(),
"Invalid port index");
338 constexpr size_t arraySize = descriptorPortSize<NodeT, PortDirection::INPUT, descriptorIndex<NodeT, PortDirection::INPUT, PortIndex>()>();
339 for (
size_t i = 0; i < arraySize; ++i)
341 initInputArrayPort<NodeT, PortIndex>(i, std::forward<Args>(args)...);
351 template <
typename NodeT,
size_t PortIndex,
typename... Args>
354 static_assert(PortIndex < portSize<NodeT, PortDirection::INPUT>(),
"Invalid port index");
355 using DataType =
decltype(portType<NodeT, PortDirection::INPUT, PortIndex>());
356 if (arrayIndex >=
descriptorPortSize<NodeT, PortDirection::INPUT, descriptorIndex<NodeT, PortDirection::INPUT, PortIndex>()>())
358 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"Invalid array index ", arrayIndex,
" for array input port ", PortIndex);
360 auto port = std::make_shared<ManagedPortInput<DataType>>(portName<NodeT, PortDirection::INPUT, PortIndex>(), std::forward<Args>(args)...);
361 if (m_inputPorts.find(PortIndex + arrayIndex) != m_inputPorts.end())
363 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"Input port with the following id registered multiple times: ", PortIndex + arrayIndex);
365 m_inputPorts[PortIndex + arrayIndex] = port;
372 template <
typename NodeT,
size_t PortIndex,
typename... Args>
375 static_assert(PortIndex - portSize<NodeT, PortDirection::INPUT>() < portSize<NodeT, PortDirection::OUTPUT>(),
"Invalid port index");
376 using DataType =
decltype(portType<NodeT, PortDirection::OUTPUT, PortIndex>());
377 std::shared_ptr<ManagedPortOutput<DataType>> port{std::make_shared<ManagedPortOutput<DataType>>(portName<NodeT, PortDirection::OUTPUT, PortIndex>(), std::forward<Args>(args)...)};
378 if (m_outputPorts.find(PortIndex) != m_outputPorts.end())
380 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"Output port with the following id registered multiple times: ", PortIndex);
382 m_outputPorts[PortIndex] = port;
392 template <
typename NodeT,
size_t PortIndex,
typename... Args>
395 static_assert(PortIndex - portSize<NodeT, PortDirection::INPUT>() < portSize<NodeT, PortDirection::OUTPUT>(),
"Invalid port index");
396 constexpr size_t arraySize{descriptorPortSize<NodeT, PortDirection::OUTPUT, descriptorIndex<NodeT, PortDirection::OUTPUT, PortIndex>()>()};
397 for (
size_t i{0U}; i < arraySize; ++i)
399 initOutputArrayPort<NodeT, PortIndex>(i, std::forward<Args>(args)...);
409 template <
typename NodeT,
size_t PortIndex,
typename... Args>
412 static_assert(PortIndex - portSize<NodeT, PortDirection::INPUT>() < portSize<NodeT, PortDirection::OUTPUT>(),
"Invalid port index");
413 using DataType =
decltype(portType<NodeT, PortDirection::OUTPUT, PortIndex>());
414 if (arrayIndex >=
descriptorPortSize<NodeT, PortDirection::OUTPUT, descriptorIndex<NodeT, PortDirection::OUTPUT, PortIndex>()>())
416 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"Invalid array index ", arrayIndex,
" for array output port ", PortIndex);
418 std::shared_ptr<ManagedPortOutput<DataType>> port{std::make_shared<ManagedPortOutput<DataType>>(portName<NodeT, PortDirection::OUTPUT, PortIndex>(), std::forward<Args>(args)...)};
419 if (m_outputPorts.find(PortIndex + arrayIndex) != m_outputPorts.end())
421 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"Output port with the following id registered multiple times: ", PortIndex + arrayIndex);
423 m_outputPorts[PortIndex + arrayIndex] = port;
427 template <
typename NodeT,
size_t PortIndex>
430 static_assert(PortIndex < portSize<NodeT, PortDirection::INPUT>(),
"Invalid port index");
432 NodeT, PortDirection::INPUT, descriptorIndex<NodeT, PortDirection::INPUT, PortIndex>()>();
433 static_assert(!isArray,
"Input port is an array, must pass an array index");
434 if (m_inputPorts.find(PortIndex) == m_inputPorts.end())
436 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"Input port with the following id not registered: ", PortIndex);
438 using DataType =
decltype(portType<NodeT, PortDirection::INPUT, PortIndex>());
440 using ReturnType = std::shared_ptr<PointerType>;
441 ReturnType port = std::dynamic_pointer_cast<PointerType>(m_inputPorts[PortIndex]);
444 throw ExceptionWithStatus(DW_BAD_CAST,
"Failed to cast the following input port to its declared type: ", PortIndex);
450 template <
typename NodeT,
size_t PortIndex>
453 static_assert(PortIndex < portSize<NodeT, PortDirection::INPUT>(),
"Invalid port index");
454 constexpr bool isArray = descriptorPortArray<NodeT, PortDirection::INPUT, descriptorIndex<NodeT, PortDirection::INPUT, PortIndex>()>();
455 static_assert(isArray,
"Input port is not an array, must not pass an array index");
456 constexpr size_t arraySize = descriptorPortSize<NodeT, PortDirection::INPUT, descriptorIndex<NodeT, PortDirection::INPUT, PortIndex>()>();
457 if (arrayIndex >= arraySize)
459 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"The array index is out of bound: ", arrayIndex);
461 if (m_inputPorts.find(PortIndex + arrayIndex) == m_inputPorts.end())
463 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"Input port with the following id not registered: ", PortIndex + arrayIndex);
465 using DataType =
decltype(portType<NodeT, PortDirection::INPUT, PortIndex>());
467 using ReturnType = std::shared_ptr<PointerType>;
468 ReturnType port = std::dynamic_pointer_cast<PointerType>(m_inputPorts[PortIndex + arrayIndex]);
471 throw ExceptionWithStatus(DW_BAD_CAST,
"Failed to cast the following input port to its declared type: ", PortIndex + arrayIndex);
477 template <
typename NodeT,
size_t PortIndex>
480 static_assert(PortIndex - portSize<NodeT, PortDirection::INPUT>() < portSize<NodeT, PortDirection::OUTPUT>(),
"Invalid port index");
482 NodeT, PortDirection::OUTPUT, descriptorIndex<NodeT, PortDirection::OUTPUT, PortIndex>()>();
483 static_assert(!isArray,
"Output port is an array, must pass an array index");
484 if (m_outputPorts.find(PortIndex) == m_outputPorts.end())
486 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"Output port with the following id not registered: ", PortIndex);
488 using DataType =
decltype(portType<NodeT, PortDirection::OUTPUT, PortIndex>());
490 using ReturnType = std::shared_ptr<PointerType>;
491 ReturnType port = std::dynamic_pointer_cast<PointerType>(m_outputPorts[PortIndex]);
494 throw ExceptionWithStatus(DW_BAD_CAST,
"Failed to cast the following output port to its declared type: ", PortIndex);
500 template <
typename NodeT,
size_t PortIndex>
503 static_assert(PortIndex - portSize<NodeT, PortDirection::INPUT>() < portSize<NodeT, PortDirection::OUTPUT>(),
"Invalid port index");
504 constexpr bool isArray = descriptorPortArray<NodeT, PortDirection::OUTPUT, descriptorIndex<NodeT, PortDirection::OUTPUT, PortIndex>()>();
505 static_assert(isArray,
"Output port is not an array, must not pass an array index");
506 constexpr size_t arraySize = descriptorPortSize<NodeT, PortDirection::OUTPUT, descriptorIndex<NodeT, PortDirection::OUTPUT, PortIndex>()>();
507 if (arrayIndex >= arraySize)
509 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"The array index is out of bound: ", arrayIndex);
511 if (m_outputPorts.find(PortIndex + arrayIndex) == m_outputPorts.end())
513 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"Output port with the following id not registered: ", PortIndex + arrayIndex);
515 using DataType =
decltype(portType<NodeT, PortDirection::OUTPUT, PortIndex>());
517 using ReturnType = std::shared_ptr<PointerType>;
518 ReturnType port = std::dynamic_pointer_cast<PointerType>(m_outputPorts[PortIndex + arrayIndex]);
521 throw ExceptionWithStatus(DW_BAD_CAST,
"Failed to cast the following output port to its declared type: ", PortIndex + arrayIndex);
566 return m_outputPorts;
577 static_cast<void>(state);
582 dw::core::HeapHashMap<size_t, std::shared_ptr<ManagedPortInputBase>>
m_inputPorts;
583 dw::core::HeapHashMap<size_t, std::shared_ptr<ManagedPortOutputBase>>
m_outputPorts;
594 throw ExceptionWithStatus(DW_NOT_IMPLEMENTED,
"SimpleSensorNode::start() not implemented");
599 throw ExceptionWithStatus(DW_NOT_IMPLEMENTED,
"SimpleSensorNode::stop() not implemented");
604 throw ExceptionWithStatus(DW_NOT_IMPLEMENTED,
"SimpleSensorNode::isVirtual() not implemented");
609 throw ExceptionWithStatus(DW_NOT_IMPLEMENTED,
"SimpleSensorNode::setDataEventReadCallback() not implemented");
614 throw ExceptionWithStatus(DW_NOT_IMPLEMENTED,
"SimpleSensorNode::setDataEventWriteCallback() not implemented");
619 throw ExceptionWithStatus(DW_NOT_IMPLEMENTED,
"SimpleSensorNode::isEnabled() not implemented");
Basic error signal that gets reported only when there is an error.
Basic health signal that describes the health status of the graph.
dw::core::Function< bool(DataEvent &)> DataEventReadCallback
dw::core::Function< void(DataEvent)> DataEventWriteCallback
Pass is a runnable describes the metadata of a pass.
dw::core::HeapHashMap< size_t, std::shared_ptr< ManagedPortInputBase > > m_inputPorts
ManagedPortOutput< decltype(portType< NodeT, PortDirection::OUTPUT, PortIndex >())> & getOutputPort(size_t arrayIndex)
Get one specific ManagedPortOutput from a previously initialized output array port.
dwStatus getInputChannel(const uint8_t portID, ChannelObject *&channel) const override
Gets the input channel associated with the input port.
void initOutputArrayPorts(Args &&... args)
Initialize an array of ManagedPortOutput which will be owned by the base class and can be retrieved u...
dwStatus reset() override
void iterateManagedInputPorts(Func func)
dwStatus setNodePeriod(uint32_t period) override
dwStatus validate() override
void initInputPort(Args &&... args)
Initialize a ManagedPortInput which will be owned by the base class and can be retrieved using getInp...
dwStatus updateHealthSignal(const dwGraphHealthSignal &signal)
Adds the provided Health Signal to the Health Signal Array. If the array is full, the new signal will...
uint32_t getNodePeriod() const
SimpleNode(NodeAllocationParams params)
Constructor which tailors the preallocated size of the internal collections for ports and passes to t...
void initOutputArrayPort(size_t arrayIndex, Args &&... args)
Initialize one ManagedPortOutput of an array which will be owned by the base class and can be retriev...
dwStatus setInputChannel(ChannelObject *channel, uint8_t portID) override
Associate an input port with a channel instances.
size_t getPassCount() const noexcept override
dwStatus clearHealthSignal() override
dwStatus getPass(Pass **pass, uint8_t index) override
dwStatus setName(const char *name) final
const dw::core::HeapHashMap< size_t, std::shared_ptr< ManagedPortOutputBase > > & getRegisteredOutputPorts() const
dwStatus getOutputChannel(const uint8_t portID, ChannelObject *&channel) const override
Gets the output channel associated with the output port.
uint32_t getIterationCount() const
dwStatus setModuleHandle(ModuleHandle_t handle, dwContextHandle_t context)
dwStatus updateCurrentErrorSignal(dwGraphErrorSignal &signal) override
A function that allows user override to update error signal It is automatically called by dwFramework...
dwStatus addToHealthSignal(uint32_t error, dwTime_t timestamp=0UL) override
const dw::core::HeapHashMap< size_t, std::shared_ptr< ManagedPortInputBase > > & getRegisteredInputPorts() const
void iterateManagedOutputPorts(Func func)
dwStatus addToErrorSignal(uint32_t error, dwTime_t timestamp=0UL) override
dwStatus getNodeErrorSignal(dwGraphErrorSignal &errorSignal) override
void resetPorts() override
Default implementation to reset ports managed by the base class.
dwStatus getNodeHealthSignal(dwGraphHealthSignal &healthSignal) override
dwStatus setState(const char *state) override
dwStatus getName(const char **name) override
dwStatus runPass(size_t passIndex) override
dwStatus collectHealthSignals(dwGraphHealthSignal *&healthSignal, bool updateFromModule=false) override
void registerPass(PassFunctionT func, cudaStream_t const cudaStream, std::initializer_list< std::pair< dwStatus, uint32_t > > const &returnMapping={})
Register a GPU pass function and a cuda stream with the node base class.
void registerPass(PassFunctionT func, std::initializer_list< std::pair< dwStatus, uint32_t > > const &returnMapping={})
Register a pass function with the node base class.
dwStatus getPasses(VectorFixed< Pass * > &passList) override
dwStatus getModuleHandle(dwModuleHandle_t *moduleHandle, void *handle, dwContextHandle_t context)
dwStatus setup()
Default implementation of the setup pass.
ManagedPortInput< decltype(portType< NodeT, PortDirection::INPUT, PortIndex >())> & getInputPort()
Get a previously initialized non-array ManagedPortInput.
void initOutputPort(Args &&... args)
Initialize a ManagedPortOutput which will be owned by the base class and can be retrieved using getOu...
void iteratePorts(PortList &portList, Func func)
dwStatus getInputPort(const uint8_t portID, dw::framework::PortBase *&port) const override
Gets the input port associated with the input port Id.
dwStatus getOutputPort(const uint8_t portID, dw::framework::PortBase *&port) const override
Gets the output port associated with the output port Id.
void initInputArrayPort(size_t arrayIndex, Args &&... args)
Initialize one ManagedPortInput of an array which will be owned by the base class and can be retrieve...
void initInputArrayPorts(Args &&... args)
Initialize an array of ManagedPortInput which will be owned by the base class and can be retrieved us...
dwGraphHealthSignal & getHealthSignal()
virtual dwStatus setObjectHandle(dwModuleHandle_t handle)
dwStatus updateCurrentHealthSignal(dwGraphHealthSignal &signal) override
A function that allows user override to update health signal It is automatically called by dwFramewor...
ManagedPortInput< decltype(portType< NodeT, PortDirection::INPUT, PortIndex >())> & getInputPort(size_t arrayIndex)
Get one specific ManagedPortInput from a previously initialized input array port.
dwStatus teardown()
Default implementation of the teardown pass.
dwStatus validate(const char *direction, const PortCollectionDescriptor &collection, dw::core::Function< bool(size_t)> isPortBound)
Helper function used by dw::framework::SimpleNodeT::validate.
dwStatus clearErrorSignal() override
dwStatus setIterationCount(uint32_t iterationCount) override
dwStatus setOutputChannel(ChannelObject *channel, uint8_t portID) override
Associate an output port with a channel instances.
dwStatus getModuleErrorSignal(dwErrorSignal &errorSignal) override
dwStatus getModuleHealthSignal(dwHealthSignal &healthSignal) override
std::atomic< bool > m_asyncResetFlag
dw::core::HeapHashMap< size_t, std::shared_ptr< ManagedPortOutputBase > > m_outputPorts
dwStatus collectErrorSignals(dwGraphErrorSignal *&errorSignal, bool updateFromModule=true) override
ManagedPortOutput< decltype(portType< NodeT, PortDirection::OUTPUT, PortIndex >())> & getOutputPort()
Get a previously initialized non-array ManagedPortOutput.
dwStatus isVirtual(bool *) override
dwStatus setDataEventWriteCallback(DataEventWriteCallback) override
dwStatus start() override
dwStatus isEnabled(bool &) override
dwStatus setDataEventReadCallback(DataEventReadCallback) override
constexpr bool descriptorPortArray()
constexpr size_t descriptorPortSize()
constexpr size_t passIndex(dw::core::StringView identifier)
Get the the pass index for a pass identified by name.
NodeAllocationParams createAllocationParams()
NodeAllocationParams()=delete
size_t maxOutputPortCount
NodeAllocationParams(size_t maxInputPortCount_, size_t maxOutputPortCount_, size_t maxPassCount_)