blob: 2f9cd4b28c813e18f04c03b60d8f901d4a2c99a0 [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
Kevin Mayec1e5b82020-02-26 17:00:39 +000067 V1_0::Request request = {};
surmeh0149b9e102018-05-17 14:11:25 +010068 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
Sadik Armagand4636872020-04-27 10:15:41 +010080 if (preparedModel.get() != nullptr)
81 {
82 Execute(preparedModel, request);
83 }
surmeh0149b9e102018-05-17 14:11:25 +010084
85 // check the result
86 BOOST_TEST(outdata[0] == 152);
87}
88
89BOOST_AUTO_TEST_CASE(TestFullyConnected4dInput)
90{
91 auto driver = std::make_unique<ArmnnDriver>(DriverOptions(armnn::Compute::CpuRef));
92
Kevin Mayec1e5b82020-02-26 17:00:39 +000093 V1_0::ErrorStatus error;
surmeh0149b9e102018-05-17 14:11:25 +010094 std::vector<bool> sup;
95
Kevin Mayec1e5b82020-02-26 17:00:39 +000096 ArmnnDriver::getSupportedOperations_cb cb = [&](V1_0::ErrorStatus status, const std::vector<bool>& supported)
surmeh0149b9e102018-05-17 14:11:25 +010097 {
98 error = status;
99 sup = supported;
100 };
101
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100102 HalPolicy::Model model = {};
surmeh0149b9e102018-05-17 14:11:25 +0100103
104 // operands
105 int32_t actValue = 0;
106 float weightValue[] = {1, 0, 0, 0, 0, 0, 0, 0,
107 0, 1, 0, 0, 0, 0, 0, 0,
108 0, 0, 1, 0, 0, 0, 0, 0,
109 0, 0, 0, 1, 0, 0, 0, 0,
110 0, 0, 0, 0, 1, 0, 0, 0,
111 0, 0, 0, 0, 0, 1, 0, 0,
112 0, 0, 0, 0, 0, 0, 1, 0,
113 0, 0, 0, 0, 0, 0, 0, 1}; //identity
114 float biasValue[] = {0, 0, 0, 0, 0, 0, 0, 0};
115
116 // fully connected operation
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100117 AddInputOperand<HalPolicy>(model, hidl_vec<uint32_t>{1, 1, 1, 8});
118 AddTensorOperand<HalPolicy>(model, hidl_vec<uint32_t>{8, 8}, weightValue);
119 AddTensorOperand<HalPolicy>(model, hidl_vec<uint32_t>{8}, biasValue);
120 AddIntOperand<HalPolicy>(model, actValue);
121 AddOutputOperand<HalPolicy>(model, hidl_vec<uint32_t>{1, 8});
surmeh0149b9e102018-05-17 14:11:25 +0100122
123 model.operations.resize(1);
124
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100125 model.operations[0].type = HalPolicy::OperationType::FULLY_CONNECTED;
surmeh0149b9e102018-05-17 14:11:25 +0100126 model.operations[0].inputs = hidl_vec<uint32_t>{0,1,2,3};
127 model.operations[0].outputs = hidl_vec<uint32_t>{4};
128
129 // make the prepared model
Sadik Armagane6e54a82019-05-08 10:18:05 +0100130 android::sp<V1_0::IPreparedModel> preparedModel = PrepareModel(model, *driver);
surmeh0149b9e102018-05-17 14:11:25 +0100131
surmeh0149b9e102018-05-17 14:11:25 +0100132 // construct the request
133 DataLocation inloc = {};
134 inloc.poolIndex = 0;
135 inloc.offset = 0;
136 inloc.length = 8 * sizeof(float);
137 RequestArgument input = {};
138 input.location = inloc;
139 input.dimensions = hidl_vec<uint32_t>{};
140
141 DataLocation outloc = {};
142 outloc.poolIndex = 1;
143 outloc.offset = 0;
144 outloc.length = 8 * sizeof(float);
145 RequestArgument output = {};
146 output.location = outloc;
147 output.dimensions = hidl_vec<uint32_t>{};
148
Kevin Mayec1e5b82020-02-26 17:00:39 +0000149 V1_0::Request request = {};
surmeh0149b9e102018-05-17 14:11:25 +0100150 request.inputs = hidl_vec<RequestArgument>{input};
151 request.outputs = hidl_vec<RequestArgument>{output};
152
153 // set the input data
154 float indata[] = {1,2,3,4,5,6,7,8};
155 AddPoolAndSetData(8, request, indata);
156
157 // add memory for the output
Ellen Norris-Thompson976ad3e2019-08-21 15:21:14 +0100158 android::sp<IMemory> outMemory = AddPoolAndGetData<float>(8, request);
surmeh0149b9e102018-05-17 14:11:25 +0100159 float* outdata = static_cast<float*>(static_cast<void*>(outMemory->getPointer()));
160
161 // run the execution
Sadik Armagand4636872020-04-27 10:15:41 +0100162 if (preparedModel != nullptr)
163 {
164 Execute(preparedModel, request);
165 }
surmeh0149b9e102018-05-17 14:11:25 +0100166
167 // check the result
168 BOOST_TEST(outdata[0] == 1);
169 BOOST_TEST(outdata[1] == 2);
170 BOOST_TEST(outdata[2] == 3);
171 BOOST_TEST(outdata[3] == 4);
172 BOOST_TEST(outdata[4] == 5);
173 BOOST_TEST(outdata[5] == 6);
174 BOOST_TEST(outdata[6] == 7);
175 BOOST_TEST(outdata[7] == 8);
176}
177
178BOOST_AUTO_TEST_CASE(TestFullyConnected4dInputReshape)
179{
180 auto driver = std::make_unique<ArmnnDriver>(DriverOptions(armnn::Compute::CpuRef));
181
Kevin Mayec1e5b82020-02-26 17:00:39 +0000182 V1_0::ErrorStatus error;
surmeh0149b9e102018-05-17 14:11:25 +0100183 std::vector<bool> sup;
184
Kevin Mayec1e5b82020-02-26 17:00:39 +0000185 ArmnnDriver::getSupportedOperations_cb cb = [&](V1_0::ErrorStatus status, const std::vector<bool>& supported)
surmeh0149b9e102018-05-17 14:11:25 +0100186 {
187 error = status;
188 sup = supported;
189 };
190
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100191 HalPolicy::Model model = {};
surmeh0149b9e102018-05-17 14:11:25 +0100192
193 // operands
194 int32_t actValue = 0;
195 float weightValue[] = {1, 0, 0, 0, 0, 0, 0, 0,
196 0, 1, 0, 0, 0, 0, 0, 0,
197 0, 0, 1, 0, 0, 0, 0, 0,
198 0, 0, 0, 1, 0, 0, 0, 0,
199 0, 0, 0, 0, 1, 0, 0, 0,
200 0, 0, 0, 0, 0, 1, 0, 0,
201 0, 0, 0, 0, 0, 0, 1, 0,
202 0, 0, 0, 0, 0, 0, 0, 1}; //identity
203 float biasValue[] = {0, 0, 0, 0, 0, 0, 0, 0};
204
205 // fully connected operation
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100206 AddInputOperand<HalPolicy>(model, hidl_vec<uint32_t>{1, 2, 2, 2});
207 AddTensorOperand<HalPolicy>(model, hidl_vec<uint32_t>{8, 8}, weightValue);
208 AddTensorOperand<HalPolicy>(model, hidl_vec<uint32_t>{8}, biasValue);
209 AddIntOperand<HalPolicy>(model, actValue);
210 AddOutputOperand<HalPolicy>(model, hidl_vec<uint32_t>{1, 8});
surmeh0149b9e102018-05-17 14:11:25 +0100211
212 model.operations.resize(1);
213
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100214 model.operations[0].type = HalPolicy::OperationType::FULLY_CONNECTED;
surmeh0149b9e102018-05-17 14:11:25 +0100215 model.operations[0].inputs = hidl_vec<uint32_t>{0,1,2,3};
216 model.operations[0].outputs = hidl_vec<uint32_t>{4};
217
218 // make the prepared model
Sadik Armagane6e54a82019-05-08 10:18:05 +0100219 android::sp<V1_0::IPreparedModel> preparedModel = PrepareModel(model, *driver);
surmeh0149b9e102018-05-17 14:11:25 +0100220
surmeh0149b9e102018-05-17 14:11:25 +0100221 // construct the request
222 DataLocation inloc = {};
223 inloc.poolIndex = 0;
224 inloc.offset = 0;
225 inloc.length = 8 * sizeof(float);
226 RequestArgument input = {};
227 input.location = inloc;
228 input.dimensions = hidl_vec<uint32_t>{};
229
230 DataLocation outloc = {};
231 outloc.poolIndex = 1;
232 outloc.offset = 0;
233 outloc.length = 8 * sizeof(float);
234 RequestArgument output = {};
235 output.location = outloc;
236 output.dimensions = hidl_vec<uint32_t>{};
237
Kevin Mayec1e5b82020-02-26 17:00:39 +0000238 V1_0::Request request = {};
surmeh0149b9e102018-05-17 14:11:25 +0100239 request.inputs = hidl_vec<RequestArgument>{input};
240 request.outputs = hidl_vec<RequestArgument>{output};
241
242 // set the input data
243 float indata[] = {1,2,3,4,5,6,7,8};
244 AddPoolAndSetData(8, request, indata);
245
246 // add memory for the output
Ellen Norris-Thompson976ad3e2019-08-21 15:21:14 +0100247 android::sp<IMemory> outMemory = AddPoolAndGetData<float>(8, request);
surmeh0149b9e102018-05-17 14:11:25 +0100248 float* outdata = static_cast<float*>(static_cast<void*>(outMemory->getPointer()));
249
250 // run the execution
Sadik Armagand4636872020-04-27 10:15:41 +0100251 if (preparedModel != nullptr)
252 {
253 Execute(preparedModel, request);
254 }
surmeh0149b9e102018-05-17 14:11:25 +0100255
256 // check the result
257 BOOST_TEST(outdata[0] == 1);
258 BOOST_TEST(outdata[1] == 2);
259 BOOST_TEST(outdata[2] == 3);
260 BOOST_TEST(outdata[3] == 4);
261 BOOST_TEST(outdata[4] == 5);
262 BOOST_TEST(outdata[5] == 6);
263 BOOST_TEST(outdata[6] == 7);
264 BOOST_TEST(outdata[7] == 8);
265}
266
267BOOST_AUTO_TEST_SUITE_END()