blob: be096b4b2514311ed50a1582a420469be1e99adc [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//
5
6#include "NeonMergerWorkload.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>
11#include <backendsCommon/CpuTensorHandle.hpp>
12#include <neon/NeonTensorHandle.hpp>
13
Matthew Benthamd80a7122019-01-08 17:52:37 +000014#include <arm_compute/runtime/NEON/functions/NEConcatenateLayer.h>
Nikhil Raj8599a412018-11-19 14:51:07 +000015
16namespace armnn
17{
18using namespace armcomputetensorutils;
19
20arm_compute::Status NeonMergerWorkloadValidate(const std::vector<const TensorInfo*>& inputs,
21 const TensorInfo& output,
22 const MergerDescriptor& descriptor)
23
24{
25 std::vector<arm_compute::TensorInfo> aclInputs;
26 for (const TensorInfo* input : inputs)
27 {
28 arm_compute::TensorInfo aclInputInfo = BuildArmComputeTensorInfo(*input, armnn::DataLayout::NCHW);
29 aclInputs.emplace_back(aclInputInfo);
30 }
31 const arm_compute::TensorInfo aclOutputInfo = BuildArmComputeTensorInfo(output);
32 arm_compute::DataLayoutDimension aclAxis = arm_compute::DataLayoutDimension::WIDTH;
33
34 std::vector<arm_compute::ITensorInfo*> aclInputPtrs;
35 for (arm_compute::ITensorInfo& input : aclInputs)
36 {
37 aclInputPtrs.emplace_back(&input);
38 }
39
40 return arm_compute::NEConcatenateLayer::validate(aclInputPtrs, &aclOutputInfo, aclAxis);
41
42}
43
44NeonMergerWorkload::NeonMergerWorkload(
45const MergerQueueDescriptor& descriptor, const WorkloadInfo& info)
46 : BaseWorkload<MergerQueueDescriptor>(descriptor, info)
47{
48 m_Execute = true;
49
50 unsigned int innerAxisOrder = descriptor.m_Parameters.GetNumDimensions() - descriptor.m_Parameters.GetConcatAxis();
51
52 if (innerAxisOrder != 1)
53 {
54 m_Execute = false;
55 return;
56 }
57
58 std::vector<arm_compute::ITensor *> aclInputs;
59 arm_compute::DataLayout aclDataLayout = ConvertDataLayout(armnn::DataLayout::NCHW);
60 for (auto input : m_Data.m_Inputs)
61 {
62 arm_compute::ITensor& aclInput = boost::polymorphic_pointer_downcast<INeonTensorHandle>(input)->GetTensor();
63 aclInput.info()->set_data_layout(aclDataLayout);
64 aclInputs.emplace_back(&aclInput);
65 }
66 arm_compute::ITensor& output = boost::polymorphic_pointer_downcast<INeonTensorHandle>(
67 m_Data.m_Outputs[0])->GetTensor();
68 output.info()->set_data_layout(aclDataLayout);
69
70 arm_compute::DataLayoutDimension aclAxis = arm_compute::DataLayoutDimension::WIDTH;
71
Matthew Benthamd80a7122019-01-08 17:52:37 +000072 auto layer = std::make_unique<arm_compute::NEConcatenateLayer>();
73 layer->configure(aclInputs, &output, aclAxis);
74 m_Layer.reset(layer.release());
Nikhil Raj8599a412018-11-19 14:51:07 +000075
Matthew Benthamd80a7122019-01-08 17:52:37 +000076 m_Layer->prepare();
Nikhil Raj8599a412018-11-19 14:51:07 +000077}
78
79void NeonMergerWorkload::Execute() const
80{
81 if (m_Execute)
82 {
83 ARMNN_SCOPED_PROFILING_EVENT_NEON("NeonMergerWorkload_Execute");
Matthew Benthamd80a7122019-01-08 17:52:37 +000084 m_Layer->run();
Nikhil Raj8599a412018-11-19 14:51:07 +000085 }
86}
87
88} //namespace armnn
89