Skip to content

Rollup of 3 pull requests #94900

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
a5789d1
rust-lang/portable-simd#248: Remove default features
workingjubilee Mar 1, 2022
3097561
rust-lang/portable-simd#250: Add bitmask i{N <8} -> u8 impls
workingjubilee Mar 2, 2022
4ddcc00
rust-lang/portable-simd#252: extern blocks don't have doc comments
RalfJung Mar 4, 2022
2e5e0ec
Remove #![feature(const_fn_trait_bound)]
workingjubilee Mar 8, 2022
2d13059
Clean up use of cargo feature "std"
workingjubilee Mar 8, 2022
adbd479
reduce number of tests being run under Miri
RalfJung Mar 6, 2022
4023d77
run Miri on CI (but allowed to fail)
RalfJung Mar 9, 2022
89bc660
rust-lang/portable-simd#255: run Miri on CI
workingjubilee Mar 9, 2022
86b9f69
rust-lang/portable-simd#260: Add `.min` and `.max` for integers
jorgecarleitao Mar 10, 2022
415d376
Remove unneeded conversions in bootstrapping code
pierwill Mar 11, 2022
c196b8a
replace horizontal_* with reduce_*
programmerjake Mar 11, 2022
af53809
Format core and std macro rules, removing needless surrounding blocks
dtolnay Mar 10, 2022
b6e03f5
Change beginner's guide to explain Reducing rather than Horizontal.
programmerjake Mar 11, 2022
b6ee529
rust-lang/portable-simd#259: remove Miri from CI
RalfJung Mar 12, 2022
49043f4
rust-lang/portable-simd#262: also implement clamp for integer vectors
RalfJung Mar 12, 2022
72df4c4
portable-simd#261: Rename horizontal_* to reduce_*
workingjubilee Mar 12, 2022
aabaf84
Sync portable-simd to rust-lang/portable-simd@72df4c45056a8bc0d1b3f06…
workingjubilee Mar 13, 2022
2b1f249
Use reduce_sum in as_simd example
workingjubilee Mar 13, 2022
009b363
Rollup merge of #94862 - pierwill:bootstrap-useless, r=Dylan-DPC
matthiaskrgr Mar 13, 2022
a8ec45b
Rollup merge of #94868 - dtolnay:noblock, r=Dylan-DPC
matthiaskrgr Mar 13, 2022
523cd35
Rollup merge of #94899 - workingjubilee:bump-simd-clamp, r=workingjub…
matthiaskrgr Mar 13, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 50 additions & 26 deletions library/core/src/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ macro_rules! panic {
#[cfg_attr(not(test), rustc_diagnostic_item = "assert_eq_macro")]
#[allow_internal_unstable(core_panic)]
macro_rules! assert_eq {
($left:expr, $right:expr $(,)?) => ({
($left:expr, $right:expr $(,)?) => {
match (&$left, &$right) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
Expand All @@ -46,8 +46,8 @@ macro_rules! assert_eq {
}
}
}
});
($left:expr, $right:expr, $($arg:tt)+) => ({
};
($left:expr, $right:expr, $($arg:tt)+) => {
match (&$left, &$right) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
Expand All @@ -59,7 +59,7 @@ macro_rules! assert_eq {
}
}
}
});
};
}

/// Asserts that two expressions are not equal to each other (using [`PartialEq`]).
Expand All @@ -84,7 +84,7 @@ macro_rules! assert_eq {
#[cfg_attr(not(test), rustc_diagnostic_item = "assert_ne_macro")]
#[allow_internal_unstable(core_panic)]
macro_rules! assert_ne {
($left:expr, $right:expr $(,)?) => ({
($left:expr, $right:expr $(,)?) => {
match (&$left, &$right) {
(left_val, right_val) => {
if *left_val == *right_val {
Expand All @@ -96,8 +96,8 @@ macro_rules! assert_ne {
}
}
}
});
($left:expr, $right:expr, $($arg:tt)+) => ({
};
($left:expr, $right:expr, $($arg:tt)+) => {
match (&($left), &($right)) {
(left_val, right_val) => {
if *left_val == *right_val {
Expand All @@ -109,7 +109,7 @@ macro_rules! assert_ne {
}
}
}
});
};
}

/// Asserts that an expression matches any of the given patterns.
Expand Down Expand Up @@ -142,7 +142,7 @@ macro_rules! assert_ne {
#[allow_internal_unstable(core_panic)]
#[rustc_macro_transparency = "semitransparent"]
pub macro assert_matches {
($left:expr, $(|)? $( $pattern:pat_param )|+ $( if $guard: expr )? $(,)?) => ({
($left:expr, $(|)? $( $pattern:pat_param )|+ $( if $guard: expr )? $(,)?) => {
match $left {
$( $pattern )|+ $( if $guard )? => {}
ref left_val => {
Expand All @@ -153,8 +153,8 @@ pub macro assert_matches {
);
}
}
}),
($left:expr, $(|)? $( $pattern:pat_param )|+ $( if $guard: expr )?, $($arg:tt)+) => ({
},
($left:expr, $(|)? $( $pattern:pat_param )|+ $( if $guard: expr )?, $($arg:tt)+) => {
match $left {
$( $pattern )|+ $( if $guard )? => {}
ref left_val => {
Expand All @@ -165,7 +165,7 @@ pub macro assert_matches {
);
}
}
}),
},
}

/// Asserts that a boolean expression is `true` at runtime.
Expand Down Expand Up @@ -214,7 +214,11 @@ pub macro assert_matches {
#[rustc_diagnostic_item = "debug_assert_macro"]
#[allow_internal_unstable(edition_panic)]
macro_rules! debug_assert {
($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert!($($arg)*); })
($($arg:tt)*) => {
if $crate::cfg!(debug_assertions) {
$crate::assert!($($arg)*);
}
};
}

/// Asserts that two expressions are equal to each other.
Expand All @@ -240,7 +244,11 @@ macro_rules! debug_assert {
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "debug_assert_eq_macro")]
macro_rules! debug_assert_eq {
($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert_eq!($($arg)*); })
($($arg:tt)*) => {
if $crate::cfg!(debug_assertions) {
$crate::assert_eq!($($arg)*);
}
};
}

/// Asserts that two expressions are not equal to each other.
Expand All @@ -266,7 +274,11 @@ macro_rules! debug_assert_eq {
#[stable(feature = "assert_ne", since = "1.13.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "debug_assert_ne_macro")]
macro_rules! debug_assert_ne {
($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert_ne!($($arg)*); })
($($arg:tt)*) => {
if $crate::cfg!(debug_assertions) {
$crate::assert_ne!($($arg)*);
}
};
}

/// Asserts that an expression matches any of the given patterns.
Expand Down Expand Up @@ -305,7 +317,9 @@ macro_rules! debug_assert_ne {
#[allow_internal_unstable(assert_matches)]
#[rustc_macro_transparency = "semitransparent"]
pub macro debug_assert_matches($($arg:tt)*) {
if $crate::cfg!(debug_assertions) { $crate::assert_matches::assert_matches!($($arg)*); }
if $crate::cfg!(debug_assertions) {
$crate::assert_matches::assert_matches!($($arg)*);
}
}

/// Returns whether the given expression matches any of the given patterns.
Expand All @@ -331,7 +345,7 @@ macro_rules! matches {
$( $pattern )|+ $( if $guard )? => true,
_ => false
}
}
};
}

/// Unwraps a result or propagates its error.
Expand Down Expand Up @@ -482,7 +496,9 @@ macro_rules! r#try {
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "write_macro")]
macro_rules! write {
($dst:expr, $($arg:tt)*) => ($dst.write_fmt($crate::format_args!($($arg)*)))
($dst:expr, $($arg:tt)*) => {
$dst.write_fmt($crate::format_args!($($arg)*))
};
}

/// Write formatted data into a buffer, with a newline appended.
Expand Down Expand Up @@ -534,12 +550,12 @@ macro_rules! write {
#[cfg_attr(not(test), rustc_diagnostic_item = "writeln_macro")]
#[allow_internal_unstable(format_args_nl)]
macro_rules! writeln {
($dst:expr $(,)?) => (
($dst:expr $(,)?) => {
$crate::write!($dst, "\n")
);
($dst:expr, $($arg:tt)*) => (
};
($dst:expr, $($arg:tt)*) => {
$dst.write_fmt($crate::format_args_nl!($($arg)*))
);
};
}

/// Indicates unreachable code.
Expand Down Expand Up @@ -683,8 +699,12 @@ macro_rules! unreachable {
#[cfg_attr(not(test), rustc_diagnostic_item = "unimplemented_macro")]
#[allow_internal_unstable(core_panic)]
macro_rules! unimplemented {
() => ($crate::panicking::panic("not implemented"));
($($arg:tt)+) => ($crate::panic!("not implemented: {}", $crate::format_args!($($arg)+)));
() => {
$crate::panicking::panic("not implemented")
};
($($arg:tt)+) => {
$crate::panic!("not implemented: {}", $crate::format_args!($($arg)+))
};
}

/// Indicates unfinished code.
Expand Down Expand Up @@ -746,8 +766,12 @@ macro_rules! unimplemented {
#[cfg_attr(not(test), rustc_diagnostic_item = "todo_macro")]
#[allow_internal_unstable(core_panic)]
macro_rules! todo {
() => ($crate::panicking::panic("not yet implemented"));
($($arg:tt)+) => ($crate::panic!("not yet implemented: {}", $crate::format_args!($($arg)+)));
() => {
$crate::panicking::panic("not yet implemented")
};
($($arg:tt)+) => {
$crate::panic!("not yet implemented: {}", $crate::format_args!($($arg)+))
};
}

/// Definitions of built-in macros.
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3536,7 +3536,7 @@ impl<T> [T] {
/// suffix.iter().copied().sum(),
/// ]);
/// let sums = middle.iter().copied().fold(sums, f32x4::add);
/// sums.horizontal_sum()
/// sums.reduce_sum()
/// }
///
/// let numbers: Vec<f32> = (1..101).map(|x| x as _).collect();
Expand Down
4 changes: 2 additions & 2 deletions library/portable-simd/beginners-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ SIMD has a few special vocabulary terms you should know:

* **Vertical:** When an operation is "vertical", each lane processes individually without regard to the other lanes in the same vector. For example, a "vertical add" between two vectors would add lane 0 in `a` with lane 0 in `b`, with the total in lane 0 of `out`, and then the same thing for lanes 1, 2, etc. Most SIMD operations are vertical operations, so if your problem is a vertical problem then you can probably solve it with SIMD.

* **Horizontal:** When an operation is "horizontal", the lanes within a single vector interact in some way. A "horizontal add" might add up lane 0 of `a` with lane 1 of `a`, with the total in lane 0 of `out`.
* **Reducing/Reduce:** When an operation is "reducing" (functions named `reduce_*`), the lanes within a single vector are merged using some operation such as addition, returning the merged value as a scalar. For instance, a reducing add would return the sum of all the lanes' values.

* **Target Feature:** Rust calls a CPU architecture extension a `target_feature`. Proper SIMD requires various CPU extensions to be enabled (details below). Don't confuse this with `feature`, which is a Cargo crate concept.

Expand Down Expand Up @@ -83,4 +83,4 @@ Fortunately, most SIMD types have a fairly predictable size. `i32x4` is bit-equi
However, this is not the same as alignment. Computer architectures generally prefer aligned accesses, especially when moving data between memory and vector registers, and while some support specialized operations that can bend the rules to help with this, unaligned access is still typically slow, or even undefined behavior. In addition, different architectures can require different alignments when interacting with their native SIMD types. For this reason, any `#[repr(simd)]` type has a non-portable alignment. If it is necessary to directly interact with the alignment of these types, it should be via [`mem::align_of`].

[`mem::transmute`]: https://doc.rust-lang.org/core/mem/fn.transmute.html
[`mem::align_of`]: https://doc.rust-lang.org/core/mem/fn.align_of.html
[`mem::align_of`]: https://doc.rust-lang.org/core/mem/fn.align_of.html
2 changes: 1 addition & 1 deletion library/portable-simd/crates/core_simd/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ categories = ["hardware-support", "no-std"]
license = "MIT OR Apache-2.0"

[features]
default = ["std", "generic_const_exprs"]
default = []
std = []
generic_const_exprs = []

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ pub fn simd_inv4x4(m: Matrix4x4) -> Option<Matrix4x4> {
let det = det.rotate_lanes_right::<2>() + det;
let det = det.reverse().rotate_lanes_right::<2>() + det;

if det.horizontal_sum() == 0. {
if det.reduce_sum() == 0. {
return None;
}
// calculate the reciprocal
Expand Down
8 changes: 4 additions & 4 deletions library/portable-simd/crates/core_simd/examples/nbody.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,10 @@ mod nbody {
let mut e = 0.;
for i in 0..N_BODIES {
let bi = &bodies[i];
e += bi.mass * (bi.v * bi.v).horizontal_sum() * 0.5;
e += bi.mass * (bi.v * bi.v).reduce_sum() * 0.5;
for bj in bodies.iter().take(N_BODIES).skip(i + 1) {
let dx = bi.x - bj.x;
e -= bi.mass * bj.mass / (dx * dx).horizontal_sum().sqrt()
e -= bi.mass * bj.mass / (dx * dx).reduce_sum().sqrt()
}
}
e
Expand All @@ -134,8 +134,8 @@ mod nbody {
let mut mag = [0.0; N];
for i in (0..N).step_by(2) {
let d2s = f64x2::from_array([
(r[i] * r[i]).horizontal_sum(),
(r[i + 1] * r[i + 1]).horizontal_sum(),
(r[i] * r[i]).reduce_sum(),
(r[i + 1] * r[i + 1]).reduce_sum(),
]);
let dmags = f64x2::splat(dt) / (d2s * d2s.sqrt());
mag[i] = dmags[0];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ fn mult_av(v: &[f64], out: &mut [f64]) {
sum += b / a;
j += 2
}
*out = sum.horizontal_sum();
*out = sum.reduce_sum();
}
}

Expand All @@ -38,7 +38,7 @@ fn mult_atv(v: &[f64], out: &mut [f64]) {
sum += b / a;
j += 2
}
*out = sum.horizontal_sum();
*out = sum.reduce_sum();
}
}

Expand Down
52 changes: 52 additions & 0 deletions library/portable-simd/crates/core_simd/src/comparisons.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,55 @@ where
unsafe { Mask::from_int_unchecked(intrinsics::simd_ge(self, other)) }
}
}

macro_rules! impl_ord_methods_vector {
{ $type:ty } => {
impl<const LANES: usize> Simd<$type, LANES>
where
LaneCount<LANES>: SupportedLaneCount,
{
/// Returns the lane-wise minimum with `other`.
#[must_use = "method returns a new vector and does not mutate the original value"]
#[inline]
pub fn min(self, other: Self) -> Self {
self.lanes_gt(other).select(other, self)
}

/// Returns the lane-wise maximum with `other`.
#[must_use = "method returns a new vector and does not mutate the original value"]
#[inline]
pub fn max(self, other: Self) -> Self {
self.lanes_lt(other).select(other, self)
}

/// Restrict each lane to a certain interval.
///
/// For each lane, returns `max` if `self` is greater than `max`, and `min` if `self` is
/// less than `min`. Otherwise returns `self`.
///
/// # Panics
///
/// Panics if `min > max` on any lane.
#[must_use = "method returns a new vector and does not mutate the original value"]
#[inline]
pub fn clamp(self, min: Self, max: Self) -> Self {
assert!(
min.lanes_le(max).all(),
"each lane in `min` must be less than or equal to the corresponding lane in `max`",
);
self.max(min).min(max)
}
}
}
}

impl_ord_methods_vector!(i8);
impl_ord_methods_vector!(i16);
impl_ord_methods_vector!(i32);
impl_ord_methods_vector!(i64);
impl_ord_methods_vector!(isize);
impl_ord_methods_vector!(u8);
impl_ord_methods_vector!(u16);
impl_ord_methods_vector!(u32);
impl_ord_methods_vector!(u64);
impl_ord_methods_vector!(usize);
9 changes: 8 additions & 1 deletion library/portable-simd/crates/core_simd/src/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
//!
//! Unless stated otherwise, all intrinsics for binary operations require SIMD vectors of equal types and lengths.


// These intrinsics aren't linked directly from LLVM and are mostly undocumented, however they are
// mostly lowered to the matching LLVM instructions by the compiler in a fairly straightforward manner.
// The associated LLVM instruction or intrinsic is documented alongside each Rust intrinsic function.
Expand Down Expand Up @@ -130,6 +129,14 @@ extern "platform-intrinsic" {
pub(crate) fn simd_reduce_xor<T, U>(x: T) -> U;

// truncate integer vector to bitmask
// `fn simd_bitmask(vector) -> unsigned integer` takes a vector of integers and
// returns either an unsigned integer or array of `u8`.
// Every element in the vector becomes a single bit in the returned bitmask.
// If the vector has less than 8 lanes, a u8 is returned with zeroed trailing bits.
// The bit order of the result depends on the byte endianness. LSB-first for little
// endian and MSB-first for big endian.
//
// UB if called on a vector with values other than 0 and -1.
#[allow(unused)]
pub(crate) fn simd_bitmask<T, U>(x: T) -> U;

Expand Down
3 changes: 1 addition & 2 deletions library/portable-simd/crates/core_simd/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![no_std]
#![feature(
const_fn_trait_bound,
convert_float_to_int,
decl_macro,
intra_doc_pointers,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ macro_rules! impl_integer_intrinsic {
}

impl_integer_intrinsic! {
unsafe impl ToBitMask<BitMask=u8> for Mask<_, 1>
unsafe impl ToBitMask<BitMask=u8> for Mask<_, 2>
unsafe impl ToBitMask<BitMask=u8> for Mask<_, 4>
unsafe impl ToBitMask<BitMask=u8> for Mask<_, 8>
unsafe impl ToBitMask<BitMask=u16> for Mask<_, 16>
unsafe impl ToBitMask<BitMask=u32> for Mask<_, 32>
Expand Down
Loading