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}