blob: e8b5dc267d4ca2d49d16637a7811c360e11a4218 [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};
Ellen Norris-Thompson976ad3e2019-08-21 15:21:14 +010073 AddPoolAndSetData<float>(3, request, indata);
surmeh0149b9e102018-05-17 14:11:25 +010074
75 // add memory for the output
Ellen Norris-Thompson976ad3e2019-08-21 15:21:14 +010076 android::sp<IMemory> outMemory = AddPoolAndGetData<float>(1, request);
surmeh0149b9e102018-05-17 14:11:25 +010077 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
surmeh0149b9e102018-05-17 14:11:25 +0100129 // construct the request
130 DataLocation inloc = {};
131 inloc.poolIndex = 0;
132 inloc.offset = 0;
133 inloc.length = 8 * sizeof(float);
134 RequestArgument input = {};
135 input.location = inloc;
136 input.dimensions = hidl_vec<uint32_t>{};
137
138 DataLocation outloc = {};
139 outloc.poolIndex = 1;
140 outloc.offset = 0;
141 outloc.length = 8 * sizeof(float);
142 RequestArgument output = {};
143 output.location = outloc;
144 output.dimensions = hidl_vec<uint32_t>{};
145
146 Request request = {};
147 request.inputs = hidl_vec<RequestArgument>{input};
148 request.outputs = hidl_vec<RequestArgument>{output};
149
150 // set the input data
151 float indata[] = {1,2,3,4,5,6,7,8};
152 AddPoolAndSetData(8, request, indata);
153
154 // add memory for the output
Ellen Norris-Thompson976ad3e2019-08-21 15:21:14 +0100155 android::sp<IMemory> outMemory = AddPoolAndGetData<float>(8, request);
surmeh0149b9e102018-05-17 14:11:25 +0100156 float* outdata = static_cast<float*>(static_cast<void*>(outMemory->getPointer()));
157
158 // run the execution
159 Execute(preparedModel, request);
160
161 // check the result
162 BOOST_TEST(outdata[0] == 1);
163 BOOST_TEST(outdata[1] == 2);
164 BOOST_TEST(outdata[2] == 3);
165 BOOST_TEST(outdata[3] == 4);
166 BOOST_TEST(outdata[4] == 5);
167 BOOST_TEST(outdata[5] == 6);
168 BOOST_TEST(outdata[6] == 7);
169 BOOST_TEST(outdata[7] == 8);
170}
171
172BOOST_AUTO_TEST_CASE(TestFullyConnected4dInputReshape)
173{
174 auto driver = std::make_unique<ArmnnDriver>(DriverOptions(armnn::Compute::CpuRef));
175
176 ErrorStatus error;
177 std::vector<bool> sup;
178
179 ArmnnDriver::getSupportedOperations_cb cb = [&](ErrorStatus status, const std::vector<bool>& supported)
180 {
181 error = status;
182 sup = supported;
183 };
184
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100185 HalPolicy::Model model = {};
surmeh0149b9e102018-05-17 14:11:25 +0100186
187 // operands
188 int32_t actValue = 0;
189 float weightValue[] = {1, 0, 0, 0, 0, 0, 0, 0,
190 0, 1, 0, 0, 0, 0, 0, 0,
191 0, 0, 1, 0, 0, 0, 0, 0,
192 0, 0, 0, 1, 0, 0, 0, 0,
193 0, 0, 0, 0, 1, 0, 0, 0,
194 0, 0, 0, 0, 0, 1, 0, 0,
195 0, 0, 0, 0, 0, 0, 1, 0,
196 0, 0, 0, 0, 0, 0, 0, 1}; //identity
197 float biasValue[] = {0, 0, 0, 0, 0, 0, 0, 0};
198
199 // fully connected operation
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100200 AddInputOperand<HalPolicy>(model, hidl_vec<uint32_t>{1, 2, 2, 2});
201 AddTensorOperand<HalPolicy>(model, hidl_vec<uint32_t>{8, 8}, weightValue);
202 AddTensorOperand<HalPolicy>(model, hidl_vec<uint32_t>{8}, biasValue);
203 AddIntOperand<HalPolicy>(model, actValue);
204 AddOutputOperand<HalPolicy>(model, hidl_vec<uint32_t>{1, 8});
surmeh0149b9e102018-05-17 14:11:25 +0100205
206 model.operations.resize(1);
207
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100208 model.operations[0].type = HalPolicy::OperationType::FULLY_CONNECTED;
surmeh0149b9e102018-05-17 14:11:25 +0100209 model.operations[0].inputs = hidl_vec<uint32_t>{0,1,2,3};
210 model.operations[0].outputs = hidl_vec<uint32_t>{4};
211
212 // make the prepared model
Sadik Armagane6e54a82019-05-08 10:18:05 +0100213 android::sp<V1_0::IPreparedModel> preparedModel = PrepareModel(model, *driver);
surmeh0149b9e102018-05-17 14:11:25 +0100214
surmeh0149b9e102018-05-17 14:11:25 +0100215 // construct the request
216 DataLocation inloc = {};
217 inloc.poolIndex = 0;
218 inloc.offset = 0;
219 inloc.length = 8 * sizeof(float);
220 RequestArgument input = {};
221 input.location = inloc;
222 input.dimensions = hidl_vec<uint32_t>{};
223
224 DataLocation outloc = {};
225 outloc.poolIndex = 1;
226 outloc.offset = 0;
227 outloc.length = 8 * sizeof(float);
228 RequestArgument output = {};
229 output.location = outloc;
230 output.dimensions = hidl_vec<uint32_t>{};
231
232 Request request = {};
233 request.inputs = hidl_vec<RequestArgument>{input};
234 request.outputs = hidl_vec<RequestArgument>{output};
235
236 // set the input data
237 float indata[] = {1,2,3,4,5,6,7,8};
238 AddPoolAndSetData(8, request, indata);
239
240 // add memory for the output
Ellen Norris-Thompson976ad3e2019-08-21 15:21:14 +0100241 android::sp<IMemory> outMemory = AddPoolAndGetData<float>(8, request);
surmeh0149b9e102018-05-17 14:11:25 +0100242 float* outdata = static_cast<float*>(static_cast<void*>(outMemory->getPointer()));
243
244 // run the execution
245 Execute(preparedModel, request);
246
247 // check the result
248 BOOST_TEST(outdata[0] == 1);
249 BOOST_TEST(outdata[1] == 2);
250 BOOST_TEST(outdata[2] == 3);
251 BOOST_TEST(outdata[3] == 4);
252 BOOST_TEST(outdata[4] == 5);
253 BOOST_TEST(outdata[5] == 6);
254 BOOST_TEST(outdata[6] == 7);
255 BOOST_TEST(outdata[7] == 8);
256}
257
258BOOST_AUTO_TEST_SUITE_END()