1 /* 2 * Copyright (c) 2019-2020 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_CL_LWS_LIST_H 25 #define ARM_COMPUTE_CL_LWS_LIST_H 26 27 #include "arm_compute/core/CL/OpenCL.h" 28 #include "arm_compute/core/Error.h" 29 #include "arm_compute/core/Helpers.h" 30 #include "arm_compute/runtime/CL/CLTunerTypes.h" 31 #include "support/ToolchainSupport.h" 32 33 #include "support/MemorySupport.h" 34 35 namespace arm_compute 36 { 37 namespace cl_tuner 38 { 39 constexpr unsigned int max_lws_supported_x{ 64u }; 40 constexpr unsigned int max_lws_supported_y{ 32u }; 41 constexpr unsigned int max_lws_supported_z{ 32u }; 42 43 /** Interface for LWS lists */ 44 class ICLLWSList 45 { 46 public: 47 /** Constructor */ 48 ICLLWSList() = default; 49 /** Copy Constructor */ 50 ICLLWSList(const ICLLWSList &) = default; 51 /** Move Constructor */ 52 ICLLWSList(ICLLWSList &&) noexcept(true) = default; 53 /** Assignment */ 54 ICLLWSList &operator=(const ICLLWSList &) = default; 55 /** Move Assignment */ 56 ICLLWSList &operator=(ICLLWSList &&) noexcept(true) = default; 57 /** Destructor */ 58 virtual ~ICLLWSList() = default; 59 60 /** Return the LWS value at the given index. 61 * 62 * @return LWS value at the given index 63 */ 64 virtual cl::NDRange operator[](size_t) = 0; 65 66 /** LWS list size. 67 * 68 * @return LWS list size 69 */ 70 virtual size_t size() = 0; 71 }; 72 73 /** Non instantiable base class for LWS combinations that use Index2Cooard mapping */ 74 class CLLWSList : public ICLLWSList 75 { 76 protected: 77 /* Shape of 3-D search space */ 78 TensorShape search_space_shape{ 0, 0, 0 }; 79 80 /** Constructor */ 81 CLLWSList() = default; 82 /** Copy Constructor */ 83 CLLWSList(const CLLWSList &) = default; 84 /** Move Constructor */ 85 CLLWSList(CLLWSList &&) noexcept(true) = default; 86 /** Assignment */ 87 CLLWSList &operator=(const CLLWSList &) = default; 88 /** Move Assignment */ 89 CLLWSList &operator=(CLLWSList &&) noexcept(true) = default; 90 /** Destructor */ 91 virtual ~CLLWSList() = default; 92 93 // Inherited methods overridden: 94 virtual size_t size() override; 95 }; 96 97 /** Exhaustive list of all possible LWS values */ 98 class CLLWSListExhaustive : public CLLWSList 99 { 100 public: 101 /** Prevent default constructor calls */ 102 CLLWSListExhaustive() = delete; 103 /** Constructor */ 104 CLLWSListExhaustive(const cl::NDRange &gws); 105 /** Copy Constructor */ 106 CLLWSListExhaustive(const CLLWSListExhaustive &) = default; 107 /** Move Constructor */ 108 CLLWSListExhaustive(CLLWSListExhaustive &&) noexcept(true) = default; 109 /** Assignment */ 110 CLLWSListExhaustive &operator=(const CLLWSListExhaustive &) = default; 111 /** Move Assignment */ 112 CLLWSListExhaustive &operator=(CLLWSListExhaustive &&) noexcept(true) = default; 113 /** Destructor */ 114 ~CLLWSListExhaustive() = default; 115 116 // Inherited methods overridden: 117 cl::NDRange operator[](size_t) override; 118 }; 119 120 /** A subset of LWS values that are either factors of gws when gws[2] < 16 or power of 2 */ 121 class CLLWSListNormal : public CLLWSList 122 { 123 public: 124 /** Constructor */ 125 CLLWSListNormal(const cl::NDRange &gws); 126 /** Copy Constructor */ 127 CLLWSListNormal(const CLLWSListNormal &) = default; 128 /** Move Constructor */ 129 CLLWSListNormal(CLLWSListNormal &&) noexcept(true) = default; 130 /** Assignment */ 131 CLLWSListNormal &operator=(const CLLWSListNormal &) = default; 132 /** Move Assignment */ 133 CLLWSListNormal &operator=(CLLWSListNormal &&) noexcept(true) = default; 134 /** Destructor */ 135 ~CLLWSListNormal() = default; 136 137 // Inherited methods overridden: 138 cl::NDRange operator[](size_t) override; 139 140 protected: 141 std::vector<unsigned int> _lws_x{}; 142 std::vector<unsigned int> _lws_y{}; 143 std::vector<unsigned int> _lws_z{}; 144 145 /** Prevent default constructor calls */ 146 CLLWSListNormal() = default; 147 148 private: 149 /** Utility function used to initialize the LWS values to test. 150 * Only the LWS values which are power of 2 or satisfy the modulo conditions with GWS are taken into account by the CLTuner 151 * 152 * @param[in, out] lws Vector of LWS to test 153 * @param[in] gws Size of the specific GWS 154 * @param[in] lws_max Max LWS value allowed to be tested 155 * @param[in] mod_let_one True if the results of the modulo operation between gws and the lws can be less than one. 156 */ 157 void initialize_lws_values(std::vector<unsigned int> &lws, unsigned int gws, unsigned int lws_max, bool mod_let_one); 158 }; 159 160 /** A minimal subset of LWS values that only have 1,2 and 4/8 */ 161 class CLLWSListRapid : public CLLWSListNormal 162 { 163 public: 164 /** Prevent default constructor calls */ 165 CLLWSListRapid() = delete; 166 /** Constructor */ 167 CLLWSListRapid(const cl::NDRange &gws); 168 /** Copy Constructor */ 169 CLLWSListRapid(const CLLWSListRapid &) = default; 170 /** Move Constructor */ 171 CLLWSListRapid(CLLWSListRapid &&) noexcept(true) = default; 172 /** Assignment */ 173 CLLWSListRapid &operator=(const CLLWSListRapid &) = default; 174 /** Move Assignment */ 175 CLLWSListRapid &operator=(CLLWSListRapid &&) noexcept(true) = default; 176 /** Destructor */ 177 virtual ~CLLWSListRapid() = default; 178 179 private: 180 /** Utility function used to initialize the LWS values to test. 181 * Only the LWS values that have 1,2 and 4/8 for each dimension are taken into account by the CLTuner 182 * 183 * @param[in, out] lws Vector of LWS to test 184 * @param[in] lws_max Max LWS value allowed to be tested 185 */ 186 void initialize_lws_values(std::vector<unsigned int> &lws, unsigned int lws_max); 187 }; 188 189 /** Factory to construct an ICLLWSList object based on the CL tuner mode */ 190 class CLLWSListFactory final 191 { 192 public: 193 /** Construct an ICLLWSList object for the given tuner mode and gws configuration. 194 * 195 * @return unique_ptr to the requested ICLLWSList implementation. 196 */ get_lws_list(CLTunerMode mode,const cl::NDRange & gws)197 static std::unique_ptr<ICLLWSList> get_lws_list(CLTunerMode mode, const cl::NDRange &gws) 198 { 199 switch(mode) 200 { 201 case CLTunerMode::EXHAUSTIVE: 202 return arm_compute::support::cpp14::make_unique<CLLWSListExhaustive>(gws); 203 case CLTunerMode::NORMAL: 204 return arm_compute::support::cpp14::make_unique<CLLWSListNormal>(gws); 205 case CLTunerMode::RAPID: 206 return arm_compute::support::cpp14::make_unique<CLLWSListRapid>(gws); 207 default: 208 return nullptr; 209 } 210 } 211 }; 212 } // namespace cl_tuner 213 } // namespace arm_compute 214 #endif /*ARM_COMPUTE_CL_LWS_LIST_H */ 215