ArmNN
 25.11
Loading...
Searching...
No Matches
RefNormalizationWorkload.cpp
Go to the documentation of this file.
1//
2// Copyright © 2017-2024 Arm Ltd and Contributors. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
7
8#include <armnn/Logging.hpp>
9#include <armnn/Tensor.hpp>
12
13#include <Profiling.hpp>
14
15#include "RefWorkloadUtils.hpp"
16#include "Decoders.hpp"
17#include "Encoders.hpp"
18
19using namespace armnn;
20using namespace armnnUtils;
21
22namespace
23{
24
25// Helper function to compute "Within" normalization using Krichevsky 2012: Local Brightness Normalization.
26void NormalizeWithinUingLbr(Decoder<float>& inputData,
27 Encoder<float>& outputData,
28 const TensorShape& tensorShape,
29 uint32_t norm_size,
30 float alpha,
31 float beta,
32 float kappa)
33{
34 const unsigned int batchSize = tensorShape[0];
35 const unsigned int depth = tensorShape[1];
36 const unsigned int rows = tensorShape[2];
37 const unsigned int cols = tensorShape[3];
38
39 int radius = armnn::numeric_cast<int>(norm_size / 2u); /* Strong Assumption on rounding Mode */
40
41 for (unsigned int n = 0; n < batchSize; n++)
42 {
43 for (unsigned int c = 0; c < depth; c++)
44 {
45 for (unsigned int h = 0; h < rows; h++)
46 {
47 for (unsigned int w = 0; w < cols; w++)
48 {
49 float accumulated_scale = 0.0;
50 for (int y = -radius; y <= radius; y++)
51 {
52 for (int x = -radius; x <= radius; x++)
53 {
54 int i = armnn::numeric_cast<int>(w) + x;
55 int j = armnn::numeric_cast<int>(h) + y;
56
57 if ((i < 0) || (i >= armnn::numeric_cast<int>(cols)))
58 {
59 continue;
60 }
61
62 if ((j < 0) || (j >= armnn::numeric_cast<int>(rows)))
63 {
64 continue;
65 }
66
67 unsigned int inputIndex = n * cols * rows * depth +
68 c * cols * rows +
71 inputData[inputIndex];
72 float inval = inputData.Get();
73
74 accumulated_scale += inval*inval;
75 }
76 }
77
78 unsigned int index = n * cols * rows * depth +
79 c * cols * rows +
80 h * cols +
81 w;
82 inputData[index];
83 outputData[index];
84 outputData.Set(inputData.Get() / (powf((kappa + (accumulated_scale * alpha)), beta)));
85 }
86 }
87 }
88 }
89}
90
91// Helper function to compute "Across" normalization using Krichevsky 2012: Local Brightness Normalization.
92void NormalizeAcrossUingLbr(Decoder<float>& inputData,
93 Encoder<float>& outputData,
94 const TensorShape& tensorShape,
95 uint32_t norm_size,
96 float alpha,
97 float beta,
98 float kappa,
99 DataLayout dataLayout)
100{
101 DataLayoutIndexed dataLayoutIndexed(dataLayout);
102
103 const unsigned int batchSize = tensorShape[0];
104 const unsigned int depth = tensorShape[dataLayoutIndexed.GetChannelsIndex()];
105 const unsigned int rows = tensorShape[dataLayoutIndexed.GetHeightIndex()];
106 const unsigned int cols = tensorShape[dataLayoutIndexed.GetWidthIndex()];
107
108 int radius = armnn::numeric_cast<int>(norm_size / 2u); /* Strong Assumption on rounding Mode */
109
110 for (unsigned int n = 0; n < batchSize; n++)
111 {
112 for (unsigned int c = 0; c < depth; c++)
113 {
114 for (unsigned int h = 0; h < rows; h++)
115 {
116 for (unsigned int w = 0; w < cols; w++)
117 {
118 float accumulated_scale = 0.0;
119 for (int z = -radius; z <= radius; z++)
120 {
121 int k = armnn::numeric_cast<int>(c) + z;
122
123 if ((k < 0) || (k >= armnn::numeric_cast<int>(depth)))
124 {
125 continue;
126 }
127
128 unsigned inputIndex = dataLayoutIndexed.GetIndex(tensorShape,
129 n,
131 h,
132 w);
133
134 inputData[inputIndex];
135 float inval = inputData.Get();
136
137 accumulated_scale += inval * inval;
138 }
139
140 float scale = kappa + (accumulated_scale * alpha);
141 scale = powf(scale, -beta);
142
143 unsigned index = dataLayoutIndexed.GetIndex(tensorShape, n, c, h, w);
144
145 inputData[index];
146 outputData[index];
147 outputData.Set(scale * inputData.Get());
148 }
149 }
150 }
151 }
152}
153
154} // Anonymous namespace
155
156namespace armnn
157{
158
163
165{
166 Execute(m_Data.m_Inputs, m_Data.m_Outputs);
167}
168
169void RefNormalizationWorkload::Execute(std::vector<ITensorHandle*> inputs, std::vector<ITensorHandle*> outputs) const
170{
171 ARMNN_SCOPED_PROFILING_EVENT_REF_NAME_GUID("RefNormalizationWorkload_Execute");
172
173 const TensorInfo& inputInfo = GetTensorInfo(inputs[0]);
174
175 auto inputDecoder = MakeDecoder<float>(inputInfo, inputs[0]->Map());
176 auto outputEncoder = MakeEncoder<float>(inputInfo, outputs[0]->Map());
177
179 {
181 {
182 NormalizeWithinUingLbr(*inputDecoder,
183 *outputEncoder,
184 inputInfo.GetShape(),
189 }
191 {
192 NormalizeAcrossUingLbr(*inputDecoder,
193 *outputEncoder,
194 inputInfo.GetShape(),
200 }
201 else
202 {
203 ARMNN_LOG(warning) << "Illegal NORMALIZATION mode in normalization_f32";
204 return;
205 }
206 }
207 else
208 {
209 ARMNN_LOG(warning) << "Lcr method (Jarret 2009: Local Contrast Normalization) not supported yet.";
210 return;
211 }
212}
213
214} // namespace armnn
#define ARMNN_LOG(severity)
Definition Logging.hpp:212
#define ARMNN_SCOPED_PROFILING_EVENT_REF_NAME_GUID(label)
Creates a profiling event that uses GetGuid() and GetName() from the calling class.
virtual IType Get() const =0
virtual void Set(IType right)=0
RefBaseWorkload(const NormalizationQueueDescriptor &descriptor, const WorkloadInfo &info)
RefNormalizationWorkload(const NormalizationQueueDescriptor &descriptor, const WorkloadInfo &info)
const TensorShape & GetShape() const
Definition Tensor.hpp:193
Provides access to the appropriate indexes for Channels, Height and Width based on DataLayout.
Copyright (c) 2021 ARM Limited and Contributors.
std::enable_if_t< std::is_unsigned< Source >::value &&std::is_unsigned< Dest >::value, Dest > numeric_cast(Source source)
std::unique_ptr< Decoder< T > > MakeDecoder(const TensorInfo &info, const void *data=nullptr)
std::unique_ptr< Encoder< T > > MakeEncoder(const TensorInfo &info, void *data=nullptr)
DataLayout
Definition Types.hpp:63
@ LocalBrightness
Krichevsky 2012: Local Brightness Normalization.
Definition Types.hpp:217
armnn::TensorInfo GetTensorInfo(unsigned int numberOfBatches, unsigned int numberOfChannels, unsigned int height, unsigned int width, const armnn::DataLayout dataLayout, const armnn::DataType dataType)
NormalizationAlgorithmMethod m_NormMethodType
Normalization method algorithm to use (LocalBrightness, LocalContrast).
float m_Alpha
Alpha value for the normalization equation.
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
float m_Beta
Beta value for the normalization equation.
float m_K
Kappa value used for the across channel normalization equation.
uint32_t m_NormSize
Depth radius value.
NormalizationAlgorithmChannel m_NormChannelType
Normalization channel algorithm to use (Across, Within).
Contains information about TensorInfos of a layer.