From 7dd0e9eb00e1be257cf192b1556392bd39b2a9d2 Mon Sep 17 00:00:00 2001 From: Jihoon Lee Date: Tue, 12 Oct 2021 21:41:43 +0900 Subject: [PATCH] [Realizer] Implement remap realizer This patch introduce remap realizer which remaps identifier inside a graph representation. Please refer to the test to see what this realizer does. **Self evaluation:** 1. Build test: [X]Passed [ ]Failed [ ]Skipped 2. Run test: [X]Passed [ ]Failed [ ]Skipped Signed-off-by: Jihoon Lee --- jni/Android.mk | 1 + nntrainer/compiler/meson.build | 3 +- nntrainer/compiler/remap_realizer.cpp | 36 ++++++++++++++++++++ nntrainer/compiler/remap_realizer.h | 50 ++++++++++++++++++++++++++++ nntrainer/layers/layer_node.cpp | 26 +++++++++++++++ nntrainer/layers/layer_node.h | 7 ++++ test/unittest/compiler/unittest_realizer.cpp | 15 +++++++++ 7 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 nntrainer/compiler/remap_realizer.cpp create mode 100644 nntrainer/compiler/remap_realizer.h diff --git a/jni/Android.mk b/jni/Android.mk index e92d2fb..0f092b6 100644 --- a/jni/Android.mk +++ b/jni/Android.mk @@ -193,6 +193,7 @@ NNTRAINER_SRCS := $(NNTRAINER_ROOT)/nntrainer/models/neuralnet.cpp \ $(NNTRAINER_ROOT)/nntrainer/compiler/ini_interpreter.cpp \ $(NNTRAINER_ROOT)/nntrainer/compiler/flatten_realizer.cpp \ $(NNTRAINER_ROOT)/nntrainer/compiler/recurrent_realizer.cpp \ + $(NNTRAINER_ROOT)/nntrainer/compiler/remap_realizer.cpp \ $(NNTRAINER_ROOT)/nntrainer/app_context.cpp ifeq ($(ENABLE_TFLITE_INTERPRETER), 1) diff --git a/nntrainer/compiler/meson.build b/nntrainer/compiler/meson.build index 1f5b7a1..ad735df 100644 --- a/nntrainer/compiler/meson.build +++ b/nntrainer/compiler/meson.build @@ -1,7 +1,8 @@ compiler_sources = [ 'ini_interpreter.cpp', 'flatten_realizer.cpp', - 'recurrent_realizer.cpp' + 'recurrent_realizer.cpp', + 'remap_realizer.cpp' ] compiler_headers = [] diff --git a/nntrainer/compiler/remap_realizer.cpp b/nntrainer/compiler/remap_realizer.cpp new file mode 100644 index 0000000..7f55613 --- /dev/null +++ b/nntrainer/compiler/remap_realizer.cpp @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: Apache-2.0 +/** + * Copyright (C) 2021 Jihoon Lee + * + * @file remap_realizer.h + * @date 12 October 2021 + * @brief NNTrainer graph realizer which realizes identifer to a new identifier + * @see https://github.com/nnstreamer/nntrainer + * @author Jihoon Lee + * @bug No known bugs except for NYI items + */ +#include + +#include +namespace nntrainer { + +RemapRealizer::RemapRealizer( + std::function remap_function) : + remap_fn(remap_function) { + if (!remap_fn) { + throw std::invalid_argument("remap function is not given!"); + } +} + +RemapRealizer::~RemapRealizer() {} + +GraphRepresentation +RemapRealizer::realize(const GraphRepresentation &reference) { + GraphRepresentation processed(reference.begin(), reference.end()); + for (auto &node : processed) { + node->remapIdentifiers(remap_fn); + } + return processed; +} + +} // namespace nntrainer diff --git a/nntrainer/compiler/remap_realizer.h b/nntrainer/compiler/remap_realizer.h new file mode 100644 index 0000000..8aaa235 --- /dev/null +++ b/nntrainer/compiler/remap_realizer.h @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: Apache-2.0 +/** + * Copyright (C) 2021 Jihoon Lee + * + * @file remap_realizer.h + * @date 12 October 2021 + * @brief NNTrainer graph realizer which realizes identifer to a new identifier + * @see https://github.com/nnstreamer/nntrainer + * @author Jihoon Lee + * @bug No known bugs except for NYI items + */ +#ifndef __REMAP_REALIZER_H__ +#define __REMAP_REALIZER_H__ + +#include +#include +#include + +#include + +namespace nntrainer { + +/** + * @brief Graph realizer class which remaps identifiers inside the graph + * representation, remap_function will be applied for all the layers identifier + * visible + * + */ +class RemapRealizer final : public GraphRealizer { +public: + RemapRealizer(std::function remap_function); + /** + * @brief Destroy the Graph Realizer object + * + */ + ~RemapRealizer(); + + /** + * @brief graph realizer creates a new graph based on the reference + * + */ + GraphRepresentation realize(const GraphRepresentation &reference) override; + +private: + std::function remap_fn; +}; + +} // namespace nntrainer + +#endif // __REMAP_REALIZER_H__ diff --git a/nntrainer/layers/layer_node.cpp b/nntrainer/layers/layer_node.cpp index 60013a1..b6495c8 100644 --- a/nntrainer/layers/layer_node.cpp +++ b/nntrainer/layers/layer_node.cpp @@ -599,6 +599,32 @@ void LayerNode::printPreset(std::ostream &out, PrintPreset preset) { print(out, flags); } +void LayerNode::remapIdentifiers(std::function remap_fn) { + NNTR_THROW_IF(isFinalized(), std::invalid_argument) + << "cannot remap identifiers after finalized"; + + auto &name = std::get(*layer_node_props); + if (!name.empty()) { + remap_fn(name.get()); + } + + auto &shared_from = std::get(*layer_node_props); + if (!shared_from.empty()) { + remap_fn(shared_from.get()); + } + + auto &input_layers = + std::get>(*layer_node_props); + + for (auto &input_layer : input_layers) { + remap_fn(input_layer); + } + + for (auto &output_layer : output_layers) { + remap_fn(output_layer); + } +} + void LayerNode::printShapeInfo(std::ostream &out) { for (unsigned int idx = 0; idx < getNumInputs(); ++idx) { out << "input " << run_context->getInput(idx).getDim(); diff --git a/nntrainer/layers/layer_node.h b/nntrainer/layers/layer_node.h index 5db3e32..9afb3a4 100644 --- a/nntrainer/layers/layer_node.h +++ b/nntrainer/layers/layer_node.h @@ -624,6 +624,13 @@ public: void printPreset(std::ostream &out, PrintPreset preset = PrintPreset::PRINT_SUMMARY); + /** + * @brief remap identifier inside layer node + * + * @param remap_fn function to remap + */ + void remapIdentifiers(std::function remap_fn); + private: std::unique_ptr layer; /**< The actual object in the graph node */ diff --git a/test/unittest/compiler/unittest_realizer.cpp b/test/unittest/compiler/unittest_realizer.cpp index 214c74d..5c54f78 100644 --- a/test/unittest/compiler/unittest_realizer.cpp +++ b/test/unittest/compiler/unittest_realizer.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -61,3 +62,17 @@ TEST(RecurrentRealizer, recurrent_p) { realizeAndEqual(r, {input1}, {input1}); } + +TEST(RemapRealizer, remap_p) { + + RemapRealizer r([](std::string &name) { name = "scoped/" + name; }); + + LayerRepresentation input1 = { + "fully_connected", {"name=layer1", "flatten=true", "input_layers=1,2"}}; + + LayerRepresentation expected1 = { + "fully_connected", + {"name=scoped/layer1", "flatten=true", "input_layers=scoped/1,scoped/2"}}; + + realizeAndEqual(r, {input1}, {expected1}); +} -- 2.7.4