Compute Graph Framework SDK Reference  5.16
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-2023 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 <dwshared/dwfoundation/dw/core/container/HashContainer.hpp>
35#include <dwshared/dwfoundation/dw/core/safety/Safety.hpp>
37
38namespace dw
39{
40namespace framework
41{
42
43// These classes are used to parse and handle indexed packets.
44// TODO (ajayawardane) Move this logic into a separate port and change
45// the port type for each pipelined node.
47{
48public:
50 : m_dataSynced(false)
51 , m_syncCount(0U)
52 , m_dataOffset(0U)
53 {
54 }
55 void setSyncCount(uint32_t index);
56 virtual void parseDataSynced(const ChannelParams& params);
58
59protected:
61 void stampSyncCount(uint32_t& syncCountOut) const;
62
64 uint32_t m_syncCount;
65 uint32_t m_dataOffset;
66};
67
68// There are no specific requirements on the template type
69// coverity[autosar_cpp14_a14_1_1_violation]
70template <typename T>
72{
73public:
76 {
77 }
78
79protected:
81 {
82 MetadataPayload* metadataPacket{genericData.template getData<MetadataPayload>()};
83
84 if (!metadataPacket)
85 {
86 throw ExceptionWithStatus(DW_INTERNAL_ERROR, "SyncPortHelperOutput extractInternalPacket: packet type mismatch");
87 }
88
89 T* packet{metadataPacket->data.template getData<T>()};
90 if (!packet)
91 {
92 throw ExceptionWithStatus(DW_INTERNAL_ERROR, "SyncPortHelperOutput extractInternalPacket: failed to extract underlying data");
93 }
94
95 m_metadataPayloadBuf[packet] = metadataPacket;
96 return packet;
97 }
98
100 {
101 MetadataPayload* metadataPacket{m_metadataPayloadBuf[frame]};
102 if (!metadataPacket)
103 {
104 throw ExceptionWithStatus(DW_INTERNAL_ERROR, "SyncPortHelperOutput getmetadataPacket: sync packet not found in packet buffer");
105 }
106
107 return metadataPacket;
108 }
109
110 void parseDataSynced(const ChannelParams& params) override
111 {
113 m_metadataPayloadBuf = HeapHashMap<T*, MetadataPayload*>(params.getPoolCapacity());
114 }
115
116private:
117 HeapHashMap<T*, MetadataPayload*> m_metadataPayloadBuf;
118};
119
120// There are no specific requirements on the template type
121// coverity[autosar_cpp14_a14_1_1_violation]
122template <typename T>
124{
125public:
128 , m_bufferedPacket()
129 , m_dataBuffered(false)
130 {
131 }
132
133protected:
135 {
136 if (m_dataBuffered)
137 {
138 return true;
139 }
140 return false;
141 }
142
144 {
145 if (!isPacketBuffered())
146 {
147 return false;
148 }
149
150 MetadataPayload* packet{m_bufferedPacket.template getData<MetadataPayload>()};
151
152 if (!packet)
153 {
154 throw ExceptionWithStatus(DW_INTERNAL_ERROR, "SyncPortHelperInput isValidPacketBuffered: packet type mistmatch");
155 }
156 return validatePacket(*packet);
157 }
158
160 {
161 m_dataBuffered = false;
162 return m_bufferedPacket;
163 }
164
166 {
167 MetadataPayload* metadataPacket{genericData.template getData<MetadataPayload>()};
168
169 if (!metadataPacket)
170 {
171 throw ExceptionWithStatus(DW_INTERNAL_ERROR, "SyncPortHelperInput extractSyncPacket: packet type mistmatch");
172 }
173
174 if (validatePacket(*metadataPacket))
175 {
176 T* packet{metadataPacket->data.template getData<T>()};
177 m_metadataPayloadBuf[packet] = metadataPacket;
178 return packet;
179 }
180 else
181 {
182 m_bufferedPacket = genericData;
183 m_dataBuffered = true;
184 return nullptr;
185 }
186 }
187
189 {
190 MetadataPayload* metadataPacket{genericData.template getData<MetadataPayload>()};
191
192 if (!metadataPacket)
193 {
194 throw ExceptionWithStatus(DW_INTERNAL_ERROR, "SyncPortHelperInput extractInternalPacket: packet type mistmatch");
195 }
196
197 T* packet{metadataPacket->data.template getData<T>()};
198 m_metadataPayloadBuf[packet] = metadataPacket;
199 return packet;
200 }
201
203 {
204 MetadataPayload* metadataPacket = m_metadataPayloadBuf[frame];
205 if (!metadataPacket)
206 {
207 throw ExceptionWithStatus(DW_INTERNAL_ERROR, "SyncPortHelperInput getmetadataPacket: sync packet not found in packet buffer");
208 }
209
210 return metadataPacket;
211 }
212
213 void parseDataSynced(const ChannelParams& params) override
214 {
216 m_metadataPayloadBuf = HeapHashMap<T*, MetadataPayload*>(params.getPoolCapacity());
217 }
218
219private:
220 bool validatePacket(MetadataPayload& pkt)
221 {
222 // If a producer - consumer pair are across pipeline boundaries, they will
223 // have non-zero data offsets; however, connections from that producer to
224 // consumers not across the pipeline boundary must also have sync ports
225 // (since if a producer is sync, all consumers must be sync). This check
226 // is in place for cases where producer -> consumer pairs are in the same
227 // pipeline boundary, and is basically a no-op for synchronization.
228 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
229 if (0U == m_dataOffset)
230 {
231 return true;
232 }
233
234 // Check if the packet is valid for consumption. The packet sync count represents
235 // when the packet was produced and the m_syncCount is the current sync count.
236 // The data offset is the offset between when it was produced and when it is
237 // available for consumption.
238 return m_syncCount >= dw::core::safeAdd(pkt.header.iterationCount, m_dataOffset).value();
239 }
240
241 HeapHashMap<T*, MetadataPayload*> m_metadataPayloadBuf;
242 GenericData m_bufferedPacket;
243 bool m_dataBuffered;
244};
245
246} // namespace framework
247} // namespace dw
248
249#endif // DW_FRAMEWORK_SYNCPORTHELPER_HPP_
T * extractInternalPacket(GenericData genericData)
T * extractSyncPacket(GenericData genericData)
MetadataPayload * getMetadataPacket(T *frame)
void parseDataSynced(const ChannelParams &params) override
T * extractInternalPacket(GenericData genericData)
void parseDataSynced(const ChannelParams &params) override
MetadataPayload * getMetadataPacket(T *frame)
uint32_t ChannelPacketTypeID
uint32_t iterationCount
Producer iteration count.
Definition: Buffer.hpp:40
ChannelPacketTypeID getNewPacketID(ChannelPacketTypeID packetTypeID)
void setSyncCount(uint32_t index)
virtual void parseDataSynced(const ChannelParams &params)
void stampSyncCount(uint32_t &syncCountOut) const