blob: d3d9c882ebf4e3cb76099cb87634bfc1583766cf [file] [log] [blame]
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001//
Colm Donelan68c60e92024-02-21 15:58:35 +00002// Copyright © 2017, 2024 Arm Ltd and Contributors. All rights reserved.
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003// SPDX-License-Identifier: MIT
4//
5
6#include "ConcatTestImpl.hpp"
7
Colm Donelanc42a9872022-02-02 16:35:09 +00008#include <armnnUtils/QuantizeHelper.hpp>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01009#include <ResolveType.hpp>
10
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010011
Matteo Martincighe011d202019-11-28 11:35:47 +000012#include <armnnUtils/Permute.hpp>
13
Sadik Armagana097d2a2021-11-24 15:47:28 +000014#include <armnnTestUtils/TensorCopyUtils.hpp>
Colm Donelan0c479742021-12-10 12:43:54 +000015#include <armnnTestUtils/WorkloadTestUtils.hpp>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010016
Colm Donelanc42a9872022-02-02 16:35:09 +000017#include <armnnTestUtils/TensorHelpers.hpp>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010018
Aron Virginas-Tar48623a02019-10-22 10:00:28 +010019using namespace armnn;
20using namespace armnnUtils;
21
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010022//
23// Helper functions and templates
24//
25
Aron Virginas-Tar48623a02019-10-22 10:00:28 +010026OriginsDescriptor CreateDescriptorForConcat(
27 const std::vector<TensorInfo> & inputTensorInfos,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010028 unsigned int concatDim)
29{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +010030 std::vector<TensorShape> shapes;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010031 shapes.reserve(inputTensorInfos.size());
Aron Virginas-Tar48623a02019-10-22 10:00:28 +010032 for (const TensorInfo& it: inputTensorInfos)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010033 {
34 shapes.push_back(it.GetShape());
35 }
36
Aron Virginas-Tar48623a02019-10-22 10:00:28 +010037 return CreateDescriptorForConcatenation(shapes.begin(), shapes.end(), concatDim);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010038}
39
40//
41// Concat is only supported for N and C dimensions for NCHW and the inner most dimension
42// In case of <4 dimensions we need to make sure that the concat dimensions are at least
43// the 3rd slowest iterating one or the inner most dimension.
44//
45
46bool NeedPermuteForConcat(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +010047 const std::vector<TensorInfo> & inputTensorInfos,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010048 unsigned int concatDim)
49{
50 // See note above. Additionally we expect the input shapes to have the
51 // same number of dimensions.
52 unsigned int nDimensions = 0;
53
54 // Determine the number of dimensions as well as sanity check them
55 // agains test implementation issues.
56 for (auto && tensorInfo : inputTensorInfos)
57 {
58 if (!nDimensions)
59 {
60 nDimensions = tensorInfo.GetShape().GetNumDimensions();
61 }
62 else
63 {
Colm Donelan68c60e92024-02-21 15:58:35 +000064 CHECK_MESSAGE(nDimensions == tensorInfo.GetShape().GetNumDimensions(),
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010065 "Input shapes must have the same number of dimensions");
66 }
67 }
68
69 return (nDimensions < 3 || (nDimensions == 3 && (nDimensions-concatDim) < 3 && (nDimensions-concatDim) != 1));
70}
71
Aron Virginas-Tar48623a02019-10-22 10:00:28 +010072TensorShape ExpandTensorShapeTo3dForPermute(const TensorShape & inputShape)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010073{
74 unsigned int numDims = inputShape.GetNumDimensions();
75 if (numDims >= 3)
76 {
77 // Nothing to do if the inputShape has at least 3 dimensions.
78 return inputShape;
79 }
80
81 std::vector<unsigned int> newDims(size_t(3), 1u);
82 unsigned int expandedBy = 3 - numDims;
83 for (unsigned int i=0; i<numDims; ++i)
84 {
85 newDims[expandedBy+i] = inputShape[i];
86 }
Aron Virginas-Tar48623a02019-10-22 10:00:28 +010087 return TensorShape(3u, &newDims[0]);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010088}
89
90void Generate3dPermuteVectorForConcat(
91 unsigned int numDimensions,
92 unsigned int & concatDim,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +010093 std::pair<PermutationVector, PermutationVector> & permutations)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010094{
Colm Donelan68c60e92024-02-21 15:58:35 +000095 CHECK_MESSAGE(numDimensions <= 3,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010096 "Only dimensions 1,2 and 3 are supported by this helper");
97 unsigned int expandedBy = 3 - numDimensions;
98 unsigned int expandedConcatAxis = concatDim + expandedBy;
99
100 if (expandedConcatAxis == 2)
101 {
102 concatDim = 0;
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100103 PermutationVector forwardPermutation({1, 2, 0});
104 PermutationVector reversePermutation({2, 0, 1});
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100105 permutations = std::make_pair(forwardPermutation, reversePermutation);
106 }
107 else if (expandedConcatAxis == 1)
108 {
109 concatDim = 0;
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100110 PermutationVector forwardPermutation({2, 0, 1});
111 PermutationVector reversePermutation({1, 2, 0});
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100112 permutations = std::make_pair(forwardPermutation, reversePermutation);
113 }
114 else
115 {
Colm Donelan68c60e92024-02-21 15:58:35 +0000116 CHECK(expandedConcatAxis == 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100117 concatDim = 0;
118 }
119}
120
121template<typename T> void PermuteTensorData(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100122 IWorkloadFactory& workloadFactory,
123 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100124 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100125 const PermutationVector& mappings,
126 TensorInfo & inputTensorInfo,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100127 const T * inputData,
128 std::vector<T>& outputData)
129{
Jan Eilers8eb25602020-03-09 12:13:48 +0000130 IgnoreUnused(memoryManager);
Colm Donelan68c60e92024-02-21 15:58:35 +0000131 CHECK_MESSAGE(inputData != nullptr, "inputData must not be null");
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100132 if (inputData == nullptr)
133 {
134 // Nullptr is an error in the test. By returning without doing the concatenation
135 // I expect the caller to fail the test. It still makes sense to report this as
136 // an assert for Debug builds.
137 return;
138 }
139
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100140 TensorInfo outputTensorInfo = armnnUtils::Permuted(inputTensorInfo, mappings);
Keith Davisf500d6c2020-08-31 08:32:55 +0100141 std::unique_ptr<ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
142 std::unique_ptr<ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100143
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100144 PermuteQueueDescriptor queueDescriptor;
145 queueDescriptor.m_Parameters = PermuteDescriptor{mappings};
146 WorkloadInfo workloadInfo;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100147 AddInputToWorkload(queueDescriptor, workloadInfo, inputTensorInfo, inputHandle.get());
148 AddOutputToWorkload(queueDescriptor, workloadInfo, outputTensorInfo, outputHandle.get());
149
Teresa Charlin611c7fb2022-01-07 09:47:29 +0000150 std::unique_ptr<IWorkload> workload = workloadFactory.CreateWorkload(LayerType::Permute,
151 queueDescriptor,
152 workloadInfo);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100153
154 inputHandle->Allocate();
155 outputHandle->Allocate();
156
157 CopyDataToITensorHandle(inputHandle.get(), inputData);
158
159 workload->PostAllocationConfigure();
160 workload->Execute();
161
162 outputData.resize(outputTensorInfo.GetNumElements());
163 CopyDataFromITensorHandle(&outputData[0], outputHandle.get());
164 inputTensorInfo = outputTensorInfo;
165}
166
167//
168// Permute the input tensors so we can do a supported concatenation.
169// Also treat lower than 3d tensors as 3d by adding dummy 1 dimensions
170// at the front. Finally this function tells what the output shape
171// of the permuted concatenated tensor is going to be.
172//
173template<typename T> void PermuteInputsForConcat(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100174 IWorkloadFactory& workloadFactory,
175 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100176 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100177 std::vector<TensorInfo> & inputTensorInfos,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100178 std::vector<T *> & inputData,
179 std::vector<std::vector<T>> & inputDataStorage,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100180 PermutationVector & permuteVector,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100181 unsigned int & concatDim,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100182 TensorInfo & outputTensorInfo)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100183{
Jan Eilers8eb25602020-03-09 12:13:48 +0000184 IgnoreUnused(memoryManager);
Colm Donelan68c60e92024-02-21 15:58:35 +0000185 CHECK_MESSAGE(inputTensorInfos.size() > 1,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100186 "Expecting more than one tensor to be concatenated here");
187
188 unsigned int numDims = 0;
189 unsigned int nthInput = 0;
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100190 const PermutationVector identity({0, 1, 2});
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100191
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100192 std::pair<PermutationVector, PermutationVector> permutations =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100193 std::make_pair(identity, identity);
194
195 inputDataStorage.resize(inputData.size());
196
197 for (auto && tensorInfo : inputTensorInfos)
198 {
199 if (numDims == 0)
200 {
201 numDims = tensorInfo.GetShape().GetNumDimensions();
202 Generate3dPermuteVectorForConcat(numDims, concatDim, permutations);
203
204 // Store the reverese permutation.
205 permuteVector = permutations.second;
Colm Donelan68c60e92024-02-21 15:58:35 +0000206 CHECK_MESSAGE(!permuteVector.IsEqual(identity),
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100207 "Test logic error, we don't need permutation, so we shouldn't arrive here");
208 }
209 else
210 {
Colm Donelan68c60e92024-02-21 15:58:35 +0000211 CHECK_MESSAGE(numDims == tensorInfo.GetShape().GetNumDimensions(),
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100212 "All inputs must have the same number of dimensions");
213 }
214
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100215 TensorInfo newTensorInfo = tensorInfo;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100216 newTensorInfo.SetShape(ExpandTensorShapeTo3dForPermute(tensorInfo.GetShape()));
217
218 PermuteTensorData<T>(workloadFactory,
219 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100220 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100221 permutations.first,
222 newTensorInfo,
223 inputData[nthInput],
224 inputDataStorage[nthInput]);
225
226 inputData[nthInput] = inputDataStorage[nthInput].data();
227 inputTensorInfos[nthInput] = newTensorInfo;
228
229 ++nthInput;
230 }
231
232 outputTensorInfo.SetShape(
233 armnnUtils::Permuted(
234 ExpandTensorShapeTo3dForPermute(outputTensorInfo.GetShape()),
235 permutations.first));
236}
237
238//
239// This is the pair of PermuteInputsForConcat(...) which permutes back
240// the output of the concatenation so we can check it against an expected
241// output.
242//
243template <typename T> void PermuteOutputForConcat(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100244 IWorkloadFactory& workloadFactory,
245 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100246 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100247 const TensorInfo & tensorInfo,
248 const PermutationVector & permuteVector,
249 std::unique_ptr<ITensorHandle> && inputDataHandle,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100250 T * data)
251{
Colm Donelan68c60e92024-02-21 15:58:35 +0000252 CHECK_MESSAGE(data != nullptr, "data must not be null");
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100253 if (data == nullptr)
254 {
255 // Nullptr is an error in the test. By returning without doing the permutation
256 // I expect the caller to fail the test. It still makes sense to report this as
257 // an assert for Debug builds.
258 return;
259 }
260
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100261 TensorInfo resultTensorInfo = tensorInfo;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100262 std::vector<T> inputData(tensorInfo.GetNumElements());
263 std::vector<T> outputData;
264
265 CopyDataFromITensorHandle(&inputData[0], inputDataHandle.get());
266
267 PermuteTensorData<T>(workloadFactory,
268 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100269 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100270 permuteVector,
271 resultTensorInfo,
272 &inputData[0],
273 outputData);
274
275 ::memcpy(data, &outputData[0], sizeof(T)*outputData.size());
276}
277
278template<typename T> void Concatenate(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100279 IWorkloadFactory& workloadFactory,
280 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100281 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100282 std::initializer_list<const TensorInfo> inputTensorInfosOrig,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100283 std::initializer_list<T *> inputsOrig,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100284 const TensorInfo& outputTensorInfoOrig,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100285 T * output,
286 unsigned int concatDim,
287 bool useSubtensor)
288{
Colm Donelan68c60e92024-02-21 15:58:35 +0000289 CHECK_MESSAGE(output != nullptr, "output must not be null");
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100290 if (output == nullptr)
291 {
292 // Nullptr is an error in the test. By returning without doing the permutation
293 // I expect the caller to fail the test. It still makes sense to report this as
294 // an assert for Debug builds.
295 return;
296 }
297
298 // Saves a copy of the parameters which we might need to change.
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100299 std::vector<TensorInfo> inputTensorInfos(inputTensorInfosOrig.begin(), inputTensorInfosOrig.end());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100300 std::vector<T *> inputs = inputsOrig;
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100301 TensorInfo outputTensorInfo = outputTensorInfoOrig;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100302
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100303 PermutationVector permuteVector{0, 1, 2};
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100304
305 // Holds and automatically releases memory for the reshaped input data.
306 std::vector<std::vector<T>> tmpInputDataStorage;
307
308 const size_t inputCount = inputTensorInfos.size();
309
310 bool needPermuteForConcat = NeedPermuteForConcat(inputTensorInfos, concatDim);
311
312 if (needPermuteForConcat)
313 {
314 //
315 // We need to permute the inputs, because concatenation along
316 // the requested axis is not supported.
317 //
318 PermuteInputsForConcat<T>(workloadFactory,
319 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100320 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100321 inputTensorInfos,
322 inputs,
323 tmpInputDataStorage,
324 permuteVector,
325 concatDim,
326 outputTensorInfo);
327 }
328
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100329 WorkloadInfo workloadInfo;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100330
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100331 std::vector<std::unique_ptr<ITensorHandle>> inputHandles;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100332 inputHandles.reserve(inputCount);
Keith Davisf500d6c2020-08-31 08:32:55 +0100333
334 std::unique_ptr<ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
335
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100336 ConcatQueueDescriptor queueDescriptor;
337 OriginsDescriptor viewsDescriptor = CreateDescriptorForConcat(inputTensorInfos, concatDim);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100338 queueDescriptor.m_Parameters = viewsDescriptor;
339
340 if (useSubtensor)
341 {
342 queueDescriptor.m_ViewOrigins.reserve(viewsDescriptor.GetNumViews());
343 for (unsigned int i = 0; i < viewsDescriptor.GetNumViews(); ++i)
344 {
345 queueDescriptor.m_ViewOrigins.emplace_back(std::vector<unsigned int>(viewsDescriptor.GetViewOrigin(i),
346 viewsDescriptor.GetViewOrigin(i) + viewsDescriptor.GetNumDimensions()));
347 }
Keith Davisf500d6c2020-08-31 08:32:55 +0100348
349 outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
350
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100351 const bool subTensorsSupported = workloadFactory.SupportsSubTensors();
352 for (unsigned int i = 0; i < inputCount; ++i)
353 {
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100354 const TensorInfo& inputTensorInfo = inputTensorInfos[i];
Keith Davisf500d6c2020-08-31 08:32:55 +0100355
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100356 std::unique_ptr<ITensorHandle> inputHandle =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100357 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +0100358 tensorHandleFactory.CreateSubTensorHandle(*outputHandle,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100359 inputTensorInfo.GetShape(),
360 queueDescriptor.m_ViewOrigins[i].m_Origin.data()) :
Keith Davisf500d6c2020-08-31 08:32:55 +0100361 tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
362
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100363 inputHandles.emplace_back(std::move(inputHandle));
364 }
365
Teresa Charlinfbf0e5b2020-08-17 01:01:06 +0100366
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100367 }
368 else
369 {
370 for (unsigned int i = 0; i < inputCount; ++i)
371 {
Keith Davisf500d6c2020-08-31 08:32:55 +0100372 std::unique_ptr<ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfos[i]);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100373 inputHandles.emplace_back(std::move(inputHandle));
374 }
375 }
376
377 for (unsigned int i = 0; i < inputCount; ++i)
378 {
379 AddInputToWorkload(queueDescriptor, workloadInfo, inputTensorInfos[i], inputHandles[i].get());
380 }
381
382 AddOutputToWorkload(queueDescriptor, workloadInfo, outputTensorInfo, outputHandle.get());
383
Teresa Charlin611c7fb2022-01-07 09:47:29 +0000384 std::unique_ptr<IWorkload> workload
385 = workloadFactory.CreateWorkload(LayerType::Concat, queueDescriptor, workloadInfo);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100386
387 for (auto& inputHandle : inputHandles)
388 {
389 inputHandle->Allocate();
390 }
391
392 outputHandle->Allocate();
393
394 unsigned int nextInputId = 0;
395 for (auto& inputHandle : inputHandles)
396 {
397 CopyDataToITensorHandle(inputHandle.get(), inputs[nextInputId]);
398 ++nextInputId;
399 }
400
401 workload->PostAllocationConfigure();
402 workload->Execute();
403
404 if (needPermuteForConcat)
405 {
406 PermuteOutputForConcat<T>(workloadFactory,
407 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100408 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100409 outputTensorInfo,
410 permuteVector,
411 std::move(outputHandle),
412 output);
413 }
414 else
415 {
416 CopyDataFromITensorHandle(output, outputHandle.get());
417 }
418}
419
420//
421// Implementation templates
422//
Teresa Charlin6abc7ee2022-02-22 17:32:27 +0000423template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
424LayerTestResult<T, 3> ConcatTestImpl(
425 IWorkloadFactory& workloadFactory,
426 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
427 const armnn::ITensorHandleFactory& tensorHandleFactory)
428{
429
430 IgnoreUnused(memoryManager);
431
432 unsigned int outputWidth = 3;
433 unsigned int outputHeight = 6;
434 unsigned int outputChannels = 3;
435
436 unsigned int inputWidth1 = 3;
437 unsigned int inputHeight1 = 6;
438 unsigned int inputChannels1 = 2;
439
440 unsigned int inputWidth2 = 3;
441 unsigned int inputHeight2 = 6;
442 unsigned int inputChannels2 = 1;
443
444 // Define the tensor descriptors.
445 TensorInfo outputTensorInfo({ outputChannels, outputHeight, outputWidth }, ArmnnType);
446 TensorInfo inputTensorInfo1({ inputChannels1, inputHeight1, inputWidth1 }, ArmnnType);
447 TensorInfo inputTensorInfo2({ inputChannels2, inputHeight2, inputWidth2 }, ArmnnType);
448
449 std::vector<T> actualOutput(outputTensorInfo.GetNumElements());
450
451 std::vector<T> expectedOutput =
452 {
453 1, 2, 3,
454 4, 5, 6,
455 7, 8, 9,
456 10, 11, 12,
457 13, 14, 15,
458 16, 17, 18,
459
460 19, 20, 21,
461 22, 23, 24,
462 25, 26, 27,
463 28, 29, 30,
464 31, 32, 33,
465 34, 35, 36,
466
467 37, 38, 39,
468 40, 41, 42,
469 43, 44, 45,
470 46, 47, 48,
471 49, 50, 51,
472 52, 53, 54
473 };
474
475 std::vector<T> input1 =
476 {
477 1, 2, 3,
478 4, 5, 6,
479 7, 8, 9,
480 10, 11, 12,
481 13, 14, 15,
482 16, 17, 18,
483
484 19, 20, 21,
485 22, 23, 24,
486 25, 26, 27,
487 28, 29, 30,
488 31, 32, 33,
489 34, 35, 36
490 };
491
492 std::vector<T> input2 =
493 {
494 37, 38, 39,
495 40, 41, 42,
496 43, 44, 45,
497 46, 47, 48,
498 49, 50, 51,
499 52, 53, 54,
500 };
501
502 std::vector<unsigned int> wOrigin1 = {0, 0, 0}; //Extent of the window is defined by size of input[0].
503 ConcatQueueDescriptor::ViewOrigin window1(wOrigin1);
504
505 std::vector<unsigned int> wOrigin2 = {2, 0, 0}; //Extent of the window is defined by size of input[1].
506 ConcatQueueDescriptor::ViewOrigin window2(wOrigin2);
507
508 std::unique_ptr<ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
509
510 bool subTensorsSupported = workloadFactory.SupportsSubTensors();
511
512 std::unique_ptr<ITensorHandle> inputHandle1 =
513 subTensorsSupported ?
514 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo1.GetShape(), wOrigin1.data()) :
515 tensorHandleFactory.CreateTensorHandle(inputTensorInfo1);
516
517 std::unique_ptr<ITensorHandle> inputHandle2 =
518 subTensorsSupported ?
519 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo2.GetShape(), wOrigin2.data()) :
520 tensorHandleFactory.CreateTensorHandle(inputTensorInfo2);
521
522 ConcatQueueDescriptor data;
523 WorkloadInfo info;
524 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
525 AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
526 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
527
528 data.m_ViewOrigins.push_back(window1);
529 data.m_ViewOrigins.push_back(window2);
530
531 std::unique_ptr<IWorkload> workload = workloadFactory.CreateWorkload(LayerType::Concat, data, info);
532
533 inputHandle1->Allocate();
534 inputHandle2->Allocate();
535 outputHandle->Allocate();
536
537 CopyDataToITensorHandle(inputHandle1.get(), input1.data());
538 CopyDataToITensorHandle(inputHandle2.get(), input2.data());
539
540 workload->PostAllocationConfigure();
541 workload->Execute();
542
543 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
544
545 return LayerTestResult<T, 3>(actualOutput,
546 expectedOutput,
547 outputHandle->GetShape(),
548 outputTensorInfo.GetShape());
549}
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100550
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100551template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100552LayerTestResult<T, 1> Concat1dTestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100553 IWorkloadFactory& workloadFactory,
554 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100555 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100556 float qScale,
557 int32_t qOffset)
558{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100559 TensorInfo inputTensorInfo({ 3 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100560
Sadik Armagan483c8112021-06-01 09:24:52 +0100561 auto input0 = QuantizedVector<T>({ 1.0f, 2.0f, 3.0f }, qScale, qOffset);
562 auto input1 = QuantizedVector<T>({ 4.0f, 5.0f, 6.0f }, qScale, qOffset);
563 auto input2 = QuantizedVector<T>({ 7.0f, 8.0f, 9.0f }, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100564
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100565 TensorInfo outputTensorInfo({ 9 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100566
567 LayerTestResult<T, 1> result(outputTensorInfo);
568
569 std::vector<T> output;
570 output.resize(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +0100571 Concatenate<T>(workloadFactory, memoryManager, tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100572 { inputTensorInfo, inputTensorInfo, inputTensorInfo },
573 { input0.data(), input1.data(), input2.data() },
574 outputTensorInfo,
575 output.data(),
576 0,
577 true);
578
Sadik Armagan483c8112021-06-01 09:24:52 +0100579 result.m_ActualData = output;
580 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100581 {
582 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f
583 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100584 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100585
586 return result;
587}
588
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100589template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100590LayerTestResult<T, 2> Concat2dTestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100591 IWorkloadFactory& workloadFactory,
592 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100593 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100594 const TensorInfo& outputTensorInfo,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100595 unsigned int dimension,
596 const float qScale,
597 const int32_t qOffset)
598{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100599 TensorInfo inputTensorInfo({ 2, 3 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100600
Sadik Armagan483c8112021-06-01 09:24:52 +0100601 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100602 {
603 // Batch 0
604 1.0f, 2.0f, 3.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100605
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100606 // Batch 1
607 10.0f, 11.0f, 12.0f,
608 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100609 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100610
Sadik Armagan483c8112021-06-01 09:24:52 +0100611 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100612 {
613 // Batch 0
614 4.0f, 5.0f, 6.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100615
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100616 // Batch 1
617 13.0f, 14.0f, 15.0f,
618 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100619 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100620
Sadik Armagan483c8112021-06-01 09:24:52 +0100621 auto input2 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100622 {
623 // Batch 0
624 7.0f, 8.0f, 9.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100625
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100626 // Batch 1
627 16.0f, 17.0f, 18.0f,
628 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100629 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100630
631 LayerTestResult<T, 2> result(outputTensorInfo);
632
633 std::vector<T> output;
634 output.resize(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +0100635 Concatenate<T>(workloadFactory, memoryManager, tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100636 { inputTensorInfo, inputTensorInfo, inputTensorInfo },
637 { input0.data(), input1.data(), input2.data() },
638 outputTensorInfo,
639 output.data(),
640 dimension,
641 true);
642
Sadik Armagan483c8112021-06-01 09:24:52 +0100643 result.m_ActualData = output;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100644 return result;
645}
646
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100647template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100648LayerTestResult<T, 2> Concat2dDim0TestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100649 IWorkloadFactory& workloadFactory,
650 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100651 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100652 float qScale,
653 int32_t qOffset)
654{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100655 TensorInfo outputTensorInfo({ 6, 3 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100656
657 LayerTestResult<T, 2> result = Concat2dTestImpl<ArmnnType>(
Keith Davisf500d6c2020-08-31 08:32:55 +0100658 workloadFactory, memoryManager, tensorHandleFactory, outputTensorInfo, 0, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100659
Sadik Armagan483c8112021-06-01 09:24:52 +0100660 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100661 {
662 // Batch 0
663 1.0f, 2.0f, 3.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100664
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100665 // Batch 1
666 10.0f, 11.0f, 12.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100667
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100668 // Batch 2
669 4.0f, 5.0f, 6.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100670
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100671 // Batch 3
672 13.0f, 14.0f, 15.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100673
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100674 // Batch 4
675 7.0f, 8.0f, 9.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100676
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100677 // Batch 5
678 16.0f, 17.0f, 18.0f,
679 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100680 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100681
682 return result;
683}
684
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100685template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100686LayerTestResult<T, 2> Concat2dDim1TestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100687 IWorkloadFactory& workloadFactory,
688 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100689 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100690 float qScale,
691 int32_t qOffset)
692{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100693 TensorInfo outputTensorInfo({ 2, 9 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100694
695 LayerTestResult<T, 2> result = Concat2dTestImpl<ArmnnType>(
Keith Davisf500d6c2020-08-31 08:32:55 +0100696 workloadFactory, memoryManager, tensorHandleFactory, outputTensorInfo, 1, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100697
Sadik Armagan483c8112021-06-01 09:24:52 +0100698 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100699 {
700 // Batch 0
701 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100702
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100703 // Batch 1
704 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f
705 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100706 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100707
708 return result;
709}
710
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100711template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100712LayerTestResult<T, 2> Concat2dDim0DiffInputDimsTestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100713 IWorkloadFactory& workloadFactory,
714 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100715 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100716 float qScale,
717 int32_t qOffset)
718{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100719 TensorInfo input0TensorInfo({ 2, 3 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +0100720 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100721 {
722 // Batch 0
723 1.0f, 2.0f, 3.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100724
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100725 // Batch 1
726 10.0f, 11.0f, 12.0f,
727 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100728 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100729
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100730 TensorInfo input1TensorInfo({ 3, 3 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +0100731 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100732 {
733 // Batch 0
734 4.0f, 5.0f, 6.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100735
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100736 // Batch 1
737 13.0f, 14.0f, 15.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100738
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100739 // Batch 0
740 7.0f, 8.0f, 9.0f,
741 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100742 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100743
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100744 TensorInfo input2TensorInfo({ 1, 3 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +0100745 auto input2 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100746 {
747 // Batch 1
748 16.0f, 17.0f, 18.0f,
749 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100750 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100751
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100752 TensorInfo outputTensorInfo({ 6, 3 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100753 LayerTestResult<T, 2> result(outputTensorInfo);
754
755 std::vector<T> output;
756 output.resize(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +0100757 Concatenate<T>(workloadFactory, memoryManager, tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100758 { input0TensorInfo, input1TensorInfo, input2TensorInfo },
759 { input0.data(), input1.data(), input2.data() },
760 outputTensorInfo,
761 output.data(),
762 0,
763 true);
764
Sadik Armagan483c8112021-06-01 09:24:52 +0100765 result.m_ActualData = output;
766 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100767 {
768 // Batch 0
769 1.0f, 2.0f, 3.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100770
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100771 // Batch 1
772 10.0f, 11.0f, 12.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100773
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100774 // Batch 2
775 4.0f, 5.0f, 6.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100776
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100777 // Batch 3
778 13.0f, 14.0f, 15.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100779
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100780 // Batch 4
781 7.0f, 8.0f, 9.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100782
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100783 // Batch 5
784 16.0f, 17.0f, 18.0f,
785 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100786 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100787
788 return result;
789}
790
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100791template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100792LayerTestResult<T, 2> Concat2dDim1DiffInputDimsTestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100793 IWorkloadFactory& workloadFactory,
794 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100795 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100796 float qScale,
797 int32_t qOffset)
798{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100799 TensorInfo input0TensorInfo({ 2, 3 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +0100800 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100801 {
802 // Batch 0
803 1.0f, 2.0f, 3.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100804
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100805 // Batch 1
806 10.0f, 11.0f, 12.0f,
807 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100808 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100809
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100810 TensorInfo input1TensorInfo({ 2, 5 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +0100811 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100812 {
813 // Batch 0
814 4.0f, 5.0f, 6.0f, 7.0f, 8.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100815
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100816 // Batch 1
817 13.0f, 14.0f, 15.0f, 16.0f, 17.0f,
818 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100819 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100820
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100821 TensorInfo input2TensorInfo({ 2, 1 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +0100822 auto input2 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100823 {
824 // Batch 0
825 9.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100826
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100827 // Batch 1
828 18.0f
829 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100830 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100831
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100832 TensorInfo outputTensorInfo({ 2, 9 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100833 LayerTestResult<T, 2> result(outputTensorInfo);
834
835 std::vector<T> output;
836 output.resize(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +0100837 Concatenate<T>(workloadFactory, memoryManager, tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100838 { input0TensorInfo, input1TensorInfo, input2TensorInfo },
839 { input0.data(), input1.data(), input2.data() },
840 outputTensorInfo,
841 output.data(),
842 1,
843 true);
844
Sadik Armagan483c8112021-06-01 09:24:52 +0100845 result.m_ActualData = output;
846 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100847 {
848 // Batch 0
849 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100850
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100851 // Batch 1
852 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f,
853 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100854 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100855
856 return result;
857}
858
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100859template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100860LayerTestResult<T, 3> Concat3dTestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100861 IWorkloadFactory& workloadFactory,
862 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100863 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100864 const TensorInfo& outputTensorInfo,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100865 unsigned int dimension,
866 bool useSubtensor,
867 float qScale,
868 int32_t qOffset)
869{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100870 TensorInfo inputTensorInfo({ 2, 3, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100871
Sadik Armagan483c8112021-06-01 09:24:52 +0100872 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100873 {
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100874 // Batch 0, Channel 0
875 1.0f, 2.0f,
876
877 // Batch 0, Channel 1
878 3.0f, 4.0f,
879
880 // Batch 0, Channel 2
881 5.0f, 6.0f,
882
883 // Batch 1, Channel 0
884 19.0f, 20.0f,
885
886 // Batch 1, Channel 1
887 21.0f, 22.0f,
888
889 // Batch 1, Channel 2
890 23.0f, 24.0f
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100891 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100892 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100893
Sadik Armagan483c8112021-06-01 09:24:52 +0100894 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100895 {
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100896 // Batch 0, Channel 0
897 7.0f, 8.0f,
898
899 // Batch 0, Channel 1
900 9.0f, 10.0f,
901
902 // Batch 0, Channel 2
903 11.0f, 12.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100904
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100905 // Batch 1, Channel 0
906 25.0f, 26.0f,
907
908 // Batch 1, Channel 1
909 27.0f, 28.0f,
910
911 // Batch 1, Channel 2
912 29.0f, 30.0f
913 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100914 qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100915
Sadik Armagan483c8112021-06-01 09:24:52 +0100916 auto input2 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100917 {
918 // Batch 0, Channel 0
919 13.0f, 14.0f,
920
921 // Batch 0, Channel 1
922 15.0f, 16.0f,
923
924 // Batch 0, Channel 2
925 17.0f, 18.0f,
926
927 // Batch 1, Channel 0
928 31.0f, 32.0f,
929
930 // Batch 1, Channel 1
931 33.0f, 34.0f,
932
933 // Batch 1, Channel 2
934 35.0f, 36.0f
935 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100936 qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100937
938 LayerTestResult<T, 3> result(outputTensorInfo);
939
940 std::vector<T> output;
941 output.resize(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +0100942 Concatenate<T>(workloadFactory, memoryManager, tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100943 { inputTensorInfo, inputTensorInfo, inputTensorInfo },
944 { input0.data(), input1.data(), input2.data() },
945 outputTensorInfo,
946 output.data(),
947 dimension,
948 useSubtensor);
949
Sadik Armagan483c8112021-06-01 09:24:52 +0100950 result.m_ActualData = output;
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100951 return result;
952}
953
954template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
955LayerTestResult<T, 3> Concat3dDim0TestImpl(
956 IWorkloadFactory& workloadFactory,
957 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100958 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100959 float qScale,
960 int32_t qOffset)
961{
962 TensorInfo outputTensorInfo({ 6, 3, 2 }, ArmnnType, qScale, qOffset);
963
964 LayerTestResult<T, 3> result = Concat3dTestImpl<ArmnnType>(
Keith Davisf500d6c2020-08-31 08:32:55 +0100965 workloadFactory, memoryManager, tensorHandleFactory, outputTensorInfo, 0, true, qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100966
Sadik Armagan483c8112021-06-01 09:24:52 +0100967 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100968 {
969 // Batch 0, Channel 0
970 1.0f, 2.0f,
971
972 // Batch 0, Channel 1
973 3.0f, 4.0f,
974
975 // Batch 0, Channel 2
976 5.0f, 6.0f,
977
978 // Batch 1, Channel 0
979 19.0f, 20.0f,
980
981 // Batch 1, Channel 1
982 21.0f, 22.0f,
983
984 // Batch 1, Channel 2
985 23.0f, 24.0f,
986
987 // Batch 2, Channel 0
988 7.0f, 8.0f,
989
990 // Batch 2, Channel 1
991 9.0f, 10.0f,
992
993 // Batch 2, Channel 2
994 11.0f, 12.0f,
995
996 // Batch 3, Channel 0
997 25.0f, 26.0f,
998
999 // Batch 3, Channel 1
1000 27.0f, 28.0f,
1001
1002 // Batch 3, Channel 2
1003 29.0f, 30.0f,
1004
1005 // Batch 4, Channel 0
1006 13.0f, 14.0f,
1007
1008 // Batch 4, Channel 1
1009 15.0f, 16.0f,
1010
1011 // Batch 4, Channel 2
1012 17.0f, 18.0f,
1013
1014 // Batch 5, Channel 0
1015 31.0f, 32.0f,
1016
1017 // Batch 5, Channel 1
1018 33.0f, 34.0f,
1019
1020 // Batch 5, Channel 2
1021 35.0f, 36.0f
1022 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001023 qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001024
1025 return result;
1026}
1027
1028template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
1029LayerTestResult<T, 3> Concat3dDim1TestImpl(
1030 IWorkloadFactory& workloadFactory,
1031 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001032 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001033 float qScale,
1034 int32_t qOffset)
1035{
1036 TensorInfo outputTensorInfo({ 2, 9, 2 }, ArmnnType, qScale, qOffset);
1037
1038 LayerTestResult<T, 3> result = Concat3dTestImpl<ArmnnType>(
Keith Davisf500d6c2020-08-31 08:32:55 +01001039 workloadFactory, memoryManager, tensorHandleFactory, outputTensorInfo, 1, true, qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001040
Sadik Armagan483c8112021-06-01 09:24:52 +01001041 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001042 {
1043 // Batch 0, Channel 0
1044 1.0f, 2.0f,
1045
1046 // Batch 0, Channel 1
1047 3.0f, 4.0f,
1048
1049 // Batch 0, Channel 2
1050 5.0f, 6.0f,
1051
1052 // Batch 0, Channel 3
1053 7.0f, 8.0f,
1054
1055 // Batch 0, Channel 4
1056 9.0f, 10.0f,
1057
1058 // Batch 0, Channel 5
1059 11.0f, 12.0f,
1060
1061 // Batch 0, Channel 6
1062 13.0f, 14.0f,
1063
1064 // Batch 0, Channel 7
1065 15.0f, 16.0f,
1066
1067 // Batch 0, Channel 8
1068 17.0f, 18.0f,
1069
1070 // Batch 1, Channel 0
1071 19.0f, 20.0f,
1072
1073 // Batch 1, Channel 1
1074 21.0f, 22.0f,
1075
1076 // Batch 1, Channel 2
1077 23.0f, 24.0f,
1078
1079 // Batch 1, Channel 3
1080 25.0f, 26.0f,
1081
1082 // Batch 1, Channel 4
1083 27.0f, 28.0f,
1084
1085 // Batch 1, Channel 5
1086 29.0f, 30.0f,
1087
1088 // Batch 1, Channel 6
1089 31.0f, 32.0f,
1090
1091 // Batch 1, Channel 7
1092 33.0f, 34.0f,
1093
1094 // Batch 1, Channel 8
1095 35.0f, 36.0f
1096 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001097 qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001098
1099 return result;
1100}
1101
1102template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
1103LayerTestResult<T, 3> Concat3dDim2TestImpl(
1104 IWorkloadFactory& workloadFactory,
1105 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001106 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001107 bool useSubtensor,
1108 float qScale,
1109 int32_t qOffset)
1110{
1111 TensorInfo outputTensorInfo({ 2, 3, 6 }, ArmnnType, qScale, qOffset);
1112
1113 LayerTestResult<T, 3> result = Concat3dTestImpl<ArmnnType>(
Keith Davisf500d6c2020-08-31 08:32:55 +01001114 workloadFactory, memoryManager, tensorHandleFactory, outputTensorInfo, 2, useSubtensor, qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001115
Sadik Armagan483c8112021-06-01 09:24:52 +01001116 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001117 {
1118 // Batch 0, Channel 0
1119 1.0f, 2.0f, 7.0f, 8.0f, 13.0f, 14.0f,
1120
1121 // Batch 0, Channel 1
1122 3.0f, 4.0f, 9.0f, 10.0f, 15.0f, 16.0f,
1123
1124 // Batch 0, Channel 2
1125 5.0f, 6.0f, 11.0f, 12.0f, 17.0f, 18.0f,
1126
1127 // Batch 1, Channel 0
1128 19.0f, 20.0f, 25.0f, 26.0f, 31.0f, 32.0f,
1129
1130 // Batch 1, Channel 1
1131 21.0f, 22.0f, 27.0f, 28.0f, 33.0f, 34.0f,
1132
1133 // Batch 1, Channel 2
1134 23.0f, 24.0f, 29.0f, 30.0f, 35.0f, 36.0f,
1135 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001136 qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001137
1138 return result;
1139}
1140
1141template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
1142LayerTestResult<T, 3> Concat3dDim0DiffInputDimsTestImpl(
1143 IWorkloadFactory& workloadFactory,
1144 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001145 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001146 float qScale,
1147 int32_t qOffset)
1148{
1149 TensorInfo input0TensorInfo({ 2, 3, 2 }, ArmnnType);
Sadik Armagan483c8112021-06-01 09:24:52 +01001150 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001151 {
1152 // Batch 0, Channel 0
1153 1.0f, 2.0f,
1154
1155 // Batch 0, Channel 1
1156 3.0f, 4.0f,
1157
1158 // Batch 0, Channel 2
1159 5.0f, 6.0f,
1160
1161 // Batch 1, Channel 0
1162 19.0f, 20.0f,
1163
1164 // Batch 1, Channel 1
1165 21.0f, 22.0f,
1166
1167 // Batch 1, Channel 2
1168 23.0f, 24.0f
1169 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001170 qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001171
1172 TensorInfo input1TensorInfo({ 1, 3, 2 }, ArmnnType);
Sadik Armagan483c8112021-06-01 09:24:52 +01001173 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001174 {
1175 // Batch 0, Channel 0
1176 7.0f, 8.0f,
1177
1178 // Batch 0, Channel 1
1179 9.0f, 10.0f,
1180
1181 // Batch 0, Channel 2
1182 11.0f, 12.0f,
1183 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001184 qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001185
1186 TensorInfo input2TensorInfo({ 3, 3, 2 }, ArmnnType);
Sadik Armagan483c8112021-06-01 09:24:52 +01001187 auto input2 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001188 {
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001189 // Batch 0, Channel 0
1190 25.0f, 26.0f,
1191
1192 // Batch 0, Channel 1
1193 27.0f, 28.0f,
1194
1195 // Batch 0, Channel 2
1196 29.0f, 30.0f,
1197
1198 // Batch 1, Channel 0
1199 13.0f, 14.0f,
1200
1201 // Batch 1, Channel 1
1202 15.0f, 16.0f,
1203
1204 // Batch 1, Channel 2
1205 17.0f, 18.0f,
1206
1207 // Batch 2, Channel 0
1208 31.0f, 32.0f,
1209
1210 // Batch 2, Channel 1
1211 33.0f, 34.0f,
1212
1213 // Batch 2, Channel 2
1214 35.0f, 36.0f
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001215 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001216 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001217
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001218 TensorInfo outputTensorInfo({ 6, 3, 2 }, ArmnnType);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001219 LayerTestResult<T, 3> result(outputTensorInfo);
1220
1221 std::vector<T> output;
1222 output.resize(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +01001223 Concatenate<T>(workloadFactory, memoryManager, tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001224 { input0TensorInfo, input1TensorInfo, input2TensorInfo },
1225 { input0.data(), input1.data(), input2.data() },
1226 outputTensorInfo,
1227 output.data(),
1228 0,
1229 true);
1230
Sadik Armagan483c8112021-06-01 09:24:52 +01001231 result.m_ActualData = output;
1232 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001233 {
1234 // Batch 0, Channel 0
1235 1.0f, 2.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001236
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001237 // Batch 0, Channel 1
1238 3.0f, 4.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001239
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001240 // Batch 0, Channel 2
1241 5.0f, 6.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001242
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001243 // Batch 1, Channel 0
1244 19.0f, 20.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001245
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001246 // Batch 1, Channel 1
1247 21.0f, 22.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001248
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001249 // Batch 1, Channel 2
1250 23.0f, 24.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001251
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001252 // Batch 2, Channel 0
1253 7.0f, 8.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001254
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001255 // Batch 2, Channel 1
1256 9.0f, 10.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001257
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001258 // Batch 2, Channel 2
1259 11.0f, 12.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001260
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001261 // Batch 3, Channel 0
1262 25.0f, 26.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001263
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001264 // Batch 3, Channel 1
1265 27.0f, 28.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001266
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001267 // Batch 3, Channel 2
1268 29.0f, 30.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001269
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001270 // Batch 4, Channel 0
1271 13.0f, 14.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001272
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001273 // Batch 4, Channel 1
1274 15.0f, 16.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001275
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001276 // Batch 4, Channel 2
1277 17.0f, 18.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001278
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001279 // Batch 5, Channel 0
1280 31.0f, 32.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001281
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001282 // Batch 5, Channel 1
1283 33.0f, 34.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001284
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001285 // Batch 5, Channel 2
1286 35.0f, 36.0f
1287 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001288 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001289
1290 return result;
1291}
1292
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001293template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001294LayerTestResult<T, 3> Concat3dDim1DiffInputDimsTestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001295 IWorkloadFactory& workloadFactory,
1296 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001297 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001298 float qScale,
1299 int32_t qOffset)
1300{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001301 TensorInfo input0TensorInfo({ 2, 3, 2 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001302 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001303 {
1304 // Batch 0, Channel 0
1305 1.0f, 2.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001306
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001307 // Batch 0, Channel 1
1308 3.0f, 4.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001309
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001310 // Batch 0, Channel 2
1311 5.0f, 6.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001312
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001313 // Batch 1, Channel 0
1314 19.0f, 20.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001315
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001316 // Batch 1, Channel 1
1317 21.0f, 22.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001318
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001319 // Batch 1, Channel 2
1320 23.0f, 24.0f
1321 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001322 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001323
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001324 TensorInfo input1TensorInfo({ 2, 4, 2 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001325 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001326 {
1327 // Batch 0, Channel 0
1328 7.0f, 8.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001329
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001330 // Batch 0, Channel 1
1331 9.0f, 10.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001332
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001333 // Batch 0, Channel 2
1334 11.0f, 12.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001335
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001336 // Batch 0, Channel 3
1337 25.0f, 26.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001338
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001339 // Batch 1, Channel 0
1340 27.0f, 28.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001341
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001342 // Batch 1, Channel 1
1343 29.0f, 30.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001344
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001345 // Batch 1, Channel 2
1346 13.0f, 14.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001347
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001348 // Batch 1, Channel 3
1349 15.0f, 16.0f,
1350 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001351 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001352
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001353 TensorInfo input2TensorInfo({ 2, 1, 2 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001354 auto input2 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001355 {
1356 // Batch 0, Channel 0
1357 17.0f, 18.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001358
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001359 // Batch 1, Channel 0
1360 31.0f, 32.0f,
1361 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001362 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001363
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001364 TensorInfo outputTensorInfo({ 2, 8, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001365 LayerTestResult<T, 3> result(outputTensorInfo);
1366
1367 std::vector<T> output;
1368 output.resize(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +01001369 Concatenate<T>(workloadFactory, memoryManager, tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001370 { input0TensorInfo, input1TensorInfo, input2TensorInfo },
1371 { input0.data(), input1.data(), input2.data() },
1372 outputTensorInfo,
1373 output.data(),
1374 1,
1375 true);
1376
Sadik Armagan483c8112021-06-01 09:24:52 +01001377 result.m_ActualData = output;
1378 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001379 {
1380 // Batch 0, Channel 0
1381 1.0f, 2.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001382
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001383 // Batch 0, Channel 1
1384 3.0f, 4.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001385
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001386 // Batch 0, Channel 2
1387 5.0f, 6.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001388
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001389 // Batch 0, Channel 3
1390 7.0f, 8.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001391
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001392 // Batch 0, Channel 4
1393 9.0f, 10.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001394
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001395 // Batch 0, Channel 5
1396 11.0f, 12.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001397
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001398 // Batch 0, Channel 6
1399 25.0f, 26.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001400
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001401 // Batch 0, Channel 7
1402 17.0f, 18.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001403
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001404 // Batch 1, Channel 0
1405 19.0f, 20.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001406
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001407 // Batch 1, Channel 1
1408 21.0f, 22.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001409
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001410 // Batch 1, Channel 2
1411 23.0f, 24.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001412
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001413 // Batch 1, Channel 3
1414 27.0f, 28.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001415
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001416 // Batch 1, Channel 4
1417 29.0f, 30.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001418
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001419 // Batch 1, Channel 5
1420 13.0f, 14.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001421
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001422 // Batch 1, Channel 6
1423 15.0f, 16.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001424
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001425 // Batch 1, Channel 7
1426 31.0f, 32.0f,
1427 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001428 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001429
1430 return result;
1431}
1432
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001433template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001434LayerTestResult<T, 3> Concat3dDim2DiffInputDimsTestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001435 IWorkloadFactory& workloadFactory,
1436 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001437 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001438 bool useSubtensor,
1439 float qScale,
1440 int32_t qOffset)
1441{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001442 TensorInfo input0TensorInfo({ 2, 3, 2 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001443 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001444 {
1445 // Batch 0, Channel 0
1446 1.0f, 2.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001447
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001448 // Batch 0, Channel 1
1449 3.0f, 4.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001450
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001451 // Batch 0, Channel 2
1452 5.0f, 6.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001453
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001454 // Batch 1, Channel 0
1455 19.0f, 20.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001456
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001457 // Batch 1, Channel 1
1458 21.0f, 22.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001459
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001460 // Batch 1, Channel 2
1461 23.0f, 24.0f
1462 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001463 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001464
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001465 TensorInfo input1TensorInfo({ 2, 3, 1 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001466 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001467 {
1468 // Batch 0, Channel 0
1469 7.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001470
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001471 // Batch 0, Channel 1
1472 9.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001473
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001474 // Batch 0, Channel 2
1475 11.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001476
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001477 // Batch 1, Channel 0
1478 25.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001479
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001480 // Batch 1, Channel 1
1481 27.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001482
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001483 // Batch 1, Channel 2
1484 29.0f
1485 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001486 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001487
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001488 TensorInfo input2TensorInfo({ 2, 3, 3 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001489 auto input2 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001490 {
1491 // Batch 0, Channel 0
1492 13.0f, 14.0f, 50.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001493
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001494 // Batch 0, Channel 1
1495 15.0f, 16.0f, 51.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001496
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001497 // Batch 0, Channel 2
1498 17.0f, 18.0f, 52.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001499
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001500 // Batch 1, Channel 0
1501 31.0f, 32.0f, 53.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001502
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001503 // Batch 1, Channel 1
1504 33.0f, 34.0f, 54.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001505
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001506 // Batch 1, Channel 2
1507 35.0f, 36.0f, 55.0f,
1508 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001509 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001510
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001511 TensorInfo outputTensorInfo({ 2, 3, 6 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001512 LayerTestResult<T, 3> result(outputTensorInfo);
1513
1514 std::vector<T> output;
1515 output.resize(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +01001516 Concatenate<T>(workloadFactory, memoryManager, tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001517 { input0TensorInfo, input1TensorInfo, input2TensorInfo },
1518 { input0.data(), input1.data(), input2.data() },
1519 outputTensorInfo,
1520 output.data(),
1521 2,
1522 useSubtensor);
1523
Sadik Armagan483c8112021-06-01 09:24:52 +01001524 result.m_ActualData = output;
1525 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001526 {
1527 // Batch 0, Channel 0
1528 1.0f, 2.0f, 7.0f, 13.0f, 14.0f, 50.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001529
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001530 // Batch 0, Channel 1
1531 3.0f, 4.0f, 9.0f, 15.0f, 16.0f, 51.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001532
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001533 // Batch 0, Channel 2
1534 5.0f, 6.0f, 11.0f, 17.0f, 18.0f, 52.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001535
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001536 // Batch 1, Channel 0
1537 19.0f, 20.0f, 25.0f, 31.0f, 32.0f, 53.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001538
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001539 // Batch 1, Channel 1
1540 21.0f, 22.0f, 27.0f, 33.0f, 34.0f, 54.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001541
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001542 // Batch 1, Channel 2
1543 23.0f, 24.0f, 29.0f, 35.0f, 36.0f, 55.0f,
1544 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001545 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001546
1547 return result;
1548}
1549
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001550template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001551LayerTestResult<T, 4> Concat4dTestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001552 IWorkloadFactory& workloadFactory,
1553 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001554 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001555 const TensorInfo& outputTensorInfo,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001556 unsigned int dimension,
1557 bool useSubtensor,
1558 float qScale,
1559 int32_t qOffset)
1560{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001561 TensorInfo inputTensorInfo({ 1, 3, 2, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001562
Sadik Armagan483c8112021-06-01 09:24:52 +01001563 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001564 {
1565 1.0f, 2.0f,
1566 3.0f, 4.0f,
1567 5.0f, 6.0f,
1568 7.0f, 8.0f,
1569 9.0f, 10.0f,
1570 11.0f, 12.0f
1571 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001572 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001573
Sadik Armagan483c8112021-06-01 09:24:52 +01001574 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001575 {
1576 11.0f, 12.0f,
1577 13.0f, 14.0f,
1578 15.0f, 16.0f,
1579 17.0f, 18.0f,
1580 19.0f, 20.0f,
1581 21.0f, 22.0f
1582 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001583 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001584
Sadik Armagan483c8112021-06-01 09:24:52 +01001585 auto input2 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001586 {
1587 21.0f, 22.0f,
1588 23.0f, 24.0f,
1589 25.0f, 26.0f,
1590 27.0f, 28.0f,
1591 29.0f, 30.0f,
1592 31.0f, 32.0f
1593 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001594 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001595
1596 LayerTestResult<T, 4> result(outputTensorInfo);
1597
1598 std::vector<T> output;
1599 output.resize(outputTensorInfo.GetNumElements());
1600
1601 Concatenate<T>(workloadFactory,
1602 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001603 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001604 {inputTensorInfo, inputTensorInfo, inputTensorInfo},
1605 {input0.data(), input1.data(), input2.data()},
1606 outputTensorInfo,
1607 output.data(),
1608 dimension,
1609 useSubtensor);
1610
Sadik Armagan483c8112021-06-01 09:24:52 +01001611 result.m_ActualData = output;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001612 return result;
1613}
1614
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001615template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001616LayerTestResult<T, 4> Concat4dDim0TestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001617 IWorkloadFactory& workloadFactory,
1618 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001619 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001620 float qScale,
1621 int32_t qOffset)
1622{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001623 TensorInfo outputTensorInfo({ 3, 3, 2, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001624
1625 LayerTestResult<T, 4> result = Concat4dTestImpl<ArmnnType>(
Keith Davisf500d6c2020-08-31 08:32:55 +01001626 workloadFactory, memoryManager, tensorHandleFactory, outputTensorInfo, 0, true, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001627
Sadik Armagan483c8112021-06-01 09:24:52 +01001628 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001629 {
1630 1.0f, 2.0f,
1631 3.0f, 4.0f,
1632 5.0f, 6.0f,
1633 7.0f, 8.0f,
1634 9.0f, 10.0f,
1635 11.0f, 12.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001636
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001637 11.0f, 12.0f,
1638 13.0f, 14.0f,
1639 15.0f, 16.0f,
1640 17.0f, 18.0f,
1641 19.0f, 20.0f,
1642 21.0f, 22.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001643
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001644 21.0f, 22.0f,
1645 23.0f, 24.0f,
1646 25.0f, 26.0f,
1647 27.0f, 28.0f,
1648 29.0f, 30.0f,
1649 31.0f, 32.0f
1650 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001651 qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001652
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001653 return result;
1654}
1655
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001656template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001657LayerTestResult<T, 4> Concat4dDim1TestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001658 IWorkloadFactory& workloadFactory,
1659 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001660 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001661 float qScale,
1662 int32_t qOffset)
1663{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001664 TensorInfo outputTensorInfo({ 1, 9, 2, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001665
1666 LayerTestResult<T, 4> result = Concat4dTestImpl<ArmnnType>(
Keith Davisf500d6c2020-08-31 08:32:55 +01001667 workloadFactory, memoryManager, tensorHandleFactory, outputTensorInfo, 1, true, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001668
Sadik Armagan483c8112021-06-01 09:24:52 +01001669 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001670 {
1671 1.0f, 2.0f,
1672 3.0f, 4.0f,
1673 5.0f, 6.0f,
1674 7.0f, 8.0f,
1675 9.0f, 10.0f,
1676 11.0f, 12.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001677
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001678 11.0f, 12.0f,
1679 13.0f, 14.0f,
1680 15.0f, 16.0f,
1681 17.0f, 18.0f,
1682 19.0f, 20.0f,
1683 21.0f, 22.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001684
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001685 21.0f, 22.0f,
1686 23.0f, 24.0f,
1687 25.0f, 26.0f,
1688 27.0f, 28.0f,
1689 29.0f, 30.0f,
1690 31.0f, 32.0f
1691 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001692 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001693
1694 return result;
1695}
1696
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001697template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001698LayerTestResult<T, 4> Concat4dDim2TestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001699 IWorkloadFactory& workloadFactory,
1700 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001701 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001702 float qScale,
1703 int32_t qOffset)
1704{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001705 TensorInfo outputTensorInfo({ 1, 3, 6, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001706
1707 LayerTestResult<T, 4> result = Concat4dTestImpl<ArmnnType>(
Keith Davisf500d6c2020-08-31 08:32:55 +01001708 workloadFactory, memoryManager, tensorHandleFactory, outputTensorInfo, 2, true, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001709
Sadik Armagan483c8112021-06-01 09:24:52 +01001710 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001711 {
1712 1.0f, 2.0f,
1713 3.0f, 4.0f,
1714 11.0f, 12.0f,
1715 13.0f, 14.0f,
1716 21.0f, 22.0f,
1717 23.0f, 24.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001718
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001719 5.0f, 6.0f,
1720 7.0f, 8.0f,
1721 15.0f, 16.0f,
1722 17.0f, 18.0f,
1723 25.0f, 26.0f,
1724 27.0f, 28.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001725
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001726 9.0f, 10.0f,
1727 11.0f, 12.0f,
1728 19.0f, 20.0f,
1729 21.0f, 22.0f,
1730 29.0f, 30.0f,
1731 31.0f, 32.0f
1732 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001733 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001734
1735 return result;
1736}
1737
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001738template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001739LayerTestResult<T, 4> Concat4dDim3TestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001740 IWorkloadFactory& workloadFactory,
1741 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001742 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001743 float qScale,
1744 int32_t qOffset,
1745 bool useSubtensor)
1746{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001747 TensorInfo outputTensorInfo({ 1, 3, 2, 6 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001748
1749 LayerTestResult<T, 4> result = Concat4dTestImpl<ArmnnType>(
Keith Davisf500d6c2020-08-31 08:32:55 +01001750 workloadFactory, memoryManager, tensorHandleFactory, outputTensorInfo, 3, useSubtensor, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001751
Sadik Armagan483c8112021-06-01 09:24:52 +01001752 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001753 {
1754 1.0f, 2.0f,
1755 11.0f, 12.0f,
1756 21.0f, 22.0f,
1757 3.0f, 4.0f,
1758 13.0f, 14.0f,
1759 23.0f, 24.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001760
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001761 5.0f, 6.0f,
1762 15.0f, 16.0f,
1763 25.0f, 26.0f,
1764 7.0f, 8.0f,
1765 17.0f, 18.0f,
1766 27.0f, 28.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001767
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001768 9.0f, 10.0f,
1769 19.0f, 20.0f,
1770 29.0f, 30.0f,
1771 11.0f, 12.0f,
1772 21.0f, 22.0f,
1773 31.0f, 32.0f
1774 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001775 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001776
1777 return result;
1778}
1779
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001780template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001781LayerTestResult<T, 4> Concat4dDiffShapeDim0TestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001782 IWorkloadFactory& workloadFactory,
1783 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001784 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001785 float qScale,
1786 int32_t qOffset)
1787{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001788 constexpr unsigned int dimension = 0u;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001789
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001790 TensorInfo inputTensorInfo0({ 1, 3, 2, 2 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001791 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001792 {
1793 1.0f, 2.0f,
1794 3.0f, 4.0f,
1795 5.0f, 6.0f,
1796 7.0f, 8.0f,
1797 9.0f, 10.0f,
1798 11.0f, 12.0f
1799 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001800 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001801
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001802 TensorInfo inputTensorInfo1({ 2, 3, 2, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001803
Sadik Armagan483c8112021-06-01 09:24:52 +01001804 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001805 {
1806 11.0f, 12.0f,
1807 13.0f, 14.0f,
1808 15.0f, 16.0f,
1809 17.0f, 18.0f,
1810 19.0f, 20.0f,
1811 21.0f, 22.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001812
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001813 21.0f, 22.0f,
1814 23.0f, 24.0f,
1815 25.0f, 26.0f,
1816 27.0f, 28.0f,
1817 29.0f, 30.0f,
1818 31.0f, 32.0f
1819 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001820 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001821
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001822 TensorInfo outputTensorInfo({ 3, 3, 2, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001823
1824 LayerTestResult<T, 4> result(outputTensorInfo);
1825
1826 std::vector<T> output;
1827 output.resize(outputTensorInfo.GetNumElements());
1828 Concatenate<T>(workloadFactory,
1829 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001830 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001831 {inputTensorInfo0, inputTensorInfo1},
1832 {input0.data(), input1.data()},
1833 outputTensorInfo,
1834 output.data(),
1835 dimension,
1836 true);
1837
Sadik Armagan483c8112021-06-01 09:24:52 +01001838 result.m_ActualData = output;
1839 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001840 {
1841 1.0f, 2.0f,
1842 3.0f, 4.0f,
1843 5.0f, 6.0f,
1844 7.0f, 8.0f,
1845 9.0f, 10.0f,
1846 11.0f, 12.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001847
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001848 11.0f, 12.0f,
1849 13.0f, 14.0f,
1850 15.0f, 16.0f,
1851 17.0f, 18.0f,
1852 19.0f, 20.0f,
1853 21.0f, 22.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001854
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001855 21.0f, 22.0f,
1856 23.0f, 24.0f,
1857 25.0f, 26.0f,
1858 27.0f, 28.0f,
1859 29.0f, 30.0f,
1860 31.0f, 32.0f
1861 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001862 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001863
1864 return result;
1865}
1866
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001867template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001868LayerTestResult<T, 4> Concat4dDiffShapeDim1TestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001869 IWorkloadFactory& workloadFactory,
1870 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001871 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001872 float qScale,
1873 int32_t qOffset)
1874{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001875 constexpr unsigned int dimension = 1u;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001876
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001877 TensorInfo inputTensorInfo0({ 1, 3, 2, 2 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001878 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001879 {
1880 1.0f, 2.0f,
1881 3.0f, 4.0f,
1882 5.0f, 6.0f,
1883 7.0f, 8.0f,
1884 9.0f, 10.0f,
1885 11.0f, 12.0f
1886 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001887 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001888
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001889 TensorInfo inputTensorInfo1({ 1, 2, 2, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001890
Sadik Armagan483c8112021-06-01 09:24:52 +01001891 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001892 {
1893 11.0f, 12.0f,
1894 13.0f, 14.0f,
1895 15.0f, 16.0f,
1896 17.0f, 18.0f,
1897 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001898 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001899
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001900 TensorInfo outputTensorInfo({ 1, 5, 2, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001901
1902 LayerTestResult<T, 4> result(outputTensorInfo);
1903
1904 std::vector<T> output;
1905 output.resize(outputTensorInfo.GetNumElements());
1906 Concatenate<T>(workloadFactory,
1907 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001908 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001909 {inputTensorInfo0, inputTensorInfo1},
1910 {input0.data(), input1.data()},
1911 outputTensorInfo,
1912 output.data(),
1913 dimension,
1914 true);
1915
Sadik Armagan483c8112021-06-01 09:24:52 +01001916 result.m_ActualData = output;
1917 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001918 {
1919 1.0f, 2.0f,
1920 3.0f, 4.0f,
1921 5.0f, 6.0f,
1922 7.0f, 8.0f,
1923 9.0f, 10.0f,
1924 11.0f, 12.0f,
1925 11.0f, 12.0f,
1926 13.0f, 14.0f,
1927 15.0f, 16.0f,
1928 17.0f, 18.0f
1929 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001930 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001931
1932 return result;
1933}
1934
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001935template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001936LayerTestResult<T, 4> Concat4dDiffShapeDim2TestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001937 IWorkloadFactory& workloadFactory,
1938 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001939 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001940 float qScale,
1941 int32_t qOffset)
1942{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001943 constexpr unsigned int dimension = 2u;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001944
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001945 TensorInfo inputTensorInfo0({ 1, 3, 2, 2 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001946 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001947 {
1948 1.0f, 2.0f,
1949 3.0f, 4.0f,
1950 5.0f, 6.0f,
1951 7.0f, 8.0f,
1952 9.0f, 10.0f,
1953 11.0f, 12.0f
1954 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001955 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001956
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001957 TensorInfo inputTensorInfo1({ 1, 3, 3, 2 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001958 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001959 {
1960 11.0f, 12.0f,
1961 13.0f, 14.0f,
1962 15.0f, 16.0f,
1963 17.0f, 18.0f,
1964 19.0f, 20.0f,
1965 21.0f, 22.0f,
1966 23.0f, 24.0f,
1967 25.0f, 26.0f,
1968 27.0f, 28.0f
1969 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001970 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001971
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001972 TensorInfo outputTensorInfo({ 1, 3, 5, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001973 LayerTestResult<T, 4> result(outputTensorInfo);
1974
1975 std::vector<T> output;
1976 output.resize(outputTensorInfo.GetNumElements());
1977 Concatenate<T>(workloadFactory,
1978 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001979 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001980 {inputTensorInfo0, inputTensorInfo1},
1981 {input0.data(), input1.data()},
1982 outputTensorInfo,
1983 output.data(),
1984 dimension,
1985 true);
1986
Sadik Armagan483c8112021-06-01 09:24:52 +01001987 result.m_ActualData = output;
1988 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001989 {
1990 1.0f, 2.0f,
1991 3.0f, 4.0f,
1992 11.0f, 12.0f,
1993 13.0f, 14.0f,
1994 15.0f, 16.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001995
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001996 5.0f, 6.0f,
1997 7.0f, 8.0f,
1998 17.0f, 18.0f,
1999 19.0f, 20.0f,
2000 21.0f, 22.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002001
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002002 9.0f, 10.0f,
2003 11.0f, 12.0f,
2004 23.0f, 24.0f,
2005 25.0f, 26.0f,
2006 27.0f, 28.0f
2007 },
Sadik Armagan483c8112021-06-01 09:24:52 +01002008 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002009
2010 return result;
2011}
2012
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002013template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002014LayerTestResult<T, 4> Concat4dDiffShapeDim3TestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002015 IWorkloadFactory& workloadFactory,
2016 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002017 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002018 float qScale,
2019 int32_t qOffset,
2020 bool useSubtensor)
2021{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002022 constexpr unsigned int dimension = 3u;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002023
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002024 TensorInfo inputTensorInfo0({ 1, 3, 2, 2 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01002025 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002026 {
2027 1.0f, 2.0f,
2028 3.0f, 4.0f,
2029 5.0f, 6.0f,
2030 7.0f, 8.0f,
2031 9.0f, 10.0f,
2032 11.0f, 12.0f
2033 },
Sadik Armagan483c8112021-06-01 09:24:52 +01002034 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002035
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002036 TensorInfo inputTensorInfo1({ 1, 3, 2, 3 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01002037 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002038 {
2039 11.0f, 12.0f, 13.0f,
2040 14.0f, 15.0f, 16.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002041
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002042 17.0f, 18.0f, 19.0f,
2043 20.0f, 21.0f, 22.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002044
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002045 23.0f, 24.0f, 25.0f,
2046 26.0f, 27.0f, 28.0f
2047 },
Sadik Armagan483c8112021-06-01 09:24:52 +01002048 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002049
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002050 TensorInfo outputTensorInfo({ 1, 3, 2, 5 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002051
2052 LayerTestResult<T, 4> result(outputTensorInfo);
2053
2054 std::vector<T> output;
2055 output.resize(outputTensorInfo.GetNumElements());
2056 Concatenate<T>(workloadFactory,
2057 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002058 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002059 {inputTensorInfo0, inputTensorInfo1},
2060 {input0.data(), input1.data()},
2061 outputTensorInfo,
2062 output.data(),
2063 dimension,
2064 useSubtensor);
2065
Sadik Armagan483c8112021-06-01 09:24:52 +01002066 result.m_ActualData = output;
2067 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002068 {
2069 1.0f, 2.0f, 11.0f, 12.0f, 13.0f,
2070 3.0f, 4.0f, 14.0f, 15.0f, 16.0f,
2071 5.0f, 6.0f, 17.0f, 18.0f, 19.0f,
2072 7.0f, 8.0f, 20.0f, 21.0f, 22.0f,
2073 9.0f, 10.0f, 23.0f, 24.0f, 25.0f,
2074 11.0f, 12.0f, 26.0f, 27.0f, 28.0f
2075 },
Sadik Armagan483c8112021-06-01 09:24:52 +01002076 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002077
2078 return result;
2079}
2080
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002081template<DataType ArmnnType, typename T>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002082LayerTestResult<T, 3> ConcatDifferentInputOutputQParamTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002083 IWorkloadFactory& workloadFactory,
2084 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002085 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002086 bool useSubtensor)
2087{
Jan Eilers8eb25602020-03-09 12:13:48 +00002088 IgnoreUnused(memoryManager);
Derek Lambertic374ff02019-12-10 21:57:35 +00002089
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002090 // Defines the tensor descriptors.
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002091 TensorInfo outputTensorInfo({ 3, 6, 3 }, ArmnnType);
2092 TensorInfo inputTensorInfo1({ 3, 6, 2 }, ArmnnType);
2093 TensorInfo inputTensorInfo2({ 3, 6, 1 }, ArmnnType);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002094
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002095 std::vector<TensorShape> inputTensorShapes({inputTensorInfo1.GetShape(), inputTensorInfo2.GetShape()});
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002096
2097 // Quantized input1 tensor.
2098 const float inputScale1 = 0.5f;
2099 const int32_t inputOffset1 = 5;
2100
Sadik Armagan483c8112021-06-01 09:24:52 +01002101 std::vector<T> input1 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002102 {
2103 1, 2, 3,
2104 4, 5, 6,
2105 7, 8, 9,
2106 10, 11, 12,
2107 13, 14, 15,
2108 16, 17, 18,
2109
2110 19, 20, 21,
2111 22, 23, 24,
2112 25, 26, 27,
2113 28, 29, 30,
2114 31, 32, 33,
2115 34, 35, 36
Sadik Armagan483c8112021-06-01 09:24:52 +01002116 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002117
2118 // Quatized input2 tensor.
2119 const float inputScale2 = 0.2f;
2120 const int32_t inputOffset2 = 10;
2121
Sadik Armagan483c8112021-06-01 09:24:52 +01002122 std::vector<T> input2 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002123 {
2124 37, 38, 39,
2125 40, 41, 42,
2126 43, 44, 45,
2127 46, 47, 48,
2128 49, 50, 51,
2129 52, 53, 54
Sadik Armagan483c8112021-06-01 09:24:52 +01002130 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002131
2132 // Quantized output tensor.
2133 const float outputScale = 0.1f;
2134 const int32_t outputOffset = 20;
2135
Sadik Armagan483c8112021-06-01 09:24:52 +01002136 std::vector<T> actualOutput(outputTensorInfo.GetNumElements());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002137
Sadik Armagan483c8112021-06-01 09:24:52 +01002138 std::vector<T> expectedOutput =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002139 {
2140 0, 5, 74,
2141 10, 15, 76,
2142 20, 25, 78,
2143 30, 35, 80,
2144 40, 45, 82,
2145 50, 55, 84,
2146
2147 60, 65, 86,
2148 70, 75, 88,
2149 80, 85, 90,
2150 90, 95, 92,
2151 100, 105, 94,
2152 110, 115, 96,
2153
2154 120, 125, 98,
2155 130, 135, 100,
2156 140, 145, 102,
2157 150, 155, 104,
2158 160, 165, 106,
2159 170, 175, 108
Sadik Armagan483c8112021-06-01 09:24:52 +01002160 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002161
2162 outputTensorInfo.SetQuantizationScale(outputScale);
2163 outputTensorInfo.SetQuantizationOffset(outputOffset);
2164 inputTensorInfo1.SetQuantizationScale(inputScale1);
2165 inputTensorInfo1.SetQuantizationOffset(inputOffset1);
2166 inputTensorInfo2.SetQuantizationScale(inputScale2);
2167 inputTensorInfo2.SetQuantizationOffset(inputOffset2);
2168
2169 std::vector<unsigned int> wOrigin1 = { 0, 0, 0 }; //Extent of the window is defined by size of input[0].
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002170 ConcatQueueDescriptor::ViewOrigin window1(wOrigin1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002171
2172 std::vector<unsigned int> wOrigin2 = { 0, 0, 2 }; //Extent of the window is defined by size of input[1].
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002173 ConcatQueueDescriptor::ViewOrigin window2(wOrigin2);
Keith Davisf500d6c2020-08-31 08:32:55 +01002174
2175 std::unique_ptr<ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
2176
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002177 bool subTensorsSupported = useSubtensor && workloadFactory.SupportsSubTensors();
Keith Davisf500d6c2020-08-31 08:32:55 +01002178
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002179 std::unique_ptr<ITensorHandle> inputHandle1 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002180 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +01002181 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo1.GetShape(), wOrigin1.data()) :
2182 tensorHandleFactory.CreateTensorHandle(inputTensorInfo1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002183
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002184 std::unique_ptr<ITensorHandle> inputHandle2 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002185 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +01002186 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo2.GetShape(), wOrigin2.data()) :
2187 tensorHandleFactory.CreateTensorHandle(inputTensorInfo2);
2188
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002189 ConcatQueueDescriptor data;
2190 OriginsDescriptor desc = CreateDescriptorForConcatenation(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002191 inputTensorShapes.begin(),inputTensorShapes.end(), 2);
2192 data.m_Parameters = desc;
2193
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002194 WorkloadInfo info;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002195 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
2196 AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
2197 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
2198
2199 data.m_ViewOrigins.push_back(window1);
2200 data.m_ViewOrigins.push_back(window2);
2201
Teresa Charlin611c7fb2022-01-07 09:47:29 +00002202 std::unique_ptr<IWorkload> workload = workloadFactory.CreateWorkload(LayerType::Concat, data, info);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002203
2204 inputHandle1->Allocate();
2205 inputHandle2->Allocate();
2206 outputHandle->Allocate();
2207
Sadik Armagan483c8112021-06-01 09:24:52 +01002208 CopyDataToITensorHandle(inputHandle1.get(), input1.data());
2209 CopyDataToITensorHandle(inputHandle2.get(), input2.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002210
2211 workload->PostAllocationConfigure();
2212 workload->Execute();
2213
Sadik Armagan483c8112021-06-01 09:24:52 +01002214 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002215
Sadik Armagan483c8112021-06-01 09:24:52 +01002216 return LayerTestResult<T, 3>(actualOutput,
2217 expectedOutput,
2218 outputHandle->GetShape(),
2219 outputTensorInfo.GetShape());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002220}
2221
2222//
2223// Explicit template specializations
2224//
2225
Derek Lambertif90c56d2020-01-10 17:14:08 +00002226template LayerTestResult<ResolveType<DataType::QAsymmU8>, 3>
2227ConcatDifferentInputOutputQParamTest<DataType::QAsymmU8>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002228 IWorkloadFactory& workloadFactory,
2229 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002230 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002231 bool useSubtensor);
2232
Derek Lambertif90c56d2020-01-10 17:14:08 +00002233template LayerTestResult<ResolveType<DataType::QSymmS16>, 3>
2234ConcatDifferentInputOutputQParamTest<DataType::QSymmS16>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002235 IWorkloadFactory& workloadFactory,
2236 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002237 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002238 bool useSubtensor);
2239
2240//
2241// Implementation functions
2242//
2243
2244LayerTestResult<float,3> ConcatTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002245 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002246 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2247 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002248{
Teresa Charlin6abc7ee2022-02-22 17:32:27 +00002249 return ConcatTestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory);
2250}
Derek Lambertic374ff02019-12-10 21:57:35 +00002251
Teresa Charlin6abc7ee2022-02-22 17:32:27 +00002252LayerTestResult<int32_t, 3> ConcatInt32Test(
2253 IWorkloadFactory& workloadFactory,
2254 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2255 const armnn::ITensorHandleFactory& tensorHandleFactory)
2256{
2257 return ConcatTestImpl<DataType::Signed32>(workloadFactory, memoryManager, tensorHandleFactory);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002258}
2259
2260LayerTestResult<float, 1> Concat1dTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002261 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002262 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2263 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002264{
Keith Davisf500d6c2020-08-31 08:32:55 +01002265 return Concat1dTestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002266}
2267
2268LayerTestResult<float, 2> Concat2dDim0Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002269 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002270 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2271 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002272{
Keith Davisf500d6c2020-08-31 08:32:55 +01002273 return Concat2dDim0TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002274}
2275
2276LayerTestResult<float, 2> Concat2dDim1Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002277 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002278 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2279 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002280{
Keith Davisf500d6c2020-08-31 08:32:55 +01002281 return Concat2dDim1TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002282}
2283
2284LayerTestResult<float, 2> Concat2dDim0DiffInputDimsTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002285 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002286 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2287 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002288{
Keith Davisf500d6c2020-08-31 08:32:55 +01002289 return Concat2dDim0DiffInputDimsTestImpl<DataType::Float32>(workloadFactory, memoryManager,
2290 tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002291}
2292
2293LayerTestResult<float, 2> Concat2dDim1DiffInputDimsTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002294 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002295 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2296 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002297{
Keith Davisf500d6c2020-08-31 08:32:55 +01002298 return Concat2dDim1DiffInputDimsTestImpl<DataType::Float32>(workloadFactory,
2299 memoryManager,
2300 tensorHandleFactory,
2301 0.0f,
2302 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002303}
2304
2305LayerTestResult<float, 3> Concat3dDim0Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002306 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002307 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2308 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002309{
Keith Davisf500d6c2020-08-31 08:32:55 +01002310 return Concat3dDim0TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002311}
2312
2313LayerTestResult<float, 3> Concat3dDim1Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002314 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002315 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2316 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002317{
Keith Davisf500d6c2020-08-31 08:32:55 +01002318 return Concat3dDim1TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002319}
2320
2321LayerTestResult<float, 3> Concat3dDim2Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002322 IWorkloadFactory& workloadFactory,
2323 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002324 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002325 bool useSubtensor)
2326{
Keith Davisf500d6c2020-08-31 08:32:55 +01002327 return Concat3dDim2TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory,
2328 useSubtensor, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002329}
2330
2331LayerTestResult<float, 3> Concat3dDim0DiffInputDimsTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002332 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002333 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2334 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002335{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002336 return Concat3dDim0DiffInputDimsTestImpl<DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002337 workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002338}
2339
2340LayerTestResult<float, 3> Concat3dDim1DiffInputDimsTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002341 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002342 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2343 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002344{
Keith Davisf500d6c2020-08-31 08:32:55 +01002345 return Concat3dDim1DiffInputDimsTestImpl<DataType::Float32>(workloadFactory, memoryManager,
2346 tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002347}
2348
2349LayerTestResult<float, 3> Concat3dDim2DiffInputDimsTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002350 IWorkloadFactory& workloadFactory,
2351 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002352 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002353 bool useSubtensor)
2354{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002355 return Concat3dDim2DiffInputDimsTestImpl<DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002356 workloadFactory, memoryManager, tensorHandleFactory, useSubtensor, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002357}
2358
2359LayerTestResult<float, 4> Concat4dDim0Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002360 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002361 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2362 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002363{
Keith Davisf500d6c2020-08-31 08:32:55 +01002364 return Concat4dDim0TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002365}
2366
2367LayerTestResult<float, 4> Concat4dDim1Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002368 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002369 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2370 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002371{
Keith Davisf500d6c2020-08-31 08:32:55 +01002372 return Concat4dDim1TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002373}
2374
2375LayerTestResult<float, 4> Concat4dDim2Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002376 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002377 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2378 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002379{
Keith Davisf500d6c2020-08-31 08:32:55 +01002380 return Concat4dDim2TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002381}
2382
2383LayerTestResult<float, 4> Concat4dDim3Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002384 IWorkloadFactory& workloadFactory,
2385 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002386 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002387 bool useSubtensor)
2388{
Keith Davisf500d6c2020-08-31 08:32:55 +01002389 return Concat4dDim3TestImpl<DataType::Float32>(workloadFactory, memoryManager,
2390 tensorHandleFactory, 0.0f, 0, useSubtensor);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002391}
2392
2393LayerTestResult<float, 4> Concat4dDiffShapeDim0Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002394 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002395 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2396 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002397{
Keith Davisf500d6c2020-08-31 08:32:55 +01002398 return Concat4dDiffShapeDim0TestImpl<DataType::Float32>(workloadFactory, memoryManager,
2399 tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002400}
2401
2402LayerTestResult<float, 4> Concat4dDiffShapeDim1Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002403 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002404 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2405 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002406{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002407 return Concat4dDiffShapeDim1TestImpl<DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002408 workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002409}
2410
2411LayerTestResult<float, 4> Concat4dDiffShapeDim2Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002412 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002413 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2414 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002415{
Keith Davisf500d6c2020-08-31 08:32:55 +01002416 return Concat4dDiffShapeDim2TestImpl<DataType::Float32>(workloadFactory, memoryManager,
2417 tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002418}
2419
2420LayerTestResult<float, 4> Concat4dDiffShapeDim3Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002421 IWorkloadFactory& workloadFactory,
2422 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002423 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002424 bool useSubtensor)
2425{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002426 return Concat4dDiffShapeDim3TestImpl<DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002427 workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0, useSubtensor);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002428}
2429
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002430LayerTestResult<Half, 3> ConcatFloat16Test(
2431 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002432 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2433 const armnn::ITensorHandleFactory& tensorHandleFactory)
Matthew Jackson9bff1442019-09-12 09:08:23 +01002434{
Keith Davisf500d6c2020-08-31 08:32:55 +01002435 return Concat3dDim1TestImpl<DataType::Float16>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Matthew Jackson9bff1442019-09-12 09:08:23 +01002436}
2437
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00002438LayerTestResult<BFloat16, 3> ConcatBFloat16Test(
2439 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002440 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2441 const armnn::ITensorHandleFactory& tensorHandleFactory)
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00002442{
Keith Davisf500d6c2020-08-31 08:32:55 +01002443 return Concat3dDim1TestImpl<DataType::BFloat16>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00002444}
2445
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002446LayerTestResult<uint8_t, 3> ConcatUint8DifferentQParamsTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002447 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002448 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2449 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002450{
Jan Eilers8eb25602020-03-09 12:13:48 +00002451 IgnoreUnused(memoryManager);
Derek Lambertic374ff02019-12-10 21:57:35 +00002452
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002453 unsigned int outputWidth = 3;
2454 unsigned int outputHeight = 6;
2455 unsigned int outputChannels = 3;
2456
2457 unsigned int inputWidth1 = 3;
2458 unsigned int inputHeight1 = 6;
2459 unsigned int inputChannels1 = 2;
2460
2461 unsigned int inputWidth2 = 3;
2462 unsigned int inputHeight2 = 6;
2463 unsigned int inputChannels2 = 1;
2464
2465 // Defines the tensor descriptors.
Derek Lambertif90c56d2020-01-10 17:14:08 +00002466 TensorInfo outputTensorInfo({ outputChannels, outputHeight, outputWidth }, DataType::QAsymmU8);
2467 TensorInfo inputTensorInfo1({ inputChannels1, inputHeight1, inputWidth1 }, DataType::QAsymmU8);
2468 TensorInfo inputTensorInfo2({ inputChannels2, inputHeight2, inputWidth2 }, DataType::QAsymmU8);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002469
2470 // Quantized input1 tensor. Range [-3, 1]
2471 const float inputScale1 = 0.015686f;
2472 const int32_t inputOffset1 = 192;
2473
Sadik Armagan483c8112021-06-01 09:24:52 +01002474 std::vector<uint8_t> input1 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002475 {
2476 1, 2, 3,
2477 4, 5, 6,
2478 7, 8, 9,
2479 10, 11, 12,
2480 13, 14, 15,
2481 16, 17, 18,
2482
2483 19, 20, 21,
2484 22, 23, 24,
2485 25, 26, 27,
2486 28, 29, 30,
2487 31, 32, 33,
Sadik Armagan483c8112021-06-01 09:24:52 +01002488 34, 35, 36
2489 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002490
2491 // Quatized input2 tensor. Range [-1, 4]
2492 const float inputScale2 = 0.019608f;
2493 const int32_t inputOffset2 = 50;
2494
Sadik Armagan483c8112021-06-01 09:24:52 +01002495 std::vector<uint8_t> input2 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002496 {
2497 37, 38, 39,
2498 40, 41, 42,
2499 43, 44, 45,
2500 46, 47, 48,
2501 49, 50, 51,
Sadik Armagan483c8112021-06-01 09:24:52 +01002502 52, 53, 54
2503 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002504
2505 // Output has the same quantization parameters than input1,
2506 // so that only the requantization of input2 is required
2507 const float outputScale = 0.015686f;
2508 const int32_t outputOffset = 192;
2509
Sadik Armagan483c8112021-06-01 09:24:52 +01002510 std::vector<uint8_t> actualOutput(outputTensorInfo.GetNumElements());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002511
Sadik Armagan483c8112021-06-01 09:24:52 +01002512 std::vector<uint8_t> expectedOutput =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002513 {
2514 1, 2, 3,
2515 4, 5, 6,
2516 7, 8, 9,
2517 10, 11, 12,
2518 13, 14, 15,
2519 16, 17, 18,
2520
2521 19, 20, 21,
2522 22, 23, 24,
2523 25, 26, 27,
2524 28, 29, 30,
2525 31, 32, 33,
2526 34, 35, 36,
2527
2528 176, 177, 178,
2529 179, 181, 182,
2530 183, 184, 186,
2531 187, 188, 189,
2532 191, 192, 193,
Sadik Armagan483c8112021-06-01 09:24:52 +01002533 195, 196, 197
2534 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002535
2536 outputTensorInfo.SetQuantizationScale(outputScale);
2537 outputTensorInfo.SetQuantizationOffset(outputOffset);
2538 inputTensorInfo1.SetQuantizationScale(inputScale1);
2539 inputTensorInfo1.SetQuantizationOffset(inputOffset1);
2540 inputTensorInfo2.SetQuantizationScale(inputScale2);
2541 inputTensorInfo2.SetQuantizationOffset(inputOffset2);
2542
2543 std::vector<unsigned int> wOrigin1 = { 0, 0, 0 }; //Extent of the window is defined by size of input[0].
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002544 ConcatQueueDescriptor::ViewOrigin window1(wOrigin1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002545
2546 std::vector<unsigned int> wOrigin2 = { 2, 0, 0 }; //Extent of the window is defined by size of input[1].
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002547 ConcatQueueDescriptor::ViewOrigin window2(wOrigin2);
Keith Davisf500d6c2020-08-31 08:32:55 +01002548
2549 std::unique_ptr<ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002550
2551 bool subTensorsSupported = workloadFactory.SupportsSubTensors();
2552
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002553 std::unique_ptr<ITensorHandle> inputHandle1 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002554 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +01002555 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo1.GetShape(), wOrigin1.data()) :
2556 tensorHandleFactory.CreateTensorHandle(inputTensorInfo1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002557
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002558 std::unique_ptr<ITensorHandle> inputHandle2 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002559 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +01002560 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo2.GetShape(), wOrigin2.data()) :
2561 tensorHandleFactory.CreateTensorHandle(inputTensorInfo2);
2562
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002563 ConcatQueueDescriptor data;
2564 WorkloadInfo info;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002565 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
2566 AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
2567 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
2568
2569 data.m_ViewOrigins.push_back(window1);
2570 data.m_ViewOrigins.push_back(window2);
2571
Teresa Charlin611c7fb2022-01-07 09:47:29 +00002572 std::unique_ptr<IWorkload> workload = workloadFactory.CreateWorkload(LayerType::Concat, data, info);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002573
2574 inputHandle1->Allocate();
2575 inputHandle2->Allocate();
2576 outputHandle->Allocate();
2577
Sadik Armagan483c8112021-06-01 09:24:52 +01002578 CopyDataToITensorHandle(inputHandle1.get(), input1.data());
2579 CopyDataToITensorHandle(inputHandle2.get(), input2.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002580
2581 workload->PostAllocationConfigure();
2582 workload->Execute();
2583
Sadik Armagan483c8112021-06-01 09:24:52 +01002584 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002585
Sadik Armagan483c8112021-06-01 09:24:52 +01002586 return LayerTestResult<uint8_t, 3>(actualOutput,
2587 expectedOutput,
2588 outputHandle->GetShape(),
2589 outputTensorInfo.GetShape());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002590}
2591
2592LayerTestResult<uint8_t, 3> ConcatUint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002593 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002594 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2595 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002596{
Jan Eilers8eb25602020-03-09 12:13:48 +00002597 IgnoreUnused(memoryManager);
Derek Lambertic374ff02019-12-10 21:57:35 +00002598
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002599 unsigned int outputWidth = 3;
2600 unsigned int outputHeight = 6;
2601 unsigned int outputChannels = 3;
2602
2603 unsigned int inputWidth1 = 3;
2604 unsigned int inputHeight1 = 6;
2605 unsigned int inputChannels1 = 2;
2606
2607 unsigned int inputWidth2 = 3;
2608 unsigned int inputHeight2 = 6;
2609 unsigned int inputChannels2 = 1;
2610
2611 // Defines the tensor descriptors.
Derek Lambertif90c56d2020-01-10 17:14:08 +00002612 TensorInfo outputTensorInfo({ outputChannels, outputHeight, outputWidth }, DataType::QAsymmU8);
2613 TensorInfo inputTensorInfo1({ inputChannels1, inputHeight1, inputWidth1 }, DataType::QAsymmU8);
2614 TensorInfo inputTensorInfo2({ inputChannels2, inputHeight2, inputWidth2 }, DataType::QAsymmU8);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002615
2616 // Arbitrary scale and offsets. They don't really matter as the Concat operator doesn't dequantize/quantize them.
2617 const float scale = 0.13497836f;
2618 const int32_t offset = -7;
2619
2620 outputTensorInfo.SetQuantizationScale(scale);
2621 outputTensorInfo.SetQuantizationOffset(offset);
2622 inputTensorInfo1.SetQuantizationScale(scale);
2623 inputTensorInfo1.SetQuantizationOffset(offset);
2624 inputTensorInfo2.SetQuantizationScale(scale);
2625 inputTensorInfo2.SetQuantizationOffset(offset);
2626
Sadik Armagan483c8112021-06-01 09:24:52 +01002627 std::vector<uint8_t> actualOutput(outputTensorInfo.GetNumElements());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002628
Sadik Armagan483c8112021-06-01 09:24:52 +01002629 std::vector<uint8_t> expectedOutput =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002630 {
2631 1, 2, 3,
2632 4, 5, 6,
2633 7, 8, 9,
2634 10, 11, 12,
2635 13, 14, 15,
2636 16, 17, 18,
2637
2638 19, 20, 21,
2639 22, 23, 24,
2640 25, 26, 27,
2641 28, 29, 30,
2642 31, 32, 33,
2643 34, 35, 36,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002644
Sadik Armagan483c8112021-06-01 09:24:52 +01002645 37, 38, 39,
2646 40, 41, 42,
2647 43, 44, 45,
2648 46, 47, 48,
2649 49, 50, 51,
2650 52, 53, 54
2651 };
2652
2653 std::vector<uint8_t> input1 =
2654 {
2655 1, 2, 3,
2656 4, 5, 6,
2657 7, 8, 9,
2658 10, 11, 12,
2659 13, 14, 15,
2660 16, 17, 18,
2661
2662 19, 20, 21,
2663 22, 23, 24,
2664 25, 26, 27,
2665 28, 29, 30,
2666 31, 32, 33,
2667 34, 35, 36
2668 };
2669
2670 std::vector<uint8_t> input2 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002671 {
2672 37, 38, 39,
2673 40, 41, 42,
2674 43, 44, 45,
2675 46, 47, 48,
2676 49, 50, 51,
Sadik Armagan483c8112021-06-01 09:24:52 +01002677 52, 53, 54
2678 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002679
2680 std::vector<unsigned int> wOrigin1 = { 0, 0, 0 }; //Extent of the window is defined by size of input[0].
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002681 ConcatQueueDescriptor::ViewOrigin window1(wOrigin1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002682
2683 std::vector<unsigned int> wOrigin2 = { 2, 0, 0 }; //Extent of the window is defined by size of input[1].
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002684 ConcatQueueDescriptor::ViewOrigin window2(wOrigin2);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002685
Keith Davisf500d6c2020-08-31 08:32:55 +01002686 std::unique_ptr<ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002687
2688 bool subTensorsSupported = workloadFactory.SupportsSubTensors();
2689
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002690 std::unique_ptr<ITensorHandle> inputHandle1 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002691 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +01002692 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo1.GetShape(), wOrigin1.data()) :
2693 tensorHandleFactory.CreateTensorHandle(inputTensorInfo1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002694
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002695 std::unique_ptr<ITensorHandle> inputHandle2 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002696 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +01002697 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo2.GetShape(), wOrigin2.data()) :
2698 tensorHandleFactory.CreateTensorHandle(inputTensorInfo2);
2699
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002700
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002701 ConcatQueueDescriptor data;
2702 WorkloadInfo info;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002703 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
2704 AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
2705 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
2706
2707 data.m_ViewOrigins.push_back(window1);
2708 data.m_ViewOrigins.push_back(window2);
2709
Teresa Charlin611c7fb2022-01-07 09:47:29 +00002710 std::unique_ptr<IWorkload> workload = workloadFactory.CreateWorkload(LayerType::Concat, data, info);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002711
2712 inputHandle1->Allocate();
2713 inputHandle2->Allocate();
2714 outputHandle->Allocate();
2715
Sadik Armagan483c8112021-06-01 09:24:52 +01002716 CopyDataToITensorHandle(inputHandle1.get(), input1.data());
2717 CopyDataToITensorHandle(inputHandle2.get(), input2.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002718
2719 workload->PostAllocationConfigure();
2720 workload->Execute();
2721
Sadik Armagan483c8112021-06-01 09:24:52 +01002722 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002723
Sadik Armagan483c8112021-06-01 09:24:52 +01002724 return LayerTestResult<uint8_t, 3>(actualOutput,
2725 expectedOutput,
2726 outputHandle->GetShape(),
2727 outputTensorInfo.GetShape());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002728}
2729
2730LayerTestResult<uint16_t, 3> ConcatUint16Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002731 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002732 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2733 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002734{
Jan Eilers8eb25602020-03-09 12:13:48 +00002735 IgnoreUnused(memoryManager);
Derek Lambertic374ff02019-12-10 21:57:35 +00002736
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002737 unsigned int outputWidth = 3;
2738 unsigned int outputHeight = 6;
2739 unsigned int outputChannels = 3;
2740
2741 unsigned int inputWidth1 = 3;
2742 unsigned int inputHeight1 = 6;
2743 unsigned int inputChannels1 = 2;
2744
2745 unsigned int inputWidth2 = 3;
2746 unsigned int inputHeight2 = 6;
2747 unsigned int inputChannels2 = 1;
2748
2749 // Defines the tensor descriptors.
Derek Lambertif90c56d2020-01-10 17:14:08 +00002750 TensorInfo outputTensorInfo({ outputChannels, outputHeight, outputWidth }, DataType::QSymmS16);
2751 TensorInfo inputTensorInfo1({ inputChannels1, inputHeight1, inputWidth1 }, DataType::QSymmS16);
2752 TensorInfo inputTensorInfo2({ inputChannels2, inputHeight2, inputWidth2 }, DataType::QSymmS16);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002753
2754 // Arbitrary scale and offsets. They don't really matter as the Concat operator doesn't dequantize/quantize them.
2755 const float scale = 0.13497836f;
2756 const int32_t offset = -7;
2757
2758 outputTensorInfo.SetQuantizationScale(scale);
2759 outputTensorInfo.SetQuantizationOffset(offset);
2760 inputTensorInfo1.SetQuantizationScale(scale);
2761 inputTensorInfo1.SetQuantizationOffset(offset);
2762 inputTensorInfo2.SetQuantizationScale(scale);
2763 inputTensorInfo2.SetQuantizationOffset(offset);
2764
Sadik Armagan483c8112021-06-01 09:24:52 +01002765 std::vector<uint16_t> actualOutput(outputTensorInfo.GetNumElements());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002766
Sadik Armagan483c8112021-06-01 09:24:52 +01002767 std::vector<uint16_t> expectedOutput =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002768 {
2769 1, 2, 3,
2770 4, 5, 6,
2771 7, 8, 9,
2772 10, 11, 12,
2773 13, 14, 15,
2774 16, 17, 18,
2775
2776 19, 20, 21,
2777 22, 23, 24,
2778 25, 26, 27,
2779 28, 29, 30,
2780 31, 32, 33,
2781 34, 35, 36,
2782
2783 37, 38, 39,
2784 40, 41, 42,
2785 43, 44, 45,
2786 46, 47, 48,
2787 49, 50, 51,
Sadik Armagan483c8112021-06-01 09:24:52 +01002788 52, 53, 54
2789 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002790
Sadik Armagan483c8112021-06-01 09:24:52 +01002791 std::vector<uint16_t> input1 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002792 {
2793 1, 2, 3,
2794 4, 5, 6,
2795 7, 8, 9,
2796 10, 11, 12,
2797 13, 14, 15,
2798 16, 17, 18,
2799
2800 19, 20, 21,
2801 22, 23, 24,
2802 25, 26, 27,
2803 28, 29, 30,
2804 31, 32, 33,
2805 34, 35, 36,
Sadik Armagan483c8112021-06-01 09:24:52 +01002806 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002807
Sadik Armagan483c8112021-06-01 09:24:52 +01002808 std::vector<uint16_t> input2 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002809 {
2810 37, 38, 39,
2811 40, 41, 42,
2812 43, 44, 45,
2813 46, 47, 48,
2814 49, 50, 51,
2815 52, 53, 54,
Sadik Armagan483c8112021-06-01 09:24:52 +01002816 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002817
2818 std::vector<unsigned int> wOrigin1 = { 0, 0, 0 }; //Extent of the window is defined by size of input[0].
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002819 ConcatQueueDescriptor::ViewOrigin window1(wOrigin1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002820
2821 std::vector<unsigned int> wOrigin2 = { 2, 0, 0 }; //Extent of the window is defined by size of input[1].
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002822 ConcatQueueDescriptor::ViewOrigin window2(wOrigin2);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002823
Keith Davisf500d6c2020-08-31 08:32:55 +01002824
2825 std::unique_ptr<ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002826
2827 bool subTensorsSupported = workloadFactory.SupportsSubTensors();
2828
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002829 std::unique_ptr<ITensorHandle> inputHandle1 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002830 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +01002831 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo1.GetShape(), wOrigin1.data()) :
2832 tensorHandleFactory.CreateTensorHandle(inputTensorInfo1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002833
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002834 std::unique_ptr<ITensorHandle> inputHandle2 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002835 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +01002836 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo2.GetShape(), wOrigin2.data()) :
2837 tensorHandleFactory.CreateTensorHandle(inputTensorInfo2);
2838
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002839
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002840 ConcatQueueDescriptor data;
2841 WorkloadInfo info;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002842 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
2843 AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
2844 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
2845
2846 data.m_ViewOrigins.push_back(window1);
2847 data.m_ViewOrigins.push_back(window2);
2848
Teresa Charlin611c7fb2022-01-07 09:47:29 +00002849 std::unique_ptr<IWorkload> workload = workloadFactory.CreateWorkload(LayerType::Concat, data, info);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002850
2851 inputHandle1->Allocate();
2852 inputHandle2->Allocate();
2853 outputHandle->Allocate();
2854
Sadik Armagan483c8112021-06-01 09:24:52 +01002855 CopyDataToITensorHandle(inputHandle1.get(), input1.data());
2856 CopyDataToITensorHandle(inputHandle2.get(), input2.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002857
2858 workload->PostAllocationConfigure();
2859 workload->Execute();
2860
Sadik Armagan483c8112021-06-01 09:24:52 +01002861 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002862
Sadik Armagan483c8112021-06-01 09:24:52 +01002863 return LayerTestResult<uint16_t, 3>(actualOutput,
2864 expectedOutput,
2865 outputHandle->GetShape(),
2866 outputTensorInfo.GetShape());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002867}
2868
2869LayerTestResult<uint8_t, 1> Concat1dUint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002870 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002871 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2872 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002873{
Keith Davisf500d6c2020-08-31 08:32:55 +01002874 return Concat1dTestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002875}
2876
2877LayerTestResult<uint8_t, 2> Concat2dDim0Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002878 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002879 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2880 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002881{
Keith Davisf500d6c2020-08-31 08:32:55 +01002882 return Concat2dDim0TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002883}
2884
2885LayerTestResult<uint8_t, 2> Concat2dDim1Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002886 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002887 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2888 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002889{
Keith Davisf500d6c2020-08-31 08:32:55 +01002890 return Concat2dDim1TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002891}
2892
2893LayerTestResult<uint8_t, 2> Concat2dDim0DiffInputDimsUint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002894 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002895 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2896 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002897{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002898 return Concat2dDim0DiffInputDimsTestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002899 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002900}
2901
2902LayerTestResult<uint8_t, 2> Concat2dDim1DiffInputDimsUint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002903 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002904 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2905 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002906{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002907 return Concat2dDim1DiffInputDimsTestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002908 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002909}
2910
2911LayerTestResult<uint8_t, 3> Concat3dDim0Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002912 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002913 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2914 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002915{
Keith Davisf500d6c2020-08-31 08:32:55 +01002916 return Concat3dDim0TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002917}
2918
2919LayerTestResult<uint8_t, 3> Concat3dDim1Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002920 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002921 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2922 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002923{
Keith Davisf500d6c2020-08-31 08:32:55 +01002924 return Concat3dDim1TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002925}
2926
2927LayerTestResult<uint8_t, 3> Concat3dDim2Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002928 IWorkloadFactory& workloadFactory,
2929 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002930 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002931 bool useSubtensor)
2932{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002933 return Concat3dDim2TestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002934 workloadFactory, memoryManager, tensorHandleFactory, useSubtensor, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002935}
2936
2937LayerTestResult<uint8_t, 3> Concat3dDim0DiffInputDimsUint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002938 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002939 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2940 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002941{
Keith Davisf500d6c2020-08-31 08:32:55 +01002942 return Concat3dDim0TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002943}
2944
2945LayerTestResult<uint8_t, 3> Concat3dDim1DiffInputDimsUint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002946 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002947 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2948 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002949{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002950 return Concat3dDim1DiffInputDimsTestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002951 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002952}
2953
2954LayerTestResult<uint8_t, 3> Concat3dDim2DiffInputDimsUint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002955 IWorkloadFactory& workloadFactory,
2956 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002957 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002958 bool useSubtensor)
2959{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002960 return Concat3dDim2DiffInputDimsTestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002961 workloadFactory, memoryManager, tensorHandleFactory, useSubtensor, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002962}
2963
2964LayerTestResult<uint8_t, 4> Concat4dDim0Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002965 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002966 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2967 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002968{
Keith Davisf500d6c2020-08-31 08:32:55 +01002969 return Concat4dDim0TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002970}
2971
2972LayerTestResult<uint8_t, 4> Concat4dDim1Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002973 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002974 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2975 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002976{
Keith Davisf500d6c2020-08-31 08:32:55 +01002977 return Concat4dDim1TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002978}
2979
2980LayerTestResult<uint8_t, 4> Concat4dDim2Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002981 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002982 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2983 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002984{
Keith Davisf500d6c2020-08-31 08:32:55 +01002985 return Concat4dDim2TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002986}
2987
2988LayerTestResult<uint8_t, 4> Concat4dDim3Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002989 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002990 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2991 const armnn::ITensorHandleFactory& tensorHandleFactory, bool useSubtensor)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002992{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002993 return Concat4dDim3TestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002994 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1, useSubtensor);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002995}
2996
2997LayerTestResult<uint8_t, 4> Concat4dDiffShapeDim0Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002998 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002999 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
3000 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003001{
Derek Lambertif90c56d2020-01-10 17:14:08 +00003002 return Concat4dDiffShapeDim0TestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003003 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003004}
3005
3006LayerTestResult<uint8_t, 4> Concat4dDiffShapeDim1Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01003007 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01003008 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
3009 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003010{
Derek Lambertif90c56d2020-01-10 17:14:08 +00003011 return Concat4dDiffShapeDim1TestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003012 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003013}
3014
3015LayerTestResult<uint8_t, 4> Concat4dDiffShapeDim2Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01003016 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01003017 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
3018 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003019{
Derek Lambertif90c56d2020-01-10 17:14:08 +00003020 return Concat4dDiffShapeDim2TestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003021 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003022}
3023
3024LayerTestResult<uint8_t, 4> Concat4dDiffShapeDim3Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01003025 IWorkloadFactory& workloadFactory,
3026 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003027 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003028 bool useSubtensor)
3029{
Derek Lambertif90c56d2020-01-10 17:14:08 +00003030 return Concat4dDiffShapeDim3TestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003031 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1, useSubtensor);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003032}