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>
65template <
typename NodeT>
71 params.maxOutputPortCount = portSize<NodeT, PortDirection::OUTPUT>();
72 params.maxPassCount = passSize<NodeT>();
86 throw ExceptionWithStatus(DW_NOT_IMPLEMENTED,
"SimpleNode::reset() not implemented");
97 throw ExceptionWithStatus(DW_NOT_IMPLEMENTED,
"SimpleNode::setInputChannel() not implemented");
114 throw ExceptionWithStatus(DW_NOT_IMPLEMENTED,
"SimpleNode::validate() not implemented");
130 dwStatus
getPasses(VectorFixed<
Pass*>& passList, dwProcessorType processorType) override;
140 template <typename Func, typename PortList>
143 for (
auto& elem : portList)
149 template <
typename Func>
153 if (elem.second.get() ==
nullptr)
155 const char* nodeName{nullptr};
156 this->getName(&nodeName);
157 throw ExceptionWithStatus(DW_NOT_INITIALIZED,
"SimpleNode: input port not initialized, node ", nodeName,
", port id ", elem.first);
163 template <
typename Func>
166 iteratePorts(m_outputPorts, [&func,
this](
decltype(m_outputPorts)::TElement& elem) {
167 if (elem.second.get() ==
nullptr)
169 const char* nodeName{nullptr};
170 this->getName(&nodeName);
171 throw ExceptionWithStatus(DW_NOT_INITIALIZED,
"SimpleNode: output port not initialized, node ", nodeName,
", port id ", elem.first);
177 template <
typename ModuleHandle_t>
180 dwModuleHandle_t moduleHandle;
182 if (DW_NULL_HANDLE == handle)
184 return DW_INVALID_ARGUMENT;
187 dwStatus ret{getModuleHandle(&moduleHandle, handle, context)};
188 if (DW_SUCCESS != ret)
193 return setObjectHandle(moduleHandle);
205 dwStatus
getModuleHandle(dwModuleHandle_t* moduleHandle,
void* handle, dwContextHandle_t context);
209 throw ExceptionWithStatus(DW_NOT_IMPLEMENTED,
"SimpleNode::createSetupPass() not implemented");
214 throw ExceptionWithStatus(DW_NOT_IMPLEMENTED,
"SimpleNode::createTeardownPass() not implemented");
239 template <
typename PassFunctionT,
typename... Args>
240 std::unique_ptr<PassImpl<PassFunctionT>>
make_pass(PassFunctionT func, Args&&... args)
242 return std::make_unique<PassImpl<PassFunctionT>>(*
this, func, std::forward<Args>(args)...);
253 typename NodeT,
size_t PassIndex,
typename PassFunctionT>
254 void registerPass(PassFunctionT func, std::initializer_list<std::pair<dwStatus, uint32_t>>
const& returnMapping = {})
257 if (!isValidPass<NodeT>(PassIndex))
259 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"registerPass called with an invalid pass id: ", PassIndex);
262 if (m_passList.size() == 0U || m_passList.size() - 1U < PassIndex)
265 m_passList.resize(PassIndex + 1U);
267 m_passOwnershipList.resize(PassIndex + 1U);
270 if (m_passList[PassIndex] !=
nullptr)
272 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"registerPass called with a pass id which has been added before: ", PassIndex);
274 dwProcessorType processorType{passProcessorType<NodeT, PassIndex>()};
276 m_passList[PassIndex] = std::make_unique<PassImpl<PassFunctionT>>(*
this, func, processorType, returnMapping);
278 m_passOwnershipList[PassIndex] =
true;
286 typename NodeT,
size_t PassIndex,
typename PassFunctionT>
287 void registerPass(PassFunctionT func, cudaStream_t
const cudaStream, std::initializer_list<std::pair<dwStatus, uint32_t>>
const& returnMapping = {})
289 static_assert(passProcessorType<NodeT, PassIndex>() == DW_PROCESSOR_TYPE_GPU,
"The processor type of a pass with a cuda stream must be GPU");
290 registerPass<NodeT, PassIndex>(func, returnMapping);
291 m_passList[PassIndex]->m_cudaStream =
cudaStream;
336 dwStatus updateHealthSignalFromModule();
338 VectorFixed<std::unique_ptr<Pass>> m_passList;
340 VectorFixed<bool> m_passOwnershipList;
341 FixedString<MAX_NAME_LEN> m_name;
342 bool m_setupTeardownCreated;
348 dwModuleHandle_t m_object;
349 uint32_t m_iterationCount{};
350 uint32_t m_nodePeriod{};
354 template <
typename TPort,
typename... Args>
357 std::unique_ptr<TPort> port{std::make_unique<TPort>(std::forward<Args>(args)...)};
358 port->setSyncRetriever(std::bind(&SimpleNode::getIterationCount,
this));
366 template <
typename NodeT,
size_t PortIndex,
typename... Args>
369 static_assert(PortIndex < portSize<NodeT, PortDirection::INPUT>(),
"Invalid port index");
370 using DataType =
decltype(portType<NodeT, PortDirection::INPUT, PortIndex>());
371 auto port = std::make_shared<ManagedPortInput<DataType>>(std::forward<Args>(args)...);
372 if (m_inputPorts.find(PortIndex) != m_inputPorts.end())
374 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"Input port with the following id registered multiple times: ", PortIndex);
376 m_inputPorts[PortIndex] = port;
383 template <
typename NodeT,
size_t PortIndex,
typename... Args>
386 static_assert(PortIndex < portSize<NodeT, PortDirection::INPUT>(),
"Invalid port index");
387 using DataType =
decltype(portType<NodeT, PortDirection::INPUT, PortIndex>());
388 constexpr size_t descriptor_index = descriptorIndex<NodeT, PortDirection::INPUT, PortIndex>();
389 constexpr size_t arraySize = descriptorPortSize<NodeT, PortDirection::INPUT, descriptor_index>();
390 for (
size_t i = 0; i < arraySize; ++i)
392 auto port = std::make_shared<ManagedPortInput<DataType>>(std::forward<Args>(args)...);
393 if (m_inputPorts.find(PortIndex + i) != m_inputPorts.end())
395 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"Input port with the following id registered multiple times: ", PortIndex + i);
397 m_inputPorts[PortIndex + i] = port;
405 template <
typename NodeT,
size_t PortIndex,
typename... Args>
408 static_assert(PortIndex - portSize<NodeT, PortDirection::INPUT>() < portSize<NodeT, PortDirection::OUTPUT>(),
"Invalid port index");
409 using DataType =
decltype(portType<NodeT, PortDirection::OUTPUT, PortIndex>());
410 std::shared_ptr<ManagedPortOutput<DataType>> port{std::make_shared<ManagedPortOutput<DataType>>(std::forward<Args>(args)...)};
411 if (m_outputPorts.find(PortIndex) != m_outputPorts.end())
413 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"Output port with the following id registered multiple times: ", PortIndex);
415 m_outputPorts[PortIndex] = port;
422 template <
typename NodeT,
size_t PortIndex,
typename... Args>
425 static_assert(PortIndex - portSize<NodeT, PortDirection::INPUT>() < portSize<NodeT, PortDirection::OUTPUT>(),
"Invalid port index");
426 using DataType =
decltype(portType<NodeT, PortDirection::OUTPUT, PortIndex>());
429 constexpr size_t descriptor_index{descriptorIndex<NodeT, PortDirection::OUTPUT, PortIndex>()};
430 constexpr size_t arraySize{descriptorPortSize<NodeT, PortDirection::OUTPUT, descriptor_index>()};
431 for (
size_t i{0U}; i < arraySize; ++i)
433 std::shared_ptr<ManagedPortOutput<DataType>> port{std::make_shared<ManagedPortOutput<DataType>>(std::forward<Args>(args)...)};
434 if (m_outputPorts.find(PortIndex + i) != m_outputPorts.end())
436 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"Output port with the following id registered multiple times: ", PortIndex + i);
438 m_outputPorts[PortIndex + i] = port;
443 template <
typename NodeT,
size_t PortIndex>
446 static_assert(PortIndex < portSize<NodeT, PortDirection::INPUT>(),
"Invalid port index");
448 NodeT, PortDirection::INPUT, descriptorIndex<NodeT, PortDirection::INPUT, PortIndex>()>();
449 static_assert(!isArray,
"Input port is an array, must pass an array index");
450 if (m_inputPorts.find(PortIndex) == m_inputPorts.end())
452 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"Input port with the following id not registered: ", PortIndex);
454 using DataType =
decltype(portType<NodeT, PortDirection::INPUT, PortIndex>());
456 using ReturnType = std::shared_ptr<PointerType>;
457 ReturnType port = std::dynamic_pointer_cast<PointerType>(m_inputPorts[PortIndex]);
460 throw ExceptionWithStatus(DW_BAD_CAST,
"Failed to cast the following input port to its declared type: ", PortIndex);
466 template <
typename NodeT,
size_t PortIndex>
469 static_assert(PortIndex < portSize<NodeT, PortDirection::INPUT>(),
"Invalid port index");
470 constexpr bool isArray = descriptorPortArray<NodeT, PortDirection::INPUT, descriptorIndex<NodeT, PortDirection::INPUT, PortIndex>()>();
471 static_assert(isArray,
"Input port is not an array, must not pass an array index");
472 constexpr size_t arraySize = descriptorPortSize<NodeT, PortDirection::INPUT, descriptorIndex<NodeT, PortDirection::INPUT, PortIndex>()>();
473 if (arrayIndex >= arraySize)
475 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"The array index is out of bound: ", arrayIndex);
477 if (m_inputPorts.find(PortIndex + arrayIndex) == m_inputPorts.end())
479 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"Input port with the following id not registered: ", PortIndex + arrayIndex);
481 using DataType =
decltype(portType<NodeT, PortDirection::INPUT, PortIndex>());
483 using ReturnType = std::shared_ptr<PointerType>;
484 ReturnType port = std::dynamic_pointer_cast<PointerType>(m_inputPorts[PortIndex + arrayIndex]);
487 throw ExceptionWithStatus(DW_BAD_CAST,
"Failed to cast the following input port to its declared type: ", PortIndex + arrayIndex);
493 template <
typename NodeT,
size_t PortIndex>
496 static_assert(PortIndex - portSize<NodeT, PortDirection::INPUT>() < portSize<NodeT, PortDirection::OUTPUT>(),
"Invalid port index");
498 NodeT, PortDirection::OUTPUT, descriptorIndex<NodeT, PortDirection::OUTPUT, PortIndex>()>();
499 static_assert(!isArray,
"Output port is an array, must pass an array index");
500 if (m_outputPorts.find(PortIndex) == m_outputPorts.end())
502 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"Output port with the following id not registered: ", PortIndex);
504 using DataType =
decltype(portType<NodeT, PortDirection::OUTPUT, PortIndex>());
506 using ReturnType = std::shared_ptr<PointerType>;
507 ReturnType port = std::dynamic_pointer_cast<PointerType>(m_outputPorts[PortIndex]);
510 throw ExceptionWithStatus(DW_BAD_CAST,
"Failed to cast the following output port to its declared type: ", PortIndex);
516 template <
typename NodeT,
size_t PortIndex>
519 static_assert(PortIndex - portSize<NodeT, PortDirection::INPUT>() < portSize<NodeT, PortDirection::OUTPUT>(),
"Invalid port index");
520 constexpr bool isArray = descriptorPortArray<NodeT, PortDirection::OUTPUT, descriptorIndex<NodeT, PortDirection::OUTPUT, PortIndex>()>();
521 static_assert(isArray,
"Output port is not an array, must not pass an array index");
522 constexpr size_t arraySize = descriptorPortSize<NodeT, PortDirection::OUTPUT, descriptorIndex<NodeT, PortDirection::OUTPUT, PortIndex>()>();
523 if (arrayIndex >= arraySize)
525 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"The array index is out of bound: ", arrayIndex);
527 if (m_outputPorts.find(PortIndex + arrayIndex) == m_outputPorts.end())
529 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"Output port with the following id not registered: ", PortIndex + arrayIndex);
531 using DataType =
decltype(portType<NodeT, PortDirection::OUTPUT, PortIndex>());
533 using ReturnType = std::shared_ptr<PointerType>;
534 ReturnType port = std::dynamic_pointer_cast<PointerType>(m_outputPorts[PortIndex + arrayIndex]);
537 throw ExceptionWithStatus(DW_BAD_CAST,
"Failed to cast the following output port to its declared type: ", PortIndex + arrayIndex);
582 return m_outputPorts;
593 static_cast<void>(state);
598 dw::core::HeapHashMap<size_t, std::shared_ptr<ManagedPortInputBase>>
m_inputPorts;
599 dw::core::HeapHashMap<size_t, std::shared_ptr<ManagedPortOutputBase>>
m_outputPorts;
610 throw ExceptionWithStatus(DW_NOT_IMPLEMENTED,
"SimpleSensorNode::start() not implemented");
615 throw ExceptionWithStatus(DW_NOT_IMPLEMENTED,
"SimpleSensorNode::stop() not implemented");
620 throw ExceptionWithStatus(DW_NOT_IMPLEMENTED,
"SimpleSensorNode::isVirtual() not implemented");
625 throw ExceptionWithStatus(DW_NOT_IMPLEMENTED,
"SimpleSensorNode::setDataEventReadCallback() not implemented");
630 throw ExceptionWithStatus(DW_NOT_IMPLEMENTED,
"SimpleSensorNode::setDataEventWriteCallback() 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
static constexpr const uint32_t MAX_PORT_COUNT
static constexpr const uint32_t MAX_PASS_COUNT
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.
dwStatus reset() override
void iterateManagedInputPorts(Func func)
dwStatus setNodePeriod(uint32_t period) override
dwStatus validate() override
dwStatus setInputChannel(ChannelObject *, uint8_t, dwSerializationType) 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...
dwStatus copyModuleHealthSignals(dwHealthSignal &outSignal)
Copy health signals from the module over to the node and stores in outSignal.
uint32_t getNodePeriod() const
void initInputArrayPort(Args &&... args)
Initialize an array of ManagedPortInput which will be owned by the base class and can be retrieved us...
SimpleNode(NodeAllocationParams params)
Constructor which tailors the preallocated size of the internal collections for ports and passes to t...
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...
virtual std::unique_ptr< Pass > createTeardownPass()
const dw::core::HeapHashMap< size_t, std::shared_ptr< ManagedPortInputBase > > & getRegisteredInputPorts() const
void iterateManagedOutputPorts(Func func)
void resetPorts() override
Default implementation to reset ports managed by the base class.
dwStatus setState(const char *state) override
dwStatus getName(const char **name) override
virtual std::unique_ptr< Pass > createSetupPass()
dwStatus runPass(size_t passIndex) override
dwStatus getErrorSignal(dwGraphErrorSignal &sehErrorSignal, dwGraphErrorSignal *&errorSignal, uint16_t const sourceId, char8_t const *instanceName=nullptr) override
std::unique_ptr< TPort > make_port(Args &&... args)
std::unique_ptr< PassImpl< PassFunctionT > > make_pass(PassFunctionT func, Args &&... args)
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 getHealthSignal(dwGraphHealthSignal *&healthSignals, bool updateFromModule=false) override
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.
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.
std::atomic< bool > m_asyncResetFlag
void initOutputArrayPort(Args &&... args)
Initialize an array of ManagedPortOutput which will be owned by the base class and can be retrieved u...
dw::core::HeapHashMap< size_t, std::shared_ptr< ManagedPortOutputBase > > m_outputPorts
ManagedPortOutput< decltype(portType< NodeT, PortDirection::OUTPUT, PortIndex >())> & getOutputPort()
Get a previously initialized non-array ManagedPortOutput.
SimpleProcessNode(NodeAllocationParams params)
dwStatus isVirtual(bool *) override
dwStatus setDataEventWriteCallback(DataEventWriteCallback) override
dwStatus start() override
dwStatus setDataEventReadCallback(DataEventReadCallback) override
constexpr bool descriptorPortArray()
constexpr size_t passIndex(dw::core::StringView identifier)
Get the the pass index for a pass identified by name.
NodeAllocationParams createAllocationParams()
size_t maxOutputPortCount