From 6822abb2d01d9af34e9942e9b3bf69e12418bab8 Mon Sep 17 00:00:00 2001 From: Parichay Kapoor Date: Fri, 3 Sep 2021 17:59:21 +0900 Subject: [PATCH] [graph/manager] Enable memory v1 optimizations This patch adds interface to enable memory optimizations with the neural network. Enabling the interface changes the planner being used for the memory allocation. With this patch, OptimizedV1Planner is put to use when enabling optimizations. Unittest of models is updated to disable optimizations in the non-optimized test cases. Signed-off-by: Parichay Kapoor --- jni/Android.mk | 1 + nntrainer/graph/network_graph.h | 9 +++++++++ nntrainer/models/neuralnet.h | 14 ++++++++++++++ nntrainer/tensor/manager.cpp | 12 ++++++++++-- nntrainer/tensor/manager.h | 21 ++++++++++++++++++++- nntrainer/tensor/memory_pool.cpp | 2 +- nntrainer/tensor/tensor_pool.cpp | 7 +++++-- test/unittest/unittest_nntrainer_models.cpp | 2 ++ 8 files changed, 62 insertions(+), 6 deletions(-) diff --git a/jni/Android.mk b/jni/Android.mk index 796772c..65c6751 100644 --- a/jni/Android.mk +++ b/jni/Android.mk @@ -142,6 +142,7 @@ NNTRAINER_SRCS := $(NNTRAINER_ROOT)/nntrainer/models/neuralnet.cpp \ $(NNTRAINER_ROOT)/nntrainer/tensor/tensor_pool.cpp \ $(NNTRAINER_ROOT)/nntrainer/tensor/memory_pool.cpp \ $(NNTRAINER_ROOT)/nntrainer/tensor/basic_planner.cpp \ + $(NNTRAINER_ROOT)/nntrainer/tensor/optimized_v1_planner.cpp \ $(NNTRAINER_ROOT)/nntrainer/tensor/blas_interface.cpp \ $(NNTRAINER_ROOT)/nntrainer/layers/layer_node.cpp \ $(NNTRAINER_ROOT)/nntrainer/layers/layer_context.cpp \ diff --git a/nntrainer/graph/network_graph.h b/nntrainer/graph/network_graph.h index 362fc0b..5ef4116 100644 --- a/nntrainer/graph/network_graph.h +++ b/nntrainer/graph/network_graph.h @@ -309,6 +309,15 @@ public: void deallocateWeights() { tensor_manager->deallocateWeights(); } /** + * @brief Enable the memory optimizations for the network + * + * @param val true to enable, else false + */ + void setMemoryOptimizations(bool val) { + tensor_manager->setOptimizations(val); + } + + /** * @brief Create optimizer variable for every weights * * @param cb Call back function which will return vector of dimension diff --git a/nntrainer/models/neuralnet.h b/nntrainer/models/neuralnet.h index c415aad..1f4a6fb 100644 --- a/nntrainer/models/neuralnet.h +++ b/nntrainer/models/neuralnet.h @@ -278,6 +278,20 @@ public: unsigned int batch); /** + * @brief Enable the memory optimizations for the network + * + */ + void enableMemoryOptimizations() { model_graph.setMemoryOptimizations(true); } + + /** + * @brief Enable the memory optimizations for the network + * + */ + void disableMemoryOptimizations() { + model_graph.setMemoryOptimizations(false); + } + + /** * @brief Run NeuralNetwork train with callback function by user * @param[in] dt datatype (mode) where it should be * @param[in] dataset set the dataset diff --git a/nntrainer/tensor/manager.cpp b/nntrainer/tensor/manager.cpp index 801dcab..a150f62 100644 --- a/nntrainer/tensor/manager.cpp +++ b/nntrainer/tensor/manager.cpp @@ -129,7 +129,7 @@ MMapedMemory::~MMapedMemory() noexcept { void Manager::allocateWeights(unsigned int max_exec_order_) { if (!weight_pool.isAllocated()) { - weight_pool.finalize(BasicPlanner(), 0, max_exec_order_); + finalizeTensorPool(weight_pool, 0, max_exec_order_); weight_pool.allocate(); } } @@ -143,7 +143,7 @@ void Manager::allocateTensors(unsigned int max_exec_order_) { allocateWeights(max_exec_order_); if (!tensor_pool.isAllocated()) { - tensor_pool.finalize(BasicPlanner(), 0, max_exec_order_); + finalizeTensorPool(tensor_pool, 0, max_exec_order_); if (tensor_pool.minMemoryRequirement() > 0) tensor_pool.allocate(); } @@ -521,4 +521,12 @@ std::vector Manager::getWeights() { return all_weights; } +void Manager::finalizeTensorPool(TensorPool &pool, unsigned int start, + unsigned int end) { + if (enable_optimizations) + pool.finalize(OptimizedV1Planner(), start, end); + else + pool.finalize(BasicPlanner(), start, end); +} + } // namespace nntrainer diff --git a/nntrainer/tensor/manager.h b/nntrainer/tensor/manager.h index 62425d6..af6f08d 100644 --- a/nntrainer/tensor/manager.h +++ b/nntrainer/tensor/manager.h @@ -111,7 +111,7 @@ public: /** * @brief Constructor of Manager */ - Manager() = default; + Manager() : enable_optimizations(true) {} /** * @brief Construct a new Manager object (deleted) @@ -289,6 +289,13 @@ public: */ void deallocateWeights(); + /** + * @brief Set optimizations for manager + * + * @param val true to enable, else false + */ + void setOptimizations(bool val) { enable_optimizations = val; } + private: /** @todo: merge this list to one */ std::vector> @@ -302,6 +309,18 @@ private: TensorPool weight_pool; /**< tensor pool to request tensors */ TensorPool tensor_pool; /**< tensor pool to request tensors */ + + bool enable_optimizations; /**< to enable memory optimizations */ + + /** + * @brief Finalize the given tensor pool + * + * @param pool Tensor pool to finalize + * @param start Start execution order + * @param end End execution order + */ + void finalizeTensorPool(TensorPool &pool, unsigned int start, + unsigned int end); }; } // namespace nntrainer diff --git a/nntrainer/tensor/memory_pool.cpp b/nntrainer/tensor/memory_pool.cpp index 32775b9..9b620c4 100644 --- a/nntrainer/tensor/memory_pool.cpp +++ b/nntrainer/tensor/memory_pool.cpp @@ -71,7 +71,7 @@ double MemoryPool::planLayout(const MemoryPlanner &planner) { if (pool_size < min_pool_size || !validateLayout()) throw std::runtime_error("Planned layout is not feasible"); - return double(pool_size) / double(min_pool_size); + return double(min_pool_size) / double(pool_size); } /** diff --git a/nntrainer/tensor/tensor_pool.cpp b/nntrainer/tensor/tensor_pool.cpp index b84a9f6..15bc2c5 100644 --- a/nntrainer/tensor/tensor_pool.cpp +++ b/nntrainer/tensor/tensor_pool.cpp @@ -14,6 +14,7 @@ */ #include +#include #include #include #include @@ -132,8 +133,10 @@ void TensorPool::finalize(const MemoryPlanner &planner, } /** 4. finalizeLayout for the memory pool. */ - if (bytes_requested > 0) - mem_pool.planLayout(planner); + if (bytes_requested > 0) { + double efficiency = mem_pool.planLayout(planner); + ml_logd("Memory layout efficiency = %lf", efficiency); + } } /** diff --git a/test/unittest/unittest_nntrainer_models.cpp b/test/unittest/unittest_nntrainer_models.cpp index 87e32df..0b7d3ec 100644 --- a/test/unittest/unittest_nntrainer_models.cpp +++ b/test/unittest/unittest_nntrainer_models.cpp @@ -383,6 +383,8 @@ GraphWatcher::GraphWatcher(const std::string &config, const bool opt) : /** Disable memory optimization as memory being matched for each layer */ + if (!opt) + nn.disableMemoryOptimizations(); if (nn.loadFromConfig(config)) { throw std::invalid_argument("load from config failed!"); -- 2.7.4