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