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/BatchMatMul.h>
25 #include <kernels/Cast.h>
26 #include <kernels/Concatenation.h>
27 #include <kernels/Conv2D.h>
28 #include <kernels/DepthToSpace.h>
29 #include <kernels/DepthwiseConv2D.h>
30 #include <kernels/Div.h>
31 #include <kernels/Elu.h>
32 #include <kernels/Exp.h>
33 #include <kernels/Floor.h>
34 #include <kernels/FloorDiv.h>
35 #include <kernels/Equal.h>
36 #include <kernels/FullyConnected.h>
37 #include <kernels/Greater.h>
38 #include <kernels/GreaterEqual.h>
39 #include <kernels/InstanceNorm.h>
40 #include <kernels/L2Normalize.h>
41 #include <kernels/L2Pool2D.h>
42 #include <kernels/LeakyRelu.h>
43 #include <kernels/Less.h>
44 #include <kernels/LessEqual.h>
45 #include <kernels/LocalResponseNormalization.h>
46 #include <kernels/LogicalAnd.h>
47 #include <kernels/LogicalNot.h>
48 #include <kernels/LogicalOr.h>
49 #include <kernels/Logistic.h>
50 #include <kernels/LogSoftmax.h>
51 #include <kernels/Maximum.h>
52 #include <kernels/MaxPool2D.h>
53 #include <kernels/Mean.h>
54 #include <kernels/Minimum.h>
55 #include <kernels/Mul.h>
56 #include <kernels/Neg.h>
57 #include <kernels/NotEqual.h>
58 #include <kernels/OneHot.h>
59 #include <kernels/Pad.h>
60 #include <kernels/PadV2.h>
61 #include <kernels/Pow.h>
62 #include <kernels/PRelu.h>
63 #include <kernels/Relu.h>
64 #include <kernels/Relu6.h>
65 #include <kernels/Reshape.h>
66 #include <kernels/ResizeBilinear.h>
67 #include <kernels/ResizeNearestNeighbor.h>
68 #include <kernels/ReverseV2.h>
69 #include <kernels/Rsqrt.h>
70 #include <kernels/Slice.h>
71 #include <kernels/Softmax.h>
72 #include <kernels/SpaceToDepth.h>
73 #include <kernels/Split.h>
74 #include <kernels/SplitV.h>
75 #include <kernels/Sqrt.h>
76 #include <kernels/SquaredDifference.h>
77 #include <kernels/Squeeze.h>
78 #include <kernels/StridedSlice.h>
79 #include <kernels/Sub.h>
80 #include <kernels/Tanh.h>
81 #include <kernels/Transpose.h>
82 #include <kernels/TransposeConv.h>
83 #include <kernels/Unpack.h>
85 #include <gmock/gmock.h>
87 namespace luci_interpreter
92 using namespace testing;
94 class KernelBuilderTest : public Test
97 luci::CircleInput *createInputNode() { return createNode<luci::CircleInput>(); }
98 void SetUp() override { _memory_manager = std::make_unique<SimpleMemoryManager>(); }
100 std::unique_ptr<IMemoryManager> _memory_manager;
102 template <typename NodeT, typename... Args> NodeT *createNode(Args &&... args)
104 auto *node = _graph.nodes()->create<NodeT>(std::forward<Args>(args)...);
105 // The actual type does not matter for the purpose of the tests.
106 // NOTE The type is meaningless for nodes with multiple outputs (corresponding *Out nodes carry
107 // actual output types).
108 node->dtype(loco::DataType::FLOAT32);
112 template <typename NodeOutT> NodeOutT *createNodeOut(loco::Node *node, int index)
114 auto *node_out = createNode<NodeOutT>();
115 node_out->input(node);
116 node_out->index(index);
120 template <typename KernelT> std::unique_ptr<KernelT> buildKernel(const luci::CircleNode *op)
122 std::unordered_map<const loco::Graph *, RuntimeGraph *> graph_to_runtime_graph;
124 RuntimeGraph runtime_graph(nullptr, _memory_manager.get());
125 graph_to_runtime_graph[&_graph] = &runtime_graph;
126 RuntimeToIR runtime_to_ir;
127 GraphLoader graph_loader(&_graph, &runtime_graph, runtime_to_ir, graph_to_runtime_graph,
128 _node_to_tensor, _memory_manager.get());
129 graph_loader.loadTensors();
131 KernelBuilder kernel_builder(graph_to_runtime_graph, _node_to_tensor);
133 auto kernel = kernel_builder.build(op);
134 return std::unique_ptr<KernelT>(dynamic_cast<KernelT *>(kernel.release()));
137 void checkTensor(const Tensor *tensor, const loco::Node *node)
139 EXPECT_THAT(tensor, Eq(_node_to_tensor.at(node)));
144 std::unordered_map<const loco::Node *, Tensor *> _node_to_tensor;
147 TEST_F(KernelBuilderTest, Add)
149 auto *input1 = createInputNode();
150 auto *input2 = createInputNode();
152 auto *op = createNode<luci::CircleAdd>();
156 op->fusedActivationFunction(luci::FusedActFunc::RELU);
158 auto kernel = buildKernel<kernels::Add>(op);
159 ASSERT_THAT(kernel, NotNull());
161 checkTensor(kernel->input1(), input1);
162 checkTensor(kernel->input2(), input2);
163 checkTensor(kernel->output(), op);
164 EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
167 TEST_F(KernelBuilderTest, ArgMax)
169 auto *input = createInputNode();
170 auto *axis = createInputNode();
172 auto *op = createNode<luci::CircleArgMax>();
176 op->output_type(loco::DataType::FLOAT32);
178 auto kernel = buildKernel<kernels::ArgMax>(op);
179 ASSERT_THAT(kernel, NotNull());
181 checkTensor(kernel->input(), input);
182 checkTensor(kernel->axis(), axis);
183 checkTensor(kernel->output(), op);
184 EXPECT_THAT(kernel->params().output_type, Eq(op->output_type()));
187 TEST_F(KernelBuilderTest, AveragePool2D)
189 auto *input = createInputNode();
191 auto *op = createNode<luci::CircleAveragePool2D>();
194 op->padding(luci::Padding::SAME);
199 op->fusedActivationFunction(luci::FusedActFunc::RELU);
201 auto kernel = buildKernel<kernels::AveragePool2D>(op);
202 ASSERT_THAT(kernel, NotNull());
204 checkTensor(kernel->input(), input);
205 checkTensor(kernel->output(), op);
206 EXPECT_THAT(kernel->params().padding, Eq(op->padding()));
207 EXPECT_THAT(kernel->params().filter_height, Eq(op->filter()->h()));
208 EXPECT_THAT(kernel->params().filter_width, Eq(op->filter()->w()));
209 EXPECT_THAT(kernel->params().stride_height, Eq(op->stride()->h()));
210 EXPECT_THAT(kernel->params().stride_width, Eq(op->stride()->w()));
211 EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
214 TEST_F(KernelBuilderTest, BatchMatMul)
216 auto *lhs = createInputNode();
217 auto *rhs = createInputNode();
219 auto *op = createNode<luci::CircleBatchMatMul>();
225 auto kernel = buildKernel<kernels::BatchMatMul>(op);
226 ASSERT_THAT(kernel, NotNull());
228 checkTensor(kernel->x(), lhs);
229 checkTensor(kernel->y(), rhs);
230 checkTensor(kernel->output(), op);
231 EXPECT_THAT(kernel->params().adj_x, Eq(op->adj_x()));
232 EXPECT_THAT(kernel->params().adj_y, Eq(op->adj_y()));
235 TEST_F(KernelBuilderTest, Cast)
237 auto *input = createInputNode();
239 auto *op = createNode<luci::CircleCast>();
242 auto kernel = buildKernel<kernels::Cast>(op);
243 ASSERT_THAT(kernel, NotNull());
245 checkTensor(kernel->input(), input);
246 checkTensor(kernel->output(), op);
249 TEST_F(KernelBuilderTest, Concatenation)
251 auto *input1 = createInputNode();
252 auto *input2 = createInputNode();
254 auto *op = createNode<luci::CircleConcatenation>(2);
255 op->values(0, input1);
256 op->values(1, input2);
259 auto kernel = buildKernel<kernels::Concatenation>(op);
260 ASSERT_THAT(kernel, NotNull());
262 checkTensor(kernel->input(0), input1);
263 checkTensor(kernel->input(1), input2);
264 checkTensor(kernel->output(), op);
265 EXPECT_THAT(kernel->params().axis, Eq(op->axis()));
266 EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
269 TEST_F(KernelBuilderTest, Conv2D)
271 auto *input = createInputNode();
272 auto *filter = createInputNode();
273 auto *bias = createInputNode();
275 auto *op = createNode<luci::CircleConv2D>();
280 op->padding(luci::Padding::SAME);
283 op->dilation()->h(17);
284 op->dilation()->w(19);
285 op->fusedActivationFunction(luci::FusedActFunc::RELU);
287 auto kernel = buildKernel<kernels::Conv2D>(op);
288 ASSERT_THAT(kernel, NotNull());
290 checkTensor(kernel->input(), input);
291 checkTensor(kernel->filter(), filter);
292 checkTensor(kernel->bias(), bias);
293 checkTensor(kernel->output(), op);
294 EXPECT_THAT(kernel->params().padding, Eq(op->padding()));
295 EXPECT_THAT(kernel->params().stride_height, Eq(op->stride()->h()));
296 EXPECT_THAT(kernel->params().stride_width, Eq(op->stride()->w()));
297 EXPECT_THAT(kernel->params().dilation_height_factor, Eq(op->dilation()->h()));
298 EXPECT_THAT(kernel->params().dilation_width_factor, Eq(op->dilation()->w()));
299 EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
302 TEST_F(KernelBuilderTest, DepthToSpace)
304 auto *input = createInputNode();
306 auto *op = createNode<luci::CircleDepthToSpace>();
311 auto kernel = buildKernel<kernels::DepthToSpace>(op);
312 ASSERT_THAT(kernel, NotNull());
314 checkTensor(kernel->input(), input);
315 checkTensor(kernel->output(), op);
316 EXPECT_THAT(kernel->params().block_size, Eq(op->block_size()));
319 TEST_F(KernelBuilderTest, DepthwiseConv2D)
321 auto *input = createInputNode();
322 auto *filter = createInputNode();
323 auto *bias = createInputNode();
325 auto *op = createNode<luci::CircleDepthwiseConv2D>();
330 op->padding(luci::Padding::SAME);
331 op->depthMultiplier(11);
334 op->dilation()->h(19);
335 op->dilation()->w(23);
336 op->fusedActivationFunction(luci::FusedActFunc::RELU);
338 auto kernel = buildKernel<kernels::DepthwiseConv2D>(op);
339 ASSERT_THAT(kernel, NotNull());
341 checkTensor(kernel->input(), input);
342 checkTensor(kernel->filter(), filter);
343 checkTensor(kernel->bias(), bias);
344 checkTensor(kernel->output(), op);
345 EXPECT_THAT(kernel->params().padding, Eq(op->padding()));
346 EXPECT_THAT(kernel->params().depth_multiplier, Eq(op->depthMultiplier()));
347 EXPECT_THAT(kernel->params().stride_height, Eq(op->stride()->h()));
348 EXPECT_THAT(kernel->params().stride_width, Eq(op->stride()->w()));
349 EXPECT_THAT(kernel->params().dilation_height_factor, Eq(op->dilation()->h()));
350 EXPECT_THAT(kernel->params().dilation_width_factor, Eq(op->dilation()->w()));
351 EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
354 TEST_F(KernelBuilderTest, Div)
356 auto *input1 = createInputNode();
357 auto *input2 = createInputNode();
359 auto *op = createNode<luci::CircleDiv>();
363 op->fusedActivationFunction(luci::FusedActFunc::RELU);
365 auto kernel = buildKernel<kernels::Div>(op);
366 ASSERT_THAT(kernel, NotNull());
368 checkTensor(kernel->input1(), input1);
369 checkTensor(kernel->input2(), input2);
370 checkTensor(kernel->output(), op);
371 EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
374 TEST_F(KernelBuilderTest, Elu)
376 auto *input = createInputNode();
378 auto *op = createNode<luci::CircleElu>();
381 auto kernel = buildKernel<kernels::Elu>(op);
382 ASSERT_THAT(kernel, NotNull());
384 checkTensor(kernel->input(), input);
385 checkTensor(kernel->output(), op);
388 TEST_F(KernelBuilderTest, Exp)
390 auto *input = createInputNode();
392 auto *op = createNode<luci::CircleExp>();
395 auto kernel = buildKernel<kernels::Exp>(op);
396 ASSERT_THAT(kernel, NotNull());
398 checkTensor(kernel->input(), input);
399 checkTensor(kernel->output(), op);
402 TEST_F(KernelBuilderTest, Floor)
404 auto *input = createInputNode();
406 auto *op = createNode<luci::CircleFloor>();
409 auto kernel = buildKernel<kernels::Floor>(op);
410 ASSERT_THAT(kernel, NotNull());
412 checkTensor(kernel->input(), input);
413 checkTensor(kernel->output(), op);
416 TEST_F(KernelBuilderTest, FloorDiv)
418 auto *x = createInputNode();
419 auto *y = createInputNode();
421 auto *op = createNode<luci::CircleFloorDiv>();
425 auto kernel = buildKernel<kernels::FloorDiv>(op);
426 ASSERT_THAT(kernel, NotNull());
428 checkTensor(kernel->x(), x);
429 checkTensor(kernel->y(), y);
430 checkTensor(kernel->output(), op);
433 TEST_F(KernelBuilderTest, Equal)
435 auto *x_input = createInputNode();
436 auto *y_input = createInputNode();
438 auto *op = createNode<luci::CircleEqual>();
442 auto kernel = buildKernel<kernels::Equal>(op);
443 ASSERT_THAT(kernel, NotNull());
445 checkTensor(kernel->x(), x_input);
446 checkTensor(kernel->y(), y_input);
447 checkTensor(kernel->output(), op);
450 TEST_F(KernelBuilderTest, FullyConnected)
452 auto *input = createInputNode();
453 auto *weights = createInputNode();
454 auto *bias = createInputNode();
456 auto *op = createNode<luci::CircleFullyConnected>();
458 op->weights(weights);
461 op->fusedActivationFunction(luci::FusedActFunc::RELU);
463 auto kernel = buildKernel<kernels::FullyConnected>(op);
464 ASSERT_THAT(kernel, NotNull());
466 checkTensor(kernel->input(), input);
467 checkTensor(kernel->weights(), weights);
468 checkTensor(kernel->bias(), bias);
469 checkTensor(kernel->output(), op);
470 EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
473 TEST_F(KernelBuilderTest, Greater)
475 auto *x_input = createInputNode();
476 auto *y_input = createInputNode();
478 auto *op = createNode<luci::CircleGreater>();
482 auto kernel = buildKernel<kernels::Greater>(op);
483 ASSERT_THAT(kernel, NotNull());
485 checkTensor(kernel->x(), x_input);
486 checkTensor(kernel->y(), y_input);
487 checkTensor(kernel->output(), op);
490 TEST_F(KernelBuilderTest, GreaterEqual)
492 auto *x_input = createInputNode();
493 auto *y_input = createInputNode();
495 auto *op = createNode<luci::CircleGreaterEqual>();
499 auto kernel = buildKernel<kernels::GreaterEqual>(op);
500 ASSERT_THAT(kernel, NotNull());
502 checkTensor(kernel->x(), x_input);
503 checkTensor(kernel->y(), y_input);
504 checkTensor(kernel->output(), op);
507 TEST_F(KernelBuilderTest, InstanceNorm)
509 auto *input = createInputNode();
510 auto *gamma = createInputNode();
511 auto *beta = createInputNode();
513 auto *op = createNode<luci::CircleInstanceNorm>();
519 op->fusedActivationFunction(luci::FusedActFunc::RELU);
521 auto kernel = buildKernel<kernels::InstanceNorm>(op);
522 ASSERT_THAT(kernel, NotNull());
524 checkTensor(kernel->input(), input);
525 checkTensor(kernel->gamma(), gamma);
526 checkTensor(kernel->beta(), beta);
527 checkTensor(kernel->output(), op);
528 EXPECT_THAT(kernel->params().epsilon, Eq(op->epsilon()));
529 EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
532 TEST_F(KernelBuilderTest, L2Normalize)
534 auto *input = createInputNode();
536 auto *op = createNode<luci::CircleL2Normalize>();
539 op->fusedActivationFunction(luci::FusedActFunc::RELU);
541 auto kernel = buildKernel<kernels::L2Normalize>(op);
542 ASSERT_THAT(kernel, NotNull());
544 checkTensor(kernel->input(), input);
545 checkTensor(kernel->output(), op);
546 EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
549 TEST_F(KernelBuilderTest, L2Pool2D)
551 auto *input = createInputNode();
553 auto *op = createNode<luci::CircleL2Pool2D>();
556 op->padding(luci::Padding::SAME);
561 op->fusedActivationFunction(luci::FusedActFunc::RELU);
563 auto kernel = buildKernel<kernels::L2Pool2D>(op);
564 ASSERT_THAT(kernel, NotNull());
566 checkTensor(kernel->input(), input);
567 checkTensor(kernel->output(), op);
568 EXPECT_THAT(kernel->params().padding, Eq(op->padding()));
569 EXPECT_THAT(kernel->params().filter_height, Eq(op->filter()->h()));
570 EXPECT_THAT(kernel->params().filter_width, Eq(op->filter()->w()));
571 EXPECT_THAT(kernel->params().stride_height, Eq(op->stride()->h()));
572 EXPECT_THAT(kernel->params().stride_width, Eq(op->stride()->w()));
573 EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
576 TEST_F(KernelBuilderTest, LeakyRelu)
578 auto *input = createInputNode();
580 auto *op = createNode<luci::CircleLeakyRelu>();
585 auto kernel = buildKernel<kernels::LeakyRelu>(op);
586 ASSERT_THAT(kernel, NotNull());
588 checkTensor(kernel->input(), input);
589 checkTensor(kernel->output(), op);
590 EXPECT_THAT(kernel->params().alpha, Eq(op->alpha()));
593 TEST_F(KernelBuilderTest, Less)
595 auto *x_input = createInputNode();
596 auto *y_input = createInputNode();
598 auto *op = createNode<luci::CircleLess>();
602 auto kernel = buildKernel<kernels::Less>(op);
603 ASSERT_THAT(kernel, NotNull());
605 checkTensor(kernel->x(), x_input);
606 checkTensor(kernel->y(), y_input);
607 checkTensor(kernel->output(), op);
610 TEST_F(KernelBuilderTest, LessEqual)
612 auto *x_input = createInputNode();
613 auto *y_input = createInputNode();
615 auto *op = createNode<luci::CircleLessEqual>();
619 auto kernel = buildKernel<kernels::LessEqual>(op);
620 ASSERT_THAT(kernel, NotNull());
622 checkTensor(kernel->x(), x_input);
623 checkTensor(kernel->y(), y_input);
624 checkTensor(kernel->output(), op);
627 TEST_F(KernelBuilderTest, LocalResponseNormalization)
629 auto *input = createInputNode();
631 auto *op = createNode<luci::CircleLocalResponseNormalization>();
639 auto kernel = buildKernel<kernels::LocalResponseNormalization>(op);
640 ASSERT_THAT(kernel, NotNull());
642 checkTensor(kernel->input(), input);
643 checkTensor(kernel->output(), op);
644 EXPECT_THAT(kernel->params().radius, Eq(op->radius()));
645 EXPECT_THAT(kernel->params().bias, Eq(op->bias()));
646 EXPECT_THAT(kernel->params().alpha, Eq(op->alpha()));
647 EXPECT_THAT(kernel->params().beta, Eq(op->beta()));
650 TEST_F(KernelBuilderTest, LogicalAnd)
652 auto *input1 = createInputNode();
653 auto *input2 = createInputNode();
655 auto *op = createNode<luci::CircleLogicalAnd>();
659 auto kernel = buildKernel<kernels::LogicalAnd>(op);
660 ASSERT_THAT(kernel, NotNull());
662 checkTensor(kernel->input1(), input1);
663 checkTensor(kernel->input2(), input2);
664 checkTensor(kernel->output(), op);
667 TEST_F(KernelBuilderTest, LogicalNot)
669 auto *input = createInputNode();
671 auto *op = createNode<luci::CircleLogicalNot>();
674 auto kernel = buildKernel<kernels::LogicalNot>(op);
675 ASSERT_THAT(kernel, NotNull());
677 checkTensor(kernel->input(), input);
678 checkTensor(kernel->output(), op);
681 TEST_F(KernelBuilderTest, LogicalOr)
683 auto *input1 = createInputNode();
684 auto *input2 = createInputNode();
686 auto *op = createNode<luci::CircleLogicalOr>();
690 auto kernel = buildKernel<kernels::LogicalOr>(op);
691 ASSERT_THAT(kernel, NotNull());
693 checkTensor(kernel->input1(), input1);
694 checkTensor(kernel->input2(), input2);
695 checkTensor(kernel->output(), op);
698 TEST_F(KernelBuilderTest, Logistic)
700 auto *input = createInputNode();
702 auto *op = createNode<luci::CircleLogistic>();
705 auto kernel = buildKernel<kernels::Logistic>(op);
706 ASSERT_THAT(kernel, NotNull());
708 checkTensor(kernel->input(), input);
709 checkTensor(kernel->output(), op);
712 TEST_F(KernelBuilderTest, LogSoftmax)
714 auto *input = createInputNode();
716 auto *op = createNode<luci::CircleLogSoftmax>();
719 auto kernel = buildKernel<kernels::LogSoftmax>(op);
720 ASSERT_THAT(kernel, NotNull());
722 checkTensor(kernel->input(), input);
723 checkTensor(kernel->output(), op);
726 TEST_F(KernelBuilderTest, Maximum)
728 auto *input1 = createInputNode();
729 auto *input2 = createInputNode();
731 auto *op = createNode<luci::CircleMaximum>();
735 auto kernel = buildKernel<kernels::Maximum>(op);
736 ASSERT_THAT(kernel, NotNull());
738 checkTensor(kernel->input1(), input1);
739 checkTensor(kernel->input2(), input2);
740 checkTensor(kernel->output(), op);
743 TEST_F(KernelBuilderTest, MaxPool2D)
745 auto *input = createInputNode();
747 auto *op = createNode<luci::CircleMaxPool2D>();
750 op->padding(luci::Padding::SAME);
755 op->fusedActivationFunction(luci::FusedActFunc::RELU);
757 auto kernel = buildKernel<kernels::MaxPool2D>(op);
758 ASSERT_THAT(kernel, NotNull());
760 checkTensor(kernel->input(), input);
761 checkTensor(kernel->output(), op);
762 EXPECT_THAT(kernel->params().padding, Eq(op->padding()));
763 EXPECT_THAT(kernel->params().filter_height, Eq(op->filter()->h()));
764 EXPECT_THAT(kernel->params().filter_width, Eq(op->filter()->w()));
765 EXPECT_THAT(kernel->params().stride_height, Eq(op->stride()->h()));
766 EXPECT_THAT(kernel->params().stride_width, Eq(op->stride()->w()));
767 EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
770 TEST_F(KernelBuilderTest, Mean)
772 auto *input = createInputNode();
773 auto *axes = createInputNode();
775 auto *op = createNode<luci::CircleMean>();
777 op->reduction_indices(axes);
781 auto kernel = buildKernel<kernels::Mean>(op);
782 ASSERT_THAT(kernel, NotNull());
784 checkTensor(kernel->input(), input);
785 checkTensor(kernel->axes(), axes);
786 checkTensor(kernel->output(), op);
787 EXPECT_THAT(kernel->params().keep_dims, Eq(op->keep_dims()));
790 TEST_F(KernelBuilderTest, Minimum)
792 auto *input1 = createInputNode();
793 auto *input2 = createInputNode();
795 auto *op = createNode<luci::CircleMinimum>();
799 auto kernel = buildKernel<kernels::Minimum>(op);
800 ASSERT_THAT(kernel, NotNull());
802 checkTensor(kernel->input1(), input1);
803 checkTensor(kernel->input2(), input2);
804 checkTensor(kernel->output(), op);
807 TEST_F(KernelBuilderTest, Mul)
809 auto *input1 = createInputNode();
810 auto *input2 = createInputNode();
812 auto *op = createNode<luci::CircleMul>();
816 op->fusedActivationFunction(luci::FusedActFunc::RELU);
818 auto kernel = buildKernel<kernels::Mul>(op);
819 ASSERT_THAT(kernel, NotNull());
821 checkTensor(kernel->input1(), input1);
822 checkTensor(kernel->input2(), input2);
823 checkTensor(kernel->output(), op);
824 EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
827 TEST_F(KernelBuilderTest, Neg)
829 auto *input = createInputNode();
831 auto *op = createNode<luci::CircleNeg>();
834 auto kernel = buildKernel<kernels::Neg>(op);
835 ASSERT_THAT(kernel, NotNull());
837 checkTensor(kernel->input(), input);
838 checkTensor(kernel->output(), op);
841 TEST_F(KernelBuilderTest, NotEqual)
843 auto *x_input = createInputNode();
844 auto *y_input = createInputNode();
846 auto *op = createNode<luci::CircleNotEqual>();
850 auto kernel = buildKernel<kernels::NotEqual>(op);
851 ASSERT_THAT(kernel, NotNull());
853 checkTensor(kernel->x(), x_input);
854 checkTensor(kernel->y(), y_input);
855 checkTensor(kernel->output(), op);
858 TEST_F(KernelBuilderTest, OneHot)
860 auto *indices = createInputNode();
861 auto *depth = createInputNode();
862 auto *on_value = createInputNode();
863 auto *off_value = createInputNode();
866 auto *op = createNode<luci::CircleOneHot>();
867 op->indices(indices);
869 op->on_value(on_value);
870 op->off_value(off_value);
873 auto kernel = buildKernel<kernels::OneHot>(op);
874 ASSERT_THAT(kernel, NotNull());
876 checkTensor(kernel->indices(), indices);
877 checkTensor(kernel->depth(), depth);
878 checkTensor(kernel->on_value(), on_value);
879 checkTensor(kernel->off_value(), off_value);
880 EXPECT_THAT(kernel->params().axis, Eq(op->axis()));
883 TEST_F(KernelBuilderTest, Pad)
885 auto *input = createInputNode();
886 auto *paddings = createInputNode();
888 auto *op = createNode<luci::CirclePad>();
890 op->paddings(paddings);
892 auto kernel = buildKernel<kernels::Pad>(op);
893 ASSERT_THAT(kernel, NotNull());
895 checkTensor(kernel->input(), input);
896 checkTensor(kernel->paddings(), paddings);
897 checkTensor(kernel->output(), op);
900 TEST_F(KernelBuilderTest, PadV2)
902 auto *input = createInputNode();
903 auto *paddings = createInputNode();
904 auto *constant_values = createInputNode();
906 auto *op = createNode<luci::CirclePadV2>();
908 op->paddings(paddings);
909 op->constant_values(constant_values);
911 auto kernel = buildKernel<kernels::PadV2>(op);
912 ASSERT_THAT(kernel, NotNull());
914 checkTensor(kernel->input(), input);
915 checkTensor(kernel->paddings(), paddings);
916 checkTensor(kernel->constant_values(), constant_values);
917 checkTensor(kernel->output(), op);
920 TEST_F(KernelBuilderTest, Pow)
922 auto *input1 = createInputNode();
923 auto *input2 = createInputNode();
925 auto *op = createNode<luci::CirclePow>();
929 auto kernel = buildKernel<kernels::Pow>(op);
930 ASSERT_THAT(kernel, NotNull());
932 checkTensor(kernel->input1(), input1);
933 checkTensor(kernel->input2(), input2);
934 checkTensor(kernel->output(), op);
937 TEST_F(KernelBuilderTest, PRelu)
939 auto *input = createInputNode();
940 auto *alpha = createInputNode();
942 auto *op = createNode<luci::CirclePRelu>();
946 auto kernel = buildKernel<kernels::PRelu>(op);
947 ASSERT_THAT(kernel, NotNull());
949 checkTensor(kernel->input(), input);
950 checkTensor(kernel->alpha(), alpha);
951 checkTensor(kernel->output(), op);
954 TEST_F(KernelBuilderTest, Relu)
956 auto *input = createInputNode();
958 auto *op = createNode<luci::CircleRelu>();
961 auto kernel = buildKernel<kernels::Relu>(op);
962 ASSERT_THAT(kernel, NotNull());
964 checkTensor(kernel->input(), input);
965 checkTensor(kernel->output(), op);
968 TEST_F(KernelBuilderTest, Relu6)
970 auto *input = createInputNode();
972 auto *op = createNode<luci::CircleRelu6>();
975 auto kernel = buildKernel<kernels::Relu6>(op);
976 ASSERT_THAT(kernel, NotNull());
978 checkTensor(kernel->input(), input);
979 checkTensor(kernel->output(), op);
982 TEST_F(KernelBuilderTest, Reshape)
984 auto *input = createInputNode();
985 auto *shape = createInputNode();
987 auto *op = createNode<luci::CircleReshape>();
991 auto kernel = buildKernel<kernels::Reshape>(op);
992 ASSERT_THAT(kernel, NotNull());
994 checkTensor(kernel->input(), input);
995 checkTensor(kernel->shape(), shape);
996 checkTensor(kernel->output(), op);
999 TEST_F(KernelBuilderTest, ResizeBilinear)
1001 auto *input = createInputNode();
1002 auto *size = createInputNode();
1004 auto *op = createNode<luci::CircleResizeBilinear>();
1007 op->align_corners(true);
1008 op->half_pixel_centers(true);
1010 auto kernel = buildKernel<kernels::ResizeBilinear>(op);
1011 ASSERT_THAT(kernel, NotNull());
1013 checkTensor(kernel->input(), input);
1014 checkTensor(kernel->size(), size);
1015 checkTensor(kernel->output(), op);
1016 EXPECT_THAT(kernel->params().align_corners, Eq(op->align_corners()));
1017 EXPECT_THAT(kernel->params().half_pixel_centers, Eq(op->half_pixel_centers()));
1020 TEST_F(KernelBuilderTest, ResizeNearestNeighbor)
1022 auto *input = createInputNode();
1023 auto *size = createInputNode();
1025 auto *op = createNode<luci::CircleResizeNearestNeighbor>();
1028 op->align_corners(true);
1030 auto kernel = buildKernel<kernels::ResizeNearestNeighbor>(op);
1031 ASSERT_THAT(kernel, NotNull());
1033 checkTensor(kernel->input(), input);
1034 checkTensor(kernel->size(), size);
1035 checkTensor(kernel->output(), op);
1036 EXPECT_THAT(kernel->params().align_corners, Eq(op->align_corners()));
1037 // TODO currently half_pixel_centers are not implemented on CircleResizeNearestNeighbor
1038 // after adding, need to be updated.
1041 TEST_F(KernelBuilderTest, ReverseV2)
1043 auto *input = createInputNode();
1044 auto *axes = createInputNode();
1046 auto *op = createNode<luci::CircleReverseV2>();
1050 auto kernel = buildKernel<kernels::ReverseV2>(op);
1051 ASSERT_THAT(kernel, NotNull());
1053 checkTensor(kernel->input(), input);
1054 checkTensor(kernel->axes(), axes);
1055 checkTensor(kernel->output(), op);
1058 TEST_F(KernelBuilderTest, Rsqrt)
1060 auto *input = createInputNode();
1062 auto *op = createNode<luci::CircleRsqrt>();
1065 auto kernel = buildKernel<kernels::Rsqrt>(op);
1066 ASSERT_THAT(kernel, NotNull());
1068 checkTensor(kernel->input(), input);
1069 checkTensor(kernel->output(), op);
1072 TEST_F(KernelBuilderTest, Slice)
1074 auto *input = createInputNode();
1075 auto *begin = createInputNode();
1076 auto *size = createInputNode();
1078 auto *op = createNode<luci::CircleSlice>();
1083 auto kernel = buildKernel<kernels::Slice>(op);
1084 ASSERT_THAT(kernel, NotNull());
1086 checkTensor(kernel->input(), input);
1087 checkTensor(kernel->begin(), begin);
1088 checkTensor(kernel->size(), size);
1089 checkTensor(kernel->output(), op);
1092 TEST_F(KernelBuilderTest, Softmax)
1094 auto *input = createInputNode();
1096 auto *op = createNode<luci::CircleSoftmax>();
1101 auto kernel = buildKernel<kernels::Softmax>(op);
1102 ASSERT_THAT(kernel, NotNull());
1104 checkTensor(kernel->input(), input);
1105 checkTensor(kernel->output(), op);
1106 EXPECT_THAT(kernel->params().beta, Eq(op->beta()));
1109 TEST_F(KernelBuilderTest, SpaceToDepth)
1111 auto *input = createInputNode();
1113 auto *op = createNode<luci::CircleSpaceToDepth>();
1118 auto kernel = buildKernel<kernels::SpaceToDepth>(op);
1119 ASSERT_THAT(kernel, NotNull());
1121 checkTensor(kernel->input(), input);
1122 checkTensor(kernel->output(), op);
1123 EXPECT_THAT(kernel->params().block_size, op->block_size());
1126 TEST_F(KernelBuilderTest, Split)
1128 auto *axis = createInputNode();
1129 auto *input = createInputNode();
1130 auto *op = createNode<luci::CircleSplit>();
1131 auto *output1 = createNodeOut<luci::CircleSplitOut>(op, 0);
1132 auto *output2 = createNodeOut<luci::CircleSplitOut>(op, 1);
1134 op->split_dim(axis);
1139 auto kernel = buildKernel<kernels::Split>(op);
1140 ASSERT_THAT(kernel, NotNull());
1142 checkTensor(kernel->axis(), axis);
1143 checkTensor(kernel->input(), input);
1144 checkTensor(kernel->output(0), output1);
1145 checkTensor(kernel->output(1), output2);
1148 TEST_F(KernelBuilderTest, SplitV)
1150 auto *input = createInputNode();
1151 auto *size_splits = createInputNode();
1152 auto *axis = createInputNode();
1153 auto *op = createNode<luci::CircleSplitV>();
1154 auto *output0 = createNodeOut<luci::CircleSplitVOut>(op, 0);
1155 auto *output1 = createNodeOut<luci::CircleSplitVOut>(op, 1);
1158 op->size_splits(size_splits);
1159 op->split_dim(axis);
1163 auto kernel = buildKernel<kernels::SplitV>(op);
1164 ASSERT_THAT(kernel, NotNull());
1166 checkTensor(kernel->input(), input);
1167 checkTensor(kernel->size_splits(), size_splits);
1168 checkTensor(kernel->axis(), axis);
1169 checkTensor(kernel->output(0), output0);
1170 checkTensor(kernel->output(1), output1);
1173 TEST_F(KernelBuilderTest, Sqrt)
1175 auto *input = createInputNode();
1177 auto *op = createNode<luci::CircleSqrt>();
1180 auto kernel = buildKernel<kernels::Sqrt>(op);
1181 ASSERT_THAT(kernel, NotNull());
1183 checkTensor(kernel->input(), input);
1184 checkTensor(kernel->output(), op);
1187 TEST_F(KernelBuilderTest, SquaredDifference)
1189 auto *input1 = createInputNode();
1190 auto *input2 = createInputNode();
1192 auto *op = createNode<luci::CircleSquaredDifference>();
1196 auto kernel = buildKernel<kernels::SquaredDifference>(op);
1197 ASSERT_THAT(kernel, NotNull());
1199 checkTensor(kernel->input1(), input1);
1200 checkTensor(kernel->input2(), input2);
1201 checkTensor(kernel->output(), op);
1204 TEST_F(KernelBuilderTest, Squeeze)
1206 auto *input = createInputNode();
1208 auto *op = createNode<luci::CircleSqueeze>();
1211 op->squeeze_dims({11, 13});
1213 auto kernel = buildKernel<kernels::Squeeze>(op);
1214 ASSERT_THAT(kernel, NotNull());
1216 checkTensor(kernel->input(), input);
1217 checkTensor(kernel->output(), op);
1218 EXPECT_THAT(kernel->params().squeeze_dims, ElementsAreArray(op->squeeze_dims()));
1221 TEST_F(KernelBuilderTest, StridedSlice)
1223 auto *input = createInputNode();
1224 auto *begin = createInputNode();
1225 auto *end = createInputNode();
1226 auto *strides = createInputNode();
1228 auto *op = createNode<luci::CircleStridedSlice>();
1232 op->strides(strides);
1235 op->ellipsis_mask(13);
1237 op->new_axis_mask(19);
1238 op->shrink_axis_mask(23);
1240 auto kernel = buildKernel<kernels::StridedSlice>(op);
1241 ASSERT_THAT(kernel, NotNull());
1243 checkTensor(kernel->input(), input);
1244 checkTensor(kernel->begin(), begin);
1245 checkTensor(kernel->end(), end);
1246 checkTensor(kernel->strides(), strides);
1247 checkTensor(kernel->output(), op);
1248 EXPECT_THAT(kernel->params().begin_mask, Eq(op->begin_mask()));
1249 EXPECT_THAT(kernel->params().ellipsis_mask, Eq(op->ellipsis_mask()));
1250 EXPECT_THAT(kernel->params().end_mask, Eq(op->end_mask()));
1251 EXPECT_THAT(kernel->params().new_axis_mask, Eq(op->new_axis_mask()));
1252 EXPECT_THAT(kernel->params().shrink_axis_mask, Eq(op->shrink_axis_mask()));
1255 TEST_F(KernelBuilderTest, Sub)
1257 auto *input1 = createInputNode();
1258 auto *input2 = createInputNode();
1260 auto *op = createNode<luci::CircleSub>();
1264 op->fusedActivationFunction(luci::FusedActFunc::RELU);
1266 auto kernel = buildKernel<kernels::Sub>(op);
1267 ASSERT_THAT(kernel, NotNull());
1269 checkTensor(kernel->input1(), input1);
1270 checkTensor(kernel->input2(), input2);
1271 checkTensor(kernel->output(), op);
1272 EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
1275 TEST_F(KernelBuilderTest, Tanh)
1277 auto *input = createInputNode();
1279 auto *op = createNode<luci::CircleTanh>();
1282 auto kernel = buildKernel<kernels::Tanh>(op);
1283 ASSERT_THAT(kernel, NotNull());
1285 checkTensor(kernel->input(), input);
1286 checkTensor(kernel->output(), op);
1289 TEST_F(KernelBuilderTest, Transpose)
1291 auto *input = createInputNode();
1292 auto *perm = createInputNode();
1294 auto *op = createNode<luci::CircleTranspose>();
1298 auto kernel = buildKernel<kernels::Transpose>(op);
1299 ASSERT_THAT(kernel, NotNull());
1301 checkTensor(kernel->input(), input);
1302 checkTensor(kernel->perm(), perm);
1303 checkTensor(kernel->output(), op);
1306 TEST_F(KernelBuilderTest, TransposeConv)
1308 auto *output_shape = createInputNode();
1309 auto *filter = createInputNode();
1310 auto *input = createInputNode();
1311 auto *bias = createInputNode();
1313 auto *op = createNode<luci::CircleTransposeConv>();
1314 op->inputSizes(output_shape);
1316 op->outBackprop(input);
1319 op->padding(luci::Padding::SAME);
1320 op->stride()->h(11);
1321 op->stride()->w(13);
1323 auto kernel = buildKernel<kernels::TransposeConv>(op);
1324 ASSERT_THAT(kernel, NotNull());
1326 checkTensor(kernel->output_shape(), output_shape);
1327 checkTensor(kernel->filter(), filter);
1328 checkTensor(kernel->input(), input);
1329 checkTensor(kernel->output(), op);
1330 checkTensor(kernel->bias(), bias);
1331 EXPECT_THAT(kernel->params().padding, Eq(op->padding()));
1332 EXPECT_THAT(kernel->params().stride_height, Eq(op->stride()->h()));
1333 EXPECT_THAT(kernel->params().stride_width, Eq(op->stride()->w()));
1336 TEST_F(KernelBuilderTest, Unpack)
1338 auto *input = createInputNode();
1339 auto *op = createNode<luci::CircleUnpack>();
1340 auto *output1 = createNodeOut<luci::CircleUnpackOut>(op, 0);
1341 auto *output2 = createNodeOut<luci::CircleUnpackOut>(op, 1);
1348 auto kernel = buildKernel<kernels::Unpack>(op);
1349 ASSERT_THAT(kernel, NotNull());
1351 checkTensor(kernel->input(), input);
1352 checkTensor(kernel->output(0), output1);
1353 checkTensor(kernel->output(1), output2);
1354 EXPECT_THAT(kernel->params().axis, Eq(op->axis()));
1357 TEST_F(KernelBuilderTest, NonExisting1_NEG)
1359 auto *op = createNode<luci::CircleConst>();
1360 ASSERT_ANY_THROW(buildKernel<Kernel>(op));
1363 TEST_F(KernelBuilderTest, NonExisting2_NEG)
1365 auto *op = createNode<luci::CircleInput>();
1366 ASSERT_ANY_THROW(buildKernel<Kernel>(op));
1369 TEST_F(KernelBuilderTest, NonExisting3_NEG)
1371 auto *op = createNode<luci::CircleOutput>();
1372 ASSERT_ANY_THROW(buildKernel<Kernel>(op));
1376 } // namespace luci_interpreter