From b0576317e29dd0cb073dffcc2b1294a141665286 Mon Sep 17 00:00:00 2001 From: Jihoon Lee Date: Thu, 6 May 2021 21:22:57 +0900 Subject: [PATCH] [Permute] Implement peripheral functions This patch implements initialize, export and setProperty of permute layer **Self evaluation:** 1. Build test: [X]Passed [ ]Failed [ ]Skipped 2. Run test: [X]Passed [ ]Failed [ ]Skipped Signed-off-by: Jihoon Lee --- nntrainer/layers/permute_layer.cpp | 76 ++++++++++++++++++++++++++++++++++++-- nntrainer/layers/permute_layer.h | 38 ++++++++++++++++++- nntrainer/utils/node_exporter.h | 7 ++-- 3 files changed, 113 insertions(+), 8 deletions(-) diff --git a/nntrainer/layers/permute_layer.cpp b/nntrainer/layers/permute_layer.cpp index e8a2543..404e4d4 100644 --- a/nntrainer/layers/permute_layer.cpp +++ b/nntrainer/layers/permute_layer.cpp @@ -9,6 +9,8 @@ * @author Jihoon Lee * @bug No known bugs except for NYI items */ +#include +#include #include #include @@ -20,9 +22,57 @@ namespace nntrainer { +bool props::Direction::isValid(const unsigned int &value) const { + return value <= 2; +} + const std::string PermuteLayer::type = "permute"; -int PermuteLayer::initialize(Manager &manager) { /** NYI */ +/** + * @brief buildTransposeString based on array + * @todo deprecate this + * + * @param arr array to make a representation + * @return const std::string string to return + */ +static std::string +buildTrasposeString(const std::array &arr) { + std::stringstream ss; + ss << arr[0].get() << ':' << arr[1].get() << ':' << arr[2].get(); + return ss.str(); +} + +int PermuteLayer::initialize(Manager &manager) { + auto initiate_direction = [this] { + std::bitset<3> check_transpose; /**< check if transpose contains all axis */ + + for (int i = 0; i < 3; ++i) { + check_transpose.set(direction[i], true); + this->reverse_direction[direction[i]].set(i); + } + + NNTR_THROW_IF(check_transpose.all() == false, std::invalid_argument) + << "[Permute] " + << "transpose direction is invalid, checked direction: " + << check_transpose.to_string(); + + /*** @todo deprecate this */ + direction_str = buildTrasposeString(direction); + rdirection_str = buildTrasposeString(direction); + }; + + auto initiate_dimension = [this] { + output_dim[0] = input_dim[0].transpose(direction_str); + }; + + try { + initiate_direction(); + initiate_dimension(); + } catch (std::exception &e) { + ml_loge("[Permute] Initiation failed, reason: %s", e.what()); + return ML_ERROR_INVALID_PARAMETER; + } + return ML_ERROR_NONE; } @@ -32,12 +82,32 @@ void PermuteLayer::forwarding(bool training) { /** NYI */ void PermuteLayer::calcDerivative() { /** NYI */ } -void PermuteLayer::copy(std::shared_ptr l) { /** NYI */ +void PermuteLayer::copy(std::shared_ptr l) { + Layer::copy(l); + + std::shared_ptr from = + std::static_pointer_cast(l); + + direction = from->direction; + direction_str = from->direction_str; + reverse_direction = from->reverse_direction; + rdirection_str = from->rdirection_str; } -void PermuteLayer::export_to(Exporter &exporter, ExportMethods method) const {} +void PermuteLayer::export_to(Exporter &exporter, ExportMethods method) const { + Layer::export_to(exporter, method); + exporter.saveResult(std::forward_as_tuple(direction), method); +} int PermuteLayer::setProperty(std::vector values) { + try { + auto left_values = loadProperties(values, std::forward_as_tuple(direction)); + Layer::setProperty(left_values); + } catch (std::invalid_argument &e) { + ml_loge("[PermuteLayer] failed to set property, reason: %s", e.what()); + return ML_ERROR_INVALID_PARAMETER; + } + return ML_ERROR_NONE; } diff --git a/nntrainer/layers/permute_layer.h b/nntrainer/layers/permute_layer.h index b5e05b4..e1c902f 100644 --- a/nntrainer/layers/permute_layer.h +++ b/nntrainer/layers/permute_layer.h @@ -14,11 +14,34 @@ #define __PERMUTE_LAYER_H__ #include +#include #include #include #include namespace nntrainer { + +namespace props { +/** + * @brief Direction property, direction property describes the axis to be + * transposed. to be used with array + * + */ +class Direction : public nntrainer::Property { +public: + static constexpr const char *key = "direction"; /**< unique key to access */ + using prop_tag = uint_prop_tag; /**< property type */ + + /** + * @brief check if given value is valid + * + * @return true if valid + * @return false if not valid + */ + bool isValid(const unsigned int &) const override; +}; +} // namespace props + /** * @class PermuteLayer * @brief Permute layer to transpose a tensor @@ -29,7 +52,11 @@ public: * @brief Constructor of Permute Layer * @param direction direction to permute */ - template PermuteLayer(Args... args) : Layer(args...) {} + template + PermuteLayer(Args... args) : + Layer(args...), + direction(), + reverse_direction() {} /** * @brief Destructor of Permute Layer @@ -91,6 +118,15 @@ public: * @copydoc Layer::setProperty(std::vector values); */ int setProperty(std::vector values) override; + +private: + std::string + direction_str; /**< transpose representation, @todo deprecate this */ + std::string rdirection_str; /**< transpose representation, @todo + deprecate this */ + + std::array direction; + std::array reverse_direction; }; } // namespace nntrainer diff --git a/nntrainer/utils/node_exporter.h b/nntrainer/utils/node_exporter.h index f25470e..c29c764 100644 --- a/nntrainer/utils/node_exporter.h +++ b/nntrainer/utils/node_exporter.h @@ -273,16 +273,15 @@ iterate_prop(Callable &&c, std::tuple &tup) { * @brief load property from the api formatted string ({"key=value", * "key1=value1"}) * - * @tparam Ts prop type + * @tparam Tuple tuple type * @param string_vector api formatted string; * @param[out] props props to be iterated * @return std::vector vector of string that is not used while * setting the property */ -template +template std::vector -loadProperties(const std::vector &string_vector, - std::tuple &props) { +loadProperties(const std::vector &string_vector, Tuple &&props) { std::vector> left; left.reserve(string_vector.size()); -- 2.7.4