Loading...
Searching...
No Matches
context.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_VDF_CONTEXT_H
8#define PXR_EXEC_VDF_CONTEXT_H
9
11
12#include "pxr/pxr.h"
13
14#include "pxr/exec/vdf/api.h"
16#include "pxr/exec/vdf/error.h"
20#include "pxr/exec/vdf/node.h"
22#include "pxr/exec/vdf/traits.h"
23#include "pxr/exec/vdf/types.h"
24#include "pxr/exec/vdf/vector.h"
25
29
30PXR_NAMESPACE_OPEN_SCOPE
31
32class TfToken;
33
40{
41public:
42
43 // VdfContext should not be copied or assigned to.
44 VdfContext(const VdfContext &rhs) = delete;
45 VdfContext &operator=(const VdfContext &rhs) = delete;
46
51 const VdfEvaluationState &state,
52 const VdfNode &node) :
53 VdfContext(state, node, VdfScheduleTaskInvalid)
54 {}
55
60 const VdfEvaluationState &state,
61 const VdfNode &node,
62 const VdfScheduleTaskIndex invocation) :
63 _state(state),
64 _node(node),
65 _invocation(invocation)
66 {}
67
72 template<typename T>
74 GetInputValue(const TfToken &name) const;
75
79 template<typename T>
80 inline const T *
81 GetInputValuePtr(const TfToken &name) const;
82
86 template<typename T>
87 inline const T *
88 GetInputValuePtr(const TfToken &name, const T *defPtr) const;
89
100 template<typename T>
101 inline bool HasInputValue(const TfToken &name) const;
102
105 VDF_API
106 bool HasInputValue(const TfToken &name) const;
107
119 VDF_API
120 bool IsOutputRequested(const TfToken &outputName) const;
121
130 template<typename T>
131 inline void SetOutput(const TfToken &outputName,
132 const T &value) const;
133
145 template<typename T>
146 inline void SetOutput(const T &value) const;
147
160 template<typename T>
161 inline void SetOutput(T &&value) const;
162
172 template<typename T>
173 inline void SetOutput(const TfToken &outputName,
174 T &&value) const;
175
181 VDF_API
182 void SetEmptyOutput() const;
183
186 VDF_API
187 void SetEmptyOutput(const TfToken &outputName) const;
188
199 VDF_API
200 void SetOutputToReferenceInput(const TfToken &inputName) const;
201
202
205
214 VDF_API
215 void Warn(const char *fmt, ...) const ARCH_PRINTF_FUNCTION(2, 3);
216
217
219
220
223
226 VDF_API
227 std::string GetNodeDebugName() const;
228
233 VDF_API
234 void CodingError(const char *fmt, ...) const ARCH_PRINTF_FUNCTION(2, 3);
235
237
238
239private:
240
241 // This API is for VdfIterators to access internal context data.
242 friend class VdfIterator;
243
244 // Speculation nodes need to call _GetExecutor.
245 friend class VdfSpeculationNode;
246
247 // Returns the first input value on the given input, or a null pointer, if
248 // no such value exists.
249 //
250 template<typename T>
251 inline const T *_GetFirstInputValue(const TfToken &name) const;
252
253 // Retrieves the request and affects mask of the requested output, if
254 // available. Returns \c true if the output is scheduled, and \c false
255 // otherwise.
256 //
257 // Note, output must be an output on the current node!
258 //
259 VDF_API
260 bool _GetOutputMasks(
261 const VdfOutput &output,
262 const VdfMask **requestMask,
263 const VdfMask **affectsMask) const;
264
265 // Returns true when the output is scheduled and required, and
266 // false otherwise. Used by special iterators to avoid computing outputs
267 // that aren't necessary.
268 //
269 VDF_API
270 bool _IsRequiredOutput(const VdfOutput &output) const;
271
272 // Returns the request mask of \p output, if the output has been scheduled
273 // and \c NULL otherwise.
274 //
275 const VdfMask *_GetRequestMask(const VdfOutput &output) const;
276
277 // Returns the current node
278 //
279 const VdfNode &_GetNode() const { return _node; }
280
281 // Returns the executor for this context.
282 //
283 const VdfExecutorInterface &_GetExecutor() const { return _state.GetExecutor(); }
284
285 // Returns the schedule for this context.
286 //
287 const VdfSchedule &_GetSchedule() const { return _state.GetSchedule(); }
288
289 // Returns the error logger for this context.
290 //
291 VdfExecutorErrorLogger *_GetErrorLogger() const {
292 return _state.GetErrorLogger();
293 }
294
295private:
296
297 // The evaluation state
298 const VdfEvaluationState &_state;
299
300 // The node this context has been built for.
301 const VdfNode &_node;
302
303 // The current node invocation index. If this context is not for a node
304 // with multiple invocations, this will be set to VdfScheduleTaskInvalid.
305 const VdfScheduleTaskIndex _invocation;
306};
307
309
310template<typename T>
313{
314 // Calling this API means that the client expects there to be one and
315 // only one value, so we always return the first one here if there are
316 // any.
317 if (const T *value = _GetFirstInputValue<T>(name)) {
318 return *value;
319 }
320
322 "No input value for token '%s' on node '%s'",
323 name.GetText(), GetNodeDebugName().c_str());
324
325 // Ask the type registry for the fallback value to use.
327}
328
329template<typename T>
330inline const T *
332{
333 return _GetFirstInputValue<T>(name);
334}
335
336template<typename T>
337inline const T *
338VdfContext::GetInputValuePtr(const TfToken &name, const T *defPtr) const
339{
340 const T *value = _GetFirstInputValue<T>(name);
341 return value ? value : defPtr;
342}
343
344template<typename T>
345bool
347{
348 // Note that we generally shouldn't have to check the result of
349 // _GetFirstInputValue(name) here, as opposed to simply checking whether
350 // there are any connections with non-zero masks on input.
351 //
352 // The one exception, unfortunately, is the EfSelectNode, which selects
353 // amongst its inputs. In the case where it doesn't have any inputs, it
354 // doesn't set an output at all even though it is connected. We technically
355 // shouldn't be compiling a select node at all when there is no input, but
356 // we do so to make sure that "first-time" constraints is fast. We should
357 // revisit that.
358
359 return _GetFirstInputValue<T>(name);
360}
361
362template<typename T>
363const T *
364VdfContext::_GetFirstInputValue(const TfToken &name) const
365{
366 // We need to implement code fairly similar to what the VdfReadIterator has
367 // to do. The up side is that we can implement a more specific semantic
368 // (namely that we return nullptr when the input is connected but not
369 // executed, whereas the read iterator will error out). Also we have the
370 // opportunity to squeeze some performance out. The downside is that we
371 // have to make sure that whenever we return true, that the read iterator
372 // can reasonably provide a value. So the code must be kept at least
373 // somewhat in sync.
374 const VdfInput *input = _GetNode().GetInput(name);
375 if (!input) {
376 return nullptr;
377 }
378
379 for (const VdfConnection *connection : input->GetConnections()) {
380 const VdfMask &mask = connection->GetMask();
381 const size_t firstIndex = mask.GetFirstSet();
382 if (firstIndex < mask.GetSize()) {
383 // The connection has a mask on it, make sure there's a value
384 // present.
385
386 // Get the output to read the value from.
387 const VdfVector *value = _GetExecutor()._GetInputValue(
388 *connection, mask);
389
390 if (value) {
392 value->GetReadAccessor<T>();
393 if (firstIndex < accessor.GetNumValues()) {
394 return &accessor[firstIndex];
395 }
396 }
397 }
398 }
399
400 // No values on any of the connections.
401 return nullptr;
402}
403
404template<typename T>
405void
407 const T &value) const
408{
409 TfAutoMallocTag2 tag("Vdf", "VdfContext::SetOutput");
410 TfAutoMallocTag2 tag2("Vdf", __ARCH_PRETTY_FUNCTION__);
411
412 // GetOutput emits an error if it returns NULL.
413 const VdfOutput *output = _node.GetOutput(outputName);
414 if (output && _IsRequiredOutput(*output))
415 if (VdfVector *v = _GetExecutor()._GetOutputValueForWriting(*output))
416 v->Set(value);
417}
418
419template<typename T>
420void
421VdfContext::SetOutput(const T &value) const
422{
423 TfAutoMallocTag2 tag("Vdf", "VdfContext::SetOutput");
424 TfAutoMallocTag2 tag2("Vdf", __ARCH_PRETTY_FUNCTION__);
425
426 // GetOutput emits an error if it returns NULL. Note that there is no need
427 // to check _IsRequiredOutput: By virtue of the owning node being scheduled,
428 // we can conclude that its only output is therefore scheduled.
429 if (const VdfOutput *output = _node.GetOutput())
430 if (VdfVector *v = _GetExecutor()._GetOutputValueForWriting(*output))
431 v->Set(value);
432}
433
434template<typename T>
435void
436VdfContext::SetOutput(T &&value) const
437{
438 TfAutoMallocTag2 tag("Vdf", "VdfContext::SetOutput (move)");
439 TfAutoMallocTag2 tag2("Vdf", __ARCH_PRETTY_FUNCTION__);
440
441 // GetOutput emits an error if it returns NULL. Note that there is no need
442 // to check _IsRequiredOutput: By virtue of the owning node being scheduled,
443 // we can conclude that its only output is therefore scheduled.
444 if (const VdfOutput *output = _node.GetOutput())
445 if (VdfVector *v =
446 _GetExecutor()._GetOutputValueForWriting(*output))
447 v->Set(std::forward<T>(value));
448}
449
450template<typename T>
451void
453 T &&value) const
454{
455 TfAutoMallocTag2 tag("Vdf", "VdfContext::SetOutput (move)");
456 TfAutoMallocTag2 tag2("Vdf", __ARCH_PRETTY_FUNCTION__);
457
458 // GetOutput emits an error if it returns NULL.
459 const VdfOutput *output = _node.GetOutput(outputName);
460 if (output && _IsRequiredOutput(*output))
461 if (VdfVector *v = _GetExecutor()._GetOutputValueForWriting(*output))
462 v->Set(std::forward<T>(value));
463}
464
465PXR_NAMESPACE_CLOSE_SCOPE
466
467#endif
Define function attributes.
#define ARCH_PRINTF_FUNCTION(_fmt, _firstArg)
Macro used to indicate a function takes a printf-like specification.
Definition: attributes.h:36
Scoped (i.e.
Definition: mallocTag.h:251
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:71
char const * GetText() const
Return the text that this token represents.
Definition: token.h:179
A class that fully represents a connection between two VdfNodes.
Definition: connection.h:30
A context is the parameter bundle passed to callbacks of computations.
Definition: context.h:40
VDF_API void SetEmptyOutput() const
Sets an empty value on the output.
VDF_API void CodingError(const char *fmt,...) const ARCH_PRINTF_FUNCTION(2
Invokes a coding error with an error message and a graph around the node that this context is current...
VDF_API void Warn(const char *fmt,...) const ARCH_PRINTF_FUNCTION(2
Reports a warning to the system that was encountered at runtime.
VdfByValueOrConstRef< T > GetInputValue(const TfToken &name) const
Returns a value from the input named name of type T.
Definition: context.h:312
VDF_API std::string GetNodeDebugName() const
Returns the debug name for the node for this context.
VDF_API void SetEmptyOutput(const TfToken &outputName) const
Sets an empty value on the output named outputName.
VdfContext(const VdfEvaluationState &state, const VdfNode &node, const VdfScheduleTaskIndex invocation)
Constructs a VdfContext for the given node and node invocation with the current evaluation state.
Definition: context.h:59
VdfContext(const VdfEvaluationState &state, const VdfNode &node)
Constructs a VdfContext for the given node with the current evaluation state.
Definition: context.h:50
VDF_API void SetOutputToReferenceInput(const TfToken &inputName) const
Sets the one and only output to have the same output value as the value on the output connected to in...
const T * GetInputValuePtr(const TfToken &name) const
Returns a pointer to the value from the input named name if the input has a valid value,...
Definition: context.h:331
VDF_API bool IsOutputRequested(const TfToken &outputName) const
Returns true if the output named outputName is requested by at least one downstream node,...
bool HasInputValue(const TfToken &name) const
Returns true if there are input values from the input named name of type T.
Definition: context.h:346
VDF_API bool HasInputValue(const TfToken &name) const
Returns true if there are input values from the input named name.
void SetOutput(const TfToken &outputName, const T &value) const
Sets the value of the output named outputName to value.
Definition: context.h:406
This object holds state that remains persistent during one round of network evaluation.
VdfExecutorErrorLogger * GetErrorLogger() const
The executor error logger.
const VdfSchedule & GetSchedule() const
The schedule used for evaluation.
const VdfExecutorInterface & GetExecutor() const
The executor used for evaluation.
const T & GetFallback() const
Returns the registered fallback value for T from the registry.
static VDF_API VdfExecutionTypeRegistry & GetInstance()
Returns the VdfExecutionTypeRegistry singleton instance.
A client may instantiate an object of this class and set it in an executor, to collect errors that ma...
Abstract base class for classes that execute a VdfNetwork to compute a requested set of values.
virtual const VdfVector * _GetInputValue(const VdfConnection &connection, const VdfMask &mask) const =0
Returns a value for the cache that flows across connection.
A VdfInput is used to connect a VdfNode to one or more VdfNodes' outputs.
Definition: input.h:36
const VdfConnectionVector & GetConnections() const
Returns a list of connections connected to this input.
Definition: input.h:54
Base class for libVdf iterators.
Definition: iterator.h:36
A VdfMask is placed on connections to specify the data flowing through them.
Definition: mask.h:37
size_t GetSize() const
Returns the size of the mask.
Definition: mask.h:158
size_t GetFirstSet() const
Returns the first set bit in the mask.
Definition: mask.h:226
This is the base class for all nodes in a VdfNetwork.
Definition: node.h:53
const VdfOutput * GetOutput(const TfToken &name) const
Returns the output object named name.
Definition: node.h:227
const VdfInput * GetInput(const TfToken &inputName) const
Returns the connector named inputName, returns NULL if no input of that name exists.
Definition: node.h:164
A VdfOutput represents an output on a node.
Definition: output.h:32
Contains a specification of how to execute a particular VdfNetwork.
Definition: schedule.h:41
A node that pulls on a vector of value that are downstream of the current execution position.
A read-only accessor for low-level acces to the contents of the VdfVector.
Definition: vector.h:476
size_t GetNumValues() const
Returns the size of the vector, i.e.
Definition: vector.h:489
This class is used to abstract away knowledge of the cache data used for each node.
Definition: vector.h:56
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:521
typename std::conditional_t< std::is_pointer_v< T >||Vdf_AndTypeIsSmall< T, std::is_arithmetic_v< T > >||Vdf_AndTypeIsSmall< T, std::is_enum_v< T > >, T, const T & > VdfByValueOrConstRef
Template that evaluates to either T or const T & depending on whether T best be passed as value or co...
Definition: traits.h:108
Define preprocessor function name macros.
#define TF_CODING_ERROR(fmt, args)
Issue an internal programming error, but continue execution.
Definition: diagnostic.h:68
STL namespace.
uint32_t VdfScheduleTaskIndex
Type describing a task index.
Definition: scheduleTasks.h:29