Hardware Locality (hwloc)
v2.0-20191027.0400.gite37e7d8
|
00001 /* 00002 * Copyright © 2010-2017 Inria. All rights reserved. 00003 * Copyright © 2010-2011 Université Bordeaux 00004 * Copyright © 2011 Cisco Systems, Inc. All rights reserved. 00005 * See COPYING in top-level directory. 00006 */ 00007 00016 #ifndef HWLOC_CUDA_H 00017 #define HWLOC_CUDA_H 00018 00019 #include <hwloc.h> 00020 #include <hwloc/autogen/config.h> 00021 #include <hwloc/helper.h> 00022 #ifdef HWLOC_LINUX_SYS 00023 #include <hwloc/linux.h> 00024 #endif 00025 00026 #include <cuda.h> 00027 00028 00029 #ifdef __cplusplus 00030 extern "C" { 00031 #endif 00032 00033 00046 static __hwloc_inline int 00047 hwloc_cuda_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unused, 00048 CUdevice cudevice, int *domain, int *bus, int *dev) 00049 { 00050 CUresult cres; 00051 00052 #if CUDA_VERSION >= 4000 00053 cres = cuDeviceGetAttribute(domain, CU_DEVICE_ATTRIBUTE_PCI_DOMAIN_ID, cudevice); 00054 if (cres != CUDA_SUCCESS) { 00055 errno = ENOSYS; 00056 return -1; 00057 } 00058 #else 00059 *domain = 0; 00060 #endif 00061 cres = cuDeviceGetAttribute(bus, CU_DEVICE_ATTRIBUTE_PCI_BUS_ID, cudevice); 00062 if (cres != CUDA_SUCCESS) { 00063 errno = ENOSYS; 00064 return -1; 00065 } 00066 cres = cuDeviceGetAttribute(dev, CU_DEVICE_ATTRIBUTE_PCI_DEVICE_ID, cudevice); 00067 if (cres != CUDA_SUCCESS) { 00068 errno = ENOSYS; 00069 return -1; 00070 } 00071 00072 return 0; 00073 } 00074 00091 static __hwloc_inline int 00092 hwloc_cuda_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused, 00093 CUdevice cudevice, hwloc_cpuset_t set) 00094 { 00095 #ifdef HWLOC_LINUX_SYS 00096 /* If we're on Linux, use the sysfs mechanism to get the local cpus */ 00097 #define HWLOC_CUDA_DEVICE_SYSFS_PATH_MAX 128 00098 char path[HWLOC_CUDA_DEVICE_SYSFS_PATH_MAX]; 00099 int domainid, busid, deviceid; 00100 00101 if (hwloc_cuda_get_device_pci_ids(topology, cudevice, &domainid, &busid, &deviceid)) 00102 return -1; 00103 00104 if (!hwloc_topology_is_thissystem(topology)) { 00105 errno = EINVAL; 00106 return -1; 00107 } 00108 00109 sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus", domainid, busid, deviceid); 00110 if (hwloc_linux_read_path_as_cpumask(path, set) < 0 00111 || hwloc_bitmap_iszero(set)) 00112 hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology)); 00113 #else 00114 /* Non-Linux systems simply get a full cpuset */ 00115 hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology)); 00116 #endif 00117 return 0; 00118 } 00119 00130 static __hwloc_inline hwloc_obj_t 00131 hwloc_cuda_get_device_pcidev(hwloc_topology_t topology, CUdevice cudevice) 00132 { 00133 int domain, bus, dev; 00134 00135 if (hwloc_cuda_get_device_pci_ids(topology, cudevice, &domain, &bus, &dev)) 00136 return NULL; 00137 00138 return hwloc_get_pcidev_by_busid(topology, domain, bus, dev, 0); 00139 } 00140 00156 static __hwloc_inline hwloc_obj_t 00157 hwloc_cuda_get_device_osdev(hwloc_topology_t topology, CUdevice cudevice) 00158 { 00159 hwloc_obj_t osdev = NULL; 00160 int domain, bus, dev; 00161 00162 if (hwloc_cuda_get_device_pci_ids(topology, cudevice, &domain, &bus, &dev)) 00163 return NULL; 00164 00165 osdev = NULL; 00166 while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) { 00167 hwloc_obj_t pcidev = osdev->parent; 00168 if (strncmp(osdev->name, "cuda", 4)) 00169 continue; 00170 if (pcidev 00171 && pcidev->type == HWLOC_OBJ_PCI_DEVICE 00172 && (int) pcidev->attr->pcidev.domain == domain 00173 && (int) pcidev->attr->pcidev.bus == bus 00174 && (int) pcidev->attr->pcidev.dev == dev 00175 && pcidev->attr->pcidev.func == 0) 00176 return osdev; 00177 /* if PCI are filtered out, we need a info attr to match on */ 00178 } 00179 00180 return NULL; 00181 } 00182 00198 static __hwloc_inline hwloc_obj_t 00199 hwloc_cuda_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx) 00200 { 00201 hwloc_obj_t osdev = NULL; 00202 while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) { 00203 if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type 00204 && osdev->name 00205 && !strncmp("cuda", osdev->name, 4) 00206 && atoi(osdev->name + 4) == (int) idx) 00207 return osdev; 00208 } 00209 return NULL; 00210 } 00211 00215 #ifdef __cplusplus 00216 } /* extern "C" */ 00217 #endif 00218 00219 00220 #endif /* HWLOC_CUDA_H */