aboutsummaryrefslogtreecommitdiff
path: root/src/backends/reference/workloads/RefL2NormalizationWorkload.cpp
blob: ce5699ef0b33c141a6f2e4476afb137396727139 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
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