Compute Graph Framework SDK Reference  5.6
PortDescriptor.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_PORTDESCRIPTOR_HPP_
32#define DW_FRAMEWORK_PORTDESCRIPTOR_HPP_
33
34#include <dw/core/container/StringView.hpp>
35#include <dwcgf/port/Port.hpp>
36#include <dw/core/language/cxx20.hpp>
37#include <dw/core/language/Tuple.hpp>
38
39#include <functional>
40#include <tuple>
41#include <type_traits>
42#include <utility>
43
44namespace dw
45{
46namespace framework
47{
48
49// API needed to declare the ports of a node.
50
51template <typename... Args>
52constexpr auto describePortCollection(Args&&... args)
53{
54 return dw::core::make_tuple<Args...>(std::forward<Args>(args)...);
55}
56
57static constexpr size_t PORT_TYPE_NAME = 0;
58static constexpr size_t PORT_NAME = 1;
59static constexpr size_t PORT_TYPE = 2;
60static constexpr size_t PORT_ARRAY_SIZE = 3;
61static constexpr size_t PORT_BINDING = 4;
62static constexpr size_t PORT_COMMENT = 5;
63
64enum class PortBinding : uint8_t
65{
66 OPTIONAL = 0,
67 REQUIRED = 1
68};
69
70#define _DW_PORT_TYPE_NAME_STRING_VIEW(TYPE_NAME_STR) TYPE_NAME_STR##_sv
71#define DW_DESCRIBE_PORT(TYPE_NAME, args...) dw::framework::describePort<TYPE_NAME>(_DW_PORT_TYPE_NAME_STRING_VIEW(#TYPE_NAME), ##args)
72
73template <typename PortType>
74constexpr auto describePort(
75 dw::core::StringView typeName, dw::core::StringView name, PortBinding binding = PortBinding::OPTIONAL, dw::core::StringView comment = ""_sv)
76{
77 return std::make_tuple(
78 std::move(typeName),
79 std::move(name),
80 static_cast<PortType*>(nullptr),
81 static_cast<size_t>(0),
82 std::move(binding),
83 std::move(comment));
84}
85
86template <typename PortType>
87constexpr auto describePort(
88 dw::core::StringView typeName, dw::core::StringView name, dw::core::StringView comment)
89{
90 return describePort<PortType>(
91 std::move(typeName),
92 std::move(name),
93 std::move(PortBinding::OPTIONAL),
94 std::move(comment));
95}
96
97#define DW_DESCRIBE_PORT_ARRAY(TYPE_NAME, ARRAYSIZE, args...) dw::framework::describePortArray<TYPE_NAME, ARRAYSIZE>(_DW_PORT_TYPE_NAME_STRING_VIEW(#TYPE_NAME), ##args)
98
99template <
100 typename PortType,
101 size_t ArraySize,
102 typename std::enable_if_t<ArraySize != 0, void>* = nullptr>
103constexpr auto describePortArray(
104 dw::core::StringView typeName, dw::core::StringView name, PortBinding binding = PortBinding::OPTIONAL, dw::core::StringView comment = ""_sv)
105{
106 return std::make_tuple(
107 std::move(typeName),
108 std::move(name),
109 static_cast<PortType*>(nullptr),
110 ArraySize,
111 std::move(binding),
112 std::move(comment));
113}
114
115template <
116 typename PortType,
117 size_t ArraySize,
118 typename std::enable_if_t<ArraySize != 0, void>* = nullptr>
119constexpr auto describePortArray(
120 dw::core::StringView typeName, dw::core::StringView name, dw::core::StringView comment)
121{
122 return describePortArray<PortType, ArraySize>(
123 std::move(typeName),
124 std::move(name),
125 std::move(PortBinding::OPTIONAL),
126 std::move(comment));
127}
128
129// API to access declared ports of a node.
130
131template <typename Node>
132constexpr auto describeInputPorts()
133{
135}
136
137template <typename Node>
138constexpr auto describeOutputPorts()
139{
141}
142
143template <
144 typename Node,
145 PortDirection Direction,
146 typename std::enable_if_t<Direction == PortDirection::INPUT, void>* = nullptr>
147constexpr auto describePorts()
148{
149 return describeInputPorts<Node>();
150}
151
152template <
153 typename Node,
154 PortDirection Direction,
155 typename std::enable_if_t<Direction == PortDirection::OUTPUT, void>* = nullptr>
156constexpr auto describePorts()
157{
158 return describeOutputPorts<Node>();
159}
160
161// API to query information about declared ports of a node.
162
163// Number of input or output port descriptors
164template <typename Node, PortDirection Direction>
165constexpr std::size_t portDescriptorSize()
166{
167 return dw::core::tuple_size<decltype(describePorts<Node, Direction>())>::value;
168}
169
170// The flag if the port described by a specific descriptor is an array
171template <typename Node, PortDirection Direction, size_t DescriptorIndex>
172constexpr bool descriptorPortArray()
173{
174 constexpr size_t array_length = std::get<dw::framework::PORT_ARRAY_SIZE>(
175 dw::core::get<DescriptorIndex>(describePorts<Node, Direction>()));
176 return array_length > 0;
177}
178
179// The number of input or output ports described by a specific descriptor
180// 1 for non-array descriptors, ARRAY_SIZE for array descriptors
181template <typename Node, PortDirection Direction, size_t DescriptorIndex>
182constexpr size_t descriptorPortSize()
183{
184 constexpr size_t array_length = std::get<dw::framework::PORT_ARRAY_SIZE>(
185 dw::core::get<DescriptorIndex>(describePorts<Node, Direction>()));
186 if (array_length == 0)
187 {
188 return 1;
189 }
190 return array_length;
191}
192
193// The binding of input or output ports described by a specific descriptor
194template <typename Node, PortDirection Direction, size_t DescriptorIndex>
196{
197 constexpr PortBinding port_binding = std::get<dw::framework::PORT_BINDING>(
198 dw::core::get<DescriptorIndex>(describePorts<Node, Direction>()));
199 return port_binding;
200}
201
202// The comment of input or output ports described by a specific descriptor
203template <typename Node, PortDirection Direction, size_t DescriptorIndex>
204constexpr dw::core::StringView descriptorPortComment()
205{
206 constexpr dw::core::StringView port_comment = std::get<dw::framework::PORT_COMMENT>(
207 dw::core::get<DescriptorIndex>(describePorts<Node, Direction>()));
208 return port_comment;
209}
210
211// Return type is the type of the descriptor, to be used with decltype()
212template <typename Node, PortDirection Direction, size_t DescriptorIndex>
213constexpr auto portDescriptorType()
214{
215 // since the PortDescriptor contains a T* to avoid storing an actual
216 // instance of T the pointer needs to be removed here
217 return std::remove_pointer_t<
218 typename std::tuple_element_t<
220 typename dw::core::tuple_element_t<
221 DescriptorIndex,
222 decltype(describePorts<Node, Direction>())>>>();
223}
224
225// Number of ports for a specific direction (sum across all descriptors)
226namespace detail
227{
228
229template <
230 typename Node, PortDirection Direction, size_t DescriptorIndex,
231 typename std::enable_if_t<DescriptorIndex == portDescriptorSize<Node, Direction>(), void>* = nullptr>
232constexpr std::size_t portSize()
233{
234 return 0;
235}
236
237template <
238 typename Node, PortDirection Direction, size_t DescriptorIndex,
239 typename std::enable_if_t<DescriptorIndex<portDescriptorSize<Node, Direction>(), void>* = nullptr> constexpr std::size_t portSize()
240{
241 return descriptorPortSize<Node, Direction, DescriptorIndex>() + portSize<Node, Direction, DescriptorIndex + 1>();
242}
243
244} // namespace detail
245
246template <typename Node, PortDirection Direction>
247constexpr std::size_t portSize()
248{
249 return detail::portSize<Node, Direction, 0>();
250}
251
252// Descriptor index from port index
253namespace detail
254{
255
256template <
257 typename Node, PortDirection Direction, size_t DescriptorIndex, size_t RemainingPortIndex,
258 typename std::enable_if_t<DescriptorIndex == portDescriptorSize<Node, Direction>(), void>* = nullptr>
259constexpr std::size_t descriptorIndex()
260{
261 return 0;
262}
263
264template <
265 typename Node, PortDirection Direction, size_t DescriptorIndex, size_t RemainingPortIndex,
266 typename std::enable_if_t<DescriptorIndex<portDescriptorSize<Node, Direction>(), void>* = nullptr> constexpr std::size_t descriptorIndex()
267{
268 if (RemainingPortIndex < descriptorPortSize<Node, Direction, DescriptorIndex>())
269 {
270 return 0;
271 }
272 constexpr size_t remainingPortIndex = RemainingPortIndex - descriptorPortSize<Node, Direction, DescriptorIndex>();
273 return 1 + descriptorIndex<Node, Direction, DescriptorIndex + 1, remainingPortIndex>();
274}
275
276} // namespace detail
277
278template <typename Node, PortDirection Direction, size_t PortIndex>
279constexpr size_t descriptorIndex()
280{
281 if (Direction == PortDirection::OUTPUT)
282 {
283 return detail::descriptorIndex<Node, Direction, 0, PortIndex - portSize<Node, PortDirection::INPUT>()>();
284 }
285 return detail::descriptorIndex<Node, Direction, 0, PortIndex>();
286}
287
288// Return type is the type of the port, to be used with decltype()
289template <typename Node, PortDirection Direction, size_t PortIndex>
290constexpr auto portType()
291{
292 constexpr size_t index = descriptorIndex<Node, Direction, PortIndex>();
293 return portDescriptorType<Node, Direction, index>();
294}
295
296// Check if port index is valid
297template <typename Node, PortDirection Direction>
298constexpr bool isValidPort(std::size_t portID)
299{
300 // only temporarily for backward compatibility with enum value
301 // output port indices are offset by the number of input ports
302 if (Direction == PortDirection::OUTPUT)
303 {
304 return portID >= portSize<Node, PortDirection::INPUT>() && portID < portSize<Node, PortDirection::INPUT>() + portSize<Node, Direction>();
305 }
306 return portID < portSize<Node, Direction>();
307}
308
309// Array size for an array port name, 0 for non-array ports
310namespace detail
311{
312
313template <
314 typename Node, PortDirection Direction, size_t DescriptorIndex,
315 typename std::enable_if_t<DescriptorIndex == portDescriptorSize<Node, Direction>(), void>* = nullptr>
316constexpr std::size_t portArraySize(StringView identifier)
317{
318 (void)identifier;
319 return 0;
320}
321
322template <
323 typename Node, PortDirection Direction, size_t DescriptorIndex,
324 typename std::enable_if_t<DescriptorIndex<portDescriptorSize<Node, Direction>(), void>* = nullptr> constexpr std::size_t portArraySize(StringView identifier)
325{
326 constexpr auto descriptorName = std::get<dw::framework::PORT_NAME>(dw::core::get<DescriptorIndex>(describePorts<Node, Direction>()));
327 if (descriptorName == identifier)
328 {
329 return descriptorPortSize<Node, Direction, DescriptorIndex>();
330 }
331 return portArraySize<Node, Direction, DescriptorIndex + 1>(identifier);
332}
333
334} // namespace detail
335
336template <typename Node, PortDirection Direction>
337constexpr size_t portArraySize(StringView identifier)
338{
339 return detail::portArraySize<Node, Direction, 0>(identifier);
340}
341
342// Get the port index for a give port name
343namespace detail
344{
345
346template <
347 typename Node, PortDirection Direction, size_t DescriptorIndex,
348 typename std::enable_if_t<DescriptorIndex == portDescriptorSize<Node, Direction>(), void>* = nullptr>
349constexpr std::size_t portIndex(StringView identifier)
350{
351 (void)identifier;
352 // since output port indices follow input port indices
353 // this must add the number of output port for invalid input port identifier
354 // to avoid that for an invalid input port identifier the index of the first output port is returned
355 if (Direction == PortDirection::INPUT)
356 {
357 return dw::framework::portSize<Node, PortDirection::OUTPUT>();
358 }
359 return 0;
360}
361
362template <
363 typename Node, PortDirection Direction, size_t DescriptorIndex,
364 typename std::enable_if_t<DescriptorIndex<portDescriptorSize<Node, Direction>(), void>* = nullptr> constexpr std::size_t portIndex(StringView identifier)
365{
366 constexpr auto descriptorName = std::get<dw::framework::PORT_NAME>(dw::core::get<DescriptorIndex>(describePorts<Node, Direction>()));
367 if (descriptorName == identifier)
368 {
369 return 0;
370 }
371 return descriptorPortSize<Node, Direction, DescriptorIndex>() + portIndex<Node, Direction, DescriptorIndex + 1>(identifier);
372}
373
374} // namespace detail
375
376template <typename Node, PortDirection Direction>
377constexpr size_t portIndex(StringView identifier)
378{
379 // only temporarily for backward compatibility with enum value
380 // output port indices are offset by the number of input ports
381 if (Direction == PortDirection::OUTPUT)
382 {
383 return portSize<Node, PortDirection::INPUT>() + detail::portIndex<Node, Direction, 0>(identifier);
384 }
385 return detail::portIndex<Node, Direction, 0>(identifier);
386}
387
388// Check if given string is a valid port name
389template <typename Node, PortDirection Direction>
390constexpr bool isValidPort(StringView identifier)
391{
392 constexpr size_t index = portIndex<Node, Direction>(identifier);
393 return isValidPort<Node, Direction>(index);
394}
395
396// Get the port index for a give port name
397namespace detail
398{
399
400template <
401 typename Node, PortDirection Direction, size_t DescriptorIndex,
402 typename std::enable_if_t<DescriptorIndex == portDescriptorSize<Node, Direction>(), void>* = nullptr>
403constexpr std::size_t portDescriptorIndex(StringView identifier)
404{
405 (void)identifier;
406 return 0;
407}
408
409template <
410 typename Node, PortDirection Direction, size_t DescriptorIndex,
411 typename std::enable_if_t<DescriptorIndex<portDescriptorSize<Node, Direction>(), void>* = nullptr> constexpr std::size_t portDescriptorIndex(StringView identifier)
412{
413 constexpr auto descriptorName = std::get<dw::framework::PORT_NAME>(dw::core::get<DescriptorIndex>(describePorts<Node, Direction>()));
414 if (descriptorName == identifier)
415 {
416 return 0;
417 }
418 return 1 + portDescriptorIndex<Node, Direction, DescriptorIndex + 1>(identifier);
419}
420
421} // namespace detail
422
423template <typename Node, PortDirection Direction>
424constexpr size_t portDescriptorIndex(StringView identifier)
425{
426 return detail::portDescriptorIndex<Node, Direction, 0>(identifier);
427}
428
429} // namespace framework
430} // namespace dw
431
432#endif // DW_FRAMEWORK_PORTDESCRIPTOR_HPP_
constexpr auto describePorts()
constexpr bool descriptorPortArray()
constexpr size_t portIndex(StringView identifier)
constexpr size_t descriptorPortSize()
constexpr size_t portDescriptorIndex(StringView identifier)
static constexpr size_t PORT_BINDING
constexpr auto portDescriptorType()
constexpr auto describePortCollection(Args &&... args)
constexpr size_t portArraySize(StringView identifier)
constexpr bool isValidPort(std::size_t portID)
constexpr std::size_t portDescriptorSize()
constexpr auto describeOutputPorts()
static constexpr size_t PORT_NAME
static constexpr size_t PORT_COMMENT
static constexpr size_t PORT_ARRAY_SIZE
static constexpr size_t PORT_TYPE
constexpr std::size_t portSize()
constexpr PortBinding descriptorPortBinding()
static constexpr size_t PORT_TYPE_NAME
constexpr auto describePort(dw::core::StringView typeName, dw::core::StringView name, PortBinding binding=PortBinding::OPTIONAL, dw::core::StringView comment=""_sv)
constexpr auto describeInputPorts()
constexpr dw::core::StringView descriptorPortComment()
constexpr auto portType()
constexpr size_t descriptorIndex()
constexpr auto describePortArray(dw::core::StringView typeName, dw::core::StringView name, PortBinding binding=PortBinding::OPTIONAL, dw::core::StringView comment=""_sv)
Definition: Exception.hpp:47