blob: 4f5aa76a035f0f8b9dcd3ae839e30aea94f6821b [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*
giuros0146a49a02019-04-01 13:50:22 +01002 * Copyright (c) 2016-2019 ARM Limited.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003 *
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_CLKERNELLIBRARY_H__
25#define __ARM_COMPUTE_CLKERNELLIBRARY_H__
26
27#include "arm_compute/core/CL/OpenCL.h"
28
29#include <map>
30#include <set>
31#include <string>
32#include <utility>
33
34namespace arm_compute
35{
Georgios Pinitas388d3ec2017-11-02 12:17:56 +000036/** Build options */
Pablo Tellodb8485a2019-09-24 11:03:47 +010037class CLBuildOptions final
Georgios Pinitas388d3ec2017-11-02 12:17:56 +000038{
39 using StringSet = std::set<std::string>;
40
41public:
42 /** Default constructor. */
43 CLBuildOptions();
44 /** Adds option to the existing build option list
45 *
46 * @param[in] option Option to add
47 */
48 void add_option(std::string option);
49 /** Adds option if a given condition is true;
50 *
51 * @param[in] cond Condition to check
52 * @param[in] option Option to add if condition is true
53 */
54 void add_option_if(bool cond, std::string option);
55 /** Adds first option if condition is true else the second one
56 *
57 * @param[in] cond Condition to check
58 * @param[in] option_true Option to add if condition is true
59 * @param[in] option_false Option to add if condition is false
60 */
61 void add_option_if_else(bool cond, std::string option_true, std::string option_false);
Chunosovf450caa2017-11-08 16:09:35 +070062 /** Appends given build options to the current's objects options.
63 *
64 * @param[in] options Build options to append
65 */
66 void add_options(const StringSet &options);
67 /** Appends given build options to the current's objects options if a given condition is true.
68 *
69 * @param[in] cond Condition to check
70 * @param[in] options Option to add if condition is true
71 */
72 void add_options_if(bool cond, const StringSet &options);
Georgios Pinitas388d3ec2017-11-02 12:17:56 +000073 /** Gets the current options list set
74 *
75 * @return Build options set
76 */
Chunosovd621bca2017-11-03 17:33:15 +070077 const StringSet &options() const;
Georgios Pinitas388d3ec2017-11-02 12:17:56 +000078
79private:
80 StringSet _build_opts; /**< Build options set */
81};
Anthony Barbier6ff3b192017-09-04 18:44:23 +010082/** Program class */
Pablo Tellodb8485a2019-09-24 11:03:47 +010083class Program final
Anthony Barbier6ff3b192017-09-04 18:44:23 +010084{
85public:
86 /** Default constructor. */
87 Program();
88 /** Construct program from source file.
89 *
90 * @param[in] context CL context used to create the program.
91 * @param[in] name Program name.
92 * @param[in] source Program source.
93 */
94 Program(cl::Context context, std::string name, std::string source);
95 /** Construct program from binary file.
96 *
97 * @param[in] context CL context used to create the program.
98 * @param[in] device CL device for which the programs are created.
99 * @param[in] name Program name.
100 * @param[in] binary Program binary.
101 */
102 Program(cl::Context context, cl::Device device, std::string name, std::vector<unsigned char> binary);
103 /** Default Copy Constructor. */
104 Program(const Program &) = default;
105 /** Default Move Constructor. */
106 Program(Program &&) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000107 /** Default copy assignment operator */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100108 Program &operator=(const Program &) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000109 /** Default move assignment operator */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100110 Program &operator=(Program &&) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000111 /** Returns program name.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100112 *
113 * @return Program's name.
114 */
115 std::string name() const
116 {
117 return _name;
118 }
119 /** User-defined conversion to the underlying CL program.
120 *
121 * @return The CL program object.
122 */
123 explicit operator cl::Program() const;
Alex Gildayc357c472018-03-21 13:54:09 +0000124 /** Build the given CL program.
125 *
126 * @param[in] program The CL program to build.
127 * @param[in] build_options Options to build the CL program.
128 *
129 * @return True if the CL program builds successfully.
130 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100131 static bool build(const cl::Program &program, const std::string &build_options = "");
132 /** Build the underlying CL program.
133 *
134 * @param[in] build_options Options used to build the CL program.
135 *
136 * @return A reference to itself.
137 */
138 cl::Program build(const std::string &build_options = "") const;
139
140private:
141 cl::Context _context; /**< Underlying CL context. */
142 cl::Device _device; /**< CL device for which the programs are created. */
143 bool _is_binary; /**< Create program from binary? */
144 std::string _name; /**< Program name. */
145 std::string _source; /**< Source code for the program. */
146 std::vector<unsigned char> _binary; /**< Binary from which to create the program. */
147};
148
149/** Kernel class */
Pablo Tellodb8485a2019-09-24 11:03:47 +0100150class Kernel final
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100151{
152public:
153 /** Default Constructor. */
154 Kernel();
155 /** Default Copy Constructor. */
156 Kernel(const Kernel &) = default;
157 /** Default Move Constructor. */
158 Kernel(Kernel &&) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000159 /** Default copy assignment operator */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100160 Kernel &operator=(const Kernel &) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000161 /** Default move assignment operator */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100162 Kernel &operator=(Kernel &&) = default;
163 /** Constructor.
164 *
165 * @param[in] name Kernel name.
166 * @param[in] program Built program.
167 */
168 Kernel(std::string name, const cl::Program &program);
169 /** Returns kernel name.
170 *
171 * @return Kernel's name.
172 */
173 std::string name() const
174 {
175 return _name;
176 }
177 /** Returns OpenCL kernel.
178 *
179 * @return OpenCL Kernel.
180 */
181 explicit operator cl::Kernel() const
182 {
183 return _kernel;
184 }
185
186private:
187 std::string _name; /**< Kernel name */
188 cl::Kernel _kernel; /**< OpenCL Kernel */
189};
190
191/** CLKernelLibrary class */
Pablo Tellodb8485a2019-09-24 11:03:47 +0100192class CLKernelLibrary final
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100193{
194 using StringSet = std::set<std::string>;
195
Pablo Tellodb8485a2019-09-24 11:03:47 +0100196public:
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100197 /** Default Constructor. */
198 CLKernelLibrary();
Alex Gildayc357c472018-03-21 13:54:09 +0000199 /** Prevent instances of this class from being copied */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100200 CLKernelLibrary(const CLKernelLibrary &) = delete;
Alex Gildayc357c472018-03-21 13:54:09 +0000201 /** Prevent instances of this class from being copied */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100202 const CLKernelLibrary &operator=(const CLKernelLibrary &) = delete;
203 /** Access the KernelLibrary singleton.
Pablo Tellodb8485a2019-09-24 11:03:47 +0100204 * This method has been deprecated and will be removed in the next release.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100205 * @return The KernelLibrary instance.
206 */
207 static CLKernelLibrary &get();
208 /** Initialises the kernel library.
209 *
Anthony Barbierb6eb3532018-08-08 13:20:04 +0100210 * @param[in] kernel_path Path of the directory from which kernel sources are loaded.
211 * @param[in] context CL context used to create programs.
212 * @param[in] device CL device for which the programs are created.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100213 */
Pablo Tellodb8485a2019-09-24 11:03:47 +0100214 void init(std::string kernel_path, cl::Context context, cl::Device device);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100215 /** Sets the path that the kernels reside in.
216 *
217 * @param[in] kernel_path Path of the kernel.
218 */
Pablo Tellodb8485a2019-09-24 11:03:47 +0100219 void set_kernel_path(const std::string &kernel_path);
Michalis Spyroud7e82812017-06-20 15:00:14 +0100220 /** Gets the path that the kernels reside in.
221 */
Pablo Tellodb8485a2019-09-24 11:03:47 +0100222 std::string get_kernel_path();
Alex Gildayc357c472018-03-21 13:54:09 +0000223 /** Gets the source of the selected program.
Anthony Barbierf202e502017-11-23 18:02:04 +0000224 *
225 * @param[in] program_name Program name.
Alex Gildayc357c472018-03-21 13:54:09 +0000226 *
227 * @return Source of the selected program.
Michalis Spyroud7e82812017-06-20 15:00:14 +0100228 */
229 std::string get_program_source(const std::string &program_name);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100230 /** Sets the CL context used to create programs.
231 *
232 * @note Setting the context also resets the device to the
233 * first one available in the new context.
234 *
235 * @param[in] context A CL context.
236 */
Pablo Tellodb8485a2019-09-24 11:03:47 +0100237 void set_context(cl::Context context);
Anthony Barbier4dcb5832018-05-08 11:29:05 +0100238
239 /** Accessor for the associated CL context.
240 *
241 * @return A CL context.
242 */
Pablo Tellodb8485a2019-09-24 11:03:47 +0100243 cl::Context &context();
Anthony Barbier4dcb5832018-05-08 11:29:05 +0100244
Giorgio Arena6200fa42018-07-06 17:06:36 +0100245 /** Gets the CL device for which the programs are created. */
Pablo Tellodb8485a2019-09-24 11:03:47 +0100246 cl::Device &get_device();
Giorgio Arena6200fa42018-07-06 17:06:36 +0100247
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100248 /** Sets the CL device for which the programs are created.
249 *
250 * @param[in] device A CL device.
251 */
Pablo Tellodb8485a2019-09-24 11:03:47 +0100252 void set_device(cl::Device device);
Anthony Barbier847864d2018-03-07 11:35:53 +0000253
254 /** Return the device version
255 *
256 * @return The content of CL_DEVICE_VERSION
257 */
258 std::string get_device_version();
Giorgio Arena5d42b462019-07-26 15:54:20 +0100259 /** Return the maximum number of compute units in the device
260 *
261 * @return The content of CL_DEVICE_MAX_COMPUTE_UNITS
262 */
263 cl_uint get_num_compute_units();
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100264 /** Creates a kernel from the kernel library.
265 *
266 * @param[in] kernel_name Kernel name.
267 * @param[in] build_options_set Kernel build options as a set.
268 *
269 * @return The created kernel.
270 */
271 Kernel create_kernel(const std::string &kernel_name, const StringSet &build_options_set = {}) const;
Abel Bernabeu5a6e0532017-09-28 09:53:45 +0100272 /** Find the maximum number of local work items in a workgroup can be supported for the kernel.
steniu015f910722017-08-23 10:15:22 +0100273 *
274 */
Abel Bernabeu5a6e0532017-09-28 09:53:45 +0100275 size_t max_local_workgroup_size(const cl::Kernel &kernel) const;
276 /** Return the default NDRange for the device.
steniu015f910722017-08-23 10:15:22 +0100277 *
278 */
Abel Bernabeu5a6e0532017-09-28 09:53:45 +0100279 cl::NDRange default_ndrange() const;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100280
Anthony Barbier200b6e32018-01-16 17:21:45 +0000281 /** Clear the library's cache of binary programs
282 */
Pablo Tellodb8485a2019-09-24 11:03:47 +0100283 void clear_programs_cache();
Anthony Barbier200b6e32018-01-16 17:21:45 +0000284
Anthony Barbier48c19f12018-04-20 11:31:52 +0100285 /** Access the cache of built OpenCL programs */
Pablo Tellodb8485a2019-09-24 11:03:47 +0100286 const std::map<std::string, cl::Program> &get_built_programs() const;
Anthony Barbier7da55aa2018-04-13 16:58:43 +0100287
288 /** Add a new built program to the cache
289 *
290 * @param[in] built_program_name Name of the program
291 * @param[in] program Built program to add to the cache
292 */
giuros0146a49a02019-04-01 13:50:22 +0100293 void add_built_program(const std::string &built_program_name, const cl::Program &program);
Anthony Barbier7da55aa2018-04-13 16:58:43 +0100294
Vidhya Sudhan Loganathanf1f49062018-05-25 13:21:26 +0100295 /** Returns true if FP16 is supported by the CL device
296 *
297 * @return true if the CL device supports FP16
298 */
299 bool fp16_supported() const;
300
Vidhya Sudhan Loganathan76c85642018-05-25 13:53:02 +0100301 /** Returns true if int64_base_atomics extension is supported by the CL device
302 *
303 * @return true if the CL device supports int64_base_atomics extension
304 */
305 bool int64_base_atomics_supported() const;
306
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100307private:
308 /** Load program and its dependencies.
309 *
310 * @param[in] program_name Name of the program to load.
311 */
312 const Program &load_program(const std::string &program_name) const;
313 /** Concatenates contents of a set into a single string.
314 *
315 * @param[in] s Input set to concatenate.
316 *
317 * @return Concatenated string.
318 */
319 std::string stringify_set(const StringSet &s) const;
320
321 cl::Context _context; /**< Underlying CL context. */
322 cl::Device _device; /**< Underlying CL device. */
323 std::string _kernel_path; /**< Path to the kernels folder. */
324 mutable std::map<std::string, const Program> _programs_map; /**< Map with all already loaded program data. */
325 mutable std::map<std::string, cl::Program> _built_programs_map; /**< Map with all already built program data. */
326 static const std::map<std::string, std::string> _kernel_program_map; /**< Map that associates kernel names with programs. */
327 static const std::map<std::string, std::string> _program_source_map; /**< Contains sources for all programs.
328 Used for compile-time kernel inclusion. >*/
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100329};
Georgios Pinitas7ae80a92019-10-25 18:25:17 +0100330} // namespace arm_compute
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100331#endif /* __ARM_COMPUTE_CLKERNELLIBRARY_H__ */