Open MPI logo

Portable Hardware Locality (hwloc) Documentation: v1.7.2

  |   Home   |   Support   |   FAQ   |  
cudart.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_CUDART_H
17 #define HWLOC_CUDART_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_runtime_api.h>
27 
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 
33 
42 static __hwloc_inline int
43 hwloc_cudart_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unused,
44  int idx, int *domain, int *bus, int *dev)
45 {
46  cudaError_t cerr;
47  struct cudaDeviceProp prop;
48 
49  cerr = cudaGetDeviceProperties(&prop, idx);
50  if (cerr) {
51  errno = ENOSYS;
52  return -1;
53  }
54 
55 #ifdef CU_DEVICE_ATTRIBUTE_PCI_DOMAIN_ID
56  *domain = prop.pciDomainID;
57 #else
58  *domain = 0;
59 #endif
60 
61  *bus = prop.pciBusID;
62  *dev = prop.pciDeviceID;
63 
64  return 0;
65 }
66 
83 static __hwloc_inline int
84 hwloc_cudart_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
85  int idx, hwloc_cpuset_t set)
86 {
87 #ifdef HWLOC_LINUX_SYS
88  /* If we're on Linux, use the sysfs mechanism to get the local cpus */
89 #define HWLOC_CUDART_DEVICE_SYSFS_PATH_MAX 128
90  char path[HWLOC_CUDART_DEVICE_SYSFS_PATH_MAX];
91  FILE *sysfile = NULL;
92  int domain, bus, dev;
93 
94  if (hwloc_cudart_get_device_pci_ids(topology, idx, &domain, &bus, &dev))
95  return -1;
96 
97  if (!hwloc_topology_is_thissystem(topology)) {
98  errno = EINVAL;
99  return -1;
100  }
101 
102  sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus", domain, bus, dev);
103  sysfile = fopen(path, "r");
104  if (!sysfile)
105  return -1;
106 
107  hwloc_linux_parse_cpumap_file(sysfile, set);
108  if (hwloc_bitmap_iszero(set))
110 
111  fclose(sysfile);
112 #else
113  /* Non-Linux systems simply get a full cpuset */
115 #endif
116  return 0;
117 }
118 
129 static __hwloc_inline hwloc_obj_t
131 {
132  int domain, bus, dev;
133 
134  if (hwloc_cudart_get_device_pci_ids(topology, idx, &domain, &bus, &dev))
135  return NULL;
136 
137  return hwloc_get_pcidev_by_busid(topology, domain, bus, dev, 0);
138 }
139 
157 static __hwloc_inline hwloc_obj_t
159 {
160  hwloc_obj_t osdev = NULL;
161  while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
162  if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type
163  && osdev->name
164  && !strncmp("cuda", osdev->name, 4)
165  && atoi(osdev->name + 4) == (int) idx)
166  return osdev;
167  }
168  return NULL;
169 }
170 
174 #ifdef __cplusplus
175 } /* extern "C" */
176 #endif
177 
178 
179 #endif /* HWLOC_CUDART_H */