HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
outputValueCache.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_OUTPUT_VALUE_CACHE_H
8 #define PXR_EXEC_EF_OUTPUT_VALUE_CACHE_H
9 
10 ///\file
11 
12 #include "pxr/pxr.h"
13 
14 #include "pxr/exec/ef/api.h"
15 
16 #include "pxr/base/tf/bits.h"
17 #include "pxr/base/tf/hash.h"
18 #include "pxr/base/tf/hashmap.h"
19 #include "pxr/exec/vdf/mask.h"
21 #include "pxr/exec/vdf/request.h"
22 
23 #include <tbb/spin_rw_mutex.h>
24 
26 
27 class VdfOutput;
28 class VdfNode;
29 class VdfVector;
30 
31 ///////////////////////////////////////////////////////////////////////////////
32 ///
33 /// \class Ef_OutputValueCache
34 ///
35 /// \brief An output-to-value storage for caching. The class provides accessor
36 /// types for thread-safe, as well as unprotected access.
37 ///
39 {
40 public:
41  /// Constructor.
42  ///
43  EF_API
45 
46  /// Destructor.
47  ///
48  EF_API
50 
51  /// An accessor that provides exclusive read/write access to the cache. No
52  /// other reader or writer will access this cache.
53  ///
55  {
56  public:
57  /// Non-copyable.
58  ///
59  ExclusiveAccess(const ExclusiveAccess &) = delete;
60  const ExclusiveAccess &operator=(const ExclusiveAccess &) = delete;
61 
62  /// Constructor.
63  ///
64  ExclusiveAccess(Ef_OutputValueCache *cache) :
65  _cache(cache),
66  _lock(cache->_mutex, /* write = */ true)
67  {}
68 
69  /// Returns \c true if the cache is empty at this time.
70  ///
71  bool IsEmpty() const {
72  return _cache->_IsEmpty();
73  }
74 
75  /// Returns \c true if any outputs in the \p request are
76  /// not currently cached.
77  ///
78  bool IsUncached(const VdfRequest &request) const {
79  return _cache->_IsUncached(request);
80  }
81 
82  /// Returns a request of outputs that are not currently
83  /// cached.
84  ///
86  const VdfRequest &request) const {
87  return _cache->_GetUncached(request);
88  }
89 
90  /// Returns the cached value for a given output and mask, if
91  /// it exists.
92  ///
94  const VdfOutput &output,
95  const VdfMask &mask) const {
96  return _cache->_GetValue(output, mask);
97  }
98 
99  /// Sets the cached values for a given output and mask.
100  /// Returns the number of bytes of additionally allocated storage.
101  ///
102  /// This will NOT update elements in the vector, which are already
103  /// cached. Only uncached data will be merged into values existing
104  /// in the cache.
105  ///
106  size_t SetValue(
107  const VdfOutput &output,
108  const VdfVector &value,
109  const VdfMask &mask) {
110  return _cache->_SetValue(output, value, mask);
111  }
112 
113  /// Invalidate an output by removing all the data stored at the output.
114  /// Returns the number of bytes invalidated.
115  ///
116  size_t Invalidate(const VdfOutput &output) {
117  return _cache->_Invalidate(output);
118  }
119 
120  /// Invalidate a vector of outputs and masks by removing the data from
121  /// the cache.
122  /// Returns the number of bytes invalidated.
123  ///
124  size_t Invalidate(const VdfMaskedOutputVector &outputs) {
125  return _cache->_Invalidate(outputs);
126  }
127 
128  /// Clears the entire cache.
129  /// Returns the number of bytes that have been removed from the cache.
130  ///
131  size_t Clear() {
132  return _cache->_Clear();
133  }
134 
135  private:
136  Ef_OutputValueCache *_cache;
137  tbb::spin_rw_mutex::scoped_lock _lock;
138 
139  };
140 
141  /// This accessor grants shared read access to the cache, preventing any
142  /// concurrent write access.
143  ///
145  {
146  public:
147  /// Non-copyable.
148  ///
149  SharedAccess(const SharedAccess &) = delete;
150  const SharedAccess &operator=(const SharedAccess &) = delete;
151 
152  /// Constructor.
153  ///
154  SharedAccess(Ef_OutputValueCache *cache) :
155  _cache(cache),
156  _lock(cache->_mutex, /* write = */ false)
157  {}
158 
159  /// Returns the cached value for a given output and mask, if
160  /// it exists.
161  ///
163  const VdfOutput &output,
164  const VdfMask &mask) const {
165  return _cache->_GetValue(output, mask);
166  }
167 
168  private:
169  Ef_OutputValueCache *_cache;
170  tbb::spin_rw_mutex::scoped_lock _lock;
171 
172  };
173 
174 private:
175  // Returns \c true if the given output is contained in this cache.
176  bool _ContainsOutput(const VdfOutput &output) const;
177 
178  // Marks the given output as contained in the cache.
179  void _AddOutput(const VdfOutput &output);
180 
181  // Marks the given output as not contained in the cache.
182  void _RemoveOutput(const VdfOutput &output);
183 
184  // Returns the value stored at the output, or NULL if the value
185  // is not available, as determined by the specified mask.
186  EF_API
187  const VdfVector *_GetValue(
188  const VdfOutput &output,
189  const VdfMask &mask) const;
190 
191  // Sets the value stored at the output. This does not update
192  // any elements currently stored! Only uncached elements will be
193  // merged into the cache.
194  size_t _SetValue(
195  const VdfOutput &output,
196  const VdfVector &value,
197  const VdfMask &mask);
198 
199  // Invalidate the entire data stored at the given output.
200  size_t _Invalidate(const VdfOutput &outut);
201 
202  // Invalidate the value stored at the given outputs.
203  size_t _Invalidate(const VdfMaskedOutputVector &outputs);
204 
205  // Clear the entire cache.
206  size_t _Clear();
207 
208  // Is this cache empty?
209  bool _IsEmpty() const;
210 
211  // Are there any uncached outputs in the given request?
212  bool _IsUncached(const VdfRequest &request) const;
213 
214  // Get all uncached outputs from the given request.
215  VdfRequest _GetUncached(const VdfRequest &request) const;
216 
217  // The entry stored for each output in the cache.
218  class _Entry
219  {
220  public:
221  // Constructor
222  _Entry();
223 
224  // Destructor
225  ~_Entry();
226 
227  // Returns the number of bytes stored at this output.
228  size_t GetNumBytes() const;
229 
230  // Returns the mask of elements stored at this output.
231  const VdfMask &GetMask() const {
232  return _mask;
233  }
234 
235  // Returns the value stored at the output, if any.
236  const VdfVector *GetValue() const {
237  return _value;
238  }
239 
240  // Returns the value stored at the output, if it exists and
241  // contains all elements specified in the given \p mask.
242  const VdfVector *GetValue(const VdfMask &mask) const;
243 
244  // Sets the value at this output, not overwriting any existing
245  // data. This will return the number of bytes allocated to
246  // store the additional data.
247  size_t SetValue(
248  const VdfVector &value,
249  const VdfMask &mask);
250 
251  // Invalidate the entire data stored at this output. Returns the
252  // number of bytes invalidated.
253  size_t Invalidate();
254 
255  // Invalidate the data stored at this output. Returns the number
256  // of bytes invalidated.
257  size_t Invalidate(const VdfMask &mask);
258 
259  private:
260  // The data value stored at this output.
261  VdfVector *_value;
262 
263  // The mask of data available at this output.
264  VdfMask _mask;
265  };
266 
267  // Retain a reference to the one-one mask as a field in order to avoid
268  // contention on any guard variables.
269  const VdfMask _oneOneMask;
270 
271  // Type of the output cache map
272  typedef
274  _OutputsMap;
275 
276  // The output cache map
277  _OutputsMap _outputs;
278 
279  // An acceleration structure with outputs contained in this cache.
280  TfBits _outputSet;
281 
282  // The mutex protecting concurrent access to this cache.
283  tbb::spin_rw_mutex _mutex;
284 
285 };
286 
288 
289 #endif
SharedAccess(Ef_OutputValueCache *cache)
const VdfVector * GetValue(const VdfOutput &output, const VdfMask &mask) const
const SharedAccess & operator=(const SharedAccess &)=delete
size_t Invalidate(const VdfMaskedOutputVector &outputs)
#define PXR_NAMESPACE_OPEN_SCOPE
Definition: pxr.h:73
GLsizei const GLfloat * value
Definition: glcorearb.h:824
SharedAccess(const SharedAccess &)=delete
Definition: node.h:52
A VdfMask is placed on connections to specify the data flowing through them.
Definition: mask.h:36
ExclusiveAccess(const ExclusiveAccess &)=delete
An output-to-value storage for caching. The class provides accessor types for thread-safe, as well as unprotected access.
const ExclusiveAccess & operator=(const ExclusiveAccess &)=delete
bool IsUncached(const VdfRequest &request) const
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
size_t SetValue(const VdfOutput &output, const VdfVector &value, const VdfMask &mask)
ExclusiveAccess(Ef_OutputValueCache *cache)
GLint GLuint mask
Definition: glcorearb.h:124
EF_API ~Ef_OutputValueCache()
size_t Invalidate(const VdfOutput &output)
VdfRequest GetUncached(const VdfRequest &request) const
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
EF_API Ef_OutputValueCache()
const VdfVector * GetValue(const VdfOutput &output, const VdfMask &mask) const
std::vector< VdfMaskedOutput > VdfMaskedOutputVector
#define EF_API
Definition: api.h:25