blob: c29610c252476b21a9b7312b3fb869337178723f [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 {
165 _kernel_path = std::move(kernel_path);
166 _context = std::move(context);
167 _device = std::move(device);
168 }
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 };
177 /** Sets the CL context used to create programs.
178 *
179 * @note Setting the context also resets the device to the
180 * first one available in the new context.
181 *
182 * @param[in] context A CL context.
183 */
184 void set_context(cl::Context context)
185 {
186 _context = std::move(context);
187
188 const auto cl_devices = _context.getInfo<CL_CONTEXT_DEVICES>();
189
190 if(cl_devices.empty())
191 {
192 _device = cl::Device();
193 }
194 else
195 {
196 _device = cl_devices[0];
197 }
198 };
199 /** Sets the CL device for which the programs are created.
200 *
201 * @param[in] device A CL device.
202 */
203 void set_device(cl::Device device)
204 {
205 _device = std::move(device);
206 };
207 /** Creates a kernel from the kernel library.
208 *
209 * @param[in] kernel_name Kernel name.
210 * @param[in] build_options_set Kernel build options as a set.
211 *
212 * @return The created kernel.
213 */
214 Kernel create_kernel(const std::string &kernel_name, const StringSet &build_options_set = {}) const;
215 /** Serializes and saves programs to a binary.
216 *
217 */
218 void save_binary();
219 /** Load serialized binary with all the programs.
220 *
221 */
222 void load_binary();
223
224private:
225 /** Load program and its dependencies.
226 *
227 * @param[in] program_name Name of the program to load.
228 */
229 const Program &load_program(const std::string &program_name) const;
230 /** Concatenates contents of a set into a single string.
231 *
232 * @param[in] s Input set to concatenate.
233 *
234 * @return Concatenated string.
235 */
236 std::string stringify_set(const StringSet &s) const;
237
238 cl::Context _context; /**< Underlying CL context. */
239 cl::Device _device; /**< Underlying CL device. */
240 std::string _kernel_path; /**< Path to the kernels folder. */
241 mutable std::map<std::string, const Program> _programs_map; /**< Map with all already loaded program data. */
242 mutable std::map<std::string, cl::Program> _built_programs_map; /**< Map with all already built program data. */
243 static const std::map<std::string, std::string> _kernel_program_map; /**< Map that associates kernel names with programs. */
244 static const std::map<std::string, std::string> _program_source_map; /**< Contains sources for all programs.
245 Used for compile-time kernel inclusion. >*/
246};
247}
248#endif /* __ARM_COMPUTE_CLKERNELLIBRARY_H__ */