xref: /aosp_15_r20/external/android-nn-driver/test/1.1/Transpose.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 #include "../TestTensor.hpp"
8 #include <1.1/HalPolicy.hpp>
9 
10 #include <log/log.h>
11 #include <OperationsUtils.h>
12 
13 #include <array>
14 #include <cmath>
15 
16 using namespace android::hardware;
17 using namespace driverTestHelpers;
18 using namespace armnn_driver;
19 
20 using HalPolicy = hal_1_1::HalPolicy;
21 using RequestArgument = V1_0::RequestArgument;
22 
23 namespace
24 {
25 
TransposeTestImpl(const TestTensor & inputs,int32_t perm[],const TestTensor & expectedOutputTensor,armnn::Compute computeDevice)26 void TransposeTestImpl(const TestTensor & inputs, int32_t perm[],
27                        const TestTensor & expectedOutputTensor, armnn::Compute computeDevice)
28 {
29     auto driver = std::make_unique<ArmnnDriver>(DriverOptions(computeDevice));
30     HalPolicy::Model model = {};
31 
32     AddInputOperand<HalPolicy>(model,inputs.GetDimensions());
33 
34     AddTensorOperand<HalPolicy>(model,
35                                 hidl_vec<uint32_t>{4},
36                                 perm,
37                                 HalPolicy::OperandType::TENSOR_INT32);
38 
39     AddOutputOperand<HalPolicy>(model, expectedOutputTensor.GetDimensions());
40 
41     model.operations.resize(1);
42     model.operations[0].type = HalPolicy::OperationType::TRANSPOSE;
43     model.operations[0].inputs  = hidl_vec<uint32_t>{0, 1};
44     model.operations[0].outputs = hidl_vec<uint32_t>{2};
45 
46     android::sp<V1_0::IPreparedModel> preparedModel = PrepareModel(model, *driver);
47 
48     // the request's memory pools will follow the same order as
49     // the inputs
50     V1_0::DataLocation inloc = {};
51     inloc.poolIndex          = 0;
52     inloc.offset             = 0;
53     inloc.length             = inputs.GetNumElements() * sizeof(float);
54     RequestArgument input    = {};
55     input.location           = inloc;
56     input.dimensions         = inputs.GetDimensions();
57 
58     // and an additional memory pool is needed for the output
59     V1_0::DataLocation outloc = {};
60     outloc.poolIndex          = 1;
61     outloc.offset             = 0;
62     outloc.length             = expectedOutputTensor.GetNumElements() * sizeof(float);
63     RequestArgument output    = {};
64     output.location           = outloc;
65     output.dimensions         = expectedOutputTensor.GetDimensions();
66 
67     // make the request based on the arguments
68     V1_0::Request request = {};
69     request.inputs  = hidl_vec<RequestArgument>{input};
70     request.outputs = hidl_vec<RequestArgument>{output};
71 
72     // set the input data
73     AddPoolAndSetData(inputs.GetNumElements(),
74                       request,
75                       inputs.GetData());
76 
77     // add memory for the output
78     android::sp<IMemory> outMemory = AddPoolAndGetData<float>(expectedOutputTensor.GetNumElements(), request);
79     float* outdata = static_cast<float*>(static_cast<void*>(outMemory->getPointer()));
80 
81     if (preparedModel.get() != nullptr)
82     {
83         auto execStatus = Execute(preparedModel, request);
84     }
85 
86     const float * expectedOutput = expectedOutputTensor.GetData();
87     for (unsigned int i = 0; i < expectedOutputTensor.GetNumElements(); ++i)
88     {
89         DOCTEST_CHECK(outdata[i] == expectedOutput[i]);
90     }
91 }
92 
93 } // namespace
94 
95 DOCTEST_TEST_SUITE("TransposeTests_CpuRef")
96 {
97     DOCTEST_TEST_CASE("Transpose_CpuRef")
98     {
99         int32_t perm[] = {2, 3, 1, 0};
100         TestTensor input{armnn::TensorShape{1, 2, 2, 2},{1, 2, 3, 4, 5, 6, 7, 8}};
101         TestTensor expected{armnn::TensorShape{2, 2, 2, 1},{1, 5, 2, 6, 3, 7, 4, 8}};
102 
103         TransposeTestImpl(input, perm, expected, armnn::Compute::CpuRef);
104     }
105 
106     DOCTEST_TEST_CASE("TransposeNHWCToArmNN_CpuRef")
107     {
108         int32_t perm[] = {0, 3, 1, 2};
109         TestTensor input{armnn::TensorShape{1, 2, 2, 3},{1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33}};
110         TestTensor expected{armnn::TensorShape{1, 3, 2, 2},{1, 11, 21, 31, 2, 12, 22, 32, 3, 13, 23, 33}};
111 
112         TransposeTestImpl(input, perm, expected, armnn::Compute::CpuRef);
113     }
114     DOCTEST_TEST_CASE("TransposeArmNNToNHWC_CpuRef")
115     {
116         int32_t perm[] = {0, 2, 3, 1};
117         TestTensor input{armnn::TensorShape{1, 2, 2, 2},{1, 2, 3, 4, 5, 6, 7, 8}};
118         TestTensor expected{armnn::TensorShape{1, 2, 2, 2},{1, 5, 2, 6, 3, 7, 4, 8}};
119 
120         TransposeTestImpl(input, perm, expected, armnn::Compute::CpuRef);
121     }
122 }
123 
124 #ifdef ARMCOMPUTECL_ENABLED
125 DOCTEST_TEST_SUITE("TransposeTests_CpuAcc")
126 {
127     DOCTEST_TEST_CASE("Transpose_CpuAcc")
128     {
129         int32_t perm[] = {2, 3, 1, 0};
130         TestTensor input{armnn::TensorShape{1, 2, 2, 2},{1, 2, 3, 4, 5, 6, 7, 8}};
131         TestTensor expected{armnn::TensorShape{2, 2, 2, 1},{1, 5, 2, 6, 3, 7, 4, 8}};
132 
133         TransposeTestImpl(input, perm, expected, armnn::Compute::CpuAcc);
134     }
135 
136     DOCTEST_TEST_CASE("TransposeNHWCToArmNN_CpuAcc")
137     {
138         int32_t perm[] = {0, 3, 1, 2};
139         TestTensor input{armnn::TensorShape{1, 2, 2, 3},{1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33}};
140         TestTensor expected{armnn::TensorShape{1, 3, 2, 2},{1, 11, 21, 31, 2, 12, 22, 32, 3, 13, 23, 33}};
141 
142         TransposeTestImpl(input, perm, expected, armnn::Compute::CpuAcc);
143     }
144 
145     DOCTEST_TEST_CASE("TransposeArmNNToNHWC_CpuAcc")
146     {
147         int32_t perm[] = {0, 2, 3, 1};
148         TestTensor input{armnn::TensorShape{1, 2, 2, 2},{1, 2, 3, 4, 5, 6, 7, 8}};
149         TestTensor expected{armnn::TensorShape{1, 2, 2, 2},{1, 5, 2, 6, 3, 7, 4, 8}};
150 
151         TransposeTestImpl(input, perm, expected, armnn::Compute::CpuAcc);
152     }
153 }
154 
155 DOCTEST_TEST_SUITE("TransposeTests_GpuAcc")
156 {
157     DOCTEST_TEST_CASE("Transpose_GpuAcc")
158     {
159         int32_t perm[] = {2, 3, 1, 0};
160         TestTensor input{armnn::TensorShape{1, 2, 2, 2},{1, 2, 3, 4, 5, 6, 7, 8}};
161         TestTensor expected{armnn::TensorShape{2, 2, 2, 1},{1, 5, 2, 6, 3, 7, 4, 8}};
162 
163         TransposeTestImpl(input, perm, expected, armnn::Compute::GpuAcc);
164     }
165 
166     DOCTEST_TEST_CASE("TransposeNHWCToArmNN_GpuAcc")
167     {
168         int32_t perm[] = {0, 3, 1, 2};
169         TestTensor input{armnn::TensorShape{1, 2, 2, 3},{1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33}};
170         TestTensor expected{armnn::TensorShape{1, 3, 2, 2},{1, 11, 21, 31, 2, 12, 22, 32, 3, 13, 23, 33}};
171 
172         TransposeTestImpl(input, perm, expected, armnn::Compute::GpuAcc);
173     }
174 
175     DOCTEST_TEST_CASE("TransposeArmNNToNHWC_GpuAcc")
176     {
177         int32_t perm[] = {0, 2, 3, 1};
178         TestTensor input{armnn::TensorShape{1, 2, 2, 2},{1, 2, 3, 4, 5, 6, 7, 8}};
179         TestTensor expected{armnn::TensorShape{1, 2, 2, 2},{1, 5, 2, 6, 3, 7, 4, 8}};
180 
181         TransposeTestImpl(input, perm, expected, armnn::Compute::GpuAcc);
182     }
183 }
184 #endif
185 
186