blob: da0d67523295e0cf75c7222078c153fc7deb2771 [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>
Nikhil Raj8599a412018-11-19 14:51:07 +00009#include <backendsCommon/CpuTensorHandle.hpp>
10#include <cl/ClTensorHandle.hpp>
11#include <cl/ClLayerSupport.hpp>
12
Derek Lamberti0790dce2019-04-15 18:37:35 +010013#include <arm_compute/core/Types.h>
Matthew Bentham9b3e7382020-02-05 21:39:55 +000014#include <arm_compute/runtime/CL/functions/CLConcatenateLayer.h>
Derek Lamberti0790dce2019-04-15 18:37:35 +010015
Nikhil Raj8599a412018-11-19 14:51:07 +000016namespace armnn
17{
18using namespace armcomputetensorutils;
19
Derek Lamberti0790dce2019-04-15 18:37:35 +010020namespace
21{
Jim Flynne242f2d2019-05-22 14:24:13 +010022size_t CalcAxis(const OriginsDescriptor& desc)
Derek Lamberti0790dce2019-04-15 18:37:35 +010023{
24 return (desc.GetNumDimensions() - desc.GetConcatAxis()) - 1;
25}
26} //namespace
27
Jim Flynn69059412019-05-17 13:03:57 +010028arm_compute::Status ClConcatWorkloadValidate(const std::vector<const TensorInfo*>& inputs,
Nikhil Raj8599a412018-11-19 14:51:07 +000029 const TensorInfo& output,
Jim Flynne242f2d2019-05-22 14:24:13 +010030 const OriginsDescriptor& descriptor)
Nikhil Raj8599a412018-11-19 14:51:07 +000031{
32 std::vector<arm_compute::TensorInfo> aclInputs;
33 for (const TensorInfo* input : inputs)
34 {
35 arm_compute::TensorInfo aclInputInfo = BuildArmComputeTensorInfo(*input, armnn::DataLayout::NCHW);
36 aclInputs.emplace_back(aclInputInfo);
37 }
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::CLConcatenateLayer::validate(aclInputPtrs, &aclOutputInfo, aclAxis);
Nikhil Raj8599a412018-11-19 14:51:07 +000047}
48
Jim Flynne242f2d2019-05-22 14:24:13 +010049ClConcatWorkload::ClConcatWorkload(const ConcatQueueDescriptor& descriptor, const WorkloadInfo& info)
50: BaseWorkload<ConcatQueueDescriptor>(descriptor, info)
Nikhil Raj8599a412018-11-19 14:51:07 +000051{
Derek Lamberti0790dce2019-04-15 18:37:35 +010052 bool allInputsAreSubtensors = true;
Nikhil Raj8599a412018-11-19 14:51:07 +000053
Derek Lamberti0790dce2019-04-15 18:37:35 +010054 // Check that all inputs are sub-tensors
55 for (auto input : descriptor.m_Inputs)
Nikhil Raj8599a412018-11-19 14:51:07 +000056 {
Derek Lamberti0790dce2019-04-15 18:37:35 +010057 if (!input->GetParent())
58 {
Jim Flynne242f2d2019-05-22 14:24:13 +010059 // Non sub-tensor input found so we need to execute the concat function
Derek Lamberti0790dce2019-04-15 18:37:35 +010060 allInputsAreSubtensors = false;
61 break;
62 }
63 }
64
65 if (allInputsAreSubtensors)
66 {
Jim Flynne242f2d2019-05-22 14:24:13 +010067 // Can skip configuring the concat function since it's not executed
Nikhil Raj8599a412018-11-19 14:51:07 +000068 return;
69 }
70
Teresa Charlin552ee4d2020-07-16 12:44:16 +010071 std::vector<const arm_compute::ICLTensor *> aclInputs;
Nikhil Raj8599a412018-11-19 14:51:07 +000072 for (auto input : m_Data.m_Inputs)
73 {
Jan Eilers3c9e0452020-04-10 13:00:44 +010074 arm_compute::ICLTensor& aclInput = armnn::PolymorphicPointerDowncast<IClTensorHandle>(input)->GetTensor();
Nikhil Raj8599a412018-11-19 14:51:07 +000075 aclInputs.emplace_back(&aclInput);
76 }
Jan Eilers3c9e0452020-04-10 13:00:44 +010077
78 arm_compute::ICLTensor& output =
79 armnn::PolymorphicPointerDowncast<IClTensorHandle>(m_Data.m_Outputs[0])->GetTensor();
Nikhil Raj8599a412018-11-19 14:51:07 +000080
Derek Lamberti0790dce2019-04-15 18:37:35 +010081 // Create the layer function
Matthew Bentham9b3e7382020-02-05 21:39:55 +000082 auto layer = std::make_unique<arm_compute::CLConcatenateLayer>();
Nikhil Raj8599a412018-11-19 14:51:07 +000083
Derek Lamberti0790dce2019-04-15 18:37:35 +010084 // Configure input and output tensors
85 size_t aclAxis = CalcAxis(descriptor.m_Parameters);
Matthew Bentham9b3e7382020-02-05 21:39:55 +000086 layer->configure(aclInputs, &output, aclAxis);
Nikhil Raj8599a412018-11-19 14:51:07 +000087
Derek Lamberti0790dce2019-04-15 18:37:35 +010088 // Prepare
Matthew Bentham9b3e7382020-02-05 21:39:55 +000089 layer->prepare();
90 m_Layer = std::move(layer);
Nikhil Raj8599a412018-11-19 14:51:07 +000091}
92
Jim Flynn69059412019-05-17 13:03:57 +010093void ClConcatWorkload::Execute() const
Nikhil Raj8599a412018-11-19 14:51:07 +000094{
Derek Lamberti0790dce2019-04-15 18:37:35 +010095 if (m_Layer)
Nikhil Raj8599a412018-11-19 14:51:07 +000096 {
Jim Flynn69059412019-05-17 13:03:57 +010097 ARMNN_SCOPED_PROFILING_EVENT_CL("ClConcatWorkload_Execute");
Derek Lamberti0790dce2019-04-15 18:37:35 +010098 m_Layer->run();
Nikhil Raj8599a412018-11-19 14:51:07 +000099 }
Nikhil Raj8599a412018-11-19 14:51:07 +0000100}
101
Matthew Bentham9b3e7382020-02-05 21:39:55 +0000102} //namespace armnn