• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include "armnnOnnxParser/IOnnxParser.hpp"
7 #include  "ParserPrototxtFixture.hpp"
8 
9 TEST_SUITE("OnnxParser_FullyConnected")
10 {
11 // A MatMul in isolation, not connected to an add. Should result in a non-biased FullyConnected layer.
12 struct MatMulFixture : public armnnUtils::ParserPrototxtFixture<armnnOnnxParser::IOnnxParser>
13 {
MatMulFixtureMatMulFixture14     MatMulFixture()
15     {
16         m_Prototext = R"(
17                     ir_version: 3
18                     producer_name:  "CNTK "
19                     producer_version:  "2.5.1 "
20                     domain:  "ai.cntk "
21                     model_version: 1
22                     graph {
23                       name:  "CNTKGraph "
24                       input {
25                          name: "Input"
26                          type {
27                            tensor_type {
28                              elem_type: 1
29                              shape {
30                                dim {
31                                  dim_value: 1
32                                }
33                                dim {
34                                  dim_value: 1
35                                }
36                              }
37                            }
38                          }
39                        }
40                        input {
41                           name: "Const"
42                           type {
43                             tensor_type {
44                               elem_type: 1
45                               shape {
46                                 dim {
47                                   dim_value: 1
48                                 }
49                                 dim {
50                                   dim_value: 1
51                                 }
52                               }
53                             }
54                           }
55                         }
56                         initializer {
57                           dims: 1
58                           dims: 1
59                           data_type: 1
60                           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 {
74                                 elem_type: 1
75                                 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 
95 TEST_CASE_FIXTURE(MatMulFixture, "MatMul")
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.
102 struct FullyConnectedFixture : public armnnUtils::ParserPrototxtFixture<armnnOnnxParser::IOnnxParser>
103 {
FullyConnectedFixtureFullyConnectedFixture104     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 {
118                              elem_type: 1
119                              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 {
134                               elem_type: 1
135                               shape {
136                                 dim {
137                                   dim_value: 1
138                                 }
139                                 dim {
140                                   dim_value: 1
141                                 }
142                               }
143                             }
144                           }
145                         }
146                         initializer {
147                           dims: 1
148                           dims: 1
149                           data_type: 1
150                           float_data: 2
151                           name: "Weight"
152                        }
153                        input {
154                           name: "Bias"
155                           type {
156                             tensor_type {
157                               elem_type: 1
158                               shape {
159                                 dim {
160                                   dim_value: 1
161                                 }
162                               }
163                             }
164                           }
165                         }
166                         initializer {
167                           dims: 1
168                           data_type: 1
169                           float_data: 1
170                           name: "Bias"
171                        }
172                        node {
173                            input: "Input"
174                            input: "Weight"
175                            output: "AddInput"
176                            name: "FCMatmul"
177                            op_type: "MatMul"
178                        }
179                        node {
180                            input: "AddInput"
181                            input: "Bias"
182                            output: "Output"
183                            name: "FCAdd"
184                            op_type: "Add"
185                        }
186                        value_info {
187                             name: "AddInput"
188                             type {
189                               tensor_type {
190                                 elem_type: 1
191                                 shape {
192                                   dim {
193                                     dim_value: 1
194                                   }
195                                   dim {
196                                     dim_value: 1
197                                   }
198                                 }
199                               }
200                             }
201                           }
202                       output {
203                            name:  "Output"
204                            type {
205                               tensor_type {
206                                 elem_type: 1
207                                 shape {
208                                   dim {
209                                      dim_value: 1
210                                   }
211                                   dim {
212                                      dim_value: 1
213                                   }
214                                 }
215                               }
216                            }
217                        }
218                     }
219                     opset_import {
220                        version: 7
221                      })";
222 
223         Setup();
224     }
225 };
226 
227 TEST_CASE_FIXTURE(FullyConnectedFixture, "FullyConnected")
228 {
229     RunTest<1>({{"Input", { 3 }}}, {{"Output", { 7 }}});
230 }
231 
232 
233 // Similar to FullyConnectedFixture, but this time the MatMul's output is used by two Adds. This should result
234 // in two FullyConnected layers being created.
235 //      I
236 //      |
237 //      M -- C
238 //     / \'
239 // C-- A  A -- C
240 //     \ /
241 //      A
242 struct MatMulUsedInTwoFcFixture : public armnnUtils::ParserPrototxtFixture<armnnOnnxParser::IOnnxParser>
243 {
MatMulUsedInTwoFcFixtureMatMulUsedInTwoFcFixture244     MatMulUsedInTwoFcFixture()
245     {
246         m_Prototext = R"(
247                     ir_version: 3
248                     producer_name:  "CNTK "
249                     producer_version:  "2.5.1 "
250                     domain:  "ai.cntk "
251                     model_version: 1
252                     graph {
253                       name:  "CNTKGraph "
254                       input {
255                          name: "Input"
256                          type {
257                            tensor_type {
258                              elem_type: 1
259                              shape {
260                                dim {
261                                  dim_value: 1
262                                }
263                                dim {
264                                  dim_value: 1
265                                }
266                              }
267                            }
268                          }
269                        }
270                        input {
271                           name: "Weight"
272                           type {
273                             tensor_type {
274                               elem_type: 1
275                               shape {
276                                 dim {
277                                   dim_value: 1
278                                 }
279                                 dim {
280                                   dim_value: 1
281                                 }
282                               }
283                             }
284                           }
285                         }
286                         initializer {
287                           dims: 1
288                           dims: 1
289                           data_type: 1
290                           float_data: 2
291                           name: "Weight"
292                        }
293                        input {
294                           name: "Bias"
295                           type {
296                             tensor_type {
297                               elem_type: 1
298                               shape {
299                                 dim {
300                                   dim_value: 1
301                                 }
302                               }
303                             }
304                           }
305                         }
306                         initializer {
307                           dims: 1
308                           data_type: 1
309                           float_data: 1
310                           name: "Bias"
311                        }
312                        input {
313                           name: "Bias_1"
314                           type {
315                             tensor_type {
316                               elem_type: 1
317                               shape {
318                                 dim {
319                                   dim_value: 1
320                                 }
321                               }
322                             }
323                           }
324                         }
325                         initializer {
326                           dims: 1
327                           data_type: 1
328                           float_data: 10.0
329                           name: "Bias_1"
330                        }
331                        node {
332                            input: "Input"
333                            input: "Weight"
334                            output: "AddInput"
335                            name: "FCMatmul"
336                            op_type: "MatMul"
337                        }
338                        node {
339                            input: "AddInput"
340                            input: "Bias"
341                            output: "AddOutput"
342                            name: "FCAdd"
343                            op_type: "Add"
344                        }
345                        node {
346                            input: "AddInput"
347                            input: "Bias_1"
348                            output: "AddOutput_1"
349                            name: "FCAdd_1"
350                            op_type: "Add"
351                        }
352                        node {
353                            input: "AddOutput"
354                            input: "AddOutput_1"
355                            output: "Output"
356                            name: "FinalAdd"
357                            op_type: "Add"
358                        }
359                        value_info {
360                             name: "AddInput"
361                             type {
362                               tensor_type {
363                                 elem_type: 1
364                                 shape {
365                                   dim {
366                                     dim_value: 1
367                                   }
368                                   dim {
369                                     dim_value: 1
370                                   }
371                                 }
372                               }
373                             }
374                           }
375                       value_info {
376                            name:  "AddOutput"
377                            type {
378                               tensor_type {
379                                 elem_type: 1
380                                 shape {
381                                   dim {
382                                      dim_value: 1
383                                   }
384                                   dim {
385                                      dim_value: 1
386                                   }
387                                 }
388                               }
389                            }
390                        }
391                        value_info {
392                             name:  "AddOutput_1"
393                             type {
394                                tensor_type {
395                                  elem_type: 1
396                                  shape {
397                                    dim {
398                                       dim_value: 1
399                                    }
400                                    dim {
401                                       dim_value: 1
402                                    }
403                                  }
404                                }
405                             }
406                         }
407                         output {
408                              name:  "Output"
409                              type {
410                                 tensor_type {
411                                   elem_type: 1
412                                   shape {
413                                     dim {
414                                        dim_value: 1
415                                     }
416                                     dim {
417                                        dim_value: 1
418                                     }
419                                   }
420                                 }
421                              }
422                          }
423                     }
424                     opset_import {
425                        version: 7
426                      })";
427 
428         Setup();
429     }
430 };
431 
432 TEST_CASE_FIXTURE(MatMulUsedInTwoFcFixture, "MatMulUsedInTwoFc")
433 {
434     RunTest<1>({{"Input", { 3 }}}, {{"Output", { 23 }}});
435 }
436 
437 
438 // Similar to MatMulUsedInTwoFc, but this time the Adds are 'staggered' (see diagram), which means that only one
439 // FullyConnected layer can be created (the other should just be an Add).
440 //        I
441 //        |
442 //        M -- C1
443 //       / \'
444 // C2 -- A  |
445 //       \ /
446 //        A
447 struct MatMulUsedInTwoFcStaggeredFixture : public armnnUtils::ParserPrototxtFixture<armnnOnnxParser::IOnnxParser>
448 {
MatMulUsedInTwoFcStaggeredFixtureMatMulUsedInTwoFcStaggeredFixture449     MatMulUsedInTwoFcStaggeredFixture()
450     {
451         m_Prototext = R"(
452                     ir_version: 3
453                     producer_name:  "CNTK "
454                     producer_version:  "2.5.1 "
455                     domain:  "ai.cntk "
456                     model_version: 1
457                     graph {
458                       name:  "CNTKGraph "
459                       input {
460                          name: "Input"
461                          type {
462                            tensor_type {
463                              elem_type: 1
464                              shape {
465                                dim {
466                                  dim_value: 1
467                                }
468                                dim {
469                                  dim_value: 1
470                                }
471                              }
472                            }
473                          }
474                        }
475                        input {
476                           name: "Weight"
477                           type {
478                             tensor_type {
479                               elem_type: 1
480                               shape {
481                                 dim {
482                                   dim_value: 1
483                                 }
484                                 dim {
485                                   dim_value: 1
486                                 }
487                               }
488                             }
489                           }
490                         }
491                         initializer {
492                           dims: 1
493                           dims: 1
494                           data_type: 1
495                           float_data: 2
496                           name: "Weight"
497                        }
498                        input {
499                           name: "Bias"
500                           type {
501                             tensor_type {
502                               elem_type: 1
503                               shape {
504                                 dim {
505                                   dim_value: 1
506                                 }
507                               }
508                             }
509                           }
510                         }
511                         initializer {
512                           dims: 1
513                           data_type: 1
514                           float_data: 1
515                           name: "Bias"
516                        }
517                         node {
518                            input: "Input"
519                            input: "Weight"
520                            output: "AddInput"
521                            name: "MatmulFC&NFC"
522                            op_type: "MatMul"
523                        }
524                        node {
525                            input: "AddInput"
526                            input: "Bias"
527                            output: "AddOutput"
528                            name: "FCAdd"
529                            op_type: "Add"
530                        }
531 
532                        node {
533                            input: "AddInput"
534                            input: "AddOutput"
535                            output: "Output"
536                            name: "FinalAdd"
537                            op_type: "Add"
538                        }
539                        value_info {
540                             name: "AddInput"
541                             type {
542                               tensor_type {
543                                 elem_type: 1
544                                 shape {
545                                   dim {
546                                     dim_value: 1
547                                   }
548                                   dim {
549                                     dim_value: 1
550                                   }
551                                 }
552                               }
553                             }
554                           }
555                       value_info {
556                            name:  "AddOutput"
557                            type {
558                               tensor_type {
559                                 elem_type: 1
560                                 shape {
561                                   dim {
562                                      dim_value: 1
563                                   }
564                                   dim {
565                                      dim_value: 1
566                                   }
567                                 }
568                               }
569                            }
570                        }
571                        output {
572                              name:  "Output"
573                              type {
574                                 tensor_type {
575                                   elem_type: 1
576                                   shape {
577                                     dim {
578                                        dim_value: 1
579                                     }
580                                     dim {
581                                        dim_value: 1
582                                     }
583                                   }
584                                 }
585                              }
586                          }
587                     }
588                     opset_import {
589                        version: 7
590                      })";
591         Setup();
592     }
593 };
594 
595 TEST_CASE_FIXTURE(MatMulUsedInTwoFcStaggeredFixture, "MatMulUsedInTwoFcStaggered")
596 {
597     RunTest<1>({{"Input", { 3 }}}, {{"Output", { 13 }}});
598 }
599 
600 }
601