Loading...
Searching...
No Matches
dependencyCache.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_EF_DEPENDENCY_CACHE_H
8#define PXR_EXEC_EF_DEPENDENCY_CACHE_H
9
11
12#include "pxr/pxr.h"
13
14#include "pxr/exec/ef/api.h"
15
16#include "pxr/base/tf/bits.h"
18#include "pxr/exec/vdf/node.h"
19#include "pxr/exec/vdf/types.h"
20
21#include <tbb/concurrent_vector.h>
22
23#include <atomic>
24#include <unordered_map>
25#include <vector>
26
27PXR_NAMESPACE_OPEN_SCOPE
28
29class VdfNetwork;
30
45{
46public:
56 bool (*) (
57 const VdfNode &node,
59 std::vector<const VdfNode *> *);
60
63 EF_API
65
68 EF_API
70
84 EF_API
86 const VdfMaskedOutputVector &outputs,
87 bool updateIncrementally) const;
88
97 EF_API
98 const std::vector<const VdfNode *> &FindNodes(
99 const VdfMaskedOutputVector &outputs,
100 bool updateIncrementally) const;
101
107 EF_API
109
117 EF_API
118 void WillDeleteConnection(const VdfConnection &connection);
119
127 EF_API
128 void DidConnect(const VdfConnection &connection);
129
130private:
131
132 // The cache entry stored for each traversal.
133 class _Entry {
134 public:
135 // Constructor.
136 _Entry(bool updateIncrementally)
137 : updateIncrementally(updateIncrementally)
138 , valid(true)
139 {}
140
141 // Returns \c true if the traversal contains the specified node.
142 bool ContainsNode(const VdfNode &node) const {
143 const VdfIndex nodeIndex = VdfNode::GetIndexFromId(node.GetId());
144 return
145 nodeRefs.GetSize() > nodeIndex &&
146 nodeRefs.IsSet(nodeIndex);
147 }
148
149 bool IsValid() const {
150 return valid.load(std::memory_order_relaxed);
151 }
152
153 void Invalidate() {
154 valid.store(std::memory_order_relaxed);
155 }
156
157 // The resulting output dependencies.
158 VdfOutputToMaskMap outputDeps;
159
160 // The resulting node dependencies.
161 std::vector<const VdfNode *> nodeDeps;
162
163 // Struct that represents a connection that may or may not exist.
164 //
165 // We store added connections using this representation beacuse it's
166 // possible that a connection may be added and then later removed.
167 // Therefore, rather than storing pointers to added connections, we
168 // store the information needed to look up the connection from the
169 // network.
170 struct _Connection {
171 _Connection(
172 VdfId sourceNodeId_,
173 TfToken outputName_,
174 VdfId targetNodeId_,
175 TfToken inputName_)
176 : sourceNodeId(sourceNodeId_)
177 , outputName(outputName_)
178 , targetNodeId(targetNodeId_)
179 , inputName(inputName_)
180 {}
181
182 // Returns the pointer to this connection, if it exists in the given
183 // network; otherwise returns nullptr.
184 EF_API
185 VdfConnection *GetConnection(
186 const VdfNetwork *network) const;
187
188 VdfId sourceNodeId;
189 TfToken outputName;
190 VdfId targetNodeId;
191 TfToken inputName;
192 };
193
194 // Any newly added connections that may affect this traversal.
195 //
196 // If this vector is non-empty when the entry is queried, the traversal
197 // must be incrementally updated.
198 tbb::concurrent_vector<_Connection> newConnections;
199
200 // Every output and mask encountered during the traversal.
201 //
202 // Note that the masks here may sometimes be empty, to signify that an
203 // output mask couldn't be inferred for that output.
204 VdfOutputToMaskMap outputRefs;
205
206 // Every node encountered during the traversal.
207 TfBits nodeRefs;
208
209 // The number of outputs for each node at the time of the traversal
210 std::vector<size_t> nodeNumOutputs;
211
212 // Incrementally update this traversal?
213 bool updateIncrementally;
214
215 // Set to false when the entry is fully invalid.
216 std::atomic<bool> valid;
217 };
218
219 // Find an entry in the cache.
220 const _Entry & _Find(
221 const VdfMaskedOutputVector &outputs,
222 bool updateIncrementally) const;
223
224 // Populates the cache with a new entry for the given request.
225 const _Entry & _PopulateCache(
226 const VdfMaskedOutputVector& outputs,
227 bool updateIncrementally) const;
228
229 // Traverse with the specified outputs and extend the traversal entry.
230 void _Traverse(
231 const VdfMaskedOutputVector &outputs,
232 _Entry *entry) const;
233
234 // Update the existing traversal, by building a partial request from
235 // the new connections stored in the traversal entry.
236 void _TraversePartially(
237 const VdfNetwork *network,
238 _Entry *entry) const;
239
240 // Gather dependencies for the partial traversal across the new connection.
241 // Will return \c true if the source output is included in the existing
242 // traversal entry.
243 bool _GatherDependenciesForNewConnection(
244 _Entry *entry,
245 const VdfConnection &connection,
246 VdfMaskedOutputVector *dependencies) const;
247
248 // Gather dependencies for the partial traversal on a node that has been
249 // extended with additional outputs.
250 void _GatherDependenciesForExtendedNode(
251 const _Entry &entry,
252 const VdfNode &node,
253 VdfMaskedOutputVector *dependencies) const;
254
255 // The traversal node callback.
256 static bool _NodeCallback(
257 const VdfNode &node,
258 PredicateFunction predicate,
259 _Entry *entry);
260
261 // The traversal output callback.
262 static bool _OutputCallback(
263 const VdfOutput &output,
264 const VdfMask &mask,
265 const VdfInput *input,
266 _Entry *entry);
267
268 //
269 // Data members
270 //
271
272 // The cache is a map from VdfMaskedOutputVector to stored entry.
273 using _Cache = std::unordered_map<
274 VdfMaskedOutputVector, _Entry, VdfMaskedOutputVector_Hash>;
275
276 // Dependency cache.
277 mutable _Cache _cache;
278
279 // The predicate function.
280 PredicateFunction _predicate;
281
282};
283
284PXR_NAMESPACE_CLOSE_SCOPE
285
286#endif
Caches output traversals by associating an input request with a set of stored output dependencies,...
bool(*)(const VdfNode &node, VdfOutputToMaskMap *, std::vector< const VdfNode * > *) PredicateFunction
The predicate function that determines the cached dependencies.
EF_API void DidConnect(const VdfConnection &connection)
Invalidate all traversals dependent on this new connection.
EF_API void WillDeleteConnection(const VdfConnection &connection)
Invalidate all traversals dependent on this connection.
EF_API const std::vector< const VdfNode * > & FindNodes(const VdfMaskedOutputVector &outputs, bool updateIncrementally) const
Find the node dependencies associated with the given request.
EF_API ~EfDependencyCache()
Destructor.
EF_API const VdfOutputToMaskMap & FindOutputs(const VdfMaskedOutputVector &outputs, bool updateIncrementally) const
Find the output dependencies associated with the given request.
EF_API void Invalidate()
Invalidate all cached dependencies.
EF_API EfDependencyCache(PredicateFunction predicate)
Constructor.
Fast bit array that keeps track of the number of bits set and can find the next set in a timely manne...
Definition: bits.h:49
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 VdfInput is used to connect a VdfNode to one or more VdfNodes' outputs.
Definition: input.h:36
A VdfMask is placed on connections to specify the data flowing through them.
Definition: mask.h:37
A VdfNetwork is a collection of VdfNodes and their connections.
Definition: network.h:60
This is the base class for all nodes in a VdfNetwork.
Definition: node.h:53
static VdfIndex GetIndexFromId(const VdfId id)
Get the node index from the node id.
Definition: node.h:123
VdfId GetId() const
Returns the unique id of this node in its network.
Definition: node.h:116
A VdfOutput represents an output on a node.
Definition: output.h:32
uint64_t VdfId
The unique identifier type for Vdf objects.
Definition: types.h:107
uint32_t VdfIndex
The index type for Vdf objects.
Definition: types.h:110
std::unordered_map< const VdfOutput *, VdfMask, TfHash > VdfOutputToMaskMap
A map from output pointer to mask.
Definition: types.h:104
Hashing functor for VdfMaskedOutputVectors.