blob: e755cacae60f305cf1a94be6880682419ee2cf48 [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*
Georgios Pinitasc6f95102021-03-30 10:03:01 +01002 * Copyright (c) 2016-2021 Arm Limited.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003 *
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 */
Michalis Spyrouf4643372019-11-29 16:17:13 +000024#ifndef ARM_COMPUTE_VALIDATE_H
25#define ARM_COMPUTE_VALIDATE_H
Anthony Barbier6ff3b192017-09-04 18:44:23 +010026
27#include "arm_compute/core/Error.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010028#include "arm_compute/core/IKernel.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010029#include "arm_compute/core/ITensor.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010030#include "arm_compute/core/Window.h"
31
32#include <algorithm>
33
34namespace arm_compute
35{
36namespace detail
37{
38/* Check whether two dimension objects differ.
39 *
40 * @param[in] dim1 First object to be compared.
41 * @param[in] dim2 Second object to be compared.
42 * @param[in] upper_dim The dimension from which to check.
43 *
44 * @return Return true if the two objects are different.
45 */
46template <typename T>
47inline bool have_different_dimensions(const Dimensions<T> &dim1, const Dimensions<T> &dim2, unsigned int upper_dim)
48{
49 for(unsigned int i = upper_dim; i < arm_compute::Dimensions<T>::num_max_dimensions; ++i)
50 {
51 if(dim1[i] != dim2[i])
52 {
53 return true;
54 }
55 }
56
57 return false;
58}
59
Alex Gildayc357c472018-03-21 13:54:09 +000060/** Function to compare two @ref Dimensions objects and throw an error on mismatch.
Anthony Barbier6ff3b192017-09-04 18:44:23 +010061 *
62 * @param[in] dim Object to compare against.
Georgios Pinitas3faea252017-10-30 14:13:50 +000063 * @param[in] function Function in which the error occurred.
64 * @param[in] file File in which the error occurred.
65 * @param[in] line Line in which the error occurred.
Anthony Barbier6ff3b192017-09-04 18:44:23 +010066 */
67template <typename T>
68class compare_dimension
69{
70public:
Alex Gildayc357c472018-03-21 13:54:09 +000071 /** Construct a comparison function.
72 *
73 * @param[in] dim Dimensions to compare.
74 * @param[in] function Source function. Used for error reporting.
75 * @param[in] file Source code file. Used for error reporting.
76 * @param[in] line Source code line. Used for error reporting.
77 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +010078 compare_dimension(const Dimensions<T> &dim, const char *function, const char *file, int line)
79 : _dim{ dim }, _function{ function }, _file{ file }, _line{ line }
80 {
81 }
82
83 /** Compare the given object against the stored one.
84 *
85 * @param[in] dim To be compared object.
Alex Gildayc357c472018-03-21 13:54:09 +000086 *
87 * @return a status.
Anthony Barbier6ff3b192017-09-04 18:44:23 +010088 */
Georgios Pinitas631c41a2017-12-06 11:53:03 +000089 arm_compute::Status operator()(const Dimensions<T> &dim)
Anthony Barbier6ff3b192017-09-04 18:44:23 +010090 {
Georgios Pinitas3faea252017-10-30 14:13:50 +000091 ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(have_different_dimensions(_dim, dim, 0), _function, _file, _line,
92 "Objects have different dimensions");
Georgios Pinitas631c41a2017-12-06 11:53:03 +000093 return arm_compute::Status{};
Anthony Barbier6ff3b192017-09-04 18:44:23 +010094 }
95
96private:
97 const Dimensions<T> &_dim;
98 const char *const _function;
99 const char *const _file;
100 const int _line;
101};
Georgios Pinitas3faea252017-10-30 14:13:50 +0000102
103template <typename F>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000104inline arm_compute::Status for_each_error(F &&)
Georgios Pinitas3faea252017-10-30 14:13:50 +0000105{
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000106 return arm_compute::Status{};
Georgios Pinitas3faea252017-10-30 14:13:50 +0000107}
108
109template <typename F, typename T, typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000110inline arm_compute::Status for_each_error(F &&func, T &&arg, Ts &&... args)
Georgios Pinitas3faea252017-10-30 14:13:50 +0000111{
112 ARM_COMPUTE_RETURN_ON_ERROR(func(arg));
113 ARM_COMPUTE_RETURN_ON_ERROR(for_each_error(func, args...));
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000114 return arm_compute::Status{};
Georgios Pinitas3faea252017-10-30 14:13:50 +0000115}
116
Alex Gildayc357c472018-03-21 13:54:09 +0000117/** Get the info for a tensor, dummy struct */
Georgios Pinitas3faea252017-10-30 14:13:50 +0000118template <typename T>
119struct get_tensor_info_t;
Alex Gildayc357c472018-03-21 13:54:09 +0000120/** Get the info for a tensor */
Georgios Pinitas3faea252017-10-30 14:13:50 +0000121template <>
122struct get_tensor_info_t<ITensorInfo *>
123{
Alex Gildayc357c472018-03-21 13:54:09 +0000124 /** Get the info for a tensor.
125 *
126 * @param[in] tensor Tensor.
127 *
128 * @return tensor info.
129 */
Georgios Pinitas3faea252017-10-30 14:13:50 +0000130 ITensorInfo *operator()(const ITensor *tensor)
131 {
132 return tensor->info();
133 }
134};
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100135} // namespace detail
Georgios Pinitas3faea252017-10-30 14:13:50 +0000136
137/** Create an error if one of the pointers is a nullptr.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100138 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000139 * @param[in] function Function in which the error occurred.
140 * @param[in] file Name of the file where the error occurred.
141 * @param[in] line Line on which the error occurred.
142 * @param[in] pointers Pointers to check against nullptr.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000143 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000144 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100145 */
146template <typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000147inline arm_compute::Status error_on_nullptr(const char *function, const char *file, const int line, Ts &&... pointers)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100148{
Georgios Pinitas3faea252017-10-30 14:13:50 +0000149 const std::array<const void *, sizeof...(Ts)> pointers_array{ { std::forward<Ts>(pointers)... } };
150 bool has_nullptr = std::any_of(pointers_array.begin(), pointers_array.end(), [&](const void *ptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100151 {
Georgios Pinitas3faea252017-10-30 14:13:50 +0000152 return (ptr == nullptr);
153 });
154 ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(has_nullptr, function, file, line, "Nullptr object!");
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000155 return arm_compute::Status{};
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100156}
Georgios Pinitas3faea252017-10-30 14:13:50 +0000157#define ARM_COMPUTE_ERROR_ON_NULLPTR(...) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000158 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_nullptr(__func__, __FILE__, __LINE__, __VA_ARGS__))
Georgios Pinitas3faea252017-10-30 14:13:50 +0000159#define ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(...) \
160 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(__func__, __FILE__, __LINE__, __VA_ARGS__))
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100161
Georgios Pinitas3faea252017-10-30 14:13:50 +0000162/** Return an error if the passed window is invalid.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100163 *
164 * The subwindow is invalid if:
165 * - It is not a valid window.
166 * - Its dimensions don't match the full window's ones
167 * - The step for each of its dimension is not identical to the corresponding one of the full window.
168 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000169 * @param[in] function Function in which the error occurred.
170 * @param[in] file Name of the file where the error occurred.
171 * @param[in] line Line on which the error occurred.
172 * @param[in] full Full size window
173 * @param[in] win Window to validate.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000174 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000175 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100176 */
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000177arm_compute::Status error_on_mismatching_windows(const char *function, const char *file, const int line,
178 const Window &full, const Window &win);
Georgios Pinitas3faea252017-10-30 14:13:50 +0000179#define ARM_COMPUTE_ERROR_ON_MISMATCHING_WINDOWS(f, w) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000180 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_windows(__func__, __FILE__, __LINE__, f, w))
Georgios Pinitas3faea252017-10-30 14:13:50 +0000181#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_WINDOWS(f, w) \
182 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_windows(__func__, __FILE__, __LINE__, f, w))
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100183
Georgios Pinitas3faea252017-10-30 14:13:50 +0000184/** Return an error if the passed subwindow is invalid.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100185 *
186 * The subwindow is invalid if:
187 * - It is not a valid window.
188 * - It is not fully contained inside the full window
189 * - The step for each of its dimension is not identical to the corresponding one of the full window.
190 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000191 * @param[in] function Function in which the error occurred.
192 * @param[in] file Name of the file where the error occurred.
193 * @param[in] line Line on which the error occurred.
194 * @param[in] full Full size window
195 * @param[in] sub Sub-window to validate.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000196 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000197 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100198 */
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000199arm_compute::Status error_on_invalid_subwindow(const char *function, const char *file, const int line,
200 const Window &full, const Window &sub);
Georgios Pinitas3faea252017-10-30 14:13:50 +0000201#define ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(f, s) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000202 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_invalid_subwindow(__func__, __FILE__, __LINE__, f, s))
Georgios Pinitas3faea252017-10-30 14:13:50 +0000203#define ARM_COMPUTE_RETURN_ERROR_ON_INVALID_SUBWINDOW(f, s) \
204 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_invalid_subwindow(__func__, __FILE__, __LINE__, f, s))
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100205
Georgios Pinitas3faea252017-10-30 14:13:50 +0000206/** Return an error if the window can't be collapsed at the given dimension.
steniu01868e5412017-07-17 23:16:00 +0100207 *
208 * The window cannot be collapsed if the given dimension not equal to the full window's dimension or not start from 0.
209 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000210 * @param[in] function Function in which the error occurred.
211 * @param[in] file Name of the file where the error occurred.
212 * @param[in] line Line on which the error occurred.
213 * @param[in] full Full size window
214 * @param[in] window Window to be collapsed.
215 * @param[in] dim Dimension need to be checked.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000216 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000217 * @return Status
steniu01868e5412017-07-17 23:16:00 +0100218 */
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000219arm_compute::Status error_on_window_not_collapsable_at_dimension(const char *function, const char *file, const int line,
220 const Window &full, const Window &window, const int dim);
Georgios Pinitas3faea252017-10-30 14:13:50 +0000221#define ARM_COMPUTE_ERROR_ON_WINDOW_NOT_COLLAPSABLE_AT_DIMENSION(f, w, d) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000222 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_window_not_collapsable_at_dimension(__func__, __FILE__, __LINE__, f, w, d))
Georgios Pinitas3faea252017-10-30 14:13:50 +0000223#define ARM_COMPUTE_RETURN_ERROR_ON_WINDOW_NOT_COLLAPSABLE_AT_DIMENSION(f, w, d) \
224 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_window_not_collapsable_at_dimension(__func__, __FILE__, __LINE__, f, w, d))
steniu01868e5412017-07-17 23:16:00 +0100225
Georgios Pinitas3faea252017-10-30 14:13:50 +0000226/** Return an error if the passed coordinates have too many dimensions.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100227 *
228 * The coordinates have too many dimensions if any of the dimensions greater or equal to max_dim is different from 0.
229 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000230 * @param[in] function Function in which the error occurred.
231 * @param[in] file Name of the file where the error occurred.
232 * @param[in] line Line on which the error occurred.
233 * @param[in] pos Coordinates to validate
234 * @param[in] max_dim Maximum number of dimensions allowed.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000235 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000236 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100237 */
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000238arm_compute::Status error_on_coordinates_dimensions_gte(const char *function, const char *file, const int line,
239 const Coordinates &pos, unsigned int max_dim);
Georgios Pinitas3faea252017-10-30 14:13:50 +0000240#define ARM_COMPUTE_ERROR_ON_COORDINATES_DIMENSIONS_GTE(p, md) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000241 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_coordinates_dimensions_gte(__func__, __FILE__, __LINE__, p, md))
Georgios Pinitas3faea252017-10-30 14:13:50 +0000242#define ARM_COMPUTE_RETURN_ERROR_ON_COORDINATES_DIMENSIONS_GTE(p, md) \
243 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_coordinates_dimensions_gte(__func__, __FILE__, __LINE__, p, md))
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100244
Georgios Pinitas3faea252017-10-30 14:13:50 +0000245/** Return an error if the passed window has too many dimensions.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100246 *
247 * The window has too many dimensions if any of the dimension greater or equal to max_dim is different from 0.
248 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000249 * @param[in] function Function in which the error occurred.
250 * @param[in] file Name of the file where the error occurred.
251 * @param[in] line Line on which the error occurred.
252 * @param[in] win Window to validate
253 * @param[in] max_dim Maximum number of dimensions allowed.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000254 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000255 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100256 */
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000257arm_compute::Status error_on_window_dimensions_gte(const char *function, const char *file, const int line,
258 const Window &win, unsigned int max_dim);
Georgios Pinitas3faea252017-10-30 14:13:50 +0000259#define ARM_COMPUTE_ERROR_ON_WINDOW_DIMENSIONS_GTE(w, md) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000260 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_window_dimensions_gte(__func__, __FILE__, __LINE__, w, md))
Georgios Pinitas3faea252017-10-30 14:13:50 +0000261#define ARM_COMPUTE_RETURN_ERROR_ON_WINDOW_DIMENSIONS_GTE(w, md) \
262 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_window_dimensions_gte(__func__, __FILE__, __LINE__, w, md))
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100263
Georgios Pinitas3faea252017-10-30 14:13:50 +0000264/** Return an error if the passed dimension objects differ.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100265 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000266 * @param[in] function Function in which the error occurred.
267 * @param[in] file Name of the file where the error occurred.
268 * @param[in] line Line on which the error occurred.
269 * @param[in] dim1 The first object to be compared.
270 * @param[in] dim2 The second object to be compared.
271 * @param[in] dims (Optional) Further allowed objects.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000272 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000273 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100274 */
275template <typename T, typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000276arm_compute::Status error_on_mismatching_dimensions(const char *function, const char *file, int line,
277 const Dimensions<T> &dim1, const Dimensions<T> &dim2, Ts &&... dims)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100278{
Georgios Pinitas3faea252017-10-30 14:13:50 +0000279 ARM_COMPUTE_RETURN_ON_ERROR(detail::for_each_error(detail::compare_dimension<T>(dim1, function, file, line), dim2, std::forward<Ts>(dims)...));
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000280 return arm_compute::Status{};
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100281}
Georgios Pinitas3faea252017-10-30 14:13:50 +0000282#define ARM_COMPUTE_ERROR_ON_MISMATCHING_DIMENSIONS(...) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000283 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_dimensions(__func__, __FILE__, __LINE__, __VA_ARGS__))
Georgios Pinitas3faea252017-10-30 14:13:50 +0000284#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DIMENSIONS(...) \
285 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_dimensions(__func__, __FILE__, __LINE__, __VA_ARGS__))
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100286
Ioan-Cristian Szabo9414f642017-10-27 17:35:40 +0100287/** Return an error if the passed tensor objects are not even.
288 *
289 * @param[in] function Function in which the error occurred.
290 * @param[in] file Name of the file where the error occurred.
291 * @param[in] line Line on which the error occurred.
292 * @param[in] format Format to check if odd shape is allowed
293 * @param[in] tensor1 The first object to be compared for odd shape.
294 * @param[in] tensors (Optional) Further allowed objects.
295 *
296 * @return Status
297 */
298template <typename... Ts>
299arm_compute::Status error_on_tensors_not_even(const char *function, const char *file, int line,
300 const Format &format, const ITensor *tensor1, Ts... tensors)
301{
302 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor1 == nullptr, function, file, line);
303 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensors)...));
304 const std::array < const ITensor *, 1 + sizeof...(Ts) > tensors_info_array{ { tensor1, std::forward<Ts>(tensors)... } };
305 ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(tensors_info_array.cbegin(), tensors_info_array.cend(), [&](const ITensor * tensor)
306 {
307 const TensorShape correct_shape = adjust_odd_shape(tensor->info()->tensor_shape(), format);
308 return detail::have_different_dimensions(tensor->info()->tensor_shape(), correct_shape, 2);
309 }),
310 function, file, line, "Tensor shape has odd dimensions");
311 return arm_compute::Status{};
312}
313
314#define ARM_COMPUTE_ERROR_ON_TENSORS_NOT_EVEN(...) \
315 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_tensors_not_even(__func__, __FILE__, __LINE__, __VA_ARGS__))
316#define ARM_COMPUTE_RETURN_ERROR_ON_TENSORS_NOT_EVEN(...) \
317 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_tensors_not_even(__func__, __FILE__, __LINE__, __VA_ARGS__))
318
Ioan-Cristian Szaboae3c8ab2017-11-16 17:55:03 +0000319/** Return an error if the passed tensor objects are not sub-sampled.
320 *
321 * @param[in] function Function in which the error occurred.
322 * @param[in] file Name of the file where the error occurred.
323 * @param[in] line Line on which the error occurred.
324 * @param[in] format Format to check if sub-sampling allowed.
325 * @param[in] shape The tensor shape to calculate sub-sampling from.
326 * @param[in] tensor1 The first object to be compared.
327 * @param[in] tensors (Optional) Further allowed objects.
328 *
329 * @return Status
330 */
331template <typename... Ts>
332arm_compute::Status error_on_tensors_not_subsampled(const char *function, const char *file, int line,
333 const Format &format, const TensorShape &shape, const ITensor *tensor1, Ts... tensors)
334{
335 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor1 == nullptr, function, file, line);
336 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensors)...));
337 const TensorShape sub2_shape = calculate_subsampled_shape(shape, format);
338 const std::array < const ITensor *, 1 + sizeof...(Ts) > tensors_info_array{ { tensor1, std::forward<Ts>(tensors)... } };
339 ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(tensors_info_array.cbegin(), tensors_info_array.cend(), [&](const ITensor * tensor)
340 {
341 return detail::have_different_dimensions(tensor->info()->tensor_shape(), sub2_shape, 2);
342 }),
343 function, file, line, "Tensor shape has mismatch dimensions for sub-sampling");
344 return arm_compute::Status{};
345}
346
347#define ARM_COMPUTE_ERROR_ON_TENSORS_NOT_SUBSAMPLED(...) \
348 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_tensors_not_subsampled(__func__, __FILE__, __LINE__, __VA_ARGS__))
349#define ARM_COMPUTE_RETURN_ERROR_ON_TENSORS_NOT_SUBSAMPLED(...) \
350 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_tensors_not_subsampled(__func__, __FILE__, __LINE__, __VA_ARGS__))
351
Georgios Pinitas3faea252017-10-30 14:13:50 +0000352/** Return an error if the passed two tensor infos have different shapes from the given dimension
353 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000354 * @param[in] function Function in which the error occurred.
355 * @param[in] file Name of the file where the error occurred.
356 * @param[in] line Line on which the error occurred.
357 * @param[in] tensor_info_1 The first tensor info to be compared.
358 * @param[in] tensor_info_2 The second tensor info to be compared.
359 * @param[in] tensor_infos (Optional) Further allowed tensor infos.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000360 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000361 * @return Status
Georgios Pinitas3faea252017-10-30 14:13:50 +0000362 */
363template <typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000364inline arm_compute::Status error_on_mismatching_shapes(const char *function, const char *file, const int line,
365 const ITensorInfo *tensor_info_1, const ITensorInfo *tensor_info_2, Ts... tensor_infos)
Georgios Pinitas3faea252017-10-30 14:13:50 +0000366{
367 return error_on_mismatching_shapes(function, file, line, 0U, tensor_info_1, tensor_info_2, std::forward<Ts>(tensor_infos)...);
368}
369/** Return an error if the passed two tensors have different shapes from the given dimension
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100370 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000371 * @param[in] function Function in which the error occurred.
372 * @param[in] file Name of the file where the error occurred.
373 * @param[in] line Line on which the error occurred.
374 * @param[in] tensor_1 The first tensor to be compared.
375 * @param[in] tensor_2 The second tensor to be compared.
376 * @param[in] tensors (Optional) Further allowed tensors.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000377 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000378 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100379 */
380template <typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000381inline arm_compute::Status error_on_mismatching_shapes(const char *function, const char *file, const int line,
382 const ITensor *tensor_1, const ITensor *tensor_2, Ts... tensors)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100383{
Georgios Pinitas3faea252017-10-30 14:13:50 +0000384 return error_on_mismatching_shapes(function, file, line, 0U, tensor_1, tensor_2, std::forward<Ts>(tensors)...);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100385}
Georgios Pinitas3faea252017-10-30 14:13:50 +0000386/** Return an error if the passed two tensors have different shapes from the given dimension
387 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000388 * @param[in] function Function in which the error occurred.
389 * @param[in] file Name of the file where the error occurred.
390 * @param[in] line Line on which the error occurred.
391 * @param[in] upper_dim The dimension from which to check.
392 * @param[in] tensor_info_1 The first tensor info to be compared.
393 * @param[in] tensor_info_2 The second tensor info to be compared.
394 * @param[in] tensor_infos (Optional) Further allowed tensor infos.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000395 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000396 * @return Status
Georgios Pinitas3faea252017-10-30 14:13:50 +0000397 */
398template <typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000399inline arm_compute::Status error_on_mismatching_shapes(const char *function, const char *file, const int line,
400 unsigned int upper_dim, const ITensorInfo *tensor_info_1, const ITensorInfo *tensor_info_2, Ts... tensor_infos)
Georgios Pinitas3faea252017-10-30 14:13:50 +0000401{
402 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_info_1 == nullptr, function, file, line);
403 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_info_2 == nullptr, function, file, line);
404 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensor_infos)...));
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100405
Georgios Pinitas3faea252017-10-30 14:13:50 +0000406 const std::array < const ITensorInfo *, 2 + sizeof...(Ts) > tensors_info_array{ { tensor_info_1, tensor_info_2, std::forward<Ts>(tensor_infos)... } };
407 ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(std::next(tensors_info_array.cbegin()), tensors_info_array.cend(), [&](const ITensorInfo * tensor_info)
408 {
409 return detail::have_different_dimensions((*tensors_info_array.cbegin())->tensor_shape(), tensor_info->tensor_shape(), upper_dim);
410 }),
411 function, file, line, "Tensors have different shapes");
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000412 return arm_compute::Status{};
Georgios Pinitas3faea252017-10-30 14:13:50 +0000413}
414/** Return an error if the passed two tensors have different shapes from the given dimension
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100415 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000416 * @param[in] function Function in which the error occurred.
417 * @param[in] file Name of the file where the error occurred.
418 * @param[in] line Line on which the error occurred.
419 * @param[in] upper_dim The dimension from which to check.
420 * @param[in] tensor_1 The first tensor to be compared.
421 * @param[in] tensor_2 The second tensor to be compared.
422 * @param[in] tensors (Optional) Further allowed tensors.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000423 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000424 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100425 */
426template <typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000427inline arm_compute::Status error_on_mismatching_shapes(const char *function, const char *file, const int line,
428 unsigned int upper_dim, const ITensor *tensor_1, const ITensor *tensor_2, Ts... tensors)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100429{
Georgios Pinitas3faea252017-10-30 14:13:50 +0000430 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_1 == nullptr, function, file, line);
431 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_2 == nullptr, function, file, line);
432 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensors)...));
433 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_shapes(function, file, line, upper_dim, tensor_1->info(), tensor_2->info(),
434 detail::get_tensor_info_t<ITensorInfo *>()(tensors)...));
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000435 return arm_compute::Status{};
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100436}
Georgios Pinitas3faea252017-10-30 14:13:50 +0000437#define ARM_COMPUTE_ERROR_ON_MISMATCHING_SHAPES(...) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000438 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_shapes(__func__, __FILE__, __LINE__, __VA_ARGS__))
Georgios Pinitas3faea252017-10-30 14:13:50 +0000439#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_SHAPES(...) \
440 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_shapes(__func__, __FILE__, __LINE__, __VA_ARGS__))
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100441
Michalis Spyrou7a569252018-03-01 12:03:14 +0000442/** Return an error if the passed tensor infos have different data layouts
443 *
444 * @param[in] function Function in which the error occurred.
445 * @param[in] file Name of the file where the error occurred.
446 * @param[in] line Line on which the error occurred.
447 * @param[in] tensor_info The first tensor info to be compared.
448 * @param[in] tensor_infos (Optional) Further allowed tensor infos.
449 *
450 * @return Status
451 */
452template <typename... Ts>
453inline arm_compute::Status error_on_mismatching_data_layouts(const char *function, const char *file, const int line,
454 const ITensorInfo *tensor_info, Ts... tensor_infos)
455{
456 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_info == nullptr, function, file, line);
457 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensor_infos)...));
458
459 DataLayout &&tensor_data_layout = tensor_info->data_layout();
460 const std::array<const ITensorInfo *, sizeof...(Ts)> tensors_infos_array{ { std::forward<Ts>(tensor_infos)... } };
461 ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(tensors_infos_array.begin(), tensors_infos_array.end(), [&](const ITensorInfo * tensor_info_obj)
462 {
463 return tensor_info_obj->data_layout() != tensor_data_layout;
464 }),
465 function, file, line, "Tensors have different data layouts");
466 return arm_compute::Status{};
467}
468/** Return an error if the passed tensors have different data layouts
469 *
470 * @param[in] function Function in which the error occurred.
471 * @param[in] file Name of the file where the error occurred.
472 * @param[in] line Line on which the error occurred.
473 * @param[in] tensor The first tensor to be compared.
474 * @param[in] tensors (Optional) Further allowed tensors.
475 *
476 * @return Status
477 */
478template <typename... Ts>
479inline arm_compute::Status error_on_mismatching_data_layouts(const char *function, const char *file, const int line,
480 const ITensor *tensor, Ts... tensors)
481{
482 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor == nullptr, function, file, line);
483 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensors)...));
484 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_data_layouts(function, file, line, tensor->info(),
485 detail::get_tensor_info_t<ITensorInfo *>()(tensors)...));
486 return arm_compute::Status{};
487}
488#define ARM_COMPUTE_ERROR_ON_MISMATCHING_DATA_LAYOUT(...) \
489 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_data_layouts(__func__, __FILE__, __LINE__, __VA_ARGS__))
490#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_LAYOUT(...) \
491 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_data_layouts(__func__, __FILE__, __LINE__, __VA_ARGS__))
492
Georgios Pinitas3faea252017-10-30 14:13:50 +0000493/** Return an error if the passed two tensor infos have different data types
494 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000495 * @param[in] function Function in which the error occurred.
496 * @param[in] file Name of the file where the error occurred.
497 * @param[in] line Line on which the error occurred.
498 * @param[in] tensor_info The first tensor info to be compared.
499 * @param[in] tensor_infos (Optional) Further allowed tensor infos.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000500 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000501 * @return Status
Georgios Pinitas3faea252017-10-30 14:13:50 +0000502 */
503template <typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000504inline arm_compute::Status error_on_mismatching_data_types(const char *function, const char *file, const int line,
505 const ITensorInfo *tensor_info, Ts... tensor_infos)
Georgios Pinitas3faea252017-10-30 14:13:50 +0000506{
507 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_info == nullptr, function, file, line);
508 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensor_infos)...));
509
510 DataType &&tensor_data_type = tensor_info->data_type();
511 const std::array<const ITensorInfo *, sizeof...(Ts)> tensors_infos_array{ { std::forward<Ts>(tensor_infos)... } };
512 ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(tensors_infos_array.begin(), tensors_infos_array.end(), [&](const ITensorInfo * tensor_info_obj)
513 {
514 return tensor_info_obj->data_type() != tensor_data_type;
515 }),
516 function, file, line, "Tensors have different data types");
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000517 return arm_compute::Status{};
Georgios Pinitas3faea252017-10-30 14:13:50 +0000518}
519/** Return an error if the passed two tensors have different data types
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100520 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000521 * @param[in] function Function in which the error occurred.
522 * @param[in] file Name of the file where the error occurred.
523 * @param[in] line Line on which the error occurred.
524 * @param[in] tensor The first tensor to be compared.
525 * @param[in] tensors (Optional) Further allowed tensors.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000526 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000527 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100528 */
529template <typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000530inline arm_compute::Status error_on_mismatching_data_types(const char *function, const char *file, const int line,
531 const ITensor *tensor, Ts... tensors)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100532{
Georgios Pinitas3faea252017-10-30 14:13:50 +0000533 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor == nullptr, function, file, line);
534 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensors)...));
535 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_data_types(function, file, line, tensor->info(),
536 detail::get_tensor_info_t<ITensorInfo *>()(tensors)...));
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000537 return arm_compute::Status{};
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100538}
Georgios Pinitas3faea252017-10-30 14:13:50 +0000539#define ARM_COMPUTE_ERROR_ON_MISMATCHING_DATA_TYPES(...) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000540 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_data_types(__func__, __FILE__, __LINE__, __VA_ARGS__))
Georgios Pinitas3faea252017-10-30 14:13:50 +0000541#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(...) \
542 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_data_types(__func__, __FILE__, __LINE__, __VA_ARGS__))
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100543
Daniil Efremoveed841c2017-11-09 19:05:25 +0700544/** Return an error if the passed tensor infos have different asymmetric quantized data types or different quantization info
545 *
546 * @note: If the first tensor info doesn't have asymmetric quantized data type, the function returns without throwing an error
547 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000548 * @param[in] function Function in which the error occurred.
549 * @param[in] file Name of the file where the error occurred.
550 * @param[in] line Line on which the error occurred.
551 * @param[in] tensor_info_1 The first tensor info to be compared.
552 * @param[in] tensor_info_2 The second tensor info to be compared.
553 * @param[in] tensor_infos (Optional) Further allowed tensor infos.
Daniil Efremoveed841c2017-11-09 19:05:25 +0700554 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000555 * @return Status
Daniil Efremoveed841c2017-11-09 19:05:25 +0700556 */
557template <typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000558inline arm_compute::Status error_on_mismatching_quantization_info(const char *function, const char *file, const int line,
559 const ITensorInfo *tensor_info_1, const ITensorInfo *tensor_info_2, Ts... tensor_infos)
Daniil Efremoveed841c2017-11-09 19:05:25 +0700560{
561 DataType &&first_data_type = tensor_info_1->data_type();
562 const QuantizationInfo first_quantization_info = tensor_info_1->quantization_info();
563
Michalis Spyrouba27e442019-05-28 10:04:57 +0100564 if(!is_data_type_quantized(first_data_type))
Daniil Efremoveed841c2017-11-09 19:05:25 +0700565 {
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000566 return arm_compute::Status{};
Daniil Efremoveed841c2017-11-09 19:05:25 +0700567 }
568
569 const std::array < const ITensorInfo *, 1 + sizeof...(Ts) > tensor_infos_array{ { tensor_info_2, std::forward<Ts>(tensor_infos)... } };
570 ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(tensor_infos_array.begin(), tensor_infos_array.end(), [&](const ITensorInfo * tensor_info)
571 {
572 return tensor_info->data_type() != first_data_type;
573 }),
574 function, file, line, "Tensors have different asymmetric quantized data types");
575 ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(tensor_infos_array.begin(), tensor_infos_array.end(), [&](const ITensorInfo * tensor_info)
576 {
577 return tensor_info->quantization_info() != first_quantization_info;
578 }),
579 function, file, line, "Tensors have different quantization information");
580
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000581 return arm_compute::Status{};
Daniil Efremoveed841c2017-11-09 19:05:25 +0700582}
583/** Return an error if the passed tensor have different asymmetric quantized data types or different quantization info
584 *
585 * @note: If the first tensor doesn't have asymmetric quantized data type, the function returns without throwing an error
586 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000587 * @param[in] function Function in which the error occurred.
588 * @param[in] file Name of the file where the error occurred.
589 * @param[in] line Line on which the error occurred.
590 * @param[in] tensor_1 The first tensor to be compared.
591 * @param[in] tensor_2 The second tensor to be compared.
592 * @param[in] tensors (Optional) Further allowed tensors.
Daniil Efremoveed841c2017-11-09 19:05:25 +0700593 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000594 * @return Status
Daniil Efremoveed841c2017-11-09 19:05:25 +0700595 */
596template <typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000597inline arm_compute::Status error_on_mismatching_quantization_info(const char *function, const char *file, const int line,
598 const ITensor *tensor_1, const ITensor *tensor_2, Ts... tensors)
Daniil Efremoveed841c2017-11-09 19:05:25 +0700599{
600 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_quantization_info(function, file, line, tensor_1->info(), tensor_2->info(),
601 detail::get_tensor_info_t<ITensorInfo *>()(tensors)...));
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000602 return arm_compute::Status{};
Daniil Efremoveed841c2017-11-09 19:05:25 +0700603}
604#define ARM_COMPUTE_ERROR_ON_MISMATCHING_QUANTIZATION_INFO(...) \
605 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_quantization_info(__func__, __FILE__, __LINE__, __VA_ARGS__))
606#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_QUANTIZATION_INFO(...) \
607 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_quantization_info(__func__, __FILE__, __LINE__, __VA_ARGS__))
608
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100609/** Throw an error if the format of the passed tensor/multi-image does not match any of the formats provided.
610 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000611 * @param[in] function Function in which the error occurred.
612 * @param[in] file Name of the file where the error occurred.
613 * @param[in] line Line on which the error occurred.
614 * @param[in] object Tensor/multi-image to validate.
615 * @param[in] format First format allowed.
616 * @param[in] formats (Optional) Further allowed formats.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100617 */
618template <typename T, typename F, typename... Fs>
619void error_on_format_not_in(const char *function, const char *file, const int line,
620 const T *object, F &&format, Fs &&... formats)
621{
622 ARM_COMPUTE_ERROR_ON_LOC(object == nullptr, function, file, line);
623
624 Format &&object_format = object->info()->format();
625 ARM_COMPUTE_UNUSED(object_format);
626
627 ARM_COMPUTE_ERROR_ON_LOC(object_format == Format::UNKNOWN, function, file, line);
628
629 const std::array<F, sizeof...(Fs)> formats_array{ { std::forward<Fs>(formats)... } };
630 ARM_COMPUTE_UNUSED(formats_array);
631
632 ARM_COMPUTE_ERROR_ON_LOC_MSG(object_format != format && std::none_of(formats_array.begin(), formats_array.end(), [&](const F & f)
633 {
634 return f == object_format;
635 }),
636 function, file, line, "Format %s not supported by this kernel", string_from_format(object_format).c_str());
Michalis Spyrou6bff1952019-10-02 17:22:11 +0100637 ARM_COMPUTE_UNUSED(function, format, file, line);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100638}
639#define ARM_COMPUTE_ERROR_ON_FORMAT_NOT_IN(t, ...) ::arm_compute::error_on_format_not_in(__func__, __FILE__, __LINE__, t, __VA_ARGS__)
640
Georgios Pinitas3faea252017-10-30 14:13:50 +0000641/** Return an error if the data type of the passed tensor info does not match any of the data types provided.
642 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000643 * @param[in] function Function in which the error occurred.
644 * @param[in] file Name of the file where the error occurred.
645 * @param[in] line Line on which the error occurred.
646 * @param[in] tensor_info Tensor info to validate.
647 * @param[in] dt First data type allowed.
648 * @param[in] dts (Optional) Further allowed data types.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000649 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000650 * @return Status
Georgios Pinitas3faea252017-10-30 14:13:50 +0000651 */
652template <typename T, typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000653inline arm_compute::Status error_on_data_type_not_in(const char *function, const char *file, const int line,
654 const ITensorInfo *tensor_info, T &&dt, Ts &&... dts)
Georgios Pinitas3faea252017-10-30 14:13:50 +0000655{
656 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_info == nullptr, function, file, line);
657
658 const DataType &tensor_dt = tensor_info->data_type(); //NOLINT
659 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_dt == DataType::UNKNOWN, function, file, line);
660
661 const std::array<T, sizeof...(Ts)> dts_array{ { std::forward<Ts>(dts)... } };
Michalis Spyrou7c60c992019-10-10 14:33:47 +0100662 ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG_VAR(tensor_dt != dt && std::none_of(dts_array.begin(), dts_array.end(), [&](const T & d)
Georgios Pinitas3faea252017-10-30 14:13:50 +0000663 {
664 return d == tensor_dt;
665 }),
666 function, file, line, "ITensor data type %s not supported by this kernel", string_from_data_type(tensor_dt).c_str());
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000667 return arm_compute::Status{};
Georgios Pinitas3faea252017-10-30 14:13:50 +0000668}
669/** Return an error if the data type of the passed tensor does not match any of the data types provided.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100670 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000671 * @param[in] function Function in which the error occurred.
672 * @param[in] file Name of the file where the error occurred.
673 * @param[in] line Line on which the error occurred.
674 * @param[in] tensor Tensor to validate.
675 * @param[in] dt First data type allowed.
676 * @param[in] dts (Optional) Further allowed data types.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000677 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000678 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100679 */
680template <typename T, typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000681inline arm_compute::Status error_on_data_type_not_in(const char *function, const char *file, const int line,
682 const ITensor *tensor, T &&dt, Ts &&... dts)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100683{
Georgios Pinitas3faea252017-10-30 14:13:50 +0000684 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor == nullptr, function, file, line);
685 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_data_type_not_in(function, file, line, tensor->info(), std::forward<T>(dt), std::forward<Ts>(dts)...));
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000686 return arm_compute::Status{};
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100687}
Georgios Pinitas3faea252017-10-30 14:13:50 +0000688#define ARM_COMPUTE_ERROR_ON_DATA_TYPE_NOT_IN(t, ...) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000689 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_data_type_not_in(__func__, __FILE__, __LINE__, t, __VA_ARGS__))
Georgios Pinitas3faea252017-10-30 14:13:50 +0000690#define ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_NOT_IN(t, ...) \
691 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_data_type_not_in(__func__, __FILE__, __LINE__, t, __VA_ARGS__))
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100692
Georgios Pinitasf1adf112018-11-02 12:54:18 +0000693/** Return an error if the data layout of the passed tensor info does not match any of the data layouts provided.
694 *
695 * @param[in] function Function in which the error occurred.
696 * @param[in] file Name of the file where the error occurred.
697 * @param[in] line Line on which the error occurred.
698 * @param[in] tensor_info Tensor info to validate.
699 * @param[in] dl First data layout allowed.
700 * @param[in] dls (Optional) Further allowed data layouts.
701 *
702 * @return Status
703 */
704template <typename T, typename... Ts>
705inline arm_compute::Status error_on_data_layout_not_in(const char *function, const char *file, const int line,
706 const ITensorInfo *tensor_info, T &&dl, Ts &&... dls)
707{
708 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_info == nullptr, function, file, line);
709
710 const DataLayout &tensor_dl = tensor_info->data_layout(); //NOLINT
711 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_dl == DataLayout::UNKNOWN, function, file, line);
712
713 const std::array<T, sizeof...(Ts)> dls_array{ { std::forward<Ts>(dls)... } };
Michalis Spyrou7c60c992019-10-10 14:33:47 +0100714 ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG_VAR(tensor_dl != dl && std::none_of(dls_array.begin(), dls_array.end(), [&](const T & l)
Georgios Pinitasf1adf112018-11-02 12:54:18 +0000715 {
716 return l == tensor_dl;
717 }),
718 function, file, line, "ITensor data layout %s not supported by this kernel", string_from_data_layout(tensor_dl).c_str());
719 return arm_compute::Status{};
720}
721/** Return an error if the data layout of the passed tensor does not match any of the data layout provided.
722 *
723 * @param[in] function Function in which the error occurred.
724 * @param[in] file Name of the file where the error occurred.
725 * @param[in] line Line on which the error occurred.
726 * @param[in] tensor Tensor to validate.
727 * @param[in] dl First data layout allowed.
728 * @param[in] dls (Optional) Further allowed data layouts.
729 *
730 * @return Status
731 */
732template <typename T, typename... Ts>
733inline arm_compute::Status error_on_data_layout_not_in(const char *function, const char *file, const int line,
734 const ITensor *tensor, T &&dl, Ts &&... dls)
735{
736 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor == nullptr, function, file, line);
737 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_data_layout_not_in(function, file, line, tensor->info(), std::forward<T>(dl), std::forward<Ts>(dls)...));
738 return arm_compute::Status{};
739}
740#define ARM_COMPUTE_ERROR_ON_DATA_LAYOUT_NOT_IN(t, ...) \
741 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_data_layout_not_in(__func__, __FILE__, __LINE__, t, __VA_ARGS__))
742#define ARM_COMPUTE_RETURN_ERROR_ON_DATA_LAYOUT_NOT_IN(t, ...) \
743 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_data_layout_not_in(__func__, __FILE__, __LINE__, t, __VA_ARGS__))
744
Georgios Pinitas3faea252017-10-30 14:13:50 +0000745/** Return an error if the data type or the number of channels of the passed tensor info does not match any of the data types and number of channels provided.
746 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000747 * @param[in] function Function in which the error occurred.
748 * @param[in] file Name of the file where the error occurred.
749 * @param[in] line Line on which the error occurred.
750 * @param[in] tensor_info Tensor info to validate.
751 * @param[in] num_channels Number of channels to check
752 * @param[in] dt First data type allowed.
753 * @param[in] dts (Optional) Further allowed data types.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000754 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000755 * @return Status
Georgios Pinitas3faea252017-10-30 14:13:50 +0000756 */
757template <typename T, typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000758inline arm_compute::Status error_on_data_type_channel_not_in(const char *function, const char *file, const int line,
759 const ITensorInfo *tensor_info, size_t num_channels, T &&dt, Ts &&... dts)
Georgios Pinitas3faea252017-10-30 14:13:50 +0000760{
761 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_data_type_not_in(function, file, line, tensor_info, std::forward<T>(dt), std::forward<Ts>(dts)...));
762 const size_t tensor_nc = tensor_info->num_channels();
Michalis Spyrou7c60c992019-10-10 14:33:47 +0100763 ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG_VAR(tensor_nc != num_channels, function, file, line, "Number of channels %zu. Required number of channels %zu", tensor_nc, num_channels);
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000764 return arm_compute::Status{};
Georgios Pinitas3faea252017-10-30 14:13:50 +0000765}
766/** Return an error if the data type or the number of channels of the passed tensor does not match any of the data types and number of channels provided.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100767 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000768 * @param[in] function Function in which the error occurred.
769 * @param[in] file Name of the file where the error occurred.
770 * @param[in] line Line on which the error occurred.
771 * @param[in] tensor Tensor to validate.
772 * @param[in] num_channels Number of channels to check
773 * @param[in] dt First data type allowed.
774 * @param[in] dts (Optional) Further allowed data types.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000775 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000776 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100777 */
778template <typename T, typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000779inline arm_compute::Status error_on_data_type_channel_not_in(const char *function, const char *file, const int line,
780 const ITensor *tensor, size_t num_channels, T &&dt, Ts &&... dts)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100781{
Georgios Pinitas3faea252017-10-30 14:13:50 +0000782 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor == nullptr, function, file, line);
783 ARM_COMPUTE_RETURN_ON_ERROR(error_on_data_type_channel_not_in(function, file, line, tensor->info(), num_channels, std::forward<T>(dt), std::forward<Ts>(dts)...));
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000784 return arm_compute::Status{};
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100785}
Georgios Pinitas3faea252017-10-30 14:13:50 +0000786#define ARM_COMPUTE_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(t, c, ...) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000787 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_data_type_channel_not_in(__func__, __FILE__, __LINE__, t, c, __VA_ARGS__))
Georgios Pinitas3faea252017-10-30 14:13:50 +0000788#define ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(t, c, ...) \
789 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_data_type_channel_not_in(__func__, __FILE__, __LINE__, t, c, __VA_ARGS__))
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100790
Vidhya Sudhan Loganathanf1f49062018-05-25 13:21:26 +0100791/** Return an error if the data type of the passed tensor info is FP16 and FP16 extension is not supported by the device.
792 *
793 * @param[in] function Function in which the error occurred.
794 * @param[in] file Name of the file where the error occurred.
795 * @param[in] line Line on which the error occurred.
796 * @param[in] tensor_info Tensor info to validate.
797 * @param[in] is_fp16_supported Is fp16 supported by the device.
798 *
799 * @return Status
800 */
801inline arm_compute::Status error_on_unsupported_fp16(const char *function, const char *file, const int line,
802 const ITensorInfo *tensor_info, bool is_fp16_supported)
803{
804 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_info == nullptr, function, file, line);
805 ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG((tensor_info->data_type() == DataType::F16 && !is_fp16_supported),
806 function, file, line, "FP16 not supported by the device");
807 return arm_compute::Status{};
808}
809
810/** Return an error if the data type of the passed tensor is FP16 and FP16 extension is not supported by the device.
811 *
812 * @param[in] function Function in which the error occurred.
813 * @param[in] file Name of the file where the error occurred.
814 * @param[in] line Line on which the error occurred.
815 * @param[in] tensor Tensor to validate.
816 * @param[in] is_fp16_supported Is fp16 supported by the device.
817 *
818 * @return Status
819 */
820inline arm_compute::Status error_on_unsupported_fp16(const char *function, const char *file, const int line,
821 const ITensor *tensor, bool is_fp16_supported)
822{
823 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor == nullptr, function, file, line);
824 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_unsupported_fp16(function, file, line, tensor->info(), is_fp16_supported));
825 return arm_compute::Status{};
826}
827
Georgios Pinitas3faea252017-10-30 14:13:50 +0000828/** Return an error if the tensor is not 2D.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100829 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000830 * @param[in] function Function in which the error occurred.
831 * @param[in] file Name of the file where the error occurred.
832 * @param[in] line Line on which the error occurred.
833 * @param[in] tensor Tensor to validate.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000834 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000835 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100836 */
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000837arm_compute::Status error_on_tensor_not_2d(const char *function, const char *file, const int line,
838 const ITensor *tensor);
Michalis Spyroud1794eb2018-06-15 16:15:26 +0100839
840/** Return an error if the tensor info is not 2D.
841 *
842 * @param[in] function Function in which the error occurred.
843 * @param[in] file Name of the file where the error occurred.
844 * @param[in] line Line on which the error occurred.
845 * @param[in] tensor Tensor info to validate.
846 *
847 * @return Status
848 */
849arm_compute::Status error_on_tensor_not_2d(const char *function, const char *file, const int line,
850 const ITensorInfo *tensor);
851
Georgios Pinitas3faea252017-10-30 14:13:50 +0000852#define ARM_COMPUTE_ERROR_ON_TENSOR_NOT_2D(t) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000853 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_tensor_not_2d(__func__, __FILE__, __LINE__, t))
Georgios Pinitas3faea252017-10-30 14:13:50 +0000854#define ARM_COMPUTE_RETURN_ERROR_ON_TENSOR_NOT_2D(t) \
855 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_tensor_not_2d(__func__, __FILE__, __LINE__, t))
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100856
Georgios Pinitas3faea252017-10-30 14:13:50 +0000857/** Return an error if the channel is not in channels.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100858 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000859 * @param[in] function Function in which the error occurred.
860 * @param[in] file Name of the file where the error occurred.
861 * @param[in] line Line on which the error occurred.
862 * @param[in] cn Input channel
863 * @param[in] channel First channel allowed.
864 * @param[in] channels (Optional) Further allowed channels.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000865 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000866 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100867 */
868template <typename T, typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000869inline arm_compute::Status error_on_channel_not_in(const char *function, const char *file, const int line,
870 T cn, T &&channel, Ts &&... channels)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100871{
Georgios Pinitas3faea252017-10-30 14:13:50 +0000872 ARM_COMPUTE_RETURN_ERROR_ON_LOC(cn == Channel::UNKNOWN, function, file, line);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100873
874 const std::array<T, sizeof...(Ts)> channels_array{ { std::forward<Ts>(channels)... } };
Georgios Pinitas3faea252017-10-30 14:13:50 +0000875 ARM_COMPUTE_RETURN_ERROR_ON_LOC(channel != cn && std::none_of(channels_array.begin(), channels_array.end(), [&](const T & f)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100876 {
877 return f == cn;
878 }),
879 function, file, line);
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000880 return arm_compute::Status{};
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100881}
Georgios Pinitas3faea252017-10-30 14:13:50 +0000882#define ARM_COMPUTE_ERROR_ON_CHANNEL_NOT_IN(c, ...) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000883 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_channel_not_in(__func__, __FILE__, __LINE__, c, __VA_ARGS__))
Georgios Pinitas3faea252017-10-30 14:13:50 +0000884#define ARM_COMPUTE_RETURN_ERROR_ON_CHANNEL_NOT_IN(c, ...) \
885 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_channel_not_in(__func__, __FILE__, __LINE__, c, __VA_ARGS__))
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100886
Georgios Pinitas3faea252017-10-30 14:13:50 +0000887/** Return an error if the channel is not in format.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100888 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000889 * @param[in] function Function in which the error occurred.
890 * @param[in] file Name of the file where the error occurred.
891 * @param[in] line Line on which the error occurred.
892 * @param[in] fmt Input channel
893 * @param[in] cn First channel allowed.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000894 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000895 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100896 */
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000897arm_compute::Status error_on_channel_not_in_known_format(const char *function, const char *file, const int line,
898 Format fmt, Channel cn);
Georgios Pinitas3faea252017-10-30 14:13:50 +0000899#define ARM_COMPUTE_ERROR_ON_CHANNEL_NOT_IN_KNOWN_FORMAT(f, c) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000900 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_channel_not_in_known_format(__func__, __FILE__, __LINE__, f, c))
Georgios Pinitas3faea252017-10-30 14:13:50 +0000901#define ARM_COMPUTE_RETURN_ERROR_ON_CHANNEL_NOT_IN_KNOWN_FORMAT(f, c) \
902 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_channel_not_in_known_format(__func__, __FILE__, __LINE__, f, c))
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100903
Georgios Pinitas3faea252017-10-30 14:13:50 +0000904/** Return an error if the kernel is not configured.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100905 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000906 * @param[in] function Function in which the error occurred.
907 * @param[in] file Name of the file where the error occurred.
908 * @param[in] line Line on which the error occurred.
909 * @param[in] kernel Kernel to validate.
Alex Gildayc357c472018-03-21 13:54:09 +0000910 *
911 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100912 */
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000913arm_compute::Status error_on_unconfigured_kernel(const char *function, const char *file, const int line,
914 const IKernel *kernel);
Georgios Pinitas3faea252017-10-30 14:13:50 +0000915#define ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(k) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000916 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_unconfigured_kernel(__func__, __FILE__, __LINE__, k))
Georgios Pinitas3faea252017-10-30 14:13:50 +0000917#define ARM_COMPUTE_RETURN_ERROR_ON_UNCONFIGURED_KERNEL(k) \
918 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_unconfigured_kernel(__func__, __FILE__, __LINE__, k))
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100919
Georgios Pinitas3faea252017-10-30 14:13:50 +0000920/** Return an error if if the coordinates and shape of the subtensor are within the parent tensor.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100921 *
922 * @param[in] function Function in which the error occurred.
923 * @param[in] file Name of the file where the error occurred.
924 * @param[in] line Line on which the error occurred.
925 * @param[in] parent_shape Parent tensor shape
926 * @param[in] coords Coordinates inside the parent tensor where the first element of the subtensor is
927 * @param[in] shape Shape of the subtensor
Georgios Pinitas3faea252017-10-30 14:13:50 +0000928 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000929 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100930 */
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000931arm_compute::Status error_on_invalid_subtensor(const char *function, const char *file, const int line,
932 const TensorShape &parent_shape, const Coordinates &coords, const TensorShape &shape);
Georgios Pinitas3faea252017-10-30 14:13:50 +0000933#define ARM_COMPUTE_ERROR_ON_INVALID_SUBTENSOR(p, c, s) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000934 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_invalid_subtensor(__func__, __FILE__, __LINE__, p, c, s))
Georgios Pinitas3faea252017-10-30 14:13:50 +0000935#define ARM_COMPUTE_RETURN_ERROR_ON_INVALID_SUBTENSOR(p, c, s) \
936 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_invalid_subtensor(__func__, __FILE__, __LINE__, p, c, s))
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100937
Georgios Pinitas3faea252017-10-30 14:13:50 +0000938/** Return an error if the valid region of a subtensor is not inside the valid region of the parent tensor.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100939 *
940 * @param[in] function Function in which the error occurred.
941 * @param[in] file Name of the file where the error occurred.
942 * @param[in] line Line on which the error occurred.
943 * @param[in] parent_valid_region Parent valid region.
944 * @param[in] valid_region Valid region of subtensor.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000945 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000946 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100947 */
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000948arm_compute::Status error_on_invalid_subtensor_valid_region(const char *function, const char *file, const int line,
949 const ValidRegion &parent_valid_region, const ValidRegion &valid_region);
Georgios Pinitas3faea252017-10-30 14:13:50 +0000950#define ARM_COMPUTE_ERROR_ON_INVALID_SUBTENSOR_VALID_REGION(pv, sv) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000951 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_invalid_subtensor_valid_region(__func__, __FILE__, __LINE__, pv, sv))
Georgios Pinitas3faea252017-10-30 14:13:50 +0000952#define ARM_COMPUTE_RETURN_ERROR_ON_INVALID_SUBTENSOR_VALID_REGION(pv, sv) \
953 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_invalid_subtensor_valid_region(__func__, __FILE__, __LINE__, pv, sv))
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100954}
Michalis Spyrouf4643372019-11-29 16:17:13 +0000955#endif /* ARM_COMPUTE_VALIDATE_H*/