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
93 template<typename T>
94 inline bool HasInputValue(const TfToken &name) const;
95
107 VDF_API
108 bool IsOutputRequested(const TfToken &outputName) const;
109
118 template<typename T>
119 inline void SetOutput(const TfToken &outputName,
120 const T &value) const;
121
133 template<typename T>
134 inline void SetOutput(const T &value) const;
135
148 template<typename T>
149 inline void SetOutput(T &&value) const;
150
160 template<typename T>
161 inline void SetOutput(const TfToken &outputName,
162 T &&value) const;
163
169 template<typename T>
170 inline void SetEmptyOutput() const;
171
174 template<typename T>
175 inline void SetEmptyOutput(const TfToken &outputName) const;
176
187 VDF_API
188 void SetOutputToReferenceInput(const TfToken &inputName) const;
189
190
193
202 VDF_API
203 void Warn(const char *fmt, ...) const ARCH_PRINTF_FUNCTION(2, 3);
204
205
207
208
211
214 VDF_API
215 std::string GetNodeDebugName() const;
216
221 VDF_API
222 void CodingError(const char *fmt, ...) const ARCH_PRINTF_FUNCTION(2, 3);
223
225
226
227private:
228
229 // This API is for VdfIterators to access internal context data.
230 friend class VdfIterator;
231
232 // Speculation nodes need to call _GetExecutor.
233 friend class VdfSpeculationNode;
234
235 // Returns the first input value on the given input, or a null pointer, if
236 // no such value exists.
237 //
238 template<typename T>
239 inline const T *_GetFirstInputValue(const TfToken &name) const;
240
241 // Retrieves the request and affects mask of the requested output, if
242 // available. Returns \c true if the output is scheduled, and \c false
243 // otherwise.
244 //
245 // Note, output must be an output on the current node!
246 //
247 VDF_API
248 bool _GetOutputMasks(
249 const VdfOutput &output,
250 const VdfMask **requestMask,
251 const VdfMask **affectsMask) const;
252
253 // Returns true when the output is scheduled and required, and
254 // false otherwise. Used by special iterators to avoid computing outputs
255 // that aren't necessary.
256 //
257 VDF_API
258 bool _IsRequiredOutput(const VdfOutput &output) const;
259
260 // Returns the request mask of \p output, if the output has been scheduled
261 // and \c NULL otherwise.
262 //
263 const VdfMask *_GetRequestMask(const VdfOutput &output) const;
264
265 // Returns the current node
266 //
267 const VdfNode &_GetNode() const { return _node; }
268
269 // Returns the executor for this context.
270 //
271 const VdfExecutorInterface &_GetExecutor() const { return _state.GetExecutor(); }
272
273 // Returns the schedule for this context.
274 //
275 const VdfSchedule &_GetSchedule() const { return _state.GetSchedule(); }
276
277 // Returns the error logger for this context.
278 //
279 VdfExecutorErrorLogger *_GetErrorLogger() const {
280 return _state.GetErrorLogger();
281 }
282
283private:
284
285 // The evaluation state
286 const VdfEvaluationState &_state;
287
288 // The node this context has been built for.
289 const VdfNode &_node;
290
291 // The current node invocation index. If this context is not for a node
292 // with multiple invocations, this will be set to VdfScheduleTaskInvalid.
293 const VdfScheduleTaskIndex _invocation;
294};
295
297
298template<typename T>
301{
302 // Calling this API means that the client expects there to be one and
303 // only one value, so we always return the first one here if there are
304 // any.
305 if (const T *value = _GetFirstInputValue<T>(name)) {
306 return *value;
307 }
308
310 "No input value for token '%s' on node '%s'",
311 name.GetText(), GetNodeDebugName().c_str());
312
313 // Ask the type registry for the fallback value to use.
315}
316
317template<typename T>
318inline const T *
320{
321 return _GetFirstInputValue<T>(name);
322}
323
324template<typename T>
325inline const T *
326VdfContext::GetInputValuePtr(const TfToken &name, const T *defPtr) const
327{
328 const T *value = _GetFirstInputValue<T>(name);
329 return value ? value : defPtr;
330}
331
332template<typename T>
333bool
335{
336 // Note that we generally shouldn't have to check the result of
337 // _GetFirstInputValue(name) here, as opposed to simply checking whether
338 // there are any connections with non-zero masks on input.
339 //
340 // The one exception, unfortunately, is the EfSelectNode, which selects
341 // amongst its inputs. In the case where it doesn't have any inputs, it
342 // doesn't set an output at all even though it is connected. We technically
343 // shouldn't be compiling a select node at all when there is no input, but
344 // we do so to make sure that "first-time" constraints is fast. We should
345 // revisit that.
346
347 return _GetFirstInputValue<T>(name);
348}
349
350template<typename T>
351const T *
352VdfContext::_GetFirstInputValue(const TfToken &name) const
353{
354 // We need to implement code fairly similar to what the VdfReadIterator has
355 // to do. The up side is that we can implement a more specific semantic
356 // (namely that we return nullptr when the input is connected but not
357 // executed, whereas the read iterator will error out). Also we have the
358 // opportunity to squeeze some performance out. The downside is that we
359 // have to make sure that whenever we return true, that the read iterator
360 // can reasonably provide a value. So the code must be kept at least
361 // somewhat in sync.
362 const VdfInput *input = _GetNode().GetInput(name);
363 if (!input) {
364 return nullptr;
365 }
366
367 for (const VdfConnection *connection : input->GetConnections()) {
368 const VdfMask &mask = connection->GetMask();
369 const size_t firstIndex = mask.GetFirstSet();
370 if (firstIndex < mask.GetSize()) {
371 // The connection has a mask on it, make sure there's a value
372 // present.
373
374 // Get the output to read the value from.
375 const VdfVector *value = _GetExecutor()._GetInputValue(
376 *connection, mask);
377
378 if (value) {
380 value->GetReadAccessor<T>();
381 if (firstIndex < accessor.GetNumValues()) {
382 return &accessor[firstIndex];
383 }
384 }
385 }
386 }
387
388 // No values on any of the connections.
389 return nullptr;
390}
391
392template<typename T>
393void
395 const T &value) const
396{
397 TfAutoMallocTag2 tag("Vdf", "VdfContext::SetOutput");
398 TfAutoMallocTag2 tag2("Vdf", __ARCH_PRETTY_FUNCTION__);
399
400 // GetOutput emits an error if it returns NULL.
401 const VdfOutput *output = _node.GetOutput(outputName);
402 if (output && _IsRequiredOutput(*output))
403 if (VdfVector *v = _GetExecutor()._GetOutputValueForWriting(*output))
404 v->Set(value);
405}
406
407template<typename T>
408void
409VdfContext::SetOutput(const T &value) const
410{
411 TfAutoMallocTag2 tag("Vdf", "VdfContext::SetOutput");
412 TfAutoMallocTag2 tag2("Vdf", __ARCH_PRETTY_FUNCTION__);
413
414 // GetOutput emits an error if it returns NULL. Note that there is no need
415 // to check _IsRequiredOutput: By virtue of the owning node being scheduled,
416 // we can conclude that its only output is therefore scheduled.
417 if (const VdfOutput *output = _node.GetOutput())
418 if (VdfVector *v = _GetExecutor()._GetOutputValueForWriting(*output))
419 v->Set(value);
420}
421
422template<typename T>
423void
424VdfContext::SetOutput(T &&value) const
425{
426 TfAutoMallocTag2 tag("Vdf", "VdfContext::SetOutput (move)");
427 TfAutoMallocTag2 tag2("Vdf", __ARCH_PRETTY_FUNCTION__);
428
429 // GetOutput emits an error if it returns NULL. Note that there is no need
430 // to check _IsRequiredOutput: By virtue of the owning node being scheduled,
431 // we can conclude that its only output is therefore scheduled.
432 if (const VdfOutput *output = _node.GetOutput())
433 if (VdfVector *v =
434 _GetExecutor()._GetOutputValueForWriting(*output))
435 v->Set(std::forward<T>(value));
436}
437
438template<typename T>
439void
441 T &&value) const
442{
443 TfAutoMallocTag2 tag("Vdf", "VdfContext::SetOutput (move)");
444 TfAutoMallocTag2 tag2("Vdf", __ARCH_PRETTY_FUNCTION__);
445
446 // GetOutput emits an error if it returns NULL.
447 const VdfOutput *output = _node.GetOutput(outputName);
448 if (output && _IsRequiredOutput(*output))
449 if (VdfVector *v = _GetExecutor()._GetOutputValueForWriting(*output))
450 v->Set(std::forward<T>(value));
451}
452
453template<typename T>
454void
456{
457 // GetOutput emits an error if it returns null. Note that there is no need
458 // to check _IsRequiredOutput: By virtue of the owning node being scheduled,
459 // we can conclude that its only output is therefore scheduled.
460 const VdfOutput *const output = _node.GetOutput();
461 if (!output) {
462 return;
463 }
464
465 VdfVector *const vector = _GetExecutor()._GetOutputValueForWriting(*output);
466 if (!vector) {
467 VDF_FATAL_ERROR(_GetNode(), "Couldn't get output vector.");
468 }
469
470 *vector = VdfTypedVector<T>();
471}
472
473template<typename T>
474void
475VdfContext::SetEmptyOutput(const TfToken &outputName) const
476{
477 // GetOutput emits an error if it returns null.
478 const VdfOutput *const output = _node.GetOutput(outputName);
479 if (!(output && _IsRequiredOutput(*output))) {
480 return;
481 }
482
483 VdfVector *const vector = _GetExecutor()._GetOutputValueForWriting(*output);
484 if (!vector) {
485 VDF_FATAL_ERROR(_GetNode(), "Couldn't get output vector.");
486 }
487
488 *vector = VdfTypedVector<T>();
489}
490
491PXR_NAMESPACE_CLOSE_SCOPE
492
493#endif
Define function attributes.
#define ARCH_PRINTF_FUNCTION(_fmt, _firstArg)
Macro used to indicate a function takes a printf-like specification.
Definition: attributes.h:34
Scoped (i.e.
Definition: mallocTag.h:249
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 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:300
VDF_API std::string GetNodeDebugName() const
Returns the debug name for the node for this context.
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
void SetEmptyOutput() const
Sets an empty value on the output.
Definition: context.h:455
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:319
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:334
void SetOutput(const TfToken &outputName, const T &value) const
Sets the value of the output named outputName to value.
Definition: context.h:394
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.
virtual VdfVector * _GetOutputValueForWriting(const VdfOutput &output) const =0
Returns an output value for writing.
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 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:469
size_t GetNumValues() const
Returns the size of the vector, i.e.
Definition: vector.h:482
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:514
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