From 10e500b38717b7250f504608dc8b75fd0bf0ad6e Mon Sep 17 00:00:00 2001 From: Jihoon Lee Date: Tue, 9 Nov 2021 15:12:41 +0900 Subject: [PATCH] [Tp] requestPreallocated -> view This patch rename requestPreallocated to view **Self evaluation:** 1. Build test: [X]Passed [ ]Failed [ ]Skipped 2. Run test: [X]Passed [ ]Failed [ ]Skipped Signed-off-by: Jihoon Lee --- nntrainer/tensor/manager.cpp | 76 +++++++----------------- nntrainer/tensor/tensor_pool.cpp | 28 +++------ nntrainer/tensor/tensor_pool.h | 28 --------- test/unittest/unittest_nntrainer_tensor_pool.cpp | 75 +++++++++-------------- 4 files changed, 59 insertions(+), 148 deletions(-) diff --git a/nntrainer/tensor/manager.cpp b/nntrainer/tensor/manager.cpp index c940a84..ee89a43 100644 --- a/nntrainer/tensor/manager.cpp +++ b/nntrainer/tensor/manager.cpp @@ -41,10 +41,7 @@ namespace nntrainer { MMapedMemory::MMapedMemory(size_t size, bool allocate_fd_) : - fd(-1), - buf(nullptr), - buf_size(0), - allocate_fd(allocate_fd_) { + fd(-1), buf(nullptr), buf_size(0), allocate_fd(allocate_fd_) { #ifndef __ANDROID__ if (allocate_fd) { @@ -279,20 +276,12 @@ std::vector Manager::requestWeights( if (is_dependent) { const auto &shared_name = shared_names.at(i); /** case when shared names are given */ - var = weight_pool.requestPrerequestedTensor( - dim, var_exec_order, var_ls, - name, /// name - shared_name, /// shared name - t_initializer /// tensor initializer - ); + var = weight_pool.view(name, shared_name, dim, var_exec_order, var_ls); if (trainable && need_gradient) { - grad = tensor_pool.requestPrerequestedTensor( - dim, grad_exec_order, grad_ls, - name + Var_Grad::grad_suffix, /// name - shared_name + Var_Grad::grad_suffix, /// shared name - Tensor::Initializer::ZEROS /// tensor initializer - ); + grad = tensor_pool.view(name + Var_Grad::grad_suffix, + shared_name + Var_Grad::grad_suffix, dim, + grad_exec_order, grad_ls); } } else { @@ -356,16 +345,12 @@ Manager::requestTensors(const GraphNode &node, Tensor *var = nullptr, *grad = nullptr; if (is_dependent) { - [[maybe_unused]] const auto &shared_name = shared_names.at(i); - var = tensor_pool.requestPrerequestedTensor(dim, var_exec_order, tspan, - name, shared_name, t_init); + const auto &shared_name = shared_names.at(i); + var = tensor_pool.view(name, shared_name, dim, var_exec_order, tspan); if (need_grad && tspan > TensorLifespan::FORWARD_FUNC_LIFESPAN) { - grad = tensor_pool.requestPrerequestedTensor( - dim, grad_exec_order, tspan, - name + Var_Grad::grad_suffix, /// name - shared_name + Var_Grad::grad_suffix, - Tensor::Initializer::ZEROS /// tensor initializer - ); + grad = tensor_pool.view(name + Var_Grad::grad_suffix, + shared_name + Var_Grad::grad_suffix, dim, + grad_exec_order, tspan); } } else { @@ -423,21 +408,14 @@ Manager::requestInputs(const GraphNode &node, const std::string &var_name = node.getName() + std::string(":input") + std::to_string(idx); if (!outputs_name.empty()) { - var = tensor_pool.requestPrerequestedTensor( - dim, /// tensor dim - var_exec_order, var_ls, - var_name, /// name - outputs_name[idx], /// shared name - Tensor::Initializer::NONE /// tensor initializer - ); - - grad = tensor_pool.requestPrerequestedTensor( - dim, /// tensor dim - grad_exec_order, grad_ls, - var_name + Var_Grad::grad_suffix, /// name - outputs_name[idx] + Var_Grad::grad_suffix, /// shared name - Tensor::Initializer::ZEROS /// tensor initializer - ); + var = tensor_pool.view(var_name, /// name + outputs_name[idx], /// shared name + dim, var_exec_order, var_ls); + + grad = tensor_pool.view(var_name + Var_Grad::grad_suffix, + outputs_name[idx] + Var_Grad::grad_suffix, + dim, /// tensor dim + grad_exec_order, grad_ls); } else if (!node.getInputConnections().empty()) { var = tensor_pool.requestTensor( dim, /// tensor dim @@ -517,12 +495,8 @@ Manager::requestOutputs(const GraphNode &node, if (shared_var) { /** request shared tensor for variable */ - var = tensor_pool.requestPrerequestedTensor( - dim, /// tensor dim - var_exec_order, var_ls, var_name, - shared_name, /// name - Tensor::Initializer::NONE /// tensor initializer - ); + var = + tensor_pool.view(var_name, shared_name, dim, var_exec_order, var_ls); } else { /** request new tensor for variable */ var = tensor_pool.requestTensor( @@ -535,13 +509,9 @@ Manager::requestOutputs(const GraphNode &node, if (shared_grad) { /** request share tensor for gradient */ - grad = tensor_pool.requestPrerequestedTensor( - dim, /// tensor dim - grad_exec_order, grad_ls, - var_name + Var_Grad::grad_suffix, /// name - shared_name + Var_Grad::grad_suffix, /// shared name - Tensor::Initializer::ZEROS /// tensor initializer - ); + grad = tensor_pool.view(var_name + Var_Grad::grad_suffix, + shared_name + Var_Grad::grad_suffix, dim, + grad_exec_order, grad_ls); } else { /** request new tensor for gradient */ if (!node.getOutputConnections().empty()) { diff --git a/nntrainer/tensor/tensor_pool.cpp b/nntrainer/tensor/tensor_pool.cpp index 2202762..fffb24c 100644 --- a/nntrainer/tensor/tensor_pool.cpp +++ b/nntrainer/tensor/tensor_pool.cpp @@ -57,12 +57,11 @@ Tensor *TensorPool::placeholder(const std::string &name, const TensorDim &dim) { * @note we assume that the caller checks if the exec_order and lifespan are * compatible. */ -Tensor *TensorPool::requestPrerequestedTensor( - const TensorDim &dim, const std::vector &exec_order, - TensorLifespan lifespan, const std::string &name, - const std::string &shared_name, const Tensor::Initializer &init, - const unsigned int offset) { - auto &spec = getSourceSpec(shared_name); +Tensor *TensorPool::view(const std::string &name, const std::string &reference, + const TensorDim &dim, + const std::vector &exec_order, + TensorLifespan lifespan, const unsigned int offset) { + auto &spec = getSourceSpec(reference); unsigned adjusted_offset = std::visit( [](const auto &s) { using T = std::decay_t; @@ -73,7 +72,7 @@ Tensor *TensorPool::requestPrerequestedTensor( } return 0u; }, - pool[name_map.at(shared_name)].details); + pool[name_map.at(reference)].details); adjusted_offset += offset; NNTR_THROW_IF(spec.tensor->getDim().getDataLen() < @@ -84,10 +83,6 @@ Tensor *TensorPool::requestPrerequestedTensor( << " source tensor: " << spec.tensor->getDim().getDataLen() << " name: " << spec.tensor->getName(); - if (init != Tensor::Initializer::NONE && - spec.tensor->getInitializer() != init) - throw std::invalid_argument("Request tensor initialization mismatch"); - expandLifespan(spec, exec_order, lifespan); std::get(spec.details).dependents.push_back(pool.size()); @@ -96,7 +91,7 @@ Tensor *TensorPool::requestPrerequestedTensor( * view index, not view to view reference in order to flatten depth */ auto parent_idx = name_map.at(spec.tensor->getName()); return registerRequestSpec( - {std::make_unique(dim, false, init, name), + {std::make_unique(dim, false, Tensor::Initializer::NONE, name), TensorPool::DependentDetails{parent_idx, adjusted_offset}}); } @@ -300,15 +295,6 @@ Tensor *TensorPool::request(const std::string &name, const TensorDim &dim, return requestTensor(dim, exec_order, lifespan, name, init); } -Tensor *TensorPool::view(const std::string &name, const std::string &reference, - const TensorDim &dim, - const std::vector &exec_order, - TensorLifespan lifespan, const unsigned int offset) { - /// @todo rename requestPrerequestedTensor -> view - return requestPrerequestedTensor(dim, exec_order, lifespan, name, reference, - Tensor::Initializer::NONE, offset); -} - Tensor *TensorPool::extend(const std::string &name, const TensorDim &dim, const std::vector &exec_order, TensorLifespan lifespan) { diff --git a/nntrainer/tensor/tensor_pool.h b/nntrainer/tensor/tensor_pool.h index 60dad85..b7a374d 100644 --- a/nntrainer/tensor/tensor_pool.h +++ b/nntrainer/tensor/tensor_pool.h @@ -67,34 +67,6 @@ public: const Tensor::Initializer &init = Tensor::Initializer::NONE); /** - * @brief Request tensor which has been already requested with the given - * spec - * - * @param dim Tensor dimensions - * @param exec_order The execution orders for this tensors - * @param lifespan Lifespan of this tensor - * @param name Name of this tensor - * @param shared_name Name of the preallocated tensor - * @param init Initializer of the tensor - * @param offset byte based offset from shared_name - * - * @return ptr to the tensor - * - * @note returns empty tensor which will be filled when allocate is called. - * @note we assume that the caller checks if the exec_order and lifespan are - * compatible. - * - * @note This interface is separated from requestTensor to reduce bugs related - * to unintentional tensor sharing. - */ - Tensor *requestPrerequestedTensor( - const TensorDim &dim, const std::vector &exec_order, - TensorLifespan lifespan, const std::string &name, - const std::string &shared_name, - const Tensor::Initializer &init = Tensor::Initializer::NONE, - const unsigned int offset = 0); - - /** * @brief finalize the requested tensors * @param planner planner to layout the tensor memories * @param start_order start value for the order_exec (inclusive) diff --git a/test/unittest/unittest_nntrainer_tensor_pool.cpp b/test/unittest/unittest_nntrainer_tensor_pool.cpp index dd25d5d..6f99049 100644 --- a/test/unittest/unittest_nntrainer_tensor_pool.cpp +++ b/test/unittest/unittest_nntrainer_tensor_pool.cpp @@ -22,6 +22,7 @@ constexpr unsigned int MEM_BYTES = 128; constexpr unsigned int MEM_QUANT = 100; constexpr unsigned int INTERVAL_SIZE = 5; +constexpr static auto max_ls = nntrainer::TensorLifespan::MAX_LIFESPAN; /** * @brief creation and destruction @@ -92,9 +93,8 @@ TEST(TensorPool, request_mem_05_p) { EXPECT_NE(t1, nullptr); EXPECT_FALSE(t1->isAllocated()); - EXPECT_NO_THROW(t2 = pool.requestPrerequestedTensor( - nntrainer::TensorDim({1}), {}, - nntrainer::TensorLifespan::UNMANAGED, "abc1", "abc")); + EXPECT_NO_THROW(t2 = pool.view("abc1", "abc", nntrainer::TensorDim({1}), {}, + nntrainer::TensorLifespan::UNMANAGED)); EXPECT_NE(t2, nullptr); EXPECT_FALSE(t2->isAllocated()); @@ -102,7 +102,7 @@ TEST(TensorPool, request_mem_05_p) { } /** - * @brief request already allocated tensor + * @brief request bigger size for view */ TEST(TensorPool, request_mem_06_n) { nntrainer::TensorPool pool; @@ -111,14 +111,13 @@ TEST(TensorPool, request_mem_06_n) { nntrainer::TensorLifespan::UNMANAGED, "abc")); - EXPECT_THROW(pool.requestPrerequestedTensor( - nntrainer::TensorDim({2}), {}, - nntrainer::TensorLifespan::UNMANAGED, "abc1", "abc"), + EXPECT_THROW(pool.view("abc1", "abc", nntrainer::TensorDim({2}), {}, + nntrainer::TensorLifespan::UNMANAGED), std::invalid_argument); } /** - * @brief request already allocated tensor + * @brief request non existing tensor */ TEST(TensorPool, request_mem_07_n) { nntrainer::TensorPool pool; @@ -127,13 +126,12 @@ TEST(TensorPool, request_mem_07_n) { nntrainer::TensorLifespan::UNMANAGED, "abc")); - EXPECT_ANY_THROW(pool.requestPrerequestedTensor( - nntrainer::TensorDim({1}), {}, nntrainer::TensorLifespan::UNMANAGED, "abc1", - "not_exist")); + EXPECT_ANY_THROW(pool.view("abc1", "not_exist", nntrainer::TensorDim({1}), {}, + nntrainer::TensorLifespan::UNMANAGED)); } /** - * @brief request already allocated tensor + * @brief request try extending lifespan of unmanaged */ TEST(TensorPool, request_mem_08_p) { nntrainer::TensorPool pool; @@ -145,17 +143,15 @@ TEST(TensorPool, request_mem_08_p) { EXPECT_NE(t1, nullptr); EXPECT_FALSE(t1->isAllocated()); - EXPECT_NO_THROW(t2 = pool.requestPrerequestedTensor( - nntrainer::TensorDim({1}), {}, - nntrainer::TensorLifespan::MAX_LIFESPAN, "abc1", "abc")); + EXPECT_NO_THROW( + t2 = pool.view("abc1", "abc", nntrainer::TensorDim({1}), {}, max_ls)); EXPECT_NE(t2, nullptr); EXPECT_FALSE(t2->isAllocated()); EXPECT_NE(t1, t2); - EXPECT_NO_THROW(t2 = pool.requestPrerequestedTensor( - nntrainer::TensorDim({1}), {}, - nntrainer::TensorLifespan::MAX_LIFESPAN, "abc2", "abc")); + EXPECT_NO_THROW( + t2 = pool.view("abc2", "abc", nntrainer::TensorDim({1}), {}, max_ls)); EXPECT_NE(t2, nullptr); EXPECT_FALSE(t2->isAllocated()); @@ -163,7 +159,7 @@ TEST(TensorPool, request_mem_08_p) { } /** - * @brief request already allocated tensor + * @brief request clashing name */ TEST(TensorPool, request_mem_09_n) { nntrainer::TensorPool pool; @@ -172,9 +168,8 @@ TEST(TensorPool, request_mem_09_n) { nntrainer::TensorLifespan::UNMANAGED, "abc")); - EXPECT_THROW(pool.requestPrerequestedTensor( - nntrainer::TensorDim({1}), {}, - nntrainer::TensorLifespan::UNMANAGED, "abc", "abc"), + EXPECT_THROW(pool.view("abc", "abc", nntrainer::TensorDim({1}), {}, + nntrainer::TensorLifespan::UNMANAGED), std::invalid_argument); } @@ -227,8 +222,7 @@ TEST(TensorPool, finalize_01_p) { EXPECT_FALSE(t1->isAllocated()); EXPECT_NO_THROW( - t2 = pool.requestTensor(nntrainer::TensorDim({1}), {}, - nntrainer::TensorLifespan::MAX_LIFESPAN, "abc2")); + t2 = pool.requestTensor(nntrainer::TensorDim({1}), {}, max_ls, "abc2")); EXPECT_NE(t2, nullptr); EXPECT_FALSE(t2->isAllocated()); @@ -249,15 +243,13 @@ TEST(TensorPool, finalize_02_p) { nntrainer::Tensor *t1, *t2; EXPECT_NO_THROW( - t1 = pool.requestTensor(nntrainer::TensorDim({1}), {0}, - nntrainer::TensorLifespan::MAX_LIFESPAN, "abc1")); + t1 = pool.requestTensor(nntrainer::TensorDim({1}), {0}, max_ls, "abc1")); EXPECT_NE(t1, nullptr); EXPECT_FALSE(t1->isAllocated()); EXPECT_NO_THROW( - t2 = pool.requestTensor(nntrainer::TensorDim({1}), {1}, - nntrainer::TensorLifespan::MAX_LIFESPAN, "abc2")); + t2 = pool.requestTensor(nntrainer::TensorDim({1}), {1}, max_ls, "abc2")); EXPECT_NE(t2, nullptr); EXPECT_FALSE(t2->isAllocated()); @@ -288,14 +280,12 @@ TEST(TensorPool, allocate_deallocate_01_p) { nntrainer::Tensor *t1, *t2; EXPECT_NO_THROW( - t1 = pool.requestTensor(nntrainer::TensorDim({1}), {0}, - nntrainer::TensorLifespan::MAX_LIFESPAN, "abc1")); + t1 = pool.requestTensor(nntrainer::TensorDim({1}), {0}, max_ls, "abc1")); EXPECT_NE(t1, nullptr); EXPECT_FALSE(t1->isAllocated()); EXPECT_NO_THROW( - t2 = pool.requestTensor(nntrainer::TensorDim({1}), {1}, - nntrainer::TensorLifespan::MAX_LIFESPAN, "abc2")); + t2 = pool.requestTensor(nntrainer::TensorDim({1}), {1}, max_ls, "abc2")); EXPECT_NE(t2, nullptr); EXPECT_FALSE(t2->isAllocated()); @@ -331,22 +321,19 @@ TEST(TensorPool, allocate_deallocate_03_p) { nntrainer::Tensor *t1, *t2, *t3; EXPECT_NO_THROW( - t1 = pool.requestTensor(nntrainer::TensorDim({1}), {0}, - nntrainer::TensorLifespan::MAX_LIFESPAN, "abc")); + t1 = pool.requestTensor(nntrainer::TensorDim({1}), {0}, max_ls, "abc")); EXPECT_NE(t1, nullptr); EXPECT_FALSE(t1->isAllocated()); - EXPECT_NO_THROW(t2 = pool.requestPrerequestedTensor( - nntrainer::TensorDim({1}), {1}, - nntrainer::TensorLifespan::MAX_LIFESPAN, "abc1", "abc")); + EXPECT_NO_THROW( + t2 = pool.view("abc1", "abc", nntrainer::TensorDim({1}), {1}, max_ls)); EXPECT_NE(t2, nullptr); EXPECT_FALSE(t2->isAllocated()); EXPECT_NE(t1, t2); - EXPECT_NO_THROW(t3 = pool.requestPrerequestedTensor( - nntrainer::TensorDim({1}), {0}, - nntrainer::TensorLifespan::MAX_LIFESPAN, "abc2", "abc")); + EXPECT_NO_THROW( + t3 = pool.view("abc2", "abc", nntrainer::TensorDim({1}), {0}, max_ls)); EXPECT_NE(t3, nullptr); EXPECT_FALSE(t3->isAllocated()); @@ -376,12 +363,10 @@ TEST(TensorPool, validate_memory) { nntrainer::Tensor *t1 = nullptr, *t2 = nullptr; EXPECT_NO_THROW( - t1 = pool.requestTensor(nntrainer::TensorDim({100}), {0}, - nntrainer::TensorLifespan::MAX_LIFESPAN, "abc1")); + t1 = pool.requestTensor(nntrainer::TensorDim({100}), {0}, max_ls, "abc1")); EXPECT_NO_THROW( - t2 = pool.requestTensor(nntrainer::TensorDim({100}), {1}, - nntrainer::TensorLifespan::MAX_LIFESPAN, "abc2")); + t2 = pool.requestTensor(nntrainer::TensorDim({100}), {1}, max_ls, "abc2")); EXPECT_NO_THROW(pool.finalize(nntrainer::BasicPlanner(), 0, 2)); EXPECT_NO_THROW(pool.allocate()); @@ -438,8 +423,6 @@ static void testSubset(nntrainer::Tensor *t1, nntrainer::Tensor *t2) { << "t2 is not subset of t1"; } -static auto max_ls = nntrainer::TensorLifespan::MAX_LIFESPAN; - TEST(TensorPool, create_allocate_has_data_p) { nntrainer::TensorPool pool; nntrainer::Tensor *t1 = nullptr, *t2 = nullptr; -- 2.7.4