Compute Graph Framework SDK Reference  5.6
SyncPortHelper.hpp
Go to the documentation of this file.
1
2//
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-2022 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
37namespace dw
38{
39namespace framework
40{
41
42using 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{
49public:
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);
60 dwStatus setSyncRetriever(const CycleCountFetcher& func);
61
62protected:
64 void stampSyncCount(uint32_t& syncCountOut) const;
65
67 uint32_t m_syncCount;
68 uint32_t m_dataOffset;
70};
71
72template <typename T>
74{
75public:
78 {
79 }
80
81protected:
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
123private:
124 HeapHashMap<T*, SyncedPacketPayload*> m_syncPacketBuf;
125};
126
127template <typename T>
129{
130public:
133 , m_bufferedPacket()
134 , m_dataBuffered(false)
135 {
136 }
137
138protected:
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
191private:
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_
T * extractInternalPacket(GenericData genericData)
T * extractInternalPacket(GenericData genericData)
SyncedPacketPayload * getSyncPacket(T *frame)
void parseDataSynced(const ChannelParams &params) override
uint32_t ChannelPacketTypeID
dw::core::Function< uint32_t(void)> CycleCountFetcher
Definition: Exception.hpp:47
dwStatus setSyncRetriever(const CycleCountFetcher &func)
ChannelPacketTypeID getNewPacketID(ChannelPacketTypeID packetTypeID)
CycleCountFetcher m_syncCountRetriever
void setSyncCount(uint32_t index)
virtual void parseDataSynced(const ChannelParams &params)
void stampSyncCount(uint32_t &syncCountOut) const