blob: fc131cdcfe3bcd195166d1737f17d5b0cbed0a63 [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{
36/** Program class */
37class Program
38{
39public:
40 /** Default constructor. */
41 Program();
42 /** Construct program from source file.
43 *
44 * @param[in] context CL context used to create the program.
45 * @param[in] name Program name.
46 * @param[in] source Program source.
47 */
48 Program(cl::Context context, std::string name, std::string source);
49 /** Construct program from binary file.
50 *
51 * @param[in] context CL context used to create the program.
52 * @param[in] device CL device for which the programs are created.
53 * @param[in] name Program name.
54 * @param[in] binary Program binary.
55 */
56 Program(cl::Context context, cl::Device device, std::string name, std::vector<unsigned char> binary);
57 /** Default Copy Constructor. */
58 Program(const Program &) = default;
59 /** Default Move Constructor. */
60 Program(Program &&) = default;
61 /** Default copy assignment operator. */
62 Program &operator=(const Program &) = default;
63 /** Default move assignment operator. */
64 Program &operator=(Program &&) = default;
65 /**Returns program name.
66 *
67 * @return Program's name.
68 */
69 std::string name() const
70 {
71 return _name;
72 }
73 /** User-defined conversion to the underlying CL program.
74 *
75 * @return The CL program object.
76 */
77 explicit operator cl::Program() const;
78
79 static bool build(const cl::Program &program, const std::string &build_options = "");
80 /** Build the underlying CL program.
81 *
82 * @param[in] build_options Options used to build the CL program.
83 *
84 * @return A reference to itself.
85 */
86 cl::Program build(const std::string &build_options = "") const;
87
88private:
89 cl::Context _context; /**< Underlying CL context. */
90 cl::Device _device; /**< CL device for which the programs are created. */
91 bool _is_binary; /**< Create program from binary? */
92 std::string _name; /**< Program name. */
93 std::string _source; /**< Source code for the program. */
94 std::vector<unsigned char> _binary; /**< Binary from which to create the program. */
95};
96
97/** Kernel class */
98class Kernel
99{
100public:
101 /** Default Constructor. */
102 Kernel();
103 /** Default Copy Constructor. */
104 Kernel(const Kernel &) = default;
105 /** Default Move Constructor. */
106 Kernel(Kernel &&) = default;
107 /** Default copy assignment operator. */
108 Kernel &operator=(const Kernel &) = default;
109 /** Default move assignment operator. */
110 Kernel &operator=(Kernel &&) = default;
111 /** Constructor.
112 *
113 * @param[in] name Kernel name.
114 * @param[in] program Built program.
115 */
116 Kernel(std::string name, const cl::Program &program);
117 /** Returns kernel name.
118 *
119 * @return Kernel's name.
120 */
121 std::string name() const
122 {
123 return _name;
124 }
125 /** Returns OpenCL kernel.
126 *
127 * @return OpenCL Kernel.
128 */
129 explicit operator cl::Kernel() const
130 {
131 return _kernel;
132 }
133
134private:
135 std::string _name; /**< Kernel name */
136 cl::Kernel _kernel; /**< OpenCL Kernel */
137};
138
139/** CLKernelLibrary class */
140class CLKernelLibrary
141{
142 using StringSet = std::set<std::string>;
143
144private:
145 /** Default Constructor. */
146 CLKernelLibrary();
147
148public:
149 /** Prevent instances of this class from being copied. */
150 CLKernelLibrary(const CLKernelLibrary &) = delete;
151 /** Prevent instances of this class from being copied. */
152 const CLKernelLibrary &operator=(const CLKernelLibrary &) = delete;
153 /** Access the KernelLibrary singleton.
154 * @return The KernelLibrary instance.
155 */
156 static CLKernelLibrary &get();
157 /** Initialises the kernel library.
158 *
159 * @param[in] kernel_path (Optional) Path of the directory from which kernel sources are loaded.
160 * @param[in] context (Optional) CL context used to create programs.
161 * @param[in] device (Optional) CL device for which the programs are created.
162 */
163 void init(std::string kernel_path = ".", cl::Context context = cl::Context::getDefault(), cl::Device device = cl::Device::getDefault())
164 {
Abel Bernabeu5a6e0532017-09-28 09:53:45 +0100165 _kernel_path = std::move(kernel_path);
166 _context = std::move(context);
167 _device = std::move(device);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100168 }
169 /** Sets the path that the kernels reside in.
170 *
171 * @param[in] kernel_path Path of the kernel.
172 */
173 void set_kernel_path(const std::string &kernel_path)
174 {
175 _kernel_path = kernel_path;
176 };
Michalis Spyroud7e82812017-06-20 15:00:14 +0100177 /** Gets the path that the kernels reside in.
178 */
179 std::string get_kernel_path()
180 {
181 return _kernel_path;
182 };
183 /** Gets the source of the selected program
184 *
185 * @param[in] program_name Program name.
186 */
187 std::string get_program_source(const std::string &program_name);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100188 /** Sets the CL context used to create programs.
189 *
190 * @note Setting the context also resets the device to the
191 * first one available in the new context.
192 *
193 * @param[in] context A CL context.
194 */
195 void set_context(cl::Context context)
196 {
197 _context = std::move(context);
198
199 const auto cl_devices = _context.getInfo<CL_CONTEXT_DEVICES>();
200
201 if(cl_devices.empty())
202 {
203 _device = cl::Device();
204 }
205 else
206 {
207 _device = cl_devices[0];
208 }
Abel Bernabeu5a6e0532017-09-28 09:53:45 +0100209 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100210 /** Sets the CL device for which the programs are created.
211 *
212 * @param[in] device A CL device.
213 */
214 void set_device(cl::Device device)
215 {
Abel Bernabeu5a6e0532017-09-28 09:53:45 +0100216 _device = std::move(device);
217 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100218 /** Creates a kernel from the kernel library.
219 *
220 * @param[in] kernel_name Kernel name.
221 * @param[in] build_options_set Kernel build options as a set.
222 *
223 * @return The created kernel.
224 */
225 Kernel create_kernel(const std::string &kernel_name, const StringSet &build_options_set = {}) const;
226 /** Serializes and saves programs to a binary.
227 *
228 */
229 void save_binary();
230 /** Load serialized binary with all the programs.
231 *
232 */
233 void load_binary();
Abel Bernabeu5a6e0532017-09-28 09:53:45 +0100234 /** Find the maximum number of local work items in a workgroup can be supported for the kernel.
steniu015f910722017-08-23 10:15:22 +0100235 *
236 */
Abel Bernabeu5a6e0532017-09-28 09:53:45 +0100237 size_t max_local_workgroup_size(const cl::Kernel &kernel) const;
238 /** Return the default NDRange for the device.
steniu015f910722017-08-23 10:15:22 +0100239 *
240 */
Abel Bernabeu5a6e0532017-09-28 09:53:45 +0100241 cl::NDRange default_ndrange() const;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100242
243private:
244 /** Load program and its dependencies.
245 *
246 * @param[in] program_name Name of the program to load.
247 */
248 const Program &load_program(const std::string &program_name) const;
249 /** Concatenates contents of a set into a single string.
250 *
251 * @param[in] s Input set to concatenate.
252 *
253 * @return Concatenated string.
254 */
255 std::string stringify_set(const StringSet &s) const;
256
257 cl::Context _context; /**< Underlying CL context. */
258 cl::Device _device; /**< Underlying CL device. */
259 std::string _kernel_path; /**< Path to the kernels folder. */
260 mutable std::map<std::string, const Program> _programs_map; /**< Map with all already loaded program data. */
261 mutable std::map<std::string, cl::Program> _built_programs_map; /**< Map with all already built program data. */
262 static const std::map<std::string, std::string> _kernel_program_map; /**< Map that associates kernel names with programs. */
263 static const std::map<std::string, std::string> _program_source_map; /**< Contains sources for all programs.
264 Used for compile-time kernel inclusion. >*/
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100265};
266}
267#endif /* __ARM_COMPUTE_CLKERNELLIBRARY_H__ */