Compute Graph Framework SDK Reference
5.4.5418 Release
For Test and Development only

ManagedPort.hpp
Go to the documentation of this file.
1 //
3 // Notice
4 // ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
5 // NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
6 // THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
7 // MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 //
9 // NVIDIA CORPORATION & AFFILIATES assumes no responsibility for the consequences of use of such
10 // information or for any infringement of patents or other rights of third parties that may
11 // result from its use. No license is granted by implication or otherwise under any patent
12 // or patent rights of NVIDIA CORPORATION & AFFILIATES. No third party distribution is allowed unless
13 // expressly authorized by NVIDIA. Details are subject to change without notice.
14 // This code supersedes and replaces all information previously supplied.
15 // NVIDIA CORPORATION & AFFILIATES products are not authorized for use as critical
16 // components in life support devices or systems without express written approval of
17 // NVIDIA CORPORATION & AFFILIATES.
18 //
19 // SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
20 // SPDX-License-Identifier: LicenseRef-NvidiaProprietary
21 //
22 // NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
23 // property and proprietary rights in and to this material, related
24 // documentation and any modifications thereto. Any use, reproduction,
25 // disclosure or distribution of this material and related documentation
26 // without an express license agreement from NVIDIA CORPORATION or
27 // its affiliates is strictly prohibited.
28 //
30 
31 #ifndef DW_FRAMEWORK_MANAGEDPORT_HPP_
32 #define DW_FRAMEWORK_MANAGEDPORT_HPP_
33 
35 #include <dwcgf/port/Port.hpp>
36 #include <dw/core/language/Optional.hpp>
37 #include <dw/core/container/RingBuffer.hpp>
38 #include <type_traits>
39 
40 namespace dw
41 {
42 namespace framework
43 {
44 
45 class ManagedPortBase : public PortBase
46 {
47 public:
49 
50  virtual ~ManagedPortBase() = default;
51 
56  ManagedPortBase(const ManagedPortBase& other) = delete;
57  ManagedPortBase& operator=(const ManagedPortBase& other) = delete;
58  ManagedPortBase(ManagedPortBase&& other) = delete;
59  ManagedPortBase& operator=(ManagedPortBase&& other) = delete;
60 
68  virtual void bindChannel(ChannelObject* channel) = 0;
69 
73  virtual bool isBound() const noexcept = 0;
74 
78  void setCycleCount(uint32_t cycleCount);
79 
84  virtual void reset();
85 
86 protected:
87  uint32_t m_cycleCount;
88 };
89 
94 {
95 public:
97  {
98  };
99 
101  {
106  bool syncEnabled = false;
107  };
108 
109  struct Properties
110  {
113  };
117  bool isBufferAvailable() const noexcept;
118 
126  void acquire();
127 
135  void send();
136 
137  const Properties& getProperties() const noexcept;
138 
139  // Implemented inherited methods
140  void bindChannel(ChannelObject* channel) override;
141  bool isBound() const noexcept override;
142 
143 protected:
145  GenericData getBufferGeneric();
146 
147 private:
148  static BoundProperties getBoundProperties(ChannelObject* channel);
149  GenericDataReference m_ref;
150  ChannelObject::Producer* m_channelProducer{};
151  Properties m_props{};
152  dw::core::Optional<GenericData> m_buffer{};
153 };
154 
159 {
160 public:
161  using RingBuffer = dw::core::RingBuffer<GenericData>;
162 
164  {
168  uint32_t maxBuffers = 1U;
174  dwTime_t waitTime = 0;
175  };
176 
178  {
188  bool enableReuse = false;
189 
193  bool syncEnabled = false;
198  uint32_t dataOffset = 0;
199  };
200 
201  struct Properties
202  {
211  };
212 
216  const Properties& getProperties() const noexcept;
217 
227  void recv();
228 
234  void release();
235 
240  void reset() override;
241 
245  bool isBufferAvailable() const noexcept;
246 
247  // Implemented inherited methods
248  void bindChannel(ChannelObject* channel) override;
249  bool isBound() const noexcept override;
250 
251 protected:
253  GenericData getBufferGeneric() const;
254  GenericData popBufferGeneric();
255  void releaseToChannel(void* data);
256 
257 private:
258  static BoundProperties getBoundProperties(ChannelObject* channel);
259  bool recvSingle(dwTime_t waitTime);
260  bool stashConsumed();
261  bool packetStashed(GenericData packet);
262  void handleReuseDrop();
263 
264  void releaseSingle();
265 
266  Properties m_props;
267  GenericDataReference m_ref;
268  ChannelObject::Consumer* m_channelConsumer{};
269  bool m_shouldDropFirstBuffer{};
270 
271 protected:
275 };
276 
278 
279 namespace detail
280 {
281 
282 template <typename T>
283 T* getBufferTyped(GenericData buffer, bool isPacketSync)
284 {
285  T* ptr = nullptr;
286 
287  if (isPacketSync)
288  {
289  auto syncPacket = extractSyncPacket(buffer);
290 
291  ptr = syncPacket->data.template getData<T>();
292  }
293  else
294  {
295  ptr = buffer.template getData<T>();
296  }
297 
298  if (ptr == nullptr)
299  {
300  throw Exception(DW_INVALID_ARGUMENT, "getBufferTyped: type mismatch");
301  }
302  return ptr;
303 }
304 
305 } // namespace detail
306 
310 template <typename T>
312 {
313  static_assert(parameter_traits<T>::IsDeclared,
314  "Channel packet type not declared. Ensure channel packet type "
315  "handling is declared with DWFRAMEWORK_DECLARE_PACKET_TYPE_RELATION");
316 
317  using SpecimenT = typename parameter_traits<T>::SpecimenT;
318 
319 public:
325  template <typename T2 = T, typename std::enable_if_t<parameter_traits<T2>::PacketTID != DWFRAMEWORK_PACKET_ID_DEFAULT, void>* = nullptr>
326  ManagedPortOutput(ConstructProperties props, SpecimenT& ref)
327  : ManagedPortOutputBase(std::move(props), make_specimen<T>(&ref))
328  {
329  }
330 
335  template <typename T2 = T, typename std::enable_if_t<parameter_traits<T2>::PacketTID != DWFRAMEWORK_PACKET_ID_DEFAULT, void>* = nullptr>
336  ManagedPortOutput(SpecimenT& ref)
337  : ManagedPortOutputBase({}, make_specimen<T>(&ref))
338  {
339  }
340 
344  template <typename T2 = T, typename std::enable_if_t<parameter_traits<T2>::PacketTID == DWFRAMEWORK_PACKET_ID_DEFAULT, void>* = nullptr>
346  : ManagedPortOutputBase(std::move(props), make_specimen<T>(nullptr))
347  {
348  }
349 
350  template <typename T2 = T, typename std::enable_if_t<parameter_traits<T2>::PacketTID == DWFRAMEWORK_PACKET_ID_DEFAULT, void>* = nullptr>
352  : ManagedPortOutputBase({}, make_specimen<T>(nullptr))
353  {
354  }
355 
361  auto getBuffer()
362  {
363  return detail::getBufferTyped<T>(getBufferGeneric(), getProperties().boundProperties.syncEnabled);
364  }
365 };
366 
370 template <typename T>
372 {
373  static_assert(parameter_traits<T>::IsDeclared,
374  "Channel packet type not declared. Ensure channel packet type "
375  "handling is declared with DWFRAMEWORK_DECLARE_PACKET_TYPE_RELATION");
376  using SpecimenT = typename parameter_traits<T>::SpecimenT;
377 
378  struct PacketDeleter;
379 
380 public:
385  : ManagedPortInputBase(std::move(props), make_specimen<T>(nullptr))
386  {
387  }
388 
390  : ManagedPortInputBase({}, make_specimen<T>(nullptr))
391  {
392  }
393 
400  {
401  return iterable(*this);
402  }
403 
409  auto getBuffer()
410  {
411  return detail::getBufferTyped<T>(getBufferGeneric(), getProperties().boundProperties.syncEnabled);
412  }
413 
421  {
422  return isBufferAvailable() ? getBuffer() : nullptr;
423  }
424 
425  using UniquePacketPtr = std::unique_ptr<T, PacketDeleter>;
426 
428  {
429  GenericData packet = popBufferGeneric();
430  auto* ptr = detail::getBufferTyped<T>(packet, getProperties().boundProperties.syncEnabled);
431  void* releasePtr = ptr;
432 
433  if (getProperties().boundProperties.syncEnabled)
434  {
435  releasePtr = packet.getPointer();
436  }
437 
438  return UniquePacketPtr(ptr, PacketDeleter{this, releasePtr});
439  }
440 
441 private:
442  struct PacketDeleter
443  {
444  void operator()(T* p)
445  {
446  (void)p;
447  port->releaseToChannel(releasePtr);
448  }
449  ManagedPortInput* port;
450  void* releasePtr;
451  };
452 
453  struct iterable
454  {
455  explicit iterable(ManagedPortInput<T>& port)
456  : m_port(port)
457  {
458  }
459 
461  template <class TT>
462  class iterator : public ManagedPortInputBase::RingBuffer::iterator
463  {
464  using Base = ManagedPortInputBase::RingBuffer::iterator;
465 
466  public:
467  iterator(Base&& base, ManagedPortInput<T>& port)
468  : Base(base)
469  , m_port(port)
470  {
471  }
472 
473  const Base& baseFromThis() const
474  {
475  return *this;
476  }
477 
478  auto operator*() const
479  {
480  GenericData buffer = *baseFromThis();
481  return detail::getBufferTyped<TT>(buffer, m_port.getProperties().boundProperties.syncEnabled);
482  }
483 
484  private:
485  ManagedPortInput<T>& m_port;
486  };
487 
488  // -----------------------------------------------------------------------------
489  iterator<T> begin() { return iterator<T>(m_port.m_buffers.begin(), m_port); }
490 
491  // -----------------------------------------------------------------------------
492  iterator<T> end() { return iterator<T>(m_port.m_buffers.end(), m_port); }
493 
494  // -----------------------------------------------------------------------------
495  iterator<const T> begin() const { return iterator<const T>(m_port.m_buffers.begin(), m_port); }
496 
497  // -----------------------------------------------------------------------------
498  iterator<const T> end() const { return iterator<const T>(m_port.m_buffers.end(), m_port); }
499 
500  private:
501  ManagedPortInput<T>& m_port;
502  };
503 };
504 
505 template <typename T>
507 
508 } // namespace framework
509 } // namespace dw
510 
511 #endif // DW_FRAMEWORK_MANAGEDPORT_HPP_
ConstructProperties constructProperties
Properties deduced when port is constructed.
auto getBufferIter()
Get iterator over received buffers.
virtual void reset()
Resets the port&#39;s cycle count to 0.
void setCycleCount(uint32_t cycleCount)
virtual bool isBound() const noexcept=0
auto getOptionalBuffer()
For bind optional and buffer optional case Get a pointer to the first received buffer if the buffer a...
ManagedPortBase & operator=(const ManagedPortBase &other)=delete
auto getBuffer()
Get a pointer to the acquired buffer.
constexpr ChannelPacketTypeID DWFRAMEWORK_PACKET_ID_DEFAULT
Derived ManagedPortInput<T> provides type-specific interfaces for accessing buffers.
virtual void bindChannel(ChannelObject *channel)=0
Bind channel to the port.
static GenericDataReference make_specimen(typename parameter_traits< T >::SpecimenT *specimen)
ManagedPortOutput(ConstructProperties props)
SyncedPacketPayload * extractSyncPacket(GenericData packet)
virtual ~ManagedPortBase()=default
ManagedPortInput(ConstructProperties props)
Base class encapsulates ownership of buffers and interactions with channel in type-agnostic way...
Definition: ManagedPort.hpp:93
iterator(Base &&base, ManagedPortInput< T > &port)
Definition: Exception.hpp:46
ManagedPortOutput(ConstructProperties props, SpecimenT &ref)
dw::core::RingBuffer< GenericData > RingBuffer
typename ManagedPortInput< T >::UniquePacketPtr UniquePacketPtr
Derived ManagedPortOutput<T> provides type-specific interfaces for accessing buffers.
Base class encapsulates ownership of buffers and interactions with channel in type-agnostic way...
std::unique_ptr< T, PacketDeleter > UniquePacketPtr
BoundProperties boundProperties
Properties deduced once port is bound to channel.
auto getBuffer()
Get a pointer to the first received buffer.