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

NodeFactory.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_NODEFACTORY_HPP_
32 #define DW_FRAMEWORK_NODEFACTORY_HPP_
33 
34 #include <dwcgf/node/Node.hpp>
35 
36 #include <dwcgf/logger/Logger.hpp>
40 
41 #include <dw/core/container/VectorFixed.hpp>
42 #include <dw/core/container/StringView.hpp>
43 
44 #include <iostream>
45 #include <map>
46 #include <memory>
47 #include <mutex>
48 
49 namespace dw
50 {
51 namespace framework
52 {
53 
54 class Node;
55 class ParameterProvider;
56 
57 namespace detail
58 {
59 
60 class AbstractMetaObject
61 {
62 public:
63  AbstractMetaObject(const dw::core::StringView className);
64 
65  virtual ~AbstractMetaObject() = default;
66 
67  const dw::core::StringView& className() const;
68 
69  virtual const PortCollectionDescriptor& getInputPorts() const = 0;
70 
71  virtual const PortCollectionDescriptor& getOutputPorts() const = 0;
72 
73  virtual const ParameterCollectionDescriptor& getParameters() const = 0;
74 
75  virtual const PassCollectionDescriptor& getPasses() const = 0;
76 
77  virtual std::unique_ptr<Node> create(ParameterProvider& provider) const = 0;
78 
79 protected:
80  dw::core::StringView m_className;
81 };
82 
83 typedef std::map<dw::core::StringView, std::unique_ptr<AbstractMetaObject>> FactoryMap;
84 
85 FactoryMap& getFactoryMap();
86 
87 std::recursive_mutex& getFactoryMapMutex();
88 
89 template <typename NodeT>
90 class MetaObject : public AbstractMetaObject
91 {
92 public:
93  MetaObject(const dw::core::StringView className)
94  : AbstractMetaObject(std::move(className))
95  {
96  }
97 
98  const PortCollectionDescriptor& getInputPorts() const override
99  {
100  static const PortCollectionDescriptor descriptor = createPortCollectionDescriptor<NodeT, PortDirection::INPUT>();
101  return descriptor;
102  }
103 
104  const PortCollectionDescriptor& getOutputPorts() const override
105  {
106  static const PortCollectionDescriptor descriptor = createPortCollectionDescriptor<NodeT, PortDirection::OUTPUT>();
107  return descriptor;
108  }
109 
110  const ParameterCollectionDescriptor& getParameters() const override
111  {
112  static const ParameterCollectionDescriptor descriptor = createParameterCollectionDescriptor<NodeT>();
113  return descriptor;
114  }
115 
116  const PassCollectionDescriptor& getPasses() const override
117  {
118  static const PassCollectionDescriptor descriptor = createPassCollectionDescriptor<NodeT>();
119  return descriptor;
120  }
121 
122  std::unique_ptr<Node> create(ParameterProvider& provider) const override
123  {
124  return NodeT::create(provider);
125  }
126 };
127 
128 } // namespace detail
129 
130 template <typename NodeT>
131 void registerNode(const char* className)
132 {
133  auto metaObject = std::make_unique<detail::MetaObject<NodeT>>(className);
134  if (!metaObject)
135  {
136  throw Exception(DW_BAD_ALLOC, "NodeFactory: cannot allocate meta object");
137  }
138 
139  std::lock_guard<std::recursive_mutex> lock(detail::getFactoryMapMutex());
140  auto& factoryMap = detail::getFactoryMap();
141  if (factoryMap.find(className) != factoryMap.end())
142  {
143  throw Exception(DW_INVALID_ARGUMENT, "registerNode() repeatedly called for the same class name: ", className);
144  }
145  else
146  {
147  factoryMap[className] = std::move(metaObject);
148  }
149 }
150 
151 dw::core::HeapVectorFixed<dw::core::StringView> getNodeNames();
152 
153 const PortCollectionDescriptor& getInputPorts(const dw::core::StringView& className);
154 
155 const PortCollectionDescriptor& getOutputPorts(const dw::core::StringView& className);
156 
157 const ParameterCollectionDescriptor& getParameters(const dw::core::StringView& className);
158 
159 const PassCollectionDescriptor& getPasses(const dw::core::StringView& className);
160 
161 std::unique_ptr<Node> createNode(const dw::core::StringView& className, ParameterProvider& provider);
162 
163 } // namespace framework
164 } // namespace dw
165 
166 #define _DW_REGISTER_NODE_WITH_SUFFIX(NodeT, UniqueSuffix) \
167  namespace \
168  { \
169  struct Proxy##UniqueSuffix \
170  { \
171  Proxy##UniqueSuffix() \
172  { \
173  dw::framework::registerNode<NodeT>(#NodeT); \
174  } \
175  }; \
176  static Proxy##UniqueSuffix g_registerNode##UniqueSuffix; \
177  } // namespace
178 
179 #define _DW_REGISTER_NODE(NodeT) \
180  _DW_REGISTER_NODE_WITH_SUFFIX(NodeT, UniqueSuffix)
181 
182 #define _DW_REGISTER_NODE_GET_3RD_ARG(arg1, arg2, arg3, ...) arg3
183 #define _DW_REGISTER_NODE_MACRO_CHOOSER(...) \
184  _DW_REGISTER_NODE_GET_3RD_ARG(__VA_ARGS__, _DW_REGISTER_NODE_WITH_SUFFIX, _DW_REGISTER_NODE, )
185 
186 #define DW_REGISTER_NODE(...) \
187  _DW_REGISTER_NODE_MACRO_CHOOSER(__VA_ARGS__) \
188  (__VA_ARGS__)
189 
190 #endif //DW_FRAMEWORK_NODEFACTORY_HPP_
const PortCollectionDescriptor & getInputPorts(const dw::core::StringView &className)
std::unique_ptr< Node > createNode(const dw::core::StringView &className, ParameterProvider &provider)
const PortCollectionDescriptor & getOutputPorts(const dw::core::StringView &className)
dw::core::HeapVectorFixed< dw::core::StringView > getNodeNames()
const ParameterCollectionDescriptor & getParameters(const dw::core::StringView &className)
auto create(const ParameterProvider &provider) -> std::unique_ptr< NodeT >
Instantiate a node using parameters from the passed provider.
void registerNode(const char *className)
Definition: Exception.hpp:46
const PassCollectionDescriptor & getPasses(const dw::core::StringView &className)
The interface to access parameter values identified by name and/or (semantic) type.