1 /* 2 * Copyright (c) 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_CLCOMPILECONTEXT_H 25 #define ARM_COMPUTE_CLCOMPILECONTEXT_H 26 27 #include "arm_compute/core/CL/CLDevice.h" 28 #include "arm_compute/core/CL/OpenCL.h" 29 30 #include <map> 31 #include <set> 32 #include <string> 33 #include <utility> 34 35 namespace arm_compute 36 { 37 /** Build options */ 38 class CLBuildOptions final 39 { 40 using StringSet = std::set<std::string>; 41 42 public: 43 /** Default constructor. */ 44 CLBuildOptions(); 45 /** Adds option to the existing build option list 46 * 47 * @param[in] option Option to add 48 */ 49 void add_option(std::string option); 50 /** Adds option if a given condition is true; 51 * 52 * @param[in] cond Condition to check 53 * @param[in] option Option to add if condition is true 54 */ 55 void add_option_if(bool cond, std::string option); 56 /** Adds first option if condition is true else the second one 57 * 58 * @param[in] cond Condition to check 59 * @param[in] option_true Option to add if condition is true 60 * @param[in] option_false Option to add if condition is false 61 */ 62 void add_option_if_else(bool cond, std::string option_true, std::string option_false); 63 /** Appends given build options to the current's objects options. 64 * 65 * @param[in] options Build options to append 66 */ 67 void add_options(const StringSet &options); 68 /** Appends given build options to the current's objects options if a given condition is true. 69 * 70 * @param[in] cond Condition to check 71 * @param[in] options Option to add if condition is true 72 */ 73 void add_options_if(bool cond, const StringSet &options); 74 /** Gets the current options list set 75 * 76 * @return Build options set 77 */ 78 const StringSet &options() const; 79 80 private: 81 StringSet _build_opts; /**< Build options set */ 82 }; 83 84 /** Program class */ 85 class Program final 86 { 87 public: 88 /** Default constructor. */ 89 Program(); 90 /** Construct program from source file. 91 * 92 * @param[in] context CL context used to create the program. 93 * @param[in] name Program name. 94 * @param[in] source Program source. 95 */ 96 Program(cl::Context context, std::string name, std::string source); 97 /** Construct program from binary file. 98 * 99 * @param[in] context CL context used to create the program. 100 * @param[in] device CL device for which the programs are created. 101 * @param[in] name Program name. 102 * @param[in] binary Program binary. 103 */ 104 Program(cl::Context context, cl::Device device, std::string name, std::vector<unsigned char> binary); 105 /** Default Copy Constructor. */ 106 Program(const Program &) = default; 107 /** Default Move Constructor. */ 108 Program(Program &&) = default; 109 /** Default copy assignment operator */ 110 Program &operator=(const Program &) = default; 111 /** Default move assignment operator */ 112 Program &operator=(Program &&) = default; 113 /** Returns program name. 114 * 115 * @return Program's name. 116 */ name()117 std::string name() const 118 { 119 return _name; 120 } 121 /** Returns program binary data. 122 * 123 * @return Program's binary data. 124 */ binary()125 const std::vector<unsigned char> &binary() const 126 { 127 return _binary; 128 } 129 /** User-defined conversion to the underlying CL program. 130 * 131 * @return The CL program object. 132 */ 133 explicit operator cl::Program() const; 134 /** Build the given CL program. 135 * 136 * @param[in] program The CL program to build. 137 * @param[in] build_options Options to build the CL program. 138 * 139 * @return True if the CL program builds successfully. 140 */ 141 static bool build(const cl::Program &program, const std::string &build_options = ""); 142 /** Build the underlying CL program. 143 * 144 * @param[in] build_options Options used to build the CL program. 145 * 146 * @return A reference to itself. 147 */ 148 cl::Program build(const std::string &build_options = "") const; 149 150 private: 151 cl::Context _context; /**< Underlying CL context. */ 152 cl::Device _device; /**< CL device for which the programs are created. */ 153 bool _is_binary; /**< Create program from binary? */ 154 std::string _name; /**< Program name. */ 155 std::string _source; /**< Source code for the program. */ 156 std::vector<unsigned char> _binary; /**< Binary from which to create the program. */ 157 }; 158 159 /** Kernel class */ 160 class Kernel final 161 { 162 public: 163 /** Default Constructor. */ 164 Kernel(); 165 /** Default Copy Constructor. */ 166 Kernel(const Kernel &) = default; 167 /** Default Move Constructor. */ 168 Kernel(Kernel &&) = default; 169 /** Default copy assignment operator */ 170 Kernel &operator=(const Kernel &) = default; 171 /** Default move assignment operator */ 172 Kernel &operator=(Kernel &&) = default; 173 /** Constructor. 174 * 175 * @param[in] name Kernel name. 176 * @param[in] program Built program. 177 */ 178 Kernel(std::string name, const cl::Program &program); 179 /** Returns kernel name. 180 * 181 * @return Kernel's name. 182 */ name()183 std::string name() const 184 { 185 return _name; 186 } 187 /** Returns OpenCL kernel. 188 * 189 * @return OpenCL Kernel. 190 */ Kernel()191 explicit operator cl::Kernel() const 192 { 193 return _kernel; 194 } 195 196 private: 197 std::string _name; /**< Kernel name */ 198 cl::Kernel _kernel; /**< OpenCL Kernel */ 199 }; 200 201 /** CLCompileContext class */ 202 class CLCompileContext final 203 { 204 using StringSet = std::set<std::string>; 205 206 public: 207 /** Constructor */ 208 CLCompileContext(); 209 /** Constructor 210 * 211 * @param[in] context A CL context. 212 * @param[in] device A CL device. 213 * */ 214 CLCompileContext(cl::Context context, const cl::Device &device); 215 216 /** Accessor for the associated CL context. 217 * 218 * @return A CL context. 219 */ 220 cl::Context &context(); 221 222 /** Sets the CL context used to create programs. 223 * 224 * @note Setting the context also resets the device to the 225 * first one available in the new context. 226 * 227 * @param[in] context A CL context. 228 */ 229 void set_context(cl::Context context); 230 231 /** Gets the CL device for which the programs are created. */ 232 const cl::Device &get_device() const; 233 234 /** Sets the CL device for which the programs are created. 235 * 236 * @param[in] device A CL device. 237 */ 238 void set_device(cl::Device device); 239 240 /** Creates an OpenCL kernel. 241 * 242 * @param[in] kernel_name Kernel name. 243 * @param[in] program_name Program name. 244 * @param[in] program_source Program source. 245 * @param[in] kernel_path CL kernel path. 246 * @param[in] build_options_set Kernel build options as a set. 247 * @param[in] is_binary Flag to indicate if the program source is binary. 248 * 249 * @return The created kernel. 250 */ 251 Kernel create_kernel(const std::string &kernel_name, const std::string &program_name, const std::string &program_source, 252 const std::string &kernel_path, const StringSet &build_options_set, bool is_binary) const; 253 254 /** Clear the library's cache of binary programs 255 */ 256 void clear_programs_cache(); 257 258 /** Access the cache of built OpenCL programs */ 259 const std::map<std::string, cl::Program> &get_built_programs() const; 260 261 /** Add a new built program to the cache 262 * 263 * @param[in] built_program_name Name of the program 264 * @param[in] program Built program to add to the cache 265 */ 266 void add_built_program(const std::string &built_program_name, const cl::Program &program) const; 267 268 /** Returns true if FP16 is supported by the CL device 269 * 270 * @return true if the CL device supports FP16 271 */ 272 bool fp16_supported() const; 273 274 /** Return the maximum number of compute units in the device 275 * 276 * @return The content of CL_DEVICE_MAX_COMPUTE_UNITS 277 */ 278 cl_uint get_num_compute_units() const; 279 /** Find the maximum number of local work items in a workgroup can be supported for the kernel. 280 * 281 */ 282 size_t max_local_workgroup_size(const cl::Kernel &kernel) const; 283 /** Return the default NDRange for the device. 284 * 285 */ 286 cl::NDRange default_ndrange() const; 287 /** Return the device version 288 * 289 * @return The content of CL_DEVICE_VERSION 290 */ 291 std::string get_device_version() const; 292 293 /** Returns true if int64_base_atomics extension is supported by the CL device 294 * 295 * @return true if the CL device supports int64_base_atomics extension 296 */ 297 bool int64_base_atomics_supported() const; 298 299 private: 300 /** Load program and its dependencies. 301 * 302 * @param[in] program_name Name of the program to load. 303 * @param[in] program_source Source of the program. 304 * @param[in] is_binary Flag to indicate if the program source is binary. 305 */ 306 const Program &load_program(const std::string &program_name, const std::string &program_source, bool is_binary) const; 307 308 /** Generates the build options given a string of user defined ones 309 * 310 * @param[in] build_options User defined build options 311 * @param[in] kernel_path Path of the CL kernels 312 * 313 * @return Generated build options 314 */ 315 std::string generate_build_options(const StringSet &build_options, const std::string &kernel_path) const; 316 317 /** Concatenates contents of a set into a single string. 318 * 319 * @param[in] s Input set to concatenate. 320 * @param[in] kernel_path Path of the CL kernels 321 * 322 * @return Concatenated string. 323 */ 324 std::string stringify_set(const StringSet &s, const std::string &kernel_path) const; 325 326 cl::Context _context; /**< Underlying CL context. */ 327 CLDevice _device; /**< Underlying CL device. */ 328 mutable std::map<std::string, const Program> _programs_map; /**< Map with all already loaded program data. */ 329 mutable std::map<std::string, cl::Program> _built_programs_map; /**< Map with all already built program data. */ 330 }; 331 } // namespace arm_compute 332 #endif /* ARM_COMPUTE_CLCOMPILECONTEXT_H */ 333