From 37b7c2234dd591a994148d14dd399037702ccd31 Mon Sep 17 00:00:00 2001 From: Jihoon Lee Date: Thu, 10 Jun 2021 19:14:57 +0900 Subject: [PATCH] [Custom/Loss] Add scaffolding for loss example This patch generates a skeleton code for mae custom loss example. **Self evaluation:** 1. Build test: [X]Passed [ ]Failed [ ]Skipped 2. Run test: [X]Passed [ ]Failed [ ]Skipped Signed-off-by: Jihoon Lee --- .../Custom/LayerClient/jni/meson.build | 3 +- .../layer_plugin_mae_loss_test.cpp | 36 ++++++++ ...gin_test.cpp => layer_plugin_pow_test.cpp} | 20 ++--- Applications/Custom/LayerPlugin/meson.build | 18 +++- Applications/Custom/mae_loss.cpp | 41 +++++++++ Applications/Custom/mae_loss.h | 89 +++++++++++++++++++ Applications/Custom/meson.build | 4 +- Applications/Custom/pow.cpp | 2 +- Applications/Custom/pow.h | 13 ++- 9 files changed, 203 insertions(+), 23 deletions(-) create mode 100644 Applications/Custom/LayerPlugin/layer_plugin_mae_loss_test.cpp rename Applications/Custom/LayerPlugin/{layer_plugin_test.cpp => layer_plugin_pow_test.cpp} (84%) create mode 100644 Applications/Custom/mae_loss.cpp create mode 100644 Applications/Custom/mae_loss.h diff --git a/Applications/Custom/LayerClient/jni/meson.build b/Applications/Custom/LayerClient/jni/meson.build index bd243743..68e7a771 100644 --- a/Applications/Custom/LayerClient/jni/meson.build +++ b/Applications/Custom/LayerClient/jni/meson.build @@ -2,7 +2,8 @@ res_path = meson.current_source_dir() / '..' / 'res' layer_client_sources = [ 'main.cpp', - layer_example_src + layer_example_pow_src, + layer_example_mae_src ] ini_in_path = res_path / 'custom_layer_client.ini' diff --git a/Applications/Custom/LayerPlugin/layer_plugin_mae_loss_test.cpp b/Applications/Custom/LayerPlugin/layer_plugin_mae_loss_test.cpp new file mode 100644 index 00000000..4e6568f5 --- /dev/null +++ b/Applications/Custom/LayerPlugin/layer_plugin_mae_loss_test.cpp @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: Apache-2.0 +/** + * Copyright (C) 2020 Jihoon Lee + * + * @file layer_plugin_mae_loss_test.cpp + * @date 10 June 2021 + * @brief This file contains the execution part of mae loss layer in + * LayerPlugin example + * @see https://github.com/nnstreamer/nntrainer + * @author Jihoon Lee + * @bug No known bugs except for NYI items + * + */ +#include + +#include +#include +#include + +#include +#include +#include + +static const char *NNTRAINER_PATH = std::getenv("NNTRAINER_PATH"); + +TEST(MaeLossLayer, DlRegisterOpen_p) { + ASSERT_NE(NNTRAINER_PATH, nullptr) + << "NNTRAINER_PATH environment value must be set"; + auto ac = nntrainer::AppContext(); + + ac.registerLayer("libmae_loss_layer.so", NNTRAINER_PATH); + + auto layer = ac.createObject("mae_loss"); + + EXPECT_EQ(layer->getType(), "mae_loss"); +} diff --git a/Applications/Custom/LayerPlugin/layer_plugin_test.cpp b/Applications/Custom/LayerPlugin/layer_plugin_pow_test.cpp similarity index 84% rename from Applications/Custom/LayerPlugin/layer_plugin_test.cpp rename to Applications/Custom/LayerPlugin/layer_plugin_pow_test.cpp index 4c97dfc8..cf297d73 100644 --- a/Applications/Custom/LayerPlugin/layer_plugin_test.cpp +++ b/Applications/Custom/LayerPlugin/layer_plugin_pow_test.cpp @@ -2,9 +2,10 @@ /** * Copyright (C) 2020 Jihoon Lee * - * @file layer_plugin_test.cpp + * @file layer_plugin_pow_test.cpp * @date 26 January 2021 - * @brief This file contains the execution part of LayerPlugin example + * @brief This file contains the execution part of pow layer in LayerPlugin + * example * @see https://github.com/nnstreamer/nntrainer * @author Jihoon Lee * @bug No known bugs except for NYI items @@ -12,7 +13,6 @@ */ #include -#include #include #include #include @@ -21,9 +21,9 @@ #include #include -const char *NNTRAINER_PATH = std::getenv("NNTRAINER_PATH"); +static const char *NNTRAINER_PATH = std::getenv("NNTRAINER_PATH"); -TEST(AppContext, DlRegisterOpen_p) { +TEST(PowLayer, DlRegisterOpen_p) { ASSERT_NE(NNTRAINER_PATH, nullptr) << "NNTRAINER_PATH environment value must be set"; auto ac = nntrainer::AppContext(); @@ -35,7 +35,7 @@ TEST(AppContext, DlRegisterOpen_p) { EXPECT_EQ(layer->getType(), "pow"); } -TEST(AppContext, DlRegisterWrongPath_n) { +TEST(PowLayer, DlRegisterWrongPath_n) { ASSERT_NE(NNTRAINER_PATH, nullptr) << "NNTRAINER_PATH environment value must be set"; auto ac = nntrainer::AppContext(); @@ -43,7 +43,7 @@ TEST(AppContext, DlRegisterWrongPath_n) { EXPECT_THROW(ac.registerLayer("wrong_name.so"), std::invalid_argument); } -TEST(AppContext, DlRegisterDirectory_p) { +TEST(PowLayer, DlRegisterDirectory_p) { ASSERT_NE(NNTRAINER_PATH, nullptr) << "NNTRAINER_PATH environment value must be set"; auto ac = nntrainer::AppContext(); @@ -55,14 +55,14 @@ TEST(AppContext, DlRegisterDirectory_p) { EXPECT_EQ(layer->getType(), "pow"); } -TEST(AppContext, DlRegisterDirectory_n) { +TEST(PowLayer, DlRegisterDirectory_n) { auto ac = nntrainer::AppContext(); EXPECT_THROW(ac.registerPluggableFromDirectory("wrong path"), std::invalid_argument); } -TEST(AppContext, DefaultEnvironmentPath_p) { +TEST(PowLayer, DefaultEnvironmentPath_p) { /// as NNTRAINER_PATH is fed to the test, this should success without an /// error std::shared_ptr l = ml::train::createLayer("pow"); @@ -89,7 +89,7 @@ TEST(AppContext, DefaultEnvironmentPath_p) { EXPECT_EQ(layer->getInputDimension()[0], nntrainer::TensorDim()); } -TEST(AppContext, DefaultEnvironmentPath_n) { +TEST(PowLayer, DefaultEnvironmentPath_n) { /// pow2 does not exist EXPECT_THROW(ml::train::createLayer("pow2"), std::invalid_argument); } diff --git a/Applications/Custom/LayerPlugin/meson.build b/Applications/Custom/LayerPlugin/meson.build index 3cc4f1b8..076d2b63 100644 --- a/Applications/Custom/LayerPlugin/meson.build +++ b/Applications/Custom/LayerPlugin/meson.build @@ -1,5 +1,16 @@ +# build command for libpow_layer.so pow_layer = shared_library('pow_layer', - layer_example_src, + layer_example_pow_src, + dependencies: [nntrainer_dep, nntrainer_ccapi_dep], + include_directories: layer_example_inc, + install: true, + install_dir: application_install_dir, + cpp_args: '-DPLUGGABLE' +) + +# build command for libmae_loss_layer.so +mae_loss_layer = shared_library('mae_loss_layer', + layer_example_mae_src, dependencies: [nntrainer_dep, nntrainer_ccapi_dep], include_directories: layer_example_inc, install: true, @@ -9,11 +20,12 @@ pow_layer = shared_library('pow_layer', if get_option('enable-test') test_target = [ - 'layer_plugin_test.cpp' + 'layer_plugin_pow_test.cpp', + 'layer_plugin_mae_loss_test.cpp', ] exe = executable( - 'app_plugin_test', test_target, + 'app_layer_plugin_test', test_target, dependencies: [ gtest_main_dep, nntrainer_dep, diff --git a/Applications/Custom/mae_loss.cpp b/Applications/Custom/mae_loss.cpp new file mode 100644 index 00000000..c9317763 --- /dev/null +++ b/Applications/Custom/mae_loss.cpp @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: Apache-2.0 +/** + * Copyright (C) 2021 Jihoon Lee + * + * @file mae_loss.cpp + * @date 10 June 2021 + * @brief This file contains the mean absolute error loss as a sample layer + * @see https://github.com/nnstreamer/nntrainer + * @author Jihoon Lee + * @bug No known bugs except for NYI items + * + */ +#include "mae_loss.h" + +namespace custom { +const std::string MaeLossLayer::type = "mae_loss"; + +#ifdef PLUGGABLE + +nntrainer::LayerV1 *create_mae_loss_layer() { + auto layer = new MaeLossLayer(); + std::cout << "mae loss layer created\n"; + return layer; +} + +void destory_mae_loss_layer(nntrainer::LayerV1 *layer) { + std::cout << "mae loss layer destroyed\n"; + delete layer; +} + +/** + * @note ml_train_layer_pluggable defines the entry point for nntrainer to + * register a plugin layer + */ +extern "C" { +nntrainer::LayerPluggable ml_train_layer_pluggable{create_mae_loss_layer, + destory_mae_loss_layer}; +} + +#endif +} // namespace custom diff --git a/Applications/Custom/mae_loss.h b/Applications/Custom/mae_loss.h new file mode 100644 index 00000000..6c47a5c6 --- /dev/null +++ b/Applications/Custom/mae_loss.h @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: Apache-2.0 +/** + * Copyright (C) 2021 Jihoon Lee + * + * @file mae_loss.h + * @date 10 June 2021 + * @brief This file contains the mean absoulte error loss as a sample layer + * @see https://github.com/nnstreamer/nntrainer + * @author Jihoon Lee + * @bug No known bugs except for NYI items + * + */ +#ifndef __MAE_LOSS_LAYER_H__ +#define __MAE_LOSS_LAYER_H__ +#include + +/// @todo migrate these to API and ensure those headers are exposed to devel +#include +#include +#include + +namespace custom { + +/** + * @brief A sample loss layer which calculates mean absolute error from output + * @todo update this to LayerV1 + * + */ +class MaeLossLayer final : public nntrainer::LayerV1 { +public: + /** + * @brief Construct a new Pow Layer object that does elementwise power + * + */ + MaeLossLayer() : LayerV1() {} + + /** + * @brief Destroy the Pow Layer object + * + */ + ~MaeLossLayer() {} + + using nntrainer::LayerV1::setProperty; + + /** + * @brief set Property of layer, currently only "exponent is accepted" + * @param[in] values values of property + * @retval #ML_ERROR_NONE Successful. + * @retval #ML_ERROR_INVALID_PARAMETER invalid parameter. + */ + int setProperty(std::vector values) override { /** NYI */ + return 0; + } + + /** + * @brief initializing nntrainer + * + * @return int ML_ERROR_NONE if success + */ + int initialize(nntrainer::Manager &manager) override { /** NYI */ + return 0; + } + + /** + * @brief nntrainer forwarding function + * @param[in] training true if forwarding is on training + */ + void forwarding(bool training = true) override { /** NYI */ + } + + /** + * @brief calc the derivative to be passed to the previous layer + */ + void calcDerivative() override { /** NYI */ + } + + /** + * @brief Get the type, it must return MaeLossLayer::type + * + * @return const std::string get type + */ + const std::string getType() const override { return MaeLossLayer::type; } + + static const std::string type; +}; + +} // namespace custom + +#endif /* __MAE_LOSS_LAYER_H__ */ diff --git a/Applications/Custom/meson.build b/Applications/Custom/meson.build index 5634e398..2e95ab0e 100644 --- a/Applications/Custom/meson.build +++ b/Applications/Custom/meson.build @@ -1,5 +1,7 @@ -layer_example_src = files('pow.cpp') +layer_example_pow_src = files('pow.cpp') +layer_example_mae_src = files('mae_loss.cpp') + layer_example_inc = include_directories('.') subdir('LayerClient/jni') diff --git a/Applications/Custom/pow.cpp b/Applications/Custom/pow.cpp index 775ed367..e9726500 100644 --- a/Applications/Custom/pow.cpp +++ b/Applications/Custom/pow.cpp @@ -14,7 +14,7 @@ #include #include -#include +#include "pow.h" namespace custom { diff --git a/Applications/Custom/pow.h b/Applications/Custom/pow.h index 1e1db6cd..9c17b14a 100644 --- a/Applications/Custom/pow.h +++ b/Applications/Custom/pow.h @@ -18,7 +18,6 @@ /// @todo migrate these to API(#987) #include #include - #include namespace custom { @@ -28,7 +27,7 @@ namespace custom { * configurable by PowLayer::setProperty) * */ -class PowLayer : public nntrainer::LayerV1 { +class PowLayer final : public nntrainer::LayerV1 { public: /** * @brief Construct a new Pow Layer object that does elementwise power @@ -51,14 +50,14 @@ public: * @retval #ML_ERROR_NONE Successful. * @retval #ML_ERROR_INVALID_PARAMETER invalid parameter. */ - int setProperty(std::vector values); + int setProperty(std::vector values) override; /** * @brief initializing nntrainer * * @return int ML_ERROR_NONE if success */ - int initialize(nntrainer::Manager &manager); + int initialize(nntrainer::Manager &manager) override; /** * @brief nntrainer forwarding function @@ -69,14 +68,14 @@ public: /** * @brief calc the derivative to be passed to the previous layer */ - void calcDerivative(); + void calcDerivative() override; /** - * @brief Get the Type object + * @brief Get the Type object, this must return PowLayer::type * * @return const std::string */ - const std::string getType() const { return PowLayer::type; } + const std::string getType() const override { return PowLayer::type; } inline static const std::string type = "pow"; -- 2.34.1