blob: 6af378c7abec5d4a30ecaac444a164046071a4ec [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*
Manuel Bottinibe9f9f92021-01-25 15:07:17 +00002 * Copyright (c) 2016-2021 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#include "arm_compute/core/CL/CLHelpers.h"
25#include "arm_compute/core/CL/CLTypes.h"
26#include "arm_compute/core/Error.h"
Georgios Pinitas3faea252017-10-30 14:13:50 +000027#include "arm_compute/core/Log.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010028#include "arm_compute/core/Types.h"
Georgios Pinitas908f6162021-05-04 10:11:09 +010029#include "src/core/gpu/cl/ClCompileContext.h"
30
31#include "src/core/gpu/cl/ClKernelLibrary.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010032
Gian Marco Iodicef1c2bf02018-06-13 14:05:54 +010033#include <utility>
Anthony Barbier6ff3b192017-09-04 18:44:23 +010034#include <vector>
35
Anthony Barbier6ff3b192017-09-04 18:44:23 +010036namespace arm_compute
37{
38std::string get_cl_type_from_data_type(const DataType &dt)
39{
40 switch(dt)
41 {
42 case DataType::U8:
Michel Iwaniec00633802017-10-12 14:14:15 +010043 case DataType::QASYMM8:
44 return "uchar";
Georgios Pinitas3d13af82019-06-04 13:04:16 +010045 case DataType::S8:
Michele Di Giorgiof9179d32019-11-27 16:17:30 +000046 case DataType::QASYMM8_SIGNED:
Georgios Pinitas3d13af82019-06-04 13:04:16 +010047 case DataType::QSYMM8:
Michalis Spyrou3f632f32019-08-22 16:52:00 +010048 case DataType::QSYMM8_PER_CHANNEL:
Georgios Pinitas3d13af82019-06-04 13:04:16 +010049 return "char";
Anthony Barbier6ff3b192017-09-04 18:44:23 +010050 case DataType::U16:
Michele Di Giorgio4aff98f2019-08-28 16:27:26 +010051 case DataType::QASYMM16:
Anthony Barbier6ff3b192017-09-04 18:44:23 +010052 return "ushort";
53 case DataType::S16:
Michele Di Giorgio6997fc92019-06-18 10:23:22 +010054 case DataType::QSYMM16:
Anthony Barbier6ff3b192017-09-04 18:44:23 +010055 return "short";
Anthony Barbier6ff3b192017-09-04 18:44:23 +010056 case DataType::U32:
57 return "uint";
58 case DataType::S32:
59 return "int";
60 case DataType::U64:
61 return "ulong";
62 case DataType::S64:
63 return "long";
64 case DataType::F16:
65 return "half";
66 case DataType::F32:
67 return "float";
68 default:
69 ARM_COMPUTE_ERROR("Unsupported input data type.");
70 return "";
71 }
72}
73
Michele Di Giorgiodf4cf572019-10-09 15:32:39 +010074std::string get_cl_promoted_type_from_data_type(const DataType &dt)
75{
76 switch(dt)
77 {
78 case DataType::U8:
79 case DataType::QASYMM8:
Michele Di Giorgiodf4cf572019-10-09 15:32:39 +010080 return "ushort";
81 case DataType::S8:
Michele Di Giorgiof9179d32019-11-27 16:17:30 +000082 case DataType::QASYMM8_SIGNED:
Michele Di Giorgiodf4cf572019-10-09 15:32:39 +010083 case DataType::QSYMM8:
84 case DataType::QSYMM8_PER_CHANNEL:
85 return "short";
86 case DataType::U16:
87 case DataType::QASYMM16:
88 return "uint";
89 case DataType::S16:
90 case DataType::QSYMM16:
91 return "int";
92 case DataType::U32:
93 return "ulong";
94 case DataType::S32:
95 return "long";
96 case DataType::F16:
97 return "float";
98 default:
99 ARM_COMPUTE_ERROR("Cannot get promoted OpenCL type for the input data type.");
100 return "";
101 }
102}
103
104std::string get_cl_unsigned_type_from_element_size(size_t element_size)
105{
106 switch(element_size)
107 {
108 case 1:
109 return "uchar";
110 case 2:
111 return "ushort";
112 case 4:
113 return "uint";
114 case 8:
115 return "ulong";
116 default:
117 ARM_COMPUTE_ERROR("Data type not supported");
118 return "";
119 }
120}
121
Michalis Spyrou7317e392020-01-17 11:27:49 +0000122std::string get_cl_signed_type_from_element_size(size_t element_size)
123{
124 switch(element_size)
125 {
126 case 1:
127 return "char";
128 case 2:
129 return "short";
130 case 4:
131 return "int";
132 case 8:
133 return "long";
134 default:
135 ARM_COMPUTE_ERROR("Data type not supported");
136 return "";
137 }
138}
139
Giorgio Arena73023022018-09-04 14:55:55 +0100140std::string get_cl_select_type_from_data_type(const DataType &dt)
141{
142 switch(dt)
143 {
144 case DataType::U8:
Giorgio Arena73023022018-09-04 14:55:55 +0100145 case DataType::QASYMM8:
146 return "uchar";
Georgios Pinitas3d13af82019-06-04 13:04:16 +0100147 case DataType::S8:
Michele Di Giorgiof9179d32019-11-27 16:17:30 +0000148 case DataType::QASYMM8_SIGNED:
Georgios Pinitas3d13af82019-06-04 13:04:16 +0100149 case DataType::QSYMM8:
Michalis Spyrou3f632f32019-08-22 16:52:00 +0100150 case DataType::QSYMM8_PER_CHANNEL:
Georgios Pinitas3d13af82019-06-04 13:04:16 +0100151 return "char";
Giorgio Arena73023022018-09-04 14:55:55 +0100152 case DataType::U16:
Michele Di Giorgio4aff98f2019-08-28 16:27:26 +0100153 case DataType::QASYMM16:
Giorgio Arena73023022018-09-04 14:55:55 +0100154 return "ushort";
155 case DataType::F16:
156 case DataType::S16:
Michele Di Giorgio6997fc92019-06-18 10:23:22 +0100157 case DataType::QSYMM16:
Giorgio Arena73023022018-09-04 14:55:55 +0100158 return "short";
159 case DataType::U32:
160 return "uint";
161 case DataType::F32:
162 case DataType::S32:
163 return "int";
164 case DataType::U64:
165 return "ulong";
166 case DataType::S64:
167 return "long";
168 default:
169 ARM_COMPUTE_ERROR("Unsupported input data type.");
170 return "";
171 }
172}
173
Michele Di Giorgiof9179d32019-11-27 16:17:30 +0000174std::string get_cl_dot8_acc_type_from_data_type(const DataType &dt)
175{
176 switch(dt)
177 {
178 case DataType::U8:
179 case DataType::QASYMM8:
180 return "uint";
181 case DataType::S8:
182 case DataType::QASYMM8_SIGNED:
183 case DataType::QSYMM8:
184 case DataType::QSYMM8_PER_CHANNEL:
185 return "int";
186 default:
187 ARM_COMPUTE_ERROR("Unsupported data type.");
188 return "";
189 }
190}
191
SiCong Lic51b72f2017-07-28 14:46:20 +0100192std::string get_data_size_from_data_type(const DataType &dt)
193{
194 switch(dt)
195 {
196 case DataType::U8:
SiCong Lic51b72f2017-07-28 14:46:20 +0100197 case DataType::S8:
Georgios Pinitas3d13af82019-06-04 13:04:16 +0100198 case DataType::QSYMM8:
Michel Iwaniec00633802017-10-12 14:14:15 +0100199 case DataType::QASYMM8:
Michele Di Giorgiof9179d32019-11-27 16:17:30 +0000200 case DataType::QASYMM8_SIGNED:
Michalis Spyrou3f632f32019-08-22 16:52:00 +0100201 case DataType::QSYMM8_PER_CHANNEL:
SiCong Lic51b72f2017-07-28 14:46:20 +0100202 return "8";
203 case DataType::U16:
204 case DataType::S16:
Michele Di Giorgio6997fc92019-06-18 10:23:22 +0100205 case DataType::QSYMM16:
Michele Di Giorgio4aff98f2019-08-28 16:27:26 +0100206 case DataType::QASYMM16:
SiCong Lic51b72f2017-07-28 14:46:20 +0100207 case DataType::F16:
208 return "16";
209 case DataType::U32:
210 case DataType::S32:
211 case DataType::F32:
212 return "32";
213 case DataType::U64:
214 case DataType::S64:
215 return "64";
216 default:
217 ARM_COMPUTE_ERROR("Unsupported input data type.");
218 return "0";
219 }
220}
221
Anthony Barbierb6eb3532018-08-08 13:20:04 +0100222GPUTarget get_target_from_device(const cl::Device &device)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100223{
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100224 // Query device name size
Anthony Barbier30a63422018-02-28 18:18:24 +0000225 std::string device_name = device.getInfo<CL_DEVICE_NAME>();
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100226
Michalis Spyroua9676112018-02-22 18:07:43 +0000227 return get_target_from_name(device_name);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100228}
229
Anthony Barbierd727e852018-04-20 11:05:29 +0100230bool arm_non_uniform_workgroup_supported(const cl::Device &device)
steniu0134702472017-07-11 09:22:58 +0100231{
Vidhya Sudhan Loganathaneb8a3992018-04-10 12:23:22 +0100232 return device_supports_extension(device, "cl_arm_non_uniform_work_group_size");
Matthew Bentham6f31f8c2017-10-27 11:50:06 +0100233}
steniu0134702472017-07-11 09:22:58 +0100234
Anthony Barbierd727e852018-04-20 11:05:29 +0100235bool fp16_supported(const cl::Device &device)
Matthew Bentham6f31f8c2017-10-27 11:50:06 +0100236{
Vidhya Sudhan Loganathaneb8a3992018-04-10 12:23:22 +0100237 return device_supports_extension(device, "cl_khr_fp16");
steniu0134702472017-07-11 09:22:58 +0100238}
239
Michalis Spyroue03342e2018-01-15 14:39:13 +0000240bool dot8_supported(const cl::Device &device)
241{
Gian Marco Iodice4b908652018-10-18 10:21:02 +0100242 std::string device_name = device.getInfo<CL_DEVICE_NAME>();
243 const GPUTarget gpu_target = get_target_from_name(device_name);
244
245 // SW_WORKAROUND: Workaround for DDK revision r14p0.to enable cl_arm_integer_dot_product_int8
giuros018b6b4a92018-12-18 19:01:33 +0000246 std::set<GPUTarget> sw_workaround_issue = { GPUTarget::G76 };
Gian Marco Iodice4b908652018-10-18 10:21:02 +0100247 return (device_supports_extension(device, "cl_arm_integer_dot_product_int8") || sw_workaround_issue.count(gpu_target) != 0);
Michalis Spyroue03342e2018-01-15 14:39:13 +0000248}
249
Giorgio Arenaeff8d952018-07-02 15:29:57 +0100250bool dot8_acc_supported(const cl::Device &device)
251{
252 return device_supports_extension(device, "cl_arm_integer_dot_product_accumulate_int8");
253}
254
steniu0134702472017-07-11 09:22:58 +0100255CLVersion get_cl_version(const cl::Device &device)
256{
Anthony Barbier30a63422018-02-28 18:18:24 +0000257 std::string version_str = device.getInfo<CL_DEVICE_VERSION>();
steniu0134702472017-07-11 09:22:58 +0100258 if(version_str.find("OpenCL 2") != std::string::npos)
259 {
260 return CLVersion::CL20;
261 }
262 else if(version_str.find("OpenCL 1.2") != std::string::npos)
263 {
264 return CLVersion::CL12;
265 }
266 else if(version_str.find("OpenCL 1.1") != std::string::npos)
267 {
268 return CLVersion::CL11;
269 }
270 else if(version_str.find("OpenCL 1.0") != std::string::npos)
271 {
272 return CLVersion::CL10;
273 }
274
275 return CLVersion::UNKNOWN;
276}
277
Vidhya Sudhan Loganathaneb8a3992018-04-10 12:23:22 +0100278bool device_supports_extension(const cl::Device &device, const char *extension_name)
279{
280 std::string extensions = device.getInfo<CL_DEVICE_EXTENSIONS>();
281 auto pos = extensions.find(extension_name);
282 return (pos != std::string::npos);
283}
284
Gian Marco Iodicef1c2bf02018-06-13 14:05:54 +0100285bool cl_winograd_convolution_layer_supported(const Size2D &output_tile, const Size2D &kernel_size, DataLayout data_layout)
286{
287 ARM_COMPUTE_ERROR_ON(data_layout == DataLayout::UNKNOWN);
288
289 using WinogradConfiguration = std::pair<std::pair<int, int>, std::pair<int, int>>;
290
Giorgio Arena149fdf32018-07-04 17:03:33 +0100291 std::vector<WinogradConfiguration> winograd_configs_nchw =
Gian Marco Iodicef1c2bf02018-06-13 14:05:54 +0100292 {
293 WinogradConfiguration(std::pair<int, int>(1, 2), std::pair<int, int>(1, 3)),
294 WinogradConfiguration(std::pair<int, int>(1, 4), std::pair<int, int>(1, 3)),
295 WinogradConfiguration(std::pair<int, int>(2, 1), std::pair<int, int>(3, 1)),
296 WinogradConfiguration(std::pair<int, int>(4, 1), std::pair<int, int>(3, 1)),
297 WinogradConfiguration(std::pair<int, int>(2, 2), std::pair<int, int>(3, 3)),
298 WinogradConfiguration(std::pair<int, int>(4, 4), std::pair<int, int>(3, 3)),
Gian Marco Iodice876be2a2018-07-03 12:22:09 +0100299 WinogradConfiguration(std::pair<int, int>(4, 4), std::pair<int, int>(5, 5)),
300 WinogradConfiguration(std::pair<int, int>(4, 1), std::pair<int, int>(5, 1)),
301 WinogradConfiguration(std::pair<int, int>(1, 4), std::pair<int, int>(1, 5))
Gian Marco Iodicef1c2bf02018-06-13 14:05:54 +0100302 };
303
Giorgio Arena149fdf32018-07-04 17:03:33 +0100304 std::vector<WinogradConfiguration> winograd_configs_nhwc =
Gian Marco Iodicef1c2bf02018-06-13 14:05:54 +0100305 {
306 WinogradConfiguration(std::pair<int, int>(2, 2), std::pair<int, int>(3, 3)),
Giorgio Arena149fdf32018-07-04 17:03:33 +0100307 WinogradConfiguration(std::pair<int, int>(1, 4), std::pair<int, int>(1, 3)),
308 WinogradConfiguration(std::pair<int, int>(4, 1), std::pair<int, int>(3, 1)),
Gian Marco Iodicef1c2bf02018-06-13 14:05:54 +0100309 WinogradConfiguration(std::pair<int, int>(4, 4), std::pair<int, int>(3, 3)),
Gian Marco Iodiced28b7512018-07-06 12:59:28 +0100310 WinogradConfiguration(std::pair<int, int>(4, 4), std::pair<int, int>(5, 5)),
311 WinogradConfiguration(std::pair<int, int>(4, 1), std::pair<int, int>(5, 1)),
Michele Di Giorgiof955d512019-02-27 14:26:51 +0000312 WinogradConfiguration(std::pair<int, int>(1, 4), std::pair<int, int>(1, 5)),
313 WinogradConfiguration(std::pair<int, int>(1, 2), std::pair<int, int>(1, 7)),
314 WinogradConfiguration(std::pair<int, int>(2, 1), std::pair<int, int>(7, 1)),
315 WinogradConfiguration(std::pair<int, int>(2, 2), std::pair<int, int>(7, 7)),
Gian Marco Iodicef1c2bf02018-06-13 14:05:54 +0100316 };
317
318 auto p = std::make_pair(std::pair<int, int>(output_tile.width, output_tile.height),
319 std::pair<int, int>(kernel_size.width, kernel_size.height));
320
321 // Return true if supported
322 if(data_layout == DataLayout::NCHW)
323 {
Giorgio Arena149fdf32018-07-04 17:03:33 +0100324 return (std::find(winograd_configs_nchw.begin(), winograd_configs_nchw.end(), p) != winograd_configs_nchw.end());
Gian Marco Iodicef1c2bf02018-06-13 14:05:54 +0100325 }
326 else
327 {
Giorgio Arena149fdf32018-07-04 17:03:33 +0100328 return (std::find(winograd_configs_nhwc.begin(), winograd_configs_nhwc.end(), p) != winograd_configs_nhwc.end());
Gian Marco Iodicef1c2bf02018-06-13 14:05:54 +0100329 }
330}
Vidhya Sudhan Loganathan5e96be72018-12-18 14:17:00 +0000331
332size_t preferred_vector_width(const cl::Device &device, const DataType dt)
333{
334 switch(dt)
335 {
336 case DataType::U8:
337 case DataType::S8:
338 case DataType::QASYMM8:
Michele Di Giorgiof9179d32019-11-27 16:17:30 +0000339 case DataType::QASYMM8_SIGNED:
Georgios Pinitas3d13af82019-06-04 13:04:16 +0100340 case DataType::QSYMM8:
Michalis Spyrou3f632f32019-08-22 16:52:00 +0100341 case DataType::QSYMM8_PER_CHANNEL:
Vidhya Sudhan Loganathan5e96be72018-12-18 14:17:00 +0000342 return device.getInfo<CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR>();
343 case DataType::U16:
344 case DataType::S16:
Michele Di Giorgio6997fc92019-06-18 10:23:22 +0100345 case DataType::QSYMM16:
Michele Di Giorgio4aff98f2019-08-28 16:27:26 +0100346 case DataType::QASYMM16:
Vidhya Sudhan Loganathan5e96be72018-12-18 14:17:00 +0000347 return device.getInfo<CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT>();
348 case DataType::U32:
349 case DataType::S32:
350 return device.getInfo<CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT>();
351 case DataType::F16:
352 case DataType::F32:
353 return device.getInfo<CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT>();
354 case DataType::U64:
355 case DataType::S64:
356 return device.getInfo<CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG>();
357 default:
358 return 1;
359 }
360}
Gian Marco Iodiceb0c50372019-03-15 10:13:05 +0000361
362bool preferred_dummy_work_items_support(const cl::Device &device)
363{
364 ARM_COMPUTE_UNUSED(device);
365 // TODO (COMPMID-2044)
366 return true;
367}
Pablo Tellodb8485a2019-09-24 11:03:47 +0100368
Gian Marco Iodicea98dee22020-06-02 12:12:35 +0100369bool image2d_from_buffer_supported(const cl::Device &device)
370{
371 return device_supports_extension(device, "cl_khr_image2d_from_buffer");
372}
373
374size_t get_cl_image_pitch_alignment(const cl::Device &device)
375{
376 cl_uint pixel_aligment = 0;
377
378 cl_int err = clGetDeviceInfo(device(), CL_DEVICE_IMAGE_PITCH_ALIGNMENT, sizeof(cl_uint), &pixel_aligment, nullptr);
379
380 if(err == CL_SUCCESS)
381 {
382 return pixel_aligment;
383 }
384 else
385 {
386 return 0;
387 }
388}
389
Manuel Bottini256c0b92020-04-21 13:29:30 +0100390cl::Kernel create_kernel(const CLCompileContext &ctx, const std::string &kernel_name, const std::set<std::string> &build_opts)
Michalis Spyrou11d49182020-03-26 10:31:32 +0000391{
Georgios Pinitas908f6162021-05-04 10:11:09 +0100392 opencl::ClKernelLibrary &klib = opencl::ClKernelLibrary::get();
393
394 const std::string program_name = klib.program_name(kernel_name);
395 auto kernel_src = klib.program(program_name);
396 const std::string kernel_path = klib.kernel_path();
397
398 return static_cast<cl::Kernel>(ctx.create_kernel(kernel_name, program_name, kernel_src.program, kernel_path, build_opts, kernel_src.is_binary));
Michalis Spyrou11d49182020-03-26 10:31:32 +0000399}
400
Manuel Bottini7b9998d2019-10-21 17:59:07 +0100401cl::NDRange create_lws_hint_parallel_implementations(unsigned int input_dimension, unsigned int vector_size)
402{
403 const unsigned int width_leftover = input_dimension % vector_size;
404 const unsigned int border_width = (width_leftover != 0) ? vector_size - width_leftover : 0;
405 const unsigned int num_of_threads = ((input_dimension + border_width) / 16);
406 return cl::NDRange(std::min(8U, num_of_threads));
407}
Manuel Bottinibe9f9f92021-01-25 15:07:17 +0000408
409bool get_wbsm_support_info(const cl::Device &device)
410{
411 cl_bitfield capabilities = 0;
412 cl_int err = clGetDeviceInfo(device.get(), ARM_COMPUTE_LIBRARY_OPENCL_DEVICE_CAPABILITIES_ARM, sizeof(cl_bitfield), &capabilities, nullptr);
413 if((err == CL_SUCCESS) && (capabilities & ARM_COMPUTE_LIBRARY_OPENCL_EXEC_WBSM_ARM))
414 {
415 return true;
416 }
417 return false;
418}
419
420void set_wbsm(cl::Kernel &kernel, cl_int wbsm_hint)
421{
422 cl_int err = clSetKernelExecInfo(kernel.get(),
423 ARM_COMPUTE_LIBRARY_OPENCL_EXEC_WBSM_ARM,
424 sizeof(cl_int),
425 &wbsm_hint);
426 ARM_COMPUTE_UNUSED(err);
427 ARM_COMPUTE_ERROR_ON(err != CL_SUCCESS);
428}
429
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100430} // namespace arm_compute