blob: bfa2eacfed0cb3c337948c0b484c727f1a9e27ee [file] [log] [blame]
SiCong Lib63b1192022-01-28 18:24:39 +00001/*
2 * Copyright (c) 2022 Arm Limited.
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24#ifndef ENABLE_EXPERIMENTAL_DYNAMIC_FUSION
25#error "This experimental feature must be enabled with -DENABLE_EXPERIMENTAL_DYNAMIC_FUSION"
26#endif /* ENABLE_EXPERIMENTAL_DYNAMIC_FUSION */
27#ifndef ARM_COMPUTE_EXPERIMENTAL_DYNAMICFUSION_ITENSORDESCPACK_H
28#define ARM_COMPUTE_EXPERIMENTAL_DYNAMICFUSION_ITENSORDESCPACK_H
29
30#include <cstddef>
31#include <unordered_map>
32#include <vector>
33
34namespace arm_compute
35{
36namespace experimental
37{
38namespace dynamic_fusion
39{
40template <typename TDesc>
41class ITensorDescPack
42{
43public:
44 struct PackElement
45 {
46 PackElement() = default;
47 ~PackElement() = default;
48 PackElement(const PackElement &) = default;
49 PackElement &operator=(const PackElement &) = default;
50 PackElement(PackElement &&) = default;
51 PackElement &operator=(PackElement &&) = default;
52 PackElement(int id, TDesc *tensor)
53 : id(id), tensor(tensor), ctensor(nullptr)
54 {
55 }
56 PackElement(int id, const TDesc *ctensor)
57 : id(id), tensor(nullptr), ctensor(ctensor)
58 {
59 }
60
61 int id{ -1 };
62 TDesc *tensor{ nullptr };
63 const TDesc *ctensor{ nullptr };
64
65 friend bool operator==(const PackElement &elem0, const PackElement &elem1)
66 {
67 const bool same_ctensor = (elem0.tensor == nullptr && elem1.tensor == nullptr && elem0.ctensor != nullptr && elem1.ctensor != nullptr && *elem0.ctensor == *elem1.ctensor);
68 const bool same_tensor = (elem0.ctensor == nullptr && elem1.ctensor == nullptr && elem0.tensor != nullptr && elem1.tensor != nullptr && *elem0.tensor == *elem1.tensor);
69
70 return elem0.id == elem1.id && (same_ctensor || same_tensor);
71 }
72 };
73
74public:
75 /** Default Constructor */
76 ITensorDescPack() = default;
77 ~ITensorDescPack() = default;
78 ITensorDescPack<TDesc>(const ITensorDescPack<TDesc> &other) = default;
79 ITensorDescPack<TDesc> &operator=(const ITensorDescPack<TDesc> &other) = default;
80 ITensorDescPack<TDesc>(ITensorDescPack<TDesc> &&other) = default;
81 ITensorDescPack<TDesc> &operator=(ITensorDescPack<TDesc> &&other) = default;
82 /** Initializer list Constructor */
83 ITensorDescPack(std::initializer_list<PackElement> l)
84 : _pack{}
85 {
86 for(auto &e : l)
87 {
88 _pack[e.id] = e;
89 }
90 }
91 /** Add tensor to the pack
92 *
93 * @param[in] id ID/type of the tensor to add
94 * @param[in] tensor Tensor to add
95 */
96 void add_tensor(int id, TDesc *tensor)
97 {
98 _pack[id] = PackElement(id, tensor);
99 }
100
101 /** Add const tensor to the pack
102 *
103 * @param[in] id ID/type of the tensor to add
104 * @param[in] tensor Tensor to add
105 */
106 void add_const_tensor(int id, const TDesc *tensor)
107 {
108 _pack[id] = PackElement(id, tensor);
109 }
110 /** Get tensor of a given id from the pac
111 *
112 * @param[in] id ID of tensor to extract
113 *
114 * @return The pointer to the tensor if exist and is non-const else nullptr
115 */
116 TDesc *get_tensor(int id)
117 {
118 auto it = _pack.find(id);
119 return it != _pack.end() ? it->second.tensor : nullptr;
120 }
121 /** Get constant tensor of a given id
122 *
123 * @param[in] id ID of tensor to extract
124 *
125 * @return The pointer to the tensor if exist and is const else nullptr
126 */
127 const TDesc *get_const_tensor(int id) const
128 {
129 auto it = _pack.find(id);
130 if(it != _pack.end())
131 {
132 return it->second.ctensor != nullptr ? it->second.ctensor : it->second.tensor;
133 }
134 return nullptr;
135 }
136 /** Remove the tensor stored with the given id
137 *
138 * @param[in] id ID of tensor to remove
139 */
140 void remove_tensor(int id)
141 {
142 _pack.erase(id);
143 }
144 /** Pack size accessor
145 *
146 * @return Number of tensors registered to the pack
147 */
148 size_t size() const
149 {
150 return _pack.size();
151 }
152 /** Checks if pack is empty
153 *
154 * @return True if empty else false
155 */
156 bool empty() const
157 {
158 return _pack.empty();
159 }
160
161 /** Get the ACL_SRC_* tensors
162 *
163 * @return std::vector<TDesc *>
164 */
165 std::vector<TDesc *> get_src_tensors()
166 {
167 std::vector<TDesc *> src_tensors{};
168 for(int id = static_cast<int>(TensorType::ACL_SRC); id <= static_cast<int>(TensorType::ACL_SRC_END); ++id)
169 {
170 auto tensor = get_tensor(id);
171 if(tensor != nullptr)
172 {
173 src_tensors.push_back(tensor);
174 }
175 }
176 return src_tensors;
177 }
178 /** Get the const ACL_SRC_* tensors
179 *
180 * @return std::vector<const TDesc *>
181 */
182 std::vector<const TDesc *> get_const_src_tensors() const
183 {
184 std::vector<const TDesc *> src_tensors{};
185 for(int id = static_cast<int>(TensorType::ACL_SRC); id <= static_cast<int>(TensorType::ACL_SRC_END); ++id)
186 {
187 auto tensor = get_const_tensor(id);
188 if(tensor != nullptr)
189 {
190 src_tensors.push_back(tensor);
191 }
192 }
193 return src_tensors;
194 }
195 /** Get the ACL_DST_* tensors
196 *
197 * @return std::vector<TDesc *>
198 */
199 std::vector<TDesc *> get_dst_tensors()
200 {
201 std::vector<TDesc *> dst_tensors{};
202 for(int id = static_cast<int>(TensorType::ACL_DST); id <= static_cast<int>(TensorType::ACL_DST_END); ++id)
203 {
204 auto tensor = get_tensor(id);
205 if(tensor != nullptr)
206 {
207 dst_tensors.push_back(tensor);
208 }
209 }
210 return dst_tensors;
211 }
212 /** Get the const ACL_DST_* tensors
213 *
214 * @return std::vector<const TDesc *>
215 */
216 std::vector<const TDesc *> get_const_dst_tensors() const
217 {
218 std::vector<const TDesc *> dst_tensors{};
219 for(int id = static_cast<int>(TensorType::ACL_DST); id <= static_cast<int>(TensorType::ACL_DST_END); ++id)
220 {
221 auto tensor = get_const_tensor(id);
222 if(tensor != nullptr)
223 {
224 dst_tensors.push_back(tensor);
225 }
226 }
227 return dst_tensors;
228 }
229
230 friend bool operator==(const ITensorDescPack<TDesc> &pack0, const ITensorDescPack<TDesc> &pack1)
231 {
232 return pack0._pack == pack1._pack;
233 }
234
235private:
236 std::unordered_map<int, PackElement> _pack{}; /**< Container with the packed tensors */
237};
238
239} // namespace dynamic_fusion
240} // namespace experimental
241} // namespace arm_compute
242#endif //ARM_COMPUTE_EXPERIMENTAL_DYNAMICFUSION_ITENSORDESCPACK_H