blob: 6125f3609d18b11c8838ba70b35127a3b1907584 [file] [log] [blame]
Sadik Armagana2747482021-02-09 10:28:54 +00001//
2// Copyright © 2021 Arm Ltd and Contributors. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#include "NeonReduceWorkload.hpp"
7
8#include <aclCommon/ArmComputeUtils.hpp>
9#include <aclCommon/ArmComputeTensorUtils.hpp>
10
11#include <neon/NeonTensorHandle.hpp>
12
13#include "NeonWorkloadUtils.hpp"
14
15namespace armnn
16{
17using namespace armcomputetensorutils;
18
19arm_compute::Status NeonReduceWorkloadValidate(const TensorInfo& input,
20 const TensorInfo& output,
21 const ReduceDescriptor& desc)
22{
23 const arm_compute::TensorInfo aclInputInfo = armcomputetensorutils::BuildArmComputeTensorInfo(input);
Sadik Armagana2747482021-02-09 10:28:54 +000024
25 arm_compute::Coordinates coords = BuildArmComputeReductionCoordinates(aclInputInfo.num_dimensions(),
26 input.GetNumDimensions(),
27 desc.m_vAxis);
28
Matthew Sloyand905dec2021-05-03 12:22:03 +010029 // As ACL only support one axis, validate the layer for each axis if more than one is present.
30 if (!desc.m_vAxis.empty() && desc.m_vAxis.size() > 1)
31 {
32 arm_compute::Status status;
33
34 for (unsigned int i = 0; i != desc.m_vAxis.size(); ++i)
35 {
36 TensorInfo inputToModify = input;
37 std::vector<uint32_t> singleAxis(1, desc.m_vAxis[i]);
38
39 // Calculate the output shape using the input shape for a single axis.
40 // Currently the output TensorInfo inferred will be reduced upon multiple axis
41 // which will fail validation as only one axis is supported.
42 const TensorShape& reducedShape = ComputeReductionTensorShape(inputToModify, singleAxis, desc.m_KeepDims);
43 inputToModify.SetShape(reducedShape);
44
45 const arm_compute::TensorInfo aclOutputInfoModified =
46 armcomputetensorutils::BuildArmComputeTensorInfo(inputToModify);
47
48 status = arm_compute::NEReductionOperation::validate(&aclInputInfo,
49 &aclOutputInfoModified,
50 static_cast<unsigned int>(coords[i]),
51 ConvertReductionOperationToAcl(desc),
52 desc.m_KeepDims);
53 if (!status)
54 {
55 break;
56 }
57 }
58 return status;
59 }
60 else
61 {
62 const arm_compute::TensorInfo aclOutputInfo = armcomputetensorutils::BuildArmComputeTensorInfo(output);
63
64 return arm_compute::NEReductionOperation::validate(&aclInputInfo,
65 &aclOutputInfo,
66 static_cast<unsigned int>(coords[0]),
67 ConvertReductionOperationToAcl(desc),
68 desc.m_KeepDims);
69 }
Sadik Armagana2747482021-02-09 10:28:54 +000070}
71
72NeonReduceWorkload::NeonReduceWorkload(const ReduceQueueDescriptor& descriptor, const WorkloadInfo& info)
73 : BaseWorkload<ReduceQueueDescriptor>(descriptor, info)
74{
75 m_Data.ValidateInputsOutputs("NeonReduceWorkload", 1, 1);
76
77 arm_compute::ITensor& input = static_cast<IAclTensorHandle*>(m_Data.m_Inputs[0])->GetTensor();
78 arm_compute::ITensor& output = static_cast<IAclTensorHandle*>(m_Data.m_Outputs[0])->GetTensor();
79
80 arm_compute::Coordinates coords = BuildArmComputeReductionCoordinates(input.info()->num_dimensions(),
81 info.m_InputTensorInfos[0].GetNumDimensions(),
82 m_Data.m_Parameters.m_vAxis);
Matthew Sloyand905dec2021-05-03 12:22:03 +010083
Sadik Armagana2747482021-02-09 10:28:54 +000084 m_Layer.configure(&input,
85 &output,
86 static_cast<unsigned int>(coords[0]),
87 ConvertReductionOperationToAcl(m_Data.m_Parameters),
88 m_Data.m_Parameters.m_KeepDims);
89}
90
91void NeonReduceWorkload::Execute() const
92{
93 ARMNN_SCOPED_PROFILING_EVENT_NEON("NeonReduceWorkload_Execute");
94 m_Layer.run();
95}
96
97} //namespace armnn