7 #ifndef PXR_EXEC_VDF_PULL_BASED_EXECUTOR_ENGINE_H
8 #define PXR_EXEC_VDF_PULL_BASED_EXECUTOR_ENGINE_H
32 #include "pxr/base/tf/mallocTag.h"
41 #define _VDF_PBEE_PROFILING_ON 0
42 #if _VDF_PBEE_PROFILING_ON
43 #define VDF_PBEE_TRACE_FUNCTION TRACE_FUNCTION
44 #define VDF_PBEE_TRACE_SCOPE TRACE_SCOPE
46 #define VDF_PBEE_TRACE_FUNCTION()
47 #define VDF_PBEE_TRACE_SCOPE(name)
66 template <
typename DataManagerType>
83 DataManagerType *dataManager) :
85 _dataManager(dataManager)
96 schedule, computeRequest, errorLogger,
105 template <
typename F >
143 bool absorbLockedCache =
false);
160 bool absorbLockedCache =
false);
170 const VdfMask &fromMask)
const;
232 struct _OutputToExecute {
237 const VdfMask &lockedCacheMask,
241 lockedCacheMask(lockedCacheMask),
242 affective(affective),
243 absorbLockedCache(false)
259 bool absorbLockedCache;
268 bool _PushBackOutput(
269 std::vector< _OutputToExecute > *outputs,
270 const VdfMask &lockedCacheMask,
285 void _FinalizeComputedOutput(
288 const bool hasBeenInterrupted,
289 const bool extendRequestMask);
297 bool _UpdateOutputForSMBL(
299 _OutputToExecute *stackEntry,
308 DataManagerType *_dataManager;
313 std::vector<_DataHandle> _dataHandleCache;
319 template<
typename DataManagerType>
341 for (
size_t i = 0; i < requestView.
GetSize(); ++i) {
353 if (_GetExecutor().GetOutputValue(output, mask)) {
354 callback(*maskedOutput, i);
359 "VdfPullBasedExecutorEngine<T>::RunSchedule (executing output)");
360 _ExecuteOutput(state, output, &executedNodes);
363 if (_GetExecutor().HasBeenInterrupted()) {
370 callback(*maskedOutput, i);
375 template<
typename DataManagerType>
383 TfAutoMallocTag2 tag(
"Vdf",
"VdfPullBasedExecutorEngine<T>::_CopyCache");
390 _executor.GetOutputValue(fromOutput, fromMask);
399 VdfVector *
result = _dataManager->CreateOutputCache(toOutput, toBuffer);
400 result->
Copy(*sourceVector, fromMask);
413 template<
typename DataManagerType>
433 while (betweenOutput && betweenOutput != &source) {
434 _GetExecutor()._TouchOutput(*betweenOutput);
438 return _PassOrCopyBufferInternal(
439 dataHandle, output, source, inputMask, schedule);
442 template<
typename DataManagerType>
456 _dataManager->GetDataHandle(source.
GetId());
463 if (_dataManager->IsValidDataHandle(sourceHandle) &&
468 _dataManager->GetBufferData(sourceHandle);
483 if (_dataManager->HasInvalidationTimestampMismatch(
484 sourceHandle, dataHandle)) {
486 .Msg(
"Mung buffer locking between outputs "
510 result = _dataManager->PassBuffer(
511 source, sourceBuffer,
512 output, _dataManager->GetBufferData(dataHandle),
516 _executor.GetExecutionStats()) {
533 "VdfPullBasedExecutorEngine<T>::_PassOrCopyBufferInternal "
536 output, _dataManager->GetBufferData(dataHandle),
source, inputMask);
542 template<
typename DataManagerType>
558 if (numInputNodes == 1 && !input[0].GetMask().IsAllZeros()) {
559 _PassOrCopyBufferInternal(
560 dataHandle, *output, input[0].GetSourceOutput(), mask, schedule);
565 _dataManager->CreateOutputCache(
566 *output, _dataManager->GetBufferData(dataHandle));
569 template<
typename DataManagerType>
572 std::vector< _OutputToExecute > *outputs,
573 const VdfMask& lockedCacheMask,
595 template<
typename DataManagerType>
599 _OutputToExecute *stackEntry,
605 const _DataHandle dataHandle = _dataManager->GetDataHandle(output.
GetId());
606 if (!_dataManager->IsValidDataHandle(dataHandle)) {
612 _dataManager->GetInvalidationTimestamp(dataHandle);
615 if (!invalidationTs) {
627 if (invalidationTs != _dataManager->GetInvalidationTimestamp()) {
628 if (!stackEntry->lockedCacheMask.IsEmpty()) {
629 stackEntry->lockedCacheMask =
VdfMask();
636 bool updated =
false;
642 _dataManager->GetBufferData(dataHandle);
643 VdfSMBLData *smblData = _dataManager->GetOrCreateSMBLData(dataHandle);
650 &stackEntry->lockedCacheMask,
652 stackEntry->absorbLockedCache =
true;
657 if (stackEntry->lockedCacheMask.IsEmpty()) {
668 &stackEntry->lockedCacheMask,
678 if (stackEntry->affective &&
680 stackEntry->lockedCacheMask,
682 stackEntry->affective =
false;
690 template<
typename DataManagerType>
698 "----------------- _ExecuteOutput --------- \n");
710 const bool enableSMBL =
711 schedule.
HasSMBL() && !_GetExecutor().GetInterruptionFlag();
714 std::vector< _OutputToExecute > outputsStack;
717 _PushBackOutput(&outputsStack,
VdfMask(), output, schedule);
719 while (!outputsStack.empty()) {
722 if (_GetExecutor().HasBeenInterrupted()) {
728 bool affective = outputsStack.back().affective;
729 VdfMask lockedCacheMask = outputsStack.back().lockedCacheMask;
730 bool absorbLockedCache = outputsStack.back().absorbLockedCache;
733 const VdfMask *requestMask = NULL;
738 switch (outputsStack.back().stage) {
740 case ExecutionStageStart:
743 .Msg(
"{ BeginNode(\"%s\");\n", node.
GetDebugName().c_str());
754 _GetExecutor().GetOutputValue(*output, *requestMask)) {
757 outputsStack.pop_back();
759 TF_DEBUG(VDF_PBEE_TRACE).Msg(
" EndNodeFoundCache(); }\n");
770 _OutputToExecute *stackTop = &outputsStack.back();
771 if (_UpdateOutputForSMBL(*output, stackTop, schedule)) {
772 affective = stackTop->affective;
773 lockedCacheMask = stackTop->lockedCacheMask;
774 absorbLockedCache = stackTop->absorbLockedCache;
783 outputsStack.back().stage = ExecutionStagePreRequisitesDone;
788 if (input.input->GetSpec().IsPrerequisite()) {
789 added |= _PushBackOutput(
790 &outputsStack,
VdfMask(), *input.source, schedule);
802 case ExecutionStagePreRequisitesDone:
810 outputsStack.back().stage = ExecutionStageCompute;
831 added |= _PushBackOutput(
833 *input.source, schedule);
843 input.input->GetAssociatedOutput();
854 added |= _PushBackOutput(
855 &outputsStack, lockedCacheMask,
856 *fromBufferOutput, schedule);
864 added |= _PushBackOutput(
865 &outputsStack, lockedCacheMask, *input.source, schedule);
882 _ComputeNode(state, node, absorbLockedCache);
885 "ComputedNode(\"%s\"); }\n", node.
GetDebugName().c_str());
891 _PassThroughNode(schedule, node, absorbLockedCache);
894 .Msg(
"ComputedNodeInaffective(\"%s\"); }\n",
899 outputsStack.pop_back();
904 template<
typename DataManagerType>
909 bool absorbLockedCache)
927 _dataHandleCache.clear();
934 _dataManager->GetOrCreateDataHandle(output.
GetId());
935 _dataHandleCache.push_back(dataHandle);
939 _dataManager->GetBufferData(dataHandle);
944 if (absorbLockedCache ||
946 _IsNotPassing(output, outputId, schedule))) {
949 _dataManager->GetOrCreateSMBLData(dataHandle));
958 _dataManager->Touch(dataHandle);
967 _PrepareReadWriteBuffer(dataHandle, *ai, requestMask, schedule);
968 _dataManager->SetComputedOutputMask(bufferData, requestMask);
975 "VdfPullBasedExecutorEngine<T>::_ComputeNode "
982 const bool hasBeenInterrupted = _GetExecutor().HasBeenInterrupted();
992 _dataManager->GetDataHandle(ctd->GetId());
993 if (_dataManager->IsValidDataHandle(dataHandle)) {
994 _dataManager->GetBufferData(dataHandle)->Reset();
999 size_t outputIndex = 0;
1005 const _DataHandle dataHandle = _dataHandleCache[outputIndex++];
1009 _dataManager->GetBufferData(dataHandle);
1014 if (!hasBeenInterrupted &&
1037 _dataManager->GetOrCreateOutputValueForWriting(
1038 output, dataHandle));
1043 _FinalizeComputedOutput(
1047 _IsNotPassing(output, outputId, schedule));
1061 template<
typename DataManagerType>
1066 bool absorbLockedCache)
1070 bool passedThrough =
false;
1082 _dataManager->GetOrCreateDataHandle(output.
GetId());
1086 _dataManager->GetBufferData(dataHandle);
1091 if (absorbLockedCache ||
1093 && _IsNotPassing(output, outputId, schedule))) {
1096 _dataManager->GetOrCreateSMBLData(dataHandle));
1106 _dataManager->Touch(dataHandle);
1111 _PassOrCopySourceOutputBuffer(
1112 dataHandle, output, *fromBufferOutput, requestMask, schedule);
1114 passedThrough =
true;
1123 _PrepareReadWriteBuffer(dataHandle, *ai, requestMask, schedule);
1124 passedThrough =
true;
1129 _FinalizeComputedOutput(
1133 _IsNotPassing(output, outputId, schedule));
1136 return passedThrough;
1139 template<
typename DataManagerType>
1142 const _DataHandle dataHandle,
1144 const bool hasBeenInterrupted,
1145 const bool extendRequestMask)
1157 if (hasBeenInterrupted) {
1158 _dataManager->SetComputedOutputMask(bufferData,
VdfMask());
1166 _dataManager->SetComputedOutputMask(
1168 extendRequestMask && !lockedMask.
IsEmpty() ?
1169 lockedMask | requestMask :
VDF_API bool IsAffective(const OutputId &outputId) const
bool _PassThroughNode(const VdfSchedule &schedule, const VdfNode &node, bool absorbLockedCache=false)
VDF_API const VdfMask & GetAffectsMask(const OutputId &outputId) const
virtual VDF_API VdfRequiredInputsPredicate GetRequiredInputsPredicate(const VdfContext &context) const
VDF_API const VdfMask & GetKeepMask(const OutputId &outputId) const
void _ComputeNode(const VdfEvaluationState &state, const VdfNode &node, bool absorbLockedCache=false)
#define VDF_PBEE_TRACE_SCOPE(name)
bool ComputeAffectiveness(const VdfMask &lockedCacheMask, const VdfMask &affectsMask)
VDF_API const VdfOutput * GetPassToOutput(const OutputId &outputId) const
const VdfNetwork * GetNetwork() const
ScheduleNodeVector & GetScheduleNodeVector()
#define VDF_FOR_EACH_SCHEDULED_OUTPUT_ID(OUTPUT_ID_NAME, VDF_SCHEDULE, VDF_NODE)
VDF_API const VdfOutput * GetFromBufferOutput(const OutputId &outputId) const
#define PXR_NAMESPACE_OPEN_SCOPE
VDF_API OutputId GetOutputId(const VdfOutput &output) const
VDF_API const std::string GetDebugName() const
#define VDF_PBEE_TRACE_FUNCTION()
std::string const & GetString() const
Return the string that this token represents.
const VdfMask & GetMask() const
VdfSpeculationExecutorEngine< DataManagerType > SpeculationExecutorEngine
A VdfMask is placed on connections to specify the data flowing through them.
const VdfNode & GetNode() const
virtual void Compute(const VdfContext &context) const =0
**But if you need a result
VDF_API const VdfOutputSpec & GetSpec() const
static VDF_API void FillVector(TfType type, size_t numElements, VdfVector *vector)
VDF_API VdfMask ReleaseExecutorCache(VdfSMBLData *smblData)
VDF_API InputsRange GetInputs(const VdfNode &node) const
const VdfInput * GetAssociatedInput() const
void _PrepareReadWriteBuffer(const _DataHandle dataHandle, const VdfInput &input, const VdfMask &mask, const VdfSchedule &schedule)
VDF_API const VdfOutput * GetOutput(const OutputId &outputId) const
#define TF_DEV_AXIOM(cond)
static bool _IsNotPassing(const VdfOutput &output, const VdfSchedule::OutputId &outputId, const VdfSchedule &schedule)
Fast bit array that keeps track of the number of bits set and can find the next set in a timely manne...
void Copy(const VdfVector &rhs, const VdfMask &mask)
VdfVector * _PassOrCopyBufferInternal(const _DataHandle dataHandle, const VdfOutput &output, const VdfOutput &source, const VdfMask &inputMask, const VdfSchedule &schedule) const
void ResetExecutorCache(const VdfMask &mask)
VdfVector * _CopyCache(const VdfOutput &toOutput, VdfExecutorBufferData *toBuffer, const VdfOutput &fromOutput, const VdfMask &fromMask) const
int GetScheduleNodeIndex(const OutputId &outputId) const
Contains a specification of how to execute a particular VdfNetwork.
const VdfMaskedOutput * Get(const size_t i) const
bool Vdf_IsPoolOutput(const VdfOutput &output)
VDF_API const VdfNode * GetNode(const OutputId &outputId) const
void LogTimestamp(EventType event, const VdfNode &node)
VdfSMBLData holds per-output data that is meant to be consumed by the executor. This data is an optio...
VDF_API const TfToken & GetName() const
GLsizei GLsizei GLchar * source
const VdfSchedule & GetSchedule() const
const VdfExecutorInterface & _GetExecutor()
bool Contains(const VdfMask &mask) const
This object is responsible for storing the executor buffer data, comprised of the executor cache vect...
DataManagerType * _GetDataManager()
VDF_API std::string GetDebugName() const
#define TF_DEBUG(enumVal)
TfType GetType() const
Returns the type of this spec.
Class to hold on to an externally owned output and a mask.
const VdfMask & GetExecutorCacheMask() const
void ExtendLockedCacheMask(VdfMask *lockedCacheMask, const VdfMask &cacheMask)
VDF_API const VdfMask & GetRequestMask(const OutputId &outputId) const
void LogData(EventType event, const VdfNode &node, EventData data)
TF_API const std::string & GetTypeName() const
void RunSchedule(const VdfSchedule &schedule, const VdfRequest &computeRequest, VdfExecutorErrorLogger *errorLogger)
unsigned int VdfInvalidationTimestamp
Type of the timestamp that identifies the most recent round of invalidation.
VdfVector * _PassOrCopySourceOutputBuffer(const _DataHandle dataHandle, const VdfOutput &output, const VdfOutput &source, const VdfMask &inputMask, const VdfSchedule &schedule)
#define PXR_NAMESPACE_CLOSE_SCOPE
DataManagerType::DataHandle _DataHandle
VDF_API const VdfOutput * VdfGetAssociatedSourceOutput(const VdfOutput &output)
This class provides an executor engine to the speculation executor.
This class is a collection of common functions used by pulled based executors.
Abstract base class for classes that execute a VdfNetwork to compute a requested set of values...
VdfVector * GetExecutorCache() const
bool IsSet(size_t index) const
void RemoveUncachedMask(VdfMask *lockedCacheMask, const VdfMask &cacheMask, const VdfMask &keepMask)
VdfOutput * GetOutput() const
VdfPullBasedExecutorEngine(const VdfExecutorInterface &executor, DataManagerType *dataManager)
VDF_API const VdfOutput * GetOutputToClear(const VdfNode &node) const
VDF_API void RetainExecutorCache(const VdfOutputSpec &spec, VdfSMBLData *smblData)