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

PortDescriptor.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_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 
44 namespace dw
45 {
46 namespace framework
47 {
48 
49 // API needed to declare the ports of a node.
50 
51 template <typename... Args>
52 constexpr auto describePortCollection(Args&&... args)
53 {
54  return dw::core::make_tuple<Args...>(std::forward<Args>(args)...);
55 }
56 
57 static constexpr size_t PORT_TYPE_NAME = 0;
58 static constexpr size_t PORT_NAME = 1;
59 static constexpr size_t PORT_TYPE = 2;
60 static constexpr size_t PORT_ARRAY_SIZE = 3;
61 static constexpr size_t PORT_BINDING = 4;
62 static constexpr size_t PORT_COMMENT = 5;
63 
64 enum 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 
73 template <typename PortType>
74 constexpr 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 
86 template <typename PortType>
87 constexpr 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 
99 template <
100  typename PortType,
101  size_t ArraySize,
102  typename std::enable_if_t<ArraySize != 0, void>* = nullptr>
103 constexpr 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 
115 template <
116  typename PortType,
117  size_t ArraySize,
118  typename std::enable_if_t<ArraySize != 0, void>* = nullptr>
119 constexpr 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 
131 template <typename Node>
132 constexpr auto describeInputPorts()
133 {
134  return Node::describeInputPorts();
135 }
136 
137 template <typename Node>
138 constexpr auto describeOutputPorts()
139 {
140  return Node::describeOutputPorts();
141 }
142 
143 template <
144  typename Node,
145  PortDirection Direction,
146  typename std::enable_if_t<Direction == PortDirection::INPUT, void>* = nullptr>
147 constexpr auto describePorts()
148 {
149  return describeInputPorts<Node>();
150 }
151 
152 template <
153  typename Node,
154  PortDirection Direction,
155  typename std::enable_if_t<Direction == PortDirection::OUTPUT, void>* = nullptr>
156 constexpr 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
164 template <typename Node, PortDirection Direction>
165 constexpr 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
171 template <typename Node, PortDirection Direction, size_t DescriptorIndex>
172 constexpr 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
181 template <typename Node, PortDirection Direction, size_t DescriptorIndex>
182 constexpr 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
194 template <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
203 template <typename Node, PortDirection Direction, size_t DescriptorIndex>
204 constexpr 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()
212 template <typename Node, PortDirection Direction, size_t DescriptorIndex>
213 constexpr 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)
226 namespace detail
227 {
228 
229 template <
230  typename Node, PortDirection Direction, size_t DescriptorIndex,
231  typename std::enable_if_t<DescriptorIndex == portDescriptorSize<Node, Direction>(), void>* = nullptr>
232 constexpr std::size_t portSize()
233 {
234  return 0;
235 }
236 
237 template <
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 
246 template <typename Node, PortDirection Direction>
247 constexpr std::size_t portSize()
248 {
249  return detail::portSize<Node, Direction, 0>();
250 }
251 
252 // Descriptor index from port index
253 namespace detail
254 {
255 
256 template <
257  typename Node, PortDirection Direction, size_t DescriptorIndex, size_t RemainingPortIndex,
258  typename std::enable_if_t<DescriptorIndex == portDescriptorSize<Node, Direction>(), void>* = nullptr>
259 constexpr std::size_t descriptorIndex()
260 {
261  return 0;
262 }
263 
264 template <
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 
278 template <typename Node, PortDirection Direction, size_t PortIndex>
279 constexpr 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()
289 template <typename Node, PortDirection Direction, size_t PortIndex>
290 constexpr 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
297 template <typename Node, PortDirection Direction>
298 constexpr 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
310 namespace detail
311 {
312 
313 template <
314  typename Node, PortDirection Direction, size_t DescriptorIndex,
315  typename std::enable_if_t<DescriptorIndex == portDescriptorSize<Node, Direction>(), void>* = nullptr>
316 constexpr std::size_t portArraySize(StringView identifier)
317 {
318  (void)identifier;
319  return 0;
320 }
321 
322 template <
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 
336 template <typename Node, PortDirection Direction>
337 constexpr 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
343 namespace detail
344 {
345 
346 template <
347  typename Node, PortDirection Direction, size_t DescriptorIndex,
348  typename std::enable_if_t<DescriptorIndex == portDescriptorSize<Node, Direction>(), void>* = nullptr>
349 constexpr 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 
362 template <
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 
376 template <typename Node, PortDirection Direction>
377 constexpr 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
389 template <typename Node, PortDirection Direction>
390 constexpr 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
397 namespace detail
398 {
399 
400 template <
401  typename Node, PortDirection Direction, size_t DescriptorIndex,
402  typename std::enable_if_t<DescriptorIndex == portDescriptorSize<Node, Direction>(), void>* = nullptr>
403 constexpr std::size_t portDescriptorIndex(StringView identifier)
404 {
405  (void)identifier;
406  return 0;
407 }
408 
409 template <
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 
423 template <typename Node, PortDirection Direction>
424 constexpr 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 std::size_t portSize()
constexpr auto describePort(dw::core::StringView typeName, dw::core::StringView name, PortBinding binding=PortBinding::OPTIONAL, dw::core::StringView comment=""_sv)
constexpr std::size_t portDescriptorSize()
constexpr size_t portIndex(StringView identifier)
constexpr dw::core::StringView descriptorPortComment()
static constexpr size_t PORT_NAME
constexpr bool descriptorPortArray()
constexpr size_t descriptorPortSize()
constexpr auto describeOutputPorts()
static constexpr size_t PORT_TYPE_NAME
static constexpr size_t PORT_COMMENT
static constexpr size_t PORT_TYPE
constexpr PortBinding descriptorPortBinding()
constexpr bool isValidPort(std::size_t portID)
static constexpr size_t PORT_ARRAY_SIZE
constexpr size_t portDescriptorIndex(StringView identifier)
constexpr auto portDescriptorType()
constexpr auto portType()
constexpr auto describePortArray(dw::core::StringView typeName, dw::core::StringView name, PortBinding binding=PortBinding::OPTIONAL, dw::core::StringView comment=""_sv)
constexpr auto describeInputPorts()
constexpr auto describePortCollection(Args &&... args)
Definition: Exception.hpp:46
static constexpr size_t PORT_BINDING
constexpr auto describePorts()
constexpr size_t portArraySize(StringView identifier)
constexpr size_t descriptorIndex()