1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20/*!
21 * \file src/contrib/ethosu/cascader/common.h
22 * \brief Common functions used in the NPU cascader
23 */
24#ifndef TVM_CONTRIB_ETHOSU_CASCADER_COMMON_H_
25#define TVM_CONTRIB_ETHOSU_CASCADER_COMMON_H_
26
27#include <tvm/ir/expr.h>
28#include <tvm/runtime/container/array.h>
29
30#include <functional>
31#include <numeric>
32#include <vector>
33
34namespace tvm {
35namespace contrib {
36namespace ethosu {
37namespace cascader {
38
39/*!
40 * \brief Make a tvm::Array<Integer> from an int vector.
41 * \param vec The int vector.
42 * \return The Integer Array.
43 * \note Array<Integer>(std::vector<int>) doesn't work as this implicit
44 * type conversion fails. This is why this helper is required.
45 */
46inline Array<Integer> make_array(const std::vector<int>& vec) {
47 Array<Integer> arr;
48 arr.resize(vec.size());
49 for (unsigned int i = 0; i < vec.size(); ++i) {
50 arr.Set(i, Integer(vec[i]));
51 }
52 return arr;
53}
54
55/*!
56 * \brief Make a tvm::Array<Integer> from a size_t vector.
57 * \param vec The size_t vector.
58 * \return The Integer Array.
59 * \note Array<Integer>(std::vector<size_t>) doesn't work as this implicit
60 * type conversion fails. This is why this helper is required.
61 */
62inline Array<Integer> make_array(const std::vector<size_t>& vec) {
63 Array<Integer> arr;
64 arr.resize(vec.size());
65 for (unsigned int i = 0; i < vec.size(); ++i) {
66 arr.Set(i, Integer(vec[i]));
67 }
68 return arr;
69}
70
71/*!
72 * \brief Make a tvm::Array<IntImm> from an int64_t vector.
73 * \param vec The int64_t vector.
74 * \return The IntImm Array.
75 * \note Array<IntImm>(std::vector<int64_t>) doesn't work as this implicit
76 * type conversion fails. This is why this helper is required.
77 */
78inline Array<IntImm> make_array(const std::vector<int64_t>& vec) {
79 Array<IntImm> arr;
80 arr.resize(vec.size());
81 for (unsigned int i = 0; i < vec.size(); ++i) {
82 arr.Set(i, IntImm(DataType::Int(64), vec[i]));
83 }
84 return arr;
85}
86
87/*!
88 * \brief Make a tvm::Array<FloatImm> from an float vector.
89 * \param vec The float vector.
90 * \return The FloatImm Array.
91 */
92inline Array<FloatImm> make_array(const std::vector<float>& vec) {
93 Array<FloatImm> arr;
94 arr.resize(vec.size());
95 for (unsigned int i = 0; i < vec.size(); ++i) {
96 arr.Set(i, FloatImm(DataType::Float(32), static_cast<double>(vec[i])));
97 }
98 return arr;
99}
100
101/*!
102 * \brief Calculate the ceil of an Integer division
103 * \param dividend The dividend of the division
104 * \param divisor The divisor of the division
105 * \return The quotient
106 */
107inline int round_up_divide(int dividend, int divisor) {
108 return dividend / divisor + (dividend % divisor != 0);
109}
110
111/*!
112 * \brief Make a vector from a tvm::Array.
113 * \param arr The Array.
114 * \return The vector.
115 */
116template <typename T, typename tvm_T>
117inline std::vector<T> make_vector(const Array<tvm_T>& arr) {
118 std::vector<T> vec(arr.size());
119 for (unsigned int i = 0; i < arr.size(); ++i) {
120 vec[i] = arr[i]->value;
121 }
122 return vec;
123}
124
125/*!
126 * \brief Create a combined hash.
127 * \param seed The current hash value.
128 * \param v The value to combine into the hash.
129 * \return The combined hash.
130 */
131template <class T>
132inline void hash_combine(std::size_t* seed, T const& v) {
133 *seed ^= std::hash<T>()(v) + 0x9e3779b9 + (*seed << 6) + (*seed >> 2);
134}
135
136/*!
137 * \brief Hash a vector.
138 * \param vec The vector to hash.
139 * \return The hash.
140 */
141template <class T>
142inline std::size_t hash_vector(const std::vector<T>& vec) {
143 std::size_t seed = vec.size();
144 for (const auto& elem : vec) {
145 hash_combine(&seed, elem);
146 }
147 return seed;
148}
149
150template <class T>
151inline T mul_reduce(const std::vector<T>& vec) {
152 return std::accumulate(vec.begin(), vec.end(), 1, std::multiplies<T>());
153}
154
155} // namespace cascader
156} // namespace ethosu
157} // namespace contrib
158} // namespace tvm
159
160#endif // TVM_CONTRIB_ETHOSU_CASCADER_COMMON_H_
161