Hardware Locality (hwloc)  v2.0-20191027.0400.gite37e7d8
cudart.h
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 */