Imported Upstream version 1.12.0
[platform/core/ml/nnfw.git] / tests / nnfw_api / src / one_op_tests / FullyConnected.cc
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include "GenModelTest.h"
18
19 #include <memory>
20
21 TEST_F(GenModelTest, OneOp_FullyConnected)
22 {
23   CircleGen cgen;
24   // clang-format off
25   std::vector<float> weight_data{ 1, 0, 0, 1,
26                                   2, 0, 0, -1,
27                                   3, 0, 0, 2,
28                                   4, 0, 0, 1,
29                                   1, 0, 0, 1,
30                                   2, 0, 0, -1,
31                                   3, 0, 0, 2,
32                                   4, 0, 0, 1,
33                                   1, 0, 0, 1,
34                                   2, 0, 0, -1,
35                                   3, 0, 0, 2,
36                                   4, 0, 0, 1,
37                                   1, 0, 0, 1,
38                                   2, 0, 0, -1,
39                                   3, 0, 0, 2,
40                                   4, 0, 0, 1 };
41   std::vector<float> bias_data{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
42   // clang-format on
43   uint32_t weight_buf = cgen.addBuffer(weight_data);
44   uint32_t bias_buf = cgen.addBuffer(bias_data);
45   int input = cgen.addTensor({{1, 4}, circle::TensorType::TensorType_FLOAT32});
46   int weight = cgen.addTensor({{16, 4}, circle::TensorType::TensorType_FLOAT32, weight_buf});
47   int bias = cgen.addTensor({{16}, circle::TensorType::TensorType_FLOAT32, bias_buf});
48   int output = cgen.addTensor({{1, 16}, circle::TensorType::TensorType_FLOAT32});
49   cgen.addOperatorFullyConnected({{input, weight, bias}, {output}});
50   cgen.setInputsAndOutputs({input}, {output});
51
52   _context = std::make_unique<GenModelTestContext>(cgen.finish());
53   _context->addTestCase(
54     uniformTCD<float>({{1, 3, 2, 1}}, {{2, 1, 5, 5, 2, 1, 5, 5, 2, 1, 5, 5, 2, 1, 5, 6}}));
55   _context->setBackends({"cpu", "acl_neon", "xnnpack", "ruy"});
56
57   SUCCEED();
58 }
59
60 #if defined(__aarch64__)
61 TEST_F(GenModelTest, OneOp_FullyConnectedShuffled16x1Float32)
62 {
63   CircleGen cgen;
64   // clang-format off
65   std::vector<float> weight_data{ 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4,
66                                   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
67                                   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
68                                   1, -1, 2, 1, 1, -1, 2, 1, 1, -1, 2, 1, 1, -1, 2, 1 };
69   std::vector<float> bias_data{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
70   // clang-format on
71   uint32_t weight_buf = cgen.addBuffer(weight_data);
72   uint32_t bias_buf = cgen.addBuffer(bias_data);
73   int input = cgen.addTensor({{1, 4}, circle::TensorType::TensorType_FLOAT32});
74   int weight = cgen.addTensor({{16, 4}, circle::TensorType::TensorType_FLOAT32, weight_buf});
75   int bias = cgen.addTensor({{16}, circle::TensorType::TensorType_FLOAT32, bias_buf});
76   int output = cgen.addTensor({{1, 16}, circle::TensorType::TensorType_FLOAT32});
77   cgen.addOperatorFullyConnected({{input, weight, bias}, {output}},
78                                  circle::FullyConnectedOptionsWeightsFormat_SHUFFLED16x1FLOAT32);
79   cgen.setInputsAndOutputs({input}, {output});
80
81   _context = std::make_unique<GenModelTestContext>(cgen.finish());
82   _context->addTestCase(
83     uniformTCD<float>({{1, 3, 2, 1}}, {{2, 1, 5, 5, 2, 1, 5, 5, 2, 1, 5, 5, 2, 1, 5, 6}}));
84   _context->setBackends({"cpu"});
85
86   SUCCEED();
87 }
88 #endif
89
90 // Failure is expected except for aarch64 and cpu backend
91 TEST_F(GenModelTest, OneOp_neg_FullyConnectedShuffled16x1Float32)
92 {
93   CircleGen cgen;
94   // clang-format off
95   std::vector<float> weight_data{ 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4,
96                                   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
97                                   1, -1, 2, 1, 1, -1, 2, 1, 1, -1, 2, 1, 1, -1, 2, 1,
98                                   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
99   std::vector<float> bias_data{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
100   // clang-format on
101   uint32_t weight_buf = cgen.addBuffer(weight_data);
102   uint32_t bias_buf = cgen.addBuffer(bias_data);
103   int input = cgen.addTensor({{1, 4}, circle::TensorType::TensorType_FLOAT32});
104   int weight = cgen.addTensor({{16, 4}, circle::TensorType::TensorType_FLOAT32, weight_buf});
105   int bias = cgen.addTensor({{16}, circle::TensorType::TensorType_FLOAT32, bias_buf});
106   int output = cgen.addTensor({{1, 16}, circle::TensorType::TensorType_FLOAT32});
107   cgen.addOperatorFullyConnected({{input, weight, bias}, {output}},
108                                  circle::FullyConnectedOptionsWeightsFormat_SHUFFLED16x1FLOAT32);
109   cgen.setInputsAndOutputs({input}, {output});
110
111   _context = std::make_unique<GenModelTestContext>(cgen.finish());
112   auto tc = uniformTCD<float>({{1, 3, 2, 1}}, {{2, 1, 5, 5, 2, 1, 5, 5, 2, 1, 5, 5, 2, 1, 5, 6}});
113   _context->addTestCase(tc);
114   _context->setBackends({"acl_neon", "acl_cl"});
115   _context->expectFailCompile();
116
117   SUCCEED();
118 }
119
120 TEST_F(GenModelTest, OneOp_FullyConnected16x1Sparse)
121 {
122   CircleGen cgen;
123   // clang-format off
124   std::vector<float> weight_data{ 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4,
125                                   1, -1, 2, 1, 1, -1, 2, 1, 1, -1, 2, 1, 1, -1, 2, 1};
126   std::vector<float> bias_data{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
127   // clang-format on
128   uint32_t weight_buf = cgen.addBuffer(weight_data);
129   uint32_t bias_buf = cgen.addBuffer(bias_data);
130   int input = cgen.addTensor({{1, 4}, circle::TensorType::TensorType_FLOAT32});
131   CircleGen::SparsityParams sp{
132     {0, 1, 2, 3},
133     {0, 1},
134     {{CircleGen::SparseDimensionType::DimensionType_DENSE, 1},
135      {CircleGen::SparseDimensionType::DimensionType_SPARSE_CSR, {0, 2}, {0, 3}},
136      {CircleGen::SparseDimensionType::DimensionType_DENSE, 16},
137      {CircleGen::SparseDimensionType::DimensionType_DENSE, 1}}};
138   int weight = cgen.addTensor({{16, 4}, circle::TensorType::TensorType_FLOAT32, weight_buf}, sp);
139   int bias = cgen.addTensor({{16}, circle::TensorType::TensorType_FLOAT32, bias_buf});
140   int output = cgen.addTensor({{1, 16}, circle::TensorType::TensorType_FLOAT32});
141   cgen.addOperatorFullyConnected({{input, weight, bias}, {output}});
142   cgen.setInputsAndOutputs({input}, {output});
143
144   _context = std::make_unique<GenModelTestContext>(cgen.finish());
145   _context->addTestCase(
146     uniformTCD<float>({{1, 3, 2, 1}}, {{2, 1, 5, 5, 2, 1, 5, 5, 2, 1, 5, 5, 2, 1, 5, 6}}));
147   _context->setBackends({"cpu"});
148
149   SUCCEED();
150 }
151
152 TEST_F(GenModelTest, OneOp_FullyConnected_OptionalBias)
153 {
154   CircleGen cgen;
155   // clang-format off
156   std::vector<float> weight_data{ -1,  4,  0,  3,
157                                    1,  4,  0, -1,
158                                    3, -1,  0, -1,
159                                   -1,  3,  4,  4,
160                                    4,  0,  4,  0,
161                                    4,  1, -1,  1,
162                                    2,  2, -2, -1,
163                                    4, -1, -2,  3 };
164   // clang-format on
165   uint32_t weight_buf = cgen.addBuffer(weight_data);
166   int input = cgen.addTensor({{2, 4}, circle::TensorType::TensorType_FLOAT32});
167   int weight = cgen.addTensor({{8, 4}, circle::TensorType::TensorType_FLOAT32, weight_buf});
168   int output = cgen.addTensor({{2, 8}, circle::TensorType::TensorType_FLOAT32});
169   cgen.addOperatorFullyConnected({{input, weight, -1 /* Optional bias */}, {output}});
170   cgen.setInputsAndOutputs({input}, {output});
171
172   _context = std::make_unique<GenModelTestContext>(cgen.finish());
173   _context->addTestCase(
174     uniformTCD<float>({{3, -1, -1, 1, -2, 0, -2, 1}},
175                       {{-4, -2, 9, -6, 8, 13, 5, 18, 5, -3, -7, -2, -16, -5, -1, -1}}));
176   _context->setBackends({"acl_cl", "acl_neon", "cpu", "xnnpack", "ruy"});
177
178   SUCCEED();
179 }
180
181 TEST_F(GenModelTest, neg_OneOp_FullyConnected_NoBias)
182 {
183   CircleGen cgen;
184   // clang-format off
185   std::vector<float> weight_data{ -1,  4,  0,  3,
186                                    1,  4,  0, -1,
187                                    3, -1,  0, -1,
188                                   -1,  3,  4,  4,
189                                    4,  0,  4,  0,
190                                    4,  1, -1,  1,
191                                    2,  2, -2, -1,
192                                    4, -1, -2,  3 };
193   // clang-format on
194   uint32_t weight_buf = cgen.addBuffer(weight_data);
195   int input = cgen.addTensor({{2, 4}, circle::TensorType::TensorType_FLOAT32});
196   int weight = cgen.addTensor({{8, 4}, circle::TensorType::TensorType_FLOAT32, weight_buf});
197   int output = cgen.addTensor({{2, 8}, circle::TensorType::TensorType_FLOAT32});
198   cgen.addOperatorFullyConnected({{input, weight /* Missing bias */}, {output}});
199   cgen.setInputsAndOutputs({input}, {output});
200
201   _context = std::make_unique<GenModelTestContext>(cgen.finish());
202   _context->addTestCase(
203     uniformTCD<float>({{3, -1, -1, 1, -2, 0, -2, 1}},
204                       {{-4, -2, 9, -6, 8, 13, 5, 18, 5, -3, -7, -2, -16, -5, -1, -1}}));
205   _context->setBackends({"acl_cl", "acl_neon", "cpu", "xnnpack", "ruy"});
206   _context->expectFailCompile();
207
208   SUCCEED();
209 }