blob: 901ac3f39a9069847d6efa74053111685b05c545 [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#include "arm_compute/core/CL/CLHelpers.h"
25#include "arm_compute/core/CL/CLTypes.h"
26#include "arm_compute/core/Error.h"
27#include "arm_compute/core/Types.h"
28
29#include <map>
Moritz Pflanzere9978592017-09-15 15:08:12 +010030#include <regex>
Anthony Barbier6ff3b192017-09-04 18:44:23 +010031#include <vector>
32
33namespace
34{
Moritz Pflanzere9978592017-09-15 15:08:12 +010035arm_compute::GPUTarget get_bifrost_target(const std::string &version)
Anthony Barbier6ff3b192017-09-04 18:44:23 +010036{
Moritz Pflanzere9978592017-09-15 15:08:12 +010037 if(version == "70")
Anthony Barbier6ff3b192017-09-04 18:44:23 +010038 {
Moritz Pflanzere9978592017-09-15 15:08:12 +010039 return arm_compute::GPUTarget::G70;
Anthony Barbier6ff3b192017-09-04 18:44:23 +010040 }
Moritz Pflanzere9978592017-09-15 15:08:12 +010041 else
42 {
43 return arm_compute::GPUTarget::BIFROST;
44 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +010045}
46
Moritz Pflanzere9978592017-09-15 15:08:12 +010047arm_compute::GPUTarget get_midgard_target(const std::string &version)
Anthony Barbier6ff3b192017-09-04 18:44:23 +010048{
Moritz Pflanzere9978592017-09-15 15:08:12 +010049 switch(version[0])
Anthony Barbier6ff3b192017-09-04 18:44:23 +010050 {
Moritz Pflanzere9978592017-09-15 15:08:12 +010051 case '6':
52 return arm_compute::GPUTarget::T600;
53 case '7':
54 return arm_compute::GPUTarget::T700;
55 case '8':
56 return arm_compute::GPUTarget::T800;
57 default:
58 return arm_compute::GPUTarget::MIDGARD;
Anthony Barbier6ff3b192017-09-04 18:44:23 +010059 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +010060}
Matthew Bentham6f31f8c2017-10-27 11:50:06 +010061
62bool extension_support(const cl::Device &device, const char *extension_name)
63{
64 std::string extensions = device.getInfo<CL_DEVICE_EXTENSIONS>();
65 auto pos = extensions.find(extension_name);
66 return (pos != std::string::npos);
67}
Anthony Barbier6ff3b192017-09-04 18:44:23 +010068} // namespace
69
70namespace arm_compute
71{
72std::string get_cl_type_from_data_type(const DataType &dt)
73{
74 switch(dt)
75 {
76 case DataType::U8:
77 return "uchar";
Georgios Pinitase5f8fd62017-06-23 18:03:44 +010078 case DataType::QS8:
79 return "qs8";
Anthony Barbier6ff3b192017-09-04 18:44:23 +010080 case DataType::S8:
81 return "char";
Michel Iwaniec00633802017-10-12 14:14:15 +010082 case DataType::QASYMM8:
83 return "uchar";
Anthony Barbier6ff3b192017-09-04 18:44:23 +010084 case DataType::U16:
85 return "ushort";
86 case DataType::S16:
87 return "short";
Gian Marco Iodice5cb4c422017-06-23 10:38:25 +010088 case DataType::QS16:
89 return "qs16";
Anthony Barbier6ff3b192017-09-04 18:44:23 +010090 case DataType::U32:
91 return "uint";
92 case DataType::S32:
93 return "int";
Michalis Spyroudef665a2017-08-14 11:26:37 +010094 case DataType::QS32:
95 return "qs32";
Anthony Barbier6ff3b192017-09-04 18:44:23 +010096 case DataType::U64:
97 return "ulong";
98 case DataType::S64:
99 return "long";
100 case DataType::F16:
101 return "half";
102 case DataType::F32:
103 return "float";
104 default:
105 ARM_COMPUTE_ERROR("Unsupported input data type.");
106 return "";
107 }
108}
109
SiCong Lic51b72f2017-07-28 14:46:20 +0100110std::string get_data_size_from_data_type(const DataType &dt)
111{
112 switch(dt)
113 {
114 case DataType::U8:
115 case DataType::QS8:
116 case DataType::S8:
Michel Iwaniec00633802017-10-12 14:14:15 +0100117 case DataType::QASYMM8:
SiCong Lic51b72f2017-07-28 14:46:20 +0100118 return "8";
119 case DataType::U16:
120 case DataType::S16:
121 case DataType::QS16:
122 case DataType::F16:
123 return "16";
124 case DataType::U32:
125 case DataType::S32:
126 case DataType::F32:
127 return "32";
128 case DataType::U64:
129 case DataType::S64:
130 return "64";
131 default:
132 ARM_COMPUTE_ERROR("Unsupported input data type.");
133 return "0";
134 }
135}
136
Georgios Pinitasac4e8732017-07-05 17:02:25 +0100137std::string get_underlying_cl_type_from_data_type(const DataType &dt)
138{
139 switch(dt)
140 {
141 case DataType::QS8:
142 return "char";
143 case DataType::QS16:
144 return "short";
Michalis Spyroudef665a2017-08-14 11:26:37 +0100145 case DataType::QS32:
146 return "int";
Georgios Pinitasac4e8732017-07-05 17:02:25 +0100147 default:
148 return get_cl_type_from_data_type(dt);
149 }
150}
151
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100152const std::string &string_from_target(GPUTarget target)
153{
154 static std::map<GPUTarget, const std::string> gpu_target_map =
155 {
156 { GPUTarget::MIDGARD, "midgard" },
157 { GPUTarget::BIFROST, "bifrost" },
158 { GPUTarget::T600, "t600" },
159 { GPUTarget::T700, "t700" },
160 { GPUTarget::T800, "t800" },
161 { GPUTarget::G70, "g70" }
162 };
163
164 return gpu_target_map[target];
165}
166
167GPUTarget get_target_from_device(cl::Device &device)
168{
Moritz Pflanzere9978592017-09-15 15:08:12 +0100169 size_t name_size = 0;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100170
171 // Query device name size
172 cl_int err = clGetDeviceInfo(device.get(), CL_DEVICE_NAME, 0, nullptr, &name_size);
173 ARM_COMPUTE_ERROR_ON_MSG((err != 0) || (name_size == 0), "clGetDeviceInfo failed to return valid information");
Georgios Pinitas30f02152017-09-27 11:20:48 +0100174 ARM_COMPUTE_UNUSED(err);
Moritz Pflanzere9978592017-09-15 15:08:12 +0100175
176 std::vector<char> name_buffer(name_size);
177
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100178 // Query device name
Moritz Pflanzere9978592017-09-15 15:08:12 +0100179 err = clGetDeviceInfo(device.get(), CL_DEVICE_NAME, name_size, name_buffer.data(), nullptr);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100180 ARM_COMPUTE_ERROR_ON_MSG(err != 0, "clGetDeviceInfo failed to return valid information");
181 ARM_COMPUTE_UNUSED(err);
182
Moritz Pflanzere9978592017-09-15 15:08:12 +0100183 std::regex mali_regex(R"(Mali-([TG])(\d+))");
184 std::string device_name(name_buffer.begin(), name_buffer.end());
185 std::smatch name_parts;
186 const bool found_mali = std::regex_search(device_name, name_parts, mali_regex);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100187
Moritz Pflanzere9978592017-09-15 15:08:12 +0100188 if(!found_mali)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100189 {
Moritz Pflanzere9978592017-09-15 15:08:12 +0100190 ARM_COMPUTE_INFO("Can't find valid Mali GPU. Target is set to MIDGARD.");
191 return GPUTarget::MIDGARD;
192 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100193
Moritz Pflanzere9978592017-09-15 15:08:12 +0100194 const char target = name_parts.str(1)[0];
195 const std::string &version = name_parts.str(2);
196
197 switch(target)
198 {
199 case 'T':
200 return get_midgard_target(version);
201 case 'G':
202 return get_bifrost_target(version);
203 default:
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100204 ARM_COMPUTE_INFO("Mali GPU unknown. Target is set to the default one.");
Moritz Pflanzere9978592017-09-15 15:08:12 +0100205 return GPUTarget::MIDGARD;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100206 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100207}
208
209GPUTarget get_arch_from_target(GPUTarget target)
210{
211 return (target & GPUTarget::GPU_ARCH_MASK);
212}
steniu0134702472017-07-11 09:22:58 +0100213
214bool non_uniform_workgroup_support(const cl::Device &device)
215{
Matthew Bentham6f31f8c2017-10-27 11:50:06 +0100216 return extension_support(device, "cl_arm_non_uniform_work_group_size");
217}
steniu0134702472017-07-11 09:22:58 +0100218
Matthew Bentham6f31f8c2017-10-27 11:50:06 +0100219bool fp16_support(const cl::Device &device)
220{
221 return extension_support(device, "cl_khr_fp16");
steniu0134702472017-07-11 09:22:58 +0100222}
223
224CLVersion get_cl_version(const cl::Device &device)
225{
226 std::vector<char> version;
227 size_t version_size = 0;
228 cl_int err = clGetDeviceInfo(device.get(), CL_DEVICE_VERSION, 0, nullptr, &version_size);
229 ARM_COMPUTE_ERROR_ON_MSG((err != 0) || (version_size == 0), "clGetDeviceInfo failed to return valid information");
Georgios Pinitas30f02152017-09-27 11:20:48 +0100230 ARM_COMPUTE_UNUSED(err);
231
steniu0134702472017-07-11 09:22:58 +0100232 // Resize vector
233 version.resize(version_size);
234 // Query version
235 err = clGetDeviceInfo(device.get(), CL_DEVICE_VERSION, version_size, version.data(), nullptr);
236 ARM_COMPUTE_ERROR_ON_MSG(err != 0, "clGetDeviceInfo failed to return valid information");
237 ARM_COMPUTE_UNUSED(err);
238
239 std::string version_str(version.begin(), version.end());
240 if(version_str.find("OpenCL 2") != std::string::npos)
241 {
242 return CLVersion::CL20;
243 }
244 else if(version_str.find("OpenCL 1.2") != std::string::npos)
245 {
246 return CLVersion::CL12;
247 }
248 else if(version_str.find("OpenCL 1.1") != std::string::npos)
249 {
250 return CLVersion::CL11;
251 }
252 else if(version_str.find("OpenCL 1.0") != std::string::npos)
253 {
254 return CLVersion::CL10;
255 }
256
257 return CLVersion::UNKNOWN;
258}
259
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100260} // namespace arm_compute