From: Jihoon Lee Date: Thu, 13 Jan 2022 15:25:50 +0000 (+0900) Subject: [Debug] Add a naive validator to the optimized planner X-Git-Tag: accepted/tizen/unified/20220323.062643~37 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=06d4c5b4282e70233c99a9ccfc18f0c3f69302a6;p=platform%2Fcore%2Fml%2Fnntrainer.git [Debug] Add a naive validator to the optimized planner This patch add a naive validator to the optimized planner. This doubles the memory consumption. So kept commented but when time comes, this function can be enabled. **Self evaluation:** 1. Build test: [X]Passed [ ]Failed [ ]Skipped 2. Run test: [X]Passed [ ]Failed [ ]Skipped Signed-off-by: Jihoon Lee --- diff --git a/nntrainer/tensor/optimized_v1_planner.cpp b/nntrainer/tensor/optimized_v1_planner.cpp index 8dfff2f..f297e61 100644 --- a/nntrainer/tensor/optimized_v1_planner.cpp +++ b/nntrainer/tensor/optimized_v1_planner.cpp @@ -12,6 +12,9 @@ */ #include +#include +#include +#include #include #include @@ -43,6 +46,69 @@ struct MemoryRequest { }; /** + * @brief check if validate interval is overlapping in a very naive way. + * + * @param memory_validity validity + * @param memory_size size + * @param memory_offset offset + * @param memory_req request + */ +[[maybe_unused]] static void validateIntervalOverlap( + const std::vector> &memory_validity, + const std::vector &memory_size, + const std::vector &memory_offset, size_t memory_req) { + auto bits = std::make_unique(memory_req); + + for (size_t i = 0; i < memory_req; ++i) { + bits[i] = 0; + } + + auto exec_start = + std::min_element(memory_validity.begin(), memory_validity.end(), + [](auto &a, auto &b) { return a.first < b.first; }); + + auto exec_end = + std::max_element(memory_validity.begin(), memory_validity.end(), + [](auto &a, auto &b) { return a.second < b.second; }); + + auto set = [&](int offset, size_t size, int idx) { + for (unsigned int i = offset; i < size; ++i) { + NNTR_THROW_IF(bits[i], std::invalid_argument) + << " bits taken at i: " << i << " offset: " << offset + << " size: " << size << " idx: " << idx; + bits[i] = 1; + } + }; + + auto unset = [&](int offset, size_t size, int idx) { + for (unsigned int i = offset; i < size; ++i) { + NNTR_THROW_IF(!bits[i], std::invalid_argument) + << "double freeing bits at i: " << i << " offset: " << offset + << " size: " << size << " idx: " << idx; + bits[i] = 0; + } + }; + + for (unsigned int exec = exec_start->first; exec <= exec_end->second; + ++exec) { + + for (unsigned int idx = 0; idx < memory_validity.size(); ++idx) { + auto &validity = memory_validity.at(idx); + auto &sz = memory_size.at(idx); + auto &offset = memory_offset.at(idx); + if (validity.first == exec) { + set(offset, sz, idx); + } + if (validity.second == exec) { + unset(offset, sz, idx); + } + } + } + // check if there is any dangling memory + set(0, memory_req, memory_validity.size()); +} + +/** * @copydoc MemoryPlanner::planLayout( * const std::vector &memory_size, * const std::vector> &memory_validity, @@ -126,6 +192,9 @@ size_t OptimizedV1Planner::planLayout( sorted_req.push_back(&req); } + // validateIntervalOverlap(memory_validity, memory_size, memory_offset, + // memory_req); + return memory_req; }