Struct hwlocality::bitmap::Bitmap
source · pub struct Bitmap(/* private fields */);
Expand description
A generic bitmap, understood by hwloc
The Bitmap
type represents a set of integers (positive or null). A bitmap
may be of infinite size (all bits are set after some point). A bitmap may
even be full if all bits are set.
Bitmaps are used by hwloc to represent sets of OS processors (which may
actually be hardware threads), via the CpuSet
newtype, or to represent
sets of NUMA memory nodes via the NodeSet
newtype.
Both CpuSet
and NodeSet
are always indexed by OS physical number.
However, users should usually not build CPU and node sets manually (e.g.
with Bitmap::set()
). One should rather use the cpu/node sets of existing
TopologyObject
s and combine them through boolean operations. For
instance, binding the current thread on a pair of cores may be performed
with:
// We want Cores, but we tolerate PUs on platforms that don't expose Cores
// (either there are no hardware threads or hwloc could not detect them)
let core_depth = topology.depth_or_below_for_type(ObjectType::Core)?;
// Yields the first two cores of a multicore system, or
// the only core of a single-core system
let cores = topology.objects_at_depth(core_depth).take(2);
// Compute the union of these cores' CPUsets, that's our CPU binding bitmap
let set = cores.fold(
CpuSet::new(),
|acc, core| { acc | core.cpuset().expect("Cores should have CPUsets") }
);
// Only actually bind if the platform supports it (macOS notably doesn't)
if topology.supports(FeatureSupport::cpu_binding, CpuBindingSupport::set_thread) {
topology.bind_cpu(&set, CpuBindingFlags::THREAD)?;
}
§Panics
Unlike most hwloc entry points in this crate, Bitmap
functions always
handle unexpected hwloc errors by panicking. The rationale for this is that
the bitmap is just a simple data structures, without any kind of
complicated interactions with the operating system, for which the only
failure mode should be running out of memory. And panicking is the normal
way to handle this in Rust.
Implementations§
source§impl Bitmap
impl Bitmap
sourcepub fn new() -> Self
pub fn new() -> Self
Creates an empty Bitmap
§Examples
use hwlocality::bitmap::Bitmap;
let empty = Bitmap::new();
assert!(empty.is_empty());
sourcepub fn full() -> Self
pub fn full() -> Self
Creates a full Bitmap
§Examples
use hwlocality::bitmap::Bitmap;
let full = Bitmap::full();
assert!(full.is_full());
sourcepub fn from_range<Idx>(range: impl RangeBounds<Idx>) -> Self
pub fn from_range<Idx>(range: impl RangeBounds<Idx>) -> Self
Creates a new Bitmap
with the given range of indices set
Accepts both ranges of BitmapIndex
and usize
. Use the former for
type safety (it is guaranteed to be in range as a type invariant) or the
latter for convenience (it is more tightly integrated with Rust’s
built-in integer support, for example it supports integer literals).
§Examples
use hwlocality::bitmap::Bitmap;
let bitmap = Bitmap::from_range(12..=34);
assert_eq!(format!("{bitmap}"), "12-34");
§Panics
If range
goes beyond the implementation-defined maximum index (at
least 2^15-1, usually 2^31-1).
sourcepub fn copy_from(&mut self, other: impl Deref<Target = Self>)
pub fn copy_from(&mut self, other: impl Deref<Target = Self>)
Turn this Bitmap
into a copy of another Bitmap
Accepts both &'_ Bitmap
and BitmapRef<'_, Bitmap>
operands.
§Examples
use hwlocality::bitmap::Bitmap;
let bitmap = Bitmap::from_range(12..=34);
let mut bitmap2 = Bitmap::new();
bitmap2.copy_from(&bitmap);
assert_eq!(format!("{bitmap2}"), "12-34");
sourcepub fn clear(&mut self)
pub fn clear(&mut self)
Clear all indices
§Examples
use hwlocality::bitmap::Bitmap;
let mut bitmap = Bitmap::from_range(12..=34);
bitmap.clear();
assert!(bitmap.is_empty());
sourcepub fn fill(&mut self)
pub fn fill(&mut self)
Set all indices
§Examples
use hwlocality::bitmap::Bitmap;
let mut bitmap = Bitmap::from_range(12..=34);
bitmap.fill();
assert!(bitmap.is_full());
sourcepub fn set_only<Idx>(&mut self, idx: Idx)
pub fn set_only<Idx>(&mut self, idx: Idx)
Clear all indices except for idx
, which is set
Accepts both BitmapIndex
and usize
operands. Use the former for
type-safety (it is guaranteed to be in range as a type invariant) or the
latter for convenience (it is more tightly integrated with Rust’s
built-in integer support, for example it supports integer literals).
§Examples
use hwlocality::bitmap::Bitmap;
let mut bitmap = Bitmap::from_range(12..=34);
bitmap.set_only(42);
assert_eq!(format!("{bitmap}"), "42");
§Panics
If idx
is above the implementation-defined maximum index (at least
2^15-1, usually 2^31-1).
sourcepub fn set_all_but<Idx>(&mut self, idx: Idx)
pub fn set_all_but<Idx>(&mut self, idx: Idx)
Set all indices except for idx
, which is cleared
Accepts both BitmapIndex
and usize
operands. Use the former for
type-safety (it is guaranteed to be in range as a type invariant) or the
latter for convenience (it is more tightly integrated with Rust’s
built-in integer support, for example it supports integer literals).
§Examples
use hwlocality::bitmap::Bitmap;
let mut bitmap = Bitmap::from_range(12..=34);
bitmap.set_all_but(42);
assert_eq!(format!("{bitmap}"), "0-41,43-");
§Panics
If idx
is above the implementation-defined maximum index (at least
2^15-1, usually 2^31-1).
sourcepub fn set<Idx>(&mut self, idx: Idx)
pub fn set<Idx>(&mut self, idx: Idx)
Set index idx
Accepts both BitmapIndex
and usize
operands. Use the former for
type-safety (it is guaranteed to be in range as a type invariant) or the
latter for convenience (it is more tightly integrated with Rust’s
built-in integer support, for example it supports integer literals).
§Examples
use hwlocality::bitmap::Bitmap;
let mut bitmap = Bitmap::from_range(12..=34);
bitmap.set(42);
assert_eq!(format!("{bitmap}"), "12-34,42");
§Panics
If idx
is above the implementation-defined maximum index (at least
2^15-1, usually 2^31-1).
sourcepub fn set_range<Idx>(&mut self, range: impl RangeBounds<Idx>)
pub fn set_range<Idx>(&mut self, range: impl RangeBounds<Idx>)
Set indices covered by range
Accepts both ranges of BitmapIndex
and usize
. Use the former for
type-safety (it is guaranteed to be in range as a type invariant) or the
latter for convenience (it is more tightly integrated with Rust’s
built-in integer support, for example it supports integer literals).
§Examples
use hwlocality::bitmap::Bitmap;
let mut bitmap = Bitmap::from_range(12..=56);
bitmap.set_range(34..=78);
assert_eq!(format!("{bitmap}"), "12-78");
bitmap.set_range(2..);
assert_eq!(format!("{bitmap}"), "2-");
§Panics
If range
goes beyond the implementation-defined maximum index (at
least 2^15-1, usually 2^31-1).
sourcepub fn unset<Idx>(&mut self, idx: Idx)
pub fn unset<Idx>(&mut self, idx: Idx)
Clear index idx
Accepts both BitmapIndex
and usize
operands. Use the former for
type-safety (it is guaranteed to be in range as a type invariant) or the
latter for convenience (it is more tightly integrated with Rust’s
built-in integer support, for example it supports integer literals).
§Examples
use hwlocality::bitmap::Bitmap;
let mut bitmap = Bitmap::from_range(12..=34);
bitmap.unset(24);
assert_eq!(format!("{bitmap}"), "12-23,25-34");
§Panics
If idx
is above the implementation-defined maximum index (at least
2^15-1, usually 2^31-1).
sourcepub fn unset_range<Idx>(&mut self, range: impl RangeBounds<Idx>)
pub fn unset_range<Idx>(&mut self, range: impl RangeBounds<Idx>)
Clear indices covered by range
Accepts both ranges of BitmapIndex
and usize
. Use the former for
type-safety (it is guaranteed to be in range as a type invariant) or the
latter for convenience (it is more tightly integrated with Rust’s
built-in integer support, for example it supports integer literals).
§Examples
use hwlocality::bitmap::Bitmap;
let mut bitmap = Bitmap::from_range(12..=34);
bitmap.unset_range(14..=18);
assert_eq!(format!("{bitmap}"), "12-13,19-34");
bitmap.unset_range(26..);
assert_eq!(format!("{bitmap}"), "12-13,19-25");
§Panics
If range
goes beyond the implementation-defined maximum index (at
least 2^15-1, usually 2^31-1).
sourcepub fn singlify(&mut self)
pub fn singlify(&mut self)
Keep a single index among those set in the bitmap
May be useful before binding so that the process does not have a chance of migrating between multiple logical CPUs in the original mask. Instead of running the task on any PU inside the given CPU set, the operating system scheduler will be forced to run it on a single of these PUs. It avoids a migration overhead and cache-line ping-pongs between PUs.
This function is NOT meant to distribute multiple processes within a
single CPU set. It always return the same single bit when called
multiple times on the same input set. Topology::distribute_items()
may be used for generating CPU sets to distribute multiple tasks below a
single multi-PU object.
The effect of singlifying an empty bitmap is not specified by hwloc.
§Examples
use hwlocality::bitmap::Bitmap;
let mut bitmap = Bitmap::from_range(12..=34);
bitmap.singlify();
assert_eq!(bitmap.weight(), Some(1));
sourcepub fn is_set<Idx>(&self, idx: Idx) -> bool
pub fn is_set<Idx>(&self, idx: Idx) -> bool
Check if index idx
is set
Accepts both BitmapIndex
and usize
operands. Use the former for
type-safety (it is guaranteed to be in range as a type invariant) or the
latter for convenience (it is more tightly integrated with Rust’s
built-in integer support, for example it supports integer literals).
§Examples
use hwlocality::bitmap::Bitmap;
let mut bitmap = Bitmap::from_range(12..=34);
assert!((0..12).all(|idx| !bitmap.is_set(idx)));
assert!((12..=34).all(|idx| bitmap.is_set(idx)));
assert!(!bitmap.is_set(35));
§Panics
If idx
is above the implementation-defined maximum index (at least
2^15-1, usually 2^31-1).
sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Check if all indices are unset
§Examples
use hwlocality::bitmap::Bitmap;
assert!(Bitmap::new().is_empty());
assert!(!Bitmap::from_range(12..=34).is_empty());
assert!(!Bitmap::full().is_empty());
sourcepub fn is_full(&self) -> bool
pub fn is_full(&self) -> bool
Check if all indices are set
§Examples
use hwlocality::bitmap::Bitmap;
assert!(!Bitmap::new().is_full());
assert!(!Bitmap::from_range(12..=34).is_full());
assert!(Bitmap::full().is_full());
sourcepub fn first_set(&self) -> Option<BitmapIndex>
pub fn first_set(&self) -> Option<BitmapIndex>
Check the first set index, if any
You can iterate over set indices with Bitmap::iter_set()
.
§Examples
use hwlocality::bitmap::Bitmap;
let first_set_usize = |b: Bitmap| b.first_set().map(usize::from);
assert_eq!(Bitmap::new().first_set(), None);
assert_eq!(first_set_usize(Bitmap::from_range(12..=34)), Some(12));
assert_eq!(first_set_usize(Bitmap::full()), Some(0));
sourcepub fn iter_set(&self) -> Iter<&Self> ⓘ
pub fn iter_set(&self) -> Iter<&Self> ⓘ
Iterate over set indices
§Examples
use hwlocality::bitmap::Bitmap;
let bitmap = Bitmap::from_range(12..=21);
let indices = bitmap.iter_set().map(usize::from).collect::<Vec<_>>();
assert_eq!(indices, &[12, 13, 14, 15, 16, 17, 18, 19, 20, 21]);
sourcepub fn last_set(&self) -> Option<BitmapIndex>
pub fn last_set(&self) -> Option<BitmapIndex>
Check the last set index, if any
§Examples
use hwlocality::bitmap::Bitmap;
let last_set_usize = |b: Bitmap| b.last_set().map(usize::from);
assert_eq!(Bitmap::new().last_set(), None);
assert_eq!(last_set_usize(Bitmap::from_range(12..=34)), Some(34));
assert_eq!(Bitmap::full().last_set(), None);
sourcepub fn weight(&self) -> Option<usize>
pub fn weight(&self) -> Option<usize>
The number of indices that are set in the bitmap
None means that an infinite number of indices are set.
§Examples
use hwlocality::bitmap::Bitmap;
assert_eq!(Bitmap::new().weight(), Some(0));
assert_eq!(Bitmap::from_range(12..34).weight(), Some(34-12));
assert_eq!(Bitmap::full().weight(), None);
sourcepub fn first_unset(&self) -> Option<BitmapIndex>
pub fn first_unset(&self) -> Option<BitmapIndex>
Check the first unset index, if any
You can iterate over set indices with Bitmap::iter_unset()
.
§Examples
use hwlocality::bitmap::Bitmap;
let first_unset_usize = |b: Bitmap| b.first_unset().map(usize::from);
assert_eq!(first_unset_usize(Bitmap::new()), Some(0));
assert_eq!(first_unset_usize(Bitmap::from_range(..12)), Some(12));
assert_eq!(Bitmap::full().first_unset(), None);
sourcepub fn iter_unset(&self) -> Iter<&Self> ⓘ
pub fn iter_unset(&self) -> Iter<&Self> ⓘ
Iterate over unset indices
§Examples
use hwlocality::bitmap::Bitmap;
let bitmap = Bitmap::from_range(12..);
let indices = bitmap.iter_unset().map(usize::from).collect::<Vec<_>>();
assert_eq!(indices, &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
sourcepub fn last_unset(&self) -> Option<BitmapIndex>
pub fn last_unset(&self) -> Option<BitmapIndex>
Check the last unset index, if any
§Examples
use hwlocality::bitmap::Bitmap;
let last_unset_usize = |b: Bitmap| b.last_unset().map(usize::from);
assert_eq!(Bitmap::new().last_unset(), None);
assert_eq!(last_unset_usize(Bitmap::from_range(12..)), Some(11));
assert_eq!(Bitmap::full().last_unset(), None);
sourcepub fn invert(&mut self)
pub fn invert(&mut self)
Optimized version of *self = !self
§Examples
use hwlocality::bitmap::Bitmap;
let mut bitmap = Bitmap::from_range(12..=34);
bitmap.invert();
assert_eq!(format!("{bitmap}"), "0-11,35-");
sourcepub fn intersects(&self, rhs: impl Deref<Target = Self>) -> bool
pub fn intersects(&self, rhs: impl Deref<Target = Self>) -> bool
Truth that self
and rhs
have some set indices in common
Accepts both &'_ Bitmap
and BitmapRef<'_, Bitmap>
operands.
§Examples
use hwlocality::bitmap::Bitmap;
let bitmap1 = Bitmap::from_range(12..=34);
let bitmap2 = Bitmap::from_range(56..=78);
assert!(!bitmap1.intersects(&bitmap2));
let bitmap3 = Bitmap::from_range(34..=56);
assert!(bitmap1.intersects(&bitmap3));
assert!(bitmap2.intersects(&bitmap3));
sourcepub fn includes(&self, inner: impl Deref<Target = Self>) -> bool
pub fn includes(&self, inner: impl Deref<Target = Self>) -> bool
Truth that the indices set in inner
are a subset of those set in self
Accepts both &'_ Bitmap
and BitmapRef<'_, Bitmap>
operands.
The empty bitmap is considered included in any other bitmap.
§Examples
use hwlocality::bitmap::Bitmap;
let bitmap1 = Bitmap::from_range(12..=78);
let bitmap2 = Bitmap::from_range(34..=56);
assert!(bitmap1.includes(&bitmap2));
assert!(!bitmap2.includes(&bitmap1));
Trait Implementations§
source§impl Arbitrary for Bitmap
Available on crate feature proptest
only.
impl Arbitrary for Bitmap
proptest
only.§type Parameters = ()
type Parameters = ()
arbitrary_with
accepts for configuration
of the generated Strategy
. Parameters must implement Default
.§type Strategy = Map<(TupleUnion<((u32, Arc<Just<HashSet<PositiveInt>>>), (u32, Arc<HashSetStrategy<Map<Range<usize>, fn(_: usize) -> PositiveInt>>>))>, Any), fn(_: (HashSet<PositiveInt>, bool)) -> Bitmap>
type Strategy = Map<(TupleUnion<((u32, Arc<Just<HashSet<PositiveInt>>>), (u32, Arc<HashSetStrategy<Map<Range<usize>, fn(_: usize) -> PositiveInt>>>))>, Any), fn(_: (HashSet<PositiveInt>, bool)) -> Bitmap>
Strategy
used to generate values of type Self
.source§fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy
source§impl<B: Borrow<Self>> BitAndAssign<B> for Bitmap
impl<B: Borrow<Self>> BitAndAssign<B> for Bitmap
source§fn bitand_assign(&mut self, rhs: B)
fn bitand_assign(&mut self, rhs: B)
&=
operation. Read moresource§impl<B: Borrow<Self>> BitOrAssign<B> for Bitmap
impl<B: Borrow<Self>> BitOrAssign<B> for Bitmap
source§fn bitor_assign(&mut self, rhs: B)
fn bitor_assign(&mut self, rhs: B)
|=
operation. Read moresource§impl<B: Borrow<Self>> BitXorAssign<B> for Bitmap
impl<B: Borrow<Self>> BitXorAssign<B> for Bitmap
source§fn bitxor_assign(&mut self, rhs: B)
fn bitxor_assign(&mut self, rhs: B)
^=
operation. Read moresource§impl<'target> BorrowMut<Bitmap> for CpuSet
impl<'target> BorrowMut<Bitmap> for CpuSet
source§fn borrow_mut(&mut self) -> &mut Bitmap
fn borrow_mut(&mut self) -> &mut Bitmap
source§impl<'target> BorrowMut<Bitmap> for NodeSet
impl<'target> BorrowMut<Bitmap> for NodeSet
source§fn borrow_mut(&mut self) -> &mut Bitmap
fn borrow_mut(&mut self) -> &mut Bitmap
source§impl<BI: Borrow<BitmapIndex>> Extend<BI> for Bitmap
impl<BI: Borrow<BitmapIndex>> Extend<BI> for Bitmap
source§fn extend<T: IntoIterator<Item = BI>>(&mut self, iter: T)
fn extend<T: IntoIterator<Item = BI>>(&mut self, iter: T)
source§fn extend_one(&mut self, item: A)
fn extend_one(&mut self, item: A)
extend_one
)source§fn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
extend_one
)source§impl<BI: Borrow<BitmapIndex>> FromIterator<BI> for Bitmap
impl<BI: Borrow<BitmapIndex>> FromIterator<BI> for Bitmap
source§fn from_iter<I: IntoIterator<Item = BI>>(iter: I) -> Self
fn from_iter<I: IntoIterator<Item = BI>>(iter: I) -> Self
source§impl<'bitmap> IntoIterator for &'bitmap Bitmap
impl<'bitmap> IntoIterator for &'bitmap Bitmap
source§impl IntoIterator for Bitmap
impl IntoIterator for Bitmap
source§impl Ord for Bitmap
impl Ord for Bitmap
source§impl<B: Borrow<Self>> PartialOrd<B> for Bitmap
impl<B: Borrow<Self>> PartialOrd<B> for Bitmap
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
fn le(&self, other: &Rhs) -> bool
self
and other
) and is used by the <=
operator. Read moresource§impl<B: Borrow<Self>> SubAssign<B> for Bitmap
impl<B: Borrow<Self>> SubAssign<B> for Bitmap
source§fn sub_assign(&mut self, rhs: B)
fn sub_assign(&mut self, rhs: B)
-=
operation. Read more