ONE - On-device Neural Engine
Loading...
Searching...
No Matches
ShapeInference.cpp
Go to the documentation of this file.
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#include "mir/Graph.h"
18#include "mir/ops/AddOp.h"
19#include "mir/ops/ReshapeOp.h"
20#include "mir/ops/ResizeOp.h"
21#include "mir/ops/SqueezeOp.h"
23#include "mir/Shape.h"
24
25#include <vector>
26
27#include "gtest/gtest.h"
28
29using namespace mir;
30
31TEST(ShapeInferenceTest, BidirectionalBroadcast)
32{
33 const Shape shape1{2, 1, 2};
34 const Shape shape2{3, 1};
35 const Shape reference{2, 3, 2};
36
37 const Shape result1 = broadcastShapes(shape1, shape2);
38 const Shape result2 = broadcastShapes(shape2, shape1);
39
40 ASSERT_EQ(result1, reference);
41 ASSERT_EQ(result2, reference);
42}
43
44TEST(ShapeInferenceTest, ReshapeAutoDimension)
45{
46 Graph g;
47
48 Shape input_shape{10, 2, 5};
49 Shape expected_shape{10, 1, 10};
50
51 mir::TensorType input_type{mir::DataType::FLOAT32, input_shape};
52 auto input = g.create<ops::InputOp>(input_type);
53 auto op = g.create<ops::ReshapeOp>(input->getOutput(0), Shape{10, 1, Shape::autoDim});
54
55 ASSERT_EQ(expected_shape, op->getOutputShape(0));
56}
57
58TEST(ShapeInferenceTest, ResizeWithShape)
59{
60 Graph g;
61
62 Shape result_shape{2, 10, 10, 3};
63
64 mir::TensorType input_type{mir::DataType::FLOAT32, Shape{1, 5, 5, 3}};
65 auto input = g.create<ops::InputOp>(input_type);
66
67 auto op = g.create<ops::ResizeOp>(input->getOutput(0),
68 ops::ResizeOp::ResizeMethod::nearestNeighbor, result_shape);
69
70 ASSERT_EQ(result_shape, op->getOutputShape(0));
71}
72
73TEST(ShapeInferenceTest, ResizeWithScale)
74{
75 Graph g;
76
77 Shape result_shape{1, 30, 10, 3};
78
79 mir::TensorType input_type{mir::DataType::FLOAT32, Shape{1, 5, 5, 3}};
80 auto input = g.create<ops::InputOp>(input_type);
81
82 auto op =
83 g.create<ops::ResizeOp>(input->getOutput(0), ops::ResizeOp::ResizeMethod::nearestNeighbor,
84 std::vector<float>{1, 6, 2, 1});
85
86 ASSERT_EQ(result_shape, op->getOutputShape(0));
87}
88
89TEST(ShapeInferenceTest, ReduceChangeRank)
90{
91 Graph g;
92
93 Shape resultShape{10, 10};
94
95 mir::TensorType input_type{mir::DataType::FLOAT32, Shape{10, 2, 10, 9}};
96 auto input = g.create<ops::InputOp>(input_type);
97
98 auto n = g.create<ops::ReduceMeanOp>(input->getOutput(0), std::vector<int32_t>{1, 3}, false);
99
100 ASSERT_EQ(resultShape, n->getOutputShape(0));
101}
102
103TEST(ShapeInferenceTest, ReshapeAutoDimensionShrink)
104{
105 Graph g;
106
107 Shape input_shape{10, 2, 10};
108 Shape result_shape_shrink{10, 20};
109
110 mir::TensorType input_type{mir::DataType::FLOAT32, input_shape};
111 auto input = g.create<ops::InputOp>(input_type);
112 auto op = g.create<ops::ReshapeOp>(input->getOutput(0), Shape{10, Shape::autoDim});
113
114 ASSERT_EQ(result_shape_shrink, op->getOutputShape(0));
115}
116
117TEST(ShapeInferenceTest, ReshapeAutoDimensionExpand)
118{
119 Graph g;
120
121 Shape input_shape{10, 2, 10};
122 Shape result_shape_expand{5, 10, 2, 2};
123
124 mir::TensorType input_type{mir::DataType::FLOAT32, input_shape};
125 auto input = g.create<ops::InputOp>(input_type);
126 auto op = g.create<ops::ReshapeOp>(input->getOutput(0), Shape{5, Shape::autoDim, 2, 2});
127
128 ASSERT_EQ(result_shape_expand, op->getOutputShape(0));
129}
130
131TEST(ShapeInferenceTest, ReshapeAutoDimensionUnsqueeze)
132{
133 Graph g;
134
135 Shape input_shape{10, 2, 10};
136 Shape result_shape_expand{1, 10, 2, 1, 10, 1};
137
138 mir::TensorType input_type{mir::DataType::FLOAT32, input_shape};
139 auto input = g.create<ops::InputOp>(input_type);
140 auto op = g.create<ops::ReshapeOp>(input->getOutput(0), Shape{1, Shape::autoDim, 2, 1, 10, 1});
141
142 ASSERT_EQ(result_shape_expand, op->getOutputShape(0));
143}
144
145TEST(ShapeInferenceTest, SqueezeTestAllDims)
146{
147 Graph g;
148
149 Shape input_shape{1, 2, 1, 4};
150 Shape expected_shape{2, 4};
151
152 mir::TensorType input_type{mir::DataType::FLOAT32, input_shape};
153 auto input = g.create<ops::InputOp>(input_type);
154 auto sq1 = g.create<ops::SqueezeOp>(input->getOutput(0), std::vector<int32_t>{});
155
156 ASSERT_EQ(sq1->getOutputShape(0), expected_shape);
157}
158
159TEST(ShapeInferenceTest, ElementwiseBC)
160{
161 Graph g;
162
163 Shape input_shape{1, 10, 10, 1};
164 Shape input2_shape{1, 1, 10, 10};
165
166 mir::TensorType input_type{mir::DataType::FLOAT32, input_shape};
167 mir::TensorType input2_type{mir::DataType::FLOAT32, input2_shape};
168
169 auto input = g.create<ops::InputOp>(input_type);
170 auto input2 = g.create<ops::InputOp>(input2_type);
171
172 auto add = g.create<ops::AddOp>(input->getOutput(0), input2->getOutput(0));
173
174 ASSERT_EQ(add->getOutputShape(0), Shape({1, 10, 10, 10}));
175}
176
177TEST(ShapeInferenceTest, SqueezeTestSpecificDims)
178{
179 Graph g;
180
181 Shape input_shape{1, 2, 1, 4};
182 Shape expected_shape{1, 2, 4};
183
184 mir::TensorType input_type{mir::DataType::FLOAT32, input_shape};
185 auto input = g.create<ops::InputOp>(input_type);
186 auto sq1 = g.create<ops::SqueezeOp>(input->getOutput(0), std::vector<int32_t>{2});
187
188 ASSERT_EQ(sq1->getOutputShape(0), expected_shape);
189}
190
191TEST(ShapeInferenceTest, SqueezeTestScalarResult)
192{
193 Graph g;
194
195 Shape input_shape{1, 1, 1, 1};
196 Shape expected_shape{1};
197
198 mir::TensorType input_type{mir::DataType::FLOAT32, input_shape};
199 auto input = g.create<ops::InputOp>(input_type);
200 auto sq1 = g.create<ops::SqueezeOp>(input->getOutput(0), std::vector<int32_t>{});
201
202 ASSERT_EQ(sq1->getOutputShape(0), expected_shape);
203}
Output * getOutput(std::size_t index)
Definition Operation.h:149
const Shape & getOutputShape(std::size_t index) const
Definition Operation.h:163
Resize operation scales are such that output = input * scale for each dimension and the number of dim...
Definition ResizeOp.h:35
TEST(ShapeInferenceTest, BidirectionalBroadcast)
Shape broadcastShapes(const Shape &lhs_shape, const Shape &rhs_shape)
Definition Shape.cpp:43
Definition Shape.h:28