blob: a2a8b7a14212366915fa03cefabd0167944292bc [file] [log] [blame]
Cathal Corbett0637bf32022-12-20 18:35:34 +00001//
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
13using Half = half_float::half;
14
15using namespace android::hardware;
16using namespace driverTestHelpers;
17using namespace armnn_driver;
18
19using HalPolicy = hal_1_2::HalPolicy;
20using RequestArgument = V1_0::RequestArgument;
21
22namespace
23{
24
25void 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
102DOCTEST_TEST_SUITE("MeanTests_1.2_CpuRef")
103{
104
105DOCTEST_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
121DOCTEST_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
137DOCTEST_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
173DOCTEST_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