blob: 1c2d476e0ca8cf55d4948f6aa9ca5d7f3f0450ea [file] [log] [blame]
Nikhil Raj8599a412018-11-19 14:51:07 +00001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
Jim Flynn69059412019-05-17 13:03:57 +01005#include "ClConcatWorkload.hpp"
Nikhil Raj8599a412018-11-19 14:51:07 +00006#include "ClWorkloadUtils.hpp"
7#include <aclCommon/ArmComputeTensorUtils.hpp>
Jan Eilers3c9e0452020-04-10 13:00:44 +01008#include <armnn/utility/PolymorphicDowncast.hpp>
James Conroy1f58f032021-04-27 17:13:27 +01009#include <backendsCommon/TensorHandle.hpp>
Nikhil Raj8599a412018-11-19 14:51:07 +000010#include <cl/ClTensorHandle.hpp>
11#include <cl/ClLayerSupport.hpp>
12
Derek Lamberti0790dce2019-04-15 18:37:35 +010013#include <arm_compute/core/Types.h>
14
Nikhil Raj8599a412018-11-19 14:51:07 +000015namespace armnn
16{
17using namespace armcomputetensorutils;
18
Derek Lamberti0790dce2019-04-15 18:37:35 +010019namespace
20{
Jim Flynne242f2d2019-05-22 14:24:13 +010021size_t CalcAxis(const OriginsDescriptor& desc)
Derek Lamberti0790dce2019-04-15 18:37:35 +010022{
23 return (desc.GetNumDimensions() - desc.GetConcatAxis()) - 1;
24}
25} //namespace
26
Jim Flynn69059412019-05-17 13:03:57 +010027arm_compute::Status ClConcatWorkloadValidate(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 std::vector<arm_compute::TensorInfo> aclInputs;
32 for (const TensorInfo* input : inputs)
33 {
34 arm_compute::TensorInfo aclInputInfo = BuildArmComputeTensorInfo(*input, armnn::DataLayout::NCHW);
35 aclInputs.emplace_back(aclInputInfo);
36 }
37 const arm_compute::TensorInfo aclOutputInfo = BuildArmComputeTensorInfo(output);
Teresa Charlin552ee4d2020-07-16 12:44:16 +010038 std::vector<const arm_compute::ITensorInfo*> aclInputPtrs;
Nikhil Raj8599a412018-11-19 14:51:07 +000039 for (arm_compute::ITensorInfo& input : aclInputs)
40 {
41 aclInputPtrs.emplace_back(&input);
42 }
43
Derek Lamberti0790dce2019-04-15 18:37:35 +010044 size_t aclAxis = CalcAxis(descriptor);
Nikhil Raj8599a412018-11-19 14:51:07 +000045 return arm_compute::CLConcatenateLayer::validate(aclInputPtrs, &aclOutputInfo, aclAxis);
Nikhil Raj8599a412018-11-19 14:51:07 +000046}
47
Sadik Armagane9444752020-12-02 11:28:58 +000048ClConcatWorkload::ClConcatWorkload(const ConcatQueueDescriptor& descriptor,
49 const WorkloadInfo& info,
50 const arm_compute::CLCompileContext& clCompileContext)
Jim Flynne242f2d2019-05-22 14:24:13 +010051: BaseWorkload<ConcatQueueDescriptor>(descriptor, info)
Nikhil Raj8599a412018-11-19 14:51:07 +000052{
Derek Lamberti0790dce2019-04-15 18:37:35 +010053 bool allInputsAreSubtensors = true;
Nikhil Raj8599a412018-11-19 14:51:07 +000054
Derek Lamberti0790dce2019-04-15 18:37:35 +010055 // Check that all inputs are sub-tensors
56 for (auto input : descriptor.m_Inputs)
Nikhil Raj8599a412018-11-19 14:51:07 +000057 {
Derek Lamberti0790dce2019-04-15 18:37:35 +010058 if (!input->GetParent())
59 {
Jim Flynne242f2d2019-05-22 14:24:13 +010060 // Non sub-tensor input found so we need to execute the concat function
Derek Lamberti0790dce2019-04-15 18:37:35 +010061 allInputsAreSubtensors = false;
62 break;
63 }
64 }
65
66 if (allInputsAreSubtensors)
67 {
Jim Flynne242f2d2019-05-22 14:24:13 +010068 // Can skip configuring the concat function since it's not executed
Nikhil Raj8599a412018-11-19 14:51:07 +000069 return;
70 }
71
Teresa Charlin552ee4d2020-07-16 12:44:16 +010072 std::vector<const arm_compute::ICLTensor *> aclInputs;
Nikhil Raj8599a412018-11-19 14:51:07 +000073 for (auto input : m_Data.m_Inputs)
74 {
Jan Eilers3c9e0452020-04-10 13:00:44 +010075 arm_compute::ICLTensor& aclInput = armnn::PolymorphicPointerDowncast<IClTensorHandle>(input)->GetTensor();
Nikhil Raj8599a412018-11-19 14:51:07 +000076 aclInputs.emplace_back(&aclInput);
77 }
Jan Eilers3c9e0452020-04-10 13:00:44 +010078
79 arm_compute::ICLTensor& output =
80 armnn::PolymorphicPointerDowncast<IClTensorHandle>(m_Data.m_Outputs[0])->GetTensor();
Nikhil Raj8599a412018-11-19 14:51:07 +000081
Derek Lamberti0790dce2019-04-15 18:37:35 +010082 // Create the layer function
Matthew Bentham9b3e7382020-02-05 21:39:55 +000083 auto layer = std::make_unique<arm_compute::CLConcatenateLayer>();
Nikhil Raj8599a412018-11-19 14:51:07 +000084
Derek Lamberti0790dce2019-04-15 18:37:35 +010085 // Configure input and output tensors
86 size_t aclAxis = CalcAxis(descriptor.m_Parameters);
Sadik Armagane9444752020-12-02 11:28:58 +000087 layer->configure(clCompileContext, aclInputs, &output, aclAxis);
Nikhil Raj8599a412018-11-19 14:51:07 +000088
Derek Lamberti0790dce2019-04-15 18:37:35 +010089 // Prepare
Matthew Bentham9b3e7382020-02-05 21:39:55 +000090 layer->prepare();
91 m_Layer = std::move(layer);
Nikhil Raj8599a412018-11-19 14:51:07 +000092}
93
Jim Flynn69059412019-05-17 13:03:57 +010094void ClConcatWorkload::Execute() const
Nikhil Raj8599a412018-11-19 14:51:07 +000095{
Derek Lamberti0790dce2019-04-15 18:37:35 +010096 if (m_Layer)
Nikhil Raj8599a412018-11-19 14:51:07 +000097 {
Jim Flynn69059412019-05-17 13:03:57 +010098 ARMNN_SCOPED_PROFILING_EVENT_CL("ClConcatWorkload_Execute");
Derek Lamberti0790dce2019-04-15 18:37:35 +010099 m_Layer->run();
Nikhil Raj8599a412018-11-19 14:51:07 +0000100 }
Nikhil Raj8599a412018-11-19 14:51:07 +0000101}
102
Matthew Bentham9b3e7382020-02-05 21:39:55 +0000103} //namespace armnn