blob: 0fa9d43b15883483de4e71ad4dd4e8927765bed2 [file] [log] [blame]
James Conroyd47a0642019-09-17 14:22:06 +01001//
2// Copyright © 2019 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#include "NeonArgMinMaxWorkload.hpp"
7#include "NeonWorkloadUtils.hpp"
8
9#include <aclCommon/ArmComputeTensorUtils.hpp>
Matteo Martincighe011d202019-11-28 11:35:47 +000010
James Conroyd47a0642019-09-17 14:22:06 +010011#include <backendsCommon/CpuTensorHandle.hpp>
Matteo Martincighe011d202019-11-28 11:35:47 +000012
13#include <armnnUtils/TensorUtils.hpp>
James Conroyd47a0642019-09-17 14:22:06 +010014
15#include <arm_compute/runtime/NEON/functions/NEArgMinMaxLayer.h>
16
17namespace
18{
19unsigned int CalcAclAxis(unsigned int numDimensions, unsigned int axisIndex)
20{
21 return (numDimensions - axisIndex) - 1;
22}
23
24} //namespace
25
26namespace armnn
27{
28
29arm_compute::Status NeonArgMinMaxWorkloadValidate(const TensorInfo& input,
30 const TensorInfo& output,
31 const ArgMinMaxDescriptor& descriptor)
32{
33 const arm_compute::TensorInfo aclInput = armcomputetensorutils::BuildArmComputeTensorInfo(input);
34 const arm_compute::TensorInfo aclOutput = armcomputetensorutils::BuildArmComputeTensorInfo(output);
35
36 auto numDims = input.GetNumDimensions();
37 auto unsignedAxis = armnnUtils::GetUnsignedAxis(numDims, descriptor.m_Axis);
38 int aclAxis = boost::numeric_cast<int>(CalcAclAxis(numDims, unsignedAxis));
39
40 if (descriptor.m_Function == ArgMinMaxFunction::Max)
41 {
42 return arm_compute::NEArgMinMaxLayer::validate(&aclInput, aclAxis, &aclOutput,
43 arm_compute::ReductionOperation::ARG_IDX_MAX);
44 }
45 else
46 {
47 return arm_compute::NEArgMinMaxLayer::validate(&aclInput, aclAxis, &aclOutput,
48 arm_compute::ReductionOperation::ARG_IDX_MIN);
49 }
50}
51
52
53NeonArgMinMaxWorkload::NeonArgMinMaxWorkload(const ArgMinMaxQueueDescriptor& descriptor,
54 const WorkloadInfo& info)
55 : BaseWorkload<ArgMinMaxQueueDescriptor>(descriptor, info)
56{
57 arm_compute::ITensor& input = boost::polymorphic_downcast<IAclTensorHandle*>(m_Data.m_Inputs[0])->GetTensor();
58 arm_compute::ITensor& output = boost::polymorphic_downcast<IAclTensorHandle*>(m_Data.m_Outputs[0])->GetTensor();
59
60 auto numDims = info.m_InputTensorInfos[0].GetNumDimensions();
61 auto unsignedAxis = armnnUtils::GetUnsignedAxis(numDims, m_Data.m_Parameters.m_Axis);
62 int aclAxis = boost::numeric_cast<int>(CalcAclAxis(numDims, unsignedAxis));
63
James Conroy663c1842019-11-01 15:21:48 +000064 auto layer = std::make_unique<arm_compute::NEArgMinMaxLayer>();
65
James Conroyd47a0642019-09-17 14:22:06 +010066 if (m_Data.m_Parameters.m_Function == ArgMinMaxFunction::Max)
67 {
James Conroy663c1842019-11-01 15:21:48 +000068 layer->configure(&input, aclAxis, &output, arm_compute::ReductionOperation::ARG_IDX_MAX);
James Conroyd47a0642019-09-17 14:22:06 +010069 }
70 else
71 {
James Conroy663c1842019-11-01 15:21:48 +000072 layer->configure(&input, aclAxis, &output, arm_compute::ReductionOperation::ARG_IDX_MIN);
James Conroyd47a0642019-09-17 14:22:06 +010073 }
James Conroy663c1842019-11-01 15:21:48 +000074
75 m_ArgMinMaxLayer.reset(layer.release());
James Conroyd47a0642019-09-17 14:22:06 +010076}
77
78void NeonArgMinMaxWorkload::Execute() const
79{
80 ARMNN_SCOPED_PROFILING_EVENT_NEON("NeonArgMinMaxWorkload_Execute");
James Conroy663c1842019-11-01 15:21:48 +000081 m_ArgMinMaxLayer->run();
James Conroyd47a0642019-09-17 14:22:06 +010082}
83
84} //namespace armnn
85