Loading...
Searching...
No Matches
typeRegistry.h
Go to the documentation of this file.
1//
2// Copyright 2025 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusd.org/license.
6//
7#ifndef PXR_EXEC_EXEC_TYPE_REGISTRY_H
8#define PXR_EXEC_EXEC_TYPE_REGISTRY_H
9
11
12#include "pxr/pxr.h"
13
14#include "pxr/exec/exec/api.h"
15#include "pxr/exec/exec/valueExtractorFunction.h"
16
18#include "pxr/exec/vdf/mask.h"
20#include "pxr/exec/vdf/vector.h"
21
22#include "pxr/base/tf/refPtr.h"
24#include "pxr/base/tf/type.h"
25#include "pxr/base/vt/array.h"
26#include "pxr/base/vt/traits.h"
27#include "pxr/base/vt/types.h"
28#include "pxr/base/vt/value.h"
29
30#include <tbb/concurrent_unordered_map.h>
31
32#include <algorithm>
33#include <memory>
34#include <type_traits>
35
36PXR_NAMESPACE_OPEN_SCOPE
37
38class Exec_ValueExtractor;
39class VdfMask;
40
50{
51public:
52 ExecTypeRegistry(ExecTypeRegistry const&) = delete;
53 ExecTypeRegistry& operator=(ExecTypeRegistry const&) = delete;
54
56
60 EXEC_API
62
124 template <typename ValueType>
125 static void RegisterType(const ValueType &fallback);
126
135 template <typename ValueType>
138 "Use ExecTypeRegistry::RegisterType<T>() to register execution "
139 "value types.");
140 }
141
143 EXEC_API
144 VdfVector CreateVector(const VtValue &value) const;
145
153 EXEC_API
154 Exec_ValueExtractor GetExtractor(TfType type) const;
155
156private:
157 // Only TfSingleton can create instances.
158 friend class TfSingleton<ExecTypeRegistry>;
159
160 // Provides access for registraion of types only.
161 EXEC_API
162 static ExecTypeRegistry& _GetInstanceForRegistration();
163
165
166 template <typename ValueType>
167 void _RegisterType(ValueType const &fallback);
168
169 template <typename T>
170 struct _CreateVector {
171 // Interface for VdfTypeDispatchTable.
172 static VdfVector Call(const VtValue &value) {
173 return Create(value.UncheckedGet<T>());
174 }
175 // Typed implementation of CreateVector.
176 //
177 // This is separate from Call so that it can be shared with the
178 // Vt known type optimization in CreateVector.
179 static VdfVector Create(const T &value);
180 };
181
182 // Returns the appropriate value extractor for T.
183 //
184 // When T is a VtArray type, the returned extractor expects a VdfVector
185 // holding T::value_type elements as its input.
186 //
187 template <typename T>
188 static auto _MakeExtractorFunction();
189
190 // Specify that values of \p type should be extracted using \p function.
191 EXEC_API
192 void _RegisterExtractor(
193 TfType type,
194 Exec_ValueExtractorFunction &extractor);
195
196 // Type trait that evaluates to true if T is a pointer type that is safe to
197 // use as an exec value type, but that points to non-const data (which is
198 // not safe).
199 //
200 // This isn't intended to be a general purpose trait, and it isn't intended
201 // to guarantee that unsafe pointer types can't be used as value types. This
202 // is used to provide compile time feedback for _some_ pointer types that
203 // aren't / safe to use as exec value types.
204 //
205 // Note that many pointer types are disallowed regardless of the type they
206 // point to for other reasons (e.g., std::unique_ptr isn't copyable and
207 // std::weak_ptr doesn't support equality comparison).
208 //
209 // TODO: We should be able to use inline constexpr variable templates, but
210 // gcc 11.5 incorrectly rejects class-scope partial specializations:
211 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71954
212
213 template <typename T>
214 struct _IsPointerToNonConst : std::false_type {};
215
216 template <typename T>
217 struct _IsPointerToNonConst<std::shared_ptr<T>> :
218 std::negation<std::is_const<T>> {};
219
220 template <typename T>
221 struct _IsPointerToNonConst<TfRefPtr<T>> :
222 std::negation<std::is_const<T>> {};
223
224private:
225
227
228 // Type-erased conversions from VdfVector to VtValue.
229 //
230 // Inside of execution, there is no distinction between a scalar value and
231 // an array value of length 1. However, systems that interact with
232 // execution may desire single values be returned directly in VtValue or
233 // as a VtValue holding a VtArray depending on the context. The type key
234 // specifies the type held in the resulting VtValue. There are separate
235 // extractors for T and VtArray<T> but they both accepts VdfVectors
236 // holding T.
237 //
238 // Note that this must support the possibility that one thread is querying
239 // extractors at the same time that another thread is registering
240 // additional types.
241 //
242 tbb::concurrent_unordered_map<TfType, Exec_ValueExtractor, TfHash>
243 _extractors;
244};
245
246template <typename ValueType>
247void
248ExecTypeRegistry::RegisterType(const ValueType &fallback)
249{
250 using T = std::decay_t<ValueType>;
251 static_assert(
252 std::is_copy_constructible_v<T> && std::is_copy_assignable_v<T>,
253 "Execution value types must be copyable.");
254 static_assert(
256 "Execution value types must support equality comparison.");
257 static_assert(
258 !std::is_pointer_v<T>,
259 "Raw pointers are not supported execution value types.");
260 static_assert(
261 !_IsPointerToNonConst<T>::value,
262 "Pointers to non-const data are not supported execution value "
263 "types.");
264 static_assert(
266 "VtArray is not a supported execution value type.");
267
268 _GetInstanceForRegistration()._RegisterType(fallback);
269}
270
271template <typename ValueType>
272void
273ExecTypeRegistry::_RegisterType(ValueType const &fallback)
274{
275 const TfType type = VdfExecutionTypeRegistry::Define(fallback);
276
277 // CreateVector has internal handling for value types known to Vt so we do
278 // not need to register them here.
279 if constexpr (!VtIsKnownValueType<ValueType>()) {
280 _createVector.RegisterType<ValueType>();
281 }
282
283 _RegisterExtractor(type, *+_MakeExtractorFunction<ValueType>());
284}
285
286template <typename T>
288ExecTypeRegistry::_CreateVector<T>::Create(const T &value)
289{
290 if constexpr (!VtIsArray<T>::value) {
292 v.Set(value);
293 return v;
294 }
295 else {
296 using ElementType = typename T::value_type;
297
298 const size_t size = value.size();
299
300 Vdf_BoxedContainer<ElementType> execValue(size);
301 std::copy_n(value.cdata(), size, execValue.data());
302
304 v.Set(std::move(execValue));
305 return v;
306 }
307}
308
309template <typename T>
310auto
311ExecTypeRegistry::_MakeExtractorFunction()
312{
313 if constexpr (!VtIsArray<T>::value) {
314 return [](const VdfVector &v, const VdfMask::Bits &mask) {
315 const VdfVector::ReadAccessor access =
316 v.GetReadAccessor<T>();
317
318 if (access.IsEmpty()) {
319 return VtValue();
320 }
321
322 if (!TF_VERIFY(mask.GetNumSet() == 1)) {
323 return VtValue();
324 }
325
326 const int offset = mask.GetFirstSet();
327 return VtValue(access[offset]);
328 };
329 }
330 else {
331 return [](const VdfVector &v, const VdfMask::Bits &mask) {
332 using ElementType = typename T::value_type;
333
334 if (!TF_VERIFY(mask.AreContiguouslySet())) {
335 return VtValue();
336 }
337
338 const VdfVector::ReadAccessor access =
339 v.GetReadAccessor<ElementType>();
340
341 const int offset = mask.GetFirstSet();
342 const size_t numValues = access.IsBoxed()
343 ? access.GetNumValues()
344 : mask.GetNumSet();
345 return VtValue(v.ExtractAsVtArray<ElementType>(numValues, offset));
346 };
347 }
348}
349
350PXR_NAMESPACE_CLOSE_SCOPE
351
352#endif
Defines all the types "TYPED" for which Vt creates a VtTYPEDArray typedef.
constexpr bool VtIsKnownValueType()
Returns true if T is a type that appears in VT_VALUE_TYPES.
Definition types.h:288
Singleton used to register and access value types used by exec computations.
EXEC_API VdfVector CreateVector(const VtValue &value) const
Construct a VdfVector whose value is copied from value.
TfType CheckForRegistration() const
Confirms that ValueType has been registered.
static void RegisterType(const ValueType &fallback)
Registers ValueType as a type that exec computations can use for input and output values,...
static EXEC_API const ExecTypeRegistry & GetInstance()
Provides access to the singleton instance, first ensuring it is constructed.
EXEC_API Exec_ValueExtractor GetExtractor(TfType type) const
Returns an extractor that produces a VtValue from values held in execution.
Fast, compressed bit array which is capable of performing logical operations without first decompress...
Reference-counted smart pointer utility class.
Definition refPtr.h:590
Manage a single instance of an object (see.
Definition singleton.h:107
TfType represents a dynamic runtime type.
Definition type.h:48
This simple container stores multiple values that flow through the network as a single data flow elem...
static TfType CheckForRegistration(const char *const additionalErrorMsg=nullptr)
Checks if T is defined as an execution value type.
static TfType Define(const T &fallback)
Registers T with execution's runtime type dispatch system.
A VdfMask is placed on connections to specify the data flowing through them.
Definition mask.h:37
Dispatches calls to template instantiations based on a TfType that is determined at runtime.
bool RegisterType()
Register an additional type with the type dispatch table.
A VdfTypedVector implements a VdfVector with a specific type.
Definition typedVector.h:23
A read-only accessor for low-level acces to the contents of the VdfVector.
Definition vector.h:479
bool IsBoxed() const
Returns true if this accessor is providing element-wise access into a boxed container.
Definition vector.h:497
bool IsEmpty() const
Returns true if the vector is empty.
Definition vector.h:488
size_t GetNumValues() const
Returns the size of the vector, i.e.
Definition vector.h:492
This class is used to abstract away knowledge of the cache data used for each node.
Definition vector.h:59
void Set(TYPE &&data)
Forwards data into the vector.
Definition vector.h:165
VtArray< T > ExtractAsVtArray(const size_t size, const int offset) const
Extracts this vector's values into a VtArray<T>.
Definition vector.h:380
ReadAccessor< TYPE > GetReadAccessor() const
GetReadAccessor() allows low level read-only access to the content of of the VdfVector via the Vdf_Ve...
Definition vector.h:524
Provides a container which may hold any type, and provides introspection and iteration over array typ...
Definition value.h:90
constexpr bool VdfIsEqualityComparable
Variable template that returns true if equality comparison is a valid operation for type T.
Definition traits.h:49
#define TF_VERIFY(cond, format,...)
Checks a condition and reports an error if it evaluates false.
Definition diagnostic.h:267
STL namespace.
Reference counting.
Manage a single instance of an object.
A trait to detect instantiations of VtArray, specialized in array.h.
Definition traits.h:22