blob: f6256727f8147f1a95ab9841c852a2ae3b0e4534 [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*
2 * Copyright (c) 2016, 2017 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_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 */
37class CLBuildOptions
38{
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);
62 /** Gets the current options list set
63 *
64 * @return Build options set
65 */
Chunosovd621bca2017-11-03 17:33:15 +070066 const StringSet &options() const;
Georgios Pinitas388d3ec2017-11-02 12:17:56 +000067
68private:
69 StringSet _build_opts; /**< Build options set */
70};
Anthony Barbier6ff3b192017-09-04 18:44:23 +010071/** Program class */
72class Program
73{
74public:
75 /** Default constructor. */
76 Program();
77 /** Construct program from source file.
78 *
79 * @param[in] context CL context used to create the program.
80 * @param[in] name Program name.
81 * @param[in] source Program source.
82 */
83 Program(cl::Context context, std::string name, std::string source);
84 /** Construct program from binary file.
85 *
86 * @param[in] context CL context used to create the program.
87 * @param[in] device CL device for which the programs are created.
88 * @param[in] name Program name.
89 * @param[in] binary Program binary.
90 */
91 Program(cl::Context context, cl::Device device, std::string name, std::vector<unsigned char> binary);
92 /** Default Copy Constructor. */
93 Program(const Program &) = default;
94 /** Default Move Constructor. */
95 Program(Program &&) = default;
96 /** Default copy assignment operator. */
97 Program &operator=(const Program &) = default;
98 /** Default move assignment operator. */
99 Program &operator=(Program &&) = default;
100 /**Returns program name.
101 *
102 * @return Program's name.
103 */
104 std::string name() const
105 {
106 return _name;
107 }
108 /** User-defined conversion to the underlying CL program.
109 *
110 * @return The CL program object.
111 */
112 explicit operator cl::Program() const;
113
114 static bool build(const cl::Program &program, const std::string &build_options = "");
115 /** Build the underlying CL program.
116 *
117 * @param[in] build_options Options used to build the CL program.
118 *
119 * @return A reference to itself.
120 */
121 cl::Program build(const std::string &build_options = "") const;
122
123private:
124 cl::Context _context; /**< Underlying CL context. */
125 cl::Device _device; /**< CL device for which the programs are created. */
126 bool _is_binary; /**< Create program from binary? */
127 std::string _name; /**< Program name. */
128 std::string _source; /**< Source code for the program. */
129 std::vector<unsigned char> _binary; /**< Binary from which to create the program. */
130};
131
132/** Kernel class */
133class Kernel
134{
135public:
136 /** Default Constructor. */
137 Kernel();
138 /** Default Copy Constructor. */
139 Kernel(const Kernel &) = default;
140 /** Default Move Constructor. */
141 Kernel(Kernel &&) = default;
142 /** Default copy assignment operator. */
143 Kernel &operator=(const Kernel &) = default;
144 /** Default move assignment operator. */
145 Kernel &operator=(Kernel &&) = default;
146 /** Constructor.
147 *
148 * @param[in] name Kernel name.
149 * @param[in] program Built program.
150 */
151 Kernel(std::string name, const cl::Program &program);
152 /** Returns kernel name.
153 *
154 * @return Kernel's name.
155 */
156 std::string name() const
157 {
158 return _name;
159 }
160 /** Returns OpenCL kernel.
161 *
162 * @return OpenCL Kernel.
163 */
164 explicit operator cl::Kernel() const
165 {
166 return _kernel;
167 }
168
169private:
170 std::string _name; /**< Kernel name */
171 cl::Kernel _kernel; /**< OpenCL Kernel */
172};
173
174/** CLKernelLibrary class */
175class CLKernelLibrary
176{
177 using StringSet = std::set<std::string>;
178
179private:
180 /** Default Constructor. */
181 CLKernelLibrary();
182
183public:
184 /** Prevent instances of this class from being copied. */
185 CLKernelLibrary(const CLKernelLibrary &) = delete;
186 /** Prevent instances of this class from being copied. */
187 const CLKernelLibrary &operator=(const CLKernelLibrary &) = delete;
188 /** Access the KernelLibrary singleton.
189 * @return The KernelLibrary instance.
190 */
191 static CLKernelLibrary &get();
192 /** Initialises the kernel library.
193 *
194 * @param[in] kernel_path (Optional) Path of the directory from which kernel sources are loaded.
195 * @param[in] context (Optional) CL context used to create programs.
196 * @param[in] device (Optional) CL device for which the programs are created.
197 */
198 void init(std::string kernel_path = ".", cl::Context context = cl::Context::getDefault(), cl::Device device = cl::Device::getDefault())
199 {
Abel Bernabeu5a6e0532017-09-28 09:53:45 +0100200 _kernel_path = std::move(kernel_path);
201 _context = std::move(context);
202 _device = std::move(device);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100203 }
204 /** Sets the path that the kernels reside in.
205 *
206 * @param[in] kernel_path Path of the kernel.
207 */
208 void set_kernel_path(const std::string &kernel_path)
209 {
210 _kernel_path = kernel_path;
211 };
Michalis Spyroud7e82812017-06-20 15:00:14 +0100212 /** Gets the path that the kernels reside in.
213 */
214 std::string get_kernel_path()
215 {
216 return _kernel_path;
217 };
218 /** Gets the source of the selected program
219 *
220 * @param[in] program_name Program name.
221 */
222 std::string get_program_source(const std::string &program_name);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100223 /** Sets the CL context used to create programs.
224 *
225 * @note Setting the context also resets the device to the
226 * first one available in the new context.
227 *
228 * @param[in] context A CL context.
229 */
230 void set_context(cl::Context context)
231 {
232 _context = std::move(context);
233
234 const auto cl_devices = _context.getInfo<CL_CONTEXT_DEVICES>();
235
236 if(cl_devices.empty())
237 {
238 _device = cl::Device();
239 }
240 else
241 {
242 _device = cl_devices[0];
243 }
Abel Bernabeu5a6e0532017-09-28 09:53:45 +0100244 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100245 /** Sets the CL device for which the programs are created.
246 *
247 * @param[in] device A CL device.
248 */
249 void set_device(cl::Device device)
250 {
Abel Bernabeu5a6e0532017-09-28 09:53:45 +0100251 _device = std::move(device);
252 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100253 /** Creates a kernel from the kernel library.
254 *
255 * @param[in] kernel_name Kernel name.
256 * @param[in] build_options_set Kernel build options as a set.
257 *
258 * @return The created kernel.
259 */
260 Kernel create_kernel(const std::string &kernel_name, const StringSet &build_options_set = {}) const;
261 /** Serializes and saves programs to a binary.
262 *
263 */
264 void save_binary();
265 /** Load serialized binary with all the programs.
266 *
267 */
268 void load_binary();
Abel Bernabeu5a6e0532017-09-28 09:53:45 +0100269 /** Find the maximum number of local work items in a workgroup can be supported for the kernel.
steniu015f910722017-08-23 10:15:22 +0100270 *
271 */
Abel Bernabeu5a6e0532017-09-28 09:53:45 +0100272 size_t max_local_workgroup_size(const cl::Kernel &kernel) const;
273 /** Return the default NDRange for the device.
steniu015f910722017-08-23 10:15:22 +0100274 *
275 */
Abel Bernabeu5a6e0532017-09-28 09:53:45 +0100276 cl::NDRange default_ndrange() const;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100277
278private:
279 /** Load program and its dependencies.
280 *
281 * @param[in] program_name Name of the program to load.
282 */
283 const Program &load_program(const std::string &program_name) const;
284 /** Concatenates contents of a set into a single string.
285 *
286 * @param[in] s Input set to concatenate.
287 *
288 * @return Concatenated string.
289 */
290 std::string stringify_set(const StringSet &s) const;
291
292 cl::Context _context; /**< Underlying CL context. */
293 cl::Device _device; /**< Underlying CL device. */
294 std::string _kernel_path; /**< Path to the kernels folder. */
295 mutable std::map<std::string, const Program> _programs_map; /**< Map with all already loaded program data. */
296 mutable std::map<std::string, cl::Program> _built_programs_map; /**< Map with all already built program data. */
297 static const std::map<std::string, std::string> _kernel_program_map; /**< Map that associates kernel names with programs. */
298 static const std::map<std::string, std::string> _program_source_map; /**< Contains sources for all programs.
299 Used for compile-time kernel inclusion. >*/
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100300};
301}
302#endif /* __ARM_COMPUTE_CLKERNELLIBRARY_H__ */