Compute Library
 20.02.1
Validate.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016-2019 ARM Limited.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 #ifndef ARM_COMPUTE_VALIDATE_H
25 #define ARM_COMPUTE_VALIDATE_H
26 
27 #include "arm_compute/core/Error.h"
35 
36 #include <algorithm>
37 
38 namespace arm_compute
39 {
40 namespace 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  */
50 template <typename T>
51 inline 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 
64 /** Function to compare two @ref Dimensions objects and throw an error on mismatch.
65  *
66  * @param[in] dim Object to compare against.
67  * @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.
70  */
71 template <typename T>
73 {
74 public:
75  /** 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  */
82  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.
90  *
91  * @return a status.
92  */
94  {
95  ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(have_different_dimensions(_dim, dim, 0), _function, _file, _line,
96  "Objects have different dimensions");
97  return arm_compute::Status{};
98  }
99 
100 private:
101  const Dimensions<T> &_dim;
102  const char *const _function;
103  const char *const _file;
104  const int _line;
105 };
106 
107 template <typename F>
109 {
110  return arm_compute::Status{};
111 }
112 
113 template <typename F, typename T, typename... Ts>
114 inline arm_compute::Status for_each_error(F &&func, T &&arg, Ts &&... args)
115 {
116  ARM_COMPUTE_RETURN_ON_ERROR(func(arg));
118  return arm_compute::Status{};
119 }
120 
121 /** Get the info for a tensor, dummy struct */
122 template <typename T>
124 /** Get the info for a tensor */
125 template <>
127 {
128  /** Get the info for a tensor.
129  *
130  * @param[in] tensor Tensor.
131  *
132  * @return tensor info.
133  */
135  {
136  return tensor->info();
137  }
138 };
139 } // namespace detail
140 
141 /** Create an error if one of the pointers is a nullptr.
142  *
143  * @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.
147  *
148  * @return Status
149  */
150 template <typename... Ts>
151 inline arm_compute::Status error_on_nullptr(const char *function, const char *file, const int line, Ts &&... pointers)
152 {
153  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)
155  {
156  return (ptr == nullptr);
157  });
158  ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(has_nullptr, function, file, line, "Nullptr object!");
159  return arm_compute::Status{};
160 }
161 #define ARM_COMPUTE_ERROR_ON_NULLPTR(...) \
162  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_nullptr(__func__, __FILE__, __LINE__, __VA_ARGS__))
163 #define ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(...) \
164  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(__func__, __FILE__, __LINE__, __VA_ARGS__))
165 
166 /** Return an error if the passed window is invalid.
167  *
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  *
173  * @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.
178  *
179  * @return Status
180  */
181 arm_compute::Status error_on_mismatching_windows(const char *function, const char *file, const int line,
182  const Window &full, const Window &win);
183 #define ARM_COMPUTE_ERROR_ON_MISMATCHING_WINDOWS(f, w) \
184  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_windows(__func__, __FILE__, __LINE__, f, w))
185 #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))
187 
188 /** Return an error if the passed subwindow is invalid.
189  *
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  *
195  * @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.
200  *
201  * @return Status
202  */
203 arm_compute::Status error_on_invalid_subwindow(const char *function, const char *file, const int line,
204  const Window &full, const Window &sub);
205 #define ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(f, s) \
206  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_invalid_subwindow(__func__, __FILE__, __LINE__, f, s))
207 #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))
209 
210 /** Return an error if the window can't be collapsed at the given dimension.
211  *
212  * The window cannot be collapsed if the given dimension not equal to the full window's dimension or not start from 0.
213  *
214  * @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.
220  *
221  * @return Status
222  */
223 arm_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);
225 #define ARM_COMPUTE_ERROR_ON_WINDOW_NOT_COLLAPSABLE_AT_DIMENSION(f, w, d) \
226  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_window_not_collapsable_at_dimension(__func__, __FILE__, __LINE__, f, w, d))
227 #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))
229 
230 /** Return an error if the passed coordinates have too many dimensions.
231  *
232  * The coordinates have too many dimensions if any of the dimensions greater or equal to max_dim is different from 0.
233  *
234  * @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.
239  *
240  * @return Status
241  */
242 arm_compute::Status error_on_coordinates_dimensions_gte(const char *function, const char *file, const int line,
243  const Coordinates &pos, unsigned int max_dim);
244 #define ARM_COMPUTE_ERROR_ON_COORDINATES_DIMENSIONS_GTE(p, md) \
245  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_coordinates_dimensions_gte(__func__, __FILE__, __LINE__, p, md))
246 #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))
248 
249 /** Return an error if the passed window has too many dimensions.
250  *
251  * The window has too many dimensions if any of the dimension greater or equal to max_dim is different from 0.
252  *
253  * @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.
258  *
259  * @return Status
260  */
261 arm_compute::Status error_on_window_dimensions_gte(const char *function, const char *file, const int line,
262  const Window &win, unsigned int max_dim);
263 #define ARM_COMPUTE_ERROR_ON_WINDOW_DIMENSIONS_GTE(w, md) \
264  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_window_dimensions_gte(__func__, __FILE__, __LINE__, w, md))
265 #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))
267 
268 /** Return an error if the passed dimension objects differ.
269  *
270  * @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.
276  *
277  * @return Status
278  */
279 template <typename T, typename... Ts>
280 arm_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)
282 {
283  ARM_COMPUTE_RETURN_ON_ERROR(detail::for_each_error(detail::compare_dimension<T>(dim1, function, file, line), dim2, std::forward<Ts>(dims)...));
284  return arm_compute::Status{};
285 }
286 #define ARM_COMPUTE_ERROR_ON_MISMATCHING_DIMENSIONS(...) \
287  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_dimensions(__func__, __FILE__, __LINE__, __VA_ARGS__))
288 #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__))
290 
291 /** 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  */
302 template <typename... Ts>
303 arm_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 
323 /** 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  */
335 template <typename... Ts>
336 arm_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 
356 /** Return an error if the passed two tensor infos have different shapes from the given dimension
357  *
358  * @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.
364  *
365  * @return Status
366  */
367 template <typename... Ts>
368 inline 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)
370 {
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
374  *
375  * @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.
381  *
382  * @return Status
383  */
384 template <typename... Ts>
385 inline 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)
387 {
388  return error_on_mismatching_shapes(function, file, line, 0U, tensor_1, tensor_2, std::forward<Ts>(tensors)...);
389 }
390 /** Return an error if the passed two tensors have different shapes from the given dimension
391  *
392  * @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.
399  *
400  * @return Status
401  */
402 template <typename... Ts>
403 inline 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)
405 {
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)...));
409 
410  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");
416  return arm_compute::Status{};
417 }
418 /** Return an error if the passed two tensors have different shapes from the given dimension
419  *
420  * @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.
427  *
428  * @return Status
429  */
430 template <typename... Ts>
431 inline 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)
433 {
434  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(),
439  return arm_compute::Status{};
440 }
441 #define ARM_COMPUTE_ERROR_ON_MISMATCHING_SHAPES(...) \
442  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_shapes(__func__, __FILE__, __LINE__, __VA_ARGS__))
443 #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__))
445 
446 /** 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  */
456 template <typename... Ts>
457 inline 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  */
482 template <typename... Ts>
483 inline 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)...));
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 
497 /** Return an error if the passed two tensor infos have different data types
498  *
499  * @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.
504  *
505  * @return Status
506  */
507 template <typename... Ts>
508 inline 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)
510 {
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");
521  return arm_compute::Status{};
522 }
523 /** Return an error if the passed two tensors have different data types
524  *
525  * @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.
530  *
531  * @return Status
532  */
533 template <typename... Ts>
534 inline arm_compute::Status error_on_mismatching_data_types(const char *function, const char *file, const int line,
535  const ITensor *tensor, Ts... tensors)
536 {
537  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)...));
541  return arm_compute::Status{};
542 }
543 #define ARM_COMPUTE_ERROR_ON_MISMATCHING_DATA_TYPES(...) \
544  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_data_types(__func__, __FILE__, __LINE__, __VA_ARGS__))
545 #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__))
547 
548 /** 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  *
552  * @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.
558  *
559  * @return Status
560  */
561 template <typename... Ts>
562 inline 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)
564 {
565  DataType &&first_data_type = tensor_info_1->data_type();
566  const QuantizationInfo first_quantization_info = tensor_info_1->quantization_info();
567 
568  if(!is_data_type_quantized(first_data_type))
569  {
570  return arm_compute::Status{};
571  }
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 
585  return arm_compute::Status{};
586 }
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  *
591  * @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.
597  *
598  * @return Status
599  */
600 template <typename... Ts>
601 inline 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)
603 {
604  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_quantization_info(function, file, line, tensor_1->info(), tensor_2->info(),
606  return arm_compute::Status{};
607 }
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 
613 /** Throw an error if the format of the passed tensor/multi-image does not match any of the formats provided.
614  *
615  * @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.
621  */
622 template <typename T, typename F, typename... Fs>
623 void 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());
641  ARM_COMPUTE_UNUSED(function, format, file, line);
642 }
643 #define ARM_COMPUTE_ERROR_ON_FORMAT_NOT_IN(t, ...) ::arm_compute::error_on_format_not_in(__func__, __FILE__, __LINE__, t, __VA_ARGS__)
644 
645 /** Return an error if the data type of the passed tensor info does not match any of the data types provided.
646  *
647  * @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.
653  *
654  * @return Status
655  */
656 template <typename T, typename... Ts>
657 inline 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)
659 {
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)... } };
666  ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG_VAR(tensor_dt != dt && std::none_of(dts_array.begin(), dts_array.end(), [&](const T & d)
667  {
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());
671  return arm_compute::Status{};
672 }
673 /** Return an error if the data type of the passed tensor does not match any of the data types provided.
674  *
675  * @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.
681  *
682  * @return Status
683  */
684 template <typename T, typename... Ts>
685 inline 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)
687 {
688  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)...));
690  return arm_compute::Status{};
691 }
692 #define ARM_COMPUTE_ERROR_ON_DATA_TYPE_NOT_IN(t, ...) \
693  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_data_type_not_in(__func__, __FILE__, __LINE__, t, __VA_ARGS__))
694 #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__))
696 
697 /** 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  */
708 template <typename T, typename... Ts>
709 inline 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)... } };
718  ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG_VAR(tensor_dl != dl && std::none_of(dls_array.begin(), dls_array.end(), [&](const T & l)
719  {
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  */
736 template <typename T, typename... Ts>
737 inline 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 
749 /** 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  *
751  * @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.
758  *
759  * @return Status
760  */
761 template <typename T, typename... Ts>
762 inline 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)
764 {
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();
767  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);
768  return arm_compute::Status{};
769 }
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.
771  *
772  * @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.
779  *
780  * @return Status
781  */
782 template <typename T, typename... Ts>
783 inline 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)
785 {
786  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)...));
788  return arm_compute::Status{};
789 }
790 #define ARM_COMPUTE_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(t, c, ...) \
791  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_data_type_channel_not_in(__func__, __FILE__, __LINE__, t, c, __VA_ARGS__))
792 #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__))
794 
795 /** 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  */
805 inline 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  */
824 inline 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 
832 /** Return an error if the tensor is not 2D.
833  *
834  * @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.
838  *
839  * @return Status
840  */
841 arm_compute::Status error_on_tensor_not_2d(const char *function, const char *file, const int line,
842  const ITensor *tensor);
843 
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  */
853 arm_compute::Status error_on_tensor_not_2d(const char *function, const char *file, const int line,
854  const ITensorInfo *tensor);
855 
856 #define ARM_COMPUTE_ERROR_ON_TENSOR_NOT_2D(t) \
857  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_tensor_not_2d(__func__, __FILE__, __LINE__, t))
858 #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))
860 
861 /** Return an error if the channel is not in channels.
862  *
863  * @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.
869  *
870  * @return Status
871  */
872 template <typename T, typename... Ts>
873 inline arm_compute::Status error_on_channel_not_in(const char *function, const char *file, const int line,
874  T cn, T &&channel, Ts &&... channels)
875 {
876  ARM_COMPUTE_RETURN_ERROR_ON_LOC(cn == Channel::UNKNOWN, function, file, line);
877 
878  const std::array<T, sizeof...(Ts)> channels_array{ { std::forward<Ts>(channels)... } };
879  ARM_COMPUTE_RETURN_ERROR_ON_LOC(channel != cn && std::none_of(channels_array.begin(), channels_array.end(), [&](const T & f)
880  {
881  return f == cn;
882  }),
883  function, file, line);
884  return arm_compute::Status{};
885 }
886 #define ARM_COMPUTE_ERROR_ON_CHANNEL_NOT_IN(c, ...) \
887  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_channel_not_in(__func__, __FILE__, __LINE__, c, __VA_ARGS__))
888 #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__))
890 
891 /** Return an error if the channel is not in format.
892  *
893  * @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.
898  *
899  * @return Status
900  */
901 arm_compute::Status error_on_channel_not_in_known_format(const char *function, const char *file, const int line,
902  Format fmt, Channel cn);
903 #define ARM_COMPUTE_ERROR_ON_CHANNEL_NOT_IN_KNOWN_FORMAT(f, c) \
904  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_channel_not_in_known_format(__func__, __FILE__, __LINE__, f, c))
905 #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))
907 
908 /** Return an error if the @ref IMultiHOG container is invalid
909  *
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  *
916  * @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
920  *
921  * @return Status
922  */
923 arm_compute::Status error_on_invalid_multi_hog(const char *function, const char *file, const int line,
924  const IMultiHOG *multi_hog);
925 #define ARM_COMPUTE_ERROR_ON_INVALID_MULTI_HOG(m) \
926  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_invalid_multi_hog(__func__, __FILE__, __LINE__, m))
927 #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))
929 
930 /** Return an error if the kernel is not configured.
931  *
932  * @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.
936  *
937  * @return Status
938  */
939 arm_compute::Status error_on_unconfigured_kernel(const char *function, const char *file, const int line,
940  const IKernel *kernel);
941 #define ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(k) \
942  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_unconfigured_kernel(__func__, __FILE__, __LINE__, k))
943 #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))
945 
946 /** Return an error if if the coordinates and shape of the subtensor are within the parent tensor.
947  *
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
954  *
955  * @return Status
956  */
957 arm_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);
959 #define ARM_COMPUTE_ERROR_ON_INVALID_SUBTENSOR(p, c, s) \
960  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_invalid_subtensor(__func__, __FILE__, __LINE__, p, c, s))
961 #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))
963 
964 /** Return an error if the valid region of a subtensor is not inside the valid region of the parent tensor.
965  *
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.
971  *
972  * @return Status
973  */
974 arm_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);
976 #define ARM_COMPUTE_ERROR_ON_INVALID_SUBTENSOR_VALID_REGION(pv, sv) \
977  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_invalid_subtensor_valid_region(__func__, __FILE__, __LINE__, pv, sv))
978 #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))
980 }
981 #endif /* ARM_COMPUTE_VALIDATE_H*/
#define ARM_COMPUTE_ERROR_ON_LOC_MSG(cond, func, file, line,...)
Definition: Error.h:458
bool is_data_type_quantized(DataType dt)
Check if a given data type is of quantized type.
Definition: Utils.h:1117
Shape of a tensor.
Definition: TensorShape.h:39
arm_compute::Status error_on_channel_not_in_known_format(const char *function, const char *file, const int line, Format fmt, Channel cn)
Return an error if the channel is not in format.
Definition: Validate.cpp:113
#define ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(cond, func, file, line, msg)
If the condition is true, an error is thrown.
Definition: Error.h:283
TensorShape calculate_subsampled_shape(const TensorShape &shape, Format format, Channel channel=Channel::UNKNOWN)
Calculate subsampled shape for a given format and channel.
Definition: Utils.h:756
arm_compute::Status error_on_unconfigured_kernel(const char *function, const char *file, const int line, const IKernel *kernel)
Return an error if the kernel is not configured.
Definition: Validate.cpp:166
arm_compute::Status error_on_window_dimensions_gte(const char *function, const char *file, const int line, const Window &win, unsigned int max_dim)
Return an error if the passed window has too many dimensions.
Definition: Validate.cpp:80
#define ARM_COMPUTE_RETURN_ERROR_ON_LOC(cond, func, file, line)
If the condition is true, an error is returned.
Definition: Error.h:306
#define ARM_COMPUTE_RETURN_ON_ERROR(status)
Checks if a status contains an error and returns it.
Definition: Error.h:204
virtual DataType data_type() const =0
Data type used for each element of the tensor.
arm_compute::Status error_on_nullptr(const char *function, const char *file, const int line, Ts &&... pointers)
Create an error if one of the pointers is a nullptr.
Definition: Validate.h:151
arm_compute::Status error_on_unsupported_fp16(const char *function, const char *file, const int line, const ITensorInfo *tensor_info, bool is_fp16_supported)
Return an error if the data type of the passed tensor info is FP16 and FP16 extension is not supporte...
Definition: Validate.h:805
Store the tensor's metadata.
Definition: ITensorInfo.h:40
arm_compute::Status error_on_tensor_not_2d(const char *function, const char *file, const int line, const ITensor *tensor)
Return an error if the tensor is not 2D.
Definition: Validate.cpp:92
Status class.
Definition: Error.h:52
arm_compute::Status error_on_data_layout_not_in(const char *function, const char *file, const int line, const ITensorInfo *tensor_info, T &&dl, Ts &&... dls)
Return an error if the data layout of the passed tensor info does not match any of the data layouts p...
Definition: Validate.h:709
Interface for NEON tensor.
Definition: ITensor.h:36
Copyright (c) 2017-2020 ARM Limited.
arm_compute::Status error_on_mismatching_shapes(const char *function, const char *file, const int line, const ITensorInfo *tensor_info_1, const ITensorInfo *tensor_info_2, Ts... tensor_infos)
Return an error if the passed two tensor infos have different shapes from the given dimension.
Definition: Validate.h:368
Function to compare two Dimensions objects and throw an error on mismatch.
Definition: Validate.h:72
1 channel, 1 F16 per channel
arm_compute::Status for_each_error(F &&)
Definition: Validate.h:108
arm_compute::Status error_on_tensors_not_even(const char *function, const char *file, int line, const Format &format, const ITensor *tensor1, Ts... tensors)
Return an error if the passed tensor objects are not even.
Definition: Validate.h:303
Get the info for a tensor, dummy struct.
Definition: Validate.h:123
Quantization information.
arm_compute::Status error_on_mismatching_quantization_info(const char *function, const char *file, const int line, const ITensorInfo *tensor_info_1, const ITensorInfo *tensor_info_2, Ts... tensor_infos)
Return an error if the passed tensor infos have different asymmetric quantized data types or differen...
Definition: Validate.h:562
const std::string & string_from_data_type(DataType dt)
Convert a data type identity into a string.
Definition: Utils.cpp:144
arm_compute::Status error_on_mismatching_windows(const char *function, const char *file, const int line, const Window &full, const Window &win)
Return an error if the passed window is invalid.
Definition: Validate.cpp:26
#define ARM_COMPUTE_UNUSED(...)
To avoid unused variables warnings.
Definition: Error.h:152
Channel
Available channels.
Definition: Types.h:461
Format
Image colour formats.
Definition: Types.h:53
arm_compute::Status error_on_channel_not_in(const char *function, const char *file, const int line, T cn, T &&channel, Ts &&... channels)
Return an error if the channel is not in channels.
Definition: Validate.h:873
arm_compute::Status error_on_mismatching_dimensions(const char *function, const char *file, int line, const Dimensions< T > &dim1, const Dimensions< T > &dim2, Ts &&... dims)
Return an error if the passed dimension objects differ.
Definition: Validate.h:280
arm_compute::Status error_on_tensors_not_subsampled(const char *function, const char *file, int line, const Format &format, const TensorShape &shape, const ITensor *tensor1, Ts... tensors)
Return an error if the passed tensor objects are not sub-sampled.
Definition: Validate.h:336
ITensorInfo * operator()(const ITensor *tensor)
Get the info for a tensor.
Definition: Validate.h:134
Dimensions with dimensionality.
Definition: Dimensions.h:41
virtual ITensorInfo * info() const =0
Interface to be implemented by the child class to return the tensor's metadata.
bool have_different_dimensions(const Dimensions< T > &dim1, const Dimensions< T > &dim2, unsigned int upper_dim)
Definition: Validate.h:51
virtual QuantizationInfo quantization_info() const =0
Get the quantization settings (scale and offset) of the tensor.
#define ARM_COMPUTE_ERROR_ON_LOC(cond, func, file, line)
If the condition is true then an error message is printed and an exception thrown.
Definition: Error.h:476
#define ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG_VAR(cond, func, file, line, msg,...)
If the condition is true, an error is thrown.
Definition: Error.h:263
TensorShape adjust_odd_shape(const TensorShape &shape, Format format)
Adjust tensor shape size if width or height are odd for a given multi-planar format.
Definition: Utils.h:729
arm_compute::Status error_on_invalid_subtensor(const char *function, const char *file, const int line, const TensorShape &parent_shape, const Coordinates &coords, const TensorShape &shape)
Return an error if if the coordinates and shape of the subtensor are within the parent tensor.
Definition: Validate.cpp:176
arm_compute::Status operator()(const Dimensions< T > &dim)
Compare the given object against the stored one.
Definition: Validate.h:93
const std::string & string_from_data_layout(DataLayout dl)
Convert a data layout identity into a string.
Definition: Utils.cpp:132
arm_compute::Status error_on_mismatching_data_types(const char *function, const char *file, const int line, const ITensorInfo *tensor_info, Ts... tensor_infos)
Return an error if the passed two tensor infos have different data types.
Definition: Validate.h:508
arm_compute::Status error_on_data_type_not_in(const char *function, const char *file, const int line, const ITensorInfo *tensor_info, T &&dt, Ts &&... dts)
Return an error if the data type of the passed tensor info does not match any of the data types provi...
Definition: Validate.h:657
arm_compute::Status error_on_invalid_multi_hog(const char *function, const char *file, const int line, const IMultiHOG *multi_hog)
Return an error if the IMultiHOG container is invalid.
Definition: Validate.cpp:144
arm_compute::Status error_on_data_type_channel_not_in(const char *function, const char *file, const int line, const ITensorInfo *tensor_info, size_t num_channels, T &&dt, Ts &&... dts)
Return an error if the data type or the number of channels of the passed tensor info does not match a...
Definition: Validate.h:762
arm_compute::Status error_on_mismatching_data_layouts(const char *function, const char *file, const int line, const ITensorInfo *tensor_info, Ts... tensor_infos)
Return an error if the passed tensor infos have different data layouts.
Definition: Validate.h:457
DataType
Available data types.
Definition: Types.h:75
compare_dimension(const Dimensions< T > &dim, const char *function, const char *file, int line)
Construct a comparison function.
Definition: Validate.h:82
DataLayout
[DataLayout enum definition]
Definition: Types.h:117
arm_compute::Status error_on_coordinates_dimensions_gte(const char *function, const char *file, const int line, const Coordinates &pos, unsigned int max_dim)
Return an error if the passed coordinates have too many dimensions.
Definition: Validate.cpp:70
arm_compute::Status error_on_invalid_subwindow(const char *function, const char *file, const int line, const Window &full, const Window &sub)
Return an error if the passed subwindow is invalid.
Definition: Validate.cpp:41
arm_compute::Status error_on_invalid_subtensor_valid_region(const char *function, const char *file, const int line, const ValidRegion &parent_valid_region, const ValidRegion &valid_region)
Return an error if the valid region of a subtensor is not inside the valid region of the parent tenso...
Definition: Validate.cpp:193
virtual size_t num_channels() const =0
The number of channels for each tensor element.
void error_on_format_not_in(const char *function, const char *file, const int line, const T *object, F &&format, Fs &&... formats)
Throw an error if the format of the passed tensor/multi-image does not match any of the formats provi...
Definition: Validate.h:623
virtual DataLayout data_layout() const =0
Get the data layout of the tensor.
const std::string & string_from_format(Format format)
Convert a tensor format into a string.
Definition: Utils.cpp:85
arm_compute::Status error_on_window_not_collapsable_at_dimension(const char *function, const char *file, const int line, const Window &full, const Window &window, const int dim)
Return an error if the window can't be collapsed at the given dimension.
Definition: Validate.cpp:57