505f5a9b39f14ae5910968d1baf13de60cd4e0d9
[platform/core/ml/nnfw.git] / runtime / onert / core / include / util / Utils.h
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *    http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /**
18  * @file     Utils.h
19  * @brief    This file contains utility macro
20  */
21
22 #ifndef __ONERT_UTIL_UTILS_H__
23 #define __ONERT_UTIL_UTILS_H__
24
25 #include "ir/Coordinates.h"
26 #include "ir/Shape.h"
27
28 #define UNUSED_RELEASE(a) (void)(a)
29
30 template <size_t from, size_t to, typename Enable = void> struct ForEachDimension
31 {
32   template <typename L>
33   static void unroll(const onert::ir::Shape &shape, onert::ir::Coordinates &coords,
34                      L lambda_function)
35   {
36     static_assert(from < to, "from must not be less than to");
37     assert(static_cast<int>(to) <= shape.rank());
38     const auto &d = shape.dim(from);
39
40     for (auto v = 0; v < d; v++)
41     {
42       coords.set(from, v);
43       ForEachDimension<from + 1, to>::unroll(shape, coords, lambda_function);
44     }
45   }
46 };
47
48 template <size_t from, size_t to>
49 struct ForEachDimension<from, to, typename std::enable_if<from == to>::type>
50 {
51   template <typename L>
52   static void unroll(const onert::ir::Shape &shape, onert::ir::Coordinates &coords,
53                      L lambda_function)
54   {
55     UNUSED_RELEASE(shape);
56     assert(static_cast<int>(to) <= shape.rank());
57     lambda_function(coords);
58   }
59 };
60
61 template <typename L> inline void ShapeLoop(const onert::ir::Shape &shape, L lambda_function)
62 {
63   assert(shape.rank() > 0);
64   for (auto i = 0; i < shape.rank(); ++i)
65   {
66     assert(shape.dim(i) > 0);
67   }
68
69   onert::ir::Coordinates coords;
70   switch (shape.rank())
71   {
72     case 0:
73       coords.set(0, 0);
74       ForEachDimension<0, 0>::unroll(shape, coords, lambda_function);
75       break;
76     case 1:
77       ForEachDimension<0, 1>::unroll(shape, coords, lambda_function);
78       break;
79     case 2:
80       ForEachDimension<0, 2>::unroll(shape, coords, lambda_function);
81       break;
82     case 3:
83       ForEachDimension<0, 3>::unroll(shape, coords, lambda_function);
84       break;
85     case 4:
86       ForEachDimension<0, 4>::unroll(shape, coords, lambda_function);
87       break;
88     case 5:
89       ForEachDimension<0, 5>::unroll(shape, coords, lambda_function);
90       break;
91     case 6:
92       ForEachDimension<0, 6>::unroll(shape, coords, lambda_function);
93       break;
94     default:
95       assert(false && "ShapeLoop, 1 <= Shape'rank <= 6");
96       break;
97   }
98 }
99 #endif // __ONERT_UTIL_UTILS_H__