2 * Copyright (c) 2021 Samsung Electronics Co., Ltd. All Rights Reserved
3 * Copyright 2017 The TensorFlow Authors. All Rights Reserved.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #ifndef LUCI_INTERPRETER_PAL_SOFTMAX_COMMON_H
19 #define LUCI_INTERPRETER_PAL_SOFTMAX_COMMON_H
21 namespace luci_interpreter_pal
26 inline int flatSizeSkipDim(const luci_interpreter::RuntimeShape &shape, int skip_dim)
28 const int dims_count = shape.dimensionsCount();
29 const auto *dims_data = shape.dimsData();
31 for (int i = 0; i < dims_count; ++i)
33 flat_size *= (i == skip_dim) ? 1 : dims_data[i];
40 inline void Softmax(const double beta, const luci_interpreter::RuntimeShape &input_shape,
41 const float *input_data, float *output_data)
43 const int trailing_dim = input_shape.dimensionsCount() - 1;
44 const int outer_size = flatSizeSkipDim(input_shape, trailing_dim);
46 const int depth = input_shape.dims(trailing_dim);
48 for (int i = 0; i < outer_size; ++i)
50 // Find max element value which we'll use to ensure numerical stability
51 // taking advantage of the following equality:
52 // exp(x[i])/sum(exp(x[i])) == exp(x[i]+C)/sum(exp(x[i]+C))
53 float max = std::numeric_limits<float>::lowest();
54 for (int c = 0; c < depth; ++c)
56 max = std::max(max, input_data[i * depth + c]);
61 for (int c = 0; c < depth; ++c)
63 const float exp_c = std::exp((input_data[i * depth + c] - max) * static_cast<float>(beta));
64 output_data[i * depth + c] = exp_c;
69 for (int c = 0; c < depth; ++c)
71 output_data[i * depth + c] = output_data[i * depth + c] / sum;
76 } // namespace luci_interpreter_pal
78 #endif // LUCI_INTERPRETER_PAL_SOFTMAX_COMMON_H