xref: /aosp_15_r20/external/android-nn-driver/test/1.2/Mean.cpp (revision 3e777be0405cee09af5d5785ff37f7cfb5bee59a)
1 //
2 // Copyright © 2022 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include "../DriverTestHelpers.hpp"
7 #include "../TestHalfTensor.hpp"
8 
9 #include <1.2/HalPolicy.hpp>
10 
11 #include <array>
12 
13 using Half = half_float::half;
14 
15 using namespace android::hardware;
16 using namespace driverTestHelpers;
17 using namespace armnn_driver;
18 
19 using HalPolicy = hal_1_2::HalPolicy;
20 using RequestArgument = V1_0::RequestArgument;
21 
22 namespace
23 {
24 
MeanTestImpl(const TestHalfTensor & input,const hidl_vec<uint32_t> & axisDimensions,const int32_t * axisValues,int32_t keepDims,const TestHalfTensor & expectedOutput,bool fp16Enabled,armnn::Compute computeDevice)25 void MeanTestImpl(const TestHalfTensor& input,
26                   const hidl_vec<uint32_t>& axisDimensions,
27                   const int32_t* axisValues,
28                   int32_t keepDims,
29                   const TestHalfTensor& expectedOutput,
30                   bool fp16Enabled,
31                   armnn::Compute computeDevice)
32 {
33     auto driver = std::make_unique<ArmnnDriver>(DriverOptions(computeDevice, fp16Enabled));
34 
35     HalPolicy::Model model = {};
36 
37     AddInputOperand<HalPolicy>(model, input.GetDimensions(), V1_2::OperandType::TENSOR_FLOAT16);
38 
39     AddTensorOperand<HalPolicy>(model,
40                                 axisDimensions,
41                                 const_cast<int32_t*>(axisValues),
42                                 HalPolicy::OperandType::TENSOR_INT32);
43 
44     AddIntOperand<HalPolicy>(model, keepDims);
45 
46     AddOutputOperand<HalPolicy>(model, expectedOutput.GetDimensions(), V1_2::OperandType::TENSOR_FLOAT16);
47 
48     model.operations.resize(1);
49     model.operations[0].type               = HalPolicy::OperationType::MEAN;
50     model.operations[0].inputs             = hidl_vec<uint32_t>{ 0, 1, 2 };
51     model.operations[0].outputs            = hidl_vec<uint32_t>{ 3 };
52     model.relaxComputationFloat32toFloat16 = fp16Enabled;
53 
54     //android::sp<V1_0::IPreparedModel> preparedModel = PrepareModel(model, *driver);
55     android::sp<V1_2::IPreparedModel> preparedModel = PrepareModel_1_2(model, *driver);
56 
57     // The request's memory pools will follow the same order as the inputs
58     V1_0::DataLocation inLoc = {};
59     inLoc.poolIndex          = 0;
60     inLoc.offset             = 0;
61     inLoc.length             = input.GetNumElements() * sizeof(Half);
62     RequestArgument inArg    = {};
63     inArg.location           = inLoc;
64     inArg.dimensions         = input.GetDimensions();
65 
66     // An additional memory pool is needed for the output
67     V1_0::DataLocation outLoc = {};
68     outLoc.poolIndex          = 1;
69     outLoc.offset             = 0;
70     outLoc.length             = expectedOutput.GetNumElements() * sizeof(Half);
71     RequestArgument outArg    = {};
72     outArg.location           = outLoc;
73     outArg.dimensions         = expectedOutput.GetDimensions();
74 
75     // Make the request based on the arguments
76     V1_0::Request request = {};
77     request.inputs  = hidl_vec<RequestArgument>{ inArg };
78     request.outputs = hidl_vec<RequestArgument>{ outArg };
79 
80     // Set the input data
81     AddPoolAndSetData(input.GetNumElements(), request, input.GetData());
82 
83     // Add memory for the output
84     android::sp<IMemory> outMemory = AddPoolAndGetData<Half>(expectedOutput.GetNumElements(), request);
85     const Half* outputData = static_cast<const Half*>(static_cast<void*>(outMemory->getPointer()));
86 
87     if (preparedModel.get() != nullptr)
88     {
89         V1_0::ErrorStatus execStatus = Execute(preparedModel, request);
90         DOCTEST_CHECK((int)execStatus == (int)V1_0::ErrorStatus::NONE);
91     }
92 
93     const Half* expectedOutputData = expectedOutput.GetData();
94     for (unsigned int i = 0; i < expectedOutput.GetNumElements(); i++)
95     {
96         DOCTEST_CHECK(outputData[i] == expectedOutputData[i]);
97     }
98 }
99 
100 } // anonymous namespace
101 
102 DOCTEST_TEST_SUITE("MeanTests_1.2_CpuRef")
103 {
104 
105 DOCTEST_TEST_CASE("MeanFp16NoKeepDimsTest_CpuRef")
106 {
107     using namespace half_float::literal;
108 
109     TestHalfTensor input{ armnn::TensorShape{ 4, 3, 2 },
110                       { 1.0_h, 2.0_h, 3.0_h, 4.0_h, 5.0_h, 6.0_h, 7.0_h, 8.0_h, 9.0_h, 10.0_h,
111                         11.0_h, 12.0_h, 13.0_h, 14.0_h, 15.0_h, 16.0_h, 17.0_h, 18.0_h, 19.0_h,
112                         20.0_h, 21.0_h, 22.0_h, 23.0_h, 24.0_h } };
113     hidl_vec<uint32_t> axisDimensions = { 2 };
114     int32_t axisValues[] = { 0, 1 };
115     int32_t keepDims = 0;
116     TestHalfTensor expectedOutput{ armnn::TensorShape{ 2 }, { 12.0_h, 13.0_h } };
117 
118     MeanTestImpl(input, axisDimensions, axisValues, keepDims, expectedOutput, true, armnn::Compute::CpuRef);
119 }
120 
121 DOCTEST_TEST_CASE("MeanFp16KeepDimsTest_CpuRef")
122 {
123     using namespace half_float::literal;
124 
125     TestHalfTensor input{ armnn::TensorShape{ 1, 1, 3, 2 }, { 1.0_h, 1.0_h, 2.0_h, 2.0_h, 3.0_h, 3.0_h } };
126     hidl_vec<uint32_t> axisDimensions = { 1 };
127     int32_t axisValues[] = { 2 };
128     int32_t keepDims = 1;
129     TestHalfTensor expectedOutput{ armnn::TensorShape{ 1, 1, 1, 2 }, {  2.0_h, 2.0_h } };
130 
131     MeanTestImpl(input, axisDimensions, axisValues, keepDims, expectedOutput, true, armnn::Compute::CpuRef);
132 }
133 
134 }
135 
136 #ifdef ARMCOMPUTECL_ENABLED
137 DOCTEST_TEST_SUITE("MeanTests_1.2_CpuAcc")
138 {
139     DOCTEST_TEST_CASE("MeanFp16NoKeepDimsTest_CpuAcc")
140     {
141         using namespace half_float::literal;
142 
143         std::vector<Half> in = { 1.0_h, 2.0_h, 3.0_h, 4.0_h, 5.0_h, 6.0_h, 7.0_h, 8.0_h, 9.0_h, 10.0_h,
144                             11.0_h, 12.0_h, 13.0_h, 14.0_h, 15.0_h, 16.0_h, 17.0_h, 18.0_h, 19.0_h,
145                             20.0_h, 21.0_h, 22.0_h, 23.0_h, 24.0_h };
146         TestHalfTensor input{ armnn::TensorShape{ 4, 3, 2 },
147                            in};
148         hidl_vec<uint32_t> axisDimensions = { 2 };
149         int32_t axisValues[] = { 0, 1 };
150         int32_t keepDims = 0;
151         std::vector<Half> out = { 12.0_h, 13.0_h };
152         TestHalfTensor expectedOutput{ armnn::TensorShape{ 2 }, out };
153 
154         MeanTestImpl(input, axisDimensions, axisValues, keepDims, expectedOutput, true, armnn::Compute::CpuAcc);
155     }
156 
157     DOCTEST_TEST_CASE("MeanFp16KeepDimsTest_CpuAcc")
158     {
159         using namespace half_float::literal;
160 
161         std::vector<Half> in = { 1.0_h, 1.0_h, 2.0_h, 2.0_h, 3.0_h, 3.0_h };
162         TestHalfTensor input{ armnn::TensorShape{ 1, 1, 3, 2 }, in };
163         hidl_vec<uint32_t> axisDimensions = { 1 };
164         int32_t axisValues[] = { 2 };
165         int32_t keepDims = 1;
166         std::vector<Half> out = {  2.0_h, 2.0_h };
167         TestHalfTensor expectedOutput{ armnn::TensorShape{ 1, 1, 1, 2 }, out };
168 
169         MeanTestImpl(input, axisDimensions, axisValues, keepDims, expectedOutput, true, armnn::Compute::CpuAcc);
170     }
171 }
172 
173 DOCTEST_TEST_SUITE("MeanTests_1.2_GpuAcc")
174 {
175     DOCTEST_TEST_CASE("MeanFp16NoKeepDimsTest_GpuAcc")
176     {
177         using namespace half_float::literal;
178 
179         TestHalfTensor input{ armnn::TensorShape{ 4, 3, 2 },
180                           { 1.0_h, 2.0_h, 3.0_h, 4.0_h, 5.0_h, 6.0_h, 7.0_h, 8.0_h, 9.0_h, 10.0_h,
181                             11.0_h, 12.0_h, 13.0_h, 14.0_h, 15.0_h, 16.0_h, 17.0_h, 18.0_h, 19.0_h,
182                             20.0_h, 21.0_h, 22.0_h, 23.0_h, 24.0_h } };
183         hidl_vec<uint32_t> axisDimensions = { 2 };
184         int32_t axisValues[] = { 0, 1 };
185         int32_t keepDims = 0;
186         TestHalfTensor expectedOutput{ armnn::TensorShape{ 2 }, { 12.0_h, 13.0_h } };
187 
188         MeanTestImpl(input, axisDimensions, axisValues, keepDims, expectedOutput, true, armnn::Compute::GpuAcc);
189     }
190 
191     DOCTEST_TEST_CASE("MeanFp16KeepDimsTest_GpuAcc")
192     {
193         using namespace half_float::literal;
194 
195         TestHalfTensor input{ armnn::TensorShape{ 1, 1, 3, 2 }, { 1.0_h, 1.0_h, 2.0_h, 2.0_h, 3.0_h, 3.0_h } };
196         hidl_vec<uint32_t> axisDimensions = { 1 };
197         int32_t axisValues[] = { 2 };
198         int32_t keepDims = 1;
199         TestHalfTensor expectedOutput{ armnn::TensorShape{ 1, 1, 1, 2 }, {  2.0_h, 2.0_h } };
200 
201         MeanTestImpl(input, axisDimensions, axisValues, keepDims, expectedOutput, true, armnn::Compute::GpuAcc);
202     }
203 }
204 #endif
205