Skip to content
This repository has been archived by the owner on Feb 18, 2024. It is now read-only.

Commit

Permalink
unsafe in trait contract/impl
Browse files Browse the repository at this point in the history
  • Loading branch information
ritchie46 committed Sep 29, 2021
1 parent b5f6430 commit 5f85f94
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 7 deletions.
5 changes: 1 addition & 4 deletions src/compute/aggregate/sum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,7 @@ where
T: NativeType + Simd + Add<Output = T> + std::iter::Sum<T>,
T::Simd: Sum<T> + Add<Output = T::Simd>,
{
// Safety:
// T::Simd is the vector type T and the alignment is similar to aligning to [T; alignment]
// the alignment of T::Simd ensures that it fits T.
let (head, simd_vals, tail) = unsafe { values.align_to::<T::Simd>() };
let (head, simd_vals, tail) = T::Simd::align(values);

let mut reduced = T::Simd::from_incomplete_chunk(&[], T::default());
for chunk in simd_vals {
Expand Down
7 changes: 6 additions & 1 deletion src/types/simd/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ pub trait FromMaskChunk<T> {
}

/// A struct that lends itself well to be compiled leveraging SIMD
pub trait NativeSimd: Default + Copy {
/// # Safety
/// The `NativeType` and the `NativeSimd` must have possible a matching alignment.
/// e.g. slicing `&[NativeType]` by `align_of<NativeSimd>()` must be properly aligned/safe.
pub unsafe trait NativeSimd: Default + Copy {
/// Number of lanes
const LANES: usize;
/// The [`NativeType`] of this struct. E.g. `f32` for a `NativeSimd = f32x16`.
Expand All @@ -32,6 +35,8 @@ pub trait NativeSimd: Default + Copy {
/// Items from `v` at positions larger than the number of lanes are ignored;
/// remaining items are populated with `remaining`.
fn from_incomplete_chunk(v: &[Self::Native], remaining: Self::Native) -> Self;

fn align(values: &[Self::Native]) -> (&[Self::Native], &[Self], &[Self::Native]);
}

/// Trait implemented by some [`NativeType`] that have a SIMD representation.
Expand Down
7 changes: 6 additions & 1 deletion src/types/simd/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ macro_rules! simd {
#[derive(Copy, Clone)]
pub struct $name(pub [$type; $lanes]);

impl NativeSimd for $name {
unsafe impl NativeSimd for $name {
const LANES: usize = $lanes;
type Native = $type;
type Chunk = $mask;
Expand All @@ -36,6 +36,11 @@ macro_rules! simd {
a.iter_mut().zip(v.iter()).for_each(|(a, b)| *a = *b);
Self(a)
}

#[inline]
fn align(values: &[Self::Native]) -> (&[Self::Native], &[Self], &[Self::Native]) {
unsafe { values.align_to::<Self>() }
}
}

impl std::ops::Index<usize> for $name {
Expand Down
7 changes: 6 additions & 1 deletion src/types/simd/packed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use super::*;

macro_rules! simd {
($name:tt, $type:ty, $lanes:expr, $chunk:ty, $mask:tt) => {
impl NativeSimd for $name {
unsafe impl NativeSimd for $name {
const LANES: usize = $lanes;
type Native = $type;
type Chunk = $chunk;
Expand All @@ -29,6 +29,11 @@ macro_rules! simd {
a.iter_mut().zip(v.iter()).for_each(|(a, b)| *a = *b);
<$name>::from_chunk(a.as_ref())
}

#[inline]
fn align(values: &[Self::Native]) -> (&[Self::Native], &[Self], &[Self::Native]) {
unsafe { values.align_to::<Self>() }
}
}
};
}
Expand Down

0 comments on commit 5f85f94

Please sign in to comment.