2 * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "loader/GraphLoader.h"
18 #include "loader/KernelBuilder.h"
19 #include "luci_interpreter/SimpleMemoryManager.h"
21 #include <kernels/Add.h>
22 #include <kernels/ArgMax.h>
23 #include <kernels/AveragePool2D.h>
24 #include <kernels/Cast.h>
25 #include <kernels/Concatenation.h>
26 #include <kernels/Conv2D.h>
27 #include <kernels/DepthToSpace.h>
28 #include <kernels/DepthwiseConv2D.h>
29 #include <kernels/Div.h>
30 #include <kernels/Elu.h>
31 #include <kernels/Exp.h>
32 #include <kernels/Floor.h>
33 #include <kernels/FloorDiv.h>
34 #include <kernels/Equal.h>
35 #include <kernels/FullyConnected.h>
36 #include <kernels/Greater.h>
37 #include <kernels/GreaterEqual.h>
38 #include <kernels/InstanceNorm.h>
39 #include <kernels/L2Normalize.h>
40 #include <kernels/L2Pool2D.h>
41 #include <kernels/LeakyRelu.h>
42 #include <kernels/Less.h>
43 #include <kernels/LessEqual.h>
44 #include <kernels/LocalResponseNormalization.h>
45 #include <kernels/LogicalAnd.h>
46 #include <kernels/LogicalNot.h>
47 #include <kernels/LogicalOr.h>
48 #include <kernels/Logistic.h>
49 #include <kernels/LogSoftmax.h>
50 #include <kernels/Maximum.h>
51 #include <kernels/MaxPool2D.h>
52 #include <kernels/Mean.h>
53 #include <kernels/Minimum.h>
54 #include <kernels/Mul.h>
55 #include <kernels/Neg.h>
56 #include <kernels/NotEqual.h>
57 #include <kernels/Pad.h>
58 #include <kernels/PadV2.h>
59 #include <kernels/Pow.h>
60 #include <kernels/PRelu.h>
61 #include <kernels/Relu.h>
62 #include <kernels/Relu6.h>
63 #include <kernels/Reshape.h>
64 #include <kernels/ResizeBilinear.h>
65 #include <kernels/ResizeNearestNeighbor.h>
66 #include <kernels/ReverseV2.h>
67 #include <kernels/Rsqrt.h>
68 #include <kernels/Slice.h>
69 #include <kernels/Softmax.h>
70 #include <kernels/SpaceToDepth.h>
71 #include <kernels/Split.h>
72 #include <kernels/SplitV.h>
73 #include <kernels/Sqrt.h>
74 #include <kernels/SquaredDifference.h>
75 #include <kernels/Squeeze.h>
76 #include <kernels/StridedSlice.h>
77 #include <kernels/Sub.h>
78 #include <kernels/Tanh.h>
79 #include <kernels/Transpose.h>
80 #include <kernels/TransposeConv.h>
81 #include <kernels/Unpack.h>
83 #include <gmock/gmock.h>
85 namespace luci_interpreter
90 using namespace testing;
92 class KernelBuilderTest : public Test
95 luci::CircleInput *createInputNode() { return createNode<luci::CircleInput>(); }
96 void SetUp() override { _memory_manager = std::make_unique<SimpleMemoryManager>(); }
98 std::unique_ptr<IMemoryManager> _memory_manager;
100 template <typename NodeT, typename... Args> NodeT *createNode(Args &&... args)
102 auto *node = _graph.nodes()->create<NodeT>(std::forward<Args>(args)...);
103 // The actual type does not matter for the purpose of the tests.
104 // NOTE The type is meaningless for nodes with multiple outputs (corresponding *Out nodes carry
105 // actual output types).
106 node->dtype(loco::DataType::FLOAT32);
110 template <typename NodeOutT> NodeOutT *createNodeOut(loco::Node *node, int index)
112 auto *node_out = createNode<NodeOutT>();
113 node_out->input(node);
114 node_out->index(index);
118 template <typename KernelT> std::unique_ptr<KernelT> buildKernel(const luci::CircleNode *op)
120 std::unordered_map<const loco::Graph *, RuntimeGraph *> graph_to_runtime_graph;
122 RuntimeGraph runtime_graph(nullptr, _memory_manager.get());
123 graph_to_runtime_graph[&_graph] = &runtime_graph;
124 RuntimeToIR runtime_to_ir;
125 GraphLoader graph_loader(&_graph, &runtime_graph, runtime_to_ir, graph_to_runtime_graph,
126 _node_to_tensor, _memory_manager.get());
127 graph_loader.loadTensors();
129 KernelBuilder kernel_builder(graph_to_runtime_graph, _node_to_tensor);
131 auto kernel = kernel_builder.build(op);
132 return std::unique_ptr<KernelT>(dynamic_cast<KernelT *>(kernel.release()));
135 void checkTensor(const Tensor *tensor, const loco::Node *node)
137 EXPECT_THAT(tensor, Eq(_node_to_tensor.at(node)));
142 std::unordered_map<const loco::Node *, Tensor *> _node_to_tensor;
145 TEST_F(KernelBuilderTest, Add)
147 auto *input1 = createInputNode();
148 auto *input2 = createInputNode();
150 auto *op = createNode<luci::CircleAdd>();
154 op->fusedActivationFunction(luci::FusedActFunc::RELU);
156 auto kernel = buildKernel<kernels::Add>(op);
157 ASSERT_THAT(kernel, NotNull());
159 checkTensor(kernel->input1(), input1);
160 checkTensor(kernel->input2(), input2);
161 checkTensor(kernel->output(), op);
162 EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
165 TEST_F(KernelBuilderTest, ArgMax)
167 auto *input = createInputNode();
168 auto *axis = createInputNode();
170 auto *op = createNode<luci::CircleArgMax>();
174 op->output_type(loco::DataType::FLOAT32);
176 auto kernel = buildKernel<kernels::ArgMax>(op);
177 ASSERT_THAT(kernel, NotNull());
179 checkTensor(kernel->input(), input);
180 checkTensor(kernel->axis(), axis);
181 checkTensor(kernel->output(), op);
182 EXPECT_THAT(kernel->params().output_type, Eq(op->output_type()));
185 TEST_F(KernelBuilderTest, AveragePool2D)
187 auto *input = createInputNode();
189 auto *op = createNode<luci::CircleAveragePool2D>();
192 op->padding(luci::Padding::SAME);
197 op->fusedActivationFunction(luci::FusedActFunc::RELU);
199 auto kernel = buildKernel<kernels::AveragePool2D>(op);
200 ASSERT_THAT(kernel, NotNull());
202 checkTensor(kernel->input(), input);
203 checkTensor(kernel->output(), op);
204 EXPECT_THAT(kernel->params().padding, Eq(op->padding()));
205 EXPECT_THAT(kernel->params().filter_height, Eq(op->filter()->h()));
206 EXPECT_THAT(kernel->params().filter_width, Eq(op->filter()->w()));
207 EXPECT_THAT(kernel->params().stride_height, Eq(op->stride()->h()));
208 EXPECT_THAT(kernel->params().stride_width, Eq(op->stride()->w()));
209 EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
212 TEST_F(KernelBuilderTest, Cast)
214 auto *input = createInputNode();
216 auto *op = createNode<luci::CircleCast>();
219 auto kernel = buildKernel<kernels::Cast>(op);
220 ASSERT_THAT(kernel, NotNull());
222 checkTensor(kernel->input(), input);
223 checkTensor(kernel->output(), op);
226 TEST_F(KernelBuilderTest, Concatenation)
228 auto *input1 = createInputNode();
229 auto *input2 = createInputNode();
231 auto *op = createNode<luci::CircleConcatenation>(2);
232 op->values(0, input1);
233 op->values(1, input2);
236 auto kernel = buildKernel<kernels::Concatenation>(op);
237 ASSERT_THAT(kernel, NotNull());
239 checkTensor(kernel->input(0), input1);
240 checkTensor(kernel->input(1), input2);
241 checkTensor(kernel->output(), op);
242 EXPECT_THAT(kernel->params().axis, Eq(op->axis()));
243 EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
246 TEST_F(KernelBuilderTest, Conv2D)
248 auto *input = createInputNode();
249 auto *filter = createInputNode();
250 auto *bias = createInputNode();
252 auto *op = createNode<luci::CircleConv2D>();
257 op->padding(luci::Padding::SAME);
260 op->dilation()->h(17);
261 op->dilation()->w(19);
262 op->fusedActivationFunction(luci::FusedActFunc::RELU);
264 auto kernel = buildKernel<kernels::Conv2D>(op);
265 ASSERT_THAT(kernel, NotNull());
267 checkTensor(kernel->input(), input);
268 checkTensor(kernel->filter(), filter);
269 checkTensor(kernel->bias(), bias);
270 checkTensor(kernel->output(), op);
271 EXPECT_THAT(kernel->params().padding, Eq(op->padding()));
272 EXPECT_THAT(kernel->params().stride_height, Eq(op->stride()->h()));
273 EXPECT_THAT(kernel->params().stride_width, Eq(op->stride()->w()));
274 EXPECT_THAT(kernel->params().dilation_height_factor, Eq(op->dilation()->h()));
275 EXPECT_THAT(kernel->params().dilation_width_factor, Eq(op->dilation()->w()));
276 EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
279 TEST_F(KernelBuilderTest, DepthToSpace)
281 auto *input = createInputNode();
283 auto *op = createNode<luci::CircleDepthToSpace>();
288 auto kernel = buildKernel<kernels::DepthToSpace>(op);
289 ASSERT_THAT(kernel, NotNull());
291 checkTensor(kernel->input(), input);
292 checkTensor(kernel->output(), op);
293 EXPECT_THAT(kernel->params().block_size, Eq(op->block_size()));
296 TEST_F(KernelBuilderTest, DepthwiseConv2D)
298 auto *input = createInputNode();
299 auto *filter = createInputNode();
300 auto *bias = createInputNode();
302 auto *op = createNode<luci::CircleDepthwiseConv2D>();
307 op->padding(luci::Padding::SAME);
308 op->depthMultiplier(11);
311 op->dilation()->h(19);
312 op->dilation()->w(23);
313 op->fusedActivationFunction(luci::FusedActFunc::RELU);
315 auto kernel = buildKernel<kernels::DepthwiseConv2D>(op);
316 ASSERT_THAT(kernel, NotNull());
318 checkTensor(kernel->input(), input);
319 checkTensor(kernel->filter(), filter);
320 checkTensor(kernel->bias(), bias);
321 checkTensor(kernel->output(), op);
322 EXPECT_THAT(kernel->params().padding, Eq(op->padding()));
323 EXPECT_THAT(kernel->params().depth_multiplier, Eq(op->depthMultiplier()));
324 EXPECT_THAT(kernel->params().stride_height, Eq(op->stride()->h()));
325 EXPECT_THAT(kernel->params().stride_width, Eq(op->stride()->w()));
326 EXPECT_THAT(kernel->params().dilation_height_factor, Eq(op->dilation()->h()));
327 EXPECT_THAT(kernel->params().dilation_width_factor, Eq(op->dilation()->w()));
328 EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
331 TEST_F(KernelBuilderTest, Div)
333 auto *input1 = createInputNode();
334 auto *input2 = createInputNode();
336 auto *op = createNode<luci::CircleDiv>();
340 op->fusedActivationFunction(luci::FusedActFunc::RELU);
342 auto kernel = buildKernel<kernels::Div>(op);
343 ASSERT_THAT(kernel, NotNull());
345 checkTensor(kernel->input1(), input1);
346 checkTensor(kernel->input2(), input2);
347 checkTensor(kernel->output(), op);
348 EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
351 TEST_F(KernelBuilderTest, Elu)
353 auto *input = createInputNode();
355 auto *op = createNode<luci::CircleElu>();
358 auto kernel = buildKernel<kernels::Elu>(op);
359 ASSERT_THAT(kernel, NotNull());
361 checkTensor(kernel->input(), input);
362 checkTensor(kernel->output(), op);
365 TEST_F(KernelBuilderTest, Exp)
367 auto *input = createInputNode();
369 auto *op = createNode<luci::CircleExp>();
372 auto kernel = buildKernel<kernels::Exp>(op);
373 ASSERT_THAT(kernel, NotNull());
375 checkTensor(kernel->input(), input);
376 checkTensor(kernel->output(), op);
379 TEST_F(KernelBuilderTest, Floor)
381 auto *input = createInputNode();
383 auto *op = createNode<luci::CircleFloor>();
386 auto kernel = buildKernel<kernels::Floor>(op);
387 ASSERT_THAT(kernel, NotNull());
389 checkTensor(kernel->input(), input);
390 checkTensor(kernel->output(), op);
393 TEST_F(KernelBuilderTest, FloorDiv)
395 auto *x = createInputNode();
396 auto *y = createInputNode();
398 auto *op = createNode<luci::CircleFloorDiv>();
402 auto kernel = buildKernel<kernels::FloorDiv>(op);
403 ASSERT_THAT(kernel, NotNull());
405 checkTensor(kernel->x(), x);
406 checkTensor(kernel->y(), y);
407 checkTensor(kernel->output(), op);
410 TEST_F(KernelBuilderTest, Equal)
412 auto *x_input = createInputNode();
413 auto *y_input = createInputNode();
415 auto *op = createNode<luci::CircleEqual>();
419 auto kernel = buildKernel<kernels::Equal>(op);
420 ASSERT_THAT(kernel, NotNull());
422 checkTensor(kernel->x(), x_input);
423 checkTensor(kernel->y(), y_input);
424 checkTensor(kernel->output(), op);
427 TEST_F(KernelBuilderTest, FullyConnected)
429 auto *input = createInputNode();
430 auto *weights = createInputNode();
431 auto *bias = createInputNode();
433 auto *op = createNode<luci::CircleFullyConnected>();
435 op->weights(weights);
438 op->fusedActivationFunction(luci::FusedActFunc::RELU);
440 auto kernel = buildKernel<kernels::FullyConnected>(op);
441 ASSERT_THAT(kernel, NotNull());
443 checkTensor(kernel->input(), input);
444 checkTensor(kernel->weights(), weights);
445 checkTensor(kernel->bias(), bias);
446 checkTensor(kernel->output(), op);
447 EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
450 TEST_F(KernelBuilderTest, Greater)
452 auto *x_input = createInputNode();
453 auto *y_input = createInputNode();
455 auto *op = createNode<luci::CircleGreater>();
459 auto kernel = buildKernel<kernels::Greater>(op);
460 ASSERT_THAT(kernel, NotNull());
462 checkTensor(kernel->x(), x_input);
463 checkTensor(kernel->y(), y_input);
464 checkTensor(kernel->output(), op);
467 TEST_F(KernelBuilderTest, GreaterEqual)
469 auto *x_input = createInputNode();
470 auto *y_input = createInputNode();
472 auto *op = createNode<luci::CircleGreaterEqual>();
476 auto kernel = buildKernel<kernels::GreaterEqual>(op);
477 ASSERT_THAT(kernel, NotNull());
479 checkTensor(kernel->x(), x_input);
480 checkTensor(kernel->y(), y_input);
481 checkTensor(kernel->output(), op);
484 TEST_F(KernelBuilderTest, InstanceNorm)
486 auto *input = createInputNode();
487 auto *gamma = createInputNode();
488 auto *beta = createInputNode();
490 auto *op = createNode<luci::CircleInstanceNorm>();
496 op->fusedActivationFunction(luci::FusedActFunc::RELU);
498 auto kernel = buildKernel<kernels::InstanceNorm>(op);
499 ASSERT_THAT(kernel, NotNull());
501 checkTensor(kernel->input(), input);
502 checkTensor(kernel->gamma(), gamma);
503 checkTensor(kernel->beta(), beta);
504 checkTensor(kernel->output(), op);
505 EXPECT_THAT(kernel->params().epsilon, Eq(op->epsilon()));
506 EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
509 TEST_F(KernelBuilderTest, L2Normalize)
511 auto *input = createInputNode();
513 auto *op = createNode<luci::CircleL2Normalize>();
516 op->fusedActivationFunction(luci::FusedActFunc::RELU);
518 auto kernel = buildKernel<kernels::L2Normalize>(op);
519 ASSERT_THAT(kernel, NotNull());
521 checkTensor(kernel->input(), input);
522 checkTensor(kernel->output(), op);
523 EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
526 TEST_F(KernelBuilderTest, L2Pool2D)
528 auto *input = createInputNode();
530 auto *op = createNode<luci::CircleL2Pool2D>();
533 op->padding(luci::Padding::SAME);
538 op->fusedActivationFunction(luci::FusedActFunc::RELU);
540 auto kernel = buildKernel<kernels::L2Pool2D>(op);
541 ASSERT_THAT(kernel, NotNull());
543 checkTensor(kernel->input(), input);
544 checkTensor(kernel->output(), op);
545 EXPECT_THAT(kernel->params().padding, Eq(op->padding()));
546 EXPECT_THAT(kernel->params().filter_height, Eq(op->filter()->h()));
547 EXPECT_THAT(kernel->params().filter_width, Eq(op->filter()->w()));
548 EXPECT_THAT(kernel->params().stride_height, Eq(op->stride()->h()));
549 EXPECT_THAT(kernel->params().stride_width, Eq(op->stride()->w()));
550 EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
553 TEST_F(KernelBuilderTest, LeakyRelu)
555 auto *input = createInputNode();
557 auto *op = createNode<luci::CircleLeakyRelu>();
562 auto kernel = buildKernel<kernels::LeakyRelu>(op);
563 ASSERT_THAT(kernel, NotNull());
565 checkTensor(kernel->input(), input);
566 checkTensor(kernel->output(), op);
567 EXPECT_THAT(kernel->params().alpha, Eq(op->alpha()));
570 TEST_F(KernelBuilderTest, Less)
572 auto *x_input = createInputNode();
573 auto *y_input = createInputNode();
575 auto *op = createNode<luci::CircleLess>();
579 auto kernel = buildKernel<kernels::Less>(op);
580 ASSERT_THAT(kernel, NotNull());
582 checkTensor(kernel->x(), x_input);
583 checkTensor(kernel->y(), y_input);
584 checkTensor(kernel->output(), op);
587 TEST_F(KernelBuilderTest, LessEqual)
589 auto *x_input = createInputNode();
590 auto *y_input = createInputNode();
592 auto *op = createNode<luci::CircleLessEqual>();
596 auto kernel = buildKernel<kernels::LessEqual>(op);
597 ASSERT_THAT(kernel, NotNull());
599 checkTensor(kernel->x(), x_input);
600 checkTensor(kernel->y(), y_input);
601 checkTensor(kernel->output(), op);
604 TEST_F(KernelBuilderTest, LocalResponseNormalization)
606 auto *input = createInputNode();
608 auto *op = createNode<luci::CircleLocalResponseNormalization>();
616 auto kernel = buildKernel<kernels::LocalResponseNormalization>(op);
617 ASSERT_THAT(kernel, NotNull());
619 checkTensor(kernel->input(), input);
620 checkTensor(kernel->output(), op);
621 EXPECT_THAT(kernel->params().radius, Eq(op->radius()));
622 EXPECT_THAT(kernel->params().bias, Eq(op->bias()));
623 EXPECT_THAT(kernel->params().alpha, Eq(op->alpha()));
624 EXPECT_THAT(kernel->params().beta, Eq(op->beta()));
627 TEST_F(KernelBuilderTest, LogicalAnd)
629 auto *input1 = createInputNode();
630 auto *input2 = createInputNode();
632 auto *op = createNode<luci::CircleLogicalAnd>();
636 auto kernel = buildKernel<kernels::LogicalAnd>(op);
637 ASSERT_THAT(kernel, NotNull());
639 checkTensor(kernel->input1(), input1);
640 checkTensor(kernel->input2(), input2);
641 checkTensor(kernel->output(), op);
644 TEST_F(KernelBuilderTest, LogicalNot)
646 auto *input = createInputNode();
648 auto *op = createNode<luci::CircleLogicalNot>();
651 auto kernel = buildKernel<kernels::LogicalNot>(op);
652 ASSERT_THAT(kernel, NotNull());
654 checkTensor(kernel->input(), input);
655 checkTensor(kernel->output(), op);
658 TEST_F(KernelBuilderTest, LogicalOr)
660 auto *input1 = createInputNode();
661 auto *input2 = createInputNode();
663 auto *op = createNode<luci::CircleLogicalOr>();
667 auto kernel = buildKernel<kernels::LogicalOr>(op);
668 ASSERT_THAT(kernel, NotNull());
670 checkTensor(kernel->input1(), input1);
671 checkTensor(kernel->input2(), input2);
672 checkTensor(kernel->output(), op);
675 TEST_F(KernelBuilderTest, Logistic)
677 auto *input = createInputNode();
679 auto *op = createNode<luci::CircleLogistic>();
682 auto kernel = buildKernel<kernels::Logistic>(op);
683 ASSERT_THAT(kernel, NotNull());
685 checkTensor(kernel->input(), input);
686 checkTensor(kernel->output(), op);
689 TEST_F(KernelBuilderTest, LogSoftmax)
691 auto *input = createInputNode();
693 auto *op = createNode<luci::CircleLogSoftmax>();
696 auto kernel = buildKernel<kernels::LogSoftmax>(op);
697 ASSERT_THAT(kernel, NotNull());
699 checkTensor(kernel->input(), input);
700 checkTensor(kernel->output(), op);
703 TEST_F(KernelBuilderTest, Maximum)
705 auto *input1 = createInputNode();
706 auto *input2 = createInputNode();
708 auto *op = createNode<luci::CircleMaximum>();
712 auto kernel = buildKernel<kernels::Maximum>(op);
713 ASSERT_THAT(kernel, NotNull());
715 checkTensor(kernel->input1(), input1);
716 checkTensor(kernel->input2(), input2);
717 checkTensor(kernel->output(), op);
720 TEST_F(KernelBuilderTest, MaxPool2D)
722 auto *input = createInputNode();
724 auto *op = createNode<luci::CircleMaxPool2D>();
727 op->padding(luci::Padding::SAME);
732 op->fusedActivationFunction(luci::FusedActFunc::RELU);
734 auto kernel = buildKernel<kernels::MaxPool2D>(op);
735 ASSERT_THAT(kernel, NotNull());
737 checkTensor(kernel->input(), input);
738 checkTensor(kernel->output(), op);
739 EXPECT_THAT(kernel->params().padding, Eq(op->padding()));
740 EXPECT_THAT(kernel->params().filter_height, Eq(op->filter()->h()));
741 EXPECT_THAT(kernel->params().filter_width, Eq(op->filter()->w()));
742 EXPECT_THAT(kernel->params().stride_height, Eq(op->stride()->h()));
743 EXPECT_THAT(kernel->params().stride_width, Eq(op->stride()->w()));
744 EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
747 TEST_F(KernelBuilderTest, Mean)
749 auto *input = createInputNode();
750 auto *axes = createInputNode();
752 auto *op = createNode<luci::CircleMean>();
754 op->reduction_indices(axes);
758 auto kernel = buildKernel<kernels::Mean>(op);
759 ASSERT_THAT(kernel, NotNull());
761 checkTensor(kernel->input(), input);
762 checkTensor(kernel->axes(), axes);
763 checkTensor(kernel->output(), op);
764 EXPECT_THAT(kernel->params().keep_dims, Eq(op->keep_dims()));
767 TEST_F(KernelBuilderTest, Minimum)
769 auto *input1 = createInputNode();
770 auto *input2 = createInputNode();
772 auto *op = createNode<luci::CircleMinimum>();
776 auto kernel = buildKernel<kernels::Minimum>(op);
777 ASSERT_THAT(kernel, NotNull());
779 checkTensor(kernel->input1(), input1);
780 checkTensor(kernel->input2(), input2);
781 checkTensor(kernel->output(), op);
784 TEST_F(KernelBuilderTest, Mul)
786 auto *input1 = createInputNode();
787 auto *input2 = createInputNode();
789 auto *op = createNode<luci::CircleMul>();
793 op->fusedActivationFunction(luci::FusedActFunc::RELU);
795 auto kernel = buildKernel<kernels::Mul>(op);
796 ASSERT_THAT(kernel, NotNull());
798 checkTensor(kernel->input1(), input1);
799 checkTensor(kernel->input2(), input2);
800 checkTensor(kernel->output(), op);
801 EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
804 TEST_F(KernelBuilderTest, Neg)
806 auto *input = createInputNode();
808 auto *op = createNode<luci::CircleNeg>();
811 auto kernel = buildKernel<kernels::Neg>(op);
812 ASSERT_THAT(kernel, NotNull());
814 checkTensor(kernel->input(), input);
815 checkTensor(kernel->output(), op);
818 TEST_F(KernelBuilderTest, NotEqual)
820 auto *x_input = createInputNode();
821 auto *y_input = createInputNode();
823 auto *op = createNode<luci::CircleNotEqual>();
827 auto kernel = buildKernel<kernels::NotEqual>(op);
828 ASSERT_THAT(kernel, NotNull());
830 checkTensor(kernel->x(), x_input);
831 checkTensor(kernel->y(), y_input);
832 checkTensor(kernel->output(), op);
835 TEST_F(KernelBuilderTest, Pad)
837 auto *input = createInputNode();
838 auto *paddings = createInputNode();
840 auto *op = createNode<luci::CirclePad>();
842 op->paddings(paddings);
844 auto kernel = buildKernel<kernels::Pad>(op);
845 ASSERT_THAT(kernel, NotNull());
847 checkTensor(kernel->input(), input);
848 checkTensor(kernel->paddings(), paddings);
849 checkTensor(kernel->output(), op);
852 TEST_F(KernelBuilderTest, PadV2)
854 auto *input = createInputNode();
855 auto *paddings = createInputNode();
856 auto *constant_values = createInputNode();
858 auto *op = createNode<luci::CirclePadV2>();
860 op->paddings(paddings);
861 op->constant_values(constant_values);
863 auto kernel = buildKernel<kernels::PadV2>(op);
864 ASSERT_THAT(kernel, NotNull());
866 checkTensor(kernel->input(), input);
867 checkTensor(kernel->paddings(), paddings);
868 checkTensor(kernel->constant_values(), constant_values);
869 checkTensor(kernel->output(), op);
872 TEST_F(KernelBuilderTest, Pow)
874 auto *input1 = createInputNode();
875 auto *input2 = createInputNode();
877 auto *op = createNode<luci::CirclePow>();
881 auto kernel = buildKernel<kernels::Pow>(op);
882 ASSERT_THAT(kernel, NotNull());
884 checkTensor(kernel->input1(), input1);
885 checkTensor(kernel->input2(), input2);
886 checkTensor(kernel->output(), op);
889 TEST_F(KernelBuilderTest, PRelu)
891 auto *input = createInputNode();
892 auto *alpha = createInputNode();
894 auto *op = createNode<luci::CirclePRelu>();
898 auto kernel = buildKernel<kernels::PRelu>(op);
899 ASSERT_THAT(kernel, NotNull());
901 checkTensor(kernel->input(), input);
902 checkTensor(kernel->alpha(), alpha);
903 checkTensor(kernel->output(), op);
906 TEST_F(KernelBuilderTest, Relu)
908 auto *input = createInputNode();
910 auto *op = createNode<luci::CircleRelu>();
913 auto kernel = buildKernel<kernels::Relu>(op);
914 ASSERT_THAT(kernel, NotNull());
916 checkTensor(kernel->input(), input);
917 checkTensor(kernel->output(), op);
920 TEST_F(KernelBuilderTest, Relu6)
922 auto *input = createInputNode();
924 auto *op = createNode<luci::CircleRelu6>();
927 auto kernel = buildKernel<kernels::Relu6>(op);
928 ASSERT_THAT(kernel, NotNull());
930 checkTensor(kernel->input(), input);
931 checkTensor(kernel->output(), op);
934 TEST_F(KernelBuilderTest, Reshape)
936 auto *input = createInputNode();
937 auto *shape = createInputNode();
939 auto *op = createNode<luci::CircleReshape>();
943 auto kernel = buildKernel<kernels::Reshape>(op);
944 ASSERT_THAT(kernel, NotNull());
946 checkTensor(kernel->input(), input);
947 checkTensor(kernel->shape(), shape);
948 checkTensor(kernel->output(), op);
951 TEST_F(KernelBuilderTest, ResizeBilinear)
953 auto *input = createInputNode();
954 auto *size = createInputNode();
956 auto *op = createNode<luci::CircleResizeBilinear>();
959 op->align_corners(true);
960 op->half_pixel_centers(true);
962 auto kernel = buildKernel<kernels::ResizeBilinear>(op);
963 ASSERT_THAT(kernel, NotNull());
965 checkTensor(kernel->input(), input);
966 checkTensor(kernel->size(), size);
967 checkTensor(kernel->output(), op);
968 EXPECT_THAT(kernel->params().align_corners, Eq(op->align_corners()));
969 EXPECT_THAT(kernel->params().half_pixel_centers, Eq(op->half_pixel_centers()));
972 TEST_F(KernelBuilderTest, ResizeNearestNeighbor)
974 auto *input = createInputNode();
975 auto *size = createInputNode();
977 auto *op = createNode<luci::CircleResizeNearestNeighbor>();
980 op->align_corners(true);
982 auto kernel = buildKernel<kernels::ResizeNearestNeighbor>(op);
983 ASSERT_THAT(kernel, NotNull());
985 checkTensor(kernel->input(), input);
986 checkTensor(kernel->size(), size);
987 checkTensor(kernel->output(), op);
988 EXPECT_THAT(kernel->params().align_corners, Eq(op->align_corners()));
989 // TODO currently half_pixel_centers are not implemented on CircleResizeNearestNeighbor
990 // after adding, need to be updated.
993 TEST_F(KernelBuilderTest, ReverseV2)
995 auto *input = createInputNode();
996 auto *axes = createInputNode();
998 auto *op = createNode<luci::CircleReverseV2>();
1002 auto kernel = buildKernel<kernels::ReverseV2>(op);
1003 ASSERT_THAT(kernel, NotNull());
1005 checkTensor(kernel->input(), input);
1006 checkTensor(kernel->axes(), axes);
1007 checkTensor(kernel->output(), op);
1010 TEST_F(KernelBuilderTest, Rsqrt)
1012 auto *input = createInputNode();
1014 auto *op = createNode<luci::CircleRsqrt>();
1017 auto kernel = buildKernel<kernels::Rsqrt>(op);
1018 ASSERT_THAT(kernel, NotNull());
1020 checkTensor(kernel->input(), input);
1021 checkTensor(kernel->output(), op);
1024 TEST_F(KernelBuilderTest, Slice)
1026 auto *input = createInputNode();
1027 auto *begin = createInputNode();
1028 auto *size = createInputNode();
1030 auto *op = createNode<luci::CircleSlice>();
1035 auto kernel = buildKernel<kernels::Slice>(op);
1036 ASSERT_THAT(kernel, NotNull());
1038 checkTensor(kernel->input(), input);
1039 checkTensor(kernel->begin(), begin);
1040 checkTensor(kernel->size(), size);
1041 checkTensor(kernel->output(), op);
1044 TEST_F(KernelBuilderTest, Softmax)
1046 auto *input = createInputNode();
1048 auto *op = createNode<luci::CircleSoftmax>();
1053 auto kernel = buildKernel<kernels::Softmax>(op);
1054 ASSERT_THAT(kernel, NotNull());
1056 checkTensor(kernel->input(), input);
1057 checkTensor(kernel->output(), op);
1058 EXPECT_THAT(kernel->params().beta, Eq(op->beta()));
1061 TEST_F(KernelBuilderTest, SpaceToDepth)
1063 auto *input = createInputNode();
1065 auto *op = createNode<luci::CircleSpaceToDepth>();
1070 auto kernel = buildKernel<kernels::SpaceToDepth>(op);
1071 ASSERT_THAT(kernel, NotNull());
1073 checkTensor(kernel->input(), input);
1074 checkTensor(kernel->output(), op);
1075 EXPECT_THAT(kernel->params().block_size, op->block_size());
1078 TEST_F(KernelBuilderTest, Split)
1080 auto *axis = createInputNode();
1081 auto *input = createInputNode();
1082 auto *op = createNode<luci::CircleSplit>();
1083 auto *output1 = createNodeOut<luci::CircleSplitOut>(op, 0);
1084 auto *output2 = createNodeOut<luci::CircleSplitOut>(op, 1);
1086 op->split_dim(axis);
1091 auto kernel = buildKernel<kernels::Split>(op);
1092 ASSERT_THAT(kernel, NotNull());
1094 checkTensor(kernel->axis(), axis);
1095 checkTensor(kernel->input(), input);
1096 checkTensor(kernel->output(0), output1);
1097 checkTensor(kernel->output(1), output2);
1100 TEST_F(KernelBuilderTest, SplitV)
1102 auto *input = createInputNode();
1103 auto *size_splits = createInputNode();
1104 auto *axis = createInputNode();
1105 auto *op = createNode<luci::CircleSplitV>();
1106 auto *output0 = createNodeOut<luci::CircleSplitVOut>(op, 0);
1107 auto *output1 = createNodeOut<luci::CircleSplitVOut>(op, 1);
1110 op->size_splits(size_splits);
1111 op->split_dim(axis);
1115 auto kernel = buildKernel<kernels::SplitV>(op);
1116 ASSERT_THAT(kernel, NotNull());
1118 checkTensor(kernel->input(), input);
1119 checkTensor(kernel->size_splits(), size_splits);
1120 checkTensor(kernel->axis(), axis);
1121 checkTensor(kernel->output(0), output0);
1122 checkTensor(kernel->output(1), output1);
1125 TEST_F(KernelBuilderTest, Sqrt)
1127 auto *input = createInputNode();
1129 auto *op = createNode<luci::CircleSqrt>();
1132 auto kernel = buildKernel<kernels::Sqrt>(op);
1133 ASSERT_THAT(kernel, NotNull());
1135 checkTensor(kernel->input(), input);
1136 checkTensor(kernel->output(), op);
1139 TEST_F(KernelBuilderTest, SquaredDifference)
1141 auto *input1 = createInputNode();
1142 auto *input2 = createInputNode();
1144 auto *op = createNode<luci::CircleSquaredDifference>();
1148 auto kernel = buildKernel<kernels::SquaredDifference>(op);
1149 ASSERT_THAT(kernel, NotNull());
1151 checkTensor(kernel->input1(), input1);
1152 checkTensor(kernel->input2(), input2);
1153 checkTensor(kernel->output(), op);
1156 TEST_F(KernelBuilderTest, Squeeze)
1158 auto *input = createInputNode();
1160 auto *op = createNode<luci::CircleSqueeze>();
1163 op->squeeze_dims({11, 13});
1165 auto kernel = buildKernel<kernels::Squeeze>(op);
1166 ASSERT_THAT(kernel, NotNull());
1168 checkTensor(kernel->input(), input);
1169 checkTensor(kernel->output(), op);
1170 EXPECT_THAT(kernel->params().squeeze_dims, ElementsAreArray(op->squeeze_dims()));
1173 TEST_F(KernelBuilderTest, StridedSlice)
1175 auto *input = createInputNode();
1176 auto *begin = createInputNode();
1177 auto *end = createInputNode();
1178 auto *strides = createInputNode();
1180 auto *op = createNode<luci::CircleStridedSlice>();
1184 op->strides(strides);
1187 op->ellipsis_mask(13);
1189 op->new_axis_mask(19);
1190 op->shrink_axis_mask(23);
1192 auto kernel = buildKernel<kernels::StridedSlice>(op);
1193 ASSERT_THAT(kernel, NotNull());
1195 checkTensor(kernel->input(), input);
1196 checkTensor(kernel->begin(), begin);
1197 checkTensor(kernel->end(), end);
1198 checkTensor(kernel->strides(), strides);
1199 checkTensor(kernel->output(), op);
1200 EXPECT_THAT(kernel->params().begin_mask, Eq(op->begin_mask()));
1201 EXPECT_THAT(kernel->params().ellipsis_mask, Eq(op->ellipsis_mask()));
1202 EXPECT_THAT(kernel->params().end_mask, Eq(op->end_mask()));
1203 EXPECT_THAT(kernel->params().new_axis_mask, Eq(op->new_axis_mask()));
1204 EXPECT_THAT(kernel->params().shrink_axis_mask, Eq(op->shrink_axis_mask()));
1207 TEST_F(KernelBuilderTest, Sub)
1209 auto *input1 = createInputNode();
1210 auto *input2 = createInputNode();
1212 auto *op = createNode<luci::CircleSub>();
1216 op->fusedActivationFunction(luci::FusedActFunc::RELU);
1218 auto kernel = buildKernel<kernels::Sub>(op);
1219 ASSERT_THAT(kernel, NotNull());
1221 checkTensor(kernel->input1(), input1);
1222 checkTensor(kernel->input2(), input2);
1223 checkTensor(kernel->output(), op);
1224 EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
1227 TEST_F(KernelBuilderTest, Tanh)
1229 auto *input = createInputNode();
1231 auto *op = createNode<luci::CircleTanh>();
1234 auto kernel = buildKernel<kernels::Tanh>(op);
1235 ASSERT_THAT(kernel, NotNull());
1237 checkTensor(kernel->input(), input);
1238 checkTensor(kernel->output(), op);
1241 TEST_F(KernelBuilderTest, Transpose)
1243 auto *input = createInputNode();
1244 auto *perm = createInputNode();
1246 auto *op = createNode<luci::CircleTranspose>();
1250 auto kernel = buildKernel<kernels::Transpose>(op);
1251 ASSERT_THAT(kernel, NotNull());
1253 checkTensor(kernel->input(), input);
1254 checkTensor(kernel->perm(), perm);
1255 checkTensor(kernel->output(), op);
1258 TEST_F(KernelBuilderTest, TransposeConv)
1260 auto *output_shape = createInputNode();
1261 auto *filter = createInputNode();
1262 auto *input = createInputNode();
1263 auto *bias = createInputNode();
1265 auto *op = createNode<luci::CircleTransposeConv>();
1266 op->inputSizes(output_shape);
1268 op->outBackprop(input);
1271 op->padding(luci::Padding::SAME);
1272 op->stride()->h(11);
1273 op->stride()->w(13);
1275 auto kernel = buildKernel<kernels::TransposeConv>(op);
1276 ASSERT_THAT(kernel, NotNull());
1278 checkTensor(kernel->output_shape(), output_shape);
1279 checkTensor(kernel->filter(), filter);
1280 checkTensor(kernel->input(), input);
1281 checkTensor(kernel->output(), op);
1282 checkTensor(kernel->bias(), bias);
1283 EXPECT_THAT(kernel->params().padding, Eq(op->padding()));
1284 EXPECT_THAT(kernel->params().stride_height, Eq(op->stride()->h()));
1285 EXPECT_THAT(kernel->params().stride_width, Eq(op->stride()->w()));
1288 TEST_F(KernelBuilderTest, Unpack)
1290 auto *input = createInputNode();
1291 auto *op = createNode<luci::CircleUnpack>();
1292 auto *output1 = createNodeOut<luci::CircleUnpackOut>(op, 0);
1293 auto *output2 = createNodeOut<luci::CircleUnpackOut>(op, 1);
1300 auto kernel = buildKernel<kernels::Unpack>(op);
1301 ASSERT_THAT(kernel, NotNull());
1303 checkTensor(kernel->input(), input);
1304 checkTensor(kernel->output(0), output1);
1305 checkTensor(kernel->output(1), output2);
1306 EXPECT_THAT(kernel->params().axis, Eq(op->axis()));
1309 TEST_F(KernelBuilderTest, NonExisting1_NEG)
1311 auto *op = createNode<luci::CircleConst>();
1312 ASSERT_ANY_THROW(buildKernel<Kernel>(op));
1315 TEST_F(KernelBuilderTest, NonExisting2_NEG)
1317 auto *op = createNode<luci::CircleInput>();
1318 ASSERT_ANY_THROW(buildKernel<Kernel>(op));
1321 TEST_F(KernelBuilderTest, NonExisting3_NEG)
1323 auto *op = createNode<luci::CircleOutput>();
1324 ASSERT_ANY_THROW(buildKernel<Kernel>(op));
1328 } // namespace luci_interpreter