File indexing completed on 2026-09-17 09:16:56
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef HWLOC_OPENCL_H
0016 #define HWLOC_OPENCL_H
0017
0018 #include "hwloc.h"
0019 #include "hwloc/autogen/config.h"
0020 #include "hwloc/helper.h"
0021 #ifdef HWLOC_LINUX_SYS
0022 #include "hwloc/linux.h"
0023 #endif
0024
0025 #ifdef __APPLE__
0026 #include <OpenCL/cl.h>
0027 #else
0028 #include <CL/cl.h>
0029 #endif
0030
0031 #include <stdio.h>
0032
0033
0034 #ifdef __cplusplus
0035 extern "C" {
0036 #endif
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046 typedef struct {
0047 cl_uint pci_domain;
0048 cl_uint pci_bus;
0049 cl_uint pci_device;
0050 cl_uint pci_function;
0051 } hwloc_cl_device_pci_bus_info_khr;
0052 #define HWLOC_CL_DEVICE_PCI_BUS_INFO_KHR 0x410F
0053
0054
0055 #define HWLOC_CL_DEVICE_TOPOLOGY_AMD 0x4037
0056 typedef union {
0057 struct { cl_uint type; cl_uint data[5]; } raw;
0058 struct { cl_uint type; cl_char unused[17]; cl_char bus; cl_char device; cl_char function; } pcie;
0059 } hwloc_cl_device_topology_amd;
0060 #define HWLOC_CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD 1
0061
0062
0063 #define HWLOC_CL_DEVICE_PCI_BUS_ID_NV 0x4008
0064 #define HWLOC_CL_DEVICE_PCI_SLOT_ID_NV 0x4009
0065 #define HWLOC_CL_DEVICE_PCI_DOMAIN_ID_NV 0x400A
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086 static __hwloc_inline int
0087 hwloc_opencl_get_device_pci_busid(cl_device_id device,
0088 unsigned *domain, unsigned *bus, unsigned *dev, unsigned *func)
0089 {
0090 hwloc_cl_device_topology_amd amdtopo;
0091 hwloc_cl_device_pci_bus_info_khr khrbusinfo;
0092 cl_uint nvbus, nvslot, nvdomain;
0093 cl_int clret;
0094
0095 clret = clGetDeviceInfo(device, HWLOC_CL_DEVICE_PCI_BUS_INFO_KHR, sizeof(khrbusinfo), &khrbusinfo, NULL);
0096 if (CL_SUCCESS == clret) {
0097 *domain = (unsigned) khrbusinfo.pci_domain;
0098 *bus = (unsigned) khrbusinfo.pci_bus;
0099 *dev = (unsigned) khrbusinfo.pci_device;
0100 *func = (unsigned) khrbusinfo.pci_function;
0101 return 0;
0102 }
0103
0104 clret = clGetDeviceInfo(device, HWLOC_CL_DEVICE_TOPOLOGY_AMD, sizeof(amdtopo), &amdtopo, NULL);
0105 if (CL_SUCCESS == clret
0106 && HWLOC_CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD == amdtopo.raw.type) {
0107 *domain = 0;
0108
0109 *bus = (unsigned) (unsigned char) amdtopo.pcie.bus;
0110 *dev = (unsigned) (unsigned char) amdtopo.pcie.device;
0111 *func = (unsigned) (unsigned char) amdtopo.pcie.function;
0112 return 0;
0113 }
0114
0115 clret = clGetDeviceInfo(device, HWLOC_CL_DEVICE_PCI_BUS_ID_NV, sizeof(nvbus), &nvbus, NULL);
0116 if (CL_SUCCESS == clret) {
0117 clret = clGetDeviceInfo(device, HWLOC_CL_DEVICE_PCI_SLOT_ID_NV, sizeof(nvslot), &nvslot, NULL);
0118 if (CL_SUCCESS == clret) {
0119 clret = clGetDeviceInfo(device, HWLOC_CL_DEVICE_PCI_DOMAIN_ID_NV, sizeof(nvdomain), &nvdomain, NULL);
0120 if (CL_SUCCESS == clret) {
0121 *domain = nvdomain;
0122 } else {
0123 *domain = 0;
0124 }
0125 *bus = nvbus & 0xff;
0126
0127 *dev = nvslot >> 3;
0128 *func = nvslot & 0x7;
0129 return 0;
0130 }
0131 }
0132
0133 return -1;
0134 }
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156 static __hwloc_inline int
0157 hwloc_opencl_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
0158 cl_device_id device __hwloc_attribute_unused,
0159 hwloc_cpuset_t set)
0160 {
0161 #if (defined HWLOC_LINUX_SYS)
0162
0163 #define HWLOC_OPENCL_DEVICE_SYSFS_PATH_MAX 128
0164 char path[HWLOC_OPENCL_DEVICE_SYSFS_PATH_MAX];
0165 unsigned pcidomain, pcibus, pcidev, pcifunc;
0166
0167 if (!hwloc_topology_is_thissystem(topology)) {
0168 errno = EINVAL;
0169 return -1;
0170 }
0171
0172 if (hwloc_opencl_get_device_pci_busid(device, &pcidomain, &pcibus, &pcidev, &pcifunc) < 0) {
0173 hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
0174 return 0;
0175 }
0176
0177 sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/local_cpus", pcidomain, pcibus, pcidev, pcifunc);
0178 if (hwloc_linux_read_path_as_cpumask(path, set) < 0
0179 || hwloc_bitmap_iszero(set))
0180 hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
0181 #else
0182
0183 hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
0184 #endif
0185 return 0;
0186 }
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203 static __hwloc_inline hwloc_obj_t
0204 hwloc_opencl_get_device_osdev_by_index(hwloc_topology_t topology,
0205 unsigned platform_index, unsigned device_index)
0206 {
0207 unsigned x = (unsigned) -1, y = (unsigned) -1;
0208 hwloc_obj_t osdev = NULL;
0209 while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
0210 if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type
0211 && osdev->name
0212 && sscanf(osdev->name, "opencl%ud%u", &x, &y) == 2
0213 && platform_index == x && device_index == y)
0214 return osdev;
0215 }
0216 return NULL;
0217 }
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240 static __hwloc_inline hwloc_obj_t
0241 hwloc_opencl_get_device_osdev(hwloc_topology_t topology __hwloc_attribute_unused,
0242 cl_device_id device __hwloc_attribute_unused)
0243 {
0244 hwloc_obj_t osdev;
0245 unsigned pcidomain, pcibus, pcidevice, pcifunc;
0246
0247 if (hwloc_opencl_get_device_pci_busid(device, &pcidomain, &pcibus, &pcidevice, &pcifunc) < 0) {
0248 errno = EINVAL;
0249 return NULL;
0250 }
0251
0252 osdev = NULL;
0253 while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
0254 hwloc_obj_t pcidev = osdev->parent;
0255 if (strncmp(osdev->name, "opencl", 6))
0256 continue;
0257 if (pcidev
0258 && pcidev->type == HWLOC_OBJ_PCI_DEVICE
0259 && pcidev->attr->pcidev.domain == pcidomain
0260 && pcidev->attr->pcidev.bus == pcibus
0261 && pcidev->attr->pcidev.dev == pcidevice
0262 && pcidev->attr->pcidev.func == pcifunc)
0263 return osdev;
0264
0265 }
0266
0267 return NULL;
0268 }
0269
0270
0271
0272
0273 #ifdef __cplusplus
0274 }
0275 #endif
0276
0277
0278 #endif