ONE - On-device Neural Engine
Loading...
Searching...
No Matches
PALLogistic.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2024 Samsung Electronics Co., Ltd. All Rights Reserved
3 * Copyright 2020 The TensorFlow Authors. All Rights Reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#ifndef ONERT_MICRO_EXECUTE_PAL_LOGISTIC_H
19#define ONERT_MICRO_EXECUTE_PAL_LOGISTIC_H
20
21#include "PALUtils.h"
22
23#include <cmath>
24
25namespace onert_micro
26{
27namespace execute
28{
29namespace pal
30{
31
32OMStatus inline Logistic(const int flat_size, const float *input_data, float *output_data)
33{
34 const float cutoff_upper = 16.619047164916992188f;
35 const float cutoff_lower = -9.f;
36
37 // Rational for using approximation in reference kernel.
38 // 0. This approximation gives enough precision for float.
39 // 1. This works around an issue on an embedded chipset where exp() does not
40 // return correctly as expected - exp(x) should return inf when overflown
41 // not 1.701417 IEEE 754 defines representation for inf.
42 // 2. This will speed up calculation and is matching the behavior in the
43 // optimized kernels. (check the definition of scalar_logistic_op<float>)
44
45 for (int i = 0; i < flat_size; i++)
46 {
47 float val = input_data[i];
48 float result;
49 if (val > cutoff_upper)
50 {
51 result = 1.0f;
52 }
53 else if (val < cutoff_lower)
54 {
55 result = std::exp(val);
56 }
57 else
58 {
59 result = 1.f / (1.f + std::exp(-val));
60 }
61 output_data[i] = result;
62 }
63 return Ok;
64}
65
66OMStatus inline Logistic(const int flat_size, const int8_t *input_data, float input_scale,
67 int input_zero_point, int8_t *output_data, float output_scale,
68 int output_zero_point)
69{
70 const float cutoff_upper = 16.619047164916992188f;
71 const float cutoff_lower = -9.f;
72
73 // Rational for using approximation in reference kernel.
74 // 0. This approximation gives enough precision for float.
75 // 1. This works around an issue on an embedded chipset where exp() does not
76 // return correctly as expected - exp(x) should return inf when overflown
77 // not 1.701417 IEEE 754 defines representation for inf.
78 // 2. This will speed up calculation and is matching the behavior in the
79 // optimized kernels. (check the definition of scalar_logistic_op<float>)
80
81 for (int i = 0; i < flat_size; i++)
82 {
83 // Dequantize.
84 float val = static_cast<float>((input_data[i] - input_zero_point) * input_scale);
85 float result;
86 if (val > cutoff_upper)
87 {
88 result = 1.0f;
89 }
90 else if (val < cutoff_lower)
91 {
92 result = std::exp(val);
93 }
94 else
95 {
96 result = 1.f / (1.f + std::exp(-val));
97 }
98 // Requantize
99 int8_t output = static_cast<int8_t>(std::round(result / output_scale) + output_zero_point);
100 output_data[i] = output;
101 }
102 return Ok;
103}
104
105} // namespace pal
106} // namespace execute
107} // namespace onert_micro
108
109#endif // ONERT_MICRO_EXECUTE_PAL_LOGISTIC_H
OMStatus Logistic(const int flat_size, const float *input_data, float *output_data)
Definition PALLogistic.h:32