xref: /aosp_15_r20/external/ComputeLibrary/src/dynamic_fusion/sketch/gpu/GpuOperatorGroup.h (revision c217d954acce2dbc11938adb493fc0abd69584f3)
1 /*
2  * Copyright (c) 2022 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_GPUOPERATORGROUP
25 #define SRC_DYNAMIC_FUSION_SKETCH_GPU_GPUOPERATORGROUP
26 
27 #include "arm_compute/core/ITensorInfo.h"
28 #include "src/dynamic_fusion/sketch/ArgumentPack.h"
29 #include "src/dynamic_fusion/sketch/gpu/GpuOperatorProperties.h"
30 #include "src/dynamic_fusion/sketch/utils/DependencyGraph.h"
31 #include <map>
32 
33 namespace arm_compute
34 {
35 namespace experimental
36 {
37 namespace dynamic_fusion
38 {
39 using OperatorId = DependencyGraph::OperatorId;
40 
41 /** An operator for the sole purpose of validating fusion
42  */
43 class Operator
44 {
45 public:
46     /** Default constructor */
47     Operator() = default;
48     /** Get Operator Id */
49     OperatorId id() const;
50     /** Get operator type */
51     GpuOperatorType operator_type() const;
52     /** Get tensor arguments */
53     ArgumentPack<ITensorInfo> tensors() const;
54     friend class GpuOperatorGroup;
55 
56 private:
57     Operator(OperatorId id, GpuOperatorType operator_type, const ArgumentPack<ITensorInfo> &tensors);
58     OperatorId                _id{};
59     GpuOperatorType           _operator_type{};
60     ArgumentPack<ITensorInfo> _tensors{};
61 };
62 
63 /** A linear sequence of operators to be fused in a workload
64  *  For the time being, this class is only used for validating operator fusion
65  * INVARIANTS:
66  * @note These invariants are exactly the same as operator fusion constraints
67  * 1. Fusion is limited to a linear sequence of operators
68  * 2. Max number of operators that can be fused is @ref GpuOperatorGroup::max_fused_operators
69  * 3. The fusion is subject to the pattern: Complex + Simple * | Simple + Simple * | Un-fusable
70  * 4. All operator but unfusable, have exactly 1 dst tensor
71  * 5. All fused operators share the same dst tensor shape
72  * 6. All fused operators' tensors share the same @ref DataLayout
73  */
74 class GpuOperatorGroup
75 {
76 public:
77     static constexpr size_t max_fused_operators = 32;
78     /** Try adding (without actually adding) an operator to the group
79      *
80      * @param[in] op        Operator to be added
81      * @param[in] is_output Whether this operator is the output operator.
82      *
83      * @return true   If @p op can be added while maintaining the invariants
84      * @return false  Otherwise
85      */
86     bool try_add_operator(const Operator &op, bool is_output = false) const;
87     /** Add an operator to the group
88      *
89      * @param[in] op        Operator to be added
90      * @param[in] is_output Whether this operator is the output operator.
91      */
92     void add_operator(const Operator &op, bool is_output = false);
93     /** Create a new operator
94      *
95      * @param[in] operator_type @ref GpuOperatorType of the new operator
96      * @param[in] tensors       Tensor arguments to the new operator
97      *
98      * @return Operator
99      */
100     Operator new_operator(const GpuOperatorType &operator_type, const ArgumentPack<ITensorInfo> &tensors) const;
101     /** Get the "root operator" of the group, which is the first operator in a linear sequence
102      * @return const Operator* Pointer to the root operator
103      */
104     const Operator *get_root_operator() const;
105 
106 private:
107     DependencyGraph _graph{};
108     std::map<OperatorId, Operator> _operators{};
109 };
110 } // namespace dynamic_fusion
111 } // namespace experimental
112 } // namespace arm_compute
113 #endif /* SRC_DYNAMIC_FUSION_SKETCH_GPU_GPUOPERATORGROUP */
114