xref: /aosp_15_r20/external/android-nn-driver/test/1.3/QosTests.cpp (revision 3e777be0405cee09af5d5785ff37f7cfb5bee59a)
1*3e777be0SXin Li //
2*3e777be0SXin Li // Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
3*3e777be0SXin Li // SPDX-License-Identifier: MIT
4*3e777be0SXin Li //
5*3e777be0SXin Li 
6*3e777be0SXin Li #include "../DriverTestHelpers.hpp"
7*3e777be0SXin Li 
8*3e777be0SXin Li #include <1.3/HalPolicy.hpp>
9*3e777be0SXin Li 
10*3e777be0SXin Li DOCTEST_TEST_SUITE("QosTests")
11*3e777be0SXin Li {
12*3e777be0SXin Li using ArmnnDriver   = armnn_driver::ArmnnDriver;
13*3e777be0SXin Li using DriverOptions = armnn_driver::DriverOptions;
14*3e777be0SXin Li 
15*3e777be0SXin Li using namespace android::nn;
16*3e777be0SXin Li using namespace android::hardware;
17*3e777be0SXin Li using namespace driverTestHelpers;
18*3e777be0SXin Li using namespace armnn_driver;
19*3e777be0SXin Li 
20*3e777be0SXin Li using HalPolicy = hal_1_3::HalPolicy;
21*3e777be0SXin Li 
22*3e777be0SXin Li namespace
23*3e777be0SXin Li {
24*3e777be0SXin Li 
ExecuteModel(const armnn_driver::hal_1_3::HalPolicy::Model & model,armnn_driver::ArmnnDriver & driver,const V1_0::Request & request)25*3e777be0SXin Li void ExecuteModel(const armnn_driver::hal_1_3::HalPolicy::Model& model,
26*3e777be0SXin Li                   armnn_driver::ArmnnDriver& driver,
27*3e777be0SXin Li                   const V1_0::Request& request)
28*3e777be0SXin Li {
29*3e777be0SXin Li     android::sp<V1_3::IPreparedModel> preparedModel = PrepareModel_1_3(model, driver);
30*3e777be0SXin Li     if (preparedModel.get() != nullptr)
31*3e777be0SXin Li     {
32*3e777be0SXin Li         Execute(preparedModel, request);
33*3e777be0SXin Li     }
34*3e777be0SXin Li }
35*3e777be0SXin Li 
36*3e777be0SXin Li DOCTEST_TEST_CASE("ConcurrentExecuteWithQosPriority")
37*3e777be0SXin Li {
38*3e777be0SXin Li     ALOGI("ConcurrentExecuteWithQOSPriority: entry");
39*3e777be0SXin Li 
40*3e777be0SXin Li     auto driver = std::make_unique<ArmnnDriver>(DriverOptions(armnn::Compute::CpuRef));
41*3e777be0SXin Li     HalPolicy::Model model = {};
42*3e777be0SXin Li 
43*3e777be0SXin Li     // add operands
44*3e777be0SXin Li     int32_t actValue      = 0;
45*3e777be0SXin Li     float   weightValue[] = {2, 4, 1};
46*3e777be0SXin Li     float   biasValue[]   = {4};
47*3e777be0SXin Li 
48*3e777be0SXin Li     AddInputOperand<HalPolicy>(model, hidl_vec<uint32_t>{1, 3});
49*3e777be0SXin Li     AddTensorOperand<HalPolicy>(model,
50*3e777be0SXin Li                       hidl_vec<uint32_t>{1, 3},
51*3e777be0SXin Li                       weightValue,
52*3e777be0SXin Li                       HalPolicy::OperandType::TENSOR_FLOAT32,
53*3e777be0SXin Li                       V1_3::OperandLifeTime::CONSTANT_COPY);
54*3e777be0SXin Li     AddTensorOperand<HalPolicy>(model,
55*3e777be0SXin Li                       hidl_vec<uint32_t>{1},
56*3e777be0SXin Li                       biasValue,
57*3e777be0SXin Li                       HalPolicy::OperandType::TENSOR_FLOAT32,
58*3e777be0SXin Li                       V1_3::OperandLifeTime::CONSTANT_COPY);
59*3e777be0SXin Li     AddIntOperand<HalPolicy>(model, actValue);
60*3e777be0SXin Li     AddOutputOperand<HalPolicy>(model, hidl_vec<uint32_t>{1, 1});
61*3e777be0SXin Li 
62*3e777be0SXin Li     // make the fully connected operation
63*3e777be0SXin Li     model.main.operations.resize(1);
64*3e777be0SXin Li     model.main.operations[0].type    = HalPolicy::OperationType::FULLY_CONNECTED;
65*3e777be0SXin Li     model.main.operations[0].inputs  = hidl_vec<uint32_t>{0, 1, 2, 3};
66*3e777be0SXin Li     model.main.operations[0].outputs = hidl_vec<uint32_t>{4};
67*3e777be0SXin Li 
68*3e777be0SXin Li     // make the prepared models
69*3e777be0SXin Li     const size_t maxRequests = 45;
70*3e777be0SXin Li     size_t preparedModelsSize = 0;
71*3e777be0SXin Li     android::sp<V1_3::IPreparedModel> preparedModels[maxRequests];
72*3e777be0SXin Li     V1_3::ErrorStatus status(V1_3::ErrorStatus::NONE);
73*3e777be0SXin Li     size_t start = preparedModelsSize;
74*3e777be0SXin Li     for (size_t i = start; i < start+15; ++i)
75*3e777be0SXin Li     {
76*3e777be0SXin Li         preparedModels[i] = PrepareModelWithStatus_1_3(model, *driver, status, V1_3::Priority::LOW);
77*3e777be0SXin Li         preparedModelsSize++;
78*3e777be0SXin Li     }
79*3e777be0SXin Li     start = preparedModelsSize;
80*3e777be0SXin Li     for (size_t i = start; i < start+15; ++i)
81*3e777be0SXin Li     {
82*3e777be0SXin Li         preparedModels[i] = PrepareModelWithStatus_1_3(model, *driver, status, V1_3::Priority::MEDIUM);
83*3e777be0SXin Li         preparedModelsSize++;
84*3e777be0SXin Li     }
85*3e777be0SXin Li     start = preparedModelsSize;
86*3e777be0SXin Li     for (size_t i = start; i < start+15; ++i)
87*3e777be0SXin Li     {
88*3e777be0SXin Li         preparedModels[i] = PrepareModelWithStatus_1_3(model, *driver, status, V1_3::Priority::HIGH);
89*3e777be0SXin Li         preparedModelsSize++;
90*3e777be0SXin Li     }
91*3e777be0SXin Li 
92*3e777be0SXin Li     DOCTEST_CHECK(maxRequests == preparedModelsSize);
93*3e777be0SXin Li 
94*3e777be0SXin Li     // construct the request data
95*3e777be0SXin Li     V1_0::DataLocation inloc = {};
96*3e777be0SXin Li     inloc.poolIndex          = 0;
97*3e777be0SXin Li     inloc.offset             = 0;
98*3e777be0SXin Li     inloc.length             = 3 * sizeof(float);
99*3e777be0SXin Li     RequestArgument input    = {};
100*3e777be0SXin Li     input.location           = inloc;
101*3e777be0SXin Li     input.dimensions         = hidl_vec<uint32_t>{};
102*3e777be0SXin Li 
103*3e777be0SXin Li     V1_0::DataLocation outloc = {};
104*3e777be0SXin Li     outloc.poolIndex          = 1;
105*3e777be0SXin Li     outloc.offset             = 0;
106*3e777be0SXin Li     outloc.length             = 1 * sizeof(float);
107*3e777be0SXin Li     RequestArgument output    = {};
108*3e777be0SXin Li     output.location           = outloc;
109*3e777be0SXin Li     output.dimensions         = hidl_vec<uint32_t>{};
110*3e777be0SXin Li 
111*3e777be0SXin Li     // build the requests
112*3e777be0SXin Li     V1_0::Request requests[maxRequests];
113*3e777be0SXin Li     android::sp<IMemory> outMemory[maxRequests];
114*3e777be0SXin Li     float* outdata[maxRequests];
115*3e777be0SXin Li     for (size_t i = 0; i < maxRequests; ++i)
116*3e777be0SXin Li     {
117*3e777be0SXin Li         requests[i].inputs  = hidl_vec<RequestArgument>{input};
118*3e777be0SXin Li         requests[i].outputs = hidl_vec<RequestArgument>{output};
119*3e777be0SXin Li         // set the input data (matching source test)
120*3e777be0SXin Li         float inDataLow[] = {2, 32, 16};
121*3e777be0SXin Li         float inDataMedium[] = {1, 31, 11};
122*3e777be0SXin Li         float inDataHigh[] = {3, 33, 17};
123*3e777be0SXin Li         if (i < 15)
124*3e777be0SXin Li         {
125*3e777be0SXin Li             AddPoolAndSetData<float>(3, requests[i], inDataLow);
126*3e777be0SXin Li         }
127*3e777be0SXin Li         else if (i < 30)
128*3e777be0SXin Li         {
129*3e777be0SXin Li             AddPoolAndSetData<float>(3, requests[i], inDataMedium);
130*3e777be0SXin Li         }
131*3e777be0SXin Li         else
132*3e777be0SXin Li         {
133*3e777be0SXin Li             AddPoolAndSetData<float>(3, requests[i], inDataHigh);
134*3e777be0SXin Li         }
135*3e777be0SXin Li         // add memory for the output
136*3e777be0SXin Li         outMemory[i] = AddPoolAndGetData<float>(1, requests[i]);
137*3e777be0SXin Li         outdata[i] = static_cast<float*>(static_cast<void*>(outMemory[i]->getPointer()));
138*3e777be0SXin Li     }
139*3e777be0SXin Li 
140*3e777be0SXin Li     // invoke the execution of the requests
141*3e777be0SXin Li     ALOGI("ConcurrentExecuteWithQOSPriority: executing requests");
142*3e777be0SXin Li     android::sp<ExecutionCallback> cb[maxRequests];
143*3e777be0SXin Li     for (size_t i = 0; i < maxRequests; ++i)
144*3e777be0SXin Li     {
145*3e777be0SXin Li         cb[i] = ExecuteNoWait(preparedModels[i], requests[i]);
146*3e777be0SXin Li     }
147*3e777be0SXin Li 
148*3e777be0SXin Li     // wait for the requests to complete
149*3e777be0SXin Li     ALOGI("ConcurrentExecuteWithQOSPriority: waiting for callbacks");
150*3e777be0SXin Li     for (size_t i = 0; i < maxRequests; ++i)
151*3e777be0SXin Li     {
152*3e777be0SXin Li         DOCTEST_CHECK(cb[i]);
153*3e777be0SXin Li         cb[i]->wait();
154*3e777be0SXin Li     }
155*3e777be0SXin Li 
156*3e777be0SXin Li     // check the results
157*3e777be0SXin Li     ALOGI("ConcurrentExecuteWithQOSPriority: validating results");
158*3e777be0SXin Li     for (size_t i = 0; i < maxRequests; ++i)
159*3e777be0SXin Li     {
160*3e777be0SXin Li         if (i < 15)
161*3e777be0SXin Li         {
162*3e777be0SXin Li             DOCTEST_CHECK(outdata[i][0] == 152);
163*3e777be0SXin Li         }
164*3e777be0SXin Li         else if (i < 30)
165*3e777be0SXin Li         {
166*3e777be0SXin Li             DOCTEST_CHECK(outdata[i][0] == 141);
167*3e777be0SXin Li         }
168*3e777be0SXin Li         else
169*3e777be0SXin Li         {
170*3e777be0SXin Li             DOCTEST_CHECK(outdata[i][0] == 159);
171*3e777be0SXin Li         }
172*3e777be0SXin Li 
173*3e777be0SXin Li     }
174*3e777be0SXin Li     ALOGI("ConcurrentExecuteWithQOSPriority: exit");
175*3e777be0SXin Li }
176*3e777be0SXin Li 
177*3e777be0SXin Li } // anonymous namespace
178*3e777be0SXin Li 
179*3e777be0SXin Li }