1#ifndef HALIDE_RUNTIME_REGION_ALLOCATOR_H
2#define HALIDE_RUNTIME_REGION_ALLOCATOR_H
4#include "../HalideRuntime.h"
53 bool collect(
void *user_context);
54 int release(
void *user_context);
55 int destroy(
void *user_context);
86 int destroy_block_region(
void *user_context,
BlockRegion *region);
89 int alloc_block_region(
void *user_context,
BlockRegion *region);
92 int release_block_region(
void *user_context,
BlockRegion *region);
95 int free_block_region(
void *user_context,
BlockRegion *region);
98 bool is_last_block_region(
void *user_context,
const BlockRegion *region)
const;
107 size_t region_count(
void *user_context)
const;
119 if (result ==
nullptr) {
130 instance->
destroy(user_context);
136int RegionAllocator::initialize(
void *user_context,
BlockResource *
mb,
const MemoryAllocators &
ma) {
173#ifdef DEBUG_RUNTIME_INTERNAL
174 debug(user_context) <<
"RegionAllocator: Failed to conform region request! Unable to reserve memory ...\n";
181#ifdef DEBUG_RUNTIME_INTERNAL
182 debug(user_context) <<
"RegionAllocator: Unable to reserve more memory from block "
191#ifdef DEBUG_RUNTIME_INTERNAL
192 debug(user_context) <<
"RegionAllocator: Failed to locate region for requested size ("
199#ifdef DEBUG_RUNTIME_INTERNAL
200 debug(user_context) <<
"RegionAllocator: Splitting region of size ( " << (
int32_t)(
block_region->memory.size) <<
") "
217 return release_block_region(user_context,
block_region);
251bool RegionAllocator::is_last_block_region(
void *user_context,
const BlockRegion *region)
const {
252 return ((region ==
nullptr) || (region == region->
next_ptr) || (region->
next_ptr ==
nullptr));
255bool RegionAllocator::is_block_region_suitable_for_request(
void *user_context,
const BlockRegion *region,
const MemoryRequest &
request)
const {
256 if (!is_available(region)) {
257#ifdef DEBUG_RUNTIME_INTERNAL
258 debug(user_context) <<
" skipping block region ... not available! ("
259 <<
" block_region=" << (
void *)region
260 <<
" region_size=" << (
uint32_t)(region->memory.size)
269#ifdef DEBUG_RUNTIME_INTERNAL
270 debug(user_context) <<
"RegionAllocator: Failed to conform region request! Unable to reserve memory ...\n";
276 if (!is_compatible_block_region(region,
region_request.properties)) {
277#ifdef DEBUG_RUNTIME_INTERNAL
278 debug(user_context) <<
" skipping block region ... incompatible properties! ("
279 <<
" block_region=" << (
void *)region
280 <<
" region_size=" << (
uint32_t)(region->memory.size)
288#ifdef DEBUG_RUNTIME_INTERNAL
289 debug(user_context) <<
" skipping block region ... not enough space for adjusted size! ("
290 <<
" block_region=" << (
void *)region
293 <<
" region_size=" << (
uint32_t)(region->memory.size)
301#ifdef DEBUG_RUNTIME_INTERNAL
302 debug(user_context) <<
" found suitable block region! ("
303 <<
" block_region=" << (
void *)region
306 <<
" region_size=" << (
uint32_t)(region->memory.size)
315BlockRegion *RegionAllocator::find_block_region(
void *user_context,
const MemoryRequest &
request) {
316#ifdef DEBUG_RUNTIME_INTERNAL
317 debug(user_context) <<
"RegionAllocator: find block region ( "
318 <<
"user_context=" << (
void *)(user_context) <<
" "
320 <<
"requested_is_dedicated=" << (
request.dedicated ?
"true" :
"false") <<
" "
328#ifdef DEBUG_RUNTIME_INTERNAL
329 debug(user_context) <<
"RegionAllocator: found suitable region ( "
330 <<
"user_context=" << (
void *)(user_context) <<
" "
331 <<
"block_resource=" << (
void *)block <<
" "
335 <<
"requested_is_dedicated=" << (
request.dedicated ?
"true" :
"false") <<
" "
351#ifdef DEBUG_RUNTIME_INTERNAL
352 debug(user_context) <<
"RegionAllocator: couldn't find suitable region! ("
353 <<
"user_context=" << (
void *)(user_context) <<
" "
355 <<
"requested_is_dedicated=" << (
request.dedicated ?
"true" :
"false") <<
" "
365bool RegionAllocator::is_available(
const BlockRegion *
block_region)
const {
378bool RegionAllocator::can_coalesce(
const BlockRegion *
block_region)
const {
391BlockRegion *RegionAllocator::coalesce_block_regions(
void *user_context, BlockRegion *
block_region) {
394#ifdef DEBUG_RUNTIME_INTERNAL
395 debug(user_context) <<
"RegionAllocator: Freeing unused region to coalesce ("
396 <<
"block_ptr=" << (
void *)
block_region->block_ptr <<
" "
411#ifdef DEBUG_RUNTIME_INTERNAL
412 debug(user_context) <<
"RegionAllocator: Coalescing "
429#ifdef DEBUG_RUNTIME_INTERNAL
430 debug(user_context) <<
"RegionAllocator: Coalescing "
450BlockRegion *RegionAllocator::split_block_region(
void *user_context, BlockRegion *
block_region,
const MemoryRequest &
request) {
453#ifdef DEBUG_RUNTIME_INTERNAL
454 debug(user_context) <<
"RegionAllocator: Split deallocate region ("
455 <<
"block_ptr=" << (
void *)
block_region->block_ptr <<
" "
471#ifdef DEBUG_RUNTIME_INTERNAL
472 debug(user_context) <<
"RegionAllocator: Splitting "
490BlockRegion *RegionAllocator::create_block_region(
void *user_context,
const MemoryRequest &
request) {
491#ifdef DEBUG_RUNTIME_INTERNAL
492 debug(user_context) <<
"RegionAllocator: Creating block region request ("
493 <<
"user_context=" << (
void *)(user_context) <<
" "
497 <<
"dedicated=" << (
request.dedicated ?
"true" :
"false") <<
" "
506#ifdef DEBUG_RUNTIME_INTERNAL
507 debug(user_context) <<
"RegionAllocator: Failed to conform request for new block region!\n";
513#ifdef DEBUG_RUNTIME_INTERNAL
514 debug(user_context) <<
"RegionAllocator: Failed to allocate new block region ... region size was zero!\n";
519 BlockRegion *
block_region =
static_cast<BlockRegion *
>(arena->
reserve(user_context,
true));
521#ifdef DEBUG_RUNTIME_INTERNAL
522 debug(user_context) <<
"RegionAllocator: Failed to allocate new block region!\n";
536#ifdef DEBUG_RUNTIME_INTERNAL
537 debug(user_context) <<
"RegionAllocator: Created block region allocation ("
538 <<
"user_context=" << (
void *)(user_context) <<
" "
539 <<
"block_ptr=" << (
void *)
block_region->block_ptr <<
" "
549int RegionAllocator::release_block_region(
void *user_context, BlockRegion *
block_region) {
550#ifdef DEBUG_RUNTIME_INTERNAL
551 debug(user_context) <<
"RegionAllocator: Releasing block region ("
552 <<
"user_context=" << (
void *)(user_context) <<
" "
558 <<
"block_reserved=" << (
uint32_t)(block->reserved) <<
") ... ";
570#ifdef DEBUG_RUNTIME_INTERNAL
571 debug(user_context) <<
" releasing region ("
572 <<
"block_ptr=" << (
void *)
block_region->block_ptr <<
" "
586int RegionAllocator::destroy_block_region(
void *user_context, BlockRegion *
block_region) {
587#ifdef DEBUG_RUNTIME_INTERNAL
588 debug(user_context) <<
"RegionAllocator: Destroying block region ("
589 <<
"user_context=" << (
void *)(user_context) <<
" "
590 <<
"block_region=" << (
void *)(
block_region) <<
") ...";
600int RegionAllocator::alloc_block_region(
void *user_context, BlockRegion *
block_region) {
601#ifdef DEBUG_RUNTIME_INTERNAL
602 debug(user_context) <<
"RegionAllocator: Allocating region (user_context=" << (
void *)(user_context)
614#ifdef DEBUG_RUNTIME_INTERNAL
615 debug(user_context) <<
" allocating region ("
616 <<
"block_ptr=" << (
void *)
block_region->block_ptr <<
" "
626#ifdef DEBUG_RUNTIME_INTERNAL
627 debug(user_context) <<
" re-using region ("
628 <<
"block_ptr=" << (
void *)
block_region->block_ptr <<
" "
641int RegionAllocator::free_block_region(
void *user_context, BlockRegion *
block_region) {
642#ifdef DEBUG_RUNTIME_INTERNAL
643 debug(user_context) <<
"RegionAllocator: Freeing block region ("
644 <<
"user_context=" << (
void *)(user_context) <<
" "
645 <<
"block_ptr=" << (
void *)
block_region->block_ptr <<
" "
653#ifdef DEBUG_RUNTIME_INTERNAL
654 debug(user_context) <<
" deallocating region ("
655 <<
"block_ptr=" << (
void *)
block_region->block_ptr <<
" "
673#ifdef DEBUG_RUNTIME_INTERNAL
674 debug(user_context) <<
"RegionAllocator: Releasing all regions ("
675 <<
"user_context=" << (
void *)(user_context) <<
") ...";
690#ifdef DEBUG_RUNTIME_INTERNAL
691 debug(user_context) <<
"RegionAllocator: Collecting free block regions ("
692 <<
"user_context=" << (
void *)(user_context) <<
") ...";
699 debug(user_context) <<
" collecting unused regions ("
700 <<
"block_ptr=" << (
void *)block <<
" "
708#ifdef DEBUG_RUNTIME_INTERNAL
710 debug(user_context) <<
" checking region ("
711 <<
"block_ptr=" << (
void *)
block_region->block_ptr <<
" "
721#ifdef DEBUG_RUNTIME_INTERNAL
723 debug(user_context) <<
" collecting region ("
724 <<
"block_ptr=" << (
void *)
block_region->block_ptr <<
" "
733#ifdef DEBUG_RUNTIME_INTERNAL
737#ifdef DEBUG_RUNTIME_INTERNAL
745#ifdef DEBUG_RUNTIME_INTERNAL
746 debug(user_context) <<
" scanned active regions ("
747 <<
"block_ptr=" << (
void *)block <<
" "
756#ifdef DEBUG_RUNTIME_INTERNAL
757 debug(user_context) <<
" collected unused regions ("
758 <<
"block_ptr=" << (
void *)block <<
" "
769#ifdef DEBUG_RUNTIME_INTERNAL
770 debug(user_context) <<
"RegionAllocator: Destroying all block regions ("
771 <<
"user_context=" << (
void *)(user_context) <<
") ...";
773 if (block->
regions !=
nullptr) {
789 if (arena !=
nullptr) {
818size_t RegionAllocator::region_count(
void *user_context)
const {
819 if (block ==
nullptr) {
823 for (BlockRegion
const *region = block->
regions; !is_last_block_region(user_context, region); region = region->next_ptr) {
void * reserve(void *user_context, bool initialize=false)
static MemoryArena * create(void *user_context, const Config &config, const SystemMemoryAllocatorFns &allocator=default_allocator())
static constexpr uint32_t default_capacity
static void destroy(void *user_context, MemoryArena *arena)
void reclaim(void *user_context, void *ptr)
Allocator class interface for sub-allocating a contiguous memory block into smaller regions of memory...
MemoryRegion * reserve(void *user_context, const MemoryRequest &request)
RegionAllocator & operator=(const RegionAllocator &)=delete
RegionAllocator(const RegionAllocator &)=delete
static int destroy(void *user_context, RegionAllocator *region_allocator)
int conform(void *user_context, MemoryRequest *request) const
static RegionAllocator * find_allocator(void *user_context, MemoryRegion *memory_region)
int retain(void *user_context, MemoryRegion *memory_region)
bool collect(void *user_context)
~RegionAllocator()=delete
int reclaim(void *user_context, MemoryRegion *memory_region)
int release(void *user_context, MemoryRegion *memory_region)
BlockResource * block_resource() const
static RegionAllocator * create(void *user_context, BlockResource *block, const MemoryAllocators &ma)
WEAK const char * halide_memory_caching_name(MemoryCaching value)
WEAK const char * halide_memory_usage_name(MemoryUsage value)
WEAK const char * halide_memory_visibility_name(MemoryVisibility value)
ALWAYS_INLINE size_t conform_alignment(size_t requested, size_t required)
ALWAYS_INLINE size_t conform_size(size_t offset, size_t size, size_t alignment, size_t nearest_multiple)
ALWAYS_INLINE size_t aligned_offset(size_t offset, size_t alignment)
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
@ Internal
Not visible externally, similar to 'static' linkage in C.
Internal::ConstantInterval cast(Type t, const Internal::ConstantInterval &a)
Cast operators for ConstantIntervals.
unsigned __INT64_TYPE__ uint64_t
signed __INT32_TYPE__ int32_t
unsigned __INT32_TYPE__ uint32_t
#define halide_abort_if_false(user_context, cond)
RegionAllocator * allocator
MemoryProperties properties
MemoryVisibility visibility
DeallocateRegionFn deallocate
AllocateRegionFn allocate
ConformBlockRegionFn conform
MemoryRegionAllocatorFns region
SystemMemoryAllocatorFns system
DeallocateSystemFn deallocate
AllocateSystemFn allocate