-
Notifications
You must be signed in to change notification settings - Fork 106
New onnx custom allocator API #827
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
33e6ef5
b101e59
be2a69d
ddb2111
68fdfc7
1136450
fffa1ea
bbfde5b
af40e81
d3310f5
6283f3a
825f4e0
c0363c8
2e42c8e
4148fec
0f20247
b36c413
e004ad2
e9dd654
90ffc90
5d2fbde
fd58367
a50542c
d684b64
22415bf
ccf75b7
171119f
4b927eb
134a8c1
ff6ecc3
8a5f168
6fa11ca
c52d579
66f8e8b
e1a8d6f
7db4313
86f6afe
1e874dd
4a13924
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| add_library(onnx_allocator STATIC onnx_allocator.cpp) | ||
| target_link_libraries(onnx_allocator "${ONNX_LIBRARIES}") | ||
| set_property(TARGET onnx_allocator PROPERTY CXX_STANDARD 14) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,114 @@ | ||
| #include "onnx_allocator.h" | ||
| #include "../onnxruntime.h" | ||
| #include "onnxruntime_cxx_api.h" | ||
| #include <atomic> | ||
|
|
||
| struct RAIOrtAllocator : OrtAllocator { | ||
| RAIOrtAllocator(); | ||
| ~RAIOrtAllocator(); | ||
| RAIOrtAllocator(const RAIOrtAllocator&) = delete; | ||
| RAIOrtAllocator& operator=(const RAIOrtAllocator&) = delete; | ||
|
|
||
| void* Alloc(size_t size); | ||
| void Free(void* p); | ||
| const OrtMemoryInfo* Info() const; | ||
| unsigned long long NumAllocatorAccess() const; | ||
| unsigned long long MemoryInUse() const; | ||
| void SetMemoryLimit(unsigned long long max_memory); | ||
| static RAIOrtAllocator *GetInstance(); | ||
|
|
||
| private: | ||
| std::atomic<unsigned long long> memory_inuse{0}; | ||
| std::atomic<unsigned long long> num_allocator_access{0}; | ||
| unsigned long long memory_limit = 0; | ||
| OrtMemoryInfo* cpu_memory_info; | ||
| static RAIOrtAllocator* allocator_instance; | ||
| }; | ||
|
|
||
| RAIOrtAllocator* RAIOrtAllocator::allocator_instance = nullptr; | ||
|
|
||
| RAIOrtAllocator::RAIOrtAllocator() { | ||
| OrtAllocator::version = ORT_API_VERSION; | ||
| OrtAllocator::Alloc = [](OrtAllocator* this_, size_t size) { return static_cast<RAIOrtAllocator*>(this_)->Alloc(size); }; | ||
| OrtAllocator::Free = [](OrtAllocator* this_, void* p) { static_cast<RAIOrtAllocator*>(this_)->Free(p); }; | ||
| OrtAllocator::Info = [](const OrtAllocator* this_) { return static_cast<const RAIOrtAllocator*>(this_)->Info(); }; | ||
| Ort::ThrowOnError(Ort::GetApi().CreateCpuMemoryInfo(OrtDeviceAllocator, OrtMemTypeDefault, &cpu_memory_info)); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why this is wrapped with
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I copied it from ONNX test. Even thought there is no obvious reason for |
||
| RAIOrtAllocator::allocator_instance = this; | ||
| } | ||
|
|
||
| RAIOrtAllocator::~RAIOrtAllocator() { | ||
| Ort::GetApi().ReleaseMemoryInfo(cpu_memory_info); | ||
| } | ||
|
|
||
| void* RAIOrtAllocator::Alloc(size_t size) { | ||
| // Allocate an additional 63 bytes to ensure that we can return an address which is | ||
| // 64-byte aligned, and an additional space in the size of a pointer to store | ||
| // the address that RedisModule_Alloc returns. | ||
| int offset = 63 + sizeof(void *); | ||
| void *allocated_address = (void *)RedisModule_Alloc(size + offset); | ||
| size_t allocated_size = RedisModule_MallocSize(allocated_address); | ||
| // Update the total number of bytes that onnx is using and the number of accesses | ||
| // that onnx made to the allocator. | ||
| size_t cur_memory = memory_inuse.load(); | ||
| if (memory_limit && cur_memory + allocated_size > memory_limit) { | ||
| RedisModule_Free(allocated_address); | ||
| throw Ort::Exception("Onnxruntime memory limit exceeded, memory allocation failed.", ORT_RUNTIME_EXCEPTION); | ||
| } | ||
| memory_inuse.fetch_add(allocated_size); | ||
| num_allocator_access.fetch_add(1); | ||
| // This operation guarantees that "aligned_address" is the closest 64-aligned address to ("allocated_address"+size_t). | ||
| void **aligned_address = (void **)(((size_t)(allocated_address) + offset) & (~63)); | ||
| // This stores the address "allocated_address" right before "aligned_address" (so we can retrieve it when we free). | ||
| aligned_address[-1] = allocated_address; | ||
| return aligned_address; | ||
| } | ||
|
|
||
| void RAIOrtAllocator::Free(void* p) { | ||
| if (p == nullptr) { | ||
| return; | ||
| } | ||
| // Retrieve the address that we originally received from RedisModule_Alloc | ||
| // (this is the address that we need to sent to RedisModule_Free). | ||
| void *allocated_address = ((void **)p)[-1]; | ||
| size_t allocated_size = RedisModule_MallocSize(allocated_address); | ||
| // Update the total number of bytes that onnx is using and the number of accesses | ||
| // that onnx made to the allocator. | ||
| memory_inuse.fetch_sub(allocated_size); | ||
| num_allocator_access.fetch_add(1); | ||
| RedisModule_Free(allocated_address); | ||
| } | ||
|
|
||
| const OrtMemoryInfo* RAIOrtAllocator::Info() const { | ||
| return cpu_memory_info; | ||
| } | ||
|
|
||
| unsigned long long RAIOrtAllocator::NumAllocatorAccess() const { | ||
| return num_allocator_access.load(); | ||
| } | ||
|
|
||
| unsigned long long RAIOrtAllocator::MemoryInUse() const { | ||
| return memory_inuse.load(); | ||
| } | ||
|
|
||
| void RAIOrtAllocator::SetMemoryLimit(unsigned long long max_memory) { | ||
| // max_memory is given in MB | ||
| memory_limit = 1000000*max_memory; | ||
| } | ||
|
|
||
| RAIOrtAllocator *RAIOrtAllocator::GetInstance() { | ||
| return RAIOrtAllocator::allocator_instance; | ||
| } | ||
|
|
||
| OrtAllocator *CreateCustomAllocator(unsigned long long max_memory) { | ||
| auto *allocator = new RAIOrtAllocator(); | ||
| allocator->SetMemoryLimit(max_memory); | ||
| return allocator; | ||
| } | ||
|
|
||
| unsigned long long RAI_GetMemoryInfoORT() { | ||
| return RAIOrtAllocator::GetInstance()->MemoryInUse(); | ||
| } | ||
|
|
||
| unsigned long long RAI_GetMemoryAccessORT() { | ||
| return RAIOrtAllocator::GetInstance()->NumAllocatorAccess(); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| #pragma once | ||
|
|
||
| #include "onnxruntime_c_api.h" | ||
|
|
||
| #ifdef __cplusplus | ||
| extern "C" { | ||
| #endif | ||
|
|
||
| OrtAllocator *CreateCustomAllocator(unsigned long long max_memory); | ||
|
|
||
| unsigned long long RAI_GetMemoryInfoORT(); | ||
|
|
||
| unsigned long long RAI_GetMemoryAccessORT(); | ||
|
|
||
| #ifdef __cplusplus | ||
| } | ||
| #endif |
Uh oh!
There was an error while loading. Please reload this page.