schedule.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_SCHEDULE_H
8 #define PXR_EXEC_VDF_SCHEDULE_H
9 
11 
12 #include "pxr/pxr.h"
13 
14 #include "pxr/exec/vdf/api.h"
15 #include "pxr/exec/vdf/countingIterator.h"
16 #include "pxr/exec/vdf/node.h"
17 #include "pxr/exec/vdf/request.h"
20 #include "pxr/exec/vdf/types.h"
21 
22 #include "pxr/base/tf/bits.h"
23 
24 #include <vector>
25 
26 PXR_NAMESPACE_OPEN_SCOPE
27 
28 class VdfConnection;
29 class VdfNetwork;
30 
39 
41 {
42 public:
46  template <typename Iterator>
47  class IteratorRange {
48  public:
49  template <typename IteratorConvertible>
50  IteratorRange(IteratorConvertible begin, IteratorConvertible end) :
51  _begin(begin), _end(end) {}
52 
53  Iterator begin() const { return _begin; }
54  Iterator end() const { return _end; }
55  bool empty() const { return _begin == _end; }
56  size_t size() const { return std::distance(_begin, _end); }
57 
58  private:
59  Iterator _begin;
60  Iterator _end;
61  };
62 
65  VdfSchedule(const VdfSchedule &) = delete;
66  VdfSchedule &operator=(const VdfSchedule &) = delete;
67 
70  using ScheduleNodeVector = std::vector<VdfScheduleNode>;
71 
75 
78  using InputDependencyRange =
80 
83  using InputsRange =
85 
91  class OutputId {
92  public:
97  bool IsValid() const {
98  return _scheduleNodeIndex >= 0 && _secondaryIndex >= 0;
99  }
100 
109  _secondaryIndex++;
110  return *this;
111  }
112 
115  bool operator==(const OutputId &rhs) const {
116  return _scheduleNodeIndex == rhs._scheduleNodeIndex &&
117  _secondaryIndex == rhs._secondaryIndex;
118  }
119 
120  bool operator!=(const OutputId &rhs) const {
121  return !(*this == rhs);
122  }
123 
124  private:
125  // Construct an OutputId with a specific schedule node index
126  // and secondary index.
127  //
128  // The scheduleNodeIndex is expected to be one of the possible values
129  // stored in VdfSchedule::_nodesToIndexMap (i.e. [0, _nodes.size()-1])
130  // or a negative value to indicate an invalid id.
131  //
132  // And invalid id signifies that an output is not scheduled.
133  //
134  // The secondaryIndex is an index into the associated
135  // VdfScheduleNode's VdfScheduleOutputs vector, which stores data
136  // about the scheduled node explicitly.
137  //
138  OutputId(int scheduleNodeIndex, int secondaryIndex) :
139  _scheduleNodeIndex(scheduleNodeIndex),
140  _secondaryIndex(secondaryIndex)
141  {}
142 
143  // Only VdfSchedule is allowed to construct instances of VdfOuputId.
144  friend class VdfSchedule;
145 
146  // Data members
147  int _scheduleNodeIndex;
148  int _secondaryIndex;
149  };
150 
153  VDF_API
154  VdfSchedule();
155 
158  VDF_API
159  ~VdfSchedule();
160 
166  VDF_API
167  void Clear();
168 
172  bool IsValid() const {
173  return _isValid;
174  }
175 
178  const VdfNetwork *GetNetwork() const { return _network; }
179 
181 
184  VDF_API
185  bool IsScheduled(const VdfNode &node) const;
186 
192  VDF_API
193  OutputId GetOutputId(const VdfOutput &output) const;
194 
199  VDF_API
200  OutputId GetOrCreateOutputId(const VdfOutput &output);
201 
207  VDF_API
208  void AddInput(const VdfConnection &connection, const VdfMask &mask);
209 
217  VDF_API
218  void DeduplicateInputs();
219 
223  VDF_API
224  const VdfNode *GetNode(const OutputId &outputId) const;
225 
236  VDF_API
237  OutputId GetOutputIdsBegin(const VdfNode &node) const;
238 
250  VDF_API
251  OutputId GetOutputIdsEnd(const VdfNode &node) const;
252 
256  VDF_API
257  InputsRange GetInputs(const VdfNode &node) const;
258 
265  VDF_API
266  bool IsAffective(const OutputId &outputId) const;
267 
269 
275 
278  VDF_API
279  const VdfOutput *GetOutput(const OutputId &outputId) const;
280 
284  VDF_API
285  const VdfOutput *GetOutputToClear(const VdfNode &node) const;
286 
289  VDF_API
290  const VdfMask &GetRequestMask(const OutputId &outputId) const;
291 
295  const VdfScheduleTaskIndex invocationIndex) const {
296  TF_DEV_AXIOM(!VdfScheduleTaskIsInvalid(invocationIndex));
297  return _nodeInvocations[invocationIndex].requestMask;
298  }
299 
304  VDF_API
306  const OutputId &outputId,
307  const VdfMask **requestMask,
308  const VdfMask **affectsMask) const;
309 
314  const VdfScheduleTaskIndex invocationIndex,
315  const VdfMask **requestMask,
316  const VdfMask **affectsMask) const {
317  TF_DEV_AXIOM(!VdfScheduleTaskIsInvalid(invocationIndex));
318  *requestMask = &_nodeInvocations[invocationIndex].requestMask;
319  *affectsMask = &_nodeInvocations[invocationIndex].affectsMask;
320  }
321 
324  VDF_API
325  const VdfMask &GetAffectsMask(const OutputId &outputId) const;
326 
329  VDF_API
330  const VdfMask &GetKeepMask(const OutputId &outputId) const;
331 
335  const VdfScheduleTaskIndex invocationIndex) const {
336  TF_DEV_AXIOM(!VdfScheduleTaskIsInvalid(invocationIndex));
337  return _nodeInvocations[invocationIndex].keepMask;
338  }
339 
342  VDF_API
343  const VdfOutput *GetPassToOutput(const OutputId &outputId) const;
344 
347  VDF_API
348  const VdfOutput *GetFromBufferOutput(const OutputId &outputId) const;
349 
353  bool HasSMBL() const {
354  return _hasSMBL;
355  }
356 
358 
362  VDF_API
364  const VdfNode &node,
365  const VdfScheduledOutputCallback &callback) const;
366 
372  return _numUniqueInputDeps;
373  }
374 
377  size_t GetNumComputeTasks() const {
378  return _computeTasks.size();
379  }
380 
383  size_t GetNumInputsTasks() const {
384  return _inputsTasks.size();
385  }
386 
389  size_t GetNumPrepTasks() const {
390  return _numPrepTasks;
391  }
392 
395  size_t GetNumKeepTasks() const {
396  return _numKeepTasks;
397  }
398 
402  const TaskIdRange GetComputeTaskIds(const VdfNode &node) const {
403  int scheduleNodeIndex = _GetScheduleNodeIndex(node);
404  TF_DEV_AXIOM(scheduleNodeIndex >= 0);
405  return TaskIdRange(
406  _nodesToComputeTasks[scheduleNodeIndex].taskId,
407  _nodesToComputeTasks[scheduleNodeIndex].taskId +
408  _nodesToComputeTasks[scheduleNodeIndex].taskNum);
409  }
410 
414  const VdfScheduleInputDependency &input) const {
415  return TaskIdRange(
416  input.computeOrKeepTaskId,
417  input.computeOrKeepTaskId + input.computeTaskNum);
418  }
419 
422  const VdfScheduleTaskIndex GetKeepTaskIndex(const VdfNode &node) const {
423  int scheduleNodeIndex = _GetScheduleNodeIndex(node);
424  return scheduleNodeIndex >= 0
425  ? _nodesToKeepTasks[scheduleNodeIndex]
426  : VdfScheduleTaskInvalid;
427  }
428 
432  const VdfScheduleTaskIndex index) const {
433  TF_DEV_AXIOM(index < _computeTasks.size());
434  return _computeTasks[index];
435  }
436 
440  const VdfScheduleTaskIndex index) const {
441  TF_DEV_AXIOM(index < _inputsTasks.size());
442  return _inputsTasks[index];
443  }
444 
449  const VdfScheduleInputsTask &task) const {
450  std::vector<VdfScheduleInputDependency>::const_iterator begin =
451  _inputDeps.begin() + task.inputDepIndex;
452  return InputDependencyRange(begin, begin + task.prereqsNum);
453  }
454 
459  const VdfScheduleInputsTask &task) const {
460  std::vector<VdfScheduleInputDependency>::const_iterator begin =
461  _inputDeps.begin() + task.inputDepIndex + task.prereqsNum;
462  return InputDependencyRange(begin, begin + task.optionalsNum);
463  }
464 
469  const VdfScheduleComputeTask &task) const {
470  std::vector<VdfScheduleInputDependency>::const_iterator begin =
471  _inputDeps.begin() + task.requiredsIndex;
472  return InputDependencyRange(begin, begin + task.requiredsNum);
473  }
474 
477  VDF_API
479  const OutputId outputId) const;
480 
482 
487  bool IsSmallSchedule() const { return _isSmallSchedule; }
488 
491  VDF_API
492  void SetRequest(const VdfRequest &request);
493 
496  const VdfRequest &GetRequest() const { return _request; }
497 
504  return _nodes;
505  }
506 
507  const ScheduleNodeVector &GetScheduleNodeVector() const {
508  return _nodes;
509  }
510 
514  int GetScheduleNodeIndex(const OutputId &outputId) const {
515  return outputId._scheduleNodeIndex;
516  }
517 
521  const TfBits &GetScheduledNodeBits() const { return _scheduledNodes; }
522 
525  VDF_API
526  void SetRequestMask(const OutputId &outputId, const VdfMask &mask);
527 
530  VDF_API
531  void SetAffectsMask(const OutputId &outputId, const VdfMask &mask);
532 
535  VDF_API
536  void SetKeepMask(const OutputId &outputId, const VdfMask &mask);
537 
540  VDF_API
541  void SetPassToOutput(const OutputId &outputId, const VdfOutput *output);
542 
545  VDF_API
546  void SetFromBufferOutput(const OutputId &outputId, const VdfOutput *output);
547 
551  VDF_API
552  void SetOutputToClear(const VdfNode &node, const VdfOutput *outputToClear);
553 
556  VDF_API
557  void InitializeFromNetwork(const VdfNetwork &network);
558 
561  void SetHasSMBL(bool enable) {
562  _hasSMBL = enable;
563  }
564 
566 
567 private:
568 
569  // The VdfScheduler and its derived classes are the only objects allowed
570  // to set a scheduler as valid.
571  friend class VdfScheduler;
572 
573  // The VdfScheduler calls this method to make sure that this schedule
574  // is marked as valid and registered with a particular network.
575  //
576  void _SetIsValidForNetwork(const VdfNetwork *network);
577 
578  // Returns the index into _nodes that corresponds to the given VdfNode.
579  // If the node is not scheduled and thus has no corresponding _nodes entry,
580  // this method returns a value less than 0.
581  VDF_API
582  int _GetScheduleNodeIndex(const VdfNode &node) const;
583 
584  // Ensures that \p node is in the schedule and returns its scheduleNode
585  // index.
586  //
587  int _EnsureNodeInSchedule(const VdfNode &node);
588 
589  // Data Members
590 
591  // The total list of nodes that we have to execute. This is where the
592  // schedule nodes are owned.
593  ScheduleNodeVector _nodes;
594 
595  // The request for this schedule
596  VdfRequest _request;
597 
598  // This is a vector that maps VdfNodes to VdfScheduleNode index in _nodes.
599  std::vector<int> _nodesToIndexMap;
600 
601  // The network that we are registered with. All of our scheduled nodes
602  // belong to this network.
603  const VdfNetwork *_network;
604 
605  // Bits are set for each schedule node's index.
606  TfBits _scheduledNodes;
607 
608  // Flag as to whether or not the schedule is valid.
609  bool _isValid;
610 
611  // A flag that determines whether this schedule's query methods will
612  // use the small schedule optimization, which is to assume there is no
613  // _nodesToIndexMap and instead find schedule nodes by searching the
614  // _nodes array directly.
615  bool _isSmallSchedule;
616 
617  // This flag indicates whether this schedule participates in sparse mung
618  // buffer locking.
619  bool _hasSMBL;
620 
621  // The number of unique input dependencies created for this schedule. Each
622  // unique input dependencies refers to the same output and mask combination.
623  size_t _numUniqueInputDeps;
624 
625  // The scheduled tasks for parallel evaluation.
628  size_t _numKeepTasks;
629  size_t _numPrepTasks;
630 
631  // Scheduled node invocations for nodes with multiple invocations.
633 
634  // The array of input dependencies used to orchestrate task synchronization.
635  std::vector<VdfScheduleInputDependency> _inputDeps;
636 
637  // Arrays that map from the scheduled node index to the scheduled tasks
638  // corresponding to that node.
639  std::vector<VdfScheduleNodeTasks> _nodesToComputeTasks;
640  std::vector<VdfScheduleTaskIndex> _nodesToKeepTasks;
641 };
642 
644 
645 // Example usage:
646 // void MyFunction(const VdfSchedule &schedule, const VdfNode &node) {
647 // VDF_FOR_EACH_SCHEDULED_OUTPUT_ID(outputId, schedule, node) {
648 // DoThingsWithARequestMask(schedule->GetRequestMask(outputId));
649 // }
650 // }
651 //
652 #define VDF_FOR_EACH_SCHEDULED_OUTPUT_ID(OUTPUT_ID_NAME,VDF_SCHEDULE,VDF_NODE) \
653  for (VdfSchedule::OutputId __endId = \
654  (VDF_SCHEDULE).GetOutputIdsEnd(VDF_NODE), \
655  OUTPUT_ID_NAME = (VDF_SCHEDULE).GetOutputIdsBegin(VDF_NODE) ; \
656  OUTPUT_ID_NAME != __endId; ++OUTPUT_ID_NAME)
657 
658 
660 
661 PXR_NAMESPACE_CLOSE_SCOPE
662 
663 #endif
#define TF_DEV_AXIOM(cond)
The same as TF_AXIOM, but compiled only in dev builds.
Definition: diagnostic.h:206
A VdfNetwork is a collection of VdfNodes and their connections.
Definition: network.h:59
bool IsSmallSchedule() const
Returns whether this schedule is small enough to avoid overhead incurred by the _nodesToIndexMap mapp...
Definition: schedule.h:487
VDF_API void SetRequestMask(const OutputId &outputId, const VdfMask &mask)
Registers a request mask for the output indicated by outputId.
A class that fully represents a connection between two VdfNodes.
Definition: connection.h:29
VDF_API bool IsScheduled(const VdfNode &node) const
Returns whether this schedule includes node in any way.
VDF_API void SetFromBufferOutput(const OutputId &outputId, const VdfOutput *output)
Registers a "from buffer" for the output indicated by outputId.
const TaskIdRange GetComputeTaskIds(const VdfNode &node) const
Returns a range of ids describing compute tasks associated with the given node.
Definition: schedule.h:402
bool HasSMBL() const
Returns true if this schedule participates in sparse mung buffer locking.
Definition: schedule.h:353
VDF_API void AddInput(const VdfConnection &connection, const VdfMask &mask)
Adds the input targeted by the given connection to the schedule.
VDF_API VdfScheduleInputDependencyUniqueIndex GetUniqueIndex(const OutputId outputId) const
Returns the unique index assigned to the output.
VDF_API void GetRequestAndAffectsMask(const OutputId &outputId, const VdfMask **requestMask, const VdfMask **affectsMask) const
Returns pointers to the request and affects masks simultaneously, saving on the overhead of making tw...
const TfBits & GetScheduledNodeBits() const
Returns a set of bits where each set bit's index corresponds to the node index of a node in this sche...
Definition: schedule.h:521
VDF_API bool IsAffective(const OutputId &outputId) const
Returns true if the output is expected to have an effect on its corresponding input,...
VDF_API void SetOutputToClear(const VdfNode &node, const VdfOutput *outputToClear)
Registers an output whose temporary buffer can be eagerly cleared as soon as node has finished execut...
VDF_API OutputId GetOrCreateOutputId(const VdfOutput &output)
Similar to GetOutputId, but creates an OutptuId if none exists, effectively adding the output to the ...
bool operator==(const OutputId &rhs) const
Equality operator.
Definition: schedule.h:115
VDF_API const VdfOutput * GetPassToOutput(const OutputId &outputId) const
Returns the "pass to" output associated with the given OutputId.
This is the base class for all nodes in a VdfNetwork.
Definition: node.h:52
VDF_API InputsRange GetInputs(const VdfNode &node) const
Returns a range of inputs scheduled for the given node.
An OutputId is a small key object that, once obtained for a particular VdfOutput, can be used to quer...
Definition: schedule.h:91
A VdfMask is placed on connections to specify the data flowing through them.
Definition: mask.h:36
IteratorRange< std::vector< VdfScheduleInput >::const_iterator > InputsRange
An iterable range of scheduled inputs.
Definition: schedule.h:84
IteratorRange< Vdf_CountingIterator< VdfScheduleTaskId > > TaskIdRange
An iterable range of task ids.
Definition: schedule.h:74
size_t GetNumUniqueInputDependencies() const
Returns the number of unique input dependencies created for the scheduled task graph.
Definition: schedule.h:371
size_t GetNumInputsTasks() const
Returns the total number of inputs tasks in the schedule.
Definition: schedule.h:383
size_t GetNumComputeTasks() const
Returns the total number of compute tasks in the schedule.
Definition: schedule.h:377
const VdfMask & GetRequestMask(const VdfScheduleTaskIndex invocationIndex) const
Returns the request mask for the given node invocation.
Definition: schedule.h:294
InputDependencyRange GetRequiredInputDependencies(const VdfScheduleComputeTask &task) const
Returns an iterable range of required (i.e.
Definition: schedule.h:468
VDF_API void SetPassToOutput(const OutputId &outputId, const VdfOutput *output)
Registers a "pass to" output for the output indicated by outputId.
VDF_API const VdfMask & GetAffectsMask(const OutputId &outputId) const
Returns the affects mask associated with the given OutputId.
std::function< void(const VdfOutput *, const VdfMask &)> VdfScheduledOutputCallback
Function type to be used with ForEachScheduledOutput().
Definition: types.h:86
TaskIdRange GetComputeTaskIds(const VdfScheduleInputDependency &input) const
Returns an iterable range of task indices given an input dependency.
Definition: schedule.h:413
const VdfNetwork * GetNetwork() const
Returns the network for this schedule.
Definition: schedule.h:178
Fast bit array that keeps track of the number of bits set and can find the next set in a timely manne...
Definition: bits.h:48
VDF_API const VdfNode * GetNode(const OutputId &outputId) const
Returns the VdfNode that owns the VdfOutput associated with the given outputId.
Contains a specification of how to execute a particular VdfNetwork.
Definition: schedule.h:40
Describes a single input dependency, i.e.
VDF_API OutputId GetOutputIdsBegin(const VdfNode &node) const
Gets an OutputId identifying the first scheduled output for the given node, if any.
std::vector< VdfScheduleNode > ScheduleNodeVector
The type for the vector of schedule nodes in the schedule.
Definition: schedule.h:70
VDF_API void ForEachScheduledOutput(const VdfNode &node, const VdfScheduledOutputCallback &callback) const
Loops over each scheduled output of node and calls callback with the output and request mask in an ef...
size_t GetNumPrepTasks() const
Returns the total number of prep tasks in the schedule.
Definition: schedule.h:389
bool IsValid() const
Returns whether or not this schedule is valid and can be used for execution.
Definition: schedule.h:172
VDF_API OutputId GetOutputId(const VdfOutput &output) const
Returns a small, cheap OutputId, which can be passed to other Get* methods in this class to efficient...
VDF_API void SetAffectsMask(const OutputId &outputId, const VdfMask &mask)
Registers an affects mask for the output indicated by outputId.
InputDependencyRange GetPrereqInputDependencies(const VdfScheduleInputsTask &task) const
Returns an iterable range of prereq input dependencies for the given inputs task.
Definition: schedule.h:448
std::vector< T, Vdf_DefaultInitAllocator< T > > Vdf_DefaultInitVector
A std::vector which on resize performs default initialization instead of value initialization.
Definition: types.h:122
VDF_API const VdfOutput * GetOutput(const OutputId &outputId) const
Returns the scheduled VdfOutput associated with the given OutputId.
bool IsValid() const
Returns whether this OutputId can be used to make queries about an output's scheduling.
Definition: schedule.h:97
ScheduleNodeVector & GetScheduleNodeVector()
Returns the vector of schedule nodes in this schedule.
Definition: schedule.h:503
VDF_API void SetKeepMask(const OutputId &outputId, const VdfMask &mask)
Registers a keep mask for the output indicated by outputId.
InputDependencyRange GetOptionalInputDependencies(const VdfScheduleInputsTask &task) const
Returns an iterable range of optional (i.e.
Definition: schedule.h:458
VDF_API void SetRequest(const VdfRequest &request)
Sets the request that was used to make up this schedule.
const VdfScheduleComputeTask & GetComputeTask(const VdfScheduleTaskIndex index) const
Returns the compute task associated with the given task index.
Definition: schedule.h:431
Minimal iterator range that the schedule returns instances of, in order to facilitate iterating over ...
Definition: schedule.h:47
Used to make a VdfSchedule.
Definition: scheduler.h:34
OutputId & operator++()
Increment this OutputId to refer to the next scheduled output on the current output's node.
Definition: schedule.h:108
VDF_API const VdfMask & GetKeepMask(const OutputId &outputId) const
Returns the keep mask associated with the given OutputId.
VDF_API ~VdfSchedule()
Destructor.
VDF_API void DeduplicateInputs()
Consolidates scheduled input entries added by AddInput.
VDF_API void Clear()
Clears the schedule.
VDF_API VdfSchedule()
Constructs an empty schedule.
A VdfOutput represents an output on a node.
Definition: output.h:31
VDF_API const VdfOutput * GetFromBufferOutput(const OutputId &outputId) const
Returns the "from buffer's" output associated with the given OutputId.
VDF_API const VdfMask & GetRequestMask(const OutputId &outputId) const
Returns the request mask associated with the given OutputId.
A VdfScheduleComputeTask represents a unit of computation for the parallel evaluation engine.
Definition: scheduleTasks.h:64
const VdfRequest & GetRequest() const
Returns the request for this schedule.
Definition: schedule.h:496
Structure describing an additional task used to run prereqs and reads concurrently with read/write in...
bool VdfScheduleTaskIsInvalid(uint32_t task)
Returns true if the given task index or id is invalid.
Definition: scheduleTasks.h:41
VDF_API const VdfOutput * GetOutputToClear(const VdfNode &node) const
Returns the output whose temporary buffer can be immediately deallocated after node has finished exec...
IteratorRange< std::vector< VdfScheduleInputDependency >::const_iterator > InputDependencyRange
An iterable range of input dependencies.
Definition: schedule.h:79
const VdfScheduleInputsTask & GetInputsTask(const VdfScheduleTaskIndex index) const
Returns the inputs task associated with the given task index.
Definition: schedule.h:439
uint32_t VdfScheduleTaskIndex
Type describing a task index.
Definition: scheduleTasks.h:29
VDF_API void InitializeFromNetwork(const VdfNetwork &network)
Initializes structures based on the size of the network.
void GetRequestAndAffectsMask(const VdfScheduleTaskIndex invocationIndex, const VdfMask **requestMask, const VdfMask **affectsMask) const
Returns pointers to the request and affects masks for the given node invocation index.
Definition: schedule.h:313
uint32_t VdfScheduleInputDependencyUniqueIndex
A sequential index assigned to the unique output and mask combination of a VdfScheduleInputDependency...
VDF_API OutputId GetOutputIdsEnd(const VdfNode &node) const
Gets an OutputId identifying the "end" of the scheduled outputs for a node.
size_t GetNumKeepTasks() const
Returns the total number of keep tasks in the schedule.
Definition: schedule.h:395
const VdfScheduleTaskIndex GetKeepTaskIndex(const VdfNode &node) const
Returns an index to the keep task associated with the given node.
Definition: schedule.h:422
int GetScheduleNodeIndex(const OutputId &outputId) const
Returns the node index of the schedule node associated with the given outputId.
Definition: schedule.h:514
const VdfMask & GetKeepMask(const VdfScheduleTaskIndex invocationIndex) const
Returns the keep mask for the given node invocation index.
Definition: schedule.h:334
void SetHasSMBL(bool enable)
Enables SMBL for this schedule.
Definition: schedule.h:561