// // Copyright © 2020 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "../DriverTestHelpers.hpp" #include "../TestTensor.hpp" #include "../1.3/HalPolicy.hpp" #include #include #include BOOST_AUTO_TEST_SUITE(QosTests) using ArmnnDriver = armnn_driver::ArmnnDriver; using DriverOptions = armnn_driver::DriverOptions; using namespace android::nn; using namespace android::hardware; using namespace driverTestHelpers; using namespace armnn_driver; using HalPolicy = hal_1_3::HalPolicy; namespace { void ExecuteModel(const armnn_driver::hal_1_3::HalPolicy::Model& model, armnn_driver::ArmnnDriver& driver, const V1_0::Request& request) { android::sp preparedModel = PrepareModel_1_3(model, driver); if (preparedModel.get() != nullptr) { Execute(preparedModel, request); } } #ifndef ARMCOMPUTECL_ENABLED static const std::array COMPUTE_DEVICES = {{ armnn::Compute::CpuRef }}; #else static const std::array COMPUTE_DEVICES = {{ armnn::Compute::CpuRef, armnn::Compute::CpuAcc }}; #endif BOOST_AUTO_TEST_CASE(ConcurrentExecuteWithQosPriority) { ALOGI("ConcurrentExecuteWithQOSPriority: entry"); auto driver = std::make_unique(DriverOptions(armnn::Compute::CpuRef)); HalPolicy::Model model = {}; // add operands int32_t actValue = 0; float weightValue[] = {2, 4, 1}; float biasValue[] = {4}; AddInputOperand(model, hidl_vec{1, 3}); AddTensorOperand(model, hidl_vec{1, 3}, weightValue, HalPolicy::OperandType::TENSOR_FLOAT32, V1_3::OperandLifeTime::CONSTANT_COPY); AddTensorOperand(model, hidl_vec{1}, biasValue, HalPolicy::OperandType::TENSOR_FLOAT32, V1_3::OperandLifeTime::CONSTANT_COPY); AddIntOperand(model, actValue); AddOutputOperand(model, hidl_vec{1, 1}); // make the fully connected operation model.main.operations.resize(1); model.main.operations[0].type = HalPolicy::OperationType::FULLY_CONNECTED; model.main.operations[0].inputs = hidl_vec{0, 1, 2, 3}; model.main.operations[0].outputs = hidl_vec{4}; // make the prepared models const size_t maxRequests = 45; size_t preparedModelsSize = 0; android::sp preparedModels[maxRequests]; V1_3::ErrorStatus status(V1_3::ErrorStatus::NONE); size_t start = preparedModelsSize; for (size_t i = start; i < start+15; ++i) { preparedModels[i] = PrepareModelWithStatus_1_3(model, *driver, status, V1_3::Priority::LOW); preparedModelsSize++; } start = preparedModelsSize; for (size_t i = start; i < start+15; ++i) { preparedModels[i] = PrepareModelWithStatus_1_3(model, *driver, status, V1_3::Priority::MEDIUM); preparedModelsSize++; } start = preparedModelsSize; for (size_t i = start; i < start+15; ++i) { preparedModels[i] = PrepareModelWithStatus_1_3(model, *driver, status, V1_3::Priority::HIGH); preparedModelsSize++; } BOOST_TEST(maxRequests == preparedModelsSize); // construct the request data DataLocation inloc = {}; inloc.poolIndex = 0; inloc.offset = 0; inloc.length = 3 * sizeof(float); RequestArgument input = {}; input.location = inloc; input.dimensions = hidl_vec{}; DataLocation outloc = {}; outloc.poolIndex = 1; outloc.offset = 0; outloc.length = 1 * sizeof(float); RequestArgument output = {}; output.location = outloc; output.dimensions = hidl_vec{}; // build the requests V1_0::Request requests[maxRequests]; android::sp outMemory[maxRequests]; float* outdata[maxRequests]; for (size_t i = 0; i < maxRequests; ++i) { requests[i].inputs = hidl_vec{input}; requests[i].outputs = hidl_vec{output}; // set the input data (matching source test) float inDataLow[] = {2, 32, 16}; float inDataMedium[] = {1, 31, 11}; float inDataHigh[] = {3, 33, 17}; if (i < 15) { AddPoolAndSetData(3, requests[i], inDataLow); } else if (i < 30) { AddPoolAndSetData(3, requests[i], inDataMedium); } else { AddPoolAndSetData(3, requests[i], inDataHigh); } // add memory for the output outMemory[i] = AddPoolAndGetData(1, requests[i]); outdata[i] = static_cast(static_cast(outMemory[i]->getPointer())); } // invoke the execution of the requests ALOGI("ConcurrentExecuteWithQOSPriority: executing requests"); android::sp cb[maxRequests]; for (size_t i = 0; i < maxRequests; ++i) { cb[i] = ExecuteNoWait(preparedModels[i], requests[i]); } // wait for the requests to complete ALOGI("ConcurrentExecuteWithQOSPriority: waiting for callbacks"); for (size_t i = 0; i < maxRequests; ++i) { ARMNN_ASSERT(cb[i]); cb[i]->wait(); } // check the results ALOGI("ConcurrentExecuteWithQOSPriority: validating results"); for (size_t i = 0; i < maxRequests; ++i) { if (i < 15) { BOOST_TEST(outdata[i][0] == 152); } else if (i < 30) { BOOST_TEST(outdata[i][0] == 141); } else { BOOST_TEST(outdata[i][0] == 159); } } ALOGI("ConcurrentExecuteWithQOSPriority: exit"); } } // anonymous namespace BOOST_AUTO_TEST_SUITE_END()