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