Skip to content

add more doctests #132

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 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
41 changes: 41 additions & 0 deletions crates/core_simd/src/first.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,54 @@ macro_rules! impl_vector {
{ $name:ident, $type:ty } => {
impl<const LANES: usize> $name<LANES> where Self: crate::LanesAtMost32 {
/// Construct a SIMD vector by setting all lanes to the given value.
/// ```
/// # use core_simd::*;
/// let a = f32x4::from_array([1.0, 1.0, 1.0, 1.0]);
/// let b = f32x4::splat(1.0);
/// assert_eq!(a, b);
/// ```
pub const fn splat(value: $type) -> Self {
Self([value; LANES])
}

/// Returns a slice containing the entire SIMD vector.
/// ```
/// # use core_simd::*;
/// let a = f32x4::from_array([1.0, 1.0, 1.0, 1.0]);
/// let b = a.as_slice();
/// ```
pub const fn as_slice(&self) -> &[$type] {
&self.0
}

/// Returns a mutable slice containing the entire SIMD vector.
/// ```
/// # use core_simd::*;
/// let mut a = f32x4::from_array([1.0, 1.0, 1.0, 1.0]);
/// let b = a.as_mut_slice();
/// ```
pub fn as_mut_slice(&mut self) -> &mut [$type] {
&mut self.0
}

/// Converts an array to a SIMD vector.
/// ```
/// # use core_simd::*;
/// let a = f32x4::from_array([1.0, 1.0, 1.0, 1.0]);
/// let b = f32x4::splat(1.0);
/// assert_eq!(a, b);
/// ```
pub const fn from_array(array: [$type; LANES]) -> Self {
Self(array)
}

/// Converts a SIMD vector to an array.
/// ```
/// # use core_simd::*;
/// let a = f32x4::from_array([1.0, 1.0, 1.0, 1.0]);
/// let b = [1.0, 1.0, 1.0, 1.0];
/// assert_eq!(f32x4::to_array(a), b);
/// ```
pub const fn to_array(self) -> [$type; LANES] {
// workaround for rust-lang/rust#80108
// TODO fix this
Expand All @@ -47,6 +75,13 @@ macro_rules! impl_vector {
impl<const LANES: usize> Copy for $name<LANES> where Self: crate::LanesAtMost32 {}

impl<const LANES: usize> Clone for $name<LANES> where Self: crate::LanesAtMost32 {
/// Clone a SIMD vector.
/// ```
/// # use core_simd::*;
/// let a = f32x4::from_array([1.0, 1.0, 1.0, 1.0]);
/// assert_eq!(a, f32x4::clone(&a));
/// assert_eq!(a, a.clone());
/// ```
#[inline]
fn clone(&self) -> Self {
*self
Expand All @@ -61,6 +96,12 @@ macro_rules! impl_vector {
}

impl<const LANES: usize> PartialEq for $name<LANES> where Self: crate::LanesAtMost32 {
/// ```
/// # use core_simd::*;
/// let a = f32x4::splat(1.0);
/// let b = f32x4::splat(1.0);
/// assert!(a == b);
/// ```
#[inline]
fn eq(&self, other: &Self) -> bool {
// TODO use SIMD equality
Expand Down
71 changes: 70 additions & 1 deletion crates/core_simd/src/reduction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,45 +5,86 @@ macro_rules! impl_integer_reductions {
Self: crate::LanesAtMost32
{
/// Horizontal wrapping add. Returns the sum of the lanes of the vector, with wrapping addition.
/// ```
/// # use core_simd::*;
/// let a = u32x4::from_array([1, 2, 3, 4]).horizontal_sum();
/// assert_eq!(10, a);
/// let b = u32x4::from_array([u32::MAX, 1, 0, 0]).horizontal_sum();
/// assert_eq!(0, b);
/// ```
#[inline]
pub fn horizontal_sum(self) -> $scalar {
unsafe { crate::intrinsics::simd_reduce_add_ordered(self, 0) }
}

/// Horizontal wrapping multiply. Returns the product of the lanes of the vector, with wrapping multiplication.
/// ```
/// # use core_simd::*;
/// let a = u32x4::from_array([2, 2, 2, 2]).horizontal_product();
/// assert_eq!(16, a);
/// let b = u32x4::from_array([u32::MAX, 2, 1, 1]).horizontal_product();
/// assert_eq!(u32::MAX, b + 1); // Because 2*u32::MAX wraps, and is 1 off from the u32::MAX
/// ```
#[inline]
pub fn horizontal_product(self) -> $scalar {
unsafe { crate::intrinsics::simd_reduce_mul_ordered(self, 1) }
}

/// Horizontal bitwise "and". Returns the cumulative bitwise "and" across the lanes of
/// the vector.
/// ```
/// # use core_simd::*;
/// let a = u32x4::from_array([3, 3, 3, 3]).horizontal_and();
/// assert_eq!(3, a);
/// let b = u32x4::from_array([1, 1, 0, 0]).horizontal_and();
/// assert_eq!(0, b);
/// ```
#[inline]
pub fn horizontal_and(self) -> $scalar {
unsafe { crate::intrinsics::simd_reduce_and(self) }
}

/// Horizontal bitwise "or". Returns the cumulative bitwise "or" across the lanes of
/// the vector.
/// ```
/// # use core_simd::*;
/// let a = u32x4::from_array([1, 2, 0, 0]).horizontal_or();
/// assert_eq!(3, a);
/// ```
#[inline]
pub fn horizontal_or(self) -> $scalar {
unsafe { crate::intrinsics::simd_reduce_or(self) }
}

/// Horizontal bitwise "xor". Returns the cumulative bitwise "xor" across the lanes of
/// the vector.
/// ```
/// # use core_simd::*;
/// let a = u32x4::from_array([5, 5, 5, 0]).horizontal_xor();
/// assert_eq!(5, a);
/// ```
#[inline]
pub fn horizontal_xor(self) -> $scalar {
unsafe { crate::intrinsics::simd_reduce_xor(self) }
}

/// Horizontal maximum. Returns the maximum lane in the vector.
/// ```
/// # use core_simd::*;
/// let a = u32x4::from_array([1, 2, 42, 0]).horizontal_max();
/// assert_eq!(42, a);
/// ```
#[inline]
pub fn horizontal_max(self) -> $scalar {
unsafe { crate::intrinsics::simd_reduce_max(self) }
}

/// Horizontal minimum. Returns the minimum lane in the vector.
/// ```
/// # use core_simd::*;
/// let a = u32x4::from_array([1, 2, 42, 0]).horizontal_min();
/// assert_eq!(0, a);
/// ```
#[inline]
pub fn horizontal_min(self) -> $scalar {
unsafe { crate::intrinsics::simd_reduce_min(self) }
Expand All @@ -59,7 +100,14 @@ macro_rules! impl_float_reductions {
Self: crate::LanesAtMost32
{

/// Horizontal add. Returns the sum of the lanes of the vector.
/// Horizontal add. Returns the sum of the lanes of the vector, with saturating addition.
/// ```
/// # use core_simd::*;
/// let a = f32x4::from_array([1.0, 2.0, 3.0, 4.0]).horizontal_sum();
/// assert_eq!(10.0, a);
/// let b = f32x4::from_array([f32::MAX, 2.0, 0.0, 0.0]).horizontal_sum();
/// assert_eq!(f32::MAX, b);
/// ```
#[inline]
pub fn horizontal_sum(self) -> $scalar {
// LLVM sum is inaccurate on i586
Expand All @@ -71,6 +119,13 @@ macro_rules! impl_float_reductions {
}

/// Horizontal multiply. Returns the product of the lanes of the vector.
/// ```
/// # use core_simd::*;
/// let a = f32x4::from_array([1.0, 2.0, 3.0, 4.0]).horizontal_product();
/// assert_eq!(24.0, a);
/// let b = f32x4::from_array([f32::MAX, 2.0, 1.0, 1.0]).horizontal_product();
/// assert_eq!(f32::MAX, b);
/// ```
#[inline]
pub fn horizontal_product(self) -> $scalar {
// LLVM product is inaccurate on i586
Expand All @@ -85,6 +140,13 @@ macro_rules! impl_float_reductions {
///
/// Returns values based on equality, so a vector containing both `0.` and `-0.` may
/// return either. This function will not return `NaN` unless all lanes are `NaN`.
/// ```
/// # use core_simd::*;
/// let a = f32x4::from_array([1.0, 2.0, 3.0, 4.0]).horizontal_max();
/// assert_eq!(4.0, a);
/// let b = f32x4::from_array([f32::NAN, 2.0, 0.0, 0.0]).horizontal_max();
/// assert_eq!(2.0, b);
/// ```
#[inline]
pub fn horizontal_max(self) -> $scalar {
unsafe { crate::intrinsics::simd_reduce_max(self) }
Expand All @@ -94,6 +156,13 @@ macro_rules! impl_float_reductions {
///
/// Returns values based on equality, so a vector containing both `0.` and `-0.` may
/// return either. This function will not return `NaN` unless all lanes are `NaN`.
/// ```
/// # use core_simd::*;
/// let a = f32x4::from_array([1.0, 2.0, 3.0, 4.0]).horizontal_min();
/// assert_eq!(1.0, a);
/// let b = f32x4::from_array([f32::NAN, 2.0, 0.0, 0.0]).horizontal_min();
/// assert_eq!(0.0, b);
/// ```
#[inline]
pub fn horizontal_min(self) -> $scalar {
unsafe { crate::intrinsics::simd_reduce_min(self) }
Expand Down
37 changes: 36 additions & 1 deletion crates/core_simd/src/round.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,69 @@ macro_rules! implement {
Self: crate::LanesAtMost32,
{
/// Returns the smallest integer greater than or equal to each lane.
/// ```
/// # use core_simd::*;
/// let a = f32x4::from_array([-3.3, -0.7, 2.9, 0.2]);
/// let b = f32x4::from_array([-3.0, 0.0, 3.0, 1.0]);
/// let c = f32x4::ceil(a);
/// assert_eq!(c, b);
/// ```
#[must_use = "method returns a new vector and does not mutate the original value"]
#[inline]
pub fn ceil(self) -> Self {
unsafe { crate::intrinsics::simd_ceil(self) }
}

/// Returns the largest integer value less than or equal to each lane.
/// ```
/// # use core_simd::*;
/// let a = f32x4::from_array([-3.3, -0.7, 2.3, 1.3]);
/// let b = f32x4::from_array([-4.0, -1.0, 2.0, 1.0]);
/// let c = f32x4::floor(a);
/// assert_eq!(c, b);
/// ```
#[must_use = "method returns a new vector and does not mutate the original value"]
#[inline]
pub fn floor(self) -> Self {
unsafe { crate::intrinsics::simd_floor(self) }
}

/// Rounds to the nearest integer value. Ties round toward zero.
/// Rounds to the nearest integer value. Ties round away from zero.
/// ```
/// # use core_simd::*;
/// let a = f32x4::from_array([-3.6, -0.5, 2.5, 0.6]);
/// let b = f32x4::from_array([-4.0, -1.0, 3.0, 1.0]);
/// let c = f32x4::round(a);
/// assert_eq!(c, b);
/// ```
#[must_use = "method returns a new vector and does not mutate the original value"]
#[inline]
pub fn round(self) -> Self {
unsafe { crate::intrinsics::simd_round(self) }
}

/// Returns the floating point's integer value, with its fractional part removed.
/// ```
/// # use core_simd::*;
/// let a = f32x4::from_array([-3.47, -0.1234, 2.3, 0.1234]);
/// let b = f32x4::from_array([-3.0, -0.0, 2.0, 0.0]);
/// let c = f32x4::trunc(a);
/// assert_eq!(c, b);
/// ```
#[must_use = "method returns a new vector and does not mutate the original value"]
#[inline]
pub fn trunc(self) -> Self {
unsafe { crate::intrinsics::simd_trunc(self) }
}

/// Returns the floating point's fractional value, with its integer part removed.
/// ```
/// # use core_simd::*;
/// let a = f32x4::from_array([-3.25, -0.75, 2.5, 10.0]);
/// let b = f32x4::from_array([-0.25, -0.75, 0.5, 0.0]);
/// let c = f32x4::fract(a);
/// assert_eq!(c, b);
/// ```
#[must_use = "method returns a new vector and does not mutate the original value"]
#[inline]
pub fn fract(self) -> Self {
Expand Down
14 changes: 14 additions & 0 deletions crates/core_simd/src/vector/float.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,27 @@ macro_rules! impl_float_vector {

/// Produces a vector where every lane has the absolute value of the
/// equivalently-indexed lane in `self`.
/// ```
/// # use core_simd::*;
/// let a = f32x4::from_array([-3.0, -0.0, 2.0, 0.0]);
/// let b = f32x4::from_array([3.0, 0.0, 2.0, 0.0]);
/// let c = f32x4::abs(a);
/// assert_eq!(c, b);
/// ```
#[inline]
pub fn abs(self) -> Self {
unsafe { crate::intrinsics::simd_fabs(self) }
}

/// Produces a vector where every lane has the square root value
/// of the equivalently-indexed lane in `self`
/// ```
/// # use core_simd::*;
/// let a = f32x4::from_array([9.0, 16.0, 4.0, 0.0]);
/// let b = f32x4::from_array([3.0, 4.0, 2.0, 0.0]);
/// let c = f32x4::sqrt(a);
/// assert_eq!(c, b);
/// ```
#[inline]
#[cfg(feature = "std")]
pub fn sqrt(self) -> Self {
Expand Down