33bc8ec9b80bf482b9b055ef32c590c6eeb283f8
[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
20 #include <kernels/Add.h>
21 #include <kernels/ArgMax.h>
22 #include <kernels/AveragePool2D.h>
23 #include <kernels/Concatenation.h>
24 #include <kernels/Conv2D.h>
25 #include <kernels/DepthToSpace.h>
26 #include <kernels/DepthwiseConv2D.h>
27 #include <kernels/Elu.h>
28 #include <kernels/FullyConnected.h>
29 #include <kernels/L2Normalize.h>
30 #include <kernels/L2Pool2D.h>
31 #include <kernels/LeakyRelu.h>
32 #include <kernels/LocalResponseNormalization.h>
33 #include <kernels/Logistic.h>
34 #include <kernels/MaxPool2D.h>
35 #include <kernels/Mean.h>
36 #include <kernels/Mul.h>
37 #include <kernels/Pad.h>
38 #include <kernels/Reshape.h>
39 #include <kernels/Reverse.h>
40 #include <kernels/Slice.h>
41 #include <kernels/Softmax.h>
42 #include <kernels/SpaceToDepth.h>
43 #include <kernels/Split.h>
44 #include <kernels/Squeeze.h>
45 #include <kernels/StridedSlice.h>
46 #include <kernels/Transpose.h>
47 #include <kernels/TransposeConv.h>
48 #include <kernels/Unpack.h>
49
50 #include <gmock/gmock.h>
51
52 namespace luci_interpreter
53 {
54 namespace
55 {
56
57 using namespace testing;
58
59 class KernelBuilderTest : public Test
60 {
61 protected:
62   luci::CircleInput *createInputNode() { return createNode<luci::CircleInput>(); }
63
64   template <typename NodeT, typename... Args> NodeT *createNode(Args &&... args)
65   {
66     auto *node = _graph.nodes()->create<NodeT>(std::forward<Args>(args)...);
67     // The actual type does not matter for the purpose of the tests.
68     // NOTE The type is meaningless for nodes with multiple outputs (corresponding *Out nodes carry
69     //  actual output types).
70     node->dtype(loco::DataType::FLOAT32);
71     return node;
72   }
73
74   template <typename NodeOutT> NodeOutT *createNodeOut(loco::Node *node, int index)
75   {
76     auto *node_out = createNode<NodeOutT>();
77     node_out->input(node);
78     node_out->index(index);
79     return node_out;
80   }
81
82   template <typename KernelT> std::unique_ptr<KernelT> buildKernel(const luci::CircleNode *op)
83   {
84     std::unordered_map<const loco::Graph *, RuntimeGraph *> graph_to_runtime_graph;
85
86     RuntimeGraph runtime_graph(nullptr);
87     RuntimeToIR runtime_to_ir;
88     GraphLoader graph_loader(&_graph, &runtime_graph, runtime_to_ir, graph_to_runtime_graph,
89                              _node_to_tensor);
90     graph_loader.loadTensors();
91
92     KernelBuilder kernel_builder(graph_to_runtime_graph, _node_to_tensor);
93
94     auto kernel = op->accept(&kernel_builder);
95     return std::unique_ptr<KernelT>(dynamic_cast<KernelT *>(kernel.release()));
96   }
97
98   void checkTensor(const Tensor *tensor, const loco::Node *node)
99   {
100     EXPECT_THAT(tensor, Eq(_node_to_tensor.at(node)));
101   }
102
103 private:
104   loco::Graph _graph;
105   std::unordered_map<const loco::Node *, Tensor *> _node_to_tensor;
106 };
107
108 TEST_F(KernelBuilderTest, Add)
109 {
110   auto *input1 = createInputNode();
111   auto *input2 = createInputNode();
112
113   auto *op = createNode<luci::CircleAdd>();
114   op->x(input1);
115   op->y(input2);
116
117   op->fusedActivationFunction(luci::FusedActFunc::RELU);
118
119   auto kernel = buildKernel<kernels::Add>(op);
120   ASSERT_THAT(kernel, NotNull());
121
122   checkTensor(kernel->input1(), input1);
123   checkTensor(kernel->input2(), input2);
124   checkTensor(kernel->output(), op);
125   EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
126 }
127
128 TEST_F(KernelBuilderTest, ArgMax)
129 {
130   auto *input = createInputNode();
131   auto *axis = createInputNode();
132
133   auto *op = createNode<luci::CircleArgMax>();
134   op->input(input);
135   op->dimension(axis);
136
137   op->output_type(loco::DataType::FLOAT32);
138
139   auto kernel = buildKernel<kernels::ArgMax>(op);
140   ASSERT_THAT(kernel, NotNull());
141
142   checkTensor(kernel->input(), input);
143   checkTensor(kernel->axis(), axis);
144   checkTensor(kernel->output(), op);
145   EXPECT_THAT(kernel->params().output_type, Eq(op->output_type()));
146 }
147
148 TEST_F(KernelBuilderTest, AveragePool2D)
149 {
150   auto *input = createInputNode();
151
152   auto *op = createNode<luci::CircleAveragePool2D>();
153   op->value(input);
154
155   op->padding(luci::Padding::SAME);
156   op->filter()->h(11);
157   op->filter()->w(13);
158   op->stride()->h(17);
159   op->stride()->w(19);
160   op->fusedActivationFunction(luci::FusedActFunc::RELU);
161
162   auto kernel = buildKernel<kernels::AveragePool2D>(op);
163   ASSERT_THAT(kernel, NotNull());
164
165   checkTensor(kernel->input(), input);
166   checkTensor(kernel->output(), op);
167   EXPECT_THAT(kernel->params().padding, Eq(op->padding()));
168   EXPECT_THAT(kernel->params().filter_height, Eq(op->filter()->h()));
169   EXPECT_THAT(kernel->params().filter_width, Eq(op->filter()->w()));
170   EXPECT_THAT(kernel->params().stride_height, Eq(op->stride()->h()));
171   EXPECT_THAT(kernel->params().stride_width, Eq(op->stride()->w()));
172   EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
173 }
174
175 TEST_F(KernelBuilderTest, Concatenation)
176 {
177   auto *input1 = createInputNode();
178   auto *input2 = createInputNode();
179
180   auto *op = createNode<luci::CircleConcatenation>(2);
181   op->values(0, input1);
182   op->values(1, input2);
183   op->axis(11);
184
185   auto kernel = buildKernel<kernels::Concatenation>(op);
186   ASSERT_THAT(kernel, NotNull());
187
188   checkTensor(kernel->input(0), input1);
189   checkTensor(kernel->input(1), input2);
190   checkTensor(kernel->output(), op);
191   EXPECT_THAT(kernel->params().axis, Eq(op->axis()));
192 }
193
194 TEST_F(KernelBuilderTest, Conv2D)
195 {
196   auto *input = createInputNode();
197   auto *filter = createInputNode();
198   auto *bias = createInputNode();
199
200   auto *op = createNode<luci::CircleConv2D>();
201   op->input(input);
202   op->filter(filter);
203   op->bias(bias);
204
205   op->padding(luci::Padding::SAME);
206   op->stride()->h(11);
207   op->stride()->w(13);
208   op->dilation()->h(17);
209   op->dilation()->w(19);
210   op->fusedActivationFunction(luci::FusedActFunc::RELU);
211
212   auto kernel = buildKernel<kernels::Conv2D>(op);
213   ASSERT_THAT(kernel, NotNull());
214
215   checkTensor(kernel->input(), input);
216   checkTensor(kernel->filter(), filter);
217   checkTensor(kernel->bias(), bias);
218   checkTensor(kernel->output(), op);
219   EXPECT_THAT(kernel->params().padding, Eq(op->padding()));
220   EXPECT_THAT(kernel->params().stride_height, Eq(op->stride()->h()));
221   EXPECT_THAT(kernel->params().stride_width, Eq(op->stride()->w()));
222   EXPECT_THAT(kernel->params().dilation_height_factor, Eq(op->dilation()->h()));
223   EXPECT_THAT(kernel->params().dilation_width_factor, Eq(op->dilation()->w()));
224   EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
225 }
226
227 TEST_F(KernelBuilderTest, DepthToSpace)
228 {
229   auto *input = createInputNode();
230
231   auto *op = createNode<luci::CircleDepthToSpace>();
232   op->input(input);
233
234   op->block_size(11);
235
236   auto kernel = buildKernel<kernels::DepthToSpace>(op);
237   ASSERT_THAT(kernel, NotNull());
238
239   checkTensor(kernel->input(), input);
240   checkTensor(kernel->output(), op);
241   EXPECT_THAT(kernel->params().block_size, Eq(op->block_size()));
242 }
243
244 TEST_F(KernelBuilderTest, DepthwiseConv2D)
245 {
246   auto *input = createInputNode();
247   auto *filter = createInputNode();
248   auto *bias = createInputNode();
249
250   auto *op = createNode<luci::CircleDepthwiseConv2D>();
251   op->input(input);
252   op->filter(filter);
253   op->bias(bias);
254
255   op->padding(luci::Padding::SAME);
256   op->depthMultiplier(11);
257   op->stride()->h(13);
258   op->stride()->w(17);
259   op->dilation()->h(19);
260   op->dilation()->w(23);
261   op->fusedActivationFunction(luci::FusedActFunc::RELU);
262
263   auto kernel = buildKernel<kernels::DepthwiseConv2D>(op);
264   ASSERT_THAT(kernel, NotNull());
265
266   checkTensor(kernel->input(), input);
267   checkTensor(kernel->filter(), filter);
268   checkTensor(kernel->bias(), bias);
269   checkTensor(kernel->output(), op);
270   EXPECT_THAT(kernel->params().padding, Eq(op->padding()));
271   EXPECT_THAT(kernel->params().depth_multiplier, Eq(op->depthMultiplier()));
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, Elu)
280 {
281   auto *input = createInputNode();
282
283   auto *op = createNode<luci::CircleElu>();
284   op->features(input);
285
286   auto kernel = buildKernel<kernels::Elu>(op);
287   ASSERT_THAT(kernel, NotNull());
288
289   checkTensor(kernel->input(), input);
290   checkTensor(kernel->output(), op);
291 }
292
293 TEST_F(KernelBuilderTest, FullyConnected)
294 {
295   auto *input = createInputNode();
296   auto *weights = createInputNode();
297   auto *bias = createInputNode();
298
299   auto *op = createNode<luci::CircleFullyConnected>();
300   op->input(input);
301   op->weights(weights);
302   op->bias(bias);
303
304   op->fusedActivationFunction(luci::FusedActFunc::RELU);
305
306   auto kernel = buildKernel<kernels::FullyConnected>(op);
307   ASSERT_THAT(kernel, NotNull());
308
309   checkTensor(kernel->input(), input);
310   checkTensor(kernel->weights(), weights);
311   checkTensor(kernel->bias(), bias);
312   checkTensor(kernel->output(), op);
313   EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
314 }
315
316 TEST_F(KernelBuilderTest, L2Normalize)
317 {
318   auto *input = createInputNode();
319
320   auto *op = createNode<luci::CircleL2Normalize>();
321   op->x(input);
322
323   op->fusedActivationFunction(luci::FusedActFunc::RELU);
324
325   auto kernel = buildKernel<kernels::L2Normalize>(op);
326   ASSERT_THAT(kernel, NotNull());
327
328   checkTensor(kernel->input(), input);
329   checkTensor(kernel->output(), op);
330   EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
331 }
332
333 TEST_F(KernelBuilderTest, L2Pool2D)
334 {
335   auto *input = createInputNode();
336
337   auto *op = createNode<luci::CircleL2Pool2D>();
338   op->value(input);
339
340   op->padding(luci::Padding::SAME);
341   op->filter()->h(11);
342   op->filter()->w(13);
343   op->stride()->h(17);
344   op->stride()->w(19);
345   op->fusedActivationFunction(luci::FusedActFunc::RELU);
346
347   auto kernel = buildKernel<kernels::L2Pool2D>(op);
348   ASSERT_THAT(kernel, NotNull());
349
350   checkTensor(kernel->input(), input);
351   checkTensor(kernel->output(), op);
352   EXPECT_THAT(kernel->params().padding, Eq(op->padding()));
353   EXPECT_THAT(kernel->params().filter_height, Eq(op->filter()->h()));
354   EXPECT_THAT(kernel->params().filter_width, Eq(op->filter()->w()));
355   EXPECT_THAT(kernel->params().stride_height, Eq(op->stride()->h()));
356   EXPECT_THAT(kernel->params().stride_width, Eq(op->stride()->w()));
357   EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
358 }
359
360 TEST_F(KernelBuilderTest, LeakyRelu)
361 {
362   auto *input = createInputNode();
363
364   auto *op = createNode<luci::CircleLeakyRelu>();
365   op->features(input);
366
367   op->alpha(11.0f);
368
369   auto kernel = buildKernel<kernels::LeakyRelu>(op);
370   ASSERT_THAT(kernel, NotNull());
371
372   checkTensor(kernel->input(), input);
373   checkTensor(kernel->output(), op);
374   EXPECT_THAT(kernel->params().alpha, Eq(op->alpha()));
375 }
376
377 TEST_F(KernelBuilderTest, LocalResponseNormalization)
378 {
379   auto *input = createInputNode();
380
381   auto *op = createNode<luci::CircleLocalResponseNormalization>();
382   op->input(input);
383
384   op->radius(11);
385   op->bias(13.0f);
386   op->alpha(15.0f);
387   op->beta(17.0f);
388
389   auto kernel = buildKernel<kernels::LocalResponseNormalization>(op);
390   ASSERT_THAT(kernel, NotNull());
391
392   checkTensor(kernel->input(), input);
393   checkTensor(kernel->output(), op);
394   EXPECT_THAT(kernel->params().radius, Eq(op->radius()));
395   EXPECT_THAT(kernel->params().bias, Eq(op->bias()));
396   EXPECT_THAT(kernel->params().alpha, Eq(op->alpha()));
397   EXPECT_THAT(kernel->params().beta, Eq(op->beta()));
398 }
399
400 TEST_F(KernelBuilderTest, Logistic)
401 {
402   auto *input = createInputNode();
403
404   auto *op = createNode<luci::CircleLogistic>();
405   op->x(input);
406
407   auto kernel = buildKernel<kernels::Logistic>(op);
408   ASSERT_THAT(kernel, NotNull());
409
410   checkTensor(kernel->input(), input);
411   checkTensor(kernel->output(), op);
412 }
413
414 TEST_F(KernelBuilderTest, MaxPool2D)
415 {
416   auto *input = createInputNode();
417
418   auto *op = createNode<luci::CircleMaxPool2D>();
419   op->value(input);
420
421   op->padding(luci::Padding::SAME);
422   op->filter()->h(11);
423   op->filter()->w(13);
424   op->stride()->h(17);
425   op->stride()->w(19);
426   op->fusedActivationFunction(luci::FusedActFunc::RELU);
427
428   auto kernel = buildKernel<kernels::MaxPool2D>(op);
429   ASSERT_THAT(kernel, NotNull());
430
431   checkTensor(kernel->input(), input);
432   checkTensor(kernel->output(), op);
433   EXPECT_THAT(kernel->params().padding, Eq(op->padding()));
434   EXPECT_THAT(kernel->params().filter_height, Eq(op->filter()->h()));
435   EXPECT_THAT(kernel->params().filter_width, Eq(op->filter()->w()));
436   EXPECT_THAT(kernel->params().stride_height, Eq(op->stride()->h()));
437   EXPECT_THAT(kernel->params().stride_width, Eq(op->stride()->w()));
438   EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
439 }
440
441 TEST_F(KernelBuilderTest, Mean)
442 {
443   auto *input = createInputNode();
444   auto *axes = createInputNode();
445
446   auto *op = createNode<luci::CircleMean>();
447   op->input(input);
448   op->reduction_indices(axes);
449
450   op->keep_dims(true);
451
452   auto kernel = buildKernel<kernels::Mean>(op);
453   ASSERT_THAT(kernel, NotNull());
454
455   checkTensor(kernel->input(), input);
456   checkTensor(kernel->axes(), axes);
457   checkTensor(kernel->output(), op);
458   EXPECT_THAT(kernel->params().keep_dims, Eq(op->keep_dims()));
459 }
460
461 TEST_F(KernelBuilderTest, Mul)
462 {
463   auto *input1 = createInputNode();
464   auto *input2 = createInputNode();
465
466   auto *op = createNode<luci::CircleMul>();
467   op->x(input1);
468   op->y(input2);
469
470   op->fusedActivationFunction(luci::FusedActFunc::RELU);
471
472   auto kernel = buildKernel<kernels::Mul>(op);
473   ASSERT_THAT(kernel, NotNull());
474
475   checkTensor(kernel->input1(), input1);
476   checkTensor(kernel->input2(), input2);
477   checkTensor(kernel->output(), op);
478   EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
479 }
480
481 TEST_F(KernelBuilderTest, Pad)
482 {
483   auto *input = createInputNode();
484   auto *paddings = createInputNode();
485
486   auto *op = createNode<luci::CirclePad>();
487   op->input(input);
488   op->paddings(paddings);
489
490   auto kernel = buildKernel<kernels::Pad>(op);
491   ASSERT_THAT(kernel, NotNull());
492
493   checkTensor(kernel->input(), input);
494   checkTensor(kernel->paddings(), paddings);
495   checkTensor(kernel->output(), op);
496 }
497
498 TEST_F(KernelBuilderTest, Reshape)
499 {
500   auto *input = createInputNode();
501   auto *shape = createInputNode();
502
503   auto *op = createNode<luci::CircleReshape>();
504   op->tensor(input);
505   op->shape(shape);
506
507   auto kernel = buildKernel<kernels::Reshape>(op);
508   ASSERT_THAT(kernel, NotNull());
509
510   checkTensor(kernel->input(), input);
511   checkTensor(kernel->shape(), shape);
512   checkTensor(kernel->output(), op);
513 }
514
515 TEST_F(KernelBuilderTest, ReverseV2)
516 {
517   auto *input = createInputNode();
518   auto *axes = createInputNode();
519
520   auto *op = createNode<luci::CircleReverseV2>();
521   op->tensor(input);
522   op->axis(axes);
523
524   auto kernel = buildKernel<kernels::Reverse>(op);
525   ASSERT_THAT(kernel, NotNull());
526
527   checkTensor(kernel->input(), input);
528   checkTensor(kernel->axes(), axes);
529   checkTensor(kernel->output(), op);
530 }
531
532 TEST_F(KernelBuilderTest, Slice)
533 {
534   auto *input = createInputNode();
535   auto *begin = createInputNode();
536   auto *size = createInputNode();
537
538   auto *op = createNode<luci::CircleSlice>();
539   op->input(input);
540   op->begin(begin);
541   op->size(size);
542
543   auto kernel = buildKernel<kernels::Slice>(op);
544   ASSERT_THAT(kernel, NotNull());
545
546   checkTensor(kernel->input(), input);
547   checkTensor(kernel->begin(), begin);
548   checkTensor(kernel->size(), size);
549   checkTensor(kernel->output(), op);
550 }
551
552 TEST_F(KernelBuilderTest, Softmax)
553 {
554   auto *input = createInputNode();
555
556   auto *op = createNode<luci::CircleSoftmax>();
557   op->logits(input);
558
559   op->beta(11.0f);
560
561   auto kernel = buildKernel<kernels::Softmax>(op);
562   ASSERT_THAT(kernel, NotNull());
563
564   checkTensor(kernel->input(), input);
565   checkTensor(kernel->output(), op);
566   EXPECT_THAT(kernel->params().beta, Eq(op->beta()));
567 }
568
569 TEST_F(KernelBuilderTest, SpaceToDepth)
570 {
571   auto *input = createInputNode();
572
573   auto *op = createNode<luci::CircleSpaceToDepth>();
574   op->input(input);
575
576   op->block_size(11);
577
578   auto kernel = buildKernel<kernels::SpaceToDepth>(op);
579   ASSERT_THAT(kernel, NotNull());
580
581   checkTensor(kernel->input(), input);
582   checkTensor(kernel->output(), op);
583   EXPECT_THAT(kernel->params().block_size, op->block_size());
584 }
585
586 TEST_F(KernelBuilderTest, Split)
587 {
588   auto *axis = createInputNode();
589   auto *input = createInputNode();
590   auto *op = createNode<luci::CircleSplit>();
591   auto *output1 = createNodeOut<luci::CircleSplitOut>(op, 0);
592   auto *output2 = createNodeOut<luci::CircleSplitOut>(op, 1);
593
594   op->split_dim(axis);
595   op->input(input);
596
597   op->num_split(2);
598
599   auto kernel = buildKernel<kernels::Split>(op);
600   ASSERT_THAT(kernel, NotNull());
601
602   checkTensor(kernel->axis(), axis);
603   checkTensor(kernel->input(), input);
604   checkTensor(kernel->output(0), output1);
605   checkTensor(kernel->output(1), output2);
606 }
607
608 TEST_F(KernelBuilderTest, Squeeze)
609 {
610   auto *input = createInputNode();
611
612   auto *op = createNode<luci::CircleSqueeze>();
613   op->input(input);
614
615   op->squeeze_dims({11, 13});
616
617   auto kernel = buildKernel<kernels::Squeeze>(op);
618   ASSERT_THAT(kernel, NotNull());
619
620   checkTensor(kernel->input(), input);
621   checkTensor(kernel->output(), op);
622   EXPECT_THAT(kernel->params().squeeze_dims, ElementsAreArray(op->squeeze_dims()));
623 }
624
625 TEST_F(KernelBuilderTest, StridedSlice)
626 {
627   auto *input = createInputNode();
628   auto *begin = createInputNode();
629   auto *end = createInputNode();
630   auto *strides = createInputNode();
631
632   auto *op = createNode<luci::CircleStridedSlice>();
633   op->input(input);
634   op->begin(begin);
635   op->end(end);
636   op->strides(strides);
637
638   op->begin_mask(11);
639   op->ellipsis_mask(13);
640   op->end_mask(17);
641   op->new_axis_mask(19);
642   op->shrink_axis_mask(23);
643
644   auto kernel = buildKernel<kernels::StridedSlice>(op);
645   ASSERT_THAT(kernel, NotNull());
646
647   checkTensor(kernel->input(), input);
648   checkTensor(kernel->begin(), begin);
649   checkTensor(kernel->end(), end);
650   checkTensor(kernel->strides(), strides);
651   checkTensor(kernel->output(), op);
652   EXPECT_THAT(kernel->params().begin_mask, Eq(op->begin_mask()));
653   EXPECT_THAT(kernel->params().ellipsis_mask, Eq(op->ellipsis_mask()));
654   EXPECT_THAT(kernel->params().end_mask, Eq(op->end_mask()));
655   EXPECT_THAT(kernel->params().new_axis_mask, Eq(op->new_axis_mask()));
656   EXPECT_THAT(kernel->params().shrink_axis_mask, Eq(op->shrink_axis_mask()));
657 }
658
659 TEST_F(KernelBuilderTest, Transpose)
660 {
661   auto *input = createInputNode();
662   auto *perm = createInputNode();
663
664   auto *op = createNode<luci::CircleTranspose>();
665   op->a(input);
666   op->perm(perm);
667
668   auto kernel = buildKernel<kernels::Transpose>(op);
669   ASSERT_THAT(kernel, NotNull());
670
671   checkTensor(kernel->input(), input);
672   checkTensor(kernel->perm(), perm);
673   checkTensor(kernel->output(), op);
674 }
675
676 TEST_F(KernelBuilderTest, TransposeConv)
677 {
678   auto *output_shape = createInputNode();
679   auto *filter = createInputNode();
680   auto *input = createInputNode();
681
682   auto *op = createNode<luci::CircleTransposeConv>();
683   op->inputSizes(output_shape);
684   op->filter(filter);
685   op->outBackprop(input);
686
687   op->padding(luci::Padding::SAME);
688   op->stride()->h(11);
689   op->stride()->w(13);
690
691   auto kernel = buildKernel<kernels::TransposeConv>(op);
692   ASSERT_THAT(kernel, NotNull());
693
694   checkTensor(kernel->output_shape(), output_shape);
695   checkTensor(kernel->filter(), filter);
696   checkTensor(kernel->input(), input);
697   checkTensor(kernel->output(), op);
698   EXPECT_THAT(kernel->params().padding, Eq(op->padding()));
699   EXPECT_THAT(kernel->params().stride_height, Eq(op->stride()->h()));
700   EXPECT_THAT(kernel->params().stride_width, Eq(op->stride()->w()));
701 }
702
703 TEST_F(KernelBuilderTest, Unpack)
704 {
705   auto *input = createInputNode();
706   auto *op = createNode<luci::CircleUnpack>();
707   auto *output1 = createNodeOut<luci::CircleUnpackOut>(op, 0);
708   auto *output2 = createNodeOut<luci::CircleUnpackOut>(op, 1);
709
710   op->value(input);
711
712   op->num(2);
713   op->axis(11);
714
715   auto kernel = buildKernel<kernels::Unpack>(op);
716   ASSERT_THAT(kernel, NotNull());
717
718   checkTensor(kernel->input(), input);
719   checkTensor(kernel->output(0), output1);
720   checkTensor(kernel->output(1), output2);
721   EXPECT_THAT(kernel->params().axis, Eq(op->axis()));
722 }
723
724 TEST_F(KernelBuilderTest, NonExisting1_NEG)
725 {
726   auto *op = createNode<luci::CircleConst>();
727   ASSERT_ANY_THROW(buildKernel<Kernel>(op));
728 }
729
730 TEST_F(KernelBuilderTest, NonExisting2_NEG)
731 {
732   auto *op = createNode<luci::CircleInput>();
733   ASSERT_ANY_THROW(buildKernel<Kernel>(op));
734 }
735
736 TEST_F(KernelBuilderTest, NonExisting3_NEG)
737 {
738   auto *op = createNode<luci::CircleOutput>();
739   ASSERT_ANY_THROW(buildKernel<Kernel>(op));
740 }
741
742 } // namespace
743 } // namespace luci_interpreter