blob: 9f18e0e4c561c3aed5264c9aad5addfb3d4ab04e [file] [log] [blame]
Michalis Spyrou373b4072021-01-20 16:41:12 +00001/*
2 * Copyright (c) 2021 Arm Limited.
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24#ifndef ARM_COMPUTE_CPU_SOFTMAX_H
25#define ARM_COMPUTE_CPU_SOFTMAX_H
26
27#include "arm_compute/core/ITensorInfo.h"
28#include "arm_compute/core/experimental/Types.h"
29#include "src/core/cpu/ICpuKernel.h"
30#include "src/runtime/cpu/ICpuOperator.h"
31#include "src/runtime/cpu/operators/CpuPermute.h"
32#include <memory>
33
34namespace arm_compute
35{
36namespace cpu
37{
38class CpuLogits1DMaxKernel;
39template <bool IS_LOG>
40class CpuLogits1DSoftmaxKernel;
41
42/** Basic function to compute a SoftmaxLayer and a Log SoftmaxLayer.
43 *
44 * Softmax is calculated by :
45 * @f[ out = exp((x - max(x)) * beta) / sum(exp((x - max(x)) * beta)) @f]
46 *
47 * Log Softmax is calculated by :
48 * @f[ out = (x - max(x) * beta) - log(\sum{e^{x - max(x) * beta}}) @f]
49 *
50 * This function runs the following function/kernels:
51 * -# If axis is not 0:
52 * -# @ref CpuPermute
53 * -# @ref kernels::CpuLogits1DMaxKernel
54 * -# @ref kernels::CpuLogits1DSoftmaxKernel
55 */
56template <bool IS_LOG = false>
57class CpuSoftmaxGeneric : public ICpuOperator
58{
59public:
60 /** Constructor */
61 CpuSoftmaxGeneric();
62 /** Set the input and output tensors.
63 *
64 * @param[in,out] src Source tensor info. Data types supported: QASYMM8/QASYMM8_SIGNED/F16/F32.
65 * last value of each row to the nearest multiple.
66 * @param[out] dst Destination tensor ifo. Data types supported: same as @p input.
67 * @param[in] beta (Optional) A scaling factor for the exponent.
68 * @param[in] axis (Optional) The dimension in which to apply the function. E.g. for input of shape 4x5x6 and
69 * axis=1, softmax will be applied to 4x6=24 vectors of size 5. Defaults to 0
70 */
71 void configure(const ITensorInfo *src, ITensorInfo *dst, float beta = 1.0f, int32_t axis = 0);
72
73 /** Static function to check if given info will lead to a valid configuration of @ref CpuSoftmax
74 *
75 * @param[in] src Source tensor info. Data types supported: QASYMM8/QASYMM8_SIGNED/F16/F32.
76 * @param[in] dst Destination tensor info. Data types supported: same as @p input
77 * @param[in] beta (Optional) A scaling factor for the exponent.
78 * @param[in] axis (Optional) The dimension in which to apply the function. E.g. for input of shape 4x5x6 and
79 * axis=1, softmax will be applied to 4x6=24 vectors of size 5. Defaults to 0
80 *
81 * @return a status
82 */
83 static Status validate(const ITensorInfo *src, const ITensorInfo *dst, float beta = 1.0f, int32_t axis = 0);
84
85 // Inherited methods overridden:
86 void run(ITensorPack &tensors) override;
87 experimental::MemoryRequirements workspace() const override;
88
89private:
90 CpuPermute _permute_input;
91 CpuPermute _permute_output;
92 std::unique_ptr<ICpuKernel> _max_kernel;
93 std::unique_ptr<ICpuKernel> _softmax_kernel;
94 std::unique_ptr<ITensorInfo> _max;
95 std::unique_ptr<ITensorInfo> _tmp;
96 std::unique_ptr<ITensorInfo> _input_permuted;
97 std::unique_ptr<ITensorInfo> _output_permuted;
98 bool _needs_permute;
99};
100using CpuSoftmax = CpuSoftmaxGeneric<false>;
101using CpuLogSoftmax = CpuSoftmaxGeneric<true>;
102
103} // namespace cpu
104} // namespace arm_compute
105#endif /* ARM_COMPUTE_CPU_SOFTMAX_H */