blob: 5b538b6481f7ae277a2bbf82e596e2300f769cbc [file] [log] [blame]
Nikhil Raj8599a412018-11-19 14:51:07 +00001//
Teresa Charlin588cbdf2022-01-19 15:55:37 +00002// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
Nikhil Raj8599a412018-11-19 14:51:07 +00003// SPDX-License-Identifier: MIT
4//
5
Jim Flynn39d487d2019-05-17 15:44:36 +01006#include "NeonConcatWorkload.hpp"
Matthew Benthamd80a7122019-01-08 17:52:37 +00007
8#include "NeonWorkloadUtils.hpp"
9
Nikhil Raj8599a412018-11-19 14:51:07 +000010#include <aclCommon/ArmComputeTensorUtils.hpp>
Jan Eilers3c9e0452020-04-10 13:00:44 +010011#include <armnn/utility/PolymorphicDowncast.hpp>
Colm Donelan0c479742021-12-10 12:43:54 +000012#include <armnn/backends/TensorHandle.hpp>
Nikhil Raj8599a412018-11-19 14:51:07 +000013#include <neon/NeonTensorHandle.hpp>
14
Nikhil Raj8599a412018-11-19 14:51:07 +000015namespace armnn
16{
17using namespace armcomputetensorutils;
18
Derek Lamberti0790dce2019-04-15 18:37:35 +010019namespace
20{
Keith Davis2d0679f2021-08-05 11:35:00 +010021size_t CalcAxis(const armnn::OriginsDescriptor& descriptor)
Derek Lamberti0790dce2019-04-15 18:37:35 +010022{
Keith Davis2d0679f2021-08-05 11:35:00 +010023 return (descriptor.GetNumDimensions() - descriptor.GetConcatAxis()) - 1;
Derek Lamberti0790dce2019-04-15 18:37:35 +010024}
25} //namespace
26
Jim Flynn39d487d2019-05-17 15:44:36 +010027arm_compute::Status NeonConcatWorkloadValidate(const std::vector<const TensorInfo*>& inputs,
Nikhil Raj8599a412018-11-19 14:51:07 +000028 const TensorInfo& output,
Jim Flynne242f2d2019-05-22 14:24:13 +010029 const OriginsDescriptor& descriptor)
Nikhil Raj8599a412018-11-19 14:51:07 +000030
31{
32 std::vector<arm_compute::TensorInfo> aclInputs;
33 for (const TensorInfo* input : inputs)
34 {
Derek Lamberti0790dce2019-04-15 18:37:35 +010035 arm_compute::TensorInfo aclInputInfo = BuildArmComputeTensorInfo(*input, armnn::DataLayout::NCHW);
36 aclInputs.emplace_back(aclInputInfo);
Nikhil Raj8599a412018-11-19 14:51:07 +000037 }
38 const arm_compute::TensorInfo aclOutputInfo = BuildArmComputeTensorInfo(output);
Teresa Charlin552ee4d2020-07-16 12:44:16 +010039 std::vector<const arm_compute::ITensorInfo*> aclInputPtrs;
Nikhil Raj8599a412018-11-19 14:51:07 +000040 for (arm_compute::ITensorInfo& input : aclInputs)
41 {
42 aclInputPtrs.emplace_back(&input);
43 }
44
Derek Lamberti0790dce2019-04-15 18:37:35 +010045 size_t aclAxis = CalcAxis(descriptor);
Nikhil Raj8599a412018-11-19 14:51:07 +000046 return arm_compute::NEConcatenateLayer::validate(aclInputPtrs, &aclOutputInfo, aclAxis);
Nikhil Raj8599a412018-11-19 14:51:07 +000047}
48
Jim Flynn39d487d2019-05-17 15:44:36 +010049NeonConcatWorkload::NeonConcatWorkload(
Jim Flynne242f2d2019-05-22 14:24:13 +010050const ConcatQueueDescriptor& descriptor, const WorkloadInfo& info)
Teresa Charlin588cbdf2022-01-19 15:55:37 +000051 : NeonBaseWorkload<ConcatQueueDescriptor>(descriptor, info)
Nikhil Raj8599a412018-11-19 14:51:07 +000052{
Keith Davis2d0679f2021-08-05 11:35:00 +010053 // Report Profiling Details
54 ARMNN_REPORT_PROFILING_WORKLOAD_DESC("NeonConcatWorkload_Construct",
55 descriptor.m_Parameters,
56 info,
57 this->GetGuid());
58
Derek Lamberti0790dce2019-04-15 18:37:35 +010059 bool allInputsAreSubtensors = true;
Nikhil Raj8599a412018-11-19 14:51:07 +000060
Derek Lamberti0790dce2019-04-15 18:37:35 +010061 // Check that all inputs are sub-tensors
62 for (auto input : descriptor.m_Inputs)
Nikhil Raj8599a412018-11-19 14:51:07 +000063 {
Derek Lamberti0790dce2019-04-15 18:37:35 +010064 if (!input->GetParent())
65 {
Jim Flynne242f2d2019-05-22 14:24:13 +010066 // Non sub-tensor input found so we need to execute the concat function
Derek Lamberti0790dce2019-04-15 18:37:35 +010067 allInputsAreSubtensors = false;
68 break;
69 }
70 }
71
72 if (allInputsAreSubtensors)
73 {
Jim Flynne242f2d2019-05-22 14:24:13 +010074 // Can skip configuring the concat function since it's not executed
Nikhil Raj8599a412018-11-19 14:51:07 +000075 return;
76 }
77
Teresa Charlin552ee4d2020-07-16 12:44:16 +010078 std::vector<const arm_compute::ITensor *> aclInputs;
Nikhil Raj8599a412018-11-19 14:51:07 +000079 for (auto input : m_Data.m_Inputs)
80 {
Jan Eilers3c9e0452020-04-10 13:00:44 +010081 arm_compute::ITensor& aclInput = armnn::PolymorphicPointerDowncast<IAclTensorHandle>(input)->GetTensor();
Nikhil Raj8599a412018-11-19 14:51:07 +000082 aclInputs.emplace_back(&aclInput);
83 }
Jan Eilers3c9e0452020-04-10 13:00:44 +010084 arm_compute::ITensor& output = armnn::PolymorphicPointerDowncast<IAclTensorHandle>(
Derek Lamberti0790dce2019-04-15 18:37:35 +010085 m_Data.m_Outputs[0])->GetTensor();
Nikhil Raj8599a412018-11-19 14:51:07 +000086
Derek Lamberti0790dce2019-04-15 18:37:35 +010087 // Create the layer function
88 m_Layer.reset(new arm_compute::NEConcatenateLayer());
Nikhil Raj8599a412018-11-19 14:51:07 +000089
Derek Lamberti0790dce2019-04-15 18:37:35 +010090 // Configure input and output tensors
91 size_t aclAxis = CalcAxis(descriptor.m_Parameters);
92 m_Layer->configure(aclInputs, &output, aclAxis);
Nikhil Raj8599a412018-11-19 14:51:07 +000093
Derek Lamberti0790dce2019-04-15 18:37:35 +010094 // Prepare
Matthew Benthamd80a7122019-01-08 17:52:37 +000095 m_Layer->prepare();
Nikhil Raj8599a412018-11-19 14:51:07 +000096}
97
Jim Flynn39d487d2019-05-17 15:44:36 +010098void NeonConcatWorkload::Execute() const
Nikhil Raj8599a412018-11-19 14:51:07 +000099{
Derek Lamberti0790dce2019-04-15 18:37:35 +0100100 if (m_Layer)
Nikhil Raj8599a412018-11-19 14:51:07 +0000101 {
Keith Davis2d0679f2021-08-05 11:35:00 +0100102 ARMNN_SCOPED_PROFILING_EVENT_NEON_GUID("NeonConcatWorkload_Execute", this->GetGuid());
Matthew Benthamd80a7122019-01-08 17:52:37 +0000103 m_Layer->run();
Nikhil Raj8599a412018-11-19 14:51:07 +0000104 }
105}
106
107} //namespace armnn
108