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 "kernels/Conv2D.h"
18 #include "kernels/TestUtils.h"
19 #include "luci_interpreter/TestMemoryManager.h"
21 namespace luci_interpreter
28 using namespace testing;
30 class Conv2DTest : public ::testing::Test
33 void SetUp() override { _memory_manager = std::make_unique<TestMemoryManager>(); }
35 std::unique_ptr<IMemoryManager> _memory_manager;
38 TEST_F(Conv2DTest, Float)
40 Shape input_shape{1, 4, 3, 2};
41 Shape filter_shape{2, 2, 2, 2};
43 std::vector<float> input_data{
44 1, 2, 3, 4, 5, 6, // row = 0
45 7, 8, 9, 10, 11, 12, // row = 1
46 13, 14, 15, 16, 17, 18, // row = 2
47 19, 20, 21, 22, 23, 24, // row = 3
49 std::vector<float> filter_data{
50 1, 2, -3, -4, // out = 0, row = 0
51 -5, 6, -7, 8, // out = 1, row = 0
52 4, -2, 3, -1, // out = 0, row = 1
53 -8, -6, 7, 5, // out = 1, row = 1
55 std::vector<float> bias_data{1, 2};
57 makeInputTensor<DataType::FLOAT32>(input_shape, input_data, _memory_manager.get());
58 Tensor filter_tensor =
59 makeInputTensor<DataType::FLOAT32>(filter_shape, filter_data, _memory_manager.get());
61 makeInputTensor<DataType::FLOAT32>(bias_shape, bias_data, _memory_manager.get());
62 Tensor im2col(DataType::FLOAT32, Shape({}), {}, "");
63 Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
65 Conv2DParams params{};
66 params.padding = Padding::VALID;
67 params.stride_height = 2;
68 params.stride_width = 1;
69 params.dilation_height_factor = 1;
70 params.dilation_width_factor = 1;
71 params.activation = Activation::RELU;
73 Conv2D kernel(&input_tensor, &filter_tensor, &bias_tensor, &output_tensor, &im2col, params);
75 _memory_manager->allocate_memory(im2col);
76 _memory_manager->allocate_memory(output_tensor);
79 std::vector<float> ref_output_data{
80 11, 16, 7, 20, // row = 0
81 0, 40, 0, 44, // row = 1
83 std::vector<int32_t> ref_output_shape{1, 2, 2, 2};
84 EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data));
85 EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
88 TEST_F(Conv2DTest, FloatPointwise)
90 Shape input_shape{1, 2, 2, 2};
91 Shape filter_shape{2, 1, 1, 2};
93 std::vector<float> input_data{
94 1, 2, // row = 0, col = 0
95 3, 4, // row = 0, col = 1
96 5, 6, // row = 1, col = 0
97 7, 8, // row = 1, col = 1
99 std::vector<float> filter_data{
103 std::vector<float> bias_data{1, 2};
104 Tensor input_tensor =
105 makeInputTensor<DataType::FLOAT32>(input_shape, input_data, _memory_manager.get());
106 Tensor filter_tensor =
107 makeInputTensor<DataType::FLOAT32>(filter_shape, filter_data, _memory_manager.get());
109 makeInputTensor<DataType::FLOAT32>(bias_shape, bias_data, _memory_manager.get());
110 Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
111 Tensor im2col(DataType::FLOAT32, Shape({}), {}, "");
113 Conv2DParams params{};
114 params.padding = Padding::VALID;
115 params.stride_height = 1;
116 params.stride_width = 1;
117 params.dilation_height_factor = 1;
118 params.dilation_width_factor = 1;
119 params.activation = Activation::RELU;
121 Conv2D kernel(&input_tensor, &filter_tensor, &bias_tensor, &output_tensor, &im2col, params);
123 _memory_manager->allocate_memory(im2col);
124 _memory_manager->allocate_memory(output_tensor);
127 std::vector<float> ref_output_data{
128 4, 7, 6, 9, // row = 0
129 8, 11, 10, 13, // row = 1
131 std::vector<int32_t> ref_output_shape{1, 2, 2, 2};
132 EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data));
133 EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
136 TEST_F(Conv2DTest, FloatCheck)
138 Shape input_shape{2, 2, 4, 1};
139 Shape filter_shape{3, 2, 2, 1};
141 std::vector<float> input_data{
143 1, 1, 1, 1, // row = 1
144 2, 2, 2, 2, // row = 2
146 1, 2, 3, 4, // row = 1
147 1, 2, 3, 4, // row = 2
149 std::vector<float> filter_data{
150 1, 2, 3, 4, // first 2x2 filter
151 -1, 1, -1, 1, // second 2x2 filter
152 -1, -1, 1, 1, // third 2x2 filter
154 std::vector<float> bias_data{1, 2, 3};
155 Tensor input_tensor =
156 makeInputTensor<DataType::FLOAT32>(input_shape, input_data, _memory_manager.get());
157 Tensor filter_tensor =
158 makeInputTensor<DataType::FLOAT32>(filter_shape, filter_data, _memory_manager.get());
160 makeInputTensor<DataType::FLOAT32>(bias_shape, bias_data, _memory_manager.get());
161 Tensor im2col(DataType::FLOAT32, Shape({}), {}, "");
162 Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
164 Conv2DParams params{};
165 params.padding = Padding::VALID;
166 params.stride_height = 2;
167 params.stride_width = 2;
168 params.dilation_height_factor = 1;
169 params.dilation_width_factor = 1;
170 params.activation = Activation::NONE;
172 Conv2D kernel(&input_tensor, &filter_tensor, &bias_tensor, &output_tensor, &im2col, params);
174 _memory_manager->allocate_memory(output_tensor);
175 _memory_manager->allocate_memory(im2col);
178 std::vector<float> ref_output_data{
179 18, 2, 5, // first batch, left
180 18, 2, 5, // first batch, right
181 17, 4, 3, // second batch, left
182 37, 4, 3, // second batch, right
184 std::vector<int32_t> ref_output_shape{2, 1, 2, 3};
185 EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data));
186 EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
189 TEST_F(Conv2DTest, Uint8)
191 std::vector<float> input_data{
193 1, 1, 1, 1, // row = 1
194 2, 2, 2, 2, // row = 2
196 1, 2, 3, 4, // row = 1
197 1, 2, 3, 4, // row = 2
199 std::vector<float> filter_data{
200 1, 2, 3, 4, // first 2x2 filter
201 -1, 1, -1, 1, // second 2x2 filter
202 -1, -1, 1, 1, // third 2x2 filter
204 std::vector<float> bias_data{1, 2, 3};
206 std::pair<float, int32_t> input_quant_param = quantizationParams<uint8_t>(-63.5, 64);
207 std::pair<float, int32_t> output_quant_param = quantizationParams<uint8_t>(-127, 128);
209 Tensor input_tensor =
210 makeInputTensor<DataType::U8>({2, 2, 4, 1}, input_quant_param.first, input_quant_param.second,
211 input_data, _memory_manager.get());
212 Tensor filter_tensor =
213 makeInputTensor<DataType::U8>({3, 2, 2, 1}, input_quant_param.first, input_quant_param.second,
214 filter_data, _memory_manager.get());
215 Tensor bias_tensor = makeInputTensor<DataType::S32>(
216 {3}, input_quant_param.first * input_quant_param.first, 0, bias_data, _memory_manager.get());
217 Tensor im2col(DataType::U8, Shape({}), {}, "");
218 Tensor output_tensor =
219 makeOutputTensor(DataType::U8, output_quant_param.first, output_quant_param.second);
221 Conv2DParams params{};
222 params.padding = Padding::VALID;
223 params.stride_height = 2;
224 params.stride_width = 2;
225 params.dilation_height_factor = 1;
226 params.dilation_width_factor = 1;
227 params.activation = Activation::NONE;
229 Conv2D kernel(&input_tensor, &filter_tensor, &bias_tensor, &output_tensor, &im2col, params);
231 _memory_manager->allocate_memory(output_tensor);
232 _memory_manager->allocate_memory(im2col);
235 std::vector<float> ref_output_data{
236 18, 2, 5, // first batch, left
237 18, 2, 5, // first batch, right
238 17, 4, 3, // second batch, left
239 37, 4, 3, // second batch, right
241 std::vector<int32_t> ref_output_shape{2, 1, 2, 3};
242 EXPECT_THAT(dequantizeTensorData(output_tensor), FloatArrayNear(ref_output_data));
243 EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
246 TEST_F(Conv2DTest, Uint8_CWQ)
248 const int output_channels = 3;
249 std::vector<float> input_data{
251 1, 1, 1, 1, // row = 1
252 2, 2, 2, 2, // row = 2
254 1, 2, 3, 4, // row = 1
255 1, 2, 3, 4, // row = 2
257 std::vector<float> filter_data{
258 1, 2, 3, 4, // first 2x2 filter
259 -1, 1, -1, 1, // second 2x2 filter
260 -1, -1, 1, 1, // third 2x2 filter
262 std::vector<float> bias_data{1, 2, 3};
263 Shape filter_shape{output_channels, 2, 2, 1};
265 std::pair<float, int32_t> input_quant_param = quantizationParams<uint8_t>(0, 4);
266 std::pair<float, int32_t> output_quant_param = quantizationParams<uint8_t>(-127, 128);
268 std::vector<std::pair<float, int32_t>> filter_quant_params;
269 filter_quant_params.push_back(quantizationParams<uint8_t>(0, 4));
270 filter_quant_params.push_back(quantizationParams<uint8_t>(-1, 1));
271 filter_quant_params.push_back(quantizationParams<uint8_t>(-1, 1));
273 std::vector<float> filter_scales;
274 std::vector<int32_t> filter_zerops;
275 for (auto iter : filter_quant_params)
277 filter_scales.push_back(iter.first);
278 filter_zerops.push_back(iter.second);
281 std::vector<float> bias_scales;
282 for (int i = 0; i < output_channels; ++i)
283 bias_scales.push_back(filter_quant_params[i].first * input_quant_param.first);
284 std::vector<int32_t> zerop(output_channels, 0);
286 Tensor input_tensor =
287 makeInputTensor<DataType::U8>({2, 2, 4, 1}, input_quant_param.first, input_quant_param.second,
288 input_data, _memory_manager.get());
289 Tensor filter_tensor = makeInputTensor<DataType::U8>(filter_shape, filter_scales, filter_zerops,
290 0, filter_data, _memory_manager.get());
291 Tensor bias_tensor = makeInputTensor<DataType::S32>({output_channels}, bias_scales, zerop, 0,
292 bias_data, _memory_manager.get());
293 Tensor im2col(DataType::U8, Shape({}), {}, "");
294 Tensor output_tensor =
295 makeOutputTensor(DataType::U8, output_quant_param.first, output_quant_param.second);
297 Conv2DParams params{};
298 params.padding = Padding::VALID;
299 params.stride_height = 2;
300 params.stride_width = 2;
301 params.dilation_height_factor = 1;
302 params.dilation_width_factor = 1;
303 params.activation = Activation::NONE;
305 Conv2D kernel(&input_tensor, &filter_tensor, &bias_tensor, &output_tensor, &im2col, params);
307 _memory_manager->allocate_memory(output_tensor);
308 _memory_manager->allocate_memory(im2col);
311 std::vector<float> ref_output_data{
312 18, 2, 5, // first batch, left
313 18, 2, 5, // first batch, right
314 17, 4, 3, // second batch, left
315 37, 4, 3, // second batch, right
317 std::vector<int32_t> ref_output_shape{2, 1, 2, 3};
318 EXPECT_THAT(dequantizeTensorData(output_tensor), FloatArrayNear(ref_output_data));
319 EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
322 TEST_F(Conv2DTest, SInt8_CWQ)
324 const int output_channels = 3;
325 std::vector<float> input_data{
327 1, 1, 1, 1, // row = 1
328 2, 2, 2, 2, // row = 2
330 1, 2, 3, 4, // row = 1
331 1, 2, 3, 4, // row = 2
333 std::vector<float> filter_data{
334 1, 2, 3, 4, // first 2x2 filter
335 -1, 1, -1, 1, // second 2x2 filter
336 -1, -1, 1, 1, // third 2x2 filter
338 std::vector<float> bias_data{1, 2, 3};
339 Shape filter_shape{output_channels, 2, 2, 1};
341 std::pair<float, int32_t> input_quant_param = quantizationParams<int8_t>(0, 4);
342 std::pair<float, int32_t> output_quant_param = quantizationParams<int8_t>(-127, 128);
344 std::vector<std::pair<float, int32_t>> filter_quant_params;
345 filter_quant_params.push_back(std::pair<float, int32_t>(0.5, 0));
346 filter_quant_params.push_back(std::pair<float, int32_t>(0.25, 0));
347 filter_quant_params.push_back(std::pair<float, int32_t>(0.125, 0));
349 std::vector<float> filter_scales;
350 std::vector<int32_t> filter_zerops;
351 for (auto iter : filter_quant_params)
353 filter_scales.push_back(iter.first);
354 filter_zerops.push_back(iter.second);
357 std::vector<float> bias_scales;
358 for (int i = 0; i < output_channels; ++i)
359 bias_scales.push_back(filter_quant_params[i].first * input_quant_param.first);
360 std::vector<int32_t> zerop(output_channels, 0);
362 Tensor input_tensor =
363 makeInputTensor<DataType::S8>({2, 2, 4, 1}, input_quant_param.first, input_quant_param.second,
364 input_data, _memory_manager.get());
365 Tensor filter_tensor = makeInputTensor<DataType::S8>(filter_shape, filter_scales, filter_zerops,
366 0, filter_data, _memory_manager.get());
367 Tensor bias_tensor = makeInputTensor<DataType::S32>({output_channels}, bias_scales, zerop, 0,
368 bias_data, _memory_manager.get());
369 Tensor im2col(DataType::S8, Shape({}), {}, "");
370 Tensor output_tensor =
371 makeOutputTensor(DataType::S8, output_quant_param.first, output_quant_param.second);
373 Conv2DParams params{};
374 params.padding = Padding::VALID;
375 params.stride_height = 2;
376 params.stride_width = 2;
377 params.dilation_height_factor = 1;
378 params.dilation_width_factor = 1;
379 params.activation = Activation::NONE;
381 Conv2D kernel(&input_tensor, &filter_tensor, &bias_tensor, &output_tensor, &im2col, params);
383 _memory_manager->allocate_memory(output_tensor);
384 _memory_manager->allocate_memory(im2col);
387 std::vector<float> ref_output_data{
388 18, 2, 5, // first batch, left
389 18, 2, 5, // first batch, right
390 17, 4, 3, // second batch, left
391 37, 4, 3, // second batch, right
393 std::vector<int32_t> ref_output_shape{2, 1, 2, 3};
394 EXPECT_THAT(dequantizeTensorData(output_tensor), FloatArrayNear(ref_output_data));
395 EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
398 TEST_F(Conv2DTest, SInt16)
400 Shape input_shape{1, 4, 3, 2};
401 Shape filter_shape{2, 2, 2, 2};
403 std::vector<int32_t> ref_output_shape{1, 2, 2, 2};
405 std::vector<float> input_data{
406 1, 2, 3, 4, 5, 6, // row = 0
407 7, 8, 9, 10, 11, 12, // row = 1
408 13, 14, 15, 16, 17, 18, // row = 2
409 19, 20, 21, 22, 23, 24, // row = 3
411 std::vector<float> filter_data{
412 1, 2, -3, -4, // out = 0, row = 0
413 -5, 6, -7, 8, // out = 1, row = 0
414 4, -2, 3, -1, // out = 0, row = 1
415 -8, -6, 7, 5, // out = 1, row = 1
417 std::vector<float> bias_data{1, 2};
418 std::vector<float> ref_output_data{
419 11, 16, 7, 20, // row = 0
420 0, 40, 0, 44, // row = 1
423 Tensor input_tensor =
424 makeInputTensor<DataType::S16>(input_shape, 0.25, 0, input_data, _memory_manager.get());
425 Tensor filter_tensor =
426 makeInputTensor<DataType::S16>(filter_shape, 0.2, 0, filter_data, _memory_manager.get());
428 makeInputTensor<DataType::S64>(bias_shape, 0.25 * 0.2, 0, bias_data, _memory_manager.get());
429 Tensor im2col(DataType::S16, Shape({}), {}, "");
430 Tensor output_tensor = makeOutputTensor(DataType::S16, 0.5, 0);
432 Conv2DParams params{};
433 params.padding = Padding::VALID;
434 params.stride_height = 2;
435 params.stride_width = 1;
436 params.dilation_height_factor = 1;
437 params.dilation_width_factor = 1;
438 params.activation = Activation::RELU;
440 Conv2D kernel(&input_tensor, &filter_tensor, &bias_tensor, &output_tensor, &im2col, params);
442 _memory_manager->allocate_memory(output_tensor);
443 _memory_manager->allocate_memory(im2col);
446 EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
447 EXPECT_THAT(dequantizeTensorData(output_tensor), FloatArrayNear(ref_output_data));
450 TEST_F(Conv2DTest, SInt16_CWQ_weights)
452 Shape input_shape{1, 2, 2, 2}; // Batch x H x W x C
453 Shape filter_shape{3, 1, 1, 2}; // Out channels x H x W x In Channels
455 std::vector<int32_t> ref_output_shape{1, 2, 2, 3};
457 std::vector<float> input_data{
458 1, 2, // row = 0, col 0
459 3, 4, // row = 0, col 1
460 5, 6, // row = 1, col 0
461 7, 8, // row = 1, col 1
463 std::vector<float> filter_data{
468 std::vector<float> bias_data{1, 10, 5};
469 std::vector<float> ref_output_data{
470 0, 5, 4, // row 0, col 0
471 1, 1, 8, // row 0, col 1
472 3, 0, 12, // row 1, col 0
473 5, 0, 16, // row 1, col 1
476 float input_scale = 0.25f;
477 float output_scale = 0.05f;
478 std::vector<float> filter_scales = {0.25f, 0.2f, 0.1f};
479 std::vector<float> bias_scales;
480 for (int i = 0; i < filter_scales.size(); ++i)
481 bias_scales.push_back(filter_scales[i] * input_scale);
482 std::vector<int32_t> zerop = {0, 0, 0};
484 Tensor input_tensor =
485 makeInputTensor<DataType::S16>(input_shape, input_scale, 0, input_data, _memory_manager.get());
486 Tensor filter_tensor = makeInputTensor<DataType::S16>(filter_shape, filter_scales, zerop, 0,
487 filter_data, _memory_manager.get());
488 Tensor bias_tensor = makeInputTensor<DataType::S64>(bias_shape, bias_scales, zerop, 0, bias_data,
489 _memory_manager.get());
490 Tensor im2col(DataType::S16, Shape({}), {}, "");
491 Tensor output_tensor = makeOutputTensor(DataType::S16, output_scale, 0);
493 Conv2DParams params{};
494 params.padding = Padding::VALID;
495 params.stride_height = 1;
496 params.stride_width = 1;
497 params.dilation_height_factor = 1;
498 params.dilation_width_factor = 1;
499 params.activation = Activation::RELU;
501 Conv2D kernel(&input_tensor, &filter_tensor, &bias_tensor, &output_tensor, &im2col, params);
503 _memory_manager->allocate_memory(output_tensor);
504 _memory_manager->allocate_memory(im2col);
507 EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
508 EXPECT_THAT(dequantizeTensorData(output_tensor), FloatArrayNear(ref_output_data));
511 TEST_F(Conv2DTest, Unsupported_Type_Configure_NEG)
513 Shape input_shape{1, 4, 3, 2};
514 Shape filter_shape{2, 2, 2, 2};
516 std::vector<int32_t> input_data{
517 1, 2, 3, 4, 5, 6, // row = 0
518 7, 8, 9, 10, 11, 12, // row = 1
519 13, 14, 15, 16, 17, 18, // row = 2
520 19, 20, 21, 22, 23, 24, // row = 3
522 std::vector<float> filter_data{
523 1, 2, -3, -4, // out = 0, row = 0
524 -5, 6, -7, 8, // out = 1, row = 0
525 4, -2, 3, -1, // out = 0, row = 1
526 -8, -6, 7, 5, // out = 1, row = 1
528 std::vector<float> bias_data{1, 2};
529 Tensor input_tensor =
530 makeInputTensor<DataType::S32>(input_shape, input_data, _memory_manager.get());
531 Tensor filter_tensor =
532 makeInputTensor<DataType::FLOAT32>(filter_shape, filter_data, _memory_manager.get());
534 makeInputTensor<DataType::FLOAT32>(bias_shape, bias_data, _memory_manager.get());
535 Tensor im2col(DataType::FLOAT32, Shape({}), {}, "");
536 Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
538 Conv2DParams params{};
539 params.padding = Padding::VALID;
540 params.stride_height = 2;
541 params.stride_width = 1;
542 params.dilation_height_factor = 1;
543 params.dilation_width_factor = 1;
544 params.activation = Activation::RELU;
546 Conv2D kernel(&input_tensor, &filter_tensor, &bias_tensor, &output_tensor, &im2col, params);
547 EXPECT_ANY_THROW(kernel.configure());
550 TEST_F(Conv2DTest, Invalid_Bias_Type_NEG)
552 Shape input_shape{1, 4, 3, 2};
553 Shape filter_shape{2, 2, 2, 2};
555 std::vector<float> input_data{
556 1, 2, 3, 4, 5, 6, // row = 0
557 7, 8, 9, 10, 11, 12, // row = 1
558 13, 14, 15, 16, 17, 18, // row = 2
559 19, 20, 21, 22, 23, 24, // row = 3
561 std::vector<float> filter_data{
562 1, 2, -3, -4, // out = 0, row = 0
563 -5, 6, -7, 8, // out = 1, row = 0
564 4, -2, 3, -1, // out = 0, row = 1
565 -8, -6, 7, 5, // out = 1, row = 1
567 std::vector<uint8_t> bias_data{1, 2};
568 Tensor input_tensor =
569 makeInputTensor<DataType::FLOAT32>(input_shape, input_data, _memory_manager.get());
570 Tensor filter_tensor =
571 makeInputTensor<DataType::FLOAT32>(filter_shape, filter_data, _memory_manager.get());
572 Tensor bias_tensor = makeInputTensor<DataType::U8>(bias_shape, bias_data, _memory_manager.get());
573 Tensor im2col(DataType::FLOAT32, Shape({}), {}, "");
574 Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
576 Conv2DParams params{};
577 params.padding = Padding::VALID;
578 params.stride_height = 2;
579 params.stride_width = 1;
580 params.dilation_height_factor = 1;
581 params.dilation_width_factor = 1;
582 params.activation = Activation::RELU;
584 Conv2D kernel(&input_tensor, &filter_tensor, &bias_tensor, &output_tensor, &im2col, params);
585 EXPECT_ANY_THROW(kernel.configure());
588 TEST_F(Conv2DTest, Invalid_Bias_Data_NEG)
590 Shape input_shape{1, 4, 3, 2};
591 Shape filter_shape{2, 2, 2, 2};
593 std::vector<float> input_data{
594 1, 2, 3, 4, 5, 6, // row = 0
595 7, 8, 9, 10, 11, 12, // row = 1
596 13, 14, 15, 16, 17, 18, // row = 2
597 19, 20, 21, 22, 23, 24, // row = 3
599 std::vector<float> filter_data{
600 1, 2, -3, -4, // out = 0, row = 0
601 -5, 6, -7, 8, // out = 1, row = 0
602 4, -2, 3, -1, // out = 0, row = 1
603 -8, -6, 7, 5, // out = 1, row = 1
605 std::vector<float> bias_data{1, 2, 3};
606 Tensor input_tensor =
607 makeInputTensor<DataType::FLOAT32>(input_shape, input_data, _memory_manager.get());
608 Tensor filter_tensor =
609 makeInputTensor<DataType::FLOAT32>(filter_shape, filter_data, _memory_manager.get());
611 makeInputTensor<DataType::FLOAT32>(bias_shape, bias_data, _memory_manager.get());
612 Tensor im2col(DataType::FLOAT32, Shape({}), {}, "");
613 Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
615 Conv2DParams params{};
616 params.padding = Padding::VALID;
617 params.stride_height = 2;
618 params.stride_width = 1;
619 params.dilation_height_factor = 1;
620 params.dilation_width_factor = 1;
621 params.activation = Activation::RELU;
623 Conv2D kernel(&input_tensor, &filter_tensor, &bias_tensor, &output_tensor, &im2col, params);
624 EXPECT_ANY_THROW(kernel.configure());
627 TEST_F(Conv2DTest, Invalid_Input_Shape_NEG)
629 Shape input_shape{1, 4, 6, 1};
630 Shape filter_shape{2, 2, 2, 2};
632 std::vector<float> input_data{
633 1, 2, 3, 4, 5, 6, // row = 0
634 7, 8, 9, 10, 11, 12, // row = 1
635 13, 14, 15, 16, 17, 18, // row = 2
636 19, 20, 21, 22, 23, 24, // row = 3
638 std::vector<float> filter_data{
639 1, 2, -3, -4, // out = 0, row = 0
640 -5, 6, -7, 8, // out = 1, row = 0
641 4, -2, 3, -1, // out = 0, row = 1
642 -8, -6, 7, 5, // out = 1, row = 1
644 std::vector<float> bias_data{1, 2};
645 Tensor input_tensor =
646 makeInputTensor<DataType::FLOAT32>(input_shape, input_data, _memory_manager.get());
647 Tensor filter_tensor =
648 makeInputTensor<DataType::FLOAT32>(filter_shape, filter_data, _memory_manager.get());
650 makeInputTensor<DataType::FLOAT32>(bias_shape, bias_data, _memory_manager.get());
651 Tensor im2col(DataType::FLOAT32, Shape({}), {}, "");
652 Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
654 Conv2DParams params{};
655 params.padding = Padding::VALID;
656 params.stride_height = 2;
657 params.stride_width = 1;
658 params.dilation_height_factor = 1;
659 params.dilation_width_factor = 1;
660 params.activation = Activation::RELU;
662 Conv2D kernel(&input_tensor, &filter_tensor, &bias_tensor, &output_tensor, &im2col, params);
663 EXPECT_ANY_THROW(kernel.configure());
666 TEST_F(Conv2DTest, Invalid_fused_act_tanh_NEG)
668 Shape input_shape{1, 4, 3, 2};
669 Shape filter_shape{2, 2, 2, 2};
671 std::vector<float> input_data{
672 1, 2, 3, 4, 5, 6, // row = 0
673 7, 8, 9, 10, 11, 12, // row = 1
674 13, 14, 15, 16, 17, 18, // row = 2
675 19, 20, 21, 22, 23, 24, // row = 3
677 std::vector<float> filter_data{
678 1, 2, -3, -4, // out = 0, row = 0
679 -5, 6, -7, 8, // out = 1, row = 0
680 4, -2, 3, -1, // out = 0, row = 1
681 -8, -6, 7, 5, // out = 1, row = 1
683 std::vector<float> bias_data{1, 2};
684 Tensor input_tensor =
685 makeInputTensor<DataType::FLOAT32>(input_shape, input_data, _memory_manager.get());
686 Tensor filter_tensor =
687 makeInputTensor<DataType::FLOAT32>(filter_shape, filter_data, _memory_manager.get());
689 makeInputTensor<DataType::FLOAT32>(bias_shape, bias_data, _memory_manager.get());
690 Tensor im2col(DataType::FLOAT32, Shape({}), {}, "");
691 Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
693 Conv2DParams params{};
694 params.padding = Padding::VALID;
695 params.stride_height = 2;
696 params.stride_width = 1;
697 params.dilation_height_factor = 1;
698 params.dilation_width_factor = 1;
699 params.activation = Activation::TANH;
701 Conv2D kernel(&input_tensor, &filter_tensor, &bias_tensor, &output_tensor, &im2col, params);
702 EXPECT_ANY_THROW(kernel.configure());
706 } // namespace kernels
707 } // namespace luci_interpreter