blob: 50ba0e9f374963743e34b1b8818221b8f40d81b2 [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(ConcurrentDriverTests)
14
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +010015using ArmnnDriver = armnn_driver::ArmnnDriver;
surmeh0149b9e102018-05-17 14:11:25 +010016using DriverOptions = armnn_driver::DriverOptions;
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +010017using HalPolicy = armnn_driver::hal_1_0::HalPolicy;
Sadik Armagan188675f2021-02-12 17:16:42 +000018using RequestArgument = V1_0::RequestArgument;
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +010019
surmeh0149b9e102018-05-17 14:11:25 +010020using namespace android::nn;
telsoa01ce3e84a2018-08-31 09:31:35 +010021using namespace android::hardware;
surmeh0149b9e102018-05-17 14:11:25 +010022using namespace driverTestHelpers;
telsoa01ce3e84a2018-08-31 09:31:35 +010023using namespace armnn_driver;
surmeh0149b9e102018-05-17 14:11:25 +010024
25// Add our own test for concurrent execution
26// The main point of this test is to check that multiple requests can be
27// executed without waiting for the callback from previous execution.
28// The operations performed are not significant.
29BOOST_AUTO_TEST_CASE(ConcurrentExecute)
30{
31 ALOGI("ConcurrentExecute: entry");
32
33 auto driver = std::make_unique<ArmnnDriver>(DriverOptions(armnn::Compute::CpuRef));
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +010034 HalPolicy::Model model = {};
surmeh0149b9e102018-05-17 14:11:25 +010035
36 // add operands
37 int32_t actValue = 0;
38 float weightValue[] = {2, 4, 1};
39 float biasValue[] = {4};
40
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +010041 AddInputOperand<HalPolicy>(model, hidl_vec<uint32_t>{1, 3});
42 AddTensorOperand<HalPolicy>(model, hidl_vec<uint32_t>{1, 3}, weightValue);
43 AddTensorOperand<HalPolicy>(model, hidl_vec<uint32_t>{1}, biasValue);
44 AddIntOperand<HalPolicy>(model, actValue);
45 AddOutputOperand<HalPolicy>(model, hidl_vec<uint32_t>{1, 1});
surmeh0149b9e102018-05-17 14:11:25 +010046
47 // make the fully connected operation
48 model.operations.resize(1);
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +010049 model.operations[0].type = HalPolicy::OperationType::FULLY_CONNECTED;
surmeh0149b9e102018-05-17 14:11:25 +010050 model.operations[0].inputs = hidl_vec<uint32_t>{0, 1, 2, 3};
51 model.operations[0].outputs = hidl_vec<uint32_t>{4};
52
53 // make the prepared models
54 const size_t maxRequests = 5;
Sadik Armagand4636872020-04-27 10:15:41 +010055 size_t preparedModelsSize = 0;
Sadik Armagane6e54a82019-05-08 10:18:05 +010056 android::sp<V1_0::IPreparedModel> preparedModels[maxRequests];
surmeh0149b9e102018-05-17 14:11:25 +010057 for (size_t i = 0; i < maxRequests; ++i)
58 {
Sadik Armagand4636872020-04-27 10:15:41 +010059 auto preparedModel = PrepareModel(model, *driver);
60 if (preparedModel.get() != nullptr)
61 {
62 preparedModels[i] = PrepareModel(model, *driver);
63 preparedModelsSize++;
64 }
surmeh0149b9e102018-05-17 14:11:25 +010065 }
66
Sadik Armagand4636872020-04-27 10:15:41 +010067 BOOST_TEST(maxRequests == preparedModelsSize);
68
surmeh0149b9e102018-05-17 14:11:25 +010069 // construct the request data
Sadik Armagan188675f2021-02-12 17:16:42 +000070 V1_0::DataLocation inloc = {};
71 inloc.poolIndex = 0;
72 inloc.offset = 0;
73 inloc.length = 3 * sizeof(float);
74 RequestArgument input = {};
75 input.location = inloc;
76 input.dimensions = hidl_vec<uint32_t>{};
surmeh0149b9e102018-05-17 14:11:25 +010077
Sadik Armagan188675f2021-02-12 17:16:42 +000078 V1_0::DataLocation outloc = {};
79 outloc.poolIndex = 1;
80 outloc.offset = 0;
81 outloc.length = 1 * sizeof(float);
82 RequestArgument output = {};
83 output.location = outloc;
84 output.dimensions = hidl_vec<uint32_t>{};
surmeh0149b9e102018-05-17 14:11:25 +010085
86 // build the requests
Kevin Mayec1e5b82020-02-26 17:00:39 +000087 V1_0::Request requests[maxRequests];
surmeh0149b9e102018-05-17 14:11:25 +010088 android::sp<IMemory> outMemory[maxRequests];
89 float* outdata[maxRequests];
90 for (size_t i = 0; i < maxRequests; ++i)
91 {
92 requests[i].inputs = hidl_vec<RequestArgument>{input};
93 requests[i].outputs = hidl_vec<RequestArgument>{output};
94 // set the input data (matching source test)
95 float indata[] = {2, 32, 16};
Ellen Norris-Thompson976ad3e2019-08-21 15:21:14 +010096 AddPoolAndSetData<float>(3, requests[i], indata);
surmeh0149b9e102018-05-17 14:11:25 +010097 // add memory for the output
Ellen Norris-Thompson976ad3e2019-08-21 15:21:14 +010098 outMemory[i] = AddPoolAndGetData<float>(1, requests[i]);
surmeh0149b9e102018-05-17 14:11:25 +010099 outdata[i] = static_cast<float*>(static_cast<void*>(outMemory[i]->getPointer()));
100 }
101
102 // invoke the execution of the requests
103 ALOGI("ConcurrentExecute: executing requests");
104 android::sp<ExecutionCallback> cb[maxRequests];
105 for (size_t i = 0; i < maxRequests; ++i)
106 {
107 cb[i] = ExecuteNoWait(preparedModels[i], requests[i]);
108 }
109
110 // wait for the requests to complete
111 ALOGI("ConcurrentExecute: waiting for callbacks");
112 for (size_t i = 0; i < maxRequests; ++i)
113 {
David Monahanc60d0fd2020-05-19 14:58:34 +0100114 ARMNN_ASSERT(cb[i]);
surmeh0149b9e102018-05-17 14:11:25 +0100115 cb[i]->wait();
116 }
117
118 // check the results
119 ALOGI("ConcurrentExecute: validating results");
120 for (size_t i = 0; i < maxRequests; ++i)
121 {
122 BOOST_TEST(outdata[i][0] == 152);
123 }
124 ALOGI("ConcurrentExecute: exit");
125}
126
127BOOST_AUTO_TEST_SUITE_END()