diff options
author | Ferran Balaguer <ferran.balaguer@arm.com> | 2019-06-10 10:29:54 +0100 |
---|---|---|
committer | Matteo Martincigh <matteo.martincigh@arm.com> | 2019-06-14 13:03:28 +0000 |
commit | d73d14fd77fe1405a33b3ecf3c56e1ac65647ff7 (patch) | |
tree | a8f51e7d7c652653dc13c8c978aca347463c03a0 /src/backends/reference/workloads/RefL2NormalizationWorkload.cpp | |
parent | 0421e7f22d9ccd5d810b345731b766a96c841492 (diff) | |
download | armnn-d73d14fd77fe1405a33b3ecf3c56e1ac65647ff7.tar.gz |
IVGCVSW-3229 Refactor L2Normalization workload to support multiple data types
Signed-off-by: Ferran Balaguer <ferran.balaguer@arm.com>
Change-Id: I848056aad4b172d432664633eea000843d85a85d
Diffstat (limited to 'src/backends/reference/workloads/RefL2NormalizationWorkload.cpp')
-rw-r--r-- | src/backends/reference/workloads/RefL2NormalizationWorkload.cpp | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/src/backends/reference/workloads/RefL2NormalizationWorkload.cpp b/src/backends/reference/workloads/RefL2NormalizationWorkload.cpp new file mode 100644 index 0000000000..ce5699ef0b --- /dev/null +++ b/src/backends/reference/workloads/RefL2NormalizationWorkload.cpp @@ -0,0 +1,75 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "RefL2NormalizationWorkload.hpp" + +#include "RefWorkloadUtils.hpp" +#include "Decoders.hpp" +#include "Encoders.hpp" +#include "DataLayoutIndexed.hpp" + + +#include "Profiling.hpp" + +#include <cmath> + +using namespace armnnUtils; + +namespace armnn +{ +RefL2NormalizationWorkload::RefL2NormalizationWorkload( + const L2NormalizationQueueDescriptor& descriptor, + const WorkloadInfo& info) + : BaseWorkload<L2NormalizationQueueDescriptor>(descriptor, info) {} + + void RefL2NormalizationWorkload::Execute() const + { + ARMNN_SCOPED_PROFILING_EVENT(Compute::CpuRef, "RefL2NormalizationWorkload_Execute"); + + const TensorInfo& inputInfo = GetTensorInfo(m_Data.m_Inputs[0]); + const TensorInfo& outputInfo = GetTensorInfo(m_Data.m_Outputs[0]); + + auto inputDecoder = MakeDecoder<float>(inputInfo, m_Data.m_Inputs[0]->Map()); + auto outputEncoder = MakeEncoder<float>(outputInfo, m_Data.m_Outputs[0]->Map()); + + DataLayoutIndexed dataLayout(m_Data.m_Parameters.m_DataLayout); + + const unsigned int batches = inputInfo.GetShape()[0]; + const unsigned int channels = inputInfo.GetShape()[dataLayout.GetChannelsIndex()]; + const unsigned int height = inputInfo.GetShape()[dataLayout.GetHeightIndex()]; + const unsigned int width = inputInfo.GetShape()[dataLayout.GetWidthIndex()]; + + for (unsigned int n = 0; n < batches; ++n) + { + for (unsigned int c = 0; c < channels; ++c) + { + for (unsigned int h = 0; h < height; ++h) + { + for (unsigned int w = 0; w < width; ++w) + { + float reduction = 0.0; + for (unsigned int d = 0; d < channels; ++d) + { + unsigned int inputIndex = dataLayout.GetIndex(inputInfo.GetShape(), n, d, h, w); + + (*inputDecoder)[inputIndex]; + const float value = inputDecoder->Get(); + reduction += value * value; + } + + unsigned int index = dataLayout.GetIndex(inputInfo.GetShape(), n, c, h, w); + + const float scale = 1.0f / sqrtf(reduction); + + (*inputDecoder)[index]; + (*outputEncoder)[index]; + outputEncoder->Set(inputDecoder->Get() * scale); + } + } + } + } + } + +} //namespace armnn |