Skip to content

Commit 2a02c4d

Browse files
committed
Create SimdFloat trait
1 parent 80469c6 commit 2a02c4d

File tree

2 files changed

+73
-36
lines changed

2 files changed

+73
-36
lines changed

crates/core_simd/src/vector/float.rs

Lines changed: 70 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -134,42 +134,6 @@ macro_rules! impl_float_vector {
134134
let magnitude = self.to_bits() & !Self::splat(-0.).to_bits();
135135
Self::from_bits(sign_bit | magnitude)
136136
}
137-
138-
/// Returns the minimum of each lane.
139-
///
140-
/// If one of the values is `NAN`, then the other value is returned.
141-
#[inline]
142-
#[must_use = "method returns a new vector and does not mutate the original value"]
143-
pub fn simd_min(self, other: Self) -> Self {
144-
unsafe { intrinsics::simd_fmin(self, other) }
145-
}
146-
147-
/// Returns the maximum of each lane.
148-
///
149-
/// If one of the values is `NAN`, then the other value is returned.
150-
#[inline]
151-
#[must_use = "method returns a new vector and does not mutate the original value"]
152-
pub fn simd_max(self, other: Self) -> Self {
153-
unsafe { intrinsics::simd_fmax(self, other) }
154-
}
155-
156-
/// Restrict each lane to a certain interval unless it is NaN.
157-
///
158-
/// For each lane in `self`, returns the corresponding lane in `max` if the lane is
159-
/// greater than `max`, and the corresponding lane in `min` if the lane is less
160-
/// than `min`. Otherwise returns the lane in `self`.
161-
#[inline]
162-
#[must_use = "method returns a new vector and does not mutate the original value"]
163-
pub fn simd_clamp(self, min: Self, max: Self) -> Self {
164-
assert!(
165-
min.simd_le(max).all(),
166-
"each lane in `min` must be less than or equal to the corresponding lane in `max`",
167-
);
168-
let mut x = self;
169-
x = x.simd_lt(min).select(min, x);
170-
x = x.simd_gt(max).select(max, x);
171-
x
172-
}
173137
}
174138
};
175139
}
@@ -197,3 +161,73 @@ pub type f64x4 = Simd<f64, 4>;
197161

198162
/// Vector of eight `f64` values
199163
pub type f64x8 = Simd<f64, 8>;
164+
165+
mod sealed {
166+
pub trait Sealed {}
167+
}
168+
use sealed::Sealed;
169+
170+
/// SIMD operations on vectors of floating point numbers.
171+
pub trait SimdFloat: Sized + Sealed {
172+
/// Returns the minimum of each lane.
173+
///
174+
/// If one of the values is `NAN`, then the other value is returned.
175+
#[must_use = "method returns a new vector and does not mutate the original value"]
176+
fn simd_min(self, other: Self) -> Self;
177+
178+
/// Returns the maximum of each lane.
179+
///
180+
/// If one of the values is `NAN`, then the other value is returned.
181+
#[must_use = "method returns a new vector and does not mutate the original value"]
182+
fn simd_max(self, other: Self) -> Self;
183+
184+
/// Restrict each lane to a certain interval unless it is NaN.
185+
///
186+
/// For each lane in `self`, returns the corresponding lane in `max` if the lane is
187+
/// greater than `max`, and the corresponding lane in `min` if the lane is less
188+
/// than `min`. Otherwise returns the lane in `self`.
189+
#[must_use = "method returns a new vector and does not mutate the original value"]
190+
fn simd_clamp(self, min: Self, max: Self) -> Self;
191+
}
192+
193+
macro_rules! impl_simd_float {
194+
{ $($float:ty),* } => {
195+
$(
196+
impl <const LANES: usize> Sealed for Simd<$float, LANES>
197+
where
198+
LaneCount<LANES>: SupportedLaneCount,
199+
{
200+
}
201+
202+
impl <const LANES: usize> SimdFloat for Simd<$float, LANES>
203+
where
204+
LaneCount<LANES>: SupportedLaneCount,
205+
{
206+
#[inline]
207+
#[must_use = "method returns a new vector and does not mutate the original value"]
208+
fn simd_min(self, other: Self) -> Self {
209+
unsafe { intrinsics::simd_fmin(self, other) }
210+
}
211+
212+
#[inline]
213+
fn simd_max(self, other: Self) -> Self {
214+
unsafe { intrinsics::simd_fmax(self, other) }
215+
}
216+
217+
#[inline]
218+
fn simd_clamp(self, min: Self, max: Self) -> Self {
219+
assert!(
220+
min.simd_le(max).all(),
221+
"each lane in `min` must be less than or equal to the corresponding lane in `max`",
222+
);
223+
let mut x = self;
224+
x = x.simd_lt(min).select(min, x);
225+
x = x.simd_gt(max).select(max, x);
226+
x
227+
}
228+
}
229+
)*
230+
}
231+
}
232+
233+
impl_simd_float! { f32, f64 }

crates/core_simd/tests/ops_macros.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,7 @@ macro_rules! impl_float_tests {
462462
}
463463

464464
fn simd_min<const LANES: usize>() {
465+
use core_simd::simd::SimdFloat;
465466
// Regular conditions (both values aren't zero)
466467
test_helpers::test_binary_elementwise(
467468
&Vector::<LANES>::simd_min,
@@ -485,6 +486,7 @@ macro_rules! impl_float_tests {
485486
}
486487

487488
fn simd_max<const LANES: usize>() {
489+
use core_simd::simd::SimdFloat;
488490
// Regular conditions (both values aren't zero)
489491
test_helpers::test_binary_elementwise(
490492
&Vector::<LANES>::simd_max,
@@ -508,6 +510,7 @@ macro_rules! impl_float_tests {
508510
}
509511

510512
fn simd_clamp<const LANES: usize>() {
513+
use core_simd::simd::SimdFloat;
511514
test_helpers::test_3(&|value: [Scalar; LANES], mut min: [Scalar; LANES], mut max: [Scalar; LANES]| {
512515
for (min, max) in min.iter_mut().zip(max.iter_mut()) {
513516
if max < min {

0 commit comments

Comments
 (0)