HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
parallelSpeculationExecutorEngine.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_PARALLEL_SPECULATION_EXECUTOR_ENGINE_H
8 #define PXR_EXEC_VDF_PARALLEL_SPECULATION_EXECUTOR_ENGINE_H
9 
10 ///\file
11 
12 #include "pxr/pxr.h"
13 
16 
17 #include <atomic>
18 
20 
21 ///////////////////////////////////////////////////////////////////////////////
22 ///
23 /// \class VdfParallelSpeculationExecutorEngine
24 ///
25 /// An executor engine used for parallel speculation node evaluation,
26 /// deriving from VdfParallelExecutorEngineBase. The engine does not support
27 /// arena execution. The reason being that the parent executor engine will
28 /// already be executing tasks inside of an arena. The engine does also not
29 /// need to do any touching, or buffer locking, due to its temporary lifetime.
30 /// It does, however, do cycle detection.
31 ///
32 template < typename DataManagerType >
35  VdfParallelSpeculationExecutorEngine<DataManagerType>,
36  DataManagerType>
37 {
38 public:
39 
40  /// Base class.
41  ///
42  typedef
45  DataManagerType>
47 
48  /// Constructor.
49  ///
51  const VdfSpeculationExecutorBase &speculationExecutor,
52  DataManagerType *dataManager);
53 
54 private:
55 
56  // Befriend the base class so that it has access to the private methods
57  // used for static polymorphism.
58  //
59  friend Base;
60 
61  // Detect a cycle by looking at the current node and determining whether it
62  // is the same node that started the speculation.
63  //
64  bool _DetectCycle(
66  const VdfNode &node);
67 
68  // This executor engine does not need to do any touching on itself. It does,
69  // however, touch output buffers on the parent executor.
70  //
71  void _Touch(const VdfOutput &output);
72 
73  // Finalize the output before publishing any buffers.
74  //
75  void _FinalizeOutput(
77  const VdfOutput &output,
78  const VdfSchedule::OutputId outputId,
79  const typename Base::_DataHandle dataHandle,
80  const VdfScheduleTaskIndex invocationIndex,
81  const VdfOutput *passToOutput);
82 
83  // Finalize any state after evaluation completed.
84  //
85  void _FinalizeEvaluation() {}
86 
87  // The first non-speculation parent executor to transfer buffers to.
88  //
89  VdfExecutorInterface *_writeBackExecutor;
90 };
91 
92 ///////////////////////////////////////////////////////////////////////////////
93 
94 template < typename DataManagerType >
97  const VdfSpeculationExecutorBase &speculationExecutor,
98  DataManagerType *dataManager) :
99  Base(speculationExecutor, dataManager),
100  _writeBackExecutor(const_cast<VdfExecutorInterface *>(
101  speculationExecutor.GetNonSpeculationParentExecutor()))
102 {
103 
104 }
105 
106 template < typename DataManagerType >
107 bool
109  const VdfEvaluationState &state,
110  const VdfNode &node)
111 {
112  // This engine is always constructed with a speculation executor (c.f.
113  // constructor).
114  const VdfSpeculationExecutorBase &speculationExecutor =
115  static_cast<const VdfSpeculationExecutorBase &>(state.GetExecutor());
116 
117  // If the node to execute is the same speculation node that ran this
118  // executor engine, evaluation is trapped in a cycle.
119  return speculationExecutor.IsSpeculatingNode(&node);
120 }
121 
122 template < typename DataManagerType >
123 void
125  const VdfOutput &output)
126 {
127  // The speculation executor engine doesn't need to touch locally, but we
128  // need to dispatch the call to th executor and its parents.
129  Base::_executor._TouchOutput(output);
130 }
131 
132 template < typename DataManagerType >
133 void
135  const VdfEvaluationState &state,
136  const VdfOutput &output,
137  const VdfSchedule::OutputId outputId,
138  const typename Base::_DataHandle dataHandle,
139  const VdfScheduleTaskIndex invocationIndex,
140  const VdfOutput *passToOutput)
141 {
142  // Only write back buffers for outputs which do not pass their buffers.
143  if (passToOutput) {
144  return;
145  }
146 
147  // Bail out of the output does not have ownership over the cache. We can't
148  // transfer ownership we don't have in the first place.
149  VdfExecutorBufferData *privateBuffer =
150  Base::_dataManager->GetPrivateBufferData(dataHandle);
151  if (!privateBuffer->HasOwnership()) {
152  return;
153  }
154 
155  // Bail out if the write back executor already contains all the data.
156  const VdfMask &mask = privateBuffer->GetExecutorCacheMask();
157  if (_writeBackExecutor->GetOutputValue(output, mask)) {
158  return;
159  }
160 
161  // Attempt to transfer ownership of the buffer to the write back executor.
162  // Relinquish ownership of the private buffer if this operation succeeds:
163  // The write back executor will now own this buffer instead.
164  VdfVector *value = privateBuffer->GetExecutorCache();
165  if (_writeBackExecutor->TakeOutputValue(output, value, mask)) {
166  privateBuffer->YieldOwnership();
167  }
168 }
169 
171 
172 #endif
#define PXR_NAMESPACE_OPEN_SCOPE
Definition: pxr.h:73
GLsizei const GLfloat * value
Definition: glcorearb.h:824
Definition: node.h:52
A VdfMask is placed on connections to specify the data flowing through them.
Definition: mask.h:36
VdfParallelExecutorEngineBase< VdfParallelSpeculationExecutorEngine< DataManagerType >, DataManagerType > Base
GLint GLuint mask
Definition: glcorearb.h:124
This object is responsible for storing the executor buffer data, comprised of the executor cache vect...
const VdfMask & GetExecutorCacheMask() const
bool IsSpeculatingNode(const VdfNode *node) const
const VdfExecutorInterface & GetExecutor() const
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
uint32_t VdfScheduleTaskIndex
Definition: scheduleTasks.h:29
Abstract base class for classes that execute a VdfNetwork to compute a requested set of values...
VdfVector * GetExecutorCache() const
state
Definition: core.h:2289
VdfParallelSpeculationExecutorEngine(const VdfSpeculationExecutorBase &speculationExecutor, DataManagerType *dataManager)