1 /*
2 * Copyright © 2012 Blue Brain Project, BBP/EPFL. All rights reserved.
3 * Copyright © 2012-2015 Inria. All rights reserved.
4 * See COPYING in top-level directory.
5 */
6
7 #include "hwloc.h"
8 #include "hwloc/gl.h"
9 #include "hwloc/helper.h"
10
11 #include <errno.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include "stdlib.h"
15
main(void)16 int main(void)
17 {
18 hwloc_topology_t topology;
19 hwloc_obj_t pcidev, osdev, parent;
20 hwloc_obj_t firstgpu = NULL, lastgpu = NULL;
21 unsigned port, device;
22 char* cpuset_string;
23 unsigned nr_pcidev;
24 unsigned nr_osdev;
25 unsigned nr_gpus;
26 unsigned i;
27 int err;
28
29 hwloc_topology_init(&topology); /* Topology initialization */
30
31 /* Flags used for loading the I/O devices, bridges and their relevant info */
32 hwloc_topology_set_io_types_filter(topology, HWLOC_TYPE_FILTER_KEEP_IMPORTANT);
33
34 /* Perform topology detection */
35 hwloc_topology_load(topology);
36
37 /* Case 1: Get the cpusets of the packages connecting the PCI devices in the topology */
38 nr_pcidev = hwloc_get_nbobjs_by_type(topology, HWLOC_OBJ_PCI_DEVICE);
39 for (i = 0; i < nr_pcidev; ++i) {
40 pcidev = hwloc_get_obj_by_type(topology, HWLOC_OBJ_PCI_DEVICE, i);
41 parent = hwloc_get_non_io_ancestor_obj(topology, pcidev);
42 /* Print the cpuset corresponding to each pci device */
43 hwloc_bitmap_asprintf(&cpuset_string, parent->cpuset);
44 printf(" %s | %s \n", cpuset_string, pcidev->name);
45 free(cpuset_string);
46 }
47
48 /* Case 2: Get the number of connected GPUs in the topology and their attached displays */
49 nr_gpus = 0;
50 nr_osdev = hwloc_get_nbobjs_by_type(topology, HWLOC_OBJ_OS_DEVICE);
51 for (i = 0; i < nr_osdev; ++i) {
52 const char *model, *backend;
53 osdev = hwloc_get_obj_by_type(topology, HWLOC_OBJ_OS_DEVICE, i);
54
55 backend = hwloc_obj_get_info_by_name(osdev, "Backend");
56 model = hwloc_obj_get_info_by_name(osdev, "GPUModel");
57
58 err = hwloc_gl_get_display_by_osdev(topology, osdev, &port, &device);
59 if (!err) {
60 err = strcmp(backend, "GL");
61 assert(!err);
62
63 assert(osdev->attr->osdev.type == HWLOC_OBJ_OSDEV_GPU);
64
65 if (!firstgpu)
66 firstgpu = osdev;
67 lastgpu = osdev;
68 printf("GPU #%u (%s) is connected to DISPLAY:%u.%u \n", nr_gpus, model, port, device);
69 nr_gpus++;
70 } else {
71 if (backend) {
72 err = strcmp(backend, "GL");
73 assert(err);
74 }
75 }
76 }
77
78 /* Case 3: Get the first GPU connected to a valid display, specified by its port and device */
79 if (firstgpu) {
80 assert(sscanf(firstgpu->name, ":%u.%u", &port, &device) == 2);
81 osdev = hwloc_gl_get_display_osdev_by_port_device(topology, port, device);
82 assert(osdev == firstgpu);
83 pcidev = osdev->parent;
84 parent = hwloc_get_non_io_ancestor_obj(topology, pcidev);
85 hwloc_bitmap_asprintf(&cpuset_string, parent->cpuset);
86 printf("GPU %s (PCI %04x:%02x:%02x.%01x) is connected to DISPLAY:%u.%u close to %s\n",
87 osdev->name,
88 pcidev->attr->pcidev.domain, pcidev->attr->pcidev.bus, pcidev->attr->pcidev.dev, pcidev->attr->pcidev.func,
89 port, device, cpuset_string);
90 free(cpuset_string);
91 }
92
93 /* Case 4: Get the last GPU connected to a valid display, specified by its name */
94 if (lastgpu) {
95 assert(sscanf(lastgpu->name, ":%u.%u", &port, &device) == 2);
96 osdev = hwloc_gl_get_display_osdev_by_name(topology, lastgpu->name);
97 assert(osdev == lastgpu);
98 pcidev = osdev->parent;
99 parent = hwloc_get_non_io_ancestor_obj(topology, pcidev);
100 hwloc_bitmap_asprintf(&cpuset_string, parent->cpuset);
101 printf("GPU %s (PCI %04x:%02x:%02x.%01x) is connected to DISPLAY:%u.%u close to %s\n",
102 osdev->name,
103 pcidev->attr->pcidev.domain, pcidev->attr->pcidev.bus, pcidev->attr->pcidev.dev, pcidev->attr->pcidev.func,
104 port, device, cpuset_string);
105 free(cpuset_string);
106 }
107
108 return 0;
109 }
110