[neurun] Apply TensorManager instead of MemoryManager (#7251)
author김용섭/On-Device Lab(SR)/Engineer/삼성전자 <yons.kim@samsung.com>
Mon, 9 Sep 2019 06:07:33 +0000 (15:07 +0900)
committer이춘석/On-Device Lab(SR)/Staff Engineer/삼성전자 <chunseok.lee@samsung.com>
Mon, 9 Sep 2019 06:07:33 +0000 (15:07 +0900)
* [neurun] Apply TensorManager instead of MemoryManager

Apply TensorManager instead of MemoryManager. It looks huge but there
are the only many changes instead TensorManager of MemoryManager

Signed-off-by: Yongseop Kim <yons.kim@samsung.com>
* Fix format

* Adding finalize() and moving wrap_tensor() in dataflow

* Fix wrong code in dataflow

27 files changed:
runtimes/neurun/backend/acl_cl/Backend.h
runtimes/neurun/backend/acl_cl/KernelGenerator.cc
runtimes/neurun/backend/acl_cl/TensorManager.h [moved from runtimes/neurun/backend/acl_cl/MemoryManager.h with 81% similarity]
runtimes/neurun/backend/acl_common/AclLinearMemoryManager.h
runtimes/neurun/backend/acl_common/AclMemoryManager.h
runtimes/neurun/backend/acl_common/AclTensorManager.h
runtimes/neurun/backend/acl_common/TemplTensorBuilder.h
runtimes/neurun/backend/acl_neon/Backend.h
runtimes/neurun/backend/acl_neon/KernelGenerator.cc
runtimes/neurun/backend/acl_neon/TensorManager.h [moved from runtimes/neurun/backend/acl_neon/MemoryManager.h with 81% similarity]
runtimes/neurun/backend/cpu/TensorBuilder.cc
runtimes/neurun/backend/cpu/TensorBuilder.h
runtimes/neurun/backend/srcn/TensorBuilder.cc
runtimes/neurun/backend/srcn/TensorBuilder.h
runtimes/neurun/backend/srcn/TensorManager.cc [new file with mode: 0644]
runtimes/neurun/backend/srcn/TensorManager.h [new file with mode: 0644]
runtimes/neurun/core/include/backend/ITensorBuilder.h
runtimes/neurun/core/include/backend/ITensorManager.h
runtimes/neurun/core/src/compiler/ExecutorFactory.cc
runtimes/neurun/core/src/compiler/Linear.cc
runtimes/neurun/core/src/exec/DataflowExecutor.cc
runtimes/neurun/core/src/exec/DataflowExecutor.h
runtimes/neurun/core/src/exec/ExecutorBase.cc
runtimes/neurun/core/src/exec/ExecutorBase.h
runtimes/neurun/core/src/exec/LinearExecutor.h
runtimes/neurun/core/src/exec/ParallelExecutor.cc
runtimes/neurun/core/src/exec/ParallelExecutor.h

index 19536d3..7c69d7b 100644 (file)
@@ -25,7 +25,7 @@
 #include "ConstantInitializer.h"
 #include "KernelGenerator.h"
 #include "ShapeFixer.h"
-#include "MemoryManager.h"
+#include "TensorManager.h"
 #include "backend/CustomKernelRegistry.h"
 
 namespace neurun
@@ -46,7 +46,7 @@ public:
   newContext(const model::Operands &operands,
              const std::shared_ptr<custom::KernelRegistry> &) const override
   {
-    auto tensor_builder = std::make_shared<TensorBuilder>(createMemoryManager());
+    auto tensor_builder = std::make_shared<TensorBuilder>(createTensorManager());
     return std::unique_ptr<BackendContext>{new BackendContext{
         this, tensor_builder, std::make_shared<ConstantInitializer>(operands, tensor_builder),
         std::make_shared<KernelGenerator>(operands, tensor_builder),
index cdc8948..9b986c9 100644 (file)
@@ -215,7 +215,7 @@ void KernelGenerator::visit(const model::operation::Conv2DNode &node)
   const auto act_info = acl_common::asActivationLayerInfo(activation);
 
   auto fn = nnfw::cpp14::make_unique<::arm_compute::CLConvolutionLayer>(
-      _tensor_builder->acl_memory_manager()->internal_buffer_manager());
+      _tensor_builder->acl_tensor_manager()->internal_buffer_manager());
 
   fn->configure(ifm_alloc->handle(), ker_alloc->handle(), bias_alloc->handle(), ofm_alloc->handle(),
                 conv_info, ::arm_compute::WeightsInfo(), ::arm_compute::Size2D(1U, 1U), act_info);
@@ -257,7 +257,7 @@ void KernelGenerator::visit(const model::operation::DepthwiseConv2DNode &node)
   if (ker_height == 3 && ker_width == 3)
   {
     auto fn = nnfw::cpp14::make_unique<::arm_compute::CLDepthwiseConvolutionLayer3x3>(
-        _tensor_builder->acl_memory_manager()->internal_buffer_manager());
+        _tensor_builder->acl_tensor_manager()->internal_buffer_manager());
 
     fn->configure(ifm_alloc->handle(), ker_alloc->handle(), bias_alloc->handle(),
                   ofm_alloc->handle(), conv_info, multiplier, act_info);
@@ -469,7 +469,7 @@ void KernelGenerator::visit(const model::operation::FullyConnectedNode &node)
   auto acl_layout = output_alloc->handle()->info()->data_layout();
 
   auto fn = nnfw::cpp14::make_unique<arm_compute::CLFullyConnectedReshapingLayer>(
-      _tensor_builder->acl_memory_manager()->internal_buffer_manager());
+      _tensor_builder->acl_tensor_manager()->internal_buffer_manager());
 
   fn->configure(
       input_alloc->handle(), weight_alloc->handle(), bias_alloc->handle(), output_alloc->handle(),
@@ -623,7 +623,7 @@ void KernelGenerator::visit(const model::operation::SoftmaxNode &node)
   auto input_alloc = _tensor_builder->at(input_index).get();
 
   auto fn = nnfw::cpp14::make_unique<::arm_compute::CLSoftmaxLayer>(
-      _tensor_builder->acl_memory_manager()->internal_buffer_manager());
+      _tensor_builder->acl_tensor_manager()->internal_buffer_manager());
 
   fn->configure(input_alloc->handle(), output_alloc->handle(), beta);
 
@@ -1319,7 +1319,7 @@ void KernelGenerator::visit(const model::operation::RNNNode &node)
 
   std::unique_ptr<::arm_compute::IFunction> fn;
   auto rnn_layer = nnfw::cpp14::make_unique<::arm_compute::CLRNNLayerEx>(
-      _tensor_builder->acl_memory_manager()->internal_buffer_manager());
+      _tensor_builder->acl_tensor_manager()->internal_buffer_manager());
   rnn_layer->configure(input_alloc->handle(), weights_alloc->handle(),
                        recurrent_weights_alloc->handle(), bias_alloc->handle(),
                        hidden_state_out_alloc->handle(), output_alloc->handle(), act_info);
@@ -1565,7 +1565,7 @@ void KernelGenerator::visit(const model::operation::TransposeConvNode &node)
   std::unique_ptr<::arm_compute::IFunction> fn;
 
   auto l = nnfw::cpp14::make_unique<::arm_compute::CLTransposeConvLayer>(
-      _tensor_builder->acl_memory_manager()->internal_buffer_manager());
+      _tensor_builder->acl_tensor_manager()->internal_buffer_manager());
 
   l->configure(ifm_alloc->handle(), ker_alloc->handle(), nullptr, ofm_alloc->handle(), tconv_info,
                invalid_horizontal, invalid_vertical);
@@ -14,9 +14,8 @@
  * limitations under the License.
  */
 
-// TODO Rename this to TensorManager.h
-#ifndef __NEURUN_BACKEND_ACL_CL_MEMORY_MANAGER_H__
-#define __NEURUN_BACKEND_ACL_CL_MEMORY_MANAGER_H__
+#ifndef __NEURUN_BACKEND_ACL_CL_TENSOR_MANAGER_H__
+#define __NEURUN_BACKEND_ACL_CL_TENSOR_MANAGER_H__
 
 #include <arm_compute/runtime/CL/CLBufferAllocator.h>
 #include <arm_compute/runtime/PoolManager.h>
@@ -52,25 +51,6 @@ using LinearMemoryManager = ::neurun::backend::acl_common::AclLinearMemoryManage
     ::arm_compute::BlobLifetimeManager, ::arm_compute::CLBufferAllocator,
     ::arm_compute::CLMemoryGroup>;
 
-// TODO Remove this
-MemoryManager *createMemoryManager()
-{
-  const std::string executor_str = util::getConfigString(util::config::EXECUTOR);
-
-  if (executor_str == "Linear")
-  {
-    VERBOSE(acl_cl_createMemoryManager) << "AclMemoryManager as Linear" << std::endl;
-    return new LinearMemoryManager();
-  }
-  else
-  {
-    VERBOSE(acl_cl_createMemoryManager) << "AclMemoryManager" << std::endl;
-    return new MemoryManager();
-  }
-}
-
-// TODO Enable this
-/*
 using InternalBufferManager = ::neurun::backend::acl_common::AclInternalBufferManager<
     ::arm_compute::MemoryManagerOnDemand, ::arm_compute::PoolManager,
     ::arm_compute::BlobLifetimeManager, ::arm_compute::CLBufferAllocator>;
@@ -96,10 +76,9 @@ TensorManager *createTensorManager()
     return new TensorManager(new MemoryManager(), new MemoryManager(), new InternalBufferManager());
   }
 }
-*/
 
 } // namespace acl_cl
 } // namespace backend
 } // namespace neurun
 
-#endif // __NEURUN_BACKEND_ACL_CL_MEMORY_MANAGER_H__
+#endif // __NEURUN_BACKEND_ACL_CL_TENSOR_MANAGER_H__
index 006c28a..793c7b2 100644 (file)
@@ -55,8 +55,7 @@ public:
   AclLinearMemoryManager()
       : _allocator{nullptr},
         _io_manager{createMemoryManager<T_MemoryManager, T_PoolManager, T_LifetimeManager>()},
-        _io_group{std::make_shared<T_MemoryGroup>(_io_manager)},
-        _internal_manager{createMemoryManager<T_MemoryManager, T_PoolManager, T_LifetimeManager>()}
+        _io_group{std::make_shared<T_MemoryGroup>(_io_manager)}
   {
     // DO NOTHING
   }
@@ -66,7 +65,6 @@ public:
   virtual void allocate(void) override
   {
     _allocator = std::make_shared<T_Allocator>();
-    _internal_manager->populate(*_allocator, 1);
     _io_manager->populate(*_allocator, 1);
     _io_group->acquire();
   }
@@ -75,7 +73,6 @@ public:
   {
     _io_group->release();
     _io_manager->clear();
-    _internal_manager->clear();
   }
 
   virtual void startLifetime(const model::OperandIndex &ind) override
@@ -100,16 +97,10 @@ public:
     tensor->allocator()->allocate();
   }
 
-  virtual std::shared_ptr<::arm_compute::IMemoryManager> internal_buffer_manager() override
-  {
-    return _internal_manager;
-  }
-
 private:
   std::shared_ptr<T_Allocator> _allocator;
   std::shared_ptr<T_MemoryManager> _io_manager;
   std::shared_ptr<T_MemoryGroup> _io_group;
-  std::shared_ptr<T_MemoryManager> _internal_manager;
 };
 
 } // namespace acl_common
index 0358b49..076a3f4 100644 (file)
@@ -62,14 +62,8 @@ public:
     }
   }
 
-  virtual void startLifetime(const model::OperandIndex &) {}
-  virtual void finishLifetime(const model::OperandIndex &) {}
-
-  // TODO Remove this
-  virtual std::shared_ptr<::arm_compute::IMemoryManager> internal_buffer_manager()
-  {
-    return nullptr;
-  }
+  virtual void startLifetime(const model::OperandIndex &) { /* DO NOTHING */}
+  virtual void finishLifetime(const model::OperandIndex &) { /* DO NOTHING */}
 
   void buildTensor(const model::OperandIndex &ind, const ::arm_compute::TensorInfo &info,
                    size_t rank)
index da81e1e..63918ff 100644 (file)
@@ -51,10 +51,11 @@ public:
   void deallocateInternalBufferManager(void);
 
   void buildTensor(const model::OperandIndex &ind, const ::arm_compute::TensorInfo &info,
-                   bool as_const);
+                   size_t rank, bool as_const);
   void buildSubtensor(const model::OperandIndex &parent, const model::OperandIndex &child,
                       const ::arm_compute::TensorShape &shape,
-                      const ::arm_compute::Coordinates &coordinates);
+                      const ::arm_compute::Coordinates &coordinates, size_t rank,
+                      bool extent_parent);
 
   std::shared_ptr<T_ITensor> findTensorAsParent(const model::OperandIndex &ind);
 
@@ -144,17 +145,18 @@ void AclTensorManager<T_ITensor, T_Tensor, T_SubTensor, T_Object>::deallocateInt
 
 template <typename T_ITensor, typename T_Tensor, typename T_SubTensor, typename T_Object>
 void AclTensorManager<T_ITensor, T_Tensor, T_SubTensor, T_Object>::buildTensor(
-    const model::OperandIndex &ind, const ::arm_compute::TensorInfo &info, bool as_const)
+    const model::OperandIndex &ind, const ::arm_compute::TensorInfo &info, size_t rank,
+    bool as_const)
 {
   assert(_ind_to_mgr.find(ind) == _ind_to_mgr.end());
   if (as_const)
   {
-    _const_mgr->buildTensor(ind, info);
+    _const_mgr->buildTensor(ind, info, rank);
     _ind_to_mgr.insert({ind, *_const_mgr});
   }
   else
   {
-    _nonconst_mgr->buildTensor(ind, info);
+    _nonconst_mgr->buildTensor(ind, info, rank);
     _ind_to_mgr.insert({ind, *_nonconst_mgr});
   }
 }
@@ -162,12 +164,13 @@ void AclTensorManager<T_ITensor, T_Tensor, T_SubTensor, T_Object>::buildTensor(
 template <typename T_ITensor, typename T_Tensor, typename T_SubTensor, typename T_Object>
 void AclTensorManager<T_ITensor, T_Tensor, T_SubTensor, T_Object>::buildSubtensor(
     const model::OperandIndex &parent, const model::OperandIndex &child,
-    const ::arm_compute::TensorShape &shape, const ::arm_compute::Coordinates &coordinates)
+    const ::arm_compute::TensorShape &shape, const ::arm_compute::Coordinates &coordinates,
+    size_t rank, bool extent_parent)
 {
   assert(_ind_to_mgr.find(child) == _ind_to_mgr.end());
   std::shared_ptr<T_ITensor> parent_tensor = findTensorAsParent(parent);
   assert(parent_tensor);
-  _nonconst_mgr->buildSubtensor(parent_tensor, child, shape, coordinates);
+  _nonconst_mgr->buildSubtensor(parent_tensor, child, shape, coordinates, rank, extent_parent);
   _ind_to_mgr.insert({child, *_nonconst_mgr});
 }
 
index c8913ef..df9fa8c 100644 (file)
@@ -23,7 +23,6 @@
 #include <arm_compute/core/Types.h>
 #include <backend/ITensorBuilder.h>
 #include "model/OperandIndexMap.h"
-#include "AclMemoryManager.h" // TODO Remove this
 #include "AclTensorManager.h"
 #include "cpp14/memory.h"
 #include <util/Utils.h>
@@ -45,9 +44,9 @@ template <typename T_ITensor, typename T_Tensor, typename T_SubTensor, typename
 class TemplTensorBuilder : public ITensorBuilder
 {
 public:
-  using T_AclMemoryManager = AclMemoryManager<T_ITensor, T_Tensor, T_SubTensor, T_Object>;
+  using T_AclTensorManager = AclTensorManager<T_ITensor, T_Tensor, T_SubTensor, T_Object>;
 
-  TemplTensorBuilder(T_AclMemoryManager *mem_mgr);
+  TemplTensorBuilder(T_AclTensorManager *tensor_mgr);
 
   /**
    * @brief     Register tensor information to allocate on ACL-CL backend
@@ -70,13 +69,11 @@ public:
   void notifyLastUse(const model::OperandIndex &) override;
 
   void prepare(void) override;
-  void allocate(void) override;
-
-  // TODO Fill these
-  void allocateConsts() override {}
-  void allocateNonconsts() override {}
-  void postFunctionPrepare() override {}
-  void finalize() override {}
+  void allocate(void) override; // TODO Remove this
+  void allocateConsts() override;
+  void allocateNonconsts() override;
+  void postFunctionPrepare() override;
+  void finalize() override;
 
   std::shared_ptr<::neurun::backend::operand::ITensor>
   tensorAt(const model::OperandIndex &ind) override;
@@ -86,7 +83,7 @@ public:
   void preVisit(const model::Operation &node) override;
   void postVisit(const model::Operation &node) override;
 
-  std::unique_ptr<IMemoryManager> releaseMemoryManager(void) override;
+  std::unique_ptr<ITensorManager> releaseTensorManager(void) override;
 
   std::shared_ptr<T_ITensor> at(const ::neurun::model::OperandIndex &ind);
   /**
@@ -99,7 +96,7 @@ public:
 
   void dimCorrection(const model::OperandIndex &index, bool apply_dim_correction);
 
-  T_AclMemoryManager *acl_memory_manager(void) { return _mem_mgr.get(); }
+  T_AclTensorManager *acl_tensor_manager(void) { return _tensor_mgr.get(); }
 
 private:
   void buildTensors(void);
@@ -113,8 +110,8 @@ private:
   model::OperandIndexMap<bool> _apply_dim_correction_map;
   model::OperandIndexMap<std::pair<model::Layout, model::Layout>> _tensor_layouts_map;
 
-  // TODO Replace this by TensorManager
-  std::unique_ptr<T_AclMemoryManager> _mem_mgr;
+  std::unique_ptr<T_AclTensorManager> _tensor_mgr;
+  model::OperandIndexSequence _constants;
 
   // TODO Consider dividing TensorBuilder into Linear and others
   const std::string _executor_str;
@@ -149,24 +146,26 @@ namespace acl_common
 
 template <typename T_ITensor, typename T_Tensor, typename T_SubTensor, typename T_Object>
 TemplTensorBuilder<T_ITensor, T_Tensor, T_SubTensor, T_Object>::TemplTensorBuilder(
-    T_AclMemoryManager *mem_mgr)
-    : _mem_mgr{mem_mgr}, _executor_str(util::getConfigString(util::config::EXECUTOR)),
+    T_AclTensorManager *tensor_mgr)
+    : _tensor_mgr{tensor_mgr}, _executor_str(util::getConfigString(util::config::EXECUTOR)),
       _first_uses_num(0)
 {
-  assert(_mem_mgr);
+  assert(_tensor_mgr);
 }
 
 template <typename T_ITensor, typename T_Tensor, typename T_SubTensor, typename T_Object>
 void TemplTensorBuilder<T_ITensor, T_Tensor, T_SubTensor, T_Object>::registerTensorInfo(
     const model::OperandIndex &ind, const model::OperandInfo &info, model::Layout frontend_layout,
-    model::Layout backend_layout, bool /*as_const*/)
+    model::Layout backend_layout, bool as_const)
 {
-  // TODO Adding handling tensor as const
-  assert(_mem_mgr->tensors().size() == 0);
+  assert(_tensor_mgr->constTensors().size() == 0);
+  assert(_tensor_mgr->nonconstTensors().size() == 0);
 
   _tensor_info_map.emplace(ind, info);
   _apply_dim_correction_map.emplace(ind, true);
   _tensor_layouts_map.insert({ind, std::make_pair(frontend_layout, backend_layout)});
+  if (as_const)
+    _constants.append(ind);
 
   assert(_first_uses_visit.find(ind) == _first_uses_visit.end());
   _first_uses_visit[ind] = false;
@@ -176,7 +175,8 @@ template <typename T_ITensor, typename T_Tensor, typename T_SubTensor, typename
 void TemplTensorBuilder<T_ITensor, T_Tensor, T_SubTensor, T_Object>::registerSubTensorInfo(
     const model::OperandIndex &ind, const compiler::SubTensorInfo &info)
 {
-  assert(_mem_mgr->tensors().size() == 0);
+  assert(_tensor_mgr->constTensors().size() == 0);
+  assert(_tensor_mgr->nonconstTensors().size() == 0);
 
   _subtensor_info_map.emplace(ind, info);
   _apply_dim_correction_map.emplace(ind, true);
@@ -220,10 +220,35 @@ void TemplTensorBuilder<T_ITensor, T_Tensor, T_SubTensor, T_Object>::prepare(voi
 template <typename T_ITensor, typename T_Tensor, typename T_SubTensor, typename T_Object>
 void TemplTensorBuilder<T_ITensor, T_Tensor, T_SubTensor, T_Object>::allocate(void)
 {
-  validate();
+  allocateConsts();
+  allocateNonconsts();
+}
+
+template <typename T_ITensor, typename T_Tensor, typename T_SubTensor, typename T_Object>
+void TemplTensorBuilder<T_ITensor, T_Tensor, T_SubTensor, T_Object>::allocateConsts(void)
+{
+  assert(_constants.size() == _tensor_mgr->constTensors().size());
+  _tensor_mgr->allocateConsts();
+}
+
+template <typename T_ITensor, typename T_Tensor, typename T_SubTensor, typename T_Object>
+void TemplTensorBuilder<T_ITensor, T_Tensor, T_SubTensor, T_Object>::allocateNonconsts(void)
+{
+  assert(_tensor_info_map.size() == _tensor_mgr->nonconstTensors().size() + _constants.size());
+  _tensor_mgr->allocateNonconsts();
+}
 
-  assert(_tensor_info_map.size() == _mem_mgr->tensors().size());
-  _mem_mgr->allocate();
+template <typename T_ITensor, typename T_Tensor, typename T_SubTensor, typename T_Object>
+void TemplTensorBuilder<T_ITensor, T_Tensor, T_SubTensor, T_Object>::postFunctionPrepare(void)
+{
+  _tensor_mgr->tryDeallocConstants();
+}
+
+template <typename T_ITensor, typename T_Tensor, typename T_SubTensor, typename T_Object>
+void TemplTensorBuilder<T_ITensor, T_Tensor, T_SubTensor, T_Object>::finalize(void)
+{
+  validate();
+  _tensor_mgr->allocateInternalBufferManager();
 }
 
 template <typename T_ITensor, typename T_Tensor, typename T_SubTensor, typename T_Object>
@@ -231,15 +256,7 @@ std::shared_ptr<::neurun::backend::operand::ITensor>
 TemplTensorBuilder<T_ITensor, T_Tensor, T_SubTensor, T_Object>::tensorAt(
     const model::OperandIndex &ind)
 {
-  auto &tensors = _mem_mgr->tensors();
-  if (tensors.find(ind) != tensors.end())
-  {
-    return tensors.at(ind);
-  }
-  else
-  {
-    return _mem_mgr->subtensors().at(ind);
-  }
+  return _tensor_mgr->at(ind);
 }
 
 template <typename T_ITensor, typename T_Tensor, typename T_SubTensor, typename T_Object>
@@ -247,36 +264,21 @@ std::shared_ptr<backend::operand::IObject>
 TemplTensorBuilder<T_ITensor, T_Tensor, T_SubTensor, T_Object>::wrapTensor(
     const model::OperandIndex &ind)
 {
-  return _mem_mgr->wrapTensor(ind);
+  return _tensor_mgr->wrapTensor(ind);
 }
 
 template <typename T_ITensor, typename T_Tensor, typename T_SubTensor, typename T_Object>
 void TemplTensorBuilder<T_ITensor, T_Tensor, T_SubTensor, T_Object>::iterate(
     const IterateFunction &fn)
 {
-  for (auto it : _mem_mgr->tensors())
-  {
-    fn(it.first);
-  }
-  for (auto it : _mem_mgr->subtensors())
-  {
-    fn(it.first);
-  }
+  _tensor_mgr->iterate(fn);
 }
 
 template <typename T_ITensor, typename T_Tensor, typename T_SubTensor, typename T_Object>
 std::shared_ptr<T_ITensor> TemplTensorBuilder<T_ITensor, T_Tensor, T_SubTensor, T_Object>::at(
     const ::neurun::model::OperandIndex &ind)
 {
-  auto &tensors = _mem_mgr->tensors();
-  if (tensors.find(ind) != tensors.end())
-  {
-    return tensors.at(ind);
-  }
-  else
-  {
-    return _mem_mgr->subtensors().at(ind);
-  }
+  return _tensor_mgr->at(ind);
 }
 
 template <typename T_ITensor, typename T_Tensor, typename T_SubTensor, typename T_Object>
@@ -288,7 +290,7 @@ bool TemplTensorBuilder<T_ITensor, T_Tensor, T_SubTensor, T_Object>::isSubTensor
     return false;
   }
 
-  auto &subtensors = _mem_mgr->subtensors();
+  auto &subtensors = _tensor_mgr->nonconstSubtensors();
   if (subtensors.find(child) == subtensors.end())
   {
     return false;
@@ -310,16 +312,17 @@ void TemplTensorBuilder<T_ITensor, T_Tensor, T_SubTensor, T_Object>::dimCorrecti
 }
 
 template <typename T_ITensor, typename T_Tensor, typename T_SubTensor, typename T_Object>
-std::unique_ptr<IMemoryManager>
-TemplTensorBuilder<T_ITensor, T_Tensor, T_SubTensor, T_Object>::releaseMemoryManager(void)
+std::unique_ptr<ITensorManager>
+TemplTensorBuilder<T_ITensor, T_Tensor, T_SubTensor, T_Object>::releaseTensorManager(void)
 {
-  return std::move(_mem_mgr);
+  return std::move(_tensor_mgr);
 }
 
 template <typename T_ITensor, typename T_Tensor, typename T_SubTensor, typename T_Object>
 void TemplTensorBuilder<T_ITensor, T_Tensor, T_SubTensor, T_Object>::buildTensors(void)
 {
-  assert(_mem_mgr->tensors().size() == 0);
+  assert(_tensor_mgr->constTensors().size() == 0);
+  assert(_tensor_mgr->nonconstTensors().size() == 0);
 
   for (auto &entry : _tensor_info_map)
   {
@@ -331,7 +334,7 @@ void TemplTensorBuilder<T_ITensor, T_Tensor, T_SubTensor, T_Object>::buildTensor
     const auto &backend_layout = _tensor_layouts_map[root_parent].second;
     auto tensor_info = asTensorInfo(info.shape(), info.typeInfo(), frontend_layout, backend_layout,
                                     _apply_dim_correction_map[ind]);
-    _mem_mgr->buildTensor(ind, tensor_info, info.shape().rank());
+    _tensor_mgr->buildTensor(ind, tensor_info, info.shape().rank(), _constants.contains(ind));
   }
 }
 
@@ -341,7 +344,7 @@ void TemplTensorBuilder<T_ITensor, T_Tensor, T_SubTensor, T_Object>::buildSubten
   // TODO Handle SubTensor(subsumption)
   //      Currently this TemplTensorBuilder does not have subsumption info yet
   //      Allocated subtensor will be mapped to _subtensors instead of _tensors
-  assert(_mem_mgr->subtensors().size() == 0);
+  assert(_tensor_mgr->nonconstSubtensors().size() == 0);
 
   // To make subtensor, parent tensor must be made first
   // For this condition, use stack
@@ -353,8 +356,7 @@ void TemplTensorBuilder<T_ITensor, T_Tensor, T_SubTensor, T_Object>::buildSubten
   //    3-2) If parent tensor is not made, we can't make child tensor yet
   //         Push parent tensor index to stack and return to 4)
   //  4) If stack is empty, return to 1), else return to 2)
-  auto &tensors = _mem_mgr->tensors();
-  auto &subtensors = _mem_mgr->subtensors();
+  auto &subtensors = _tensor_mgr->nonconstSubtensors();
   for (auto &entry : _subtensor_info_map)
   {
     model::OperandIndex ind = entry.first;
@@ -375,19 +377,8 @@ void TemplTensorBuilder<T_ITensor, T_Tensor, T_SubTensor, T_Object>::buildSubten
       }
 
       auto parent = info.parent();
-      std::shared_ptr<T_ITensor> parent_tensor;
-
-      if (tensors.find(parent) != tensors.end())
-      {
-        // Parent is allocated as tensor
-        parent_tensor = tensors[parent];
-      }
-      else if (subtensors.find(parent) != subtensors.end())
-      {
-        // Parent is allocated as subtensor
-        parent_tensor = subtensors[parent];
-      }
-      else
+      std::shared_ptr<T_ITensor> parent_tensor = _tensor_mgr->findTensorAsParent(parent);
+      if (!parent_tensor)
       {
         // Cannot find allocated parent tensor: allocate parent first
         assert(_subtensor_info_map.find(parent) != _subtensor_info_map.end());
@@ -400,6 +391,7 @@ void TemplTensorBuilder<T_ITensor, T_Tensor, T_SubTensor, T_Object>::buildSubten
       assert(info.type().offset() == parent_tensor->info()->quantization_info().offset);
       assert(info.type().scale() == parent_tensor->info()->quantization_info().scale);
       assert(asDataType(info.type().type()) == parent_tensor->info()->data_type());
+
       // NOTE SubTensor's layout must be the same with layout of parent tensor
       const auto &root_parent = findRootParent(parent);
       const auto &frontend_layout = _tensor_layouts_map[root_parent].first;
@@ -409,8 +401,7 @@ void TemplTensorBuilder<T_ITensor, T_Tensor, T_SubTensor, T_Object>::buildSubten
                                  _apply_dim_correction_map[current]);
       ::arm_compute::Coordinates coordinates =
           asTensorCoordinate(info.offset(), frontend_layout, backend_layout);
-      _mem_mgr->buildSubtensor(parent_tensor, current, shape, coordinates, info.shape().rank(),
-                               true);
+      _tensor_mgr->buildSubtensor(parent, current, shape, coordinates, info.shape().rank(), true);
       stack.pop();
     }
   }
@@ -432,7 +423,7 @@ void TemplTensorBuilder<T_ITensor, T_Tensor, T_SubTensor, T_Object>::preVisit(
         bool is_parent = _parent_def.find(ind) != _parent_def.end();
         if (!is_subtensor && !is_parent)
         {
-          _mem_mgr->startLifetime(ind);
+          _tensor_mgr->startLifetime(ind);
           return;
         }
 
@@ -451,7 +442,7 @@ void TemplTensorBuilder<T_ITensor, T_Tensor, T_SubTensor, T_Object>::preVisit(
           }
           else
           {
-            _mem_mgr->startLifetime(ind);
+            _tensor_mgr->startLifetime(ind);
           }
         }
         else if (is_subtensor)
@@ -507,7 +498,7 @@ void TemplTensorBuilder<T_ITensor, T_Tensor, T_SubTensor, T_Object>::postVisit(
         bool is_parent = _parent_uses.find(ind) != _parent_uses.end();
         if (!is_subtensor && !is_parent)
         {
-          _mem_mgr->finishLifetime(ind);
+          _tensor_mgr->finishLifetime(ind);
           return;
         }
 
@@ -526,7 +517,7 @@ void TemplTensorBuilder<T_ITensor, T_Tensor, T_SubTensor, T_Object>::postVisit(
           }
           else
           {
-            _mem_mgr->finishLifetime(ind);
+            _tensor_mgr->finishLifetime(ind);
           }
         }
         else if (is_subtensor)
index 6cac3f3..38769e5 100644 (file)
@@ -25,7 +25,7 @@
 #include "ConstantInitializer.h"
 #include "KernelGenerator.h"
 #include "ShapeFixer.h"
-#include "MemoryManager.h"
+#include "TensorManager.h"
 #include "backend/CustomKernelRegistry.h"
 
 namespace neurun
@@ -46,7 +46,7 @@ public:
   newContext(const model::Operands &operands,
              const std::shared_ptr<custom::KernelRegistry> &) const override
   {
-    auto tensor_builder = std::make_shared<TensorBuilder>(createMemoryManager());
+    auto tensor_builder = std::make_shared<TensorBuilder>(createTensorManager());
     return std::unique_ptr<BackendContext>{new BackendContext{
         this, tensor_builder, std::make_shared<ConstantInitializer>(operands, tensor_builder),
         std::make_shared<KernelGenerator>(operands, tensor_builder),
index 2bc6db2..c21d630 100644 (file)
@@ -215,7 +215,7 @@ void KernelGenerator::visit(const model::operation::Conv2DNode &node)
   const auto act_info = acl_common::asActivationLayerInfo(activation);
 
   auto fn = nnfw::cpp14::make_unique<::arm_compute::NEConvolutionLayer>(
-      _tensor_builder->acl_memory_manager()->internal_buffer_manager());
+      _tensor_builder->acl_tensor_manager()->internal_buffer_manager());
 
   fn->configure(ifm_alloc->handle(), ker_alloc->handle(), bias_alloc->handle(), ofm_alloc->handle(),
                 conv_info, ::arm_compute::WeightsInfo(), ::arm_compute::Size2D(1U, 1U), act_info);
@@ -562,7 +562,7 @@ void KernelGenerator::visit(const model::operation::FullyConnectedNode &node)
   auto acl_layout = output_alloc->handle()->info()->data_layout();
 
   auto fn = nnfw::cpp14::make_unique<arm_compute::NEFullyConnectedReshapingLayer>(
-      _tensor_builder->acl_memory_manager()->internal_buffer_manager());
+      _tensor_builder->acl_tensor_manager()->internal_buffer_manager());
 
   fn->configure(
       input_alloc->handle(), weight_alloc->handle(), bias_alloc->handle(), output_alloc->handle(),
@@ -1151,7 +1151,7 @@ void KernelGenerator::visit(const model::operation::RNNNode &node)
 
   std::unique_ptr<::arm_compute::IFunction> fn;
   auto rnn_layer = nnfw::cpp14::make_unique<::arm_compute::NERNNLayerEx>(
-      _tensor_builder->acl_memory_manager()->internal_buffer_manager());
+      _tensor_builder->acl_tensor_manager()->internal_buffer_manager());
   rnn_layer->configure(input_alloc->handle(), weights_alloc->handle(),
                        recurrent_weights_alloc->handle(), bias_alloc->handle(),
                        hidden_state_out_alloc->handle(), output_alloc->handle(), act_info);
@@ -1222,7 +1222,7 @@ void KernelGenerator::visit(const model::operation::SoftmaxNode &node)
   auto input_alloc = _tensor_builder->at(input_index).get();
 
   auto fn = nnfw::cpp14::make_unique<::arm_compute::NESoftmaxLayer>(
-      _tensor_builder->acl_memory_manager()->internal_buffer_manager());
+      _tensor_builder->acl_tensor_manager()->internal_buffer_manager());
 
   fn->configure(input_alloc->handle(), output_alloc->handle(), beta);
 
@@ -14,9 +14,8 @@
  * limitations under the License.
  */
 
-// TODO Rename this to TensorManager.h
-#ifndef __NEURUN_BACKEND_ACL_NEON_MEMORY_MANAGER_H__
-#define __NEURUN_BACKEND_ACL_NEON_MEMORY_MANAGER_H__
+#ifndef __NEURUN_BACKEND_ACL_NEON_TENSOR_MANAGER_H__
+#define __NEURUN_BACKEND_ACL_NEON_TENSOR_MANAGER_H__
 
 #include <arm_compute/runtime/Allocator.h>
 #include <arm_compute/runtime/PoolManager.h>
@@ -52,24 +51,6 @@ using LinearMemoryManager = ::neurun::backend::acl_common::AclLinearMemoryManage
     ::arm_compute::MemoryManagerOnDemand, ::arm_compute::PoolManager,
     ::arm_compute::OffsetLifetimeManager, ::arm_compute::Allocator, ::arm_compute::MemoryGroup>;
 
-// TODO Remove this
-MemoryManager *createMemoryManager()
-{
-  const std::string executor_str = util::getConfigString(util::config::EXECUTOR);
-  if (executor_str == "Linear")
-  {
-    VERBOSE(acl_neon_createMemoryManager) << "AclMemoryManager as Linear" << std::endl;
-    return new LinearMemoryManager();
-  }
-  else
-  {
-    VERBOSE(acl_neon_createMemoryManager) << "AclMemoryManager" << std::endl;
-    return new MemoryManager();
-  }
-}
-
-// TODO Enable this instead of createMemoryManager()
-/*
 using InternalBufferManager = ::neurun::backend::acl_common::AclInternalBufferManager<
     ::arm_compute::MemoryManagerOnDemand, ::arm_compute::PoolManager,
     ::arm_compute::OffsetLifetimeManager, ::arm_compute::Allocator>;
@@ -94,10 +75,9 @@ TensorManager *createTensorManager()
     return new TensorManager(new MemoryManager(), new MemoryManager(), new InternalBufferManager());
   }
 }
-*/
 
 } // namespace acl_neon
 } // namespace backend
 } // namespace neurun
 
-#endif // __NEURUN_BACKEND_ACL_NEON_MEMORY_MANAGER_H__
+#endif // __NEURUN_BACKEND_ACL_NEON_TENSOR_MANAGER_H__
index 87e81bd..cf91e5e 100644 (file)
@@ -53,7 +53,7 @@ namespace backend
 namespace cpu
 {
 
-TensorBuilder::TensorBuilder() : _mem_mgr{new MemoryManager()}
+TensorBuilder::TensorBuilder() : _tensor_mgr{new TensorManager()}
 {
   // DO NOTHING
 }
@@ -61,11 +61,13 @@ TensorBuilder::TensorBuilder() : _mem_mgr{new MemoryManager()}
 void TensorBuilder::registerTensorInfo(const model::OperandIndex &ind,
                                        const model::OperandInfo &info,
                                        model::Layout frontend_layout, model::Layout backend_layout,
-                                       bool /*as_const*/)
+                                       bool as_const)
 {
-  // TODO Adding handling tensor as const
   _tensor_info_map.emplace(ind, info);
   _tensor_layouts_map.insert({ind, std::make_pair(frontend_layout, backend_layout)});
+
+  if (as_const)
+    _constants.append(ind);
 }
 
 void TensorBuilder::registerSubTensorInfo(const model::OperandIndex &,
@@ -79,49 +81,59 @@ void TensorBuilder::notifyFirstUse(const model::OperandIndex &ind)
 {
   assert(_tensor_info_map.find(ind) != _tensor_info_map.end());
   const auto tensor_info = asTensorInfo(_tensor_info_map.at(ind), _tensor_layouts_map[ind].first);
-  _mem_mgr->buildTensor(ind, tensor_info);
-
   const auto size = tensor_info.total_size();
-  _mem_mgr->claimPlan(ind, size);
+  _tensor_mgr->buildTensor(ind, tensor_info, _constants.contains(ind));
+  _tensor_mgr->claimPlan(ind, size);
 }
 
-void TensorBuilder::notifyLastUse(const model::OperandIndex &ind) { _mem_mgr->releasePlan(ind); }
+void TensorBuilder::notifyLastUse(const model::OperandIndex &ind) { _tensor_mgr->releasePlan(ind); }
 
-void TensorBuilder::prepare(void) { _mem_mgr->allocate(); }
+void TensorBuilder::prepare(void)
+{
+  _tensor_mgr->allocateConsts();
+  _tensor_mgr->allocateNonconsts();
+}
 
+// TODO Remove this
 void TensorBuilder::allocate(void)
 {
   // NOTE For now nothing to do. Allocation is done in prepare stage, which is not appropriate
   //      This is because CPU kernels require `ITensor`s to be allocated before Kernel Generation.
 }
 
+void TensorBuilder::allocateConsts()
+{
+  // NOTE For now nothing to do. Allocation is done in prepare stage, which is not appropriate
+  //      This is because CPU kernels require `ITensor`s to be allocated before Kernel Generation.
+}
+
+void TensorBuilder::allocateNonconsts()
+{
+  // NOTE For now nothing to do. Allocation is done in prepare stage, which is not appropriate
+  //      This is because CPU kernels require `ITensor`s to be allocated before Kernel Generation.
+}
+
 std::shared_ptr<::neurun::backend::operand::ITensor>
 TensorBuilder::tensorAt(const model::OperandIndex &ind)
 {
-  return _mem_mgr->tensors().at(ind);
+  return _tensor_mgr->at(ind);
 }
 
 std::shared_ptr<backend::operand::IObject> TensorBuilder::wrapTensor(const model::OperandIndex &ind)
 {
-  return _mem_mgr->wrapTensor(ind);
+  return _tensor_mgr->wrapTensor(ind);
 }
 
-void TensorBuilder::iterate(const IterateFunction &fn)
-{
-  for (auto it : _mem_mgr->tensors())
-  {
-    fn(it.first);
-  }
-}
+void TensorBuilder::iterate(const IterateFunction &fn) { _tensor_mgr->iterate(fn); }
 
 std::shared_ptr<operand::Tensor> TensorBuilder::at(const ::neurun::model::OperandIndex &ind)
 {
-  return _mem_mgr->tensors().at(ind);
+  return _tensor_mgr->at(ind);
 }
 
-std::unique_ptr<IMemoryManager> TensorBuilder::releaseMemoryManager(void)
+std::unique_ptr<ITensorManager> TensorBuilder::releaseTensorManager(void)
 {
-  return std::move(_mem_mgr);
+  return std::move(_tensor_mgr);
 }
 
 } // namespace cpu
index 5bcbb6c..efafbd9 100644 (file)
@@ -23,7 +23,6 @@
 #include <backend/operand/Object.h>
 #include "operand/Tensor.h"
 #include "model/OperandIndexMap.h"
-#include "MemoryManager.h" // TODO Remove this
 #include "TensorManager.h"
 
 namespace neurun
@@ -56,18 +55,14 @@ public:
                              const compiler::SubTensorInfo &info) override;
 
   void notifyFirstUse(const model::OperandIndex &) override;
-
   void notifyLastUse(const model::OperandIndex &) override;
 
   void prepare(void) override;
-
-  void allocate(void) override;
-
-  // TODO Fill these
-  void allocateConsts() override {}
-  void allocateNonconsts() override {}
-  void postFunctionPrepare() override {}
-  void finalize() override {}
+  void allocate(void) override; // TODO Remove this
+  void allocateConsts() override;
+  void allocateNonconsts() override;
+  void postFunctionPrepare() override { /* DO NOTHING */}
+  void finalize() override { /* DO NOTHING */}
 
   std::shared_ptr<::neurun::backend::operand::ITensor>
   tensorAt(const model::OperandIndex &ind) override;
@@ -76,18 +71,18 @@ public:
 
   void iterate(const IterateFunction &fn) override;
 
-  void preVisit(const model::Operation &) override {}
-  void postVisit(const model::Operation &) override {}
+  void preVisit(const model::Operation &) override { /* DO NOTHING */}
+  void postVisit(const model::Operation &) override { /* DO NOTHING */}
 
-  std::unique_ptr<IMemoryManager> releaseMemoryManager(void) override;
+  std::unique_ptr<ITensorManager> releaseTensorManager(void) override;
 
   std::shared_ptr<operand::Tensor> at(const ::neurun::model::OperandIndex &ind);
 
 private:
-  // TODO Replace this by TensorManager
-  std::unique_ptr<MemoryManager> _mem_mgr;
+  std::unique_ptr<TensorManager> _tensor_mgr;
   model::OperandIndexMap<model::OperandInfo> _tensor_info_map;
   model::OperandIndexMap<std::pair<model::Layout, model::Layout>> _tensor_layouts_map;
+  model::OperandIndexSequence _constants;
 };
 
 } // namespace cpu
index 5816eda..52c11ad 100644 (file)
@@ -27,18 +27,22 @@ namespace backend
 namespace srcn
 {
 
-TensorBuilder::TensorBuilder() : _mem_mgr{new MemoryManager()}
+TensorBuilder::TensorBuilder() : _tensor_mgr{new TensorManager()}
 {
   // DO NOTHING
 }
 
 void TensorBuilder::registerTensorInfo(const model::OperandIndex &ind,
-                                       const model::OperandInfo &info, model::Layout, model::Layout,
-                                       bool /*as_const*/)
+                                       const model::OperandInfo &info,
+                                       model::Layout /*frontend_layout*/,
+                                       model::Layout /*backend_layout*/, bool as_const)
 {
-  // TODO Adding handling tensor as const
   _tensor_info_map.emplace(ind, info);
+
   // TODO set the layout
+
+  if (as_const)
+    _constants.append(ind);
 }
 
 void TensorBuilder::registerSubTensorInfo(const model::OperandIndex &,
@@ -52,49 +56,59 @@ void TensorBuilder::notifyFirstUse(const model::OperandIndex &ind)
 {
   assert(_tensor_info_map.find(ind) != _tensor_info_map.end());
   const auto &info = _tensor_info_map.at(ind);
-  _mem_mgr->buildTensor(ind, info);
-
   const auto size = info.total_size();
-  _mem_mgr->claimPlan(ind, size);
+  _tensor_mgr->buildTensor(ind, info, _constants.contains(ind));
+  _tensor_mgr->claimPlan(ind, size);
 }
 
-void TensorBuilder::notifyLastUse(const model::OperandIndex &ind) { _mem_mgr->releasePlan(ind); }
+void TensorBuilder::notifyLastUse(const model::OperandIndex &ind) { _tensor_mgr->releasePlan(ind); }
 
-void TensorBuilder::prepare(void) { _mem_mgr->allocate(); }
+void TensorBuilder::prepare(void)
+{
+  _tensor_mgr->allocateConsts();
+  _tensor_mgr->allocateNonconsts();
+}
 
+// TODO Remove this
 void TensorBuilder::allocate(void)
 {
   // NOTE For now nothing to do. Allocation is done in prepare stage, which is not appropriate
-  //      This is because CPU kernels require `ITensor`s to be allocated before Kernel Generation.
+  //      This is because SRCN kernels require `ITensor`s to be allocated before Kernel Generation.
+}
+
+void TensorBuilder::allocateConsts()
+{
+  // NOTE For now nothing to do. Allocation is done in prepare stage, which is not appropriate
+  //      This is because SRCN kernels require `ITensor`s to be allocated before Kernel Generation.
+}
+
+void TensorBuilder::allocateNonconsts()
+{
+  // NOTE For now nothing to do. Allocation is done in prepare stage, which is not appropriate
+  //      This is because SRCN kernels require `ITensor`s to be allocated before Kernel Generation.
 }
 
 std::shared_ptr<::neurun::backend::operand::ITensor>
 TensorBuilder::tensorAt(const model::OperandIndex &ind)
 {
-  return _mem_mgr->tensors().at(ind);
+  return _tensor_mgr->at(ind);
 }
 
 std::shared_ptr<backend::operand::IObject> TensorBuilder::wrapTensor(const model::OperandIndex &ind)
 {
-  return _mem_mgr->wrapTensor(ind);
+  return _tensor_mgr->wrapTensor(ind);
 }
 
-void TensorBuilder::iterate(const IterateFunction &fn)
-{
-  for (auto it : _mem_mgr->tensors())
-  {
-    fn(it.first);
-  }
-}
+void TensorBuilder::iterate(const IterateFunction &fn) { _tensor_mgr->iterate(fn); }
 
 std::shared_ptr<operand::Tensor> TensorBuilder::at(const ::neurun::model::OperandIndex &ind)
 {
-  return _mem_mgr->tensors().at(ind);
+  return _tensor_mgr->at(ind);
 }
 
-std::unique_ptr<IMemoryManager> TensorBuilder::releaseMemoryManager(void)
+std::unique_ptr<ITensorManager> TensorBuilder::releaseTensorManager(void)
 {
-  return std::move(_mem_mgr);
+  return std::move(_tensor_mgr);
 }
 
 } // namespace srcn
index 2edce47..98b45b6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -23,7 +23,7 @@
 #include <backend/operand/Object.h>
 #include "operand/Tensor.h"
 #include "model/OperandIndexMap.h"
-#include "MemoryManager.h"
+#include "TensorManager.h"
 
 namespace neurun
 {
@@ -55,18 +55,14 @@ public:
                              const compiler::SubTensorInfo &info) override;
 
   void notifyFirstUse(const model::OperandIndex &) override;
-
   void notifyLastUse(const model::OperandIndex &) override;
 
   void prepare(void) override;
-
-  void allocate(void) override;
-
-  // TODO Fill these
-  void allocateConsts() override {}
-  void allocateNonconsts() override {}
-  void postFunctionPrepare() override {}
-  void finalize() override {}
+  void allocate(void) override; // TODO Remove this
+  void allocateConsts() override;
+  void allocateNonconsts() override;
+  void postFunctionPrepare() override { /* DO NOTHING */}
+  void finalize() override { /* DO NOTHING */}
 
   std::shared_ptr<::neurun::backend::operand::ITensor>
   tensorAt(const model::OperandIndex &ind) override;
@@ -75,16 +71,18 @@ public:
 
   void iterate(const IterateFunction &fn) override;
 
-  void preVisit(const model::Operation &) override {}
-  void postVisit(const model::Operation &) override {}
+  void preVisit(const model::Operation &) override { /* DO NOTHING */}
+  void postVisit(const model::Operation &) override { /* DO NOTHING */}
 
-  std::unique_ptr<IMemoryManager> releaseMemoryManager(void) override;
+  std::unique_ptr<ITensorManager> releaseTensorManager(void) override;
 
   std::shared_ptr<operand::Tensor> at(const ::neurun::model::OperandIndex &ind);
 
 private:
-  std::unique_ptr<MemoryManager> _mem_mgr;
+  std::unique_ptr<TensorManager> _tensor_mgr;
   model::OperandIndexMap<model::OperandInfo> _tensor_info_map;
+  model::OperandIndexMap<std::pair<model::Layout, model::Layout>> _tensor_layouts_map;
+  model::OperandIndexSequence _constants;
 };
 
 } // namespace srcn
diff --git a/runtimes/neurun/backend/srcn/TensorManager.cc b/runtimes/neurun/backend/srcn/TensorManager.cc
new file mode 100644 (file)
index 0000000..d0c8027
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "TensorManager.h"
+
+namespace neurun
+{
+namespace backend
+{
+namespace srcn
+{
+
+TensorManager::TensorManager() : _const_mgr{new MemoryManager()}, _nonconst_mgr{new MemoryManager()}
+{
+  // DO NOTHING
+}
+
+void TensorManager::allocateConsts(void) { _const_mgr->allocate(); }
+
+void TensorManager::allocateNonconsts(void) { _nonconst_mgr->allocate(); }
+
+void TensorManager::deallocateConsts(void) { _const_mgr->deallocate(); }
+
+void TensorManager::deallocateNonconsts(void) { _nonconst_mgr->deallocate(); }
+
+void TensorManager::buildTensor(const model::OperandIndex &ind,
+                                const model::OperandInfo &tensor_info, bool as_const)
+{
+  assert(_ind_to_mgr.find(ind) == _ind_to_mgr.end());
+  if (as_const)
+  {
+    _const_mgr->buildTensor(ind, tensor_info);
+    _ind_to_mgr.insert({ind, *_const_mgr});
+  }
+  else
+  {
+    _nonconst_mgr->buildTensor(ind, tensor_info);
+    _ind_to_mgr.insert({ind, *_nonconst_mgr});
+  }
+}
+
+void TensorManager::claimPlan(const model::OperandIndex &ind, uint32_t size)
+{
+  assert(_ind_to_mgr.find(ind) != _ind_to_mgr.end());
+  _ind_to_mgr.at(ind).claimPlan(ind, size);
+}
+
+void TensorManager::releasePlan(const model::OperandIndex &ind)
+{
+  assert(_ind_to_mgr.find(ind) != _ind_to_mgr.end());
+  _ind_to_mgr.at(ind).releasePlan(ind);
+}
+
+std::shared_ptr<backend::operand::IObject> TensorManager::wrapTensor(const model::OperandIndex &ind)
+{
+  assert(_ind_to_mgr.find(ind) != _ind_to_mgr.end());
+  return _ind_to_mgr.at(ind).wrapTensor(ind);
+}
+
+std::shared_ptr<operand::Tensor> TensorManager::at(const ::neurun::model::OperandIndex &ind)
+{
+  assert(_ind_to_mgr.find(ind) != _ind_to_mgr.end());
+  return _ind_to_mgr.at(ind).tensors().at(ind);
+}
+
+model::OperandIndexMap<std::shared_ptr<operand::Tensor>> &TensorManager::constTensors(void)
+{
+  return _const_mgr->tensors();
+}
+
+model::OperandIndexMap<std::shared_ptr<operand::Tensor>> &TensorManager::nonconstTensors(void)
+{
+  return _nonconst_mgr->tensors();
+}
+
+void TensorManager::iterate(const std::function<void(const model::OperandIndex &)> &fn)
+{
+  for (auto it : _nonconst_mgr->tensors())
+    fn(it.first);
+
+  for (auto it : _const_mgr->tensors())
+    fn(it.first);
+}
+
+} // namespace srcn
+} // namespace backend
+} // namespace neurun
diff --git a/runtimes/neurun/backend/srcn/TensorManager.h b/runtimes/neurun/backend/srcn/TensorManager.h
new file mode 100644 (file)
index 0000000..61a10d2
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __NEURUN_BACKEND_SRCN_TENSOR_MANAGER_H__
+#define __NEURUN_BACKEND_SRCN_TENSOR_MANAGER_H__
+
+#include "backend/ITensorManager.h"
+#include "MemoryManager.h"
+#include "model/OperandIndexMap.h"
+
+namespace neurun
+{
+namespace backend
+{
+namespace srcn
+{
+
+class TensorManager : public backend::ITensorManager
+{
+public:
+  TensorManager();
+  virtual ~TensorManager() = default;
+
+  void allocateConsts(void) override;
+  void allocateNonconsts(void) override;
+  void deallocateConsts(void) override;
+  void deallocateNonconsts(void) override;
+
+  void buildTensor(const model::OperandIndex &ind, const model::OperandInfo &tensor_info,
+                   bool as_const);
+
+  void claimPlan(const model::OperandIndex &ind, uint32_t size);
+  void releasePlan(const model::OperandIndex &ind);
+
+  std::shared_ptr<backend::operand::IObject> wrapTensor(const model::OperandIndex &ind);
+  std::shared_ptr<operand::Tensor> at(const ::neurun::model::OperandIndex &ind);
+
+  model::OperandIndexMap<std::shared_ptr<operand::Tensor>> &constTensors(void);
+  model::OperandIndexMap<std::shared_ptr<operand::Tensor>> &nonconstTensors(void);
+
+  void iterate(const std::function<void(const model::OperandIndex &)> &fn);
+
+private:
+  std::unique_ptr<MemoryManager> _const_mgr;
+  std::unique_ptr<MemoryManager> _nonconst_mgr;
+  model::OperandIndexMap<MemoryManager &> _ind_to_mgr;
+};
+
+} // namespace srcn
+} // namespace backend
+} // namespace neurun
+
+#endif // __NEURUN_BACKEND_SRCN_TENSOR_MANAGER_H__
index 3735d54..72079a2 100644 (file)
@@ -26,7 +26,7 @@
 #include "operand/IObject.h"
 #include "operand/ITensor.h"
 #include "compiler/SubTensorInfo.h"
-#include "IMemoryManager.h"
+#include "ITensorManager.h"
 
 namespace neurun
 {
@@ -72,7 +72,7 @@ struct ITensorBuilder
   virtual void preVisit(const model::Operation &) = 0;
   virtual void postVisit(const model::Operation &) = 0;
 
-  virtual std::unique_ptr<IMemoryManager> releaseMemoryManager(void) = 0;
+  virtual std::unique_ptr<ITensorManager> releaseTensorManager(void) = 0;
 };
 
 } // namespace backend
index 43fafe7..74506ef 100644 (file)
@@ -22,7 +22,8 @@ namespace neurun
 namespace backend
 {
 
-// TODO Replace existing MemoryManager which TensorBuilder uses by this
+// NOTE This name ITensorManager has been discussed whether or not the name is proper.
+// Anyone can argue with any better name.
 /**
  * @brief Interface as an abstract tensor manager which has MemoryManager
  */
index 8c562c6..2ff32a5 100644 (file)
@@ -110,12 +110,6 @@ exec::IExecutor *ExecutorFactory::createLinearExecutor(graph::Graph &graph)
   for (auto &tensor_builder : tensor_builders)
   {
     tensor_builder->prepare();
-
-    // Wrap tensors as Object and store them to plan
-    tensor_builder->iterate([&](const model::OperandIndex &index) {
-      auto object = tensor_builder->wrapTensor(index);
-      operand_context->set(index, object);
-    });
   }
 
   // Generate initializers
@@ -162,16 +156,31 @@ exec::IExecutor *ExecutorFactory::createLinearExecutor(graph::Graph &graph)
     linear->getBackendContext(backend)->constant_initializer->run();
   }
 
-  // Prepare each MemoryManager on each backend
-  auto mem_mgrs = nnfw::cpp14::make_unique<backend::MemoryManagerSet>();
   for (auto &tensor_builder : tensor_builders)
   {
-    mem_mgrs->insert(tensor_builder->releaseMemoryManager());
+    tensor_builder->finalize();
+  }
+
+  // Wrap tensors as Object and store them to plan
+  for (auto &tensor_builder : tensor_builders)
+  {
+    tensor_builder->iterate([&](const model::OperandIndex &index) {
+      auto object = tensor_builder->wrapTensor(index);
+      operand_context->set(index, object);
+    });
+  }
+
+  // Prepare each TensorManager on each backend
+  auto tensor_mgrs = nnfw::cpp14::make_unique<backend::TensorManagerSet>();
+  for (auto &tensor_builder : tensor_builders)
+  {
+    tensor_mgrs->insert(tensor_builder->releaseTensorManager());
   }
 
-  return new exec::LinearExecutor{
-      graph.shareModel(),  linear->releaseSubgraphs(), operand_context,  linear->releaseLowerInfo(),
-      std::move(mem_mgrs), linear->releaseElements(),  function_sequence};
+  return new exec::LinearExecutor{graph.shareModel(),     linear->releaseSubgraphs(),
+                                  operand_context,        linear->releaseLowerInfo(),
+                                  std::move(tensor_mgrs), linear->releaseElements(),
+                                  function_sequence};
 }
 
 exec::IExecutor *ExecutorFactory::createDataflowExecutor(graph::Graph &graph, bool parallel)
@@ -227,7 +236,8 @@ exec::IExecutor *ExecutorFactory::createDataflowExecutor(graph::Graph &graph, bo
           frontend_layout = graph.subgraphs().at(graph.subgraphs().getOperation(use)).getLayout();
         }
         const auto backend_layout = lower_info->def_factors().getOnlyElement().layout();
-        tensor_builder->registerTensorInfo(ind, info, frontend_layout, backend_layout, false);
+        tensor_builder->registerTensorInfo(ind, info, frontend_layout, backend_layout,
+                                           obj.isConstant());
         // To make this never be deallocated, this is a workaround to use static memory planner
         tensor_builder->notifyFirstUse(ind);
       }
@@ -239,12 +249,6 @@ exec::IExecutor *ExecutorFactory::createDataflowExecutor(graph::Graph &graph, bo
   for (auto &tensor_builder : tensor_builders)
   {
     tensor_builder->prepare();
-
-    // Wrap tensors as Object and store them to plan
-    tensor_builder->iterate([&](const model::OperandIndex &index) {
-      auto object = tensor_builder->wrapTensor(index);
-      operand_context->set(index, object);
-    });
   }
 
   class ExecutionBuilder : public IExecutionBuilder
@@ -298,26 +302,40 @@ exec::IExecutor *ExecutorFactory::createDataflowExecutor(graph::Graph &graph, bo
 
   auto lower_info = graph.releaseLowerInfo();
 
-  // Prepare each MemoryManager on each backend
-  auto mem_mgrs = nnfw::cpp14::make_unique<backend::MemoryManagerSet>();
   for (auto &tensor_builder : tensor_builders)
   {
-    mem_mgrs->insert(tensor_builder->releaseMemoryManager());
+    tensor_builder->finalize();
+  }
+
+  // Wrap tensors as Object and store them to plan
+  for (auto &tensor_builder : tensor_builders)
+  {
+    tensor_builder->iterate([&](const model::OperandIndex &index) {
+      auto object = tensor_builder->wrapTensor(index);
+      operand_context->set(index, object);
+    });
+  }
+
+  // Prepare each TensorManager on each backend
+  auto tensor_mgrs = nnfw::cpp14::make_unique<backend::TensorManagerSet>();
+  for (auto &tensor_builder : tensor_builders)
+  {
+    tensor_mgrs->insert(tensor_builder->releaseTensorManager());
   }
 
   if (parallel)
   {
     return new exec::ParallelExecutor{
-        graph.shareModel(),  graph.releaseSubgraphs(),
-        operand_context,     std::move(lower_info),
-        std::move(mem_mgrs), std::move(execution_builder->releaseCodeMap())};
+        graph.shareModel(),     graph.releaseSubgraphs(),
+        operand_context,        std::move(lower_info),
+        std::move(tensor_mgrs), std::move(execution_builder->releaseCodeMap())};
   }
   else
   {
     auto exec = new exec::DataflowExecutor{
-        graph.shareModel(),  graph.releaseSubgraphs(),
-        operand_context,     std::move(lower_info),
-        std::move(mem_mgrs), std::move(execution_builder->releaseCodeMap())};
+        graph.shareModel(),     graph.releaseSubgraphs(),
+        operand_context,        std::move(lower_info),
+        std::move(tensor_mgrs), std::move(execution_builder->releaseCodeMap())};
     if (util::getConfigBool(util::config::PROFILING_MODE))
     {
       auto et = std::make_shared<backend::ExecTime>(backend::BackendManager::instance().getAll());
index 059d0d2..72d0fdb 100644 (file)
@@ -182,7 +182,8 @@ void Linear::planTensors()
     uses_map[ind] = obj.getUses().size();
     def_map[ind] = obj.getDef().size(); // should be 1 or 0
 
-    if (obj.isConstant())
+    bool is_const = obj.isConstant();
+    if (is_const)
     {
       constants.append(ind);
     }
@@ -221,7 +222,7 @@ void Linear::planTensors()
           frontend_layout = _subgraphs->at(_subgraphs->getOperation(use)).getLayout();
         }
         const auto backend_layout = lower_info->def_factors().getOnlyElement().layout();
-        tensor_builder->registerTensorInfo(ind, info, frontend_layout, backend_layout, false);
+        tensor_builder->registerTensorInfo(ind, info, frontend_layout, backend_layout, is_const);
       }
 
       tensor_builder_map[ind] = tensor_builder;
index a7f22c4..75d6161 100644 (file)
@@ -80,10 +80,10 @@ DataflowExecutor::DataflowExecutor(const std::shared_ptr<const model::Model> &mo
                                    std::unique_ptr<model::Subgraphs> subgraphs,
                                    const std::shared_ptr<compiler::OperandContext> &operand_context,
                                    std::unique_ptr<graph::LowerInfoMap> lower_info,
-                                   std::unique_ptr<backend::MemoryManagerSet> mem_mgrs,
+                                   std::unique_ptr<backend::TensorManagerSet> tensor_mgrs,
                                    CodeMap &&code_map)
     : ExecutorBase{model, std::move(subgraphs), operand_context, std::move(lower_info),
-                   std::move(mem_mgrs)},
+                   std::move(tensor_mgrs)},
       _code_map{std::move(code_map)}
 {
   VERBOSE(DataflowExecutor) << "Constructing Dataflow Executor" << std::endl;
index 1e5f05c..935f997 100644 (file)
@@ -57,7 +57,7 @@ public:
                    std::unique_ptr<model::Subgraphs> subgraphs,
                    const std::shared_ptr<compiler::OperandContext> &operand_context,
                    std::unique_ptr<graph::LowerInfoMap> lower_info,
-                   std::unique_ptr<backend::MemoryManagerSet> mem_mgrs, CodeMap &&code_map);
+                   std::unique_ptr<backend::TensorManagerSet> tensor_mgrs, CodeMap &&code_map);
 
   void executeImpl() override;
 
index 8590387..827d4dc 100644 (file)
@@ -25,10 +25,10 @@ ExecutorBase::ExecutorBase(const std::shared_ptr<const model::Model> &model,
                            std::unique_ptr<model::Subgraphs> subgraphs,
                            const std::shared_ptr<compiler::OperandContext> &operand_context,
                            std::unique_ptr<graph::LowerInfoMap> lower_info,
-                           std::unique_ptr<backend::MemoryManagerSet> mem_mgrs)
+                           std::unique_ptr<backend::TensorManagerSet> tensor_mgrs)
     : _observers(), _model{model}, _subgraphs{std::move(subgraphs)},
       _operand_context{operand_context}, _lower_info{std::move(lower_info)},
-      _mem_mgrs{std::move(mem_mgrs)}, _mutex()
+      _tensor_mgrs{std::move(tensor_mgrs)}, _mutex()
 {
   // DO NOTHING
 }
index ef66111..c283e7f 100644 (file)
@@ -33,7 +33,7 @@
 #include "model/Subgraph.h"
 #include "backend/ExecTime.h"
 #include "exec/IFunction.h"
-#include "backend/IMemoryManager.h"
+#include "backend/ITensorManager.h"
 #include <list>
 
 namespace neurun
@@ -48,7 +48,7 @@ public:
                std::unique_ptr<model::Subgraphs> subgraphs,
                const std::shared_ptr<compiler::OperandContext> &operand_context,
                std::unique_ptr<graph::LowerInfoMap> lower_info,
-               std::unique_ptr<backend::MemoryManagerSet> mem_mgrs);
+               std::unique_ptr<backend::TensorManagerSet> tensor_mgrs);
 
   virtual ~ExecutorBase() = default;
 
@@ -114,7 +114,7 @@ protected:
   std::unique_ptr<model::Subgraphs> _subgraphs;
   std::shared_ptr<compiler::OperandContext> _operand_context;
   std::unique_ptr<graph::LowerInfoMap> _lower_info;
-  std::unique_ptr<backend::MemoryManagerSet> _mem_mgrs;
+  std::unique_ptr<backend::TensorManagerSet> _tensor_mgrs;
   std::mutex _mutex;
 };
 
index 25fdad8..58c1ea9 100644 (file)
@@ -46,11 +46,11 @@ public:
                  std::unique_ptr<model::Subgraphs> subgraphs,
                  const std::shared_ptr<compiler::OperandContext> &operand_context,
                  std::unique_ptr<graph::LowerInfoMap> lower_info,
-                 std::unique_ptr<backend::MemoryManagerSet> mem_mgrs,
+                 std::unique_ptr<backend::TensorManagerSet> tensor_mgrs,
                  std::vector<compiler::Linear::Element> &&elements,
                  const std::shared_ptr<exec::FunctionSequence> &fn_seq)
       : ExecutorBase{model, std::move(subgraphs), operand_context, std::move(lower_info),
-                     std::move(mem_mgrs)},
+                     std::move(tensor_mgrs)},
         _fn_seq{fn_seq}, _elements{std::move(elements)}
   {
   }
index e26caf0..81d4ac0 100644 (file)
@@ -59,13 +59,13 @@ ParallelExecutor::ParallelExecutor(const std::shared_ptr<const model::Model> &mo
                                    std::unique_ptr<model::Subgraphs> subgraphs,
                                    const std::shared_ptr<compiler::OperandContext> &operand_context,
                                    std::unique_ptr<graph::LowerInfoMap> lower_info,
-                                   std::unique_ptr<backend::MemoryManagerSet> mem_mgrs,
+                                   std::unique_ptr<backend::TensorManagerSet> tensor_mgrs,
                                    CodeMap &&code_map)
     : DataflowExecutor{model,
                        std::move(subgraphs),
                        operand_context,
                        std::move(lower_info),
-                       std::move(mem_mgrs),
+                       std::move(tensor_mgrs),
                        std::move(code_map)}
 {
   VERBOSE(ParallelExecutor) << "Constructing Parallel Executor" << std::endl;
index ff86bc5..7a4673b 100644 (file)
@@ -57,7 +57,7 @@ public:
                    std::unique_ptr<model::Subgraphs> subgraphs,
                    const std::shared_ptr<compiler::OperandContext> &operand_context,
                    std::unique_ptr<graph::LowerInfoMap> lower_info,
-                   std::unique_ptr<backend::MemoryManagerSet> mem_mgrs, CodeMap &&code_map);
+                   std::unique_ptr<backend::TensorManagerSet> tensor_mgrs, CodeMap &&code_map);
 
   void executeImpl() override;