blob: 2b64becb26adb2ae636b548c4485e3cb63d6520f [file] [log] [blame]
Ferran Balaguerd73d14f2019-06-10 10:29:54 +01001//
Mike Kelly7cbe7812023-07-25 17:37:33 +01002// Copyright © 2019-2023 Arm Ltd and Contributors. All rights reserved.
Ferran Balaguerd73d14f2019-06-10 10:29:54 +01003// SPDX-License-Identifier: MIT
4//
5
6#include "RefL2NormalizationWorkload.hpp"
Ferran Balaguerd73d14f2019-06-10 10:29:54 +01007#include "RefWorkloadUtils.hpp"
8#include "Decoders.hpp"
9#include "Encoders.hpp"
Ferran Balaguerd73d14f2019-06-10 10:29:54 +010010
Matteo Martincighe011d202019-11-28 11:35:47 +000011#include <Profiling.hpp>
12
13#include <armnnUtils/DataLayoutIndexed.hpp>
Matthew Sloyan171214c2020-09-09 09:07:37 +010014#include <armnn/utility/NumericCast.hpp>
Matthew Jackson82b15ed2019-07-25 16:14:30 +010015
Ferran Balaguerd73d14f2019-06-10 10:29:54 +010016#include <cmath>
17
18using namespace armnnUtils;
19
20namespace armnn
21{
22RefL2NormalizationWorkload::RefL2NormalizationWorkload(
Matteo Martincighe011d202019-11-28 11:35:47 +000023 const L2NormalizationQueueDescriptor& descriptor,
24 const WorkloadInfo& info)
Finn Williams73c547d2022-02-15 20:47:34 +000025 : RefBaseWorkload<L2NormalizationQueueDescriptor>(descriptor, info) {}
Ferran Balaguerd73d14f2019-06-10 10:29:54 +010026
Matteo Martincighe011d202019-11-28 11:35:47 +000027void RefL2NormalizationWorkload::Execute() const
28{
Finn Williamsb8181f72021-04-07 10:23:21 +010029 Execute(m_Data.m_Inputs, m_Data.m_Outputs);
30}
31
Matthew Sloyan2d213a72022-06-30 17:13:04 +010032void RefL2NormalizationWorkload::ExecuteAsync(ExecutionData& executionData)
Finn Williamsb8181f72021-04-07 10:23:21 +010033{
Matthew Sloyan2d213a72022-06-30 17:13:04 +010034 WorkingMemDescriptor* workingMemDescriptor = static_cast<WorkingMemDescriptor*>(executionData.m_Data);
35 Execute(workingMemDescriptor->m_Inputs, workingMemDescriptor->m_Outputs);
Finn Williamsb8181f72021-04-07 10:23:21 +010036}
37
38void RefL2NormalizationWorkload::Execute(std::vector<ITensorHandle*> inputs, std::vector<ITensorHandle*> outputs) const
39{
Mike Kelly7cbe7812023-07-25 17:37:33 +010040 ARMNN_SCOPED_PROFILING_EVENT_REF_NAME_GUID("RefL2NormalizationWorkload_Execute");
Matteo Martincighe011d202019-11-28 11:35:47 +000041
Finn Williamsb8181f72021-04-07 10:23:21 +010042 const TensorInfo& inputInfo = GetTensorInfo(inputs[0]);
43 const TensorInfo& outputInfo = GetTensorInfo(outputs[0]);
Matteo Martincighe011d202019-11-28 11:35:47 +000044
Finn Williamsb8181f72021-04-07 10:23:21 +010045 auto inputDecoder = MakeDecoder<float>(inputInfo, inputs[0]->Map());
46 auto outputEncoder = MakeEncoder<float>(outputInfo, outputs[0]->Map());
Matteo Martincighe011d202019-11-28 11:35:47 +000047
48 DataLayoutIndexed dataLayout(m_Data.m_Parameters.m_DataLayout);
49
50 const TensorShape& shape = inputInfo.GetShape();
51 unsigned int paddedShapeArray[4];
Matthew Sloyan171214c2020-09-09 09:07:37 +010052 const int idxShift = 4 - armnn::numeric_cast<int>(shape.GetNumDimensions());
Matteo Martincighe011d202019-11-28 11:35:47 +000053
54 const unsigned int batches = (idxShift == 0) ? shape[0] : 1;
55 paddedShapeArray[0] = batches;
56
Matthew Sloyan171214c2020-09-09 09:07:37 +010057 const int channelsIdx = armnn::numeric_cast<int>(dataLayout.GetChannelsIndex());
Matteo Martincighe011d202019-11-28 11:35:47 +000058 const unsigned int channels = (channelsIdx - idxShift >= 0)
Matthew Sloyan171214c2020-09-09 09:07:37 +010059 ? shape[armnn::numeric_cast<unsigned int>(channelsIdx - idxShift)]
Matteo Martincighe011d202019-11-28 11:35:47 +000060 : 1;
61 paddedShapeArray[channelsIdx] = channels;
62
Matthew Sloyan171214c2020-09-09 09:07:37 +010063 const int heightIdx = armnn::numeric_cast<int>(dataLayout.GetHeightIndex());
Matteo Martincighe011d202019-11-28 11:35:47 +000064 const unsigned int height = (heightIdx - idxShift >= 0)
Matthew Sloyan171214c2020-09-09 09:07:37 +010065 ? shape[armnn::numeric_cast<unsigned int>(heightIdx - idxShift)]
Matteo Martincighe011d202019-11-28 11:35:47 +000066 : 1;
67 paddedShapeArray[heightIdx] = height;
68
Matthew Sloyan171214c2020-09-09 09:07:37 +010069 const int widthIdx = armnn::numeric_cast<int>(dataLayout.GetWidthIndex());
Matteo Martincighe011d202019-11-28 11:35:47 +000070 const unsigned int width = (widthIdx - idxShift >= 0)
Matthew Sloyan171214c2020-09-09 09:07:37 +010071 ? shape[armnn::numeric_cast<unsigned int>(widthIdx - idxShift)]
Matteo Martincighe011d202019-11-28 11:35:47 +000072 : 1;
73 paddedShapeArray[widthIdx] = width;
74
75 const TensorShape& paddedShape = TensorShape(4, paddedShapeArray);
76
77 for (unsigned int n = 0; n < batches; ++n)
Ferran Balaguerd73d14f2019-06-10 10:29:54 +010078 {
Matteo Martincighe011d202019-11-28 11:35:47 +000079 for (unsigned int c = 0; c < channels; ++c)
Ferran Balaguerd73d14f2019-06-10 10:29:54 +010080 {
Matteo Martincighe011d202019-11-28 11:35:47 +000081 for (unsigned int h = 0; h < height; ++h)
Ferran Balaguerd73d14f2019-06-10 10:29:54 +010082 {
Matteo Martincighe011d202019-11-28 11:35:47 +000083 for (unsigned int w = 0; w < width; ++w)
Ferran Balaguerd73d14f2019-06-10 10:29:54 +010084 {
Matteo Martincighe011d202019-11-28 11:35:47 +000085 float reduction = 0.0;
86 for (unsigned int d = 0; d < channels; ++d)
Ferran Balaguerd73d14f2019-06-10 10:29:54 +010087 {
Matteo Martincighe011d202019-11-28 11:35:47 +000088 unsigned int inputIndex = dataLayout.GetIndex(paddedShape, n, d, h, w);
Ferran Balaguerd73d14f2019-06-10 10:29:54 +010089
Matteo Martincighe011d202019-11-28 11:35:47 +000090 (*inputDecoder)[inputIndex];
91 const float value = inputDecoder->Get();
92 reduction += value * value;
Ferran Balaguerd73d14f2019-06-10 10:29:54 +010093 }
Matteo Martincighe011d202019-11-28 11:35:47 +000094
95 unsigned int index = dataLayout.GetIndex(paddedShape, n, c, h, w);
96
97 float maximum = reduction < m_Data.m_Parameters.m_Eps ? m_Data.m_Parameters.m_Eps : reduction;
98
99 const float scale = 1.0f / sqrtf(maximum);
100
101 (*inputDecoder)[index];
102 (*outputEncoder)[index];
103 outputEncoder->Set(inputDecoder->Get() * scale);
Ferran Balaguerd73d14f2019-06-10 10:29:54 +0100104 }
105 }
106 }
107 }
Matteo Martincighe011d202019-11-28 11:35:47 +0000108}
Ferran Balaguerd73d14f2019-06-10 10:29:54 +0100109
110} //namespace armnn