Unverified Commit 23c3d356 authored by Jayaram Bobba's avatar Jayaram Bobba Committed by GitHub

[PRIVATE] Jbobba/memory allocator (#2707)

* Change Allocator arguments to raw pointers

* Change backend API to return a single device allocator object
parent 58acd894
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
// limitations under the License. // limitations under the License.
//***************************************************************************** //*****************************************************************************
#include <iostream>
#include <memory> #include <memory>
#include "ngraph/runtime/aligned_buffer.hpp" #include "ngraph/runtime/aligned_buffer.hpp"
...@@ -21,6 +22,7 @@ ...@@ -21,6 +22,7 @@
#include "ngraph/util.hpp" #include "ngraph/util.hpp"
using namespace ngraph; using namespace ngraph;
using namespace std;
runtime::AlignedBuffer::AlignedBuffer() runtime::AlignedBuffer::AlignedBuffer()
: m_allocator(nullptr) : m_allocator(nullptr)
...@@ -30,22 +32,22 @@ runtime::AlignedBuffer::AlignedBuffer() ...@@ -30,22 +32,22 @@ runtime::AlignedBuffer::AlignedBuffer()
{ {
} }
runtime::AlignedBuffer::AlignedBuffer(size_t byte_size, runtime::AlignedBuffer::AlignedBuffer(size_t byte_size, size_t alignment, Allocator* allocator)
size_t alignment,
std::shared_ptr<ngraph::runtime::Allocator> allocator)
{ {
m_byte_size = byte_size; m_byte_size = byte_size;
m_allocator = allocator; m_allocator = allocator;
if (m_byte_size > 0) if (m_byte_size > 0)
{ {
size_t allocation_size = m_byte_size + alignment; m_allocated_buffer = static_cast<char*>(m_allocator->Malloc(m_byte_size, alignment));
m_allocated_buffer = static_cast<char*>(m_allocator->Malloc(allocation_size, alignment));
m_aligned_buffer = m_allocated_buffer; m_aligned_buffer = m_allocated_buffer;
size_t mod = size_t(m_aligned_buffer) % alignment; size_t mod = size_t(m_aligned_buffer) % alignment;
if (mod != 0) if (mod != 0)
{ {
m_aligned_buffer += (alignment - mod); ostringstream os;
os << m_aligned_buffer;
throw ngraph_error("Incorrect alignment on newly allocated buffer at address: 0x" +
os.str() + ". Expected alignment: " + to_string(alignment));
} }
} }
else else
......
...@@ -19,12 +19,13 @@ ...@@ -19,12 +19,13 @@
#include <cstddef> #include <cstddef>
#include <memory> #include <memory>
#include "ngraph/runtime/allocator.hpp"
namespace ngraph namespace ngraph
{ {
namespace runtime namespace runtime
{ {
class AlignedBuffer; class AlignedBuffer;
class Allocator;
} }
} }
...@@ -36,8 +37,7 @@ class ngraph::runtime::AlignedBuffer ...@@ -36,8 +37,7 @@ class ngraph::runtime::AlignedBuffer
public: public:
AlignedBuffer(size_t byte_size, AlignedBuffer(size_t byte_size,
size_t alignment, size_t alignment,
std::shared_ptr<ngraph::runtime::Allocator> allocator = Allocator* allocator = get_ngraph_allocator());
std::make_shared<runtime::Allocator>());
AlignedBuffer(); AlignedBuffer();
~AlignedBuffer(); ~AlignedBuffer();
...@@ -49,7 +49,7 @@ private: ...@@ -49,7 +49,7 @@ private:
AlignedBuffer(AlignedBuffer&&) = delete; AlignedBuffer(AlignedBuffer&&) = delete;
AlignedBuffer& operator=(const AlignedBuffer&) = delete; AlignedBuffer& operator=(const AlignedBuffer&) = delete;
std::shared_ptr<ngraph::runtime::Allocator> m_allocator; Allocator* m_allocator;
char* m_allocated_buffer; char* m_allocated_buffer;
char* m_aligned_buffer; char* m_aligned_buffer;
size_t m_byte_size; size_t m_byte_size;
......
...@@ -16,22 +16,33 @@ ...@@ -16,22 +16,33 @@
#include "ngraph/runtime/allocator.hpp" #include "ngraph/runtime/allocator.hpp"
void* ngraph::runtime::Allocator::Malloc(size_t size, size_t alignment) class DefaultNgraphAllocator : public ngraph::runtime::Allocator
{ {
void* ptr = ngraph::aligned_alloc(alignment, size); public:
void* Malloc(size_t size, size_t alignment)
// check for exception
if (!ptr)
{ {
throw ngraph_error("malloc failed to allocate memory of size " + std::to_string(size)); void* ptr = ngraph::aligned_alloc(alignment, size);
// check for exception
if (!ptr)
{
throw ngraph::ngraph_error("malloc failed to allocate memory of size " +
std::to_string(size));
}
return ptr;
} }
return ptr;
}
void ngraph::runtime::Allocator::Free(void* ptr) void Free(void* ptr)
{
if (ptr)
{ {
ngraph::aligned_free(ptr); if (ptr)
{
ngraph::aligned_free(ptr);
}
} }
};
ngraph::runtime::Allocator* ngraph::runtime::get_ngraph_allocator()
{
static DefaultNgraphAllocator* allocator = new DefaultNgraphAllocator();
return allocator;
} }
...@@ -27,20 +27,22 @@ namespace ngraph ...@@ -27,20 +27,22 @@ namespace ngraph
namespace runtime namespace runtime
{ {
class Allocator; class Allocator;
/// \brief Returns a statically allocated default ngraph allocator
// that calls into system allocation libraries
Allocator* get_ngraph_allocator();
} }
} }
/// \brief Abstract class for the allocator, for allocating and deallocating device memory /// \brief Abstract class for the allocator
class ngraph::runtime::Allocator class ngraph::runtime::Allocator
{ {
public: public:
virtual ~Allocator() = default; /// \brief allocates memory with the given size and alignment requirement
/// \brief allocates the memory on the device with the given size and alignment requirement
/// \param size exact size of bytes to allocate /// \param size exact size of bytes to allocate
/// \param alignment specifies the alignment. Must be a valid alignment supported by the implementation. /// \param alignment specifies the alignment. Must be a valid alignment supported by the implementation.
virtual void* Malloc(size_t size, size_t alignment); virtual void* Malloc(size_t size, size_t alignment) = 0;
/// \brief deallocates the memory pointed by ptr /// \brief deallocates the memory pointed by ptr
/// \param ptr pointer to the aligned memory to be released /// \param ptr pointer to the aligned memory to be released
virtual void Free(void* ptr); virtual void Free(void* ptr) = 0;
}; };
...@@ -69,32 +69,6 @@ void runtime::Backend::remove_compiled_function(std::shared_ptr<Executable> exec ...@@ -69,32 +69,6 @@ void runtime::Backend::remove_compiled_function(std::shared_ptr<Executable> exec
{ {
} }
std::shared_ptr<ngraph::runtime::Allocator> runtime::Backend::get_framework_memory_allocator()
{
return nullptr;
}
void runtime::Backend::set_framework_memory_allocator(
const std::shared_ptr<ngraph::runtime::Allocator>& allocator)
{
// override this method from all supported backends to set its memory allocator to
// framework passed memory allocator
}
ngraph::runtime::AllocateFunc runtime::Backend::get_device_memory_alloc()
{
// override this method from all supported backends to return memory allocator
// which allocates device pinned memory
return nullptr;
}
ngraph::runtime::DestroyFunc runtime::Backend::get_device_memory_dealloc()
{
// override this method from all supported backends to return memory de-allocator
// which de-allocates device pinned memory
return nullptr;
}
bool runtime::Backend::is_device_memory(void* ptr) bool runtime::Backend::is_device_memory(void* ptr)
{ {
// override this method for each supported backend to determine if the passed pointer is in // override this method for each supported backend to determine if the passed pointer is in
......
...@@ -31,10 +31,6 @@ namespace ngraph ...@@ -31,10 +31,6 @@ namespace ngraph
{ {
namespace runtime namespace runtime
{ {
// aliases for framework provided function pointers as defined in onnx runtime
using AllocateFunc = void* (*)(void*, size_t, size_t);
using DestroyFunc = void (*)(void*, void*);
class Tensor; class Tensor;
class Backend; class Backend;
} }
...@@ -124,19 +120,21 @@ public: ...@@ -124,19 +120,21 @@ public:
// \returns a shared pointer to the op if found, else nullptr // \returns a shared pointer to the op if found, else nullptr
virtual std::shared_ptr<ngraph::Node> get_backend_op(const std::string& op_name, ...); virtual std::shared_ptr<ngraph::Node> get_backend_op(const std::string& op_name, ...);
/// \brief method which returns the framework passed memory allocator /// \brief Returns memory allocator used by backend for host allocations
virtual std::shared_ptr<ngraph::runtime::Allocator> get_framework_memory_allocator(); virtual Allocator* get_host_memory_allocator()
{
/// \brief method for the framework to set its memory allocator object in the backend. return ngraph::runtime::get_ngraph_allocator();
/// \param allocator reference to framework memory allocator object };
virtual void set_framework_memory_allocator(
const std::shared_ptr<ngraph::runtime::Allocator>& allocator);
/// \brief method to return memory de-allocator which de-allocates device pinned memory /// \brief Set the host memory allocator to be used by the backend
virtual ngraph::runtime::AllocateFunc get_device_memory_alloc(); /// \param pointer to host memory allocator object
virtual void set_host_memory_allocator(Allocator* allocator){};
/// \brief method to return memory allocator which allocates device pinned memory /// \brief Returns memory allocator used by backend for device allocations
virtual ngraph::runtime::DestroyFunc get_device_memory_dealloc(); virtual Allocator* get_device_memory_allocator()
{
return ngraph::runtime::get_ngraph_allocator();
};
/// \brief method for each supported backend to determine if the passed pointer is in device pinned memory or not /// \brief method for each supported backend to determine if the passed pointer is in device pinned memory or not
/// \param ptr pointer to the memory to determine if its in device memory or not /// \param ptr pointer to the memory to determine if its in device memory or not
......
...@@ -50,18 +50,10 @@ namespace ...@@ -50,18 +50,10 @@ namespace
} s_cpu_static_init; } s_cpu_static_init;
} }
runtime::cpu::CPU_Backend::CPU_Backend()
{
m_allocator = make_shared<ngraph::runtime::Allocator>();
}
runtime::cpu::CPU_Backend::~CPU_Backend()
{
}
shared_ptr<runtime::cpu::CPU_CallFrame> runtime::cpu::CPU_Backend::make_call_frame( shared_ptr<runtime::cpu::CPU_CallFrame> runtime::cpu::CPU_Backend::make_call_frame(
const shared_ptr<runtime::cpu::CPU_ExternalFunction>& external_function, const shared_ptr<runtime::cpu::CPU_ExternalFunction>& external_function,
ngraph::pass::PassConfig& pass_config, ngraph::pass::PassConfig& pass_config,
std::shared_ptr<ngraph::runtime::Allocator> allocator) Allocator* allocator)
{ {
return external_function->make_call_frame(pass_config, allocator); return external_function->make_call_frame(pass_config, allocator);
} }
...@@ -72,17 +64,6 @@ shared_ptr<runtime::Tensor> ...@@ -72,17 +64,6 @@ shared_ptr<runtime::Tensor>
return make_shared<runtime::cpu::CPUTensorView>(element_type, shape, this); return make_shared<runtime::cpu::CPUTensorView>(element_type, shape, this);
} }
shared_ptr<ngraph::runtime::Allocator> runtime::cpu::CPU_Backend::get_framework_memory_allocator()
{
return m_allocator;
}
void runtime::cpu::CPU_Backend::set_framework_memory_allocator(
const std::shared_ptr<ngraph::runtime::Allocator>& allocator)
{
m_allocator = allocator;
}
shared_ptr<runtime::Tensor> runtime::cpu::CPU_Backend::create_tensor( shared_ptr<runtime::Tensor> runtime::cpu::CPU_Backend::create_tensor(
const element::Type& element_type, const Shape& shape, void* memory_pointer) const element::Type& element_type, const Shape& shape, void* memory_pointer)
{ {
...@@ -110,7 +91,7 @@ shared_ptr<runtime::Executable> ...@@ -110,7 +91,7 @@ shared_ptr<runtime::Executable>
else else
{ {
rc = make_shared<CPU_Executable>( rc = make_shared<CPU_Executable>(
func, pass_config, m_allocator, performance_counters_enabled); func, pass_config, get_host_memory_allocator(), performance_counters_enabled);
m_exec_map.insert({func, rc}); m_exec_map.insert({func, rc});
} }
return rc; return rc;
...@@ -118,7 +99,7 @@ shared_ptr<runtime::Executable> ...@@ -118,7 +99,7 @@ shared_ptr<runtime::Executable>
runtime::cpu::CPU_Executable::CPU_Executable(shared_ptr<Function> func, runtime::cpu::CPU_Executable::CPU_Executable(shared_ptr<Function> func,
ngraph::pass::PassConfig& pass_config, ngraph::pass::PassConfig& pass_config,
std::shared_ptr<ngraph::runtime::Allocator> allocator, Allocator* allocator,
bool performance_counters_enabled) bool performance_counters_enabled)
{ {
FunctionInstance& instance = m_function_instance; FunctionInstance& instance = m_function_instance;
...@@ -167,6 +148,23 @@ void runtime::cpu::CPU_Backend::remove_compiled_function(shared_ptr<Executable> ...@@ -167,6 +148,23 @@ void runtime::cpu::CPU_Backend::remove_compiled_function(shared_ptr<Executable>
} }
} }
runtime::Allocator* runtime::cpu::CPU_Backend::get_host_memory_allocator()
{
if (m_allocator)
{
return m_allocator;
}
else
{
runtime::get_ngraph_allocator();
}
}
void runtime::cpu::CPU_Backend::set_host_memory_allocator(runtime::Allocator* allocator)
{
m_allocator = allocator;
}
vector<runtime::PerformanceCounter> runtime::cpu::CPU_Executable::get_performance_data() const vector<runtime::PerformanceCounter> runtime::cpu::CPU_Executable::get_performance_data() const
{ {
vector<runtime::PerformanceCounter> rc; vector<runtime::PerformanceCounter> rc;
......
...@@ -36,12 +36,10 @@ namespace ngraph ...@@ -36,12 +36,10 @@ namespace ngraph
class CPU_BACKEND_API CPU_Backend : public runtime::Backend class CPU_BACKEND_API CPU_Backend : public runtime::Backend
{ {
public: public:
CPU_Backend();
~CPU_Backend();
std::shared_ptr<CPU_CallFrame> std::shared_ptr<CPU_CallFrame>
make_call_frame(const std::shared_ptr<CPU_ExternalFunction>& external_function, make_call_frame(const std::shared_ptr<CPU_ExternalFunction>& external_function,
ngraph::pass::PassConfig& pass_config, ngraph::pass::PassConfig& pass_config,
std::shared_ptr<ngraph::runtime::Allocator> allocator); Allocator* allocator);
std::shared_ptr<ngraph::runtime::Tensor> std::shared_ptr<ngraph::runtime::Tensor>
create_tensor(const ngraph::element::Type& element_type, create_tensor(const ngraph::element::Type& element_type,
...@@ -63,17 +61,16 @@ namespace ngraph ...@@ -63,17 +61,16 @@ namespace ngraph
void remove_compiled_function(std::shared_ptr<Executable> exec) override; void remove_compiled_function(std::shared_ptr<Executable> exec) override;
std::shared_ptr<ngraph::runtime::Allocator> Allocator* get_host_memory_allocator() override;
get_framework_memory_allocator() override; void set_host_memory_allocator(Allocator* allocator) override;
void set_framework_memory_allocator(
const std::shared_ptr<ngraph::runtime::Allocator>& allocator) override;
bool is_supported(const Node& node) const override; bool is_supported(const Node& node) const override;
bool is_supported_property(const Property prop) const override; bool is_supported_property(const Property prop) const override;
private: private:
std::unordered_map<std::shared_ptr<Function>, std::shared_ptr<Executable>> std::unordered_map<std::shared_ptr<Function>, std::shared_ptr<Executable>>
m_exec_map; m_exec_map;
std::shared_ptr<ngraph::runtime::Allocator> m_allocator = nullptr; Allocator* m_allocator;
}; };
class CPU_BACKEND_API CPU_Executable : public runtime::Executable class CPU_BACKEND_API CPU_Executable : public runtime::Executable
...@@ -81,7 +78,7 @@ namespace ngraph ...@@ -81,7 +78,7 @@ namespace ngraph
public: public:
CPU_Executable(std::shared_ptr<Function> func, CPU_Executable(std::shared_ptr<Function> func,
ngraph::pass::PassConfig& pass_config, ngraph::pass::PassConfig& pass_config,
std::shared_ptr<ngraph::runtime::Allocator> allocator, Allocator* allocator,
bool performance_counters_enabled); bool performance_counters_enabled);
bool call(const std::vector<std::shared_ptr<runtime::Tensor>>& outputs, bool call(const std::vector<std::shared_ptr<runtime::Tensor>>& outputs,
const std::vector<std::shared_ptr<runtime::Tensor>>& inputs) override; const std::vector<std::shared_ptr<runtime::Tensor>>& inputs) override;
......
...@@ -33,7 +33,7 @@ runtime::cpu::CPU_CallFrame::CPU_CallFrame(std::shared_ptr<CPU_ExternalFunction> ...@@ -33,7 +33,7 @@ runtime::cpu::CPU_CallFrame::CPU_CallFrame(std::shared_ptr<CPU_ExternalFunction>
InitContextFuncCG compiled_init_ctx_func, InitContextFuncCG compiled_init_ctx_func,
DestroyContextFuncCG compiled_destroy_ctx_func, DestroyContextFuncCG compiled_destroy_ctx_func,
EntryPoint compiled_function, EntryPoint compiled_function,
std::shared_ptr<ngraph::runtime::Allocator> allocator) runtime::Allocator* allocator)
: m_external_function(external_function) : m_external_function(external_function)
, m_compiled_init_ctx_func(compiled_init_ctx_func) , m_compiled_init_ctx_func(compiled_init_ctx_func)
, m_compiled_destroy_ctx_func(compiled_destroy_ctx_func) , m_compiled_destroy_ctx_func(compiled_destroy_ctx_func)
...@@ -126,8 +126,7 @@ void runtime::cpu::CPU_CallFrame::propagate_layouts( ...@@ -126,8 +126,7 @@ void runtime::cpu::CPU_CallFrame::propagate_layouts(
} }
} }
void runtime::cpu::CPU_CallFrame::setup_runtime_context( void runtime::cpu::CPU_CallFrame::setup_runtime_context(Allocator* allocator)
std::shared_ptr<ngraph::runtime::Allocator> allocator)
{ {
ctx = new CPURuntimeContext; ctx = new CPURuntimeContext;
ctx->pc = 0; ctx->pc = 0;
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <vector> #include <vector>
#include "ngraph/function.hpp" #include "ngraph/function.hpp"
#include "ngraph/runtime/allocator.hpp"
#include "ngraph/runtime/cpu/cpu_layout_descriptor.hpp" #include "ngraph/runtime/cpu/cpu_layout_descriptor.hpp"
#include "ngraph/runtime/cpu/cpu_runtime_context.hpp" #include "ngraph/runtime/cpu/cpu_runtime_context.hpp"
#include "ngraph/runtime/tensor.hpp" #include "ngraph/runtime/tensor.hpp"
...@@ -58,7 +59,7 @@ namespace ngraph ...@@ -58,7 +59,7 @@ namespace ngraph
InitContextFuncCG compiled_init_ctx_func, InitContextFuncCG compiled_init_ctx_func,
DestroyContextFuncCG compiled_destroy_ctx_func, DestroyContextFuncCG compiled_destroy_ctx_func,
EntryPoint compiled_function, EntryPoint compiled_function,
std::shared_ptr<ngraph::runtime::Allocator> allocator); runtime::Allocator* allocator);
~CPU_CallFrame(); ~CPU_CallFrame();
/// \brief Invoke the function with values matching the signature of the function. /// \brief Invoke the function with values matching the signature of the function.
...@@ -70,7 +71,7 @@ namespace ngraph ...@@ -70,7 +71,7 @@ namespace ngraph
void propagate_layouts(const std::vector<std::shared_ptr<runtime::Tensor>>& tvs, void propagate_layouts(const std::vector<std::shared_ptr<runtime::Tensor>>& tvs,
const LayoutDescriptorPtrs& layouts) const; const LayoutDescriptorPtrs& layouts) const;
void setup_runtime_context(std::shared_ptr<ngraph::runtime::Allocator> allocator); void setup_runtime_context(runtime::Allocator* allocator);
void setup_cg_runtime_context(); void setup_cg_runtime_context();
void cleanup_runtime_context(); void cleanup_runtime_context();
......
...@@ -1716,8 +1716,9 @@ void*& runtime::cpu::CPU_ExternalFunction::get_tensor_data(const std::string& na ...@@ -1716,8 +1716,9 @@ void*& runtime::cpu::CPU_ExternalFunction::get_tensor_data(const std::string& na
} }
} }
shared_ptr<ngraph::runtime::cpu::CPU_CallFrame> runtime::cpu::CPU_ExternalFunction::make_call_frame( shared_ptr<ngraph::runtime::cpu::CPU_CallFrame>
ngraph::pass::PassConfig& pass_config, std::shared_ptr<ngraph::runtime::Allocator> allocator) runtime::cpu::CPU_ExternalFunction::make_call_frame(ngraph::pass::PassConfig& pass_config,
Allocator* allocator)
{ {
#if defined(NGRAPH_DEX_ONLY) #if defined(NGRAPH_DEX_ONLY)
if (pass_config.get_compilation_mode() == ngraph::pass::CompilationMode::CODEGEN) if (pass_config.get_compilation_mode() == ngraph::pass::CompilationMode::CODEGEN)
......
...@@ -100,8 +100,7 @@ namespace ngraph ...@@ -100,8 +100,7 @@ namespace ngraph
bool release_function = true); bool release_function = true);
~CPU_ExternalFunction(); ~CPU_ExternalFunction();
std::shared_ptr<ngraph::runtime::cpu::CPU_CallFrame> std::shared_ptr<ngraph::runtime::cpu::CPU_CallFrame>
make_call_frame(ngraph::pass::PassConfig& pass_config, make_call_frame(ngraph::pass::PassConfig& pass_config, Allocator* allocator);
std::shared_ptr<ngraph::runtime::Allocator> allocator);
const LayoutDescriptorPtrs& get_parameter_layout_descriptors(); const LayoutDescriptorPtrs& get_parameter_layout_descriptors();
const LayoutDescriptorPtrs& get_result_layout_descriptors(); const LayoutDescriptorPtrs& get_result_layout_descriptors();
const std::vector<size_t>& get_memory_buffer_sizes() const const std::vector<size_t>& get_memory_buffer_sizes() const
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment