xref: /aosp_15_r20/external/android-nn-driver/test/Concurrent.cpp (revision 3e777be0405cee09af5d5785ff37f7cfb5bee59a)
1 //
2 // Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include "DriverTestHelpers.hpp"
7 
8 #include <log/log.h>
9 
10 DOCTEST_TEST_SUITE("ConcurrentDriverTests")
11 {
12 using ArmnnDriver   = armnn_driver::ArmnnDriver;
13 using DriverOptions = armnn_driver::DriverOptions;
14 using HalPolicy     = armnn_driver::hal_1_0::HalPolicy;
15 using RequestArgument = V1_0::RequestArgument;
16 
17 using namespace android::nn;
18 using namespace android::hardware;
19 using namespace driverTestHelpers;
20 using namespace armnn_driver;
21 
22 // Add our own test for concurrent execution
23 // The main point of this test is to check that multiple requests can be
24 // executed without waiting for the callback from previous execution.
25 // The operations performed are not significant.
26 DOCTEST_TEST_CASE("ConcurrentExecute")
27 {
28     ALOGI("ConcurrentExecute: entry");
29 
30     auto driver = std::make_unique<ArmnnDriver>(DriverOptions(armnn::Compute::CpuRef));
31     HalPolicy::Model model = {};
32 
33     // add operands
34     int32_t actValue      = 0;
35     float   weightValue[] = {2, 4, 1};
36     float   biasValue[]   = {4};
37 
38     AddInputOperand<HalPolicy>(model, hidl_vec<uint32_t>{1, 3});
39     AddTensorOperand<HalPolicy>(model, hidl_vec<uint32_t>{1, 3}, weightValue);
40     AddTensorOperand<HalPolicy>(model, hidl_vec<uint32_t>{1}, biasValue);
41     AddIntOperand<HalPolicy>(model, actValue);
42     AddOutputOperand<HalPolicy>(model, hidl_vec<uint32_t>{1, 1});
43 
44     // make the fully connected operation
45     model.operations.resize(1);
46     model.operations[0].type    = HalPolicy::OperationType::FULLY_CONNECTED;
47     model.operations[0].inputs  = hidl_vec<uint32_t>{0, 1, 2, 3};
48     model.operations[0].outputs = hidl_vec<uint32_t>{4};
49 
50     // make the prepared models
51     const size_t maxRequests = 5;
52     size_t preparedModelsSize = 0;
53     android::sp<V1_0::IPreparedModel> preparedModels[maxRequests];
54     for (size_t i = 0; i < maxRequests; ++i)
55     {
56         auto preparedModel = PrepareModel(model, *driver);
57         if (preparedModel.get() != nullptr)
58         {
59             preparedModels[i] = PrepareModel(model, *driver);
60             preparedModelsSize++;
61         }
62     }
63 
64     DOCTEST_CHECK(maxRequests == preparedModelsSize);
65 
66     // construct the request data
67     V1_0::DataLocation inloc = {};
68     inloc.poolIndex          = 0;
69     inloc.offset             = 0;
70     inloc.length             = 3 * sizeof(float);
71     RequestArgument input    = {};
72     input.location           = inloc;
73     input.dimensions         = hidl_vec<uint32_t>{};
74 
75     V1_0::DataLocation outloc = {};
76     outloc.poolIndex          = 1;
77     outloc.offset             = 0;
78     outloc.length             = 1 * sizeof(float);
79     RequestArgument output    = {};
80     output.location           = outloc;
81     output.dimensions         = hidl_vec<uint32_t>{};
82 
83     // build the requests
84     V1_0::Request requests[maxRequests];
85     android::sp<IMemory> inMemory[maxRequests];
86     android::sp<IMemory> outMemory[maxRequests];
87     float indata[] = {2, 32, 16};
88     float* outdata[maxRequests];
89     for (size_t i = 0; i < maxRequests; ++i)
90     {
91         requests[i].inputs  = hidl_vec<RequestArgument>{input};
92         requests[i].outputs = hidl_vec<RequestArgument>{output};
93         // set the input data (matching source test)
94         inMemory[i] = AddPoolAndSetData<float>(3, requests[i], indata);
95         // add memory for the output
96         outMemory[i] = AddPoolAndGetData<float>(1, requests[i]);
97         outdata[i] = static_cast<float*>(static_cast<void*>(outMemory[i]->getPointer()));
98     }
99 
100     // invoke the execution of the requests
101     ALOGI("ConcurrentExecute: executing requests");
102     android::sp<ExecutionCallback> cb[maxRequests];
103     for (size_t i = 0; i < maxRequests; ++i)
104     {
105         cb[i] = ExecuteNoWait(preparedModels[i], requests[i]);
106     }
107 
108     // wait for the requests to complete
109     ALOGI("ConcurrentExecute: waiting for callbacks");
110     for (size_t i = 0; i < maxRequests; ++i)
111     {
112         DOCTEST_CHECK(cb[i]);
113         cb[i]->wait();
114     }
115 
116     // check the results
117     ALOGI("ConcurrentExecute: validating results");
118     for (size_t i = 0; i < maxRequests; ++i)
119     {
120         DOCTEST_CHECK(outdata[i][0] == 152);
121     }
122     ALOGI("ConcurrentExecute: exit");
123 }
124 
125 }
126