1 /*
2  * Copyright (c) 2022-2023 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 SRC_DYNAMIC_FUSION_SKETCH_GPU_COMPONENTS_CL_CLCOMPONENTLOGITS1DMAXSHIFTEXPSUM
25 #define SRC_DYNAMIC_FUSION_SKETCH_GPU_COMPONENTS_CL_CLCOMPONENTLOGITS1DMAXSHIFTEXPSUM
26 
27 #include "arm_compute/dynamic_fusion/sketch/attributes/SoftmaxAttributes.h"
28 #include "src/dynamic_fusion/sketch/gpu/components/IGpuKernelComponent.h"
29 
30 namespace arm_compute
31 {
32 /** Forward declaration */
33 class ITensorInfo;
34 namespace experimental
35 {
36 namespace dynamic_fusion
37 {
38 /** Forward declaration */
39 template <typename T>
40 class ArgumentPack;
41 
42 /** Forward declaration */
43 class ClTemplateLogits1DMaxShiftExpSum;
44 
45 /** Component to calculate max-shifted exponentials and their sum
46  *
47  *  1D example:
48  *      input:  [x1, x2, ... , xn], shape: (1 x d)
49  *
50  *      Let max(x1...xn) = m
51  *
52  *      (output) sum: [exp(x1-m) + ... + exp(xn-m)], shape: (1 x 1)
53  *      (output) dst: [exp(x1-m) ... exp(xn-m)], shape: (1 x d)
54  *
55  *  This component is used by the softmax operator. The subsequent
56  *  operation normalizes dst with sum, therefore the max-shifting
57  *  since exp(m) will be cancelled in numerator and denominator.
58 */
59 class ClComponentLogits1DMaxShiftExpSum final : public IGpuKernelComponent
60 {
61 public:
62     /** Attributes are a set of backend-agnostic parameters that define what a component does */
63     using Attributes = SoftmaxAttributes;
64 
65     /** Validate the component
66      *
67      * @param[in] properties Component properties @ref Properties
68      * @param[in] tensors    Tensor arguments to the component
69      * @param[in] attributes Component attributes @ref Attributes
70      *
71      * @return Status        Validation results
72      *
73      * Tensor argument names:
74      * - ACL_SRC_0: Input
75      * - ACL_DST_0: Output
76      * - ACL_DST_1: Output
77      *
78      * Tensor argument constness:
79      * - ACL_SRC_0: Const
80      * - ACL_DST_0: Const
81      * - ACL_DST_1: Const
82      *
83      * Valid data layouts:
84      * - All
85      *
86      ** Valid data type configurations:
87      * |ACL_SRC_0  |ACL_DST_0  |ACL_DST_1  |
88      * |:----------|:----------|:----------|
89      * |F16        | F16       | F16       |
90      * |F32        | F32       | F32       |
91      */
92     static Status validate(
93         const Properties                &properties,
94         const ArgumentPack<ITensorInfo> &tensors,
95         const Attributes                &attributes);
96 
97     /** Constructor
98      *
99      * Similar to @ref ClComponentLogits1DMaxShiftExpSum::validate()
100      */
101     ClComponentLogits1DMaxShiftExpSum(ComponentId                      id,
102                                       const Properties                &properties,
103                                       const ArgumentPack<ITensorInfo> &tensors,
104                                       const Attributes                &attributes);
105 
106     /** Destructor */
107     ~ClComponentLogits1DMaxShiftExpSum() override;
108     /** Prevent instances of this class from being copy constructed */
109     ClComponentLogits1DMaxShiftExpSum(const ClComponentLogits1DMaxShiftExpSum &component) = delete;
110     /** Prevent instances of this class from being copied */
111     ClComponentLogits1DMaxShiftExpSum &operator=(const ClComponentLogits1DMaxShiftExpSum &component) = delete;
112     /** Allow instances of this class to be move constructed */
113     ClComponentLogits1DMaxShiftExpSum(ClComponentLogits1DMaxShiftExpSum &&component) = default;
114     /** Allow instances of this class to be moved */
115     ClComponentLogits1DMaxShiftExpSum &operator=(ClComponentLogits1DMaxShiftExpSum &&component) = default;
116     /** Get template writer for the component */
117     const IGpuTemplateComponentWriter *template_writer() const override;
118     /** Get component type */
type()119     GpuComponentType type() const override
120     {
121         return GpuComponentType::Unfusable;
122     }
123 
124 private:
125     std::unique_ptr<ClTemplateLogits1DMaxShiftExpSum> _component_writer;
126 };
127 } // namespace dynamic_fusion
128 } // namespace experimental
129 } // namespace arm_compute
130 
131 #endif /* SRC_DYNAMIC_FUSION_SKETCH_GPU_COMPONENTS_CL_CLCOMPONENTLOGITS1DMAXSHIFTEXPSUM */
132