From b1cf58292f0596a369d527b25b4519c1c5585002 Mon Sep 17 00:00:00 2001 From: sarah <> Date: Wed, 22 May 2024 19:01:14 +0200 Subject: [PATCH] add rsimd split --- pulp/Cargo.toml | 2 +- pulp/src/lib.rs | 149 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+), 1 deletion(-) diff --git a/pulp/Cargo.toml b/pulp/Cargo.toml index b0a8b1f..a6ae6c6 100644 --- a/pulp/Cargo.toml +++ b/pulp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pulp" -version = "0.18.12" +version = "0.18.13" edition = "2021" authors = ["sarah <>"] description = "Safe generic simd" diff --git a/pulp/src/lib.rs b/pulp/src/lib.rs index f2ea902..a474d3a 100644 --- a/pulp/src/lib.rs +++ b/pulp/src/lib.rs @@ -262,6 +262,119 @@ pub trait Simd: Seal + Debug + Copy + Send + Sync + 'static { unsafe { split_mut_slice(slice) } } + #[inline(always)] + fn f32s_as_rsimd(slice: &[f32]) -> (&[f32], &[Self::f32s]) { + unsafe { rsplit_slice(slice) } + } + #[inline(always)] + fn f32s_as_mut_rsimd(slice: &mut [f32]) -> (&mut [f32], &mut [Self::f32s]) { + unsafe { rsplit_mut_slice(slice) } + } + #[inline(always)] + fn f32s_as_uninit_mut_rsimd( + slice: &mut [MaybeUninit], + ) -> (&mut [MaybeUninit], &mut [MaybeUninit]) { + unsafe { rsplit_mut_slice(slice) } + } + #[inline(always)] + fn c32s_as_rsimd(slice: &[c32]) -> (&[c32], &[Self::c32s]) { + unsafe { rsplit_slice(slice) } + } + #[inline(always)] + fn c32s_as_mut_rsimd(slice: &mut [c32]) -> (&mut [c32], &mut [Self::c32s]) { + unsafe { rsplit_mut_slice(slice) } + } + #[inline(always)] + fn c32s_as_uninit_mut_rsimd( + slice: &mut [MaybeUninit], + ) -> (&mut [MaybeUninit], &mut [MaybeUninit]) { + unsafe { rsplit_mut_slice(slice) } + } + #[inline(always)] + fn i32s_as_rsimd(slice: &[i32]) -> (&[i32], &[Self::i32s]) { + unsafe { rsplit_slice(slice) } + } + #[inline(always)] + fn i32s_as_mut_rsimd(slice: &mut [i32]) -> (&mut [i32], &mut [Self::i32s]) { + unsafe { rsplit_mut_slice(slice) } + } + #[inline(always)] + fn i32s_as_uninit_mut_rsimd( + slice: &mut [MaybeUninit], + ) -> (&mut [MaybeUninit], &mut [MaybeUninit]) { + unsafe { rsplit_mut_slice(slice) } + } + #[inline(always)] + fn u32s_as_rsimd(slice: &[u32]) -> (&[u32], &[Self::u32s]) { + unsafe { rsplit_slice(slice) } + } + #[inline(always)] + fn u32s_as_mut_rsimd(slice: &mut [u32]) -> (&mut [u32], &mut [Self::u32s]) { + unsafe { rsplit_mut_slice(slice) } + } + #[inline(always)] + fn u32s_as_uninit_mut_rsimd( + slice: &mut [MaybeUninit], + ) -> (&mut [MaybeUninit], &mut [MaybeUninit]) { + unsafe { rsplit_mut_slice(slice) } + } + #[inline(always)] + fn f64s_as_rsimd(slice: &[f64]) -> (&[f64], &[Self::f64s]) { + unsafe { rsplit_slice(slice) } + } + #[inline(always)] + fn f64s_as_mut_rsimd(slice: &mut [f64]) -> (&mut [f64], &mut [Self::f64s]) { + unsafe { rsplit_mut_slice(slice) } + } + #[inline(always)] + fn f64s_as_uninit_mut_rsimd( + slice: &mut [MaybeUninit], + ) -> (&mut [MaybeUninit], &mut [MaybeUninit]) { + unsafe { rsplit_mut_slice(slice) } + } + #[inline(always)] + fn c64s_as_rsimd(slice: &[c64]) -> (&[c64], &[Self::c64s]) { + unsafe { rsplit_slice(slice) } + } + #[inline(always)] + fn c64s_as_mut_rsimd(slice: &mut [c64]) -> (&mut [c64], &mut [Self::c64s]) { + unsafe { rsplit_mut_slice(slice) } + } + #[inline(always)] + fn c64s_as_uninit_mut_rsimd( + slice: &mut [MaybeUninit], + ) -> (&mut [MaybeUninit], &mut [MaybeUninit]) { + unsafe { rsplit_mut_slice(slice) } + } + #[inline(always)] + fn i64s_as_rsimd(slice: &[i64]) -> (&[i64], &[Self::i64s]) { + unsafe { rsplit_slice(slice) } + } + #[inline(always)] + fn i64s_as_mut_rsimd(slice: &mut [i64]) -> (&mut [i64], &mut [Self::i64s]) { + unsafe { rsplit_mut_slice(slice) } + } + #[inline(always)] + fn i64s_as_uninit_mut_rsimd( + slice: &mut [MaybeUninit], + ) -> (&mut [MaybeUninit], &mut [MaybeUninit]) { + unsafe { rsplit_mut_slice(slice) } + } + #[inline(always)] + fn u64s_as_rsimd(slice: &[u64]) -> (&[u64], &[Self::u64s]) { + unsafe { rsplit_slice(slice) } + } + #[inline(always)] + fn u64s_as_mut_rsimd(slice: &mut [u64]) -> (&mut [u64], &mut [Self::u64s]) { + unsafe { rsplit_mut_slice(slice) } + } + #[inline(always)] + fn u64s_as_uninit_mut_rsimd( + slice: &mut [MaybeUninit], + ) -> (&mut [MaybeUninit], &mut [MaybeUninit]) { + unsafe { rsplit_mut_slice(slice) } + } + #[inline(always)] fn i32s_align_offset(self, ptr: *const i32, len: usize) -> Offset { align_offset_u32::( @@ -3400,6 +3513,42 @@ unsafe fn split_mut_slice(slice: &mut [T]) -> (&mut [U], &mut [T]) { ) } +#[inline(always)] +unsafe fn rsplit_slice(slice: &[T]) -> (&[T], &[U]) { + assert_eq!(core::mem::size_of::() % core::mem::size_of::(), 0); + assert_eq!(core::mem::align_of::(), core::mem::align_of::()); + + let chunk_size = core::mem::size_of::() / core::mem::size_of::(); + + let len = slice.len(); + let data = slice.as_ptr(); + + let div = len / chunk_size; + let rem = len % chunk_size; + ( + from_raw_parts(data, rem), + from_raw_parts(data.add(rem) as *const U, div), + ) +} + +#[inline(always)] +unsafe fn rsplit_mut_slice(slice: &mut [T]) -> (&mut [T], &mut [U]) { + assert_eq!(core::mem::size_of::() % core::mem::size_of::(), 0); + assert_eq!(core::mem::align_of::(), core::mem::align_of::()); + + let chunk_size = core::mem::size_of::() / core::mem::size_of::(); + + let len = slice.len(); + let data = slice.as_mut_ptr(); + + let div = len / chunk_size; + let rem = len % chunk_size; + ( + from_raw_parts_mut(data, rem), + from_raw_parts_mut(data.add(rem) as *mut U, div), + ) +} + #[cfg(not(any(target_arch = "aarch64", target_arch = "x86", target_arch = "x86_64")))] #[derive(Debug, Clone, Copy)] #[non_exhaustive]