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