Loading...
Searching...
No Matches
speculationExecutor.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_SPECULATION_EXECUTOR_H
8#define PXR_EXEC_VDF_SPECULATION_EXECUTOR_H
9
11
12#include "pxr/pxr.h"
13
19
22
23PXR_NAMESPACE_OPEN_SCOPE
24
26
33
34template <
35 template <typename> class EngineType,
36 typename DataManagerType>
38 public VdfDataManagerBasedSubExecutor <
39 DataManagerType,
40 VdfSpeculationExecutorBase >
41{
42 // Base class type
43 typedef
44 VdfDataManagerBasedSubExecutor <
45 DataManagerType,
46 VdfSpeculationExecutorBase >
47 Base;
48
49 // Executor factory.
50 typedef
51 VdfExecutorFactory<
54 _Factory;
55
56public:
57
62 const VdfSpeculationNode *speculationNode,
63 const VdfExecutorInterface *parentExecutor);
64
69 const VdfExecutorInterface *parentExecutor) :
70 VdfSpeculationExecutor(nullptr, parentExecutor)
71 {}
72
76
79 virtual void SetOutputValue(
80 const VdfOutput &output,
81 const VdfVector &value,
82 const VdfMask &mask) override final;
83
86 virtual bool TakeOutputValue(
87 const VdfOutput &output,
88 VdfVector *value,
89 const VdfMask &mask) override final;
90
93 virtual const VdfExecutorFactoryBase &GetFactory() const override final {
94 return _factory;
95 }
96
97private:
98
99 // Run this executor with the given \p schedule and \p request.
100 //
101 virtual void _Run(
102 const VdfSchedule &schedule,
103 const VdfRequest &computeRequest,
104 VdfExecutorErrorLogger *errorLogger) override final;
105
106 // Mark the output as having been visited. On speculation executors,
107 // we don't need to do anything other than notify the parent. Since this
108 // executor is temporary, we never do invalidation on it, and therefore
109 // can safely avoid doing the touching on the local data manager.
110 //
111 virtual void _TouchOutput(const VdfOutput &output) const override final {
112 Base::GetNonSpeculationParentExecutor()->_TouchOutput(output);
113 }
114
115private:
116
117 // The factory instance.
118 //
119 static const _Factory _factory;
120
121 // This is the engine that will do most of our hard work for us.
122 //
123 EngineType<DataManagerType> _engine;
124
125};
126
128
129template <template <typename> class EngineType, typename DataManagerType>
130const typename VdfSpeculationExecutor<EngineType, DataManagerType>::_Factory
132
133template <template <typename> class EngineType, typename DataManagerType>
135 const VdfSpeculationNode *speculationNode,
136 const VdfExecutorInterface *parentExecutor) :
137 Base(parentExecutor),
138 _engine(*this, &this->_dataManager)
139{
140 // Apply the executors speculation node.
141 Base::_SetSpeculationNode(speculationNode);
142
143 // Create sub stats on the parent executor and set them on this speculation
144 // executor. Set a nullptr if the parent does not have stats itself, or if
145 // speculationNode is a nullptr.
146 VdfExecutionStats *stats = parentExecutor->GetExecutionStats();
147 VdfExecutionStats *subStats = stats && speculationNode
148 ? stats->AddSubStat(&speculationNode->GetNetwork(), speculationNode)
149 : stats;
150 Base::SetExecutionStats(subStats);
151
152 // Propagate the interruption flag from the parent executor to the
153 // speculation executor. This must be done in order to ensure that when the
154 // parent executor has been interrupted, execution will also be interrupted
155 // on the speculation executor.
156 Base::SetInterruptionFlag(parentExecutor->GetInterruptionFlag());
157}
158
159template <template <typename> class EngineType, typename DataManagerType>
160void
162 const VdfOutput &output,
163 const VdfVector &value,
164 const VdfMask &mask)
165{
166 // Call into the base class to set the output value.
167 Base::SetOutputValue(output, value, mask);
168
169 // Make sure to also touch the output on the non-speculation-parent.
170 _TouchOutput(output);
171}
172
173template <template <typename> class EngineType, typename DataManagerType>
174bool
176 const VdfOutput &output,
177 VdfVector *value,
178 const VdfMask &mask)
179{
180 // Call into the base class to take the output value.
181 const bool success = Base::TakeOutputValue(output, value, mask);
182
183 // Make sure to also touch the output on the non-speculation-parent.
184 _TouchOutput(output);
185
186 return success;
187}
188
189template <template <typename> class EngineType, typename DataManagerType>
190void
192 const VdfSchedule &schedule,
193 const VdfRequest &computeRequest,
194 VdfExecutorErrorLogger *errorLogger)
195{
196 TRACE_FUNCTION();
197
198 TF_VERIFY(Base::GetParentExecutor());
199 // Isolate tasks for speculation to ensure that they can make progress
200 // independently of parent execution tasks, i.e. threads that enter this
201 // isolated region will only be able to steal other speculation tasks
202 // spawned within the region. Note that main execution tasks are still
203 // free to steal tasks spawned from within this isolated region when idle,
204 // at which point they will become isolated until completion. This is a
205 // performance optimization that ensures idle threads are making progress
206 // on blocking tasks.
208 [&engine = _engine, &schedule, &computeRequest, errorLogger]() {
209 engine.RunSchedule(schedule, computeRequest, errorLogger);
210 });
211}
212
213PXR_NAMESPACE_CLOSE_SCOPE
214
215#endif
Low-level utilities for informing users of various internal and external diagnostic conditions.
Execution stats profiling event logger.
VDF_API VdfExecutionStats * AddSubStat(const VdfNetwork *network, const VdfNode *invokingNode)
Push execution stats onto the hierarchy queue.
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.
const std::atomic_bool * GetInterruptionFlag() const
Returns the interruption flag.
VdfExecutionStats * GetExecutionStats() const
Returns the Execution Stats object, if any.
A VdfMask is placed on connections to specify the data flowing through them.
Definition: mask.h:37
const VdfNetwork & GetNetwork() const
Returns the network to which this node belongs.
Definition: node.h:138
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
Executor used in speculation.
VdfSpeculationExecutor(const VdfSpeculationNode *speculationNode, const VdfExecutorInterface *parentExecutor)
Constructs a speculation executor that was initiated from speculationNode while being computed by par...
virtual void SetOutputValue(const VdfOutput &output, const VdfVector &value, const VdfMask &mask) override final
Set the cached value for a given output.
virtual bool TakeOutputValue(const VdfOutput &output, VdfVector *value, const VdfMask &mask) override final
Transfers ownership of value to the given output.
virtual ~VdfSpeculationExecutor()
Destructor.
virtual const VdfExecutorFactoryBase & GetFactory() const override final
Returns the factory instance for this executor.
VdfSpeculationExecutor(const VdfExecutorInterface *parentExecutor)
Construct a speculation executor with the given parentExecutor, without registering a speculation nod...
A node that pulls on a vector of value that are downstream of the current execution position.
This class is used to abstract away knowledge of the cache data used for each node.
Definition: vector.h:56
#define TF_VERIFY(cond, format,...)
Checks a condition and reports an error if it evaluates false.
Definition: diagnostic.h:266
auto WorkWithScopedParallelism(Fn &&fn, bool dropPythonGIL=true)
Invoke fn, ensuring that all wait operations on concurrent constructs invoked by the calling thread o...