HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CE_HotSwapPool.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  */
7 
8 #pragma once
9 
10 #include "CE_API.h"
11 
12 #include "CE_HotSwapPoolEntry.h"
13 
14 #include <list>
15 
16 #include <UT/UT_Cache.h>
17 #include <UT/UT_Map.h>
18 #include <UT/UT_MemoryResource.h>
19 
20 /// This is a memory manager that is responsible for allocating GPU storage for
21 /// CE buffers. It has a watermark for the maximum amount of live GPU usage
22 /// that it tries to stay under.
23 /// There should only ever be one memory pool active. It can be accessed using
24 /// the static getMemoryPool() method (or CEgetHotSwapPool() free-standing
25 /// function).
27 {
28 public:
29  /// This static member returns the global memory pool.
30  static CE_HotSwapPool &getMemoryPool();
31 
32  /// Registeres GPU storage of given buffer for its size.
33  /// This will make it eligible for invoking unloadToGPU to reduce
34  /// GPU memory usage.
35  void registerCEBuffer(CE_HotSwapPoolEntry *buffer, exint nbytes);
36 
37  /// Ensures there is enough room to fit the desired number of bytes.
38  /// Returns true if the memory pool will have that much room free.
39  /// NOTE: You probably want to allocate anyways if false, this is more
40  /// a warning.
41  bool reserveSpace(exint nbytes);
42 
43  /// Releases the GPU memory held by buffer. The myGPUBuffer member of buffer
44  /// will be automatically updated.
45  void releaseCEBuffer(CE_HotSwapPoolEntry *buffer);
46 
47  /// Indicates that dst is to share the GPU buffer of src.
48  void shareCEBuffer(CE_HotSwapPoolEntry *dst, const CE_HotSwapPoolEntry *src);
49 
50  /// Indicates that GPU buffers should be swapped between the two inputs.
51  void swapCEBuffer(CE_HotSwapPoolEntry *buffer1, CE_HotSwapPoolEntry *buffer2);
52 
53  /// Mark the given buffer as currently in use. This will prevent it from
54  /// getting unloaded to make room.
55  /// This method should not be called directly (i.e. use setInUseGPUFlag()
56  /// and clearInUseGPUFlag() on CE_HotSwapPoolEntry; or better yet, use
57  /// CE_ScopedPoolEntryInUseGPU).
58  void setInUse(const CE_HotSwapPoolEntry *buffer);
59  /// This function should be called after setInUse(), once the GPU buffer has
60  /// been used (to enqueue a kernel with it, for example). If nobody has
61  /// marked a buffer in use, it will be a candidate for unloading when the
62  /// pool needs to make space.
63  /// This function also bumps recency of the buffer's use, making it less
64  /// likely to get unloaded due the pool's LRU pollicy.
65  /// This method should not be called directly (i.e. use setInUseGPUFlag()
66  /// and clearInUseGPUFlag() on CE_HotSwapPoolEntry; or better yet, use
67  /// CE_ScopedPoolEntryInUseGPU).
68  void clearInUse(const CE_HotSwapPoolEntry *buffer);
69 
70 
71  exint numReductionRequests() const { return myStatsNumReductions; }
72  exint bytesFlushed() const { return myStatsFlushedBytes; }
73  void clearStats() { myStatsNumReductions = 0; myStatsFlushedBytes = 0; }
74 
75 public:
76  /// Returns name of this cache.
77  const char *utGetCacheName() const override;
78 
79  /// Returns the amount of GPU memory currently in use by CE buffers.
80  int64 utGetCurrentSize() const override
81  {
82  return myCurrentUsage;
83  }
84 
85  /// Attempts to free the specified amount of GPU memory by unloading image
86  /// data to main memory. Returns the actual amount of memory freed.
87  int64 utReduceCacheSizeBy(int64 amount) override;
88 
89  /// Required override to indicate that this cache has a maximum size.
90  bool utHasMaxSize() const override
91  {
92  return true;
93  }
94 
95  /// Returns the maximum amount of GPU memory CE buffers are allowed to use.
96  int64 utGetMaxSize() const override
97  {
98  return myMaximumUsage;
99  }
100 
101  /// Change the maximum amount of GPU memory CE buffers are allowed to use.
102  void utSetMaxSize(int64 size) override;
103 
104  /// Set maximum memory as a ratio of total GPU memory.
105  static void setMemoryUsageRatio(fpreal ratio);
106 
107  ~CE_HotSwapPool() override;
108 
109  // PassKey idion to allow private construction via UTmakeUnique
110 private:
111  struct PassKey {};
112 public:
113  CE_HotSwapPool(PassKey);
114 
115 private:
116  /// Dumps out the current state of the pool.
117  void printDebug(const UT_StringHolder& title);
118 
119  void internalSetMemoryUsageRatio(fpreal ratio);
120 
121 private:
122  /// This memory client is used to ensure that this memory pool plays nicely
123  /// with other users of memory on the OpenCL device.
124  class MemoryClient : public UT_MemoryClient
125  {
126  public:
127  MemoryClient(CE_HotSwapPool &pool) : myMemoryPool(pool) {}
128 
129  const char *name() const override
130  {
131  return myMemoryPool.utGetCacheName();
132  }
133 
134  bool freeMemoryRequest(const UT_MemoryResource *resource,
135  RequestSeverity severity, Niceness niceness,
136  exint amount, exint &freed_amount) override
137  {
138  freed_amount = myMemoryPool.utReduceCacheSizeBy(amount);
139  return freed_amount > 0;
140  }
141 
142  bool memoryUse(const UT_MemoryResource *resource, exint &in_use,
143  exint &cache) override
144  {
145  in_use = myMemoryPool.utGetCurrentSize();
146  cache = 0;
147  return true;
148  }
149 
150  private:
151  CE_HotSwapPool &myMemoryPool;
152  };
153 
154 private:
155  class ImageUsersRecord;
156 
157  /// Map of all known live buffers to their record with GPU data.
159  myLiveBuffers;
160  /// List of most recently used records. Front of the list is the least
161  /// recently used entry.
162  std::list<ImageUsersRecord*> myLRUList;
163  /// Total amount of GPU memory usage by CE buffers.
164  exint myCurrentUsage = 0;
165  /// Maximum amount of GPU memory usage by CE buffers.
166  exint myMaximumUsage = 0;
167  /// Number of reduction attempts since last reset.
168  exint myStatsNumReductions = 0;
169  /// Number of bytes unloaded since last reset.
170  exint myStatsFlushedBytes = 0;
171  /// Lock to enforce exclusive access to the memory pool.
172  UT_Lock myMutex;
173 
174  /// The memory client that's registered with with the OpenCL device.
175  MemoryClient myMemoryClient;
176 };
177 
178 /// Returns the global memory pool for CE GPU storage.
180 
#define CE_API
Definition: CE_API.h:13
virtual const char * utGetCacheName() const =0
required - return the english name for this cache.
bool utHasMaxSize() const override
Required override to indicate that this cache has a maximum size.
int64 exint
Definition: SYS_Types.h:125
exint bytesFlushed() const
GLuint buffer
Definition: glcorearb.h:660
exint numReductionRequests() const
virtual int64 utReduceCacheSizeBy(int64 amount)=0
long long int64
Definition: SYS_Types.h:116
GLenum GLenum severity
Definition: glcorearb.h:2539
int64 utGetCurrentSize() const override
Returns the amount of GPU memory currently in use by CE buffers.
GLuint const GLchar * name
Definition: glcorearb.h:786
Common base class for various caches.
Definition: UT_Cache.h:21
int64 utGetMaxSize() const override
Returns the maximum amount of GPU memory CE buffers are allowed to use.
GLsizeiptr size
Definition: glcorearb.h:664
GLenum GLenum dst
Definition: glcorearb.h:1793
fpreal64 fpreal
Definition: SYS_Types.h:283
virtual void utSetMaxSize(int64)
Definition: UT_Cache.h:51
CE_API CE_HotSwapPool & CEgetHotSwapPool()
Returns the global memory pool for CE GPU storage.
Wrapper for a client of a limit memory resource.
**Note that the tasks the is the thread number *for the pool
Definition: thread.h:646
GLenum src
Definition: glcorearb.h:1793