Open MPI logo

Portable Hardware Locality (hwloc) Documentation: v1.7

  |   Home   |   Support   |   FAQ   |  
cuda.h
1 /*
2  * Copyright © 2010-2013 Inria. All rights reserved.
3  * Copyright © 2010-2011 Université Bordeaux 1
4  * Copyright © 2011 Cisco Systems, Inc. All rights reserved.
5  * See COPYING in top-level directory.
6  */
7 
16 #ifndef HWLOC_CUDA_H
17 #define HWLOC_CUDA_H
18 
19 #include <hwloc.h>
20 #include <hwloc/autogen/config.h>
21 #include <hwloc/helper.h>
22 #ifdef HWLOC_LINUX_SYS
23 #include <hwloc/linux.h>
24 #endif
25 
26 #include <cuda.h>
27 
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 
33 
42 static inline int
44  CUdevice cudevice, int *domain, int *bus, int *dev)
45 {
46  CUresult cres;
47 
48 #ifdef CU_DEVICE_ATTRIBUTE_PCI_DOMAIN_ID
49  cres = cuDeviceGetAttribute(domain, CU_DEVICE_ATTRIBUTE_PCI_DOMAIN_ID, cudevice);
50  if (cres != CUDA_SUCCESS) {
51  errno = ENOSYS;
52  return -1;
53  }
54 #else
55  *domain = 0;
56 #endif
57  cres = cuDeviceGetAttribute(bus, CU_DEVICE_ATTRIBUTE_PCI_BUS_ID, cudevice);
58  if (cres != CUDA_SUCCESS) {
59  errno = ENOSYS;
60  return -1;
61  }
62  cres = cuDeviceGetAttribute(dev, CU_DEVICE_ATTRIBUTE_PCI_DEVICE_ID, cudevice);
63  if (cres != CUDA_SUCCESS) {
64  errno = ENOSYS;
65  return -1;
66  }
67 
68  return 0;
69 }
70 
87 static inline int
89  CUdevice cudevice, hwloc_cpuset_t set)
90 {
91 #ifdef HWLOC_LINUX_SYS
92  /* If we're on Linux, use the sysfs mechanism to get the local cpus */
93 #define HWLOC_CUDA_DEVICE_SYSFS_PATH_MAX 128
94  char path[HWLOC_CUDA_DEVICE_SYSFS_PATH_MAX];
95  FILE *sysfile = NULL;
96  int domainid, busid, deviceid;
97 
98  if (hwloc_cuda_get_device_pci_ids(topology, cudevice, &domainid, &busid, &deviceid))
99  return -1;
100 
101  if (!hwloc_topology_is_thissystem(topology)) {
102  errno = EINVAL;
103  return -1;
104  }
105 
106  sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus", domainid, busid, deviceid);
107  sysfile = fopen(path, "r");
108  if (!sysfile)
109  return -1;
110 
111  hwloc_linux_parse_cpumap_file(sysfile, set);
112  if (hwloc_bitmap_iszero(set))
114 
115  fclose(sysfile);
116 #else
117  /* Non-Linux systems simply get a full cpuset */
119 #endif
120  return 0;
121 }
122 
133 static inline hwloc_obj_t
134 hwloc_cuda_get_device_pcidev(hwloc_topology_t topology, CUdevice cudevice)
135 {
136  int domain, bus, dev;
137 
138  if (hwloc_cuda_get_device_pci_ids(topology, cudevice, &domain, &bus, &dev))
139  return NULL;
140 
141  return hwloc_get_pcidev_by_busid(topology, domain, bus, dev, 0);
142 }
143 
157 static inline hwloc_obj_t
158 hwloc_cuda_get_device_osdev(hwloc_topology_t topology, CUdevice cudevice)
159 {
160  hwloc_obj_t osdev = NULL;
161  int domain, bus, dev;
162 
163  if (hwloc_cuda_get_device_pci_ids(topology, cudevice, &domain, &bus, &dev))
164  return NULL;
165 
166  osdev = NULL;
167  while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
168  hwloc_obj_t pcidev = osdev->parent;
169  if (strncmp(osdev->name, "cuda", 4))
170  continue;
171  if (pcidev
172  && pcidev->type == HWLOC_OBJ_PCI_DEVICE
173  && (int) pcidev->attr->pcidev.domain == domain
174  && (int) pcidev->attr->pcidev.bus == bus
175  && (int) pcidev->attr->pcidev.dev == dev
176  && pcidev->attr->pcidev.func == 0)
177  return osdev;
178  }
179 
180  return NULL;
181 }
182 
198 static inline hwloc_obj_t
200 {
201  hwloc_obj_t osdev = NULL;
202  while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
203  if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type
204  && osdev->name
205  && !strncmp("cuda", osdev->name, 4)
206  && atoi(osdev->name + 4) == (int) idx)
207  return osdev;
208  }
209  return NULL;
210 }
211 
215 #ifdef __cplusplus
216 } /* extern "C" */
217 #endif
218 
219 
220 #endif /* HWLOC_CUDA_H */