blob: 76a32f40070835594bffc8100e586d689173d8ee [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*
Michalis Spyrouba27e442019-05-28 10:04:57 +01002 * Copyright (c) 2016-2019 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 */
24#ifndef __ARM_COMPUTE_VALIDATE_H__
25#define __ARM_COMPUTE_VALIDATE_H__
26
27#include "arm_compute/core/Error.h"
28#include "arm_compute/core/HOGInfo.h"
29#include "arm_compute/core/IKernel.h"
30#include "arm_compute/core/IMultiHOG.h"
31#include "arm_compute/core/IMultiImage.h"
32#include "arm_compute/core/ITensor.h"
33#include "arm_compute/core/MultiImageInfo.h"
34#include "arm_compute/core/Window.h"
35
36#include <algorithm>
37
38namespace arm_compute
39{
40namespace detail
41{
42/* Check whether two dimension objects differ.
43 *
44 * @param[in] dim1 First object to be compared.
45 * @param[in] dim2 Second object to be compared.
46 * @param[in] upper_dim The dimension from which to check.
47 *
48 * @return Return true if the two objects are different.
49 */
50template <typename T>
51inline bool have_different_dimensions(const Dimensions<T> &dim1, const Dimensions<T> &dim2, unsigned int upper_dim)
52{
53 for(unsigned int i = upper_dim; i < arm_compute::Dimensions<T>::num_max_dimensions; ++i)
54 {
55 if(dim1[i] != dim2[i])
56 {
57 return true;
58 }
59 }
60
61 return false;
62}
63
Alex Gildayc357c472018-03-21 13:54:09 +000064/** Function to compare two @ref Dimensions objects and throw an error on mismatch.
Anthony Barbier6ff3b192017-09-04 18:44:23 +010065 *
66 * @param[in] dim Object to compare against.
Georgios Pinitas3faea252017-10-30 14:13:50 +000067 * @param[in] function Function in which the error occurred.
68 * @param[in] file File in which the error occurred.
69 * @param[in] line Line in which the error occurred.
Anthony Barbier6ff3b192017-09-04 18:44:23 +010070 */
71template <typename T>
72class compare_dimension
73{
74public:
Alex Gildayc357c472018-03-21 13:54:09 +000075 /** Construct a comparison function.
76 *
77 * @param[in] dim Dimensions to compare.
78 * @param[in] function Source function. Used for error reporting.
79 * @param[in] file Source code file. Used for error reporting.
80 * @param[in] line Source code line. Used for error reporting.
81 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +010082 compare_dimension(const Dimensions<T> &dim, const char *function, const char *file, int line)
83 : _dim{ dim }, _function{ function }, _file{ file }, _line{ line }
84 {
85 }
86
87 /** Compare the given object against the stored one.
88 *
89 * @param[in] dim To be compared object.
Alex Gildayc357c472018-03-21 13:54:09 +000090 *
91 * @return a status.
Anthony Barbier6ff3b192017-09-04 18:44:23 +010092 */
Georgios Pinitas631c41a2017-12-06 11:53:03 +000093 arm_compute::Status operator()(const Dimensions<T> &dim)
Anthony Barbier6ff3b192017-09-04 18:44:23 +010094 {
Georgios Pinitas3faea252017-10-30 14:13:50 +000095 ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(have_different_dimensions(_dim, dim, 0), _function, _file, _line,
96 "Objects have different dimensions");
Georgios Pinitas631c41a2017-12-06 11:53:03 +000097 return arm_compute::Status{};
Anthony Barbier6ff3b192017-09-04 18:44:23 +010098 }
99
100private:
101 const Dimensions<T> &_dim;
102 const char *const _function;
103 const char *const _file;
104 const int _line;
105};
Georgios Pinitas3faea252017-10-30 14:13:50 +0000106
107template <typename F>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000108inline arm_compute::Status for_each_error(F &&)
Georgios Pinitas3faea252017-10-30 14:13:50 +0000109{
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000110 return arm_compute::Status{};
Georgios Pinitas3faea252017-10-30 14:13:50 +0000111}
112
113template <typename F, typename T, typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000114inline arm_compute::Status for_each_error(F &&func, T &&arg, Ts &&... args)
Georgios Pinitas3faea252017-10-30 14:13:50 +0000115{
116 ARM_COMPUTE_RETURN_ON_ERROR(func(arg));
117 ARM_COMPUTE_RETURN_ON_ERROR(for_each_error(func, args...));
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000118 return arm_compute::Status{};
Georgios Pinitas3faea252017-10-30 14:13:50 +0000119}
120
Alex Gildayc357c472018-03-21 13:54:09 +0000121/** Get the info for a tensor, dummy struct */
Georgios Pinitas3faea252017-10-30 14:13:50 +0000122template <typename T>
123struct get_tensor_info_t;
Alex Gildayc357c472018-03-21 13:54:09 +0000124/** Get the info for a tensor */
Georgios Pinitas3faea252017-10-30 14:13:50 +0000125template <>
126struct get_tensor_info_t<ITensorInfo *>
127{
Alex Gildayc357c472018-03-21 13:54:09 +0000128 /** Get the info for a tensor.
129 *
130 * @param[in] tensor Tensor.
131 *
132 * @return tensor info.
133 */
Georgios Pinitas3faea252017-10-30 14:13:50 +0000134 ITensorInfo *operator()(const ITensor *tensor)
135 {
136 return tensor->info();
137 }
138};
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100139} // namespace detail
Georgios Pinitas3faea252017-10-30 14:13:50 +0000140
141/** Create an error if one of the pointers is a nullptr.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100142 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000143 * @param[in] function Function in which the error occurred.
144 * @param[in] file Name of the file where the error occurred.
145 * @param[in] line Line on which the error occurred.
146 * @param[in] pointers Pointers to check against nullptr.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000147 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000148 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100149 */
150template <typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000151inline arm_compute::Status error_on_nullptr(const char *function, const char *file, const int line, Ts &&... pointers)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100152{
Georgios Pinitas3faea252017-10-30 14:13:50 +0000153 const std::array<const void *, sizeof...(Ts)> pointers_array{ { std::forward<Ts>(pointers)... } };
154 bool has_nullptr = std::any_of(pointers_array.begin(), pointers_array.end(), [&](const void *ptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100155 {
Georgios Pinitas3faea252017-10-30 14:13:50 +0000156 return (ptr == nullptr);
157 });
158 ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(has_nullptr, function, file, line, "Nullptr object!");
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000159 return arm_compute::Status{};
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100160}
Georgios Pinitas3faea252017-10-30 14:13:50 +0000161#define ARM_COMPUTE_ERROR_ON_NULLPTR(...) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000162 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_nullptr(__func__, __FILE__, __LINE__, __VA_ARGS__))
Georgios Pinitas3faea252017-10-30 14:13:50 +0000163#define ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(...) \
164 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(__func__, __FILE__, __LINE__, __VA_ARGS__))
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100165
Georgios Pinitas3faea252017-10-30 14:13:50 +0000166/** Return an error if the passed window is invalid.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100167 *
168 * The subwindow is invalid if:
169 * - It is not a valid window.
170 * - Its dimensions don't match the full window's ones
171 * - The step for each of its dimension is not identical to the corresponding one of the full window.
172 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000173 * @param[in] function Function in which the error occurred.
174 * @param[in] file Name of the file where the error occurred.
175 * @param[in] line Line on which the error occurred.
176 * @param[in] full Full size window
177 * @param[in] win Window to validate.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000178 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000179 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100180 */
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000181arm_compute::Status error_on_mismatching_windows(const char *function, const char *file, const int line,
182 const Window &full, const Window &win);
Georgios Pinitas3faea252017-10-30 14:13:50 +0000183#define ARM_COMPUTE_ERROR_ON_MISMATCHING_WINDOWS(f, w) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000184 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_windows(__func__, __FILE__, __LINE__, f, w))
Georgios Pinitas3faea252017-10-30 14:13:50 +0000185#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_WINDOWS(f, w) \
186 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_windows(__func__, __FILE__, __LINE__, f, w))
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100187
Georgios Pinitas3faea252017-10-30 14:13:50 +0000188/** Return an error if the passed subwindow is invalid.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100189 *
190 * The subwindow is invalid if:
191 * - It is not a valid window.
192 * - It is not fully contained inside the full window
193 * - The step for each of its dimension is not identical to the corresponding one of the full window.
194 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000195 * @param[in] function Function in which the error occurred.
196 * @param[in] file Name of the file where the error occurred.
197 * @param[in] line Line on which the error occurred.
198 * @param[in] full Full size window
199 * @param[in] sub Sub-window to validate.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000200 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000201 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100202 */
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000203arm_compute::Status error_on_invalid_subwindow(const char *function, const char *file, const int line,
204 const Window &full, const Window &sub);
Georgios Pinitas3faea252017-10-30 14:13:50 +0000205#define ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(f, s) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000206 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_invalid_subwindow(__func__, __FILE__, __LINE__, f, s))
Georgios Pinitas3faea252017-10-30 14:13:50 +0000207#define ARM_COMPUTE_RETURN_ERROR_ON_INVALID_SUBWINDOW(f, s) \
208 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_invalid_subwindow(__func__, __FILE__, __LINE__, f, s))
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100209
Georgios Pinitas3faea252017-10-30 14:13:50 +0000210/** Return an error if the window can't be collapsed at the given dimension.
steniu01868e5412017-07-17 23:16:00 +0100211 *
212 * The window cannot be collapsed if the given dimension not equal to the full window's dimension or not start from 0.
213 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000214 * @param[in] function Function in which the error occurred.
215 * @param[in] file Name of the file where the error occurred.
216 * @param[in] line Line on which the error occurred.
217 * @param[in] full Full size window
218 * @param[in] window Window to be collapsed.
219 * @param[in] dim Dimension need to be checked.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000220 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000221 * @return Status
steniu01868e5412017-07-17 23:16:00 +0100222 */
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000223arm_compute::Status error_on_window_not_collapsable_at_dimension(const char *function, const char *file, const int line,
224 const Window &full, const Window &window, const int dim);
Georgios Pinitas3faea252017-10-30 14:13:50 +0000225#define ARM_COMPUTE_ERROR_ON_WINDOW_NOT_COLLAPSABLE_AT_DIMENSION(f, w, d) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000226 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 +0000227#define ARM_COMPUTE_RETURN_ERROR_ON_WINDOW_NOT_COLLAPSABLE_AT_DIMENSION(f, w, d) \
228 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 +0100229
Georgios Pinitas3faea252017-10-30 14:13:50 +0000230/** Return an error if the passed coordinates have too many dimensions.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100231 *
232 * The coordinates have too many dimensions if any of the dimensions greater or equal to max_dim is different from 0.
233 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000234 * @param[in] function Function in which the error occurred.
235 * @param[in] file Name of the file where the error occurred.
236 * @param[in] line Line on which the error occurred.
237 * @param[in] pos Coordinates to validate
238 * @param[in] max_dim Maximum number of dimensions allowed.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000239 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000240 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100241 */
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000242arm_compute::Status error_on_coordinates_dimensions_gte(const char *function, const char *file, const int line,
243 const Coordinates &pos, unsigned int max_dim);
Georgios Pinitas3faea252017-10-30 14:13:50 +0000244#define ARM_COMPUTE_ERROR_ON_COORDINATES_DIMENSIONS_GTE(p, md) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000245 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_coordinates_dimensions_gte(__func__, __FILE__, __LINE__, p, md))
Georgios Pinitas3faea252017-10-30 14:13:50 +0000246#define ARM_COMPUTE_RETURN_ERROR_ON_COORDINATES_DIMENSIONS_GTE(p, md) \
247 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_coordinates_dimensions_gte(__func__, __FILE__, __LINE__, p, md))
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100248
Georgios Pinitas3faea252017-10-30 14:13:50 +0000249/** Return an error if the passed window has too many dimensions.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100250 *
251 * The window has too many dimensions if any of the dimension greater or equal to max_dim is different from 0.
252 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000253 * @param[in] function Function in which the error occurred.
254 * @param[in] file Name of the file where the error occurred.
255 * @param[in] line Line on which the error occurred.
256 * @param[in] win Window to validate
257 * @param[in] max_dim Maximum number of dimensions allowed.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000258 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000259 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100260 */
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000261arm_compute::Status error_on_window_dimensions_gte(const char *function, const char *file, const int line,
262 const Window &win, unsigned int max_dim);
Georgios Pinitas3faea252017-10-30 14:13:50 +0000263#define ARM_COMPUTE_ERROR_ON_WINDOW_DIMENSIONS_GTE(w, md) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000264 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_window_dimensions_gte(__func__, __FILE__, __LINE__, w, md))
Georgios Pinitas3faea252017-10-30 14:13:50 +0000265#define ARM_COMPUTE_RETURN_ERROR_ON_WINDOW_DIMENSIONS_GTE(w, md) \
266 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_window_dimensions_gte(__func__, __FILE__, __LINE__, w, md))
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100267
Georgios Pinitas3faea252017-10-30 14:13:50 +0000268/** Return an error if the passed dimension objects differ.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100269 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000270 * @param[in] function Function in which the error occurred.
271 * @param[in] file Name of the file where the error occurred.
272 * @param[in] line Line on which the error occurred.
273 * @param[in] dim1 The first object to be compared.
274 * @param[in] dim2 The second object to be compared.
275 * @param[in] dims (Optional) Further allowed objects.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000276 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000277 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100278 */
279template <typename T, typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000280arm_compute::Status error_on_mismatching_dimensions(const char *function, const char *file, int line,
281 const Dimensions<T> &dim1, const Dimensions<T> &dim2, Ts &&... dims)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100282{
Georgios Pinitas3faea252017-10-30 14:13:50 +0000283 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 +0000284 return arm_compute::Status{};
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100285}
Georgios Pinitas3faea252017-10-30 14:13:50 +0000286#define ARM_COMPUTE_ERROR_ON_MISMATCHING_DIMENSIONS(...) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000287 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_dimensions(__func__, __FILE__, __LINE__, __VA_ARGS__))
Georgios Pinitas3faea252017-10-30 14:13:50 +0000288#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DIMENSIONS(...) \
289 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_dimensions(__func__, __FILE__, __LINE__, __VA_ARGS__))
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100290
Ioan-Cristian Szabo9414f642017-10-27 17:35:40 +0100291/** Return an error if the passed tensor objects are not even.
292 *
293 * @param[in] function Function in which the error occurred.
294 * @param[in] file Name of the file where the error occurred.
295 * @param[in] line Line on which the error occurred.
296 * @param[in] format Format to check if odd shape is allowed
297 * @param[in] tensor1 The first object to be compared for odd shape.
298 * @param[in] tensors (Optional) Further allowed objects.
299 *
300 * @return Status
301 */
302template <typename... Ts>
303arm_compute::Status error_on_tensors_not_even(const char *function, const char *file, int line,
304 const Format &format, const ITensor *tensor1, Ts... tensors)
305{
306 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor1 == nullptr, function, file, line);
307 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensors)...));
308 const std::array < const ITensor *, 1 + sizeof...(Ts) > tensors_info_array{ { tensor1, std::forward<Ts>(tensors)... } };
309 ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(tensors_info_array.cbegin(), tensors_info_array.cend(), [&](const ITensor * tensor)
310 {
311 const TensorShape correct_shape = adjust_odd_shape(tensor->info()->tensor_shape(), format);
312 return detail::have_different_dimensions(tensor->info()->tensor_shape(), correct_shape, 2);
313 }),
314 function, file, line, "Tensor shape has odd dimensions");
315 return arm_compute::Status{};
316}
317
318#define ARM_COMPUTE_ERROR_ON_TENSORS_NOT_EVEN(...) \
319 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_tensors_not_even(__func__, __FILE__, __LINE__, __VA_ARGS__))
320#define ARM_COMPUTE_RETURN_ERROR_ON_TENSORS_NOT_EVEN(...) \
321 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_tensors_not_even(__func__, __FILE__, __LINE__, __VA_ARGS__))
322
Ioan-Cristian Szaboae3c8ab2017-11-16 17:55:03 +0000323/** Return an error if the passed tensor objects are not sub-sampled.
324 *
325 * @param[in] function Function in which the error occurred.
326 * @param[in] file Name of the file where the error occurred.
327 * @param[in] line Line on which the error occurred.
328 * @param[in] format Format to check if sub-sampling allowed.
329 * @param[in] shape The tensor shape to calculate sub-sampling from.
330 * @param[in] tensor1 The first object to be compared.
331 * @param[in] tensors (Optional) Further allowed objects.
332 *
333 * @return Status
334 */
335template <typename... Ts>
336arm_compute::Status error_on_tensors_not_subsampled(const char *function, const char *file, int line,
337 const Format &format, const TensorShape &shape, const ITensor *tensor1, Ts... tensors)
338{
339 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor1 == nullptr, function, file, line);
340 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensors)...));
341 const TensorShape sub2_shape = calculate_subsampled_shape(shape, format);
342 const std::array < const ITensor *, 1 + sizeof...(Ts) > tensors_info_array{ { tensor1, std::forward<Ts>(tensors)... } };
343 ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(tensors_info_array.cbegin(), tensors_info_array.cend(), [&](const ITensor * tensor)
344 {
345 return detail::have_different_dimensions(tensor->info()->tensor_shape(), sub2_shape, 2);
346 }),
347 function, file, line, "Tensor shape has mismatch dimensions for sub-sampling");
348 return arm_compute::Status{};
349}
350
351#define ARM_COMPUTE_ERROR_ON_TENSORS_NOT_SUBSAMPLED(...) \
352 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_tensors_not_subsampled(__func__, __FILE__, __LINE__, __VA_ARGS__))
353#define ARM_COMPUTE_RETURN_ERROR_ON_TENSORS_NOT_SUBSAMPLED(...) \
354 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_tensors_not_subsampled(__func__, __FILE__, __LINE__, __VA_ARGS__))
355
Georgios Pinitas3faea252017-10-30 14:13:50 +0000356/** Return an error if the passed two tensor infos have different shapes from the given dimension
357 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000358 * @param[in] function Function in which the error occurred.
359 * @param[in] file Name of the file where the error occurred.
360 * @param[in] line Line on which the error occurred.
361 * @param[in] tensor_info_1 The first tensor info to be compared.
362 * @param[in] tensor_info_2 The second tensor info to be compared.
363 * @param[in] tensor_infos (Optional) Further allowed tensor infos.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000364 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000365 * @return Status
Georgios Pinitas3faea252017-10-30 14:13:50 +0000366 */
367template <typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000368inline arm_compute::Status error_on_mismatching_shapes(const char *function, const char *file, const int line,
369 const ITensorInfo *tensor_info_1, const ITensorInfo *tensor_info_2, Ts... tensor_infos)
Georgios Pinitas3faea252017-10-30 14:13:50 +0000370{
371 return error_on_mismatching_shapes(function, file, line, 0U, tensor_info_1, tensor_info_2, std::forward<Ts>(tensor_infos)...);
372}
373/** Return an error if the passed two tensors have different shapes from the given dimension
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100374 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000375 * @param[in] function Function in which the error occurred.
376 * @param[in] file Name of the file where the error occurred.
377 * @param[in] line Line on which the error occurred.
378 * @param[in] tensor_1 The first tensor to be compared.
379 * @param[in] tensor_2 The second tensor to be compared.
380 * @param[in] tensors (Optional) Further allowed tensors.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000381 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000382 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100383 */
384template <typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000385inline arm_compute::Status error_on_mismatching_shapes(const char *function, const char *file, const int line,
386 const ITensor *tensor_1, const ITensor *tensor_2, Ts... tensors)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100387{
Georgios Pinitas3faea252017-10-30 14:13:50 +0000388 return error_on_mismatching_shapes(function, file, line, 0U, tensor_1, tensor_2, std::forward<Ts>(tensors)...);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100389}
Georgios Pinitas3faea252017-10-30 14:13:50 +0000390/** Return an error if the passed two tensors have different shapes from the given dimension
391 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000392 * @param[in] function Function in which the error occurred.
393 * @param[in] file Name of the file where the error occurred.
394 * @param[in] line Line on which the error occurred.
395 * @param[in] upper_dim The dimension from which to check.
396 * @param[in] tensor_info_1 The first tensor info to be compared.
397 * @param[in] tensor_info_2 The second tensor info to be compared.
398 * @param[in] tensor_infos (Optional) Further allowed tensor infos.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000399 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000400 * @return Status
Georgios Pinitas3faea252017-10-30 14:13:50 +0000401 */
402template <typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000403inline arm_compute::Status error_on_mismatching_shapes(const char *function, const char *file, const int line,
404 unsigned int upper_dim, const ITensorInfo *tensor_info_1, const ITensorInfo *tensor_info_2, Ts... tensor_infos)
Georgios Pinitas3faea252017-10-30 14:13:50 +0000405{
406 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_info_1 == nullptr, function, file, line);
407 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_info_2 == nullptr, function, file, line);
408 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 +0100409
Georgios Pinitas3faea252017-10-30 14:13:50 +0000410 const std::array < const ITensorInfo *, 2 + sizeof...(Ts) > tensors_info_array{ { tensor_info_1, tensor_info_2, std::forward<Ts>(tensor_infos)... } };
411 ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(std::next(tensors_info_array.cbegin()), tensors_info_array.cend(), [&](const ITensorInfo * tensor_info)
412 {
413 return detail::have_different_dimensions((*tensors_info_array.cbegin())->tensor_shape(), tensor_info->tensor_shape(), upper_dim);
414 }),
415 function, file, line, "Tensors have different shapes");
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000416 return arm_compute::Status{};
Georgios Pinitas3faea252017-10-30 14:13:50 +0000417}
418/** Return an error if the passed two tensors have different shapes from the given dimension
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100419 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000420 * @param[in] function Function in which the error occurred.
421 * @param[in] file Name of the file where the error occurred.
422 * @param[in] line Line on which the error occurred.
423 * @param[in] upper_dim The dimension from which to check.
424 * @param[in] tensor_1 The first tensor to be compared.
425 * @param[in] tensor_2 The second tensor to be compared.
426 * @param[in] tensors (Optional) Further allowed tensors.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000427 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000428 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100429 */
430template <typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000431inline arm_compute::Status error_on_mismatching_shapes(const char *function, const char *file, const int line,
432 unsigned int upper_dim, const ITensor *tensor_1, const ITensor *tensor_2, Ts... tensors)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100433{
Georgios Pinitas3faea252017-10-30 14:13:50 +0000434 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_1 == nullptr, function, file, line);
435 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_2 == nullptr, function, file, line);
436 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensors)...));
437 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_shapes(function, file, line, upper_dim, tensor_1->info(), tensor_2->info(),
438 detail::get_tensor_info_t<ITensorInfo *>()(tensors)...));
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000439 return arm_compute::Status{};
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100440}
Georgios Pinitas3faea252017-10-30 14:13:50 +0000441#define ARM_COMPUTE_ERROR_ON_MISMATCHING_SHAPES(...) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000442 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_shapes(__func__, __FILE__, __LINE__, __VA_ARGS__))
Georgios Pinitas3faea252017-10-30 14:13:50 +0000443#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_SHAPES(...) \
444 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_shapes(__func__, __FILE__, __LINE__, __VA_ARGS__))
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100445
Michalis Spyrou7a569252018-03-01 12:03:14 +0000446/** Return an error if the passed tensor infos have different data layouts
447 *
448 * @param[in] function Function in which the error occurred.
449 * @param[in] file Name of the file where the error occurred.
450 * @param[in] line Line on which the error occurred.
451 * @param[in] tensor_info The first tensor info to be compared.
452 * @param[in] tensor_infos (Optional) Further allowed tensor infos.
453 *
454 * @return Status
455 */
456template <typename... Ts>
457inline arm_compute::Status error_on_mismatching_data_layouts(const char *function, const char *file, const int line,
458 const ITensorInfo *tensor_info, Ts... tensor_infos)
459{
460 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_info == nullptr, function, file, line);
461 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensor_infos)...));
462
463 DataLayout &&tensor_data_layout = tensor_info->data_layout();
464 const std::array<const ITensorInfo *, sizeof...(Ts)> tensors_infos_array{ { std::forward<Ts>(tensor_infos)... } };
465 ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(tensors_infos_array.begin(), tensors_infos_array.end(), [&](const ITensorInfo * tensor_info_obj)
466 {
467 return tensor_info_obj->data_layout() != tensor_data_layout;
468 }),
469 function, file, line, "Tensors have different data layouts");
470 return arm_compute::Status{};
471}
472/** Return an error if the passed tensors have different data layouts
473 *
474 * @param[in] function Function in which the error occurred.
475 * @param[in] file Name of the file where the error occurred.
476 * @param[in] line Line on which the error occurred.
477 * @param[in] tensor The first tensor to be compared.
478 * @param[in] tensors (Optional) Further allowed tensors.
479 *
480 * @return Status
481 */
482template <typename... Ts>
483inline arm_compute::Status error_on_mismatching_data_layouts(const char *function, const char *file, const int line,
484 const ITensor *tensor, Ts... tensors)
485{
486 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor == nullptr, function, file, line);
487 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensors)...));
488 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_data_layouts(function, file, line, tensor->info(),
489 detail::get_tensor_info_t<ITensorInfo *>()(tensors)...));
490 return arm_compute::Status{};
491}
492#define ARM_COMPUTE_ERROR_ON_MISMATCHING_DATA_LAYOUT(...) \
493 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_data_layouts(__func__, __FILE__, __LINE__, __VA_ARGS__))
494#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_LAYOUT(...) \
495 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_data_layouts(__func__, __FILE__, __LINE__, __VA_ARGS__))
496
Georgios Pinitas3faea252017-10-30 14:13:50 +0000497/** Return an error if the passed two tensor infos have different data types
498 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000499 * @param[in] function Function in which the error occurred.
500 * @param[in] file Name of the file where the error occurred.
501 * @param[in] line Line on which the error occurred.
502 * @param[in] tensor_info The first tensor info to be compared.
503 * @param[in] tensor_infos (Optional) Further allowed tensor infos.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000504 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000505 * @return Status
Georgios Pinitas3faea252017-10-30 14:13:50 +0000506 */
507template <typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000508inline arm_compute::Status error_on_mismatching_data_types(const char *function, const char *file, const int line,
509 const ITensorInfo *tensor_info, Ts... tensor_infos)
Georgios Pinitas3faea252017-10-30 14:13:50 +0000510{
511 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_info == nullptr, function, file, line);
512 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensor_infos)...));
513
514 DataType &&tensor_data_type = tensor_info->data_type();
515 const std::array<const ITensorInfo *, sizeof...(Ts)> tensors_infos_array{ { std::forward<Ts>(tensor_infos)... } };
516 ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(tensors_infos_array.begin(), tensors_infos_array.end(), [&](const ITensorInfo * tensor_info_obj)
517 {
518 return tensor_info_obj->data_type() != tensor_data_type;
519 }),
520 function, file, line, "Tensors have different data types");
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000521 return arm_compute::Status{};
Georgios Pinitas3faea252017-10-30 14:13:50 +0000522}
523/** Return an error if the passed two tensors have different data types
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100524 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000525 * @param[in] function Function in which the error occurred.
526 * @param[in] file Name of the file where the error occurred.
527 * @param[in] line Line on which the error occurred.
528 * @param[in] tensor The first tensor to be compared.
529 * @param[in] tensors (Optional) Further allowed tensors.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000530 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000531 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100532 */
533template <typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000534inline arm_compute::Status error_on_mismatching_data_types(const char *function, const char *file, const int line,
535 const ITensor *tensor, Ts... tensors)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100536{
Georgios Pinitas3faea252017-10-30 14:13:50 +0000537 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor == nullptr, function, file, line);
538 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensors)...));
539 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_data_types(function, file, line, tensor->info(),
540 detail::get_tensor_info_t<ITensorInfo *>()(tensors)...));
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000541 return arm_compute::Status{};
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100542}
Georgios Pinitas3faea252017-10-30 14:13:50 +0000543#define ARM_COMPUTE_ERROR_ON_MISMATCHING_DATA_TYPES(...) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000544 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_data_types(__func__, __FILE__, __LINE__, __VA_ARGS__))
Georgios Pinitas3faea252017-10-30 14:13:50 +0000545#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(...) \
546 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_data_types(__func__, __FILE__, __LINE__, __VA_ARGS__))
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100547
Daniil Efremoveed841c2017-11-09 19:05:25 +0700548/** Return an error if the passed tensor infos have different asymmetric quantized data types or different quantization info
549 *
550 * @note: If the first tensor info doesn't have asymmetric quantized data type, the function returns without throwing an error
551 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000552 * @param[in] function Function in which the error occurred.
553 * @param[in] file Name of the file where the error occurred.
554 * @param[in] line Line on which the error occurred.
555 * @param[in] tensor_info_1 The first tensor info to be compared.
556 * @param[in] tensor_info_2 The second tensor info to be compared.
557 * @param[in] tensor_infos (Optional) Further allowed tensor infos.
Daniil Efremoveed841c2017-11-09 19:05:25 +0700558 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000559 * @return Status
Daniil Efremoveed841c2017-11-09 19:05:25 +0700560 */
561template <typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000562inline arm_compute::Status error_on_mismatching_quantization_info(const char *function, const char *file, const int line,
563 const ITensorInfo *tensor_info_1, const ITensorInfo *tensor_info_2, Ts... tensor_infos)
Daniil Efremoveed841c2017-11-09 19:05:25 +0700564{
565 DataType &&first_data_type = tensor_info_1->data_type();
566 const QuantizationInfo first_quantization_info = tensor_info_1->quantization_info();
567
Michalis Spyrouba27e442019-05-28 10:04:57 +0100568 if(!is_data_type_quantized(first_data_type))
Daniil Efremoveed841c2017-11-09 19:05:25 +0700569 {
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000570 return arm_compute::Status{};
Daniil Efremoveed841c2017-11-09 19:05:25 +0700571 }
572
573 const std::array < const ITensorInfo *, 1 + sizeof...(Ts) > tensor_infos_array{ { tensor_info_2, std::forward<Ts>(tensor_infos)... } };
574 ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(tensor_infos_array.begin(), tensor_infos_array.end(), [&](const ITensorInfo * tensor_info)
575 {
576 return tensor_info->data_type() != first_data_type;
577 }),
578 function, file, line, "Tensors have different asymmetric quantized data types");
579 ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(tensor_infos_array.begin(), tensor_infos_array.end(), [&](const ITensorInfo * tensor_info)
580 {
581 return tensor_info->quantization_info() != first_quantization_info;
582 }),
583 function, file, line, "Tensors have different quantization information");
584
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000585 return arm_compute::Status{};
Daniil Efremoveed841c2017-11-09 19:05:25 +0700586}
587/** Return an error if the passed tensor have different asymmetric quantized data types or different quantization info
588 *
589 * @note: If the first tensor doesn't have asymmetric quantized data type, the function returns without throwing an error
590 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000591 * @param[in] function Function in which the error occurred.
592 * @param[in] file Name of the file where the error occurred.
593 * @param[in] line Line on which the error occurred.
594 * @param[in] tensor_1 The first tensor to be compared.
595 * @param[in] tensor_2 The second tensor to be compared.
596 * @param[in] tensors (Optional) Further allowed tensors.
Daniil Efremoveed841c2017-11-09 19:05:25 +0700597 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000598 * @return Status
Daniil Efremoveed841c2017-11-09 19:05:25 +0700599 */
600template <typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000601inline arm_compute::Status error_on_mismatching_quantization_info(const char *function, const char *file, const int line,
602 const ITensor *tensor_1, const ITensor *tensor_2, Ts... tensors)
Daniil Efremoveed841c2017-11-09 19:05:25 +0700603{
604 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_quantization_info(function, file, line, tensor_1->info(), tensor_2->info(),
605 detail::get_tensor_info_t<ITensorInfo *>()(tensors)...));
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000606 return arm_compute::Status{};
Daniil Efremoveed841c2017-11-09 19:05:25 +0700607}
608#define ARM_COMPUTE_ERROR_ON_MISMATCHING_QUANTIZATION_INFO(...) \
609 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_quantization_info(__func__, __FILE__, __LINE__, __VA_ARGS__))
610#define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_QUANTIZATION_INFO(...) \
611 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_quantization_info(__func__, __FILE__, __LINE__, __VA_ARGS__))
612
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100613/** Throw an error if the format of the passed tensor/multi-image does not match any of the formats provided.
614 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000615 * @param[in] function Function in which the error occurred.
616 * @param[in] file Name of the file where the error occurred.
617 * @param[in] line Line on which the error occurred.
618 * @param[in] object Tensor/multi-image to validate.
619 * @param[in] format First format allowed.
620 * @param[in] formats (Optional) Further allowed formats.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100621 */
622template <typename T, typename F, typename... Fs>
623void error_on_format_not_in(const char *function, const char *file, const int line,
624 const T *object, F &&format, Fs &&... formats)
625{
626 ARM_COMPUTE_ERROR_ON_LOC(object == nullptr, function, file, line);
627
628 Format &&object_format = object->info()->format();
629 ARM_COMPUTE_UNUSED(object_format);
630
631 ARM_COMPUTE_ERROR_ON_LOC(object_format == Format::UNKNOWN, function, file, line);
632
633 const std::array<F, sizeof...(Fs)> formats_array{ { std::forward<Fs>(formats)... } };
634 ARM_COMPUTE_UNUSED(formats_array);
635
636 ARM_COMPUTE_ERROR_ON_LOC_MSG(object_format != format && std::none_of(formats_array.begin(), formats_array.end(), [&](const F & f)
637 {
638 return f == object_format;
639 }),
640 function, file, line, "Format %s not supported by this kernel", string_from_format(object_format).c_str());
Michalis Spyrou6bff1952019-10-02 17:22:11 +0100641 ARM_COMPUTE_UNUSED(function, format, file, line);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100642}
643#define ARM_COMPUTE_ERROR_ON_FORMAT_NOT_IN(t, ...) ::arm_compute::error_on_format_not_in(__func__, __FILE__, __LINE__, t, __VA_ARGS__)
644
Georgios Pinitas3faea252017-10-30 14:13:50 +0000645/** Return an error if the data type of the passed tensor info does not match any of the data types provided.
646 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000647 * @param[in] function Function in which the error occurred.
648 * @param[in] file Name of the file where the error occurred.
649 * @param[in] line Line on which the error occurred.
650 * @param[in] tensor_info Tensor info to validate.
651 * @param[in] dt First data type allowed.
652 * @param[in] dts (Optional) Further allowed data types.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000653 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000654 * @return Status
Georgios Pinitas3faea252017-10-30 14:13:50 +0000655 */
656template <typename T, typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000657inline arm_compute::Status error_on_data_type_not_in(const char *function, const char *file, const int line,
658 const ITensorInfo *tensor_info, T &&dt, Ts &&... dts)
Georgios Pinitas3faea252017-10-30 14:13:50 +0000659{
660 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_info == nullptr, function, file, line);
661
662 const DataType &tensor_dt = tensor_info->data_type(); //NOLINT
663 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_dt == DataType::UNKNOWN, function, file, line);
664
665 const std::array<T, sizeof...(Ts)> dts_array{ { std::forward<Ts>(dts)... } };
Michalis Spyrou7c60c992019-10-10 14:33:47 +0100666 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 +0000667 {
668 return d == tensor_dt;
669 }),
670 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 +0000671 return arm_compute::Status{};
Georgios Pinitas3faea252017-10-30 14:13:50 +0000672}
673/** 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 +0100674 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000675 * @param[in] function Function in which the error occurred.
676 * @param[in] file Name of the file where the error occurred.
677 * @param[in] line Line on which the error occurred.
678 * @param[in] tensor Tensor to validate.
679 * @param[in] dt First data type allowed.
680 * @param[in] dts (Optional) Further allowed data types.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000681 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000682 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100683 */
684template <typename T, typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000685inline arm_compute::Status error_on_data_type_not_in(const char *function, const char *file, const int line,
686 const ITensor *tensor, T &&dt, Ts &&... dts)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100687{
Georgios Pinitas3faea252017-10-30 14:13:50 +0000688 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor == nullptr, function, file, line);
689 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 +0000690 return arm_compute::Status{};
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100691}
Georgios Pinitas3faea252017-10-30 14:13:50 +0000692#define ARM_COMPUTE_ERROR_ON_DATA_TYPE_NOT_IN(t, ...) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000693 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 +0000694#define ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_NOT_IN(t, ...) \
695 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 +0100696
Georgios Pinitasf1adf112018-11-02 12:54:18 +0000697/** Return an error if the data layout of the passed tensor info does not match any of the data layouts provided.
698 *
699 * @param[in] function Function in which the error occurred.
700 * @param[in] file Name of the file where the error occurred.
701 * @param[in] line Line on which the error occurred.
702 * @param[in] tensor_info Tensor info to validate.
703 * @param[in] dl First data layout allowed.
704 * @param[in] dls (Optional) Further allowed data layouts.
705 *
706 * @return Status
707 */
708template <typename T, typename... Ts>
709inline arm_compute::Status error_on_data_layout_not_in(const char *function, const char *file, const int line,
710 const ITensorInfo *tensor_info, T &&dl, Ts &&... dls)
711{
712 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_info == nullptr, function, file, line);
713
714 const DataLayout &tensor_dl = tensor_info->data_layout(); //NOLINT
715 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_dl == DataLayout::UNKNOWN, function, file, line);
716
717 const std::array<T, sizeof...(Ts)> dls_array{ { std::forward<Ts>(dls)... } };
Michalis Spyrou7c60c992019-10-10 14:33:47 +0100718 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 +0000719 {
720 return l == tensor_dl;
721 }),
722 function, file, line, "ITensor data layout %s not supported by this kernel", string_from_data_layout(tensor_dl).c_str());
723 return arm_compute::Status{};
724}
725/** Return an error if the data layout of the passed tensor does not match any of the data layout provided.
726 *
727 * @param[in] function Function in which the error occurred.
728 * @param[in] file Name of the file where the error occurred.
729 * @param[in] line Line on which the error occurred.
730 * @param[in] tensor Tensor to validate.
731 * @param[in] dl First data layout allowed.
732 * @param[in] dls (Optional) Further allowed data layouts.
733 *
734 * @return Status
735 */
736template <typename T, typename... Ts>
737inline arm_compute::Status error_on_data_layout_not_in(const char *function, const char *file, const int line,
738 const ITensor *tensor, T &&dl, Ts &&... dls)
739{
740 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor == nullptr, function, file, line);
741 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)...));
742 return arm_compute::Status{};
743}
744#define ARM_COMPUTE_ERROR_ON_DATA_LAYOUT_NOT_IN(t, ...) \
745 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_data_layout_not_in(__func__, __FILE__, __LINE__, t, __VA_ARGS__))
746#define ARM_COMPUTE_RETURN_ERROR_ON_DATA_LAYOUT_NOT_IN(t, ...) \
747 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_data_layout_not_in(__func__, __FILE__, __LINE__, t, __VA_ARGS__))
748
Georgios Pinitas3faea252017-10-30 14:13:50 +0000749/** 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.
750 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000751 * @param[in] function Function in which the error occurred.
752 * @param[in] file Name of the file where the error occurred.
753 * @param[in] line Line on which the error occurred.
754 * @param[in] tensor_info Tensor info to validate.
755 * @param[in] num_channels Number of channels to check
756 * @param[in] dt First data type allowed.
757 * @param[in] dts (Optional) Further allowed data types.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000758 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000759 * @return Status
Georgios Pinitas3faea252017-10-30 14:13:50 +0000760 */
761template <typename T, typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000762inline arm_compute::Status error_on_data_type_channel_not_in(const char *function, const char *file, const int line,
763 const ITensorInfo *tensor_info, size_t num_channels, T &&dt, Ts &&... dts)
Georgios Pinitas3faea252017-10-30 14:13:50 +0000764{
765 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)...));
766 const size_t tensor_nc = tensor_info->num_channels();
Michalis Spyrou7c60c992019-10-10 14:33:47 +0100767 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 +0000768 return arm_compute::Status{};
Georgios Pinitas3faea252017-10-30 14:13:50 +0000769}
770/** 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 +0100771 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000772 * @param[in] function Function in which the error occurred.
773 * @param[in] file Name of the file where the error occurred.
774 * @param[in] line Line on which the error occurred.
775 * @param[in] tensor Tensor to validate.
776 * @param[in] num_channels Number of channels to check
777 * @param[in] dt First data type allowed.
778 * @param[in] dts (Optional) Further allowed data types.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000779 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000780 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100781 */
782template <typename T, typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000783inline arm_compute::Status error_on_data_type_channel_not_in(const char *function, const char *file, const int line,
784 const ITensor *tensor, size_t num_channels, T &&dt, Ts &&... dts)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100785{
Georgios Pinitas3faea252017-10-30 14:13:50 +0000786 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor == nullptr, function, file, line);
787 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 +0000788 return arm_compute::Status{};
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100789}
Georgios Pinitas3faea252017-10-30 14:13:50 +0000790#define ARM_COMPUTE_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(t, c, ...) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000791 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 +0000792#define ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(t, c, ...) \
793 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 +0100794
Vidhya Sudhan Loganathanf1f49062018-05-25 13:21:26 +0100795/** Return an error if the data type of the passed tensor info is FP16 and FP16 extension is not supported by the device.
796 *
797 * @param[in] function Function in which the error occurred.
798 * @param[in] file Name of the file where the error occurred.
799 * @param[in] line Line on which the error occurred.
800 * @param[in] tensor_info Tensor info to validate.
801 * @param[in] is_fp16_supported Is fp16 supported by the device.
802 *
803 * @return Status
804 */
805inline arm_compute::Status error_on_unsupported_fp16(const char *function, const char *file, const int line,
806 const ITensorInfo *tensor_info, bool is_fp16_supported)
807{
808 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_info == nullptr, function, file, line);
809 ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG((tensor_info->data_type() == DataType::F16 && !is_fp16_supported),
810 function, file, line, "FP16 not supported by the device");
811 return arm_compute::Status{};
812}
813
814/** Return an error if the data type of the passed tensor is FP16 and FP16 extension is not supported by the device.
815 *
816 * @param[in] function Function in which the error occurred.
817 * @param[in] file Name of the file where the error occurred.
818 * @param[in] line Line on which the error occurred.
819 * @param[in] tensor Tensor to validate.
820 * @param[in] is_fp16_supported Is fp16 supported by the device.
821 *
822 * @return Status
823 */
824inline arm_compute::Status error_on_unsupported_fp16(const char *function, const char *file, const int line,
825 const ITensor *tensor, bool is_fp16_supported)
826{
827 ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor == nullptr, function, file, line);
828 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_unsupported_fp16(function, file, line, tensor->info(), is_fp16_supported));
829 return arm_compute::Status{};
830}
831
Georgios Pinitas3faea252017-10-30 14:13:50 +0000832/** Return an error if the tensor is not 2D.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100833 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000834 * @param[in] function Function in which the error occurred.
835 * @param[in] file Name of the file where the error occurred.
836 * @param[in] line Line on which the error occurred.
837 * @param[in] tensor Tensor to validate.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000838 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000839 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100840 */
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000841arm_compute::Status error_on_tensor_not_2d(const char *function, const char *file, const int line,
842 const ITensor *tensor);
Michalis Spyroud1794eb2018-06-15 16:15:26 +0100843
844/** Return an error if the tensor info is not 2D.
845 *
846 * @param[in] function Function in which the error occurred.
847 * @param[in] file Name of the file where the error occurred.
848 * @param[in] line Line on which the error occurred.
849 * @param[in] tensor Tensor info to validate.
850 *
851 * @return Status
852 */
853arm_compute::Status error_on_tensor_not_2d(const char *function, const char *file, const int line,
854 const ITensorInfo *tensor);
855
Georgios Pinitas3faea252017-10-30 14:13:50 +0000856#define ARM_COMPUTE_ERROR_ON_TENSOR_NOT_2D(t) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000857 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_tensor_not_2d(__func__, __FILE__, __LINE__, t))
Georgios Pinitas3faea252017-10-30 14:13:50 +0000858#define ARM_COMPUTE_RETURN_ERROR_ON_TENSOR_NOT_2D(t) \
859 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_tensor_not_2d(__func__, __FILE__, __LINE__, t))
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100860
Georgios Pinitas3faea252017-10-30 14:13:50 +0000861/** Return an error if the channel is not in channels.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100862 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000863 * @param[in] function Function in which the error occurred.
864 * @param[in] file Name of the file where the error occurred.
865 * @param[in] line Line on which the error occurred.
866 * @param[in] cn Input channel
867 * @param[in] channel First channel allowed.
868 * @param[in] channels (Optional) Further allowed channels.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000869 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000870 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100871 */
872template <typename T, typename... Ts>
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000873inline arm_compute::Status error_on_channel_not_in(const char *function, const char *file, const int line,
874 T cn, T &&channel, Ts &&... channels)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100875{
Georgios Pinitas3faea252017-10-30 14:13:50 +0000876 ARM_COMPUTE_RETURN_ERROR_ON_LOC(cn == Channel::UNKNOWN, function, file, line);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100877
878 const std::array<T, sizeof...(Ts)> channels_array{ { std::forward<Ts>(channels)... } };
Georgios Pinitas3faea252017-10-30 14:13:50 +0000879 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 +0100880 {
881 return f == cn;
882 }),
883 function, file, line);
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000884 return arm_compute::Status{};
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100885}
Georgios Pinitas3faea252017-10-30 14:13:50 +0000886#define ARM_COMPUTE_ERROR_ON_CHANNEL_NOT_IN(c, ...) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000887 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 +0000888#define ARM_COMPUTE_RETURN_ERROR_ON_CHANNEL_NOT_IN(c, ...) \
889 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 +0100890
Georgios Pinitas3faea252017-10-30 14:13:50 +0000891/** Return an error if the channel is not in format.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100892 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000893 * @param[in] function Function in which the error occurred.
894 * @param[in] file Name of the file where the error occurred.
895 * @param[in] line Line on which the error occurred.
896 * @param[in] fmt Input channel
897 * @param[in] cn First channel allowed.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000898 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000899 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100900 */
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000901arm_compute::Status error_on_channel_not_in_known_format(const char *function, const char *file, const int line,
902 Format fmt, Channel cn);
Georgios Pinitas3faea252017-10-30 14:13:50 +0000903#define ARM_COMPUTE_ERROR_ON_CHANNEL_NOT_IN_KNOWN_FORMAT(f, c) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000904 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 +0000905#define ARM_COMPUTE_RETURN_ERROR_ON_CHANNEL_NOT_IN_KNOWN_FORMAT(f, c) \
906 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 +0100907
Georgios Pinitas3faea252017-10-30 14:13:50 +0000908/** Return an error if the @ref IMultiHOG container is invalid
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100909 *
910 * An @ref IMultiHOG container is invalid if:
911 *
912 * -# it is a nullptr
913 * -# it doesn't contain models
914 * -# it doesn't have the HOG data objects with the same phase_type, normalization_type and l2_hyst_threshold (if normalization_type == L2HYS_NORM)
915 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000916 * @param[in] function Function in which the error occurred.
917 * @param[in] file Name of the file where the error occurred.
918 * @param[in] line Line on which the error occurred.
919 * @param[in] multi_hog IMultiHOG container to validate
Georgios Pinitas3faea252017-10-30 14:13:50 +0000920 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000921 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100922 */
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000923arm_compute::Status error_on_invalid_multi_hog(const char *function, const char *file, const int line,
924 const IMultiHOG *multi_hog);
Georgios Pinitas3faea252017-10-30 14:13:50 +0000925#define ARM_COMPUTE_ERROR_ON_INVALID_MULTI_HOG(m) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000926 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_invalid_multi_hog(__func__, __FILE__, __LINE__, m))
Georgios Pinitas3faea252017-10-30 14:13:50 +0000927#define ARM_COMPUTE_RETURN_ERROR_ON_INVALID_MULTI_HOG(m) \
928 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_invalid_multi_hog(__func__, __FILE__, __LINE__, m))
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100929
Georgios Pinitas3faea252017-10-30 14:13:50 +0000930/** Return an error if the kernel is not configured.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100931 *
Anthony Barbierf202e502017-11-23 18:02:04 +0000932 * @param[in] function Function in which the error occurred.
933 * @param[in] file Name of the file where the error occurred.
934 * @param[in] line Line on which the error occurred.
935 * @param[in] kernel Kernel to validate.
Alex Gildayc357c472018-03-21 13:54:09 +0000936 *
937 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100938 */
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000939arm_compute::Status error_on_unconfigured_kernel(const char *function, const char *file, const int line,
940 const IKernel *kernel);
Georgios Pinitas3faea252017-10-30 14:13:50 +0000941#define ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(k) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000942 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_unconfigured_kernel(__func__, __FILE__, __LINE__, k))
Georgios Pinitas3faea252017-10-30 14:13:50 +0000943#define ARM_COMPUTE_RETURN_ERROR_ON_UNCONFIGURED_KERNEL(k) \
944 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_unconfigured_kernel(__func__, __FILE__, __LINE__, k))
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100945
Georgios Pinitas3faea252017-10-30 14:13:50 +0000946/** Return an error if if the coordinates and shape of the subtensor are within the parent tensor.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100947 *
948 * @param[in] function Function in which the error occurred.
949 * @param[in] file Name of the file where the error occurred.
950 * @param[in] line Line on which the error occurred.
951 * @param[in] parent_shape Parent tensor shape
952 * @param[in] coords Coordinates inside the parent tensor where the first element of the subtensor is
953 * @param[in] shape Shape of the subtensor
Georgios Pinitas3faea252017-10-30 14:13:50 +0000954 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000955 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100956 */
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000957arm_compute::Status error_on_invalid_subtensor(const char *function, const char *file, const int line,
958 const TensorShape &parent_shape, const Coordinates &coords, const TensorShape &shape);
Georgios Pinitas3faea252017-10-30 14:13:50 +0000959#define ARM_COMPUTE_ERROR_ON_INVALID_SUBTENSOR(p, c, s) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000960 ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_invalid_subtensor(__func__, __FILE__, __LINE__, p, c, s))
Georgios Pinitas3faea252017-10-30 14:13:50 +0000961#define ARM_COMPUTE_RETURN_ERROR_ON_INVALID_SUBTENSOR(p, c, s) \
962 ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_invalid_subtensor(__func__, __FILE__, __LINE__, p, c, s))
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100963
Georgios Pinitas3faea252017-10-30 14:13:50 +0000964/** 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 +0100965 *
966 * @param[in] function Function in which the error occurred.
967 * @param[in] file Name of the file where the error occurred.
968 * @param[in] line Line on which the error occurred.
969 * @param[in] parent_valid_region Parent valid region.
970 * @param[in] valid_region Valid region of subtensor.
Georgios Pinitas3faea252017-10-30 14:13:50 +0000971 *
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000972 * @return Status
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100973 */
Georgios Pinitas631c41a2017-12-06 11:53:03 +0000974arm_compute::Status error_on_invalid_subtensor_valid_region(const char *function, const char *file, const int line,
975 const ValidRegion &parent_valid_region, const ValidRegion &valid_region);
Georgios Pinitas3faea252017-10-30 14:13:50 +0000976#define ARM_COMPUTE_ERROR_ON_INVALID_SUBTENSOR_VALID_REGION(pv, sv) \
Georgios Pinitasf9d3a0a2017-11-03 19:01:44 +0000977 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 +0000978#define ARM_COMPUTE_RETURN_ERROR_ON_INVALID_SUBTENSOR_VALID_REGION(pv, sv) \
979 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 +0100980}
981#endif /* __ARM_COMPUTE_VALIDATE_H__*/