Imported Upstream version 1.18.0
[platform/core/ml/nnfw.git] / compiler / luci-interpreter / src / loader / KernelBuilder.test.cpp
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 "loader/GraphLoader.h"
18 #include "loader/KernelBuilder.h"
19 #include "luci_interpreter/SimpleMemoryManager.h"
20
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>
82
83 #include <gmock/gmock.h>
84
85 namespace luci_interpreter
86 {
87 namespace
88 {
89
90 using namespace testing;
91
92 class KernelBuilderTest : public Test
93 {
94 protected:
95   luci::CircleInput *createInputNode() { return createNode<luci::CircleInput>(); }
96   void SetUp() override { _memory_manager = std::make_unique<SimpleMemoryManager>(); }
97
98   std::unique_ptr<IMemoryManager> _memory_manager;
99
100   template <typename NodeT, typename... Args> NodeT *createNode(Args &&... args)
101   {
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);
107     return node;
108   }
109
110   template <typename NodeOutT> NodeOutT *createNodeOut(loco::Node *node, int index)
111   {
112     auto *node_out = createNode<NodeOutT>();
113     node_out->input(node);
114     node_out->index(index);
115     return node_out;
116   }
117
118   template <typename KernelT> std::unique_ptr<KernelT> buildKernel(const luci::CircleNode *op)
119   {
120     std::unordered_map<const loco::Graph *, RuntimeGraph *> graph_to_runtime_graph;
121
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();
128
129     KernelBuilder kernel_builder(graph_to_runtime_graph, _node_to_tensor);
130
131     auto kernel = kernel_builder.build(op);
132     return std::unique_ptr<KernelT>(dynamic_cast<KernelT *>(kernel.release()));
133   }
134
135   void checkTensor(const Tensor *tensor, const loco::Node *node)
136   {
137     EXPECT_THAT(tensor, Eq(_node_to_tensor.at(node)));
138   }
139
140 private:
141   loco::Graph _graph;
142   std::unordered_map<const loco::Node *, Tensor *> _node_to_tensor;
143 };
144
145 TEST_F(KernelBuilderTest, Add)
146 {
147   auto *input1 = createInputNode();
148   auto *input2 = createInputNode();
149
150   auto *op = createNode<luci::CircleAdd>();
151   op->x(input1);
152   op->y(input2);
153
154   op->fusedActivationFunction(luci::FusedActFunc::RELU);
155
156   auto kernel = buildKernel<kernels::Add>(op);
157   ASSERT_THAT(kernel, NotNull());
158
159   checkTensor(kernel->input1(), input1);
160   checkTensor(kernel->input2(), input2);
161   checkTensor(kernel->output(), op);
162   EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
163 }
164
165 TEST_F(KernelBuilderTest, ArgMax)
166 {
167   auto *input = createInputNode();
168   auto *axis = createInputNode();
169
170   auto *op = createNode<luci::CircleArgMax>();
171   op->input(input);
172   op->dimension(axis);
173
174   op->output_type(loco::DataType::FLOAT32);
175
176   auto kernel = buildKernel<kernels::ArgMax>(op);
177   ASSERT_THAT(kernel, NotNull());
178
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()));
183 }
184
185 TEST_F(KernelBuilderTest, AveragePool2D)
186 {
187   auto *input = createInputNode();
188
189   auto *op = createNode<luci::CircleAveragePool2D>();
190   op->value(input);
191
192   op->padding(luci::Padding::SAME);
193   op->filter()->h(11);
194   op->filter()->w(13);
195   op->stride()->h(17);
196   op->stride()->w(19);
197   op->fusedActivationFunction(luci::FusedActFunc::RELU);
198
199   auto kernel = buildKernel<kernels::AveragePool2D>(op);
200   ASSERT_THAT(kernel, NotNull());
201
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()));
210 }
211
212 TEST_F(KernelBuilderTest, Cast)
213 {
214   auto *input = createInputNode();
215
216   auto *op = createNode<luci::CircleCast>();
217   op->x(input);
218
219   auto kernel = buildKernel<kernels::Cast>(op);
220   ASSERT_THAT(kernel, NotNull());
221
222   checkTensor(kernel->input(), input);
223   checkTensor(kernel->output(), op);
224 }
225
226 TEST_F(KernelBuilderTest, Concatenation)
227 {
228   auto *input1 = createInputNode();
229   auto *input2 = createInputNode();
230
231   auto *op = createNode<luci::CircleConcatenation>(2);
232   op->values(0, input1);
233   op->values(1, input2);
234   op->axis(11);
235
236   auto kernel = buildKernel<kernels::Concatenation>(op);
237   ASSERT_THAT(kernel, NotNull());
238
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()));
244 }
245
246 TEST_F(KernelBuilderTest, Conv2D)
247 {
248   auto *input = createInputNode();
249   auto *filter = createInputNode();
250   auto *bias = createInputNode();
251
252   auto *op = createNode<luci::CircleConv2D>();
253   op->input(input);
254   op->filter(filter);
255   op->bias(bias);
256
257   op->padding(luci::Padding::SAME);
258   op->stride()->h(11);
259   op->stride()->w(13);
260   op->dilation()->h(17);
261   op->dilation()->w(19);
262   op->fusedActivationFunction(luci::FusedActFunc::RELU);
263
264   auto kernel = buildKernel<kernels::Conv2D>(op);
265   ASSERT_THAT(kernel, NotNull());
266
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()));
277 }
278
279 TEST_F(KernelBuilderTest, DepthToSpace)
280 {
281   auto *input = createInputNode();
282
283   auto *op = createNode<luci::CircleDepthToSpace>();
284   op->input(input);
285
286   op->block_size(11);
287
288   auto kernel = buildKernel<kernels::DepthToSpace>(op);
289   ASSERT_THAT(kernel, NotNull());
290
291   checkTensor(kernel->input(), input);
292   checkTensor(kernel->output(), op);
293   EXPECT_THAT(kernel->params().block_size, Eq(op->block_size()));
294 }
295
296 TEST_F(KernelBuilderTest, DepthwiseConv2D)
297 {
298   auto *input = createInputNode();
299   auto *filter = createInputNode();
300   auto *bias = createInputNode();
301
302   auto *op = createNode<luci::CircleDepthwiseConv2D>();
303   op->input(input);
304   op->filter(filter);
305   op->bias(bias);
306
307   op->padding(luci::Padding::SAME);
308   op->depthMultiplier(11);
309   op->stride()->h(13);
310   op->stride()->w(17);
311   op->dilation()->h(19);
312   op->dilation()->w(23);
313   op->fusedActivationFunction(luci::FusedActFunc::RELU);
314
315   auto kernel = buildKernel<kernels::DepthwiseConv2D>(op);
316   ASSERT_THAT(kernel, NotNull());
317
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()));
329 }
330
331 TEST_F(KernelBuilderTest, Div)
332 {
333   auto *input1 = createInputNode();
334   auto *input2 = createInputNode();
335
336   auto *op = createNode<luci::CircleDiv>();
337   op->x(input1);
338   op->y(input2);
339
340   op->fusedActivationFunction(luci::FusedActFunc::RELU);
341
342   auto kernel = buildKernel<kernels::Div>(op);
343   ASSERT_THAT(kernel, NotNull());
344
345   checkTensor(kernel->input1(), input1);
346   checkTensor(kernel->input2(), input2);
347   checkTensor(kernel->output(), op);
348   EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
349 }
350
351 TEST_F(KernelBuilderTest, Elu)
352 {
353   auto *input = createInputNode();
354
355   auto *op = createNode<luci::CircleElu>();
356   op->features(input);
357
358   auto kernel = buildKernel<kernels::Elu>(op);
359   ASSERT_THAT(kernel, NotNull());
360
361   checkTensor(kernel->input(), input);
362   checkTensor(kernel->output(), op);
363 }
364
365 TEST_F(KernelBuilderTest, Exp)
366 {
367   auto *input = createInputNode();
368
369   auto *op = createNode<luci::CircleExp>();
370   op->x(input);
371
372   auto kernel = buildKernel<kernels::Exp>(op);
373   ASSERT_THAT(kernel, NotNull());
374
375   checkTensor(kernel->input(), input);
376   checkTensor(kernel->output(), op);
377 }
378
379 TEST_F(KernelBuilderTest, Floor)
380 {
381   auto *input = createInputNode();
382
383   auto *op = createNode<luci::CircleFloor>();
384   op->x(input);
385
386   auto kernel = buildKernel<kernels::Floor>(op);
387   ASSERT_THAT(kernel, NotNull());
388
389   checkTensor(kernel->input(), input);
390   checkTensor(kernel->output(), op);
391 }
392
393 TEST_F(KernelBuilderTest, FloorDiv)
394 {
395   auto *x = createInputNode();
396   auto *y = createInputNode();
397
398   auto *op = createNode<luci::CircleFloorDiv>();
399   op->x(x);
400   op->y(y);
401
402   auto kernel = buildKernel<kernels::FloorDiv>(op);
403   ASSERT_THAT(kernel, NotNull());
404
405   checkTensor(kernel->x(), x);
406   checkTensor(kernel->y(), y);
407   checkTensor(kernel->output(), op);
408 }
409
410 TEST_F(KernelBuilderTest, Equal)
411 {
412   auto *x_input = createInputNode();
413   auto *y_input = createInputNode();
414
415   auto *op = createNode<luci::CircleEqual>();
416   op->x(x_input);
417   op->y(y_input);
418
419   auto kernel = buildKernel<kernels::Equal>(op);
420   ASSERT_THAT(kernel, NotNull());
421
422   checkTensor(kernel->x(), x_input);
423   checkTensor(kernel->y(), y_input);
424   checkTensor(kernel->output(), op);
425 }
426
427 TEST_F(KernelBuilderTest, FullyConnected)
428 {
429   auto *input = createInputNode();
430   auto *weights = createInputNode();
431   auto *bias = createInputNode();
432
433   auto *op = createNode<luci::CircleFullyConnected>();
434   op->input(input);
435   op->weights(weights);
436   op->bias(bias);
437
438   op->fusedActivationFunction(luci::FusedActFunc::RELU);
439
440   auto kernel = buildKernel<kernels::FullyConnected>(op);
441   ASSERT_THAT(kernel, NotNull());
442
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()));
448 }
449
450 TEST_F(KernelBuilderTest, Greater)
451 {
452   auto *x_input = createInputNode();
453   auto *y_input = createInputNode();
454
455   auto *op = createNode<luci::CircleGreater>();
456   op->x(x_input);
457   op->y(y_input);
458
459   auto kernel = buildKernel<kernels::Greater>(op);
460   ASSERT_THAT(kernel, NotNull());
461
462   checkTensor(kernel->x(), x_input);
463   checkTensor(kernel->y(), y_input);
464   checkTensor(kernel->output(), op);
465 }
466
467 TEST_F(KernelBuilderTest, GreaterEqual)
468 {
469   auto *x_input = createInputNode();
470   auto *y_input = createInputNode();
471
472   auto *op = createNode<luci::CircleGreaterEqual>();
473   op->x(x_input);
474   op->y(y_input);
475
476   auto kernel = buildKernel<kernels::GreaterEqual>(op);
477   ASSERT_THAT(kernel, NotNull());
478
479   checkTensor(kernel->x(), x_input);
480   checkTensor(kernel->y(), y_input);
481   checkTensor(kernel->output(), op);
482 }
483
484 TEST_F(KernelBuilderTest, InstanceNorm)
485 {
486   auto *input = createInputNode();
487   auto *gamma = createInputNode();
488   auto *beta = createInputNode();
489
490   auto *op = createNode<luci::CircleInstanceNorm>();
491   op->input(input);
492   op->gamma(gamma);
493   op->beta(beta);
494
495   op->epsilon(1e-05);
496   op->fusedActivationFunction(luci::FusedActFunc::RELU);
497
498   auto kernel = buildKernel<kernels::InstanceNorm>(op);
499   ASSERT_THAT(kernel, NotNull());
500
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()));
507 }
508
509 TEST_F(KernelBuilderTest, L2Normalize)
510 {
511   auto *input = createInputNode();
512
513   auto *op = createNode<luci::CircleL2Normalize>();
514   op->x(input);
515
516   op->fusedActivationFunction(luci::FusedActFunc::RELU);
517
518   auto kernel = buildKernel<kernels::L2Normalize>(op);
519   ASSERT_THAT(kernel, NotNull());
520
521   checkTensor(kernel->input(), input);
522   checkTensor(kernel->output(), op);
523   EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
524 }
525
526 TEST_F(KernelBuilderTest, L2Pool2D)
527 {
528   auto *input = createInputNode();
529
530   auto *op = createNode<luci::CircleL2Pool2D>();
531   op->value(input);
532
533   op->padding(luci::Padding::SAME);
534   op->filter()->h(11);
535   op->filter()->w(13);
536   op->stride()->h(17);
537   op->stride()->w(19);
538   op->fusedActivationFunction(luci::FusedActFunc::RELU);
539
540   auto kernel = buildKernel<kernels::L2Pool2D>(op);
541   ASSERT_THAT(kernel, NotNull());
542
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()));
551 }
552
553 TEST_F(KernelBuilderTest, LeakyRelu)
554 {
555   auto *input = createInputNode();
556
557   auto *op = createNode<luci::CircleLeakyRelu>();
558   op->features(input);
559
560   op->alpha(11.0f);
561
562   auto kernel = buildKernel<kernels::LeakyRelu>(op);
563   ASSERT_THAT(kernel, NotNull());
564
565   checkTensor(kernel->input(), input);
566   checkTensor(kernel->output(), op);
567   EXPECT_THAT(kernel->params().alpha, Eq(op->alpha()));
568 }
569
570 TEST_F(KernelBuilderTest, Less)
571 {
572   auto *x_input = createInputNode();
573   auto *y_input = createInputNode();
574
575   auto *op = createNode<luci::CircleLess>();
576   op->x(x_input);
577   op->y(y_input);
578
579   auto kernel = buildKernel<kernels::Less>(op);
580   ASSERT_THAT(kernel, NotNull());
581
582   checkTensor(kernel->x(), x_input);
583   checkTensor(kernel->y(), y_input);
584   checkTensor(kernel->output(), op);
585 }
586
587 TEST_F(KernelBuilderTest, LessEqual)
588 {
589   auto *x_input = createInputNode();
590   auto *y_input = createInputNode();
591
592   auto *op = createNode<luci::CircleLessEqual>();
593   op->x(x_input);
594   op->y(y_input);
595
596   auto kernel = buildKernel<kernels::LessEqual>(op);
597   ASSERT_THAT(kernel, NotNull());
598
599   checkTensor(kernel->x(), x_input);
600   checkTensor(kernel->y(), y_input);
601   checkTensor(kernel->output(), op);
602 }
603
604 TEST_F(KernelBuilderTest, LocalResponseNormalization)
605 {
606   auto *input = createInputNode();
607
608   auto *op = createNode<luci::CircleLocalResponseNormalization>();
609   op->input(input);
610
611   op->radius(11);
612   op->bias(13.0f);
613   op->alpha(15.0f);
614   op->beta(17.0f);
615
616   auto kernel = buildKernel<kernels::LocalResponseNormalization>(op);
617   ASSERT_THAT(kernel, NotNull());
618
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()));
625 }
626
627 TEST_F(KernelBuilderTest, LogicalAnd)
628 {
629   auto *input1 = createInputNode();
630   auto *input2 = createInputNode();
631
632   auto *op = createNode<luci::CircleLogicalAnd>();
633   op->x(input1);
634   op->y(input2);
635
636   auto kernel = buildKernel<kernels::LogicalAnd>(op);
637   ASSERT_THAT(kernel, NotNull());
638
639   checkTensor(kernel->input1(), input1);
640   checkTensor(kernel->input2(), input2);
641   checkTensor(kernel->output(), op);
642 }
643
644 TEST_F(KernelBuilderTest, LogicalNot)
645 {
646   auto *input = createInputNode();
647
648   auto *op = createNode<luci::CircleLogicalNot>();
649   op->x(input);
650
651   auto kernel = buildKernel<kernels::LogicalNot>(op);
652   ASSERT_THAT(kernel, NotNull());
653
654   checkTensor(kernel->input(), input);
655   checkTensor(kernel->output(), op);
656 }
657
658 TEST_F(KernelBuilderTest, LogicalOr)
659 {
660   auto *input1 = createInputNode();
661   auto *input2 = createInputNode();
662
663   auto *op = createNode<luci::CircleLogicalOr>();
664   op->x(input1);
665   op->y(input2);
666
667   auto kernel = buildKernel<kernels::LogicalOr>(op);
668   ASSERT_THAT(kernel, NotNull());
669
670   checkTensor(kernel->input1(), input1);
671   checkTensor(kernel->input2(), input2);
672   checkTensor(kernel->output(), op);
673 }
674
675 TEST_F(KernelBuilderTest, Logistic)
676 {
677   auto *input = createInputNode();
678
679   auto *op = createNode<luci::CircleLogistic>();
680   op->x(input);
681
682   auto kernel = buildKernel<kernels::Logistic>(op);
683   ASSERT_THAT(kernel, NotNull());
684
685   checkTensor(kernel->input(), input);
686   checkTensor(kernel->output(), op);
687 }
688
689 TEST_F(KernelBuilderTest, LogSoftmax)
690 {
691   auto *input = createInputNode();
692
693   auto *op = createNode<luci::CircleLogSoftmax>();
694   op->logits(input);
695
696   auto kernel = buildKernel<kernels::LogSoftmax>(op);
697   ASSERT_THAT(kernel, NotNull());
698
699   checkTensor(kernel->input(), input);
700   checkTensor(kernel->output(), op);
701 }
702
703 TEST_F(KernelBuilderTest, Maximum)
704 {
705   auto *input1 = createInputNode();
706   auto *input2 = createInputNode();
707
708   auto *op = createNode<luci::CircleMaximum>();
709   op->x(input1);
710   op->y(input2);
711
712   auto kernel = buildKernel<kernels::Maximum>(op);
713   ASSERT_THAT(kernel, NotNull());
714
715   checkTensor(kernel->input1(), input1);
716   checkTensor(kernel->input2(), input2);
717   checkTensor(kernel->output(), op);
718 }
719
720 TEST_F(KernelBuilderTest, MaxPool2D)
721 {
722   auto *input = createInputNode();
723
724   auto *op = createNode<luci::CircleMaxPool2D>();
725   op->value(input);
726
727   op->padding(luci::Padding::SAME);
728   op->filter()->h(11);
729   op->filter()->w(13);
730   op->stride()->h(17);
731   op->stride()->w(19);
732   op->fusedActivationFunction(luci::FusedActFunc::RELU);
733
734   auto kernel = buildKernel<kernels::MaxPool2D>(op);
735   ASSERT_THAT(kernel, NotNull());
736
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()));
745 }
746
747 TEST_F(KernelBuilderTest, Mean)
748 {
749   auto *input = createInputNode();
750   auto *axes = createInputNode();
751
752   auto *op = createNode<luci::CircleMean>();
753   op->input(input);
754   op->reduction_indices(axes);
755
756   op->keep_dims(true);
757
758   auto kernel = buildKernel<kernels::Mean>(op);
759   ASSERT_THAT(kernel, NotNull());
760
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()));
765 }
766
767 TEST_F(KernelBuilderTest, Minimum)
768 {
769   auto *input1 = createInputNode();
770   auto *input2 = createInputNode();
771
772   auto *op = createNode<luci::CircleMinimum>();
773   op->x(input1);
774   op->y(input2);
775
776   auto kernel = buildKernel<kernels::Minimum>(op);
777   ASSERT_THAT(kernel, NotNull());
778
779   checkTensor(kernel->input1(), input1);
780   checkTensor(kernel->input2(), input2);
781   checkTensor(kernel->output(), op);
782 }
783
784 TEST_F(KernelBuilderTest, Mul)
785 {
786   auto *input1 = createInputNode();
787   auto *input2 = createInputNode();
788
789   auto *op = createNode<luci::CircleMul>();
790   op->x(input1);
791   op->y(input2);
792
793   op->fusedActivationFunction(luci::FusedActFunc::RELU);
794
795   auto kernel = buildKernel<kernels::Mul>(op);
796   ASSERT_THAT(kernel, NotNull());
797
798   checkTensor(kernel->input1(), input1);
799   checkTensor(kernel->input2(), input2);
800   checkTensor(kernel->output(), op);
801   EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
802 }
803
804 TEST_F(KernelBuilderTest, Neg)
805 {
806   auto *input = createInputNode();
807
808   auto *op = createNode<luci::CircleNeg>();
809   op->x(input);
810
811   auto kernel = buildKernel<kernels::Neg>(op);
812   ASSERT_THAT(kernel, NotNull());
813
814   checkTensor(kernel->input(), input);
815   checkTensor(kernel->output(), op);
816 }
817
818 TEST_F(KernelBuilderTest, NotEqual)
819 {
820   auto *x_input = createInputNode();
821   auto *y_input = createInputNode();
822
823   auto *op = createNode<luci::CircleNotEqual>();
824   op->x(x_input);
825   op->y(y_input);
826
827   auto kernel = buildKernel<kernels::NotEqual>(op);
828   ASSERT_THAT(kernel, NotNull());
829
830   checkTensor(kernel->x(), x_input);
831   checkTensor(kernel->y(), y_input);
832   checkTensor(kernel->output(), op);
833 }
834
835 TEST_F(KernelBuilderTest, Pad)
836 {
837   auto *input = createInputNode();
838   auto *paddings = createInputNode();
839
840   auto *op = createNode<luci::CirclePad>();
841   op->input(input);
842   op->paddings(paddings);
843
844   auto kernel = buildKernel<kernels::Pad>(op);
845   ASSERT_THAT(kernel, NotNull());
846
847   checkTensor(kernel->input(), input);
848   checkTensor(kernel->paddings(), paddings);
849   checkTensor(kernel->output(), op);
850 }
851
852 TEST_F(KernelBuilderTest, PadV2)
853 {
854   auto *input = createInputNode();
855   auto *paddings = createInputNode();
856   auto *constant_values = createInputNode();
857
858   auto *op = createNode<luci::CirclePadV2>();
859   op->input(input);
860   op->paddings(paddings);
861   op->constant_values(constant_values);
862
863   auto kernel = buildKernel<kernels::PadV2>(op);
864   ASSERT_THAT(kernel, NotNull());
865
866   checkTensor(kernel->input(), input);
867   checkTensor(kernel->paddings(), paddings);
868   checkTensor(kernel->constant_values(), constant_values);
869   checkTensor(kernel->output(), op);
870 }
871
872 TEST_F(KernelBuilderTest, Pow)
873 {
874   auto *input1 = createInputNode();
875   auto *input2 = createInputNode();
876
877   auto *op = createNode<luci::CirclePow>();
878   op->x(input1);
879   op->y(input2);
880
881   auto kernel = buildKernel<kernels::Pow>(op);
882   ASSERT_THAT(kernel, NotNull());
883
884   checkTensor(kernel->input1(), input1);
885   checkTensor(kernel->input2(), input2);
886   checkTensor(kernel->output(), op);
887 }
888
889 TEST_F(KernelBuilderTest, PRelu)
890 {
891   auto *input = createInputNode();
892   auto *alpha = createInputNode();
893
894   auto *op = createNode<luci::CirclePRelu>();
895   op->input(input);
896   op->alpha(alpha);
897
898   auto kernel = buildKernel<kernels::PRelu>(op);
899   ASSERT_THAT(kernel, NotNull());
900
901   checkTensor(kernel->input(), input);
902   checkTensor(kernel->alpha(), alpha);
903   checkTensor(kernel->output(), op);
904 }
905
906 TEST_F(KernelBuilderTest, Relu)
907 {
908   auto *input = createInputNode();
909
910   auto *op = createNode<luci::CircleRelu>();
911   op->features(input);
912
913   auto kernel = buildKernel<kernels::Relu>(op);
914   ASSERT_THAT(kernel, NotNull());
915
916   checkTensor(kernel->input(), input);
917   checkTensor(kernel->output(), op);
918 }
919
920 TEST_F(KernelBuilderTest, Relu6)
921 {
922   auto *input = createInputNode();
923
924   auto *op = createNode<luci::CircleRelu6>();
925   op->features(input);
926
927   auto kernel = buildKernel<kernels::Relu6>(op);
928   ASSERT_THAT(kernel, NotNull());
929
930   checkTensor(kernel->input(), input);
931   checkTensor(kernel->output(), op);
932 }
933
934 TEST_F(KernelBuilderTest, Reshape)
935 {
936   auto *input = createInputNode();
937   auto *shape = createInputNode();
938
939   auto *op = createNode<luci::CircleReshape>();
940   op->tensor(input);
941   op->shape(shape);
942
943   auto kernel = buildKernel<kernels::Reshape>(op);
944   ASSERT_THAT(kernel, NotNull());
945
946   checkTensor(kernel->input(), input);
947   checkTensor(kernel->shape(), shape);
948   checkTensor(kernel->output(), op);
949 }
950
951 TEST_F(KernelBuilderTest, ResizeBilinear)
952 {
953   auto *input = createInputNode();
954   auto *size = createInputNode();
955
956   auto *op = createNode<luci::CircleResizeBilinear>();
957   op->input(input);
958   op->size(size);
959   op->align_corners(true);
960   op->half_pixel_centers(true);
961
962   auto kernel = buildKernel<kernels::ResizeBilinear>(op);
963   ASSERT_THAT(kernel, NotNull());
964
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()));
970 }
971
972 TEST_F(KernelBuilderTest, ResizeNearestNeighbor)
973 {
974   auto *input = createInputNode();
975   auto *size = createInputNode();
976
977   auto *op = createNode<luci::CircleResizeNearestNeighbor>();
978   op->input(input);
979   op->size(size);
980   op->align_corners(true);
981
982   auto kernel = buildKernel<kernels::ResizeNearestNeighbor>(op);
983   ASSERT_THAT(kernel, NotNull());
984
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.
991 }
992
993 TEST_F(KernelBuilderTest, ReverseV2)
994 {
995   auto *input = createInputNode();
996   auto *axes = createInputNode();
997
998   auto *op = createNode<luci::CircleReverseV2>();
999   op->tensor(input);
1000   op->axis(axes);
1001
1002   auto kernel = buildKernel<kernels::ReverseV2>(op);
1003   ASSERT_THAT(kernel, NotNull());
1004
1005   checkTensor(kernel->input(), input);
1006   checkTensor(kernel->axes(), axes);
1007   checkTensor(kernel->output(), op);
1008 }
1009
1010 TEST_F(KernelBuilderTest, Rsqrt)
1011 {
1012   auto *input = createInputNode();
1013
1014   auto *op = createNode<luci::CircleRsqrt>();
1015   op->x(input);
1016
1017   auto kernel = buildKernel<kernels::Rsqrt>(op);
1018   ASSERT_THAT(kernel, NotNull());
1019
1020   checkTensor(kernel->input(), input);
1021   checkTensor(kernel->output(), op);
1022 }
1023
1024 TEST_F(KernelBuilderTest, Slice)
1025 {
1026   auto *input = createInputNode();
1027   auto *begin = createInputNode();
1028   auto *size = createInputNode();
1029
1030   auto *op = createNode<luci::CircleSlice>();
1031   op->input(input);
1032   op->begin(begin);
1033   op->size(size);
1034
1035   auto kernel = buildKernel<kernels::Slice>(op);
1036   ASSERT_THAT(kernel, NotNull());
1037
1038   checkTensor(kernel->input(), input);
1039   checkTensor(kernel->begin(), begin);
1040   checkTensor(kernel->size(), size);
1041   checkTensor(kernel->output(), op);
1042 }
1043
1044 TEST_F(KernelBuilderTest, Softmax)
1045 {
1046   auto *input = createInputNode();
1047
1048   auto *op = createNode<luci::CircleSoftmax>();
1049   op->logits(input);
1050
1051   op->beta(11.0f);
1052
1053   auto kernel = buildKernel<kernels::Softmax>(op);
1054   ASSERT_THAT(kernel, NotNull());
1055
1056   checkTensor(kernel->input(), input);
1057   checkTensor(kernel->output(), op);
1058   EXPECT_THAT(kernel->params().beta, Eq(op->beta()));
1059 }
1060
1061 TEST_F(KernelBuilderTest, SpaceToDepth)
1062 {
1063   auto *input = createInputNode();
1064
1065   auto *op = createNode<luci::CircleSpaceToDepth>();
1066   op->input(input);
1067
1068   op->block_size(11);
1069
1070   auto kernel = buildKernel<kernels::SpaceToDepth>(op);
1071   ASSERT_THAT(kernel, NotNull());
1072
1073   checkTensor(kernel->input(), input);
1074   checkTensor(kernel->output(), op);
1075   EXPECT_THAT(kernel->params().block_size, op->block_size());
1076 }
1077
1078 TEST_F(KernelBuilderTest, Split)
1079 {
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);
1085
1086   op->split_dim(axis);
1087   op->input(input);
1088
1089   op->num_split(2);
1090
1091   auto kernel = buildKernel<kernels::Split>(op);
1092   ASSERT_THAT(kernel, NotNull());
1093
1094   checkTensor(kernel->axis(), axis);
1095   checkTensor(kernel->input(), input);
1096   checkTensor(kernel->output(0), output1);
1097   checkTensor(kernel->output(1), output2);
1098 }
1099
1100 TEST_F(KernelBuilderTest, SplitV)
1101 {
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);
1108
1109   op->input(input);
1110   op->size_splits(size_splits);
1111   op->split_dim(axis);
1112
1113   op->num_split(2);
1114
1115   auto kernel = buildKernel<kernels::SplitV>(op);
1116   ASSERT_THAT(kernel, NotNull());
1117
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);
1123 }
1124
1125 TEST_F(KernelBuilderTest, Sqrt)
1126 {
1127   auto *input = createInputNode();
1128
1129   auto *op = createNode<luci::CircleSqrt>();
1130   op->x(input);
1131
1132   auto kernel = buildKernel<kernels::Sqrt>(op);
1133   ASSERT_THAT(kernel, NotNull());
1134
1135   checkTensor(kernel->input(), input);
1136   checkTensor(kernel->output(), op);
1137 }
1138
1139 TEST_F(KernelBuilderTest, SquaredDifference)
1140 {
1141   auto *input1 = createInputNode();
1142   auto *input2 = createInputNode();
1143
1144   auto *op = createNode<luci::CircleSquaredDifference>();
1145   op->x(input1);
1146   op->y(input2);
1147
1148   auto kernel = buildKernel<kernels::SquaredDifference>(op);
1149   ASSERT_THAT(kernel, NotNull());
1150
1151   checkTensor(kernel->input1(), input1);
1152   checkTensor(kernel->input2(), input2);
1153   checkTensor(kernel->output(), op);
1154 }
1155
1156 TEST_F(KernelBuilderTest, Squeeze)
1157 {
1158   auto *input = createInputNode();
1159
1160   auto *op = createNode<luci::CircleSqueeze>();
1161   op->input(input);
1162
1163   op->squeeze_dims({11, 13});
1164
1165   auto kernel = buildKernel<kernels::Squeeze>(op);
1166   ASSERT_THAT(kernel, NotNull());
1167
1168   checkTensor(kernel->input(), input);
1169   checkTensor(kernel->output(), op);
1170   EXPECT_THAT(kernel->params().squeeze_dims, ElementsAreArray(op->squeeze_dims()));
1171 }
1172
1173 TEST_F(KernelBuilderTest, StridedSlice)
1174 {
1175   auto *input = createInputNode();
1176   auto *begin = createInputNode();
1177   auto *end = createInputNode();
1178   auto *strides = createInputNode();
1179
1180   auto *op = createNode<luci::CircleStridedSlice>();
1181   op->input(input);
1182   op->begin(begin);
1183   op->end(end);
1184   op->strides(strides);
1185
1186   op->begin_mask(11);
1187   op->ellipsis_mask(13);
1188   op->end_mask(17);
1189   op->new_axis_mask(19);
1190   op->shrink_axis_mask(23);
1191
1192   auto kernel = buildKernel<kernels::StridedSlice>(op);
1193   ASSERT_THAT(kernel, NotNull());
1194
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()));
1205 }
1206
1207 TEST_F(KernelBuilderTest, Sub)
1208 {
1209   auto *input1 = createInputNode();
1210   auto *input2 = createInputNode();
1211
1212   auto *op = createNode<luci::CircleSub>();
1213   op->x(input1);
1214   op->y(input2);
1215
1216   op->fusedActivationFunction(luci::FusedActFunc::RELU);
1217
1218   auto kernel = buildKernel<kernels::Sub>(op);
1219   ASSERT_THAT(kernel, NotNull());
1220
1221   checkTensor(kernel->input1(), input1);
1222   checkTensor(kernel->input2(), input2);
1223   checkTensor(kernel->output(), op);
1224   EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
1225 }
1226
1227 TEST_F(KernelBuilderTest, Tanh)
1228 {
1229   auto *input = createInputNode();
1230
1231   auto *op = createNode<luci::CircleTanh>();
1232   op->x(input);
1233
1234   auto kernel = buildKernel<kernels::Tanh>(op);
1235   ASSERT_THAT(kernel, NotNull());
1236
1237   checkTensor(kernel->input(), input);
1238   checkTensor(kernel->output(), op);
1239 }
1240
1241 TEST_F(KernelBuilderTest, Transpose)
1242 {
1243   auto *input = createInputNode();
1244   auto *perm = createInputNode();
1245
1246   auto *op = createNode<luci::CircleTranspose>();
1247   op->a(input);
1248   op->perm(perm);
1249
1250   auto kernel = buildKernel<kernels::Transpose>(op);
1251   ASSERT_THAT(kernel, NotNull());
1252
1253   checkTensor(kernel->input(), input);
1254   checkTensor(kernel->perm(), perm);
1255   checkTensor(kernel->output(), op);
1256 }
1257
1258 TEST_F(KernelBuilderTest, TransposeConv)
1259 {
1260   auto *output_shape = createInputNode();
1261   auto *filter = createInputNode();
1262   auto *input = createInputNode();
1263   auto *bias = createInputNode();
1264
1265   auto *op = createNode<luci::CircleTransposeConv>();
1266   op->inputSizes(output_shape);
1267   op->filter(filter);
1268   op->outBackprop(input);
1269   op->bias(bias);
1270
1271   op->padding(luci::Padding::SAME);
1272   op->stride()->h(11);
1273   op->stride()->w(13);
1274
1275   auto kernel = buildKernel<kernels::TransposeConv>(op);
1276   ASSERT_THAT(kernel, NotNull());
1277
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()));
1286 }
1287
1288 TEST_F(KernelBuilderTest, Unpack)
1289 {
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);
1294
1295   op->value(input);
1296
1297   op->num(2);
1298   op->axis(11);
1299
1300   auto kernel = buildKernel<kernels::Unpack>(op);
1301   ASSERT_THAT(kernel, NotNull());
1302
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()));
1307 }
1308
1309 TEST_F(KernelBuilderTest, NonExisting1_NEG)
1310 {
1311   auto *op = createNode<luci::CircleConst>();
1312   ASSERT_ANY_THROW(buildKernel<Kernel>(op));
1313 }
1314
1315 TEST_F(KernelBuilderTest, NonExisting2_NEG)
1316 {
1317   auto *op = createNode<luci::CircleInput>();
1318   ASSERT_ANY_THROW(buildKernel<Kernel>(op));
1319 }
1320
1321 TEST_F(KernelBuilderTest, NonExisting3_NEG)
1322 {
1323   auto *op = createNode<luci::CircleOutput>();
1324   ASSERT_ANY_THROW(buildKernel<Kernel>(op));
1325 }
1326
1327 } // namespace
1328 } // namespace luci_interpreter