ONE - On-device Neural Engine
Loading...
Searching...
No Matches
Unpack.cpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 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#include "Builders.h"
18#include "kernels/Utils.h"
19
20namespace luci_interpreter
21{
22namespace
23{
24
25constexpr int kInputTensor = 0;
26
27template <typename T>
28void UnpackImpl(const circle::Operator *cur_op, const circle::Tensor *input, int output_count,
29 int axis, RuntimeGraph *runtime_graph)
30{
31 const auto output0_index = cur_op->outputs()->operator[](0);
32 assert(output0_index != -1);
33
34 const auto output0 = runtime_graph->getCircleTensorByIndex(output0_index);
35 assert(output0 != nullptr);
36
37 const auto input_dims = Tensor::tensor_shape(input);
38 const auto output_dims = Tensor::tensor_shape(output0);
39 const int dimensions = input_dims.size();
40
41 if (axis < 0)
42 {
43 axis += input_dims.size();
44 }
45
46 int outer_size = 1;
47 for (int i = 0; i < axis; ++i)
48 {
49 outer_size *= input_dims[i];
50 }
51 int copy_size = 1;
52 for (int i = axis + 1; i < dimensions; ++i)
53 {
54 copy_size *= input_dims[i];
55 }
56 int output_size = 1;
57 for (int i = 0; i < output_dims.size(); ++i)
58 {
59 output_size *= output_dims[i];
60 }
61
62 const T *input_data = kernels::getTensorData<T>(runtime_graph->getDataByTensor(input));
63
64 for (int i = 0; i < output_count; ++i)
65 {
66 const auto output_index = cur_op->outputs()->operator[](i);
67 assert(output_index != -1);
68
69 const auto t = runtime_graph->getCircleTensorByIndex(output_index);
70 assert(output0 != nullptr);
71 T *output_data = kernels::getTensorData<T>(runtime_graph->getDataByTensor(t));
72 for (int k = 0; k < outer_size; ++k)
73 {
74 T *output_ptr = output_data + copy_size * k;
75 int loc = k * output_count * copy_size + i * copy_size;
76 const T *input_ptr = input_data + loc;
77 for (int j = 0; j < copy_size; ++j)
78 output_ptr[j] = input_ptr[j];
79 }
80 }
81}
82} // namespace
83
84void configure_kernel_CircleUnpack(const circle::Operator *cur_op, BaseRuntimeGraph *runtime_graph)
85{
86 const auto input_index = cur_op->inputs()->operator[](0);
87 const auto output_index = cur_op->outputs()->operator[](0);
88
89 assert(input_index != -1);
90 assert(output_index != -1);
91
92 const auto input = runtime_graph->getCircleTensorByIndex(input_index);
93 const auto output = runtime_graph->getCircleTensorByIndex(output_index);
94
95 assert(input != nullptr);
96 assert(output != nullptr);
97
98 const auto *options = cur_op->builtin_options_as_UnpackOptions();
99
100 LUCI_INTERPRETER_CHECK(cur_op->outputs()->size() == options->num());
101 LUCI_INTERPRETER_CHECK(Tensor::element_type(input) == Tensor::element_type(output));
102
103 for (int i = 0; i < Tensor::num_dims(input); ++i)
104 {
105 if (i == options->axis())
106 continue;
107
108 if (i < options->axis())
109 {
110 LUCI_INTERPRETER_CHECK(Tensor::dim(input, i) == Tensor::dim(output, i));
111 }
112 else
113 {
114 LUCI_INTERPRETER_CHECK(Tensor::dim(input, i) == Tensor::dim(output, i - 1));
115 }
116 }
117}
118
119void execute_kernel_CircleUnpack(const circle::Operator *cur_op, BaseRuntimeGraph *runtime_graph)
120{
121 const auto input_index = cur_op->inputs()->operator[](0);
122 assert(input_index != -1);
123
124 const auto input = runtime_graph->getCircleTensorByIndex(input_index);
125 assert(input != nullptr);
126
127 const auto type = Tensor::element_type(input);
128
129 const auto *options = cur_op->builtin_options_as_UnpackOptions();
130
131 switch (type)
132 {
133#ifndef DIS_FLOAT
134 case DataType::FLOAT32:
135 {
136 UnpackImpl<float>(cur_op, input, options->num(), options->axis(), runtime_graph);
137 break;
138 }
139#endif // DIS_FLOAT
140 default:
141 assert(false && "Unsupported type");
142 }
143}
144} // namespace luci_interpreter
const circle::Tensor * getCircleTensorByIndex(int32_t index)
#define LUCI_INTERPRETER_CHECK(cond)
Definition Utils.h:36
list input_data
Definition infer.py:29
void execute_kernel_CircleUnpack(const circle::Operator *cur_op, BaseRuntimeGraph *runtime_graph)
Definition Unpack.cpp:119
void configure_kernel_CircleUnpack(const circle::Operator *cur_op, BaseRuntimeGraph *runtime_graph)
Definition Unpack.cpp:84
const loco::Dimension & dim(uint32_t axis) const
Definition Tensor.h:44