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

SyncPortHelper.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_SYNCPORTHELPER_HPP_
32 #define DW_FRAMEWORK_SYNCPORTHELPER_HPP_
33 
34 #include <dw/core/container/HashContainer.hpp>
36 
37 namespace dw
38 {
39 namespace framework
40 {
41 
42 using CycleCountFetcher = dw::core::Function<uint32_t(void)>;
43 
44 // These classes are used to parse and handle indexed packets.
45 // TODO (ajayawardane) Move this logic into a separate port and change
46 // the port type for each pipelined node.
48 {
49 public:
51  : m_dataSynced(false)
52  , m_syncCount(0U)
53  , m_dataOffset(0U)
54  , m_syncCountRetriever(nullptr)
55  {
56  }
57  void setSyncCount(uint32_t index);
58  virtual void parseDataSynced(const ChannelParams& params);
59  bool isDataSynced();
60  dwStatus setSyncRetriever(const CycleCountFetcher& func);
61 
62 protected:
64  void stampSyncCount(uint32_t& syncCountOut) const;
65 
67  uint32_t m_syncCount;
68  uint32_t m_dataOffset;
70 };
71 
72 template <typename T>
74 {
75 public:
77  : SyncPortHelper()
78  {
79  }
80 
81 protected:
83  {
84  auto syncPacket = genericData.template getData<SyncedPacketPayload>();
85 
86  if (!syncPacket)
87  {
88  throw Exception(DW_INTERNAL_ERROR, "SyncPortHelperOutput extractInternalPacket: packet type mismatch");
89  }
90 
91  auto packet = syncPacket->data.template getData<T>();
92  if (!packet)
93  {
94  throw Exception(DW_INTERNAL_ERROR, "SyncPortHelperOutput extractInternalPacket: failed to extract underlying data");
95  }
96 
97  m_syncPacketBuf[packet] = syncPacket;
98  return packet;
99  }
100 
102  {
103  SyncedPacketPayload* syncPacket = m_syncPacketBuf[frame];
104  if (!syncPacket)
105  {
106  throw Exception(DW_INTERNAL_ERROR, "SyncPortHelperOutput getSyncPacket: sync packet not found in packet buffer");
107  }
108 
109  stampSyncCount(syncPacket->syncCount);
110 
111  return syncPacket;
112  }
113 
114  void parseDataSynced(const ChannelParams& params) override
115  {
117  if (isDataSynced())
118  {
119  m_syncPacketBuf = HeapHashMap<T*, SyncedPacketPayload*>(params.getPoolCapacity());
120  }
121  }
122 
123 private:
124  HeapHashMap<T*, SyncedPacketPayload*> m_syncPacketBuf;
125 };
126 
127 template <typename T>
129 {
130 public:
132  : SyncPortHelper()
133  , m_bufferedPacket()
134  , m_dataBuffered(false)
135  {
136  }
137 
138 protected:
140  {
141  if (m_dataBuffered)
142  {
143  return true;
144  }
145  return false;
146  }
147 
149  {
150  if (!isPacketBuffered())
151  {
152  return false;
153  }
154 
155  auto packet = m_bufferedPacket.template getData<SyncedPacketPayload>();
156 
157  if (!packet)
158  {
159  throw Exception(DW_INTERNAL_ERROR, "SyncPortHelperInput isValidPacketBuffered: packet type mistmatch");
160  }
161  return validatePacket(*packet);
162  }
163 
165  {
166  m_dataBuffered = false;
167  return m_bufferedPacket;
168  }
169 
171  {
172  auto syncPacket = genericData.template getData<SyncedPacketPayload>();
173 
174  if (!syncPacket)
175  {
176  throw Exception(DW_INTERNAL_ERROR, "SyncPortHelperInput extractInternalPacket: packet type mistmatch");
177  }
178 
179  if (validatePacket(*syncPacket))
180  {
181  return syncPacket->data.template getData<T>();
182  }
183  else
184  {
185  m_bufferedPacket = genericData;
186  m_dataBuffered = true;
187  return nullptr;
188  }
189  }
190 
191 private:
192  bool validatePacket(SyncedPacketPayload& pkt)
193  {
194  // If a producer - consumer pair are across pipeline boundaries, they will
195  // have non-zero data offsets; however, connections from that producer to
196  // consumers not across the pipeline boundary must also have sync ports
197  // (since if a producer is sync, all consumers must be sync). This check
198  // is in place for cases where producer -> consumer pairs are in the same
199  // pipeline boundary, and is basically a no-op for synchronization.
200  if (m_dataOffset == 0)
201  {
202  return true;
203  }
204 
205  uint32_t syncCount = (m_syncCountRetriever) ? m_syncCountRetriever() : m_syncCount;
206 
207  // Check if the packet is valid for consumption. The packet sync count represents
208  // when the packet was produced and the m_syncCount is the current sync count.
209  // The data offset is the offset between when it was produced and when it is
210  // available for consumption.
211  int validOffset = static_cast<int>(syncCount - pkt.syncCount - m_dataOffset);
212 
213  if (validOffset >= 0)
214  {
215  return true;
216  }
217 
218  return false;
219  }
220 
221  GenericData m_bufferedPacket;
222  bool m_dataBuffered;
223 };
224 
225 } // namespace framework
226 } // namespace dw
227 
228 #endif // DW_FRAMEWORK_SYNCPORTHELPER_HPP_
uint32_t ChannelPacketTypeID
SyncedPacketPayload * getSyncPacket(T *frame)
void parseDataSynced(const ChannelParams &params) override
void setSyncCount(uint32_t index)
CycleCountFetcher m_syncCountRetriever
T * extractInternalPacket(GenericData genericData)
dwStatus setSyncRetriever(const CycleCountFetcher &func)
void stampSyncCount(uint32_t &syncCountOut) const
Definition: Exception.hpp:46
ChannelPacketTypeID getNewPacketID(ChannelPacketTypeID packetTypeID)
T * extractInternalPacket(GenericData genericData)
dw::core::Function< uint32_t(void)> CycleCountFetcher
virtual void parseDataSynced(const ChannelParams &params)