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
92 VDF_API
93 bool HasInputValue(const TfToken &name) const;
94
106 VDF_API
107 bool IsOutputRequested(const TfToken &outputName) const;
108
117 template<typename T>
118 inline void SetOutput(const TfToken &outputName,
119 const T &value) const;
120
132 template<typename T>
133 inline void SetOutput(const T &value) const;
134
147 template<typename T>
148 inline void SetOutput(T &&value) const;
149
159 template<typename T>
160 inline void SetOutput(const TfToken &outputName,
161 T &&value) const;
162
168 VDF_API
169 void SetEmptyOutput() const;
170
173 VDF_API
174 void SetEmptyOutput(const TfToken &outputName) const;
175
186 VDF_API
187 void SetOutputToReferenceInput(const TfToken &inputName) const;
188
189
192
201 VDF_API
202 void Warn(const char *fmt, ...) const ARCH_PRINTF_FUNCTION(2, 3);
203
204
206
207
210
213 VDF_API
214 std::string GetNodeDebugName() const;
215
220 VDF_API
221 void CodingError(const char *fmt, ...) const ARCH_PRINTF_FUNCTION(2, 3);
222
224
225
226private:
227
228 // This API is for VdfIterators to access internal context data.
229 friend class VdfIterator;
230
231 // Speculation nodes need to call _GetExecutor.
232 friend class VdfSpeculationNode;
233
234 // Returns the first input value on the given input, or a null pointer, if
235 // no such value exists.
236 //
237 template<typename T>
238 inline const T *_GetFirstInputValue(const TfToken &name) const;
239
240 // Retrieves the request and affects mask of the requested output, if
241 // available. Returns \c true if the output is scheduled, and \c false
242 // otherwise.
243 //
244 // Note, output must be an output on the current node!
245 //
246 VDF_API
247 bool _GetOutputMasks(
248 const VdfOutput &output,
249 const VdfMask **requestMask,
250 const VdfMask **affectsMask) const;
251
252 // Returns true when the output is scheduled and required, and
253 // false otherwise. Used by special iterators to avoid computing outputs
254 // that aren't necessary.
255 //
256 VDF_API
257 bool _IsRequiredOutput(const VdfOutput &output) const;
258
259 // Returns the request mask of \p output, if the output has been scheduled
260 // and \c NULL otherwise.
261 //
262 const VdfMask *_GetRequestMask(const VdfOutput &output) const;
263
264 // Returns the current node
265 //
266 const VdfNode &_GetNode() const { return _node; }
267
268 // Returns the executor for this context.
269 //
270 const VdfExecutorInterface &_GetExecutor() const { return _state.GetExecutor(); }
271
272 // Returns the schedule for this context.
273 //
274 const VdfSchedule &_GetSchedule() const { return _state.GetSchedule(); }
275
276 // Returns the error logger for this context.
277 //
278 VdfExecutorErrorLogger *_GetErrorLogger() const {
279 return _state.GetErrorLogger();
280 }
281
282private:
283
284 // The evaluation state
285 const VdfEvaluationState &_state;
286
287 // The node this context has been built for.
288 const VdfNode &_node;
289
290 // The current node invocation index. If this context is not for a node
291 // with multiple invocations, this will be set to VdfScheduleTaskInvalid.
292 const VdfScheduleTaskIndex _invocation;
293};
294
296
297template<typename T>
300{
301 // Calling this API means that the client expects there to be one and
302 // only one value, so we always return the first one here if there are
303 // any.
304 if (const T *value = _GetFirstInputValue<T>(name)) {
305 return *value;
306 }
307
309 "No input value for token '%s' on node '%s'",
310 name.GetText(), GetNodeDebugName().c_str());
311
312 // Ask the type registry for the fallback value to use.
314}
315
316template<typename T>
317inline const T *
319{
320 return _GetFirstInputValue<T>(name);
321}
322
323template<typename T>
324inline const T *
325VdfContext::GetInputValuePtr(const TfToken &name, const T *defPtr) const
326{
327 const T *value = _GetFirstInputValue<T>(name);
328 return value ? value : defPtr;
329}
330
331template<typename T>
332const T *
333VdfContext::_GetFirstInputValue(const TfToken &name) const
334{
335 // We need to implement code fairly similar to what the VdfReadIterator has
336 // to do. The up side is that we can implement a more specific semantic
337 // (namely that we return nullptr when the input is connected but not
338 // executed, whereas the read iterator will error out). Also we have the
339 // opportunity to squeeze some performance out. The downside is that we
340 // have to make sure that whenever we return true, that the read iterator
341 // can reasonably provide a value. So the code must be kept at least
342 // somewhat in sync.
343 const VdfInput *input = _GetNode().GetInput(name);
344 if (!input) {
345 return nullptr;
346 }
347
348 for (const VdfConnection *connection : input->GetConnections()) {
349 const VdfMask &mask = connection->GetMask();
350 const size_t firstIndex = mask.GetFirstSet();
351 if (firstIndex < mask.GetSize()) {
352 // The connection has a mask on it, make sure there's a value
353 // present.
354
355 // Get the output to read the value from.
356 const VdfVector *value = _GetExecutor()._GetInputValue(
357 *connection, mask);
358
359 if (value) {
361 value->GetReadAccessor<T>();
362 if (firstIndex < accessor.GetNumValues()) {
363 return &accessor[firstIndex];
364 }
365 }
366 }
367 }
368
369 // No values on any of the connections.
370 return nullptr;
371}
372
373template<typename T>
374void
376 const T &value) const
377{
378 TfAutoMallocTag2 tag("Vdf", "VdfContext::SetOutput");
379 TfAutoMallocTag2 tag2("Vdf", __ARCH_PRETTY_FUNCTION__);
380
381 // GetOutput emits an error if it returns NULL.
382 const VdfOutput *output = _node.GetOutput(outputName);
383 if (output && _IsRequiredOutput(*output))
384 if (VdfVector *v = _GetExecutor()._GetOutputValueForWriting(*output))
385 v->Set(value);
386}
387
388template<typename T>
389void
390VdfContext::SetOutput(const T &value) const
391{
392 TfAutoMallocTag2 tag("Vdf", "VdfContext::SetOutput");
393 TfAutoMallocTag2 tag2("Vdf", __ARCH_PRETTY_FUNCTION__);
394
395 // GetOutput emits an error if it returns NULL. Note that there is no need
396 // to check _IsRequiredOutput: By virtue of the owning node being scheduled,
397 // we can conclude that its only output is therefore scheduled.
398 if (const VdfOutput *output = _node.GetOutput())
399 if (VdfVector *v = _GetExecutor()._GetOutputValueForWriting(*output))
400 v->Set(value);
401}
402
403template<typename T>
404void
405VdfContext::SetOutput(T &&value) const
406{
407 TfAutoMallocTag2 tag("Vdf", "VdfContext::SetOutput (move)");
408 TfAutoMallocTag2 tag2("Vdf", __ARCH_PRETTY_FUNCTION__);
409
410 // GetOutput emits an error if it returns NULL. Note that there is no need
411 // to check _IsRequiredOutput: By virtue of the owning node being scheduled,
412 // we can conclude that its only output is therefore scheduled.
413 if (const VdfOutput *output = _node.GetOutput())
414 if (VdfVector *v =
415 _GetExecutor()._GetOutputValueForWriting(*output))
416 v->Set(std::forward<T>(value));
417}
418
419template<typename T>
420void
422 T &&value) const
423{
424 TfAutoMallocTag2 tag("Vdf", "VdfContext::SetOutput (move)");
425 TfAutoMallocTag2 tag2("Vdf", __ARCH_PRETTY_FUNCTION__);
426
427 // GetOutput emits an error if it returns NULL.
428 const VdfOutput *output = _node.GetOutput(outputName);
429 if (output && _IsRequiredOutput(*output))
430 if (VdfVector *v = _GetExecutor()._GetOutputValueForWriting(*output))
431 v->Set(std::forward<T>(value));
432}
433
434PXR_NAMESPACE_CLOSE_SCOPE
435
436#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:299
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:318
VDF_API bool IsOutputRequested(const TfToken &outputName) const
Returns true if the output named outputName is requested by at least one downstream node,...
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:375
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
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:104
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.