blob: 395ff90bb9d2b6cc336033f40e9b8f43c6d55ac2 [file] [log] [blame]
telsoa01c577f2c2018-08-31 09:22:23 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
David Beckecb56cd2018-09-05 12:52:57 +01003// SPDX-License-Identifier: MIT
telsoa01c577f2c2018-08-31 09:22:23 +01004//
5
6#include <boost/test/unit_test.hpp>
7#include "armnnOnnxParser/IOnnxParser.hpp"
8#include "ParserPrototxtFixture.hpp"
9
10BOOST_AUTO_TEST_SUITE(OnnxParser)
11
12// A MatMul in isolation, not connected to an add. Should result in a non-biased FullyConnected layer.
13struct MatMulFixture : public armnnUtils::ParserPrototxtFixture<armnnOnnxParser::IOnnxParser>
14{
15 MatMulFixture()
16 {
17 m_Prototext = R"(
18 ir_version: 3
19 producer_name: "CNTK "
20 producer_version: "2.5.1 "
21 domain: "ai.cntk "
22 model_version: 1
23 graph {
24 name: "CNTKGraph "
25 input {
26 name: "Input"
27 type {
28 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +000029 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +010030 shape {
31 dim {
32 dim_value: 1
33 }
34 dim {
35 dim_value: 1
36 }
37 }
38 }
39 }
40 }
41 input {
42 name: "Const"
43 type {
44 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +000045 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +010046 shape {
47 dim {
48 dim_value: 1
49 }
50 dim {
51 dim_value: 1
52 }
53 }
54 }
55 }
56 }
57 initializer {
58 dims: 1
Matteo Martincigh44a71672018-12-11 13:46:52 +000059 data_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +010060 float_data: 17.0
61 name: "Const"
62 }
63 node {
64 input: "Input"
65 input: "Const"
66 output: "Output"
67 name: "SimpleMatmul"
68 op_type: "MatMul"
69 }
70 output {
71 name: "Output"
72 type {
73 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +000074 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +010075 shape {
76 dim {
77 dim_value: 1
78 }
79 dim {
80 dim_value: 1
81 }
82 }
83 }
84 }
85 }
86 }
87 opset_import {
88 version: 7
89 })";
90
91 Setup();
92 }
93};
94
95BOOST_FIXTURE_TEST_CASE(MatMul, MatMulFixture)
96{
97 RunTest<1>({{"Input", { 2 }}}, {{"Output", { 34 }}});
98}
99
100// In Onnx fully connected layers are expressed as a MatMul followed by an Add.
101// The OnnxParser must detect this case and convert them to a FullyConnected layer.
102struct FullyConnectedFixture : public armnnUtils::ParserPrototxtFixture<armnnOnnxParser::IOnnxParser>
103{
104 FullyConnectedFixture()
105 {
106 m_Prototext = R"(
107 ir_version: 3
108 producer_name: "CNTK "
109 producer_version: "2.5.1 "
110 domain: "ai.cntk "
111 model_version: 1
112 graph {
113 name: "CNTKGraph "
114 input {
115 name: "Input"
116 type {
117 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000118 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100119 shape {
120 dim {
121 dim_value: 1
122 }
123 dim {
124 dim_value: 1
125 }
126 }
127 }
128 }
129 }
130 input {
131 name: "Weight"
132 type {
133 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000134 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100135 shape {
136 dim {
137 dim_value: 1
138 }
139 dim {
140 dim_value: 1
141 }
142 }
143 }
144 }
145 }
146 initializer {
147 dims: 1
Matteo Martincigh44a71672018-12-11 13:46:52 +0000148 data_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100149 float_data: 2
150 name: "Weight"
151 }
152 input {
153 name: "Bias"
154 type {
155 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000156 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100157 shape {
158 dim {
159 dim_value: 1
160 }
161 }
162 }
163 }
164 }
165 initializer {
166 dims: 1
Matteo Martincigh44a71672018-12-11 13:46:52 +0000167 data_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100168 float_data: 1
169 name: "Bias"
170 }
171 node {
172 input: "Input"
173 input: "Weight"
174 output: "AddInput"
175 name: "FCMatmul"
176 op_type: "MatMul"
177 }
178 node {
179 input: "AddInput"
180 input: "Bias"
181 output: "Output"
182 name: "FCAdd"
183 op_type: "Add"
184 }
185 value_info {
186 name: "AddInput"
187 type {
188 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000189 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100190 shape {
191 dim {
192 dim_value: 1
193 }
194 dim {
195 dim_value: 1
196 }
197 }
198 }
199 }
200 }
201 output {
202 name: "Output"
203 type {
204 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000205 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100206 shape {
207 dim {
208 dim_value: 1
209 }
210 dim {
211 dim_value: 1
212 }
213 }
214 }
215 }
216 }
217 }
218 opset_import {
219 version: 7
220 })";
221
222 Setup();
223 }
224};
225
226BOOST_FIXTURE_TEST_CASE(FullyConnected, FullyConnectedFixture)
227{
228 RunTest<1>({{"Input", { 3 }}}, {{"Output", { 7 }}});
229}
230
231
232// Similar to FullyConnectedFixture, but this time the MatMul's output is used by two Adds. This should result
233// in two FullyConnected layers being created.
234// I
235// |
236// M -- C
237// / \'
238// C-- A A -- C
239// \ /
240// A
241struct MatMulUsedInTwoFcFixture : public armnnUtils::ParserPrototxtFixture<armnnOnnxParser::IOnnxParser>
242{
243 MatMulUsedInTwoFcFixture()
244 {
245 m_Prototext = R"(
246 ir_version: 3
247 producer_name: "CNTK "
248 producer_version: "2.5.1 "
249 domain: "ai.cntk "
250 model_version: 1
251 graph {
252 name: "CNTKGraph "
253 input {
254 name: "Input"
255 type {
256 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000257 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100258 shape {
259 dim {
260 dim_value: 1
261 }
262 dim {
263 dim_value: 1
264 }
265 }
266 }
267 }
268 }
269 input {
270 name: "Weight"
271 type {
272 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000273 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100274 shape {
275 dim {
276 dim_value: 1
277 }
278 dim {
279 dim_value: 1
280 }
281 }
282 }
283 }
284 }
285 initializer {
286 dims: 1
Matteo Martincigh44a71672018-12-11 13:46:52 +0000287 data_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100288 float_data: 2
289 name: "Weight"
290 }
291 input {
292 name: "Bias"
293 type {
294 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000295 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100296 shape {
297 dim {
298 dim_value: 1
299 }
300 }
301 }
302 }
303 }
304 initializer {
305 dims: 1
Matteo Martincigh44a71672018-12-11 13:46:52 +0000306 data_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100307 float_data: 1
308 name: "Bias"
309 }
310 input {
311 name: "Bias_1"
312 type {
313 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000314 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100315 shape {
316 dim {
317 dim_value: 1
318 }
319 }
320 }
321 }
322 }
323 initializer {
324 dims: 1
Matteo Martincigh44a71672018-12-11 13:46:52 +0000325 data_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100326 float_data: 10.0
327 name: "Bias_1"
328 }
329 node {
330 input: "Input"
331 input: "Weight"
332 output: "AddInput"
333 name: "FCMatmul"
334 op_type: "MatMul"
335 }
336 node {
337 input: "AddInput"
338 input: "Bias"
339 output: "AddOutput"
340 name: "FCAdd"
341 op_type: "Add"
342 }
343 node {
344 input: "AddInput"
345 input: "Bias_1"
346 output: "AddOutput_1"
347 name: "FCAdd_1"
348 op_type: "Add"
349 }
350 node {
351 input: "AddOutput"
352 input: "AddOutput_1"
353 output: "Output"
354 name: "FinalAdd"
355 op_type: "Add"
356 }
357 value_info {
358 name: "AddInput"
359 type {
360 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000361 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100362 shape {
363 dim {
364 dim_value: 1
365 }
366 dim {
367 dim_value: 1
368 }
369 }
370 }
371 }
372 }
373 value_info {
374 name: "AddOutput"
375 type {
376 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000377 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100378 shape {
379 dim {
380 dim_value: 1
381 }
382 dim {
383 dim_value: 1
384 }
385 }
386 }
387 }
388 }
389 value_info {
390 name: "AddOutput_1"
391 type {
392 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000393 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100394 shape {
395 dim {
396 dim_value: 1
397 }
398 dim {
399 dim_value: 1
400 }
401 }
402 }
403 }
404 }
405 output {
406 name: "Output"
407 type {
408 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000409 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100410 shape {
411 dim {
412 dim_value: 1
413 }
414 dim {
415 dim_value: 1
416 }
417 }
418 }
419 }
420 }
421 }
422 opset_import {
423 version: 7
424 })";
425
426 Setup();
427 }
428};
429
430BOOST_FIXTURE_TEST_CASE(MatMulUsedInTwoFc, MatMulUsedInTwoFcFixture)
431{
432 RunTest<1>({{"Input", { 3 }}}, {{"Output", { 23 }}});
433}
434
435
436// Similar to MatMulUsedInTwoFc, but this time the Adds are 'staggered' (see diagram), which means that only one
437// FullyConnected layer can be created (the other should just be an Add).
438// I
439// |
440// M -- C1
441// / \'
442// C2 -- A |
443// \ /
444// A
445struct MatMulUsedInTwoFcStaggeredFixture : public armnnUtils::ParserPrototxtFixture<armnnOnnxParser::IOnnxParser>
446{
447 MatMulUsedInTwoFcStaggeredFixture()
448 {
449 m_Prototext = R"(
450 ir_version: 3
451 producer_name: "CNTK "
452 producer_version: "2.5.1 "
453 domain: "ai.cntk "
454 model_version: 1
455 graph {
456 name: "CNTKGraph "
457 input {
458 name: "Input"
459 type {
460 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000461 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100462 shape {
463 dim {
464 dim_value: 1
465 }
466 dim {
467 dim_value: 1
468 }
469 }
470 }
471 }
472 }
473 input {
474 name: "Weight"
475 type {
476 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000477 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100478 shape {
479 dim {
480 dim_value: 1
481 }
482 dim {
483 dim_value: 1
484 }
485 }
486 }
487 }
488 }
489 initializer {
490 dims: 1
Matteo Martincigh44a71672018-12-11 13:46:52 +0000491 data_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100492 float_data: 2
493 name: "Weight"
494 }
495 input {
496 name: "Bias"
497 type {
498 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000499 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100500 shape {
501 dim {
502 dim_value: 1
503 }
504 }
505 }
506 }
507 }
508 initializer {
509 dims: 1
Matteo Martincigh44a71672018-12-11 13:46:52 +0000510 data_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100511 float_data: 1
512 name: "Bias"
513 }
514 node {
515 input: "Input"
516 input: "Weight"
517 output: "AddInput"
518 name: "MatmulFC&NFC"
519 op_type: "MatMul"
520 }
521 node {
522 input: "AddInput"
523 input: "Bias"
524 output: "AddOutput"
525 name: "FCAdd"
526 op_type: "Add"
527 }
528
529 node {
530 input: "AddInput"
531 input: "AddOutput"
532 output: "Output"
533 name: "FinalAdd"
534 op_type: "Add"
535 }
536 value_info {
537 name: "AddInput"
538 type {
539 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000540 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100541 shape {
542 dim {
543 dim_value: 1
544 }
545 dim {
546 dim_value: 1
547 }
548 }
549 }
550 }
551 }
552 value_info {
553 name: "AddOutput"
554 type {
555 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000556 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100557 shape {
558 dim {
559 dim_value: 1
560 }
561 dim {
562 dim_value: 1
563 }
564 }
565 }
566 }
567 }
568 output {
569 name: "Output"
570 type {
571 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000572 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100573 shape {
574 dim {
575 dim_value: 1
576 }
577 dim {
578 dim_value: 1
579 }
580 }
581 }
582 }
583 }
584 }
585 opset_import {
586 version: 7
587 })";
588 Setup();
589 }
590};
591
592BOOST_FIXTURE_TEST_CASE(MatMulUsedInTwoFcStaggered, MatMulUsedInTwoFcStaggeredFixture)
593{
594 RunTest<1>({{"Input", { 3 }}}, {{"Output", { 13 }}});
595}
596
597BOOST_AUTO_TEST_SUITE_END()