Loading...
Searching...
No Matches
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
11
12#include "pxr/pxr.h"
13
16
17#include <atomic>
18
19PXR_NAMESPACE_OPEN_SCOPE
20
32template < typename DataManagerType >
35 VdfParallelSpeculationExecutorEngine<DataManagerType>,
36 DataManagerType>
37{
38public:
39
42 typedef
45 DataManagerType>
47
51 const VdfSpeculationExecutorBase &speculationExecutor,
52 DataManagerType *dataManager);
53
54private:
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(
65 const VdfEvaluationState &state,
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(
76 const VdfEvaluationState &state,
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
93
94template < 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
106template < typename DataManagerType >
107bool
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
122template < typename DataManagerType >
123void
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
132template < typename DataManagerType >
133void
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
170PXR_NAMESPACE_CLOSE_SCOPE
171
172#endif
This object holds state that remains persistent during one round of network evaluation.
const VdfExecutorInterface & GetExecutor() const
The executor used for evaluation.
This object is responsible for storing the executor buffer data, comprised of the executor cache vect...
const VdfMask & GetExecutorCacheMask() const
Get the available mask.
bool HasOwnership() const
Returns true if the buffer owns the executor cache.
VdfVector * GetExecutorCache() const
Returns the executor cache stored at this buffer data instance.
void YieldOwnership()
Yields ownership of the internal vector, i.e.
Abstract base class for classes that execute a VdfNetwork to compute a requested set of values.
A VdfMask is placed on connections to specify the data flowing through them.
Definition: mask.h:37
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
The base class for all parallel executor engines.
An executor engine used for parallel speculation node evaluation, deriving from VdfParallelExecutorEn...
VdfParallelSpeculationExecutorEngine(const VdfSpeculationExecutorBase &speculationExecutor, DataManagerType *dataManager)
Constructor.
VdfParallelExecutorEngineBase< VdfParallelSpeculationExecutorEngine< DataManagerType >, DataManagerType > Base
Base class.
An OutputId is a small key object that, once obtained for a particular VdfOutput, can be used to quer...
Definition: schedule.h:91
This class is used to abstract away knowledge of the cache data used for each node.
Definition: vector.h:56
uint32_t VdfScheduleTaskIndex
Type describing a task index.
Definition: scheduleTasks.h:29