blob: 133b8a68483de004be9ac029bc56a9a49ca1ead3 [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
Tee Jungd94efa82019-11-01 11:55:21 +000059 dims: 1
Matteo Martincigh44a71672018-12-11 13:46:52 +000060 data_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +010061 float_data: 17.0
62 name: "Const"
63 }
64 node {
65 input: "Input"
66 input: "Const"
67 output: "Output"
68 name: "SimpleMatmul"
69 op_type: "MatMul"
70 }
71 output {
72 name: "Output"
73 type {
74 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +000075 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +010076 shape {
77 dim {
78 dim_value: 1
79 }
80 dim {
81 dim_value: 1
82 }
83 }
84 }
85 }
86 }
87 }
88 opset_import {
89 version: 7
90 })";
91
92 Setup();
93 }
94};
95
96BOOST_FIXTURE_TEST_CASE(MatMul, MatMulFixture)
97{
98 RunTest<1>({{"Input", { 2 }}}, {{"Output", { 34 }}});
99}
100
101// In Onnx fully connected layers are expressed as a MatMul followed by an Add.
102// The OnnxParser must detect this case and convert them to a FullyConnected layer.
103struct FullyConnectedFixture : public armnnUtils::ParserPrototxtFixture<armnnOnnxParser::IOnnxParser>
104{
105 FullyConnectedFixture()
106 {
107 m_Prototext = R"(
108 ir_version: 3
109 producer_name: "CNTK "
110 producer_version: "2.5.1 "
111 domain: "ai.cntk "
112 model_version: 1
113 graph {
114 name: "CNTKGraph "
115 input {
116 name: "Input"
117 type {
118 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000119 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100120 shape {
121 dim {
122 dim_value: 1
123 }
124 dim {
125 dim_value: 1
126 }
127 }
128 }
129 }
130 }
131 input {
132 name: "Weight"
133 type {
134 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000135 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100136 shape {
137 dim {
138 dim_value: 1
139 }
140 dim {
141 dim_value: 1
142 }
143 }
144 }
145 }
146 }
147 initializer {
148 dims: 1
Tee Jungd94efa82019-11-01 11:55:21 +0000149 dims: 1
Matteo Martincigh44a71672018-12-11 13:46:52 +0000150 data_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100151 float_data: 2
152 name: "Weight"
153 }
154 input {
155 name: "Bias"
156 type {
157 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000158 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100159 shape {
160 dim {
161 dim_value: 1
162 }
163 }
164 }
165 }
166 }
167 initializer {
168 dims: 1
Matteo Martincigh44a71672018-12-11 13:46:52 +0000169 data_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100170 float_data: 1
171 name: "Bias"
172 }
173 node {
174 input: "Input"
175 input: "Weight"
176 output: "AddInput"
177 name: "FCMatmul"
178 op_type: "MatMul"
179 }
180 node {
181 input: "AddInput"
182 input: "Bias"
183 output: "Output"
184 name: "FCAdd"
185 op_type: "Add"
186 }
187 value_info {
188 name: "AddInput"
189 type {
190 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000191 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100192 shape {
193 dim {
194 dim_value: 1
195 }
196 dim {
197 dim_value: 1
198 }
199 }
200 }
201 }
202 }
203 output {
204 name: "Output"
205 type {
206 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000207 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100208 shape {
209 dim {
210 dim_value: 1
211 }
212 dim {
213 dim_value: 1
214 }
215 }
216 }
217 }
218 }
219 }
220 opset_import {
221 version: 7
222 })";
223
224 Setup();
225 }
226};
227
228BOOST_FIXTURE_TEST_CASE(FullyConnected, FullyConnectedFixture)
229{
230 RunTest<1>({{"Input", { 3 }}}, {{"Output", { 7 }}});
231}
232
233
234// Similar to FullyConnectedFixture, but this time the MatMul's output is used by two Adds. This should result
235// in two FullyConnected layers being created.
236// I
237// |
238// M -- C
239// / \'
240// C-- A A -- C
241// \ /
242// A
243struct MatMulUsedInTwoFcFixture : public armnnUtils::ParserPrototxtFixture<armnnOnnxParser::IOnnxParser>
244{
245 MatMulUsedInTwoFcFixture()
246 {
247 m_Prototext = R"(
248 ir_version: 3
249 producer_name: "CNTK "
250 producer_version: "2.5.1 "
251 domain: "ai.cntk "
252 model_version: 1
253 graph {
254 name: "CNTKGraph "
255 input {
256 name: "Input"
257 type {
258 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000259 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100260 shape {
261 dim {
262 dim_value: 1
263 }
264 dim {
265 dim_value: 1
266 }
267 }
268 }
269 }
270 }
271 input {
272 name: "Weight"
273 type {
274 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000275 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100276 shape {
277 dim {
278 dim_value: 1
279 }
280 dim {
281 dim_value: 1
282 }
283 }
284 }
285 }
286 }
287 initializer {
288 dims: 1
Tee Jungd94efa82019-11-01 11:55:21 +0000289 dims: 1
Matteo Martincigh44a71672018-12-11 13:46:52 +0000290 data_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100291 float_data: 2
292 name: "Weight"
293 }
294 input {
295 name: "Bias"
296 type {
297 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000298 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100299 shape {
300 dim {
301 dim_value: 1
302 }
303 }
304 }
305 }
306 }
307 initializer {
308 dims: 1
Matteo Martincigh44a71672018-12-11 13:46:52 +0000309 data_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100310 float_data: 1
311 name: "Bias"
312 }
313 input {
314 name: "Bias_1"
315 type {
316 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000317 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100318 shape {
319 dim {
320 dim_value: 1
321 }
322 }
323 }
324 }
325 }
326 initializer {
327 dims: 1
Matteo Martincigh44a71672018-12-11 13:46:52 +0000328 data_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100329 float_data: 10.0
330 name: "Bias_1"
331 }
332 node {
333 input: "Input"
334 input: "Weight"
335 output: "AddInput"
336 name: "FCMatmul"
337 op_type: "MatMul"
338 }
339 node {
340 input: "AddInput"
341 input: "Bias"
342 output: "AddOutput"
343 name: "FCAdd"
344 op_type: "Add"
345 }
346 node {
347 input: "AddInput"
348 input: "Bias_1"
349 output: "AddOutput_1"
350 name: "FCAdd_1"
351 op_type: "Add"
352 }
353 node {
354 input: "AddOutput"
355 input: "AddOutput_1"
356 output: "Output"
357 name: "FinalAdd"
358 op_type: "Add"
359 }
360 value_info {
361 name: "AddInput"
362 type {
363 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000364 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100365 shape {
366 dim {
367 dim_value: 1
368 }
369 dim {
370 dim_value: 1
371 }
372 }
373 }
374 }
375 }
376 value_info {
377 name: "AddOutput"
378 type {
379 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000380 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100381 shape {
382 dim {
383 dim_value: 1
384 }
385 dim {
386 dim_value: 1
387 }
388 }
389 }
390 }
391 }
392 value_info {
393 name: "AddOutput_1"
394 type {
395 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000396 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100397 shape {
398 dim {
399 dim_value: 1
400 }
401 dim {
402 dim_value: 1
403 }
404 }
405 }
406 }
407 }
408 output {
409 name: "Output"
410 type {
411 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000412 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100413 shape {
414 dim {
415 dim_value: 1
416 }
417 dim {
418 dim_value: 1
419 }
420 }
421 }
422 }
423 }
424 }
425 opset_import {
426 version: 7
427 })";
428
429 Setup();
430 }
431};
432
433BOOST_FIXTURE_TEST_CASE(MatMulUsedInTwoFc, MatMulUsedInTwoFcFixture)
434{
435 RunTest<1>({{"Input", { 3 }}}, {{"Output", { 23 }}});
436}
437
438
439// Similar to MatMulUsedInTwoFc, but this time the Adds are 'staggered' (see diagram), which means that only one
440// FullyConnected layer can be created (the other should just be an Add).
441// I
442// |
443// M -- C1
444// / \'
445// C2 -- A |
446// \ /
447// A
448struct MatMulUsedInTwoFcStaggeredFixture : public armnnUtils::ParserPrototxtFixture<armnnOnnxParser::IOnnxParser>
449{
450 MatMulUsedInTwoFcStaggeredFixture()
451 {
452 m_Prototext = R"(
453 ir_version: 3
454 producer_name: "CNTK "
455 producer_version: "2.5.1 "
456 domain: "ai.cntk "
457 model_version: 1
458 graph {
459 name: "CNTKGraph "
460 input {
461 name: "Input"
462 type {
463 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000464 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100465 shape {
466 dim {
467 dim_value: 1
468 }
469 dim {
470 dim_value: 1
471 }
472 }
473 }
474 }
475 }
476 input {
477 name: "Weight"
478 type {
479 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000480 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100481 shape {
482 dim {
483 dim_value: 1
484 }
485 dim {
486 dim_value: 1
487 }
488 }
489 }
490 }
491 }
492 initializer {
493 dims: 1
Tee Jungd94efa82019-11-01 11:55:21 +0000494 dims: 1
Matteo Martincigh44a71672018-12-11 13:46:52 +0000495 data_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100496 float_data: 2
497 name: "Weight"
498 }
499 input {
500 name: "Bias"
501 type {
502 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000503 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100504 shape {
505 dim {
506 dim_value: 1
507 }
508 }
509 }
510 }
511 }
512 initializer {
513 dims: 1
Matteo Martincigh44a71672018-12-11 13:46:52 +0000514 data_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100515 float_data: 1
516 name: "Bias"
517 }
518 node {
519 input: "Input"
520 input: "Weight"
521 output: "AddInput"
522 name: "MatmulFC&NFC"
523 op_type: "MatMul"
524 }
525 node {
526 input: "AddInput"
527 input: "Bias"
528 output: "AddOutput"
529 name: "FCAdd"
530 op_type: "Add"
531 }
532
533 node {
534 input: "AddInput"
535 input: "AddOutput"
536 output: "Output"
537 name: "FinalAdd"
538 op_type: "Add"
539 }
540 value_info {
541 name: "AddInput"
542 type {
543 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000544 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100545 shape {
546 dim {
547 dim_value: 1
548 }
549 dim {
550 dim_value: 1
551 }
552 }
553 }
554 }
555 }
556 value_info {
557 name: "AddOutput"
558 type {
559 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000560 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100561 shape {
562 dim {
563 dim_value: 1
564 }
565 dim {
566 dim_value: 1
567 }
568 }
569 }
570 }
571 }
572 output {
573 name: "Output"
574 type {
575 tensor_type {
Matteo Martincigh44a71672018-12-11 13:46:52 +0000576 elem_type: 1
telsoa01c577f2c2018-08-31 09:22:23 +0100577 shape {
578 dim {
579 dim_value: 1
580 }
581 dim {
582 dim_value: 1
583 }
584 }
585 }
586 }
587 }
588 }
589 opset_import {
590 version: 7
591 })";
592 Setup();
593 }
594};
595
596BOOST_FIXTURE_TEST_CASE(MatMulUsedInTwoFcStaggered, MatMulUsedInTwoFcStaggeredFixture)
597{
598 RunTest<1>({{"Input", { 3 }}}, {{"Output", { 13 }}});
599}
600
601BOOST_AUTO_TEST_SUITE_END()