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 
20 #include "pxr/base/tf/diagnostic.h"
22 
23 PXR_NAMESPACE_OPEN_SCOPE
24 
26 
33 
34 template <
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 
56 public:
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 
97 private:
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 
115 private:
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 
129 template <template <typename> class EngineType, typename DataManagerType>
130 const typename VdfSpeculationExecutor<EngineType, DataManagerType>::_Factory
132 
133 template <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 
159 template <template <typename> class EngineType, typename DataManagerType>
160 void
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 
173 template <template <typename> class EngineType, typename DataManagerType>
174 bool
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 
189 template <template <typename> class EngineType, typename DataManagerType>
190 void
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 
213 PXR_NAMESPACE_CLOSE_SCOPE
214 
215 #endif
A client may instantiate an object of this class and set it in an executor, to collect errors that ma...
VdfExecutionStats * GetExecutionStats() const
Returns the Execution Stats object, if any.
Base class for executors that use a data manager.
const VdfNetwork & GetNetwork() const
Returns the network to which this node belongs.
Definition: node.h:138
Execution stats profiling event logger.
virtual const VdfExecutorFactoryBase & GetFactory() const override final
Returns the factory instance for this executor.
A VdfMask is placed on connections to specify the data flowing through them.
Definition: mask.h:36
Low-level utilities for informing users of various internal and external diagnostic conditions.
Executor used in speculation.
This class is used to abstract away knowledge of the cache data used for each node.
Definition: vector.h:58
Contains a specification of how to execute a particular VdfNetwork.
Definition: schedule.h:40
#define TF_VERIFY(cond, format,...)
Checks a condition and reports an error if it evaluates false.
Definition: diagnostic.h:267
#define TRACE_FUNCTION()
Records a timestamp when constructed and a timespan event when destructed, using the name of the func...
Definition: trace.h:30
A node that pulls on a vector of value that are downstream of the current execution position.
auto WorkWithScopedParallelism(Fn &&fn, bool dropPythonGIL=true)
Invoke fn, ensuring that all wait operations on concurrent constructs invoked by the calling thread o...
const std::atomic_bool * GetInterruptionFlag() const
Returns the interruption flag.
VdfSpeculationExecutor(const VdfSpeculationNode *speculationNode, const VdfExecutorInterface *parentExecutor)
Constructs a speculation executor that was initiated from speculationNode while being computed by par...
A VdfOutput represents an output on a node.
Definition: output.h:31
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.
VDF_API VdfExecutionStats * AddSubStat(const VdfNetwork *network, const VdfNode *invokingNode)
Push execution stats onto the hierarchy queue.
VdfSpeculationExecutor(const VdfExecutorInterface *parentExecutor)
Construct a speculation executor with the given parentExecutor, without registering a speculation nod...
Abstract base class for classes that execute a VdfNetwork to compute a requested set of values.
virtual ~VdfSpeculationExecutor()
Destructor.