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