blob: de885153745b9b42ca5a658a593cbdec4f538490 [file] [log] [blame]
surmeh0149b9e102018-05-17 14:11:25 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
David Beck93e48982018-09-05 13:05:09 +01003// SPDX-License-Identifier: MIT
surmeh0149b9e102018-05-17 14:11:25 +01004//
5#include "DriverTestHelpers.hpp"
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +01006
7#include "../1.0/HalPolicy.hpp"
8
surmeh0149b9e102018-05-17 14:11:25 +01009#include <boost/test/unit_test.hpp>
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +010010
surmeh0149b9e102018-05-17 14:11:25 +010011#include <log/log.h>
12
13BOOST_AUTO_TEST_SUITE(FullyConnectedTests)
14
telsoa01ce3e84a2018-08-31 09:31:35 +010015using namespace android::hardware;
surmeh0149b9e102018-05-17 14:11:25 +010016using namespace driverTestHelpers;
telsoa01ce3e84a2018-08-31 09:31:35 +010017using namespace armnn_driver;
surmeh0149b9e102018-05-17 14:11:25 +010018
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +010019using HalPolicy = hal_1_0::HalPolicy;
20
surmeh0149b9e102018-05-17 14:11:25 +010021// Add our own test here since we fail the fc tests which Google supplies (because of non-const weights)
22BOOST_AUTO_TEST_CASE(FullyConnected)
23{
24 // this should ideally replicate fully_connected_float.model.cpp
25 // but that uses slightly weird dimensions which I don't think we need to support for now
26
27 auto driver = std::make_unique<ArmnnDriver>(DriverOptions(armnn::Compute::CpuRef));
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +010028 HalPolicy::Model model = {};
surmeh0149b9e102018-05-17 14:11:25 +010029
30 // add operands
31 int32_t actValue = 0;
32 float weightValue[] = {2, 4, 1};
33 float biasValue[] = {4};
34
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +010035 AddInputOperand<HalPolicy>(model, hidl_vec<uint32_t>{1, 3});
36 AddTensorOperand<HalPolicy>(model, hidl_vec<uint32_t>{1, 3}, weightValue);
37 AddTensorOperand<HalPolicy>(model, hidl_vec<uint32_t>{1}, biasValue);
38 AddIntOperand<HalPolicy>(model, actValue);
39 AddOutputOperand<HalPolicy>(model, hidl_vec<uint32_t>{1, 1});
surmeh0149b9e102018-05-17 14:11:25 +010040
41 // make the fully connected operation
42 model.operations.resize(1);
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +010043 model.operations[0].type = HalPolicy::OperationType::FULLY_CONNECTED;
surmeh0149b9e102018-05-17 14:11:25 +010044 model.operations[0].inputs = hidl_vec<uint32_t>{0, 1, 2, 3};
45 model.operations[0].outputs = hidl_vec<uint32_t>{4};
46
47 // make the prepared model
Sadik Armagane6e54a82019-05-08 10:18:05 +010048 android::sp<V1_0::IPreparedModel> preparedModel = PrepareModel(model, *driver);
surmeh0149b9e102018-05-17 14:11:25 +010049
50 // construct the request
51 DataLocation inloc = {};
52 inloc.poolIndex = 0;
53 inloc.offset = 0;
54 inloc.length = 3 * sizeof(float);
55 RequestArgument input = {};
56 input.location = inloc;
57 input.dimensions = hidl_vec<uint32_t>{};
58
59 DataLocation outloc = {};
60 outloc.poolIndex = 1;
61 outloc.offset = 0;
62 outloc.length = 1 * sizeof(float);
63 RequestArgument output = {};
64 output.location = outloc;
65 output.dimensions = hidl_vec<uint32_t>{};
66
67 Request request = {};
68 request.inputs = hidl_vec<RequestArgument>{input};
69 request.outputs = hidl_vec<RequestArgument>{output};
70
71 // set the input data (matching source test)
72 float indata[] = {2, 32, 16};
73 AddPoolAndSetData(3, request, indata);
74
75 // add memory for the output
76 android::sp<IMemory> outMemory = AddPoolAndGetData(1, request);
77 float* outdata = static_cast<float*>(static_cast<void*>(outMemory->getPointer()));
78
79 // run the execution
80 Execute(preparedModel, request);
81
82 // check the result
83 BOOST_TEST(outdata[0] == 152);
84}
85
86BOOST_AUTO_TEST_CASE(TestFullyConnected4dInput)
87{
88 auto driver = std::make_unique<ArmnnDriver>(DriverOptions(armnn::Compute::CpuRef));
89
90 ErrorStatus error;
91 std::vector<bool> sup;
92
93 ArmnnDriver::getSupportedOperations_cb cb = [&](ErrorStatus status, const std::vector<bool>& supported)
94 {
95 error = status;
96 sup = supported;
97 };
98
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +010099 HalPolicy::Model model = {};
surmeh0149b9e102018-05-17 14:11:25 +0100100
101 // operands
102 int32_t actValue = 0;
103 float weightValue[] = {1, 0, 0, 0, 0, 0, 0, 0,
104 0, 1, 0, 0, 0, 0, 0, 0,
105 0, 0, 1, 0, 0, 0, 0, 0,
106 0, 0, 0, 1, 0, 0, 0, 0,
107 0, 0, 0, 0, 1, 0, 0, 0,
108 0, 0, 0, 0, 0, 1, 0, 0,
109 0, 0, 0, 0, 0, 0, 1, 0,
110 0, 0, 0, 0, 0, 0, 0, 1}; //identity
111 float biasValue[] = {0, 0, 0, 0, 0, 0, 0, 0};
112
113 // fully connected operation
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100114 AddInputOperand<HalPolicy>(model, hidl_vec<uint32_t>{1, 1, 1, 8});
115 AddTensorOperand<HalPolicy>(model, hidl_vec<uint32_t>{8, 8}, weightValue);
116 AddTensorOperand<HalPolicy>(model, hidl_vec<uint32_t>{8}, biasValue);
117 AddIntOperand<HalPolicy>(model, actValue);
118 AddOutputOperand<HalPolicy>(model, hidl_vec<uint32_t>{1, 8});
surmeh0149b9e102018-05-17 14:11:25 +0100119
120 model.operations.resize(1);
121
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100122 model.operations[0].type = HalPolicy::OperationType::FULLY_CONNECTED;
surmeh0149b9e102018-05-17 14:11:25 +0100123 model.operations[0].inputs = hidl_vec<uint32_t>{0,1,2,3};
124 model.operations[0].outputs = hidl_vec<uint32_t>{4};
125
126 // make the prepared model
Sadik Armagane6e54a82019-05-08 10:18:05 +0100127 android::sp<V1_0::IPreparedModel> preparedModel = PrepareModel(model, *driver);
surmeh0149b9e102018-05-17 14:11:25 +0100128
129
130 // construct the request
131 DataLocation inloc = {};
132 inloc.poolIndex = 0;
133 inloc.offset = 0;
134 inloc.length = 8 * sizeof(float);
135 RequestArgument input = {};
136 input.location = inloc;
137 input.dimensions = hidl_vec<uint32_t>{};
138
139 DataLocation outloc = {};
140 outloc.poolIndex = 1;
141 outloc.offset = 0;
142 outloc.length = 8 * sizeof(float);
143 RequestArgument output = {};
144 output.location = outloc;
145 output.dimensions = hidl_vec<uint32_t>{};
146
147 Request request = {};
148 request.inputs = hidl_vec<RequestArgument>{input};
149 request.outputs = hidl_vec<RequestArgument>{output};
150
151 // set the input data
152 float indata[] = {1,2,3,4,5,6,7,8};
153 AddPoolAndSetData(8, request, indata);
154
155 // add memory for the output
156 android::sp<IMemory> outMemory = AddPoolAndGetData(8, request);
157 float* outdata = static_cast<float*>(static_cast<void*>(outMemory->getPointer()));
158
159 // run the execution
160 Execute(preparedModel, request);
161
162 // check the result
163 BOOST_TEST(outdata[0] == 1);
164 BOOST_TEST(outdata[1] == 2);
165 BOOST_TEST(outdata[2] == 3);
166 BOOST_TEST(outdata[3] == 4);
167 BOOST_TEST(outdata[4] == 5);
168 BOOST_TEST(outdata[5] == 6);
169 BOOST_TEST(outdata[6] == 7);
170 BOOST_TEST(outdata[7] == 8);
171}
172
173BOOST_AUTO_TEST_CASE(TestFullyConnected4dInputReshape)
174{
175 auto driver = std::make_unique<ArmnnDriver>(DriverOptions(armnn::Compute::CpuRef));
176
177 ErrorStatus error;
178 std::vector<bool> sup;
179
180 ArmnnDriver::getSupportedOperations_cb cb = [&](ErrorStatus status, const std::vector<bool>& supported)
181 {
182 error = status;
183 sup = supported;
184 };
185
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100186 HalPolicy::Model model = {};
surmeh0149b9e102018-05-17 14:11:25 +0100187
188 // operands
189 int32_t actValue = 0;
190 float weightValue[] = {1, 0, 0, 0, 0, 0, 0, 0,
191 0, 1, 0, 0, 0, 0, 0, 0,
192 0, 0, 1, 0, 0, 0, 0, 0,
193 0, 0, 0, 1, 0, 0, 0, 0,
194 0, 0, 0, 0, 1, 0, 0, 0,
195 0, 0, 0, 0, 0, 1, 0, 0,
196 0, 0, 0, 0, 0, 0, 1, 0,
197 0, 0, 0, 0, 0, 0, 0, 1}; //identity
198 float biasValue[] = {0, 0, 0, 0, 0, 0, 0, 0};
199
200 // fully connected operation
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100201 AddInputOperand<HalPolicy>(model, hidl_vec<uint32_t>{1, 2, 2, 2});
202 AddTensorOperand<HalPolicy>(model, hidl_vec<uint32_t>{8, 8}, weightValue);
203 AddTensorOperand<HalPolicy>(model, hidl_vec<uint32_t>{8}, biasValue);
204 AddIntOperand<HalPolicy>(model, actValue);
205 AddOutputOperand<HalPolicy>(model, hidl_vec<uint32_t>{1, 8});
surmeh0149b9e102018-05-17 14:11:25 +0100206
207 model.operations.resize(1);
208
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100209 model.operations[0].type = HalPolicy::OperationType::FULLY_CONNECTED;
surmeh0149b9e102018-05-17 14:11:25 +0100210 model.operations[0].inputs = hidl_vec<uint32_t>{0,1,2,3};
211 model.operations[0].outputs = hidl_vec<uint32_t>{4};
212
213 // make the prepared model
Sadik Armagane6e54a82019-05-08 10:18:05 +0100214 android::sp<V1_0::IPreparedModel> preparedModel = PrepareModel(model, *driver);
surmeh0149b9e102018-05-17 14:11:25 +0100215
216
217 // construct the request
218 DataLocation inloc = {};
219 inloc.poolIndex = 0;
220 inloc.offset = 0;
221 inloc.length = 8 * sizeof(float);
222 RequestArgument input = {};
223 input.location = inloc;
224 input.dimensions = hidl_vec<uint32_t>{};
225
226 DataLocation outloc = {};
227 outloc.poolIndex = 1;
228 outloc.offset = 0;
229 outloc.length = 8 * sizeof(float);
230 RequestArgument output = {};
231 output.location = outloc;
232 output.dimensions = hidl_vec<uint32_t>{};
233
234 Request request = {};
235 request.inputs = hidl_vec<RequestArgument>{input};
236 request.outputs = hidl_vec<RequestArgument>{output};
237
238 // set the input data
239 float indata[] = {1,2,3,4,5,6,7,8};
240 AddPoolAndSetData(8, request, indata);
241
242 // add memory for the output
243 android::sp<IMemory> outMemory = AddPoolAndGetData(8, request);
244 float* outdata = static_cast<float*>(static_cast<void*>(outMemory->getPointer()));
245
246 // run the execution
247 Execute(preparedModel, request);
248
249 // check the result
250 BOOST_TEST(outdata[0] == 1);
251 BOOST_TEST(outdata[1] == 2);
252 BOOST_TEST(outdata[2] == 3);
253 BOOST_TEST(outdata[3] == 4);
254 BOOST_TEST(outdata[4] == 5);
255 BOOST_TEST(outdata[5] == 6);
256 BOOST_TEST(outdata[6] == 7);
257 BOOST_TEST(outdata[7] == 8);
258}
259
260BOOST_AUTO_TEST_SUITE_END()