1 /*
2 * Copyright © 2009 CNRS
3 * Copyright © 2009-2019 Inria. All rights reserved.
4 * Copyright © 2009-2012 Université Bordeaux
5 * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
6 * See COPYING in top-level directory.
7 */
8
9 #include <private/autogen/config.h>
10 #include <hwloc.h>
11
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <string.h>
15 #include <fcntl.h>
16 #include <assert.h>
17
18 #include "misc.h"
19 #include "hwloc-calc.h"
20
21 static int pid_number = -1;
22 static hwloc_pid_t pid;
23 static int verbose_mode = 0;
24 static int logical = 1;
25 static int show_ancestors = 0;
26 static hwloc_obj_type_t show_ancestor_type = (hwloc_obj_type_t) -1;
27 static int show_ancestor_attrdepth = -1;
28 static hwloc_obj_cache_type_t show_ancestor_attrcachetype = (hwloc_obj_cache_type_t) -1;
29 static int show_children = 0;
30 static int show_descendants_depth = HWLOC_TYPE_DEPTH_UNKNOWN;
31 static int show_index_prefix = 0;
32 static unsigned current_obj;
33
usage(const char * name,FILE * where)34 void usage(const char *name, FILE *where)
35 {
36 fprintf (where, "Usage: %s [ options ] [ locations ]\n", name);
37 fprintf (where, "\nOutput options:\n");
38 fprintf (where, " --objects Report information about specific objects\n");
39 fprintf (where, " --topology Report information the topology\n");
40 fprintf (where, " --support Report information about supported features\n");
41 fprintf (where, " -v --verbose Include additional details\n");
42 fprintf (where, " -s --silent Reduce the amount of details to show\n");
43 fprintf (where, " --ancestors Display the chain of ancestor objects up to the root\n");
44 fprintf (where, " --ancestor <type> Only display the ancestor of the given type\n");
45 fprintf (where, " --children Display all children\n");
46 fprintf (where, " --descendants <type> Only display descendants of the given type\n");
47 fprintf (where, " -n Prefix each line with the index of the considered object\n");
48 fprintf (where, "Object filtering options:\n");
49 fprintf (where, " --restrict <cpuset> Restrict the topology to processors listed in <cpuset>\n");
50 fprintf (where, " --restrict binding Restrict the topology to the current process binding\n");
51 fprintf (where, " --no-icaches Do not show instruction caches\n");
52 fprintf (where, " --no-io Do not show any I/O device or bridge\n");
53 fprintf (where, " --no-bridges Do not any I/O bridge except hostbridges\n");
54 fprintf (where, " --whole-io Show all I/O devices and bridges\n");
55 fprintf (where, "Input options:\n");
56 hwloc_utils_input_format_usage(where, 6);
57 fprintf (where, " --thissystem Assume that the input topology provides the topology\n"
58 " for the system on which we are running\n");
59 fprintf (where, " --pid <pid> Detect topology as seen by process <pid>\n");
60 fprintf (where, " --whole-system Do not consider administration limitations\n");
61 fprintf (where, " -l --logical Use logical object indexes for input (default)\n");
62 fprintf (where, " -p --physical Use physical object indexes for input\n");
63 fprintf (where, "Miscellaneous options:\n");
64 fprintf (where, " --version Report version and exit\n");
65 }
66
67 static void
hwloc_info_show_obj(hwloc_obj_t obj,const char * type,const char * prefix,int verbose)68 hwloc_info_show_obj(hwloc_obj_t obj, const char *type, const char *prefix, int verbose)
69 {
70 char s[128];
71 unsigned i;
72 if (verbose < 0)
73 return;
74 printf("%s type = %s\n", prefix, hwloc_obj_type_string(obj->type));
75 printf("%s full type = %s\n", prefix, type);
76 printf("%s logical index = %u\n", prefix, obj->logical_index);
77 if (obj->os_index != (unsigned) -1)
78 printf("%s os index = %u\n", prefix, obj->os_index);
79 if (obj->name)
80 printf("%s name = %s\n", prefix, obj->name);
81 if (obj->depth != (unsigned) -1)
82 printf("%s depth = %d\n", prefix, (int) obj->depth); /* special levels have negative values */
83 printf("%s sibling rank = %u\n", prefix, obj->sibling_rank);
84 printf("%s children = %u\n", prefix, obj->arity);
85 if (obj->memory.local_memory)
86 printf("%s local memory = %llu\n", prefix, (unsigned long long) obj->memory.local_memory);
87 if (obj->memory.total_memory)
88 printf("%s total memory = %llu\n", prefix, (unsigned long long) obj->memory.total_memory);
89
90 if (obj->cpuset) {
91 hwloc_bitmap_snprintf(s, sizeof(s), obj->cpuset);
92 printf("%s cpuset = %s\n", prefix, s);
93 }
94 if (obj->complete_cpuset) {
95 hwloc_bitmap_snprintf(s, sizeof(s), obj->complete_cpuset);
96 printf("%s complete cpuset = %s\n", prefix, s);
97 }
98 if (obj->online_cpuset) {
99 hwloc_bitmap_snprintf(s, sizeof(s), obj->online_cpuset);
100 printf("%s online cpuset = %s\n", prefix, s);
101 }
102 if (obj->allowed_cpuset) {
103 hwloc_bitmap_snprintf(s, sizeof(s), obj->allowed_cpuset);
104 printf("%s allowed cpuset = %s\n", prefix, s);
105 }
106
107 if (obj->nodeset) {
108 hwloc_bitmap_snprintf(s, sizeof(s), obj->nodeset);
109 printf("%s nodeset = %s\n", prefix, s);
110 }
111 if (obj->complete_nodeset) {
112 hwloc_bitmap_snprintf(s, sizeof(s), obj->complete_nodeset);
113 printf("%s complete nodeset = %s\n", prefix, s);
114 }
115 if (obj->allowed_nodeset) {
116 hwloc_bitmap_snprintf(s, sizeof(s), obj->allowed_nodeset);
117 printf("%s allowed nodeset = %s\n", prefix, s);
118 }
119
120 switch (obj->type) {
121 case HWLOC_OBJ_CACHE:
122 printf("%s attr cache depth = %u\n", prefix, obj->attr->cache.depth);
123 switch (obj->attr->cache.type) {
124 case HWLOC_OBJ_CACHE_UNIFIED: printf("%s attr cache type = Unified\n", prefix); break;
125 case HWLOC_OBJ_CACHE_DATA: printf("%s attr cache type = Data\n", prefix); break;
126 case HWLOC_OBJ_CACHE_INSTRUCTION: printf("%s attr cache type = Instruction\n", prefix); break;
127 }
128 printf("%s attr cache size = %llu\n", prefix, (unsigned long long) obj->attr->cache.size);
129 printf("%s attr cache line size = %u\n", prefix, obj->attr->cache.linesize);
130 if (obj->attr->cache.associativity == -1)
131 printf("%s attr cache ways = Fully-associative\n", prefix);
132 else if (obj->attr->cache.associativity != 0)
133 printf("%s attr cache ways = %d\n", prefix, obj->attr->cache.associativity);
134 break;
135 case HWLOC_OBJ_GROUP:
136 printf("%s attr group depth = %u\n", prefix, obj->attr->group.depth);
137 break;
138 case HWLOC_OBJ_BRIDGE:
139 switch (obj->attr->bridge.upstream_type) {
140 case HWLOC_OBJ_BRIDGE_HOST:
141 printf("%s attr bridge upstream type = Host\n", prefix);
142 break;
143 case HWLOC_OBJ_BRIDGE_PCI:
144 printf("%s attr bridge upstream type = PCI\n", prefix);
145 printf("%s attr PCI bus id = %04x:%02x:%02x.%01x\n",
146 prefix, obj->attr->pcidev.domain, obj->attr->pcidev.bus, obj->attr->pcidev.dev, obj->attr->pcidev.func);
147 printf("%s attr PCI class = %04x\n",
148 prefix, obj->attr->pcidev.class_id);
149 printf("%s attr PCI id = %04x:%04x\n",
150 prefix, obj->attr->pcidev.vendor_id, obj->attr->pcidev.device_id);
151 if (obj->attr->pcidev.linkspeed)
152 printf("%s attr PCI linkspeed = %f GB/s\n", prefix, obj->attr->pcidev.linkspeed);
153 break;
154 }
155 switch (obj->attr->bridge.downstream_type) {
156 case HWLOC_OBJ_BRIDGE_HOST:
157 assert(0);
158 case HWLOC_OBJ_BRIDGE_PCI:
159 printf("%s attr bridge downstream type = PCI\n", prefix);
160 printf("%s attr PCI secondary bus = %02x\n",
161 prefix, obj->attr->bridge.downstream.pci.secondary_bus);
162 printf("%s attr PCI subordinate bus = %02x\n",
163 prefix, obj->attr->bridge.downstream.pci.subordinate_bus);
164 break;
165 }
166 break;
167 case HWLOC_OBJ_PCI_DEVICE:
168 printf("%s attr PCI bus id = %04x:%02x:%02x.%01x\n",
169 prefix, obj->attr->pcidev.domain, obj->attr->pcidev.bus, obj->attr->pcidev.dev, obj->attr->pcidev.func);
170 printf("%s attr PCI class = %04x\n",
171 prefix, obj->attr->pcidev.class_id);
172 printf("%s attr PCI id = %04x:%04x\n",
173 prefix, obj->attr->pcidev.vendor_id, obj->attr->pcidev.device_id);
174 if (obj->attr->pcidev.linkspeed)
175 printf("%s attr PCI linkspeed = %f GB/s\n", prefix, obj->attr->pcidev.linkspeed);
176 break;
177 case HWLOC_OBJ_OS_DEVICE:
178 printf("%s attr osdev type = %s\n", prefix, type);
179 break;
180 default:
181 /* nothing to show */
182 break;
183 }
184
185 printf("%s symmetric subtree = %d\n", prefix, obj->symmetric_subtree);
186
187 for(i=0; i<obj->infos_count; i++) {
188 printf("%s info %s = %s\n", prefix, obj->infos[i].name, obj->infos[i].value);
189 }
190 }
191
192 static void
hwloc_calc_process_location_info_cb(struct hwloc_calc_location_context_s * lcontext,void * _data __hwloc_attribute_unused,hwloc_obj_t obj)193 hwloc_calc_process_location_info_cb(struct hwloc_calc_location_context_s *lcontext,
194 void *_data __hwloc_attribute_unused,
195 hwloc_obj_t obj)
196 {
197 hwloc_topology_t topology = lcontext->topology;
198 int verbose = lcontext->verbose;
199 char prefix[32];
200 char objs[128];
201
202 prefix[0] = '\0';
203 if (show_index_prefix)
204 snprintf(prefix, sizeof(prefix), "%u: ", current_obj);
205
206 hwloc_obj_type_snprintf(objs, sizeof(objs), obj, 1);
207
208 if (show_ancestors) {
209 char parents[128];
210 unsigned level = 0;
211 hwloc_obj_t parent = obj;
212 while (parent) {
213 if (show_index_prefix)
214 snprintf(prefix, sizeof(prefix), "%u.%u: ", current_obj, level);
215 hwloc_obj_type_snprintf(parents, sizeof(parents), parent, 1);
216 if (verbose < 0)
217 printf("%s%s:%u\n", prefix, parents, parent->logical_index);
218 else if (level)
219 printf("%s%s L#%u = parent #%u of %s L#%u\n",
220 prefix, parents, parent->logical_index, level, objs, obj->logical_index);
221 else
222 printf("%s%s L#%u\n", prefix, parents, parent->logical_index);
223 hwloc_info_show_obj(parent, parents, prefix, verbose);
224 parent = parent->parent;
225 level++;
226 }
227 } else if (show_ancestor_type != (hwloc_obj_type_t) -1) {
228 char parents[128];
229 hwloc_obj_t parent = obj;
230 while (parent) {
231 if (parent->type == show_ancestor_type) {
232 if (parent->type == HWLOC_OBJ_GROUP
233 && show_ancestor_attrdepth != -1
234 && show_ancestor_attrdepth != (int) parent->attr->group.depth)
235 goto next;
236 if (parent->type == HWLOC_OBJ_CACHE
237 && show_ancestor_attrdepth != -1
238 && show_ancestor_attrdepth != (int) parent->attr->cache.depth)
239 goto next;
240 if (parent->type == HWLOC_OBJ_CACHE
241 && show_ancestor_attrcachetype != (hwloc_obj_cache_type_t) -1
242 && parent->attr->cache.type != HWLOC_OBJ_CACHE_UNIFIED
243 && show_ancestor_attrcachetype != parent->attr->cache.type)
244 goto next;
245 hwloc_obj_type_snprintf(parents, sizeof(parents), parent, 1);
246 if (verbose < 0)
247 printf("%s%s:%u\n", prefix, parents, parent->logical_index);
248 else
249 printf("%s%s L#%u = parent of %s L#%u\n",
250 prefix, parents, parent->logical_index, objs, obj->logical_index);
251 hwloc_info_show_obj(parent, parents, prefix, verbose);
252 }
253 next:
254 parent = parent->parent;
255 }
256 } else if (show_children) {
257 unsigned i = 0;
258 hwloc_obj_t child = NULL;
259 while ((child = hwloc_get_next_child(topology, obj, child)) != NULL) {
260 char childs[128];
261 if (show_index_prefix)
262 snprintf(prefix, sizeof(prefix), "%u.%u: ", current_obj, i);
263 hwloc_obj_type_snprintf(childs, sizeof(childs), child, 1);
264 if (verbose < 0)
265 printf("%s%s:%u\n", prefix, childs, child->logical_index);
266 else
267 printf("%s%s L#%u = child #%u of %s L#%u\n",
268 prefix, childs, child->logical_index, i, objs, obj->logical_index);
269 hwloc_info_show_obj(child, childs, prefix, verbose);
270 i++;
271 }
272 } else if (show_descendants_depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
273 if (show_descendants_depth >= 0) {
274 /* normal level */
275 unsigned i = 0;
276 unsigned n = hwloc_calc_get_nbobjs_inside_sets_by_depth(lcontext, obj->cpuset, obj->nodeset, show_descendants_depth);
277 for(i=0; i<n; i++) {
278 hwloc_obj_t child = hwloc_calc_get_obj_inside_sets_by_depth(lcontext, obj->cpuset, obj->nodeset, show_descendants_depth, i);
279 char childs[128];
280 if (show_index_prefix)
281 snprintf(prefix, sizeof(prefix), "%u.%u: ", current_obj, i);
282 hwloc_obj_type_snprintf(childs, sizeof(childs), child, 1);
283 if (verbose < 0)
284 printf("%s%s:%u\n", prefix, childs, child->logical_index);
285 else
286 printf("%s%s L#%u = descendant #%u of %s L#%u\n",
287 prefix, childs, child->logical_index, i, objs, obj->logical_index);
288 hwloc_info_show_obj(child, childs, prefix, verbose);
289 }
290 } else {
291 /* custom level */
292 unsigned i = 0;
293 hwloc_obj_t child = NULL;
294 while ((child = hwloc_get_next_obj_by_depth(topology, show_descendants_depth, child)) != NULL) {
295 char childs[128];
296 hwloc_obj_t parent = child->parent;
297 if (obj->cpuset) {
298 while (parent && !parent->cpuset)
299 parent = parent->parent;
300 if (!parent)
301 continue;
302 if (!hwloc_bitmap_isincluded(parent->cpuset, obj->cpuset)
303 || !hwloc_bitmap_isincluded(parent->nodeset, obj->nodeset))
304 continue;
305 } else {
306 while (parent && parent != obj)
307 parent = parent->parent;
308 if (!parent)
309 continue;
310 }
311 if (show_index_prefix)
312 snprintf(prefix, sizeof(prefix), "%u.%u: ", current_obj, i);
313 hwloc_obj_type_snprintf(childs, sizeof(childs), child, 1);
314 if (verbose < 0)
315 printf("%s%s:%u\n", prefix, childs, child->logical_index);
316 else
317 printf("%s%s L#%u = descendant #%u of %s L#%u\n",
318 prefix, childs, child->logical_index, i, objs, obj->logical_index);
319 hwloc_info_show_obj(child, childs, prefix, verbose);
320 i++;
321 }
322 }
323 } else {
324 if (verbose < 0)
325 printf("%s%s:%u\n", prefix, objs, obj->logical_index);
326 else
327 printf("%s%s L#%u\n", prefix, objs, obj->logical_index);
328 hwloc_info_show_obj(obj, objs, prefix, verbose);
329 }
330
331 current_obj++;
332 }
333
334 int
main(int argc,char * argv[])335 main (int argc, char *argv[])
336 {
337 int err;
338 hwloc_topology_t topology;
339 unsigned topodepth;
340 unsigned long flags = HWLOC_TOPOLOGY_FLAG_IO_DEVICES | HWLOC_TOPOLOGY_FLAG_IO_BRIDGES | HWLOC_TOPOLOGY_FLAG_ICACHES;
341 char * callname;
342 char * input = NULL;
343 enum hwloc_utils_input_format input_format = HWLOC_UTILS_INPUT_DEFAULT;
344 hwloc_obj_type_t show_descendants_type = (hwloc_obj_type_t) -1;
345 int show_descendants_attrdepth = -1;
346 hwloc_obj_cache_type_t show_descendants_attrcachetype = (hwloc_obj_cache_type_t) -1;
347 char *restrictstring = NULL;
348 size_t typelen;
349 int opt;
350 enum hwloc_info_mode { HWLOC_INFO_MODE_UNKNOWN, HWLOC_INFO_MODE_TOPOLOGY, HWLOC_INFO_MODE_OBJECTS, HWLOC_INFO_MODE_SUPPORT } mode = HWLOC_INFO_MODE_UNKNOWN;
351
352 /* enable verbose backends */
353 putenv((char *) "HWLOC_XML_VERBOSE=1");
354 putenv((char *) "HWLOC_SYNTHETIC_VERBOSE=1");
355
356 callname = strrchr(argv[0], '/');
357 if (!callname)
358 callname = argv[0];
359 else
360 callname++;
361 /* skip argv[0], handle options */
362 argc--;
363 argv++;
364
365 err = hwloc_topology_init (&topology);
366 if (err)
367 return EXIT_FAILURE;
368
369 hwloc_topology_set_flags(topology, flags);
370
371 while (argc >= 1) {
372 opt = 0;
373 if (*argv[0] == '-') {
374 if (!strcmp (argv[0], "--objects"))
375 mode = HWLOC_INFO_MODE_OBJECTS;
376 else if (!strcmp (argv[0], "--topology"))
377 mode = HWLOC_INFO_MODE_TOPOLOGY;
378 else if (!strcmp (argv[0], "--support"))
379 mode = HWLOC_INFO_MODE_SUPPORT;
380 else if (!strcmp (argv[0], "-v") || !strcmp (argv[0], "--verbose"))
381 verbose_mode++;
382 else if (!strcmp (argv[0], "-s") || !strcmp (argv[0], "--silent"))
383 verbose_mode--;
384 else if (!strcmp (argv[0], "-h") || !strcmp (argv[0], "--help")) {
385 usage(callname, stdout);
386 exit(EXIT_SUCCESS);
387 }
388 else if (!strcmp (argv[0], "-n"))
389 show_index_prefix = 1;
390 else if (!strcmp (argv[0], "--ancestors"))
391 show_ancestors = 1;
392 else if (!strcmp (argv[0], "--ancestor")) {
393 if (argc < 2) {
394 usage (callname, stderr);
395 exit(EXIT_FAILURE);
396 }
397 err = hwloc_obj_type_sscanf(argv[1], &show_ancestor_type, &show_ancestor_attrdepth, &show_ancestor_attrcachetype, sizeof(show_ancestor_attrcachetype));
398 if (err < 0) {
399 fprintf(stderr, "unrecognized --ancestor type %s\n", argv[1]);
400 usage(callname, stderr);
401 return EXIT_FAILURE;
402 }
403 opt = 1;
404 }
405 else if (!strcmp (argv[0], "--children"))
406 show_children = 1;
407 else if (!strcmp (argv[0], "--descendants")) {
408 if (argc < 2) {
409 usage (callname, stderr);
410 exit(EXIT_FAILURE);
411 }
412 err = hwloc_obj_type_sscanf(argv[1], &show_descendants_type, &show_descendants_attrdepth, &show_descendants_attrcachetype, sizeof(show_descendants_attrcachetype));
413 if (err < 0) {
414 fprintf(stderr, "unrecognized --descendants type %s\n", argv[1]);
415 usage(callname, stderr);
416 return EXIT_FAILURE;
417 }
418 opt = 1;
419 }
420 else if (!strcmp (argv[0], "--no-icaches"))
421 flags &= ~HWLOC_TOPOLOGY_FLAG_ICACHES;
422 else if (!strcmp (argv[0], "--whole-system"))
423 flags |= HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM;
424 else if (!strcmp (argv[0], "--no-io"))
425 flags &= ~(HWLOC_TOPOLOGY_FLAG_IO_DEVICES | HWLOC_TOPOLOGY_FLAG_IO_BRIDGES);
426 else if (!strcmp (argv[0], "--no-bridges"))
427 flags &= ~(HWLOC_TOPOLOGY_FLAG_IO_BRIDGES);
428 else if (!strcmp (argv[0], "--whole-io"))
429 flags |= HWLOC_TOPOLOGY_FLAG_WHOLE_IO;
430 else if (!strcmp (argv[0], "--thissystem"))
431 flags |= HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM;
432 else if (!strcmp (argv[0], "--restrict")) {
433 if (argc < 2) {
434 usage (callname, stderr);
435 exit(EXIT_FAILURE);
436 }
437 restrictstring = strdup(argv[1]);
438 opt = 1;
439 }
440
441 else if (hwloc_utils_lookup_input_option(argv, argc, &opt,
442 &input, &input_format,
443 callname)) {
444 /* we'll enable later */
445 }
446 else if (!strcmp (argv[0], "--pid")) {
447 if (argc < 2) {
448 usage (callname, stderr);
449 exit(EXIT_FAILURE);
450 }
451 pid_number = atoi(argv[1]); opt = 1;
452 }
453 else if (!strcmp(argv[0], "-l") || !strcmp(argv[0], "--logical"))
454 logical = 1;
455 else if (!strcmp(argv[0], "-p") || !strcmp(argv[0], "--physical"))
456 logical = 0;
457 else if (!strcmp (argv[0], "--version")) {
458 printf("%s %s\n", callname, HWLOC_VERSION);
459 exit(EXIT_SUCCESS);
460 }
461 else {
462 fprintf (stderr, "Unrecognized option: %s\n", argv[0]);
463 usage(callname, stderr);
464 return EXIT_FAILURE;
465 }
466 argc -= opt+1;
467 argv += opt+1;
468 } else {
469 /* not an option */
470 break;
471 }
472 }
473
474 hwloc_topology_set_flags(topology, flags);
475
476 if (input) {
477 err = hwloc_utils_enable_input_format(topology, input, &input_format, verbose_mode, callname);
478 if (err)
479 return err;
480 }
481
482 if (pid_number > 0) {
483 if (hwloc_pid_from_number(&pid, pid_number, 0, 1 /* verbose */) < 0
484 || hwloc_topology_set_pid(topology, pid)) {
485 perror("Setting target pid");
486 return EXIT_FAILURE;
487 }
488 }
489
490 err = hwloc_topology_load (topology);
491 if (err) {
492 perror("hwloc_topology_load");
493 return EXIT_FAILURE;
494 }
495
496 topodepth = hwloc_topology_get_depth(topology);
497
498 if (show_descendants_type != (hwloc_obj_type_t) -1) {
499 show_descendants_depth = hwloc_get_type_depth(topology, show_descendants_type);
500 if (show_descendants_depth == HWLOC_TYPE_DEPTH_UNKNOWN) {
501 fprintf(stderr, "unavailable --descendants type %s\n", hwloc_obj_type_string(show_descendants_type));
502 return EXIT_FAILURE;
503 }
504 if (show_descendants_depth == HWLOC_TYPE_DEPTH_MULTIPLE) {
505 if (show_descendants_type == HWLOC_OBJ_CACHE)
506 show_descendants_depth = hwloc_get_cache_type_depth(topology, show_descendants_attrdepth, show_descendants_attrcachetype);
507 else if (show_descendants_type == HWLOC_OBJ_GROUP) {
508 unsigned i;
509 for(i=0; i<hwloc_topology_get_depth(topology); i++) {
510 hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, i, 0);
511 if (obj->type == HWLOC_OBJ_GROUP && obj->attr->group.depth == (unsigned) show_descendants_attrdepth) {
512 show_descendants_depth = i;
513 break;
514 }
515 }
516 }
517 }
518 if (show_descendants_depth == HWLOC_TYPE_DEPTH_MULTIPLE) {
519 fprintf(stderr, "multiple --descendants type %s\n", hwloc_obj_type_string(show_descendants_type));
520 return EXIT_FAILURE;
521 }
522 }
523
524 if (restrictstring) {
525 hwloc_bitmap_t restrictset = hwloc_bitmap_alloc();
526 if (!strcmp (restrictstring, "binding")) {
527 if (pid_number > 0)
528 hwloc_get_proc_cpubind(topology, pid, restrictset, HWLOC_CPUBIND_PROCESS);
529 else
530 hwloc_get_cpubind(topology, restrictset, HWLOC_CPUBIND_PROCESS);
531 } else {
532 hwloc_bitmap_sscanf(restrictset, restrictstring);
533 }
534 err = hwloc_topology_restrict (topology, restrictset, 0);
535 if (err) {
536 perror("Restricting the topology");
537 /* FALLTHRU */
538 }
539 hwloc_bitmap_free(restrictset);
540 free(restrictstring);
541 }
542
543 if (mode == HWLOC_INFO_MODE_UNKNOWN) {
544 if (argc)
545 mode = HWLOC_INFO_MODE_OBJECTS;
546 else
547 mode = HWLOC_INFO_MODE_TOPOLOGY;
548 }
549
550 if (mode == HWLOC_INFO_MODE_TOPOLOGY) {
551 hwloc_lstopo_show_summary(stdout, topology);
552
553 } else if (mode == HWLOC_INFO_MODE_SUPPORT) {
554 const struct hwloc_topology_support *support = hwloc_topology_get_support(topology);
555 #define DO(x,y) printf(#x ":" #y " = %u\n", (unsigned char) support->x->y);
556 DO(discovery, pu);
557
558 DO(cpubind, set_thisproc_cpubind);
559 DO(cpubind, get_thisproc_cpubind);
560 DO(cpubind, set_proc_cpubind);
561 DO(cpubind, get_proc_cpubind);
562 DO(cpubind, set_thisthread_cpubind);
563 DO(cpubind, get_thisthread_cpubind);
564 DO(cpubind, set_thread_cpubind);
565 DO(cpubind, get_thread_cpubind);
566 DO(cpubind, get_thisproc_last_cpu_location);
567 DO(cpubind, get_proc_last_cpu_location);
568 DO(cpubind, get_thisthread_last_cpu_location);
569
570 DO(membind, set_thisproc_membind);
571 DO(membind, get_thisproc_membind);
572 DO(membind, set_proc_membind);
573 DO(membind, get_proc_membind);
574 DO(membind, set_thisthread_membind);
575 DO(membind, get_thisthread_membind);
576 DO(membind, set_area_membind);
577 DO(membind, get_area_membind);
578 DO(membind, alloc_membind);
579 DO(membind, firsttouch_membind);
580 DO(membind, bind_membind);
581 DO(membind, interleave_membind);
582 DO(membind, nexttouch_membind);
583 DO(membind, migrate_membind);
584 DO(membind, get_area_memlocation);
585
586 } else if (mode == HWLOC_INFO_MODE_OBJECTS) {
587 struct hwloc_calc_location_context_s lcontext;
588 lcontext.topology = topology;
589 lcontext.topodepth = topodepth;
590 lcontext.only_hbm = -1;
591 lcontext.logical = logical;
592 lcontext.verbose = verbose_mode;
593 current_obj = 0;
594 while (argc >= 1) {
595 if (!strcmp(argv[0], "all") || !strcmp(argv[0], "root")) {
596 hwloc_calc_process_location_info_cb(&lcontext, NULL, hwloc_get_root_obj(topology));
597 } else {
598 /* try to match a type/depth followed by a special character */
599 typelen = strspn(argv[0], "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
600 if (typelen && (argv[0][typelen] == ':' || argv[0][typelen] == '=' || argv[0][typelen] == '[')) {
601 err = hwloc_calc_process_location(&lcontext, argv[0], typelen,
602 hwloc_calc_process_location_info_cb, NULL);
603 }
604 }
605 argc--; argv++;
606 }
607
608 } else assert(0);
609
610 hwloc_topology_destroy (topology);
611
612 return EXIT_SUCCESS;
613 }
614