Imported Upstream version 1.12.0
[platform/core/ml/nnfw.git] / compute / cker / include / cker / operation / InstanceNorm.h
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifndef __NNFW_CKER_INSTANCE_NORM_H__
18 #define __NNFW_CKER_INSTANCE_NORM_H__
19
20 #include "cker/Shape.h"
21 #include "cker/Types.h"
22 #include "cker/Utils.h"
23
24 #include <cmath>
25
26 namespace nnfw
27 {
28 namespace cker
29 {
30
31 inline void InstanceNorm(const InstanceNormParams &params, const Shape &input_shape,
32                          const float *input_data, const Shape &gamma_shape, const float *gamma_data,
33                          const Shape &beta_shape, const float *beta_data, const Shape &output_shape,
34                          float *output_data)
35 {
36   const int32_t batches = MatchingDim(input_shape, 0, output_shape, 0);
37   const int32_t heights = MatchingDim(input_shape, 1, output_shape, 1);
38   const int32_t widths = MatchingDim(input_shape, 2, output_shape, 2);
39   const int32_t channels = MatchingDim(input_shape, 3, output_shape, 3);
40   const float output_activation_min = params.float_activation_min;
41   const float output_activation_max = params.float_activation_max;
42
43   UNUSED_RELEASE(gamma_shape);
44   UNUSED_RELEASE(beta_shape);
45   assert(output_activation_min <= output_activation_max);
46
47   for (int32_t batch = 0; batch < batches; batch++)
48   {
49     for (int32_t channel = 0; channel < channels; channel++)
50     {
51       double sum = 0.0f;
52       double square_sum = 0.0f;
53       int32_t size = heights * widths;
54
55       for (int32_t height = 0; height < heights; height++)
56       {
57         for (int32_t width = 0; width < widths; width++)
58         {
59           double input_val = input_data[Offset(input_shape, batch, height, width, channel)];
60           sum += input_val;
61           square_sum += (input_val * input_val);
62         }
63       }
64
65       double mean = sum / size;
66       double var = square_sum / size - mean * mean;
67
68       double gamma = gamma_data[channel];
69       double beta = beta_data[channel];
70
71       double a = gamma / (std::sqrt(var + params.epsilon));
72       double b = -mean * a + beta;
73
74       for (int32_t height = 0; height < heights; height++)
75       {
76         for (int32_t width = 0; width < widths; width++)
77         {
78           double input_value = input_data[Offset(output_shape, batch, height, width, channel)];
79           double output_value = input_value * a + b;
80           output_data[Offset(output_shape, batch, height, width, channel)] =
81             ActivationFunctionWithMinMax((float)output_value, output_activation_min,
82                                          output_activation_max);
83         }
84       }
85     }
86   }
87 }
88
89 } // namespace cker
90 } // namespace nnfw
91
92 #endif // __NNFW_CKER_INSTANCE_NORM_H__