Hardware Locality (hwloc)  v2.2-20200401.0300.gitd2f52ab
nvml.h
00001 /*
00002  * Copyright © 2012-2016 Inria.  All rights reserved.
00003  * See COPYING in top-level directory.
00004  */
00005 
00013 #ifndef HWLOC_NVML_H
00014 #define HWLOC_NVML_H
00015 
00016 #include "hwloc.h"
00017 #include "hwloc/autogen/config.h"
00018 #include "hwloc/helper.h"
00019 #ifdef HWLOC_LINUX_SYS
00020 #include "hwloc/linux.h"
00021 #endif
00022 
00023 #include <nvml.h>
00024 
00025 
00026 #ifdef __cplusplus
00027 extern "C" {
00028 #endif
00029 
00030 
00055 static __hwloc_inline int
00056 hwloc_nvml_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
00057                              nvmlDevice_t device, hwloc_cpuset_t set)
00058 {
00059 #ifdef HWLOC_LINUX_SYS
00060   /* If we're on Linux, use the sysfs mechanism to get the local cpus */
00061 #define HWLOC_NVML_DEVICE_SYSFS_PATH_MAX 128
00062   char path[HWLOC_NVML_DEVICE_SYSFS_PATH_MAX];
00063   nvmlReturn_t nvres;
00064   nvmlPciInfo_t pci;
00065 
00066   if (!hwloc_topology_is_thissystem(topology)) {
00067     errno = EINVAL;
00068     return -1;
00069   }
00070 
00071   nvres = nvmlDeviceGetPciInfo(device, &pci);
00072   if (NVML_SUCCESS != nvres) {
00073     errno = EINVAL;
00074     return -1;
00075   }
00076 
00077   sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus", pci.domain, pci.bus, pci.device);
00078   if (hwloc_linux_read_path_as_cpumask(path, set) < 0
00079       || hwloc_bitmap_iszero(set))
00080     hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
00081 #else
00082   /* Non-Linux systems simply get a full cpuset */
00083   hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
00084 #endif
00085   return 0;
00086 }
00087 
00101 static __hwloc_inline hwloc_obj_t
00102 hwloc_nvml_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx)
00103 {
00104         hwloc_obj_t osdev = NULL;
00105         while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
00106                 if (HWLOC_OBJ_OSDEV_GPU == osdev->attr->osdev.type
00107                     && osdev->name
00108                     && !strncmp("nvml", osdev->name, 4)
00109                     && atoi(osdev->name + 4) == (int) idx)
00110                         return osdev;
00111         }
00112         return NULL;
00113 }
00114 
00128 static __hwloc_inline hwloc_obj_t
00129 hwloc_nvml_get_device_osdev(hwloc_topology_t topology, nvmlDevice_t device)
00130 {
00131         hwloc_obj_t osdev;
00132         nvmlReturn_t nvres;
00133         nvmlPciInfo_t pci;
00134         char uuid[64];
00135 
00136         if (!hwloc_topology_is_thissystem(topology)) {
00137                 errno = EINVAL;
00138                 return NULL;
00139         }
00140 
00141         nvres = nvmlDeviceGetPciInfo(device, &pci);
00142         if (NVML_SUCCESS != nvres)
00143                 return NULL;
00144 
00145         nvres = nvmlDeviceGetUUID(device, uuid, sizeof(uuid));
00146         if (NVML_SUCCESS != nvres)
00147                 uuid[0] = '\0';
00148 
00149         osdev = NULL;
00150         while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
00151                 hwloc_obj_t pcidev = osdev->parent;
00152                 const char *info;
00153 
00154                 if (strncmp(osdev->name, "nvml", 4))
00155                         continue;
00156 
00157                 if (pcidev
00158                     && pcidev->type == HWLOC_OBJ_PCI_DEVICE
00159                     && pcidev->attr->pcidev.domain == pci.domain
00160                     && pcidev->attr->pcidev.bus == pci.bus
00161                     && pcidev->attr->pcidev.dev == pci.device
00162                     && pcidev->attr->pcidev.func == 0)
00163                         return osdev;
00164 
00165                 info = hwloc_obj_get_info_by_name(osdev, "NVIDIAUUID");
00166                 if (info && !strcmp(info, uuid))
00167                         return osdev;
00168         }
00169 
00170         return NULL;
00171 }
00172 
00176 #ifdef __cplusplus
00177 } /* extern "C" */
00178 #endif
00179 
00180 
00181 #endif /* HWLOC_NVML_H */