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 
27 PXR_NAMESPACE_OPEN_SCOPE
28 
29 class VdfNetwork;
30 
45 {
46 public:
55  using PredicateFunction =
56  bool (*) (
57  const VdfNode &node,
59  std::vector<const VdfNode *> *);
60 
63  EF_API
64  explicit EfDependencyCache(PredicateFunction predicate);
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
108  void Invalidate();
109 
117  EF_API
118  void WillDeleteConnection(const VdfConnection &connection);
119 
127  EF_API
128  void DidConnect(const VdfConnection &connection);
129 
130 private:
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(false, 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<
275 
276  // Dependency cache.
277  mutable _Cache _cache;
278 
279  // The predicate function.
280  PredicateFunction _predicate;
281 
282 };
283 
284 PXR_NAMESPACE_CLOSE_SCOPE
285 
286 #endif
A VdfNetwork is a collection of VdfNodes and their connections.
Definition: network.h:59
A class that fully represents a connection between two VdfNodes.
Definition: connection.h:29
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(PredicateFunction predicate)
Constructor.
This is the base class for all nodes in a VdfNetwork.
Definition: node.h:52
VdfId GetId() const
Returns the unique id of this node in its network.
Definition: node.h:116
A VdfMask is placed on connections to specify the data flowing through them.
Definition: mask.h:36
bool(*)(const VdfNode &node, VdfOutputToMaskMap *, std::vector< const VdfNode * > *) PredicateFunction
The predicate function that determines the cached dependencies.
EF_API void WillDeleteConnection(const VdfConnection &connection)
Invalidate all traversals dependent on this connection.
A VdfInput is used to connect a VdfNode to one or more VdfNodes' outputs.
Definition: input.h:35
std::vector< VdfMaskedOutput > VdfMaskedOutputVector
A vector of VdfMaskedOutputs.
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:80
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:48
EF_API void Invalidate()
Invalidate all cached dependencies.
EF_API ~EfDependencyCache()
Destructor.
std::unordered_map< const VdfOutput *, VdfMask, TfHash > VdfOutputToMaskMap
A map from output pointer to mask.
Definition: types.h:104
A VdfOutput represents an output on a node.
Definition: output.h:31
Hashing functor for VdfMaskedOutputVectors.
EF_API const VdfOutputToMaskMap & FindOutputs(const VdfMaskedOutputVector &outputs, bool updateIncrementally) const
Find the output dependencies associated with the given request.
EF_API void DidConnect(const VdfConnection &connection)
Invalidate all traversals dependent on this new connection.
Caches output traversals by associating an input request with a set of stored output dependencies,...
static VdfIndex GetIndexFromId(const VdfId id)
Get the node index from the node id.
Definition: node.h:123
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