blob: 537046616304d9d3321cfe81107e1cb3f20186e1 [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>
8#include <backendsCommon/CpuTensorHandle.hpp>
9#include <cl/ClTensorHandle.hpp>
10#include <cl/ClLayerSupport.hpp>
11
Derek Lamberti0790dce2019-04-15 18:37:35 +010012#include <arm_compute/core/Types.h>
Matthew Bentham9b3e7382020-02-05 21:39:55 +000013#include <arm_compute/runtime/CL/functions/CLConcatenateLayer.h>
Derek Lamberti0790dce2019-04-15 18:37:35 +010014
Nikhil Raj8599a412018-11-19 14:51:07 +000015#include <boost/polymorphic_pointer_cast.hpp>
16
17namespace armnn
18{
19using namespace armcomputetensorutils;
20
Derek Lamberti0790dce2019-04-15 18:37:35 +010021namespace
22{
Jim Flynne242f2d2019-05-22 14:24:13 +010023size_t CalcAxis(const OriginsDescriptor& desc)
Derek Lamberti0790dce2019-04-15 18:37:35 +010024{
25 return (desc.GetNumDimensions() - desc.GetConcatAxis()) - 1;
26}
27} //namespace
28
Jim Flynn69059412019-05-17 13:03:57 +010029arm_compute::Status ClConcatWorkloadValidate(const std::vector<const TensorInfo*>& inputs,
Nikhil Raj8599a412018-11-19 14:51:07 +000030 const TensorInfo& output,
Jim Flynne242f2d2019-05-22 14:24:13 +010031 const OriginsDescriptor& descriptor)
Nikhil Raj8599a412018-11-19 14:51:07 +000032{
33 std::vector<arm_compute::TensorInfo> aclInputs;
34 for (const TensorInfo* input : inputs)
35 {
36 arm_compute::TensorInfo aclInputInfo = BuildArmComputeTensorInfo(*input, armnn::DataLayout::NCHW);
37 aclInputs.emplace_back(aclInputInfo);
38 }
39 const arm_compute::TensorInfo aclOutputInfo = BuildArmComputeTensorInfo(output);
Nikhil Raj8599a412018-11-19 14:51:07 +000040 std::vector<arm_compute::ITensorInfo*> aclInputPtrs;
41 for (arm_compute::ITensorInfo& input : aclInputs)
42 {
43 aclInputPtrs.emplace_back(&input);
44 }
45
Derek Lamberti0790dce2019-04-15 18:37:35 +010046 size_t aclAxis = CalcAxis(descriptor);
Nikhil Raj8599a412018-11-19 14:51:07 +000047 return arm_compute::CLConcatenateLayer::validate(aclInputPtrs, &aclOutputInfo, aclAxis);
Nikhil Raj8599a412018-11-19 14:51:07 +000048}
49
Jim Flynne242f2d2019-05-22 14:24:13 +010050ClConcatWorkload::ClConcatWorkload(const ConcatQueueDescriptor& descriptor, const WorkloadInfo& info)
51: 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
72 std::vector<arm_compute::ICLTensor *> aclInputs;
Nikhil Raj8599a412018-11-19 14:51:07 +000073 for (auto input : m_Data.m_Inputs)
74 {
75 arm_compute::ICLTensor& aclInput = boost::polymorphic_pointer_downcast<IClTensorHandle>(input)->GetTensor();
Nikhil Raj8599a412018-11-19 14:51:07 +000076 aclInputs.emplace_back(&aclInput);
77 }
78 arm_compute::ICLTensor& output = boost::polymorphic_pointer_downcast<IClTensorHandle>(
79 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