File indexing completed on 2026-09-16 09:13:58
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef HWLOC_CUDA_H
0018 #define HWLOC_CUDA_H
0019
0020 #include "hwloc.h"
0021 #include "hwloc/autogen/config.h"
0022 #include "hwloc/helper.h"
0023 #ifdef HWLOC_LINUX_SYS
0024 #include "hwloc/linux.h"
0025 #endif
0026
0027 #include <cuda.h>
0028
0029
0030 #ifdef __cplusplus
0031 extern "C" {
0032 #endif
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 static __hwloc_inline int
0051 hwloc_cuda_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unused,
0052 CUdevice cudevice, int *domain, int *bus, int *dev)
0053 {
0054 CUresult cres;
0055
0056 #if CUDA_VERSION >= 4000
0057 cres = cuDeviceGetAttribute(domain, CU_DEVICE_ATTRIBUTE_PCI_DOMAIN_ID, cudevice);
0058 if (cres != CUDA_SUCCESS) {
0059 errno = ENOSYS;
0060 return -1;
0061 }
0062 #else
0063 *domain = 0;
0064 #endif
0065 cres = cuDeviceGetAttribute(bus, CU_DEVICE_ATTRIBUTE_PCI_BUS_ID, cudevice);
0066 if (cres != CUDA_SUCCESS) {
0067 errno = ENOSYS;
0068 return -1;
0069 }
0070 cres = cuDeviceGetAttribute(dev, CU_DEVICE_ATTRIBUTE_PCI_DEVICE_ID, cudevice);
0071 if (cres != CUDA_SUCCESS) {
0072 errno = ENOSYS;
0073 return -1;
0074 }
0075
0076 return 0;
0077 }
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098 static __hwloc_inline int
0099 hwloc_cuda_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
0100 CUdevice cudevice, hwloc_cpuset_t set)
0101 {
0102 #ifdef HWLOC_LINUX_SYS
0103
0104 #define HWLOC_CUDA_DEVICE_SYSFS_PATH_MAX 128
0105 char path[HWLOC_CUDA_DEVICE_SYSFS_PATH_MAX];
0106 int domainid, busid, deviceid;
0107
0108 if (hwloc_cuda_get_device_pci_ids(topology, cudevice, &domainid, &busid, &deviceid))
0109 return -1;
0110
0111 if (!hwloc_topology_is_thissystem(topology)) {
0112 errno = EINVAL;
0113 return -1;
0114 }
0115
0116 sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus", domainid, busid, deviceid);
0117 if (hwloc_linux_read_path_as_cpumask(path, set) < 0
0118 || hwloc_bitmap_iszero(set))
0119 hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
0120 #else
0121
0122 hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
0123 #endif
0124 return 0;
0125 }
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137 static __hwloc_inline hwloc_obj_t
0138 hwloc_cuda_get_device_pcidev(hwloc_topology_t topology, CUdevice cudevice)
0139 {
0140 int domain, bus, dev;
0141
0142 if (hwloc_cuda_get_device_pci_ids(topology, cudevice, &domain, &bus, &dev))
0143 return NULL;
0144
0145 return hwloc_get_pcidev_by_busid(topology, domain, bus, dev, 0);
0146 }
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163 static __hwloc_inline hwloc_obj_t
0164 hwloc_cuda_get_device_osdev(hwloc_topology_t topology, CUdevice cudevice)
0165 {
0166 hwloc_obj_t osdev = NULL;
0167 int domain, bus, dev;
0168
0169 if (hwloc_cuda_get_device_pci_ids(topology, cudevice, &domain, &bus, &dev))
0170 return NULL;
0171
0172 osdev = NULL;
0173 while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
0174 hwloc_obj_t pcidev = osdev->parent;
0175 if (strncmp(osdev->name, "cuda", 4))
0176 continue;
0177 if (pcidev
0178 && pcidev->type == HWLOC_OBJ_PCI_DEVICE
0179 && (int) pcidev->attr->pcidev.domain == domain
0180 && (int) pcidev->attr->pcidev.bus == bus
0181 && (int) pcidev->attr->pcidev.dev == dev
0182 && pcidev->attr->pcidev.func == 0)
0183 return osdev;
0184
0185 }
0186
0187 return NULL;
0188 }
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205 static __hwloc_inline hwloc_obj_t
0206 hwloc_cuda_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx)
0207 {
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 && !strncmp("cuda", osdev->name, 4)
0213 && atoi(osdev->name + 4) == (int) idx)
0214 return osdev;
0215 }
0216 return NULL;
0217 }
0218
0219
0220
0221
0222 #ifdef __cplusplus
0223 }
0224 #endif
0225
0226
0227 #endif