root/opal/mca/hwloc/hwloc201/hwloc/include/hwloc/nvml.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. hwloc_nvml_get_device_cpuset
  2. hwloc_nvml_get_device_osdev_by_index
  3. hwloc_nvml_get_device_osdev

   1 /*
   2  * Copyright © 2012-2016 Inria.  All rights reserved.
   3  * See COPYING in top-level directory.
   4  */
   5 
   6 /** \file
   7  * \brief Macros to help interaction between hwloc and the NVIDIA Management Library.
   8  *
   9  * Applications that use both hwloc and the NVIDIA Management Library may want to
  10  * include this file so as to get topology information for NVML devices.
  11  */
  12 
  13 #ifndef HWLOC_NVML_H
  14 #define HWLOC_NVML_H
  15 
  16 #include <hwloc.h>
  17 #include <hwloc/autogen/config.h>
  18 #include <hwloc/helper.h>
  19 #ifdef HWLOC_LINUX_SYS
  20 #include <hwloc/linux.h>
  21 #endif
  22 
  23 #include <nvml.h>
  24 
  25 
  26 #ifdef __cplusplus
  27 extern "C" {
  28 #endif
  29 
  30 
  31 /** \defgroup hwlocality_nvml Interoperability with the NVIDIA Management Library
  32  *
  33  * This interface offers ways to retrieve topology information about
  34  * devices managed by the NVIDIA Management Library (NVML).
  35  *
  36  * @{
  37  */
  38 
  39 /** \brief Get the CPU set of logical processors that are physically
  40  * close to NVML device \p device.
  41  *
  42  * Return the CPU set describing the locality of the NVML device \p device.
  43  *
  44  * Topology \p topology and device \p device must match the local machine.
  45  * I/O devices detection and the NVML component are not needed in the topology.
  46  *
  47  * The function only returns the locality of the device.
  48  * If more information about the device is needed, OS objects should
  49  * be used instead, see hwloc_nvml_get_device_osdev()
  50  * and hwloc_nvml_get_device_osdev_by_index().
  51  *
  52  * This function is currently only implemented in a meaningful way for
  53  * Linux; other systems will simply get a full cpuset.
  54  */
  55 static __hwloc_inline int
  56 hwloc_nvml_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
  57                              nvmlDevice_t device, hwloc_cpuset_t set)
  58 {
  59 #ifdef HWLOC_LINUX_SYS
  60   /* If we're on Linux, use the sysfs mechanism to get the local cpus */
  61 #define HWLOC_NVML_DEVICE_SYSFS_PATH_MAX 128
  62   char path[HWLOC_NVML_DEVICE_SYSFS_PATH_MAX];
  63   nvmlReturn_t nvres;
  64   nvmlPciInfo_t pci;
  65 
  66   if (!hwloc_topology_is_thissystem(topology)) {
  67     errno = EINVAL;
  68     return -1;
  69   }
  70 
  71   nvres = nvmlDeviceGetPciInfo(device, &pci);
  72   if (NVML_SUCCESS != nvres) {
  73     errno = EINVAL;
  74     return -1;
  75   }
  76 
  77   sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus", pci.domain, pci.bus, pci.device);
  78   if (hwloc_linux_read_path_as_cpumask(path, set) < 0
  79       || hwloc_bitmap_iszero(set))
  80     hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
  81 #else
  82   /* Non-Linux systems simply get a full cpuset */
  83   hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
  84 #endif
  85   return 0;
  86 }
  87 
  88 /** \brief Get the hwloc OS device object corresponding to the
  89  * NVML device whose index is \p idx.
  90  *
  91  * Return the OS device object describing the NVML device whose
  92  * index is \p idx. Returns NULL if there is none.
  93  *
  94  * The topology \p topology does not necessarily have to match the current
  95  * machine. For instance the topology may be an XML import of a remote host.
  96  * I/O devices detection and the NVML component must be enabled in the topology.
  97  *
  98  * \note The corresponding PCI device object can be obtained by looking
  99  * at the OS device parent object (unless PCI devices are filtered out).
 100  */
 101 static __hwloc_inline hwloc_obj_t
 102 hwloc_nvml_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx)
 103 {
 104         hwloc_obj_t osdev = NULL;
 105         while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
 106                 if (HWLOC_OBJ_OSDEV_GPU == osdev->attr->osdev.type
 107                     && osdev->name
 108                     && !strncmp("nvml", osdev->name, 4)
 109                     && atoi(osdev->name + 4) == (int) idx)
 110                         return osdev;
 111         }
 112         return NULL;
 113 }
 114 
 115 /** \brief Get the hwloc OS device object corresponding to NVML device \p device.
 116  *
 117  * Return the hwloc OS device object that describes the given
 118  * NVML device \p device. Return NULL if there is none.
 119  *
 120  * Topology \p topology and device \p device must match the local machine.
 121  * I/O devices detection and the NVML component must be enabled in the topology.
 122  * If not, the locality of the object may still be found using
 123  * hwloc_nvml_get_device_cpuset().
 124  *
 125  * \note The corresponding hwloc PCI device may be found by looking
 126  * at the result parent pointer (unless PCI devices are filtered out).
 127  */
 128 static __hwloc_inline hwloc_obj_t
 129 hwloc_nvml_get_device_osdev(hwloc_topology_t topology, nvmlDevice_t device)
 130 {
 131         hwloc_obj_t osdev;
 132         nvmlReturn_t nvres;
 133         nvmlPciInfo_t pci;
 134         char uuid[64];
 135 
 136         if (!hwloc_topology_is_thissystem(topology)) {
 137                 errno = EINVAL;
 138                 return NULL;
 139         }
 140 
 141         nvres = nvmlDeviceGetPciInfo(device, &pci);
 142         if (NVML_SUCCESS != nvres)
 143                 return NULL;
 144 
 145         nvres = nvmlDeviceGetUUID(device, uuid, sizeof(uuid));
 146         if (NVML_SUCCESS != nvres)
 147                 uuid[0] = '\0';
 148 
 149         osdev = NULL;
 150         while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
 151                 hwloc_obj_t pcidev = osdev->parent;
 152                 const char *info;
 153 
 154                 if (strncmp(osdev->name, "nvml", 4))
 155                         continue;
 156 
 157                 if (pcidev
 158                     && pcidev->type == HWLOC_OBJ_PCI_DEVICE
 159                     && pcidev->attr->pcidev.domain == pci.domain
 160                     && pcidev->attr->pcidev.bus == pci.bus
 161                     && pcidev->attr->pcidev.dev == pci.device
 162                     && pcidev->attr->pcidev.func == 0)
 163                         return osdev;
 164 
 165                 info = hwloc_obj_get_info_by_name(osdev, "NVIDIAUUID");
 166                 if (info && !strcmp(info, uuid))
 167                         return osdev;
 168         }
 169 
 170         return NULL;
 171 }
 172 
 173 /** @} */
 174 
 175 
 176 #ifdef __cplusplus
 177 } /* extern "C" */
 178 #endif
 179 
 180 
 181 #endif /* HWLOC_NVML_H */

/* [<][>][^][v][top][bottom][index][help] */