hwlocality_sys/
lib.rs

1#![allow(non_camel_case_types, unknown_lints)]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3#![cfg_attr(docsrs, doc(cfg_hide(doc)))]
4// Last allow-by-default lint review performed as of Rust 1.72
5#![deny(
6    clippy::as_ptr_cast_mut,
7    clippy::as_underscore,
8    clippy::assertions_on_result_states,
9    clippy::bool_to_int_with_if,
10    clippy::borrow_as_ptr,
11    clippy::branches_sharing_code,
12    clippy::cargo_common_metadata,
13    clippy::case_sensitive_file_extension_comparisons,
14    clippy::cast_lossless,
15    clippy::cast_possible_truncation,
16    clippy::cast_possible_wrap,
17    clippy::cast_precision_loss,
18    clippy::cast_ptr_alignment,
19    clippy::cast_sign_loss,
20    clippy::checked_conversions,
21    clippy::clear_with_drain,
22    clippy::clone_on_ref_ptr,
23    clippy::cloned_instead_of_copied,
24    clippy::cognitive_complexity,
25    clippy::collection_is_never_read,
26    clippy::create_dir,
27    clippy::debug_assert_with_mut_call,
28    clippy::decimal_literal_representation,
29    clippy::derive_partial_eq_without_eq,
30    clippy::doc_link_with_quotes,
31    clippy::doc_markdown,
32    clippy::empty_drop,
33    clippy::empty_line_after_doc_comments,
34    clippy::empty_line_after_outer_attr,
35    clippy::empty_structs_with_brackets,
36    clippy::enum_glob_use,
37    clippy::equatable_if_let,
38    clippy::exit,
39    clippy::expl_impl_clone_on_copy,
40    clippy::explicit_deref_methods,
41    clippy::explicit_into_iter_loop,
42    clippy::explicit_iter_loop,
43    clippy::fallible_impl_from,
44    clippy::filter_map_next,
45    clippy::flat_map_option,
46    clippy::float_cmp,
47    clippy::float_cmp_const,
48    clippy::fn_to_numeric_cast_any,
49    clippy::format_push_string,
50    clippy::from_iter_instead_of_collect,
51    clippy::get_unwrap,
52    clippy::if_not_else,
53    clippy::if_then_some_else_none,
54    clippy::implicit_clone,
55    clippy::implicit_hasher,
56    clippy::imprecise_flops,
57    clippy::index_refutable_slice,
58    clippy::inline_always,
59    clippy::invalid_upcast_comparisons,
60    clippy::iter_not_returning_iterator,
61    clippy::iter_on_empty_collections,
62    clippy::iter_on_single_items,
63    clippy::large_digit_groups,
64    clippy::large_stack_arrays,
65    clippy::large_types_passed_by_value,
66    clippy::linkedlist,
67    clippy::macro_use_imports,
68    clippy::manual_assert,
69    clippy::manual_clamp,
70    clippy::manual_instant_elapsed,
71    clippy::manual_let_else,
72    clippy::manual_ok_or,
73    clippy::manual_string_new,
74    clippy::many_single_char_names,
75    clippy::map_unwrap_or,
76    clippy::match_bool,
77    clippy::match_same_arms,
78    clippy::match_wildcard_for_single_variants,
79    clippy::mismatching_type_param_order,
80    clippy::missing_assert_message,
81    clippy::missing_docs_in_private_items,
82    clippy::missing_errors_doc,
83    clippy::missing_fields_in_debug,
84    clippy::mixed_read_write_in_expression,
85    clippy::mut_mut,
86    clippy::mutex_atomic,
87    clippy::mutex_integer,
88    clippy::naive_bytecount,
89    clippy::needless_collect,
90    clippy::needless_continue,
91    clippy::needless_for_each,
92    clippy::negative_feature_names,
93    clippy::no_mangle_with_rust_abi,
94    clippy::non_send_fields_in_send_ty,
95    clippy::nonstandard_macro_braces,
96    clippy::option_if_let_else,
97    clippy::option_option,
98    clippy::or_fun_call,
99    clippy::partial_pub_fields,
100    clippy::path_buf_push_overwrite,
101    clippy::print_stdout,
102    clippy::ptr_as_ptr,
103    clippy::ptr_cast_constness,
104    clippy::pub_without_shorthand,
105    clippy::range_minus_one,
106    clippy::range_plus_one,
107    clippy::rc_buffer,
108    clippy::rc_mutex,
109    clippy::redundant_clone,
110    clippy::redundant_closure_for_method_calls,
111    clippy::redundant_feature_names,
112    clippy::ref_option_ref,
113    clippy::ref_patterns,
114    clippy::rest_pat_in_fully_bound_structs,
115    clippy::same_functions_in_if_condition,
116    clippy::self_named_module_files,
117    clippy::semicolon_inside_block,
118    clippy::semicolon_outside_block,
119    clippy::significant_drop_in_scrutinee,
120    clippy::similar_names,
121    clippy::single_match_else,
122    clippy::str_to_string,
123    clippy::string_add,
124    clippy::string_lit_as_bytes,
125    clippy::suboptimal_flops,
126    clippy::suspicious_operation_groupings,
127    clippy::tests_outside_test_module,
128    clippy::todo,
129    clippy::too_many_lines,
130    clippy::trailing_empty_array,
131    clippy::transmute_ptr_to_ptr,
132    clippy::trivial_regex,
133    clippy::trivially_copy_pass_by_ref,
134    clippy::try_err,
135    clippy::type_repetition_in_bounds,
136    clippy::undocumented_unsafe_blocks,
137    clippy::unicode_not_nfc,
138    clippy::unimplemented,
139    clippy::uninlined_format_args,
140    clippy::unnecessary_box_returns,
141    clippy::unnecessary_join,
142    clippy::unnecessary_safety_comment,
143    clippy::unnecessary_safety_doc,
144    clippy::unnecessary_self_imports,
145    clippy::unnecessary_struct_initialization,
146    clippy::unnecessary_wraps,
147    clippy::unneeded_field_pattern,
148    clippy::unnested_or_patterns,
149    clippy::unreadable_literal,
150    clippy::unsafe_derive_deserialize,
151    clippy::unused_async,
152    clippy::unused_peekable,
153    clippy::unused_rounding,
154    clippy::unwrap_used,
155    clippy::use_self,
156    clippy::used_underscore_binding,
157    clippy::useless_let_if_seq,
158    clippy::verbose_bit_mask,
159    clippy::verbose_file_reads,
160    clippy::wildcard_dependencies,
161    clippy::wildcard_enum_match_arm,
162    clippy::wildcard_imports,
163    clippy::zero_sized_map_values,
164    invalid_reference_casting,
165    macro_use_extern_crate,
166    missing_abi,
167    missing_copy_implementations,
168    missing_debug_implementations,
169    // FIXME: Bring back missing_docs,
170    non_ascii_idents,
171    rust_2018_compatibility,
172    rust_2021_compatibility,
173    rustdoc::bare_urls,
174    rustdoc::broken_intra_doc_links,
175    rustdoc::invalid_codeblock_attributes,
176    rustdoc::invalid_html_tags,
177    rustdoc::invalid_rust_codeblocks,
178    rustdoc::missing_crate_level_docs,
179    rustdoc::private_intra_doc_links,
180    rustdoc::unescaped_backticks,
181    trivial_casts,
182    trivial_numeric_casts,
183    unreachable_pub,
184    unsafe_op_in_unsafe_fn,
185    variant_size_differences
186)]
187#![warn(
188    clippy::dbg_macro,
189    clippy::print_stderr,
190    clippy::use_debug,
191    future_incompatible,
192    keyword_idents,
193    let_underscore,
194    meta_variable_misuse,
195    noop_method_call,
196    rust_2018_idioms,
197    unused
198)]
199#![doc = include_str!("../README.md")]
200
201#[cfg(target_os = "linux")]
202use libc::pid_t;
203#[cfg(doc)]
204use std::panic::UnwindSafe;
205use std::{
206    cell::UnsafeCell,
207    ffi::{c_char, c_float, c_int, c_uchar, c_uint, c_ulong, c_ushort, c_void},
208    fmt::Debug,
209    marker::{PhantomData, PhantomPinned},
210    panic::RefUnwindSafe,
211    ptr,
212};
213
214// === Things which are not part of the main hwloc documentation
215
216/// pid_t placeholder for rustdoc
217#[cfg(all(doc, not(target_os = "linux")))]
218pub type pid_t = c_int;
219
220/// Rust model of a C incomplete type (struct declaration without a definition)
221///
222/// From <https://doc.rust-lang.org/nomicon/ffi.html#representing-opaque-structs>
223///
224/// This type purposely implements no traits, not even Debug, because you should
225/// never, ever deal with it directly, only with raw pointers to it that you
226/// blindly pass to the hwloc API.
227#[repr(C)]
228struct IncompleteType {
229    /// Stolen from
230    /// <https://doc.rust-lang.org/nomicon/ffi.html#representing-opaque-structs>
231    ///
232    /// No idea why the original author thought the `_marker` field is not
233    /// sufficient, but the authors of this book tend to be more well-versed
234    /// into compiler black magic than I do, so let's keep it that way...
235    _data: [u8; 0],
236
237    /// Ensures `RefUnwindSafe`, `Send`, `Sync`, `Unpin` and `UndindSafe` are
238    /// not implemented
239    _marker: PhantomData<(*mut u8, PhantomPinned, &'static UnsafeCell<u8>)>,
240}
241
242/// Thread identifier (OS-specific)
243///
244/// This is `HANDLE` on Windows and `libc::pthread_t` on most other platforms,
245/// except on musl where it must be hardcoded to `c_ulong` to [preserve
246/// sanity](https://elixir.bootlin.com/musl/v1.2.4/source/include/alltypes.h.in#L53).
247#[cfg(target_os = "windows")]
248#[cfg_attr(docsrs, doc(cfg(all())))]
249pub type hwloc_thread_t = windows_sys::Win32::Foundation::HANDLE;
250
251/// Process identifier (OS-specific)
252///
253/// This is `u32` on Windows and `libc::pid_t` on all other platforms.
254#[cfg(target_os = "windows")]
255#[cfg_attr(docsrs, doc(cfg(all())))]
256pub type hwloc_pid_t = u32;
257
258/// Thread identifier (OS-specific)
259///
260/// This is `HANDLE` on Windows and `libc::pthread_t` on most other platforms,
261/// except on musl where it must be hardcoded to `c_ulong` to [preserve
262/// sanity](https://elixir.bootlin.com/musl/v1.2.4/source/include/alltypes.h.in#L53)
263#[cfg(not(any(target_os = "windows", target_env = "musl")))]
264#[cfg_attr(docsrs, doc(cfg(all())))]
265pub type hwloc_thread_t = libc::pthread_t;
266
267/// Thread identifier (OS-specific)
268///
269/// This is `HANDLE` on Windows and `libc::pthread_t` on most other platforms,
270/// except on musl where it must be hardcoded to `c_ulong` to [preserve
271/// sanity](https://elixir.bootlin.com/musl/v1.2.4/source/include/alltypes.h.in#L53)
272#[cfg(target_env = "musl")]
273#[cfg_attr(docsrs, doc(cfg(all())))]
274pub type hwloc_thread_t = c_ulong;
275
276/// Process identifier (OS-specific)
277///
278/// This is `u32` on Windows and `libc::pid_t` on all other platforms.
279#[cfg(not(target_os = "windows"))]
280#[cfg_attr(docsrs, doc(cfg(all())))]
281pub type hwloc_pid_t = libc::pid_t;
282
283// === Object Sets: https://hwloc.readthedocs.io/en/stable/group__hwlocality__object__sets.html
284
285/// A non-modifiable [`hwloc_cpuset_t`]
286pub type hwloc_const_cpuset_t = hwloc_const_bitmap_t;
287
288/// A non-modifiable [`hwloc_nodeset_t`]
289pub type hwloc_const_nodeset_t = hwloc_const_bitmap_t;
290
291/// A CPU set is a bitmap whose bits are set according to CPU physical OS indexes
292///
293/// It may be consulted and modified with the bitmap API as any [`hwloc_bitmap_t`].
294pub type hwloc_cpuset_t = hwloc_bitmap_t;
295
296/// A node set is a bitmap whose bits are set according to NUMA memory node
297/// physical OS indexes
298///
299/// It may be consulted and modified with the bitmap API as any
300/// [`hwloc_bitmap_t`].
301///
302/// When binding memory on a system without any NUMA node, the single main
303/// memory bank is considered as NUMA node `#0`.
304///
305/// See also [Converting between CPU sets and node
306/// sets](https://hwloc.readthedocs.io/en/stable/group__hwlocality__helper__nodeset__convert.html).
307pub type hwloc_nodeset_t = hwloc_bitmap_t;
308
309// === Object Types: https://hwloc.readthedocs.io/en/stable/group__hwlocality__object__types.html
310
311/// Value returned by [`hwloc_compare_types()`] when types can not be compared
312pub const HWLOC_TYPE_UNORDERED: c_int = c_int::MAX;
313
314/// Type of one side (upstream or downstream) of an I/O bridge
315///
316/// We can't use Rust enums to model C enums in FFI because that results in
317/// undefined behavior if the C API gets new enum variants and sends them to us.
318#[doc(alias = "hwloc_obj_bridge_type_e")]
319pub type hwloc_obj_bridge_type_t = c_uint;
320
321/// Host-side of a bridge, only possible upstream
322pub const HWLOC_OBJ_BRIDGE_HOST: hwloc_obj_bridge_type_t = 0;
323
324/// PCI-side of a bridge
325pub const HWLOC_OBJ_BRIDGE_PCI: hwloc_obj_bridge_type_t = 1;
326
327/// Cache type
328///
329/// We can't use Rust enums to model C enums in FFI because that results in
330/// undefined behavior if the C API gets new enum variants and sends them to us.
331#[doc(alias = "hwloc_obj_cache_type_e")]
332pub type hwloc_obj_cache_type_t = c_uint;
333
334/// Unified cache
335pub const HWLOC_OBJ_CACHE_UNIFIED: hwloc_obj_cache_type_t = 0;
336
337/// Data cache
338pub const HWLOC_OBJ_CACHE_DATA: hwloc_obj_cache_type_t = 1;
339
340/// Instruction cache (filtered out by default)
341pub const HWLOC_OBJ_CACHE_INSTRUCTION: hwloc_obj_cache_type_t = 2;
342
343/// Type of a OS device
344///
345/// We can't use Rust enums to model C enums in FFI because that results in
346/// undefined behavior if the C API gets new enum variants and sends them to us.
347#[doc(alias = "hwloc_obj_osdev_type_e")]
348pub type hwloc_obj_osdev_type_t = c_uint;
349
350/// Operating system storage device (e.g. block)
351///
352/// For instance "sda" or "dax2.0" on Linux.
353#[doc(alias = "HWLOC_OBJ_OSDEV_BLOCK")]
354pub const HWLOC_OBJ_OSDEV_STORAGE: hwloc_obj_osdev_type_t = 0;
355
356/// Operating system GPU device
357///
358/// For instance ":0.0" for a GL display, "card0" for a Linux DRM device.
359pub const HWLOC_OBJ_OSDEV_GPU: hwloc_obj_osdev_type_t = 1;
360
361/// Operating system network device
362///
363/// For instance the "eth0" interface on Linux.
364pub const HWLOC_OBJ_OSDEV_NETWORK: hwloc_obj_osdev_type_t = 2;
365
366#[allow(clippy::doc_markdown)]
367/// Operating system openfabrics device
368///
369/// For instance the "mlx4_0" InfiniBand HCA, "hfi1_0" Omni-Path interface,
370/// or "bxi0" Atos/Bull BXI HCA on Linux.
371pub const HWLOC_OBJ_OSDEV_OPENFABRICS: hwloc_obj_osdev_type_t = 3;
372
373#[allow(clippy::doc_markdown)]
374/// Operating system dma engine device
375///
376/// For instance the "dma0chan0" DMA channel on Linux.
377pub const HWLOC_OBJ_OSDEV_DMA: hwloc_obj_osdev_type_t = 4;
378
379#[allow(clippy::doc_markdown)]
380/// Operating system co-processor device
381///
382/// For instance "opencl0d0" for a OpenCL device, "cuda0" for a CUDA device.
383pub const HWLOC_OBJ_OSDEV_COPROC: hwloc_obj_osdev_type_t = 5;
384
385#[allow(clippy::doc_markdown)]
386/// Operating system memory device
387///
388/// For instance DAX file for non-volatile or high-bandwidth memory, like
389/// "dax2.0" on Linux.
390#[cfg(feature = "hwloc-3_0_0")]
391pub const HWLOC_OBJ_OSDEV_MEMORY: hwloc_obj_osdev_type_t = 6;
392
393/// Type of topology object
394///
395/// We can't use Rust enums to model C enums in FFI because that results in
396/// undefined behavior if the C API gets new enum variants and sends them to us.
397#[doc(alias = "hwloc_obj_type_e")]
398pub type hwloc_obj_type_t = c_uint;
399
400/// The root object, a set of processors and memory with cache coherency
401///
402/// This type is always used for the root object of a topology, and never
403/// used anywhere else. Hence it never has a parent.
404pub const HWLOC_OBJ_MACHINE: hwloc_obj_type_t = 0;
405
406/// Physical package, what goes into a physical motherboard socket
407///
408/// Usually contains multiple cores, and possibly some dies.
409pub const HWLOC_OBJ_PACKAGE: hwloc_obj_type_t = 1;
410
411/// A computation unit (may be shared by several PUs aka logical processors)
412pub const HWLOC_OBJ_CORE: hwloc_obj_type_t = 2;
413
414/// Processing Unit, or (Logical) Processor
415///
416/// An execution unit (may share a core with some other logical
417/// processors, e.g. in the case of an SMT core).
418///
419/// This is the leaf of the CPU resource hierarchy, it can only have Misc
420/// children.
421///
422/// It is always reported even when other objects are not detected. However,
423/// an incorrect number of PUs may be reported if
424/// [`hwloc_topology_discovery_support::pu`] is not set.
425pub const HWLOC_OBJ_PU: hwloc_obj_type_t = 3;
426
427/// Level 1 Data (or Unified) Cache
428pub const HWLOC_OBJ_L1CACHE: hwloc_obj_type_t = 4;
429
430/// Level 2 Data (or Unified) Cache
431pub const HWLOC_OBJ_L2CACHE: hwloc_obj_type_t = 5;
432
433/// Level 3 Data (or Unified) Cache
434pub const HWLOC_OBJ_L3CACHE: hwloc_obj_type_t = 6;
435
436/// Level 4 Data (or Unified) Cache
437pub const HWLOC_OBJ_L4CACHE: hwloc_obj_type_t = 7;
438
439/// Level 5 Data (or Unified) Cache
440// NOTE: If hwloc adds more cache levels, update the hwlocality::cache module accordingly
441pub const HWLOC_OBJ_L5CACHE: hwloc_obj_type_t = 8;
442
443/// Level 1 Instruction cache (filtered out by default)
444pub const HWLOC_OBJ_L1ICACHE: hwloc_obj_type_t = 9;
445
446/// Level 2 Instruction cache (filtered out by default)
447pub const HWLOC_OBJ_L2ICACHE: hwloc_obj_type_t = 10;
448
449/// Level 3 Instruction cache (filtered out by default)
450pub const HWLOC_OBJ_L3ICACHE: hwloc_obj_type_t = 11;
451
452/// Group object
453///
454/// Objects which do not fit in the above but are detected by hwloc and
455/// are useful to take into account for affinity. For instance, some
456/// operating systems expose their arbitrary processors aggregation this
457/// way. And hwloc may insert such objects to group NUMA nodes according
458/// to their distances. See also [What are these Group objects in my
459/// topology?](https://hwloc.readthedocs.io/en/stable/faq.html#faq_groups).
460///
461/// These objects are ignored when they do not bring any structure (see
462/// [`HWLOC_TYPE_FILTER_KEEP_STRUCTURE`])
463pub const HWLOC_OBJ_GROUP: hwloc_obj_type_t = 12;
464
465/// NUMA node
466///
467/// An object that contains memory that is directly and byte-accessible to
468/// the host processors. It is usually close to some cores
469/// (the corresponding objects are descendants of the NUMA node object in
470/// the hwloc tree).
471///
472/// This is the smallest object representing Memory resources, it cannot
473/// have any child except Misc objects. However it may have Memory-side
474/// cache parents.
475///
476/// There is always at least one such object in the topology even if the machine
477/// is not NUMA. However, an incorrect number of NUMA nodes may be reported if
478/// [`hwloc_topology_discovery_support::numa`] is not set.
479///
480/// Memory objects are not listed in the main children list, but rather in the
481/// dedicated Memory children list. They also have a special depth
482/// [`HWLOC_TYPE_DEPTH_NUMANODE`] instead of a normal depth just like other
483/// objects in the main tree.
484pub const HWLOC_OBJ_NUMANODE: hwloc_obj_type_t = 13;
485
486/// Bridge (filtered out by default)
487///
488/// Any bridge that connects the host or an I/O bus, to another I/O bus.
489///
490/// Bridges are not added to the topology unless their filtering is changed
491/// (see [`hwloc_topology_set_type_filter()`] and
492/// [`hwloc_topology_set_io_types_filter()`]).
493///
494/// I/O objects are not listed in the main children list, but rather in the
495/// dedicated Memory children list. They have NULL CPU and node sets. They
496/// also have a special depth [`HWLOC_TYPE_DEPTH_BRIDGE`] instead of a normal
497/// depth just like other objects in the main tree.
498pub const HWLOC_OBJ_BRIDGE: hwloc_obj_type_t = 14;
499
500/// PCI device (filtered out by default)
501///
502/// PCI devices are not added to the topology unless their filtering is
503/// changed (see [`hwloc_topology_set_type_filter()`] and
504/// [`hwloc_topology_set_io_types_filter()`]).
505///
506/// I/O objects are not listed in the main children list, but rather in the
507/// dedicated I/O children list. They have NULL CPU and node sets. They also
508/// have a special depth [`HWLOC_TYPE_DEPTH_PCI_DEVICE`] instead of a normal
509/// depth just like other objects in the main tree.
510pub const HWLOC_OBJ_PCI_DEVICE: hwloc_obj_type_t = 15;
511
512/// Operating system device (filtered out by default)
513///
514/// OS devices are not added to the topology unless their filtering is
515/// changed (see [`hwloc_topology_set_type_filter()`] and
516/// [`hwloc_topology_set_io_types_filter()`]).
517///
518/// I/O objects are not listed in the main children list, but rather in the
519/// dedicated I/O children list. They have NULL CPU and node sets. They also
520/// have a special depth [`HWLOC_TYPE_DEPTH_OS_DEVICE`] instead of a normal
521/// depth just like other objects in the main tree.
522pub const HWLOC_OBJ_OS_DEVICE: hwloc_obj_type_t = 16;
523
524/// Miscellaneous object (filtered out by default)
525///
526/// Objects without particular meaning, that can e.g. be added by the
527/// application for its own use, or by hwloc for miscellaneous objects such
528/// as memory modules (DIMMs).
529///
530/// They are not added to the topology unless their filtering is
531/// changed (see [`hwloc_topology_set_type_filter()`]).
532///
533/// Misc objects have no CPU and node sets, and may only have other Misc objects
534/// as children. They are not part of the main children list, but rather reside
535/// in the dedicated Misc children list. They have NULL CPU and node sets.
536/// They also have a special depth [`HWLOC_TYPE_DEPTH_MISC`] instead of a normal
537/// depth just like other objects in the main tree.
538pub const HWLOC_OBJ_MISC: hwloc_obj_type_t = 17;
539
540/// Memory-side cache (filtered out by default)
541///
542/// A cache in front of a specific NUMA node. This object always has at
543/// least one NUMA node as a memory child.
544///
545/// Memory objects are not listed in the main children list, but rather in
546/// the dedicated Memory children list. They also have a special depth
547/// [`HWLOC_TYPE_DEPTH_MEMCACHE`] instead of a normal depth just like other
548/// objects in the main tree.
549#[cfg(feature = "hwloc-2_1_0")]
550pub const HWLOC_OBJ_MEMCACHE: hwloc_obj_type_t = 18;
551
552/// Die within a physical package
553///
554/// A subpart of the physical package, that contains multiple cores.
555#[cfg(feature = "hwloc-2_1_0")]
556pub const HWLOC_OBJ_DIE: hwloc_obj_type_t = 19;
557
558// === Object Structure and Attributes: https://hwloc.readthedocs.io/en/stable/group__hwlocality__objects.html
559
560/// Hardware topology object
561///
562/// This type does not implement [`Default`] because hwloc all but guarantees
563/// that some inner pointers of this struct will not be null.
564#[derive(Copy, Clone, Debug)]
565#[repr(C)]
566pub struct hwloc_obj {
567    /// Type of object
568    #[doc(alias = "hwloc_obj::type")]
569    pub ty: hwloc_obj_type_t,
570
571    /// Subtype string to better describe the type field
572    ///
573    /// See <https://hwloc.readthedocs.io/en/stable/attributes.html#attributes_normal>
574    /// for a list of subtype strings that hwloc can emit.
575    pub subtype: *mut c_char,
576
577    /// The OS-provided physical index number
578    ///
579    /// It is not guaranteed unique across the entire machine,
580    /// except for PUs and NUMA nodes.
581    ///
582    /// Set to [`HWLOC_UNKNOWN_INDEX`] if unknown or irrelevant for this object.
583    pub os_index: c_uint,
584
585    /// Object-specific name, if any
586    ///
587    /// Mostly used for identifying OS devices and Misc objects where a name
588    /// string is more useful than numerical indices.
589    pub name: *mut c_char,
590
591    /// Total memory (in bytes) in NUMA nodes below this object
592    ///
593    /// May not be accurate if
594    /// [`hwloc_topology_discovery_support::numa_memory`] is not set.
595    pub total_memory: u64,
596
597    /// Object type-specific attributes, if any
598    pub attr: *mut hwloc_obj_attr_u,
599
600    /// Vertical index in the hierarchy
601    ///
602    /// For normal objects, this is the depth of the horizontal level that
603    /// contains this object and its cousins of the same type. If the topology
604    /// is symmetric, this is equal to the parent depth plus one, and also equal
605    /// to the number of parent/child links from the root object to here.
606    ///
607    /// For special objects (NUMA nodes, I/O and Misc) that are not in the main
608    /// tree, this is a special value that is unique to their type.
609    pub depth: hwloc_get_type_depth_e,
610
611    /// Horizontal index in the whole list of similar objects, hence guaranteed
612    /// unique across the entire machine
613    ///
614    /// Could be a `cousin_rank` since it's the rank within the "cousin" list.
615    ///
616    /// Note that this index may change when restricting the topology
617    /// or when inserting a group.
618    pub logical_index: c_uint,
619
620    /// Next object of same type and depth
621    pub next_cousin: hwloc_obj_t,
622
623    /// Previous object of same type and depth
624    pub prev_cousin: hwloc_obj_t,
625
626    /// Parent object
627    ///
628    /// Only NULL for the root [`HWLOC_OBJ_MACHINE`] object.
629    pub parent: hwloc_obj_t,
630
631    /// Index in the parent's relevant child list for this object type
632    pub sibling_rank: c_uint,
633
634    /// Next object below the same parent, in the same child list
635    pub next_sibling: hwloc_obj_t,
636
637    /// Previous object below the same parent, in the same child list
638    pub prev_sibling: hwloc_obj_t,
639
640    /// Number of normal children (excluding Memory, Misc and I/O)
641    pub arity: c_uint,
642
643    /// Normal children of this object
644    pub children: *mut hwloc_obj_t,
645
646    /// First normal child of this object
647    pub first_child: hwloc_obj_t,
648
649    /// Last normal child of this object
650    pub last_child: hwloc_obj_t,
651
652    /// Truth that this object is symmetric, which means all normal children and
653    /// their children have identical subtrees
654    ///
655    /// Memory, I/O and Misc children are ignored.
656    ///
657    /// If this is true of the root object, then the topology may be exported
658    /// as a synthetic string.
659    pub symmetric_subtree: c_int,
660
661    /// Number of memory children
662    pub memory_arity: c_uint,
663
664    /// First memory child of this object
665    ///
666    /// NUMA nodes and Memory-side caches are listed here instead of in the
667    /// normal [`children`] list. See also [`hwloc_obj_type_is_memory()`].
668    ///
669    /// A memory hierarchy starts from a normal CPU-side object (e.g.
670    /// [`HWLOC_OBJ_PACKAGE`]) and ends with NUMA nodes as leaves. There might
671    /// exist some memory-side caches between them in the middle of the memory
672    /// subtree.
673    ///
674    /// [`children`]: Self::children
675    pub memory_first_child: hwloc_obj_t,
676
677    /// Number of I/O children
678    pub io_arity: c_uint,
679
680    /// First I/O child of this object
681    ///
682    /// Bridges, PCI and OS devices are listed here instead of in the normal
683    /// [`children`] list. See also [`hwloc_obj_type_is_io()`].
684    ///
685    /// [`children`]: Self::children
686    pub io_first_child: hwloc_obj_t,
687
688    /// Number of Misc children
689    pub misc_arity: c_uint,
690
691    /// First Misc child of this object
692    ///
693    /// Misc objects are listed here instead of in the normal [`children`] list.
694    ///
695    /// [`children`]: Self::children
696    pub misc_first_child: hwloc_obj_t,
697
698    /// CPUs covered by this object
699    ///
700    /// This is the set of CPUs for which there are PU objects in the
701    /// topology under this object, i.e. which are known to be physically
702    /// contained in this object and known how (the children path between this
703    /// object and the PU objects).
704    ///
705    /// If the [`HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED`] topology building
706    /// configuration flag is set, some of these CPUs may be online but not
707    /// allowed for binding, see [`hwloc_topology_get_allowed_cpuset()`].
708    ///
709    /// All objects have CPU and node sets except Misc and I/O objects, so if
710    /// you know this object to be a normal or Memory object, you can safely
711    /// assume this pointer to be non-NULL.
712    pub cpuset: hwloc_cpuset_t,
713
714    /// The complete CPU set of this object
715    ///
716    /// To the CPUs listed by [`cpuset`], this adds CPUs for which topology
717    /// information is unknown or incomplete, some offline CPUs, and CPUs that
718    /// are ignored when the [`HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED`] topology
719    /// building configuration flag is not set.
720    ///
721    /// Thus no corresponding PU object may be found in the topology, because
722    /// the precise position is undefined. It is however known that it would be
723    /// somewhere under this object.
724    ///
725    /// [`cpuset`]: Self::cpuset
726    pub complete_cpuset: hwloc_cpuset_t,
727
728    /// NUMA nodes covered by this object or containing this object.
729    ///
730    /// This is the set of NUMA nodes for which there are NUMA node objects in
731    /// the topology under or above this object, i.e. which are known to be
732    /// physically contained in this object or containing it and known how
733    /// (the children path between this object and the NUMA node objects). In
734    /// the end, these nodes are those that are close to the current object.
735    ///
736    #[cfg_attr(
737        feature = "hwloc-2_3_0",
738        doc = "With hwloc 2.3+, [`hwloc_get_local_numanode_objs()`] may be used to"
739    )]
740    #[cfg_attr(feature = "hwloc-2_3_0", doc = "list those NUMA nodes more precisely.")]
741    ///
742    /// If the [`HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED`] topology building
743    /// configuration flag is set, some of these nodes may not be allowed for
744    /// allocation, see [`hwloc_topology_get_allowed_nodeset()`].
745    ///
746    /// If there are no NUMA nodes in the machine, all the memory is close to
747    /// this object, so the nodeset is full.
748    ///
749    /// All objects have CPU and node sets except Misc and I/O objects, so if
750    /// you know this object to be a normal or Memory object, you can safely
751    /// assume this pointer to be non-NULL.
752    pub nodeset: hwloc_nodeset_t,
753
754    /// The complete NUMA node set of this object
755    ///
756    /// To the nodes listed by [`nodeset`], this adds nodes for which topology
757    /// information is unknown or incomplete, some offline nodes, and nodes
758    /// that are ignored when the
759    /// [`HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED`] topology building
760    /// configuration flag is not set.
761    ///
762    /// Thus no corresponding `NUMANode` object may be found in the topology,
763    /// because the precise position is undefined. It is however known that it
764    /// would be somewhere under this object.
765    ///
766    /// If there are no NUMA nodes in the machine, all the memory is close to
767    /// this object, so `complete_nodeset` is full.
768    ///
769    /// [`nodeset`]: Self::nodeset
770    pub complete_nodeset: hwloc_nodeset_t,
771
772    /// Complete list of (key, value) textual info pairs
773    ///
774    /// hwloc defines [a number of standard object info attribute names with
775    /// associated semantics](https://hwloc.readthedocs.io/en/stable/attributes.html#attributes_info).
776    ///
777    /// Beware that hwloc allows multiple informations with the same key to
778    /// exist, although no sane programs should leverage this possibility.
779    pub infos: *mut hwloc_info_s,
780
781    /// Number of (key, value) pairs in [`infos`]
782    ///
783    /// [`infos`]: Self::infos
784    pub infos_count: c_uint,
785
786    /// Application-given private data pointer, initialized to NULL, use it as
787    /// you wish
788    //
789    // --- Implementation details ---
790    //
791    // TODO: Add once support is ready: "See
792    // [`hwloc_topology_set_userdata_export_callback()`] if you wish to export
793    // this field to XML."
794    pub userdata: *mut c_void,
795
796    /// Global persistent index
797    ///
798    /// Generated by hwloc, unique across the topology (contrary to
799    /// [`os_index`]) and persistent across topology changes (contrary to
800    /// [`logical_index`]).
801    ///
802    /// All this means you can safely use this index as a cheap key representing
803    /// the object in a Set or a Map, as long as that Set or Map only refers to
804    /// [`hwloc_obj`]s originating from a single [`hwloc_topology`].
805    ///
806    /// [`logical_index`]: Self::logical_index
807    /// [`os_index`]: Self::os_index
808    pub gp_index: u64,
809}
810
811/// Value of [`hwloc_obj::os_index`] when unknown or irrelevant for this object
812pub const HWLOC_UNKNOWN_INDEX: c_uint = c_uint::MAX;
813
814/// Convenience typedef, a pointer to a struct [`hwloc_obj`]
815pub type hwloc_obj_t = *mut hwloc_obj;
816
817/// [`hwloc_obj_type_t`]-specific attributes
818#[derive(Copy, Clone)]
819#[repr(C)]
820pub union hwloc_obj_attr_u {
821    /// [`HWLOC_OBJ_NUMANODE`]-specific attributes
822    pub numa: hwloc_numanode_attr_s,
823
824    /// Cache-specific attributes
825    pub cache: hwloc_cache_attr_s,
826
827    /// [`HWLOC_OBJ_GROUP`]-specific attributes
828    pub group: hwloc_group_attr_s,
829
830    /// [`HWLOC_OBJ_PCI_DEVICE`]-specific attributes
831    pub pcidev: hwloc_pcidev_attr_s,
832
833    /// [`HWLOC_OBJ_BRIDGE`]-specific attributes
834    pub bridge: hwloc_bridge_attr_s,
835
836    /// [`HWLOC_OBJ_OS_DEVICE`]-specific attributes
837    pub osdev: hwloc_osdev_attr_s,
838}
839//
840impl Debug for hwloc_obj_attr_u {
841    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
842        f.debug_struct("hwloc_obj_attr_u").finish_non_exhaustive()
843    }
844}
845
846/// [`HWLOC_OBJ_NUMANODE`]-specific attributes
847#[derive(Copy, Clone, Debug)]
848#[doc(alias = "hwloc_obj_attr_u::hwloc_numanode_attr_s")]
849#[repr(C)]
850pub struct hwloc_numanode_attr_s {
851    /// Local memory in bytes
852    ///
853    /// May not be accurate if
854    /// [`hwloc_topology_discovery_support::numa_memory`] is not set.
855    #[doc(alias = "hwloc_obj_attr_u::hwloc_numanode_attr_s::local_memory")]
856    pub local_memory: u64,
857
858    /// Number of memory page types
859    #[doc(alias = "hwloc_obj_attr_u::hwloc_numanode_attr_s::page_types_len")]
860    pub page_types_len: c_uint,
861
862    /// Memory page types, sorted by increasing page size
863    #[doc(alias = "hwloc_obj_attr_u::hwloc_numanode_attr_s::page_types")]
864    pub page_types: *mut hwloc_memory_page_type_s,
865}
866//
867impl Default for hwloc_numanode_attr_s {
868    fn default() -> Self {
869        Self {
870            local_memory: 0,
871            page_types_len: 0,
872            page_types: std::ptr::null_mut(),
873        }
874    }
875}
876
877/// Local memory page type
878#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq, PartialOrd, Ord)]
879#[doc(alias = "hwloc_numanode_attr_s::hwloc_memory_page_type_s")]
880#[doc(alias = "hwloc_obj_attr_u::hwloc_numanode_attr_s::hwloc_memory_page_type_s")]
881#[repr(C)]
882pub struct hwloc_memory_page_type_s {
883    /// Size of pages
884    #[doc(alias = "hwloc_numanode_attr_s::hwloc_memory_page_type_s::size")]
885    #[doc(alias = "hwloc_obj_attr_u::hwloc_numanode_attr_s::hwloc_memory_page_type_s::size")]
886    pub size: u64,
887
888    /// Number of pages of this size
889    #[doc(alias = "hwloc_numanode_attr_s::hwloc_memory_page_type_s::count")]
890    #[doc(alias = "hwloc_obj_attr_u::hwloc_numanode_attr_s::hwloc_memory_page_type_s::count")]
891    pub count: u64,
892}
893
894/// Cache-specific attributes
895#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq)]
896#[doc(alias = "hwloc_obj_attr_u::hwloc_cache_attr_s")]
897#[repr(C)]
898pub struct hwloc_cache_attr_s {
899    /// Size of the cache in bytes
900    #[doc(alias = "hwloc_obj_attr_u::hwloc_cache_attr_s::size")]
901    pub size: u64,
902
903    /// Depth of the cache (e.g. L1, L2, ...)
904    #[doc(alias = "hwloc_obj_attr_u::hwloc_cache_attr_s::depth")]
905    pub depth: c_uint,
906
907    /// Cache line size in bytes
908    #[doc(alias = "hwloc_obj_attr_u::hwloc_cache_attr_s::linesize")]
909    pub linesize: c_uint,
910
911    /// Ways of associativity, -1 if fully associative, 0 if unknown
912    #[doc(alias = "hwloc_obj_attr_u::hwloc_cache_attr_s::associativity")]
913    pub associativity: c_int,
914
915    /// Cache type
916    #[doc(alias = "hwloc_cache_attr_s::type")]
917    #[doc(alias = "hwloc_obj_attr_u::hwloc_cache_attr_s::type")]
918    pub ty: hwloc_obj_cache_type_t,
919}
920
921/// [`HWLOC_OBJ_GROUP`]-specific attributes
922#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq)]
923#[doc(alias = "hwloc_obj_attr_u::hwloc_group_attr_s")]
924#[repr(C)]
925pub struct hwloc_group_attr_s {
926    /// Depth of group object
927    ///
928    /// It may change if intermediate Group objects are added.
929    #[doc(alias = "hwloc_obj_attr_u::hwloc_group_attr_s::depth")]
930    pub depth: c_uint,
931
932    /// Internally-used kind of group
933    #[doc(alias = "hwloc_obj_attr_u::hwloc_group_attr_s::kind")]
934    pub kind: c_uint,
935
936    /// Internally-used subkind to distinguish different levels of groups with
937    /// the same kind
938    #[doc(alias = "hwloc_obj_attr_u::hwloc_group_attr_s::subkind")]
939    pub subkind: c_uint,
940
941    /// Flag preventing groups from being automatically merged with identical
942    /// parent or children
943    #[cfg(feature = "hwloc-2_0_4")]
944    #[doc(alias = "hwloc_obj_attr_u::hwloc_group_attr_s::dont_merge")]
945    pub dont_merge: c_uchar,
946}
947
948/// PCI domain width (depends on hwloc version)
949#[cfg(feature = "hwloc-3_0_0")]
950#[cfg_attr(docsrs, doc(cfg(all())))]
951pub type PCIDomain = u32;
952
953/// PCI domain width (depends on hwloc version)
954#[cfg(not(feature = "hwloc-3_0_0"))]
955#[cfg_attr(docsrs, doc(cfg(all())))]
956pub type PCIDomain = u16;
957
958/// [`HWLOC_OBJ_PCI_DEVICE`]-specific attributes
959#[derive(Copy, Clone, Debug, Default, PartialEq)]
960#[doc(alias = "hwloc_obj_attr_u::hwloc_pcidev_attr_s")]
961#[repr(C)]
962pub struct hwloc_pcidev_attr_s {
963    /// PCI domain
964    #[doc(alias = "hwloc_obj_attr_u::hwloc_pcidev_attr_s::domain")]
965    pub domain: PCIDomain,
966
967    /// PCI bus id
968    #[doc(alias = "hwloc_obj_attr_u::hwloc_pcidev_attr_s::bus")]
969    pub bus: c_uchar,
970
971    /// PCI bus device
972    #[doc(alias = "hwloc_obj_attr_u::hwloc_pcidev_attr_s::dev")]
973    pub dev: c_uchar,
974
975    /// PCI function
976    #[doc(alias = "hwloc_obj_attr_u::hwloc_pcidev_attr_s::func")]
977    pub func: c_uchar,
978
979    /// PCI class ID
980    #[doc(alias = "hwloc_obj_attr_u::hwloc_pcidev_attr_s::class_id")]
981    pub class_id: c_ushort,
982
983    /// PCI vendor ID
984    #[doc(alias = "hwloc_obj_attr_u::hwloc_pcidev_attr_s::vendor_id")]
985    pub vendor_id: c_ushort,
986
987    /// PCI device ID
988    #[doc(alias = "hwloc_obj_attr_u::hwloc_pcidev_attr_s::device_id")]
989    pub device_id: c_ushort,
990
991    /// PCI sub-vendor ID
992    #[doc(alias = "hwloc_obj_attr_u::hwloc_pcidev_attr_s::subvendor_id")]
993    pub subvendor_id: c_ushort,
994
995    /// PCI sub-device ID
996    #[doc(alias = "hwloc_obj_attr_u::hwloc_pcidev_attr_s::subdevice_id")]
997    pub subdevice_id: c_ushort,
998
999    /// PCI revision
1000    #[doc(alias = "hwloc_obj_attr_u::hwloc_pcidev_attr_s::revision")]
1001    pub revision: c_uchar,
1002
1003    /// Link speed in GB/s
1004    #[doc(alias = "hwloc_obj_attr_u::hwloc_pcidev_attr_s::linkspeed")]
1005    pub linkspeed: c_float,
1006}
1007
1008/// [`HWLOC_OBJ_BRIDGE`]-specific attributes
1009#[derive(Copy, Clone, Debug)]
1010#[doc(alias = "hwloc_obj_attr_u::hwloc_bridge_attr_s")]
1011#[repr(C)]
1012pub struct hwloc_bridge_attr_s {
1013    /// Upstream attributes
1014    #[doc(alias = "hwloc_bridge_attr_s::upstream")]
1015    pub upstream: RawUpstreamAttributes,
1016
1017    /// Upstream type
1018    #[doc(alias = "hwloc_obj_attr_u::hwloc_bridge_attr_s::upstream_type")]
1019    pub upstream_type: hwloc_obj_bridge_type_t,
1020
1021    /// Downstream attributes
1022    #[doc(alias = "hwloc_obj_attr_u::hwloc_bridge_attr_s::downstream")]
1023    pub downstream: RawDownstreamAttributes,
1024
1025    /// Downstream type
1026    #[doc(alias = "hwloc_obj_attr_u::hwloc_bridge_attr_s::downstream_type")]
1027    pub downstream_type: hwloc_obj_bridge_type_t,
1028
1029    /// Bridge depth
1030    #[doc(alias = "hwloc_obj_attr_u::hwloc_bridge_attr_s::depth")]
1031    pub depth: c_uint,
1032}
1033
1034/// Upstream device attributes
1035#[derive(Copy, Clone)]
1036#[repr(C)]
1037pub union RawUpstreamAttributes {
1038    /// PCI-specific attributes
1039    pub pci: hwloc_pcidev_attr_s,
1040}
1041//
1042impl Debug for RawUpstreamAttributes {
1043    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1044        f.debug_struct("RawUpstreamAttributes")
1045            .finish_non_exhaustive()
1046    }
1047}
1048
1049/// Downstream PCI device attributes
1050#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq)]
1051#[repr(C)]
1052pub struct RawDownstreamPCIAttributes {
1053    /// Downstram domain
1054    pub domain: PCIDomain,
1055
1056    /// Downstream secondary bus
1057    pub secondary_bus: c_uchar,
1058
1059    /// Downstream subordinate bus
1060    pub subordinate_bus: c_uchar,
1061}
1062
1063/// Downstream device attributes
1064#[derive(Copy, Clone)]
1065#[repr(C)]
1066pub union RawDownstreamAttributes {
1067    /// PCI-specific attributes
1068    pub pci: RawDownstreamPCIAttributes,
1069}
1070//
1071impl Debug for RawDownstreamAttributes {
1072    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1073        f.debug_struct("RawDownstreamAttributes")
1074            .finish_non_exhaustive()
1075    }
1076}
1077
1078/// [`HWLOC_OBJ_OS_DEVICE`]-specific attributes
1079#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq)]
1080#[doc(alias = "hwloc_obj_attr_u::hwloc_osdev_attr_s")]
1081#[repr(C)]
1082pub struct hwloc_osdev_attr_s {
1083    /// OS device type
1084    #[doc(alias = "hwloc_osdev_attr_s::type")]
1085    #[doc(alias = "hwloc_obj_attr_u::hwloc_osdev_attr_s::type")]
1086    pub ty: hwloc_obj_osdev_type_t,
1087}
1088
1089/// Key-value string attributes
1090///
1091/// Used in multiple places of the hwloc API for extensible metadata.
1092///
1093/// See also [Consulting and Adding Info
1094/// Attributes](https://hwloc.readthedocs.io/en/stable/group__hwlocality__info__attr.html).
1095///
1096/// This type does not implement [`Default`] because hwloc all but guarantees
1097/// that the inner pointers of this struct will not be null.
1098#[derive(Copy, Clone, Debug)]
1099#[repr(C)]
1100pub struct hwloc_info_s {
1101    /// Info name
1102    pub name: *mut c_char,
1103
1104    /// Info value
1105    pub value: *mut c_char,
1106}
1107
1108// === Topology Creation and Destruction: https://hwloc.readthedocs.io/en/stable/group__hwlocality__creation.html
1109
1110/// Opaque topology struct
1111///
1112/// Models the incomplete type that [`hwloc_topology_t`] API pointers map to.
1113///
1114/// This type purposely implements almost no traits, not even Debug, because you
1115/// should never, ever deal with it directly, only with raw pointers to it that
1116/// you blindly pass to the hwloc API.
1117///
1118/// The only exception to this rule is [`RefUnwindSafe`], which is special
1119/// because...
1120///
1121/// - You cannot implement [`UnwindSafe`] yourself for standard pointer types
1122///   due to orphan rules
1123/// - Rust implements it for pointers to [`RefUnwindSafe`], i.e. it assumes you
1124///   use pointers to such data responsibly.
1125/// - The ergonomic impact of everyday types not being [`UnwindSafe`] is
1126///   annoying (need [`AssertUnwindSafe`] in every [`catch_unwind()`]).
1127///
1128/// [`AssertUnwindSafe`]: std::panic::AssertUnwindSafe
1129/// [`catch_unwind()`]: std::panic::catch_unwind()
1130#[allow(missing_debug_implementations)]
1131#[repr(C)]
1132pub struct hwloc_topology(IncompleteType);
1133//
1134impl RefUnwindSafe for hwloc_topology {}
1135
1136/// Topology context
1137///
1138/// To be initialized with [`hwloc_topology_init()`] and built with [`hwloc_topology_load()`].
1139pub type hwloc_topology_t = *mut hwloc_topology;
1140
1141/// A non-modifiable [`hwloc_topology_t`]
1142pub type hwloc_const_topology_t = *const hwloc_topology;
1143
1144// === Object levels, depths and types: https://hwloc.readthedocs.io/en/stable/group__hwlocality__levels.html
1145
1146/// Depth of an object (or object type) in the topology
1147///
1148/// We can't use Rust enums to model C enums in FFI because that results in
1149/// undefined behavior if the C API gets new enum variants and sends them to us.
1150pub type hwloc_get_type_depth_e = c_int;
1151
1152/// No object of given type exists in the topology
1153pub const HWLOC_TYPE_DEPTH_UNKNOWN: hwloc_get_type_depth_e = -1;
1154
1155/// Objects of given type exist at different depth in the topology (only for Groups)
1156pub const HWLOC_TYPE_DEPTH_MULTIPLE: hwloc_get_type_depth_e = -2;
1157
1158/// Virtual depth for [`HWLOC_OBJ_NUMANODE`]
1159pub const HWLOC_TYPE_DEPTH_NUMANODE: hwloc_get_type_depth_e = -3;
1160
1161/// Virtual depth for [`HWLOC_OBJ_BRIDGE`]
1162pub const HWLOC_TYPE_DEPTH_BRIDGE: hwloc_get_type_depth_e = -4;
1163
1164/// Virtual depth for [`HWLOC_OBJ_PCI_DEVICE`]
1165pub const HWLOC_TYPE_DEPTH_PCI_DEVICE: hwloc_get_type_depth_e = -5;
1166
1167/// Virtual depth for [`HWLOC_OBJ_OS_DEVICE`]
1168pub const HWLOC_TYPE_DEPTH_OS_DEVICE: hwloc_get_type_depth_e = -6;
1169
1170/// Virtual depth for [`HWLOC_OBJ_MISC`]
1171pub const HWLOC_TYPE_DEPTH_MISC: hwloc_get_type_depth_e = -7;
1172
1173/// Virtual depth for [`HWLOC_OBJ_MEMCACHE`]
1174#[cfg(feature = "hwloc-2_1_0")]
1175pub const HWLOC_TYPE_DEPTH_MEMCACHE: hwloc_get_type_depth_e = -8;
1176
1177// === CPU binding: https://hwloc.readthedocs.io/en/stable/group__hwlocality__cpubinding.html
1178
1179/// Process/Thread binding flags
1180///
1181/// These bit flags can be used to refine the binding policy. All flags can be
1182/// OR'ed together with the exception of the binding targets flags
1183/// [`HWLOC_CPUBIND_THREAD`] and [`HWLOC_CPUBIND_PROCESS`], which are mutually
1184/// exclusive.
1185///
1186/// When using one of the functions that target the active process, you must use
1187/// at most one of these flags. The most portable binding targets are no flags,
1188/// which is interpreted as "assume a single-threaded process", followed by
1189/// [`HWLOC_CPUBIND_THREAD`] and [`HWLOC_CPUBIND_PROCESS`] in this order. These
1190/// flags must generally not be used with any other function, except on Linux
1191/// where flag [`HWLOC_CPUBIND_THREAD`] can also be used to turn
1192/// process-binding functions into thread-binding functions.
1193///
1194/// Individual CPU binding functions may not support all of these flags.
1195/// Please check the documentation of the function that you are
1196/// trying to call for more information.
1197pub type hwloc_cpubind_flags_t = c_int;
1198
1199/// Bind the current thread of the current process
1200///
1201/// This is the second most portable option when the process is multi-threaded,
1202/// and specifying no flags would thus be incorrect.
1203///
1204/// On Linux, this flag can also be used to turn process-binding
1205/// functions into thread-binding functions.
1206///
1207/// This is mutually exclusive with [`HWLOC_CPUBIND_PROCESS`].
1208pub const HWLOC_CPUBIND_THREAD: hwloc_cpubind_flags_t = 1 << 1;
1209
1210/// Bind all threads of the current process
1211///
1212/// This is mutually exclusive with [`HWLOC_CPUBIND_THREAD`].
1213pub const HWLOC_CPUBIND_PROCESS: hwloc_cpubind_flags_t = 1 << 0;
1214
1215/// Request for strict binding from the OS
1216///
1217/// By default, when the designated CPUs are all busy while other CPUs
1218/// are idle, operating systems may execute the thread/process on those
1219/// other CPUs instead of the designated CPUs, to let them progress
1220/// anyway. Strict binding means that the thread/process will _never_
1221/// execute on other CPUs than the designated CPUs, even when those are
1222/// busy with other tasks and other CPUs are idle.
1223///
1224/// Depending on the operating system, strict binding may not be
1225/// possible (e.g. the OS does not implement it) or not allowed (e.g.
1226/// for an administrative reasons), and the binding function will fail
1227/// in that case.
1228///
1229/// When retrieving the binding of a process, this flag checks whether
1230/// all its threads actually have the same binding. If the flag is not
1231/// given, the binding of each thread will be accumulated.
1232///
1233/// This flag should not be used when retrieving the binding of a
1234/// thread or the CPU location of a process.
1235pub const HWLOC_CPUBIND_STRICT: hwloc_cpubind_flags_t = 1 << 2;
1236
1237/// Avoid any effect on memory binding
1238///
1239/// On some operating systems, some CPU binding function would also bind
1240/// the memory on the corresponding NUMA node. It is often not a
1241/// problem for the application, but if it is, setting this flag will
1242/// make hwloc avoid using OS functions that would also bind memory.
1243/// This will however reduce the support of CPU bindings, i.e.
1244/// potentially result in the binding function erroring out.
1245///
1246/// This flag should only be used with functions that set the CPU
1247/// binding.
1248pub const HWLOC_CPUBIND_NOMEMBIND: hwloc_cpubind_flags_t = 1 << 3;
1249
1250// === Memory binding: https://hwloc.readthedocs.io/en/stable/group__hwlocality__membinding.html
1251
1252/// Memory binding flags.
1253///
1254/// These bit flags can be used to refine the binding policy. All flags can
1255/// be OR'ed together with the exception of the binding target flags
1256/// [`HWLOC_MEMBIND_THREAD`] and [`HWLOC_MEMBIND_PROCESS`], which are mutually
1257/// exclusive.
1258///
1259/// When using one of the methods that target a process, you must use
1260/// at most one of these flags. The most portable option is to specify no flags,
1261/// which means "assume the target process is single-threaded". These
1262/// flags must not be used with any other method.
1263///
1264/// Individual memory binding methods may not support all of these flags. Please
1265/// check the documentation of the function that you are trying to call for
1266/// more information.
1267pub type hwloc_membind_flags_t = c_int;
1268
1269/// Apply command to all threads of the specified process
1270///
1271/// This is mutually exclusive with [`HWLOC_MEMBIND_THREAD`]
1272pub const HWLOC_MEMBIND_PROCESS: hwloc_membind_flags_t = 1 << 0;
1273
1274/// Apply command to the current thread of the current process
1275///
1276/// This is mutually exclusive with [`HWLOC_MEMBIND_PROCESS`]
1277pub const HWLOC_MEMBIND_THREAD: hwloc_membind_flags_t = 1 << 1;
1278
1279/// Request strict binding from the OS
1280///
1281/// If this flag is set, a binding method will fail if the binding can
1282/// not be guaranteed or completely enforced. Otherwise, hwloc will
1283/// attempt to achieve an approximation of the requested binding (e.g.
1284/// targeting more or less threads and NUMA nodes).
1285///
1286/// This flag has slightly different meanings depending on which
1287/// method it is used with.
1288pub const HWLOC_MEMBIND_STRICT: hwloc_membind_flags_t = 1 << 2;
1289
1290/// Migrate existing allocated memory
1291///
1292/// If the memory cannot be migrated and the [`HWLOC_MEMBIND_STRICT`] flag is
1293/// set, an error will be returned.
1294///
1295/// This flag is only meaningful on operations that bind memory.
1296///
1297/// Only available if [`hwloc_topology_membind_support::migrate_membind`] is set.
1298pub const HWLOC_MEMBIND_MIGRATE: hwloc_membind_flags_t = 1 << 3;
1299
1300/// Avoid any effect on CPU binding
1301///
1302/// On some operating systems, some underlying memory binding
1303/// methods also bind the application to the corresponding CPU(s).
1304/// Using this flag will cause hwloc to avoid using OS functions that
1305/// could potentially affect CPU bindings.
1306///
1307/// Note, however, that using this flag may reduce hwloc's overall
1308/// memory binding support.
1309pub const HWLOC_MEMBIND_NOCPUBIND: hwloc_membind_flags_t = 1 << 4;
1310
1311/// Consider the bitmap argument as a nodeset.
1312///
1313/// The bitmap argument is considered a nodeset if this flag is given,
1314/// or a cpuset otherwise by default.
1315///
1316/// Memory binding by CPU set cannot work for CPU-less NUMA memory nodes.
1317/// Binding by nodeset should therefore be preferred whenever possible.
1318pub const HWLOC_MEMBIND_BYNODESET: hwloc_membind_flags_t = 1 << 5;
1319
1320/// Memory binding policy.
1321///
1322/// Not all systems support all kinds of binding.
1323/// [`hwloc_topology_get_support()`] may be used to query the
1324/// actual memory binding support in the currently used operating system.
1325pub type hwloc_membind_policy_t = c_int;
1326
1327/// Reset the memory allocation policy of the current process or thread to
1328/// the system default
1329///
1330/// Depending on the operating system, this may correspond to
1331/// [`HWLOC_MEMBIND_FIRSTTOUCH`] (Linux, FreeBSD) or [`HWLOC_MEMBIND_BIND`]
1332/// (AIX, HP-UX, Solaris, Windows).
1333///
1334/// This policy is never returned by get membind functions. The `nodeset`
1335/// argument is ignored.
1336pub const HWLOC_MEMBIND_DEFAULT: hwloc_membind_policy_t = 0;
1337
1338/// Allocate each memory page individually on the local NUMA
1339/// node of the thread that touches it
1340///
1341/// The given nodeset should usually be
1342/// [`hwloc_topology_get_topology_nodeset()`] so that the touching thread may
1343/// run and allocate on any node in the system.
1344///
1345/// On AIX, if the nodeset is smaller, pages are allocated locally (if the
1346/// local node is in the nodeset) or from a random non-local node (otherwise).
1347///
1348/// Only available if [`hwloc_topology_membind_support::firsttouch_membind`] is
1349/// set.
1350pub const HWLOC_MEMBIND_FIRSTTOUCH: hwloc_membind_policy_t = 1;
1351
1352/// Allocate memory on the specified nodes (most portable option)
1353///
1354/// The actual behavior may slightly vary between operating systems, especially
1355/// when (some of) the requested nodes are full. On Linux, by default, the
1356/// `MPOL_PREFERRED_MANY` (or `MPOL_PREFERRED`) policy is used. However, if
1357/// the [`HWLOC_MEMBIND_STRICT`] flag is also given, the Linux `MPOL_BIND`
1358/// policy is rather used.
1359///
1360/// Only available if [`hwloc_topology_membind_support::bind_membind`] is set.
1361pub const HWLOC_MEMBIND_BIND: hwloc_membind_policy_t = 2;
1362
1363/// Allocate memory on the given nodes in an interleaved round-robin manner
1364///
1365/// The precise layout of the memory across multiple NUMA nodes is OS/system
1366/// specific.
1367///
1368/// Interleaving can be useful when threads distributed across the specified
1369/// NUMA nodes will all be accessing the whole memory range concurrently,
1370/// since the interleave will then balance the memory references.
1371///
1372/// Only available if [`hwloc_topology_membind_support::interleave_membind`] is
1373/// set.
1374pub const HWLOC_MEMBIND_INTERLEAVE: hwloc_membind_policy_t = 3;
1375
1376/// Allocate memory on the given nodes in an interleaved / weighted manner.
1377///
1378/// The precise layout of the memory across multiple NUMA nodes is OS/system
1379/// specific.
1380///
1381/// Weighted interleaving can be useful when threads distributed
1382/// across the specified NUMA nodes with different bandwidth capabilities will
1383/// all be accessing the whole memory range concurrently, since the interleave
1384/// will then balance the memory references.
1385///
1386/// Only available if
1387/// [`hwloc_topology_membind_support::weighted_interleave_membind`] is set.
1388#[cfg(feature = "hwloc-2_11_0")]
1389pub const HWLOC_MEMBIND_WEIGHTED_INTERLEAVE: hwloc_membind_policy_t = 5;
1390
1391/// Migrate pages on next touch
1392///
1393/// For each page bound with this policy, by next time it is touched (and
1394/// next time only), it is moved from its current location to the local NUMA
1395/// node of the thread where the memory reference occurred (if it needs to
1396/// be moved at all).
1397///
1398/// Only available if [`hwloc_topology_membind_support::nexttouch_membind`] is
1399/// set.
1400pub const HWLOC_MEMBIND_NEXTTOUCH: hwloc_membind_policy_t = 4;
1401
1402/// Mixture of memory binding policies
1403///
1404/// Returned by `get_membind()` functions when multiple threads or parts of a
1405/// memory area have differing memory binding policies. Also returned when
1406/// binding is unknown because binding hooks are empty when the topology is
1407/// loaded from XML without `HWLOC_THISSYSTEM=1`, etc.
1408pub const HWLOC_MEMBIND_MIXED: hwloc_membind_policy_t = -1;
1409
1410// === Changing the source of topology discovery: https://hwloc.readthedocs.io/en/stable/group__hwlocality__setsource.html
1411
1412/// Flags to be passed to [`hwloc_topology_set_components()`]
1413#[cfg(feature = "hwloc-2_1_0")]
1414pub type hwloc_topology_components_flag_e = c_ulong;
1415
1416/// Blacklist the target component from being used
1417#[cfg(feature = "hwloc-2_1_0")]
1418pub const HWLOC_TOPOLOGY_COMPONENTS_FLAG_BLACKLIST: hwloc_topology_components_flag_e = 1 << 0;
1419
1420// === Topology detection configuration and query: https://hwloc.readthedocs.io/en/stable/group__hwlocality__configuration.html
1421
1422/// Topology building configuration flags
1423pub type hwloc_topology_flags_e = c_ulong;
1424
1425/// Detect the whole system, ignore reservations, include disallowed objects
1426///
1427/// Gather all online resources, even if some were disabled by the
1428/// administrator. For instance, ignore Linux Cgroup/Cpusets and gather
1429/// all processors and memory nodes. However offline PUs and NUMA nodes
1430/// are still ignored.
1431///
1432/// When this flag is not set, PUs and NUMA nodes that are disallowed
1433/// are not added to the topology. Parent objects (package, core, cache,
1434/// etc.) are added only if some of their children are allowed. All
1435/// existing PUs and NUMA nodes in the topology are allowed.
1436/// [`hwloc_topology_get_allowed_cpuset()`] and
1437/// [`hwloc_topology_get_allowed_nodeset()`] are equal to the root object cpuset
1438/// and nodeset.
1439///
1440/// When this flag is set, the actual sets of allowed PUs and NUMA nodes
1441/// are given by [`hwloc_topology_get_allowed_cpuset()`] and
1442/// [`hwloc_topology_get_allowed_nodeset()`]. They may be smaller than the root
1443/// object cpuset and nodeset.
1444///
1445/// If the current topology is exported to XML and reimported later,
1446/// this flag should be set again in the reimported topology so that
1447/// disallowed resources are reimported as well.
1448///
1449#[cfg_attr(
1450    feature = "hwloc-2_1_0",
1451    doc = "What additional objects could be detected with this flag depends on"
1452)]
1453#[cfg_attr(
1454    feature = "hwloc-2_1_0",
1455    doc = "[`hwloc_topology_discovery_support::disallowed_pu`] and"
1456)]
1457#[cfg_attr(
1458    feature = "hwloc-2_1_0",
1459    doc = "[`hwloc_topology_discovery_support::disallowed_numa`], which can be checked"
1460)]
1461#[cfg_attr(feature = "hwloc-2_1_0", doc = "after building the topology.")]
1462#[doc(alias = "HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM")]
1463pub const HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED: hwloc_topology_flags_e = 1 << 0;
1464
1465/// Assume that the selected backend provides the topology for the
1466/// system on which we are running
1467///
1468/// This forces [`hwloc_topology_is_thissystem()`] to return true, i.e. makes
1469/// hwloc assume that the selected backend provides the topology for the system
1470/// on which we are running, even if it is not the OS-specific backend but the
1471/// XML backend for instance. This means making the binding functions actually
1472/// call the OS-specific system calls and really do binding, while the XML
1473/// backend would otherwise provide empty hooks just returning success.
1474///
1475/// Setting the environment variable `HWLOC_THISSYSTEM` may also result
1476/// in the same behavior.
1477///
1478/// This can be used for efficiency reasons to first detect the topology
1479/// once, save it to an XML file, and quickly reload it later through
1480/// the XML backend, but still having binding functions actually do bind.
1481pub const HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM: hwloc_topology_flags_e = 1 << 1;
1482
1483/// Get the set of allowed resources from the local operating system
1484/// even if the topology was loaded from XML or synthetic description
1485///
1486/// If the topology was loaded from XML or from a synthetic string,
1487/// restrict it by applying the current process restrictions such as
1488/// Linux Cgroup/Cpuset.
1489///
1490/// This is useful when the topology is not loaded directly from the
1491/// local machine (e.g. for performance reason) and it comes with all
1492/// resources, while the running process is restricted to only parts of
1493/// the machine.
1494///
1495/// If this flag is set, [`HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM`] must also be set,
1496/// since the loaded topology must match the underlying machine where
1497/// restrictions will be gathered from.
1498///
1499/// Setting the environment variable `HWLOC_THISSYSTEM_ALLOWED_RESOURCES`
1500/// would result in the same behavior.
1501pub const HWLOC_TOPOLOGY_FLAG_THISSYSTEM_ALLOWED_RESOURCES: hwloc_topology_flags_e = 1 << 2;
1502
1503/// Import support from the imported topology
1504///
1505/// When importing a XML topology from a remote machine, binding is disabled by
1506/// default (see [`HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM`]). This disabling is also
1507/// marked by putting zeroes in the corresponding supported feature bits
1508/// reported by [`hwloc_topology_get_support()`].
1509///
1510/// This flag allows you to actually import support bits from the remote
1511/// machine. It also sets the
1512/// [`hwloc_topology_misc_support::imported_support`] support flag. If the
1513/// imported XML did not contain any support information(exporter hwloc is too
1514/// old), this flag is not set.
1515///
1516/// Note that these supported features are only relevant for the hwloc
1517/// installation that actually exported the XML topology (it may vary
1518/// with the operating system, or with how hwloc was compiled).
1519///
1520/// Note that setting this flag however does not enable binding for the
1521/// locally imported hwloc topology, it only reports what the remote
1522/// hwloc and machine support.
1523#[cfg(feature = "hwloc-2_3_0")]
1524pub const HWLOC_TOPOLOGY_FLAG_IMPORT_SUPPORT: hwloc_topology_flags_e = 1 << 3;
1525
1526/// Do not consider resources outside of the process CPU binding
1527///
1528/// If the binding of the process is limited to a subset of cores,
1529/// ignore the other cores during discovery.
1530///
1531/// The resulting topology is identical to what a call to
1532/// [`hwloc_topology_restrict()`] would generate, but this flag also
1533/// prevents hwloc from ever touching other resources during the
1534/// discovery.
1535///
1536/// This flag especially tells the x86 backend to never temporarily
1537/// rebind a thread on any excluded core. This is useful on Windows
1538/// because such temporary rebinding can change the process binding.
1539/// Another use-case is to avoid cores that would not be able to perform
1540/// the hwloc discovery anytime soon because they are busy executing
1541/// some high-priority real-time tasks.
1542///
1543/// If process CPU binding is not supported, the thread CPU binding is
1544/// considered instead if supported, or the flag is ignored.
1545///
1546/// This flag requires [`HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM`] as well since
1547/// binding support is required.
1548#[cfg(feature = "hwloc-2_5_0")]
1549pub const HWLOC_TOPOLOGY_FLAG_RESTRICT_TO_CPUBINDING: hwloc_topology_flags_e = 1 << 4;
1550
1551/// Do not consider resources outside of the process memory binding
1552///
1553/// If the binding of the process is limited to a subset of NUMA nodes,
1554/// ignore the other NUMA nodes during discovery.
1555///
1556/// The resulting topology is identical to what a call to
1557/// [`hwloc_topology_restrict()`] would generate, but this flag also
1558/// prevents hwloc from ever touching other resources during the
1559/// discovery.
1560///
1561/// This flag is meant to be used together with
1562/// `RESTRICT_CPU_TO_THIS_PROCESS` when both cores and NUMA nodes should
1563/// be ignored outside of the process binding.
1564///
1565/// If process memory binding is not supported, the thread memory
1566/// binding is considered instead if supported, or the flag is ignored.
1567///
1568/// This flag requires [`HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM`] as well since
1569/// binding support is required.
1570#[cfg(feature = "hwloc-2_5_0")]
1571pub const HWLOC_TOPOLOGY_FLAG_RESTRICT_TO_MEMBINDING: hwloc_topology_flags_e = 1 << 5;
1572
1573/// Do not ever modify the process or thread binding during discovery
1574///
1575/// This flag disables all hwloc discovery steps that require a change
1576/// of the process or thread binding. This currently only affects the
1577/// x86 backend which gets entirely disabled.
1578///
1579/// This is useful when a topology is loaded while the application also creates
1580/// additional threads or modifies the binding.
1581///
1582/// This flag is also a strict way to make sure the process binding will
1583/// not change to due thread binding changes on Windows (see
1584/// `RESTRICT_CPU_TO_THIS_PROCESS`).
1585#[cfg(feature = "hwloc-2_5_0")]
1586pub const HWLOC_TOPOLOGY_FLAG_DONT_CHANGE_BINDING: hwloc_topology_flags_e = 1 << 6;
1587
1588/// Ignore distance information from the operating system (and from
1589/// XML)
1590///
1591/// Distances will not be used for grouping topology objects.
1592#[cfg(feature = "hwloc-2_8_0")]
1593pub const HWLOC_TOPOLOGY_FLAG_NO_DISTANCES: hwloc_topology_flags_e = 1 << 7;
1594
1595/// Ignore memory attribues from the operating system (and from XML)
1596#[cfg(feature = "hwloc-2_8_0")]
1597pub const HWLOC_TOPOLOGY_FLAG_NO_MEMATTRS: hwloc_topology_flags_e = 1 << 8;
1598
1599/// Ignore CPU kind information from the operating system (and from
1600/// XML)
1601#[cfg(feature = "hwloc-2_8_0")]
1602pub const HWLOC_TOPOLOGY_FLAG_NO_CPUKINDS: hwloc_topology_flags_e = 1 << 9;
1603
1604/// Set of flags describing actual hwloc feature support for this topology
1605#[derive(Copy, Clone, Debug)]
1606#[repr(C)]
1607pub struct hwloc_topology_support {
1608    /// Support for discovering information about the topology
1609    pub discovery: *const hwloc_topology_discovery_support,
1610
1611    /// Support for getting and setting thread/process CPU bindings
1612    pub cpubind: *const hwloc_topology_cpubind_support,
1613
1614    /// Support for getting and setting thread/process NUMA node bindings
1615    pub membind: *const hwloc_topology_membind_support,
1616
1617    /// Miscellaneous support information
1618    #[cfg(feature = "hwloc-2_3_0")]
1619    pub misc: *const hwloc_topology_misc_support,
1620}
1621//
1622impl Default for hwloc_topology_support {
1623    fn default() -> Self {
1624        Self {
1625            discovery: ptr::null(),
1626            cpubind: ptr::null(),
1627            membind: ptr::null(),
1628            #[cfg(feature = "hwloc-2_3_0")]
1629            misc: ptr::null(),
1630        }
1631    }
1632}
1633
1634/// Support for discovering information about the topology
1635#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq)]
1636#[repr(C)]
1637pub struct hwloc_topology_discovery_support {
1638    /// Detecting the number of PU objects is supported
1639    pub pu: c_uchar,
1640
1641    /// Detecting the number of NUMA nodes is supported
1642    pub numa: c_uchar,
1643
1644    /// Detecting the amount of memory in NUMA nodes is supported
1645    pub numa_memory: c_uchar,
1646
1647    /// Detecting and identifying PU objects that are not available to the
1648    /// current process is supported
1649    #[cfg(feature = "hwloc-2_1_0")]
1650    pub disallowed_pu: c_uchar,
1651
1652    /// Detecting and identifying NUMA nodes that are not available to the
1653    /// current process is supported
1654    #[cfg(feature = "hwloc-2_1_0")]
1655    pub disallowed_numa: c_uchar,
1656
1657    /// Detecting the efficiency of CPU kinds is supported
1658    ///
1659    /// See also [Kinds of CPU cores](https://hwloc.readthedocs.io/en/stable/group__hwlocality__cpukinds.html).
1660    #[cfg(feature = "hwloc-2_4_0")]
1661    pub cpukind_efficiency: c_uchar,
1662}
1663
1664/// Support for getting and setting thread/process CPU bindings
1665///
1666/// A flag may be set even if the feature isn't supported in all cases
1667/// (e.g. binding to random sets of non-contiguous objects).
1668#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq)]
1669#[repr(C)]
1670pub struct hwloc_topology_cpubind_support {
1671    /// Binding the whole current process is supported
1672    pub set_thisproc_cpubind: c_uchar,
1673
1674    /// Getting the binding of the whole current process is supported
1675    pub get_thisproc_cpubind: c_uchar,
1676
1677    /// Binding a whole given process is supported
1678    pub set_proc_cpubind: c_uchar,
1679
1680    /// Getting the binding of a whole given process is supported
1681    pub get_proc_cpubind: c_uchar,
1682
1683    /// Binding the current thread only is supported
1684    pub set_thisthread_cpubind: c_uchar,
1685
1686    /// Getting the binding of the current thread only is supported
1687    pub get_thisthread_cpubind: c_uchar,
1688
1689    /// Binding a given thread only is supported
1690    pub set_thread_cpubind: c_uchar,
1691
1692    /// Getting the binding of a given thread only is supported
1693    pub get_thread_cpubind: c_uchar,
1694
1695    /// Getting the last processors where the whole current process ran is supported
1696    pub get_thisproc_last_cpu_location: c_uchar,
1697
1698    /// Getting the last processors where a whole process ran is supported
1699    pub get_proc_last_cpu_location: c_uchar,
1700
1701    /// Getting the last processors where the current thread ran is supported
1702    pub get_thisthread_last_cpu_location: c_uchar,
1703}
1704
1705/// Support for getting and setting thread/process NUMA node bindings
1706///
1707/// A flag may be set even if the feature isn't supported in all cases
1708/// (e.g. binding to random sets of non-contiguous objects).
1709#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq)]
1710#[repr(C)]
1711pub struct hwloc_topology_membind_support {
1712    /// Binding the whole current process is supported
1713    pub set_thisproc_membind: c_uchar,
1714
1715    /// Getting the binding of the whole current process is supported
1716    pub get_thisproc_membind: c_uchar,
1717
1718    /// Binding a whole given process is supported
1719    pub set_proc_membind: c_uchar,
1720
1721    /// Getting the binding of a whole given process is supported
1722    pub get_proc_membind: c_uchar,
1723
1724    /// Binding the current thread only is supported
1725    pub set_thisthread_membind: c_uchar,
1726
1727    /// Getting the binding of the current thread only is supported
1728    pub get_thisthread_membind: c_uchar,
1729
1730    /// Binding a given memory area is supported
1731    pub set_area_membind: c_uchar,
1732
1733    /// Getting the binding of a given memory area is supported
1734    pub get_area_membind: c_uchar,
1735
1736    /// Allocating a bound memory area is supported
1737    pub alloc_membind: c_uchar,
1738
1739    /// First-touch policy is supported
1740    pub firsttouch_membind: c_uchar,
1741
1742    /// Bind policy is supported
1743    pub bind_membind: c_uchar,
1744
1745    /// Interleave policy is supported
1746    pub interleave_membind: c_uchar,
1747
1748    /// Next-touch migration policy is supported
1749    pub nexttouch_membind: c_uchar,
1750
1751    /// Migration flag is supported
1752    pub migrate_membind: c_uchar,
1753
1754    /// Getting the last NUMA nodes where a memory area was allocated is supported
1755    pub get_area_memlocation: c_uchar,
1756
1757    /// Weighted interleave policy is supported
1758    #[cfg(feature = "hwloc-2_11_0")]
1759    pub weighted_interleave_membind: c_uchar,
1760}
1761
1762/// Miscellaneous support information
1763#[cfg(feature = "hwloc-2_3_0")]
1764#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq)]
1765#[repr(C)]
1766pub struct hwloc_topology_misc_support {
1767    /// Support was imported when importing another topology
1768    ///
1769    /// See also [`HWLOC_TOPOLOGY_FLAG_IMPORT_SUPPORT`].
1770    pub imported_support: c_uchar,
1771}
1772
1773/// Type filtering flags
1774///
1775/// By default...
1776///
1777/// - Most objects are kept ([`HWLOC_TYPE_FILTER_KEEP_ALL`])
1778/// - Instruction caches, I/O and Misc objects are ignored (
1779///   [`HWLOC_TYPE_FILTER_KEEP_NONE`]).
1780/// - Die and Group levels are ignored unless they bring structure (
1781///   [`HWLOC_TYPE_FILTER_KEEP_STRUCTURE`]).
1782///
1783/// Note that group objects are also ignored individually (without the entire
1784/// level) when they do not bring structure.
1785///
1786/// We can't use Rust enums to model C enums in FFI because that results in
1787/// undefined behavior if the C API gets new enum variants and sends them to us.
1788pub type hwloc_type_filter_e = c_int;
1789
1790/// Keep all objects of this type
1791///
1792/// Cannot be set for [`HWLOC_OBJ_GROUP`] (groups are designed only to add
1793/// more structure to the topology).
1794pub const HWLOC_TYPE_FILTER_KEEP_ALL: hwloc_type_filter_e = 0;
1795
1796/// Ignore all objects of this type
1797///
1798/// The bottom-level type [`HWLOC_OBJ_PU`], the [`HWLOC_OBJ_NUMANODE`] type
1799/// and the top-level type [`HWLOC_OBJ_MACHINE`] may not be ignored.
1800pub const HWLOC_TYPE_FILTER_KEEP_NONE: hwloc_type_filter_e = 1;
1801
1802/// Only ignore objects if their entire level does not bring any structure
1803///
1804/// Keep the entire level of objects if at least one of these objects adds
1805/// structure to the topology. An object brings structure when it has
1806/// multiple children and it is not the only child of its parent.
1807///
1808/// If all objects in the level are the only child of their parent, and if
1809/// none of them has multiple children, the entire level is removed.
1810///
1811/// Cannot be set for I/O and Misc objects since the topology structure does
1812/// not matter there.
1813pub const HWLOC_TYPE_FILTER_KEEP_STRUCTURE: hwloc_type_filter_e = 2;
1814
1815/// Only keep likely-important objects of the given type.
1816///
1817/// This is only useful for I/O object types.
1818///
1819/// For [`HWLOC_OBJ_PCI_DEVICE`] and [`HWLOC_OBJ_OS_DEVICE`], it means that
1820/// only objects of major/common kinds are kept (storage, network,
1821/// OpenFabrics, CUDA, OpenCL, RSMI, NVML, and displays).
1822/// Also, only OS devices directly attached on PCI (e.g. no USB) are reported.
1823///
1824/// For [`HWLOC_OBJ_BRIDGE`], it means that bridges are kept only if they
1825/// have children.
1826///
1827/// This flag is equivalent to [`HWLOC_TYPE_FILTER_KEEP_ALL`] for Normal, Memory
1828/// and Misc types since they are likely important.
1829pub const HWLOC_TYPE_FILTER_KEEP_IMPORTANT: hwloc_type_filter_e = 3;
1830
1831// === Modifying a loaded Topology: https://hwloc.readthedocs.io/en/stable/group__hwlocality__tinker.html
1832
1833/// Module existing solely to apply a common hwloc version gate
1834#[allow(clippy::wildcard_imports)]
1835#[cfg(feature = "hwloc-2_3_0")]
1836mod topology_editing {
1837    use super::*;
1838
1839    /// Flags to be given to [`hwloc_topology_restrict()`]
1840    pub type hwloc_restrict_flags_e = c_ulong;
1841
1842    /// Remove all objects that became CPU-less
1843    ///
1844    /// By default, only objects that contain no PU and no memory are removed. This
1845    /// flag allows you to remove all objects that do not have access to any CPU
1846    /// anymore when restricting by CPU set.
1847    pub const HWLOC_RESTRICT_FLAG_REMOVE_CPULESS: hwloc_restrict_flags_e = 1 << 0;
1848
1849    /// Restrict by NUMA node set insted of by CPU set
1850    pub const HWLOC_RESTRICT_FLAG_BYNODESET: hwloc_restrict_flags_e = 1 << 3;
1851
1852    /// Remove all objects that became memory-less
1853    ///
1854    /// By default, only objects that contain no PU and no memory are removed. This
1855    /// flag allows you to remove all objects that do not have access to any memory
1856    /// anymore when restricting by NUMA node set.
1857    pub const HWLOC_RESTRICT_FLAG_REMOVE_MEMLESS: hwloc_restrict_flags_e = 1 << 4;
1858
1859    /// Move Misc objects to ancestors if their parents are removed during
1860    /// restriction
1861    ///
1862    /// If this flag is not set, Misc objects are removed when their parents
1863    /// are removed.
1864    pub const HWLOC_RESTRICT_FLAG_ADAPT_MISC: hwloc_restrict_flags_e = 1 << 1;
1865
1866    /// Move I/O objects to ancestors if their parents are removed
1867    /// during restriction
1868    ///
1869    /// If this flag is not set, I/O devices and bridges are removed when
1870    /// their parents are removed.
1871    pub const HWLOC_RESTRICT_FLAG_ADAPT_IO: hwloc_restrict_flags_e = 1 << 2;
1872
1873    /// Flags to be given to [`hwloc_topology_allow()`]
1874    pub type hwloc_allow_flags_e = c_ulong;
1875
1876    /// Mark all objects as allowed in the topology
1877    ///
1878    /// `cpuset` and `nodeset` given to [`hwloc_topology_allow()`] must be NULL.
1879    pub const HWLOC_ALLOW_FLAG_ALL: hwloc_allow_flags_e = 1 << 0;
1880
1881    /// Only allow objects that are available to the current process
1882    ///
1883    /// Requires [`HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM`] so that the set of available
1884    /// resources can actually be retrieved from the operating system.
1885    ///
1886    /// `cpuset` and `nodeset` given to [`hwloc_topology_allow()`] must be NULL.
1887    pub const HWLOC_ALLOW_FLAG_LOCAL_RESTRICTIONS: hwloc_allow_flags_e = 1 << 1;
1888
1889    /// Allow a custom set of objects, given to [`hwloc_topology_allow()`] as
1890    /// `cpuset` and/or `nodeset` parameters.
1891    pub const HWLOC_ALLOW_FLAG_CUSTOM: hwloc_allow_flags_e = 1 << 2;
1892}
1893#[cfg(feature = "hwloc-2_3_0")]
1894pub use topology_editing::*;
1895
1896// === Distributing items over a topology:
1897// https://hwloc.readthedocs.io/en/stable/group__hwlocality__helper__distribute.html
1898
1899/// Flags to be given to `hwloc_distrib()`
1900///
1901/// Note that the C version of `hwloc_distrib()` is not actually exposed in the
1902/// Rust binding as it is a static header function in the C library.
1903pub type hwloc_distrib_flags_e = c_ulong;
1904
1905/// Distrib in reverse order, starting from the last objects
1906pub const HWLOC_DISTRIB_FLAG_REVERSE: hwloc_distrib_flags_e = 1 << 0;
1907
1908// === The bitmap API: https://hwloc.readthedocs.io/en/stable/group__hwlocality__bitmap.html
1909
1910/// Opaque bitmap struct
1911///
1912/// Represents the private `hwloc_bitmap_s` type that `hwloc_bitmap_t` API
1913/// pointers map to.
1914///
1915/// This type purposely implements almost no traits, not even Debug, because you
1916/// should never, ever deal with it directly, only with raw pointers to it that
1917/// you blindly pass to the hwloc API.
1918///
1919/// The only exception to this rule is [`RefUnwindSafe`], which is special
1920/// because...
1921///
1922/// - You cannot implement [`UnwindSafe`] yourself for standard pointer types
1923///   due to orphan rules
1924/// - Rust implements it for pointers to [`RefUnwindSafe`], i.e. it assumes you
1925///   use pointers to such data responsibly.
1926/// - The ergonomic impact of everyday types not being [`UnwindSafe`] is
1927///   annoying (need [`AssertUnwindSafe`] in every [`catch_unwind()`]).
1928///
1929/// [`AssertUnwindSafe`]: std::panic::AssertUnwindSafe
1930/// [`catch_unwind()`]: std::panic::catch_unwind()
1931#[allow(missing_debug_implementations)]
1932#[repr(C)]
1933pub struct hwloc_bitmap_s(IncompleteType);
1934//
1935impl RefUnwindSafe for hwloc_bitmap_s {}
1936
1937/// Set of bits represented as an opaque pointer to an internal bitmap
1938pub type hwloc_bitmap_t = *mut hwloc_bitmap_s;
1939
1940/// A non-modifiable [`hwloc_bitmap_t`]
1941pub type hwloc_const_bitmap_t = *const hwloc_bitmap_s;
1942
1943// === Exporting Topologies to XML: https://hwloc.readthedocs.io/en/stable/group__hwlocality__xmlexport.html
1944
1945/// Flags to be given to [`hwloc_topology_export_xml()`]
1946pub type hwloc_topology_export_xml_flags_e = c_ulong;
1947
1948/// Export XML that is loadable by hwloc v1.x
1949///
1950/// The export may miss some details about the topology.
1951pub const HWLOC_TOPOLOGY_EXPORT_XML_FLAG_V1: hwloc_topology_export_xml_flags_e = 1 << 0;
1952
1953// === Exporting Topologies to Synthetic: https://hwloc.readthedocs.io/en/stable/group__hwlocality__syntheticexport.html
1954
1955/// Flags to be given to [`hwloc_topology_export_synthetic()`]
1956pub type hwloc_topology_export_synthetic_flags_e = c_ulong;
1957
1958/// Export extended types such as L2dcache as basic types such as Cache
1959///
1960/// This is required if loading the synthetic description with hwloc < 1.9.
1961pub const HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_EXTENDED_TYPES:
1962    hwloc_topology_export_synthetic_flags_e = 1 << 0;
1963
1964/// Do not export level attributes
1965///
1966/// Ignore level attributes such as memory/cache sizes or PU indices.
1967///
1968/// This is required if loading the synthetic description with hwloc < 1.10.
1969pub const HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_ATTRS: hwloc_topology_export_synthetic_flags_e =
1970    1 << 1;
1971
1972/// Export the memory hierarchy as expected in hwloc 1.x
1973///
1974/// Instead of attaching memory children to levels, export single NUMA
1975/// node children as normal intermediate levels, when possible.
1976///
1977/// This is required if loading the synthetic description with hwloc 1.x.
1978/// However this may fail if some objects have multiple local NUMA nodes.
1979pub const HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_V1: hwloc_topology_export_synthetic_flags_e = 1 << 2;
1980
1981/// Do not export memory information
1982///
1983/// Only export the actual hierarchy of normal CPU-side objects and
1984/// ignore where memory is attached.
1985///
1986/// This is useful for when the hierarchy of CPUs is what really matters,
1987/// but it behaves as if there was a single machine-wide NUMA node.
1988pub const HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_IGNORE_MEMORY:
1989    hwloc_topology_export_synthetic_flags_e = 1 << 3;
1990
1991// === Retrieve distances between objects: https://hwloc.readthedocs.io/en/stable/group__hwlocality__distances__get.html
1992
1993/// Kinds of distance matrices
1994///
1995/// A kind with a name starting with "FROM_" specifies where the distance
1996/// information comes from, if known.
1997///
1998/// A kind with a name starting with "MEANS_" specifies whether values are
1999/// latencies or bandwidths, if applicable.
2000///
2001/// Only one of the "FROM_" and "MEANS_" kinds should be present.
2002pub type hwloc_distances_kind_e = c_ulong;
2003
2004/// These distances were obtained from the operating system or hardware
2005pub const HWLOC_DISTANCES_KIND_FROM_OS: hwloc_distances_kind_e = 1 << 0;
2006
2007/// These distances were provided by the user
2008pub const HWLOC_DISTANCES_KIND_FROM_USER: hwloc_distances_kind_e = 1 << 1;
2009
2010/// Distance values are similar to latencies between objects
2011///
2012/// Values are smaller for closer objects, hence minimal on the diagonal
2013/// of the matrix (distance between an object and itself).
2014///
2015/// It could also be the number of network hops between objects, etc.
2016pub const HWLOC_DISTANCES_KIND_MEANS_LATENCY: hwloc_distances_kind_e = 1 << 2;
2017
2018/// Distance values are similar to bandwidths between objects
2019///
2020/// Values are higher for closer objects, hence maximal on the diagonal
2021/// of the matrix (distance between an object and itself).
2022///
2023/// Such values are currently ignored for distance-based grouping.
2024pub const HWLOC_DISTANCES_KIND_MEANS_BANDWIDTH: hwloc_distances_kind_e = 1 << 3;
2025
2026/// This distances structure covers objects of different types
2027///
2028/// This may apply to the "NVLinkBandwidth" structure in presence of a
2029/// NVSwitch or POWER processor NVLink port.
2030#[cfg(feature = "hwloc-2_1_0")]
2031pub const HWLOC_DISTANCES_KIND_HETEROGENEOUS_TYPES: hwloc_distances_kind_e = 1 << 4;
2032
2033/// Module existing solely to apply a common hwloc version gate
2034#[allow(clippy::wildcard_imports)]
2035#[cfg(feature = "hwloc-2_5_0")]
2036mod distances_transform {
2037    use super::*;
2038
2039    /// Transformations of distances structures
2040    ///
2041    /// We can't use Rust enums to model C enums in FFI because that results in
2042    /// undefined behavior if the C API gets new enum variants and sends them to us.
2043    pub type hwloc_distances_transform_e = c_uint;
2044
2045    /// Remove NULL objects from the distances structure.
2046    ///
2047    /// Every object that was replaced with NULL in [`hwloc_distances_s::objs`]
2048    /// is removed and the matrix is updated accordingly.
2049    ///
2050    /// At least 2 objects must remain, otherwise [`hwloc_distances_transform()`]
2051    /// will fail.
2052    ///
2053    /// [`hwloc_distances_s::kind`] will be updated with or without
2054    /// [`HWLOC_DISTANCES_KIND_HETEROGENEOUS_TYPES`] according to the remaining
2055    /// objects.
2056    pub const HWLOC_DISTANCES_TRANSFORM_REMOVE_NULL: hwloc_distances_transform_e = 0;
2057
2058    /// Replace bandwidth values with a number of links
2059    ///
2060    /// Usually all values will be either 0 (no link) or 1 (one link).
2061    /// However some matrices could get larger values if some pairs of
2062    /// peers are connected by different numbers of links.
2063    ///
2064    /// Values on the diagonal are set to 0.
2065    ///
2066    /// This transformation only applies to bandwidth matrices.
2067    pub const HWLOC_DISTANCES_TRANSFORM_LINKS: hwloc_distances_transform_e = 1;
2068
2069    /// Merge switches with multiple ports into a single object
2070    ///
2071    /// This currently only applies to NVSwitches where GPUs seem connected to
2072    /// different separate switch ports in the NVLinkBandwidth matrix.
2073    ///
2074    /// This transformation will replace all switch ports with the same port
2075    /// connected to all GPUs.
2076    ///
2077    /// Other ports are removed by applying the
2078    /// [`HWLOC_DISTANCES_TRANSFORM_REMOVE_NULL`] transformation internally.
2079    pub const HWLOC_DISTANCES_TRANSFORM_MERGE_SWITCH_PORTS: hwloc_distances_transform_e = 2;
2080
2081    /// Apply a transitive closure to the matrix to connect objects across
2082    /// switches.
2083    ///
2084    /// This currently only applies to GPUs and NVSwitches in the
2085    /// NVLinkBandwidth matrix.
2086    ///
2087    /// All pairs of GPUs will be reported as directly connected.
2088    pub const HWLOC_DISTANCES_TRANSFORM_TRANSITIVE_CLOSURE: hwloc_distances_transform_e = 3;
2089}
2090#[cfg(feature = "hwloc-2_5_0")]
2091pub use distances_transform::*;
2092
2093/// Matrix of distances between a set of objects
2094///
2095/// This matrix often contains latencies between NUMA nodes (as reported in the
2096/// System Locality Distance Information Table (SLIT) in the ACPI
2097/// specification), which may or may not be physically accurate. It corresponds
2098/// to the latency for accessing the memory of one node from a core in another
2099/// node. The corresponding kind is [`HWLOC_DISTANCES_KIND_FROM_OS`] |
2100/// [`HWLOC_DISTANCES_KIND_FROM_USER`]. The name of this distances structure is
2101/// "NUMALatency".
2102///
2103/// The names and semantics of other distances matrices currently created by
2104/// hwloc may be found
2105/// [in the hwloc documentation](https://hwloc.readthedocs.io/en/stable/topoattrs.html#topoattrs_distances).
2106///
2107/// The matrix may also contain bandwidths between random sets of objects,
2108/// possibly provided by the user, as specified in the `kind` attribute.
2109///
2110/// Pointers `objs` and `values` should not be replaced, reallocated, freed, etc.
2111/// However callers are allowed to modify `kind` as well as the contents of `objs`
2112/// and `values` arrays.
2113///
2114#[cfg_attr(
2115    feature = "hwloc-2_5_0",
2116    doc = "For instance, on hwloc 2.5+, if there is a single NUMA node per Package,"
2117)]
2118#[cfg_attr(
2119    feature = "hwloc-2_5_0",
2120    doc = "[`hwloc_get_obj_with_same_locality()`] may be used to convert"
2121)]
2122#[cfg_attr(
2123    feature = "hwloc-2_5_0",
2124    doc = "between them and replace NUMA nodes in the objs array with the corresponding"
2125)]
2126#[cfg_attr(feature = "hwloc-2_5_0", doc = "Packages.")]
2127#[cfg_attr(feature = "hwloc-2_5_0", doc = "")]
2128#[cfg_attr(
2129    feature = "hwloc-2_5_0",
2130    doc = "See also [`hwloc_distances_transform()`] for applying some"
2131)]
2132#[cfg_attr(feature = "hwloc-2_5_0", doc = "transformations to the structure.")]
2133#[derive(Copy, Clone, Debug)]
2134#[repr(C)]
2135pub struct hwloc_distances_s {
2136    /// Number of objects described by the distance matrix
2137    pub nbobj: c_uint,
2138
2139    /// Array of `nbobj` objects described by the distance matrix
2140    ///
2141    /// These objects are not in any particular order
2142    pub objs: *mut hwloc_obj_t,
2143
2144    /// OR'ed set of [`hwloc_distances_kind_e`].
2145    pub kind: c_ulong,
2146
2147    /// Matrix of distances between objects, stored as a
2148    /// one-dimension array of length `nbobj*nbobj`
2149    ///
2150    /// Distance from i-th to j-th object is stored in slot `i*nbobjs+j`. The
2151    /// meaning of the value depends on the `kind` attribute.
2152    pub values: *mut u64,
2153}
2154//
2155impl Default for hwloc_distances_s {
2156    fn default() -> Self {
2157        Self {
2158            nbobj: 0,
2159            objs: ptr::null_mut(),
2160            kind: 0,
2161            values: ptr::null_mut(),
2162        }
2163    }
2164}
2165
2166// === Add distances between objects: https://hwloc.readthedocs.io/en/stable/group__hwlocality__distances__add.html
2167
2168/// Handle to a new distances structure during its addition to the topology
2169#[cfg(feature = "hwloc-2_5_0")]
2170pub type hwloc_distances_add_handle_t = *mut c_void;
2171
2172/// Flags to be given to [`hwloc_distances_add_commit()`]
2173#[cfg(feature = "hwloc-2_5_0")]
2174pub type hwloc_distances_add_flag_e = c_ulong;
2175
2176/// Try to group objects based on the newly provided distance information
2177///
2178/// This is ignored for distances between objects of different types.
2179#[cfg(feature = "hwloc-2_5_0")]
2180pub const HWLOC_DISTANCES_ADD_FLAG_GROUP: hwloc_distances_add_flag_e = 1 << 0;
2181
2182/// Treat distances as inaccurate for grouping purposes
2183///
2184/// If grouping, consider the distance values as inaccurate and relax the
2185/// comparisons during the grouping algorithms. The actual accuracy may be
2186/// modified through the `HWLOC_GROUPING_ACCURACY` environment variable (see
2187/// [Environment Variables](https://hwloc.readthedocs.io/en/stable/envvar.html)).
2188#[cfg(feature = "hwloc-2_5_0")]
2189pub const HWLOC_DISTANCES_ADD_FLAG_GROUP_INACCURATE: hwloc_distances_add_flag_e = 1 << 1;
2190
2191// === Memory attributes
2192
2193/// Module existing solely to apply a common hwloc version gate
2194#[allow(clippy::wildcard_imports)]
2195#[cfg(feature = "hwloc-2_3_0")]
2196mod memory_attributes {
2197    use super::*;
2198
2199    // === Comparing memory node attributes for finding where to allocate on: https://hwloc.readthedocs.io/en/stable/group__hwlocality__memattrs.html
2200
2201    /// Memory attribute identifier
2202    ///
2203    /// May be one of the `HWLOC_MEMATTR_ID_` constants or a new id returned by
2204    /// [`hwloc_memattr_register()`].
2205    #[doc(alias = "hwloc_memattr_id_e")]
2206    pub type hwloc_memattr_id_t = c_uint;
2207
2208    /// Node capacity in bytes (see [`hwloc_obj::total_memory`])
2209    ///
2210    /// This attribute involves no initiator.
2211    ///
2212    /// Requires [`hwloc_topology_discovery_support::numa_memory`] to be set.
2213    pub const HWLOC_MEMATTR_ID_CAPACITY: hwloc_memattr_id_t = 0;
2214
2215    /// Number of PUs in that locality (i.e. cpuset weight)
2216    ///
2217    /// Smaller locality is better. This attribute involves no initiator.
2218    ///
2219    /// Requires [`hwloc_topology_discovery_support::pu`] to be set.
2220    pub const HWLOC_MEMATTR_ID_LOCALITY: hwloc_memattr_id_t = 1;
2221
2222    /// Average bandwidth in MiB/s, as seen from the given initiator location
2223    ///
2224    /// This is the average bandwidth for read and write accesses. If the
2225    /// platform provides individual read and write bandwidths but no
2226    /// explicit average value, hwloc computes and returns the average.
2227    pub const HWLOC_MEMATTR_ID_BANDWIDTH: hwloc_memattr_id_t = 2;
2228
2229    /// Read bandwidth in MiB/s, as seen from the given initiator location
2230    #[cfg(feature = "hwloc-2_8_0")]
2231    #[cfg_attr(docsrs, doc(cfg(feature = "hwloc-2_8_0")))]
2232    pub const HWLOC_MEMATTR_ID_READ_BANDWIDTH: hwloc_memattr_id_t = 4;
2233
2234    /// Write bandwidth in MiB/s, as seen from the given initiator location
2235    #[cfg(feature = "hwloc-2_8_0")]
2236    #[cfg_attr(docsrs, doc(cfg(feature = "hwloc-2_8_0")))]
2237    pub const HWLOC_MEMATTR_ID_WRITE_BANDWIDTH: hwloc_memattr_id_t = 5;
2238
2239    /// Latency in nanoseconds, as seen from the given initiator location
2240    ///
2241    /// This is the average latency for read and write accesses. If the
2242    /// platform value provides individual read and write latencies but no
2243    /// explicit average, hwloc computes and returns the average.
2244    pub const HWLOC_MEMATTR_ID_LATENCY: hwloc_memattr_id_t = 3;
2245
2246    /// Read latency in nanoseconds, as seen from the given initiator location
2247    #[cfg(feature = "hwloc-2_8_0")]
2248    #[cfg_attr(docsrs, doc(cfg(feature = "hwloc-2_8_0")))]
2249    pub const HWLOC_MEMATTR_ID_READ_LATENCY: hwloc_memattr_id_t = 6;
2250
2251    /// Write latency in nanoseconds, as seen from the given initiator location
2252    #[cfg(feature = "hwloc-2_8_0")]
2253    #[cfg_attr(docsrs, doc(cfg(feature = "hwloc-2_8_0")))]
2254    pub const HWLOC_MEMATTR_ID_WRITE_LATENCY: hwloc_memattr_id_t = 7;
2255    // NOTE: If you add new attributes, add support to hwlocality's
2256    //       hwloc_memattr_id_t, static_flags and MemoryAttribute constructors
2257
2258    /// Flags for selecting more target NUMA nodes
2259    ///
2260    /// By default only NUMA nodes whose locality is exactly the given location
2261    /// are selected.
2262    pub type hwloc_local_numanode_flag_e = c_ulong;
2263
2264    /// Select NUMA nodes whose locality is larger than the given cpuset
2265    ///
2266    /// For instance, if a single PU (or its cpuset) is given in `initiator`,
2267    /// select all nodes close to the package that contains this PU.
2268    pub const HWLOC_LOCAL_NUMANODE_FLAG_LARGER_LOCALITY: hwloc_local_numanode_flag_e = 1 << 0;
2269
2270    /// Select NUMA nodes whose locality is smaller than the given cpuset
2271    ///
2272    /// For instance, if a package (or its cpuset) is given in `initiator`,
2273    /// also select nodes that are attached to only a half of that package.
2274    pub const HWLOC_LOCAL_NUMANODE_FLAG_SMALLER_LOCALITY: hwloc_local_numanode_flag_e = 1 << 1;
2275
2276    /// Select NUMA nodes whose locality intersects the given cpuset
2277    ///
2278    /// This includes larger and smaller localities as well as localities that
2279    /// are partially included.
2280    ///
2281    /// For instance, if the locality is one core of both packages, a NUMA node
2282    /// local to one package is neither larger nor smaller than this locality,
2283    /// but it intersects it.
2284    #[cfg(feature = "hwloc-2_12_1")]
2285    pub const HWLOC_LOCAL_NUMANODE_FLAG_INTERSECT_LOCALITY: hwloc_local_numanode_flag_e = 1 << 3;
2286
2287    /// Select all NUMA nodes in the topology
2288    ///
2289    /// The initiator is ignored.
2290    pub const HWLOC_LOCAL_NUMANODE_FLAG_ALL: hwloc_local_numanode_flag_e = 1 << 2;
2291
2292    /// Where to measure attributes from
2293    #[derive(Copy, Clone, Debug)]
2294    #[repr(C)]
2295    pub struct hwloc_location {
2296        /// Type of location
2297        #[doc(alias = "hwloc_location::type")]
2298        pub ty: hwloc_location_type_e,
2299
2300        /// Actual location
2301        pub location: hwloc_location_u,
2302    }
2303
2304    /// Type of location
2305    ///
2306    /// C enums can't be modeled as Rust enums because new variants would be UB
2307    pub type hwloc_location_type_e = c_int;
2308
2309    /// Location is given as a cpuset, in the [`hwloc_location_u::cpuset`] union field
2310    pub const HWLOC_LOCATION_TYPE_CPUSET: hwloc_location_type_e = 1;
2311
2312    /// Location is given as an object, in the [`hwloc_location_u::object`] union field
2313    pub const HWLOC_LOCATION_TYPE_OBJECT: hwloc_location_type_e = 0;
2314
2315    /// Actual location
2316    #[derive(Copy, Clone)]
2317    #[doc(alias = "hwloc_location::hwloc_location_u")]
2318    #[repr(C)]
2319    pub union hwloc_location_u {
2320        /// Directly provide CPU set to find NUMA nodes with corresponding
2321        /// locality
2322        ///
2323        /// This is the only initiator type supported by most memory attribute
2324        /// queries on hwloc-defined memory attributes, though `object` remains
2325        /// an option for user-defined memory attributes.
2326        pub cpuset: hwloc_const_cpuset_t,
2327
2328        /// Use a topology object as an initiator
2329        ///
2330        /// Most memory attribute queries on hwloc-defined memory attributes do
2331        /// not support this initiator type, or translate it to a cpuset
2332        /// (going up the ancestor chain if necessary). But user-defined memory
2333        /// attributes may for instance use it to provide custom information
2334        /// about host memory accesses performed by GPUs.
2335        pub object: *const hwloc_obj,
2336    }
2337    //
2338    impl Debug for hwloc_location_u {
2339        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2340            f.debug_struct("hwloc_location_u").finish_non_exhaustive()
2341        }
2342    }
2343
2344    /// Memory attribute flags
2345    ///
2346    /// At least one of [`HWLOC_MEMATTR_FLAG_HIGHER_FIRST`] and
2347    /// [`HWLOC_MEMATTR_FLAG_LOWER_FIRST`] must be set.
2348    pub type hwloc_memattr_flag_e = c_ulong;
2349
2350    /// The best nodes for this memory attribute are those with the higher
2351    /// values
2352    ///
2353    /// For instance [`HWLOC_MEMATTR_ID_BANDWIDTH`].
2354    pub const HWLOC_MEMATTR_FLAG_HIGHER_FIRST: hwloc_memattr_flag_e = 1 << 0;
2355
2356    /// The best nodes for this memory attribute are those with the lower
2357    /// values
2358    ///
2359    /// For instance [`HWLOC_MEMATTR_ID_LATENCY`].
2360    pub const HWLOC_MEMATTR_FLAG_LOWER_FIRST: hwloc_memattr_flag_e = 1 << 1;
2361
2362    /// The value returned for this memory attribute depends on the given
2363    /// initiator
2364    ///
2365    /// For instance [`HWLOC_MEMATTR_ID_BANDWIDTH`] and
2366    /// [`HWLOC_MEMATTR_ID_LATENCY`], but not[`HWLOC_MEMATTR_ID_CAPACITY`].
2367    pub const HWLOC_MEMATTR_FLAG_NEED_INITIATOR: hwloc_memattr_flag_e = 1 << 2;
2368}
2369#[cfg(feature = "hwloc-2_3_0")]
2370pub use memory_attributes::*;
2371
2372// === Entry points
2373
2374/// Implement all the entry points with the right link name
2375macro_rules! extern_c_block {
2376    ($link_name:literal) => {
2377        #[link(name = $link_name)]
2378        extern "C" {
2379            // === API versioning: https://hwloc.readthedocs.io/en/stable/group__hwlocality__api__version.html
2380
2381            /// Indicate at runtime which hwloc API version was used at build time
2382            ///
2383            /// This number is updated to `(X<<16)+(Y<<8)+Z` when a new release X.Y.Z
2384            /// actually modifies the API.
2385            #[must_use]
2386            pub fn hwloc_get_api_version() -> c_uint;
2387
2388            // === Object types: https://hwloc.readthedocs.io/en/stable/group__hwlocality__object__types.html
2389
2390            /// Compare the depth of two object types.
2391            ///
2392            /// Types shouldn't be compared as they are, since newer ones may be
2393            /// added in the future.
2394            ///
2395            /// # Returns
2396            ///
2397            /// - A negative integer if `type1` objects usually include `type2`
2398            ///   objects.
2399            /// - A positive integer if `type1` objects are usually included in
2400            ///   `type2` objects.
2401            /// - 0 if `type1` and `type2` objects are the same.
2402            /// - [`HWLOC_TYPE_UNORDERED`] if objects cannot be compared
2403            ///   (because neither is usually contained in the other).
2404            ///
2405            /// # Note
2406            ///
2407            /// - Object types containing CPUs can always be compared (usually,
2408            ///   a machine contains packages, which contain caches, which
2409            ///   contain cores, which contain PUs).
2410            /// - [`HWLOC_OBJ_PU`] will always be the deepest, while
2411            ///   [`HWLOC_OBJ_MACHINE`] is always the highest.
2412            /// - This does not mean that the actual topology will respect that
2413            ///   order: e.g. as of today cores may also contain caches, and
2414            ///   packages may also contain nodes. This is thus just to be seen
2415            ///   as a fallback comparison method.
2416            #[must_use]
2417            pub fn hwloc_compare_types(type1: hwloc_obj_type_t, type2: hwloc_obj_type_t) -> c_int;
2418
2419            // === Topology creation and destruction: https://hwloc.readthedocs.io/en/stable/group__hwlocality__creation.html
2420
2421            /// Allocate a topology context
2422            ///
2423            /// # Parameters
2424            ///
2425            /// `[out] topologyp` is assigned a pointer to the new allocated
2426            /// context.
2427            ///
2428            /// # Returns
2429            ///
2430            /// 0 on success, -1 on error
2431            #[must_use]
2432            pub fn hwloc_topology_init(topology: *mut hwloc_topology_t) -> c_int;
2433
2434            /// Build the actual topology
2435            ///
2436            /// Build the actual topology once initialized with
2437            /// [`hwloc_topology_init()`] and tuned with[Topology Detection
2438            /// Configuration and
2439            /// Query](https://hwloc.readthedocs.io/en/stable/group__hwlocality__configuration.html)
2440            /// and [Changing the Source of Topology
2441            /// Discovery](https://hwloc.readthedocs.io/en/stable/group__hwlocality__setsource.html)
2442            /// routines. No other routine may be called earlier using this
2443            /// topology context.
2444            ///
2445            /// # Parameters
2446            ///
2447            /// `topology` is the topology to be loaded with objects.
2448            ///
2449            /// # Returns
2450            ///
2451            /// 0 on success, -1 on error
2452            ///
2453            /// # Note
2454            ///
2455            /// - On failure, the topology is reinitialized. It should be either
2456            ///   destroyed with [`hwloc_topology_destroy()`] or configured and
2457            ///   loaded again.
2458            /// - This function may be called only once per topology.
2459            /// - The binding of the current thread or process may temporarily
2460            ///   change during this call but it will be restored before it
2461            ///   returns.
2462            #[must_use]
2463            pub fn hwloc_topology_load(topology: hwloc_topology_t) -> c_int;
2464
2465            /// Terminate and free a topology context
2466            ///
2467            /// # Parameters
2468            ///
2469            /// `topology` is the topology to be freed
2470            pub fn hwloc_topology_destroy(topology: hwloc_topology_t);
2471
2472            /// Duplicate a topology
2473            ///
2474            /// The entire topology structure as well as its objects are
2475            /// duplicated into a new one.
2476            ///
2477            /// This is useful for keeping a backup while modifying a topology.
2478            ///
2479            /// # Returns
2480            ///
2481            /// 0 on success, -1 on error
2482            ///
2483            /// # Note
2484            ///
2485            /// Object userdata is not duplicated since hwloc does not know what
2486            /// it points to. The objects of both old and new topologies will
2487            /// point to the same userdata.
2488            #[must_use]
2489            pub fn hwloc_topology_dup(
2490                newtop: *mut hwloc_topology_t,
2491                oldtop: hwloc_const_topology_t,
2492            ) -> c_int;
2493
2494            /// Check that this topology is compatible with the current hwloc
2495            /// library
2496            ///
2497            /// This is useful when using the same topology structure (in
2498            /// memory) in different libraries that may use different hwloc
2499            /// installations (for instance if one library embeds a specific
2500            /// version of hwloc, while another library uses a default
2501            /// system-wide hwloc installation).
2502            ///
2503            /// If all libraries/programs use the same hwloc installation, this
2504            /// function always returns 0.
2505            ///
2506            /// # Returns
2507            ///
2508            /// - `0` on success
2509            /// - `-1` with errno set to `EINVAL` if incompatible
2510            //
2511            // --- Implementation details ---
2512            //
2513            // TODO: Propagate note about interprocess sharing from upstream docs
2514            //       once interprocess sharing is implemented.
2515            #[must_use]
2516            pub fn hwloc_topology_abi_check(topology: hwloc_const_topology_t) -> c_int;
2517
2518            /// Run internal checks on a topology structure
2519            ///
2520            /// The program aborts if an inconsistency is detected in the given
2521            /// topology.
2522            ///
2523            /// # Parameters
2524            ///
2525            /// `topology` is the topology to be checked
2526            ///
2527            /// # Note
2528            ///
2529            /// - This routine is only useful to developers.
2530            /// - The input topology should have been previously loaded with
2531            ///   [`hwloc_topology_load()`].
2532            pub fn hwloc_topology_check(topology: hwloc_const_topology_t);
2533
2534            // === Object levels, depths and types: https://hwloc.readthedocs.io/en/stable/group__hwlocality__levels.html
2535
2536            #[must_use]
2537            pub fn hwloc_topology_get_depth(
2538                topology: hwloc_const_topology_t,
2539            ) -> hwloc_get_type_depth_e;
2540            #[must_use]
2541            pub fn hwloc_get_type_depth(
2542                topology: hwloc_const_topology_t,
2543                object_type: hwloc_obj_type_t,
2544            ) -> hwloc_get_type_depth_e;
2545            #[must_use]
2546            pub fn hwloc_get_memory_parents_depth(
2547                topology: hwloc_const_topology_t,
2548            ) -> hwloc_get_type_depth_e;
2549            #[must_use]
2550            pub fn hwloc_get_depth_type(
2551                topology: hwloc_const_topology_t,
2552                depth: hwloc_get_type_depth_e,
2553            ) -> hwloc_obj_type_t;
2554            #[must_use]
2555            pub fn hwloc_get_nbobjs_by_depth(
2556                topology: hwloc_const_topology_t,
2557                depth: hwloc_get_type_depth_e,
2558            ) -> c_uint;
2559            #[must_use]
2560            pub fn hwloc_get_obj_by_depth(
2561                topology: hwloc_const_topology_t,
2562                depth: hwloc_get_type_depth_e,
2563                idx: c_uint,
2564            ) -> hwloc_obj_t;
2565
2566            // === Converting between object types, attributes and strings: https://hwloc.readthedocs.io/en/stable/group__hwlocality__object__strings.html
2567
2568            #[must_use]
2569            pub fn hwloc_obj_type_snprintf(
2570                into: *mut c_char,
2571                size: usize,
2572                object: *const hwloc_obj,
2573                verbose: c_int,
2574            ) -> c_int;
2575            #[must_use]
2576            pub fn hwloc_obj_attr_snprintf(
2577                into: *mut c_char,
2578                size: usize,
2579                object: *const hwloc_obj,
2580                separator: *const c_char,
2581                verbose: c_int,
2582            ) -> c_int;
2583            // NOTE: Not exposing type printf/scanf for now
2584
2585            // === Consulting and adding Key-Value info attributes: https://hwloc.readthedocs.io/en/stable/group__hwlocality__info__attr.html
2586
2587            #[must_use]
2588            pub fn hwloc_obj_add_info(
2589                obj: hwloc_obj_t,
2590                name: *const c_char,
2591                value: *const c_char,
2592            ) -> c_int;
2593
2594            /// Set (or replace) the subtype of an object.
2595            ///
2596            /// The given `subtype` is copied internally, the caller is
2597            /// responsible for freeing the original `subtype` if needed.
2598            ///
2599            /// If another subtype already exists in `object`, it is replaced.
2600            /// The given `subtype` may be `NULL` to remove the existing subtype.
2601            ///
2602            /// This function is mostly meant to initialize the subtype of
2603            /// user-added objects such as groups with
2604            /// `hwloc_topology_alloc_group_object()`.
2605            ///
2606            /// # Return values
2607            ///
2608            /// - `0` on success.
2609            /// - `-1` with `errno` set to `ENOMEM` on failure to allocate
2610            ///   memory.
2611            #[cfg(feature = "hwloc-2_11_0")]
2612            #[must_use]
2613            pub fn hwloc_obj_set_subtype(
2614                topology: hwloc_topology_t,
2615                obj: hwloc_obj_t,
2616                subtype: *const c_char,
2617            ) -> c_int;
2618
2619            // === CPU binding: https://hwloc.readthedocs.io/en/stable/group__hwlocality__cpubinding.html
2620
2621            #[must_use]
2622            pub fn hwloc_set_cpubind(
2623                topology: hwloc_const_topology_t,
2624                set: hwloc_const_cpuset_t,
2625                flags: hwloc_cpubind_flags_t,
2626            ) -> c_int;
2627            #[must_use]
2628            pub fn hwloc_get_cpubind(
2629                topology: hwloc_const_topology_t,
2630                set: hwloc_cpuset_t,
2631                flags: hwloc_cpubind_flags_t,
2632            ) -> c_int;
2633            #[must_use]
2634            pub fn hwloc_set_proc_cpubind(
2635                topology: hwloc_const_topology_t,
2636                pid: hwloc_pid_t,
2637                set: hwloc_const_cpuset_t,
2638                flags: hwloc_cpubind_flags_t,
2639            ) -> c_int;
2640            #[must_use]
2641            pub fn hwloc_get_proc_cpubind(
2642                topology: hwloc_const_topology_t,
2643                pid: hwloc_pid_t,
2644                set: hwloc_cpuset_t,
2645                flags: hwloc_cpubind_flags_t,
2646            ) -> c_int;
2647            #[must_use]
2648            pub fn hwloc_set_thread_cpubind(
2649                topology: hwloc_const_topology_t,
2650                thread: hwloc_thread_t,
2651                set: hwloc_const_cpuset_t,
2652                flags: hwloc_cpubind_flags_t,
2653            ) -> c_int;
2654            #[must_use]
2655            pub fn hwloc_get_thread_cpubind(
2656                topology: hwloc_const_topology_t,
2657                pid: hwloc_thread_t,
2658                set: hwloc_cpuset_t,
2659                flags: hwloc_cpubind_flags_t,
2660            ) -> c_int;
2661            #[must_use]
2662            pub fn hwloc_get_last_cpu_location(
2663                topology: hwloc_const_topology_t,
2664                set: hwloc_cpuset_t,
2665                flags: hwloc_cpubind_flags_t,
2666            ) -> c_int;
2667            #[must_use]
2668            pub fn hwloc_get_proc_last_cpu_location(
2669                topology: hwloc_const_topology_t,
2670                pid: hwloc_pid_t,
2671                set: hwloc_cpuset_t,
2672                flags: hwloc_cpubind_flags_t,
2673            ) -> c_int;
2674
2675            // === Memory binding: https://hwloc.readthedocs.io/en/stable/group__hwlocality__membinding.html
2676
2677            #[must_use]
2678            pub fn hwloc_set_membind(
2679                topology: hwloc_const_topology_t,
2680                set: hwloc_const_bitmap_t,
2681                policy: hwloc_membind_policy_t,
2682                flags: hwloc_membind_flags_t,
2683            ) -> c_int;
2684            #[must_use]
2685            pub fn hwloc_get_membind(
2686                topology: hwloc_const_topology_t,
2687                set: hwloc_bitmap_t,
2688                policy: *mut hwloc_membind_policy_t,
2689                flags: hwloc_membind_flags_t,
2690            ) -> c_int;
2691            #[must_use]
2692            pub fn hwloc_set_proc_membind(
2693                topology: hwloc_const_topology_t,
2694                pid: hwloc_pid_t,
2695                set: hwloc_const_bitmap_t,
2696                policy: hwloc_membind_policy_t,
2697                flags: hwloc_membind_flags_t,
2698            ) -> c_int;
2699            #[must_use]
2700            pub fn hwloc_get_proc_membind(
2701                topology: hwloc_const_topology_t,
2702                pid: hwloc_pid_t,
2703                set: hwloc_bitmap_t,
2704                policy: *mut hwloc_membind_policy_t,
2705                flags: hwloc_membind_flags_t,
2706            ) -> c_int;
2707            #[must_use]
2708            pub fn hwloc_set_area_membind(
2709                topology: hwloc_const_topology_t,
2710                addr: *const c_void,
2711                len: usize,
2712                set: hwloc_const_bitmap_t,
2713                policy: hwloc_membind_policy_t,
2714                flags: hwloc_membind_flags_t,
2715            ) -> c_int;
2716            #[must_use]
2717            pub fn hwloc_get_area_membind(
2718                topology: hwloc_const_topology_t,
2719                addr: *const c_void,
2720                len: usize,
2721                set: hwloc_bitmap_t,
2722                policy: *mut hwloc_membind_policy_t,
2723                flags: hwloc_membind_flags_t,
2724            ) -> c_int;
2725            #[must_use]
2726            pub fn hwloc_get_area_memlocation(
2727                topology: hwloc_const_topology_t,
2728                addr: *const c_void,
2729                len: usize,
2730                set: hwloc_bitmap_t,
2731                flags: hwloc_membind_flags_t,
2732            ) -> c_int;
2733            #[must_use]
2734            pub fn hwloc_alloc(topology: hwloc_const_topology_t, len: usize) -> *mut c_void;
2735            #[must_use]
2736            pub fn hwloc_alloc_membind(
2737                topology: hwloc_const_topology_t,
2738                len: usize,
2739                set: hwloc_const_bitmap_t,
2740                policy: hwloc_membind_policy_t,
2741                flags: hwloc_membind_flags_t,
2742            ) -> *mut c_void;
2743            #[must_use]
2744            pub fn hwloc_free(
2745                topology: hwloc_const_topology_t,
2746                addr: *mut c_void,
2747                len: usize,
2748            ) -> c_int;
2749
2750            // === Changing the source of topology discovery: https://hwloc.readthedocs.io/en/stable/group__hwlocality__setsource.html
2751
2752            #[must_use]
2753            pub fn hwloc_topology_set_pid(topology: hwloc_topology_t, pid: hwloc_pid_t) -> c_int;
2754            #[must_use]
2755            pub fn hwloc_topology_set_synthetic(
2756                topology: hwloc_topology_t,
2757                description: *const c_char,
2758            ) -> c_int;
2759            #[must_use]
2760            pub fn hwloc_topology_set_xml(
2761                topology: hwloc_topology_t,
2762                xmlpath: *const c_char,
2763            ) -> c_int;
2764            #[must_use]
2765            pub fn hwloc_topology_set_xmlbuffer(
2766                topology: hwloc_topology_t,
2767                buffer: *const c_char,
2768                size: c_int,
2769            ) -> c_int;
2770            #[cfg(feature = "hwloc-2_1_0")]
2771            #[must_use]
2772            pub fn hwloc_topology_set_components(
2773                topology: hwloc_topology_t,
2774                flags: hwloc_topology_components_flag_e,
2775                name: *const c_char,
2776            ) -> c_int;
2777
2778            // === Topology detection configuration and query: https://hwloc.readthedocs.io/en/stable/group__hwlocality__configuration.html
2779
2780            #[must_use]
2781            pub fn hwloc_topology_set_flags(
2782                topology: hwloc_topology_t,
2783                flags: hwloc_topology_flags_e,
2784            ) -> c_int;
2785            #[must_use]
2786            pub fn hwloc_topology_get_flags(
2787                topology: hwloc_const_topology_t,
2788            ) -> hwloc_topology_flags_e;
2789            #[must_use]
2790            pub fn hwloc_topology_is_thissystem(topology: hwloc_const_topology_t) -> c_int;
2791            #[must_use]
2792            pub fn hwloc_topology_get_support(
2793                topology: hwloc_const_topology_t,
2794            ) -> *const hwloc_topology_support;
2795            #[must_use]
2796            pub fn hwloc_topology_set_type_filter(
2797                topology: hwloc_topology_t,
2798                ty: hwloc_obj_type_t,
2799                filter: hwloc_type_filter_e,
2800            ) -> c_int;
2801            #[must_use]
2802            pub fn hwloc_topology_get_type_filter(
2803                topology: hwloc_const_topology_t,
2804                ty: hwloc_obj_type_t,
2805                filter: *mut hwloc_type_filter_e,
2806            ) -> c_int;
2807            #[must_use]
2808            pub fn hwloc_topology_set_all_types_filter(
2809                topology: hwloc_topology_t,
2810                filter: hwloc_type_filter_e,
2811            ) -> c_int;
2812            #[must_use]
2813            pub fn hwloc_topology_set_cache_types_filter(
2814                topology: hwloc_topology_t,
2815                filter: hwloc_type_filter_e,
2816            ) -> c_int;
2817            #[must_use]
2818            pub fn hwloc_topology_set_icache_types_filter(
2819                topology: hwloc_topology_t,
2820                filter: hwloc_type_filter_e,
2821            ) -> c_int;
2822            #[must_use]
2823            pub fn hwloc_topology_set_io_types_filter(
2824                topology: hwloc_topology_t,
2825                filter: hwloc_type_filter_e,
2826            ) -> c_int;
2827            // NOTE: set_userdata and get_userdata are NOT exposed because they
2828            //       are hard to make work with copying, persistence and thread
2829            //       safety and are not so useful as to justify the effort.
2830
2831            // === Modifying a loaded Topology: https://hwloc.readthedocs.io/en/stable/group__hwlocality__tinker.html
2832
2833            #[cfg(feature = "hwloc-2_3_0")]
2834            #[must_use]
2835            pub fn hwloc_topology_restrict(
2836                topology: hwloc_topology_t,
2837                set: hwloc_const_bitmap_t,
2838                flags: hwloc_restrict_flags_e,
2839            ) -> c_int;
2840            #[cfg(feature = "hwloc-2_3_0")]
2841            #[must_use]
2842            pub fn hwloc_topology_allow(
2843                topology: hwloc_topology_t,
2844                cpuset: hwloc_const_cpuset_t,
2845                nodeset: hwloc_const_nodeset_t,
2846                flags: hwloc_allow_flags_e,
2847            ) -> c_int;
2848            #[cfg(feature = "hwloc-2_3_0")]
2849            #[must_use]
2850            pub fn hwloc_topology_insert_misc_object(
2851                topology: hwloc_topology_t,
2852                parent: hwloc_obj_t,
2853                name: *const c_char,
2854            ) -> hwloc_obj_t;
2855            #[cfg(feature = "hwloc-2_3_0")]
2856            #[must_use]
2857            pub fn hwloc_topology_alloc_group_object(topology: hwloc_topology_t) -> hwloc_obj_t;
2858            #[cfg(feature = "hwloc-2_10_0")]
2859            #[must_use]
2860            pub fn hwloc_topology_free_group_object(
2861                topology: hwloc_topology_t,
2862                group: hwloc_obj_t,
2863            ) -> c_int;
2864            #[cfg(feature = "hwloc-2_3_0")]
2865            #[must_use]
2866            pub fn hwloc_topology_insert_group_object(
2867                topology: hwloc_topology_t,
2868                group: hwloc_obj_t,
2869            ) -> hwloc_obj_t;
2870            #[cfg(feature = "hwloc-2_3_0")]
2871            #[must_use]
2872            pub fn hwloc_obj_add_other_obj_sets(dst: hwloc_obj_t, src: *const hwloc_obj) -> c_int;
2873            #[cfg(feature = "hwloc-2_3_0")]
2874            #[must_use]
2875            pub fn hwloc_topology_refresh(topology: hwloc_topology_t) -> c_int;
2876
2877            // === Kinds of ObjectTypes: https://hwloc.readthedocs.io/en/stable/group__hwlocality__helper__types.html
2878
2879            #[must_use]
2880            pub fn hwloc_obj_type_is_normal(ty: hwloc_obj_type_t) -> c_int;
2881            #[must_use]
2882            pub fn hwloc_obj_type_is_io(ty: hwloc_obj_type_t) -> c_int;
2883            #[must_use]
2884            pub fn hwloc_obj_type_is_memory(ty: hwloc_obj_type_t) -> c_int;
2885            #[must_use]
2886            pub fn hwloc_obj_type_is_cache(ty: hwloc_obj_type_t) -> c_int;
2887            #[must_use]
2888            pub fn hwloc_obj_type_is_dcache(ty: hwloc_obj_type_t) -> c_int;
2889            #[must_use]
2890            pub fn hwloc_obj_type_is_icache(ty: hwloc_obj_type_t) -> c_int;
2891
2892            // === Finding objects, miscellaneous helpers: https://hwloc.readthedocs.io/en/stable/group__hwlocality__helper__find__misc.html
2893
2894            #[cfg(feature = "hwloc-2_2_0")]
2895            #[must_use]
2896            pub fn hwloc_bitmap_singlify_per_core(
2897                topology: hwloc_const_topology_t,
2898                cpuset: hwloc_cpuset_t,
2899                which: c_uint,
2900            ) -> c_int;
2901            #[cfg(feature = "hwloc-2_5_0")]
2902            #[must_use]
2903            pub fn hwloc_get_obj_with_same_locality(
2904                topology: hwloc_const_topology_t,
2905                src: *const hwloc_obj,
2906                ty: hwloc_obj_type_t,
2907                subtype: *const c_char,
2908                nameprefix: *const c_char,
2909                flags: c_ulong,
2910            ) -> *const hwloc_obj;
2911
2912            // === CPU and node sets of entire topologies: https://hwloc.readthedocs.io/en/stable/group__hwlocality__helper__topology__sets.html
2913
2914            #[must_use]
2915            pub fn hwloc_topology_get_complete_cpuset(
2916                topology: hwloc_const_topology_t,
2917            ) -> hwloc_const_cpuset_t;
2918            #[must_use]
2919            pub fn hwloc_topology_get_topology_cpuset(
2920                topology: hwloc_const_topology_t,
2921            ) -> hwloc_const_cpuset_t;
2922            #[must_use]
2923            pub fn hwloc_topology_get_allowed_cpuset(
2924                topology: hwloc_const_topology_t,
2925            ) -> hwloc_const_cpuset_t;
2926            #[must_use]
2927            pub fn hwloc_topology_get_complete_nodeset(
2928                topology: hwloc_const_topology_t,
2929            ) -> hwloc_const_nodeset_t;
2930            #[must_use]
2931            pub fn hwloc_topology_get_topology_nodeset(
2932                topology: hwloc_const_topology_t,
2933            ) -> hwloc_const_nodeset_t;
2934            #[must_use]
2935            pub fn hwloc_topology_get_allowed_nodeset(
2936                topology: hwloc_const_topology_t,
2937            ) -> hwloc_const_nodeset_t;
2938
2939            // === Bitmap API: https://hwloc.readthedocs.io/en/stable/group__hwlocality__bitmap.html
2940
2941            #[must_use]
2942            pub fn hwloc_bitmap_alloc() -> hwloc_bitmap_t;
2943            #[must_use]
2944            pub fn hwloc_bitmap_alloc_full() -> hwloc_bitmap_t;
2945            pub fn hwloc_bitmap_free(bitmap: hwloc_bitmap_t);
2946            #[must_use]
2947            pub fn hwloc_bitmap_dup(src: hwloc_const_bitmap_t) -> hwloc_bitmap_t;
2948            #[must_use]
2949            pub fn hwloc_bitmap_copy(dst: hwloc_bitmap_t, src: hwloc_const_bitmap_t) -> c_int;
2950
2951            #[must_use]
2952            pub fn hwloc_bitmap_list_snprintf(
2953                buf: *mut c_char,
2954                len: usize,
2955                bitmap: hwloc_const_bitmap_t,
2956            ) -> c_int;
2957            // NOTE: Not exposing other printfs and scanfs for now
2958
2959            pub fn hwloc_bitmap_zero(bitmap: hwloc_bitmap_t);
2960            pub fn hwloc_bitmap_fill(bitmap: hwloc_bitmap_t);
2961            #[must_use]
2962            pub fn hwloc_bitmap_only(bitmap: hwloc_bitmap_t, id: c_uint) -> c_int;
2963            #[must_use]
2964            pub fn hwloc_bitmap_allbut(bitmap: hwloc_bitmap_t, id: c_uint) -> c_int;
2965            // NOTE: Not exposing ulong-based APIs for now, so no from_ulong, from_ith_ulong, from_ulongs
2966            //       If I decide to add them, gate from_ulongs with #[cfg(feature = "hwloc-2_1_0")]
2967            #[must_use]
2968            pub fn hwloc_bitmap_set(bitmap: hwloc_bitmap_t, id: c_uint) -> c_int;
2969            #[must_use]
2970            pub fn hwloc_bitmap_set_range(
2971                bitmap: hwloc_bitmap_t,
2972                begin: c_uint,
2973                end: c_int,
2974            ) -> c_int;
2975            // NOTE: Not exposing ulong-based APIs for now, so no set_ith_ulong
2976            #[must_use]
2977            pub fn hwloc_bitmap_clr(bitmap: hwloc_bitmap_t, id: c_uint) -> c_int;
2978            #[must_use]
2979            pub fn hwloc_bitmap_clr_range(
2980                bitmap: hwloc_bitmap_t,
2981                begin: c_uint,
2982                end: c_int,
2983            ) -> c_int;
2984            pub fn hwloc_bitmap_singlify(bitmap: hwloc_bitmap_t) -> c_int;
2985            // NOTE: Not exposing ulong-based APIs for now, so no to_ulong, to_ith_ulong, to_ulongs and nr_ulongs
2986            //       If I decide to add them, gate nr_ulongs and to_ulongs with #[cfg(feature = "hwloc-2_1_0")]
2987
2988            #[must_use]
2989            pub fn hwloc_bitmap_isset(bitmap: hwloc_const_bitmap_t, id: c_uint) -> c_int;
2990            #[must_use]
2991            pub fn hwloc_bitmap_iszero(bitmap: hwloc_const_bitmap_t) -> c_int;
2992            #[must_use]
2993            pub fn hwloc_bitmap_isfull(bitmap: hwloc_const_bitmap_t) -> c_int;
2994
2995            #[must_use]
2996            pub fn hwloc_bitmap_first(bitmap: hwloc_const_bitmap_t) -> c_int;
2997            #[must_use]
2998            pub fn hwloc_bitmap_next(bitmap: hwloc_const_bitmap_t, prev: c_int) -> c_int;
2999            #[must_use]
3000            pub fn hwloc_bitmap_last(bitmap: hwloc_const_bitmap_t) -> c_int;
3001
3002            #[must_use]
3003            pub fn hwloc_bitmap_weight(bitmap: hwloc_const_bitmap_t) -> c_int;
3004
3005            #[must_use]
3006            pub fn hwloc_bitmap_first_unset(bitmap: hwloc_const_bitmap_t) -> c_int;
3007            #[must_use]
3008            pub fn hwloc_bitmap_next_unset(bitmap: hwloc_const_bitmap_t, prev: c_int) -> c_int;
3009            #[must_use]
3010            pub fn hwloc_bitmap_last_unset(bitmap: hwloc_const_bitmap_t) -> c_int;
3011
3012            #[must_use]
3013            pub fn hwloc_bitmap_or(
3014                result: hwloc_bitmap_t,
3015                bitmap1: hwloc_const_bitmap_t,
3016                bitmap2: hwloc_const_bitmap_t,
3017            ) -> c_int;
3018            #[must_use]
3019            pub fn hwloc_bitmap_and(
3020                result: hwloc_bitmap_t,
3021                bitmap1: hwloc_const_bitmap_t,
3022                bitmap2: hwloc_const_bitmap_t,
3023            ) -> c_int;
3024            #[must_use]
3025            pub fn hwloc_bitmap_andnot(
3026                result: hwloc_bitmap_t,
3027                bitmap1: hwloc_const_bitmap_t,
3028                bitmap2: hwloc_const_bitmap_t,
3029            ) -> c_int;
3030            #[must_use]
3031            pub fn hwloc_bitmap_xor(
3032                result: hwloc_bitmap_t,
3033                bitmap1: hwloc_const_bitmap_t,
3034                bitmap2: hwloc_const_bitmap_t,
3035            ) -> c_int;
3036            #[must_use]
3037            pub fn hwloc_bitmap_not(result: hwloc_bitmap_t, bitmap: hwloc_const_bitmap_t) -> c_int;
3038
3039            #[must_use]
3040            pub fn hwloc_bitmap_intersects(
3041                left: hwloc_const_bitmap_t,
3042                right: hwloc_const_bitmap_t,
3043            ) -> c_int;
3044            #[must_use]
3045            pub fn hwloc_bitmap_isincluded(
3046                left: hwloc_const_bitmap_t,
3047                right: hwloc_const_bitmap_t,
3048            ) -> c_int;
3049            #[must_use]
3050            pub fn hwloc_bitmap_isequal(
3051                left: hwloc_const_bitmap_t,
3052                right: hwloc_const_bitmap_t,
3053            ) -> c_int;
3054            // NOTE: Not providing compare_first since it trivially follows from
3055            //       first_set and seems obscure.
3056            #[must_use]
3057            pub fn hwloc_bitmap_compare(
3058                left: hwloc_const_bitmap_t,
3059                right: hwloc_const_bitmap_t,
3060            ) -> c_int;
3061
3062            // === Exporting Topologies to XML: https://hwloc.readthedocs.io/en/stable/group__hwlocality__xmlexport.html
3063
3064            #[must_use]
3065            pub fn hwloc_topology_export_xml(
3066                topology: hwloc_const_topology_t,
3067                xmlpath: *const c_char,
3068                flags: hwloc_topology_export_xml_flags_e,
3069            ) -> c_int;
3070            #[must_use]
3071            pub fn hwloc_topology_export_xmlbuffer(
3072                topology: hwloc_const_topology_t,
3073                xmlbuffer: *mut *mut c_char,
3074                buflen: *mut c_int,
3075                flags: hwloc_topology_export_xml_flags_e,
3076            ) -> c_int;
3077            pub fn hwloc_free_xmlbuffer(topology: hwloc_const_topology_t, xmlbuffer: *mut c_char);
3078            // NOTE: Not exposing userdata at the moment, so no need to bind
3079            //       associated API functions yet.
3080
3081            // === Exporting Topologies to Synthetic: https://hwloc.readthedocs.io/en/stable/group__hwlocality__syntheticexport.html
3082
3083            #[must_use]
3084            pub fn hwloc_topology_export_synthetic(
3085                topology: hwloc_const_topology_t,
3086                buffer: *mut c_char,
3087                buflen: usize,
3088                flags: hwloc_topology_export_synthetic_flags_e,
3089            ) -> c_int;
3090
3091            // === Retrieve distances between objects: https://hwloc.readthedocs.io/en/stable/group__hwlocality__distances__get.html
3092
3093            #[must_use]
3094            pub fn hwloc_distances_get(
3095                topology: hwloc_const_topology_t,
3096                nr: *mut c_uint,
3097                distances: *mut *mut hwloc_distances_s,
3098                kind: hwloc_distances_kind_e,
3099                flags: c_ulong,
3100            ) -> c_int;
3101            #[must_use]
3102            pub fn hwloc_distances_get_by_depth(
3103                topology: hwloc_const_topology_t,
3104                depth: c_int,
3105                nr: *mut c_uint,
3106                distances: *mut *mut hwloc_distances_s,
3107                kind: hwloc_distances_kind_e,
3108                flags: c_ulong,
3109            ) -> c_int;
3110            #[must_use]
3111            pub fn hwloc_distances_get_by_type(
3112                topology: hwloc_const_topology_t,
3113                ty: hwloc_obj_type_t,
3114                nr: *mut c_uint,
3115                distances: *mut *mut hwloc_distances_s,
3116                kind: hwloc_distances_kind_e,
3117                flags: c_ulong,
3118            ) -> c_int;
3119            #[cfg(feature = "hwloc-2_1_0")]
3120            #[must_use]
3121            pub fn hwloc_distances_get_by_name(
3122                topology: hwloc_const_topology_t,
3123                name: *const c_char,
3124                nr: *mut c_uint,
3125                distances: *mut *mut hwloc_distances_s,
3126                flags: c_ulong,
3127            ) -> c_int;
3128            #[cfg(feature = "hwloc-2_1_0")]
3129            #[must_use]
3130            pub fn hwloc_distances_get_name(
3131                topology: hwloc_const_topology_t,
3132                distances: *const hwloc_distances_s,
3133            ) -> *const c_char;
3134            pub fn hwloc_distances_release(
3135                topology: hwloc_const_topology_t,
3136                distances: *const hwloc_distances_s,
3137            );
3138            #[cfg(feature = "hwloc-2_5_0")]
3139            #[must_use]
3140            pub fn hwloc_distances_transform(
3141                topology: hwloc_const_topology_t,
3142                distances: *mut hwloc_distances_s,
3143                transform: hwloc_distances_transform_e,
3144                transform_attr: *mut c_void,
3145                flags: c_ulong,
3146            ) -> c_int;
3147
3148            // === Add distances between objects: https://hwloc.readthedocs.io/en/stable/group__hwlocality__distances__add.html
3149
3150            #[cfg(feature = "hwloc-2_5_0")]
3151            #[must_use]
3152            pub fn hwloc_distances_add_create(
3153                topology: hwloc_topology_t,
3154                name: *const c_char,
3155                kind: hwloc_distances_kind_e,
3156                flags: c_ulong,
3157            ) -> hwloc_distances_add_handle_t;
3158            #[cfg(feature = "hwloc-2_5_0")]
3159            #[must_use]
3160            pub fn hwloc_distances_add_values(
3161                topology: hwloc_topology_t,
3162                handle: hwloc_distances_add_handle_t,
3163                nbobjs: c_uint,
3164                objs: *const *const hwloc_obj,
3165                values: *const u64,
3166                flags: c_ulong,
3167            ) -> c_int;
3168            #[cfg(feature = "hwloc-2_5_0")]
3169            #[must_use]
3170            pub fn hwloc_distances_add_commit(
3171                topology: hwloc_topology_t,
3172                handle: hwloc_distances_add_handle_t,
3173                flags: hwloc_distances_add_flag_e,
3174            ) -> c_int;
3175
3176            // === Remove distances between objects: https://hwloc.readthedocs.io/en/stable/group__hwlocality__distances__remove.html
3177
3178            #[cfg(feature = "hwloc-2_3_0")]
3179            #[must_use]
3180            pub fn hwloc_distances_remove(topology: hwloc_topology_t) -> c_int;
3181            #[cfg(feature = "hwloc-2_3_0")]
3182            #[must_use]
3183            pub fn hwloc_distances_remove_by_depth(
3184                topology: hwloc_topology_t,
3185                depth: hwloc_get_type_depth_e,
3186            ) -> c_int;
3187            #[cfg(feature = "hwloc-2_3_0")]
3188            #[must_use]
3189            pub fn hwloc_distances_release_remove(
3190                topology: hwloc_topology_t,
3191                distances: *mut hwloc_distances_s,
3192            ) -> c_int;
3193
3194            // === Comparing memory node attributes for finding where to allocate on: https://hwloc.readthedocs.io/en/stable/group__hwlocality__memattrs.html
3195
3196            #[cfg(feature = "hwloc-2_3_0")]
3197            #[must_use]
3198            pub fn hwloc_memattr_get_by_name(
3199                topology: hwloc_const_topology_t,
3200                name: *const c_char,
3201                id: *mut hwloc_memattr_id_t,
3202            ) -> c_int;
3203            #[cfg(feature = "hwloc-2_3_0")]
3204            #[must_use]
3205            pub fn hwloc_get_local_numanode_objs(
3206                topology: hwloc_const_topology_t,
3207                location: *const hwloc_location,
3208                nr: *mut c_uint,
3209                nodes: *mut *const hwloc_obj,
3210                flags: hwloc_local_numanode_flag_e,
3211            ) -> c_int;
3212            #[cfg(feature = "hwloc-2_3_0")]
3213            #[must_use]
3214            pub fn hwloc_memattr_get_value(
3215                topology: hwloc_const_topology_t,
3216                attribute: hwloc_memattr_id_t,
3217                target_node: *const hwloc_obj,
3218                initiator: *const hwloc_location,
3219                flags: c_ulong,
3220                value: *mut u64,
3221            ) -> c_int;
3222            #[cfg(feature = "hwloc-2_3_0")]
3223            #[must_use]
3224            pub fn hwloc_memattr_get_best_target(
3225                topology: hwloc_const_topology_t,
3226                attribute: hwloc_memattr_id_t,
3227                initiator: *const hwloc_location,
3228                flags: c_ulong,
3229                best_target: *mut *const hwloc_obj,
3230                value: *mut u64,
3231            ) -> c_int;
3232            #[cfg(feature = "hwloc-2_3_0")]
3233            #[must_use]
3234            pub fn hwloc_memattr_get_best_initiator(
3235                topology: hwloc_const_topology_t,
3236                attribute: hwloc_memattr_id_t,
3237                target: *const hwloc_obj,
3238                flags: c_ulong,
3239                best_initiator: *mut hwloc_location,
3240                value: *mut u64,
3241            ) -> c_int;
3242
3243            /// Return the set of default NUMA nodes
3244            ///
3245            /// In machines with heterogeneous memory, some NUMA nodes are
3246            /// considered the default ones, i.e. where basic allocations should
3247            /// be made from. These are usually DRAM nodes.
3248            ///
3249            /// Other nodes may be reserved for specific use (I/O device memory,
3250            /// e.g. GPU memory), small but high performance (HBM), large but
3251            /// slow memory (NVM), etc. Buffers should usually not be allocated
3252            /// from there unless explicitly required.
3253            ///
3254            /// This function fills `nodeset` with the bits of NUMA nodes
3255            /// considered default.
3256            ///
3257            /// It is guaranteed that these nodes have non-intersecting CPU
3258            /// sets, i.e. cores may not have multiple local NUMA nodes anymore.
3259            /// Hence this may be used to iterate over the platform divided into
3260            /// separate NUMA localities, for instance for binding one task per
3261            /// NUMA domain.
3262            ///
3263            /// Any core that had some local NUMA node(s) in the initial
3264            /// topology should still have one in the default nodeset. Corner
3265            /// cases where this would be wrong consist in asymmetric platforms
3266            /// with missing DRAM nodes, or topologies that were already
3267            /// restricted to less NUMA nodes.
3268            ///
3269            /// The returned nodeset may be passed to
3270            /// [`hwloc_topology_restrict()`] with
3271            /// [`HWLOC_RESTRICT_FLAG_BYNODESET`] to remove all non-default
3272            /// nodes from the topology. The resulting topology will be easier
3273            /// to use when iterating over (now homogeneous) NUMA nodes.
3274            ///
3275            /// The heuristics for finding default nodes relies on memory tiers
3276            /// and subtypes as well as the assumption that hardware vendors
3277            /// list default nodes first in hardware tables.
3278            ///
3279            /// `flags` must be 0 for now.
3280            ///
3281            /// Returns 0 on success, -1 on error.
3282            ///
3283            /// The returned nodeset usually contains all nodes from a single
3284            /// memory tier, likely the DRAM one.
3285            ///
3286            /// The returned nodeset is included in the list of available nodes
3287            /// returned by [`hwloc_topology_get_topology_nodeset()`]. It is
3288            /// strictly smaller if the machine has heterogeneous memory.
3289            ///
3290            /// The heuristics may return a suboptimal set of nodes if hwloc
3291            /// could not guess memory types and/or if some default nodes were
3292            /// removed earlier from the topology (e.g. with
3293            /// [`hwloc_topology_restrict()`]).
3294            #[cfg(feature = "hwloc-2_12_0")]
3295            pub fn hwloc_topology_get_default_nodeset(
3296                // FIXME: Defined as hwloc_topology_t in hwloc, but that's
3297                //        hopefully an oversight as there is no reason for
3298                //        this function to modify the topology. See
3299                //        https://github.com/open-mpi/hwloc/issues/722 .
3300                topology: hwloc_const_topology_t,
3301                nodeset: hwloc_nodeset_t,
3302                flags: c_ulong,
3303            ) -> c_int;
3304
3305            // === Managing memory attributes: https://hwloc.readthedocs.io/en/stable/group__hwlocality__memattrs__manage.html
3306
3307            #[cfg(feature = "hwloc-2_3_0")]
3308            #[must_use]
3309            pub fn hwloc_memattr_get_name(
3310                topology: hwloc_const_topology_t,
3311                attribute: hwloc_memattr_id_t,
3312                name: *mut *const c_char,
3313            ) -> c_int;
3314            #[cfg(feature = "hwloc-2_3_0")]
3315            #[must_use]
3316            pub fn hwloc_memattr_get_flags(
3317                topology: hwloc_const_topology_t,
3318                attribute: hwloc_memattr_id_t,
3319                flags: *mut hwloc_memattr_flag_e,
3320            ) -> c_int;
3321            #[cfg(feature = "hwloc-2_3_0")]
3322            #[must_use]
3323            pub fn hwloc_memattr_register(
3324                topology: hwloc_topology_t,
3325                name: *const c_char,
3326                flags: hwloc_memattr_flag_e,
3327                id: *mut hwloc_memattr_id_t,
3328            ) -> c_int;
3329            #[cfg(feature = "hwloc-2_3_0")]
3330            #[must_use]
3331            pub fn hwloc_memattr_set_value(
3332                topology: hwloc_topology_t,
3333                attribute: hwloc_memattr_id_t,
3334                target_node: *const hwloc_obj,
3335                initiator: *const hwloc_location,
3336                flags: c_ulong,
3337                value: u64,
3338            ) -> c_int;
3339            #[cfg(feature = "hwloc-2_3_0")]
3340            #[must_use]
3341            pub fn hwloc_memattr_get_targets(
3342                topology: hwloc_const_topology_t,
3343                attribute: hwloc_memattr_id_t,
3344                initiator: *const hwloc_location,
3345                flags: c_ulong,
3346                nr: *mut c_uint,
3347                targets: *mut *const hwloc_obj,
3348                values: *mut u64,
3349            ) -> c_int;
3350            #[cfg(feature = "hwloc-2_3_0")]
3351            #[must_use]
3352            pub fn hwloc_memattr_get_initiators(
3353                topology: hwloc_const_topology_t,
3354                attribute: hwloc_memattr_id_t,
3355                target_node: *const hwloc_obj,
3356                flags: c_ulong,
3357                nr: *mut c_uint,
3358                initiators: *mut hwloc_location,
3359                values: *mut u64,
3360            ) -> c_int;
3361
3362            // === Kinds of CPU cores: https://hwloc.readthedocs.io/en/stable/group__hwlocality__cpukinds.html
3363
3364            #[cfg(feature = "hwloc-2_4_0")]
3365            #[must_use]
3366            pub fn hwloc_cpukinds_get_nr(topology: hwloc_const_topology_t, flags: c_ulong)
3367                -> c_int;
3368            #[cfg(feature = "hwloc-2_4_0")]
3369            #[must_use]
3370            pub fn hwloc_cpukinds_get_by_cpuset(
3371                topology: hwloc_const_topology_t,
3372                cpuset: hwloc_const_cpuset_t,
3373                flags: c_ulong,
3374            ) -> c_int;
3375            #[cfg(feature = "hwloc-2_4_0")]
3376            #[must_use]
3377            pub fn hwloc_cpukinds_get_info(
3378                topology: hwloc_const_topology_t,
3379                kind_index: c_uint,
3380                cpuset: hwloc_cpuset_t,
3381                efficiency: *mut c_int,
3382                nr_infos: *mut c_uint,
3383                infos: *mut *mut hwloc_info_s,
3384                flags: c_ulong,
3385            ) -> c_int;
3386            #[cfg(feature = "hwloc-2_4_0")]
3387            #[must_use]
3388            pub fn hwloc_cpukinds_register(
3389                topology: hwloc_topology_t,
3390                cpuset: hwloc_const_cpuset_t,
3391                forced_efficiency: c_int,
3392                nr_infos: c_uint,
3393                infos: *const hwloc_info_s,
3394                flags: c_ulong,
3395            ) -> c_int;
3396
3397            // === Linux-specific helpers: https://hwloc.readthedocs.io/en/stable/group__hwlocality__linux.html
3398
3399            #[cfg(any(doc, target_os = "linux"))]
3400            #[must_use]
3401            pub fn hwloc_linux_set_tid_cpubind(
3402                topology: hwloc_const_topology_t,
3403                tid: pid_t,
3404                set: hwloc_const_cpuset_t,
3405            ) -> c_int;
3406            #[cfg(any(doc, target_os = "linux"))]
3407            #[must_use]
3408            pub fn hwloc_linux_get_tid_cpubind(
3409                topology: hwloc_const_topology_t,
3410                tid: pid_t,
3411                set: hwloc_cpuset_t,
3412            ) -> c_int;
3413            #[cfg(any(doc, target_os = "linux"))]
3414            #[must_use]
3415            pub fn hwloc_linux_get_tid_last_cpu_location(
3416                topology: hwloc_const_topology_t,
3417                tid: pid_t,
3418                set: hwloc_cpuset_t,
3419            ) -> c_int;
3420            #[cfg(any(doc, target_os = "linux"))]
3421            #[must_use]
3422            pub fn hwloc_linux_read_path_as_cpumask(
3423                path: *const c_char,
3424                set: hwloc_cpuset_t,
3425            ) -> c_int;
3426
3427            // NOTE: libnuma interop is waiting for higher quality libnuma bindings
3428
3429            // === Windows-specific helpers: https://hwloc.readthedocs.io/en/stable/group__hwlocality__windows.html
3430
3431            #[cfg(any(doc, all(feature = "hwloc-2_5_0", target_os = "windows")))]
3432            #[must_use]
3433            pub fn hwloc_windows_get_nr_processor_groups(
3434                topology: hwloc_const_topology_t,
3435                flags: c_ulong,
3436            ) -> c_int;
3437            #[cfg(any(doc, all(feature = "hwloc-2_5_0", target_os = "windows")))]
3438            #[must_use]
3439            pub fn hwloc_windows_get_processor_group_cpuset(
3440                topology: hwloc_const_topology_t,
3441                pg_index: c_uint,
3442                cpuset: hwloc_cpuset_t,
3443                flags: c_ulong,
3444            ) -> c_int;
3445
3446            // NOTE: glibc interop is waiting for higher quality cpuset support
3447            //       in the libc crate: right now, it is not possible to safely
3448            //       crate a `cpu_set_t`, but functions that manipulate them
3449            //       expect `&mut cpu_set_t`...
3450
3451            // TODO: Cover more later: interop, differences, sharing, etc...
3452            //       Beware that primitives that modify the topology should be
3453            //       exposed in the TopologyEditor, not Topology, because per
3454            //       hwloc documentation hwloc_topology_refresh() must be called
3455            //       before multithreaded access is thread-safe again.
3456        }
3457    };
3458}
3459
3460#[cfg(all(not(feature = "vendored"), target_os = "windows"))]
3461extern_c_block!("libhwloc");
3462
3463#[cfg(all(feature = "vendored", target_os = "windows"))]
3464extern_c_block!("hwloc");
3465
3466#[cfg(not(target_os = "windows"))]
3467extern_c_block!("hwloc");
3468
3469#[cfg(test)]
3470mod tests {
3471    use super::*;
3472    use static_assertions::{assert_impl_all, assert_not_impl_any};
3473    use std::{
3474        fmt::{self, Binary, Display, LowerExp, LowerHex, Octal, Pointer, UpperExp, UpperHex},
3475        hash::Hash,
3476        io::{self, Read},
3477        ops::Deref,
3478        panic::UnwindSafe,
3479    };
3480
3481    // Opaque types implement almost no trait since the user shouldn't
3482    // manipulate them
3483    assert_impl_all!(IncompleteType: Sized);
3484    assert_not_impl_any!(IncompleteType:
3485        Binary, Clone, Debug, Default, Deref, Display, Drop, IntoIterator,
3486        LowerExp, LowerHex, Octal, PartialEq, Pointer, Read, Send, ToOwned,
3487        Unpin, RefUnwindSafe, UpperExp, UpperHex, fmt::Write, io::Write
3488    );
3489    assert_impl_all!(hwloc_bitmap_s: Sized, RefUnwindSafe);
3490    assert_not_impl_any!(hwloc_bitmap_s:
3491        Binary, Clone, Debug, Default, Deref, Display, Drop, IntoIterator,
3492        LowerExp, LowerHex, Octal, PartialEq, Pointer, Read, Send, ToOwned,
3493        Unpin, UnwindSafe, UpperExp, UpperHex, fmt::Write, io::Write
3494    );
3495    assert_impl_all!(hwloc_topology: Sized, RefUnwindSafe);
3496    assert_not_impl_any!(hwloc_topology:
3497        Binary, Clone, Debug, Default, Deref, Display, Drop, IntoIterator,
3498        LowerExp, LowerHex, Octal, PartialEq, Pointer, Read, Send, ToOwned,
3499        Unpin, UnwindSafe, UpperExp, UpperHex, fmt::Write, io::Write
3500    );
3501
3502    // Types with inner pointers that shouldn't be null and have unspecified
3503    // semantics implement a basic set of traits
3504    assert_impl_all!(hwloc_info_s:
3505        Copy, Debug, Sized, Unpin, UnwindSafe
3506    );
3507    assert_not_impl_any!(hwloc_info_s:
3508        Binary, Default, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex,
3509        Octal, PartialEq, Pointer, Read, Send, UpperExp, UpperHex, fmt::Write,
3510        io::Write
3511    );
3512    #[cfg(feature = "hwloc-2_3_0")]
3513    mod hwloc_location_impls {
3514        use super::*;
3515        assert_impl_all!(hwloc_location:
3516            Copy, Debug, Sized, Unpin, UnwindSafe
3517        );
3518        assert_not_impl_any!(hwloc_location:
3519            Binary, Default, Deref, Display, Drop, IntoIterator, LowerExp,
3520            LowerHex, Octal, PartialEq, Pointer, Read, Send, UpperExp, UpperHex,
3521            fmt::Write, io::Write
3522        );
3523        assert_impl_all!(hwloc_location_u:
3524            Copy, Debug, Sized, Unpin, UnwindSafe
3525        );
3526        assert_not_impl_any!(hwloc_location_u:
3527            Binary, Default, Deref, Display, Drop, IntoIterator, LowerExp,
3528            LowerHex, Octal, PartialEq, Pointer, Read, Send, UpperExp, UpperHex,
3529            fmt::Write, io::Write
3530        );
3531    }
3532    assert_impl_all!(hwloc_obj:
3533        Copy, Debug, Sized, Unpin, UnwindSafe
3534    );
3535    assert_not_impl_any!(hwloc_obj:
3536        Binary, Default, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex,
3537        Octal, PartialEq, Pointer, Read, Send, UpperExp, UpperHex, fmt::Write,
3538        io::Write
3539    );
3540
3541    // Types with pointers that can reasonably be null are like types with
3542    // non-nullable pointers, but also implement Default
3543    assert_impl_all!(hwloc_distances_s:
3544        Copy, Debug, Default, Sized, Unpin, UnwindSafe
3545    );
3546    assert_not_impl_any!(hwloc_distances_s:
3547        Binary, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex, Octal,
3548        PartialEq, Pointer, Read, Send, UpperExp, UpperHex, fmt::Write,
3549        io::Write
3550    );
3551    assert_impl_all!(hwloc_numanode_attr_s:
3552        Copy, Debug, Default, Sized, Unpin, UnwindSafe
3553    );
3554    assert_not_impl_any!(hwloc_numanode_attr_s:
3555        Binary, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex, Octal,
3556        PartialEq, Pointer, Read, Send, UpperExp, UpperHex, fmt::Write,
3557        io::Write
3558    );
3559    assert_impl_all!(hwloc_topology_support:
3560        Copy, Debug, Default, Sized, Unpin, UnwindSafe
3561    );
3562    assert_not_impl_any!(hwloc_topology_support:
3563        Binary, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex, Octal,
3564        PartialEq, Pointer, Read, Send, UpperExp, UpperHex, fmt::Write,
3565        io::Write
3566    );
3567
3568    // As the union of all attribute structs, hwloc_obj_attr_u can only
3569    // implement the common subset of their inner traits. It also cannot
3570    // implement any trait that requires looking into the active variant since
3571    // it doesn't know what the active variant is, nor if there is even one.
3572    assert_impl_all!(hwloc_obj_attr_u:
3573        Copy, Debug, Sized, Unpin, UnwindSafe
3574    );
3575    assert_not_impl_any!(hwloc_obj_attr_u:
3576        Binary, Default, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex,
3577        Octal, PartialEq, Pointer, Read, Send, UpperExp, UpperHex, fmt::Write,
3578        io::Write
3579    );
3580
3581    // Unions that contain only Sync types can additionally impl Sync, and this
3582    // also applies to types that contain such unions
3583    assert_impl_all!(hwloc_bridge_attr_s:
3584        Copy, Debug, Sized, Sync, Unpin, UnwindSafe
3585    );
3586    assert_not_impl_any!(hwloc_bridge_attr_s:
3587        Binary, Default, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex,
3588        Octal, PartialEq, Pointer, Read, UpperExp, UpperHex, fmt::Write,
3589        io::Write
3590    );
3591    assert_impl_all!(RawDownstreamAttributes:
3592        Copy, Debug, Sized, Sync, Unpin, UnwindSafe
3593    );
3594    assert_not_impl_any!(RawDownstreamAttributes:
3595        Binary, Default, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex,
3596        Octal, PartialEq, Pointer, Read, UpperExp, UpperHex, fmt::Write,
3597        io::Write
3598    );
3599    assert_impl_all!(RawUpstreamAttributes:
3600        Copy, Debug, Sized, Sync, Unpin, UnwindSafe
3601    );
3602    assert_not_impl_any!(RawUpstreamAttributes:
3603        Binary, Default, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex,
3604        Octal, PartialEq, Pointer, Read, UpperExp, UpperHex, fmt::Write,
3605        io::Write
3606    );
3607
3608    // Most plain old data structs implement Default, Sync and comparisons
3609    //
3610    // Implemented comparisons are mostly equality+hashing and not order, since
3611    // ordering random structs with unrelated members doesn't make much sense.
3612    // We make an exception for hwloc_memory_page_type_s which has an officially
3613    // defined order.
3614    assert_impl_all!(hwloc_cache_attr_s:
3615        Copy, Debug, Default, Hash, Sized, Sync, Unpin, UnwindSafe
3616    );
3617    assert_not_impl_any!(hwloc_cache_attr_s:
3618        Binary, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex, Octal,
3619        PartialOrd, Pointer, Read, UpperExp, UpperHex, fmt::Write, io::Write
3620    );
3621    assert_impl_all!(hwloc_group_attr_s:
3622        Copy, Debug, Default, Hash, Sized, Sync, Unpin, UnwindSafe
3623    );
3624    assert_not_impl_any!(hwloc_group_attr_s:
3625        Binary, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex, Octal,
3626        PartialOrd, Pointer, Read, UpperExp, UpperHex, fmt::Write, io::Write
3627    );
3628    assert_impl_all!(hwloc_osdev_attr_s:
3629        Copy, Debug, Default, Hash, Sized, Sync, Unpin, UnwindSafe
3630    );
3631    assert_not_impl_any!(hwloc_osdev_attr_s:
3632        Binary, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex, Octal,
3633        PartialOrd, Pointer, Read, UpperExp, UpperHex, fmt::Write, io::Write
3634    );
3635    assert_impl_all!(hwloc_topology_cpubind_support:
3636        Copy, Debug, Default, Hash, Sized, Sync, Unpin, UnwindSafe
3637    );
3638    assert_not_impl_any!(hwloc_topology_cpubind_support:
3639        Binary, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex, Octal,
3640        PartialOrd, Pointer, Read, UpperExp, UpperHex, fmt::Write, io::Write
3641    );
3642    assert_impl_all!(hwloc_topology_discovery_support:
3643        Copy, Debug, Default, Hash, Sized, Sync, Unpin, UnwindSafe
3644    );
3645    assert_not_impl_any!(hwloc_topology_discovery_support:
3646        Binary, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex, Octal,
3647        PartialOrd, Pointer, Read, UpperExp, UpperHex, fmt::Write, io::Write
3648    );
3649    assert_impl_all!(hwloc_topology_membind_support:
3650        Copy, Debug, Default, Hash, Sized, Sync, Unpin, UnwindSafe
3651    );
3652    assert_not_impl_any!(hwloc_topology_membind_support:
3653        Binary, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex, Octal,
3654        PartialOrd, Pointer, Read, UpperExp, UpperHex, fmt::Write, io::Write
3655    );
3656    #[cfg(feature = "hwloc-2_3_0")]
3657    assert_impl_all!(hwloc_topology_misc_support:
3658        Copy, Debug, Default, Hash, Sized, Sync, Unpin, UnwindSafe
3659    );
3660    #[cfg(feature = "hwloc-2_3_0")]
3661    assert_not_impl_any!(hwloc_topology_misc_support:
3662        Binary, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex, Octal,
3663        PartialOrd, Pointer, Read, UpperExp, UpperHex, fmt::Write, io::Write
3664    );
3665    assert_impl_all!(RawDownstreamPCIAttributes:
3666        Copy, Debug, Default, Hash, Sized, Sync, Unpin, UnwindSafe
3667    );
3668    assert_not_impl_any!(RawDownstreamPCIAttributes:
3669        Binary, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex, Octal,
3670        PartialOrd, Pointer, Read, UpperExp, UpperHex, fmt::Write, io::Write
3671    );
3672
3673    // hwloc_memory_page_type_s has an officially defined order and has its
3674    // comparison abilities expanded accordingly
3675    assert_impl_all!(hwloc_memory_page_type_s:
3676        Copy, Debug, Default, Hash, Ord, Sized, Sync, Unpin, UnwindSafe
3677    );
3678    assert_not_impl_any!(hwloc_memory_page_type_s:
3679        Binary, Deref, Display, Drop, IntoIterator, LowerExp, LowerHex, Octal,
3680        Pointer, Read, UpperExp, UpperHex, fmt::Write, io::Write
3681    );
3682
3683    // PCIDevice attributes, contain a floating-point value and have their
3684    // comparison abilities restricted accordingly
3685    assert_impl_all!(hwloc_pcidev_attr_s:
3686        Copy, Debug, Default, PartialEq, Sized, Sync, Unpin,
3687        UnwindSafe
3688    );
3689    assert_not_impl_any!(hwloc_pcidev_attr_s:
3690        Binary, Deref, Display, Drop, Eq, IntoIterator, LowerExp, LowerHex,
3691        Octal, PartialOrd, Pointer, Read, UpperExp, UpperHex, fmt::Write,
3692        io::Write
3693    );
3694
3695    #[test]
3696    fn hwloc_obj_attr_u() {
3697        let attr = super::hwloc_obj_attr_u {
3698            cache: hwloc_cache_attr_s::default(),
3699        };
3700        assert_eq!(format!("{attr:?}"), "hwloc_obj_attr_u { .. }");
3701    }
3702
3703    #[test]
3704    fn hwloc_numanode_attr_s() {
3705        let hwloc_numanode_attr_s {
3706            local_memory,
3707            page_types_len,
3708            page_types,
3709        } = super::hwloc_numanode_attr_s::default();
3710        assert_eq!(local_memory, 0);
3711        assert_eq!(page_types_len, 0);
3712        assert!(page_types.is_null());
3713    }
3714
3715    #[test]
3716    fn hwloc_bridge_attr_s() {
3717        let attr = super::hwloc_bridge_attr_s {
3718            upstream: RawUpstreamAttributes {
3719                pci: hwloc_pcidev_attr_s::default(),
3720            },
3721            upstream_type: HWLOC_OBJ_BRIDGE_PCI,
3722            downstream: RawDownstreamAttributes {
3723                pci: RawDownstreamPCIAttributes::default(),
3724            },
3725            downstream_type: HWLOC_OBJ_BRIDGE_PCI,
3726            depth: 42,
3727        };
3728        assert_eq!(
3729            format!("{attr:?}"),
3730            "hwloc_bridge_attr_s { upstream: RawUpstreamAttributes { .. }, \
3731                                   upstream_type: 1, \
3732                                   downstream: RawDownstreamAttributes { .. }, \
3733                                   downstream_type: 1, \
3734                                   depth: 42 }"
3735        );
3736    }
3737
3738    #[test]
3739    fn hwloc_topology_support() {
3740        let default = super::hwloc_topology_support::default();
3741        #[cfg(not(feature = "hwloc-2_3_0"))]
3742        let hwloc_topology_support {
3743            discovery,
3744            cpubind,
3745            membind,
3746        } = default;
3747        #[cfg(feature = "hwloc-2_3_0")]
3748        let hwloc_topology_support {
3749            discovery,
3750            cpubind,
3751            membind,
3752            misc,
3753        } = default;
3754        assert!(discovery.is_null());
3755        assert!(cpubind.is_null());
3756        assert!(membind.is_null());
3757        #[cfg(feature = "hwloc-2_3_0")]
3758        assert!(misc.is_null());
3759    }
3760
3761    #[test]
3762    fn hwloc_distances_s() {
3763        let hwloc_distances_s {
3764            nbobj,
3765            objs,
3766            kind,
3767            values,
3768        } = super::hwloc_distances_s::default();
3769        assert_eq!(nbobj, 0);
3770        assert!(objs.is_null());
3771        assert_eq!(kind, 0);
3772        assert!(values.is_null());
3773    }
3774
3775    #[cfg(feature = "hwloc-2_3_0")]
3776    #[test]
3777    fn hwloc_location() {
3778        let location = super::hwloc_location {
3779            ty: HWLOC_LOCATION_TYPE_CPUSET,
3780            location: hwloc_location_u {
3781                cpuset: ptr::null(),
3782            },
3783        };
3784        assert_eq!(
3785            format!("{location:?}"),
3786            "hwloc_location { ty: 1, \
3787                              location: hwloc_location_u { .. } }"
3788        );
3789    }
3790}