Last active
March 16, 2022 10:12
-
-
Save luojia65/5355bf7fea7b783d36e86ffa6467febe to your computer and use it in GitHub Desktop.
RISC-V V DynSimd
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /// Runtime dynamic SIMD value | |
| /// | |
| /// This structure a wrap of an unsized slice, whose memory layout varies by architecture | |
| /// under #[repr(simd)]. | |
| /// | |
| /// In RISC-V, this type represents a group of elements to be processed in application, | |
| /// or VL number of T values. Length of current vector is placed in separate vector length | |
| /// CSR register `vl`. | |
| #[repr(simd)] | |
| pub struct DynSimd<T>([T]); | |
| impl<T> DynSimd<T> { | |
| #[inline] | |
| pub fn len(&self) -> usize { | |
| #[cfg(target_arch = "riscv32")] | |
| core::arch::riscv32::vl() | |
| #[cfg(target_arch = "riscv64")] | |
| core::arch::riscv64::vl() | |
| #[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))] | |
| unimplemented!("not supported under current architecture") | |
| } | |
| #[inline] | |
| pub fn as_slice(&self) -> &[T] { | |
| } | |
| } | |
| impl<T> Index<usize> for DynSimd<T> { | |
| type Output = T; | |
| fn index(&self, idx: usize) -> &Self::Output { | |
| simd_dyn_extract(self, idx) // ? | |
| } | |
| } | |
| // IndexMut?? | |
| extern "platform-intrinsic" { | |
| fn simd_dyn_extract<V, T>(x: V, i: usize) -> T; | |
| } | |
| /* | |
| compiler/rustc_codegen_llvm/src/intrinsic.rs | |
| */ | |
| pub type u64xN = DynSimd<u64>; | |
| // pub fn as_simd(&self) -> (&[T], SimdSteps<T>, &[T]) | |
| struct SimdSteps<T> { | |
| len: usize | |
| } | |
| impl<T> Iterator for SimdSteps<T> { | |
| type Item = T; | |
| fn next(&mut self) -> Option<&Self::Item> { | |
| // ... | |
| } | |
| } | |
| fn main() { | |
| let a: &[u64] = &[1, 2, 3, 4, 5]; | |
| let (lo_a, steps_a, hi_a) = a.as_simd(); | |
| let mut ret = scalar_sum(lo_a); | |
| for step_a in steps_a { | |
| ret += step_a.sum(); | |
| } | |
| ret += scalar_sum(hi_a); | |
| assert_eq!(ret, 15); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment