blob: 3eca27364dee06640cdd3144b9ecf9589f12c779 [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
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +010014#include <backendsCommon/test/TensorCopyUtils.hpp>
15#include <backendsCommon/test/WorkloadTestUtils.hpp>
16
17#include <test/TensorHelpers.hpp>
18
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
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100150 std::unique_ptr<IWorkload> workload = workloadFactory.CreatePermute(queueDescriptor, workloadInfo);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100151
152 inputHandle->Allocate();
153 outputHandle->Allocate();
154
155 CopyDataToITensorHandle(inputHandle.get(), inputData);
156
157 workload->PostAllocationConfigure();
158 workload->Execute();
159
160 outputData.resize(outputTensorInfo.GetNumElements());
161 CopyDataFromITensorHandle(&outputData[0], outputHandle.get());
162 inputTensorInfo = outputTensorInfo;
163}
164
165//
166// Permute the input tensors so we can do a supported concatenation.
167// Also treat lower than 3d tensors as 3d by adding dummy 1 dimensions
168// at the front. Finally this function tells what the output shape
169// of the permuted concatenated tensor is going to be.
170//
171template<typename T> void PermuteInputsForConcat(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100172 IWorkloadFactory& workloadFactory,
173 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100174 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100175 std::vector<TensorInfo> & inputTensorInfos,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100176 std::vector<T *> & inputData,
177 std::vector<std::vector<T>> & inputDataStorage,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100178 PermutationVector & permuteVector,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100179 unsigned int & concatDim,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100180 TensorInfo & outputTensorInfo)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100181{
Jan Eilers8eb25602020-03-09 12:13:48 +0000182 IgnoreUnused(memoryManager);
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100183 ARMNN_ASSERT_MSG(inputTensorInfos.size() > 1,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100184 "Expecting more than one tensor to be concatenated here");
185
186 unsigned int numDims = 0;
187 unsigned int nthInput = 0;
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100188 const PermutationVector identity({0, 1, 2});
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100189
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100190 std::pair<PermutationVector, PermutationVector> permutations =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100191 std::make_pair(identity, identity);
192
193 inputDataStorage.resize(inputData.size());
194
195 for (auto && tensorInfo : inputTensorInfos)
196 {
197 if (numDims == 0)
198 {
199 numDims = tensorInfo.GetShape().GetNumDimensions();
200 Generate3dPermuteVectorForConcat(numDims, concatDim, permutations);
201
202 // Store the reverese permutation.
203 permuteVector = permutations.second;
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100204 ARMNN_ASSERT_MSG(!permuteVector.IsEqual(identity),
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100205 "Test logic error, we don't need permutation, so we shouldn't arrive here");
206 }
207 else
208 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100209 ARMNN_ASSERT_MSG(numDims == tensorInfo.GetShape().GetNumDimensions(),
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100210 "All inputs must have the same number of dimensions");
211 }
212
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100213 TensorInfo newTensorInfo = tensorInfo;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100214 newTensorInfo.SetShape(ExpandTensorShapeTo3dForPermute(tensorInfo.GetShape()));
215
216 PermuteTensorData<T>(workloadFactory,
217 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100218 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100219 permutations.first,
220 newTensorInfo,
221 inputData[nthInput],
222 inputDataStorage[nthInput]);
223
224 inputData[nthInput] = inputDataStorage[nthInput].data();
225 inputTensorInfos[nthInput] = newTensorInfo;
226
227 ++nthInput;
228 }
229
230 outputTensorInfo.SetShape(
231 armnnUtils::Permuted(
232 ExpandTensorShapeTo3dForPermute(outputTensorInfo.GetShape()),
233 permutations.first));
234}
235
236//
237// This is the pair of PermuteInputsForConcat(...) which permutes back
238// the output of the concatenation so we can check it against an expected
239// output.
240//
241template <typename T> void PermuteOutputForConcat(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100242 IWorkloadFactory& workloadFactory,
243 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100244 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100245 const TensorInfo & tensorInfo,
246 const PermutationVector & permuteVector,
247 std::unique_ptr<ITensorHandle> && inputDataHandle,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100248 T * data)
249{
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100250 ARMNN_ASSERT_MSG(data != nullptr, "data must not be null");
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100251 if (data == nullptr)
252 {
253 // Nullptr is an error in the test. By returning without doing the permutation
254 // I expect the caller to fail the test. It still makes sense to report this as
255 // an assert for Debug builds.
256 return;
257 }
258
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100259 TensorInfo resultTensorInfo = tensorInfo;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100260 std::vector<T> inputData(tensorInfo.GetNumElements());
261 std::vector<T> outputData;
262
263 CopyDataFromITensorHandle(&inputData[0], inputDataHandle.get());
264
265 PermuteTensorData<T>(workloadFactory,
266 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100267 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100268 permuteVector,
269 resultTensorInfo,
270 &inputData[0],
271 outputData);
272
273 ::memcpy(data, &outputData[0], sizeof(T)*outputData.size());
274}
275
276template<typename T> void Concatenate(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100277 IWorkloadFactory& workloadFactory,
278 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100279 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100280 std::initializer_list<const TensorInfo> inputTensorInfosOrig,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100281 std::initializer_list<T *> inputsOrig,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100282 const TensorInfo& outputTensorInfoOrig,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100283 T * output,
284 unsigned int concatDim,
285 bool useSubtensor)
286{
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100287 ARMNN_ASSERT_MSG(output != nullptr, "output must not be null");
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100288 if (output == nullptr)
289 {
290 // Nullptr is an error in the test. By returning without doing the permutation
291 // I expect the caller to fail the test. It still makes sense to report this as
292 // an assert for Debug builds.
293 return;
294 }
295
296 // Saves a copy of the parameters which we might need to change.
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100297 std::vector<TensorInfo> inputTensorInfos(inputTensorInfosOrig.begin(), inputTensorInfosOrig.end());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100298 std::vector<T *> inputs = inputsOrig;
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100299 TensorInfo outputTensorInfo = outputTensorInfoOrig;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100300
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100301 PermutationVector permuteVector{0, 1, 2};
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100302
303 // Holds and automatically releases memory for the reshaped input data.
304 std::vector<std::vector<T>> tmpInputDataStorage;
305
306 const size_t inputCount = inputTensorInfos.size();
307
308 bool needPermuteForConcat = NeedPermuteForConcat(inputTensorInfos, concatDim);
309
310 if (needPermuteForConcat)
311 {
312 //
313 // We need to permute the inputs, because concatenation along
314 // the requested axis is not supported.
315 //
316 PermuteInputsForConcat<T>(workloadFactory,
317 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100318 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100319 inputTensorInfos,
320 inputs,
321 tmpInputDataStorage,
322 permuteVector,
323 concatDim,
324 outputTensorInfo);
325 }
326
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100327 WorkloadInfo workloadInfo;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100328
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100329 std::vector<std::unique_ptr<ITensorHandle>> inputHandles;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100330 inputHandles.reserve(inputCount);
Keith Davisf500d6c2020-08-31 08:32:55 +0100331
332 std::unique_ptr<ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
333
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100334 ConcatQueueDescriptor queueDescriptor;
335 OriginsDescriptor viewsDescriptor = CreateDescriptorForConcat(inputTensorInfos, concatDim);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100336 queueDescriptor.m_Parameters = viewsDescriptor;
337
338 if (useSubtensor)
339 {
340 queueDescriptor.m_ViewOrigins.reserve(viewsDescriptor.GetNumViews());
341 for (unsigned int i = 0; i < viewsDescriptor.GetNumViews(); ++i)
342 {
343 queueDescriptor.m_ViewOrigins.emplace_back(std::vector<unsigned int>(viewsDescriptor.GetViewOrigin(i),
344 viewsDescriptor.GetViewOrigin(i) + viewsDescriptor.GetNumDimensions()));
345 }
Keith Davisf500d6c2020-08-31 08:32:55 +0100346
347 outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
348
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100349 const bool subTensorsSupported = workloadFactory.SupportsSubTensors();
350 for (unsigned int i = 0; i < inputCount; ++i)
351 {
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100352 const TensorInfo& inputTensorInfo = inputTensorInfos[i];
Keith Davisf500d6c2020-08-31 08:32:55 +0100353
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100354 std::unique_ptr<ITensorHandle> inputHandle =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100355 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +0100356 tensorHandleFactory.CreateSubTensorHandle(*outputHandle,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100357 inputTensorInfo.GetShape(),
358 queueDescriptor.m_ViewOrigins[i].m_Origin.data()) :
Keith Davisf500d6c2020-08-31 08:32:55 +0100359 tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
360
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100361 inputHandles.emplace_back(std::move(inputHandle));
362 }
363
Teresa Charlinfbf0e5b2020-08-17 01:01:06 +0100364
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100365 }
366 else
367 {
368 for (unsigned int i = 0; i < inputCount; ++i)
369 {
Keith Davisf500d6c2020-08-31 08:32:55 +0100370 std::unique_ptr<ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfos[i]);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100371 inputHandles.emplace_back(std::move(inputHandle));
372 }
373 }
374
375 for (unsigned int i = 0; i < inputCount; ++i)
376 {
377 AddInputToWorkload(queueDescriptor, workloadInfo, inputTensorInfos[i], inputHandles[i].get());
378 }
379
380 AddOutputToWorkload(queueDescriptor, workloadInfo, outputTensorInfo, outputHandle.get());
381
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100382 std::unique_ptr<IWorkload> workload = workloadFactory.CreateConcat(queueDescriptor, workloadInfo);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100383
384 for (auto& inputHandle : inputHandles)
385 {
386 inputHandle->Allocate();
387 }
388
389 outputHandle->Allocate();
390
391 unsigned int nextInputId = 0;
392 for (auto& inputHandle : inputHandles)
393 {
394 CopyDataToITensorHandle(inputHandle.get(), inputs[nextInputId]);
395 ++nextInputId;
396 }
397
398 workload->PostAllocationConfigure();
399 workload->Execute();
400
401 if (needPermuteForConcat)
402 {
403 PermuteOutputForConcat<T>(workloadFactory,
404 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100405 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100406 outputTensorInfo,
407 permuteVector,
408 std::move(outputHandle),
409 output);
410 }
411 else
412 {
413 CopyDataFromITensorHandle(output, outputHandle.get());
414 }
415}
416
417//
418// Implementation templates
419//
420
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100421template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100422LayerTestResult<T, 1> Concat1dTestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100423 IWorkloadFactory& workloadFactory,
424 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100425 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100426 float qScale,
427 int32_t qOffset)
428{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100429 TensorInfo inputTensorInfo({ 3 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100430
Sadik Armagan483c8112021-06-01 09:24:52 +0100431 auto input0 = QuantizedVector<T>({ 1.0f, 2.0f, 3.0f }, qScale, qOffset);
432 auto input1 = QuantizedVector<T>({ 4.0f, 5.0f, 6.0f }, qScale, qOffset);
433 auto input2 = QuantizedVector<T>({ 7.0f, 8.0f, 9.0f }, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100434
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100435 TensorInfo outputTensorInfo({ 9 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100436
437 LayerTestResult<T, 1> result(outputTensorInfo);
438
439 std::vector<T> output;
440 output.resize(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +0100441 Concatenate<T>(workloadFactory, memoryManager, tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100442 { inputTensorInfo, inputTensorInfo, inputTensorInfo },
443 { input0.data(), input1.data(), input2.data() },
444 outputTensorInfo,
445 output.data(),
446 0,
447 true);
448
Sadik Armagan483c8112021-06-01 09:24:52 +0100449 result.m_ActualData = output;
450 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100451 {
452 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f
453 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100454 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100455
456 return result;
457}
458
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100459template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100460LayerTestResult<T, 2> Concat2dTestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100461 IWorkloadFactory& workloadFactory,
462 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100463 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100464 const TensorInfo& outputTensorInfo,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100465 unsigned int dimension,
466 const float qScale,
467 const int32_t qOffset)
468{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100469 TensorInfo inputTensorInfo({ 2, 3 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100470
Sadik Armagan483c8112021-06-01 09:24:52 +0100471 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100472 {
473 // Batch 0
474 1.0f, 2.0f, 3.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100475
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100476 // Batch 1
477 10.0f, 11.0f, 12.0f,
478 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100479 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100480
Sadik Armagan483c8112021-06-01 09:24:52 +0100481 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100482 {
483 // Batch 0
484 4.0f, 5.0f, 6.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100485
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100486 // Batch 1
487 13.0f, 14.0f, 15.0f,
488 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100489 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100490
Sadik Armagan483c8112021-06-01 09:24:52 +0100491 auto input2 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100492 {
493 // Batch 0
494 7.0f, 8.0f, 9.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100495
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100496 // Batch 1
497 16.0f, 17.0f, 18.0f,
498 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100499 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100500
501 LayerTestResult<T, 2> result(outputTensorInfo);
502
503 std::vector<T> output;
504 output.resize(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +0100505 Concatenate<T>(workloadFactory, memoryManager, tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100506 { inputTensorInfo, inputTensorInfo, inputTensorInfo },
507 { input0.data(), input1.data(), input2.data() },
508 outputTensorInfo,
509 output.data(),
510 dimension,
511 true);
512
Sadik Armagan483c8112021-06-01 09:24:52 +0100513 result.m_ActualData = output;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100514 return result;
515}
516
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100517template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100518LayerTestResult<T, 2> Concat2dDim0TestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100519 IWorkloadFactory& workloadFactory,
520 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100521 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100522 float qScale,
523 int32_t qOffset)
524{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100525 TensorInfo outputTensorInfo({ 6, 3 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100526
527 LayerTestResult<T, 2> result = Concat2dTestImpl<ArmnnType>(
Keith Davisf500d6c2020-08-31 08:32:55 +0100528 workloadFactory, memoryManager, tensorHandleFactory, outputTensorInfo, 0, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100529
Sadik Armagan483c8112021-06-01 09:24:52 +0100530 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100531 {
532 // Batch 0
533 1.0f, 2.0f, 3.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100534
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100535 // Batch 1
536 10.0f, 11.0f, 12.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100537
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100538 // Batch 2
539 4.0f, 5.0f, 6.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100540
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100541 // Batch 3
542 13.0f, 14.0f, 15.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100543
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100544 // Batch 4
545 7.0f, 8.0f, 9.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100546
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100547 // Batch 5
548 16.0f, 17.0f, 18.0f,
549 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100550 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100551
552 return result;
553}
554
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100555template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100556LayerTestResult<T, 2> Concat2dDim1TestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100557 IWorkloadFactory& workloadFactory,
558 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100559 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100560 float qScale,
561 int32_t qOffset)
562{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100563 TensorInfo outputTensorInfo({ 2, 9 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100564
565 LayerTestResult<T, 2> result = Concat2dTestImpl<ArmnnType>(
Keith Davisf500d6c2020-08-31 08:32:55 +0100566 workloadFactory, memoryManager, tensorHandleFactory, outputTensorInfo, 1, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100567
Sadik Armagan483c8112021-06-01 09:24:52 +0100568 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100569 {
570 // Batch 0
571 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 +0100572
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100573 // Batch 1
574 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f
575 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100576 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100577
578 return result;
579}
580
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100581template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100582LayerTestResult<T, 2> Concat2dDim0DiffInputDimsTestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100583 IWorkloadFactory& workloadFactory,
584 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100585 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100586 float qScale,
587 int32_t qOffset)
588{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100589 TensorInfo input0TensorInfo({ 2, 3 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +0100590 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100591 {
592 // Batch 0
593 1.0f, 2.0f, 3.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100594
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100595 // Batch 1
596 10.0f, 11.0f, 12.0f,
597 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100598 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100599
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100600 TensorInfo input1TensorInfo({ 3, 3 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +0100601 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100602 {
603 // Batch 0
604 4.0f, 5.0f, 6.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100605
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100606 // Batch 1
607 13.0f, 14.0f, 15.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100608
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100609 // Batch 0
610 7.0f, 8.0f, 9.0f,
611 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100612 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100613
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100614 TensorInfo input2TensorInfo({ 1, 3 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +0100615 auto input2 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100616 {
617 // Batch 1
618 16.0f, 17.0f, 18.0f,
619 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100620 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100621
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100622 TensorInfo outputTensorInfo({ 6, 3 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100623 LayerTestResult<T, 2> result(outputTensorInfo);
624
625 std::vector<T> output;
626 output.resize(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +0100627 Concatenate<T>(workloadFactory, memoryManager, tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100628 { input0TensorInfo, input1TensorInfo, input2TensorInfo },
629 { input0.data(), input1.data(), input2.data() },
630 outputTensorInfo,
631 output.data(),
632 0,
633 true);
634
Sadik Armagan483c8112021-06-01 09:24:52 +0100635 result.m_ActualData = output;
636 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100637 {
638 // Batch 0
639 1.0f, 2.0f, 3.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100640
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100641 // Batch 1
642 10.0f, 11.0f, 12.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100643
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100644 // Batch 2
645 4.0f, 5.0f, 6.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100646
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100647 // Batch 3
648 13.0f, 14.0f, 15.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100649
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100650 // Batch 4
651 7.0f, 8.0f, 9.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100652
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100653 // Batch 5
654 16.0f, 17.0f, 18.0f,
655 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100656 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100657
658 return result;
659}
660
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100661template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100662LayerTestResult<T, 2> Concat2dDim1DiffInputDimsTestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100663 IWorkloadFactory& workloadFactory,
664 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100665 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100666 float qScale,
667 int32_t qOffset)
668{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100669 TensorInfo input0TensorInfo({ 2, 3 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +0100670 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100671 {
672 // Batch 0
673 1.0f, 2.0f, 3.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100674
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100675 // Batch 1
676 10.0f, 11.0f, 12.0f,
677 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100678 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100679
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100680 TensorInfo input1TensorInfo({ 2, 5 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +0100681 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100682 {
683 // Batch 0
684 4.0f, 5.0f, 6.0f, 7.0f, 8.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100685
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100686 // Batch 1
687 13.0f, 14.0f, 15.0f, 16.0f, 17.0f,
688 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100689 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100690
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100691 TensorInfo input2TensorInfo({ 2, 1 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +0100692 auto input2 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100693 {
694 // Batch 0
695 9.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100696
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100697 // Batch 1
698 18.0f
699 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100700 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100701
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100702 TensorInfo outputTensorInfo({ 2, 9 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100703 LayerTestResult<T, 2> result(outputTensorInfo);
704
705 std::vector<T> output;
706 output.resize(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +0100707 Concatenate<T>(workloadFactory, memoryManager, tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100708 { input0TensorInfo, input1TensorInfo, input2TensorInfo },
709 { input0.data(), input1.data(), input2.data() },
710 outputTensorInfo,
711 output.data(),
712 1,
713 true);
714
Sadik Armagan483c8112021-06-01 09:24:52 +0100715 result.m_ActualData = output;
716 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100717 {
718 // Batch 0
719 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 +0100720
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100721 // Batch 1
722 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f,
723 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100724 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100725
726 return result;
727}
728
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100729template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100730LayerTestResult<T, 3> Concat3dTestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100731 IWorkloadFactory& workloadFactory,
732 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100733 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100734 const TensorInfo& outputTensorInfo,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100735 unsigned int dimension,
736 bool useSubtensor,
737 float qScale,
738 int32_t qOffset)
739{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100740 TensorInfo inputTensorInfo({ 2, 3, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100741
Sadik Armagan483c8112021-06-01 09:24:52 +0100742 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100743 {
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100744 // Batch 0, Channel 0
745 1.0f, 2.0f,
746
747 // Batch 0, Channel 1
748 3.0f, 4.0f,
749
750 // Batch 0, Channel 2
751 5.0f, 6.0f,
752
753 // Batch 1, Channel 0
754 19.0f, 20.0f,
755
756 // Batch 1, Channel 1
757 21.0f, 22.0f,
758
759 // Batch 1, Channel 2
760 23.0f, 24.0f
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100761 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100762 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100763
Sadik Armagan483c8112021-06-01 09:24:52 +0100764 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100765 {
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100766 // Batch 0, Channel 0
767 7.0f, 8.0f,
768
769 // Batch 0, Channel 1
770 9.0f, 10.0f,
771
772 // Batch 0, Channel 2
773 11.0f, 12.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100774
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100775 // Batch 1, Channel 0
776 25.0f, 26.0f,
777
778 // Batch 1, Channel 1
779 27.0f, 28.0f,
780
781 // Batch 1, Channel 2
782 29.0f, 30.0f
783 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100784 qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100785
Sadik Armagan483c8112021-06-01 09:24:52 +0100786 auto input2 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100787 {
788 // Batch 0, Channel 0
789 13.0f, 14.0f,
790
791 // Batch 0, Channel 1
792 15.0f, 16.0f,
793
794 // Batch 0, Channel 2
795 17.0f, 18.0f,
796
797 // Batch 1, Channel 0
798 31.0f, 32.0f,
799
800 // Batch 1, Channel 1
801 33.0f, 34.0f,
802
803 // Batch 1, Channel 2
804 35.0f, 36.0f
805 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100806 qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100807
808 LayerTestResult<T, 3> result(outputTensorInfo);
809
810 std::vector<T> output;
811 output.resize(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +0100812 Concatenate<T>(workloadFactory, memoryManager, tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100813 { inputTensorInfo, inputTensorInfo, inputTensorInfo },
814 { input0.data(), input1.data(), input2.data() },
815 outputTensorInfo,
816 output.data(),
817 dimension,
818 useSubtensor);
819
Sadik Armagan483c8112021-06-01 09:24:52 +0100820 result.m_ActualData = output;
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100821 return result;
822}
823
824template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
825LayerTestResult<T, 3> Concat3dDim0TestImpl(
826 IWorkloadFactory& workloadFactory,
827 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100828 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100829 float qScale,
830 int32_t qOffset)
831{
832 TensorInfo outputTensorInfo({ 6, 3, 2 }, ArmnnType, qScale, qOffset);
833
834 LayerTestResult<T, 3> result = Concat3dTestImpl<ArmnnType>(
Keith Davisf500d6c2020-08-31 08:32:55 +0100835 workloadFactory, memoryManager, tensorHandleFactory, outputTensorInfo, 0, true, qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100836
Sadik Armagan483c8112021-06-01 09:24:52 +0100837 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100838 {
839 // Batch 0, Channel 0
840 1.0f, 2.0f,
841
842 // Batch 0, Channel 1
843 3.0f, 4.0f,
844
845 // Batch 0, Channel 2
846 5.0f, 6.0f,
847
848 // Batch 1, Channel 0
849 19.0f, 20.0f,
850
851 // Batch 1, Channel 1
852 21.0f, 22.0f,
853
854 // Batch 1, Channel 2
855 23.0f, 24.0f,
856
857 // Batch 2, Channel 0
858 7.0f, 8.0f,
859
860 // Batch 2, Channel 1
861 9.0f, 10.0f,
862
863 // Batch 2, Channel 2
864 11.0f, 12.0f,
865
866 // Batch 3, Channel 0
867 25.0f, 26.0f,
868
869 // Batch 3, Channel 1
870 27.0f, 28.0f,
871
872 // Batch 3, Channel 2
873 29.0f, 30.0f,
874
875 // Batch 4, Channel 0
876 13.0f, 14.0f,
877
878 // Batch 4, Channel 1
879 15.0f, 16.0f,
880
881 // Batch 4, Channel 2
882 17.0f, 18.0f,
883
884 // Batch 5, Channel 0
885 31.0f, 32.0f,
886
887 // Batch 5, Channel 1
888 33.0f, 34.0f,
889
890 // Batch 5, Channel 2
891 35.0f, 36.0f
892 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100893 qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100894
895 return result;
896}
897
898template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
899LayerTestResult<T, 3> Concat3dDim1TestImpl(
900 IWorkloadFactory& workloadFactory,
901 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100902 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100903 float qScale,
904 int32_t qOffset)
905{
906 TensorInfo outputTensorInfo({ 2, 9, 2 }, ArmnnType, qScale, qOffset);
907
908 LayerTestResult<T, 3> result = Concat3dTestImpl<ArmnnType>(
Keith Davisf500d6c2020-08-31 08:32:55 +0100909 workloadFactory, memoryManager, tensorHandleFactory, outputTensorInfo, 1, true, qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100910
Sadik Armagan483c8112021-06-01 09:24:52 +0100911 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100912 {
913 // Batch 0, Channel 0
914 1.0f, 2.0f,
915
916 // Batch 0, Channel 1
917 3.0f, 4.0f,
918
919 // Batch 0, Channel 2
920 5.0f, 6.0f,
921
922 // Batch 0, Channel 3
923 7.0f, 8.0f,
924
925 // Batch 0, Channel 4
926 9.0f, 10.0f,
927
928 // Batch 0, Channel 5
929 11.0f, 12.0f,
930
931 // Batch 0, Channel 6
932 13.0f, 14.0f,
933
934 // Batch 0, Channel 7
935 15.0f, 16.0f,
936
937 // Batch 0, Channel 8
938 17.0f, 18.0f,
939
940 // Batch 1, Channel 0
941 19.0f, 20.0f,
942
943 // Batch 1, Channel 1
944 21.0f, 22.0f,
945
946 // Batch 1, Channel 2
947 23.0f, 24.0f,
948
949 // Batch 1, Channel 3
950 25.0f, 26.0f,
951
952 // Batch 1, Channel 4
953 27.0f, 28.0f,
954
955 // Batch 1, Channel 5
956 29.0f, 30.0f,
957
958 // Batch 1, Channel 6
959 31.0f, 32.0f,
960
961 // Batch 1, Channel 7
962 33.0f, 34.0f,
963
964 // Batch 1, Channel 8
965 35.0f, 36.0f
966 },
Sadik Armagan483c8112021-06-01 09:24:52 +0100967 qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100968
969 return result;
970}
971
972template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
973LayerTestResult<T, 3> Concat3dDim2TestImpl(
974 IWorkloadFactory& workloadFactory,
975 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +0100976 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100977 bool useSubtensor,
978 float qScale,
979 int32_t qOffset)
980{
981 TensorInfo outputTensorInfo({ 2, 3, 6 }, ArmnnType, qScale, qOffset);
982
983 LayerTestResult<T, 3> result = Concat3dTestImpl<ArmnnType>(
Keith Davisf500d6c2020-08-31 08:32:55 +0100984 workloadFactory, memoryManager, tensorHandleFactory, outputTensorInfo, 2, useSubtensor, qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100985
Sadik Armagan483c8112021-06-01 09:24:52 +0100986 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100987 {
988 // Batch 0, Channel 0
989 1.0f, 2.0f, 7.0f, 8.0f, 13.0f, 14.0f,
990
991 // Batch 0, Channel 1
992 3.0f, 4.0f, 9.0f, 10.0f, 15.0f, 16.0f,
993
994 // Batch 0, Channel 2
995 5.0f, 6.0f, 11.0f, 12.0f, 17.0f, 18.0f,
996
997 // Batch 1, Channel 0
998 19.0f, 20.0f, 25.0f, 26.0f, 31.0f, 32.0f,
999
1000 // Batch 1, Channel 1
1001 21.0f, 22.0f, 27.0f, 28.0f, 33.0f, 34.0f,
1002
1003 // Batch 1, Channel 2
1004 23.0f, 24.0f, 29.0f, 30.0f, 35.0f, 36.0f,
1005 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001006 qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001007
1008 return result;
1009}
1010
1011template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
1012LayerTestResult<T, 3> Concat3dDim0DiffInputDimsTestImpl(
1013 IWorkloadFactory& workloadFactory,
1014 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001015 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001016 float qScale,
1017 int32_t qOffset)
1018{
1019 TensorInfo input0TensorInfo({ 2, 3, 2 }, ArmnnType);
Sadik Armagan483c8112021-06-01 09:24:52 +01001020 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001021 {
1022 // Batch 0, Channel 0
1023 1.0f, 2.0f,
1024
1025 // Batch 0, Channel 1
1026 3.0f, 4.0f,
1027
1028 // Batch 0, Channel 2
1029 5.0f, 6.0f,
1030
1031 // Batch 1, Channel 0
1032 19.0f, 20.0f,
1033
1034 // Batch 1, Channel 1
1035 21.0f, 22.0f,
1036
1037 // Batch 1, Channel 2
1038 23.0f, 24.0f
1039 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001040 qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001041
1042 TensorInfo input1TensorInfo({ 1, 3, 2 }, ArmnnType);
Sadik Armagan483c8112021-06-01 09:24:52 +01001043 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001044 {
1045 // Batch 0, Channel 0
1046 7.0f, 8.0f,
1047
1048 // Batch 0, Channel 1
1049 9.0f, 10.0f,
1050
1051 // Batch 0, Channel 2
1052 11.0f, 12.0f,
1053 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001054 qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001055
1056 TensorInfo input2TensorInfo({ 3, 3, 2 }, ArmnnType);
Sadik Armagan483c8112021-06-01 09:24:52 +01001057 auto input2 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001058 {
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001059 // Batch 0, Channel 0
1060 25.0f, 26.0f,
1061
1062 // Batch 0, Channel 1
1063 27.0f, 28.0f,
1064
1065 // Batch 0, Channel 2
1066 29.0f, 30.0f,
1067
1068 // Batch 1, Channel 0
1069 13.0f, 14.0f,
1070
1071 // Batch 1, Channel 1
1072 15.0f, 16.0f,
1073
1074 // Batch 1, Channel 2
1075 17.0f, 18.0f,
1076
1077 // Batch 2, Channel 0
1078 31.0f, 32.0f,
1079
1080 // Batch 2, Channel 1
1081 33.0f, 34.0f,
1082
1083 // Batch 2, Channel 2
1084 35.0f, 36.0f
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001085 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001086 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001087
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001088 TensorInfo outputTensorInfo({ 6, 3, 2 }, ArmnnType);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001089 LayerTestResult<T, 3> result(outputTensorInfo);
1090
1091 std::vector<T> output;
1092 output.resize(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +01001093 Concatenate<T>(workloadFactory, memoryManager, tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001094 { input0TensorInfo, input1TensorInfo, input2TensorInfo },
1095 { input0.data(), input1.data(), input2.data() },
1096 outputTensorInfo,
1097 output.data(),
1098 0,
1099 true);
1100
Sadik Armagan483c8112021-06-01 09:24:52 +01001101 result.m_ActualData = output;
1102 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001103 {
1104 // Batch 0, Channel 0
1105 1.0f, 2.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001106
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001107 // Batch 0, Channel 1
1108 3.0f, 4.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001109
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001110 // Batch 0, Channel 2
1111 5.0f, 6.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001112
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001113 // Batch 1, Channel 0
1114 19.0f, 20.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001115
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001116 // Batch 1, Channel 1
1117 21.0f, 22.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001118
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001119 // Batch 1, Channel 2
1120 23.0f, 24.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001121
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001122 // Batch 2, Channel 0
1123 7.0f, 8.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001124
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001125 // Batch 2, Channel 1
1126 9.0f, 10.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001127
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001128 // Batch 2, Channel 2
1129 11.0f, 12.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001130
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001131 // Batch 3, Channel 0
1132 25.0f, 26.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001133
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001134 // Batch 3, Channel 1
1135 27.0f, 28.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001136
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001137 // Batch 3, Channel 2
1138 29.0f, 30.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001139
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001140 // Batch 4, Channel 0
1141 13.0f, 14.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001142
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001143 // Batch 4, Channel 1
1144 15.0f, 16.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001145
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001146 // Batch 4, Channel 2
1147 17.0f, 18.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001148
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001149 // Batch 5, Channel 0
1150 31.0f, 32.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001151
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001152 // Batch 5, Channel 1
1153 33.0f, 34.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001154
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001155 // Batch 5, Channel 2
1156 35.0f, 36.0f
1157 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001158 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001159
1160 return result;
1161}
1162
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001163template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001164LayerTestResult<T, 3> Concat3dDim1DiffInputDimsTestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001165 IWorkloadFactory& workloadFactory,
1166 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001167 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001168 float qScale,
1169 int32_t qOffset)
1170{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001171 TensorInfo input0TensorInfo({ 2, 3, 2 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001172 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001173 {
1174 // Batch 0, Channel 0
1175 1.0f, 2.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001176
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001177 // Batch 0, Channel 1
1178 3.0f, 4.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001179
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001180 // Batch 0, Channel 2
1181 5.0f, 6.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001182
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001183 // Batch 1, Channel 0
1184 19.0f, 20.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001185
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001186 // Batch 1, Channel 1
1187 21.0f, 22.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001188
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001189 // Batch 1, Channel 2
1190 23.0f, 24.0f
1191 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001192 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001193
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001194 TensorInfo input1TensorInfo({ 2, 4, 2 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001195 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001196 {
1197 // Batch 0, Channel 0
1198 7.0f, 8.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001199
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001200 // Batch 0, Channel 1
1201 9.0f, 10.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001202
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001203 // Batch 0, Channel 2
1204 11.0f, 12.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001205
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001206 // Batch 0, Channel 3
1207 25.0f, 26.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001208
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001209 // Batch 1, Channel 0
1210 27.0f, 28.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001211
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001212 // Batch 1, Channel 1
1213 29.0f, 30.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001214
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001215 // Batch 1, Channel 2
1216 13.0f, 14.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001217
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001218 // Batch 1, Channel 3
1219 15.0f, 16.0f,
1220 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001221 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001222
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001223 TensorInfo input2TensorInfo({ 2, 1, 2 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001224 auto input2 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001225 {
1226 // Batch 0, Channel 0
1227 17.0f, 18.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001228
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001229 // Batch 1, Channel 0
1230 31.0f, 32.0f,
1231 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001232 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001233
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001234 TensorInfo outputTensorInfo({ 2, 8, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001235 LayerTestResult<T, 3> result(outputTensorInfo);
1236
1237 std::vector<T> output;
1238 output.resize(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +01001239 Concatenate<T>(workloadFactory, memoryManager, tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001240 { input0TensorInfo, input1TensorInfo, input2TensorInfo },
1241 { input0.data(), input1.data(), input2.data() },
1242 outputTensorInfo,
1243 output.data(),
1244 1,
1245 true);
1246
Sadik Armagan483c8112021-06-01 09:24:52 +01001247 result.m_ActualData = output;
1248 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001249 {
1250 // Batch 0, Channel 0
1251 1.0f, 2.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001252
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001253 // Batch 0, Channel 1
1254 3.0f, 4.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001255
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001256 // Batch 0, Channel 2
1257 5.0f, 6.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001258
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001259 // Batch 0, Channel 3
1260 7.0f, 8.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001261
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001262 // Batch 0, Channel 4
1263 9.0f, 10.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001264
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001265 // Batch 0, Channel 5
1266 11.0f, 12.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001267
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001268 // Batch 0, Channel 6
1269 25.0f, 26.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001270
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001271 // Batch 0, Channel 7
1272 17.0f, 18.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001273
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001274 // Batch 1, Channel 0
1275 19.0f, 20.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001276
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001277 // Batch 1, Channel 1
1278 21.0f, 22.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001279
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001280 // Batch 1, Channel 2
1281 23.0f, 24.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001282
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001283 // Batch 1, Channel 3
1284 27.0f, 28.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001285
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001286 // Batch 1, Channel 4
1287 29.0f, 30.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001288
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001289 // Batch 1, Channel 5
1290 13.0f, 14.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001291
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001292 // Batch 1, Channel 6
1293 15.0f, 16.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001294
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001295 // Batch 1, Channel 7
1296 31.0f, 32.0f,
1297 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001298 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001299
1300 return result;
1301}
1302
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001303template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001304LayerTestResult<T, 3> Concat3dDim2DiffInputDimsTestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001305 IWorkloadFactory& workloadFactory,
1306 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001307 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001308 bool useSubtensor,
1309 float qScale,
1310 int32_t qOffset)
1311{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001312 TensorInfo input0TensorInfo({ 2, 3, 2 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001313 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001314 {
1315 // Batch 0, Channel 0
1316 1.0f, 2.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001317
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001318 // Batch 0, Channel 1
1319 3.0f, 4.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001320
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001321 // Batch 0, Channel 2
1322 5.0f, 6.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001323
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001324 // Batch 1, Channel 0
1325 19.0f, 20.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001326
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001327 // Batch 1, Channel 1
1328 21.0f, 22.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001329
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001330 // Batch 1, Channel 2
1331 23.0f, 24.0f
1332 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001333 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001334
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001335 TensorInfo input1TensorInfo({ 2, 3, 1 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001336 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001337 {
1338 // Batch 0, Channel 0
1339 7.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001340
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001341 // Batch 0, Channel 1
1342 9.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001343
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001344 // Batch 0, Channel 2
1345 11.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001346
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001347 // Batch 1, Channel 0
1348 25.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001349
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001350 // Batch 1, Channel 1
1351 27.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001352
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001353 // Batch 1, Channel 2
1354 29.0f
1355 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001356 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001357
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001358 TensorInfo input2TensorInfo({ 2, 3, 3 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001359 auto input2 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001360 {
1361 // Batch 0, Channel 0
1362 13.0f, 14.0f, 50.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001363
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001364 // Batch 0, Channel 1
1365 15.0f, 16.0f, 51.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001366
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001367 // Batch 0, Channel 2
1368 17.0f, 18.0f, 52.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001369
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001370 // Batch 1, Channel 0
1371 31.0f, 32.0f, 53.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001372
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001373 // Batch 1, Channel 1
1374 33.0f, 34.0f, 54.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001375
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001376 // Batch 1, Channel 2
1377 35.0f, 36.0f, 55.0f,
1378 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001379 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001380
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001381 TensorInfo outputTensorInfo({ 2, 3, 6 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001382 LayerTestResult<T, 3> result(outputTensorInfo);
1383
1384 std::vector<T> output;
1385 output.resize(outputTensorInfo.GetNumElements());
Keith Davisf500d6c2020-08-31 08:32:55 +01001386 Concatenate<T>(workloadFactory, memoryManager, tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001387 { input0TensorInfo, input1TensorInfo, input2TensorInfo },
1388 { input0.data(), input1.data(), input2.data() },
1389 outputTensorInfo,
1390 output.data(),
1391 2,
1392 useSubtensor);
1393
Sadik Armagan483c8112021-06-01 09:24:52 +01001394 result.m_ActualData = output;
1395 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001396 {
1397 // Batch 0, Channel 0
1398 1.0f, 2.0f, 7.0f, 13.0f, 14.0f, 50.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001399
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001400 // Batch 0, Channel 1
1401 3.0f, 4.0f, 9.0f, 15.0f, 16.0f, 51.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001402
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001403 // Batch 0, Channel 2
1404 5.0f, 6.0f, 11.0f, 17.0f, 18.0f, 52.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001405
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001406 // Batch 1, Channel 0
1407 19.0f, 20.0f, 25.0f, 31.0f, 32.0f, 53.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001408
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001409 // Batch 1, Channel 1
1410 21.0f, 22.0f, 27.0f, 33.0f, 34.0f, 54.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001411
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001412 // Batch 1, Channel 2
1413 23.0f, 24.0f, 29.0f, 35.0f, 36.0f, 55.0f,
1414 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001415 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001416
1417 return result;
1418}
1419
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001420template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001421LayerTestResult<T, 4> Concat4dTestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001422 IWorkloadFactory& workloadFactory,
1423 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001424 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001425 const TensorInfo& outputTensorInfo,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001426 unsigned int dimension,
1427 bool useSubtensor,
1428 float qScale,
1429 int32_t qOffset)
1430{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001431 TensorInfo inputTensorInfo({ 1, 3, 2, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001432
Sadik Armagan483c8112021-06-01 09:24:52 +01001433 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001434 {
1435 1.0f, 2.0f,
1436 3.0f, 4.0f,
1437 5.0f, 6.0f,
1438 7.0f, 8.0f,
1439 9.0f, 10.0f,
1440 11.0f, 12.0f
1441 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001442 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001443
Sadik Armagan483c8112021-06-01 09:24:52 +01001444 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001445 {
1446 11.0f, 12.0f,
1447 13.0f, 14.0f,
1448 15.0f, 16.0f,
1449 17.0f, 18.0f,
1450 19.0f, 20.0f,
1451 21.0f, 22.0f
1452 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001453 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001454
Sadik Armagan483c8112021-06-01 09:24:52 +01001455 auto input2 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001456 {
1457 21.0f, 22.0f,
1458 23.0f, 24.0f,
1459 25.0f, 26.0f,
1460 27.0f, 28.0f,
1461 29.0f, 30.0f,
1462 31.0f, 32.0f
1463 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001464 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001465
1466 LayerTestResult<T, 4> result(outputTensorInfo);
1467
1468 std::vector<T> output;
1469 output.resize(outputTensorInfo.GetNumElements());
1470
1471 Concatenate<T>(workloadFactory,
1472 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001473 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001474 {inputTensorInfo, inputTensorInfo, inputTensorInfo},
1475 {input0.data(), input1.data(), input2.data()},
1476 outputTensorInfo,
1477 output.data(),
1478 dimension,
1479 useSubtensor);
1480
Sadik Armagan483c8112021-06-01 09:24:52 +01001481 result.m_ActualData = output;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001482 return result;
1483}
1484
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001485template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001486LayerTestResult<T, 4> Concat4dDim0TestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001487 IWorkloadFactory& workloadFactory,
1488 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001489 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001490 float qScale,
1491 int32_t qOffset)
1492{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001493 TensorInfo outputTensorInfo({ 3, 3, 2, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001494
1495 LayerTestResult<T, 4> result = Concat4dTestImpl<ArmnnType>(
Keith Davisf500d6c2020-08-31 08:32:55 +01001496 workloadFactory, memoryManager, tensorHandleFactory, outputTensorInfo, 0, true, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001497
Sadik Armagan483c8112021-06-01 09:24:52 +01001498 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001499 {
1500 1.0f, 2.0f,
1501 3.0f, 4.0f,
1502 5.0f, 6.0f,
1503 7.0f, 8.0f,
1504 9.0f, 10.0f,
1505 11.0f, 12.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001506
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001507 11.0f, 12.0f,
1508 13.0f, 14.0f,
1509 15.0f, 16.0f,
1510 17.0f, 18.0f,
1511 19.0f, 20.0f,
1512 21.0f, 22.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001513
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001514 21.0f, 22.0f,
1515 23.0f, 24.0f,
1516 25.0f, 26.0f,
1517 27.0f, 28.0f,
1518 29.0f, 30.0f,
1519 31.0f, 32.0f
1520 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001521 qScale, qOffset);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001522
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001523 return result;
1524}
1525
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001526template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001527LayerTestResult<T, 4> Concat4dDim1TestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001528 IWorkloadFactory& workloadFactory,
1529 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001530 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001531 float qScale,
1532 int32_t qOffset)
1533{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001534 TensorInfo outputTensorInfo({ 1, 9, 2, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001535
1536 LayerTestResult<T, 4> result = Concat4dTestImpl<ArmnnType>(
Keith Davisf500d6c2020-08-31 08:32:55 +01001537 workloadFactory, memoryManager, tensorHandleFactory, outputTensorInfo, 1, true, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001538
Sadik Armagan483c8112021-06-01 09:24:52 +01001539 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001540 {
1541 1.0f, 2.0f,
1542 3.0f, 4.0f,
1543 5.0f, 6.0f,
1544 7.0f, 8.0f,
1545 9.0f, 10.0f,
1546 11.0f, 12.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001547
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001548 11.0f, 12.0f,
1549 13.0f, 14.0f,
1550 15.0f, 16.0f,
1551 17.0f, 18.0f,
1552 19.0f, 20.0f,
1553 21.0f, 22.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001554
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001555 21.0f, 22.0f,
1556 23.0f, 24.0f,
1557 25.0f, 26.0f,
1558 27.0f, 28.0f,
1559 29.0f, 30.0f,
1560 31.0f, 32.0f
1561 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001562 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001563
1564 return result;
1565}
1566
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001567template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001568LayerTestResult<T, 4> Concat4dDim2TestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001569 IWorkloadFactory& workloadFactory,
1570 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001571 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001572 float qScale,
1573 int32_t qOffset)
1574{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001575 TensorInfo outputTensorInfo({ 1, 3, 6, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001576
1577 LayerTestResult<T, 4> result = Concat4dTestImpl<ArmnnType>(
Keith Davisf500d6c2020-08-31 08:32:55 +01001578 workloadFactory, memoryManager, tensorHandleFactory, outputTensorInfo, 2, true, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001579
Sadik Armagan483c8112021-06-01 09:24:52 +01001580 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001581 {
1582 1.0f, 2.0f,
1583 3.0f, 4.0f,
1584 11.0f, 12.0f,
1585 13.0f, 14.0f,
1586 21.0f, 22.0f,
1587 23.0f, 24.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001588
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001589 5.0f, 6.0f,
1590 7.0f, 8.0f,
1591 15.0f, 16.0f,
1592 17.0f, 18.0f,
1593 25.0f, 26.0f,
1594 27.0f, 28.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001595
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001596 9.0f, 10.0f,
1597 11.0f, 12.0f,
1598 19.0f, 20.0f,
1599 21.0f, 22.0f,
1600 29.0f, 30.0f,
1601 31.0f, 32.0f
1602 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001603 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001604
1605 return result;
1606}
1607
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001608template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001609LayerTestResult<T, 4> Concat4dDim3TestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001610 IWorkloadFactory& workloadFactory,
1611 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001612 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001613 float qScale,
1614 int32_t qOffset,
1615 bool useSubtensor)
1616{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001617 TensorInfo outputTensorInfo({ 1, 3, 2, 6 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001618
1619 LayerTestResult<T, 4> result = Concat4dTestImpl<ArmnnType>(
Keith Davisf500d6c2020-08-31 08:32:55 +01001620 workloadFactory, memoryManager, tensorHandleFactory, outputTensorInfo, 3, useSubtensor, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001621
Sadik Armagan483c8112021-06-01 09:24:52 +01001622 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001623 {
1624 1.0f, 2.0f,
1625 11.0f, 12.0f,
1626 21.0f, 22.0f,
1627 3.0f, 4.0f,
1628 13.0f, 14.0f,
1629 23.0f, 24.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001630
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001631 5.0f, 6.0f,
1632 15.0f, 16.0f,
1633 25.0f, 26.0f,
1634 7.0f, 8.0f,
1635 17.0f, 18.0f,
1636 27.0f, 28.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001637
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001638 9.0f, 10.0f,
1639 19.0f, 20.0f,
1640 29.0f, 30.0f,
1641 11.0f, 12.0f,
1642 21.0f, 22.0f,
1643 31.0f, 32.0f
1644 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001645 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001646
1647 return result;
1648}
1649
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001650template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001651LayerTestResult<T, 4> Concat4dDiffShapeDim0TestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001652 IWorkloadFactory& workloadFactory,
1653 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001654 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001655 float qScale,
1656 int32_t qOffset)
1657{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001658 constexpr unsigned int dimension = 0u;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001659
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001660 TensorInfo inputTensorInfo0({ 1, 3, 2, 2 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001661 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001662 {
1663 1.0f, 2.0f,
1664 3.0f, 4.0f,
1665 5.0f, 6.0f,
1666 7.0f, 8.0f,
1667 9.0f, 10.0f,
1668 11.0f, 12.0f
1669 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001670 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001671
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001672 TensorInfo inputTensorInfo1({ 2, 3, 2, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001673
Sadik Armagan483c8112021-06-01 09:24:52 +01001674 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001675 {
1676 11.0f, 12.0f,
1677 13.0f, 14.0f,
1678 15.0f, 16.0f,
1679 17.0f, 18.0f,
1680 19.0f, 20.0f,
1681 21.0f, 22.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001682
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001683 21.0f, 22.0f,
1684 23.0f, 24.0f,
1685 25.0f, 26.0f,
1686 27.0f, 28.0f,
1687 29.0f, 30.0f,
1688 31.0f, 32.0f
1689 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001690 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001691
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001692 TensorInfo outputTensorInfo({ 3, 3, 2, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001693
1694 LayerTestResult<T, 4> result(outputTensorInfo);
1695
1696 std::vector<T> output;
1697 output.resize(outputTensorInfo.GetNumElements());
1698 Concatenate<T>(workloadFactory,
1699 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001700 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001701 {inputTensorInfo0, inputTensorInfo1},
1702 {input0.data(), input1.data()},
1703 outputTensorInfo,
1704 output.data(),
1705 dimension,
1706 true);
1707
Sadik Armagan483c8112021-06-01 09:24:52 +01001708 result.m_ActualData = output;
1709 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001710 {
1711 1.0f, 2.0f,
1712 3.0f, 4.0f,
1713 5.0f, 6.0f,
1714 7.0f, 8.0f,
1715 9.0f, 10.0f,
1716 11.0f, 12.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001717
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001718 11.0f, 12.0f,
1719 13.0f, 14.0f,
1720 15.0f, 16.0f,
1721 17.0f, 18.0f,
1722 19.0f, 20.0f,
1723 21.0f, 22.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001724
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001725 21.0f, 22.0f,
1726 23.0f, 24.0f,
1727 25.0f, 26.0f,
1728 27.0f, 28.0f,
1729 29.0f, 30.0f,
1730 31.0f, 32.0f
1731 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001732 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001733
1734 return result;
1735}
1736
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001737template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001738LayerTestResult<T, 4> Concat4dDiffShapeDim1TestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001739 IWorkloadFactory& workloadFactory,
1740 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001741 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001742 float qScale,
1743 int32_t qOffset)
1744{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001745 constexpr unsigned int dimension = 1u;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001746
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001747 TensorInfo inputTensorInfo0({ 1, 3, 2, 2 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001748 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001749 {
1750 1.0f, 2.0f,
1751 3.0f, 4.0f,
1752 5.0f, 6.0f,
1753 7.0f, 8.0f,
1754 9.0f, 10.0f,
1755 11.0f, 12.0f
1756 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001757 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001758
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001759 TensorInfo inputTensorInfo1({ 1, 2, 2, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001760
Sadik Armagan483c8112021-06-01 09:24:52 +01001761 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001762 {
1763 11.0f, 12.0f,
1764 13.0f, 14.0f,
1765 15.0f, 16.0f,
1766 17.0f, 18.0f,
1767 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001768 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001769
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001770 TensorInfo outputTensorInfo({ 1, 5, 2, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001771
1772 LayerTestResult<T, 4> result(outputTensorInfo);
1773
1774 std::vector<T> output;
1775 output.resize(outputTensorInfo.GetNumElements());
1776 Concatenate<T>(workloadFactory,
1777 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001778 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001779 {inputTensorInfo0, inputTensorInfo1},
1780 {input0.data(), input1.data()},
1781 outputTensorInfo,
1782 output.data(),
1783 dimension,
1784 true);
1785
Sadik Armagan483c8112021-06-01 09:24:52 +01001786 result.m_ActualData = output;
1787 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001788 {
1789 1.0f, 2.0f,
1790 3.0f, 4.0f,
1791 5.0f, 6.0f,
1792 7.0f, 8.0f,
1793 9.0f, 10.0f,
1794 11.0f, 12.0f,
1795 11.0f, 12.0f,
1796 13.0f, 14.0f,
1797 15.0f, 16.0f,
1798 17.0f, 18.0f
1799 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001800 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001801
1802 return result;
1803}
1804
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001805template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001806LayerTestResult<T, 4> Concat4dDiffShapeDim2TestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001807 IWorkloadFactory& workloadFactory,
1808 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001809 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001810 float qScale,
1811 int32_t qOffset)
1812{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001813 constexpr unsigned int dimension = 2u;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001814
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001815 TensorInfo inputTensorInfo0({ 1, 3, 2, 2 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001816 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001817 {
1818 1.0f, 2.0f,
1819 3.0f, 4.0f,
1820 5.0f, 6.0f,
1821 7.0f, 8.0f,
1822 9.0f, 10.0f,
1823 11.0f, 12.0f
1824 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001825 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001826
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001827 TensorInfo inputTensorInfo1({ 1, 3, 3, 2 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001828 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001829 {
1830 11.0f, 12.0f,
1831 13.0f, 14.0f,
1832 15.0f, 16.0f,
1833 17.0f, 18.0f,
1834 19.0f, 20.0f,
1835 21.0f, 22.0f,
1836 23.0f, 24.0f,
1837 25.0f, 26.0f,
1838 27.0f, 28.0f
1839 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001840 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001841
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001842 TensorInfo outputTensorInfo({ 1, 3, 5, 2 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001843 LayerTestResult<T, 4> result(outputTensorInfo);
1844
1845 std::vector<T> output;
1846 output.resize(outputTensorInfo.GetNumElements());
1847 Concatenate<T>(workloadFactory,
1848 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001849 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001850 {inputTensorInfo0, inputTensorInfo1},
1851 {input0.data(), input1.data()},
1852 outputTensorInfo,
1853 output.data(),
1854 dimension,
1855 true);
1856
Sadik Armagan483c8112021-06-01 09:24:52 +01001857 result.m_ActualData = output;
1858 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001859 {
1860 1.0f, 2.0f,
1861 3.0f, 4.0f,
1862 11.0f, 12.0f,
1863 13.0f, 14.0f,
1864 15.0f, 16.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001865
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001866 5.0f, 6.0f,
1867 7.0f, 8.0f,
1868 17.0f, 18.0f,
1869 19.0f, 20.0f,
1870 21.0f, 22.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001871
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001872 9.0f, 10.0f,
1873 11.0f, 12.0f,
1874 23.0f, 24.0f,
1875 25.0f, 26.0f,
1876 27.0f, 28.0f
1877 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001878 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001879
1880 return result;
1881}
1882
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001883template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001884LayerTestResult<T, 4> Concat4dDiffShapeDim3TestImpl(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001885 IWorkloadFactory& workloadFactory,
1886 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001887 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001888 float qScale,
1889 int32_t qOffset,
1890 bool useSubtensor)
1891{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001892 constexpr unsigned int dimension = 3u;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001893
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001894 TensorInfo inputTensorInfo0({ 1, 3, 2, 2 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001895 auto input0 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001896 {
1897 1.0f, 2.0f,
1898 3.0f, 4.0f,
1899 5.0f, 6.0f,
1900 7.0f, 8.0f,
1901 9.0f, 10.0f,
1902 11.0f, 12.0f
1903 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001904 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001905
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001906 TensorInfo inputTensorInfo1({ 1, 3, 2, 3 }, ArmnnType, qScale, qOffset);
Sadik Armagan483c8112021-06-01 09:24:52 +01001907 auto input1 = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001908 {
1909 11.0f, 12.0f, 13.0f,
1910 14.0f, 15.0f, 16.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001911
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001912 17.0f, 18.0f, 19.0f,
1913 20.0f, 21.0f, 22.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001914
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001915 23.0f, 24.0f, 25.0f,
1916 26.0f, 27.0f, 28.0f
1917 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001918 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001919
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001920 TensorInfo outputTensorInfo({ 1, 3, 2, 5 }, ArmnnType, qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001921
1922 LayerTestResult<T, 4> result(outputTensorInfo);
1923
1924 std::vector<T> output;
1925 output.resize(outputTensorInfo.GetNumElements());
1926 Concatenate<T>(workloadFactory,
1927 memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001928 tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001929 {inputTensorInfo0, inputTensorInfo1},
1930 {input0.data(), input1.data()},
1931 outputTensorInfo,
1932 output.data(),
1933 dimension,
1934 useSubtensor);
1935
Sadik Armagan483c8112021-06-01 09:24:52 +01001936 result.m_ActualData = output;
1937 result.m_ExpectedData = QuantizedVector<T>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001938 {
1939 1.0f, 2.0f, 11.0f, 12.0f, 13.0f,
1940 3.0f, 4.0f, 14.0f, 15.0f, 16.0f,
1941 5.0f, 6.0f, 17.0f, 18.0f, 19.0f,
1942 7.0f, 8.0f, 20.0f, 21.0f, 22.0f,
1943 9.0f, 10.0f, 23.0f, 24.0f, 25.0f,
1944 11.0f, 12.0f, 26.0f, 27.0f, 28.0f
1945 },
Sadik Armagan483c8112021-06-01 09:24:52 +01001946 qScale, qOffset);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001947
1948 return result;
1949}
1950
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001951template<DataType ArmnnType, typename T>
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001952LayerTestResult<T, 3> ConcatDifferentInputOutputQParamTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001953 IWorkloadFactory& workloadFactory,
1954 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01001955 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001956 bool useSubtensor)
1957{
Jan Eilers8eb25602020-03-09 12:13:48 +00001958 IgnoreUnused(memoryManager);
Derek Lambertic374ff02019-12-10 21:57:35 +00001959
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001960 // Defines the tensor descriptors.
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001961 TensorInfo outputTensorInfo({ 3, 6, 3 }, ArmnnType);
1962 TensorInfo inputTensorInfo1({ 3, 6, 2 }, ArmnnType);
1963 TensorInfo inputTensorInfo2({ 3, 6, 1 }, ArmnnType);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001964
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001965 std::vector<TensorShape> inputTensorShapes({inputTensorInfo1.GetShape(), inputTensorInfo2.GetShape()});
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001966
1967 // Quantized input1 tensor.
1968 const float inputScale1 = 0.5f;
1969 const int32_t inputOffset1 = 5;
1970
Sadik Armagan483c8112021-06-01 09:24:52 +01001971 std::vector<T> input1 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001972 {
1973 1, 2, 3,
1974 4, 5, 6,
1975 7, 8, 9,
1976 10, 11, 12,
1977 13, 14, 15,
1978 16, 17, 18,
1979
1980 19, 20, 21,
1981 22, 23, 24,
1982 25, 26, 27,
1983 28, 29, 30,
1984 31, 32, 33,
1985 34, 35, 36
Sadik Armagan483c8112021-06-01 09:24:52 +01001986 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001987
1988 // Quatized input2 tensor.
1989 const float inputScale2 = 0.2f;
1990 const int32_t inputOffset2 = 10;
1991
Sadik Armagan483c8112021-06-01 09:24:52 +01001992 std::vector<T> input2 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001993 {
1994 37, 38, 39,
1995 40, 41, 42,
1996 43, 44, 45,
1997 46, 47, 48,
1998 49, 50, 51,
1999 52, 53, 54
Sadik Armagan483c8112021-06-01 09:24:52 +01002000 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002001
2002 // Quantized output tensor.
2003 const float outputScale = 0.1f;
2004 const int32_t outputOffset = 20;
2005
Sadik Armagan483c8112021-06-01 09:24:52 +01002006 std::vector<T> actualOutput(outputTensorInfo.GetNumElements());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002007
Sadik Armagan483c8112021-06-01 09:24:52 +01002008 std::vector<T> expectedOutput =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002009 {
2010 0, 5, 74,
2011 10, 15, 76,
2012 20, 25, 78,
2013 30, 35, 80,
2014 40, 45, 82,
2015 50, 55, 84,
2016
2017 60, 65, 86,
2018 70, 75, 88,
2019 80, 85, 90,
2020 90, 95, 92,
2021 100, 105, 94,
2022 110, 115, 96,
2023
2024 120, 125, 98,
2025 130, 135, 100,
2026 140, 145, 102,
2027 150, 155, 104,
2028 160, 165, 106,
2029 170, 175, 108
Sadik Armagan483c8112021-06-01 09:24:52 +01002030 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002031
2032 outputTensorInfo.SetQuantizationScale(outputScale);
2033 outputTensorInfo.SetQuantizationOffset(outputOffset);
2034 inputTensorInfo1.SetQuantizationScale(inputScale1);
2035 inputTensorInfo1.SetQuantizationOffset(inputOffset1);
2036 inputTensorInfo2.SetQuantizationScale(inputScale2);
2037 inputTensorInfo2.SetQuantizationOffset(inputOffset2);
2038
2039 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 +01002040 ConcatQueueDescriptor::ViewOrigin window1(wOrigin1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002041
2042 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 +01002043 ConcatQueueDescriptor::ViewOrigin window2(wOrigin2);
Keith Davisf500d6c2020-08-31 08:32:55 +01002044
2045 std::unique_ptr<ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
2046
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002047 bool subTensorsSupported = useSubtensor && workloadFactory.SupportsSubTensors();
Keith Davisf500d6c2020-08-31 08:32:55 +01002048
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002049 std::unique_ptr<ITensorHandle> inputHandle1 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002050 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +01002051 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo1.GetShape(), wOrigin1.data()) :
2052 tensorHandleFactory.CreateTensorHandle(inputTensorInfo1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002053
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002054 std::unique_ptr<ITensorHandle> inputHandle2 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002055 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +01002056 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo2.GetShape(), wOrigin2.data()) :
2057 tensorHandleFactory.CreateTensorHandle(inputTensorInfo2);
2058
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002059 ConcatQueueDescriptor data;
2060 OriginsDescriptor desc = CreateDescriptorForConcatenation(
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002061 inputTensorShapes.begin(),inputTensorShapes.end(), 2);
2062 data.m_Parameters = desc;
2063
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002064 WorkloadInfo info;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002065 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
2066 AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
2067 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
2068
2069 data.m_ViewOrigins.push_back(window1);
2070 data.m_ViewOrigins.push_back(window2);
2071
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002072 std::unique_ptr<IWorkload> workload = workloadFactory.CreateConcat(data, info);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002073
2074 inputHandle1->Allocate();
2075 inputHandle2->Allocate();
2076 outputHandle->Allocate();
2077
Sadik Armagan483c8112021-06-01 09:24:52 +01002078 CopyDataToITensorHandle(inputHandle1.get(), input1.data());
2079 CopyDataToITensorHandle(inputHandle2.get(), input2.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002080
2081 workload->PostAllocationConfigure();
2082 workload->Execute();
2083
Sadik Armagan483c8112021-06-01 09:24:52 +01002084 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002085
Sadik Armagan483c8112021-06-01 09:24:52 +01002086 return LayerTestResult<T, 3>(actualOutput,
2087 expectedOutput,
2088 outputHandle->GetShape(),
2089 outputTensorInfo.GetShape());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002090}
2091
2092//
2093// Explicit template specializations
2094//
2095
Derek Lambertif90c56d2020-01-10 17:14:08 +00002096template LayerTestResult<ResolveType<DataType::QAsymmU8>, 3>
2097ConcatDifferentInputOutputQParamTest<DataType::QAsymmU8>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002098 IWorkloadFactory& workloadFactory,
2099 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002100 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002101 bool useSubtensor);
2102
Derek Lambertif90c56d2020-01-10 17:14:08 +00002103template LayerTestResult<ResolveType<DataType::QSymmS16>, 3>
2104ConcatDifferentInputOutputQParamTest<DataType::QSymmS16>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002105 IWorkloadFactory& workloadFactory,
2106 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002107 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002108 bool useSubtensor);
2109
2110//
2111// Implementation functions
2112//
2113
2114LayerTestResult<float,3> ConcatTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002115 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002116 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2117 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002118{
Jan Eilers8eb25602020-03-09 12:13:48 +00002119 IgnoreUnused(memoryManager);
Derek Lambertic374ff02019-12-10 21:57:35 +00002120
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002121 unsigned int outputWidth = 3;
2122 unsigned int outputHeight = 6;
2123 unsigned int outputChannels = 3;
2124
2125 unsigned int inputWidth1 = 3;
2126 unsigned int inputHeight1 = 6;
2127 unsigned int inputChannels1 = 2;
2128
2129 unsigned int inputWidth2 = 3;
2130 unsigned int inputHeight2 = 6;
2131 unsigned int inputChannels2 = 1;
2132
2133 // Define the tensor descriptors.
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002134 TensorInfo outputTensorInfo({ outputChannels, outputHeight, outputWidth }, DataType::Float32);
2135 TensorInfo inputTensorInfo1({ inputChannels1, inputHeight1, inputWidth1 }, DataType::Float32);
2136 TensorInfo inputTensorInfo2({ inputChannels2, inputHeight2, inputWidth2 }, DataType::Float32);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002137
Sadik Armagan483c8112021-06-01 09:24:52 +01002138 std::vector<float> actualOutput(outputTensorInfo.GetNumElements());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002139
Sadik Armagan483c8112021-06-01 09:24:52 +01002140 std::vector<float> expectedOutput =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002141 {
Sadik Armagan483c8112021-06-01 09:24:52 +01002142 1.0f, 2.0f, 3.0f,
2143 4.0f, 5.0f, 6.0f,
2144 7.0f, 8.0f, 9.0f,
2145 10.0f, 11.0f, 12.0f,
2146 13.0f, 14.0f, 15.0f,
2147 16.0f, 17.0f, 18.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002148
Sadik Armagan483c8112021-06-01 09:24:52 +01002149 19.0f, 20.0f, 21.0f,
2150 22.0f, 23.0f, 24.0f,
2151 25.0f, 26.0f, 27.0f,
2152 28.0f, 29.0f, 30.0f,
2153 31.0f, 32.0f, 33.0f,
2154 34.0f, 35.0f, 36.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002155
Sadik Armagan483c8112021-06-01 09:24:52 +01002156 37.0f, 38.0f, 39.0f,
2157 40.0f, 41.0f, 42.0f,
2158 43.0f, 44.0f, 45.0f,
2159 46.0f, 47.0f, 48.0f,
2160 49.0f, 50.0f, 51.0f,
2161 52.0f, 53.0f, 54.0f
2162 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002163
Sadik Armagan483c8112021-06-01 09:24:52 +01002164 std::vector<float> input1 =
2165 {
2166 1.0f, 2.0f, 3.0f,
2167 4.0f, 5.0f, 6.0f,
2168 7.0f, 8.0f, 9.0f,
2169 10.0f, 11.0f, 12.0f,
2170 13.0f, 14.0f, 15.0f,
2171 16.0f, 17.0f, 18.0f,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002172
Sadik Armagan483c8112021-06-01 09:24:52 +01002173 19.0f, 20.0f, 21.0f,
2174 22.0f, 23.0f, 24.0f,
2175 25.0f, 26.0f, 27.0f,
2176 28.0f, 29.0f, 30.0f,
2177 31.0f, 32.0f, 33.0f,
2178 34.0f, 35.0f, 36.0f
2179 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002180
Sadik Armagan483c8112021-06-01 09:24:52 +01002181 std::vector<float> input2 =
2182 {
2183 37.0f, 38.0f, 39.0f,
2184 40.0f, 41.0f, 42.0f,
2185 43.0f, 44.0f, 45.0f,
2186 46.0f, 47.0f, 48.0f,
2187 49.0f, 50.0f, 51.0f,
2188 52.0f, 53.0f, 54.0f,
2189 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002190
2191 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 +01002192 ConcatQueueDescriptor::ViewOrigin window1(wOrigin1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002193
2194 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 +01002195 ConcatQueueDescriptor::ViewOrigin window2(wOrigin2);
Keith Davisf500d6c2020-08-31 08:32:55 +01002196
2197 std::unique_ptr<ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002198
2199 bool subTensorsSupported = workloadFactory.SupportsSubTensors();
2200
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002201 std::unique_ptr<ITensorHandle> inputHandle1 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002202 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +01002203 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo1.GetShape(), wOrigin1.data()) :
2204 tensorHandleFactory.CreateTensorHandle(inputTensorInfo1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002205
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002206 std::unique_ptr<ITensorHandle> inputHandle2 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002207 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +01002208 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo2.GetShape(), wOrigin2.data()) :
2209 tensorHandleFactory.CreateTensorHandle(inputTensorInfo2);
2210
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002211 ConcatQueueDescriptor data;
2212 WorkloadInfo info;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002213 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
2214 AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
2215 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
2216
2217 data.m_ViewOrigins.push_back(window1);
2218 data.m_ViewOrigins.push_back(window2);
2219
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002220 std::unique_ptr<IWorkload> workload = workloadFactory.CreateConcat(data, info);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002221
2222 inputHandle1->Allocate();
2223 inputHandle2->Allocate();
2224 outputHandle->Allocate();
2225
Sadik Armagan483c8112021-06-01 09:24:52 +01002226 CopyDataToITensorHandle(inputHandle1.get(), input1.data());
2227 CopyDataToITensorHandle(inputHandle2.get(), input2.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002228
2229 workload->PostAllocationConfigure();
2230 workload->Execute();
2231
Sadik Armagan483c8112021-06-01 09:24:52 +01002232 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002233
Sadik Armagan483c8112021-06-01 09:24:52 +01002234 return LayerTestResult<float, 3>(actualOutput,
2235 expectedOutput,
2236 outputHandle->GetShape(),
2237 outputTensorInfo.GetShape());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002238}
2239
2240LayerTestResult<float, 1> Concat1dTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002241 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002242 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2243 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002244{
Keith Davisf500d6c2020-08-31 08:32:55 +01002245 return Concat1dTestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002246}
2247
2248LayerTestResult<float, 2> Concat2dDim0Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002249 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002250 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2251 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002252{
Keith Davisf500d6c2020-08-31 08:32:55 +01002253 return Concat2dDim0TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002254}
2255
2256LayerTestResult<float, 2> Concat2dDim1Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002257 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002258 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2259 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002260{
Keith Davisf500d6c2020-08-31 08:32:55 +01002261 return Concat2dDim1TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002262}
2263
2264LayerTestResult<float, 2> Concat2dDim0DiffInputDimsTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002265 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002266 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2267 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002268{
Keith Davisf500d6c2020-08-31 08:32:55 +01002269 return Concat2dDim0DiffInputDimsTestImpl<DataType::Float32>(workloadFactory, memoryManager,
2270 tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002271}
2272
2273LayerTestResult<float, 2> Concat2dDim1DiffInputDimsTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002274 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002275 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2276 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002277{
Keith Davisf500d6c2020-08-31 08:32:55 +01002278 return Concat2dDim1DiffInputDimsTestImpl<DataType::Float32>(workloadFactory,
2279 memoryManager,
2280 tensorHandleFactory,
2281 0.0f,
2282 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002283}
2284
2285LayerTestResult<float, 3> Concat3dDim0Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002286 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002287 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2288 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002289{
Keith Davisf500d6c2020-08-31 08:32:55 +01002290 return Concat3dDim0TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002291}
2292
2293LayerTestResult<float, 3> Concat3dDim1Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002294 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002295 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2296 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002297{
Keith Davisf500d6c2020-08-31 08:32:55 +01002298 return Concat3dDim1TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002299}
2300
2301LayerTestResult<float, 3> Concat3dDim2Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002302 IWorkloadFactory& workloadFactory,
2303 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002304 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002305 bool useSubtensor)
2306{
Keith Davisf500d6c2020-08-31 08:32:55 +01002307 return Concat3dDim2TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory,
2308 useSubtensor, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002309}
2310
2311LayerTestResult<float, 3> Concat3dDim0DiffInputDimsTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002312 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002313 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2314 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002315{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002316 return Concat3dDim0DiffInputDimsTestImpl<DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002317 workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002318}
2319
2320LayerTestResult<float, 3> Concat3dDim1DiffInputDimsTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002321 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002322 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2323 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002324{
Keith Davisf500d6c2020-08-31 08:32:55 +01002325 return Concat3dDim1DiffInputDimsTestImpl<DataType::Float32>(workloadFactory, memoryManager,
2326 tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002327}
2328
2329LayerTestResult<float, 3> Concat3dDim2DiffInputDimsTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002330 IWorkloadFactory& workloadFactory,
2331 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002332 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002333 bool useSubtensor)
2334{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002335 return Concat3dDim2DiffInputDimsTestImpl<DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002336 workloadFactory, memoryManager, tensorHandleFactory, useSubtensor, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002337}
2338
2339LayerTestResult<float, 4> Concat4dDim0Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002340 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002341 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2342 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002343{
Keith Davisf500d6c2020-08-31 08:32:55 +01002344 return Concat4dDim0TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002345}
2346
2347LayerTestResult<float, 4> Concat4dDim1Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002348 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002349 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2350 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002351{
Keith Davisf500d6c2020-08-31 08:32:55 +01002352 return Concat4dDim1TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002353}
2354
2355LayerTestResult<float, 4> Concat4dDim2Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002356 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002357 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2358 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002359{
Keith Davisf500d6c2020-08-31 08:32:55 +01002360 return Concat4dDim2TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002361}
2362
2363LayerTestResult<float, 4> Concat4dDim3Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002364 IWorkloadFactory& workloadFactory,
2365 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002366 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002367 bool useSubtensor)
2368{
Keith Davisf500d6c2020-08-31 08:32:55 +01002369 return Concat4dDim3TestImpl<DataType::Float32>(workloadFactory, memoryManager,
2370 tensorHandleFactory, 0.0f, 0, useSubtensor);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002371}
2372
2373LayerTestResult<float, 4> Concat4dDiffShapeDim0Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002374 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002375 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2376 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002377{
Keith Davisf500d6c2020-08-31 08:32:55 +01002378 return Concat4dDiffShapeDim0TestImpl<DataType::Float32>(workloadFactory, memoryManager,
2379 tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002380}
2381
2382LayerTestResult<float, 4> Concat4dDiffShapeDim1Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002383 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002384 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2385 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002386{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002387 return Concat4dDiffShapeDim1TestImpl<DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002388 workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002389}
2390
2391LayerTestResult<float, 4> Concat4dDiffShapeDim2Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002392 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002393 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2394 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002395{
Keith Davisf500d6c2020-08-31 08:32:55 +01002396 return Concat4dDiffShapeDim2TestImpl<DataType::Float32>(workloadFactory, memoryManager,
2397 tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002398}
2399
2400LayerTestResult<float, 4> Concat4dDiffShapeDim3Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002401 IWorkloadFactory& workloadFactory,
2402 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002403 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002404 bool useSubtensor)
2405{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002406 return Concat4dDiffShapeDim3TestImpl<DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002407 workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0, useSubtensor);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002408}
2409
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002410LayerTestResult<Half, 3> ConcatFloat16Test(
2411 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002412 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2413 const armnn::ITensorHandleFactory& tensorHandleFactory)
Matthew Jackson9bff1442019-09-12 09:08:23 +01002414{
Keith Davisf500d6c2020-08-31 08:32:55 +01002415 return Concat3dDim1TestImpl<DataType::Float16>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Matthew Jackson9bff1442019-09-12 09:08:23 +01002416}
2417
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00002418LayerTestResult<BFloat16, 3> ConcatBFloat16Test(
2419 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002420 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2421 const armnn::ITensorHandleFactory& tensorHandleFactory)
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00002422{
Keith Davisf500d6c2020-08-31 08:32:55 +01002423 return Concat3dDim1TestImpl<DataType::BFloat16>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00002424}
2425
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002426LayerTestResult<uint8_t, 3> ConcatUint8DifferentQParamsTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002427 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002428 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2429 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002430{
Jan Eilers8eb25602020-03-09 12:13:48 +00002431 IgnoreUnused(memoryManager);
Derek Lambertic374ff02019-12-10 21:57:35 +00002432
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002433 unsigned int outputWidth = 3;
2434 unsigned int outputHeight = 6;
2435 unsigned int outputChannels = 3;
2436
2437 unsigned int inputWidth1 = 3;
2438 unsigned int inputHeight1 = 6;
2439 unsigned int inputChannels1 = 2;
2440
2441 unsigned int inputWidth2 = 3;
2442 unsigned int inputHeight2 = 6;
2443 unsigned int inputChannels2 = 1;
2444
2445 // Defines the tensor descriptors.
Derek Lambertif90c56d2020-01-10 17:14:08 +00002446 TensorInfo outputTensorInfo({ outputChannels, outputHeight, outputWidth }, DataType::QAsymmU8);
2447 TensorInfo inputTensorInfo1({ inputChannels1, inputHeight1, inputWidth1 }, DataType::QAsymmU8);
2448 TensorInfo inputTensorInfo2({ inputChannels2, inputHeight2, inputWidth2 }, DataType::QAsymmU8);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002449
2450 // Quantized input1 tensor. Range [-3, 1]
2451 const float inputScale1 = 0.015686f;
2452 const int32_t inputOffset1 = 192;
2453
Sadik Armagan483c8112021-06-01 09:24:52 +01002454 std::vector<uint8_t> input1 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002455 {
2456 1, 2, 3,
2457 4, 5, 6,
2458 7, 8, 9,
2459 10, 11, 12,
2460 13, 14, 15,
2461 16, 17, 18,
2462
2463 19, 20, 21,
2464 22, 23, 24,
2465 25, 26, 27,
2466 28, 29, 30,
2467 31, 32, 33,
Sadik Armagan483c8112021-06-01 09:24:52 +01002468 34, 35, 36
2469 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002470
2471 // Quatized input2 tensor. Range [-1, 4]
2472 const float inputScale2 = 0.019608f;
2473 const int32_t inputOffset2 = 50;
2474
Sadik Armagan483c8112021-06-01 09:24:52 +01002475 std::vector<uint8_t> input2 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002476 {
2477 37, 38, 39,
2478 40, 41, 42,
2479 43, 44, 45,
2480 46, 47, 48,
2481 49, 50, 51,
Sadik Armagan483c8112021-06-01 09:24:52 +01002482 52, 53, 54
2483 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002484
2485 // Output has the same quantization parameters than input1,
2486 // so that only the requantization of input2 is required
2487 const float outputScale = 0.015686f;
2488 const int32_t outputOffset = 192;
2489
Sadik Armagan483c8112021-06-01 09:24:52 +01002490 std::vector<uint8_t> actualOutput(outputTensorInfo.GetNumElements());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002491
Sadik Armagan483c8112021-06-01 09:24:52 +01002492 std::vector<uint8_t> expectedOutput =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002493 {
2494 1, 2, 3,
2495 4, 5, 6,
2496 7, 8, 9,
2497 10, 11, 12,
2498 13, 14, 15,
2499 16, 17, 18,
2500
2501 19, 20, 21,
2502 22, 23, 24,
2503 25, 26, 27,
2504 28, 29, 30,
2505 31, 32, 33,
2506 34, 35, 36,
2507
2508 176, 177, 178,
2509 179, 181, 182,
2510 183, 184, 186,
2511 187, 188, 189,
2512 191, 192, 193,
Sadik Armagan483c8112021-06-01 09:24:52 +01002513 195, 196, 197
2514 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002515
2516 outputTensorInfo.SetQuantizationScale(outputScale);
2517 outputTensorInfo.SetQuantizationOffset(outputOffset);
2518 inputTensorInfo1.SetQuantizationScale(inputScale1);
2519 inputTensorInfo1.SetQuantizationOffset(inputOffset1);
2520 inputTensorInfo2.SetQuantizationScale(inputScale2);
2521 inputTensorInfo2.SetQuantizationOffset(inputOffset2);
2522
2523 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 +01002524 ConcatQueueDescriptor::ViewOrigin window1(wOrigin1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002525
2526 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 +01002527 ConcatQueueDescriptor::ViewOrigin window2(wOrigin2);
Keith Davisf500d6c2020-08-31 08:32:55 +01002528
2529 std::unique_ptr<ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002530
2531 bool subTensorsSupported = workloadFactory.SupportsSubTensors();
2532
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002533 std::unique_ptr<ITensorHandle> inputHandle1 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002534 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +01002535 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo1.GetShape(), wOrigin1.data()) :
2536 tensorHandleFactory.CreateTensorHandle(inputTensorInfo1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002537
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002538 std::unique_ptr<ITensorHandle> inputHandle2 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002539 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +01002540 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo2.GetShape(), wOrigin2.data()) :
2541 tensorHandleFactory.CreateTensorHandle(inputTensorInfo2);
2542
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002543 ConcatQueueDescriptor data;
2544 WorkloadInfo info;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002545 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
2546 AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
2547 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
2548
2549 data.m_ViewOrigins.push_back(window1);
2550 data.m_ViewOrigins.push_back(window2);
2551
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002552 std::unique_ptr<IWorkload> workload = workloadFactory.CreateConcat(data, info);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002553
2554 inputHandle1->Allocate();
2555 inputHandle2->Allocate();
2556 outputHandle->Allocate();
2557
Sadik Armagan483c8112021-06-01 09:24:52 +01002558 CopyDataToITensorHandle(inputHandle1.get(), input1.data());
2559 CopyDataToITensorHandle(inputHandle2.get(), input2.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002560
2561 workload->PostAllocationConfigure();
2562 workload->Execute();
2563
Sadik Armagan483c8112021-06-01 09:24:52 +01002564 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002565
Sadik Armagan483c8112021-06-01 09:24:52 +01002566 return LayerTestResult<uint8_t, 3>(actualOutput,
2567 expectedOutput,
2568 outputHandle->GetShape(),
2569 outputTensorInfo.GetShape());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002570}
2571
2572LayerTestResult<uint8_t, 3> ConcatUint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002573 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002574 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2575 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002576{
Jan Eilers8eb25602020-03-09 12:13:48 +00002577 IgnoreUnused(memoryManager);
Derek Lambertic374ff02019-12-10 21:57:35 +00002578
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002579 unsigned int outputWidth = 3;
2580 unsigned int outputHeight = 6;
2581 unsigned int outputChannels = 3;
2582
2583 unsigned int inputWidth1 = 3;
2584 unsigned int inputHeight1 = 6;
2585 unsigned int inputChannels1 = 2;
2586
2587 unsigned int inputWidth2 = 3;
2588 unsigned int inputHeight2 = 6;
2589 unsigned int inputChannels2 = 1;
2590
2591 // Defines the tensor descriptors.
Derek Lambertif90c56d2020-01-10 17:14:08 +00002592 TensorInfo outputTensorInfo({ outputChannels, outputHeight, outputWidth }, DataType::QAsymmU8);
2593 TensorInfo inputTensorInfo1({ inputChannels1, inputHeight1, inputWidth1 }, DataType::QAsymmU8);
2594 TensorInfo inputTensorInfo2({ inputChannels2, inputHeight2, inputWidth2 }, DataType::QAsymmU8);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002595
2596 // Arbitrary scale and offsets. They don't really matter as the Concat operator doesn't dequantize/quantize them.
2597 const float scale = 0.13497836f;
2598 const int32_t offset = -7;
2599
2600 outputTensorInfo.SetQuantizationScale(scale);
2601 outputTensorInfo.SetQuantizationOffset(offset);
2602 inputTensorInfo1.SetQuantizationScale(scale);
2603 inputTensorInfo1.SetQuantizationOffset(offset);
2604 inputTensorInfo2.SetQuantizationScale(scale);
2605 inputTensorInfo2.SetQuantizationOffset(offset);
2606
Sadik Armagan483c8112021-06-01 09:24:52 +01002607 std::vector<uint8_t> actualOutput(outputTensorInfo.GetNumElements());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002608
Sadik Armagan483c8112021-06-01 09:24:52 +01002609 std::vector<uint8_t> expectedOutput =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002610 {
2611 1, 2, 3,
2612 4, 5, 6,
2613 7, 8, 9,
2614 10, 11, 12,
2615 13, 14, 15,
2616 16, 17, 18,
2617
2618 19, 20, 21,
2619 22, 23, 24,
2620 25, 26, 27,
2621 28, 29, 30,
2622 31, 32, 33,
2623 34, 35, 36,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002624
Sadik Armagan483c8112021-06-01 09:24:52 +01002625 37, 38, 39,
2626 40, 41, 42,
2627 43, 44, 45,
2628 46, 47, 48,
2629 49, 50, 51,
2630 52, 53, 54
2631 };
2632
2633 std::vector<uint8_t> input1 =
2634 {
2635 1, 2, 3,
2636 4, 5, 6,
2637 7, 8, 9,
2638 10, 11, 12,
2639 13, 14, 15,
2640 16, 17, 18,
2641
2642 19, 20, 21,
2643 22, 23, 24,
2644 25, 26, 27,
2645 28, 29, 30,
2646 31, 32, 33,
2647 34, 35, 36
2648 };
2649
2650 std::vector<uint8_t> input2 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002651 {
2652 37, 38, 39,
2653 40, 41, 42,
2654 43, 44, 45,
2655 46, 47, 48,
2656 49, 50, 51,
Sadik Armagan483c8112021-06-01 09:24:52 +01002657 52, 53, 54
2658 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002659
2660 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 +01002661 ConcatQueueDescriptor::ViewOrigin window1(wOrigin1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002662
2663 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 +01002664 ConcatQueueDescriptor::ViewOrigin window2(wOrigin2);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002665
Keith Davisf500d6c2020-08-31 08:32:55 +01002666 std::unique_ptr<ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002667
2668 bool subTensorsSupported = workloadFactory.SupportsSubTensors();
2669
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002670 std::unique_ptr<ITensorHandle> inputHandle1 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002671 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +01002672 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo1.GetShape(), wOrigin1.data()) :
2673 tensorHandleFactory.CreateTensorHandle(inputTensorInfo1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002674
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002675 std::unique_ptr<ITensorHandle> inputHandle2 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002676 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +01002677 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo2.GetShape(), wOrigin2.data()) :
2678 tensorHandleFactory.CreateTensorHandle(inputTensorInfo2);
2679
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002680
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002681 ConcatQueueDescriptor data;
2682 WorkloadInfo info;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002683 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
2684 AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
2685 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
2686
2687 data.m_ViewOrigins.push_back(window1);
2688 data.m_ViewOrigins.push_back(window2);
2689
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002690 std::unique_ptr<IWorkload> workload = workloadFactory.CreateConcat(data, info);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002691
2692 inputHandle1->Allocate();
2693 inputHandle2->Allocate();
2694 outputHandle->Allocate();
2695
Sadik Armagan483c8112021-06-01 09:24:52 +01002696 CopyDataToITensorHandle(inputHandle1.get(), input1.data());
2697 CopyDataToITensorHandle(inputHandle2.get(), input2.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002698
2699 workload->PostAllocationConfigure();
2700 workload->Execute();
2701
Sadik Armagan483c8112021-06-01 09:24:52 +01002702 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002703
Sadik Armagan483c8112021-06-01 09:24:52 +01002704 return LayerTestResult<uint8_t, 3>(actualOutput,
2705 expectedOutput,
2706 outputHandle->GetShape(),
2707 outputTensorInfo.GetShape());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002708}
2709
2710LayerTestResult<uint16_t, 3> ConcatUint16Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002711 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002712 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2713 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002714{
Jan Eilers8eb25602020-03-09 12:13:48 +00002715 IgnoreUnused(memoryManager);
Derek Lambertic374ff02019-12-10 21:57:35 +00002716
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002717 unsigned int outputWidth = 3;
2718 unsigned int outputHeight = 6;
2719 unsigned int outputChannels = 3;
2720
2721 unsigned int inputWidth1 = 3;
2722 unsigned int inputHeight1 = 6;
2723 unsigned int inputChannels1 = 2;
2724
2725 unsigned int inputWidth2 = 3;
2726 unsigned int inputHeight2 = 6;
2727 unsigned int inputChannels2 = 1;
2728
2729 // Defines the tensor descriptors.
Derek Lambertif90c56d2020-01-10 17:14:08 +00002730 TensorInfo outputTensorInfo({ outputChannels, outputHeight, outputWidth }, DataType::QSymmS16);
2731 TensorInfo inputTensorInfo1({ inputChannels1, inputHeight1, inputWidth1 }, DataType::QSymmS16);
2732 TensorInfo inputTensorInfo2({ inputChannels2, inputHeight2, inputWidth2 }, DataType::QSymmS16);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002733
2734 // Arbitrary scale and offsets. They don't really matter as the Concat operator doesn't dequantize/quantize them.
2735 const float scale = 0.13497836f;
2736 const int32_t offset = -7;
2737
2738 outputTensorInfo.SetQuantizationScale(scale);
2739 outputTensorInfo.SetQuantizationOffset(offset);
2740 inputTensorInfo1.SetQuantizationScale(scale);
2741 inputTensorInfo1.SetQuantizationOffset(offset);
2742 inputTensorInfo2.SetQuantizationScale(scale);
2743 inputTensorInfo2.SetQuantizationOffset(offset);
2744
Sadik Armagan483c8112021-06-01 09:24:52 +01002745 std::vector<uint16_t> actualOutput(outputTensorInfo.GetNumElements());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002746
Sadik Armagan483c8112021-06-01 09:24:52 +01002747 std::vector<uint16_t> expectedOutput =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002748 {
2749 1, 2, 3,
2750 4, 5, 6,
2751 7, 8, 9,
2752 10, 11, 12,
2753 13, 14, 15,
2754 16, 17, 18,
2755
2756 19, 20, 21,
2757 22, 23, 24,
2758 25, 26, 27,
2759 28, 29, 30,
2760 31, 32, 33,
2761 34, 35, 36,
2762
2763 37, 38, 39,
2764 40, 41, 42,
2765 43, 44, 45,
2766 46, 47, 48,
2767 49, 50, 51,
Sadik Armagan483c8112021-06-01 09:24:52 +01002768 52, 53, 54
2769 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002770
Sadik Armagan483c8112021-06-01 09:24:52 +01002771 std::vector<uint16_t> input1 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002772 {
2773 1, 2, 3,
2774 4, 5, 6,
2775 7, 8, 9,
2776 10, 11, 12,
2777 13, 14, 15,
2778 16, 17, 18,
2779
2780 19, 20, 21,
2781 22, 23, 24,
2782 25, 26, 27,
2783 28, 29, 30,
2784 31, 32, 33,
2785 34, 35, 36,
Sadik Armagan483c8112021-06-01 09:24:52 +01002786 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002787
Sadik Armagan483c8112021-06-01 09:24:52 +01002788 std::vector<uint16_t> input2 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002789 {
2790 37, 38, 39,
2791 40, 41, 42,
2792 43, 44, 45,
2793 46, 47, 48,
2794 49, 50, 51,
2795 52, 53, 54,
Sadik Armagan483c8112021-06-01 09:24:52 +01002796 };
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002797
2798 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 +01002799 ConcatQueueDescriptor::ViewOrigin window1(wOrigin1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002800
2801 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 +01002802 ConcatQueueDescriptor::ViewOrigin window2(wOrigin2);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002803
Keith Davisf500d6c2020-08-31 08:32:55 +01002804
2805 std::unique_ptr<ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002806
2807 bool subTensorsSupported = workloadFactory.SupportsSubTensors();
2808
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002809 std::unique_ptr<ITensorHandle> inputHandle1 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002810 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +01002811 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo1.GetShape(), wOrigin1.data()) :
2812 tensorHandleFactory.CreateTensorHandle(inputTensorInfo1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002813
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002814 std::unique_ptr<ITensorHandle> inputHandle2 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002815 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +01002816 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo2.GetShape(), wOrigin2.data()) :
2817 tensorHandleFactory.CreateTensorHandle(inputTensorInfo2);
2818
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002819
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002820 ConcatQueueDescriptor data;
2821 WorkloadInfo info;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002822 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
2823 AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
2824 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
2825
2826 data.m_ViewOrigins.push_back(window1);
2827 data.m_ViewOrigins.push_back(window2);
2828
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002829 std::unique_ptr<IWorkload> workload = workloadFactory.CreateConcat(data, info);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002830
2831 inputHandle1->Allocate();
2832 inputHandle2->Allocate();
2833 outputHandle->Allocate();
2834
Sadik Armagan483c8112021-06-01 09:24:52 +01002835 CopyDataToITensorHandle(inputHandle1.get(), input1.data());
2836 CopyDataToITensorHandle(inputHandle2.get(), input2.data());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002837
2838 workload->PostAllocationConfigure();
2839 workload->Execute();
2840
Sadik Armagan483c8112021-06-01 09:24:52 +01002841 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002842
Sadik Armagan483c8112021-06-01 09:24:52 +01002843 return LayerTestResult<uint16_t, 3>(actualOutput,
2844 expectedOutput,
2845 outputHandle->GetShape(),
2846 outputTensorInfo.GetShape());
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002847}
2848
2849LayerTestResult<uint8_t, 1> Concat1dUint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002850 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002851 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2852 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002853{
Keith Davisf500d6c2020-08-31 08:32:55 +01002854 return Concat1dTestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002855}
2856
2857LayerTestResult<uint8_t, 2> Concat2dDim0Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002858 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002859 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2860 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002861{
Keith Davisf500d6c2020-08-31 08:32:55 +01002862 return Concat2dDim0TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002863}
2864
2865LayerTestResult<uint8_t, 2> Concat2dDim1Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002866 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002867 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2868 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002869{
Keith Davisf500d6c2020-08-31 08:32:55 +01002870 return Concat2dDim1TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002871}
2872
2873LayerTestResult<uint8_t, 2> Concat2dDim0DiffInputDimsUint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002874 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002875 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2876 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002877{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002878 return Concat2dDim0DiffInputDimsTestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002879 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002880}
2881
2882LayerTestResult<uint8_t, 2> Concat2dDim1DiffInputDimsUint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002883 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002884 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2885 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002886{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002887 return Concat2dDim1DiffInputDimsTestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002888 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002889}
2890
2891LayerTestResult<uint8_t, 3> Concat3dDim0Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002892 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002893 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2894 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002895{
Keith Davisf500d6c2020-08-31 08:32:55 +01002896 return Concat3dDim0TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002897}
2898
2899LayerTestResult<uint8_t, 3> Concat3dDim1Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002900 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002901 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2902 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002903{
Keith Davisf500d6c2020-08-31 08:32:55 +01002904 return Concat3dDim1TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002905}
2906
2907LayerTestResult<uint8_t, 3> Concat3dDim2Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002908 IWorkloadFactory& workloadFactory,
2909 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002910 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002911 bool useSubtensor)
2912{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002913 return Concat3dDim2TestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002914 workloadFactory, memoryManager, tensorHandleFactory, useSubtensor, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002915}
2916
2917LayerTestResult<uint8_t, 3> Concat3dDim0DiffInputDimsUint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002918 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002919 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2920 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002921{
Keith Davisf500d6c2020-08-31 08:32:55 +01002922 return Concat3dDim0TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002923}
2924
2925LayerTestResult<uint8_t, 3> Concat3dDim1DiffInputDimsUint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002926 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002927 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2928 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002929{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002930 return Concat3dDim1DiffInputDimsTestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002931 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002932}
2933
2934LayerTestResult<uint8_t, 3> Concat3dDim2DiffInputDimsUint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002935 IWorkloadFactory& workloadFactory,
2936 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002937 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002938 bool useSubtensor)
2939{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002940 return Concat3dDim2DiffInputDimsTestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002941 workloadFactory, memoryManager, tensorHandleFactory, useSubtensor, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002942}
2943
2944LayerTestResult<uint8_t, 4> Concat4dDim0Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002945 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002946 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2947 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002948{
Keith Davisf500d6c2020-08-31 08:32:55 +01002949 return Concat4dDim0TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002950}
2951
2952LayerTestResult<uint8_t, 4> Concat4dDim1Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002953 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002954 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2955 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002956{
Keith Davisf500d6c2020-08-31 08:32:55 +01002957 return Concat4dDim1TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002958}
2959
2960LayerTestResult<uint8_t, 4> Concat4dDim2Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002961 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002962 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2963 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002964{
Keith Davisf500d6c2020-08-31 08:32:55 +01002965 return Concat4dDim2TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002966}
2967
2968LayerTestResult<uint8_t, 4> Concat4dDim3Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002969 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002970 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2971 const armnn::ITensorHandleFactory& tensorHandleFactory, bool useSubtensor)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002972{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002973 return Concat4dDim3TestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002974 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1, useSubtensor);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002975}
2976
2977LayerTestResult<uint8_t, 4> Concat4dDiffShapeDim0Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002978 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002979 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2980 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002981{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002982 return Concat4dDiffShapeDim0TestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002983 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002984}
2985
2986LayerTestResult<uint8_t, 4> Concat4dDiffShapeDim1Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002987 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002988 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2989 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002990{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002991 return Concat4dDiffShapeDim1TestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002992 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002993}
2994
2995LayerTestResult<uint8_t, 4> Concat4dDiffShapeDim2Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002996 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002997 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2998 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002999{
Derek Lambertif90c56d2020-01-10 17:14:08 +00003000 return Concat4dDiffShapeDim2TestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003001 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003002}
3003
3004LayerTestResult<uint8_t, 4> Concat4dDiffShapeDim3Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01003005 IWorkloadFactory& workloadFactory,
3006 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003007 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003008 bool useSubtensor)
3009{
Derek Lambertif90c56d2020-01-10 17:14:08 +00003010 return Concat4dDiffShapeDim3TestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003011 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1, useSubtensor);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003012}