blob: 88a392cf18066de528fd708235b3b6b030912820 [file] [log] [blame]
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001//
Teresa Charlinfbf0e5b2020-08-17 01:01:06 +01002// Copyright © 2017 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
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01008#include <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
Sadik Armagana097d2a2021-11-24 15:47:28 +000017#include <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 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +010064 ARMNN_ASSERT_MSG(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{
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +010095 ARMNN_ASSERT_MSG(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 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100116 ARMNN_ASSERT(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);
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100131 ARMNN_ASSERT_MSG(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);
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100185 ARMNN_ASSERT_MSG(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;
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100206 ARMNN_ASSERT_MSG(!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 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100211 ARMNN_ASSERT_MSG(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{
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100252 ARMNN_ASSERT_MSG(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{
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100289 ARMNN_ASSERT_MSG(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//
423
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100424template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100425LayerTestResult<T, 1> Concat1dTestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100426 IWorkloadFactory& workloadFactory,
427 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100428 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100429 float qScale,
430 int32_t qOffset)
431{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100432 TensorInfo inputTensorInfo({ 3 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100433
Sadik Armagan483c8112021-06-01 09:24:52 +0100434 auto input0 = QuantizedVector<T>({ 1.0f, 2.0f, 3.0f }, qScale, qOffset);
435 auto input1 = QuantizedVector<T>({ 4.0f, 5.0f, 6.0f }, qScale, qOffset);
436 auto input2 = QuantizedVector<T>({ 7.0f, 8.0f, 9.0f }, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100437
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100438 TensorInfo outputTensorInfo({ 9 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100439
440 LayerTestResult<T, 1> result(outputTensorInfo);
441
442 std::vector<T> output;
443 output.resize(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +0100444 Concatenate<T>(workloadFactory, memoryManager, tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100445 { inputTensorInfo, inputTensorInfo, inputTensorInfo },
446 { input0.data(), input1.data(), input2.data() },
447 outputTensorInfo,
448 output.data(),
449 0,
450 true);
451
Sadik Armagan483c8112021-06-01 09:24:52 +0100452 result.m_ActualData = output;
453 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100454 {
455 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f
456 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100457 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100458
459 return result;
460}
461
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100462template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100463LayerTestResult<T, 2> Concat2dTestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100464 IWorkloadFactory& workloadFactory,
465 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100466 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100467 const TensorInfo& outputTensorInfo,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100468 unsigned int dimension,
469 const float qScale,
470 const int32_t qOffset)
471{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100472 TensorInfo inputTensorInfo({ 2, 3 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100473
Sadik Armagan483c8112021-06-01 09:24:52 +0100474 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100475 {
476 // Batch 0
477 1.0f, 2.0f, 3.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100478
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100479 // Batch 1
480 10.0f, 11.0f, 12.0f,
481 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100482 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100483
Sadik Armagan483c8112021-06-01 09:24:52 +0100484 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100485 {
486 // Batch 0
487 4.0f, 5.0f, 6.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100488
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100489 // Batch 1
490 13.0f, 14.0f, 15.0f,
491 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100492 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100493
Sadik Armagan483c8112021-06-01 09:24:52 +0100494 auto input2 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100495 {
496 // Batch 0
497 7.0f, 8.0f, 9.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100498
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100499 // Batch 1
500 16.0f, 17.0f, 18.0f,
501 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100502 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100503
504 LayerTestResult<T, 2> result(outputTensorInfo);
505
506 std::vector<T> output;
507 output.resize(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +0100508 Concatenate<T>(workloadFactory, memoryManager, tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100509 { inputTensorInfo, inputTensorInfo, inputTensorInfo },
510 { input0.data(), input1.data(), input2.data() },
511 outputTensorInfo,
512 output.data(),
513 dimension,
514 true);
515
Sadik Armagan483c8112021-06-01 09:24:52 +0100516 result.m_ActualData = output;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100517 return result;
518}
519
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100520template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100521LayerTestResult<T, 2> Concat2dDim0TestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100522 IWorkloadFactory& workloadFactory,
523 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100524 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100525 float qScale,
526 int32_t qOffset)
527{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100528 TensorInfo outputTensorInfo({ 6, 3 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100529
530 LayerTestResult<T, 2> result = Concat2dTestImpl<ArmnnType>(
Keith Davisf500d6c2020-08-31 08:32:55 +0100531 workloadFactory, memoryManager, tensorHandleFactory, outputTensorInfo, 0, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100532
Sadik Armagan483c8112021-06-01 09:24:52 +0100533 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100534 {
535 // Batch 0
536 1.0f, 2.0f, 3.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100537
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100538 // Batch 1
539 10.0f, 11.0f, 12.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100540
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100541 // Batch 2
542 4.0f, 5.0f, 6.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100543
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100544 // Batch 3
545 13.0f, 14.0f, 15.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100546
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100547 // Batch 4
548 7.0f, 8.0f, 9.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100549
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100550 // Batch 5
551 16.0f, 17.0f, 18.0f,
552 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100553 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100554
555 return result;
556}
557
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100558template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100559LayerTestResult<T, 2> Concat2dDim1TestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100560 IWorkloadFactory& workloadFactory,
561 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100562 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100563 float qScale,
564 int32_t qOffset)
565{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100566 TensorInfo outputTensorInfo({ 2, 9 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100567
568 LayerTestResult<T, 2> result = Concat2dTestImpl<ArmnnType>(
Keith Davisf500d6c2020-08-31 08:32:55 +0100569 workloadFactory, memoryManager, tensorHandleFactory, outputTensorInfo, 1, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100570
Sadik Armagan483c8112021-06-01 09:24:52 +0100571 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100572 {
573 // Batch 0
574 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 +0100575
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100576 // Batch 1
577 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f
578 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100579 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100580
581 return result;
582}
583
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100584template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100585LayerTestResult<T, 2> Concat2dDim0DiffInputDimsTestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100586 IWorkloadFactory& workloadFactory,
587 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100588 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100589 float qScale,
590 int32_t qOffset)
591{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100592 TensorInfo input0TensorInfo({ 2, 3 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +0100593 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100594 {
595 // Batch 0
596 1.0f, 2.0f, 3.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100597
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100598 // Batch 1
599 10.0f, 11.0f, 12.0f,
600 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100601 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100602
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100603 TensorInfo input1TensorInfo({ 3, 3 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +0100604 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100605 {
606 // Batch 0
607 4.0f, 5.0f, 6.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100608
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100609 // Batch 1
610 13.0f, 14.0f, 15.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100611
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100612 // Batch 0
613 7.0f, 8.0f, 9.0f,
614 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100615 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100616
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100617 TensorInfo input2TensorInfo({ 1, 3 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +0100618 auto input2 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100619 {
620 // Batch 1
621 16.0f, 17.0f, 18.0f,
622 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100623 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100624
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100625 TensorInfo outputTensorInfo({ 6, 3 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100626 LayerTestResult<T, 2> result(outputTensorInfo);
627
628 std::vector<T> output;
629 output.resize(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +0100630 Concatenate<T>(workloadFactory, memoryManager, tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100631 { input0TensorInfo, input1TensorInfo, input2TensorInfo },
632 { input0.data(), input1.data(), input2.data() },
633 outputTensorInfo,
634 output.data(),
635 0,
636 true);
637
Sadik Armagan483c8112021-06-01 09:24:52 +0100638 result.m_ActualData = output;
639 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100640 {
641 // Batch 0
642 1.0f, 2.0f, 3.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100643
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100644 // Batch 1
645 10.0f, 11.0f, 12.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100646
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100647 // Batch 2
648 4.0f, 5.0f, 6.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100649
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100650 // Batch 3
651 13.0f, 14.0f, 15.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100652
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100653 // Batch 4
654 7.0f, 8.0f, 9.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100655
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100656 // Batch 5
657 16.0f, 17.0f, 18.0f,
658 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100659 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100660
661 return result;
662}
663
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100664template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100665LayerTestResult<T, 2> Concat2dDim1DiffInputDimsTestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100666 IWorkloadFactory& workloadFactory,
667 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100668 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100669 float qScale,
670 int32_t qOffset)
671{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100672 TensorInfo input0TensorInfo({ 2, 3 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +0100673 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100674 {
675 // Batch 0
676 1.0f, 2.0f, 3.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100677
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100678 // Batch 1
679 10.0f, 11.0f, 12.0f,
680 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100681 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100682
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100683 TensorInfo input1TensorInfo({ 2, 5 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +0100684 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100685 {
686 // Batch 0
687 4.0f, 5.0f, 6.0f, 7.0f, 8.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100688
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100689 // Batch 1
690 13.0f, 14.0f, 15.0f, 16.0f, 17.0f,
691 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100692 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100693
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100694 TensorInfo input2TensorInfo({ 2, 1 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +0100695 auto input2 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100696 {
697 // Batch 0
698 9.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100699
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100700 // Batch 1
701 18.0f
702 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100703 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100704
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100705 TensorInfo outputTensorInfo({ 2, 9 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100706 LayerTestResult<T, 2> result(outputTensorInfo);
707
708 std::vector<T> output;
709 output.resize(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +0100710 Concatenate<T>(workloadFactory, memoryManager, tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100711 { input0TensorInfo, input1TensorInfo, input2TensorInfo },
712 { input0.data(), input1.data(), input2.data() },
713 outputTensorInfo,
714 output.data(),
715 1,
716 true);
717
Sadik Armagan483c8112021-06-01 09:24:52 +0100718 result.m_ActualData = output;
719 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100720 {
721 // Batch 0
722 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 +0100723
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100724 // Batch 1
725 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f,
726 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100727 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100728
729 return result;
730}
731
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100732template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100733LayerTestResult<T, 3> Concat3dTestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100734 IWorkloadFactory& workloadFactory,
735 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100736 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100737 const TensorInfo& outputTensorInfo,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100738 unsigned int dimension,
739 bool useSubtensor,
740 float qScale,
741 int32_t qOffset)
742{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100743 TensorInfo inputTensorInfo({ 2, 3, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100744
Sadik Armagan483c8112021-06-01 09:24:52 +0100745 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100746 {
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100747 // Batch 0, Channel 0
748 1.0f, 2.0f,
749
750 // Batch 0, Channel 1
751 3.0f, 4.0f,
752
753 // Batch 0, Channel 2
754 5.0f, 6.0f,
755
756 // Batch 1, Channel 0
757 19.0f, 20.0f,
758
759 // Batch 1, Channel 1
760 21.0f, 22.0f,
761
762 // Batch 1, Channel 2
763 23.0f, 24.0f
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100764 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100765 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100766
Sadik Armagan483c8112021-06-01 09:24:52 +0100767 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100768 {
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100769 // Batch 0, Channel 0
770 7.0f, 8.0f,
771
772 // Batch 0, Channel 1
773 9.0f, 10.0f,
774
775 // Batch 0, Channel 2
776 11.0f, 12.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100777
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100778 // Batch 1, Channel 0
779 25.0f, 26.0f,
780
781 // Batch 1, Channel 1
782 27.0f, 28.0f,
783
784 // Batch 1, Channel 2
785 29.0f, 30.0f
786 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100787 qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100788
Sadik Armagan483c8112021-06-01 09:24:52 +0100789 auto input2 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100790 {
791 // Batch 0, Channel 0
792 13.0f, 14.0f,
793
794 // Batch 0, Channel 1
795 15.0f, 16.0f,
796
797 // Batch 0, Channel 2
798 17.0f, 18.0f,
799
800 // Batch 1, Channel 0
801 31.0f, 32.0f,
802
803 // Batch 1, Channel 1
804 33.0f, 34.0f,
805
806 // Batch 1, Channel 2
807 35.0f, 36.0f
808 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100809 qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100810
811 LayerTestResult<T, 3> result(outputTensorInfo);
812
813 std::vector<T> output;
814 output.resize(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +0100815 Concatenate<T>(workloadFactory, memoryManager, tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100816 { inputTensorInfo, inputTensorInfo, inputTensorInfo },
817 { input0.data(), input1.data(), input2.data() },
818 outputTensorInfo,
819 output.data(),
820 dimension,
821 useSubtensor);
822
Sadik Armagan483c8112021-06-01 09:24:52 +0100823 result.m_ActualData = output;
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100824 return result;
825}
826
827template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
828LayerTestResult<T, 3> Concat3dDim0TestImpl(
829 IWorkloadFactory& workloadFactory,
830 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100831 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100832 float qScale,
833 int32_t qOffset)
834{
835 TensorInfo outputTensorInfo({ 6, 3, 2 }, ArmnnType, qScale, qOffset);
836
837 LayerTestResult<T, 3> result = Concat3dTestImpl<ArmnnType>(
Keith Davisf500d6c2020-08-31 08:32:55 +0100838 workloadFactory, memoryManager, tensorHandleFactory, outputTensorInfo, 0, true, qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100839
Sadik Armagan483c8112021-06-01 09:24:52 +0100840 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100841 {
842 // Batch 0, Channel 0
843 1.0f, 2.0f,
844
845 // Batch 0, Channel 1
846 3.0f, 4.0f,
847
848 // Batch 0, Channel 2
849 5.0f, 6.0f,
850
851 // Batch 1, Channel 0
852 19.0f, 20.0f,
853
854 // Batch 1, Channel 1
855 21.0f, 22.0f,
856
857 // Batch 1, Channel 2
858 23.0f, 24.0f,
859
860 // Batch 2, Channel 0
861 7.0f, 8.0f,
862
863 // Batch 2, Channel 1
864 9.0f, 10.0f,
865
866 // Batch 2, Channel 2
867 11.0f, 12.0f,
868
869 // Batch 3, Channel 0
870 25.0f, 26.0f,
871
872 // Batch 3, Channel 1
873 27.0f, 28.0f,
874
875 // Batch 3, Channel 2
876 29.0f, 30.0f,
877
878 // Batch 4, Channel 0
879 13.0f, 14.0f,
880
881 // Batch 4, Channel 1
882 15.0f, 16.0f,
883
884 // Batch 4, Channel 2
885 17.0f, 18.0f,
886
887 // Batch 5, Channel 0
888 31.0f, 32.0f,
889
890 // Batch 5, Channel 1
891 33.0f, 34.0f,
892
893 // Batch 5, Channel 2
894 35.0f, 36.0f
895 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100896 qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100897
898 return result;
899}
900
901template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
902LayerTestResult<T, 3> Concat3dDim1TestImpl(
903 IWorkloadFactory& workloadFactory,
904 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100905 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100906 float qScale,
907 int32_t qOffset)
908{
909 TensorInfo outputTensorInfo({ 2, 9, 2 }, ArmnnType, qScale, qOffset);
910
911 LayerTestResult<T, 3> result = Concat3dTestImpl<ArmnnType>(
Keith Davisf500d6c2020-08-31 08:32:55 +0100912 workloadFactory, memoryManager, tensorHandleFactory, outputTensorInfo, 1, true, qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100913
Sadik Armagan483c8112021-06-01 09:24:52 +0100914 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100915 {
916 // Batch 0, Channel 0
917 1.0f, 2.0f,
918
919 // Batch 0, Channel 1
920 3.0f, 4.0f,
921
922 // Batch 0, Channel 2
923 5.0f, 6.0f,
924
925 // Batch 0, Channel 3
926 7.0f, 8.0f,
927
928 // Batch 0, Channel 4
929 9.0f, 10.0f,
930
931 // Batch 0, Channel 5
932 11.0f, 12.0f,
933
934 // Batch 0, Channel 6
935 13.0f, 14.0f,
936
937 // Batch 0, Channel 7
938 15.0f, 16.0f,
939
940 // Batch 0, Channel 8
941 17.0f, 18.0f,
942
943 // Batch 1, Channel 0
944 19.0f, 20.0f,
945
946 // Batch 1, Channel 1
947 21.0f, 22.0f,
948
949 // Batch 1, Channel 2
950 23.0f, 24.0f,
951
952 // Batch 1, Channel 3
953 25.0f, 26.0f,
954
955 // Batch 1, Channel 4
956 27.0f, 28.0f,
957
958 // Batch 1, Channel 5
959 29.0f, 30.0f,
960
961 // Batch 1, Channel 6
962 31.0f, 32.0f,
963
964 // Batch 1, Channel 7
965 33.0f, 34.0f,
966
967 // Batch 1, Channel 8
968 35.0f, 36.0f
969 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100970 qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100971
972 return result;
973}
974
975template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
976LayerTestResult<T, 3> Concat3dDim2TestImpl(
977 IWorkloadFactory& workloadFactory,
978 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100979 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100980 bool useSubtensor,
981 float qScale,
982 int32_t qOffset)
983{
984 TensorInfo outputTensorInfo({ 2, 3, 6 }, ArmnnType, qScale, qOffset);
985
986 LayerTestResult<T, 3> result = Concat3dTestImpl<ArmnnType>(
Keith Davisf500d6c2020-08-31 08:32:55 +0100987 workloadFactory, memoryManager, tensorHandleFactory, outputTensorInfo, 2, useSubtensor, qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100988
Sadik Armagan483c8112021-06-01 09:24:52 +0100989 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100990 {
991 // Batch 0, Channel 0
992 1.0f, 2.0f, 7.0f, 8.0f, 13.0f, 14.0f,
993
994 // Batch 0, Channel 1
995 3.0f, 4.0f, 9.0f, 10.0f, 15.0f, 16.0f,
996
997 // Batch 0, Channel 2
998 5.0f, 6.0f, 11.0f, 12.0f, 17.0f, 18.0f,
999
1000 // Batch 1, Channel 0
1001 19.0f, 20.0f, 25.0f, 26.0f, 31.0f, 32.0f,
1002
1003 // Batch 1, Channel 1
1004 21.0f, 22.0f, 27.0f, 28.0f, 33.0f, 34.0f,
1005
1006 // Batch 1, Channel 2
1007 23.0f, 24.0f, 29.0f, 30.0f, 35.0f, 36.0f,
1008 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001009 qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001010
1011 return result;
1012}
1013
1014template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
1015LayerTestResult<T, 3> Concat3dDim0DiffInputDimsTestImpl(
1016 IWorkloadFactory& workloadFactory,
1017 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001018 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001019 float qScale,
1020 int32_t qOffset)
1021{
1022 TensorInfo input0TensorInfo({ 2, 3, 2 }, ArmnnType);
Sadik Armagan483c8112021-06-01 09:24:52 +01001023 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001024 {
1025 // Batch 0, Channel 0
1026 1.0f, 2.0f,
1027
1028 // Batch 0, Channel 1
1029 3.0f, 4.0f,
1030
1031 // Batch 0, Channel 2
1032 5.0f, 6.0f,
1033
1034 // Batch 1, Channel 0
1035 19.0f, 20.0f,
1036
1037 // Batch 1, Channel 1
1038 21.0f, 22.0f,
1039
1040 // Batch 1, Channel 2
1041 23.0f, 24.0f
1042 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001043 qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001044
1045 TensorInfo input1TensorInfo({ 1, 3, 2 }, ArmnnType);
Sadik Armagan483c8112021-06-01 09:24:52 +01001046 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001047 {
1048 // Batch 0, Channel 0
1049 7.0f, 8.0f,
1050
1051 // Batch 0, Channel 1
1052 9.0f, 10.0f,
1053
1054 // Batch 0, Channel 2
1055 11.0f, 12.0f,
1056 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001057 qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001058
1059 TensorInfo input2TensorInfo({ 3, 3, 2 }, ArmnnType);
Sadik Armagan483c8112021-06-01 09:24:52 +01001060 auto input2 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001061 {
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001062 // Batch 0, Channel 0
1063 25.0f, 26.0f,
1064
1065 // Batch 0, Channel 1
1066 27.0f, 28.0f,
1067
1068 // Batch 0, Channel 2
1069 29.0f, 30.0f,
1070
1071 // Batch 1, Channel 0
1072 13.0f, 14.0f,
1073
1074 // Batch 1, Channel 1
1075 15.0f, 16.0f,
1076
1077 // Batch 1, Channel 2
1078 17.0f, 18.0f,
1079
1080 // Batch 2, Channel 0
1081 31.0f, 32.0f,
1082
1083 // Batch 2, Channel 1
1084 33.0f, 34.0f,
1085
1086 // Batch 2, Channel 2
1087 35.0f, 36.0f
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001088 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001089 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001090
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001091 TensorInfo outputTensorInfo({ 6, 3, 2 }, ArmnnType);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001092 LayerTestResult<T, 3> result(outputTensorInfo);
1093
1094 std::vector<T> output;
1095 output.resize(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +01001096 Concatenate<T>(workloadFactory, memoryManager, tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001097 { input0TensorInfo, input1TensorInfo, input2TensorInfo },
1098 { input0.data(), input1.data(), input2.data() },
1099 outputTensorInfo,
1100 output.data(),
1101 0,
1102 true);
1103
Sadik Armagan483c8112021-06-01 09:24:52 +01001104 result.m_ActualData = output;
1105 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001106 {
1107 // Batch 0, Channel 0
1108 1.0f, 2.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001109
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001110 // Batch 0, Channel 1
1111 3.0f, 4.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001112
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001113 // Batch 0, Channel 2
1114 5.0f, 6.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001115
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001116 // Batch 1, Channel 0
1117 19.0f, 20.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001118
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001119 // Batch 1, Channel 1
1120 21.0f, 22.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001121
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001122 // Batch 1, Channel 2
1123 23.0f, 24.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001124
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001125 // Batch 2, Channel 0
1126 7.0f, 8.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001127
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001128 // Batch 2, Channel 1
1129 9.0f, 10.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001130
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001131 // Batch 2, Channel 2
1132 11.0f, 12.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001133
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001134 // Batch 3, Channel 0
1135 25.0f, 26.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001136
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001137 // Batch 3, Channel 1
1138 27.0f, 28.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001139
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001140 // Batch 3, Channel 2
1141 29.0f, 30.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001142
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001143 // Batch 4, Channel 0
1144 13.0f, 14.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001145
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001146 // Batch 4, Channel 1
1147 15.0f, 16.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001148
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001149 // Batch 4, Channel 2
1150 17.0f, 18.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001151
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001152 // Batch 5, Channel 0
1153 31.0f, 32.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001154
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001155 // Batch 5, Channel 1
1156 33.0f, 34.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001157
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001158 // Batch 5, Channel 2
1159 35.0f, 36.0f
1160 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001161 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001162
1163 return result;
1164}
1165
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001166template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001167LayerTestResult<T, 3> Concat3dDim1DiffInputDimsTestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001168 IWorkloadFactory& workloadFactory,
1169 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001170 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001171 float qScale,
1172 int32_t qOffset)
1173{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001174 TensorInfo input0TensorInfo({ 2, 3, 2 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001175 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001176 {
1177 // Batch 0, Channel 0
1178 1.0f, 2.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001179
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001180 // Batch 0, Channel 1
1181 3.0f, 4.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001182
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001183 // Batch 0, Channel 2
1184 5.0f, 6.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001185
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001186 // Batch 1, Channel 0
1187 19.0f, 20.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001188
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001189 // Batch 1, Channel 1
1190 21.0f, 22.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001191
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001192 // Batch 1, Channel 2
1193 23.0f, 24.0f
1194 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001195 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001196
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001197 TensorInfo input1TensorInfo({ 2, 4, 2 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001198 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001199 {
1200 // Batch 0, Channel 0
1201 7.0f, 8.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001202
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001203 // Batch 0, Channel 1
1204 9.0f, 10.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001205
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001206 // Batch 0, Channel 2
1207 11.0f, 12.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001208
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001209 // Batch 0, Channel 3
1210 25.0f, 26.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001211
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001212 // Batch 1, Channel 0
1213 27.0f, 28.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001214
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001215 // Batch 1, Channel 1
1216 29.0f, 30.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001217
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001218 // Batch 1, Channel 2
1219 13.0f, 14.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001220
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001221 // Batch 1, Channel 3
1222 15.0f, 16.0f,
1223 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001224 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001225
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001226 TensorInfo input2TensorInfo({ 2, 1, 2 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001227 auto input2 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001228 {
1229 // Batch 0, Channel 0
1230 17.0f, 18.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001231
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001232 // Batch 1, Channel 0
1233 31.0f, 32.0f,
1234 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001235 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001236
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001237 TensorInfo outputTensorInfo({ 2, 8, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001238 LayerTestResult<T, 3> result(outputTensorInfo);
1239
1240 std::vector<T> output;
1241 output.resize(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +01001242 Concatenate<T>(workloadFactory, memoryManager, tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001243 { input0TensorInfo, input1TensorInfo, input2TensorInfo },
1244 { input0.data(), input1.data(), input2.data() },
1245 outputTensorInfo,
1246 output.data(),
1247 1,
1248 true);
1249
Sadik Armagan483c8112021-06-01 09:24:52 +01001250 result.m_ActualData = output;
1251 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001252 {
1253 // Batch 0, Channel 0
1254 1.0f, 2.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001255
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001256 // Batch 0, Channel 1
1257 3.0f, 4.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001258
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001259 // Batch 0, Channel 2
1260 5.0f, 6.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001261
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001262 // Batch 0, Channel 3
1263 7.0f, 8.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001264
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001265 // Batch 0, Channel 4
1266 9.0f, 10.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001267
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001268 // Batch 0, Channel 5
1269 11.0f, 12.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001270
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001271 // Batch 0, Channel 6
1272 25.0f, 26.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001273
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001274 // Batch 0, Channel 7
1275 17.0f, 18.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001276
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001277 // Batch 1, Channel 0
1278 19.0f, 20.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001279
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001280 // Batch 1, Channel 1
1281 21.0f, 22.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001282
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001283 // Batch 1, Channel 2
1284 23.0f, 24.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001285
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001286 // Batch 1, Channel 3
1287 27.0f, 28.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001288
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001289 // Batch 1, Channel 4
1290 29.0f, 30.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001291
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001292 // Batch 1, Channel 5
1293 13.0f, 14.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001294
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001295 // Batch 1, Channel 6
1296 15.0f, 16.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001297
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001298 // Batch 1, Channel 7
1299 31.0f, 32.0f,
1300 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001301 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001302
1303 return result;
1304}
1305
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001306template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001307LayerTestResult<T, 3> Concat3dDim2DiffInputDimsTestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001308 IWorkloadFactory& workloadFactory,
1309 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001310 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001311 bool useSubtensor,
1312 float qScale,
1313 int32_t qOffset)
1314{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001315 TensorInfo input0TensorInfo({ 2, 3, 2 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001316 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001317 {
1318 // Batch 0, Channel 0
1319 1.0f, 2.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001320
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001321 // Batch 0, Channel 1
1322 3.0f, 4.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001323
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001324 // Batch 0, Channel 2
1325 5.0f, 6.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001326
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001327 // Batch 1, Channel 0
1328 19.0f, 20.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001329
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001330 // Batch 1, Channel 1
1331 21.0f, 22.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001332
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001333 // Batch 1, Channel 2
1334 23.0f, 24.0f
1335 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001336 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001337
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001338 TensorInfo input1TensorInfo({ 2, 3, 1 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001339 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001340 {
1341 // Batch 0, Channel 0
1342 7.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001343
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001344 // Batch 0, Channel 1
1345 9.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001346
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001347 // Batch 0, Channel 2
1348 11.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001349
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001350 // Batch 1, Channel 0
1351 25.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001352
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001353 // Batch 1, Channel 1
1354 27.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001355
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001356 // Batch 1, Channel 2
1357 29.0f
1358 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001359 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001360
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001361 TensorInfo input2TensorInfo({ 2, 3, 3 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001362 auto input2 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001363 {
1364 // Batch 0, Channel 0
1365 13.0f, 14.0f, 50.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001366
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001367 // Batch 0, Channel 1
1368 15.0f, 16.0f, 51.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001369
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001370 // Batch 0, Channel 2
1371 17.0f, 18.0f, 52.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001372
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001373 // Batch 1, Channel 0
1374 31.0f, 32.0f, 53.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001375
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001376 // Batch 1, Channel 1
1377 33.0f, 34.0f, 54.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001378
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001379 // Batch 1, Channel 2
1380 35.0f, 36.0f, 55.0f,
1381 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001382 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001383
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001384 TensorInfo outputTensorInfo({ 2, 3, 6 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001385 LayerTestResult<T, 3> result(outputTensorInfo);
1386
1387 std::vector<T> output;
1388 output.resize(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +01001389 Concatenate<T>(workloadFactory, memoryManager, tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001390 { input0TensorInfo, input1TensorInfo, input2TensorInfo },
1391 { input0.data(), input1.data(), input2.data() },
1392 outputTensorInfo,
1393 output.data(),
1394 2,
1395 useSubtensor);
1396
Sadik Armagan483c8112021-06-01 09:24:52 +01001397 result.m_ActualData = output;
1398 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001399 {
1400 // Batch 0, Channel 0
1401 1.0f, 2.0f, 7.0f, 13.0f, 14.0f, 50.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001402
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001403 // Batch 0, Channel 1
1404 3.0f, 4.0f, 9.0f, 15.0f, 16.0f, 51.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001405
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001406 // Batch 0, Channel 2
1407 5.0f, 6.0f, 11.0f, 17.0f, 18.0f, 52.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001408
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001409 // Batch 1, Channel 0
1410 19.0f, 20.0f, 25.0f, 31.0f, 32.0f, 53.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001411
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001412 // Batch 1, Channel 1
1413 21.0f, 22.0f, 27.0f, 33.0f, 34.0f, 54.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001414
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001415 // Batch 1, Channel 2
1416 23.0f, 24.0f, 29.0f, 35.0f, 36.0f, 55.0f,
1417 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001418 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001419
1420 return result;
1421}
1422
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001423template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001424LayerTestResult<T, 4> Concat4dTestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001425 IWorkloadFactory& workloadFactory,
1426 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001427 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001428 const TensorInfo& outputTensorInfo,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001429 unsigned int dimension,
1430 bool useSubtensor,
1431 float qScale,
1432 int32_t qOffset)
1433{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001434 TensorInfo inputTensorInfo({ 1, 3, 2, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001435
Sadik Armagan483c8112021-06-01 09:24:52 +01001436 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001437 {
1438 1.0f, 2.0f,
1439 3.0f, 4.0f,
1440 5.0f, 6.0f,
1441 7.0f, 8.0f,
1442 9.0f, 10.0f,
1443 11.0f, 12.0f
1444 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001445 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001446
Sadik Armagan483c8112021-06-01 09:24:52 +01001447 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001448 {
1449 11.0f, 12.0f,
1450 13.0f, 14.0f,
1451 15.0f, 16.0f,
1452 17.0f, 18.0f,
1453 19.0f, 20.0f,
1454 21.0f, 22.0f
1455 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001456 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001457
Sadik Armagan483c8112021-06-01 09:24:52 +01001458 auto input2 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001459 {
1460 21.0f, 22.0f,
1461 23.0f, 24.0f,
1462 25.0f, 26.0f,
1463 27.0f, 28.0f,
1464 29.0f, 30.0f,
1465 31.0f, 32.0f
1466 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001467 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001468
1469 LayerTestResult<T, 4> result(outputTensorInfo);
1470
1471 std::vector<T> output;
1472 output.resize(outputTensorInfo.GetNumElements());
1473
1474 Concatenate<T>(workloadFactory,
1475 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001476 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001477 {inputTensorInfo, inputTensorInfo, inputTensorInfo},
1478 {input0.data(), input1.data(), input2.data()},
1479 outputTensorInfo,
1480 output.data(),
1481 dimension,
1482 useSubtensor);
1483
Sadik Armagan483c8112021-06-01 09:24:52 +01001484 result.m_ActualData = output;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001485 return result;
1486}
1487
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001488template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001489LayerTestResult<T, 4> Concat4dDim0TestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001490 IWorkloadFactory& workloadFactory,
1491 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001492 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001493 float qScale,
1494 int32_t qOffset)
1495{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001496 TensorInfo outputTensorInfo({ 3, 3, 2, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001497
1498 LayerTestResult<T, 4> result = Concat4dTestImpl<ArmnnType>(
Keith Davisf500d6c2020-08-31 08:32:55 +01001499 workloadFactory, memoryManager, tensorHandleFactory, outputTensorInfo, 0, true, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001500
Sadik Armagan483c8112021-06-01 09:24:52 +01001501 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001502 {
1503 1.0f, 2.0f,
1504 3.0f, 4.0f,
1505 5.0f, 6.0f,
1506 7.0f, 8.0f,
1507 9.0f, 10.0f,
1508 11.0f, 12.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001509
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001510 11.0f, 12.0f,
1511 13.0f, 14.0f,
1512 15.0f, 16.0f,
1513 17.0f, 18.0f,
1514 19.0f, 20.0f,
1515 21.0f, 22.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001516
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001517 21.0f, 22.0f,
1518 23.0f, 24.0f,
1519 25.0f, 26.0f,
1520 27.0f, 28.0f,
1521 29.0f, 30.0f,
1522 31.0f, 32.0f
1523 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001524 qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001525
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001526 return result;
1527}
1528
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001529template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001530LayerTestResult<T, 4> Concat4dDim1TestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001531 IWorkloadFactory& workloadFactory,
1532 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001533 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001534 float qScale,
1535 int32_t qOffset)
1536{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001537 TensorInfo outputTensorInfo({ 1, 9, 2, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001538
1539 LayerTestResult<T, 4> result = Concat4dTestImpl<ArmnnType>(
Keith Davisf500d6c2020-08-31 08:32:55 +01001540 workloadFactory, memoryManager, tensorHandleFactory, outputTensorInfo, 1, true, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001541
Sadik Armagan483c8112021-06-01 09:24:52 +01001542 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001543 {
1544 1.0f, 2.0f,
1545 3.0f, 4.0f,
1546 5.0f, 6.0f,
1547 7.0f, 8.0f,
1548 9.0f, 10.0f,
1549 11.0f, 12.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001550
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001551 11.0f, 12.0f,
1552 13.0f, 14.0f,
1553 15.0f, 16.0f,
1554 17.0f, 18.0f,
1555 19.0f, 20.0f,
1556 21.0f, 22.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001557
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001558 21.0f, 22.0f,
1559 23.0f, 24.0f,
1560 25.0f, 26.0f,
1561 27.0f, 28.0f,
1562 29.0f, 30.0f,
1563 31.0f, 32.0f
1564 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001565 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001566
1567 return result;
1568}
1569
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001570template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001571LayerTestResult<T, 4> Concat4dDim2TestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001572 IWorkloadFactory& workloadFactory,
1573 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001574 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001575 float qScale,
1576 int32_t qOffset)
1577{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001578 TensorInfo outputTensorInfo({ 1, 3, 6, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001579
1580 LayerTestResult<T, 4> result = Concat4dTestImpl<ArmnnType>(
Keith Davisf500d6c2020-08-31 08:32:55 +01001581 workloadFactory, memoryManager, tensorHandleFactory, outputTensorInfo, 2, true, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001582
Sadik Armagan483c8112021-06-01 09:24:52 +01001583 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001584 {
1585 1.0f, 2.0f,
1586 3.0f, 4.0f,
1587 11.0f, 12.0f,
1588 13.0f, 14.0f,
1589 21.0f, 22.0f,
1590 23.0f, 24.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001591
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001592 5.0f, 6.0f,
1593 7.0f, 8.0f,
1594 15.0f, 16.0f,
1595 17.0f, 18.0f,
1596 25.0f, 26.0f,
1597 27.0f, 28.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001598
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001599 9.0f, 10.0f,
1600 11.0f, 12.0f,
1601 19.0f, 20.0f,
1602 21.0f, 22.0f,
1603 29.0f, 30.0f,
1604 31.0f, 32.0f
1605 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001606 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001607
1608 return result;
1609}
1610
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001611template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001612LayerTestResult<T, 4> Concat4dDim3TestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001613 IWorkloadFactory& workloadFactory,
1614 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001615 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001616 float qScale,
1617 int32_t qOffset,
1618 bool useSubtensor)
1619{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001620 TensorInfo outputTensorInfo({ 1, 3, 2, 6 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001621
1622 LayerTestResult<T, 4> result = Concat4dTestImpl<ArmnnType>(
Keith Davisf500d6c2020-08-31 08:32:55 +01001623 workloadFactory, memoryManager, tensorHandleFactory, outputTensorInfo, 3, useSubtensor, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001624
Sadik Armagan483c8112021-06-01 09:24:52 +01001625 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001626 {
1627 1.0f, 2.0f,
1628 11.0f, 12.0f,
1629 21.0f, 22.0f,
1630 3.0f, 4.0f,
1631 13.0f, 14.0f,
1632 23.0f, 24.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001633
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001634 5.0f, 6.0f,
1635 15.0f, 16.0f,
1636 25.0f, 26.0f,
1637 7.0f, 8.0f,
1638 17.0f, 18.0f,
1639 27.0f, 28.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001640
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001641 9.0f, 10.0f,
1642 19.0f, 20.0f,
1643 29.0f, 30.0f,
1644 11.0f, 12.0f,
1645 21.0f, 22.0f,
1646 31.0f, 32.0f
1647 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001648 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001649
1650 return result;
1651}
1652
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001653template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001654LayerTestResult<T, 4> Concat4dDiffShapeDim0TestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001655 IWorkloadFactory& workloadFactory,
1656 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001657 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001658 float qScale,
1659 int32_t qOffset)
1660{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001661 constexpr unsigned int dimension = 0u;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001662
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001663 TensorInfo inputTensorInfo0({ 1, 3, 2, 2 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001664 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001665 {
1666 1.0f, 2.0f,
1667 3.0f, 4.0f,
1668 5.0f, 6.0f,
1669 7.0f, 8.0f,
1670 9.0f, 10.0f,
1671 11.0f, 12.0f
1672 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001673 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001674
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001675 TensorInfo inputTensorInfo1({ 2, 3, 2, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001676
Sadik Armagan483c8112021-06-01 09:24:52 +01001677 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001678 {
1679 11.0f, 12.0f,
1680 13.0f, 14.0f,
1681 15.0f, 16.0f,
1682 17.0f, 18.0f,
1683 19.0f, 20.0f,
1684 21.0f, 22.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001685
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001686 21.0f, 22.0f,
1687 23.0f, 24.0f,
1688 25.0f, 26.0f,
1689 27.0f, 28.0f,
1690 29.0f, 30.0f,
1691 31.0f, 32.0f
1692 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001693 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001694
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001695 TensorInfo outputTensorInfo({ 3, 3, 2, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001696
1697 LayerTestResult<T, 4> result(outputTensorInfo);
1698
1699 std::vector<T> output;
1700 output.resize(outputTensorInfo.GetNumElements());
1701 Concatenate<T>(workloadFactory,
1702 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001703 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001704 {inputTensorInfo0, inputTensorInfo1},
1705 {input0.data(), input1.data()},
1706 outputTensorInfo,
1707 output.data(),
1708 dimension,
1709 true);
1710
Sadik Armagan483c8112021-06-01 09:24:52 +01001711 result.m_ActualData = output;
1712 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001713 {
1714 1.0f, 2.0f,
1715 3.0f, 4.0f,
1716 5.0f, 6.0f,
1717 7.0f, 8.0f,
1718 9.0f, 10.0f,
1719 11.0f, 12.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001720
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001721 11.0f, 12.0f,
1722 13.0f, 14.0f,
1723 15.0f, 16.0f,
1724 17.0f, 18.0f,
1725 19.0f, 20.0f,
1726 21.0f, 22.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001727
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001728 21.0f, 22.0f,
1729 23.0f, 24.0f,
1730 25.0f, 26.0f,
1731 27.0f, 28.0f,
1732 29.0f, 30.0f,
1733 31.0f, 32.0f
1734 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001735 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001736
1737 return result;
1738}
1739
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001740template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001741LayerTestResult<T, 4> Concat4dDiffShapeDim1TestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001742 IWorkloadFactory& workloadFactory,
1743 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001744 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001745 float qScale,
1746 int32_t qOffset)
1747{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001748 constexpr unsigned int dimension = 1u;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001749
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001750 TensorInfo inputTensorInfo0({ 1, 3, 2, 2 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001751 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001752 {
1753 1.0f, 2.0f,
1754 3.0f, 4.0f,
1755 5.0f, 6.0f,
1756 7.0f, 8.0f,
1757 9.0f, 10.0f,
1758 11.0f, 12.0f
1759 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001760 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001761
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001762 TensorInfo inputTensorInfo1({ 1, 2, 2, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001763
Sadik Armagan483c8112021-06-01 09:24:52 +01001764 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001765 {
1766 11.0f, 12.0f,
1767 13.0f, 14.0f,
1768 15.0f, 16.0f,
1769 17.0f, 18.0f,
1770 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001771 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001772
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001773 TensorInfo outputTensorInfo({ 1, 5, 2, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001774
1775 LayerTestResult<T, 4> result(outputTensorInfo);
1776
1777 std::vector<T> output;
1778 output.resize(outputTensorInfo.GetNumElements());
1779 Concatenate<T>(workloadFactory,
1780 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001781 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001782 {inputTensorInfo0, inputTensorInfo1},
1783 {input0.data(), input1.data()},
1784 outputTensorInfo,
1785 output.data(),
1786 dimension,
1787 true);
1788
Sadik Armagan483c8112021-06-01 09:24:52 +01001789 result.m_ActualData = output;
1790 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001791 {
1792 1.0f, 2.0f,
1793 3.0f, 4.0f,
1794 5.0f, 6.0f,
1795 7.0f, 8.0f,
1796 9.0f, 10.0f,
1797 11.0f, 12.0f,
1798 11.0f, 12.0f,
1799 13.0f, 14.0f,
1800 15.0f, 16.0f,
1801 17.0f, 18.0f
1802 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001803 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001804
1805 return result;
1806}
1807
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001808template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001809LayerTestResult<T, 4> Concat4dDiffShapeDim2TestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001810 IWorkloadFactory& workloadFactory,
1811 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001812 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001813 float qScale,
1814 int32_t qOffset)
1815{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001816 constexpr unsigned int dimension = 2u;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001817
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001818 TensorInfo inputTensorInfo0({ 1, 3, 2, 2 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001819 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001820 {
1821 1.0f, 2.0f,
1822 3.0f, 4.0f,
1823 5.0f, 6.0f,
1824 7.0f, 8.0f,
1825 9.0f, 10.0f,
1826 11.0f, 12.0f
1827 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001828 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001829
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001830 TensorInfo inputTensorInfo1({ 1, 3, 3, 2 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001831 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001832 {
1833 11.0f, 12.0f,
1834 13.0f, 14.0f,
1835 15.0f, 16.0f,
1836 17.0f, 18.0f,
1837 19.0f, 20.0f,
1838 21.0f, 22.0f,
1839 23.0f, 24.0f,
1840 25.0f, 26.0f,
1841 27.0f, 28.0f
1842 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001843 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001844
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001845 TensorInfo outputTensorInfo({ 1, 3, 5, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001846 LayerTestResult<T, 4> result(outputTensorInfo);
1847
1848 std::vector<T> output;
1849 output.resize(outputTensorInfo.GetNumElements());
1850 Concatenate<T>(workloadFactory,
1851 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001852 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001853 {inputTensorInfo0, inputTensorInfo1},
1854 {input0.data(), input1.data()},
1855 outputTensorInfo,
1856 output.data(),
1857 dimension,
1858 true);
1859
Sadik Armagan483c8112021-06-01 09:24:52 +01001860 result.m_ActualData = output;
1861 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001862 {
1863 1.0f, 2.0f,
1864 3.0f, 4.0f,
1865 11.0f, 12.0f,
1866 13.0f, 14.0f,
1867 15.0f, 16.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001868
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001869 5.0f, 6.0f,
1870 7.0f, 8.0f,
1871 17.0f, 18.0f,
1872 19.0f, 20.0f,
1873 21.0f, 22.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001874
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001875 9.0f, 10.0f,
1876 11.0f, 12.0f,
1877 23.0f, 24.0f,
1878 25.0f, 26.0f,
1879 27.0f, 28.0f
1880 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001881 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001882
1883 return result;
1884}
1885
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001886template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001887LayerTestResult<T, 4> Concat4dDiffShapeDim3TestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001888 IWorkloadFactory& workloadFactory,
1889 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001890 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001891 float qScale,
1892 int32_t qOffset,
1893 bool useSubtensor)
1894{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001895 constexpr unsigned int dimension = 3u;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001896
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001897 TensorInfo inputTensorInfo0({ 1, 3, 2, 2 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001898 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001899 {
1900 1.0f, 2.0f,
1901 3.0f, 4.0f,
1902 5.0f, 6.0f,
1903 7.0f, 8.0f,
1904 9.0f, 10.0f,
1905 11.0f, 12.0f
1906 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001907 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001908
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001909 TensorInfo inputTensorInfo1({ 1, 3, 2, 3 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001910 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001911 {
1912 11.0f, 12.0f, 13.0f,
1913 14.0f, 15.0f, 16.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001914
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001915 17.0f, 18.0f, 19.0f,
1916 20.0f, 21.0f, 22.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001917
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001918 23.0f, 24.0f, 25.0f,
1919 26.0f, 27.0f, 28.0f
1920 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001921 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001922
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001923 TensorInfo outputTensorInfo({ 1, 3, 2, 5 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001924
1925 LayerTestResult<T, 4> result(outputTensorInfo);
1926
1927 std::vector<T> output;
1928 output.resize(outputTensorInfo.GetNumElements());
1929 Concatenate<T>(workloadFactory,
1930 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001931 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001932 {inputTensorInfo0, inputTensorInfo1},
1933 {input0.data(), input1.data()},
1934 outputTensorInfo,
1935 output.data(),
1936 dimension,
1937 useSubtensor);
1938
Sadik Armagan483c8112021-06-01 09:24:52 +01001939 result.m_ActualData = output;
1940 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001941 {
1942 1.0f, 2.0f, 11.0f, 12.0f, 13.0f,
1943 3.0f, 4.0f, 14.0f, 15.0f, 16.0f,
1944 5.0f, 6.0f, 17.0f, 18.0f, 19.0f,
1945 7.0f, 8.0f, 20.0f, 21.0f, 22.0f,
1946 9.0f, 10.0f, 23.0f, 24.0f, 25.0f,
1947 11.0f, 12.0f, 26.0f, 27.0f, 28.0f
1948 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001949 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001950
1951 return result;
1952}
1953
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001954template<DataType ArmnnType, typename T>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001955LayerTestResult<T, 3> ConcatDifferentInputOutputQParamTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001956 IWorkloadFactory& workloadFactory,
1957 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001958 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001959 bool useSubtensor)
1960{
Jan Eilers8eb25602020-03-09 12:13:48 +00001961 IgnoreUnused(memoryManager);
Derek Lambertic374ff02019-12-10 21:57:35 +00001962
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001963 // Defines the tensor descriptors.
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001964 TensorInfo outputTensorInfo({ 3, 6, 3 }, ArmnnType);
1965 TensorInfo inputTensorInfo1({ 3, 6, 2 }, ArmnnType);
1966 TensorInfo inputTensorInfo2({ 3, 6, 1 }, ArmnnType);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001967
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001968 std::vector<TensorShape> inputTensorShapes({inputTensorInfo1.GetShape(), inputTensorInfo2.GetShape()});
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001969
1970 // Quantized input1 tensor.
1971 const float inputScale1 = 0.5f;
1972 const int32_t inputOffset1 = 5;
1973
Sadik Armagan483c8112021-06-01 09:24:52 +01001974 std::vector<T> input1 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001975 {
1976 1, 2, 3,
1977 4, 5, 6,
1978 7, 8, 9,
1979 10, 11, 12,
1980 13, 14, 15,
1981 16, 17, 18,
1982
1983 19, 20, 21,
1984 22, 23, 24,
1985 25, 26, 27,
1986 28, 29, 30,
1987 31, 32, 33,
1988 34, 35, 36
Sadik Armagan483c8112021-06-01 09:24:52 +01001989 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001990
1991 // Quatized input2 tensor.
1992 const float inputScale2 = 0.2f;
1993 const int32_t inputOffset2 = 10;
1994
Sadik Armagan483c8112021-06-01 09:24:52 +01001995 std::vector<T> input2 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001996 {
1997 37, 38, 39,
1998 40, 41, 42,
1999 43, 44, 45,
2000 46, 47, 48,
2001 49, 50, 51,
2002 52, 53, 54
Sadik Armagan483c8112021-06-01 09:24:52 +01002003 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002004
2005 // Quantized output tensor.
2006 const float outputScale = 0.1f;
2007 const int32_t outputOffset = 20;
2008
Sadik Armagan483c8112021-06-01 09:24:52 +01002009 std::vector<T> actualOutput(outputTensorInfo.GetNumElements());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002010
Sadik Armagan483c8112021-06-01 09:24:52 +01002011 std::vector<T> expectedOutput =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002012 {
2013 0, 5, 74,
2014 10, 15, 76,
2015 20, 25, 78,
2016 30, 35, 80,
2017 40, 45, 82,
2018 50, 55, 84,
2019
2020 60, 65, 86,
2021 70, 75, 88,
2022 80, 85, 90,
2023 90, 95, 92,
2024 100, 105, 94,
2025 110, 115, 96,
2026
2027 120, 125, 98,
2028 130, 135, 100,
2029 140, 145, 102,
2030 150, 155, 104,
2031 160, 165, 106,
2032 170, 175, 108
Sadik Armagan483c8112021-06-01 09:24:52 +01002033 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002034
2035 outputTensorInfo.SetQuantizationScale(outputScale);
2036 outputTensorInfo.SetQuantizationOffset(outputOffset);
2037 inputTensorInfo1.SetQuantizationScale(inputScale1);
2038 inputTensorInfo1.SetQuantizationOffset(inputOffset1);
2039 inputTensorInfo2.SetQuantizationScale(inputScale2);
2040 inputTensorInfo2.SetQuantizationOffset(inputOffset2);
2041
2042 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 +01002043 ConcatQueueDescriptor::ViewOrigin window1(wOrigin1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002044
2045 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 +01002046 ConcatQueueDescriptor::ViewOrigin window2(wOrigin2);
Keith Davisf500d6c2020-08-31 08:32:55 +01002047
2048 std::unique_ptr<ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
2049
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002050 bool subTensorsSupported = useSubtensor && workloadFactory.SupportsSubTensors();
Keith Davisf500d6c2020-08-31 08:32:55 +01002051
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002052 std::unique_ptr<ITensorHandle> inputHandle1 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002053 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +01002054 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo1.GetShape(), wOrigin1.data()) :
2055 tensorHandleFactory.CreateTensorHandle(inputTensorInfo1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002056
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002057 std::unique_ptr<ITensorHandle> inputHandle2 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002058 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +01002059 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo2.GetShape(), wOrigin2.data()) :
2060 tensorHandleFactory.CreateTensorHandle(inputTensorInfo2);
2061
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002062 ConcatQueueDescriptor data;
2063 OriginsDescriptor desc = CreateDescriptorForConcatenation(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002064 inputTensorShapes.begin(),inputTensorShapes.end(), 2);
2065 data.m_Parameters = desc;
2066
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002067 WorkloadInfo info;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002068 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
2069 AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
2070 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
2071
2072 data.m_ViewOrigins.push_back(window1);
2073 data.m_ViewOrigins.push_back(window2);
2074
Teresa Charlin611c7fb2022-01-07 09:47:29 +00002075 std::unique_ptr<IWorkload> workload = workloadFactory.CreateWorkload(LayerType::Concat, data, info);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002076
2077 inputHandle1->Allocate();
2078 inputHandle2->Allocate();
2079 outputHandle->Allocate();
2080
Sadik Armagan483c8112021-06-01 09:24:52 +01002081 CopyDataToITensorHandle(inputHandle1.get(), input1.data());
2082 CopyDataToITensorHandle(inputHandle2.get(), input2.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002083
2084 workload->PostAllocationConfigure();
2085 workload->Execute();
2086
Sadik Armagan483c8112021-06-01 09:24:52 +01002087 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002088
Sadik Armagan483c8112021-06-01 09:24:52 +01002089 return LayerTestResult<T, 3>(actualOutput,
2090 expectedOutput,
2091 outputHandle->GetShape(),
2092 outputTensorInfo.GetShape());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002093}
2094
2095//
2096// Explicit template specializations
2097//
2098
Derek Lambertif90c56d2020-01-10 17:14:08 +00002099template LayerTestResult<ResolveType<DataType::QAsymmU8>, 3>
2100ConcatDifferentInputOutputQParamTest<DataType::QAsymmU8>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002101 IWorkloadFactory& workloadFactory,
2102 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002103 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002104 bool useSubtensor);
2105
Derek Lambertif90c56d2020-01-10 17:14:08 +00002106template LayerTestResult<ResolveType<DataType::QSymmS16>, 3>
2107ConcatDifferentInputOutputQParamTest<DataType::QSymmS16>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002108 IWorkloadFactory& workloadFactory,
2109 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002110 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002111 bool useSubtensor);
2112
2113//
2114// Implementation functions
2115//
2116
2117LayerTestResult<float,3> ConcatTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002118 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002119 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2120 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002121{
Jan Eilers8eb25602020-03-09 12:13:48 +00002122 IgnoreUnused(memoryManager);
Derek Lambertic374ff02019-12-10 21:57:35 +00002123
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002124 unsigned int outputWidth = 3;
2125 unsigned int outputHeight = 6;
2126 unsigned int outputChannels = 3;
2127
2128 unsigned int inputWidth1 = 3;
2129 unsigned int inputHeight1 = 6;
2130 unsigned int inputChannels1 = 2;
2131
2132 unsigned int inputWidth2 = 3;
2133 unsigned int inputHeight2 = 6;
2134 unsigned int inputChannels2 = 1;
2135
2136 // Define the tensor descriptors.
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002137 TensorInfo outputTensorInfo({ outputChannels, outputHeight, outputWidth }, DataType::Float32);
2138 TensorInfo inputTensorInfo1({ inputChannels1, inputHeight1, inputWidth1 }, DataType::Float32);
2139 TensorInfo inputTensorInfo2({ inputChannels2, inputHeight2, inputWidth2 }, DataType::Float32);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002140
Sadik Armagan483c8112021-06-01 09:24:52 +01002141 std::vector<float> actualOutput(outputTensorInfo.GetNumElements());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002142
Sadik Armagan483c8112021-06-01 09:24:52 +01002143 std::vector<float> expectedOutput =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002144 {
Sadik Armagan483c8112021-06-01 09:24:52 +01002145 1.0f, 2.0f, 3.0f,
2146 4.0f, 5.0f, 6.0f,
2147 7.0f, 8.0f, 9.0f,
2148 10.0f, 11.0f, 12.0f,
2149 13.0f, 14.0f, 15.0f,
2150 16.0f, 17.0f, 18.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002151
Sadik Armagan483c8112021-06-01 09:24:52 +01002152 19.0f, 20.0f, 21.0f,
2153 22.0f, 23.0f, 24.0f,
2154 25.0f, 26.0f, 27.0f,
2155 28.0f, 29.0f, 30.0f,
2156 31.0f, 32.0f, 33.0f,
2157 34.0f, 35.0f, 36.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002158
Sadik Armagan483c8112021-06-01 09:24:52 +01002159 37.0f, 38.0f, 39.0f,
2160 40.0f, 41.0f, 42.0f,
2161 43.0f, 44.0f, 45.0f,
2162 46.0f, 47.0f, 48.0f,
2163 49.0f, 50.0f, 51.0f,
2164 52.0f, 53.0f, 54.0f
2165 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002166
Sadik Armagan483c8112021-06-01 09:24:52 +01002167 std::vector<float> input1 =
2168 {
2169 1.0f, 2.0f, 3.0f,
2170 4.0f, 5.0f, 6.0f,
2171 7.0f, 8.0f, 9.0f,
2172 10.0f, 11.0f, 12.0f,
2173 13.0f, 14.0f, 15.0f,
2174 16.0f, 17.0f, 18.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002175
Sadik Armagan483c8112021-06-01 09:24:52 +01002176 19.0f, 20.0f, 21.0f,
2177 22.0f, 23.0f, 24.0f,
2178 25.0f, 26.0f, 27.0f,
2179 28.0f, 29.0f, 30.0f,
2180 31.0f, 32.0f, 33.0f,
2181 34.0f, 35.0f, 36.0f
2182 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002183
Sadik Armagan483c8112021-06-01 09:24:52 +01002184 std::vector<float> input2 =
2185 {
2186 37.0f, 38.0f, 39.0f,
2187 40.0f, 41.0f, 42.0f,
2188 43.0f, 44.0f, 45.0f,
2189 46.0f, 47.0f, 48.0f,
2190 49.0f, 50.0f, 51.0f,
2191 52.0f, 53.0f, 54.0f,
2192 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002193
2194 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 +01002195 ConcatQueueDescriptor::ViewOrigin window1(wOrigin1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002196
2197 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 +01002198 ConcatQueueDescriptor::ViewOrigin window2(wOrigin2);
Keith Davisf500d6c2020-08-31 08:32:55 +01002199
2200 std::unique_ptr<ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002201
2202 bool subTensorsSupported = workloadFactory.SupportsSubTensors();
2203
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002204 std::unique_ptr<ITensorHandle> inputHandle1 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002205 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +01002206 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo1.GetShape(), wOrigin1.data()) :
2207 tensorHandleFactory.CreateTensorHandle(inputTensorInfo1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002208
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002209 std::unique_ptr<ITensorHandle> inputHandle2 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002210 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +01002211 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo2.GetShape(), wOrigin2.data()) :
2212 tensorHandleFactory.CreateTensorHandle(inputTensorInfo2);
2213
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002214 ConcatQueueDescriptor data;
2215 WorkloadInfo info;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002216 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
2217 AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
2218 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
2219
2220 data.m_ViewOrigins.push_back(window1);
2221 data.m_ViewOrigins.push_back(window2);
2222
Teresa Charlin611c7fb2022-01-07 09:47:29 +00002223 std::unique_ptr<IWorkload> workload = workloadFactory.CreateWorkload(LayerType::Concat, data, info);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002224
2225 inputHandle1->Allocate();
2226 inputHandle2->Allocate();
2227 outputHandle->Allocate();
2228
Sadik Armagan483c8112021-06-01 09:24:52 +01002229 CopyDataToITensorHandle(inputHandle1.get(), input1.data());
2230 CopyDataToITensorHandle(inputHandle2.get(), input2.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002231
2232 workload->PostAllocationConfigure();
2233 workload->Execute();
2234
Sadik Armagan483c8112021-06-01 09:24:52 +01002235 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002236
Sadik Armagan483c8112021-06-01 09:24:52 +01002237 return LayerTestResult<float, 3>(actualOutput,
2238 expectedOutput,
2239 outputHandle->GetShape(),
2240 outputTensorInfo.GetShape());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002241}
2242
2243LayerTestResult<float, 1> Concat1dTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002244 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002245 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2246 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002247{
Keith Davisf500d6c2020-08-31 08:32:55 +01002248 return Concat1dTestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002249}
2250
2251LayerTestResult<float, 2> Concat2dDim0Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002252 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002253 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2254 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002255{
Keith Davisf500d6c2020-08-31 08:32:55 +01002256 return Concat2dDim0TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002257}
2258
2259LayerTestResult<float, 2> Concat2dDim1Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002260 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002261 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2262 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002263{
Keith Davisf500d6c2020-08-31 08:32:55 +01002264 return Concat2dDim1TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002265}
2266
2267LayerTestResult<float, 2> Concat2dDim0DiffInputDimsTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002268 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002269 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2270 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002271{
Keith Davisf500d6c2020-08-31 08:32:55 +01002272 return Concat2dDim0DiffInputDimsTestImpl<DataType::Float32>(workloadFactory, memoryManager,
2273 tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002274}
2275
2276LayerTestResult<float, 2> Concat2dDim1DiffInputDimsTest(
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 Concat2dDim1DiffInputDimsTestImpl<DataType::Float32>(workloadFactory,
2282 memoryManager,
2283 tensorHandleFactory,
2284 0.0f,
2285 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002286}
2287
2288LayerTestResult<float, 3> Concat3dDim0Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002289 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002290 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2291 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002292{
Keith Davisf500d6c2020-08-31 08:32:55 +01002293 return Concat3dDim0TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002294}
2295
2296LayerTestResult<float, 3> Concat3dDim1Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002297 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002298 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2299 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002300{
Keith Davisf500d6c2020-08-31 08:32:55 +01002301 return Concat3dDim1TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002302}
2303
2304LayerTestResult<float, 3> Concat3dDim2Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002305 IWorkloadFactory& workloadFactory,
2306 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002307 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002308 bool useSubtensor)
2309{
Keith Davisf500d6c2020-08-31 08:32:55 +01002310 return Concat3dDim2TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory,
2311 useSubtensor, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002312}
2313
2314LayerTestResult<float, 3> Concat3dDim0DiffInputDimsTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002315 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002316 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2317 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002318{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002319 return Concat3dDim0DiffInputDimsTestImpl<DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002320 workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002321}
2322
2323LayerTestResult<float, 3> Concat3dDim1DiffInputDimsTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002324 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002325 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2326 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002327{
Keith Davisf500d6c2020-08-31 08:32:55 +01002328 return Concat3dDim1DiffInputDimsTestImpl<DataType::Float32>(workloadFactory, memoryManager,
2329 tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002330}
2331
2332LayerTestResult<float, 3> Concat3dDim2DiffInputDimsTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002333 IWorkloadFactory& workloadFactory,
2334 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002335 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002336 bool useSubtensor)
2337{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002338 return Concat3dDim2DiffInputDimsTestImpl<DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002339 workloadFactory, memoryManager, tensorHandleFactory, useSubtensor, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002340}
2341
2342LayerTestResult<float, 4> Concat4dDim0Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002343 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002344 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2345 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002346{
Keith Davisf500d6c2020-08-31 08:32:55 +01002347 return Concat4dDim0TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002348}
2349
2350LayerTestResult<float, 4> Concat4dDim1Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002351 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002352 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2353 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002354{
Keith Davisf500d6c2020-08-31 08:32:55 +01002355 return Concat4dDim1TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002356}
2357
2358LayerTestResult<float, 4> Concat4dDim2Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002359 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002360 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2361 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002362{
Keith Davisf500d6c2020-08-31 08:32:55 +01002363 return Concat4dDim2TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002364}
2365
2366LayerTestResult<float, 4> Concat4dDim3Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002367 IWorkloadFactory& workloadFactory,
2368 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002369 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002370 bool useSubtensor)
2371{
Keith Davisf500d6c2020-08-31 08:32:55 +01002372 return Concat4dDim3TestImpl<DataType::Float32>(workloadFactory, memoryManager,
2373 tensorHandleFactory, 0.0f, 0, useSubtensor);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002374}
2375
2376LayerTestResult<float, 4> Concat4dDiffShapeDim0Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002377 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002378 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2379 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002380{
Keith Davisf500d6c2020-08-31 08:32:55 +01002381 return Concat4dDiffShapeDim0TestImpl<DataType::Float32>(workloadFactory, memoryManager,
2382 tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002383}
2384
2385LayerTestResult<float, 4> Concat4dDiffShapeDim1Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002386 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002387 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2388 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002389{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002390 return Concat4dDiffShapeDim1TestImpl<DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002391 workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002392}
2393
2394LayerTestResult<float, 4> Concat4dDiffShapeDim2Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002395 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002396 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2397 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002398{
Keith Davisf500d6c2020-08-31 08:32:55 +01002399 return Concat4dDiffShapeDim2TestImpl<DataType::Float32>(workloadFactory, memoryManager,
2400 tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002401}
2402
2403LayerTestResult<float, 4> Concat4dDiffShapeDim3Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002404 IWorkloadFactory& workloadFactory,
2405 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002406 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002407 bool useSubtensor)
2408{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002409 return Concat4dDiffShapeDim3TestImpl<DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002410 workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0, useSubtensor);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002411}
2412
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002413LayerTestResult<Half, 3> ConcatFloat16Test(
2414 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002415 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2416 const armnn::ITensorHandleFactory& tensorHandleFactory)
Matthew Jackson9bff1442019-09-12 09:08:23 +01002417{
Keith Davisf500d6c2020-08-31 08:32:55 +01002418 return Concat3dDim1TestImpl<DataType::Float16>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Matthew Jackson9bff1442019-09-12 09:08:23 +01002419}
2420
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00002421LayerTestResult<BFloat16, 3> ConcatBFloat16Test(
2422 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002423 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2424 const armnn::ITensorHandleFactory& tensorHandleFactory)
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00002425{
Keith Davisf500d6c2020-08-31 08:32:55 +01002426 return Concat3dDim1TestImpl<DataType::BFloat16>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00002427}
2428
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002429LayerTestResult<uint8_t, 3> ConcatUint8DifferentQParamsTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002430 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002431 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2432 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002433{
Jan Eilers8eb25602020-03-09 12:13:48 +00002434 IgnoreUnused(memoryManager);
Derek Lambertic374ff02019-12-10 21:57:35 +00002435
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002436 unsigned int outputWidth = 3;
2437 unsigned int outputHeight = 6;
2438 unsigned int outputChannels = 3;
2439
2440 unsigned int inputWidth1 = 3;
2441 unsigned int inputHeight1 = 6;
2442 unsigned int inputChannels1 = 2;
2443
2444 unsigned int inputWidth2 = 3;
2445 unsigned int inputHeight2 = 6;
2446 unsigned int inputChannels2 = 1;
2447
2448 // Defines the tensor descriptors.
Derek Lambertif90c56d2020-01-10 17:14:08 +00002449 TensorInfo outputTensorInfo({ outputChannels, outputHeight, outputWidth }, DataType::QAsymmU8);
2450 TensorInfo inputTensorInfo1({ inputChannels1, inputHeight1, inputWidth1 }, DataType::QAsymmU8);
2451 TensorInfo inputTensorInfo2({ inputChannels2, inputHeight2, inputWidth2 }, DataType::QAsymmU8);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002452
2453 // Quantized input1 tensor. Range [-3, 1]
2454 const float inputScale1 = 0.015686f;
2455 const int32_t inputOffset1 = 192;
2456
Sadik Armagan483c8112021-06-01 09:24:52 +01002457 std::vector<uint8_t> input1 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002458 {
2459 1, 2, 3,
2460 4, 5, 6,
2461 7, 8, 9,
2462 10, 11, 12,
2463 13, 14, 15,
2464 16, 17, 18,
2465
2466 19, 20, 21,
2467 22, 23, 24,
2468 25, 26, 27,
2469 28, 29, 30,
2470 31, 32, 33,
Sadik Armagan483c8112021-06-01 09:24:52 +01002471 34, 35, 36
2472 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002473
2474 // Quatized input2 tensor. Range [-1, 4]
2475 const float inputScale2 = 0.019608f;
2476 const int32_t inputOffset2 = 50;
2477
Sadik Armagan483c8112021-06-01 09:24:52 +01002478 std::vector<uint8_t> input2 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002479 {
2480 37, 38, 39,
2481 40, 41, 42,
2482 43, 44, 45,
2483 46, 47, 48,
2484 49, 50, 51,
Sadik Armagan483c8112021-06-01 09:24:52 +01002485 52, 53, 54
2486 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002487
2488 // Output has the same quantization parameters than input1,
2489 // so that only the requantization of input2 is required
2490 const float outputScale = 0.015686f;
2491 const int32_t outputOffset = 192;
2492
Sadik Armagan483c8112021-06-01 09:24:52 +01002493 std::vector<uint8_t> actualOutput(outputTensorInfo.GetNumElements());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002494
Sadik Armagan483c8112021-06-01 09:24:52 +01002495 std::vector<uint8_t> expectedOutput =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002496 {
2497 1, 2, 3,
2498 4, 5, 6,
2499 7, 8, 9,
2500 10, 11, 12,
2501 13, 14, 15,
2502 16, 17, 18,
2503
2504 19, 20, 21,
2505 22, 23, 24,
2506 25, 26, 27,
2507 28, 29, 30,
2508 31, 32, 33,
2509 34, 35, 36,
2510
2511 176, 177, 178,
2512 179, 181, 182,
2513 183, 184, 186,
2514 187, 188, 189,
2515 191, 192, 193,
Sadik Armagan483c8112021-06-01 09:24:52 +01002516 195, 196, 197
2517 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002518
2519 outputTensorInfo.SetQuantizationScale(outputScale);
2520 outputTensorInfo.SetQuantizationOffset(outputOffset);
2521 inputTensorInfo1.SetQuantizationScale(inputScale1);
2522 inputTensorInfo1.SetQuantizationOffset(inputOffset1);
2523 inputTensorInfo2.SetQuantizationScale(inputScale2);
2524 inputTensorInfo2.SetQuantizationOffset(inputOffset2);
2525
2526 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 +01002527 ConcatQueueDescriptor::ViewOrigin window1(wOrigin1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002528
2529 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 +01002530 ConcatQueueDescriptor::ViewOrigin window2(wOrigin2);
Keith Davisf500d6c2020-08-31 08:32:55 +01002531
2532 std::unique_ptr<ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002533
2534 bool subTensorsSupported = workloadFactory.SupportsSubTensors();
2535
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002536 std::unique_ptr<ITensorHandle> inputHandle1 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002537 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +01002538 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo1.GetShape(), wOrigin1.data()) :
2539 tensorHandleFactory.CreateTensorHandle(inputTensorInfo1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002540
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002541 std::unique_ptr<ITensorHandle> inputHandle2 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002542 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +01002543 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo2.GetShape(), wOrigin2.data()) :
2544 tensorHandleFactory.CreateTensorHandle(inputTensorInfo2);
2545
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002546 ConcatQueueDescriptor data;
2547 WorkloadInfo info;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002548 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
2549 AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
2550 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
2551
2552 data.m_ViewOrigins.push_back(window1);
2553 data.m_ViewOrigins.push_back(window2);
2554
Teresa Charlin611c7fb2022-01-07 09:47:29 +00002555 std::unique_ptr<IWorkload> workload = workloadFactory.CreateWorkload(LayerType::Concat, data, info);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002556
2557 inputHandle1->Allocate();
2558 inputHandle2->Allocate();
2559 outputHandle->Allocate();
2560
Sadik Armagan483c8112021-06-01 09:24:52 +01002561 CopyDataToITensorHandle(inputHandle1.get(), input1.data());
2562 CopyDataToITensorHandle(inputHandle2.get(), input2.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002563
2564 workload->PostAllocationConfigure();
2565 workload->Execute();
2566
Sadik Armagan483c8112021-06-01 09:24:52 +01002567 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002568
Sadik Armagan483c8112021-06-01 09:24:52 +01002569 return LayerTestResult<uint8_t, 3>(actualOutput,
2570 expectedOutput,
2571 outputHandle->GetShape(),
2572 outputTensorInfo.GetShape());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002573}
2574
2575LayerTestResult<uint8_t, 3> ConcatUint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002576 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002577 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2578 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002579{
Jan Eilers8eb25602020-03-09 12:13:48 +00002580 IgnoreUnused(memoryManager);
Derek Lambertic374ff02019-12-10 21:57:35 +00002581
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002582 unsigned int outputWidth = 3;
2583 unsigned int outputHeight = 6;
2584 unsigned int outputChannels = 3;
2585
2586 unsigned int inputWidth1 = 3;
2587 unsigned int inputHeight1 = 6;
2588 unsigned int inputChannels1 = 2;
2589
2590 unsigned int inputWidth2 = 3;
2591 unsigned int inputHeight2 = 6;
2592 unsigned int inputChannels2 = 1;
2593
2594 // Defines the tensor descriptors.
Derek Lambertif90c56d2020-01-10 17:14:08 +00002595 TensorInfo outputTensorInfo({ outputChannels, outputHeight, outputWidth }, DataType::QAsymmU8);
2596 TensorInfo inputTensorInfo1({ inputChannels1, inputHeight1, inputWidth1 }, DataType::QAsymmU8);
2597 TensorInfo inputTensorInfo2({ inputChannels2, inputHeight2, inputWidth2 }, DataType::QAsymmU8);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002598
2599 // Arbitrary scale and offsets. They don't really matter as the Concat operator doesn't dequantize/quantize them.
2600 const float scale = 0.13497836f;
2601 const int32_t offset = -7;
2602
2603 outputTensorInfo.SetQuantizationScale(scale);
2604 outputTensorInfo.SetQuantizationOffset(offset);
2605 inputTensorInfo1.SetQuantizationScale(scale);
2606 inputTensorInfo1.SetQuantizationOffset(offset);
2607 inputTensorInfo2.SetQuantizationScale(scale);
2608 inputTensorInfo2.SetQuantizationOffset(offset);
2609
Sadik Armagan483c8112021-06-01 09:24:52 +01002610 std::vector<uint8_t> actualOutput(outputTensorInfo.GetNumElements());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002611
Sadik Armagan483c8112021-06-01 09:24:52 +01002612 std::vector<uint8_t> expectedOutput =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002613 {
2614 1, 2, 3,
2615 4, 5, 6,
2616 7, 8, 9,
2617 10, 11, 12,
2618 13, 14, 15,
2619 16, 17, 18,
2620
2621 19, 20, 21,
2622 22, 23, 24,
2623 25, 26, 27,
2624 28, 29, 30,
2625 31, 32, 33,
2626 34, 35, 36,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002627
Sadik Armagan483c8112021-06-01 09:24:52 +01002628 37, 38, 39,
2629 40, 41, 42,
2630 43, 44, 45,
2631 46, 47, 48,
2632 49, 50, 51,
2633 52, 53, 54
2634 };
2635
2636 std::vector<uint8_t> input1 =
2637 {
2638 1, 2, 3,
2639 4, 5, 6,
2640 7, 8, 9,
2641 10, 11, 12,
2642 13, 14, 15,
2643 16, 17, 18,
2644
2645 19, 20, 21,
2646 22, 23, 24,
2647 25, 26, 27,
2648 28, 29, 30,
2649 31, 32, 33,
2650 34, 35, 36
2651 };
2652
2653 std::vector<uint8_t> input2 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002654 {
2655 37, 38, 39,
2656 40, 41, 42,
2657 43, 44, 45,
2658 46, 47, 48,
2659 49, 50, 51,
Sadik Armagan483c8112021-06-01 09:24:52 +01002660 52, 53, 54
2661 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002662
2663 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 +01002664 ConcatQueueDescriptor::ViewOrigin window1(wOrigin1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002665
2666 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 +01002667 ConcatQueueDescriptor::ViewOrigin window2(wOrigin2);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002668
Keith Davisf500d6c2020-08-31 08:32:55 +01002669 std::unique_ptr<ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002670
2671 bool subTensorsSupported = workloadFactory.SupportsSubTensors();
2672
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002673 std::unique_ptr<ITensorHandle> inputHandle1 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002674 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +01002675 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo1.GetShape(), wOrigin1.data()) :
2676 tensorHandleFactory.CreateTensorHandle(inputTensorInfo1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002677
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002678 std::unique_ptr<ITensorHandle> inputHandle2 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002679 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +01002680 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo2.GetShape(), wOrigin2.data()) :
2681 tensorHandleFactory.CreateTensorHandle(inputTensorInfo2);
2682
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002683
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002684 ConcatQueueDescriptor data;
2685 WorkloadInfo info;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002686 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
2687 AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
2688 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
2689
2690 data.m_ViewOrigins.push_back(window1);
2691 data.m_ViewOrigins.push_back(window2);
2692
Teresa Charlin611c7fb2022-01-07 09:47:29 +00002693 std::unique_ptr<IWorkload> workload = workloadFactory.CreateWorkload(LayerType::Concat, data, info);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002694
2695 inputHandle1->Allocate();
2696 inputHandle2->Allocate();
2697 outputHandle->Allocate();
2698
Sadik Armagan483c8112021-06-01 09:24:52 +01002699 CopyDataToITensorHandle(inputHandle1.get(), input1.data());
2700 CopyDataToITensorHandle(inputHandle2.get(), input2.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002701
2702 workload->PostAllocationConfigure();
2703 workload->Execute();
2704
Sadik Armagan483c8112021-06-01 09:24:52 +01002705 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002706
Sadik Armagan483c8112021-06-01 09:24:52 +01002707 return LayerTestResult<uint8_t, 3>(actualOutput,
2708 expectedOutput,
2709 outputHandle->GetShape(),
2710 outputTensorInfo.GetShape());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002711}
2712
2713LayerTestResult<uint16_t, 3> ConcatUint16Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002714 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002715 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2716 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002717{
Jan Eilers8eb25602020-03-09 12:13:48 +00002718 IgnoreUnused(memoryManager);
Derek Lambertic374ff02019-12-10 21:57:35 +00002719
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002720 unsigned int outputWidth = 3;
2721 unsigned int outputHeight = 6;
2722 unsigned int outputChannels = 3;
2723
2724 unsigned int inputWidth1 = 3;
2725 unsigned int inputHeight1 = 6;
2726 unsigned int inputChannels1 = 2;
2727
2728 unsigned int inputWidth2 = 3;
2729 unsigned int inputHeight2 = 6;
2730 unsigned int inputChannels2 = 1;
2731
2732 // Defines the tensor descriptors.
Derek Lambertif90c56d2020-01-10 17:14:08 +00002733 TensorInfo outputTensorInfo({ outputChannels, outputHeight, outputWidth }, DataType::QSymmS16);
2734 TensorInfo inputTensorInfo1({ inputChannels1, inputHeight1, inputWidth1 }, DataType::QSymmS16);
2735 TensorInfo inputTensorInfo2({ inputChannels2, inputHeight2, inputWidth2 }, DataType::QSymmS16);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002736
2737 // Arbitrary scale and offsets. They don't really matter as the Concat operator doesn't dequantize/quantize them.
2738 const float scale = 0.13497836f;
2739 const int32_t offset = -7;
2740
2741 outputTensorInfo.SetQuantizationScale(scale);
2742 outputTensorInfo.SetQuantizationOffset(offset);
2743 inputTensorInfo1.SetQuantizationScale(scale);
2744 inputTensorInfo1.SetQuantizationOffset(offset);
2745 inputTensorInfo2.SetQuantizationScale(scale);
2746 inputTensorInfo2.SetQuantizationOffset(offset);
2747
Sadik Armagan483c8112021-06-01 09:24:52 +01002748 std::vector<uint16_t> actualOutput(outputTensorInfo.GetNumElements());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002749
Sadik Armagan483c8112021-06-01 09:24:52 +01002750 std::vector<uint16_t> expectedOutput =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002751 {
2752 1, 2, 3,
2753 4, 5, 6,
2754 7, 8, 9,
2755 10, 11, 12,
2756 13, 14, 15,
2757 16, 17, 18,
2758
2759 19, 20, 21,
2760 22, 23, 24,
2761 25, 26, 27,
2762 28, 29, 30,
2763 31, 32, 33,
2764 34, 35, 36,
2765
2766 37, 38, 39,
2767 40, 41, 42,
2768 43, 44, 45,
2769 46, 47, 48,
2770 49, 50, 51,
Sadik Armagan483c8112021-06-01 09:24:52 +01002771 52, 53, 54
2772 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002773
Sadik Armagan483c8112021-06-01 09:24:52 +01002774 std::vector<uint16_t> input1 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002775 {
2776 1, 2, 3,
2777 4, 5, 6,
2778 7, 8, 9,
2779 10, 11, 12,
2780 13, 14, 15,
2781 16, 17, 18,
2782
2783 19, 20, 21,
2784 22, 23, 24,
2785 25, 26, 27,
2786 28, 29, 30,
2787 31, 32, 33,
2788 34, 35, 36,
Sadik Armagan483c8112021-06-01 09:24:52 +01002789 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002790
Sadik Armagan483c8112021-06-01 09:24:52 +01002791 std::vector<uint16_t> input2 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002792 {
2793 37, 38, 39,
2794 40, 41, 42,
2795 43, 44, 45,
2796 46, 47, 48,
2797 49, 50, 51,
2798 52, 53, 54,
Sadik Armagan483c8112021-06-01 09:24:52 +01002799 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002800
2801 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 +01002802 ConcatQueueDescriptor::ViewOrigin window1(wOrigin1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002803
2804 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 +01002805 ConcatQueueDescriptor::ViewOrigin window2(wOrigin2);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002806
Keith Davisf500d6c2020-08-31 08:32:55 +01002807
2808 std::unique_ptr<ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002809
2810 bool subTensorsSupported = workloadFactory.SupportsSubTensors();
2811
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002812 std::unique_ptr<ITensorHandle> inputHandle1 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002813 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +01002814 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo1.GetShape(), wOrigin1.data()) :
2815 tensorHandleFactory.CreateTensorHandle(inputTensorInfo1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002816
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002817 std::unique_ptr<ITensorHandle> inputHandle2 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002818 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +01002819 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo2.GetShape(), wOrigin2.data()) :
2820 tensorHandleFactory.CreateTensorHandle(inputTensorInfo2);
2821
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002822
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002823 ConcatQueueDescriptor data;
2824 WorkloadInfo info;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002825 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
2826 AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
2827 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
2828
2829 data.m_ViewOrigins.push_back(window1);
2830 data.m_ViewOrigins.push_back(window2);
2831
Teresa Charlin611c7fb2022-01-07 09:47:29 +00002832 std::unique_ptr<IWorkload> workload = workloadFactory.CreateWorkload(LayerType::Concat, data, info);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002833
2834 inputHandle1->Allocate();
2835 inputHandle2->Allocate();
2836 outputHandle->Allocate();
2837
Sadik Armagan483c8112021-06-01 09:24:52 +01002838 CopyDataToITensorHandle(inputHandle1.get(), input1.data());
2839 CopyDataToITensorHandle(inputHandle2.get(), input2.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002840
2841 workload->PostAllocationConfigure();
2842 workload->Execute();
2843
Sadik Armagan483c8112021-06-01 09:24:52 +01002844 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002845
Sadik Armagan483c8112021-06-01 09:24:52 +01002846 return LayerTestResult<uint16_t, 3>(actualOutput,
2847 expectedOutput,
2848 outputHandle->GetShape(),
2849 outputTensorInfo.GetShape());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002850}
2851
2852LayerTestResult<uint8_t, 1> Concat1dUint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002853 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002854 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2855 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002856{
Keith Davisf500d6c2020-08-31 08:32:55 +01002857 return Concat1dTestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002858}
2859
2860LayerTestResult<uint8_t, 2> Concat2dDim0Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002861 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002862 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2863 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002864{
Keith Davisf500d6c2020-08-31 08:32:55 +01002865 return Concat2dDim0TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002866}
2867
2868LayerTestResult<uint8_t, 2> Concat2dDim1Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002869 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002870 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2871 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002872{
Keith Davisf500d6c2020-08-31 08:32:55 +01002873 return Concat2dDim1TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002874}
2875
2876LayerTestResult<uint8_t, 2> Concat2dDim0DiffInputDimsUint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002877 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002878 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2879 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002880{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002881 return Concat2dDim0DiffInputDimsTestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002882 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002883}
2884
2885LayerTestResult<uint8_t, 2> Concat2dDim1DiffInputDimsUint8Test(
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{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002890 return Concat2dDim1DiffInputDimsTestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002891 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002892}
2893
2894LayerTestResult<uint8_t, 3> Concat3dDim0Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002895 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002896 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2897 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002898{
Keith Davisf500d6c2020-08-31 08:32:55 +01002899 return Concat3dDim0TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002900}
2901
2902LayerTestResult<uint8_t, 3> Concat3dDim1Uint8Test(
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{
Keith Davisf500d6c2020-08-31 08:32:55 +01002907 return Concat3dDim1TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002908}
2909
2910LayerTestResult<uint8_t, 3> Concat3dDim2Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002911 IWorkloadFactory& workloadFactory,
2912 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002913 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002914 bool useSubtensor)
2915{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002916 return Concat3dDim2TestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002917 workloadFactory, memoryManager, tensorHandleFactory, useSubtensor, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002918}
2919
2920LayerTestResult<uint8_t, 3> Concat3dDim0DiffInputDimsUint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002921 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002922 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2923 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002924{
Keith Davisf500d6c2020-08-31 08:32:55 +01002925 return Concat3dDim0TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002926}
2927
2928LayerTestResult<uint8_t, 3> Concat3dDim1DiffInputDimsUint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002929 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002930 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2931 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002932{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002933 return Concat3dDim1DiffInputDimsTestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002934 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002935}
2936
2937LayerTestResult<uint8_t, 3> Concat3dDim2DiffInputDimsUint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002938 IWorkloadFactory& workloadFactory,
2939 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002940 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002941 bool useSubtensor)
2942{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002943 return Concat3dDim2DiffInputDimsTestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002944 workloadFactory, memoryManager, tensorHandleFactory, useSubtensor, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002945}
2946
2947LayerTestResult<uint8_t, 4> Concat4dDim0Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002948 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002949 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2950 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002951{
Keith Davisf500d6c2020-08-31 08:32:55 +01002952 return Concat4dDim0TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002953}
2954
2955LayerTestResult<uint8_t, 4> Concat4dDim1Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002956 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002957 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2958 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002959{
Keith Davisf500d6c2020-08-31 08:32:55 +01002960 return Concat4dDim1TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002961}
2962
2963LayerTestResult<uint8_t, 4> Concat4dDim2Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002964 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002965 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2966 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002967{
Keith Davisf500d6c2020-08-31 08:32:55 +01002968 return Concat4dDim2TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002969}
2970
2971LayerTestResult<uint8_t, 4> Concat4dDim3Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002972 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002973 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2974 const armnn::ITensorHandleFactory& tensorHandleFactory, bool useSubtensor)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002975{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002976 return Concat4dDim3TestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002977 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1, useSubtensor);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002978}
2979
2980LayerTestResult<uint8_t, 4> Concat4dDiffShapeDim0Uint8Test(
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{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002985 return Concat4dDiffShapeDim0TestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002986 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002987}
2988
2989LayerTestResult<uint8_t, 4> Concat4dDiffShapeDim1Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002990 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002991 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2992 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002993{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002994 return Concat4dDiffShapeDim1TestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002995 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002996}
2997
2998LayerTestResult<uint8_t, 4> Concat4dDiffShapeDim2Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002999 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01003000 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
3001 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003002{
Derek Lambertif90c56d2020-01-10 17:14:08 +00003003 return Concat4dDiffShapeDim2TestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003004 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003005}
3006
3007LayerTestResult<uint8_t, 4> Concat4dDiffShapeDim3Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01003008 IWorkloadFactory& workloadFactory,
3009 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003010 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003011 bool useSubtensor)
3012{
Derek Lambertif90c56d2020-01-10 17:14:08 +00003013 return Concat4dDiffShapeDim3TestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003014 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1, useSubtensor);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003015}