Loading...
Searching...
No Matches
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"
20#include "pxr/exec/vdf/types.h"
21
22#include "pxr/base/tf/bits.h"
23
24#include <vector>
25
26PXR_NAMESPACE_OPEN_SCOPE
27
28class VdfConnection;
29class VdfNetwork;
30
39
41{
42public:
46 template <typename Iterator>
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
80
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
155
158 VDF_API
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
201
207 VDF_API
208 void AddInput(const VdfConnection &connection, const VdfMask &mask);
209
217 VDF_API
219
223 VDF_API
224 const VdfNode *GetNode(const OutputId &outputId) const;
225
236 VDF_API
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
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
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
567private:
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
661PXR_NAMESPACE_CLOSE_SCOPE
662
663#endif
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:49
A class that fully represents a connection between two VdfNodes.
Definition: connection.h:30
A VdfMask is placed on connections to specify the data flowing through them.
Definition: mask.h:37
A VdfNetwork is a collection of VdfNodes and their connections.
Definition: network.h:60
This is the base class for all nodes in a VdfNetwork.
Definition: node.h:53
A VdfOutput represents an output on a node.
Definition: output.h:32
Minimal iterator range that the schedule returns instances of, in order to facilitate iterating over ...
Definition: schedule.h:47
An OutputId is a small key object that, once obtained for a particular VdfOutput, can be used to quer...
Definition: schedule.h:91
OutputId & operator++()
Increment this OutputId to refer to the next scheduled output on the current output's node.
Definition: schedule.h:108
bool IsValid() const
Returns whether this OutputId can be used to make queries about an output's scheduling.
Definition: schedule.h:97
bool operator==(const OutputId &rhs) const
Equality operator.
Definition: schedule.h:115
Contains a specification of how to execute a particular VdfNetwork.
Definition: schedule.h:41
VDF_API const VdfMask & GetAffectsMask(const OutputId &outputId) const
Returns the affects mask associated with the given OutputId.
const VdfNetwork * GetNetwork() const
Returns the network for this schedule.
Definition: schedule.h:178
void SetHasSMBL(bool enable)
Enables SMBL for this schedule.
Definition: schedule.h:561
InputDependencyRange GetRequiredInputDependencies(const VdfScheduleComputeTask &task) const
Returns an iterable range of required (i.e.
Definition: schedule.h:468
VDF_API OutputId GetOrCreateOutputId(const VdfOutput &output)
Similar to GetOutputId, but creates an OutptuId if none exists, effectively adding the output to the ...
VDF_API void SetPassToOutput(const OutputId &outputId, const VdfOutput *output)
Registers a "pass to" output for the output indicated by outputId.
const VdfMask & GetKeepMask(const VdfScheduleTaskIndex invocationIndex) const
Returns the keep mask for the given node invocation index.
Definition: schedule.h:334
VDF_API VdfSchedule()
Constructs an empty schedule.
VDF_API ~VdfSchedule()
Destructor.
VDF_API void InitializeFromNetwork(const VdfNetwork &network)
Initializes structures based on the size of the network.
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.
VDF_API const VdfMask & GetRequestMask(const OutputId &outputId) const
Returns the request mask associated with the given OutputId.
size_t GetNumUniqueInputDependencies() const
Returns the number of unique input dependencies created for the scheduled task graph.
Definition: schedule.h:371
VDF_API OutputId GetOutputIdsBegin(const VdfNode &node) const
Gets an OutputId identifying the first scheduled output for the given node, if any.
InputDependencyRange GetPrereqInputDependencies(const VdfScheduleInputsTask &task) const
Returns an iterable range of prereq input dependencies for the given inputs task.
Definition: schedule.h:448
VDF_API OutputId GetOutputIdsEnd(const VdfNode &node) const
Gets an OutputId identifying the "end" of the scheduled outputs for a node.
VDF_API const VdfOutput * GetFromBufferOutput(const OutputId &outputId) const
Returns the "from buffer's" output associated with the given OutputId.
const VdfScheduleTaskIndex GetKeepTaskIndex(const VdfNode &node) const
Returns an index to the keep task associated with the given node.
Definition: schedule.h:422
const VdfScheduleComputeTask & GetComputeTask(const VdfScheduleTaskIndex index) const
Returns the compute task associated with the given task index.
Definition: schedule.h:431
VDF_API bool IsScheduled(const VdfNode &node) const
Returns whether this schedule includes node in any way.
size_t GetNumKeepTasks() const
Returns the total number of keep tasks in the schedule.
Definition: schedule.h:395
TaskIdRange GetComputeTaskIds(const VdfScheduleInputDependency &input) const
Returns an iterable range of task indices given an input dependency.
Definition: schedule.h:413
VDF_API void DeduplicateInputs()
Consolidates scheduled input entries added by AddInput.
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...
VDF_API void SetRequest(const VdfRequest &request)
Sets the request that was used to make up this schedule.
VDF_API InputsRange GetInputs(const VdfNode &node) const
Returns a range of inputs scheduled for the given node.
IteratorRange< std::vector< VdfScheduleInputDependency >::const_iterator > InputDependencyRange
An iterable range of input dependencies.
Definition: schedule.h:79
int GetScheduleNodeIndex(const OutputId &outputId) const
Returns the node index of the schedule node associated with the given outputId.
Definition: schedule.h:514
const VdfRequest & GetRequest() const
Returns the request for this schedule.
Definition: schedule.h:496
VDF_API const VdfMask & GetKeepMask(const OutputId &outputId) const
Returns the keep mask associated with the given OutputId.
VDF_API VdfScheduleInputDependencyUniqueIndex GetUniqueIndex(const OutputId outputId) const
Returns the unique index assigned to the output.
IteratorRange< Vdf_CountingIterator< VdfScheduleTaskId > > TaskIdRange
An iterable range of task ids.
Definition: schedule.h:74
VDF_API void SetRequestMask(const OutputId &outputId, const VdfMask &mask)
Registers a request mask for the output indicated by outputId.
VDF_API void AddInput(const VdfConnection &connection, const VdfMask &mask)
Adds the input targeted by the given connection to the schedule.
VDF_API const VdfOutput * GetPassToOutput(const OutputId &outputId) const
Returns the "pass to" output associated with the given OutputId.
std::vector< VdfScheduleNode > ScheduleNodeVector
The type for the vector of schedule nodes in the schedule.
Definition: schedule.h:70
const TaskIdRange GetComputeTaskIds(const VdfNode &node) const
Returns a range of ids describing compute tasks associated with the given node.
Definition: schedule.h:402
VDF_API void SetKeepMask(const OutputId &outputId, const VdfMask &mask)
Registers a keep mask for the output indicated by outputId.
const VdfScheduleInputsTask & GetInputsTask(const VdfScheduleTaskIndex index) const
Returns the inputs task associated with the given task index.
Definition: schedule.h:439
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 VdfMask & GetRequestMask(const VdfScheduleTaskIndex invocationIndex) const
Returns the request mask for the given node invocation.
Definition: schedule.h:294
VDF_API const VdfNode * GetNode(const OutputId &outputId) const
Returns the VdfNode that owns the VdfOutput associated with the given outputId.
VdfSchedule(const VdfSchedule &)=delete
Noncopyable.
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 const VdfOutput * GetOutputToClear(const VdfNode &node) const
Returns the output whose temporary buffer can be immediately deallocated after node has finished exec...
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
bool IsValid() const
Returns whether or not this schedule is valid and can be used for execution.
Definition: schedule.h:172
ScheduleNodeVector & GetScheduleNodeVector()
Returns the vector of schedule nodes in this schedule.
Definition: schedule.h:503
size_t GetNumInputsTasks() const
Returns the total number of inputs tasks in the schedule.
Definition: schedule.h:383
VDF_API void Clear()
Clears the schedule.
bool IsSmallSchedule() const
Returns whether this schedule is small enough to avoid overhead incurred by the _nodesToIndexMap mapp...
Definition: schedule.h:487
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 const VdfOutput * GetOutput(const OutputId &outputId) const
Returns the scheduled VdfOutput associated with the given OutputId.
size_t GetNumPrepTasks() const
Returns the total number of prep tasks in the schedule.
Definition: schedule.h:389
VDF_API void SetFromBufferOutput(const OutputId &outputId, const VdfOutput *output)
Registers a "from buffer" for the output indicated by outputId.
InputDependencyRange GetOptionalInputDependencies(const VdfScheduleInputsTask &task) const
Returns an iterable range of optional (i.e.
Definition: schedule.h:458
size_t GetNumComputeTasks() const
Returns the total number of compute tasks in the schedule.
Definition: schedule.h:377
bool HasSMBL() const
Returns true if this schedule participates in sparse mung buffer locking.
Definition: schedule.h:353
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...
Used to make a VdfSchedule.
Definition: scheduler.h:35
std::function< void(const VdfOutput *, const VdfMask &)> VdfScheduledOutputCallback
Function type to be used with ForEachScheduledOutput().
Definition: types.h:86
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
#define TF_DEV_AXIOM(cond)
The same as TF_AXIOM, but compiled only in dev builds.
Definition: diagnostic.h:205
uint32_t VdfScheduleInputDependencyUniqueIndex
A sequential index assigned to the unique output and mask combination of a VdfScheduleInputDependency...
bool VdfScheduleTaskIsInvalid(uint32_t task)
Returns true if the given task index or id is invalid.
Definition: scheduleTasks.h:41
uint32_t VdfScheduleTaskIndex
Type describing a task index.
Definition: scheduleTasks.h:29
A VdfScheduleComputeTask represents a unit of computation for the parallel evaluation engine.
Definition: scheduleTasks.h:64
Describes a single input dependency, i.e.
Structure describing an additional task used to run prereqs and reads concurrently with read/write in...