Open MPI logo

Portable Hardware Locality (hwloc) Documentation: v1.7.1

  |   Home   |   Support   |   FAQ   |  
nvml.h
1 /*
2  * Copyright © 2012-2013 Inria. All rights reserved.
3  * See COPYING in top-level directory.
4  */
5 
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 
51 static inline int
53  nvmlDevice_t device, hwloc_cpuset_t set)
54 {
55 #ifdef HWLOC_LINUX_SYS
56  /* If we're on Linux, use the sysfs mechanism to get the local cpus */
57 #define HWLOC_NVML_DEVICE_SYSFS_PATH_MAX 128
58  char path[HWLOC_NVML_DEVICE_SYSFS_PATH_MAX];
59  FILE *sysfile = NULL;
60  nvmlReturn_t nvres;
61  nvmlPciInfo_t pci;
62 
63  if (!hwloc_topology_is_thissystem(topology)) {
64  errno = EINVAL;
65  return -1;
66  }
67 
68  nvres = nvmlDeviceGetPciInfo(device, &pci);
69  if (NVML_SUCCESS != nvres) {
70  errno = EINVAL;
71  return -1;
72  }
73 
74  sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus", pci.domain, pci.bus, pci.device);
75  sysfile = fopen(path, "r");
76  if (!sysfile)
77  return -1;
78 
79  hwloc_linux_parse_cpumap_file(sysfile, set);
80  if (hwloc_bitmap_iszero(set))
82 
83  fclose(sysfile);
84 #else
85  /* Non-Linux systems simply get a full cpuset */
87 #endif
88  return 0;
89 }
90 
104 static inline hwloc_obj_t
106 {
107  hwloc_obj_t osdev = NULL;
108  while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
109  if (HWLOC_OBJ_OSDEV_GPU == osdev->attr->osdev.type
110  && osdev->name
111  && !strncmp("nvml", osdev->name, 4)
112  && atoi(osdev->name + 4) == (int) idx)
113  return osdev;
114  }
115  return NULL;
116 }
117 
131 static inline hwloc_obj_t
132 hwloc_nvml_get_device_osdev(hwloc_topology_t topology, nvmlDevice_t device)
133 {
134  hwloc_obj_t osdev;
135  nvmlReturn_t nvres;
136  nvmlPciInfo_t pci;
137 
138  if (!hwloc_topology_is_thissystem(topology)) {
139  errno = EINVAL;
140  return NULL;
141  }
142 
143  nvres = nvmlDeviceGetPciInfo(device, &pci);
144  if (NVML_SUCCESS != nvres)
145  return NULL;
146 
147  osdev = NULL;
148  while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
149  hwloc_obj_t pcidev = osdev->parent;
150  if (strncmp(osdev->name, "nvml", 4))
151  continue;
152  if (pcidev
153  && pcidev->type == HWLOC_OBJ_PCI_DEVICE
154  && pcidev->attr->pcidev.domain == pci.domain
155  && pcidev->attr->pcidev.bus == pci.bus
156  && pcidev->attr->pcidev.dev == pci.device
157  && pcidev->attr->pcidev.func == 0)
158  return osdev;
159  }
160 
161  return NULL;
162 }
163 
167 #ifdef __cplusplus
168 } /* extern "C" */
169 #endif
170 
171 
172 #endif /* HWLOC_NVML_H */