diff options
Diffstat (limited to 'runtime/onert/core/include/util')
-rw-r--r-- | runtime/onert/core/include/util/CalculateActivationRange.h | 66 | ||||
-rw-r--r-- | runtime/onert/core/include/util/Config.lst | 8 | ||||
-rw-r--r-- | runtime/onert/core/include/util/ConfigSource.h | 9 | ||||
-rw-r--r-- | runtime/onert/core/include/util/Exceptions.h | 2 | ||||
-rw-r--r-- | runtime/onert/core/include/util/GeneralConfigSource.h | 44 | ||||
-rw-r--r-- | runtime/onert/core/include/util/IConfigSource.h | 46 | ||||
-rw-r--r-- | runtime/onert/core/include/util/ITimer.h | 2 | ||||
-rw-r--r-- | runtime/onert/core/include/util/Index.h | 13 | ||||
-rw-r--r-- | runtime/onert/core/include/util/MinMaxMap.h (renamed from runtime/onert/core/include/util/EnvConfigSource.h) | 26 | ||||
-rw-r--r-- | runtime/onert/core/include/util/ObjectManager.h | 139 | ||||
-rw-r--r-- | runtime/onert/core/include/util/Set.h | 16 | ||||
-rw-r--r-- | runtime/onert/core/include/util/ShapeInference.h | 28 | ||||
-rw-r--r-- | runtime/onert/core/include/util/TracingCtx.h | 81 | ||||
-rw-r--r-- | runtime/onert/core/include/util/Utils.h | 55 | ||||
-rw-r--r-- | runtime/onert/core/include/util/logging.h | 23 |
15 files changed, 410 insertions, 148 deletions
diff --git a/runtime/onert/core/include/util/CalculateActivationRange.h b/runtime/onert/core/include/util/CalculateActivationRange.h new file mode 100644 index 000000000..4369ca53e --- /dev/null +++ b/runtime/onert/core/include/util/CalculateActivationRange.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2022 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 __ONERT_UTIL_CALCULATE_ACTIVATION_RANGE_H__ +#define __ONERT_UTIL_CALCULATE_ACTIVATION_RANGE_H__ + +#include <limits> + +#include "ir/InternalType.h" + +namespace onert +{ +namespace util +{ + +template <typename T> +void CalculateActivationRange(ir::Activation activation, T *activation_min, T *activation_max) +{ + if (activation == ir::Activation::RELU) + { + *activation_min = 0; + *activation_max = std::numeric_limits<T>::max(); + } + else if (activation == ir::Activation::RELU6) + { + *activation_min = 0; + *activation_max = 6; + } + else if (activation == ir::Activation::RELU1) + { + *activation_min = -1; + *activation_max = 1; + } + else if (activation == ir::Activation::SIGMOID) + { + *activation_min = 0; + *activation_max = 1; + } + else if (activation == ir::Activation::NONE) + { + *activation_min = std::numeric_limits<T>::lowest(); + *activation_max = std::numeric_limits<T>::max(); + } + else + { + throw std::runtime_error{"Unsupported fused activation function."}; + } +} + +} // namespace util +} // namespace onert + +#endif // __ONERT_UTIL_CALCULATE_ACTIVATION_RANGE_H__ diff --git a/runtime/onert/core/include/util/Config.lst b/runtime/onert/core/include/util/Config.lst index 5077fad69..d3e37ce8f 100644 --- a/runtime/onert/core/include/util/Config.lst +++ b/runtime/onert/core/include/util/Config.lst @@ -20,10 +20,9 @@ // Name | Type | Default CONFIG(GRAPH_DOT_DUMP , int , "0") -CONFIG(BACKENDS , std::string , "cpu;acl_cl;acl_neon;bcq") // FIXME Remove bcq +CONFIG(BACKENDS , std::string , "cpu;acl_cl;acl_neon;ruy;xnnpack;gpu_cl;trix;bcq") // FIXME Remove bcq CONFIG(OP_BACKEND_ALLOPS , std::string , "") CONFIG(OP_BACKEND_MAP , std::string , "") -CONFIG(DISABLE_COMPILE , bool , "0") CONFIG(ONERT_LOG_ENABLE , bool , "0") CONFIG(CPU_MEMORY_PLANNER , std::string , "WIC") CONFIG(EXECUTOR , std::string , "Linear") @@ -31,10 +30,12 @@ CONFIG(ACL_LAYOUT , std::string , "none") CONFIG(NCNN_LAYOUT , std::string , "NCHW") CONFIG(PROFILING_MODE , bool , "0") CONFIG(USE_SCHEDULER , bool , "0") -CONFIG(OP_SEQ_MAX_NODE , int , "0") CONFIG(TRACE_FILEPATH , std::string , "") +CONFIG(MINMAX_FILEPATH , std::string , "") CONFIG(FP16_ENABLE , bool , "0") CONFIG(RUY_THREADS , int , "-1") +CONFIG(XNNPACK_THREADS , int , "-1") +CONFIG(USE_MMAPED_DATA , bool , "0") // Auto-generate all operations @@ -42,4 +43,3 @@ CONFIG(RUY_THREADS , int , "-1") CONFIG(OP_BACKEND_ ## InternalName, std::string, "") #include "ir/Operations.lst" #undef OP - diff --git a/runtime/onert/core/include/util/ConfigSource.h b/runtime/onert/core/include/util/ConfigSource.h index b6a8144fd..d53b8106d 100644 --- a/runtime/onert/core/include/util/ConfigSource.h +++ b/runtime/onert/core/include/util/ConfigSource.h @@ -17,16 +17,17 @@ #ifndef __ONERT_UTIL_CONFIG_SOURCE_H__ #define __ONERT_UTIL_CONFIG_SOURCE_H__ -#include <memory> - -#include "IConfigSource.h" +#include <string> +#include <unordered_map> namespace onert { namespace util { -void config_source(std::unique_ptr<IConfigSource> &&source); +using CfgKeyValues = std::unordered_map<std::string, std::string>; + +void setConfigKeyValues(const CfgKeyValues &keyValues); bool toBool(const std::string &val); int toInt(const std::string &val); diff --git a/runtime/onert/core/include/util/Exceptions.h b/runtime/onert/core/include/util/Exceptions.h index fc3fa0f64..e77686593 100644 --- a/runtime/onert/core/include/util/Exceptions.h +++ b/runtime/onert/core/include/util/Exceptions.h @@ -38,7 +38,7 @@ class InsufficientBufferSizeException : public OnertException { public: InsufficientBufferSizeException(const std::string &msg) - : OnertException{"InsufficientBufferSize", msg} + : OnertException{"InsufficientBufferSize", msg} { } }; diff --git a/runtime/onert/core/include/util/GeneralConfigSource.h b/runtime/onert/core/include/util/GeneralConfigSource.h deleted file mode 100644 index dedc820ec..000000000 --- a/runtime/onert/core/include/util/GeneralConfigSource.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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 __ONERT_UTIL_GLOBAL_CONFIG_SOURCE_H__ -#define __ONERT_UTIL_GLOBAL_CONFIG_SOURCE_H__ - -#include <unordered_map> - -#include "util/IConfigSource.h" - -namespace onert -{ -namespace util -{ - -class GeneralConfigSource : public IConfigSource -{ -public: - GeneralConfigSource() = default; - - std::string get(const std::string &key) const override; - void set(const std::string &key, const std::string &val); - -private: - std::unordered_map<std::string, std::string> _map; -}; - -} // namespace util -} // namespace onert - -#endif // __ONERT_UTIL_GLOBAL_CONFIG_SOURCE_H__ diff --git a/runtime/onert/core/include/util/IConfigSource.h b/runtime/onert/core/include/util/IConfigSource.h deleted file mode 100644 index 07b09848a..000000000 --- a/runtime/onert/core/include/util/IConfigSource.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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 __ONERT_UTIL_I_CONFIG_SOURCE_H__ -#define __ONERT_UTIL_I_CONFIG_SOURCE_H__ - -#include <string> - -namespace onert -{ -namespace util -{ - -struct IConfigSource -{ - /** - * @brief Destroy the IConfigSource object - */ - virtual ~IConfigSource() = default; - - /** - * @brief get the value for the matching key - * - * @param key string key to search - * @return string value associated with the key - */ - virtual std::string get(const std::string &key) const = 0; -}; - -} // namespace util -} // namespace onert - -#endif // __ONERT_UTIL_I_CONFIG_SOURCE_H__ diff --git a/runtime/onert/core/include/util/ITimer.h b/runtime/onert/core/include/util/ITimer.h index d5a4e1eb0..f63a3f220 100644 --- a/runtime/onert/core/include/util/ITimer.h +++ b/runtime/onert/core/include/util/ITimer.h @@ -46,7 +46,7 @@ public: { const auto end_time = std::chrono::steady_clock::now(); _timer_res = - std::chrono::duration_cast<std::chrono::microseconds>(end_time - _start_time).count(); + std::chrono::duration_cast<std::chrono::microseconds>(end_time - _start_time).count(); }; private: diff --git a/runtime/onert/core/include/util/Index.h b/runtime/onert/core/include/util/Index.h index e8f59282d..49c5f4c6d 100644 --- a/runtime/onert/core/include/util/Index.h +++ b/runtime/onert/core/include/util/Index.h @@ -138,13 +138,12 @@ public: */ T value() const { return _index; } - friend std::ostream &operator<<(std::ostream &o, const Index &t) - { - if (t.undefined()) - return o << std::string("undefined"); - else - return o << t.value(); - } + /** + * @brief Return max index value + * + * @return Maximum valid index value + */ + static T max() { return UNDEFINED - 1; } private: T _index; diff --git a/runtime/onert/core/include/util/EnvConfigSource.h b/runtime/onert/core/include/util/MinMaxMap.h index 8c5d0e8e9..2245f84b0 100644 --- a/runtime/onert/core/include/util/EnvConfigSource.h +++ b/runtime/onert/core/include/util/MinMaxMap.h @@ -1,11 +1,11 @@ /* - * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved + * Copyright (c) 2023 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 + * 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, @@ -14,28 +14,34 @@ * limitations under the License. */ -#ifndef __ONERT_UTIL_ENV_CONFIG_SOURCE_H__ -#define __ONERT_UTIL_ENV_CONFIG_SOURCE_H__ +#ifndef __ONERT_UTIL_MINMAX_MAP_H_ +#define __ONERT_UTIL_MINMAX_MAP_H_ #include <unordered_map> - -#include "util/GeneralConfigSource.h" +#include <utility> namespace onert { namespace util { -class EnvConfigSource final : public GeneralConfigSource +template <typename N, typename Hash = std::hash<N>> class MinMaxMap { + struct MinMaxPair + { + float data[2]; // [0] = min, [1] = max + }; + public: - std::string get(const std::string &key) const override; + void append(N node, float min, float max) { _minmax_map[node] = {min, max}; } + auto begin() const { return _minmax_map.begin(); } + auto end() const { return _minmax_map.end(); } private: - std::unordered_map<std::string, std::string> _default_attributes; + std::unordered_map<N, MinMaxPair, Hash> _minmax_map; }; } // namespace util } // namespace onert -#endif // __ONERT_UTIL_ENV_CONFIG_SOURCE_H__ +#endif // __ONERT_UTIL_MINMAX_MAP_H_ diff --git a/runtime/onert/core/include/util/ObjectManager.h b/runtime/onert/core/include/util/ObjectManager.h index d2dd881a8..077a4c2ef 100644 --- a/runtime/onert/core/include/util/ObjectManager.h +++ b/runtime/onert/core/include/util/ObjectManager.h @@ -17,12 +17,13 @@ #ifndef __ONERT_UTIL_OBJECT_MANAGER_H__ #define __ONERT_UTIL_OBJECT_MANAGER_H__ -#include <unordered_map> -#include <memory> -#include <list> -#include <functional> +#include "util/logging.h" +#include <cassert> +#include <functional> +#include <list> #include <memory> +#include <unordered_map> namespace onert { @@ -36,35 +37,71 @@ namespace util template <typename Index, typename Object> class ObjectManager { public: - ObjectManager() : _index_count{0u} {} + ObjectManager() : _next_index{0u} {} public: /** - * @brief Create an object with args and put it in the container with a new Index for that + * @brief Create an object with args and put it in the container with a newly assigned @c Index * * @param[in] args Arguments for creating Operand object - * @return Created index that is associated to the object + * @return Created index that is associated to the object if successful, Undefined index otherwise */ template <class... Args> Index emplace(Args &&... args) { auto index = generateIndex(); + if (!index.valid()) + return index; _objects.emplace(index, std::make_unique<Object>(std::forward<Args>(args)...)); return index; } /** - * @brief Put object in the container with a new Index for that + * @brief Put the object in the container with given index. + * + * It fails when the given index is already taken or @c index is Undefined. + * + * @param[in] object Object to be pushed + * @param[in] index Index associated with the object + * @return @c index if successful, an Undefined index otherwise + */ + Index push(std::unique_ptr<Object> &&object, Index index) + { + auto gen_index = tryIndex(index); + if (gen_index.valid()) + _objects.emplace(gen_index, std::move(object)); + return gen_index; + } + /** + * @brief Put the object in the container with a newly assigned index. + * + * It fails when it cannot generate a valid index. * * @param[in] object Object to be pushed - * @return Created index that is associated to the object + * @return The newly assigned index if successful, an Undefined index otherwise */ Index push(std::unique_ptr<Object> &&object) { - auto index = generateIndex(); - _objects.emplace(index, std::move(object)); + auto gen_index = generateIndex(); + if (gen_index.valid()) + _objects.emplace(gen_index, std::move(object)); + return gen_index; + } + /** + * @brief Set the object in the container with given index. + * + * If the index is Undefined, it will fail. + * If the index is already taken, it will overwrite the content. + * + * @param[in] object Object to be pushed + * @param[in] index Index associated with the object + * @return @c index if successful, an Undefined index otherwise + */ + Index set(Index index, std::unique_ptr<Object> &&object) + { + if (index.valid()) + _objects[index] = std::move(object); return index; } - /** * @brief Remove the object that is associated with the given index * @@ -76,6 +113,8 @@ public: /** * @brief Get the object that is associated with the given index * + * If such object does not exist, it will throw @c std::out_of_range + * * @param[in] index Index of the object to be returned * @return Object */ @@ -83,6 +122,8 @@ public: /** * @brief Get the object that is associated with the given index * + * If such object does not exist, it will throw @c std::out_of_range + * * @param[in] index Index of the object to be returned * @return Object */ @@ -90,6 +131,38 @@ public: /** * @brief Get the object that is associated with the given index * + * If such object does not exist, it will return `nullptr` + * + * @param[in] index Index of the object to be returned + * @return Object + */ + const Object *getRawPtr(const Index &index) const + { + auto itr = _objects.find(index); + if (itr == _objects.end()) + return nullptr; + else + { + assert(itr->second != nullptr); + return itr->second.get(); + } + } + /** + * @brief Get the object that is associated with the given index + * + * If such object does not exist, it will return `nullptr` + * + * @param[in] index Index of the object to be returned + * @return Object The found object + */ + Object *getRawPtr(const Index &index) + { + return const_cast<Object *>( + const_cast<const ObjectManager<Index, Object> *>(this)->getRawPtr(index)); + } + /** + * @brief Get the object that is associated with the given index + * * @param[in] index Index of the object to be returned * @return true if such entry exists otherwise false */ @@ -99,6 +172,12 @@ public: return it != _objects.end(); } /** + * @brief Return the number of objects that the manager contains + * + * @return size_t Number of objects + */ + size_t size() const { return _objects.size(); } + /** * @brief Iterate over the container with given function * * @param[in] fn Function to be run for every container entry @@ -123,23 +202,51 @@ public: // This implementation is a workaround in case of adding operands while iteration std::list<Index> l; - for (auto &e : _objects) + for (const auto &e : _objects) { l.push_back(e.first); } - for (auto index : l) + for (const auto &index : l) { fn(index, *_objects[index]); } } private: - Index generateIndex() { return Index{_index_count++}; } + // Try assigning the given index + Index tryIndex(Index index) + { + if (!index.valid()) + return index; + if (_objects.find(index) == _objects.end()) + { + // If the given index does not exist, update the next index and return the index + if (index.value() >= _next_index) + _next_index = index.value() + 1; + return index; + } + else + { + // If the given index exists already, return a non-valid index + return Index{}; + } + } + + // Generate a new index with `_next_index` + Index generateIndex() + { + // No need to check if there is an entry with _next_index since + // _next_index is always ("the highest index in the object map" + 1) + if (Index{_next_index}.valid()) + return Index{_next_index++}; + else + return Index{}; + } protected: std::unordered_map<Index, std::unique_ptr<Object>> _objects; - uint32_t _index_count; + uint32_t _next_index; }; } // namespace util diff --git a/runtime/onert/core/include/util/Set.h b/runtime/onert/core/include/util/Set.h index ee4062d25..73d43d4f0 100644 --- a/runtime/onert/core/include/util/Set.h +++ b/runtime/onert/core/include/util/Set.h @@ -53,6 +53,16 @@ public: public: /** + * @brief copy assignment operator + */ + Set<Element> &operator=(const Set<Element> &) = default; + /** + * @brief move assignment operator + */ + Set<Element> &operator=(Set<Element> &&) = default; + +public: + /** * @brief Add a given element to the set * * @param e Element added @@ -104,7 +114,7 @@ public: Set<Element> operator|(const Set<Element> &other) const // Union { auto ret = *this; - for (auto e : other) + for (auto &&e : other) { ret.add(e); } @@ -118,7 +128,7 @@ public: Set<Element> operator&(const Set<Element> &other) const // Intersect { Set<Element> ret; - for (auto e : other) + for (auto &&e : other) { if (contains(e)) { @@ -135,7 +145,7 @@ public: Set<Element> operator-(const Set<Element> &other) const // Minus { auto ret = *this; - for (auto e : other) + for (auto &&e : other) { ret.remove(e); } diff --git a/runtime/onert/core/include/util/ShapeInference.h b/runtime/onert/core/include/util/ShapeInference.h index 1ebed48f2..d859378c6 100644 --- a/runtime/onert/core/include/util/ShapeInference.h +++ b/runtime/onert/core/include/util/ShapeInference.h @@ -29,7 +29,6 @@ #include "ir/Index.h" #include "ir/Layout.h" #include "ir/OperationVisitor.h" -#include "backend/IDynamicTensorManager.h" #include "backend/ITensor.h" #include "backend/ITensorRegistry.h" @@ -42,12 +41,19 @@ using Shapes = std::vector<ir::Shape>; // Define shape calculation for operations. List them in alphabetic order. -ir::Shape inferArgMaxShape(const ir::Shape &input_shape, int axis, int rank); +ir::Shape inferArgMinMaxShape(const ir::Shape &input_shape, int axis, int rank); ir::Shape inferBatchMatMulShape(const ir::Shape &lhs_shape, const ir::Shape &rhs_shape, const ir::operation::BatchMatMul::Param ¶m); -ir::Shape inferBroadcastToShape(const ir::Shape wshape, const int32_t *shape_buffer); +ir::Shape inferBCQFullyConnectedShape(const ir::Shape &in_shape, const ir::Shape &cluster_shape, + const int32_t *cluster_buf); + +ir::Shape inferBCQGatherShape(const ir::Shape &indices_shape, const ir::Shape &cluster_shape, + const int32_t *cluster_buf, int rank, + const ir::operation::BCQGather::Param ¶m); + +ir::Shape inferBroadcastToShape(const ir::Shape shp_shape, const int32_t *shp_buf); ir::Shape inferConcatShape(const Shapes &in_shapes, const ir::operation::Concat::Param ¶m); @@ -63,7 +69,7 @@ ir::Shape inferEltwiseShape(const ir::Shape &lhs_shape, const ir::Shape &rhs_sha ir::Shape inferExpandDimsShape(const ir::Shape &in_shape, int32_t axis); -ir::Shape inferFillShape(const ir::Shape &in_shape, const int32_t *buf); +template <typename T> ir::Shape inferFillShape(const ir::Shape &fill_shape, const T *shape_buf); ir::Shape inferFullyConnectedShape(const ir::Shape &in_shape, const ir::Shape &ker_shape); @@ -97,12 +103,12 @@ ir::Shape inferResizeBilinearShape(const ir::Shape &in_shape, const int32_t outp ir::Shape inferSelectShape(const ir::Shape &input_cond_shape, const ir::Shape &input_true_shape, const ir::Shape &input_false_shape); -ir::Shape inferSliceShape(const ir::Shape &input_shape, const int32_t *begins, - const int32_t *sizes); +template <typename T> +ir::Shape inferSliceShape(const ir::Shape &input_shape, const T *begins_buf, const T *sizes_buf); ir::Shape inferSpaceToBatchNDShape(const ir::Shape &input_shape, const ir::Shape &block_shape_shape, - const ir::Shape &padding_shape, const int32_t *block_shape_data, - const int32_t *padding_data); + const ir::Shape &padding_shape, const int32_t *block_shape_buf, + const int32_t *padding_buf); ir::Shape inferSplitShape(const ir::Shape input_shape, int axis_value, int num_splits); @@ -132,9 +138,11 @@ StridedSliceParams buildStridedSliceParams(const T *begin, const T *end, const T ir::Shape inferStridedSliceShape(const ir::Shape &input_shape, const StridedSliceParams &op_params, uint32_t rank); -ir::Shape inferTileShape(const ir::Shape &in_shape, const int32_t *multiplier); +ir::Shape inferTileShape(const ir::Shape &in_shape, const int32_t *multiplier_buf, + const int32_t multiplier_size); -ir::Shape inferTransposeShape(const ir::Shape &in_shape, const std::vector<int> &perm); +ir::Shape inferTransposeShape(const ir::Shape &in_shape, const int32_t *perm_buf, + const int32_t rank); ir::Shape inferUnpackShape(const ir::Shape &input_shape, int axis, int rank); diff --git a/runtime/onert/core/include/util/TracingCtx.h b/runtime/onert/core/include/util/TracingCtx.h new file mode 100644 index 000000000..da284d2fb --- /dev/null +++ b/runtime/onert/core/include/util/TracingCtx.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2020 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 __ONERT_UTIL_TRACING_CTX_H__ +#define __ONERT_UTIL_TRACING_CTX_H__ + +#include "ir/Graph.h" +#include "ir/Index.h" +#include "ir/Model.h" + +#include <unordered_map> +#include <mutex> + +namespace onert +{ +namespace util +{ + +/** + * @brief Class to maintain information about profiling per session + */ +class TracingCtx +{ +public: + /** + * @brief Create and store unique session id managed by this class + * @note This constructor can be called by multiple session running in parallely. + */ + TracingCtx(void) { decideSessionID(); } + + uint32_t getSessionId() const { return _session_id; } + + /** + * @brief Return true if more than 1 session exist + * + * @note This method is NOT thread-safe. Call this in thread-safe situation. + */ + bool hasMultipleSessions() const { return _next_session_id > 1; } + + /** + * @brief Set subgraph index of a graph + */ + void setSubgraphIndex(const ir::Graph *g, uint32_t index) { _subgraph_indices.emplace(g, index); } + + /** + * @brief Get subgraph index of a graph. + */ + ir::SubgraphIndex getSubgraphIndex(const ir::Graph *g) const { return _subgraph_indices.at(g); } + +private: + void decideSessionID() + { + std::unique_lock<std::mutex> lock{_session_id_mutex}; + + _session_id = _next_session_id++; + } + +private: + std::unordered_map<const ir::Graph *, ir::SubgraphIndex> _subgraph_indices; + uint32_t _session_id; + static std::mutex _session_id_mutex; + static uint32_t _next_session_id; +}; + +} // namespace util +} // namespace onert + +#endif // __ONERT_UTIL_TRACING_CTX_H__ diff --git a/runtime/onert/core/include/util/Utils.h b/runtime/onert/core/include/util/Utils.h index 847fb6971..6b6bc2400 100644 --- a/runtime/onert/core/include/util/Utils.h +++ b/runtime/onert/core/include/util/Utils.h @@ -22,6 +22,61 @@ #ifndef __ONERT_UTIL_UTILS_H__ #define __ONERT_UTIL_UTILS_H__ +#include "ir/Coordinates.h" +#include "ir/Shape.h" + #define UNUSED_RELEASE(a) (void)(a) +template <size_t rest> struct ForEachDimension +{ + template <typename L> + static void unroll(const onert::ir::Shape &shape, onert::ir::Coordinates &coords, + L lambda_function) + { + if (static_cast<int>(rest) > shape.rank()) + { + ForEachDimension<rest - 1>::unroll(shape, coords, lambda_function); + return; + } + + const auto axis = shape.rank() - rest; + const auto &d = shape.dim(axis); + + for (auto v = 0; v < d; v++) + { + coords.set(axis, v); + ForEachDimension<rest - 1>::unroll(shape, coords, lambda_function); + } + } +}; + +template <> struct ForEachDimension<0> +{ + template <typename L> + static void unroll(const onert::ir::Shape &shape, onert::ir::Coordinates &coords, + L lambda_function) + { + UNUSED_RELEASE(shape); + lambda_function(coords); + } +}; + +template <typename L> inline void ShapeLoop(const onert::ir::Shape &shape, L lambda_function) +{ + int32_t rank = shape.rank(); + assert(rank > 0); + for (int32_t i = 0; i < rank; ++i) + { + assert(shape.dim(i) > 0); + } + + onert::ir::Coordinates coords; + if (rank == 0) + { + coords.set(0, 0); + } + // TODO Change 6 to onert::ir::Shape::kMaxRank if onert::ir::Shape::kMaxRank is modified as a + // constant expression + ForEachDimension<6>::unroll(shape, coords, lambda_function); +} #endif // __ONERT_UTIL_UTILS_H__ diff --git a/runtime/onert/core/include/util/logging.h b/runtime/onert/core/include/util/logging.h index 76cfb8d60..fe255f8ff 100644 --- a/runtime/onert/core/include/util/logging.h +++ b/runtime/onert/core/include/util/logging.h @@ -18,6 +18,7 @@ #define __ONERT_UTIL_LOGGING_H__ #include <iostream> +#include <cstring> #include "util/ConfigSource.h" @@ -52,16 +53,34 @@ private: static Context &ctx = Context::get(); +inline std::string decorated_name(const char *input) +{ + const int min_prefix = 16; + std::string prefix(input); + auto len_prefix = prefix.size(); + if (len_prefix > min_prefix) + return "[" + prefix + "] "; + std::string spaces((min_prefix - len_prefix) / 2, ' '); + return (len_prefix % 2 ? "[ " : "[") + spaces + prefix + spaces + "] "; +} + } // namespace logging } // namespace util } // namespace onert #define VERBOSE(name) \ if (::onert::util::logging::ctx.enabled()) \ - std::cout << "[" << #name << "] " + std::cout << ::onert::util::logging::decorated_name(#name) #define VERBOSE_F() \ if (::onert::util::logging::ctx.enabled()) \ - std::cout << "[" << __func__ << "] " + std::cout << ::onert::util::logging::decorated_name(__func__) + +#define WHEN_LOG_ENABLED(METHOD) \ + if (::onert::util::logging::ctx.enabled()) \ + do \ + { \ + METHOD; \ + } while (0) #endif // __ONERT_UTIL_LOGGING_H__ |