Imported Upstream version 1.25.0
[platform/core/ml/nnfw.git] / compiler / record-minmax / src / RecordFunction.cpp
1 /*
2  * Copyright (c) 2023 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 #include "RecordFunction.h"
18
19 #include <luci/IR/CircleQuantParam.h>
20
21 #include <cassert>
22 #include <algorithm>
23 #include <cmath>
24 #include <limits>
25 #include <stdexcept>
26
27 namespace record_minmax
28 {
29
30 float getNthPercentile(std::vector<float> &vector, float percentile)
31 {
32   if (percentile < 0 || percentile > 100)
33     throw std::runtime_error("Percentile must be ranged from 0 to 100");
34
35   if (vector.empty())
36     throw std::runtime_error("Percentile must take a non-empty vector as an argument");
37
38   if (vector.size() == 1)
39     return vector[0];
40
41   std::vector<float> copy;
42   copy.assign(vector.begin(), vector.end());
43   std::sort(copy.begin(), copy.end());
44
45   if (percentile == 0.0)
46     return copy.front();
47
48   if (percentile == 100.0)
49     return copy.back();
50
51   int index = static_cast<int>(std::floor((copy.size() - 1) * percentile / 100.0));
52
53   float percent_i = static_cast<float>(index) / static_cast<float>(copy.size() - 1);
54   float fraction =
55     (percentile / 100.0 - percent_i) / ((index + 1.0) / (copy.size() - 1.0) - percent_i);
56   float res = copy[index] + fraction * (copy[index + 1] - copy[index]);
57   return res;
58 }
59
60 float getMovingAverage(const std::vector<float> &vector, const float alpha,
61                        const uint8_t batch_size, bool is_min)
62 {
63   assert(!vector.empty());
64   assert(alpha >= 0.0 && alpha <= 1.0);
65   assert(batch_size > 0);
66
67   auto getBatchMinOrMax = [&](uint32_t start_index) {
68     assert(start_index < vector.size());
69
70     float res = is_min ? std::numeric_limits<float>::max() : std::numeric_limits<float>::lowest();
71     for (uint32_t offset = 0; offset < batch_size; offset++)
72     {
73       uint32_t index = start_index + offset;
74       if (index >= vector.size())
75         break;
76
77       if (is_min)
78       {
79         res = vector[index] < res ? vector[index] : res;
80       }
81       else
82       {
83         res = vector[index] > res ? vector[index] : res;
84       }
85     }
86     return res;
87   };
88
89   float curr_avg = getBatchMinOrMax(0);
90   for (uint32_t i = batch_size; i < vector.size(); i += batch_size)
91   {
92     curr_avg = curr_avg * alpha + getBatchMinOrMax(i) * (1.0 - alpha);
93   }
94   return curr_avg;
95 }
96
97 } // namespace record_minmax