Skip to content

Commit 21be6e9

Browse files
authored
Custom and default allocator added
1 parent 2c53747 commit 21be6e9

File tree

1 file changed

+182
-6
lines changed

1 file changed

+182
-6
lines changed

rfcs/20200612-stream-executor-c-api.md

Lines changed: 182 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,151 @@ typedef struct SE_CreateStreamExecutorParams {
437437
#define SE_CREATE_STREAM_EXECUTOR_PARAMS_STRUCT_SIZE \
438438
TF_OFFSET_OF_END(SE_CreateStreamExecutorParams, stream_executor)
439439

440+
typedef struct SP_Allocator {
441+
size_t struct_size;
442+
void* ext; // free-form field set by plugin.
443+
444+
// Whether this platform supports unified memory.
445+
// Unified memory is a single memory address space accessible from any device.
446+
TF_Bool supports_unified_memory;
447+
} SP_Allocator;
448+
449+
#define SP_ALLOCATOR_STRUCT_SIZE \
450+
TF_OFFSET_OF_END(SP_Allocator, supports_unified_memory)
451+
452+
typedef struct SP_AllocatorFns {
453+
size_t struct_size;
454+
void* ext; // reserved for future use.
455+
456+
// Synchronously allocates `size` bytes on the underlying platform and returns
457+
// `SP_DeviceMemoryBase` representing that allocation. In the case of failure,
458+
// nullptr is returned.
459+
// `memory_space` is reserved for a potential future usage and should be set
460+
// to 0.
461+
void (*allocate)(const SP_Device* device, const SP_Allocator* allocator,
462+
uint64_t size, int64_t memory_space,
463+
SP_DeviceMemoryBase* mem);
464+
465+
// Deallocate the device memory previously allocated via this interface.
466+
// Deallocation of a nullptr-representative value is permitted.
467+
void (*deallocate)(const SP_Device* device, const SP_Allocator* allocator,
468+
SP_DeviceMemoryBase* memory);
469+
470+
// Allocates a region of host memory and registers it with the platform API.
471+
// Memory allocated in this manner is required for use in asynchronous memcpy
472+
// operations, such as `memcpy_dtoh`.
473+
void* (*host_memory_allocate)(const SP_Device* device,
474+
const SP_Allocator* allocator, uint64_t size);
475+
476+
// Deallocates a region of host memory allocated by `host_memory_allocate`.
477+
void (*host_memory_deallocate)(const SP_Device* device,
478+
const SP_Allocator* allocator, void* mem);
479+
480+
// Allocates unified memory space of the given size, if supported. Unified
481+
482+
// memory support should be added by setting `supports_unified_memory` field
483+
// in `SP_Platform`.
484+
void* (*unified_memory_allocate)(const SP_Device* device,
485+
const SP_Allocator* allocator,
486+
uint64_t bytes);
487+
488+
// Deallocates unified memory space previously allocated with
489+
// `unified_memory_allocate`. Unified
490+
// memory support should be added by setting `supports_unified_memory` field
491+
// in `SP_Platform`.
492+
void (*unified_memory_deallocate)(const SP_Device* device,
493+
const SP_Allocator* allocator,
494+
void* location);
495+
496+
// Fills SP_AllocatorStats with allocator statistics, if it is available.
497+
// If it is not available, return false.
498+
TF_Bool (*get_allocator_stats)(const SP_Device* device,
499+
const SP_Allocator* allocator,
500+
SP_AllocatorStats* stats);
501+
502+
// Fills the underlying device memory usage information, if it is
503+
// available. If it is not available (false is returned), free/total need not
504+
// be initialized.
505+
TF_Bool (*device_memory_usage)(const SP_Device* device,
506+
const SP_Allocator* allocator, int64_t* free,
507+
int64_t* total);
508+
} SP_AllocatorFns;
509+
510+
#define SP_ALLOCATOR_FNS_STRUCT_SIZE \
511+
TF_OFFSET_OF_END(SP_AllocatorFns, device_memory_usage)
512+
513+
typedef struct SP_CustomAllocator {
514+
size_t struct_size;
515+
void* ext; // free-form data set by plugin
516+
} SP_CustomAllocator;
517+
518+
#define SP_CUSTOM_ALLOCATOR_STRUCT_SIZE \
519+
TF_OFFSET_OF_END(SP_CustomAllocator, ext)
520+
521+
typedef struct SP_CustomAllocatorFns {
522+
size_t struct_size;
523+
void* ext; // reserved for future use
524+
525+
// Synchronously allocates `size` bytes on the underlying platform and returns
526+
// a pointer to that allocation. In the case of failure,
527+
// nullptr is returned.
528+
void* (*allocate_raw)(const SP_Device* device,
529+
const SP_CustomAllocator* allocator, size_t size,
530+
size_t alignment);
531+
532+
// Deallocate the device memory previously allocated via `allocate_raw`.
533+
// Deallocation of a nullptr-representative value is permitted.
534+
void (*deallocate_raw)(const SP_Device* device,
535+
const SP_CustomAllocator* allocator, void* ptr);
536+
537+
// Allocates a region of host memory.
538+
void* (*host_allocate_raw)(const SP_Device* device,
539+
const SP_CustomAllocator* allocator,
540+
uint64_t size);
541+
542+
// Deallocates a region of host memory allocated by `host_allocate_raw`.
543+
void (*host_deallocate_raw)(const SP_Device* device,
544+
const SP_CustomAllocator* allocator, void* mem);
545+
546+
// Fills SP_AllocatorStats with allocator statistics, if it is available.
547+
// If it is not available, return false.
548+
TF_Bool (*get_allocator_stats)(const SP_Device* device,
549+
const SP_CustomAllocator* allocator,
550+
SP_AllocatorStats* stats);
551+
552+
// Fills the underlying device memory usage information, if it is
553+
// available. If it is not available (false is returned), free/total need not
554+
// be initialized.
555+
TF_Bool (*device_memory_usage)(const SP_Device* device,
556+
const SP_CustomAllocator* allocator,
557+
int64_t* free, int64_t* total);
558+
} SP_CustomAllocatorFns;
559+
560+
#define SP_CUSTOM_ALLOCATOR_FNS_STRUCT_SIZE \
561+
TF_OFFSET_OF_END(SP_CustomAllocatorFns, device_memory_usage)
562+
563+
typedef struct SE_CreateAllocatorParams {
564+
size_t struct_size;
565+
void* ext; // reserved for future use
566+
567+
SP_Allocator* allocator;
568+
SP_AllocatorFns* allocator_fns;
569+
} SE_CreateAllocatorParams;
570+
571+
#define SE_CREATE_ALLOCATOR_PARAMS_STRUCT_SIZE \
572+
TF_OFFSET_OF_END(SE_CreateAllocatorParams, allocator_fns)
573+
574+
typedef struct SE_CreateCustomAllocatorParams {
575+
size_t struct_size;
576+
void* ext; // reserved for future use
577+
578+
SP_CustomAllocator* custom_allocator;
579+
SP_CustomAllocatorFns* custom_allocator_fns;
580+
} SE_CreateCustomAllocatorParams;
581+
582+
#define SE_CREATE_CUSTOM_ALLOCATOR_PARAMS_STRUCT_SIZE \
583+
TF_OFFSET_OF_END(SE_CreateCustomAllocatorParams, custom_allocator_fns)
584+
440585
typedef struct SP_Platform {
441586
size_t struct_size;
442587

@@ -450,15 +595,10 @@ typedef struct SP_Platform {
450595

451596
// Number of visible devices.
452597
size_t visible_device_count;
453-
454-
// Whether this platform supports unified memory.
455-
// Unified memory is a single memory address space that virtualizes device and
456-
// host memory addresses. It is accessible to both the device and host.
457-
TF_Bool supports_unified_memory;
458598
} SP_Platform;
459599

460600
#define SP_PLATFORM_STRUCT_SIZE \
461-
TF_OFFSET_OF_END(SP_Platform, supports_unified_memory)
601+
TF_OFFSET_OF_END(SP_Platform, visible_device_count)
462602

463603
typedef struct SP_PlatformFns {
464604
size_t struct_size;
@@ -488,11 +628,38 @@ typedef struct SP_PlatformFns {
488628

489629
void (*destroy_timer_fns)(const SP_Platform* platform,
490630
SP_TimerFns* timer_fns);
631+
632+
// Set only one of `create_allocator` or `create_custom_allocator` functions
633+
// below.
634+
635+
// Callback for creating an allocator that uses default TensorFlow allocation
636+
// strategy (BFC: best-fit with coalescing). For more details, see
637+
// https://cs.opensource.google/tensorflow/tensorflow/+/master:tensorflow/core/common_runtime/bfc_allocator.h.
638+
// If `create_allocator` is set, then `create_custom_allocator` should *not*
639+
// be set.
640+
void (*create_allocator)(const SP_Platform* platform,
641+
SE_CreateAllocatorParams* params, TF_Status* status);
642+
void (*destroy_allocator)(const SP_Platform* platform,
643+
SP_Allocator* allocator,
644+
SP_AllocatorFns* allocator_fns);
645+
646+
// Callback for creating a custom allocator. Allows using a custom allocation
647+
// strategy.
648+
// If `create_custom_allocator` is set, then `create_allocator` should *not*
649+
// be set.
650+
// Note: deallocator functions must be set in params.
651+
void (*create_custom_allocator)(const SP_Platform* platform,
652+
SE_CreateCustomAllocatorParams* params,
653+
TF_Status* status);
654+
void (*destroy_custom_allocator)(const SP_Platform* platform,
655+
SP_CustomAllocator* allocator,
656+
SP_CustomAllocatorFns* allocator_fns);
491657
} SP_PlatformFns;
492658

493659
#define SP_PLATFORM_FNS_STRUCT_SIZE \
494660
TF_OFFSET_OF_END(SP_PlatformFns, destroy_timer_fns)
495661

662+
496663
typedef struct SE_PlatformRegistrationParams {
497664
size_t struct_size;
498665
void* ext; // reserved for future use
@@ -584,6 +751,10 @@ void create_timer_fns(const SP_Platform* platform, SP_TimerFns* timer_fns,
584751
timer_fns->nanoseconds = nanoseconds;
585752
...
586753
}
754+
void create_allocator(const SP_Platform* platform, SP_CreateAllocatorParams* params,
755+
TF_Status* status) {
756+
...
757+
}
587758
void destroy_device(const SP_Platform* platform, SP_Device* device) {
588759
// Destroy device handle here.
589760
}
@@ -594,6 +765,9 @@ void destroy_stream_executor(const SP_Platform* platform,
594765
void destroy_timer_fns(const SP_Platform* platform, SP_TimerFns* timer_fns) {
595766
// Destroy timer functions here.
596767
}
768+
void destroy_allocator(const SP_Platform* platform, SP_Allocator* allocator, SP_AllocatorFns* allocator_fns) {
769+
// Clean up allocator here.
770+
}
597771
```
598772
599773
Define `SE_InitPlugin` that TensorFlow will call when registering the device
@@ -616,6 +790,8 @@ void SE_InitPlugin(SE_PlatformRegistrationParams* params, TF_Status* status) {
616790
params->platform_fns->destroy_stream_executor = destroy_stream_executor;
617791
params->platform_fns->create_timer_fns = create_timer_fns;
618792
params->platform_fns->destroy_timer_fns = destroy_timer_fns;
793+
params->platform_fns->create_allocator = create_allocator;
794+
params->platform_fns->destroy_allocator = destroy_allocator;
619795
}
620796
```
621797

0 commit comments

Comments
 (0)