ArmNN
 22.05.01
RefL2NormalizationWorkload.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
7 #include "RefWorkloadUtils.hpp"
8 #include "Decoders.hpp"
9 #include "Encoders.hpp"
10 
11 #include <Profiling.hpp>
12 
15 
16 #include <cmath>
17 
18 using namespace armnnUtils;
19 
20 namespace armnn
21 {
23  const L2NormalizationQueueDescriptor& descriptor,
24  const WorkloadInfo& info)
25  : RefBaseWorkload<L2NormalizationQueueDescriptor>(descriptor, info) {}
26 
28 {
30 }
31 
33 {
34  Execute(workingMemDescriptor.m_Inputs, workingMemDescriptor.m_Outputs);
35 }
36 
37 void RefL2NormalizationWorkload::Execute(std::vector<ITensorHandle*> inputs, std::vector<ITensorHandle*> outputs) const
38 {
39  ARMNN_SCOPED_PROFILING_EVENT(Compute::CpuRef, "RefL2NormalizationWorkload_Execute");
40 
41  const TensorInfo& inputInfo = GetTensorInfo(inputs[0]);
42  const TensorInfo& outputInfo = GetTensorInfo(outputs[0]);
43 
44  auto inputDecoder = MakeDecoder<float>(inputInfo, inputs[0]->Map());
45  auto outputEncoder = MakeEncoder<float>(outputInfo, outputs[0]->Map());
46 
48 
49  const TensorShape& shape = inputInfo.GetShape();
50  unsigned int paddedShapeArray[4];
51  const int idxShift = 4 - armnn::numeric_cast<int>(shape.GetNumDimensions());
52 
53  const unsigned int batches = (idxShift == 0) ? shape[0] : 1;
54  paddedShapeArray[0] = batches;
55 
56  const int channelsIdx = armnn::numeric_cast<int>(dataLayout.GetChannelsIndex());
57  const unsigned int channels = (channelsIdx - idxShift >= 0)
58  ? shape[armnn::numeric_cast<unsigned int>(channelsIdx - idxShift)]
59  : 1;
60  paddedShapeArray[channelsIdx] = channels;
61 
62  const int heightIdx = armnn::numeric_cast<int>(dataLayout.GetHeightIndex());
63  const unsigned int height = (heightIdx - idxShift >= 0)
64  ? shape[armnn::numeric_cast<unsigned int>(heightIdx - idxShift)]
65  : 1;
66  paddedShapeArray[heightIdx] = height;
67 
68  const int widthIdx = armnn::numeric_cast<int>(dataLayout.GetWidthIndex());
69  const unsigned int width = (widthIdx - idxShift >= 0)
70  ? shape[armnn::numeric_cast<unsigned int>(widthIdx - idxShift)]
71  : 1;
72  paddedShapeArray[widthIdx] = width;
73 
74  const TensorShape& paddedShape = TensorShape(4, paddedShapeArray);
75 
76  for (unsigned int n = 0; n < batches; ++n)
77  {
78  for (unsigned int c = 0; c < channels; ++c)
79  {
80  for (unsigned int h = 0; h < height; ++h)
81  {
82  for (unsigned int w = 0; w < width; ++w)
83  {
84  float reduction = 0.0;
85  for (unsigned int d = 0; d < channels; ++d)
86  {
87  unsigned int inputIndex = dataLayout.GetIndex(paddedShape, n, d, h, w);
88 
89  (*inputDecoder)[inputIndex];
90  const float value = inputDecoder->Get();
91  reduction += value * value;
92  }
93 
94  unsigned int index = dataLayout.GetIndex(paddedShape, n, c, h, w);
95 
96  float maximum = reduction < m_Data.m_Parameters.m_Eps ? m_Data.m_Parameters.m_Eps : reduction;
97 
98  const float scale = 1.0f / sqrtf(maximum);
99 
100  (*inputDecoder)[index];
101  (*outputEncoder)[index];
102  outputEncoder->Set(inputDecoder->Get() * scale);
103  }
104  }
105  }
106  }
107 }
108 
109 } //namespace armnn
float m_Eps
Used to avoid dividing by zero.
CPU Execution: Reference C++ kernels.
Copyright (c) 2021 ARM Limited and Contributors.
#define ARMNN_SCOPED_PROFILING_EVENT(backendId, name)
Definition: Profiling.hpp:220
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
Provides access to the appropriate indexes for Channels, Height and Width based on DataLayout...
std::vector< ITensorHandle * > m_Outputs
void ExecuteAsync(WorkingMemDescriptor &workingMemDescriptor) override
unsigned int GetNumDimensions() const
Function that returns the tensor rank.
Definition: Tensor.cpp:174
RefL2NormalizationWorkload(const L2NormalizationQueueDescriptor &descriptor, const WorkloadInfo &info)
std::enable_if_t< std::is_unsigned< Source >::value &&std::is_unsigned< Dest >::value, Dest > numeric_cast(Source source)
Definition: NumericCast.hpp:35
Contains information about TensorInfos of a layer.
std::vector< ITensorHandle * > m_Inputs
const TensorInfo & GetTensorInfo(const ITensorHandle *tensorHandle)
float32 helpers