blob: 3764b9a49a0299396864b7f8f88eff8cc4e9ce62 [file] [log] [blame]
Ferran Balaguerd73d14f2019-06-10 10:29:54 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#include "RefL2NormalizationWorkload.hpp"
7
8#include "RefWorkloadUtils.hpp"
9#include "Decoders.hpp"
10#include "Encoders.hpp"
11#include "DataLayoutIndexed.hpp"
12
Ferran Balaguerd73d14f2019-06-10 10:29:54 +010013#include "Profiling.hpp"
14
Matthew Jackson82b15ed2019-07-25 16:14:30 +010015#include <boost/numeric/conversion/cast.hpp>
16
Ferran Balaguerd73d14f2019-06-10 10:29:54 +010017#include <cmath>
18
19using namespace armnnUtils;
20
21namespace armnn
22{
23RefL2NormalizationWorkload::RefL2NormalizationWorkload(
24 const L2NormalizationQueueDescriptor& descriptor,
25 const WorkloadInfo& info)
26 : BaseWorkload<L2NormalizationQueueDescriptor>(descriptor, info) {}
27
28 void RefL2NormalizationWorkload::Execute() const
29 {
30 ARMNN_SCOPED_PROFILING_EVENT(Compute::CpuRef, "RefL2NormalizationWorkload_Execute");
31
32 const TensorInfo& inputInfo = GetTensorInfo(m_Data.m_Inputs[0]);
33 const TensorInfo& outputInfo = GetTensorInfo(m_Data.m_Outputs[0]);
34
35 auto inputDecoder = MakeDecoder<float>(inputInfo, m_Data.m_Inputs[0]->Map());
36 auto outputEncoder = MakeEncoder<float>(outputInfo, m_Data.m_Outputs[0]->Map());
37
38 DataLayoutIndexed dataLayout(m_Data.m_Parameters.m_DataLayout);
39
Matthew Jackson82b15ed2019-07-25 16:14:30 +010040 const TensorShape& shape = inputInfo.GetShape();
41 unsigned int paddedShapeArray[4];
42 const int idxShift = 4 - boost::numeric_cast<int>(shape.GetNumDimensions());
43
44 const unsigned int batches = (idxShift == 0) ? shape[0] : 1;
45 paddedShapeArray[0] = batches;
46
47 const int channelsIdx = boost::numeric_cast<int>(dataLayout.GetChannelsIndex());
48 const unsigned int channels = (channelsIdx - idxShift >= 0)
49 ? shape[boost::numeric_cast<unsigned int>(channelsIdx - idxShift)]
50 : 1;
51 paddedShapeArray[channelsIdx] = channels;
52
53 const int heightIdx = boost::numeric_cast<int>(dataLayout.GetHeightIndex());
54 const unsigned int height = (heightIdx - idxShift >= 0)
55 ? shape[boost::numeric_cast<unsigned int>(heightIdx - idxShift)]
56 : 1;
57 paddedShapeArray[heightIdx] = height;
58
59 const int widthIdx = boost::numeric_cast<int>(dataLayout.GetWidthIndex());
60 const unsigned int width = (widthIdx - idxShift >= 0)
61 ? shape[boost::numeric_cast<unsigned int>(widthIdx - idxShift)]
62 : 1;
63 paddedShapeArray[widthIdx] = width;
64
65 const TensorShape& paddedShape = TensorShape(4, paddedShapeArray);
Ferran Balaguerd73d14f2019-06-10 10:29:54 +010066
67 for (unsigned int n = 0; n < batches; ++n)
68 {
69 for (unsigned int c = 0; c < channels; ++c)
70 {
71 for (unsigned int h = 0; h < height; ++h)
72 {
73 for (unsigned int w = 0; w < width; ++w)
74 {
75 float reduction = 0.0;
76 for (unsigned int d = 0; d < channels; ++d)
77 {
Matthew Jackson82b15ed2019-07-25 16:14:30 +010078 unsigned int inputIndex = dataLayout.GetIndex(paddedShape, n, d, h, w);
Ferran Balaguerd73d14f2019-06-10 10:29:54 +010079
80 (*inputDecoder)[inputIndex];
81 const float value = inputDecoder->Get();
82 reduction += value * value;
83 }
84
Matthew Jackson82b15ed2019-07-25 16:14:30 +010085 unsigned int index = dataLayout.GetIndex(paddedShape, n, c, h, w);
Ferran Balaguerd73d14f2019-06-10 10:29:54 +010086
Ferran Balaguere52211e2019-06-17 12:23:52 +010087 float maximum = reduction < m_Data.m_Parameters.m_Eps ? m_Data.m_Parameters.m_Eps : reduction;
88
89 const float scale = 1.0f / sqrtf(maximum);
Ferran Balaguerd73d14f2019-06-10 10:29:54 +010090
91 (*inputDecoder)[index];
92 (*outputEncoder)[index];
93 outputEncoder->Set(inputDecoder->Get() * scale);
94 }
95 }
96 }
97 }
98 }
99
100} //namespace armnn