pub fn map_into_uninit_with_kernel<T>(
dest: &mut StridedViewMut<'_, MaybeUninit<T>>,
src: &StridedView<'_, T>,
kernel: impl Fn(&[T], &mut [MaybeUninit<T>]) -> bool + Sync,
scalar: impl Fn(T) -> T + MaybeSync,
) -> Result<(), StridedError>where
T: Copy + MaybeSendSync,Expand description
Apply an element-wise function into a potentially uninitialized destination, handing a vectorized kernel the flat runs it can take.
kernel is offered a flat, unit-stride run whenever this crate has one to give: the whole
buffer when the two views share a contiguous layout and the operation runs sequentially, and
one block at a time on the parallel path. It must write every element of the run or write
nothing — returning false makes that run fall back to scalar, element by element. Runs whose
strides are not both 1 never reach it. It is called from whichever threads this crate’s
execution policy selected, so it must be Sync.
The point of the entry point is that a caller which owns vector kernels — a SIMD math library,
say — reuses this crate’s layout logic and this crate’s threading decision instead of
rebuilding either. scalar and kernel must agree up to the caller’s own error bound; this
crate only guarantees that every destination element is written exactly once.
§Examples
use std::mem::MaybeUninit;
use strided_basic::{map_into_uninit_with_kernel, StridedView, StridedViewMut};
let src = vec![1.0f64, 2.0, 3.0];
let mut out = vec![MaybeUninit::<f64>::uninit(); 3];
let mut dest = StridedViewMut::new(&mut out, &[3], &[1], 0).unwrap();
let source = StridedView::new(&src, &[3], &[1], 0).unwrap();
let kernel = |src: &[f64], dst: &mut [MaybeUninit<f64>]| {
for (slot, value) in dst.iter_mut().zip(src) {
slot.write(value * 2.0);
}
true
};
map_into_uninit_with_kernel(&mut dest, &source, kernel, |x| x * 2.0).unwrap();
// SAFETY: the kernel wrote every element.
let values: Vec<f64> = out.into_iter().map(|x| unsafe { x.assume_init() }).collect();
assert_eq!(values, [2.0, 4.0, 6.0]);§Errors
Returns StridedError::ShapeMismatch when the shapes differ and
StridedError::NonInjectiveOutputLayout when the destination layout cannot be proven
injective.