[GPU] Moved memory pool to network (#6599)

This commit is contained in:
Vladimir Paramuzov
2021-07-14 14:17:55 +03:00
committed by GitHub
parent 1cfe27ae1f
commit cbad1b2539
10 changed files with 96 additions and 88 deletions
@@ -15,6 +15,7 @@
#include <set>
#include <utility>
#include <string>
#include <atomic>
#define CLDNN_THREADING_SEQ 0
#define CLDNN_THREADING_TBB 1
@@ -39,15 +40,6 @@ public:
/// Returns runtime type used in the engine
virtual runtime_types runtime_type() const = 0;
/// Create memory object with specified @p layout and allocation @p type for primitive with @p id
/// Underlying memory handle can be reused with other primitives from memory pool based on @p dependencies
memory_ptr get_memory_from_pool(const layout& layout,
primitive_id id,
uint32_t network_id,
std::set<primitive_id> dependencies,
allocation_type type,
bool reusable = true);
/// Create memory object attached to the buffer allocated by user.
/// @param ptr The pointer to user allocated buffer.
/// @note Size (in bytes) of the buffer should be equal to @p layout.bytes_count()
@@ -101,9 +93,6 @@ public:
/// Returns device object associated with the engine
const device::ptr get_device() const;
/// Returns memory pool for the engine
memory_pool& get_memory_pool();
/// Returns user context handle which was used to create the engine
virtual void* get_user_context() const = 0;
@@ -113,6 +102,12 @@ public:
/// Returns the amount of GPU memory currently used by the engine
uint64_t get_used_device_memory() const;
/// Adds @p bytes count to currently used memory size
void add_memory_used(uint64_t bytes);
/// Subtracts @p bytes count from currently used memory size
void subtract_memory_used(uint64_t bytes);
/// Returns true if USM is enabled in engine config and device/driver supports required features
bool use_unified_shared_memory() const;
@@ -144,11 +139,11 @@ public:
protected:
/// Create engine for given @p device and @p configuration
engine(const device::ptr device, const engine_configuration& configuration);
// TODO: Consider moving memory pool to cldnn::network
std::unique_ptr<memory_pool> _memory_pool;
const device::ptr _device;
engine_configuration _configuration;
std::atomic<uint64_t> memory_usage = {0};
std::atomic<uint64_t> peak_memory_usage = {0};
};
} // namespace cldnn
@@ -8,6 +8,7 @@
#include <string>
#include <vector>
#include <algorithm>
#include <ostream>
namespace cldnn {
@@ -19,6 +20,18 @@ enum class allocation_type {
usm_device, // Accessible only by device. Not migratable.
};
inline std::ostream& operator<<(std::ostream& out, const allocation_type& alloc_type) {
switch (alloc_type) {
case allocation_type::cl_mem: out << "cl_mem"; break;
case allocation_type::usm_host: out << "usm_host"; break;
case allocation_type::usm_shared: out << "usm_shared"; break;
case allocation_type::usm_device: out << "usm_device"; break;
default: out << "unknown"; break;
}
return out;
}
class memory_capabilities {
public:
memory_capabilities(std::vector<allocation_type> supported_allocation_types) : _caps(supported_allocation_types) {}
@@ -97,8 +97,6 @@ class memory_pool {
std::map<layout, std::list<memory_record>, padded_pool_comparer> _padded_pool;
std::multimap<uint64_t, memory_record> _no_reusable_pool;
engine* _engine;
std::atomic<uint64_t> _temp_memory_used;
std::atomic<uint64_t> _max_peak_memory_used;
public:
explicit memory_pool(engine& engine);
@@ -127,11 +125,6 @@ public:
void clear_pool();
void clear_pool_for_network(uint32_t network_id);
void release_memory(memory* memory, const primitive_id& id, uint32_t network_id);
uint64_t get_temp_memory_used() const { return _temp_memory_used; }
uint64_t get_max_peak_device_memory_used() const { return _max_peak_memory_used; }
void add_memory_used(size_t value);
void subtract_memory_used(size_t value);
};
} // namespace cldnn
+14 -19
View File
@@ -20,8 +20,7 @@
namespace cldnn {
engine::engine(const device::ptr device, const engine_configuration& configuration)
: _memory_pool(new memory_pool(*this))
, _device(device)
: _device(device)
, _configuration(configuration) {}
device_info engine::get_device_info() const {
@@ -72,17 +71,6 @@ allocation_type engine::get_lockable_preffered_memory_allocation_type(bool is_im
throw std::runtime_error("[clDNN internal error] Could not find proper allocation type!");
}
memory::ptr engine::get_memory_from_pool(const layout& layout,
primitive_id id,
uint32_t network_id,
std::set<primitive_id> dependencies,
allocation_type type,
bool reusable) {
if (_configuration.use_memory_pool)
return _memory_pool->get_memory(layout, id, network_id, dependencies, type, reusable);
return _memory_pool->get_memory(layout, type);
}
memory::ptr engine::attach_memory(const layout& layout, void* ptr) {
return std::make_shared<simple_attached_memory>(layout, ptr);
}
@@ -131,16 +119,23 @@ memory_ptr engine::share_surface(const layout& layout, shared_surface surf, uint
}
#endif // _WIN32
memory_pool& engine::get_memory_pool() {
return *_memory_pool.get();
}
uint64_t engine::get_max_used_device_memory() const {
return _memory_pool->get_max_peak_device_memory_used();
return peak_memory_usage.load();
}
uint64_t engine::get_used_device_memory() const {
return _memory_pool->get_temp_memory_used();
return memory_usage.load();
}
void engine::add_memory_used(size_t bytes) {
memory_usage += bytes;
if (memory_usage > peak_memory_usage) {
peak_memory_usage = memory_usage.load();
}
}
void engine::subtract_memory_used(size_t bytes) {
memory_usage -= bytes;
}
std::shared_ptr<cldnn::engine> engine::create(engine_types engine_type,
+21 -3
View File
@@ -5,6 +5,7 @@
#include "cldnn/runtime/memory.hpp"
#include "cldnn/runtime/engine.hpp"
#include "cldnn/runtime/stream.hpp"
#include "cldnn/runtime/debug_configuration.hpp"
#include "ocl/ocl_memory.hpp"
@@ -17,12 +18,29 @@
namespace cldnn {
memory::memory(engine* engine, const layout& layout, allocation_type type, bool reused)
: _engine(engine), _layout(layout), _bytes_count(_layout.bytes_count()), _type(type), _reused(reused) {}
: _engine(engine), _layout(layout), _bytes_count(_layout.bytes_count()), _type(type), _reused(reused) {
if (!_reused && _engine) {
_engine->add_memory_used(_bytes_count);
}
GPU_DEBUG_GET_INSTANCE(debug_config);
GPU_DEBUG_IF(debug_config->verbose >= 1) {
GPU_DEBUG_COUT << "Allocate " << _bytes_count << " bytes of " << type << " allocation type"
<< " (current=" << _engine->get_used_device_memory() << ";"
<< " max=" << _engine->get_max_used_device_memory() << ")" << std::endl;
}
}
memory::~memory() {
if (!_reused && _engine) {
// TODO: Make memory usage tracker static in memory class
_engine->get_memory_pool().subtract_memory_used(_bytes_count);
_engine->subtract_memory_used(_bytes_count);
}
GPU_DEBUG_GET_INSTANCE(debug_config);
GPU_DEBUG_IF(debug_config->verbose >= 1) {
GPU_DEBUG_COUT << "Free " << _bytes_count << " bytes"
<< " (current=" << _engine->get_used_device_memory() << ";"
<< " max=" << _engine->get_max_used_device_memory() << ")" << std::endl;
}
}
+1 -25
View File
@@ -24,10 +24,6 @@ memory_record::memory_record(memory_set users,
: _users(users), _memory(memory), _network_id(net_id), _type(type) {}
memory::ptr memory_pool::alloc_memory(const layout& layout, allocation_type type) {
if (_max_peak_memory_used > _engine->get_device_info().max_global_mem_size) {
throw std::runtime_error("exceeded global device memory");
}
return _engine->allocate_memory(layout, type);
}
@@ -298,26 +294,6 @@ void memory_pool::clear_pool_for_network(uint32_t network_id) {
}
}
memory_pool::memory_pool(engine& engine) : _engine(&engine), _temp_memory_used(0), _max_peak_memory_used(0) { }
void memory_pool::add_memory_used(size_t value) {
// std::cerr << "ADD MEM: " << value
// << " max: " << _engine->get_device_info().max_global_mem_size
// << " peak: " << _max_peak_memory_used
// << " tmp: " << _temp_memory_used << std::endl;
_temp_memory_used += value;
if (_temp_memory_used > _max_peak_memory_used) {
_max_peak_memory_used = _temp_memory_used.load();
}
}
void memory_pool::subtract_memory_used(size_t value) {
_temp_memory_used -= value;
// std::cerr << "FREE MEM: " << value
// << " max: " << _engine->get_device_info().max_global_mem_size
// << " peak: " << _max_peak_memory_used
// << " tmp: " << _temp_memory_used << std::endl;
}
memory_pool::memory_pool(engine& engine) : _engine(&engine) { }
} // namespace cldnn
@@ -73,8 +73,6 @@ memory::ptr ocl_engine::allocate_memory(const layout& layout, allocation_type ty
throw std::runtime_error("exceeded max size of memory object allocation");
}
_memory_pool->add_memory_used(layout.bytes_count());
try {
memory::ptr res = nullptr;
if (layout.format.is_image_2d()) {
@@ -102,10 +102,19 @@ public:
bool is_internal() const { return _internal; }
bool is_primary_stream() { return _is_primary_stream; }
/// Create memory object with specified @p layout and allocation @p type for primitive with @p id
/// Underlying memory handle can be reused with other primitives from memory pool based on @p dependencies
memory_ptr get_memory_from_pool(const layout& layout,
primitive_id id,
std::set<primitive_id> dependencies,
allocation_type type,
bool reusable = true);
private:
uint32_t net_id = 0;
program_impl::ptr _program;
stream::ptr _stream;
std::unique_ptr<memory_pool> _memory_pool;
bool _internal;
bool _is_primary_stream;
bool _reset_arguments;
+18 -4
View File
@@ -284,7 +284,12 @@ Network_impl will always have net_id = 0 when it will be cldnn internal micronet
opt pass).
*/
network_impl::network_impl(program_impl::ptr program, stream::ptr stream, bool is_internal, bool is_primary_stream)
: _program(program), _stream(stream), _internal(is_internal), _is_primary_stream(is_primary_stream), _reset_arguments(true) {
: _program(program)
, _stream(stream)
, _memory_pool(new memory_pool(program->get_engine()))
, _internal(is_internal)
, _is_primary_stream(is_primary_stream)
, _reset_arguments(true) {
static std::atomic<uint32_t> id_gen{0};
if (!_internal) {
net_id = ++id_gen;
@@ -298,7 +303,7 @@ network_impl::network_impl(program_impl::ptr program, stream::ptr stream, bool i
}
network_impl::~network_impl() {
get_engine().get_memory_pool().clear_pool_for_network(net_id);
_memory_pool->clear_pool_for_network(net_id);
}
network_impl::ptr network_impl::allocate_network(stream::ptr stream, program_impl::ptr program, bool is_internal, bool is_primary_stream) {
@@ -711,11 +716,20 @@ void network_impl::transfer_memory_to_device(std::shared_ptr<primitive_inst> ins
if (alloc_type == allocation_type::usm_host || alloc_type == allocation_type::usm_shared) {
// Allocate and transfer memory
auto& mem_pool = inst_mem.get_engine()->get_memory_pool();
auto device_mem = inst_mem.get_engine()->allocate_memory(inst_mem.get_layout(), allocation_type::usm_device, false);
device_mem->copy_from(get_stream(), inst_mem);
mem_pool.release_memory(&inst_mem, node.id(), get_id());
_memory_pool->release_memory(&inst_mem, node.id(), get_id());
instance->set_output_memory(device_mem);
}
}
memory::ptr network_impl::get_memory_from_pool(const layout& layout,
primitive_id id,
std::set<primitive_id> dependencies,
allocation_type type,
bool reusable) {
if (get_engine().configuration().use_memory_pool)
return _memory_pool->get_memory(layout, id, get_id(), dependencies, type, reusable);
return _memory_pool->get_memory(layout, type);
}
} // namespace cldnn
+10 -13
View File
@@ -149,7 +149,6 @@ primitive_inst::primitive_inst(network_impl& network, program_node const& node,
memory::ptr primitive_inst::allocate_output() {
auto layout = _node.get_output_layout();
auto net_id = get_network_id();
auto& engine = get_network().get_engine();
// For outputs, cpu prim we want to have lockable alloc type
@@ -163,12 +162,11 @@ memory::ptr primitive_inst::allocate_output() {
: allocation_type::usm_device;
if (!_network.is_internal() && (_node.can_be_optimized() || _node.is_type<generic_layer>())) {
return engine.get_memory_from_pool(layout,
_node.id(),
net_id,
_node.get_memory_dependencies(),
alloc_type,
false);
return _network.get_memory_from_pool(layout,
_node.id(),
_node.get_memory_dependencies(),
alloc_type,
false);
} else if (_network.is_internal() && _node.is_output() && _node.is_type<generic_layer>() &&
engine.supports_allocation(allocation_type::usm_device)) {
return engine.allocate_memory(layout, allocation_type::usm_device, false);
@@ -179,12 +177,11 @@ memory::ptr primitive_inst::allocate_output() {
} else if (_network.is_internal() || (!_node.can_share_buffer()) || _node.can_be_optimized() || _node.is_output()) {
return engine.allocate_memory(layout, alloc_type);
} else {
return engine.get_memory_from_pool(layout,
_node.id(),
net_id,
_node.get_memory_dependencies(),
alloc_type,
true);
return _network.get_memory_from_pool(layout,
_node.id(),
_node.get_memory_dependencies(),
alloc_type,
true);
}
}