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 
28 #include "pxr/base/tf/mallocTag.h"
29 
30 PXR_NAMESPACE_OPEN_SCOPE
31 
32 class TfToken;
33 
40 {
41 public:
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 
226 private:
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 
282 private:
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 
297 template<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 
316 template<typename T>
317 inline const T *
319 {
320  return _GetFirstInputValue<T>(name);
321 }
322 
323 template<typename T>
324 inline const T *
325 VdfContext::GetInputValuePtr(const TfToken &name, const T *defPtr) const
326 {
327  const T *value = _GetFirstInputValue<T>(name);
328  return value ? value : defPtr;
329 }
330 
331 template<typename T>
332 const T *
333 VdfContext::_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) {
360  VdfVector::ReadAccessor<T> accessor =
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 
373 template<typename T>
374 void
375 VdfContext::SetOutput(const TfToken &outputName,
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 
388 template<typename T>
389 void
390 VdfContext::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 
403 template<typename T>
404 void
405 VdfContext::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 
419 template<typename T>
420 void
421 VdfContext::SetOutput(const TfToken &outputName,
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 
434 PXR_NAMESPACE_CLOSE_SCOPE
435 
436 #endif
A class that fully represents a connection between two VdfNodes.
Definition: connection.h:29
VdfExecutorErrorLogger * GetErrorLogger() const
The executor error logger.
This object holds state that remains persistent during one round of network evaluation.
A client may instantiate an object of this class and set it in an executor, to collect errors that ma...
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 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...
size_t GetFirstSet() const
Returns the first set bit in the mask.
Definition: mask.h:226
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
Define preprocessor function name macros.
Define function attributes.
#define TF_CODING_ERROR(fmt, args)
Issue an internal programming error, but continue execution.
Definition: diagnostic.h:69
This is the base class for all nodes in a VdfNetwork.
Definition: node.h:52
const T * GetInputValuePtr(const TfToken &name) const
Returns a pointer to the value from the input named name if the.
Definition: context.h:318
const T & GetFallback() const
Returns the registered fallback value for T from the registry.
A VdfMask is placed on connections to specify the data flowing through them.
Definition: mask.h:36
This class is used to abstract away knowledge of the cache data used for each node.
Definition: vector.h:58
const VdfConnectionVector & GetConnections() const
Returns a list of connections connected to this input.
Definition: input.h:54
A VdfInput is used to connect a VdfNode to one or more VdfNodes' outputs.
Definition: input.h:35
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...
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:80
Contains a specification of how to execute a particular VdfNetwork.
Definition: schedule.h:40
virtual const VdfVector * _GetInputValue(const VdfConnection &connection, const VdfMask &mask) const =0
Returns a value for the cache that flows across connection.
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 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
A node that pulls on a vector of value that are downstream of the current execution position.
const VdfOutput * GetOutput(const TfToken &name) const
Returns the output object named name.
Definition: node.h:227
size_t GetNumValues() const
Returns the size of the vector, i.e.
Definition: vector.h:492
void SetOutput(const TfToken &outputName, const T &value) const
Sets the value of the output named outputName to value.
Definition: context.h:375
const VdfSchedule & GetSchedule() const
The schedule used for evaluation.
VDF_API void Warn(const char *fmt,...) const ARCH_PRINTF_FUNCTION(2
Reports a warning to the system that was encountered at runtime.
size_t GetSize() const
Returns the size of the mask.
Definition: mask.h:158
A VdfOutput represents an output on a node.
Definition: output.h:31
VDF_API bool HasInputValue(const TfToken &name) const
Returns true if there are input values from the input named name.
virtual VdfVector * _GetOutputValueForWriting(const VdfOutput &output) const =0
Returns an output value for writing.
Base class for libVdf iterators.
Definition: iterator.h:35
uint32_t VdfScheduleTaskIndex
Type describing a task index.
Definition: scheduleTasks.h:29
A context is the parameter bundle passed to callbacks of computations.
Definition: context.h:39
const VdfExecutorInterface & GetExecutor() const
The executor used for evaluation.
VdfByValueOrConstRef< T > GetInputValue(const TfToken &name) const
Returns a value from the input named name of type T.
Definition: context.h:299
Abstract base class for classes that execute a VdfNetwork to compute a requested set of values.
VDF_API void SetEmptyOutput() const
Sets an empty value on the output.
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
VDF_API std::string GetNodeDebugName() const
Returns the debug name for the node for this context.
char const * GetText() const
Return the text that this token represents.
Definition: token.h:216
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
static VDF_API VdfExecutionTypeRegistry & GetInstance()
Returns the VdfExecutionTypeRegistry singleton instance.