xref: /aosp_15_r20/external/ComputeLibrary/arm_compute/core/CL/CLDevice.h (revision c217d954acce2dbc11938adb493fc0abd69584f3)
1 /*
2  * Copyright (c) 2020-2022 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_CLDEVICE_H
25 #define ARM_COMPUTE_CLDEVICE_H
26 
27 #include "arm_compute/core/CL/CLHelpers.h"
28 #include "arm_compute/core/CL/CLTypes.h"
29 #include "arm_compute/core/GPUTarget.h"
30 #include "arm_compute/core/IDevice.h"
31 
32 #include <set>
33 #include <sstream>
34 #include <string>
35 
36 namespace arm_compute
37 {
38 /**  OpenCL device type class
39  *
40  *   Initializes and stores all the information about a cl device,
41  *   working mainly as a cache mechanism.
42  * */
43 class CLDevice : public IDevice
44 {
45 public:
46     /** Default Constructor */
CLDevice()47     CLDevice()
48         : _device(cl::Device()), _options()
49     {
50     }
51 
52     /** Constructor
53      *
54      * @param[in] cl_device OpenCL device
55      */
CLDevice(const cl::Device & cl_device)56     CLDevice(const cl::Device &cl_device)
57         : _device(), _options()
58     {
59         _device = cl_device;
60 
61         // Get device target
62         std::string device_name = _device.getInfo<CL_DEVICE_NAME>();
63         _options.gpu_target     = get_target_from_name(device_name);
64 
65         // Fill extensions
66         std::string extensions = _device.getInfo<CL_DEVICE_EXTENSIONS>();
67 
68         std::istringstream iss(extensions);
69         for(std::string s; iss >> s;)
70         {
71             _options.extensions.insert(s);
72         }
73 
74         // SW workaround for G76
75         if(_options.gpu_target == GPUTarget::G76)
76         {
77             _options.extensions.insert("cl_arm_integer_dot_product_int8");
78         }
79 
80         // Get device version
81         _options.version = get_cl_version(_device);
82 
83         // Get compute units
84         _options.compute_units = _device.getInfo<CL_DEVICE_MAX_COMPUTE_UNITS>();
85 
86         // Get device version
87         _options.device_version = _device.getInfo<CL_DEVICE_VERSION>();
88     }
89 
90     /** Returns the GPU target of the cl device
91      *
92      * @return The GPU target
93      */
target()94     const GPUTarget &target() const
95     {
96         return _options.gpu_target;
97     }
98 
99     /** Returns the number of compute units available
100      *
101      * @return Number of compute units
102      */
compute_units()103     size_t compute_units() const
104     {
105         return _options.compute_units;
106     }
107 
108     /** Returns the underlying cl device object
109      *
110      * @return A cl device
111      */
cl_device()112     const cl::Device &cl_device() const
113     {
114         return _device;
115     }
116 
117     /** Returns the device's CL version
118      *
119      * @return CLVersion of the device
120      */
version()121     CLVersion version() const
122     {
123         return _options.version;
124     }
125 
126     /** Returns the device version as a string
127      *
128      * @return CLVersion of the device
129      */
device_version()130     std::string device_version() const
131     {
132         return _options.device_version;
133     }
134 
135     // Inherrited methods
type()136     DeviceType type() const override
137     {
138         return DeviceType::CL;
139     }
140 
supported(const std::string & extension)141     bool supported(const std::string &extension) const override
142     {
143         return _options.extensions.count(extension) != 0;
144     }
145 
146     /** Returns whether non-uniform workgroup is supported and the build options.
147      *
148      * If the feature is supported, the appropriate build options will be
149      * appended to the specified string.
150      *
151      * @return A tuple (supported, build_options) indicating whether the feature
152      *         is supported and the corresponding build options to enable it.
153      */
is_non_uniform_workgroup_supported()154     std::tuple<bool, std::string> is_non_uniform_workgroup_supported() const
155     {
156         if(version() == CLVersion::CL30 && get_cl_non_uniform_work_group_supported(_device))
157         {
158             return {true, " -cl-std=CL3.0 "};
159         }
160         else if(version() == CLVersion::CL20)
161         {
162             return {true, " -cl-std=CL2.0 "};
163         }
164         else if(supported("cl_arm_non_uniform_work_group_size"))
165         {
166             return {true, " -cl-arm-non-uniform-work-group-size "};
167         }
168 
169         return {false, ""};
170     }
171 
172 private:
173     cl::Device             _device;  /**< OpenCL device. */
174     struct CLDeviceOptions _options; /**< OpenCL device options */
175 };
176 
177 } // namespace arm_compute
178 
179 #endif /* ARM_COMPUTE_CLDEVICE_H */
180