From 302e6564a7a76109e1178207e44e45a58631c477 Mon Sep 17 00:00:00 2001 From: Chunseok Lee Date: Wed, 4 Mar 2020 18:09:24 +0900 Subject: Imported Upstream version 1.1.0 --- runtime/libs/misc/CMakeLists.txt | 11 ++ .../libs/misc/examples/tensor_index_iterator.cpp | 74 ++++++++++ runtime/libs/misc/include/misc/EnvVar.h | 120 +++++++++++++++++ runtime/libs/misc/include/misc/EventCollector.h | 51 +++++++ runtime/libs/misc/include/misc/EventRecorder.h | 67 +++++++++ runtime/libs/misc/include/misc/benchmark.h | 87 ++++++++++++ runtime/libs/misc/include/misc/feature/Index.h | 137 +++++++++++++++++++ .../libs/misc/include/misc/feature/IndexIterator.h | 105 +++++++++++++++ runtime/libs/misc/include/misc/feature/Object.h | 117 ++++++++++++++++ runtime/libs/misc/include/misc/feature/Reader.h | 69 ++++++++++ runtime/libs/misc/include/misc/feature/Shape.h | 77 +++++++++++ .../libs/misc/include/misc/feature/TextFormatter.h | 116 ++++++++++++++++ runtime/libs/misc/include/misc/fp32.h | 99 ++++++++++++++ .../libs/misc/include/misc/kernel/IndexIterator.h | 102 ++++++++++++++ runtime/libs/misc/include/misc/kernel/Reader.h | 60 +++++++++ runtime/libs/misc/include/misc/kernel/Shape.h | 68 ++++++++++ .../libs/misc/include/misc/matrix/IndexIterator.h | 99 ++++++++++++++ runtime/libs/misc/include/misc/matrix/Reader.h | 59 ++++++++ runtime/libs/misc/include/misc/matrix/Shape.h | 63 +++++++++ .../libs/misc/include/misc/polymorphic_downcast.h | 43 ++++++ runtime/libs/misc/include/misc/string_helpers.h | 66 +++++++++ runtime/libs/misc/include/misc/tensor/Comparator.h | 95 +++++++++++++ runtime/libs/misc/include/misc/tensor/Diff.h | 70 ++++++++++ runtime/libs/misc/include/misc/tensor/Index.h | 107 +++++++++++++++ .../misc/include/misc/tensor/IndexEnumerator.h | 131 ++++++++++++++++++ .../libs/misc/include/misc/tensor/IndexFormatter.h | 75 +++++++++++ .../libs/misc/include/misc/tensor/IndexIterator.h | 107 +++++++++++++++ .../misc/include/misc/tensor/NonIncreasingStride.h | 88 ++++++++++++ runtime/libs/misc/include/misc/tensor/Object.h | 110 +++++++++++++++ runtime/libs/misc/include/misc/tensor/Reader.h | 58 ++++++++ runtime/libs/misc/include/misc/tensor/Shape.h | 150 +++++++++++++++++++++ runtime/libs/misc/include/misc/tensor/Zipper.h | 104 ++++++++++++++ runtime/libs/misc/include/misc/vector.h | 52 +++++++ runtime/libs/misc/include/misc/vector/Object.h | 92 +++++++++++++ runtime/libs/misc/include/misc/vector/Reader.h | 58 ++++++++ runtime/libs/misc/src/EventCollector.cpp | 104 ++++++++++++++ runtime/libs/misc/src/EventRecorder.cpp | 136 +++++++++++++++++++ runtime/libs/misc/src/tensor/Comparator.cpp | 38 ++++++ runtime/libs/misc/src/tensor/IndexFormatter.cpp | 49 +++++++ .../libs/misc/src/tensor/NonIncreasingStride.cpp | 46 +++++++ runtime/libs/misc/src/tensor/Shape.cpp | 107 +++++++++++++++ 41 files changed, 3467 insertions(+) create mode 100644 runtime/libs/misc/CMakeLists.txt create mode 100644 runtime/libs/misc/examples/tensor_index_iterator.cpp create mode 100644 runtime/libs/misc/include/misc/EnvVar.h create mode 100644 runtime/libs/misc/include/misc/EventCollector.h create mode 100644 runtime/libs/misc/include/misc/EventRecorder.h create mode 100644 runtime/libs/misc/include/misc/benchmark.h create mode 100644 runtime/libs/misc/include/misc/feature/Index.h create mode 100644 runtime/libs/misc/include/misc/feature/IndexIterator.h create mode 100644 runtime/libs/misc/include/misc/feature/Object.h create mode 100644 runtime/libs/misc/include/misc/feature/Reader.h create mode 100644 runtime/libs/misc/include/misc/feature/Shape.h create mode 100644 runtime/libs/misc/include/misc/feature/TextFormatter.h create mode 100644 runtime/libs/misc/include/misc/fp32.h create mode 100644 runtime/libs/misc/include/misc/kernel/IndexIterator.h create mode 100644 runtime/libs/misc/include/misc/kernel/Reader.h create mode 100644 runtime/libs/misc/include/misc/kernel/Shape.h create mode 100644 runtime/libs/misc/include/misc/matrix/IndexIterator.h create mode 100644 runtime/libs/misc/include/misc/matrix/Reader.h create mode 100644 runtime/libs/misc/include/misc/matrix/Shape.h create mode 100644 runtime/libs/misc/include/misc/polymorphic_downcast.h create mode 100644 runtime/libs/misc/include/misc/string_helpers.h create mode 100644 runtime/libs/misc/include/misc/tensor/Comparator.h create mode 100644 runtime/libs/misc/include/misc/tensor/Diff.h create mode 100644 runtime/libs/misc/include/misc/tensor/Index.h create mode 100644 runtime/libs/misc/include/misc/tensor/IndexEnumerator.h create mode 100644 runtime/libs/misc/include/misc/tensor/IndexFormatter.h create mode 100644 runtime/libs/misc/include/misc/tensor/IndexIterator.h create mode 100644 runtime/libs/misc/include/misc/tensor/NonIncreasingStride.h create mode 100644 runtime/libs/misc/include/misc/tensor/Object.h create mode 100644 runtime/libs/misc/include/misc/tensor/Reader.h create mode 100644 runtime/libs/misc/include/misc/tensor/Shape.h create mode 100644 runtime/libs/misc/include/misc/tensor/Zipper.h create mode 100644 runtime/libs/misc/include/misc/vector.h create mode 100644 runtime/libs/misc/include/misc/vector/Object.h create mode 100644 runtime/libs/misc/include/misc/vector/Reader.h create mode 100644 runtime/libs/misc/src/EventCollector.cpp create mode 100644 runtime/libs/misc/src/EventRecorder.cpp create mode 100644 runtime/libs/misc/src/tensor/Comparator.cpp create mode 100644 runtime/libs/misc/src/tensor/IndexFormatter.cpp create mode 100644 runtime/libs/misc/src/tensor/NonIncreasingStride.cpp create mode 100644 runtime/libs/misc/src/tensor/Shape.cpp (limited to 'runtime/libs/misc') diff --git a/runtime/libs/misc/CMakeLists.txt b/runtime/libs/misc/CMakeLists.txt new file mode 100644 index 000000000..557d403ec --- /dev/null +++ b/runtime/libs/misc/CMakeLists.txt @@ -0,0 +1,11 @@ +# Library `nnfw_lib_misc` +file(GLOB_RECURSE NNFW_UTILITY_SRCS "src/*.cpp") + +add_library(nnfw_lib_misc STATIC ${NNFW_UTILITY_SRCS}) +target_include_directories(nnfw_lib_misc PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) +set_target_properties(nnfw_lib_misc PROPERTIES POSITION_INDEPENDENT_CODE ON) +target_link_libraries(nnfw_lib_misc PRIVATE nnfw_common) +target_link_libraries(nnfw_lib_misc PRIVATE nnfw_coverage) + +add_executable(nnfw_tensor_index_iterator "examples/tensor_index_iterator.cpp") +target_link_libraries(nnfw_tensor_index_iterator nnfw_lib_misc) diff --git a/runtime/libs/misc/examples/tensor_index_iterator.cpp b/runtime/libs/misc/examples/tensor_index_iterator.cpp new file mode 100644 index 000000000..d94da9f49 --- /dev/null +++ b/runtime/libs/misc/examples/tensor_index_iterator.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "misc/tensor/IndexIterator.h" + +#include + +#include +#include + +#include + +void test_iterate(void) +{ + const nnfw::misc::tensor::Shape shape{3, 4, 7}; + + std::array array; + + array.fill(0); + + using nnfw::misc::tensor::iterate; + using nnfw::misc::tensor::Index; + + iterate(shape) << [&](const Index &index) { + assert(index.rank() == shape.rank()); + + const uint32_t rank = index.rank(); + + uint32_t offset = index.at(0); + + for (uint32_t axis = 1; axis < rank; ++axis) + { + offset *= shape.dim(axis); + offset += index.at(axis); + } + + array[offset] += 1; + }; + + assert(std::all_of(array.begin(), array.end(), [](int num) { return num == 1; })); +} + +int main(int argc, char **argv) +{ + test_iterate(); + + nnfw::misc::tensor::Shape shape{3, 4, 3, 4}; + + std::cout << "Iterate over tensor{3, 4, 3, 4}" << std::endl; + + nnfw::misc::tensor::iterate(shape) << [](const nnfw::misc::tensor::Index &index) { + std::cout << "rank: " << index.rank() << std::endl; + + for (uint32_t d = 0; d < index.rank(); ++d) + { + std::cout << " offset(" << d << ") = " << index.at(d) << std::endl; + } + }; + + return 0; +} diff --git a/runtime/libs/misc/include/misc/EnvVar.h b/runtime/libs/misc/include/misc/EnvVar.h new file mode 100644 index 000000000..db28a3c7d --- /dev/null +++ b/runtime/libs/misc/include/misc/EnvVar.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file EnvVar.h + * @ingroup COM_AI_RUNTIME + * @brief This file contains nnfw::misc::EnvVar class + */ + +#ifndef __NNFW_MISC_ENV_VAR__ +#define __NNFW_MISC_ENV_VAR__ + +#include +#include +#include +#include + +namespace nnfw +{ +namespace misc +{ +/** + * @brief Class to access environment variable + */ +class EnvVar +{ +public: + /** + * @brief Construct a new EnvVar object + * @param[in] key environment variable + */ + EnvVar(const std::string &key) + { + const char *value = std::getenv(key.c_str()); + if (value == nullptr) + { + // An empty string is considered as an empty value + _value = ""; + } + else + { + _value = value; + } + } + + /** + * @brief Get environment variable of string type + * @param[in] def Default value of environment variable + * @return Defaut value passed as a parameter when there is no environment variable, + * otherwise the value of environment variable passed into constructor + */ + std::string asString(const std::string &def) const + { + if (_value.empty()) + return def; + return _value; + } + + /** + * @brief Get environment variable of boolean type + * @param[in] def Default value of environment variable + * @return Defaut value passed as a parameter when there is no environment variable, + * otherwise the value of environment variable passed into constructor + */ + bool asBool(bool def) const + { + if (_value.empty()) + return def; + static const std::array false_list{"0", "OFF", "FALSE", "N", "NO"}; + auto false_found = std::find(false_list.begin(), false_list.end(), _value); + return (false_found == false_list.end()); + } + + /** + * @brief Get environment variable of int type + * @param[in] def Default value of environment variable + * @return Defaut value passed as a parameter when there is no environment variable, + * otherwise the value of environment variable passed into constructor + */ + int asInt(int def) const + { + if (_value.empty()) + return def; + return std::stoi(_value); + } + + /** + * @brief Get environment variable of float type + * @param[in] def Default value of environment variable + * @return Defaut value passed as a parameter when there is no environment variable, + * otherwise the value of environment variable passed into constructor + */ + float asFloat(float def) const + { + if (_value.empty()) + return def; + return std::stof(_value); + } + +private: + std::string _value; +}; + +} // namespace misc +} // namespace nnfw + +#endif // __NNFW_MISC_ENV_VAR__ diff --git a/runtime/libs/misc/include/misc/EventCollector.h b/runtime/libs/misc/include/misc/EventCollector.h new file mode 100644 index 000000000..530a90906 --- /dev/null +++ b/runtime/libs/misc/include/misc/EventCollector.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __EVENT_COLLECTOR_H__ +#define __EVENT_COLLECTOR_H__ + +#include "misc/EventRecorder.h" + +class EventCollector +{ +public: + enum class Edge + { + BEGIN, + END + }; + + struct Event + { + Edge edge; + std::string backend; + std::string label; + }; + +public: + EventCollector(EventRecorder *rec) : _rec{rec} + { + // DO NOTHING + } + +public: + void onEvent(const Event &event); + +protected: + EventRecorder *_rec; +}; + +#endif // __EVENT_COLLECTOR_H__ diff --git a/runtime/libs/misc/include/misc/EventRecorder.h b/runtime/libs/misc/include/misc/EventRecorder.h new file mode 100644 index 000000000..1e621fdf8 --- /dev/null +++ b/runtime/libs/misc/include/misc/EventRecorder.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __EVENT_RECORDER_H__ +#define __EVENT_RECORDER_H__ + +#include +#include +#include + +#include +#include + +struct Event +{ + std::string name; + std::string tid; + std::string ph; /* REQUIRED */ + std::string ts; /* REQUIRED */ +}; + +struct DurationEvent : public Event +{ + // TO BE FILLED +}; + +struct CounterEvent : public Event +{ + std::map values; +}; + +// +// Record Event as Chrome Trace Event File Format +// +// Refrence: https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/edit +// +class EventRecorder +{ +public: + EventRecorder() = default; + +public: + void emit(const DurationEvent &evt); + void emit(const CounterEvent &evt); + +public: + void writeToFile(std::ostream &os); + +private: + std::mutex _mu; + std::stringstream _ss; +}; + +#endif // __EVENT_RECORDER_H__ diff --git a/runtime/libs/misc/include/misc/benchmark.h b/runtime/libs/misc/include/misc/benchmark.h new file mode 100644 index 000000000..fe5b97585 --- /dev/null +++ b/runtime/libs/misc/include/misc/benchmark.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file benchmark.h + * @ingroup COM_AI_RUNTIME + * @brief This file contains nnfw::misc::benchmark::Accumulator class + */ +#ifndef __NNFW_MISC_BENCHMARK_H__ +#define __NNFW_MISC_BENCHMARK_H__ + +#include + +namespace nnfw +{ +namespace misc +{ +// Benckmark support +namespace benchmark +{ + +/** + * @brief Class to accumulate time during benchmark + */ +template class Accumulator +{ +public: + /** + * @brief Construct a new Accumulator object + * @param[in] ref Object to keep time duration + */ + Accumulator(T &ref) : _ref(ref) + { + // DO NOTHING + } + +public: + /** + * @brief Return the reference of @c ref passed to constructor + * @return Reference of @c ref + */ + T &operator()(void) { return _ref; } + +private: + T &_ref; +}; + +/** + * @brief Run passed function and returns accumulated time + * @tparam T Period used by @c std::chrono::duration_cast + * @tparam Callable Function type to benchmark + * @param[in] acc Accumulated time after running @cb + * @param[in] cb Function to run and benchmark + * @return Accumulated time + */ +template +Accumulator &operator<<(Accumulator &&acc, Callable cb) +{ + auto begin = std::chrono::steady_clock::now(); + cb(); + auto end = std::chrono::steady_clock::now(); + + acc() += std::chrono::duration_cast(end - begin); + + return acc; +} + +template Accumulator measure(T &out) { return Accumulator(out); } + +} // namespace benchmark +} // namespace misc +} // namespace nnfw + +#endif // __NNFW_MISC_BENCHMARK_H__ diff --git a/runtime/libs/misc/include/misc/feature/Index.h b/runtime/libs/misc/include/misc/feature/Index.h new file mode 100644 index 000000000..a361d8dd2 --- /dev/null +++ b/runtime/libs/misc/include/misc/feature/Index.h @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file Index.h + * @brief This file contains Index class + * @ingroup COM_AI_RUNTIME + */ + +#ifndef __NNFW_MISC_FEATURE_INDEX_H__ +#define __NNFW_MISC_FEATURE_INDEX_H__ + +#include + +namespace nnfw +{ +namespace misc +{ +namespace feature +{ + +/** + * @brief Class to have the index information for calculating the offset. + */ +class Index +{ +public: + /** + * @brief Construct Index object using default constrcutor + */ + Index() = default; + +public: + /** + * @brief Construct Index object with three indexes of dimensions + * @param[in] ch The depth index + * @param[in] row The heigth index + * @param[in] col The width index + */ + Index(int32_t ch, int32_t row, int32_t col) : _batch{1}, _ch{ch}, _row{row}, _col{col} + { + // DO NOTHING + } + /** + * @brief Construct Index object with four indexes of dimensions + * @param[in] batch The batch index + * @param[in] ch The depth index + * @param[in] row The height index + * @param[in] col The width index + */ + Index(int32_t batch, int32_t ch, int32_t row, int32_t col) + : _batch{batch}, _ch{ch}, _row{row}, _col{col} + { + // DO NOTHING + } + +public: + /** + * @brief Get the batch index + * @return The batch index + */ + int32_t batch(void) const { return _batch; } + /** + * @brief Get the depth index + * @return The depth index + */ + int32_t ch(void) const { return _ch; } + /** + * @brief Get the height index + * @return The height index + */ + int32_t row(void) const { return _row; } + /** + * @brief Get the width index + * @return The width index + */ + int32_t col(void) const { return _col; } + +public: + /** + * @brief Get the batch index as the lvalue reference + * @return The reference of the batch value + */ + int32_t &batch(void) { return _batch; } + /** + * @brief Get the depth index as the lvalue reference + * @return The reference of the depth value + */ + int32_t &ch(void) { return _ch; } + /** + * @brief Get the height index as the lvalue reference + * @return The reference of the height value + */ + int32_t &row(void) { return _row; } + /** + * @brief Get the width index as the lvalue reference + * @return The reference of the width value + */ + int32_t &col(void) { return _col; } + +private: + /** + * @brief The batch index + */ + int32_t _batch; + /** + * @brief The depth index + */ + int32_t _ch; + /** + * @brief The height index + */ + int32_t _row; + /** + * @brief The width index + */ + int32_t _col; +}; + +} // namespace feature +} // namespace misc +} // namespace nnfw + +#endif // __NNFW_MISC_FEATURE_INDEX_H__ diff --git a/runtime/libs/misc/include/misc/feature/IndexIterator.h b/runtime/libs/misc/include/misc/feature/IndexIterator.h new file mode 100644 index 000000000..1cf675526 --- /dev/null +++ b/runtime/libs/misc/include/misc/feature/IndexIterator.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file IndexIterator.h + * @brief This file contains IndexIterator class + * @ingroup COM_AI_RUNTIME + */ + +#ifndef __NNFW_MISC_FEATURE_INDEX_ITERATOR_H__ +#define __NNFW_MISC_FEATURE_INDEX_ITERATOR_H__ + +#include "misc/feature/Shape.h" + +namespace nnfw +{ +namespace misc +{ +namespace feature +{ + +/** + * @brief Class to iterate Callable with Index of feature + */ +class IndexIterator +{ +public: + /** + * @brief Construct IndexIterator object with Shape of feature + * @param[in] shape Shape reference of feature + */ + IndexIterator(const Shape &shape) : _shape{shape} + { + // DO NOTHING + } + +public: + /** + * @brief Call a function iterated + * @param[in] cb A callback function + * @return Current IndexIterator object + */ + template IndexIterator &iter(Callable cb) + { + for (int32_t batch = 0; batch < _shape.N; ++batch) + { + for (int32_t ch = 0; ch < _shape.C; ++ch) + { + for (int32_t row = 0; row < _shape.H; ++row) + { + for (int32_t col = 0; col < _shape.W; ++col) + { + cb(batch, ch, row, col); + } + } + } + } + + return (*this); + } + +private: + /** + * @brief Shape for feature + */ + const Shape _shape; +}; + +/** + * @brief Create an object of IndexIterator for feature + * @param[in] Shape reference of feature + * @return Created IndexIterator object + */ +static inline IndexIterator iterate(const Shape &shape) { return IndexIterator{shape}; } + +/** + * @brief Call a function iterated using IndexIterator of feature + * Overloaded operator<< + * @param[in] it An IndexIterator reference + * @param[in] cb A callback function + * @return created IndexIterator object + */ +template IndexIterator &operator<<(IndexIterator &&it, Callable cb) +{ + return it.iter(cb); +} + +} // namespace feature +} // namespace misc +} // namespace nnfw + +#endif // __NNFW_MISC_FEATURE_INDEX_ITERATOR_H__ diff --git a/runtime/libs/misc/include/misc/feature/Object.h b/runtime/libs/misc/include/misc/feature/Object.h new file mode 100644 index 000000000..7af0e28f4 --- /dev/null +++ b/runtime/libs/misc/include/misc/feature/Object.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file Object.h + * @brief This file contains Object class + * @ingroup COM_AI_RUNTIME + */ + +#ifndef __NNFW_MISC_FEATURE_OBJECT_H__ +#define __NNFW_MISC_FEATURE_OBJECT_H__ + +#include "misc/feature/Shape.h" +#include "misc/feature/Index.h" +#include "misc/feature/Reader.h" + +#include + +namespace nnfw +{ +namespace misc +{ +namespace feature +{ + +/** + * @brief Class to have information of the operand for feature + */ +template class Object final : public Reader +{ +public: + using Generator = std::function; + +public: + /** + * @brief Construct Object object with Shape of feature and set value used by Generator + * @param[in] shape Reference of Shape for feature + * @param[in] fn A function to set values of operand tensor + */ + Object(const Shape &shape, const Generator &fn) : _shape{shape} + { + _value.resize(_shape.C * _shape.H * _shape.W); + + for (int32_t ch = 0; ch < _shape.C; ++ch) + { + for (int32_t row = 0; row < _shape.H; ++row) + { + for (int32_t col = 0; col < _shape.W; ++col) + { + _value.at(offsetOf(ch, row, col)) = fn(_shape, Index{ch, row, col}); + } + } + } + } + +public: + /** + * @brief Get Shape of feature as the reference + * @return The reference of the width value + */ + const Shape &shape(void) const { return _shape; } + +public: + /** + * @brief Get the value used by three indexes + * @param[in] ch The depth index + * @param[in] row The height index + * @param[in] col The width index + * @return The value at the offset + */ + T at(uint32_t ch, uint32_t row, uint32_t col) const override + { + return _value.at(offsetOf(ch, row, col)); + } + +private: + /** + * @brief Get the offset value at three indexes + * @param[in] ch The depth index + * @param[in] row The height index + * @param[in] col The width index + * @return The offset value + */ + uint32_t offsetOf(uint32_t ch, uint32_t row, uint32_t col) const + { + return ch * _shape.H * _shape.W + row * _shape.W + col; + } + +private: + /** + * @brief Shape of operand + */ + Shape _shape; + /** + * @brief The tensor vector of operand + */ + std::vector _value; +}; + +} // namespace feature +} // namespace misc +} // namespace nnfw + +#endif // __NNFW_MISC_FEATURE_OBJECT_H__ diff --git a/runtime/libs/misc/include/misc/feature/Reader.h b/runtime/libs/misc/include/misc/feature/Reader.h new file mode 100644 index 000000000..b09209789 --- /dev/null +++ b/runtime/libs/misc/include/misc/feature/Reader.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file Reader.h + * @brief This file contains Reader class + * @ingroup COM_AI_RUNTIME + */ + +#ifndef __NNFW_MISC_FEATURE_READER_H__ +#define __NNFW_MISC_FEATURE_READER_H__ + +#include + +namespace nnfw +{ +namespace misc +{ +namespace feature +{ + +/** + * @brief Class reads values of feature + * The interface class + */ +template struct Reader +{ + /** + * @brief Destruct Reader object using default destructor + */ + virtual ~Reader() = default; + + /** + * @brief Get the value used by three indexes + * @param[in] ch The depth index + * @param[in] row The height index + * @param[in] col The width index + * @return The value at the offset + */ + virtual T at(uint32_t ch, uint32_t row, uint32_t col) const = 0; + /** + * @brief Get the value used by four indexes + * @param[in] batch The batch index + * @param[in] ch The depth index + * @param[in] row The height index + * @param[in] col The width index + * @return The value at the offset + */ + virtual T at(uint32_t batch, uint32_t ch, uint32_t row, uint32_t col) const = 0; +}; + +} // namespace feature +} // namespace misc +} // namespace nnfw + +#endif // __NNFW_MISC_FEATURE_READER_H__ diff --git a/runtime/libs/misc/include/misc/feature/Shape.h b/runtime/libs/misc/include/misc/feature/Shape.h new file mode 100644 index 000000000..09881f58b --- /dev/null +++ b/runtime/libs/misc/include/misc/feature/Shape.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file Shape.h + * @brief This file contains Shape class for feature + * @ingroup COM_AI_RUNTIME + */ + +#ifndef __NNFW_MISC_FEATURE_SHAPE_H__ +#define __NNFW_MISC_FEATURE_SHAPE_H__ + +#include + +namespace nnfw +{ +namespace misc +{ +namespace feature +{ + +/** + * @brief Structure to have values of dimensions for feature + */ +struct Shape +{ + int32_t N; /**< The batch value */ + int32_t C; /**< The depth value */ + int32_t H; /**< The height value */ + int32_t W; /**< The width value */ + + /** + * @brief Construct Shape object using default constrcutor + */ + Shape() = default; + /** + * @brief Construct Shape object with three values of dimensions + * @param[in] depth The depth value + * @param[in] height The height value + * @param[in] width The width value + */ + Shape(int32_t depth, int32_t height, int32_t width) : N{1}, C{depth}, H{height}, W{width} + { + // DO NOTHING + } + /** + * @brief Construct Shape object with four values of dimensions + * @param[in] batch The batch value + * @param[in] depth The depth value + * @param[in] height The height value + * @param[in] width The width value + */ + Shape(int32_t batch, int32_t depth, int32_t height, int32_t width) + : N{batch}, C{depth}, H{height}, W{width} + { + // DO NOTHING + } +}; + +} // namespace feature +} // namespace misc +} // namespace nnfw + +#endif // __NNFW_MISC_FEATURE_H__ diff --git a/runtime/libs/misc/include/misc/feature/TextFormatter.h b/runtime/libs/misc/include/misc/feature/TextFormatter.h new file mode 100644 index 000000000..e053f1c61 --- /dev/null +++ b/runtime/libs/misc/include/misc/feature/TextFormatter.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file TextFormatter.h + * @brief This file contains TextFormatter class + * @ingroup COM_AI_RUNTIME + */ + +#ifndef __NNFW_MISC_FEATURE_TEXT_FORMATTER_H__ +#define __NNFW_MISC_FEATURE_TEXT_FORMATTER_H__ + +#include "misc/feature/Shape.h" +#include "misc/feature/Reader.h" + +#include +#include +#include + +namespace nnfw +{ +namespace misc +{ +namespace feature +{ + +/** + * @brief Class to print operand of feature to ostream in the given string format + */ +template class TextFormatter +{ +public: + /** + * @brief Construct TextFormatter object with an operand's information. + * @param[in] shape The shape of an operand + * @param[in] data The data of an operand + */ + TextFormatter(const Shape &shape, const Reader &data) : _shape(shape), _data(data) + { + // DO NOTHING + } + +public: + /** + * @brief Get Shape of feature as the lvalue reference + * @return Shape of feature + */ + const Shape &shape(void) const { return _shape; } + /** + * @brief Get Reader that can read the data of an operand + * @return Reader + */ + const Reader &data(void) const { return _data; } + +private: + /** + * @brief Shape of feature + */ + const Shape &_shape; + /** + * @brief Reader that can read the data of an operand + */ + const Reader &_data; +}; + +/** + * @brief Print operand of feature + * @param[in] os Standard output stream + * @param[in] fmt TextFormatter to print information of an operand + * @return Standard output stream + */ +template std::ostream &operator<<(std::ostream &os, const TextFormatter &fmt) +{ + const auto &shape = fmt.shape(); + + for (uint32_t ch = 0; ch < shape.C; ++ch) + { + os << " Channel " << ch << ":" << std::endl; + for (uint32_t row = 0; row < shape.H; ++row) + { + os << " "; + for (uint32_t col = 0; col < shape.W; ++col) + { + const auto value = fmt.data().at(ch, row, col); + os << std::right; + os << std::fixed; + os << std::setw(std::numeric_limits::digits10 + 2); + os << std::setprecision(5); + os << value; + os << " "; + } + os << std::endl; + } + } + + return os; +} + +} // namespace feature +} // namespace misc +} // namespace nnfw + +#endif // __NNFW_MISC_FEATURE_TEXT_FORMATTER_H__ diff --git a/runtime/libs/misc/include/misc/fp32.h b/runtime/libs/misc/include/misc/fp32.h new file mode 100644 index 000000000..c310402ba --- /dev/null +++ b/runtime/libs/misc/include/misc/fp32.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file fp32.h + * @brief This file contains functions to compare float values + * @ingroup COM_AI_RUNTIME + */ + +#ifndef __NNFW_MISC_FP32_H__ +#define __NNFW_MISC_FP32_H__ + +#include +#include +#include +#include + +namespace nnfw +{ +namespace misc +{ +namespace fp32 +{ + +/** + * @brief Get the difference between two float values as a relative value. + * @param[in] lhs A float value to be compared + * @param[in] rhs A float value to be compared + * @return A relative value of difference between two float values. + */ +inline float relative_diff(float lhs, float rhs) +{ + const auto diff = std::fabs(lhs - rhs); + const auto base = std::max(std::fabs(lhs), std::fabs(rhs)); + + return diff / base; +} + +/** + * @brief Verify that an obtained float value is equal to the expected float value + * by using FLT_EPSILON + * @param[in] expected An expected float value to be compared + * @param[in] obtained An obtained float value to be compared + * @param[in] tolerance A tolerance value + * @return @c true if both values are equal, otherwise @c false + */ +inline bool epsilon_equal(float expected, float obtained, uint32_t tolerance = 1) +{ + if (std::isnan(expected) && std::isnan(obtained)) + { + return true; + } + + // Let's use relative epsilon comparision + const auto diff = std::fabs(expected - obtained); + const auto max = std::max(std::fabs(expected), std::fabs(obtained)); + + return diff <= (max * FLT_EPSILON * tolerance); +} + +/** + * @brief Verify that an obtained float value is equal to the expected float value + * by comparing absolute tolerance value + * @param[in] expected An expected float value to be compared + * @param[in] obtained An obtained float value to be compared + * @param[in] tolerance A tolerance value + * @return @c true if both values are equal, otherwise @c false + */ +inline bool absolute_epsilon_equal(float expected, float obtained, float tolerance = 0.001) +{ + if (std::isnan(expected) && std::isnan(obtained)) + { + return true; + } + + // Let's use absolute epsilon comparision + const auto diff = std::fabs(expected - obtained); + + return diff <= tolerance; +} + +} // namespace fp32 +} // namespace misc +} // namespace nnfw + +#endif // __NNFW_MISC_FP32_H__ diff --git a/runtime/libs/misc/include/misc/kernel/IndexIterator.h b/runtime/libs/misc/include/misc/kernel/IndexIterator.h new file mode 100644 index 000000000..59e0f0095 --- /dev/null +++ b/runtime/libs/misc/include/misc/kernel/IndexIterator.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file IndexIterator.h + * @brief This file contains IndexIterator class + * @ingroup COM_AI_RUNTIME + */ + +#ifndef __NNFW_MISC_KERNEL_INDEX_ITERATOR_H__ +#define __NNFW_MISC_KERNEL_INDEX_ITERATOR_H__ + +#include "misc/kernel/Shape.h" + +namespace nnfw +{ +namespace misc +{ +namespace kernel +{ + +/** + * @brief Class to iterate Callable with Index of kernel + */ +class IndexIterator +{ +public: + /** + * @brief Construct IndexIterator object with Shape of kernel + * @param[in] shape Shape reference of feature + */ + IndexIterator(const Shape &shape) : _shape{shape} + { + // DO NOTHING + } + +public: + /** + * @brief Call a function iterated + * @param[in] cb A callback function + * @return Current IndexIterator object + */ + template IndexIterator &iter(Callable cb) + { + for (int32_t nth = 0; nth < _shape.N; ++nth) + { + for (int32_t ch = 0; ch < _shape.C; ++ch) + { + for (int32_t row = 0; row < _shape.H; ++row) + { + for (int32_t col = 0; col < _shape.W; ++col) + { + cb(nth, ch, row, col); + } + } + } + } + + return (*this); + } + +private: + const Shape _shape; /**< Shape for kernel */ +}; + +/** + * @brief Create an object of IndexIterator for kernel + * @param[in] shape reference of feature + * @return Created IndexIterator object + */ +inline IndexIterator iterate(const Shape &shape) { return IndexIterator{shape}; } + +/** + * @brief Call a function iterated using IndexIterator of kernel + * Overloaded operator<< + * @param[in] it An IndexIterator reference + * @param[in] cb A callback function + * @return Created IndexIterator object + */ +template IndexIterator &operator<<(IndexIterator &&it, Callable cb) +{ + return it.iter(cb); +} + +} // namespace kernel +} // namespace misc +} // namespace nnfw + +#endif // __NNFW_MISC_FEATURE_INDEX_ITERATOR_H__ diff --git a/runtime/libs/misc/include/misc/kernel/Reader.h b/runtime/libs/misc/include/misc/kernel/Reader.h new file mode 100644 index 000000000..019c809ee --- /dev/null +++ b/runtime/libs/misc/include/misc/kernel/Reader.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file Reader.h + * @brief This file contains Reader structure + * @ingroup COM_AI_RUNTIME + */ + +#ifndef __NNFW_MISC_KERNEL_READER_H__ +#define __NNFW_MISC_KERNEL_READER_H__ + +#include + +namespace nnfw +{ +namespace misc +{ +namespace kernel +{ + +/** + * @brief Structure to Reader + */ +template struct Reader +{ + /** + * @brief Destroy the Reader object as default + */ + virtual ~Reader() = default; + + /** + * @brief Get the value used by four indexes + * @param[in] nth The kernel index + * @param[in] ch The channel index + * @param[in] row The row index + * @param[in] col The column index + * @return The value at the offset + */ + virtual T at(uint32_t nth, uint32_t ch, uint32_t row, uint32_t col) const = 0; +}; + +} // namespace kernel +} // namespace misc +} // namespace nnfw + +#endif // __NNFW_MISC_KERNEL_READER_H__ diff --git a/runtime/libs/misc/include/misc/kernel/Shape.h b/runtime/libs/misc/include/misc/kernel/Shape.h new file mode 100644 index 000000000..27d6a8bf0 --- /dev/null +++ b/runtime/libs/misc/include/misc/kernel/Shape.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file Shape.h + * @brief This file contains Shape structure + * @ingroup COM_AI_RUNTIME + */ + +#ifndef __NNFW_MISC_KERNEL_SHAPE_H__ +#define __NNFW_MISC_KERNEL_SHAPE_H__ + +#include + +namespace nnfw +{ +namespace misc +{ +namespace kernel +{ + +/** + * @brief Structure to Shape + */ +struct Shape +{ + int32_t N; /**< The kernel index */ + int32_t C; /**< The channel index */ + int32_t H; /**< The height index */ + int32_t W; /**< The width index */ + + /** + * @brief Construct a new Shape object as default + */ + Shape() = default; + + /** + * @brief Construct a new Shape object with parameters + * @param[in] count The kernel index + * @param[in] depth The channel index + * @param[in] height The height index + * @param[in] width The width index + */ + Shape(int32_t count, int32_t depth, int32_t height, int32_t width) + : N{count}, C{depth}, H{height}, W{width} + { + // DO NOTHING + } +}; + +} // namespace kernel +} // namespace misc +} // namespace nnfw + +#endif // __NNFW_MISC_KERNEL_SHAPE_H__ diff --git a/runtime/libs/misc/include/misc/matrix/IndexIterator.h b/runtime/libs/misc/include/misc/matrix/IndexIterator.h new file mode 100644 index 000000000..742ed3a65 --- /dev/null +++ b/runtime/libs/misc/include/misc/matrix/IndexIterator.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file IndexIterator.h + * @brief This file contains IndexIterator class + * @ingroup COM_AI_RUNTIME + */ + +#ifndef __NNFW_MISC_MATRIX_INDEX_ITERATOR_H__ +#define __NNFW_MISC_MATRIX_INDEX_ITERATOR_H__ + +#include "misc/matrix/Shape.h" + +namespace nnfw +{ +namespace misc +{ +namespace matrix +{ + +/** + * @brief Class to iterate Callable with Index of matrix + */ +class IndexIterator +{ +public: + /** + * @brief Construct IndexIterator object with Shape of matrix + * @param[in] shape Shape reference of matrix + */ + IndexIterator(const Shape &shape) : _shape{shape} + { + // DO NOTHING + } + +public: + /** + * @brief Call a function iterated + * @param[in] cb A callback function + * @return Current IndexIterator object + */ + template IndexIterator &iter(Callable cb) + { + for (uint32_t row = 0; row < _shape.H; ++row) + { + for (uint32_t col = 0; col < _shape.W; ++col) + { + cb(row, col); + } + } + + return (*this); + } + +private: + /** + * @brief Shape for matrix + */ + const Shape _shape; +}; + +/** + * @brief Create an object of IndexIterator for matrix + * @param[in] Shape reference of matrix + * @return Created IndexIterator object + */ +inline IndexIterator iterate(const Shape &shape) { return IndexIterator{shape}; } + +/** + * @brief Call a function iterated using IndexIterator of matrix + * Overloaded operator<< + * @param[in] it An IndexIterator reference + * @param[in] cb A callback function + * @return created IndexIterator object + */ +template IndexIterator &operator<<(IndexIterator &&it, Callable cb) +{ + return it.iter(cb); +} + +} // namespace matrix +} // namespace misc +} // namespace nnfw + +#endif // __NNFW_MISC_MATRIX_INDEX_ITERATOR_H__ diff --git a/runtime/libs/misc/include/misc/matrix/Reader.h b/runtime/libs/misc/include/misc/matrix/Reader.h new file mode 100644 index 000000000..ea222c9d1 --- /dev/null +++ b/runtime/libs/misc/include/misc/matrix/Reader.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file Reader.h + * @brief This file contains Reader class + * @ingroup COM_AI_RUNTIME + */ + +#ifndef __NNFW_MISC_MATRIX_READER_H__ +#define __NNFW_MISC_MATRIX_READER_H__ + +#include + +namespace nnfw +{ +namespace misc +{ +namespace matrix +{ + +/** + * @brief Class reads values of matrix + * The interface class + */ +template struct Reader +{ + /** + * @brief Destruct Reader object using default destructor + */ + virtual ~Reader() = default; + + /** + * @brief Get the value used by two indexes + * @param[in] row The height index + * @param[in] col The width index + * @return The value at the offset + */ + virtual T at(uint32_t row, uint32_t col) const = 0; +}; + +} // namespace matrix +} // namespace misc +} // namespace nnfw + +#endif // __NNFW_MISC_MATRIX_READER_H__ diff --git a/runtime/libs/misc/include/misc/matrix/Shape.h b/runtime/libs/misc/include/misc/matrix/Shape.h new file mode 100644 index 000000000..8cbcc1e12 --- /dev/null +++ b/runtime/libs/misc/include/misc/matrix/Shape.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file Shape.h + * @brief This file contains Shape class for matrix + * @ingroup COM_AI_RUNTIME + */ + +#ifndef __NNFW_MISC_MATRIX_SHAPE_H__ +#define __NNFW_MISC_MATRIX_SHAPE_H__ + +#include + +namespace nnfw +{ +namespace misc +{ +namespace matrix +{ + +/** + * @brief Structure to have values of dimensions for matrix + */ +struct Shape +{ + int32_t H; /**< The height value */ + int32_t W; /**< The width value */ + + /** + * @brief Construct Shape object using default constrcutor + */ + Shape() = default; + + /** + * @brief Construct Shape object with two values of dimensions + * @param[in] height The height value + * @param[in] width The width value + */ + Shape(int32_t height, int32_t width) : H{height}, W{width} + { + // DO NOTHING + } +}; + +} // namespace matrix +} // namespace misc +} // namespace nnfw + +#endif // __NNFW_MISC_MATRIX_SHAPE_H__ diff --git a/runtime/libs/misc/include/misc/polymorphic_downcast.h b/runtime/libs/misc/include/misc/polymorphic_downcast.h new file mode 100644 index 000000000..ee885eb70 --- /dev/null +++ b/runtime/libs/misc/include/misc/polymorphic_downcast.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NNFW_MISC_POLYMORPHIC_DOWNCAST_H__ +#define __NNFW_MISC_POLYMORPHIC_DOWNCAST_H__ + +#include +#include + +namespace nnfw +{ +namespace misc +{ + +template inline DstType polymorphic_downcast(SrcType *x) +{ + assert(dynamic_cast(x) == x); + return static_cast(x); +} + +template inline DstType polymorphic_downcast(SrcType &x) +{ + assert(std::addressof(dynamic_cast(x)) == std::addressof(x)); + return static_cast(x); +} + +} // namespace misc +} // namespace nnfw + +#endif // __NNFW_MISC_POLYMORPHIC_DOWNCAST_H__ diff --git a/runtime/libs/misc/include/misc/string_helpers.h b/runtime/libs/misc/include/misc/string_helpers.h new file mode 100644 index 000000000..e42a12754 --- /dev/null +++ b/runtime/libs/misc/include/misc/string_helpers.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file string_helpers.h + * @ingroup COM_AI_RUNTIME + * @brief This file contains helper functions for std::string + */ + +#include +#include +#include +#include + +namespace +{ + +template void _str(std::ostream &os, Arg &&arg) { os << std::forward(arg); } + +template void _str(std::ostream &os, Arg &&arg, Args &&... args) +{ + _str(os, std::forward(arg)); + _str(os, std::forward(args)...); +} + +} // namespace {anonymous} + +namespace nnfw +{ +namespace misc +{ + +inline std::vector split(const std::string &s, char delim) +{ + std::stringstream ss(s); + std::string item; + std::vector elems; + while (std::getline(ss, item, delim)) + { + elems.push_back(std::move(item)); + } + return elems; +} + +template std::string str(Args &&... args) +{ + std::stringstream ss; + _str(ss, std::forward(args)...); + return ss.str(); +} + +} // namespace misc +} // namespace nnfw diff --git a/runtime/libs/misc/include/misc/tensor/Comparator.h b/runtime/libs/misc/include/misc/tensor/Comparator.h new file mode 100644 index 000000000..80f53043c --- /dev/null +++ b/runtime/libs/misc/include/misc/tensor/Comparator.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file Comparator.h + * @ingroup COM_AI_RUNTIME + * @brief This file contains nnfw::misc::tensor::Comparator class + */ + +#ifndef __NNFW_MISC_TENSOR_COMPARATOR_H__ +#define __NNFW_MISC_TENSOR_COMPARATOR_H__ + +#include "misc/tensor/Index.h" +#include "misc/tensor/Shape.h" +#include "misc/tensor/Reader.h" +#include "misc/tensor/Diff.h" + +#include + +#include + +namespace nnfw +{ +namespace misc +{ +namespace tensor +{ + +/** + * @brief Class to compare two tensors (expected and obtained to compare) + */ +class Comparator +{ +public: + /** + * @brief Construct a new @c Comparator object + * @param[in] fn Function that compares two float values + */ + Comparator(const std::function &fn) : _compare_fn{fn} + { + // DO NOTHING + } + +public: + /** + * @brief Struct to observe comparison results + */ + struct Observer + { + /** + * @brief Get notification of comparison result at every index of two tensors + * @param[in] index Index of tensors compared + * @param[in] expected Expected value of element at @c index + * @param[in] obtained Obtained value of element at @c index + * @return N/A + */ + virtual void notify(const Index &index, float expected, float obtained) = 0; + }; + +public: + /** + * @brief Compare two tensors + * @param[in] shape Shape of two tensors + * @param[in] expected @c Reader object that accesses expected tensor + * @param[in] obtained @c Reader object that accesses obtained tensor + * @param[in] observer @c Observer notified of expected value and obtained value at every index + * @return @c std::vector> containing information of failed comparison + */ + // NOTE Observer should live longer than comparator + std::vector> compare(const Shape &shape, const Reader &expected, + const Reader &obtained, + Observer *observer = nullptr) const; + +private: + std::function _compare_fn; +}; + +} // namespace tensor +} // namespace misc +} // namespace nnfw + +#endif // __NNFW_MISC_TENSOR_COMPARATOR_H__ diff --git a/runtime/libs/misc/include/misc/tensor/Diff.h b/runtime/libs/misc/include/misc/tensor/Diff.h new file mode 100644 index 000000000..c41a97987 --- /dev/null +++ b/runtime/libs/misc/include/misc/tensor/Diff.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file Diff.h + * @ingroup COM_AI_RUNTIME + * @brief This file contains nnfw::misc::tensor::Diff struct + */ + +#ifndef __NNFW_MISC_TENSOR_DIFF_H__ +#define __NNFW_MISC_TENSOR_DIFF_H__ + +#include "misc/tensor/Index.h" + +namespace nnfw +{ +namespace misc +{ +namespace tensor +{ + +/** + * @brief Struct to have information after comparing two elements of two tensors + */ +template struct Diff +{ + Index index; /**< Index of elements in two tensors, which turn out to be different */ + + T expected; /**< Expected value of element of first tensor */ + T obtained; /**< Obtained value of element of second tensor */ + + /** + * @brief Construct a new @c Diff object + * @param[in] i Initial value of index + */ + Diff(const Index &i) : index(i) + { + // DO NOTHING + } + + /** + * @brief Construct a new @c Diff object + * @param[in] i Index value + * @param[in] e Expected value of element of first tensor + * @param[in] o Obtained value of element of second tensor + */ + Diff(const Index &i, const T &e, const T &o) : index(i), expected{e}, obtained{o} + { + // DO NOTHING + } +}; + +} // namespace tensor +} // namespace misc +} // namespace nnfw + +#endif // __NNFW_MISC_TENSOR_DIFF_H__ diff --git a/runtime/libs/misc/include/misc/tensor/Index.h b/runtime/libs/misc/include/misc/tensor/Index.h new file mode 100644 index 000000000..a633b4ce0 --- /dev/null +++ b/runtime/libs/misc/include/misc/tensor/Index.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file Index.h + * @ingroup COM_AI_RUNTIME + * @brief This file contains nnfw::misc::tensor::Index struct + */ +#ifndef __NNFW_MISC_TENSOR_INDEX_H__ +#define __NNFW_MISC_TENSOR_INDEX_H__ + +#include +#include + +#include +#include + +namespace nnfw +{ +namespace misc +{ +namespace tensor +{ + +/** + * @brief Struct to represent index of each dimension of a tensor + */ +struct Index +{ +public: + /** + * @brief Construct a new @c Index object + * @param[in] rank Rank of a tensor + */ + Index(uint32_t rank) { _offsets.resize(rank); } + +public: + /** + * @brief Construct a new @c Index object + * @param[in] offsets Rank of a tensor of @c std::initializer_list type + */ + Index(std::initializer_list offsets) : _offsets{offsets} + { + // DO NOTHING + } + +public: + /** + * @brief Get the rank + * @return Rank that this @c Index object can handle + * @note We can use static_cast\n + * because size of _offsets is decieded by constructor's uintt_32 type argument + */ + uint32_t rank(void) const { return static_cast(_offsets.size()); } + +public: + /** + * @brief Get the index n'th dimension + * @param[in] n Dimension + * @return index of n'th dimension + */ + int32_t at(uint32_t n) const { return _offsets.at(n); } + + /** + * @brief Get the reference of the index n'th dimension + * @param[in] n Dimension + * @return reference of index of n'th dimension + */ + int32_t &at(uint32_t n) { return _offsets.at(n); } + +private: + std::vector _offsets; +}; + +/** + * @brief Copy an @c Index with reversed order + * @param[in] origin @c Index object to copy + * @return an @c Index object with reversed order + * @note This is used to convert NNAPI tensor index to ARM tensor index or vice versa + */ +inline static Index copy_reverse(const Index &origin) +{ + uint32_t rank = origin.rank(); + Index target(rank); + for (uint32_t i = 0; i < rank; i++) + target.at(i) = origin.at(rank - 1 - i); + return target; +} + +} // namespace tensor +} // namespace misc +} // namespace nnfw + +#endif // __NNFW_MISC_TENSOR_INDEX_H__ diff --git a/runtime/libs/misc/include/misc/tensor/IndexEnumerator.h b/runtime/libs/misc/include/misc/tensor/IndexEnumerator.h new file mode 100644 index 000000000..6ce3add77 --- /dev/null +++ b/runtime/libs/misc/include/misc/tensor/IndexEnumerator.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file IndexEnumerator.h + * @ingroup COM_AI_RUNTIME + * @brief This file contains nnfw::misc::tensor::IndexEnumerator class + */ + +#ifndef __NNFW_MISC_TENSOR_INDEX_ENUMERATOR_H__ +#define __NNFW_MISC_TENSOR_INDEX_ENUMERATOR_H__ + +#include "misc/tensor/Shape.h" +#include "misc/tensor/Index.h" + +namespace nnfw +{ +namespace misc +{ +namespace tensor +{ +/** + * @brief Class to enumerate index of a tensor + * + */ +class IndexEnumerator +{ +public: + /** + * @brief Construct a new @c IndexEnumerator object + * @param[in] shape Shape of tensor of which index will be enumerate + */ + explicit IndexEnumerator(const Shape &shape) : _shape(shape), _cursor(0), _index(shape.rank()) + { + const uint32_t rank = _shape.rank(); + + for (uint32_t axis = 0; axis < rank; ++axis) + { + _index.at(axis) = 0; + } + + for (_cursor = 0; _cursor < rank; ++_cursor) + { + if (_index.at(_cursor) < _shape.dim(_cursor)) + { + break; + } + } + } + +public: + /** + * @brief Prevent constructing @c IndexEnumerator object by using R-value reference + */ + IndexEnumerator(IndexEnumerator &&) = delete; + /** + * @brief Prevent copy constructor + */ + IndexEnumerator(const IndexEnumerator &) = delete; + +public: + /** + * @brief Check if more enumeration is available + * @return @c true if more @c advance() is available, otherwise @c false + */ + bool valid(void) const { return _cursor < _shape.rank(); } + +public: + /** + * @brief Get the current index to enumerate + * @return Current index + */ + const Index &curr(void) const { return _index; } + +public: + /** + * @brief Advance index by +1 + */ + void advance(void) + { + const uint32_t rank = _shape.rank(); + + // Find axis to be updated + while ((_cursor < rank) && !(_index.at(_cursor) + 1 < _shape.dim(_cursor))) + { + ++_cursor; + } + + if (_cursor == rank) + { + return; + } + + // Update index + _index.at(_cursor) += 1; + + for (uint32_t axis = 0; axis < _cursor; ++axis) + { + _index.at(axis) = 0; + } + + // Update cursor + _cursor = 0; + } + +public: + const Shape _shape; //!< Shape to enumerate + +private: + uint32_t _cursor; + Index _index; +}; + +} // namespace tensor +} // namespace misc +} // namespace nnfw + +#endif // __NNFW_MISC_TENSOR_INDEX_ENUMERATOR_H__ diff --git a/runtime/libs/misc/include/misc/tensor/IndexFormatter.h b/runtime/libs/misc/include/misc/tensor/IndexFormatter.h new file mode 100644 index 000000000..7ae34eec1 --- /dev/null +++ b/runtime/libs/misc/include/misc/tensor/IndexFormatter.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file IndexFormatter.h + * @ingroup COM_AI_RUNTIME + * @brief This file contains nnfw::misc::tensor::IndexFormatter class + */ + +#ifndef __NNFW_MISC_TENSOR_INDEX_FORMATTER_H__ +#define __NNFW_MISC_TENSOR_INDEX_FORMATTER_H__ + +#include "misc/tensor/Index.h" + +#include + +namespace nnfw +{ +namespace misc +{ +namespace tensor +{ + +/** + * @brief Class to send @c Index object to output stream + */ +class IndexFormatter +{ +public: + /** + * @brief Construct a new @c IndexFormatter object + * @param[in] index index to be sent to output stream + */ + IndexFormatter(const nnfw::misc::tensor::Index &index) : _index(index) + { + // DO NOTHING + } + +public: + /** + * @brief Get an @c Index object + * @return @c Index object previously passed to the constructor + */ + const nnfw::misc::tensor::Index &index(void) const { return _index; } + +private: + const nnfw::misc::tensor::Index &_index; +}; + +/** + * @brief Send @c IndexFormatter object to output stream + * @param[in] os Output stream + * @param[in] fmt @c IndexFormatter object that is sent to output stream + * @return Output stream + */ +std::ostream &operator<<(std::ostream &os, const IndexFormatter &fmt); + +} // namespace tensor +} // namespace misc +} // namespace nnfw + +#endif // __NNFW_MISC_TENSOR_INDEX_FORMATTER_H__ diff --git a/runtime/libs/misc/include/misc/tensor/IndexIterator.h b/runtime/libs/misc/include/misc/tensor/IndexIterator.h new file mode 100644 index 000000000..f6428e19e --- /dev/null +++ b/runtime/libs/misc/include/misc/tensor/IndexIterator.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file IndexIterator.h + * @ingroup COM_AI_RUNTIME + * @brief This file contains nnfw::misc::tensor::IndexIterator class and + * helper function and operator + */ +#ifndef __NNFW_MISC_TENSOR_INDEX_ITERATOR_H__ +#define __NNFW_MISC_TENSOR_INDEX_ITERATOR_H__ + +#include "misc/tensor/Shape.h" +#include "misc/tensor/Index.h" +#include "misc/tensor/IndexEnumerator.h" + +namespace nnfw +{ +namespace misc +{ +namespace tensor +{ + +/** + * @brief Class to iterate indexes available for given shape + */ +class IndexIterator +{ +public: + /** + * @brief Construct a new @c IndexIterator object + * @param[in] shape Shape of tensor of which index will be iterated + */ + IndexIterator(const Shape &shape) : _shape(shape) + { + // DO NOTHING + } + +public: + /** + * @brief Construct a new IndexIterator object using reference + * @param[in] IndexIterator @c IndexIterator object to move + */ + IndexIterator(IndexIterator &&) = default; + + /** + * @brief Prevent copy constructor + */ + IndexIterator(const IndexIterator &) = delete; + +public: + /** + * @brief Iterate all available indexes and run a function for each index + * @param[in] fn Function that requires an index as a parameter. + * @return @c IndexIterator object + */ + template IndexIterator &iter(Callable fn) + { + for (IndexEnumerator e{_shape}; e.valid(); e.advance()) + { + fn(e.curr()); + } + + return (*this); + } + +private: + const Shape &_shape; +}; + +/** + * @brief Get an @c IndexItator object + * @param[in] shape Shape of tensor of which index will be iterated + * @return @c IndexIterator object + */ +inline IndexIterator iterate(const Shape &shape) { return IndexIterator{shape}; } + +/** + * @brief Iterate all indexes and apply a function + * @param[in] it @c IndexIterator object that is constructed with a tensor shape + * @param[in] cb A function that will receive a specific index. + * Inside the function, the index is used to manipulate tensor element. + * @return @c IndexIterator object + */ +template IndexIterator &operator<<(IndexIterator &&it, Callable cb) +{ + return it.iter(cb); +} + +} // namespace tensor +} // namespace misc +} // namespace nnfw + +#endif // __NNFW_MISC_TENSOR_INDEX_ITERATOR_H__ diff --git a/runtime/libs/misc/include/misc/tensor/NonIncreasingStride.h b/runtime/libs/misc/include/misc/tensor/NonIncreasingStride.h new file mode 100644 index 000000000..3bc0c115c --- /dev/null +++ b/runtime/libs/misc/include/misc/tensor/NonIncreasingStride.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file NonIncreasingStride.h + * @ingroup COM_AI_RUNTIME + * @brief This file contains nnfw::misc::tensor::NonIncreasingStride class + */ +#ifndef __NNFW_MISC_TENSOR_NON_INCREASING_STRIDE_H__ +#define __NNFW_MISC_TENSOR_NON_INCREASING_STRIDE_H__ + +#include "misc/tensor/Shape.h" +#include "misc/tensor/Index.h" + +#include + +namespace nnfw +{ +namespace misc +{ +namespace tensor +{ + +/** + * @brief Class to represent strides where stride[N-1] >= stride[N] holds for all N < rank + */ +class NonIncreasingStride +{ +public: + /** + * @brief Initialize the stride data using @c Shape + * @param[in] shape to build stride info + * @return N/A + */ + void init(const Shape &shape) + { + _stride.resize(shape.rank()); + + // Scalar + if (shape.rank() == 0) + return; + + _stride.at(shape.rank() - 1) = 1; + + for (uint32_t axis = shape.rank() - 1; axis > 0; --axis) + { + _stride.at(axis - 1) = _stride.at(axis) * shape.dim(axis); + } + } + +public: + /** + * @brief Get an stride value for specific axis + * @param[in] axis Axis of stride + * @return The value of stride + */ + uint32_t at(uint32_t axis) const { return _stride.at(axis); } + +public: + /** + * @brief Get the 1-D offset of specified index for n-D tensor + * @param index @c Index object + * @return 1-D offset of index + */ + uint32_t offset(const Index &index) const; + +private: + std::vector _stride; +}; + +} // namespace tensor +} // namespace misc +} // namespace nnfw + +#endif // __NNFW_MISC_TENSOR_NON_INCREASING_STRIDE_H__ diff --git a/runtime/libs/misc/include/misc/tensor/Object.h b/runtime/libs/misc/include/misc/tensor/Object.h new file mode 100644 index 000000000..cba4f1baf --- /dev/null +++ b/runtime/libs/misc/include/misc/tensor/Object.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file Object.h + * @ingroup COM_AI_RUNTIME + * @brief This file contains nnfw::misc::tensor::Object class + */ + +#ifndef __NNFW_MISC_TENSOR_OBJECT_H__ +#define __NNFW_MISC_TENSOR_OBJECT_H__ + +#include "misc/tensor/Shape.h" +#include "misc/tensor/Index.h" +#include "misc/tensor/IndexIterator.h" +#include "misc/tensor/NonIncreasingStride.h" +#include "misc/tensor/Reader.h" + +#include + +namespace nnfw +{ +namespace misc +{ +namespace tensor +{ + +/** + * @brief Class to build a tensor using specific generator + * @tparam T Type of tensor element + */ + +template class Object final : public Reader +{ +public: + /** + * @brief Function to generate tensor element + */ + using Generator = std::function; + +public: + /** + * @brief Construct a new @c Object object + * @param[in] shape Tensor shape + * @param[in] fn Function to generate tensor elements + */ + Object(const Shape &shape, const Generator &fn) : _shape{shape} + { + // Set 'stride' + _stride.init(shape); + + // Handle scalar object + if (shape.rank() == 0) + { + _values.resize(1); + _values.at(0) = fn(_shape, 0); + } + else + { + // Pre-allocate buffer + _values.resize(_shape.dim(0) * _stride.at(0)); + + // Set 'value' + iterate(_shape) << [this, &fn](const Index &index) { + _values.at(_stride.offset(index)) = fn(_shape, index); + }; + } + } + +public: + /** + * @brief Get reference of shape + * @return Reference of shape + */ + const Shape &shape(void) const { return _shape; } + +public: + /** + * @brief Get and element of tensor + * @param[in] index Index of a tensor element + * @return Value of tensor element + */ + T at(const Index &index) const override { return _values.at(_stride.offset(index)); } + +private: + Shape _shape; + NonIncreasingStride _stride; + +private: + std::vector _values; +}; + +} // namespace tensor +} // namespace misc +} // namespace nnfw + +#endif // __NNFW_MISC_FEATURE_OBJECT_H__ diff --git a/runtime/libs/misc/include/misc/tensor/Reader.h b/runtime/libs/misc/include/misc/tensor/Reader.h new file mode 100644 index 000000000..9175a913e --- /dev/null +++ b/runtime/libs/misc/include/misc/tensor/Reader.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file Reader.h + * @ingroup COM_AI_RUNTIME + * @brief This file contains nnfw::misc::tensor::Reader struct + */ + +#ifndef __NNFW_MISC_TENSOR_READER_H__ +#define __NNFW_MISC_TENSOR_READER_H__ + +#include "misc/tensor/Index.h" + +namespace nnfw +{ +namespace misc +{ +namespace tensor +{ + +/** + * @brief Struct to read element of tensor + * @tparam T Type of elements in tensor + */ +template struct Reader +{ + /** + * @brief Destroy the Reader object + */ + virtual ~Reader() = default; + + /** + * @brief Get an element of tensor + * @param[in] index Index specifying indexes of tensor element + * @return The value of specificed element + */ + virtual T at(const Index &index) const = 0; +}; + +} // namespace tensor +} // namespace misc +} // namespace nnfw + +#endif // __NNFW_MISC_TENSOR_READER_H__ diff --git a/runtime/libs/misc/include/misc/tensor/Shape.h b/runtime/libs/misc/include/misc/tensor/Shape.h new file mode 100644 index 000000000..bd0eac0a5 --- /dev/null +++ b/runtime/libs/misc/include/misc/tensor/Shape.h @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file Shape.h + * @ingroup COM_AI_RUNTIME + * @brief This file contains nnfw::misc::tensor::Shape class + */ + +#ifndef __NNFW_MISC_TENSOR_SHAPE_H__ +#define __NNFW_MISC_TENSOR_SHAPE_H__ + +#include +#include +#include +#include +#include +#include +#include + +namespace nnfw +{ +namespace misc +{ +namespace tensor +{ + +/** + * @brief Class to represent shape of a tensor + */ +class Shape +{ +public: + /** + * @brief Construct a new Shape object + * @param[in] rank Rank of a tensor + */ + Shape(uint32_t rank) { _dimensions.resize(rank); } + +public: + /** + * @brief Construct a new Shape object + * @param[in] dimensions @c initializer_list of dimensions of tensor + */ + Shape(const std::initializer_list &dimensions) : _dimensions{dimensions} + { + // Check overflow because initializer_list type can be larger size than max of uint32_t + assert(dimensions.size() <= 0xFFFFFFFF); + } + + /** + * @brief Construct a new Shape object + * @param[in] origin @c Shape object to copy + */ + Shape(const Shape &origin) = default; + +public: + /** + * @brief Add dimension to the beginning + * @param[in] d dimension to add to the beginning + * @return N/A + */ + void prepend(int32_t d) { _dimensions.emplace_front(d); } + + /** + * @brief Add dimension to the back + * @param[in] d dimension to add to the back + * @return N/A + */ + void append(int32_t d) { _dimensions.emplace_back(d); } + +public: + /** + * @brief Get the rank of this shape + * @return rank + * @note We can use static_cast\n + * because we don't support larger than max of uint32_t on constructor + */ + uint32_t rank(void) const { return static_cast(_dimensions.size()); } + +public: + /** + * @brief Get specific dimension + * @param[in] n Index of dimension + * @return n'th dimension + */ + int32_t dim(uint32_t n) const { return _dimensions.at(n); } + + /** + * @brief Get the reference of specific dimension + * @param[in] n Index of dimension + * @return Reference of n'th dimension + */ + int32_t &dim(uint32_t n) { return _dimensions.at(n); } + + const std::deque &dims() const { return _dimensions; } + +public: + /** + * @brief Get the number of elements specified by this shape + * @return The number of elements + */ + uint64_t num_elements() const; + +private: + std::deque _dimensions; + +public: + /** + * @brief Get a @c Shape object after parsing string + * @param[in] s String of dimension list. Accepted format is numbers separated by comma. + * @return @c Shape object + */ + static Shape from(const std::string &s); +}; + +/** + * @brief Check equality of two @c Shape + * @param[in] Shape First shape to compare + * @param[in] Shape Second shape to compare + * @return @c true if both shapes are equal, otherwise @c false + */ +bool operator==(const Shape &, const Shape &); + +/** + * @brief Send @c Shape to @c std::ostream + * @param[in] os @c std::ostream to process this @c Shape + * @param[in] shape @c Shape to send to @c ostream + * @return Reference of @c std::ostream + */ +std::ostream &operator<<(std::ostream &os, const Shape &shape); + +} // namespace tensor +} // namespace misc +} // namespace nnfw + +#endif // __NNFW_MISC_TENSOR_SHAPE_H__ diff --git a/runtime/libs/misc/include/misc/tensor/Zipper.h b/runtime/libs/misc/include/misc/tensor/Zipper.h new file mode 100644 index 000000000..8f0ec4ab6 --- /dev/null +++ b/runtime/libs/misc/include/misc/tensor/Zipper.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file Zipper.h + * @ingroup COM_AI_RUNTIME + * @brief This file contains nnfw::misc::tensor::Zipper class + */ + +#ifndef __NNFW_MISC_TENSOR_ZIPPER_H__ +#define __NNFW_MISC_TENSOR_ZIPPER_H__ + +#include "misc/tensor/Index.h" +#include "misc/tensor/IndexIterator.h" +#include "misc/tensor/Reader.h" + +namespace nnfw +{ +namespace misc +{ +namespace tensor +{ + +/** + * @brief Class to apply a function with three params: @c Index, elements of a tensor + * at passed index read by @c Reader objects + */ +template class Zipper +{ +public: + /** + * @brief Construct a new @c Zipper object + * @param[in] shape Shape of @c lhs and @c rhs + * @param[in] lhs @c Reader object of a tensor + * @param[in] rhs @c Reader object of a tensor + */ + Zipper(const Shape &shape, const Reader &lhs, const Reader &rhs) + : _shape{shape}, _lhs{lhs}, _rhs{rhs} + { + // DO NOTHING + } + +public: + /** + * @brief Apply @c cb to all elements of tensors. Elements of two tensors + * at passed @c index are read by @c lhs and @c rhs + * @param[in] cb Function to apply + * @return N/A + */ + template void zip(Callable cb) const + { + iterate(_shape) << + [this, &cb](const Index &index) { cb(index, _lhs.at(index), _rhs.at(index)); }; + } + +private: + const Shape &_shape; + const Reader &_lhs; + const Reader &_rhs; +}; + +/** + * @brief Apply @c cb by using @c lhs and @c rhs passed to the constructor of @c zipper + * @param[in] zipper @c Zipper object + * @param[in] cb Function to zpply using @c zip function + * @return @c zipper object after applying @c cb to @c zipper + */ +template +const Zipper &operator<<(const Zipper &zipper, Callable cb) +{ + zipper.zip(cb); + return zipper; +} + +/** + * @brief Get @c Zipper object constructed using passed params + * @param shape Shape of @c lhs and @c rhs + * @param lhs @c Reader object of a tensor + * @param rhs @c Reader object of a tensor + * @return @c Zipper object + */ +template Zipper zip(const Shape &shape, const Reader &lhs, const Reader &rhs) +{ + return Zipper{shape, lhs, rhs}; +} + +} // namespace tensor +} // namespace misc +} // namespace nnfw + +#endif // __NNFW_MISC_TENSOR_ZIPPER_H__ diff --git a/runtime/libs/misc/include/misc/vector.h b/runtime/libs/misc/include/misc/vector.h new file mode 100644 index 000000000..395b08912 --- /dev/null +++ b/runtime/libs/misc/include/misc/vector.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file vector.h + * @ingroup COM_AI_RUNTIME + * @brief This file contains @c == operator to check equality of elements in two vectors + */ +#ifndef __NNFW_MISC_VECTOR_H__ +#define __NNFW_MISC_VECTOR_H__ + +#include + +/** + * @brief Compare elements of two vectors + * @tparam T Type of elements in vectors + * @param[in] lhs First vector to compare + * @param[in] rhs Second vector to compare + * @return @c true if all elements are equal, otherwise @c false. + */ +template bool operator==(const std::vector &lhs, const std::vector &rhs) +{ + if (lhs.size() != rhs.size()) + { + return false; + } + + for (size_t ind = 0; ind < lhs.size(); ++ind) + { + if (lhs.at(ind) != rhs.at(ind)) + { + return false; + } + } + + return true; +} + +#endif // __NNFW_MISC_VECTOR_H__ diff --git a/runtime/libs/misc/include/misc/vector/Object.h b/runtime/libs/misc/include/misc/vector/Object.h new file mode 100644 index 000000000..65d4bc613 --- /dev/null +++ b/runtime/libs/misc/include/misc/vector/Object.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file Object.h + * @brief This file contains Object class + * @ingroup COM_AI_RUNTIME + */ + +#ifndef __NNFW_MISC_VECTOR_OBJECT_H__ +#define __NNFW_MISC_VECTOR_OBJECT_H__ + +#include "misc/vector/Reader.h" + +#include +#include + +namespace nnfw +{ +namespace misc +{ +namespace vector +{ + +/** + * @brief Class to have information of the operand for vector + */ +template class Object final : public Reader +{ +public: + using Generator = std::function; + +public: + /** + * @brief Construct Object object with size of vector and set value used by Generator + * @param[in] size The size of vector + * @param[in] gen A function to set values of operand tensor + */ + Object(int32_t size, const Generator &gen) : _size{size} + { + _value.resize(_size); + + for (int32_t offset = 0; offset < size; ++offset) + { + _value.at(offset) = gen(size, offset); + } + } + +public: + /** + * @brief Get size of vector + * @return Size of vector + */ + int32_t size(void) const { return _size; } + +public: + /** + * @brief Get the value used by index + * @param[in] nth The vector index + * @return The value at the offset + */ + T at(uint32_t nth) const override { return _value.at(nth); } + +private: + /** + * @brief Size of vector + */ + const int32_t _size; + /** + * @brief The tensor vector of operand + */ + std::vector _value; +}; + +} // namespace vector +} // namespace misc +} // namespace nnfw + +#endif // __NNFW_MISC_VECTOR_OBJECT_H__ diff --git a/runtime/libs/misc/include/misc/vector/Reader.h b/runtime/libs/misc/include/misc/vector/Reader.h new file mode 100644 index 000000000..eab4c427b --- /dev/null +++ b/runtime/libs/misc/include/misc/vector/Reader.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file Reader.h + * @brief This file contains Reader class + * @ingroup COM_AI_RUNTIME + */ + +#ifndef __NNFW_MISC_VECTOR_READER_H__ +#define __NNFW_MISC_VECTOR_READER_H__ + +#include + +namespace nnfw +{ +namespace misc +{ +namespace vector +{ + +/** + * @brief Class reads values of vector + * The interface class + */ +template struct Reader +{ + /** + * @brief Destruct Reader object using default destructor + */ + virtual ~Reader() = default; + + /** + * @brief Get the value used by the index + * @param[in] nth The vector index + * @return The value at the offset + */ + virtual T at(uint32_t nth) const = 0; +}; + +} // namespace vector +} // namespace misc +} // namespace nnfw + +#endif // __NNFW_MISC_VECTOR_READER_H__ diff --git a/runtime/libs/misc/src/EventCollector.cpp b/runtime/libs/misc/src/EventCollector.cpp new file mode 100644 index 000000000..452a29166 --- /dev/null +++ b/runtime/libs/misc/src/EventCollector.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "misc/EventCollector.h" + +// C++ standard libraries +#include + +// POSIX standard libraries +#include +#include + +namespace +{ + +std::string timestamp(void) +{ + auto now = std::chrono::steady_clock::now(); + return std::to_string( + std::chrono::duration_cast(now.time_since_epoch()).count()); +} + +class DurationEventBuilder +{ +public: + DurationEventBuilder(const std::string &ts) : _ts{ts} {} + + DurationEvent build(const std::string &tid, const std::string &name, const std::string &ph) const + { + DurationEvent evt; + + evt.name = name; + evt.tid = tid; + evt.ph = ph; + evt.ts = _ts; + + return evt; + } + +private: + std::string _ts; +}; + +void emit_rusage(EventRecorder *rec, const std::string &ts) +{ + struct rusage ru; + + getrusage(RUSAGE_SELF, &ru); + { + CounterEvent evt; + + evt.name = "maxrss"; + evt.ph = "C"; + evt.ts = ts; + evt.values["value"] = std::to_string(ru.ru_maxrss); + + rec->emit(evt); + } + + { + CounterEvent evt; + + evt.name = "minflt"; + evt.ph = "C"; + evt.ts = ts; + evt.values["value"] = std::to_string(ru.ru_minflt); + + rec->emit(evt); + } +} + +} // namespace + +void EventCollector::onEvent(const Event &event) +{ + auto ts = timestamp(); + + switch (event.edge) + { + case Edge::BEGIN: + _rec->emit(DurationEventBuilder(ts).build(event.backend, event.label, "B")); + break; + + case Edge::END: + _rec->emit(DurationEventBuilder(ts).build(event.backend, event.label, "E")); + break; + } + + // Trace resource usage per each event notification + emit_rusage(_rec, ts); +} diff --git a/runtime/libs/misc/src/EventRecorder.cpp b/runtime/libs/misc/src/EventRecorder.cpp new file mode 100644 index 000000000..5fdeef5fe --- /dev/null +++ b/runtime/libs/misc/src/EventRecorder.cpp @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "misc/EventRecorder.h" + +#include +#include + +namespace +{ + +std::string quote(const std::string &value) +{ + std::stringstream ss; + ss << '"' << value << '"'; + return ss.str(); +} + +std::string field(const std::string &k, const std::string &v) +{ + std::stringstream ss; + ss << quote(k) << " : " << quote(v); + return ss.str(); +} + +struct Content // One Entry in Chrome Event Trace +{ + std::vector> flds; + std::vector> args; +}; + +std::string object(const Content &content) +{ + std::stringstream ss; + + ss << "{ "; + + ss << field(content.flds[0].first, content.flds[0].second); + + for (uint32_t n = 1; n < content.flds.size(); ++n) + { + ss << ", " << field(content.flds.at(n).first, content.flds.at(n).second); + } + + if (content.args.size() > 0) + { + ss << ", " << quote("args") << " : { "; + ss << field(content.args.at(0).first, content.args.at(0).second); + + for (uint32_t n = 1; n < content.args.size(); ++n) + { + ss << ", " << field(content.args.at(n).first, content.args.at(n).second); + } + + ss << "}"; + } + + ss << " }"; + + return ss.str(); +} + +void fill(Content &content, const Event &evt) +{ + content.flds.emplace_back("name", evt.name); + content.flds.emplace_back("pid", "0"); + content.flds.emplace_back("tid", evt.tid); + content.flds.emplace_back("ph", evt.ph); + content.flds.emplace_back("ts", evt.ts); +} + +std::string object(const DurationEvent &evt) +{ + Content content; + + fill(content, evt); + + return ::object(content); +} + +std::string object(const CounterEvent &evt) +{ + Content content; + + fill(content, evt); + + for (auto it = evt.values.begin(); it != evt.values.end(); ++it) + { + content.args.emplace_back(it->first, it->second); + } + + return ::object(content); +} + +} // namespace + +void EventRecorder::emit(const DurationEvent &evt) +{ + std::lock_guard lock{_mu}; + + _ss << " " << object(evt) << ",\n"; +} + +void EventRecorder::emit(const CounterEvent &evt) +{ + std::lock_guard lock{_mu}; + + _ss << " " << object(evt) << ",\n"; +} + +void EventRecorder::writeToFile(std::ostream &os) +{ + std::lock_guard lock{_mu}; + + os << "{\n"; + os << " " << quote("traceEvents") << ": [\n"; + + os << _ss.str(); + + os << " { }\n"; + os << " ]\n"; + os << "}\n"; +} diff --git a/runtime/libs/misc/src/tensor/Comparator.cpp b/runtime/libs/misc/src/tensor/Comparator.cpp new file mode 100644 index 000000000..e765e77b2 --- /dev/null +++ b/runtime/libs/misc/src/tensor/Comparator.cpp @@ -0,0 +1,38 @@ +#include "misc/tensor/Comparator.h" +#include "misc/tensor/Zipper.h" + +#include "misc/fp32.h" + +namespace nnfw +{ +namespace misc +{ +namespace tensor +{ + +std::vector> Comparator::compare(const Shape &shape, const Reader &expected, + const Reader &obtained, + Observer *observer) const +{ + std::vector> res; + + zip(shape, expected, obtained) << + [&](const Index &index, float expected_value, float obtained_value) { + if (!_compare_fn(expected_value, obtained_value)) + { + res.emplace_back(index, expected_value, obtained_value); + } + + // Update max_diff_index, if necessary + if (observer != nullptr) + { + observer->notify(index, expected_value, obtained_value); + } + }; + + return res; +} + +} // namespace tensor +} // namespace misc +} // namespace nnfw diff --git a/runtime/libs/misc/src/tensor/IndexFormatter.cpp b/runtime/libs/misc/src/tensor/IndexFormatter.cpp new file mode 100644 index 000000000..c949db7a8 --- /dev/null +++ b/runtime/libs/misc/src/tensor/IndexFormatter.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "misc/tensor/IndexFormatter.h" + +#include + +namespace nnfw +{ +namespace misc +{ +namespace tensor +{ + +std::ostream &operator<<(std::ostream &os, const IndexFormatter &fmt) +{ + const auto rank = fmt.index().rank(); + + assert(rank > 0); + + os << fmt.index().at(0); + + if (rank > 1) + { + for (uint32_t axis = 1; axis < rank; ++axis) + { + os << ", " << fmt.index().at(axis); + } + } + + return os; +} + +} // namespace tensor +} // namespace misc +} // namespace nnfw diff --git a/runtime/libs/misc/src/tensor/NonIncreasingStride.cpp b/runtime/libs/misc/src/tensor/NonIncreasingStride.cpp new file mode 100644 index 000000000..c51ad0324 --- /dev/null +++ b/runtime/libs/misc/src/tensor/NonIncreasingStride.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "misc/tensor/NonIncreasingStride.h" + +#include + +namespace nnfw +{ +namespace misc +{ +namespace tensor +{ + +uint32_t NonIncreasingStride::offset(const Index &index) const +{ + const size_t rank = _stride.size(); + + assert(index.rank() == rank); + + uint32_t offset = 0; + + for (size_t axis = 0; axis < rank; ++axis) + { + offset += _stride.at(axis) * index.at(axis); + } + + return offset; +} + +} // namespace tensor +} // namespace misc +} // namespace nnfw diff --git a/runtime/libs/misc/src/tensor/Shape.cpp b/runtime/libs/misc/src/tensor/Shape.cpp new file mode 100644 index 000000000..70d3bdfdb --- /dev/null +++ b/runtime/libs/misc/src/tensor/Shape.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "misc/tensor/Shape.h" + +#include +#include +#include + +namespace nnfw +{ +namespace misc +{ +namespace tensor +{ + +bool operator==(const Shape &lhs, const Shape &rhs) +{ + if (lhs.rank() != rhs.rank()) + { + return false; + } + + for (uint32_t axis = 0; axis < lhs.rank(); ++axis) + { + if (lhs.dim(axis) != rhs.dim(axis)) + { + return false; + } + } + + return true; +} + +Shape Shape::from(const std::string &str) +{ + Shape shape(0); + + bool pending = false; + int value = 0; + + for (const char *cur = str.c_str(); true; ++cur) + { + if (*cur == ',' || *cur == '\0') + { + if (pending) + { + shape.append(value); + } + + if (*cur == '\0') + { + break; + } + + pending = false; + value = 0; + continue; + } + + assert(*cur >= '0' && *cur <= '9'); + + pending = true; + value *= 10; + value += *cur - '0'; + } + + return shape; +} + +uint64_t Shape::num_elements() const +{ + return std::accumulate(_dimensions.cbegin(), _dimensions.cend(), UINT64_C(1), + std::multiplies()); +} + +std::ostream &operator<<(std::ostream &os, const Shape &shape) +{ + if (shape.rank() > 0) + { + os << shape.dim(0); + + for (uint32_t axis = 1; axis < shape.rank(); ++axis) + { + os << "," << shape.dim(axis); + } + } + + return os; +} + +} // namespace tensor +} // namespace misc +} // namespace nnfw -- cgit v1.2.3