HDK
Main Page
Related Pages
Modules
Namespaces
Classes
Files
Examples
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Groups
Pages
CE_MemoryPool.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
* NAME: CE_MemoryPool.h ( CE Library, C++)
7
*
8
* COMMENTS: Compute Engine Memory Pool.
9
*/
10
11
#ifndef __CE_MemoryPool__
12
#define __CE_MemoryPool__
13
14
#include "
CE_API.h
"
15
16
#include <
UT/UT_Array.h
>
17
#include <
UT/UT_Lock.h
>
18
#include <
UT/UT_LRUCache.h
>
19
#include <
UT/UT_Map.h
>
20
#include <
UT/UT_MemoryResource.h
>
21
#include <
UT/UT_UniquePtr.h
>
22
#include <
SYS/SYS_Types.h
>
23
24
#include <iosfwd>
25
26
#if UT_ASSERT_LEVEL >= UT_ASSERT_LEVEL_NORMAL
27
#include <set>
28
#endif
29
30
class
CE_Context
;
31
32
/// This class implements a memory pool for OpenCL buffer objects, using an
33
/// LRUCache to limit the size of the pool.
34
class
CE_API
CE_MemoryPool
35
{
36
public
:
37
/// Initialize the pool with specified maximum size.
38
CE_MemoryPool
(
int64
size
);
39
virtual
~
CE_MemoryPool
();
40
41
/// Empty the memory pool of all held buffers.
42
void
clear();
43
44
/// Set the maximums size of the pool. This will prune the LRUCache as
45
/// needed to fit the size.
46
void
setMaxSize
(
int64
size) { myLRUCache.setMaxSize(size); }
47
48
/// Returns the maximum size of the pool.
49
int64
getMaxSize
()
const
{
return
myLRUCache.maxSize(); }
50
51
/// Dump memory usage statistics to stderr.
52
void
reportUsage()
const
;
53
54
/// Dump memory to a stream
55
void
reportUsage(std::ostream &os)
const
;
56
57
/// Query the current usage; total is the total amount of memory held by the
58
/// pool, not_in_use is the amount that can be freed immediately on demand.
59
void
getUsage
(
exint
& total,
exint
& not_in_use)
const
60
{
61
not_in_use = myLRUCache.currentSize();
62
total = not_in_use + myInUseSize;
63
}
64
65
/// Allocate a buffer for the provided context. If a buffer of the
66
/// specified size already exists in the pool, it will be returned.
67
/// Otherwise a new one will be created on the device.
68
cl::Buffer
allocBuffer(
CE_Context
*,
int64
size);
69
70
/// Check the provided buffer's reference count. If it is about to be
71
/// released, return it to the pool if it will fit, else release it. If
72
/// the reference count is higher than 1, meaning it is still active in
73
/// an asynchronous operation like a kernel, put it on the inUse list to
74
/// check later in sweepInUse().
75
void
returnBuffer(
cl::Buffer
&&
buf
,
bool
use_pool);
76
77
/// Sweep the inUse list, looking for buffers that are no longer being used
78
/// in an asynchronous operation and can be returned to the pool. Returns
79
/// the amount of released memory (i.e. memory that's returned back to the
80
/// system).
81
exint
sweepInUse();
82
83
/// Attempts to release the requested amount of memory back to the system.
84
/// Returns the amount actually freed.
85
exint
freeMemory(
exint
amount);
86
87
/// Registers this memory pool as a client for the given resource. This must
88
/// be called with the appropriate memory resource to ensure that the memory
89
/// pool can be asked to unload when device memory is tight.
90
void
registerClient
(
UT_MemoryResource
* resource)
91
{
92
resource->
registerClient
(&myMemoryClient,
UT_MemoryClient::NORMAL_FREE
);
93
}
94
/// Unregisters this memory pool as a client for the given resource. This
95
/// must be called on destruction with the same resource used with
96
/// registerClient().
97
void
unregisterClient
(
UT_MemoryResource
* resource)
98
{
99
resource->
unregisterClient
(&myMemoryClient);
100
}
101
102
private
:
103
// This class just holds a cl::Buffer while it's in the LRUCache. It's also
104
// responsible for alerting the CE_MemoryPool object when it's deleted
105
// by pruning or other means. Each cl::Buffer is owned by only one of
106
// these objects, as maintained by being non-copyable and having move
107
// semantics.
108
class
ut_clBuffer :
public
UT_NonCopyable
109
{
110
public
:
111
ut_clBuffer(
CE_MemoryPool
*
pool
,
const
cl::Buffer
&
buf
,
int64
size);
112
113
ut_clBuffer(ut_clBuffer &&
b
);
114
115
~ut_clBuffer();
116
117
ut_clBuffer &
operator=
(ut_clBuffer &&
b
);
118
119
static
exint
size
(
const
ut_clBuffer &
b
) {
return
b.mySize; }
120
121
private
:
122
int64
mySize;
123
cl::Buffer
myBuffer;
124
CE_MemoryPool
*myPool;
125
};
126
127
/// This memory client is used to ensure that this memory pool plays nicely
128
/// with other users of memory on the OpenCL device.
129
class
MemoryClient :
public
UT_MemoryClient
130
{
131
public
:
132
MemoryClient(
CE_MemoryPool
&
pool
) : myMemoryPool(pool) {}
133
134
const
char
*
name
()
const override
135
{
136
return
"OpenCL Buffer Pool"
;
137
}
138
139
bool
freeMemoryRequest(
const
UT_MemoryResource
* resource,
140
RequestSeverity
severity
, Niceness niceness,
141
exint
amount,
exint
& freed_amount)
override
142
{
143
freed_amount = myMemoryPool.sweepInUse();
144
if
(freed_amount < amount)
145
freed_amount += myMemoryPool.freeMemory(amount - freed_amount);
146
return
freed_amount > 0;
147
}
148
149
bool
memoryUse(
const
UT_MemoryResource
* resource,
exint
& in_use,
150
exint
& cache)
override
151
{
152
myMemoryPool.getUsage(in_use, cache);
153
return
true
;
154
}
155
156
private
:
157
CE_MemoryPool
& myMemoryPool;
158
};
159
160
friend
class
ut_clBuffer;
161
friend
class
CE_Context
;
162
163
bool
getBufferFromPool(
int64
size,
cl::Buffer
&
buf
);
164
165
/// Add the buffer to the pool. Returns false if it operation fails.
166
bool
appendToPool(
const
cl::Buffer
&
buf
,
int64
size);
167
168
/// Remove the the buffer from the pool.
169
void
releaseBuffer
(
const
cl::Buffer
&
buf
,
int64
size);
170
171
/// Used for tracing and debugging buffer allocations.
172
void
recordAlloc(
cl_mem
buffer
,
int64
size);
173
void
recordDealloc(
cl_mem
buffer
,
int64
size,
bool
returning=
true
);
174
175
using
BufferCache
=
UT_LRUCache<cl_mem, ut_clBuffer, ut_clBuffer::size>
;
176
using
BufferTable
=
UT_Map<exint, UT_Array<cl::Buffer *>
>;
177
using
BufferPtr =
UT_UniquePtr<cl::Buffer>
;
178
179
BufferCache
myLRUCache;
180
UT_Array<BufferPtr>
myInUseList;
181
BufferTable
myBufferTable;
182
int64
myInUseSize;
183
int64
myTotalAllocSize;
184
mutable
UT_Lock
myMemoryPoolLock;
185
186
/// The memory client that's registered with the OpenCL device.
187
MemoryClient myMemoryClient;
188
189
#if UT_ASSERT_LEVEL >= UT_ASSERT_LEVEL_NORMAL
190
// Used for catching dangling buffers in debug/opt builds.
191
void
validateAndFreeBuffer(
cl_mem
buf
);
192
static
void
memDestructorCallback(
cl_mem
,
void
*);
193
UT_Map<cl_mem, int64>
myActiveBuffers;
194
std::multiset<cl_mem> myReturnedBuffers;
195
#endif
196
};
197
198
199
#endif
CE_API
#define CE_API
Definition:
CE_API.h:13
buf
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition:
glcorearb.h:2540
CE_MemoryPool::getUsage
void getUsage(exint &total, exint ¬_in_use) const
Definition:
CE_MemoryPool.h:59
UT_Map
Unsorted map container.
Definition:
UT_Map.h:109
CE_API.h
exint
int64 exint
Definition:
SYS_Types.h:125
CE_Context::releaseBuffer
void releaseBuffer(cl::Buffer &&buf, bool use_pool=true)
Release the specified buffer, possibly to the CE_MemoryPool.
CE_MemoryPool::setMaxSize
void setMaxSize(int64 size)
Definition:
CE_MemoryPool.h:46
UT_Array.h
UT_Array< BufferPtr >
buffer
GLuint buffer
Definition:
glcorearb.h:660
UT_SpinLockT< true, false >
UT_UniquePtr
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition:
UT_UniquePtr.h:39
SYS_Types.h
UT_Map.h
UT_LRUCache.h
UT_MemoryResource::registerClient
bool registerClient(UT_MemoryClient *client, UT_MemoryClient::Niceness niceness)
Register as a client of the memory resource.
int64
long long int64
Definition:
SYS_Types.h:116
severity
GLenum GLenum severity
Definition:
glcorearb.h:2539
cl_mem
struct _cl_mem * cl_mem
Definition:
cl.h:33
name
GLuint const GLchar * name
Definition:
glcorearb.h:786
UT_MemoryResource::unregisterClient
bool unregisterClient(UT_MemoryClient *client)
Remove 'client' from this memory resource.
UT_MemoryResource.h
b
GLboolean GLboolean GLboolean b
Definition:
glcorearb.h:1222
CE_MemoryPool::getMaxSize
int64 getMaxSize() const
Returns the maximum size of the pool.
Definition:
CE_MemoryPool.h:49
CE_Context
Definition:
CE_Context.h:85
size
GLsizeiptr size
Definition:
glcorearb.h:664
UT_UniquePtr.h
CE_MemoryPool
Definition:
CE_MemoryPool.h:34
UT_MemoryClient::NORMAL_FREE
Definition:
UT_MemoryResource.h:49
CE_MemoryPool::registerClient
void registerClient(UT_MemoryResource *resource)
Definition:
CE_MemoryPool.h:90
nanovdb::operator=
LeafData & operator=(const LeafData &)=delete
UT_NonCopyableNS::UT_NonCopyable
Definition:
UT_NonCopyable.h:17
cl::Buffer
Memory buffer interface.
Definition:
cl.hpp:1867
UT_MemoryResource
Definition:
UT_MemoryResource.h:86
UT_MemoryClient
Wrapper for a client of a limit memory resource.
Definition:
UT_MemoryResource.h:26
UT_Lock.h
CE_MemoryPool::unregisterClient
void unregisterClient(UT_MemoryResource *resource)
Definition:
CE_MemoryPool.h:97
UT_LRUCache< cl_mem, ut_clBuffer, ut_clBuffer::size >
pool
**Note that the tasks the is the thread number *for the pool
Definition:
thread.h:646
CE
CE_MemoryPool.h
Generated on Wed Aug 27 2025 03:06:29 for HDK by
1.8.6