blob: d486bc0c193d2bf952ac4501176a7d46330affba [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
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100431 auto input0 = MakeTensor<T, 1>(inputTensorInfo, QuantizedVector<T>({ 1.0f, 2.0f, 3.0f }, qScale, qOffset));
432 auto input1 = MakeTensor<T, 1>(inputTensorInfo, QuantizedVector<T>({ 4.0f, 5.0f, 6.0f }, qScale, qOffset));
433 auto input2 = MakeTensor<T, 1>(inputTensorInfo, 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
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100449 result.output = MakeTensor<T, 1>(outputTensorInfo, output);
450 result.outputExpected = MakeTensor<T, 1>(outputTensorInfo, QuantizedVector<T>(
451 {
452 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f
453 },
454 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
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100471 auto input0 = MakeTensor<T, 2>(inputTensorInfo, QuantizedVector<T>(
472 {
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 },
479 qScale, qOffset));
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100480
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100481 auto input1 = MakeTensor<T, 2>(inputTensorInfo, QuantizedVector<T>(
482 {
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 },
489 qScale, qOffset));
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100490
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100491 auto input2 = MakeTensor<T, 2>(inputTensorInfo, QuantizedVector<T>(
492 {
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 },
499 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
513 result.output = MakeTensor<T, 2>(outputTensorInfo, output);
514 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
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100530 result.outputExpected = MakeTensor<T, 2>(outputTensorInfo, QuantizedVector<T>(
531 {
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 },
550 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
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100568 result.outputExpected = MakeTensor<T, 2>(outputTensorInfo, QuantizedVector<T>(
569 {
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 },
576 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);
590 auto input0 = MakeTensor<T, 2>(input0TensorInfo, QuantizedVector<T>(
591 {
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 },
598 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);
601 auto input1 = MakeTensor<T, 2>(input1TensorInfo, QuantizedVector<T>(
602 {
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 },
612 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);
615 auto input2 = MakeTensor<T, 2>(input2TensorInfo, QuantizedVector<T>(
616 {
617 // Batch 1
618 16.0f, 17.0f, 18.0f,
619 },
620 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
635 result.output = MakeTensor<T, 2>(outputTensorInfo, output);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100636 result.outputExpected = MakeTensor<T, 2>(outputTensorInfo, QuantizedVector<T>(
637 {
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 },
656 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);
670 auto input0 = MakeTensor<T, 2>(input0TensorInfo, QuantizedVector<T>(
671 {
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 },
678 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);
681 auto input1 = MakeTensor<T, 2>(input1TensorInfo, QuantizedVector<T>(
682 {
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 },
689 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);
692 auto input2 = MakeTensor<T, 2>(input2TensorInfo, QuantizedVector<T>(
693 {
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 },
700 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
715 result.output = MakeTensor<T, 2>(outputTensorInfo, output);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100716 result.outputExpected = MakeTensor<T, 2>(outputTensorInfo, QuantizedVector<T>(
717 {
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 },
724 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
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100742 auto input0 = MakeTensor<T, 3>(inputTensorInfo, QuantizedVector<T>(
743 {
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 },
762 qScale, qOffset));
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +0100763
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100764 auto input1 = MakeTensor<T, 3>(inputTensorInfo, QuantizedVector<T>(
765 {
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 },
784 qScale, qOffset));
785
786 auto input2 = MakeTensor<T, 3>(inputTensorInfo, QuantizedVector<T>(
787 {
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 },
806 qScale, qOffset));
807
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
820 result.output = MakeTensor<T, 3>(outputTensorInfo, output);
821 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
837 result.outputExpected = MakeTensor<T, 3>(outputTensorInfo, QuantizedVector<T>(
838 {
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 },
893 qScale, qOffset));
894
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
911 result.outputExpected = MakeTensor<T, 3>(outputTensorInfo, QuantizedVector<T>(
912 {
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 },
967 qScale, qOffset));
968
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
986 result.outputExpected = MakeTensor<T, 3>(outputTensorInfo, QuantizedVector<T>(
987 {
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 },
1006 qScale, qOffset));
1007
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);
1020 auto input0 = MakeTensor<T, 3>(input0TensorInfo, QuantizedVector<T>(
1021 {
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 },
1040 qScale, qOffset));
1041
1042 TensorInfo input1TensorInfo({ 1, 3, 2 }, ArmnnType);
1043 auto input1 = MakeTensor<T, 3>(input1TensorInfo, QuantizedVector<T>(
1044 {
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 },
1054 qScale, qOffset));
1055
1056 TensorInfo input2TensorInfo({ 3, 3, 2 }, ArmnnType);
1057 auto input2 = MakeTensor<T, 3>(input2TensorInfo, QuantizedVector<T>(
1058 {
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 },
1086 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
1101 result.output = MakeTensor<T, 3>(outputTensorInfo, output);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001102 result.outputExpected = MakeTensor<T, 3>(outputTensorInfo, QuantizedVector<T>(
1103 {
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 },
1158 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);
1172 auto input0 = MakeTensor<T, 3>(input0TensorInfo, QuantizedVector<T>(
1173 {
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 },
1192 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);
1195 auto input1 = MakeTensor<T, 3>(input1TensorInfo, QuantizedVector<T>(
1196 {
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 },
1221 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);
1224 auto input2 = MakeTensor<T, 3>(input2TensorInfo, QuantizedVector<T>(
1225 {
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 },
1232 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
1247 result.output = MakeTensor<T, 3>(outputTensorInfo, output);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001248 result.outputExpected = MakeTensor<T, 3>(outputTensorInfo, QuantizedVector<T>(
1249 {
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 },
1298 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);
1313 auto input0 = MakeTensor<T, 3>(input0TensorInfo, QuantizedVector<T>(
1314 {
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 },
1333 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);
1336 auto input1 = MakeTensor<T, 3>(input1TensorInfo, QuantizedVector<T>(
1337 {
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 },
1356 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);
1359 auto input2 = MakeTensor<T, 3>(input2TensorInfo, QuantizedVector<T>(
1360 {
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 },
1379 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
1394 result.output = MakeTensor<T, 3>(outputTensorInfo, output);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001395 result.outputExpected = MakeTensor<T, 3>(outputTensorInfo, QuantizedVector<T>(
1396 {
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 },
1415 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
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001433 auto input0 = MakeTensor<T, 4>(inputTensorInfo, QuantizedVector<T>(
1434 {
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 },
1442 qScale, qOffset));
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001443
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001444 auto input1 = MakeTensor<T, 4>(inputTensorInfo, QuantizedVector<T>(
1445 {
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 },
1453 qScale, qOffset));
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01001454
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001455 auto input2 = MakeTensor<T, 4>(inputTensorInfo, QuantizedVector<T>(
1456 {
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 },
1464 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
1481 result.output = MakeTensor<T, 4>(outputTensorInfo, output);
1482 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
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001498 result.outputExpected = MakeTensor<T, 4>(outputTensorInfo, QuantizedVector<T>(
1499 {
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 },
1521 qScale, qOffset));
1522
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
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001539 result.outputExpected = MakeTensor<T, 4>(outputTensorInfo, QuantizedVector<T>(
1540 {
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 },
1562 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
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001580 result.outputExpected = MakeTensor<T, 4>(outputTensorInfo, QuantizedVector<T>(
1581 {
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 },
1603 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
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001622 result.outputExpected = MakeTensor<T, 4>(outputTensorInfo, QuantizedVector<T>(
1623 {
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 },
1645 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);
1661 auto input0 = MakeTensor<T, 4>(inputTensorInfo0, QuantizedVector<T>(
1662 {
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 },
1670 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
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001674 auto input1 = MakeTensor<T, 4>(inputTensorInfo1, QuantizedVector<T>(
1675 {
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 },
1690 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
1708 result.output = MakeTensor<T, 4>(outputTensorInfo, output);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001709 result.outputExpected = MakeTensor<T, 4>(outputTensorInfo, QuantizedVector<T>(
1710 {
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 },
1732 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);
1748 auto input0 = MakeTensor<T, 4>(inputTensorInfo0, QuantizedVector<T>(
1749 {
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 },
1757 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
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001761 auto input1 = MakeTensor<T, 4>(inputTensorInfo1, QuantizedVector<T>(
1762 {
1763 11.0f, 12.0f,
1764 13.0f, 14.0f,
1765 15.0f, 16.0f,
1766 17.0f, 18.0f,
1767 },
1768 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
1786 result.output = MakeTensor<T, 4>(outputTensorInfo, output);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001787 result.outputExpected = MakeTensor<T, 4>(outputTensorInfo, QuantizedVector<T>(
1788 {
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 },
1800 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);
1816 auto input0 = MakeTensor<T, 4>(inputTensorInfo0, QuantizedVector<T>(
1817 {
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 },
1825 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);
1828 auto input1 = MakeTensor<T, 4>(inputTensorInfo1, QuantizedVector<T>(
1829 {
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 },
1840 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
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001857 result.output = MakeTensor<T, 4>(outputTensorInfo, output);
1858 result.outputExpected = MakeTensor<T, 4>(outputTensorInfo, QuantizedVector<T>(
1859 {
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 },
1878 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);
1895 auto input0 = MakeTensor<T, 4>(inputTensorInfo0, QuantizedVector<T>(
1896 {
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 },
1904 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);
1907 auto input1 = MakeTensor<T, 4>(inputTensorInfo1, QuantizedVector<T>(
1908 {
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 },
1918 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
1936 result.output = MakeTensor<T, 4>(outputTensorInfo, output);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01001937 result.outputExpected = MakeTensor<T, 4>(outputTensorInfo, QuantizedVector<T>(
1938 {
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 },
1946 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
1971 auto input1 = MakeTensor<T, 3>(inputTensorInfo1, std::vector<T>(
1972 {
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
1986 }));
1987
1988 // Quatized input2 tensor.
1989 const float inputScale2 = 0.2f;
1990 const int32_t inputOffset2 = 10;
1991
1992 auto input2 = MakeTensor<T, 3>(inputTensorInfo2, std::vector<T>(
1993 {
1994 37, 38, 39,
1995 40, 41, 42,
1996 43, 44, 45,
1997 46, 47, 48,
1998 49, 50, 51,
1999 52, 53, 54
2000 }));
2001
2002 // Quantized output tensor.
2003 const float outputScale = 0.1f;
2004 const int32_t outputOffset = 20;
2005
2006 LayerTestResult<T, 3> ret(outputTensorInfo);
2007
2008 ret.outputExpected = MakeTensor<T, 3>(outputTensorInfo, std::vector<T>(
2009 {
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
2030 }));
2031
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
2078 CopyDataToITensorHandle(inputHandle1.get(), &input1[0][0][0]);
2079 CopyDataToITensorHandle(inputHandle2.get(), &input2[0][0][0]);
2080
2081 workload->PostAllocationConfigure();
2082 workload->Execute();
2083
2084 CopyDataFromITensorHandle(&ret.output[0][0][0], outputHandle.get());
2085
2086 return ret;
2087}
2088
2089//
2090// Explicit template specializations
2091//
2092
Derek Lambertif90c56d2020-01-10 17:14:08 +00002093template LayerTestResult<ResolveType<DataType::QAsymmU8>, 3>
2094ConcatDifferentInputOutputQParamTest<DataType::QAsymmU8>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002095 IWorkloadFactory& workloadFactory,
2096 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002097 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002098 bool useSubtensor);
2099
Derek Lambertif90c56d2020-01-10 17:14:08 +00002100template LayerTestResult<ResolveType<DataType::QSymmS16>, 3>
2101ConcatDifferentInputOutputQParamTest<DataType::QSymmS16>(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002102 IWorkloadFactory& workloadFactory,
2103 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002104 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002105 bool useSubtensor);
2106
2107//
2108// Implementation functions
2109//
2110
2111LayerTestResult<float,3> ConcatTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002112 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002113 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2114 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002115{
Jan Eilers8eb25602020-03-09 12:13:48 +00002116 IgnoreUnused(memoryManager);
Derek Lambertic374ff02019-12-10 21:57:35 +00002117
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002118 unsigned int outputWidth = 3;
2119 unsigned int outputHeight = 6;
2120 unsigned int outputChannels = 3;
2121
2122 unsigned int inputWidth1 = 3;
2123 unsigned int inputHeight1 = 6;
2124 unsigned int inputChannels1 = 2;
2125
2126 unsigned int inputWidth2 = 3;
2127 unsigned int inputHeight2 = 6;
2128 unsigned int inputChannels2 = 1;
2129
2130 // Define the tensor descriptors.
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002131 TensorInfo outputTensorInfo({ outputChannels, outputHeight, outputWidth }, DataType::Float32);
2132 TensorInfo inputTensorInfo1({ inputChannels1, inputHeight1, inputWidth1 }, DataType::Float32);
2133 TensorInfo inputTensorInfo2({ inputChannels2, inputHeight2, inputWidth2 }, DataType::Float32);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002134
2135 LayerTestResult<float,3> ret(outputTensorInfo);
2136
2137 ret.outputExpected = MakeTensor<float, 3>(outputTensorInfo, std::vector<float>(
2138 {
2139 1.0f, 2.0f, 3.0f,
2140 4.0f, 5.0f, 6.0f,
2141 7.0f, 8.0f, 9.0f,
2142 10.0f, 11.0f, 12.0f,
2143 13.0f, 14.0f, 15.0f,
2144 16.0f, 17.0f, 18.0f,
2145
2146 19.0f, 20.0f, 21.0f,
2147 22.0f, 23.0f, 24.0f,
2148 25.0f, 26.0f, 27.0f,
2149 28.0f, 29.0f, 30.0f,
2150 31.0f, 32.0f, 33.0f,
2151 34.0f, 35.0f, 36.0f,
2152
2153 37.0f, 38.0f, 39.0f,
2154 40.0f, 41.0f, 42.0f,
2155 43.0f, 44.0f, 45.0f,
2156 46.0f, 47.0f, 48.0f,
2157 49.0f, 50.0f, 51.0f,
2158 52.0f, 53.0f, 54.0f,
2159 })
2160 );
2161
2162 auto input1 = MakeTensor<float, 3>(inputTensorInfo1, std::vector<float>(
2163 {
2164 1.0f, 2.0f, 3.0f,
2165 4.0f, 5.0f, 6.0f,
2166 7.0f, 8.0f, 9.0f,
2167 10.0f, 11.0f, 12.0f,
2168 13.0f, 14.0f, 15.0f,
2169 16.0f, 17.0f, 18.0f,
2170
2171 19.0f, 20.0f, 21.0f,
2172 22.0f, 23.0f, 24.0f,
2173 25.0f, 26.0f, 27.0f,
2174 28.0f, 29.0f, 30.0f,
2175 31.0f, 32.0f, 33.0f,
2176 34.0f, 35.0f, 36.0f,
2177 })
2178 );
2179
2180 auto input2 = MakeTensor<float, 3>(inputTensorInfo2, std::vector<float>(
2181 {
2182 37.0f, 38.0f, 39.0f,
2183 40.0f, 41.0f, 42.0f,
2184 43.0f, 44.0f, 45.0f,
2185 46.0f, 47.0f, 48.0f,
2186 49.0f, 50.0f, 51.0f,
2187 52.0f, 53.0f, 54.0f,
2188 })
2189 );
2190
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
2226 CopyDataToITensorHandle(inputHandle1.get(), &input1[0][0][0]);
2227 CopyDataToITensorHandle(inputHandle2.get(), &input2[0][0][0]);
2228
2229 workload->PostAllocationConfigure();
2230 workload->Execute();
2231
2232 CopyDataFromITensorHandle(&ret.output[0][0][0], outputHandle.get());
2233
2234 return ret;
2235}
2236
2237LayerTestResult<float, 1> Concat1dTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002238 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002239 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2240 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002241{
Keith Davisf500d6c2020-08-31 08:32:55 +01002242 return Concat1dTestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002243}
2244
2245LayerTestResult<float, 2> Concat2dDim0Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002246 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002247 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2248 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002249{
Keith Davisf500d6c2020-08-31 08:32:55 +01002250 return Concat2dDim0TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002251}
2252
2253LayerTestResult<float, 2> Concat2dDim1Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002254 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002255 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2256 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002257{
Keith Davisf500d6c2020-08-31 08:32:55 +01002258 return Concat2dDim1TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002259}
2260
2261LayerTestResult<float, 2> Concat2dDim0DiffInputDimsTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002262 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002263 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2264 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002265{
Keith Davisf500d6c2020-08-31 08:32:55 +01002266 return Concat2dDim0DiffInputDimsTestImpl<DataType::Float32>(workloadFactory, memoryManager,
2267 tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002268}
2269
2270LayerTestResult<float, 2> Concat2dDim1DiffInputDimsTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002271 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002272 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2273 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002274{
Keith Davisf500d6c2020-08-31 08:32:55 +01002275 return Concat2dDim1DiffInputDimsTestImpl<DataType::Float32>(workloadFactory,
2276 memoryManager,
2277 tensorHandleFactory,
2278 0.0f,
2279 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002280}
2281
2282LayerTestResult<float, 3> Concat3dDim0Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002283 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002284 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2285 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002286{
Keith Davisf500d6c2020-08-31 08:32:55 +01002287 return Concat3dDim0TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002288}
2289
2290LayerTestResult<float, 3> Concat3dDim1Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002291 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002292 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2293 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002294{
Keith Davisf500d6c2020-08-31 08:32:55 +01002295 return Concat3dDim1TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002296}
2297
2298LayerTestResult<float, 3> Concat3dDim2Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002299 IWorkloadFactory& workloadFactory,
2300 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002301 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002302 bool useSubtensor)
2303{
Keith Davisf500d6c2020-08-31 08:32:55 +01002304 return Concat3dDim2TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory,
2305 useSubtensor, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002306}
2307
2308LayerTestResult<float, 3> Concat3dDim0DiffInputDimsTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002309 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002310 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2311 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002312{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002313 return Concat3dDim0DiffInputDimsTestImpl<DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002314 workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002315}
2316
2317LayerTestResult<float, 3> Concat3dDim1DiffInputDimsTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002318 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002319 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2320 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002321{
Keith Davisf500d6c2020-08-31 08:32:55 +01002322 return Concat3dDim1DiffInputDimsTestImpl<DataType::Float32>(workloadFactory, memoryManager,
2323 tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002324}
2325
2326LayerTestResult<float, 3> Concat3dDim2DiffInputDimsTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002327 IWorkloadFactory& workloadFactory,
2328 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002329 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002330 bool useSubtensor)
2331{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002332 return Concat3dDim2DiffInputDimsTestImpl<DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002333 workloadFactory, memoryManager, tensorHandleFactory, useSubtensor, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002334}
2335
2336LayerTestResult<float, 4> Concat4dDim0Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002337 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002338 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2339 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002340{
Keith Davisf500d6c2020-08-31 08:32:55 +01002341 return Concat4dDim0TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002342}
2343
2344LayerTestResult<float, 4> Concat4dDim1Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002345 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002346 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2347 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002348{
Keith Davisf500d6c2020-08-31 08:32:55 +01002349 return Concat4dDim1TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002350}
2351
2352LayerTestResult<float, 4> Concat4dDim2Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002353 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002354 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2355 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002356{
Keith Davisf500d6c2020-08-31 08:32:55 +01002357 return Concat4dDim2TestImpl<DataType::Float32>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002358}
2359
2360LayerTestResult<float, 4> Concat4dDim3Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002361 IWorkloadFactory& workloadFactory,
2362 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002363 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002364 bool useSubtensor)
2365{
Keith Davisf500d6c2020-08-31 08:32:55 +01002366 return Concat4dDim3TestImpl<DataType::Float32>(workloadFactory, memoryManager,
2367 tensorHandleFactory, 0.0f, 0, useSubtensor);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002368}
2369
2370LayerTestResult<float, 4> Concat4dDiffShapeDim0Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002371 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002372 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2373 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002374{
Keith Davisf500d6c2020-08-31 08:32:55 +01002375 return Concat4dDiffShapeDim0TestImpl<DataType::Float32>(workloadFactory, memoryManager,
2376 tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002377}
2378
2379LayerTestResult<float, 4> Concat4dDiffShapeDim1Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002380 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002381 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2382 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002383{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002384 return Concat4dDiffShapeDim1TestImpl<DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002385 workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002386}
2387
2388LayerTestResult<float, 4> Concat4dDiffShapeDim2Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002389 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002390 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2391 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002392{
Keith Davisf500d6c2020-08-31 08:32:55 +01002393 return Concat4dDiffShapeDim2TestImpl<DataType::Float32>(workloadFactory, memoryManager,
2394 tensorHandleFactory, 0.0f, 0);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002395}
2396
2397LayerTestResult<float, 4> Concat4dDiffShapeDim3Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002398 IWorkloadFactory& workloadFactory,
2399 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002400 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002401 bool useSubtensor)
2402{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002403 return Concat4dDiffShapeDim3TestImpl<DataType::Float32>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002404 workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0, useSubtensor);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002405}
2406
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002407LayerTestResult<Half, 3> ConcatFloat16Test(
2408 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002409 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2410 const armnn::ITensorHandleFactory& tensorHandleFactory)
Matthew Jackson9bff1442019-09-12 09:08:23 +01002411{
Keith Davisf500d6c2020-08-31 08:32:55 +01002412 return Concat3dDim1TestImpl<DataType::Float16>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Matthew Jackson9bff1442019-09-12 09:08:23 +01002413}
2414
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00002415LayerTestResult<BFloat16, 3> ConcatBFloat16Test(
2416 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002417 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2418 const armnn::ITensorHandleFactory& tensorHandleFactory)
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00002419{
Keith Davisf500d6c2020-08-31 08:32:55 +01002420 return Concat3dDim1TestImpl<DataType::BFloat16>(workloadFactory, memoryManager, tensorHandleFactory, 0.0f, 0);
Narumol Prangnawarat44179c32020-03-11 14:51:27 +00002421}
2422
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002423LayerTestResult<uint8_t, 3> ConcatUint8DifferentQParamsTest(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002424 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002425 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2426 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002427{
Jan Eilers8eb25602020-03-09 12:13:48 +00002428 IgnoreUnused(memoryManager);
Derek Lambertic374ff02019-12-10 21:57:35 +00002429
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002430 unsigned int outputWidth = 3;
2431 unsigned int outputHeight = 6;
2432 unsigned int outputChannels = 3;
2433
2434 unsigned int inputWidth1 = 3;
2435 unsigned int inputHeight1 = 6;
2436 unsigned int inputChannels1 = 2;
2437
2438 unsigned int inputWidth2 = 3;
2439 unsigned int inputHeight2 = 6;
2440 unsigned int inputChannels2 = 1;
2441
2442 // Defines the tensor descriptors.
Derek Lambertif90c56d2020-01-10 17:14:08 +00002443 TensorInfo outputTensorInfo({ outputChannels, outputHeight, outputWidth }, DataType::QAsymmU8);
2444 TensorInfo inputTensorInfo1({ inputChannels1, inputHeight1, inputWidth1 }, DataType::QAsymmU8);
2445 TensorInfo inputTensorInfo2({ inputChannels2, inputHeight2, inputWidth2 }, DataType::QAsymmU8);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002446
2447 // Quantized input1 tensor. Range [-3, 1]
2448 const float inputScale1 = 0.015686f;
2449 const int32_t inputOffset1 = 192;
2450
2451 auto input1 = MakeTensor<uint8_t, 3>(inputTensorInfo1, std::vector<uint8_t>(
2452 {
2453 1, 2, 3,
2454 4, 5, 6,
2455 7, 8, 9,
2456 10, 11, 12,
2457 13, 14, 15,
2458 16, 17, 18,
2459
2460 19, 20, 21,
2461 22, 23, 24,
2462 25, 26, 27,
2463 28, 29, 30,
2464 31, 32, 33,
2465 34, 35, 36,
2466 })
2467 );
2468
2469 // Quatized input2 tensor. Range [-1, 4]
2470 const float inputScale2 = 0.019608f;
2471 const int32_t inputOffset2 = 50;
2472
2473 auto input2 = MakeTensor<uint8_t, 3>(inputTensorInfo2, std::vector<uint8_t>(
2474 {
2475 37, 38, 39,
2476 40, 41, 42,
2477 43, 44, 45,
2478 46, 47, 48,
2479 49, 50, 51,
2480 52, 53, 54,
2481 })
2482 );
2483
2484 // Output has the same quantization parameters than input1,
2485 // so that only the requantization of input2 is required
2486 const float outputScale = 0.015686f;
2487 const int32_t outputOffset = 192;
2488
2489 LayerTestResult<uint8_t, 3> ret(outputTensorInfo);
2490
2491 ret.outputExpected = MakeTensor<uint8_t, 3>(outputTensorInfo, std::vector<uint8_t>(
2492 {
2493 1, 2, 3,
2494 4, 5, 6,
2495 7, 8, 9,
2496 10, 11, 12,
2497 13, 14, 15,
2498 16, 17, 18,
2499
2500 19, 20, 21,
2501 22, 23, 24,
2502 25, 26, 27,
2503 28, 29, 30,
2504 31, 32, 33,
2505 34, 35, 36,
2506
2507 176, 177, 178,
2508 179, 181, 182,
2509 183, 184, 186,
2510 187, 188, 189,
2511 191, 192, 193,
2512 195, 196, 197,
2513 })
2514 );
2515
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
2558 CopyDataToITensorHandle(inputHandle1.get(), &input1[0][0][0]);
2559 CopyDataToITensorHandle(inputHandle2.get(), &input2[0][0][0]);
2560
2561 workload->PostAllocationConfigure();
2562 workload->Execute();
2563
2564 CopyDataFromITensorHandle(&ret.output[0][0][0], outputHandle.get());
2565
2566 return ret;
2567}
2568
2569LayerTestResult<uint8_t, 3> ConcatUint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002570 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002571 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2572 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002573{
Jan Eilers8eb25602020-03-09 12:13:48 +00002574 IgnoreUnused(memoryManager);
Derek Lambertic374ff02019-12-10 21:57:35 +00002575
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002576 unsigned int outputWidth = 3;
2577 unsigned int outputHeight = 6;
2578 unsigned int outputChannels = 3;
2579
2580 unsigned int inputWidth1 = 3;
2581 unsigned int inputHeight1 = 6;
2582 unsigned int inputChannels1 = 2;
2583
2584 unsigned int inputWidth2 = 3;
2585 unsigned int inputHeight2 = 6;
2586 unsigned int inputChannels2 = 1;
2587
2588 // Defines the tensor descriptors.
Derek Lambertif90c56d2020-01-10 17:14:08 +00002589 TensorInfo outputTensorInfo({ outputChannels, outputHeight, outputWidth }, DataType::QAsymmU8);
2590 TensorInfo inputTensorInfo1({ inputChannels1, inputHeight1, inputWidth1 }, DataType::QAsymmU8);
2591 TensorInfo inputTensorInfo2({ inputChannels2, inputHeight2, inputWidth2 }, DataType::QAsymmU8);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002592
2593 // Arbitrary scale and offsets. They don't really matter as the Concat operator doesn't dequantize/quantize them.
2594 const float scale = 0.13497836f;
2595 const int32_t offset = -7;
2596
2597 outputTensorInfo.SetQuantizationScale(scale);
2598 outputTensorInfo.SetQuantizationOffset(offset);
2599 inputTensorInfo1.SetQuantizationScale(scale);
2600 inputTensorInfo1.SetQuantizationOffset(offset);
2601 inputTensorInfo2.SetQuantizationScale(scale);
2602 inputTensorInfo2.SetQuantizationOffset(offset);
2603
2604 LayerTestResult<uint8_t, 3> ret(outputTensorInfo);
2605
2606 ret.outputExpected = MakeTensor<uint8_t, 3>(outputTensorInfo, std::vector<uint8_t>(
2607 {
2608 1, 2, 3,
2609 4, 5, 6,
2610 7, 8, 9,
2611 10, 11, 12,
2612 13, 14, 15,
2613 16, 17, 18,
2614
2615 19, 20, 21,
2616 22, 23, 24,
2617 25, 26, 27,
2618 28, 29, 30,
2619 31, 32, 33,
2620 34, 35, 36,
2621
2622 37, 38, 39,
2623 40, 41, 42,
2624 43, 44, 45,
2625 46, 47, 48,
2626 49, 50, 51,
2627 52, 53, 54,
2628 })
2629 );
2630
2631 auto input1 = MakeTensor<uint8_t, 3>(inputTensorInfo1, std::vector<uint8_t>(
2632 {
2633 1, 2, 3,
2634 4, 5, 6,
2635 7, 8, 9,
2636 10, 11, 12,
2637 13, 14, 15,
2638 16, 17, 18,
2639
2640 19, 20, 21,
2641 22, 23, 24,
2642 25, 26, 27,
2643 28, 29, 30,
2644 31, 32, 33,
2645 34, 35, 36,
2646 })
2647 );
2648
2649 auto input2 = MakeTensor<uint8_t, 3>(inputTensorInfo2, std::vector<uint8_t>(
2650 {
2651 37, 38, 39,
2652 40, 41, 42,
2653 43, 44, 45,
2654 46, 47, 48,
2655 49, 50, 51,
2656 52, 53, 54,
2657 })
2658 );
2659
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
2696 CopyDataToITensorHandle(inputHandle1.get(), &input1[0][0][0]);
2697 CopyDataToITensorHandle(inputHandle2.get(), &input2[0][0][0]);
2698
2699 workload->PostAllocationConfigure();
2700 workload->Execute();
2701
2702 CopyDataFromITensorHandle(&ret.output[0][0][0], outputHandle.get());
2703
2704 return ret;
2705}
2706
2707LayerTestResult<uint16_t, 3> ConcatUint16Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002708 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002709 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2710 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002711{
Jan Eilers8eb25602020-03-09 12:13:48 +00002712 IgnoreUnused(memoryManager);
Derek Lambertic374ff02019-12-10 21:57:35 +00002713
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002714 unsigned int outputWidth = 3;
2715 unsigned int outputHeight = 6;
2716 unsigned int outputChannels = 3;
2717
2718 unsigned int inputWidth1 = 3;
2719 unsigned int inputHeight1 = 6;
2720 unsigned int inputChannels1 = 2;
2721
2722 unsigned int inputWidth2 = 3;
2723 unsigned int inputHeight2 = 6;
2724 unsigned int inputChannels2 = 1;
2725
2726 // Defines the tensor descriptors.
Derek Lambertif90c56d2020-01-10 17:14:08 +00002727 TensorInfo outputTensorInfo({ outputChannels, outputHeight, outputWidth }, DataType::QSymmS16);
2728 TensorInfo inputTensorInfo1({ inputChannels1, inputHeight1, inputWidth1 }, DataType::QSymmS16);
2729 TensorInfo inputTensorInfo2({ inputChannels2, inputHeight2, inputWidth2 }, DataType::QSymmS16);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002730
2731 // Arbitrary scale and offsets. They don't really matter as the Concat operator doesn't dequantize/quantize them.
2732 const float scale = 0.13497836f;
2733 const int32_t offset = -7;
2734
2735 outputTensorInfo.SetQuantizationScale(scale);
2736 outputTensorInfo.SetQuantizationOffset(offset);
2737 inputTensorInfo1.SetQuantizationScale(scale);
2738 inputTensorInfo1.SetQuantizationOffset(offset);
2739 inputTensorInfo2.SetQuantizationScale(scale);
2740 inputTensorInfo2.SetQuantizationOffset(offset);
2741
2742 LayerTestResult<uint16_t, 3> ret(outputTensorInfo);
2743
2744 ret.outputExpected = MakeTensor<uint16_t, 3>(outputTensorInfo, std::vector<uint16_t>(
2745 {
2746 1, 2, 3,
2747 4, 5, 6,
2748 7, 8, 9,
2749 10, 11, 12,
2750 13, 14, 15,
2751 16, 17, 18,
2752
2753 19, 20, 21,
2754 22, 23, 24,
2755 25, 26, 27,
2756 28, 29, 30,
2757 31, 32, 33,
2758 34, 35, 36,
2759
2760 37, 38, 39,
2761 40, 41, 42,
2762 43, 44, 45,
2763 46, 47, 48,
2764 49, 50, 51,
2765 52, 53, 54,
2766 }));
2767
2768 auto input1 = MakeTensor<uint16_t, 3>(inputTensorInfo1, std::vector<uint16_t>(
2769 {
2770 1, 2, 3,
2771 4, 5, 6,
2772 7, 8, 9,
2773 10, 11, 12,
2774 13, 14, 15,
2775 16, 17, 18,
2776
2777 19, 20, 21,
2778 22, 23, 24,
2779 25, 26, 27,
2780 28, 29, 30,
2781 31, 32, 33,
2782 34, 35, 36,
2783 }));
2784
2785 auto input2 = MakeTensor<uint16_t, 3>(inputTensorInfo2, std::vector<uint16_t>(
2786 {
2787 37, 38, 39,
2788 40, 41, 42,
2789 43, 44, 45,
2790 46, 47, 48,
2791 49, 50, 51,
2792 52, 53, 54,
2793 }));
2794
2795 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 +01002796 ConcatQueueDescriptor::ViewOrigin window1(wOrigin1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002797
2798 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 +01002799 ConcatQueueDescriptor::ViewOrigin window2(wOrigin2);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002800
Keith Davisf500d6c2020-08-31 08:32:55 +01002801
2802 std::unique_ptr<ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002803
2804 bool subTensorsSupported = workloadFactory.SupportsSubTensors();
2805
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002806 std::unique_ptr<ITensorHandle> inputHandle1 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002807 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +01002808 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo1.GetShape(), wOrigin1.data()) :
2809 tensorHandleFactory.CreateTensorHandle(inputTensorInfo1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002810
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002811 std::unique_ptr<ITensorHandle> inputHandle2 =
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002812 subTensorsSupported ?
Keith Davisf500d6c2020-08-31 08:32:55 +01002813 tensorHandleFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo2.GetShape(), wOrigin2.data()) :
2814 tensorHandleFactory.CreateTensorHandle(inputTensorInfo2);
2815
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002816
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002817 ConcatQueueDescriptor data;
2818 WorkloadInfo info;
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002819 AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
2820 AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
2821 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
2822
2823 data.m_ViewOrigins.push_back(window1);
2824 data.m_ViewOrigins.push_back(window2);
2825
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002826 std::unique_ptr<IWorkload> workload = workloadFactory.CreateConcat(data, info);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002827
2828 inputHandle1->Allocate();
2829 inputHandle2->Allocate();
2830 outputHandle->Allocate();
2831
2832 CopyDataToITensorHandle(inputHandle1.get(), &input1[0][0][0]);
2833 CopyDataToITensorHandle(inputHandle2.get(), &input2[0][0][0]);
2834
2835 workload->PostAllocationConfigure();
2836 workload->Execute();
2837
2838 CopyDataFromITensorHandle(&ret.output[0][0][0], outputHandle.get());
2839
2840 return ret;
2841}
2842
2843LayerTestResult<uint8_t, 1> Concat1dUint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002844 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002845 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2846 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002847{
Keith Davisf500d6c2020-08-31 08:32:55 +01002848 return Concat1dTestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002849}
2850
2851LayerTestResult<uint8_t, 2> Concat2dDim0Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002852 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002853 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2854 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002855{
Keith Davisf500d6c2020-08-31 08:32:55 +01002856 return Concat2dDim0TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002857}
2858
2859LayerTestResult<uint8_t, 2> Concat2dDim1Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002860 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002861 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2862 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002863{
Keith Davisf500d6c2020-08-31 08:32:55 +01002864 return Concat2dDim1TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002865}
2866
2867LayerTestResult<uint8_t, 2> Concat2dDim0DiffInputDimsUint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002868 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002869 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2870 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002871{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002872 return Concat2dDim0DiffInputDimsTestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002873 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002874}
2875
2876LayerTestResult<uint8_t, 2> Concat2dDim1DiffInputDimsUint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002877 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002878 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2879 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002880{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002881 return Concat2dDim1DiffInputDimsTestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002882 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002883}
2884
2885LayerTestResult<uint8_t, 3> Concat3dDim0Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002886 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002887 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2888 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002889{
Keith Davisf500d6c2020-08-31 08:32:55 +01002890 return Concat3dDim0TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002891}
2892
2893LayerTestResult<uint8_t, 3> Concat3dDim1Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002894 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002895 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2896 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002897{
Keith Davisf500d6c2020-08-31 08:32:55 +01002898 return Concat3dDim1TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002899}
2900
2901LayerTestResult<uint8_t, 3> Concat3dDim2Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002902 IWorkloadFactory& workloadFactory,
2903 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002904 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002905 bool useSubtensor)
2906{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002907 return Concat3dDim2TestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002908 workloadFactory, memoryManager, tensorHandleFactory, useSubtensor, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002909}
2910
2911LayerTestResult<uint8_t, 3> Concat3dDim0DiffInputDimsUint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002912 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002913 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2914 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002915{
Keith Davisf500d6c2020-08-31 08:32:55 +01002916 return Concat3dDim0TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002917}
2918
2919LayerTestResult<uint8_t, 3> Concat3dDim1DiffInputDimsUint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002920 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002921 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2922 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002923{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002924 return Concat3dDim1DiffInputDimsTestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002925 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002926}
2927
2928LayerTestResult<uint8_t, 3> Concat3dDim2DiffInputDimsUint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002929 IWorkloadFactory& workloadFactory,
2930 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01002931 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002932 bool useSubtensor)
2933{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002934 return Concat3dDim2DiffInputDimsTestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002935 workloadFactory, memoryManager, tensorHandleFactory, useSubtensor, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002936}
2937
2938LayerTestResult<uint8_t, 4> Concat4dDim0Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002939 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002940 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2941 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002942{
Keith Davisf500d6c2020-08-31 08:32:55 +01002943 return Concat4dDim0TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002944}
2945
2946LayerTestResult<uint8_t, 4> Concat4dDim1Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002947 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002948 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2949 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002950{
Keith Davisf500d6c2020-08-31 08:32:55 +01002951 return Concat4dDim1TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002952}
2953
2954LayerTestResult<uint8_t, 4> Concat4dDim2Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002955 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002956 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2957 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002958{
Keith Davisf500d6c2020-08-31 08:32:55 +01002959 return Concat4dDim2TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002960}
2961
2962LayerTestResult<uint8_t, 4> Concat4dDim3Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002963 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002964 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2965 const armnn::ITensorHandleFactory& tensorHandleFactory, bool useSubtensor)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002966{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002967 return Concat4dDim3TestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002968 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1, useSubtensor);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002969}
2970
2971LayerTestResult<uint8_t, 4> Concat4dDiffShapeDim0Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002972 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002973 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2974 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002975{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002976 return Concat4dDiffShapeDim0TestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002977 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002978}
2979
2980LayerTestResult<uint8_t, 4> Concat4dDiffShapeDim1Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002981 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002982 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2983 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002984{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002985 return Concat4dDiffShapeDim1TestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002986 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002987}
2988
2989LayerTestResult<uint8_t, 4> Concat4dDiffShapeDim2Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002990 IWorkloadFactory& workloadFactory,
Keith Davisf500d6c2020-08-31 08:32:55 +01002991 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2992 const armnn::ITensorHandleFactory& tensorHandleFactory)
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002993{
Derek Lambertif90c56d2020-01-10 17:14:08 +00002994 return Concat4dDiffShapeDim2TestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01002995 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01002996}
2997
2998LayerTestResult<uint8_t, 4> Concat4dDiffShapeDim3Uint8Test(
Aron Virginas-Tar48623a02019-10-22 10:00:28 +01002999 IWorkloadFactory& workloadFactory,
3000 const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Keith Davisf500d6c2020-08-31 08:32:55 +01003001 const armnn::ITensorHandleFactory& tensorHandleFactory,
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003002 bool useSubtensor)
3003{
Derek Lambertif90c56d2020-01-10 17:14:08 +00003004 return Concat4dDiffShapeDim3TestImpl<DataType::QAsymmU8>(
Keith Davisf500d6c2020-08-31 08:32:55 +01003005 workloadFactory, memoryManager, tensorHandleFactory, 0.5f, -1, useSubtensor);
Aron Virginas-Tar00d306e2019-08-28 18:08:46 +01003006}