/
hwloc.h
2400 lines (2178 loc) · 100 KB
/
hwloc.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2020 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2020 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
/*=====================================================================
* PLEASE GO READ THE DOCUMENTATION!
* ------------------------------------------------
* $tarball_directory/doc/doxygen-doc/
* or
* https://www.open-mpi.org/projects/hwloc/doc/
*=====================================================================
*
* FAIR WARNING: Do NOT expect to be able to figure out all the
* subtleties of hwloc by simply reading function prototypes and
* constant descrptions here in this file.
*
* Hwloc has wonderful documentation in both PDF and HTML formats for
* your reading pleasure. The formal documentation explains a LOT of
* hwloc-specific concepts, provides definitions, and discusses the
* "big picture" for many of the things that you'll find here in this
* header file.
*
* The PDF/HTML documentation was generated via Doxygen; much of what
* you'll see in there is also here in this file. BUT THERE IS A LOT
* THAT IS IN THE PDF/HTML THAT IS ***NOT*** IN hwloc.h!
*
* There are entire paragraph-length descriptions, discussions, and
* pretty prictures to explain subtle corner cases, provide concrete
* examples, etc.
*
* Please, go read the documentation. :-)
*
* Moreover there are several examples of hwloc use under doc/examples
* in the source tree.
*
*=====================================================================*/
/** \file
* \brief The hwloc API.
*
* See hwloc/bitmap.h for bitmap specific macros.
* See hwloc/helper.h for high-level topology traversal helpers.
* See hwloc/inlines.h for the actual inline code of some functions below.
* See hwloc/export.h for exporting topologies to XML or to synthetic descriptions.
* See hwloc/distances.h for querying and modifying distances between objects.
* See hwloc/diff.h for manipulating differences between similar topologies.
*/
#ifndef HWLOC_H
#define HWLOC_H
#include "hwloc/autogen/config.h"
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
/*
* Symbol transforms
*/
#include "hwloc/rename.h"
/*
* Bitmap definitions
*/
#include "hwloc/bitmap.h"
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup hwlocality_api_version API version
* @{
*/
/** \brief Indicate at build time which hwloc API version is being used.
*
* This number is updated to (X<<16)+(Y<<8)+Z when a new release X.Y.Z
* actually modifies the API.
*
* Users may check for available features at build time using this number
* (see \ref faq_version_api).
*
* \note This should not be confused with HWLOC_VERSION, the library version.
* Two stable releases of the same series usually have the same ::HWLOC_API_VERSION
* even if their HWLOC_VERSION are different.
*/
#define HWLOC_API_VERSION 0x00020100
/** \brief Indicate at runtime which hwloc API version was used at build time.
*
* Should be ::HWLOC_API_VERSION if running on the same version.
*/
HWLOC_DECLSPEC unsigned hwloc_get_api_version(void);
/** \brief Current component and plugin ABI version (see hwloc/plugins.h) */
#define HWLOC_COMPONENT_ABI 6
/** @} */
/** \defgroup hwlocality_object_sets Object Sets (hwloc_cpuset_t and hwloc_nodeset_t)
*
* Hwloc uses bitmaps to represent two distinct kinds of object sets:
* CPU sets (::hwloc_cpuset_t) and NUMA node sets (::hwloc_nodeset_t).
* These types are both typedefs to a common back end type
* (::hwloc_bitmap_t), and therefore all the hwloc bitmap functions
* are applicable to both ::hwloc_cpuset_t and ::hwloc_nodeset_t (see
* \ref hwlocality_bitmap).
*
* The rationale for having two different types is that even though
* the actions one wants to perform on these types are the same (e.g.,
* enable and disable individual items in the set/mask), they're used
* in very different contexts: one for specifying which processors to
* use and one for specifying which NUMA nodes to use. Hence, the
* name difference is really just to reflect the intent of where the
* type is used.
*
* @{
*/
/** \brief A CPU set is a bitmap whose bits are set according to CPU
* physical OS indexes.
*
* It may be consulted and modified with the bitmap API as any
* ::hwloc_bitmap_t (see hwloc/bitmap.h).
*
* Each bit may be converted into a PU object using
* hwloc_get_pu_obj_by_os_index().
*/
typedef hwloc_bitmap_t hwloc_cpuset_t;
/** \brief A non-modifiable ::hwloc_cpuset_t. */
typedef hwloc_const_bitmap_t hwloc_const_cpuset_t;
/** \brief A node set is a bitmap whose bits are set according to NUMA
* memory node physical OS indexes.
*
* It may be consulted and modified with the bitmap API as any
* ::hwloc_bitmap_t (see hwloc/bitmap.h).
* Each bit may be converted into a NUMA node object using
* hwloc_get_numanode_obj_by_os_index().
*
* When binding memory on a system without any NUMA node,
* the single main memory bank is considered as NUMA node #0.
*
* See also \ref hwlocality_helper_nodeset_convert.
*/
typedef hwloc_bitmap_t hwloc_nodeset_t;
/** \brief A non-modifiable ::hwloc_nodeset_t.
*/
typedef hwloc_const_bitmap_t hwloc_const_nodeset_t;
/** @} */
/** \defgroup hwlocality_object_types Object Types
* @{
*/
/** \brief Type of topology object.
*
* \note Do not rely on the ordering or completeness of the values as new ones
* may be defined in the future! If you need to compare types, use
* hwloc_compare_types() instead.
*/
typedef enum {
/** \cond */
#define HWLOC_OBJ_TYPE_MIN HWLOC_OBJ_MACHINE /* Sentinel value */
/** \endcond */
HWLOC_OBJ_MACHINE, /**< \brief Machine.
* A set of processors and memory with cache
* coherency.
*
* This type is always used for the root object of a topology,
* and never used anywhere else.
* Hence its parent is always \c NULL.
*/
HWLOC_OBJ_PACKAGE, /**< \brief Physical package.
* The physical package that usually gets inserted
* into a socket on the motherboard.
* A processor package usually contains multiple cores,
* and possibly some dies.
*/
HWLOC_OBJ_CORE, /**< \brief Core.
* A computation unit (may be shared by several
* PUs, aka logical processors).
*/
HWLOC_OBJ_PU, /**< \brief Processing Unit, or (Logical) Processor.
* An execution unit (may share a core with some
* other logical processors, e.g. in the case of
* an SMT core).
*
* This is the smallest object representing CPU resources,
* it cannot have any child except Misc objects.
*
* Objects of this kind are always reported and can
* thus be used as fallback when others are not.
*/
HWLOC_OBJ_L1CACHE, /**< \brief Level 1 Data (or Unified) Cache. */
HWLOC_OBJ_L2CACHE, /**< \brief Level 2 Data (or Unified) Cache. */
HWLOC_OBJ_L3CACHE, /**< \brief Level 3 Data (or Unified) Cache. */
HWLOC_OBJ_L4CACHE, /**< \brief Level 4 Data (or Unified) Cache. */
HWLOC_OBJ_L5CACHE, /**< \brief Level 5 Data (or Unified) Cache. */
HWLOC_OBJ_L1ICACHE, /**< \brief Level 1 instruction Cache (filtered out by default). */
HWLOC_OBJ_L2ICACHE, /**< \brief Level 2 instruction Cache (filtered out by default). */
HWLOC_OBJ_L3ICACHE, /**< \brief Level 3 instruction Cache (filtered out by default). */
HWLOC_OBJ_GROUP, /**< \brief Group objects.
* Objects which do not fit in the above but are
* detected by hwloc and are useful to take into
* account for affinity. For instance, some operating systems
* expose their arbitrary processors aggregation this
* way. And hwloc may insert such objects to group
* NUMA nodes according to their distances.
* See also \ref faq_groups.
*
* These objects are removed when they do not bring
* any structure (see ::HWLOC_TYPE_FILTER_KEEP_STRUCTURE).
*/
HWLOC_OBJ_NUMANODE, /**< \brief NUMA node.
* An object that contains memory that is directly
* and byte-accessible to the host processors.
* It is usually close to some cores (the corresponding objects
* are descendants of the NUMA node object in the hwloc tree).
*
* This is the smallest object representing Memory resources,
* it cannot have any child except Misc objects.
* However it may have Memory-side cache parents.
*
* There is always at least one such object in the topology
* even if the machine is not NUMA.
*
* Memory objects are not listed in the main children list,
* but rather in the dedicated Memory children list.
*
* NUMA nodes have a special depth ::HWLOC_TYPE_DEPTH_NUMANODE
* instead of a normal depth just like other objects in the
* main tree.
*/
HWLOC_OBJ_BRIDGE, /**< \brief Bridge (filtered out by default).
* Any bridge (or PCI switch) that connects the host or an I/O bus,
* to another I/O bus.
* They are not added to the topology unless I/O discovery
* is enabled with hwloc_topology_set_flags().
* I/O objects are not listed in the main children list,
* but rather in the dedicated io children list.
* I/O objects have NULL CPU and node sets.
*/
HWLOC_OBJ_PCI_DEVICE, /**< \brief PCI device (filtered out by default).
* They are not added to the topology unless I/O discovery
* is enabled with hwloc_topology_set_flags().
* I/O objects are not listed in the main children list,
* but rather in the dedicated io children list.
* I/O objects have NULL CPU and node sets.
*/
HWLOC_OBJ_OS_DEVICE, /**< \brief Operating system device (filtered out by default).
* They are not added to the topology unless I/O discovery
* is enabled with hwloc_topology_set_flags().
* I/O objects are not listed in the main children list,
* but rather in the dedicated io children list.
* I/O objects have NULL CPU and node sets.
*/
HWLOC_OBJ_MISC, /**< \brief Miscellaneous objects (filtered out by default).
* Objects without particular meaning, that can e.g. be
* added by the application for its own use, or by hwloc
* for miscellaneous objects such as MemoryModule (DIMMs).
* These objects are not listed in the main children list,
* but rather in the dedicated misc children list.
* Misc objects may only have Misc objects as children,
* and those are in the dedicated misc children list as well.
* Misc objects have NULL CPU and node sets.
*/
HWLOC_OBJ_MEMCACHE, /**< \brief Memory-side cache (filtered out by default).
* A cache in front of a specific NUMA node.
*
* This object always has at least one NUMA node as a memory child.
*
* Memory objects are not listed in the main children list,
* but rather in the dedicated Memory children list.
*
* Memory-side cache have a special depth ::HWLOC_TYPE_DEPTH_MEMCACHE
* instead of a normal depth just like other objects in the
* main tree.
*/
HWLOC_OBJ_DIE, /**< \brief Die within a physical package.
* A subpart of the physical package, that contains multiple cores.
*/
HWLOC_OBJ_TYPE_MAX /**< \private Sentinel value */
} hwloc_obj_type_t;
/** \brief Cache type. */
typedef enum hwloc_obj_cache_type_e {
HWLOC_OBJ_CACHE_UNIFIED, /**< \brief Unified cache. */
HWLOC_OBJ_CACHE_DATA, /**< \brief Data cache. */
HWLOC_OBJ_CACHE_INSTRUCTION /**< \brief Instruction cache (filtered out by default). */
} hwloc_obj_cache_type_t;
/** \brief Type of one side (upstream or downstream) of an I/O bridge. */
typedef enum hwloc_obj_bridge_type_e {
HWLOC_OBJ_BRIDGE_HOST, /**< \brief Host-side of a bridge, only possible upstream. */
HWLOC_OBJ_BRIDGE_PCI /**< \brief PCI-side of a bridge. */
} hwloc_obj_bridge_type_t;
/** \brief Type of a OS device. */
typedef enum hwloc_obj_osdev_type_e {
HWLOC_OBJ_OSDEV_BLOCK, /**< \brief Operating system block device, or non-volatile memory device.
* For instance "sda" or "dax2.0" on Linux. */
HWLOC_OBJ_OSDEV_GPU, /**< \brief Operating system GPU device.
* For instance ":0.0" for a GL display,
* "card0" for a Linux DRM device. */
HWLOC_OBJ_OSDEV_NETWORK, /**< \brief Operating system network device.
* For instance the "eth0" interface on Linux. */
HWLOC_OBJ_OSDEV_OPENFABRICS, /**< \brief Operating system openfabrics device.
* For instance the "mlx4_0" InfiniBand HCA,
* or "hfi1_0" Omni-Path interface on Linux. */
HWLOC_OBJ_OSDEV_DMA, /**< \brief Operating system dma engine device.
* For instance the "dma0chan0" DMA channel on Linux. */
HWLOC_OBJ_OSDEV_COPROC /**< \brief Operating system co-processor device.
* For instance "mic0" for a Xeon Phi (MIC) on Linux,
* "opencl0d0" for a OpenCL device,
* "cuda0" for a CUDA device. */
} hwloc_obj_osdev_type_t;
/** \brief Compare the depth of two object types
*
* Types shouldn't be compared as they are, since newer ones may be added in
* the future. This function returns less than, equal to, or greater than zero
* respectively if \p type1 objects usually include \p type2 objects, are the
* same as \p type2 objects, or are included in \p type2 objects. If the types
* can not be compared (because neither is usually contained in the other),
* ::HWLOC_TYPE_UNORDERED is returned. Object types containing CPUs can always
* be compared (usually, a system contains machines which contain nodes which
* contain packages which contain caches, which contain cores, which contain
* processors).
*
* \note ::HWLOC_OBJ_PU will always be the deepest,
* while ::HWLOC_OBJ_MACHINE is always the highest.
*
* \note This does not mean that the actual topology will respect that order:
* e.g. as of today cores may also contain caches, and packages may also contain
* nodes. This is thus just to be seen as a fallback comparison method.
*/
HWLOC_DECLSPEC int hwloc_compare_types (hwloc_obj_type_t type1, hwloc_obj_type_t type2) __hwloc_attribute_const;
/** \brief Value returned by hwloc_compare_types() when types can not be compared. \hideinitializer */
#define HWLOC_TYPE_UNORDERED INT_MAX
/** @} */
/** \defgroup hwlocality_objects Object Structure and Attributes
* @{
*/
union hwloc_obj_attr_u;
/** \brief Structure of a topology object
*
* Applications must not modify any field except \p hwloc_obj.userdata.
*/
struct hwloc_obj {
/* physical information */
hwloc_obj_type_t type; /**< \brief Type of object */
char *subtype; /**< \brief Subtype string to better describe the type field. */
unsigned os_index; /**< \brief OS-provided physical index number.
* It is not guaranteed unique across the entire machine,
* except for PUs and NUMA nodes.
* Set to HWLOC_UNKNOWN_INDEX if unknown or irrelevant for this object.
*/
#define HWLOC_UNKNOWN_INDEX (unsigned)-1
char *name; /**< \brief Object-specific name if any.
* Mostly used for identifying OS devices and Misc objects where
* a name string is more useful than numerical indexes.
*/
hwloc_uint64_t total_memory; /**< \brief Total memory (in bytes) in NUMA nodes below this object. */
union hwloc_obj_attr_u *attr; /**< \brief Object type-specific Attributes,
* may be \c NULL if no attribute value was found */
/* global position */
int depth; /**< \brief Vertical index in the hierarchy.
*
* For normal objects, this is the depth of the horizontal level
* that contains this object and its cousins of the same type.
* If the topology is symmetric, this is equal to the parent depth
* plus one, and also equal to the number of parent/child links
* from the root object to here.
*
* For special objects (NUMA nodes, I/O and Misc) that are not
* in the main tree, this is a special negative value that
* corresponds to their dedicated level,
* see hwloc_get_type_depth() and ::hwloc_get_type_depth_e.
* Those special values can be passed to hwloc functions such
* hwloc_get_nbobjs_by_depth() as usual.
*/
unsigned logical_index; /**< \brief Horizontal index in the whole list of similar objects,
* hence guaranteed unique across the entire machine.
* Could be a "cousin_rank" since it's the rank within the "cousin" list below
* Note that this index may change when restricting the topology
* or when inserting a group.
*/
/* cousins are all objects of the same type (and depth) across the entire topology */
struct hwloc_obj *next_cousin; /**< \brief Next object of same type and depth */
struct hwloc_obj *prev_cousin; /**< \brief Previous object of same type and depth */
/* children of the same parent are siblings, even if they may have different type and depth */
struct hwloc_obj *parent; /**< \brief Parent, \c NULL if root (Machine object) */
unsigned sibling_rank; /**< \brief Index in parent's \c children[] array. Or the index in parent's Memory, I/O or Misc children list. */
struct hwloc_obj *next_sibling; /**< \brief Next object below the same parent (inside the same list of children). */
struct hwloc_obj *prev_sibling; /**< \brief Previous object below the same parent (inside the same list of children). */
/** @name List and array of normal children below this object (except Memory, I/O and Misc children). */
/**@{*/
unsigned arity; /**< \brief Number of normal children.
* Memory, Misc and I/O children are not listed here
* but rather in their dedicated children list.
*/
struct hwloc_obj **children; /**< \brief Normal children, \c children[0 .. arity -1] */
struct hwloc_obj *first_child; /**< \brief First normal child */
struct hwloc_obj *last_child; /**< \brief Last normal child */
/**@}*/
int symmetric_subtree; /**< \brief Set if the subtree of normal objects below this object is symmetric,
* which means all normal children and their children have identical subtrees.
*
* Memory, I/O and Misc children are ignored.
*
* If set in the topology root object, lstopo may export the topology
* as a synthetic string.
*/
/** @name List of Memory children below this object. */
/**@{*/
unsigned memory_arity; /**< \brief Number of Memory children.
* These children are listed in \p memory_first_child.
*/
struct hwloc_obj *memory_first_child; /**< \brief First Memory child.
* NUMA nodes and Memory-side caches are listed here
* (\p memory_arity and \p memory_first_child)
* instead of in the normal children list.
* See also hwloc_obj_type_is_memory().
*
* A memory hierarchy starts from a normal CPU-side object
* (e.g. Package) and ends with NUMA nodes as leaves.
* There might exist some memory-side caches between them
* in the middle of the memory subtree.
*/
/**@}*/
/** @name List of I/O children below this object. */
/**@{*/
unsigned io_arity; /**< \brief Number of I/O children.
* These children are listed in \p io_first_child.
*/
struct hwloc_obj *io_first_child; /**< \brief First I/O child.
* Bridges, PCI and OS devices are listed here (\p io_arity and \p io_first_child)
* instead of in the normal children list.
* See also hwloc_obj_type_is_io().
*/
/**@}*/
/** @name List of Misc children below this object. */
/**@{*/
unsigned misc_arity; /**< \brief Number of Misc children.
* These children are listed in \p misc_first_child.
*/
struct hwloc_obj *misc_first_child; /**< \brief First Misc child.
* Misc objects are listed here (\p misc_arity and \p misc_first_child)
* instead of in the normal children list.
*/
/**@}*/
/* cpusets and nodesets */
hwloc_cpuset_t cpuset; /**< \brief CPUs covered by this object
*
* This is the set of CPUs for which there are PU objects in the topology
* under this object, i.e. which are known to be physically contained in this
* object and known how (the children path between this object and the PU
* objects).
*
* If the ::HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED configuration flag is set,
* some of these CPUs may not be allowed for binding,
* see hwloc_topology_get_allowed_cpuset().
*
* \note All objects have non-NULL CPU and node sets except Misc and I/O objects.
*
* \note Its value must not be changed, hwloc_bitmap_dup() must be used instead.
*/
hwloc_cpuset_t complete_cpuset; /**< \brief The complete CPU set of processors of this object,
*
* This may include not only the same as the cpuset field, but also some CPUs for
* which topology information is unknown or incomplete, some offlines CPUs, and
* the CPUs that are ignored when the ::HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED flag
* is not set.
* Thus no corresponding PU object may be found in the topology, because the
* precise position is undefined. It is however known that it would be somewhere
* under this object.
*
* \note Its value must not be changed, hwloc_bitmap_dup() must be used instead.
*/
hwloc_nodeset_t nodeset; /**< \brief NUMA nodes covered by this object or containing this object
*
* This is the set of NUMA nodes for which there are NUMA node objects in the
* topology under or above this object, i.e. which are known to be physically
* contained in this object or containing it and known how (the children path
* between this object and the NUMA node objects).
*
* In the end, these nodes are those that are close to the current object.
*
* If the ::HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED configuration flag is set,
* some of these nodes may not be allowed for allocation,
* see hwloc_topology_get_allowed_nodeset().
*
* If there are no NUMA nodes in the machine, all the memory is close to this
* object, so only the first bit may be set in \p nodeset.
*
* \note All objects have non-NULL CPU and node sets except Misc and I/O objects.
*
* \note Its value must not be changed, hwloc_bitmap_dup() must be used instead.
*/
hwloc_nodeset_t complete_nodeset; /**< \brief The complete NUMA node set of this object,
*
* This may include not only the same as the nodeset field, but also some NUMA
* nodes for which topology information is unknown or incomplete, some offlines
* nodes, and the nodes that are ignored when the ::HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED
* flag is not set.
* Thus no corresponding NUMA node object may be found in the topology, because the
* precise position is undefined. It is however known that it would be
* somewhere under this object.
*
* If there are no NUMA nodes in the machine, all the memory is close to this
* object, so only the first bit is set in \p complete_nodeset.
*
* \note Its value must not be changed, hwloc_bitmap_dup() must be used instead.
*/
struct hwloc_info_s *infos; /**< \brief Array of stringified info type=name. */
unsigned infos_count; /**< \brief Size of infos array. */
/* misc */
void *userdata; /**< \brief Application-given private data pointer,
* initialized to \c NULL, use it as you wish.
* See hwloc_topology_set_userdata_export_callback() in hwloc/export.h
* if you wish to export this field to XML. */
hwloc_uint64_t gp_index; /**< \brief Global persistent index.
* Generated by hwloc, unique across the topology (contrary to os_index)
* and persistent across topology changes (contrary to logical_index).
* Mostly used internally, but could also be used by application to identify objects.
*/
};
/**
* \brief Convenience typedef; a pointer to a struct hwloc_obj.
*/
typedef struct hwloc_obj * hwloc_obj_t;
/** \brief Object type-specific Attributes */
union hwloc_obj_attr_u {
/** \brief NUMA node-specific Object Attributes */
struct hwloc_numanode_attr_s {
hwloc_uint64_t local_memory; /**< \brief Local memory (in bytes) */
unsigned page_types_len; /**< \brief Size of array \p page_types */
/** \brief Array of local memory page types, \c NULL if no local memory and \p page_types is 0.
*
* The array is sorted by increasing \p size fields.
* It contains \p page_types_len slots.
*/
struct hwloc_memory_page_type_s {
hwloc_uint64_t size; /**< \brief Size of pages */
hwloc_uint64_t count; /**< \brief Number of pages of this size */
} * page_types;
} numanode;
/** \brief Cache-specific Object Attributes */
struct hwloc_cache_attr_s {
hwloc_uint64_t size; /**< \brief Size of cache in bytes */
unsigned depth; /**< \brief Depth of cache (e.g., L1, L2, ...etc.) */
unsigned linesize; /**< \brief Cache-line size in bytes. 0 if unknown */
int associativity; /**< \brief Ways of associativity,
* -1 if fully associative, 0 if unknown */
hwloc_obj_cache_type_t type; /**< \brief Cache type */
} cache;
/** \brief Group-specific Object Attributes */
struct hwloc_group_attr_s {
unsigned depth; /**< \brief Depth of group object.
* It may change if intermediate Group objects are added. */
unsigned kind; /**< \brief Internally-used kind of group. */
unsigned subkind; /**< \brief Internally-used subkind to distinguish different levels of groups with same kind */
unsigned char dont_merge; /**< \brief Flag preventing groups from being automatically merged with identical parent or children. */
} group;
/** \brief PCI Device specific Object Attributes */
struct hwloc_pcidev_attr_s {
#ifndef HWLOC_HAVE_32BITS_PCI_DOMAIN
unsigned short domain; /* Only 16bits PCI domains are supported by default */
#else
unsigned int domain; /* 32bits PCI domain support break the library ABI, hence it's disabled by default */
#endif
unsigned char bus, dev, func;
unsigned short class_id;
unsigned short vendor_id, device_id, subvendor_id, subdevice_id;
unsigned char revision;
float linkspeed; /* in GB/s */
} pcidev;
/** \brief Bridge specific Object Attribues */
struct hwloc_bridge_attr_s {
union {
struct hwloc_pcidev_attr_s pci;
} upstream;
hwloc_obj_bridge_type_t upstream_type;
union {
struct {
#ifndef HWLOC_HAVE_32BITS_PCI_DOMAIN
unsigned short domain; /* Only 16bits PCI domains are supported by default */
#else
unsigned int domain; /* 32bits PCI domain support break the library ABI, hence it's disabled by default */
#endif
unsigned char secondary_bus, subordinate_bus;
} pci;
} downstream;
hwloc_obj_bridge_type_t downstream_type;
unsigned depth;
} bridge;
/** \brief OS Device specific Object Attributes */
struct hwloc_osdev_attr_s {
hwloc_obj_osdev_type_t type;
} osdev;
};
/** \brief Object info
*
* \sa hwlocality_info_attr
*/
struct hwloc_info_s {
char *name; /**< \brief Info name */
char *value; /**< \brief Info value */
};
/** @} */
/** \defgroup hwlocality_creation Topology Creation and Destruction
* @{
*/
struct hwloc_topology;
/** \brief Topology context
*
* To be initialized with hwloc_topology_init() and built with hwloc_topology_load().
*/
typedef struct hwloc_topology * hwloc_topology_t;
/** \brief Allocate a topology context.
*
* \param[out] topologyp is assigned a pointer to the new allocated context.
*
* \return 0 on success, -1 on error.
*/
HWLOC_DECLSPEC int hwloc_topology_init (hwloc_topology_t *topologyp);
/** \brief Build the actual topology
*
* Build the actual topology once initialized with hwloc_topology_init() and
* tuned with \ref hwlocality_configuration and \ref hwlocality_setsource routines.
* No other routine may be called earlier using this topology context.
*
* \param topology is the topology to be loaded with objects.
*
* \return 0 on success, -1 on error.
*
* \note On failure, the topology is reinitialized. It should be either
* destroyed with hwloc_topology_destroy() or configured and loaded again.
*
* \note This function may be called only once per topology.
*
* \note The binding of the current thread or process may temporarily change
* during this call but it will be restored before it returns.
*
* \sa hwlocality_configuration and hwlocality_setsource
*/
HWLOC_DECLSPEC int hwloc_topology_load(hwloc_topology_t topology);
/** \brief Terminate and free a topology context
*
* \param topology is the topology to be freed
*/
HWLOC_DECLSPEC void hwloc_topology_destroy (hwloc_topology_t topology);
/** \brief Duplicate a topology.
*
* The entire topology structure as well as its objects
* are duplicated into a new one.
*
* This is useful for keeping a backup while modifying a topology.
*
* \note Object userdata is not duplicated since hwloc does not know what it point to.
* The objects of both old and new topologies will point to the same userdata.
*/
HWLOC_DECLSPEC int hwloc_topology_dup(hwloc_topology_t *newtopology, hwloc_topology_t oldtopology);
/** \brief Verify that the topology is compatible with the current hwloc library.
*
* This is useful when using the same topology structure (in memory)
* in different libraries that may use different hwloc installations
* (for instance if one library embeds a specific version of hwloc,
* while another library uses a default system-wide hwloc installation).
*
* If all libraries/programs use the same hwloc installation, this function
* always returns success.
*
* \return \c 0 on success.
*
* \return \c -1 with \p errno set to \c EINVAL if incompatible.
*
* \note If sharing between processes with hwloc_shmem_topology_write(),
* the relevant check is already performed inside hwloc_shmem_topology_adopt().
*/
HWLOC_DECLSPEC int hwloc_topology_abi_check(hwloc_topology_t topology);
/** \brief Run internal checks on a topology structure
*
* The program aborts if an inconsistency is detected in the given topology.
*
* \param topology is the topology to be checked
*
* \note This routine is only useful to developers.
*
* \note The input topology should have been previously loaded with
* hwloc_topology_load().
*/
HWLOC_DECLSPEC void hwloc_topology_check(hwloc_topology_t topology);
/** @} */
/** \defgroup hwlocality_levels Object levels, depths and types
* @{
*
* Be sure to see the figure in \ref termsanddefs that shows a
* complete topology tree, including depths, child/sibling/cousin
* relationships, and an example of an asymmetric topology where one
* package has fewer caches than its peers.
*/
/** \brief Get the depth of the hierarchical tree of objects.
*
* This is the depth of ::HWLOC_OBJ_PU objects plus one.
*
* \note NUMA nodes, I/O and Misc objects are ignored when computing
* the depth of the tree (they are placed on special levels).
*/
HWLOC_DECLSPEC int hwloc_topology_get_depth(hwloc_topology_t __hwloc_restrict topology) __hwloc_attribute_pure;
/** \brief Returns the depth of objects of type \p type.
*
* If no object of this type is present on the underlying architecture, or if
* the OS doesn't provide this kind of information, the function returns
* ::HWLOC_TYPE_DEPTH_UNKNOWN.
*
* If type is absent but a similar type is acceptable, see also
* hwloc_get_type_or_below_depth() and hwloc_get_type_or_above_depth().
*
* If ::HWLOC_OBJ_GROUP is given, the function may return ::HWLOC_TYPE_DEPTH_MULTIPLE
* if multiple levels of Groups exist.
*
* If a NUMA node, I/O or Misc object type is given, the function returns a virtual
* value because these objects are stored in special levels that are not CPU-related.
* This virtual depth may be passed to other hwloc functions such as
* hwloc_get_obj_by_depth() but it should not be considered as an actual
* depth by the application. In particular, it should not be compared with
* any other object depth or with the entire topology depth.
* \sa hwloc_get_memory_parents_depth().
*
* \sa hwloc_type_sscanf_as_depth() for returning the depth of objects
* whose type is given as a string.
*/
HWLOC_DECLSPEC int hwloc_get_type_depth (hwloc_topology_t topology, hwloc_obj_type_t type);
enum hwloc_get_type_depth_e {
HWLOC_TYPE_DEPTH_UNKNOWN = -1, /**< \brief No object of given type exists in the topology. \hideinitializer */
HWLOC_TYPE_DEPTH_MULTIPLE = -2, /**< \brief Objects of given type exist at different depth in the topology (only for Groups). \hideinitializer */
HWLOC_TYPE_DEPTH_NUMANODE = -3, /**< \brief Virtual depth for NUMA nodes. \hideinitializer */
HWLOC_TYPE_DEPTH_BRIDGE = -4, /**< \brief Virtual depth for bridge object level. \hideinitializer */
HWLOC_TYPE_DEPTH_PCI_DEVICE = -5, /**< \brief Virtual depth for PCI device object level. \hideinitializer */
HWLOC_TYPE_DEPTH_OS_DEVICE = -6, /**< \brief Virtual depth for software device object level. \hideinitializer */
HWLOC_TYPE_DEPTH_MISC = -7, /**< \brief Virtual depth for Misc object. \hideinitializer */
HWLOC_TYPE_DEPTH_MEMCACHE = -8 /**< \brief Virtual depth for MemCache object. \hideinitializer */
};
/** \brief Return the depth of parents where memory objects are attached.
*
* Memory objects have virtual negative depths because they are not part of
* the main CPU-side hierarchy of objects. This depth should not be compared
* with other level depths.
*
* If all Memory objects are attached to Normal parents at the same depth,
* this parent depth may be compared to other as usual, for instance
* for knowing whether NUMA nodes is attached above or below Packages.
*
* \return The depth of Normal parents of all memory children
* if all these parents have the same depth. For instance the depth of
* the Package level if all NUMA nodes are attached to Package objects.
*
* \return ::HWLOC_TYPE_DEPTH_MULTIPLE if Normal parents of all
* memory children do not have the same depth. For instance if some
* NUMA nodes are attached to Packages while others are attached to
* Groups.
*/
HWLOC_DECLSPEC int hwloc_get_memory_parents_depth (hwloc_topology_t topology);
/** \brief Returns the depth of objects of type \p type or below
*
* If no object of this type is present on the underlying architecture, the
* function returns the depth of the first "present" object typically found
* inside \p type.
*
* This function is only meaningful for normal object types.
* If a memory, I/O or Misc object type is given, the corresponding virtual
* depth is always returned (see hwloc_get_type_depth()).
*
* May return ::HWLOC_TYPE_DEPTH_MULTIPLE for ::HWLOC_OBJ_GROUP just like
* hwloc_get_type_depth().
*/
static __hwloc_inline int
hwloc_get_type_or_below_depth (hwloc_topology_t topology, hwloc_obj_type_t type) __hwloc_attribute_pure;
/** \brief Returns the depth of objects of type \p type or above
*
* If no object of this type is present on the underlying architecture, the
* function returns the depth of the first "present" object typically
* containing \p type.
*
* This function is only meaningful for normal object types.
* If a memory, I/O or Misc object type is given, the corresponding virtual
* depth is always returned (see hwloc_get_type_depth()).
*
* May return ::HWLOC_TYPE_DEPTH_MULTIPLE for ::HWLOC_OBJ_GROUP just like
* hwloc_get_type_depth().
*/
static __hwloc_inline int
hwloc_get_type_or_above_depth (hwloc_topology_t topology, hwloc_obj_type_t type) __hwloc_attribute_pure;
/** \brief Returns the type of objects at depth \p depth.
*
* \p depth should between 0 and hwloc_topology_get_depth()-1,
* or a virtual depth such as ::HWLOC_TYPE_DEPTH_NUMANODE.
*
* \return (hwloc_obj_type_t)-1 if depth \p depth does not exist.
*/
HWLOC_DECLSPEC hwloc_obj_type_t hwloc_get_depth_type (hwloc_topology_t topology, int depth) __hwloc_attribute_pure;
/** \brief Returns the width of level at depth \p depth.
*/
HWLOC_DECLSPEC unsigned hwloc_get_nbobjs_by_depth (hwloc_topology_t topology, int depth) __hwloc_attribute_pure;
/** \brief Returns the width of level type \p type
*
* If no object for that type exists, 0 is returned.
* If there are several levels with objects of that type, -1 is returned.
*/
static __hwloc_inline int
hwloc_get_nbobjs_by_type (hwloc_topology_t topology, hwloc_obj_type_t type) __hwloc_attribute_pure;
/** \brief Returns the top-object of the topology-tree.
*
* Its type is ::HWLOC_OBJ_MACHINE.
*/
static __hwloc_inline hwloc_obj_t
hwloc_get_root_obj (hwloc_topology_t topology) __hwloc_attribute_pure;
/** \brief Returns the topology object at logical index \p idx from depth \p depth */
HWLOC_DECLSPEC hwloc_obj_t hwloc_get_obj_by_depth (hwloc_topology_t topology, int depth, unsigned idx) __hwloc_attribute_pure;
/** \brief Returns the topology object at logical index \p idx with type \p type
*
* If no object for that type exists, \c NULL is returned.
* If there are several levels with objects of that type (::HWLOC_OBJ_GROUP),
* \c NULL is returned and the caller may fallback to hwloc_get_obj_by_depth().
*/
static __hwloc_inline hwloc_obj_t
hwloc_get_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type, unsigned idx) __hwloc_attribute_pure;
/** \brief Returns the next object at depth \p depth.
*
* If \p prev is \c NULL, return the first object at depth \p depth.
*/
static __hwloc_inline hwloc_obj_t
hwloc_get_next_obj_by_depth (hwloc_topology_t topology, int depth, hwloc_obj_t prev);
/** \brief Returns the next object of type \p type.
*
* If \p prev is \c NULL, return the first object at type \p type. If
* there are multiple or no depth for given type, return \c NULL and
* let the caller fallback to hwloc_get_next_obj_by_depth().
*/
static __hwloc_inline hwloc_obj_t
hwloc_get_next_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type,
hwloc_obj_t prev);
/** @} */
/** \defgroup hwlocality_object_strings Converting between Object Types and Attributes, and Strings
* @{
*/
/** \brief Return a constant stringified object type.
*
* This function is the basic way to convert a generic type into a string.
* The output string may be parsed back by hwloc_type_sscanf().
*
* hwloc_obj_type_snprintf() may return a more precise output for a specific
* object, but it requires the caller to provide the output buffer.
*/
HWLOC_DECLSPEC const char * hwloc_obj_type_string (hwloc_obj_type_t type) __hwloc_attribute_const;
/** \brief Stringify the type of a given topology object into a human-readable form.
*
* Contrary to hwloc_obj_type_string(), this function includes object-specific
* attributes (such as the Group depth, the Bridge type, or OS device type)
* in the output, and it requires the caller to provide the output buffer.
*
* The output is guaranteed to be the same for all objects of a same topology level.
*
* If \p verbose is 1, longer type names are used, e.g. L1Cache instead of L1.
*
* The output string may be parsed back by hwloc_type_sscanf().
*
* If \p size is 0, \p string may safely be \c NULL.
*
* \return the number of character that were actually written if not truncating,
* or that would have been written (not including the ending \\0).
*/
HWLOC_DECLSPEC int hwloc_obj_type_snprintf(char * __hwloc_restrict string, size_t size,
hwloc_obj_t obj,
int verbose);
/** \brief Stringify the attributes of a given topology object into a human-readable form.
*
* Attribute values are separated by \p separator.
*
* Only the major attributes are printed in non-verbose mode.
*
* If \p size is 0, \p string may safely be \c NULL.
*
* \return the number of character that were actually written if not truncating,
* or that would have been written (not including the ending \\0).
*/
HWLOC_DECLSPEC int hwloc_obj_attr_snprintf(char * __hwloc_restrict string, size_t size,
hwloc_obj_t obj, const char * __hwloc_restrict separator,
int verbose);
/** \brief Return an object type and attributes from a type string.
*
* Convert strings such as "Package" or "L1iCache" into the corresponding types.
* Matching is case-insensitive, and only the first letters are actually
* required to match.
*
* The matched object type is set in \p typep (which cannot be \c NULL).
*
* Type-specific attributes, for instance Cache type, Cache depth, Group depth,
* Bridge type or OS Device type may be returned in \p attrp.
* Attributes that are not specified in the string (for instance "Group"
* without a depth, or "L2Cache" without a cache type) are set to -1.
*
* \p attrp is only filled if not \c NULL and if its size specified in \p attrsize
* is large enough. It should be at least as large as union hwloc_obj_attr_u.
*
* \return 0 if a type was correctly identified, otherwise -1.
*
* \note This function is guaranteed to match any string returned by
* hwloc_obj_type_string() or hwloc_obj_type_snprintf().