Imported Upstream version 1.12.0
[platform/core/ml/nnfw.git] / compute / cker / include / cker / operation / Tile.h
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
3  * Copyright 2017 The TensorFlow Authors. All Rights Reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #ifndef __NNFW_CKER_TILE_H__
19 #define __NNFW_CKER_TILE_H__
20
21 #include "cker/Shape.h"
22
23 namespace nnfw
24 {
25 namespace cker
26 {
27
28 template <typename T, typename M>
29 void CopyMultipleTimes(const T *in_data, int32_t in_size, M multiplier, T *out_data)
30 {
31   for (M i = 0; i < multiplier; ++i)
32   {
33     const T *in_end = in_data + in_size;
34     T *new_out_data = std::copy(in_data, in_end, out_data);
35     in_data = out_data;
36     out_data = new_out_data;
37   }
38 }
39
40 template <typename T, typename M>
41 std::pair<int, int> TileOneDimension(const Shape &in_dimensions, const T *in_data,
42                                      const M *multipliers, T *out_data, int dimension)
43 {
44   const int dimension_size = in_dimensions.Dims(dimension);
45   if (dimension == in_dimensions.DimensionsCount() - 1)
46   {
47     CopyMultipleTimes(in_data, dimension_size, multipliers[dimension], out_data);
48     return std::make_pair(dimension_size,
49                           dimension_size * static_cast<int>(multipliers[dimension]));
50   }
51   int total_stride_size = 0, total_tiled_stride_size = 0;
52   const T *copy_from_data = in_data;
53   T *copy_to_data = out_data;
54   for (int i = 0; i < dimension_size; ++i)
55   {
56     int stride_size = 0, tiled_stride_size = 0;
57     std::tie(stride_size, tiled_stride_size) =
58       TileOneDimension(in_dimensions, copy_from_data, multipliers, copy_to_data, dimension + 1);
59     copy_from_data += stride_size;
60     copy_to_data += tiled_stride_size;
61     total_stride_size += stride_size;
62     total_tiled_stride_size += tiled_stride_size;
63   }
64   CopyMultipleTimes(out_data, total_tiled_stride_size, multipliers[dimension] - 1,
65                     out_data + total_tiled_stride_size);
66   return std::make_pair(total_stride_size,
67                         static_cast<int>(total_tiled_stride_size * multipliers[dimension]));
68 }
69
70 } // namespace cker
71 } // namespace nnfw
72
73 #endif // __NNFW_CKER_TILE_H__