Hardware Locality (hwloc)
v2.2-20200408.0300.gitad4a86f
|
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_CUDART_H 00017 #define HWLOC_CUDART_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> /* for CUDA_VERSION */ 00027 #include <cuda_runtime_api.h> 00028 00029 00030 #ifdef __cplusplus 00031 extern "C" { 00032 #endif 00033 00034 00047 static __hwloc_inline int 00048 hwloc_cudart_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unused, 00049 int idx, int *domain, int *bus, int *dev) 00050 { 00051 cudaError_t cerr; 00052 struct cudaDeviceProp prop; 00053 00054 cerr = cudaGetDeviceProperties(&prop, idx); 00055 if (cerr) { 00056 errno = ENOSYS; 00057 return -1; 00058 } 00059 00060 #if CUDA_VERSION >= 4000 00061 *domain = prop.pciDomainID; 00062 #else 00063 *domain = 0; 00064 #endif 00065 00066 *bus = prop.pciBusID; 00067 *dev = prop.pciDeviceID; 00068 00069 return 0; 00070 } 00071 00088 static __hwloc_inline int 00089 hwloc_cudart_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused, 00090 int idx, hwloc_cpuset_t set) 00091 { 00092 #ifdef HWLOC_LINUX_SYS 00093 /* If we're on Linux, use the sysfs mechanism to get the local cpus */ 00094 #define HWLOC_CUDART_DEVICE_SYSFS_PATH_MAX 128 00095 char path[HWLOC_CUDART_DEVICE_SYSFS_PATH_MAX]; 00096 int domain, bus, dev; 00097 00098 if (hwloc_cudart_get_device_pci_ids(topology, idx, &domain, &bus, &dev)) 00099 return -1; 00100 00101 if (!hwloc_topology_is_thissystem(topology)) { 00102 errno = EINVAL; 00103 return -1; 00104 } 00105 00106 sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus", (unsigned) domain, (unsigned) bus, (unsigned) dev); 00107 if (hwloc_linux_read_path_as_cpumask(path, set) < 0 00108 || hwloc_bitmap_iszero(set)) 00109 hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology)); 00110 #else 00111 /* Non-Linux systems simply get a full cpuset */ 00112 hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology)); 00113 #endif 00114 return 0; 00115 } 00116 00127 static __hwloc_inline hwloc_obj_t 00128 hwloc_cudart_get_device_pcidev(hwloc_topology_t topology, int idx) 00129 { 00130 int domain, bus, dev; 00131 00132 if (hwloc_cudart_get_device_pci_ids(topology, idx, &domain, &bus, &dev)) 00133 return NULL; 00134 00135 return hwloc_get_pcidev_by_busid(topology, domain, bus, dev, 0); 00136 } 00137 00155 static __hwloc_inline hwloc_obj_t 00156 hwloc_cudart_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx) 00157 { 00158 hwloc_obj_t osdev = NULL; 00159 while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) { 00160 if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type 00161 && osdev->name 00162 && !strncmp("cuda", osdev->name, 4) 00163 && atoi(osdev->name + 4) == (int) idx) 00164 return osdev; 00165 } 00166 return NULL; 00167 } 00168 00172 #ifdef __cplusplus 00173 } /* extern "C" */ 00174 #endif 00175 00176 00177 #endif /* HWLOC_CUDART_H */