This source file includes following definitions.
- hwloc_opencl_discover
- hwloc_opencl_component_instantiate
- hwloc_opencl_component_init
1
2
3
4
5
6
7 #include <private/autogen/config.h>
8 #include <hwloc.h>
9 #include <hwloc/plugins.h>
10
11
12 #include <private/misc.h>
13 #include <private/debug.h>
14
15 #ifdef __APPLE__
16 #include <OpenCL/cl_ext.h>
17 #else
18 #include <CL/cl_ext.h>
19 #endif
20
21 static int
22 hwloc_opencl_discover(struct hwloc_backend *backend)
23 {
24 struct hwloc_topology *topology = backend->topology;
25 enum hwloc_type_filter_e filter;
26 cl_uint nr_platforms;
27 cl_int clret;
28 unsigned j;
29
30 hwloc_topology_get_type_filter(topology, HWLOC_OBJ_OS_DEVICE, &filter);
31 if (filter == HWLOC_TYPE_FILTER_KEEP_NONE)
32 return 0;
33
34 clret = clGetPlatformIDs(0, NULL, &nr_platforms);
35 if (CL_SUCCESS != clret || !nr_platforms)
36 return -1;
37 hwloc_debug("%u OpenCL platforms\n", nr_platforms);
38
39 cl_platform_id platform_ids[nr_platforms];
40 clret = clGetPlatformIDs(nr_platforms, platform_ids, &nr_platforms);
41 if (CL_SUCCESS != clret || !nr_platforms)
42 return -1;
43
44 for(j=0; j<nr_platforms; j++) {
45 cl_uint nr_devices;
46 unsigned i;
47
48 clret = clGetDeviceIDs(platform_ids[j], CL_DEVICE_TYPE_ALL, 0, NULL, &nr_devices);
49 if (CL_SUCCESS != clret)
50 continue;
51
52 cl_device_id device_ids[nr_devices];
53 clret = clGetDeviceIDs(platform_ids[j], CL_DEVICE_TYPE_ALL, nr_devices, device_ids, &nr_devices);
54 if (CL_SUCCESS != clret)
55 continue;
56
57 for(i=0; i<nr_devices; i++) {
58 cl_platform_id platform_id = 0;
59 cl_device_type type;
60 #ifdef CL_DEVICE_TOPOLOGY_AMD
61 cl_device_topology_amd amdtopo;
62 #endif
63 cl_ulong globalmemsize;
64 cl_uint computeunits;
65 hwloc_obj_t osdev, parent;
66 char buffer[64];
67
68 hwloc_debug("This is opencl%ud%u\n", j, i);
69
70 clGetDeviceInfo(device_ids[i], CL_DEVICE_TYPE, sizeof(type), &type, NULL);
71 if (type == CL_DEVICE_TYPE_CPU)
72
73 continue;
74
75 osdev = hwloc_alloc_setup_object(topology, HWLOC_OBJ_OS_DEVICE, HWLOC_UNKNOWN_INDEX);
76 snprintf(buffer, sizeof(buffer), "opencl%ud%u", j, i);
77 osdev->name = strdup(buffer);
78 osdev->depth = HWLOC_TYPE_DEPTH_UNKNOWN;
79 osdev->attr->osdev.type = HWLOC_OBJ_OSDEV_COPROC;
80
81 osdev->subtype = strdup("OpenCL");
82 hwloc_obj_add_info(osdev, "Backend", "OpenCL");
83
84 if (type == CL_DEVICE_TYPE_GPU)
85 hwloc_obj_add_info(osdev, "OpenCLDeviceType", "GPU");
86 else if (type == CL_DEVICE_TYPE_ACCELERATOR)
87 hwloc_obj_add_info(osdev, "OpenCLDeviceType", "Accelerator");
88 else if (type == CL_DEVICE_TYPE_CUSTOM)
89 hwloc_obj_add_info(osdev, "OpenCLDeviceType", "Custom");
90 else
91 hwloc_obj_add_info(osdev, "OpenCLDeviceType", "Unknown");
92
93 buffer[0] = '\0';
94 clGetDeviceInfo(device_ids[i], CL_DEVICE_VENDOR, sizeof(buffer), buffer, NULL);
95 if (buffer[0] != '\0')
96 hwloc_obj_add_info(osdev, "GPUVendor", buffer);
97
98 buffer[0] = '\0';
99 #ifdef CL_DEVICE_BOARD_NAME_AMD
100 clret = clGetDeviceInfo(device_ids[i], CL_DEVICE_BOARD_NAME_AMD, sizeof(buffer), buffer, NULL);
101 if (CL_SUCCESS != clret || buffer[0] == '\0')
102 #endif
103 clGetDeviceInfo(device_ids[i], CL_DEVICE_NAME, sizeof(buffer), buffer, NULL);
104 if (buffer[0] != '\0')
105 hwloc_obj_add_info(osdev, "GPUModel", buffer);
106
107 snprintf(buffer, sizeof(buffer), "%u", j);
108 hwloc_obj_add_info(osdev, "OpenCLPlatformIndex", buffer);
109
110 buffer[0] = '\0';
111 clret = clGetDeviceInfo(device_ids[i], CL_DEVICE_PLATFORM, sizeof(platform_id), &platform_id, NULL);
112 if (CL_SUCCESS == clret) {
113 clGetPlatformInfo(platform_id, CL_PLATFORM_NAME, sizeof(buffer), buffer, NULL);
114 if (buffer[0] != '\0')
115 hwloc_obj_add_info(osdev, "OpenCLPlatformName", buffer);
116 }
117
118 snprintf(buffer, sizeof(buffer), "%u", i);
119 hwloc_obj_add_info(osdev, "OpenCLPlatformDeviceIndex", buffer);
120
121 clGetDeviceInfo(device_ids[i], CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(computeunits), &computeunits, NULL);
122 snprintf(buffer, sizeof(buffer), "%u", computeunits);
123 hwloc_obj_add_info(osdev, "OpenCLComputeUnits", buffer);
124
125 clGetDeviceInfo(device_ids[i], CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(globalmemsize), &globalmemsize, NULL);
126 snprintf(buffer, sizeof(buffer), "%llu", (unsigned long long) globalmemsize / 1024);
127 hwloc_obj_add_info(osdev, "OpenCLGlobalMemorySize", buffer);
128
129 parent = NULL;
130 #ifdef CL_DEVICE_TOPOLOGY_AMD
131 clret = clGetDeviceInfo(device_ids[i], CL_DEVICE_TOPOLOGY_AMD, sizeof(amdtopo), &amdtopo, NULL);
132 if (CL_SUCCESS != clret) {
133 hwloc_debug("no AMD-specific device information: %d\n", clret);
134 } else if (CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD != amdtopo.raw.type) {
135 hwloc_debug("AMD-specific device topology reports non-PCIe device type: %u\n", amdtopo.raw.type);
136 } else {
137 parent = hwloc_pcidisc_find_by_busid(topology, 0, (unsigned)amdtopo.pcie.bus, (unsigned)amdtopo.pcie.device, (unsigned)amdtopo.pcie.function);
138 if (!parent)
139 parent = hwloc_pcidisc_find_busid_parent(topology, 0, (unsigned)amdtopo.pcie.bus, (unsigned)amdtopo.pcie.device, (unsigned)amdtopo.pcie.function);
140 }
141 #else
142 hwloc_debug("No locality information found.\n");
143 #endif
144 if (!parent)
145 parent = hwloc_get_root_obj(topology);
146
147 hwloc_insert_object_by_parent(topology, parent, osdev);
148 }
149 }
150 return 0;
151 }
152
153 static struct hwloc_backend *
154 hwloc_opencl_component_instantiate(struct hwloc_disc_component *component,
155 const void *_data1 __hwloc_attribute_unused,
156 const void *_data2 __hwloc_attribute_unused,
157 const void *_data3 __hwloc_attribute_unused)
158 {
159 struct hwloc_backend *backend;
160
161 backend = hwloc_backend_alloc(component);
162 if (!backend)
163 return NULL;
164 backend->discover = hwloc_opencl_discover;
165 return backend;
166 }
167
168 static struct hwloc_disc_component hwloc_opencl_disc_component = {
169 HWLOC_DISC_COMPONENT_TYPE_MISC,
170 "opencl",
171 HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
172 hwloc_opencl_component_instantiate,
173 10,
174 1,
175 NULL
176 };
177
178 static int
179 hwloc_opencl_component_init(unsigned long flags)
180 {
181 if (flags)
182 return -1;
183 if (hwloc_plugin_check_namespace("opencl", "hwloc_backend_alloc") < 0)
184 return -1;
185 return 0;
186 }
187
188 #ifdef HWLOC_INSIDE_PLUGIN
189 HWLOC_DECLSPEC extern const struct hwloc_component hwloc_opencl_component;
190 #endif
191
192 const struct hwloc_component hwloc_opencl_component = {
193 HWLOC_COMPONENT_ABI,
194 hwloc_opencl_component_init, NULL,
195 HWLOC_COMPONENT_TYPE_DISC,
196 0,
197 &hwloc_opencl_disc_component
198 };