Halide
memory_resources.h
Go to the documentation of this file.
1 #ifndef HALIDE_RUNTIME_MEMORY_RESOURCES_H
2 #define HALIDE_RUNTIME_MEMORY_RESOURCES_H
3 
4 #include "../HalideRuntime.h"
5 
6 namespace Halide {
7 namespace Runtime {
8 namespace Internal {
9 
10 // --
11 
12 // Hint for allocation usage indicating whether or not the resource
13 // is in use, available, or dedicated (and can't be split or shared)
14 enum class AllocationStatus {
16  InUse,
17  Available,
18  Purgeable,
19  Dedicated
20 };
21 
22 // Hint for allocation requests indicating intended usage
23 // required between host and device address space mappings
24 enum class MemoryVisibility {
25  InvalidVisibility, //< invalid enum value
26  HostOnly, //< host local
27  DeviceOnly, //< device local
28  DeviceToHost, //< transfer from device to host
29  HostToDevice, //< transfer from host to device
30  DefaultVisibility, //< default visibility (use any valid visibility -- unable to determine prior to usage)
31 };
32 
33 // Hint for allocation requests indicating intended update
34 // frequency for modifying the contents of the allocation
35 enum class MemoryUsage {
36  InvalidUsage, //< invalid enum value
37  StaticStorage, //< intended for static storage, whereby the contents will be set once and remain unchanged
38  DynamicStorage, //< intended for dyanmic storage, whereby the contents will be set frequently and change constantly
39  UniformStorage, //< intended for fast & small fixed read-only uniform storage (intended for passing shader parameters), whereby the contents will be set once and remain unchanged
40  TransferSrc, //< intended for staging storage updates, whereby the contents will be used as the source of a transfer
41  TransferDst, //< intended for staging storage updates, whereby the contents will be used as the destination of a transfer
42  TransferSrcDst, //< intended for staging storage updates, whereby the contents will be used either as a source or destination of a transfer
43  DefaultUsage //< default usage (use any valid usage -- unable to determine prior to usage)
44 };
45 
46 // Hint for allocation requests indicating ideal caching support (if available)
47 enum class MemoryCaching {
48  InvalidCaching, //< invalid enum value
49  Cached, //< cached
50  Uncached, //< uncached
51  CachedCoherent, //< cached and coherent
52  UncachedCoherent, //< uncached but still coherent
53  DefaultCaching //< default caching (use any valid caching behaviour -- unable to determine prior to usage)
54 };
55 
60  size_t alignment = 0; //< required alignment of allocations (zero for no constraint)
61  size_t nearest_multiple = 0; //< require the allocation size to round up to the nearest multiple (zero means no rounding)
62 };
63 
64 // Client-facing struct for exchanging memory block allocation requests
65 struct MemoryBlock {
66  void *handle = nullptr; //< client data storing native handle (managed by alloc_block_region/free_block_region)
67  size_t size = 0; //< allocated size (in bytes)
68  bool dedicated = false; //< flag indicating whether allocation is one dedicated resource (or split/shared into other resources)
69  MemoryProperties properties; //< properties for the allocated block
70 };
71 
72 // Client-facing struct for specifying a range of a memory region (eg for crops)
73 struct MemoryRange {
74  size_t head_offset = 0; //< byte offset from start of region
75  size_t tail_offset = 0; //< byte offset from end of region
76 };
77 
78 // Client-facing struct for exchanging memory region allocation requests
79 struct MemoryRegion {
80  void *handle = nullptr; //< client data storing native handle (managed by alloc_block_region/free_block_region) or a pointer to region owning allocation
81  size_t offset = 0; //< offset from base address in block (in bytes)
82  size_t size = 0; //< allocated size (in bytes)
83  MemoryRange range; //< optional range (e.g. for handling crops, etc)
84  bool dedicated = false; //< flag indicating whether allocation is one dedicated resource (or split/shared into other resources)
85  bool is_owner = true; //< flag indicating whether allocation is owned by this region, in which case handle is a native handle. Otherwise handle points to owning region of alloction.
86  MemoryProperties properties; //< properties for the allocated region
87 };
88 
89 // Client-facing struct for issuing memory allocation requests
90 struct MemoryRequest {
91  size_t offset = 0; //< offset from base address in block (in bytes)
92  size_t size = 0; //< allocated size (in bytes)
93  size_t alignment = 0; //< alignment constraint for address
94  bool dedicated = false; //< flag indicating whether allocation is one dedicated resource (or split/shared into other resources)
95  MemoryProperties properties; //< properties for the allocated region
96 };
97 
98 class RegionAllocator;
99 struct BlockRegion;
100 
101 // Internal struct for block resource state
102 // -- Note: first field must MemoryBlock
104  MemoryBlock memory; //< memory info for the allocated block
105  RegionAllocator *allocator = nullptr; //< designated allocator for the block
106  BlockRegion *regions = nullptr; //< head of linked list of memory regions
107  size_t reserved = 0; //< number of bytes already reserved to regions
108 };
109 
110 // Internal struct for block region state
111 // -- Note: first field must MemoryRegion
112 struct BlockRegion {
113  MemoryRegion memory; //< memory info for the allocated region
114  uint32_t usage_count = 0; //< number of active clients using region
115  AllocationStatus status = AllocationStatus::InvalidStatus; //< allocation status indicator
116  BlockRegion *next_ptr = nullptr; //< pointer to next block region in linked list
117  BlockRegion *prev_ptr = nullptr; //< pointer to prev block region in linked list
118  BlockResource *block_ptr = nullptr; //< pointer to parent block resource
119 };
120 
121 // Returns true if given byte alignment is a power of two
123  return (x & (x - 1)) == 0;
124 }
125 
126 // Returns an aligned byte offset to adjust the given offset based on alignment constraints
127 // -- Alignment must be power of two!
128 ALWAYS_INLINE size_t aligned_offset(size_t offset, size_t alignment) {
130  return (offset + (alignment - 1)) & ~(alignment - 1);
131 }
132 
133 // Returns a suitable alignment such that requested alignment is a suitable
134 // integer multiple of the required alignment
135 ALWAYS_INLINE size_t conform_alignment(size_t requested, size_t required) {
136  size_t alignment = max(requested, required);
137  return ((required > 0) && (alignment > required)) ? (required * ((alignment / required) + 1)) : alignment;
138 }
139 
140 // Returns a padded size to accommodate an adjusted offset due to alignment constraints
141 // -- Alignment must be power of two!
142 ALWAYS_INLINE size_t aligned_size(size_t offset, size_t size, size_t alignment) {
143  size_t actual_offset = aligned_offset(offset, alignment);
144  size_t padding = actual_offset - offset;
145  size_t actual_size = padding + size;
146  return actual_size;
147 }
148 
149 // Returns a padded size to accommodate an adjusted offset due to alignment constraints rounded up to the nearest multiple
150 // -- Alignment must be power of two!
151 ALWAYS_INLINE size_t conform_size(size_t offset, size_t size, size_t alignment, size_t nearest_multiple) {
152  size_t adjusted_size = aligned_size(offset, size, alignment);
153  adjusted_size = (alignment > adjusted_size) ? alignment : adjusted_size;
154  if (nearest_multiple > 0) {
155  size_t rounded_size = (((adjusted_size + nearest_multiple - 1) / nearest_multiple) * nearest_multiple);
156  return rounded_size;
157  } else {
158  return adjusted_size;
159  }
160 }
161 
162 // Clamps the given value to be within the [min_value, max_value] range
163 ALWAYS_INLINE size_t clamped_size(size_t value, size_t min_value, size_t max_value) {
164  size_t result = (value < min_value) ? min_value : value;
165  return (result > max_value) ? max_value : result;
166 }
167 
168 // Offset the untyped pointer by the given number of bytes
169 ALWAYS_INLINE const void *offset_address(const void *address, size_t byte_offset) {
170  const uintptr_t base = reinterpret_cast<uintptr_t>(address);
171  return reinterpret_cast<const void *>(base + byte_offset);
172 }
173 
174 // Offset the untyped pointer by the given number of bytes
175 ALWAYS_INLINE void *offset_address(void *address, size_t byte_offset) {
176  const uintptr_t base = reinterpret_cast<uintptr_t>(address);
177  return reinterpret_cast<void *>(base + byte_offset);
178 }
179 
180 // --
181 
182 typedef void *(*AllocateSystemFn)(void *, size_t);
183 typedef void (*DeallocateSystemFn)(void *, void *);
184 
185 ALWAYS_INLINE void *native_system_malloc(void *user_context, size_t bytes) {
186  return malloc(bytes);
187 }
188 
189 ALWAYS_INLINE void native_system_free(void *user_context, void *ptr) {
190  free(ptr);
191 }
192 
196 };
197 
201 };
202 
203 typedef int (*AllocateBlockFn)(void *, MemoryBlock *);
204 typedef int (*DeallocateBlockFn)(void *, MemoryBlock *);
205 
209 };
210 
211 typedef int (*AllocateRegionFn)(void *, MemoryRegion *);
212 typedef int (*DeallocateRegionFn)(void *, MemoryRegion *);
213 
217 };
218 
219 // --
220 
221 } // namespace Internal
222 } // namespace Runtime
223 } // namespace Halide
224 
225 // --
226 
227 extern "C" {
228 
230  switch (value) {
231  case MemoryVisibility::InvalidVisibility: {
232  return "InvalidVisibility";
233  }
234  case MemoryVisibility::DefaultVisibility: {
235  return "DefaultVisibility";
236  }
237  case MemoryVisibility::HostOnly: {
238  return "HostOnly";
239  }
240  case MemoryVisibility::DeviceOnly: {
241  return "DeviceOnly";
242  }
243  case MemoryVisibility::HostToDevice: {
244  return "HostToDevice";
245  }
246  case MemoryVisibility::DeviceToHost: {
247  return "DeviceToHost";
248  }
249  default: {
250  return "<unknown memory visibility value>";
251  }
252  };
253  return "<unknown memory visibility value>";
254 }
255 
257  switch (value) {
258  case MemoryUsage::InvalidUsage: {
259  return "InvalidUsage";
260  }
261  case MemoryUsage::DefaultUsage: {
262  return "DefaultUsage";
263  }
264  case MemoryUsage::StaticStorage: {
265  return "StaticStorage";
266  }
267  case MemoryUsage::DynamicStorage: {
268  return "DynamicStorage";
269  }
270  case MemoryUsage::UniformStorage: {
271  return "UniformStorage";
272  }
273  case MemoryUsage::TransferSrc: {
274  return "TransferSrc";
275  }
276  case MemoryUsage::TransferDst: {
277  return "TransferDst";
278  }
279  case MemoryUsage::TransferSrcDst: {
280  return "TransferSrcDst";
281  }
282  default: {
283  return "<unknown memory usage value>";
284  }
285  };
286  return "<unknown memory usage value>";
287 }
288 
290  switch (value) {
291  case MemoryCaching::InvalidCaching: {
292  return "InvalidCaching";
293  }
294  case MemoryCaching::DefaultCaching: {
295  return "DefaultCaching";
296  }
297  case MemoryCaching::Cached: {
298  return "Cached";
299  }
300  case MemoryCaching::Uncached: {
301  return "Uncached";
302  }
303  case MemoryCaching::CachedCoherent: {
304  return "CachedCoherent";
305  }
306  case MemoryCaching::UncachedCoherent: {
307  return "UncachedCoherent";
308  }
309  default: {
310  return "<unknown memory visibility value>";
311  }
312  };
313  return "<unknown memory visibility value>";
314 }
315 
316 } // extern "C"
317 
318 // --
319 
320 #endif // HALIDE_RUNTIME_MEMORY_RESOURCES_H
Halide::Runtime::Internal::MemoryRegion::range
MemoryRange range
Definition: memory_resources.h:83
Halide::Runtime::Internal::MemoryRegion::handle
void * handle
Definition: memory_resources.h:80
Halide::Runtime::Internal::HalideSystemAllocatorFns::deallocate
DeallocateSystemFn deallocate
Definition: memory_resources.h:200
Halide::Runtime::Internal::AllocateBlockFn
int(* AllocateBlockFn)(void *, MemoryBlock *)
Definition: memory_resources.h:203
Halide::Runtime::Internal::AllocationStatus::Dedicated
@ Dedicated
Halide::Runtime::Internal::AllocationStatus::InUse
@ InUse
halide_free
void halide_free(void *user_context, void *ptr)
Halide::Runtime::Internal::native_system_free
ALWAYS_INLINE void native_system_free(void *user_context, void *ptr)
Definition: memory_resources.h:189
Halide::Runtime::Internal::DeallocateSystemFn
void(* DeallocateSystemFn)(void *, void *)
Definition: memory_resources.h:183
Halide::Runtime::Internal::MemoryRegion::dedicated
bool dedicated
Definition: memory_resources.h:84
Halide::Runtime::Internal::conform_size
ALWAYS_INLINE size_t conform_size(size_t offset, size_t size, size_t alignment, size_t nearest_multiple)
Definition: memory_resources.h:151
Halide::Runtime::Internal::MemoryRequest::alignment
size_t alignment
Definition: memory_resources.h:93
Halide::Runtime::Internal::MemoryUsage::StaticStorage
@ StaticStorage
Halide::Runtime::Internal::AllocationStatus::InvalidStatus
@ InvalidStatus
Halide::Runtime::Internal::MemoryRange
Definition: memory_resources.h:73
Halide::Runtime::Internal::MemoryRegionAllocatorFns
Definition: memory_resources.h:214
Halide::Runtime::Internal::MemoryBlockAllocatorFns::deallocate
DeallocateBlockFn deallocate
Definition: memory_resources.h:208
Halide::Runtime::Internal::AllocationStatus::Available
@ Available
Halide::Runtime::Internal::MemoryUsage
MemoryUsage
Definition: memory_resources.h:35
Halide::Runtime::Internal::MemoryRequest::dedicated
bool dedicated
Definition: memory_resources.h:94
Halide::Runtime::Internal::BlockResource::regions
BlockRegion * regions
Definition: memory_resources.h:106
Halide::Runtime::Internal::MemoryVisibility::InvalidVisibility
@ InvalidVisibility
Halide::Runtime::Internal::MemoryRequest::size
size_t size
Definition: memory_resources.h:92
Halide::Runtime::Internal::MemoryVisibility::DefaultVisibility
@ DefaultVisibility
Halide::Runtime::Internal::MemoryUsage::DynamicStorage
@ DynamicStorage
Halide::Runtime::Internal::MemoryRegion
Definition: memory_resources.h:79
halide_memory_caching_name
const WEAK char * halide_memory_caching_name(MemoryCaching value)
Definition: memory_resources.h:289
Halide::Runtime::Internal::MemoryCaching
MemoryCaching
Definition: memory_resources.h:47
Halide::Runtime::Internal::BlockRegion::next_ptr
BlockRegion * next_ptr
Definition: memory_resources.h:116
Halide::Runtime::Internal::BlockRegion::block_ptr
BlockResource * block_ptr
Definition: memory_resources.h:118
Halide::Runtime::Internal::MemoryCaching::InvalidCaching
@ InvalidCaching
Halide::Runtime::Internal::MemoryUsage::DefaultUsage
@ DefaultUsage
uintptr_t
__UINTPTR_TYPE__ uintptr_t
Definition: runtime_internal.h:73
Halide::Runtime::Internal::MemoryRequest::properties
MemoryProperties properties
Definition: memory_resources.h:95
Halide::Runtime::Internal::SystemMemoryAllocatorFns::allocate
AllocateSystemFn allocate
Definition: memory_resources.h:194
malloc
void * malloc(size_t)
Halide::Runtime::Internal::MemoryProperties::alignment
size_t alignment
Definition: memory_resources.h:60
Halide
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
Definition: AbstractGenerator.h:19
Halide::Runtime::Internal::aligned_offset
ALWAYS_INLINE size_t aligned_offset(size_t offset, size_t alignment)
Definition: memory_resources.h:128
Halide::Runtime::Internal::BlockRegion::prev_ptr
BlockRegion * prev_ptr
Definition: memory_resources.h:117
Halide::LinkageType::Internal
@ Internal
Not visible externally, similar to 'static' linkage in C.
Halide::Runtime::Internal::MemoryRange::head_offset
size_t head_offset
Definition: memory_resources.h:74
Halide::Runtime::Internal::MemoryBlock::dedicated
bool dedicated
Definition: memory_resources.h:68
Halide::Runtime::Internal::MemoryRange::tail_offset
size_t tail_offset
Definition: memory_resources.h:75
size_t
__SIZE_TYPE__ size_t
Definition: runtime_internal.h:31
Halide::Runtime::Internal::MemoryCaching::UncachedCoherent
@ UncachedCoherent
Halide::Runtime::Internal::MemoryUsage::UniformStorage
@ UniformStorage
Halide::Runtime::Internal::MemoryVisibility::HostOnly
@ HostOnly
Halide::Runtime::Internal::MemoryCaching::Uncached
@ Uncached
Halide::Runtime::Internal::MemoryCaching::DefaultCaching
@ DefaultCaching
Halide::Runtime::Internal::SystemMemoryAllocatorFns::deallocate
DeallocateSystemFn deallocate
Definition: memory_resources.h:195
Halide::Runtime::Internal::MemoryRequest::offset
size_t offset
Definition: memory_resources.h:91
Halide::Runtime::Internal::MemoryProperties::nearest_multiple
size_t nearest_multiple
Definition: memory_resources.h:61
Halide::Runtime::Internal::AllocationStatus::Purgeable
@ Purgeable
Halide::Runtime::Internal::MemoryUsage::TransferSrcDst
@ TransferSrcDst
halide_memory_visibility_name
const WEAK char * halide_memory_visibility_name(MemoryVisibility value)
Definition: memory_resources.h:229
Halide::Runtime::Internal::MemoryProperties
Definition: memory_resources.h:56
Halide::Runtime::Internal::native_system_malloc
ALWAYS_INLINE void * native_system_malloc(void *user_context, size_t bytes)
Definition: memory_resources.h:185
Halide::Runtime::Internal::conform_alignment
ALWAYS_INLINE size_t conform_alignment(size_t requested, size_t required)
Definition: memory_resources.h:135
Halide::Runtime::Internal::MemoryRegionAllocatorFns::allocate
AllocateRegionFn allocate
Definition: memory_resources.h:215
Halide::Runtime::Internal::is_power_of_two_alignment
ALWAYS_INLINE bool is_power_of_two_alignment(size_t x)
Definition: memory_resources.h:122
Halide::Runtime::Internal::MemoryCaching::Cached
@ Cached
Halide::Runtime::Internal::HalideSystemAllocatorFns
Definition: memory_resources.h:198
Halide::Runtime::Internal::AllocationStatus
AllocationStatus
Definition: memory_resources.h:14
Halide::Runtime::Internal::MemoryBlockAllocatorFns::allocate
AllocateBlockFn allocate
Definition: memory_resources.h:207
halide_malloc
void * halide_malloc(void *user_context, size_t x)
Halide calls these functions to allocate and free memory.
Halide::Runtime::Internal::BlockResource::memory
MemoryBlock memory
Definition: memory_resources.h:104
Halide::Runtime::Internal::MemoryRegion::properties
MemoryProperties properties
Definition: memory_resources.h:86
Halide::Runtime::Internal::MemoryRegion::offset
size_t offset
Definition: memory_resources.h:81
Halide::Runtime::Internal::MemoryBlock::size
size_t size
Definition: memory_resources.h:67
Halide::Runtime::Internal::BlockRegion::usage_count
uint32_t usage_count
Definition: memory_resources.h:114
Halide::Runtime::Internal::MemoryCaching::CachedCoherent
@ CachedCoherent
Halide::Runtime::Internal::MemoryVisibility
MemoryVisibility
Definition: memory_resources.h:24
Halide::Runtime::Internal::BlockResource::allocator
RegionAllocator * allocator
Definition: memory_resources.h:105
Halide::Runtime::Internal::RegionAllocator
Allocator class interface for sub-allocating a contiguous memory block into smaller regions of memory...
Definition: region_allocator.h:24
Halide::Runtime::Internal::DeallocateRegionFn
int(* DeallocateRegionFn)(void *, MemoryRegion *)
Definition: memory_resources.h:212
halide_memory_usage_name
const WEAK char * halide_memory_usage_name(MemoryUsage value)
Definition: memory_resources.h:256
Halide::Runtime::Internal::MemoryRegionAllocatorFns::deallocate
DeallocateRegionFn deallocate
Definition: memory_resources.h:216
ALWAYS_INLINE
#define ALWAYS_INLINE
Definition: runtime_internal.h:55
Halide::Runtime::Internal::MemoryProperties::caching
MemoryCaching caching
Definition: memory_resources.h:59
Halide::Runtime::Internal::MemoryVisibility::DeviceOnly
@ DeviceOnly
Halide::Runtime::Internal::AllocateSystemFn
void *(* AllocateSystemFn)(void *, size_t)
Definition: memory_resources.h:182
Halide::Runtime::Internal::BlockResource
Definition: memory_resources.h:103
Halide::Runtime::Internal::MemoryProperties::visibility
MemoryVisibility visibility
Definition: memory_resources.h:57
Halide::Runtime::Internal::BlockRegion::status
AllocationStatus status
Definition: memory_resources.h:115
Halide::Runtime::Internal::MemoryProperties::usage
MemoryUsage usage
Definition: memory_resources.h:58
Halide::Runtime::Internal::SystemMemoryAllocatorFns
Definition: memory_resources.h:193
Halide::Runtime::Internal::MemoryVisibility::DeviceToHost
@ DeviceToHost
free
void free(void *)
Halide::Runtime::Internal::BlockRegion::memory
MemoryRegion memory
Definition: memory_resources.h:113
Halide::Runtime::Internal::MemoryBlock::handle
void * handle
Definition: memory_resources.h:66
Halide::Runtime::Internal::clamped_size
ALWAYS_INLINE size_t clamped_size(size_t value, size_t min_value, size_t max_value)
Definition: memory_resources.h:163
halide_abort_if_false
#define halide_abort_if_false(user_context, cond)
Definition: runtime_internal.h:262
Halide::Runtime::Internal::MemoryUsage::TransferDst
@ TransferDst
Halide::Runtime::Internal::offset_address
const ALWAYS_INLINE void * offset_address(const void *address, size_t byte_offset)
Definition: memory_resources.h:169
Halide::Runtime::Internal::aligned_size
ALWAYS_INLINE size_t aligned_size(size_t offset, size_t size, size_t alignment)
Definition: memory_resources.h:142
WEAK
#define WEAK
Definition: runtime_internal.h:52
Halide::Runtime::Internal::MemoryRequest
Definition: memory_resources.h:90
uint32_t
unsigned __INT32_TYPE__ uint32_t
Definition: runtime_internal.h:25
Halide::max
Expr max(const FuncRef &a, const FuncRef &b)
Definition: Func.h:587
Halide::Runtime::Internal::MemoryRegion::is_owner
bool is_owner
Definition: memory_resources.h:85
Halide::Runtime::Internal::BlockRegion
Definition: memory_resources.h:112
Halide::Runtime::Internal::MemoryBlockAllocatorFns
Definition: memory_resources.h:206
Halide::Runtime::Internal::MemoryUsage::InvalidUsage
@ InvalidUsage
Halide::Runtime::Internal::BlockResource::reserved
size_t reserved
Definition: memory_resources.h:107
Halide::Runtime::Internal::HalideSystemAllocatorFns::allocate
AllocateSystemFn allocate
Definition: memory_resources.h:199
Halide::Runtime::Internal::MemoryRegion::size
size_t size
Definition: memory_resources.h:82
Halide::Runtime::Internal::AllocateRegionFn
int(* AllocateRegionFn)(void *, MemoryRegion *)
Definition: memory_resources.h:211
Halide::Runtime::Internal::MemoryUsage::TransferSrc
@ TransferSrc
Halide::Runtime::Internal::MemoryBlock
Definition: memory_resources.h:65
Halide::Runtime::Internal::MemoryBlock::properties
MemoryProperties properties
Definition: memory_resources.h:69
Halide::Runtime::Internal::MemoryVisibility::HostToDevice
@ HostToDevice
Halide::Runtime::Internal::DeallocateBlockFn
int(* DeallocateBlockFn)(void *, MemoryBlock *)
Definition: memory_resources.h:204