Skip to content

Commit

Permalink
Remove bitmask vectors in favor of extracting bitmasks
Browse files Browse the repository at this point in the history
  • Loading branch information
calebzulawski committed Jun 5, 2024
1 parent 675401b commit 3733375
Show file tree
Hide file tree
Showing 4 changed files with 0 additions and 157 deletions.
42 changes: 0 additions & 42 deletions crates/core_simd/src/masks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,48 +308,6 @@ where
Self(mask_impl::Mask::from_bitmask_integer(bitmask))
}

/// Create a bitmask vector from a mask.
///
/// Each bit is set if the corresponding element in the mask is `true`.
/// The remaining bits are unset.
///
/// The bits are packed into the first N bits of the vector:
/// ```
/// # #![feature(portable_simd)]
/// # #[cfg(feature = "as_crate")] use core_simd::simd;
/// # #[cfg(not(feature = "as_crate"))] use core::simd;
/// # use simd::mask32x8;
/// let mask = mask32x8::from_array([true, false, true, false, false, false, true, false]);
/// assert_eq!(mask.to_bitmask_vector()[0], 0b01000101);
/// ```
#[inline]
#[must_use = "method returns a new integer and does not mutate the original value"]
pub fn to_bitmask_vector(self) -> Simd<u8, N> {
self.0.to_bitmask_vector()
}

/// Create a mask from a bitmask vector.
///
/// For each bit, if it is set, the corresponding element in the mask is set to `true`.
///
/// The bits are packed into the first N bits of the vector:
/// ```
/// # #![feature(portable_simd)]
/// # #[cfg(feature = "as_crate")] use core_simd::simd;
/// # #[cfg(not(feature = "as_crate"))] use core::simd;
/// # use simd::{mask32x8, u8x8};
/// let bitmask = u8x8::from_array([0b01000101, 0, 0, 0, 0, 0, 0, 0]);
/// assert_eq!(
/// mask32x8::from_bitmask_vector(bitmask),
/// mask32x8::from_array([true, false, true, false, false, false, true, false]),
/// );
/// ```
#[inline]
#[must_use = "method returns a new mask and does not mutate the original value"]
pub fn from_bitmask_vector(bitmask: Simd<u8, N>) -> Self {
Self(mask_impl::Mask::from_bitmask_vector(bitmask))
}

/// Find the index of the first set element.
///
/// ```
Expand Down
17 changes: 0 additions & 17 deletions crates/core_simd/src/masks/bitmask.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,23 +122,6 @@ where
unsafe { Self(core::intrinsics::simd::simd_bitmask(value), PhantomData) }
}

#[inline]
#[must_use = "method returns a new vector and does not mutate the original value"]
pub fn to_bitmask_vector(self) -> Simd<u8, N> {
let mut bitmask = Simd::splat(0);
bitmask.as_mut_array()[..self.0.as_ref().len()].copy_from_slice(self.0.as_ref());
bitmask
}

#[inline]
#[must_use = "method returns a new mask and does not mutate the original value"]
pub fn from_bitmask_vector(bitmask: Simd<u8, N>) -> Self {
let mut bytes = <LaneCount<N> as SupportedLaneCount>::BitMask::default();
let len = bytes.as_ref().len();
bytes.as_mut().copy_from_slice(&bitmask.as_array()[..len]);
Self(bytes, PhantomData)
}

#[inline]
pub fn to_bitmask_integer(self) -> u64 {
let mut bitmask = [0u8; 8];
Expand Down
56 changes: 0 additions & 56 deletions crates/core_simd/src/masks/full_masks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,62 +140,6 @@ where
unsafe { Mask(core::intrinsics::simd::simd_cast(self.0)) }
}

#[inline]
#[must_use = "method returns a new vector and does not mutate the original value"]
pub fn to_bitmask_vector(self) -> Simd<u8, N> {
let mut bitmask = Simd::splat(0);

// Safety: Bytes is the right size array
unsafe {
// Compute the bitmask
let mut bytes: <LaneCount<N> as SupportedLaneCount>::BitMask =
core::intrinsics::simd::simd_bitmask(self.0);

// LLVM assumes bit order should match endianness
if cfg!(target_endian = "big") {
for x in bytes.as_mut() {
*x = x.reverse_bits()
}
if N % 8 > 0 {
bytes.as_mut()[N / 8] >>= 8 - N % 8;
}
}

bitmask.as_mut_array()[..bytes.as_ref().len()].copy_from_slice(bytes.as_ref());
}

bitmask
}

#[inline]
#[must_use = "method returns a new mask and does not mutate the original value"]
pub fn from_bitmask_vector(bitmask: Simd<u8, N>) -> Self {
let mut bytes = <LaneCount<N> as SupportedLaneCount>::BitMask::default();

// Safety: Bytes is the right size array
unsafe {
let len = bytes.as_ref().len();
bytes.as_mut().copy_from_slice(&bitmask.as_array()[..len]);

// LLVM assumes bit order should match endianness
if cfg!(target_endian = "big") {
for x in bytes.as_mut() {
*x = x.reverse_bits();
}
if N % 8 > 0 {
bytes.as_mut()[N / 8] >>= 8 - N % 8;
}
}

// Compute the regular mask
Self::from_int_unchecked(core::intrinsics::simd::simd_select_bitmask(
bytes,
Self::splat(true).to_int(),
Self::splat(false).to_int(),
))
}
}

#[inline]
unsafe fn to_bitmask_impl<U: ReverseBits, const M: usize>(self) -> U
where
Expand Down
42 changes: 0 additions & 42 deletions crates/core_simd/tests/masks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,48 +134,6 @@ macro_rules! test_mask_api {
cast_impl::<i64>();
cast_impl::<isize>();
}

#[test]
fn roundtrip_bitmask_vector_conversion() {
use core_simd::simd::ToBytes;
let values = [
true, false, false, true, false, false, true, false,
true, true, false, false, false, false, false, true,
];
let mask = Mask::<$type, 16>::from_array(values);
let bitmask = mask.to_bitmask_vector();
assert_eq!(bitmask.resize::<2>(0).to_ne_bytes()[..2], [0b01001001, 0b10000011]);
assert_eq!(Mask::<$type, 16>::from_bitmask_vector(bitmask), mask);
}

// rust-lang/portable-simd#379
#[test]
fn roundtrip_bitmask_vector_conversion_small() {
use core_simd::simd::ToBytes;
let values = [
true, false, true, true
];
let mask = Mask::<$type, 4>::from_array(values);
let bitmask = mask.to_bitmask_vector();
assert_eq!(bitmask.resize::<1>(0).to_ne_bytes()[0], 0b00001101);
assert_eq!(Mask::<$type, 4>::from_bitmask_vector(bitmask), mask);
}

/* FIXME doesn't work with non-powers-of-two, yet
// rust-lang/portable-simd#379
#[cfg(feature = "all_lane_counts")]
#[test]
fn roundtrip_bitmask_vector_conversion_odd() {
use core_simd::simd::ToBytes;
let values = [
true, false, true, false, true, true, false, false, false, true, true,
];
let mask = Mask::<$type, 11>::from_array(values);
let bitmask = mask.to_bitmask_vector();
assert_eq!(bitmask.resize::<2>(0).to_ne_bytes()[..2], [0b00110101, 0b00000110]);
assert_eq!(Mask::<$type, 11>::from_bitmask_vector(bitmask), mask);
}
*/
}
}
}
Expand Down

0 comments on commit 3733375

Please sign in to comment.