ArmNN
 21.11
FullyConnected.cpp File Reference

Go to the source code of this file.

Functions

 TEST_SUITE ("OnnxParser_FullyConnected")
 

Function Documentation

◆ TEST_SUITE()

TEST_SUITE ( "OnnxParser_FullyConnected"  )

Definition at line 9 of file FullyConnected.cpp.

References ParserPrototxtFixture< TParser >::Setup(), and TEST_CASE_FIXTURE().

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 {
14  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 {
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 {
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 {
244  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 {
449  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 }
TEST_CASE_FIXTURE(ClContextControlFixture, "CopyBetweenNeonAndGpu")