Loading...
Searching...
No Matches
testUtils.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_TEST_UTILS_H
8#define PXR_EXEC_VDF_TEST_UTILS_H
9
11
12#include "pxr/pxr.h"
13
14#include "pxr/exec/vdf/api.h"
27
28#include "pxr/base/tf/hash.h"
29#include "pxr/base/tf/hashmap.h"
30#include "pxr/base/tf/token.h"
31
32#include <functional>
33#include <memory>
34#include <string>
35
36PXR_NAMESPACE_OPEN_SCOPE
37
38class VdfMask;
39class VdfNode;
41
73
74namespace VdfTestUtils
75{
76
82class VDF_API_TYPE CallbackNode : public VdfNode
83{
84public:
85
86 using ValueFunction = void(const VdfContext &context);
87
89 VdfNetwork *network,
90 const VdfInputSpecs &inputSpecs,
91 const VdfOutputSpecs &outputSpecs,
92 ValueFunction *const cb)
93 : VdfNode(network, inputSpecs, outputSpecs),
94 _cb(cb) {}
95
96 virtual void Compute(const VdfContext &context) const override {
97 (*_cb)(context);
98 }
99
100protected:
101
102 virtual ~CallbackNode() {}
103
104 virtual bool _IsDerivedEqual(const VdfNode &rhs) const override {
105 return false;
106 }
107
108private:
109
110 ValueFunction *const _cb;
111};
112
119{
120public:
121 OutputAccessor(const VdfContext &context) : _context(context) {}
122
123 const VdfOutput *GetOutput() const {
124 return _GetNode(_context).GetOutput();
125 }
126
127private:
128 const VdfContext &_context;
129
130};
131
138class VDF_API_TYPE DependencyCallbackNode : public CallbackNode
139{
140public:
141 using InputDependencyFunction = std::function<
142 VdfMask::Bits (const VdfMaskedOutput &maskedOutput,
143 const VdfConnection &inputConnection)>;
144
145 using OutputDependencyFunction = std::function<
146 VdfMask (const VdfConnection &inputConnection,
147 const VdfMask &inputDependencyMask,
148 const VdfOutput &output)>;
149
151 VdfNetwork *network,
152 const VdfInputSpecs &inputSpecs,
153 const VdfOutputSpecs &outputSpecs,
154 ValueFunction *function,
155 const InputDependencyFunction &inputDependencyFunction,
156 const OutputDependencyFunction &outputDependencyFunction) :
157 CallbackNode(network, inputSpecs, outputSpecs, function),
158 _inputDependencyFunction(inputDependencyFunction),
159 _outputDependencyFunction(outputDependencyFunction) {
160 }
161
162protected:
164 const VdfMaskedOutput &maskedOutput,
165 const VdfConnection &inputConnection) const {
166 if (_inputDependencyFunction) {
167 return _inputDependencyFunction(
168 maskedOutput, inputConnection);
169 } else {
171 maskedOutput, inputConnection);
172 }
173 }
174
176 const VdfConnection &inputConnection,
177 const VdfMask &inputDependencyMask,
178 const VdfOutput &output) const {
179 if (_outputDependencyFunction) {
180 return _outputDependencyFunction(
181 inputConnection, inputDependencyMask, output);
182 } else {
184 inputConnection, inputDependencyMask, output);
185 }
186 }
187
188private:
189 InputDependencyFunction _inputDependencyFunction;
190 OutputDependencyFunction _outputDependencyFunction;
191
192};
193
199class VDF_API_TYPE NodeType
200{
201public:
202 VDF_API
203 virtual ~NodeType();
204 virtual VdfNode *NewNode(VdfNetwork *net) const = 0;
205};
206
207
213template<typename T>
215{
216public:
217 InputNodeType(size_t size) : _size(size) {}
218
221 virtual VdfNode *NewNode(VdfNetwork *net) const
222 {
223 return new VdfInputVector<T>(net, _size);
224 }
225
226private:
227
228 const size_t _size;
229
230};
231
238{
239public:
240
243 CallbackNodeType(CallbackNode::ValueFunction *function) :
244 _function(function) {
245 }
246
249 virtual VdfNode *NewNode(VdfNetwork *net) const
250 {
251 return new DependencyCallbackNode(
252 net, _inputSpecs, _outputSpecs,
253 _function, _inputDependencyFunction, _outputDependencyFunction);
254 }
255
258 template <typename T>
260 _inputSpecs.ReadConnector<T>(name);
261 return *this;
262 }
263
266 template<typename T>
267 CallbackNodeType &ReadWrite(const TfToken &name, const TfToken &outName) {
268 _inputSpecs.ReadWriteConnector<T>(name, outName);
269 _outputSpecs.Connector<T>(outName);
270 return *this;
271 }
272
275 template<typename T>
277 _outputSpecs.Connector<T>(name);
278 return *this;
279 }
280
285 const DependencyCallbackNode::InputDependencyFunction &function) {
286 _inputDependencyFunction = function;
287 return *this;
288 }
289
294 const DependencyCallbackNode::OutputDependencyFunction &function) {
295 _outputDependencyFunction = function;
296 return *this;
297 }
298
299private:
300
301 VdfInputSpecs _inputSpecs;
302 VdfOutputSpecs _outputSpecs;
303
304 CallbackNode::ValueFunction *_function;
305 DependencyCallbackNode::InputDependencyFunction _inputDependencyFunction;
306 DependencyCallbackNode::OutputDependencyFunction _outputDependencyFunction;
307};
308
309
315
316class Node
317{
318private:
319
320 // These are private helper classes to support connection creation.
321
322 // Represents a node's input.
323 class _NodeInput
324 {
325 public:
326 VdfNode *inputNode;
327 TfToken inputName;
328 VdfMask inputMask;
329 };
330
331 // Represents a node's output.
332 class _NodeOutput
333 {
334 public:
335
336 VDF_API
337 Node &operator>>(const _NodeInput &rhs);
338
339 Node *owner;
340 TfToken outputName;
341 };
342
343
344public:
345
349 VDF_API
350 Node &operator>>(const _NodeInput &rhs);
351
354 VDF_API
355 _NodeInput In(const TfToken &inputName, const VdfMask &inputMask);
356
359 VDF_API
360 _NodeOutput Output(const TfToken &outputName);
361
366 template<typename T>
367 Node &SetValue(int index, const T &val) {
368 dynamic_cast<VdfInputVector<T> *>(_vdfNode)->SetValue(index, val);
369 return *this;
370 }
371
374 operator VdfNode *() { return GetVdfNode(); }
375
376 VdfNode *GetVdfNode() { return _vdfNode; }
377
378 const VdfNode *GetVdfNode() const { return _vdfNode; }
379
380 VdfOutput *GetOutput() const { return _vdfNode->GetOutput(); }
381
382private:
383
384 // Helper method to actually do the connection.
385 //
386 void _Connect(const _NodeInput &rhs, VdfOutput *output);
387
388 friend class Network;
389 friend class _NodeOutput;
390
391 // The network for connection purposes.
392 VdfNetwork *_network;
393
394 // The underlying VdfNode that we represent.
395 VdfNode *_vdfNode;
396};
397
398
406{
407
408private:
409
416 class VDF_API_TYPE _EditMonitor : public VdfNetwork::EditMonitor
417 {
418 public:
419
422 _EditMonitor(Network *network) : _network(network) {}
423
424 VDF_API
425 ~_EditMonitor();
426
429
433 VDF_API
434 void WillDelete(const VdfNode *node) override;
435
439 VDF_API
440 void WillClear() override;
442
445 void DidConnect(const VdfConnection *connection) override {}
446 void DidAddNode(const VdfNode *node) override {}
447 void WillDelete(const VdfConnection *connection) override {}
449
450
451 private:
452 Network *_network;
453 };
454
455
456public:
457
458 Network() : _editMonitor(this) {
459 _network.RegisterEditMonitor(&_editMonitor);
460 }
461
462 ~Network() {
463 _network.UnregisterEditMonitor(&_editMonitor);
464 }
465
474 VDF_API
475 void Add(const std::string &nodeName, const NodeType &nodeType);
476
481 VDF_API
482 void Add(const std::string &nodeName, VdfNode *customNode);
483
486 template <typename T>
487 void AddInputVector(const std::string &nodeName, size_t size = 1) {
488 Add(nodeName, InputNodeType<T>(size));
489 }
490
493 VDF_API
494 Node &operator[](const std::string &nodeName);
495
498 VDF_API
499 const Node &operator[](const std::string &nodeName) const;
500
504 VDF_API
505 const std::string GetNodeName(const VdfId nodeId);
506
517 VDF_API
518 VdfConnection *GetConnection(const std::string &connectionName);
519
522 VdfNetwork &GetNetwork() { return _network; }
523
526 const VdfNetwork &GetNetwork() const { return _network; }
527
528private:
529
530 // Node class needs to publish _connections;
531 friend class Node;
532
533 // Nodes that have been created, indexed by their name.
534 typedef TfHashMap<std::string, Node, TfHash> _StringToNodeMap;
535 _StringToNodeMap _nodes;
536
537 // The network that will contain the VdfNodes we create.
538 VdfNetwork _network;
539
540 // An EditMonitor that allows us to keep the Network in sync when Nodes
541 // are deleted
542 _EditMonitor _editMonitor;
543};
544
545
553
554
555class VDF_API_TYPE ExecutionStatsProcessor : public VdfExecutionStatsProcessor {
556public:
557
560 ExecutionStatsProcessor() : VdfExecutionStatsProcessor() {}
561
564 VDF_API
566
567 typedef
568 std::unordered_map<
569 ExecutionStatsProcessor::ThreadId,
570 std::vector<VdfExecutionStats::Event>>
571 ThreadToEvents;
572
573 ThreadToEvents events;
574 std::vector<ExecutionStatsProcessor*> subStats;
575
576protected:
579 VDF_API
581 VdfExecutionStatsProcessor::ThreadId threadId,
582 const VdfExecutionStats::Event& event) override;
583
586 VDF_API
587 void _ProcessSubStat(const VdfExecutionStats* stats) override;
588};
589
596
598public:
599
602 ExecutionStats() : _stats(std::make_unique<_ExecutionStats>()) {}
603
607
610 VDF_API
611 void Log(VdfExecutionStats::EventType event, VdfId nodeId, uint64_t data);
612
615 VDF_API
618 VdfId nodeId,
619 uint64_t data);
620
623 VDF_API
624 void LogEnd(
626 VdfId nodeId,
627 uint64_t data);
628
631 VDF_API
632 void GetProcessedStats(VdfExecutionStatsProcessor* processor) const;
633
636 VDF_API
637 void AddSubStat(VdfId nodeId);
638
639private:
643 class _ExecutionStats : public VdfExecutionStats {
644 public:
645 _ExecutionStats() : VdfExecutionStats(&_network) {}
646 ~_ExecutionStats() {}
647
648 void Log(
650 VdfId nodeId,
651 uint64_t data);
652
653 void LogBegin(
655 VdfId nodeId,
656 uint64_t data);
657
658 void LogEnd(
660 VdfId nodeId,
661 uint64_t data);
662
663 void AddSubStat(VdfId nodeId);
664
665 private:
666 VdfNetwork _network;
667 };
668
669private:
670 std::unique_ptr<_ExecutionStats> _stats;
671};
672
677inline std::unique_ptr<VdfSpeculationExecutorBase>
679 const VdfSpeculationNode *speculationNode,
680 const VdfExecutorInterface *parentExecutor) {
681 // Multi-threaded executor.
683 return std::unique_ptr<VdfSpeculationExecutorBase>(
687 speculationNode, parentExecutor));
688 }
689
690 // Single-threaded executor.
691 return std::unique_ptr<VdfSpeculationExecutorBase>(
695 speculationNode, parentExecutor));
696}
697
699
700} // namespace VdfTestUtils
701
702PXR_NAMESPACE_CLOSE_SCOPE
703
704#endif
Fast, compressed bit array which is capable of performing logical operations without first decompress...
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:71
A class that fully represents a connection between two VdfNodes.
Definition: connection.h:30
A context is the parameter bundle passed to callbacks of computations.
Definition: context.h:40
This is a data manager for executors that uses data stored in a vector indexed by output ids.
Execution stats profiling event logger.
EventType
The upper 2 bits are reserved as a flag for the event type: Highest bit : time event flag 2nd high bi...
Abstract base class for classes that execute a VdfNetwork to compute a requested set of values.
VdfInputSpecs is a container for VdfInputSpec objects.
VdfInputSpecs & ReadWriteConnector(const TfToken &inName, const TfToken &outName)
Create a "Read/Write" connector with the name inName associated with the output named outName.
VdfInputSpecs & ReadConnector(const TfToken &inName, const TfToken &outName=VdfTokens->empty, bool prerequisite=false)
Create a "Read" connector with the name inName and optionally associated with the output named outNam...
Base class for libVdf iterators.
Definition: iterator.h:36
const VdfNode & _GetNode(const VdfContext &context) const
Returns the current node being run.
Definition: iterator.h:45
A VdfMask is placed on connections to specify the data flowing through them.
Definition: mask.h:37
TfCompressedBits Bits
Typedef on the internal bitset implementation used.
Definition: mask.h:43
Class to hold on to an externally owned output and a mask.
Definition: maskedOutput.h:32
An abstract class to monitor network edit operations.
Definition: network.h:139
A VdfNetwork is a collection of VdfNodes and their connections.
Definition: network.h:60
VDF_API void UnregisterEditMonitor(EditMonitor *monitor)
Unregisters an edit monitor for this network.
VDF_API void RegisterEditMonitor(EditMonitor *monitor)
Registers an edit monitor for this network.
This is the base class for all nodes in a VdfNetwork.
Definition: node.h:53
virtual VDF_API VdfMask::Bits _ComputeInputDependencyMask(const VdfMaskedOutput &maskedOutput, const VdfConnection &inputConnection) const
Returns a mask that indicates which elements of the data that flows along inputConnection are needed ...
const VdfOutput * GetOutput(const TfToken &name) const
Returns the output object named name.
Definition: node.h:227
virtual VDF_API VdfMask _ComputeOutputDependencyMask(const VdfConnection &inputConnection, const VdfMask &inputDependencyMask, const VdfOutput &output) const
Returns a mask that indicates which elements of the data that flows along output depend on the elemen...
A VdfOutput represents an output on a node.
Definition: output.h:32
VdfOutputSpecs is a container for VdfOutputSpec objects.
VdfOutputSpecs & Connector(const TfToken &name)
Create an "Out" connector with the given name.
This is a data manager for executors that uses data stored in a vector indexed by output ids.
An executor engine used for parallel speculation node evaluation, deriving from VdfParallelExecutorEn...
This class provides an executor engine to the speculation executor.
Executor used in speculation.
A node that pulls on a vector of value that are downstream of the current execution position.
A helper class that implements a simple callback node.
Definition: testUtils.h:83
virtual bool _IsDerivedEqual(const VdfNode &rhs) const override
Can be overridden by derived classes to facilitate equality comparision.
Definition: testUtils.h:104
virtual void Compute(const VdfContext &context) const override
This is the method called to perform computation.
Definition: testUtils.h:96
This class specifies a CallbackNode with a given callback function.
Definition: testUtils.h:238
CallbackNodeType & ComputeInputDependencyMaskCallback(const DependencyCallbackNode::InputDependencyFunction &function)
Sets an input dependency mask computation callback for this node type.
Definition: testUtils.h:284
CallbackNodeType(CallbackNode::ValueFunction *function)
Creates a callback node type with callback function function.
Definition: testUtils.h:243
virtual VdfNode * NewNode(VdfNetwork *net) const
Creates a CallbackNode from this node type.
Definition: testUtils.h:249
CallbackNodeType & ReadWrite(const TfToken &name, const TfToken &outName)
Adds a ReadWrite input and an associated Output to this node type.
Definition: testUtils.h:267
CallbackNodeType & ComputeOutputDependencyMaskCallback(const DependencyCallbackNode::OutputDependencyFunction &function)
Sets an output dependency mask computation callback for this node type.
Definition: testUtils.h:293
CallbackNodeType & Read(const TfToken &name)
Adds a ReadConnector to this node type.
Definition: testUtils.h:259
CallbackNodeType & Out(const TfToken &name)
Adds an output to this node type.
Definition: testUtils.h:276
A CallbackNode which allows for passing in a custom input / output dependency callback.
Definition: testUtils.h:139
virtual VdfMask _ComputeOutputDependencyMask(const VdfConnection &inputConnection, const VdfMask &inputDependencyMask, const VdfOutput &output) const
Returns a mask that indicates which elements of the data that flows along output depend on the elemen...
Definition: testUtils.h:175
virtual VdfMask::Bits _ComputeInputDependencyMask(const VdfMaskedOutput &maskedOutput, const VdfConnection &inputConnection) const
Returns a mask that indicates which elements of the data that flows along inputConnection are needed ...
Definition: testUtils.h:163
Simple wrapper around ExecutionStats that allows for logging arbitrary data for testing.
Definition: testUtils.h:597
VDF_API void LogBegin(VdfExecutionStats::EventType event, VdfId nodeId, uint64_t data)
Public log begin function.
VDF_API void LogEnd(VdfExecutionStats::EventType event, VdfId nodeId, uint64_t data)
Public log end function.
VDF_API void AddSubStat(VdfId nodeId)
Adds a sub stat to the internally held ExecutionStats.
ExecutionStats()
Constructor.
Definition: testUtils.h:602
VDF_API void GetProcessedStats(VdfExecutionStatsProcessor *processor) const
Processes the processor using the internally held stats.
VDF_API void Log(VdfExecutionStats::EventType event, VdfId nodeId, uint64_t data)
Public log function.
~ExecutionStats()
Destructor.
Definition: testUtils.h:606
Simple processor that processor ExecutionStats into a vector of vector of events and a vector of subs...
Definition: testUtils.h:555
VDF_API void _ProcessSubStat(const VdfExecutionStats *stats) override
Virtual method implementing process sub stat for processing.
VDF_API void _ProcessEvent(VdfExecutionStatsProcessor::ThreadId threadId, const VdfExecutionStats::Event &event) override
Virtual method implementing process event for processing.
VDF_API ~ExecutionStatsProcessor()
Destructor.
This class specifies a VdfInputVector of type T.
Definition: testUtils.h:215
virtual VdfNode * NewNode(VdfNetwork *net) const
Creates a VdfInputVector<T>.
Definition: testUtils.h:221
This is a container class used to hold on to all the nodes and to facilitate their management.
Definition: testUtils.h:406
VDF_API Node & operator[](const std::string &nodeName)
Returns a reference to a node named nodeName.
VDF_API void Add(const std::string &nodeName, VdfNode *customNode)
Takes ownership of a customNode that was created externally.
VDF_API const std::string GetNodeName(const VdfId nodeId)
Returns the node name for the VdfTestUtils::Node corresponding to a VdfNode with VdfId nodeId.
VDF_API VdfConnection * GetConnection(const std::string &connectionName)
Returns a pointer to a connection named connectionName.
VDF_API void Add(const std::string &nodeName, const NodeType &nodeType)
Creates a node named nodeName of type nodeType.
VdfNetwork & GetNetwork()
Returns a reference to the underlying VdfNetwork.
Definition: testUtils.h:522
const VdfNetwork & GetNetwork() const
Returns a const reference to the underlying VdfNetwork.
Definition: testUtils.h:526
VDF_API const Node & operator[](const std::string &nodeName) const
Returns a const reference to a node named nodeName.
void AddInputVector(const std::string &nodeName, size_t size=1)
Creates an input vector of type T named nodeName.
Definition: testUtils.h:487
This class is a wrapper around a VdfNode.
Definition: testUtils.h:317
Node & SetValue(int index, const T &val)
Set a value on this node.
Definition: testUtils.h:367
VDF_API Node & operator>>(const _NodeInput &rhs)
Operator used to connect the default output of this node to the input described by rhs.
VDF_API _NodeInput In(const TfToken &inputName, const VdfMask &inputMask)
Returns an input to this node that can be connected to an output.
VDF_API _NodeOutput Output(const TfToken &outputName)
Returns an output to this node that can be connected to an input.
Base class for various kinds of nodes that can be created.
Definition: testUtils.h:200
A helper class which enables access to a VdfOutput from a VdfContext.
Definition: testUtils.h:119
uint64_t VdfId
The unique identifier type for Vdf objects.
Definition: types.h:107
VDF_API bool VdfIsParallelEvaluationEnabled()
Returns true if single-frame parallel evaluation is enabled.
This file contains classes to facilitate network creation in unit tests.
Definition: testUtils.h:75
std::unique_ptr< VdfSpeculationExecutorBase > CreateSpeculationExecutor(const VdfSpeculationNode *speculationNode, const VdfExecutorInterface *parentExecutor)
Create a new test speculation executor.
Definition: testUtils.h:678
STL namespace.
Execution Stats event.
TfToken class for efficient string referencing and hashing, plus conversions to and from stl string c...