Compute Library
 21.05
Validate.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016-2021 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"
31 
32 #include <algorithm>
33 
34 namespace arm_compute
35 {
36 namespace detail
37 {
38 /* Check whether two dimension objects differ.
39  *
40  * @param[in] dim1 First object to be compared.
41  * @param[in] dim2 Second object to be compared.
42  * @param[in] upper_dim The dimension from which to check.
43  *
44  * @return Return true if the two objects are different.
45  */
46 template <typename T>
47 inline bool have_different_dimensions(const Dimensions<T> &dim1, const Dimensions<T> &dim2, unsigned int upper_dim)
48 {
49  for(unsigned int i = upper_dim; i < arm_compute::Dimensions<T>::num_max_dimensions; ++i)
50  {
51  if(dim1[i] != dim2[i])
52  {
53  return true;
54  }
55  }
56 
57  return false;
58 }
59 
60 /** Function to compare two @ref Dimensions objects and throw an error on mismatch.
61  *
62  * @param[in] dim Object to compare against.
63  * @param[in] function Function in which the error occurred.
64  * @param[in] file File in which the error occurred.
65  * @param[in] line Line in which the error occurred.
66  */
67 template <typename T>
69 {
70 public:
71  /** Construct a comparison function.
72  *
73  * @param[in] dim Dimensions to compare.
74  * @param[in] function Source function. Used for error reporting.
75  * @param[in] file Source code file. Used for error reporting.
76  * @param[in] line Source code line. Used for error reporting.
77  */
78  compare_dimension(const Dimensions<T> &dim, const char *function, const char *file, int line)
79  : _dim{ dim }, _function{ function }, _file{ file }, _line{ line }
80  {
81  }
82 
83  /** Compare the given object against the stored one.
84  *
85  * @param[in] dim To be compared object.
86  *
87  * @return a status.
88  */
90  {
91  ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(have_different_dimensions(_dim, dim, 0), _function, _file, _line,
92  "Objects have different dimensions");
93  return arm_compute::Status{};
94  }
95 
96 private:
97  const Dimensions<T> &_dim;
98  const char *const _function;
99  const char *const _file;
100  const int _line;
101 };
102 
103 template <typename F>
105 {
106  return arm_compute::Status{};
107 }
108 
109 template <typename F, typename T, typename... Ts>
110 inline arm_compute::Status for_each_error(F &&func, T &&arg, Ts &&... args)
111 {
114  return arm_compute::Status{};
115 }
116 
117 /** Get the info for a tensor, dummy struct */
118 template <typename T>
120 /** Get the info for a tensor */
121 template <>
123 {
124  /** Get the info for a tensor.
125  *
126  * @param[in] tensor Tensor.
127  *
128  * @return tensor info.
129  */
131  {
132  return tensor->info();
133  }
134 };
135 } // namespace detail
136 
137 /** Create an error if one of the pointers is a nullptr.
138  *
139  * @param[in] function Function in which the error occurred.
140  * @param[in] file Name of the file where the error occurred.
141  * @param[in] line Line on which the error occurred.
142  * @param[in] pointers Pointers to check against nullptr.
143  *
144  * @return Status
145  */
146 template <typename... Ts>
147 inline arm_compute::Status error_on_nullptr(const char *function, const char *file, const int line, Ts &&... pointers)
148 {
149  const std::array<const void *, sizeof...(Ts)> pointers_array{ { std::forward<Ts>(pointers)... } };
150  bool has_nullptr = std::any_of(pointers_array.begin(), pointers_array.end(), [&](const void *ptr)
151  {
152  return (ptr == nullptr);
153  });
154  ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(has_nullptr, function, file, line, "Nullptr object!");
155  return arm_compute::Status{};
156 }
157 #define ARM_COMPUTE_ERROR_ON_NULLPTR(...) \
158  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_nullptr(__func__, __FILE__, __LINE__, __VA_ARGS__))
159 #define ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(...) \
160  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(__func__, __FILE__, __LINE__, __VA_ARGS__))
161 
162 /** Return an error if the passed window is invalid.
163  *
164  * The subwindow is invalid if:
165  * - It is not a valid window.
166  * - Its dimensions don't match the full window's ones
167  * - The step for each of its dimension is not identical to the corresponding one of the full window.
168  *
169  * @param[in] function Function in which the error occurred.
170  * @param[in] file Name of the file where the error occurred.
171  * @param[in] line Line on which the error occurred.
172  * @param[in] full Full size window
173  * @param[in] win Window to validate.
174  *
175  * @return Status
176  */
177 arm_compute::Status error_on_mismatching_windows(const char *function, const char *file, const int line,
178  const Window &full, const Window &win);
179 #define ARM_COMPUTE_ERROR_ON_MISMATCHING_WINDOWS(f, w) \
180  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_windows(__func__, __FILE__, __LINE__, f, w))
181 #define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_WINDOWS(f, w) \
182  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_windows(__func__, __FILE__, __LINE__, f, w))
183 
184 /** Return an error if the passed subwindow is invalid.
185  *
186  * The subwindow is invalid if:
187  * - It is not a valid window.
188  * - It is not fully contained inside the full window
189  * - The step for each of its dimension is not identical to the corresponding one of the full window.
190  *
191  * @param[in] function Function in which the error occurred.
192  * @param[in] file Name of the file where the error occurred.
193  * @param[in] line Line on which the error occurred.
194  * @param[in] full Full size window
195  * @param[in] sub Sub-window to validate.
196  *
197  * @return Status
198  */
199 arm_compute::Status error_on_invalid_subwindow(const char *function, const char *file, const int line,
200  const Window &full, const Window &sub);
201 #define ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(f, s) \
202  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_invalid_subwindow(__func__, __FILE__, __LINE__, f, s))
203 #define ARM_COMPUTE_RETURN_ERROR_ON_INVALID_SUBWINDOW(f, s) \
204  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_invalid_subwindow(__func__, __FILE__, __LINE__, f, s))
205 
206 /** Return an error if the window can't be collapsed at the given dimension.
207  *
208  * The window cannot be collapsed if the given dimension not equal to the full window's dimension or not start from 0.
209  *
210  * @param[in] function Function in which the error occurred.
211  * @param[in] file Name of the file where the error occurred.
212  * @param[in] line Line on which the error occurred.
213  * @param[in] full Full size window
214  * @param[in] window Window to be collapsed.
215  * @param[in] dim Dimension need to be checked.
216  *
217  * @return Status
218  */
219 arm_compute::Status error_on_window_not_collapsable_at_dimension(const char *function, const char *file, const int line,
220  const Window &full, const Window &window, const int dim);
221 #define ARM_COMPUTE_ERROR_ON_WINDOW_NOT_COLLAPSABLE_AT_DIMENSION(f, w, d) \
222  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_window_not_collapsable_at_dimension(__func__, __FILE__, __LINE__, f, w, d))
223 #define ARM_COMPUTE_RETURN_ERROR_ON_WINDOW_NOT_COLLAPSABLE_AT_DIMENSION(f, w, d) \
224  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_window_not_collapsable_at_dimension(__func__, __FILE__, __LINE__, f, w, d))
225 
226 /** Return an error if the passed coordinates have too many dimensions.
227  *
228  * The coordinates have too many dimensions if any of the dimensions greater or equal to max_dim is different from 0.
229  *
230  * @param[in] function Function in which the error occurred.
231  * @param[in] file Name of the file where the error occurred.
232  * @param[in] line Line on which the error occurred.
233  * @param[in] pos Coordinates to validate
234  * @param[in] max_dim Maximum number of dimensions allowed.
235  *
236  * @return Status
237  */
238 arm_compute::Status error_on_coordinates_dimensions_gte(const char *function, const char *file, const int line,
239  const Coordinates &pos, unsigned int max_dim);
240 #define ARM_COMPUTE_ERROR_ON_COORDINATES_DIMENSIONS_GTE(p, md) \
241  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_coordinates_dimensions_gte(__func__, __FILE__, __LINE__, p, md))
242 #define ARM_COMPUTE_RETURN_ERROR_ON_COORDINATES_DIMENSIONS_GTE(p, md) \
243  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_coordinates_dimensions_gte(__func__, __FILE__, __LINE__, p, md))
244 
245 /** Return an error if the passed window has too many dimensions.
246  *
247  * The window has too many dimensions if any of the dimension greater or equal to max_dim is different from 0.
248  *
249  * @param[in] function Function in which the error occurred.
250  * @param[in] file Name of the file where the error occurred.
251  * @param[in] line Line on which the error occurred.
252  * @param[in] win Window to validate
253  * @param[in] max_dim Maximum number of dimensions allowed.
254  *
255  * @return Status
256  */
257 arm_compute::Status error_on_window_dimensions_gte(const char *function, const char *file, const int line,
258  const Window &win, unsigned int max_dim);
259 #define ARM_COMPUTE_ERROR_ON_WINDOW_DIMENSIONS_GTE(w, md) \
260  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_window_dimensions_gte(__func__, __FILE__, __LINE__, w, md))
261 #define ARM_COMPUTE_RETURN_ERROR_ON_WINDOW_DIMENSIONS_GTE(w, md) \
262  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_window_dimensions_gte(__func__, __FILE__, __LINE__, w, md))
263 
264 /** Return an error if the passed dimension objects differ.
265  *
266  * @param[in] function Function in which the error occurred.
267  * @param[in] file Name of the file where the error occurred.
268  * @param[in] line Line on which the error occurred.
269  * @param[in] dim1 The first object to be compared.
270  * @param[in] dim2 The second object to be compared.
271  * @param[in] dims (Optional) Further allowed objects.
272  *
273  * @return Status
274  */
275 template <typename T, typename... Ts>
276 arm_compute::Status error_on_mismatching_dimensions(const char *function, const char *file, int line,
277  const Dimensions<T> &dim1, const Dimensions<T> &dim2, Ts &&... dims)
278 {
279  ARM_COMPUTE_RETURN_ON_ERROR(detail::for_each_error(detail::compare_dimension<T>(dim1, function, file, line), dim2, std::forward<Ts>(dims)...));
280  return arm_compute::Status{};
281 }
282 #define ARM_COMPUTE_ERROR_ON_MISMATCHING_DIMENSIONS(...) \
283  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_dimensions(__func__, __FILE__, __LINE__, __VA_ARGS__))
284 #define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DIMENSIONS(...) \
285  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_dimensions(__func__, __FILE__, __LINE__, __VA_ARGS__))
286 
287 /** Return an error if the passed tensor objects are not even.
288  *
289  * @param[in] function Function in which the error occurred.
290  * @param[in] file Name of the file where the error occurred.
291  * @param[in] line Line on which the error occurred.
292  * @param[in] format Format to check if odd shape is allowed
293  * @param[in] tensor1 The first object to be compared for odd shape.
294  * @param[in] tensors (Optional) Further allowed objects.
295  *
296  * @return Status
297  */
298 template <typename... Ts>
299 arm_compute::Status error_on_tensors_not_even(const char *function, const char *file, int line,
300  const Format &format, const ITensor *tensor1, Ts... tensors)
301 {
302  ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor1 == nullptr, function, file, line);
303  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensors)...));
304  const std::array < const ITensor *, 1 + sizeof...(Ts) > tensors_info_array{ { tensor1, std::forward<Ts>(tensors)... } };
305  ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(tensors_info_array.cbegin(), tensors_info_array.cend(), [&](const ITensor * tensor)
306  {
307  const TensorShape correct_shape = adjust_odd_shape(tensor->info()->tensor_shape(), format);
308  return detail::have_different_dimensions(tensor->info()->tensor_shape(), correct_shape, 2);
309  }),
310  function, file, line, "Tensor shape has odd dimensions");
311  return arm_compute::Status{};
312 }
313 
314 #define ARM_COMPUTE_ERROR_ON_TENSORS_NOT_EVEN(...) \
315  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_tensors_not_even(__func__, __FILE__, __LINE__, __VA_ARGS__))
316 #define ARM_COMPUTE_RETURN_ERROR_ON_TENSORS_NOT_EVEN(...) \
317  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_tensors_not_even(__func__, __FILE__, __LINE__, __VA_ARGS__))
318 
319 /** Return an error if the passed tensor objects are not sub-sampled.
320  *
321  * @param[in] function Function in which the error occurred.
322  * @param[in] file Name of the file where the error occurred.
323  * @param[in] line Line on which the error occurred.
324  * @param[in] format Format to check if sub-sampling allowed.
325  * @param[in] shape The tensor shape to calculate sub-sampling from.
326  * @param[in] tensor1 The first object to be compared.
327  * @param[in] tensors (Optional) Further allowed objects.
328  *
329  * @return Status
330  */
331 template <typename... Ts>
332 arm_compute::Status error_on_tensors_not_subsampled(const char *function, const char *file, int line,
333  const Format &format, const TensorShape &shape, const ITensor *tensor1, Ts... tensors)
334 {
335  ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor1 == nullptr, function, file, line);
336  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensors)...));
337  const TensorShape sub2_shape = calculate_subsampled_shape(shape, format);
338  const std::array < const ITensor *, 1 + sizeof...(Ts) > tensors_info_array{ { tensor1, std::forward<Ts>(tensors)... } };
339  ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(tensors_info_array.cbegin(), tensors_info_array.cend(), [&](const ITensor * tensor)
340  {
341  return detail::have_different_dimensions(tensor->info()->tensor_shape(), sub2_shape, 2);
342  }),
343  function, file, line, "Tensor shape has mismatch dimensions for sub-sampling");
344  return arm_compute::Status{};
345 }
346 
347 #define ARM_COMPUTE_ERROR_ON_TENSORS_NOT_SUBSAMPLED(...) \
348  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_tensors_not_subsampled(__func__, __FILE__, __LINE__, __VA_ARGS__))
349 #define ARM_COMPUTE_RETURN_ERROR_ON_TENSORS_NOT_SUBSAMPLED(...) \
350  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_tensors_not_subsampled(__func__, __FILE__, __LINE__, __VA_ARGS__))
351 
352 /** Return an error if the passed two tensor infos have different shapes from the given dimension
353  *
354  * @param[in] function Function in which the error occurred.
355  * @param[in] file Name of the file where the error occurred.
356  * @param[in] line Line on which the error occurred.
357  * @param[in] tensor_info_1 The first tensor info to be compared.
358  * @param[in] tensor_info_2 The second tensor info to be compared.
359  * @param[in] tensor_infos (Optional) Further allowed tensor infos.
360  *
361  * @return Status
362  */
363 template <typename... Ts>
364 inline arm_compute::Status error_on_mismatching_shapes(const char *function, const char *file, const int line,
365  const ITensorInfo *tensor_info_1, const ITensorInfo *tensor_info_2, Ts... tensor_infos)
366 {
367  return error_on_mismatching_shapes(function, file, line, 0U, tensor_info_1, tensor_info_2, std::forward<Ts>(tensor_infos)...);
368 }
369 /** Return an error if the passed two tensors have different shapes from the given dimension
370  *
371  * @param[in] function Function in which the error occurred.
372  * @param[in] file Name of the file where the error occurred.
373  * @param[in] line Line on which the error occurred.
374  * @param[in] tensor_1 The first tensor to be compared.
375  * @param[in] tensor_2 The second tensor to be compared.
376  * @param[in] tensors (Optional) Further allowed tensors.
377  *
378  * @return Status
379  */
380 template <typename... Ts>
381 inline arm_compute::Status error_on_mismatching_shapes(const char *function, const char *file, const int line,
382  const ITensor *tensor_1, const ITensor *tensor_2, Ts... tensors)
383 {
384  return error_on_mismatching_shapes(function, file, line, 0U, tensor_1, tensor_2, std::forward<Ts>(tensors)...);
385 }
386 /** Return an error if the passed two tensors have different shapes from the given dimension
387  *
388  * @param[in] function Function in which the error occurred.
389  * @param[in] file Name of the file where the error occurred.
390  * @param[in] line Line on which the error occurred.
391  * @param[in] upper_dim The dimension from which to check.
392  * @param[in] tensor_info_1 The first tensor info to be compared.
393  * @param[in] tensor_info_2 The second tensor info to be compared.
394  * @param[in] tensor_infos (Optional) Further allowed tensor infos.
395  *
396  * @return Status
397  */
398 template <typename... Ts>
399 inline arm_compute::Status error_on_mismatching_shapes(const char *function, const char *file, const int line,
400  unsigned int upper_dim, const ITensorInfo *tensor_info_1, const ITensorInfo *tensor_info_2, Ts... tensor_infos)
401 {
402  ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_info_1 == nullptr, function, file, line);
403  ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_info_2 == nullptr, function, file, line);
404  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensor_infos)...));
405 
406  const std::array < const ITensorInfo *, 2 + sizeof...(Ts) > tensors_info_array{ { tensor_info_1, tensor_info_2, std::forward<Ts>(tensor_infos)... } };
407  ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(std::next(tensors_info_array.cbegin()), tensors_info_array.cend(), [&](const ITensorInfo * tensor_info)
408  {
409  return detail::have_different_dimensions((*tensors_info_array.cbegin())->tensor_shape(), tensor_info->tensor_shape(), upper_dim);
410  }),
411  function, file, line, "Tensors have different shapes");
412  return arm_compute::Status{};
413 }
414 /** Return an error if the passed two tensors have different shapes from the given dimension
415  *
416  * @param[in] function Function in which the error occurred.
417  * @param[in] file Name of the file where the error occurred.
418  * @param[in] line Line on which the error occurred.
419  * @param[in] upper_dim The dimension from which to check.
420  * @param[in] tensor_1 The first tensor to be compared.
421  * @param[in] tensor_2 The second tensor to be compared.
422  * @param[in] tensors (Optional) Further allowed tensors.
423  *
424  * @return Status
425  */
426 template <typename... Ts>
427 inline arm_compute::Status error_on_mismatching_shapes(const char *function, const char *file, const int line,
428  unsigned int upper_dim, const ITensor *tensor_1, const ITensor *tensor_2, Ts... tensors)
429 {
430  ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_1 == nullptr, function, file, line);
431  ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_2 == nullptr, function, file, line);
432  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensors)...));
433  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_shapes(function, file, line, upper_dim, tensor_1->info(), tensor_2->info(),
435  return arm_compute::Status{};
436 }
437 #define ARM_COMPUTE_ERROR_ON_MISMATCHING_SHAPES(...) \
438  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_shapes(__func__, __FILE__, __LINE__, __VA_ARGS__))
439 #define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_SHAPES(...) \
440  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_shapes(__func__, __FILE__, __LINE__, __VA_ARGS__))
441 
442 /** Return an error if the passed tensor infos have different data layouts
443  *
444  * @param[in] function Function in which the error occurred.
445  * @param[in] file Name of the file where the error occurred.
446  * @param[in] line Line on which the error occurred.
447  * @param[in] tensor_info The first tensor info to be compared.
448  * @param[in] tensor_infos (Optional) Further allowed tensor infos.
449  *
450  * @return Status
451  */
452 template <typename... Ts>
453 inline arm_compute::Status error_on_mismatching_data_layouts(const char *function, const char *file, const int line,
454  const ITensorInfo *tensor_info, Ts... tensor_infos)
455 {
456  ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_info == nullptr, function, file, line);
457  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensor_infos)...));
458 
459  DataLayout &&tensor_data_layout = tensor_info->data_layout();
460  const std::array<const ITensorInfo *, sizeof...(Ts)> tensors_infos_array{ { std::forward<Ts>(tensor_infos)... } };
461  ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(tensors_infos_array.begin(), tensors_infos_array.end(), [&](const ITensorInfo * tensor_info_obj)
462  {
463  return tensor_info_obj->data_layout() != tensor_data_layout;
464  }),
465  function, file, line, "Tensors have different data layouts");
466  return arm_compute::Status{};
467 }
468 /** Return an error if the passed tensors have different data layouts
469  *
470  * @param[in] function Function in which the error occurred.
471  * @param[in] file Name of the file where the error occurred.
472  * @param[in] line Line on which the error occurred.
473  * @param[in] tensor The first tensor to be compared.
474  * @param[in] tensors (Optional) Further allowed tensors.
475  *
476  * @return Status
477  */
478 template <typename... Ts>
479 inline arm_compute::Status error_on_mismatching_data_layouts(const char *function, const char *file, const int line,
480  const ITensor *tensor, Ts... tensors)
481 {
482  ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor == nullptr, function, file, line);
483  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensors)...));
486  return arm_compute::Status{};
487 }
488 #define ARM_COMPUTE_ERROR_ON_MISMATCHING_DATA_LAYOUT(...) \
489  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_data_layouts(__func__, __FILE__, __LINE__, __VA_ARGS__))
490 #define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_LAYOUT(...) \
491  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_data_layouts(__func__, __FILE__, __LINE__, __VA_ARGS__))
492 
493 /** Return an error if the passed two tensor infos have different data types
494  *
495  * @param[in] function Function in which the error occurred.
496  * @param[in] file Name of the file where the error occurred.
497  * @param[in] line Line on which the error occurred.
498  * @param[in] tensor_info The first tensor info to be compared.
499  * @param[in] tensor_infos (Optional) Further allowed tensor infos.
500  *
501  * @return Status
502  */
503 template <typename... Ts>
504 inline arm_compute::Status error_on_mismatching_data_types(const char *function, const char *file, const int line,
505  const ITensorInfo *tensor_info, Ts... tensor_infos)
506 {
507  ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_info == nullptr, function, file, line);
508  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensor_infos)...));
509 
510  DataType &&tensor_data_type = tensor_info->data_type();
511  const std::array<const ITensorInfo *, sizeof...(Ts)> tensors_infos_array{ { std::forward<Ts>(tensor_infos)... } };
512  ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(tensors_infos_array.begin(), tensors_infos_array.end(), [&](const ITensorInfo * tensor_info_obj)
513  {
514  return tensor_info_obj->data_type() != tensor_data_type;
515  }),
516  function, file, line, "Tensors have different data types");
517  return arm_compute::Status{};
518 }
519 /** Return an error if the passed two tensors have different data types
520  *
521  * @param[in] function Function in which the error occurred.
522  * @param[in] file Name of the file where the error occurred.
523  * @param[in] line Line on which the error occurred.
524  * @param[in] tensor The first tensor to be compared.
525  * @param[in] tensors (Optional) Further allowed tensors.
526  *
527  * @return Status
528  */
529 template <typename... Ts>
530 inline arm_compute::Status error_on_mismatching_data_types(const char *function, const char *file, const int line,
531  const ITensor *tensor, Ts... tensors)
532 {
533  ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor == nullptr, function, file, line);
534  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_nullptr(function, file, line, std::forward<Ts>(tensors)...));
537  return arm_compute::Status{};
538 }
539 #define ARM_COMPUTE_ERROR_ON_MISMATCHING_DATA_TYPES(...) \
540  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_data_types(__func__, __FILE__, __LINE__, __VA_ARGS__))
541 #define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(...) \
542  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_data_types(__func__, __FILE__, __LINE__, __VA_ARGS__))
543 
544 /** Return an error if the passed tensor infos have different asymmetric quantized data types or different quantization info
545  *
546  * @note: If the first tensor info doesn't have asymmetric quantized data type, the function returns without throwing an error
547  *
548  * @param[in] function Function in which the error occurred.
549  * @param[in] file Name of the file where the error occurred.
550  * @param[in] line Line on which the error occurred.
551  * @param[in] tensor_info_1 The first tensor info to be compared.
552  * @param[in] tensor_info_2 The second tensor info to be compared.
553  * @param[in] tensor_infos (Optional) Further allowed tensor infos.
554  *
555  * @return Status
556  */
557 template <typename... Ts>
558 inline arm_compute::Status error_on_mismatching_quantization_info(const char *function, const char *file, const int line,
559  const ITensorInfo *tensor_info_1, const ITensorInfo *tensor_info_2, Ts... tensor_infos)
560 {
561  DataType &&first_data_type = tensor_info_1->data_type();
562  const QuantizationInfo first_quantization_info = tensor_info_1->quantization_info();
563 
564  if(!is_data_type_quantized(first_data_type))
565  {
566  return arm_compute::Status{};
567  }
568 
569  const std::array < const ITensorInfo *, 1 + sizeof...(Ts) > tensor_infos_array{ { tensor_info_2, std::forward<Ts>(tensor_infos)... } };
570  ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(tensor_infos_array.begin(), tensor_infos_array.end(), [&](const ITensorInfo * tensor_info)
571  {
572  return tensor_info->data_type() != first_data_type;
573  }),
574  function, file, line, "Tensors have different asymmetric quantized data types");
575  ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(std::any_of(tensor_infos_array.begin(), tensor_infos_array.end(), [&](const ITensorInfo * tensor_info)
576  {
577  return tensor_info->quantization_info() != first_quantization_info;
578  }),
579  function, file, line, "Tensors have different quantization information");
580 
581  return arm_compute::Status{};
582 }
583 /** Return an error if the passed tensor have different asymmetric quantized data types or different quantization info
584  *
585  * @note: If the first tensor doesn't have asymmetric quantized data type, the function returns without throwing an error
586  *
587  * @param[in] function Function in which the error occurred.
588  * @param[in] file Name of the file where the error occurred.
589  * @param[in] line Line on which the error occurred.
590  * @param[in] tensor_1 The first tensor to be compared.
591  * @param[in] tensor_2 The second tensor to be compared.
592  * @param[in] tensors (Optional) Further allowed tensors.
593  *
594  * @return Status
595  */
596 template <typename... Ts>
597 inline arm_compute::Status error_on_mismatching_quantization_info(const char *function, const char *file, const int line,
598  const ITensor *tensor_1, const ITensor *tensor_2, Ts... tensors)
599 {
600  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_quantization_info(function, file, line, tensor_1->info(), tensor_2->info(),
602  return arm_compute::Status{};
603 }
604 #define ARM_COMPUTE_ERROR_ON_MISMATCHING_QUANTIZATION_INFO(...) \
605  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_mismatching_quantization_info(__func__, __FILE__, __LINE__, __VA_ARGS__))
606 #define ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_QUANTIZATION_INFO(...) \
607  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_mismatching_quantization_info(__func__, __FILE__, __LINE__, __VA_ARGS__))
608 
609 /** Throw an error if the format of the passed tensor/multi-image does not match any of the formats provided.
610  *
611  * @param[in] function Function in which the error occurred.
612  * @param[in] file Name of the file where the error occurred.
613  * @param[in] line Line on which the error occurred.
614  * @param[in] object Tensor/multi-image to validate.
615  * @param[in] format First format allowed.
616  * @param[in] formats (Optional) Further allowed formats.
617  */
618 template <typename T, typename F, typename... Fs>
619 void error_on_format_not_in(const char *function, const char *file, const int line,
620  const T *object, F &&format, Fs &&... formats)
621 {
622  ARM_COMPUTE_ERROR_ON_LOC(object == nullptr, function, file, line);
623 
624  Format &&object_format = object->info()->format();
625  ARM_COMPUTE_UNUSED(object_format);
626 
627  ARM_COMPUTE_ERROR_ON_LOC(object_format == Format::UNKNOWN, function, file, line);
628 
629  const std::array<F, sizeof...(Fs)> formats_array{ { std::forward<Fs>(formats)... } };
630  ARM_COMPUTE_UNUSED(formats_array);
631 
632  ARM_COMPUTE_ERROR_ON_LOC_MSG(object_format != format && std::none_of(formats_array.begin(), formats_array.end(), [&](const F & f)
633  {
634  return f == object_format;
635  }),
636  function, file, line, "Format %s not supported by this kernel", string_from_format(object_format).c_str());
637  ARM_COMPUTE_UNUSED(function, format, file, line);
638 }
639 #define ARM_COMPUTE_ERROR_ON_FORMAT_NOT_IN(t, ...) ::arm_compute::error_on_format_not_in(__func__, __FILE__, __LINE__, t, __VA_ARGS__)
640 
641 /** Return an error if the data type of the passed tensor info does not match any of the data types provided.
642  *
643  * @param[in] function Function in which the error occurred.
644  * @param[in] file Name of the file where the error occurred.
645  * @param[in] line Line on which the error occurred.
646  * @param[in] tensor_info Tensor info to validate.
647  * @param[in] dt First data type allowed.
648  * @param[in] dts (Optional) Further allowed data types.
649  *
650  * @return Status
651  */
652 template <typename T, typename... Ts>
653 inline arm_compute::Status error_on_data_type_not_in(const char *function, const char *file, const int line,
654  const ITensorInfo *tensor_info, T &&dt, Ts &&... dts)
655 {
656  ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_info == nullptr, function, file, line);
657 
658  const DataType &tensor_dt = tensor_info->data_type(); //NOLINT
659  ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_dt == DataType::UNKNOWN, function, file, line);
660 
661  const std::array<T, sizeof...(Ts)> dts_array{ { std::forward<Ts>(dts)... } };
662  ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG_VAR(tensor_dt != dt && std::none_of(dts_array.begin(), dts_array.end(), [&](const T & d)
663  {
664  return d == tensor_dt;
665  }),
666  function, file, line, "ITensor data type %s not supported by this kernel", string_from_data_type(tensor_dt).c_str());
667  return arm_compute::Status{};
668 }
669 /** Return an error if the data type of the passed tensor does not match any of the data types provided.
670  *
671  * @param[in] function Function in which the error occurred.
672  * @param[in] file Name of the file where the error occurred.
673  * @param[in] line Line on which the error occurred.
674  * @param[in] tensor Tensor to validate.
675  * @param[in] dt First data type allowed.
676  * @param[in] dts (Optional) Further allowed data types.
677  *
678  * @return Status
679  */
680 template <typename T, typename... Ts>
681 inline arm_compute::Status error_on_data_type_not_in(const char *function, const char *file, const int line,
682  const ITensor *tensor, T &&dt, Ts &&... dts)
683 {
684  ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor == nullptr, function, file, line);
685  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_data_type_not_in(function, file, line, tensor->info(), std::forward<T>(dt), std::forward<Ts>(dts)...));
686  return arm_compute::Status{};
687 }
688 #define ARM_COMPUTE_ERROR_ON_DATA_TYPE_NOT_IN(t, ...) \
689  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_data_type_not_in(__func__, __FILE__, __LINE__, t, __VA_ARGS__))
690 #define ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_NOT_IN(t, ...) \
691  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_data_type_not_in(__func__, __FILE__, __LINE__, t, __VA_ARGS__))
692 
693 /** Return an error if the data layout of the passed tensor info does not match any of the data layouts provided.
694  *
695  * @param[in] function Function in which the error occurred.
696  * @param[in] file Name of the file where the error occurred.
697  * @param[in] line Line on which the error occurred.
698  * @param[in] tensor_info Tensor info to validate.
699  * @param[in] dl First data layout allowed.
700  * @param[in] dls (Optional) Further allowed data layouts.
701  *
702  * @return Status
703  */
704 template <typename T, typename... Ts>
705 inline arm_compute::Status error_on_data_layout_not_in(const char *function, const char *file, const int line,
706  const ITensorInfo *tensor_info, T &&dl, Ts &&... dls)
707 {
708  ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_info == nullptr, function, file, line);
709 
710  const DataLayout &tensor_dl = tensor_info->data_layout(); //NOLINT
711  ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_dl == DataLayout::UNKNOWN, function, file, line);
712 
713  const std::array<T, sizeof...(Ts)> dls_array{ { std::forward<Ts>(dls)... } };
714  ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG_VAR(tensor_dl != dl && std::none_of(dls_array.begin(), dls_array.end(), [&](const T & l)
715  {
716  return l == tensor_dl;
717  }),
718  function, file, line, "ITensor data layout %s not supported by this kernel", string_from_data_layout(tensor_dl).c_str());
719  return arm_compute::Status{};
720 }
721 /** Return an error if the data layout of the passed tensor does not match any of the data layout provided.
722  *
723  * @param[in] function Function in which the error occurred.
724  * @param[in] file Name of the file where the error occurred.
725  * @param[in] line Line on which the error occurred.
726  * @param[in] tensor Tensor to validate.
727  * @param[in] dl First data layout allowed.
728  * @param[in] dls (Optional) Further allowed data layouts.
729  *
730  * @return Status
731  */
732 template <typename T, typename... Ts>
733 inline arm_compute::Status error_on_data_layout_not_in(const char *function, const char *file, const int line,
734  const ITensor *tensor, T &&dl, Ts &&... dls)
735 {
736  ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor == nullptr, function, file, line);
737  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_data_layout_not_in(function, file, line, tensor->info(), std::forward<T>(dl), std::forward<Ts>(dls)...));
738  return arm_compute::Status{};
739 }
740 #define ARM_COMPUTE_ERROR_ON_DATA_LAYOUT_NOT_IN(t, ...) \
741  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_data_layout_not_in(__func__, __FILE__, __LINE__, t, __VA_ARGS__))
742 #define ARM_COMPUTE_RETURN_ERROR_ON_DATA_LAYOUT_NOT_IN(t, ...) \
743  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_data_layout_not_in(__func__, __FILE__, __LINE__, t, __VA_ARGS__))
744 
745 /** Return an error if the data type or the number of channels of the passed tensor info does not match any of the data types and number of channels provided.
746  *
747  * @param[in] function Function in which the error occurred.
748  * @param[in] file Name of the file where the error occurred.
749  * @param[in] line Line on which the error occurred.
750  * @param[in] tensor_info Tensor info to validate.
751  * @param[in] num_channels Number of channels to check
752  * @param[in] dt First data type allowed.
753  * @param[in] dts (Optional) Further allowed data types.
754  *
755  * @return Status
756  */
757 template <typename T, typename... Ts>
758 inline arm_compute::Status error_on_data_type_channel_not_in(const char *function, const char *file, const int line,
759  const ITensorInfo *tensor_info, size_t num_channels, T &&dt, Ts &&... dts)
760 {
761  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_data_type_not_in(function, file, line, tensor_info, std::forward<T>(dt), std::forward<Ts>(dts)...));
762  const size_t tensor_nc = tensor_info->num_channels();
763  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);
764  return arm_compute::Status{};
765 }
766 /** Return an error if the data type or the number of channels of the passed tensor does not match any of the data types and number of channels provided.
767  *
768  * @param[in] function Function in which the error occurred.
769  * @param[in] file Name of the file where the error occurred.
770  * @param[in] line Line on which the error occurred.
771  * @param[in] tensor Tensor to validate.
772  * @param[in] num_channels Number of channels to check
773  * @param[in] dt First data type allowed.
774  * @param[in] dts (Optional) Further allowed data types.
775  *
776  * @return Status
777  */
778 template <typename T, typename... Ts>
779 inline arm_compute::Status error_on_data_type_channel_not_in(const char *function, const char *file, const int line,
780  const ITensor *tensor, size_t num_channels, T &&dt, Ts &&... dts)
781 {
782  ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor == nullptr, function, file, line);
783  ARM_COMPUTE_RETURN_ON_ERROR(error_on_data_type_channel_not_in(function, file, line, tensor->info(), num_channels, std::forward<T>(dt), std::forward<Ts>(dts)...));
784  return arm_compute::Status{};
785 }
786 #define ARM_COMPUTE_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(t, c, ...) \
787  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_data_type_channel_not_in(__func__, __FILE__, __LINE__, t, c, __VA_ARGS__))
788 #define ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(t, c, ...) \
789  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_data_type_channel_not_in(__func__, __FILE__, __LINE__, t, c, __VA_ARGS__))
790 
791 /** Return an error if the data type of the passed tensor info is FP16 and FP16 extension is not supported by the device.
792  *
793  * @param[in] function Function in which the error occurred.
794  * @param[in] file Name of the file where the error occurred.
795  * @param[in] line Line on which the error occurred.
796  * @param[in] tensor_info Tensor info to validate.
797  * @param[in] is_fp16_supported Is fp16 supported by the device.
798  *
799  * @return Status
800  */
801 inline arm_compute::Status error_on_unsupported_fp16(const char *function, const char *file, const int line,
802  const ITensorInfo *tensor_info, bool is_fp16_supported)
803 {
804  ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor_info == nullptr, function, file, line);
805  ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG((tensor_info->data_type() == DataType::F16 && !is_fp16_supported),
806  function, file, line, "FP16 not supported by the device");
807  return arm_compute::Status{};
808 }
809 
810 /** Return an error if the data type of the passed tensor is FP16 and FP16 extension is not supported by the device.
811  *
812  * @param[in] function Function in which the error occurred.
813  * @param[in] file Name of the file where the error occurred.
814  * @param[in] line Line on which the error occurred.
815  * @param[in] tensor Tensor to validate.
816  * @param[in] is_fp16_supported Is fp16 supported by the device.
817  *
818  * @return Status
819  */
820 inline arm_compute::Status error_on_unsupported_fp16(const char *function, const char *file, const int line,
821  const ITensor *tensor, bool is_fp16_supported)
822 {
823  ARM_COMPUTE_RETURN_ERROR_ON_LOC(tensor == nullptr, function, file, line);
824  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_unsupported_fp16(function, file, line, tensor->info(), is_fp16_supported));
825  return arm_compute::Status{};
826 }
827 
828 /** Return an error if the tensor is not 2D.
829  *
830  * @param[in] function Function in which the error occurred.
831  * @param[in] file Name of the file where the error occurred.
832  * @param[in] line Line on which the error occurred.
833  * @param[in] tensor Tensor to validate.
834  *
835  * @return Status
836  */
837 arm_compute::Status error_on_tensor_not_2d(const char *function, const char *file, const int line,
838  const ITensor *tensor);
839 
840 /** Return an error if the tensor info is not 2D.
841  *
842  * @param[in] function Function in which the error occurred.
843  * @param[in] file Name of the file where the error occurred.
844  * @param[in] line Line on which the error occurred.
845  * @param[in] tensor Tensor info to validate.
846  *
847  * @return Status
848  */
849 arm_compute::Status error_on_tensor_not_2d(const char *function, const char *file, const int line,
850  const ITensorInfo *tensor);
851 
852 #define ARM_COMPUTE_ERROR_ON_TENSOR_NOT_2D(t) \
853  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_tensor_not_2d(__func__, __FILE__, __LINE__, t))
854 #define ARM_COMPUTE_RETURN_ERROR_ON_TENSOR_NOT_2D(t) \
855  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_tensor_not_2d(__func__, __FILE__, __LINE__, t))
856 
857 /** Return an error if the channel is not in channels.
858  *
859  * @param[in] function Function in which the error occurred.
860  * @param[in] file Name of the file where the error occurred.
861  * @param[in] line Line on which the error occurred.
862  * @param[in] cn Input channel
863  * @param[in] channel First channel allowed.
864  * @param[in] channels (Optional) Further allowed channels.
865  *
866  * @return Status
867  */
868 template <typename T, typename... Ts>
869 inline arm_compute::Status error_on_channel_not_in(const char *function, const char *file, const int line,
870  T cn, T &&channel, Ts &&... channels)
871 {
872  ARM_COMPUTE_RETURN_ERROR_ON_LOC(cn == Channel::UNKNOWN, function, file, line);
873 
874  const std::array<T, sizeof...(Ts)> channels_array{ { std::forward<Ts>(channels)... } };
875  ARM_COMPUTE_RETURN_ERROR_ON_LOC(channel != cn && std::none_of(channels_array.begin(), channels_array.end(), [&](const T & f)
876  {
877  return f == cn;
878  }),
879  function, file, line);
880  return arm_compute::Status{};
881 }
882 #define ARM_COMPUTE_ERROR_ON_CHANNEL_NOT_IN(c, ...) \
883  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_channel_not_in(__func__, __FILE__, __LINE__, c, __VA_ARGS__))
884 #define ARM_COMPUTE_RETURN_ERROR_ON_CHANNEL_NOT_IN(c, ...) \
885  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_channel_not_in(__func__, __FILE__, __LINE__, c, __VA_ARGS__))
886 
887 /** Return an error if the channel is not in format.
888  *
889  * @param[in] function Function in which the error occurred.
890  * @param[in] file Name of the file where the error occurred.
891  * @param[in] line Line on which the error occurred.
892  * @param[in] fmt Input channel
893  * @param[in] cn First channel allowed.
894  *
895  * @return Status
896  */
897 arm_compute::Status error_on_channel_not_in_known_format(const char *function, const char *file, const int line,
898  Format fmt, Channel cn);
899 #define ARM_COMPUTE_ERROR_ON_CHANNEL_NOT_IN_KNOWN_FORMAT(f, c) \
900  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_channel_not_in_known_format(__func__, __FILE__, __LINE__, f, c))
901 #define ARM_COMPUTE_RETURN_ERROR_ON_CHANNEL_NOT_IN_KNOWN_FORMAT(f, c) \
902  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_channel_not_in_known_format(__func__, __FILE__, __LINE__, f, c))
903 
904 /** Return an error if the kernel is not configured.
905  *
906  * @param[in] function Function in which the error occurred.
907  * @param[in] file Name of the file where the error occurred.
908  * @param[in] line Line on which the error occurred.
909  * @param[in] kernel Kernel to validate.
910  *
911  * @return Status
912  */
913 arm_compute::Status error_on_unconfigured_kernel(const char *function, const char *file, const int line,
914  const IKernel *kernel);
915 #define ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(k) \
916  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_unconfigured_kernel(__func__, __FILE__, __LINE__, k))
917 #define ARM_COMPUTE_RETURN_ERROR_ON_UNCONFIGURED_KERNEL(k) \
918  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_unconfigured_kernel(__func__, __FILE__, __LINE__, k))
919 
920 /** Return an error if if the coordinates and shape of the subtensor are within the parent tensor.
921  *
922  * @param[in] function Function in which the error occurred.
923  * @param[in] file Name of the file where the error occurred.
924  * @param[in] line Line on which the error occurred.
925  * @param[in] parent_shape Parent tensor shape
926  * @param[in] coords Coordinates inside the parent tensor where the first element of the subtensor is
927  * @param[in] shape Shape of the subtensor
928  *
929  * @return Status
930  */
931 arm_compute::Status error_on_invalid_subtensor(const char *function, const char *file, const int line,
932  const TensorShape &parent_shape, const Coordinates &coords, const TensorShape &shape);
933 #define ARM_COMPUTE_ERROR_ON_INVALID_SUBTENSOR(p, c, s) \
934  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_invalid_subtensor(__func__, __FILE__, __LINE__, p, c, s))
935 #define ARM_COMPUTE_RETURN_ERROR_ON_INVALID_SUBTENSOR(p, c, s) \
936  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_invalid_subtensor(__func__, __FILE__, __LINE__, p, c, s))
937 
938 /** Return an error if the valid region of a subtensor is not inside the valid region of the parent tensor.
939  *
940  * @param[in] function Function in which the error occurred.
941  * @param[in] file Name of the file where the error occurred.
942  * @param[in] line Line on which the error occurred.
943  * @param[in] parent_valid_region Parent valid region.
944  * @param[in] valid_region Valid region of subtensor.
945  *
946  * @return Status
947  */
948 arm_compute::Status error_on_invalid_subtensor_valid_region(const char *function, const char *file, const int line,
949  const ValidRegion &parent_valid_region, const ValidRegion &valid_region);
950 #define ARM_COMPUTE_ERROR_ON_INVALID_SUBTENSOR_VALID_REGION(pv, sv) \
951  ARM_COMPUTE_ERROR_THROW_ON(::arm_compute::error_on_invalid_subtensor_valid_region(__func__, __FILE__, __LINE__, pv, sv))
952 #define ARM_COMPUTE_RETURN_ERROR_ON_INVALID_SUBTENSOR_VALID_REGION(pv, sv) \
953  ARM_COMPUTE_RETURN_ON_ERROR(::arm_compute::error_on_invalid_subtensor_valid_region(__func__, __FILE__, __LINE__, pv, sv))
954 }
955 #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:967
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:698
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:144
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:147
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:801
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:705
const ValidRegion valid_region
Definition: Scale.cpp:223
Interface for CPU tensor.
Definition: ITensor.h:36
Copyright (c) 2017-2021 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:364
Function to compare two Dimensions objects and throw an error on mismatch.
Definition: Validate.h:68
1 channel, 1 F16 per channel
DataType dt
arm_compute::Status for_each_error(F &&)
Definition: Validate.h:104
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:299
Get the info for a tensor, dummy struct.
Definition: Validate.h:119
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:558
DataLayout dl
const std::string & string_from_data_type(DataType dt)
Convert a data type identity into a string.
Definition: Utils.cpp:135
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:440
Format
Image colour formats.
Definition: Types.h:54
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:869
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:276
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:332
ITensorInfo * operator()(const ITensor *tensor)
Get the info for a tensor.
Definition: Validate.h:130
Dimensions with dimensionality.
Definition: Dimensions.h:42
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:47
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:671
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:154
FloorUKernelPtr func
arm_compute::Status operator()(const Dimensions< T > &dim)
Compare the given object against the stored one.
Definition: Validate.h:89
const std::string & string_from_data_layout(DataLayout dl)
Convert a data layout identity into a string.
Definition: Utils.cpp:123
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:504
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:653
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:758
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:453
DataType
Available data types.
Definition: Types.h:77
compare_dimension(const Dimensions< T > &dim, const char *function, const char *file, int line)
Construct a comparison function.
Definition: Validate.h:78
DataLayout
[DataLayout enum definition]
Definition: Types.h:114
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:167
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:619
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:76
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