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