pub struct ErasedUpdatePlan { /* private fields */ }Expand description
Dtype-erased wrapper around UpdatePlan.
The layout traversal is compiled once and stored without a scalar type;
each execute names the concrete scalar type, resolves the
runtime element op once per call, and then replays monomorphized loops.
Implementations§
Source§impl ErasedUpdatePlan
impl ErasedUpdatePlan
Sourcepub fn compile(
dtype: KernelDType,
dims: &[usize],
dst_strides: &[isize],
src_strides: &[isize],
) -> Result<ErasedUpdatePlan, StridedError>
pub fn compile( dtype: KernelDType, dims: &[usize], dst_strides: &[isize], src_strides: &[isize], ) -> Result<ErasedUpdatePlan, StridedError>
Compile an update plan for one dtype and layout pair.
pub fn dtype(&self) -> KernelDType
Sourcepub fn plan(&self) -> &UpdatePlan
pub fn plan(&self) -> &UpdatePlan
The compiled typed traversal.
Sourcepub fn execute<T>(
&self,
dest: &mut ErasedRawStridedMut<'_>,
src: &ErasedRawStridedRef<'_>,
alpha: T,
beta: T,
op: UpdateOp,
exec: Exec<'_>,
) -> Result<(), StridedError>where
T: Copy + Send + Sync + KernelStorageElement + Add<Output = T> + Mul<Output = T> + Zero + One + PartialEq + ElementOpApply,
pub fn execute<T>(
&self,
dest: &mut ErasedRawStridedMut<'_>,
src: &ErasedRawStridedRef<'_>,
alpha: T,
beta: T,
op: UpdateOp,
exec: Exec<'_>,
) -> Result<(), StridedError>where
T: Copy + Send + Sync + KernelStorageElement + Add<Output = T> + Mul<Output = T> + Zero + One + PartialEq + ElementOpApply,
dest = alpha * op(src) + beta * dest into an erased destination.
alpha, beta, and op are resolved once per call; the layout check
and replay are the same allocation-free UpdatePlan path.
§Examples
use strided_basic::{
ErasedRawStridedMut, ErasedRawStridedRef, ErasedUpdatePlan, Exec, KernelDType,
UpdateOp,
};
let plan = ErasedUpdatePlan::compile(KernelDType::F64, &[2], &[1], &[1]).unwrap();
let src_data = [1.0_f64, 2.0];
let mut dst_data = [10.0_f64, 20.0];
let src = ErasedRawStridedRef::from_slice(&src_data, &[2], &[1], 0).unwrap();
let mut dst = ErasedRawStridedMut::from_slice_mut(&mut dst_data, &[2], &[1], 0).unwrap();
// dst = 2 * src + 3 * dst
plan.execute(&mut dst, &src, 2.0, 3.0, UpdateOp::Identity, Exec::serial())
.unwrap();
drop(dst);
assert_eq!(dst_data, [32.0, 64.0]);Sourcepub fn execute_uninit<T>(
&self,
dest: &mut ErasedRawStridedUninitMut<'_>,
src: &ErasedRawStridedPtr<'_>,
alpha: T,
op: UpdateOp,
exec: Exec<'_>,
) -> Result<(), StridedError>where
T: Copy + Send + Sync + KernelStorageElement + Mul<Output = T> + One + PartialEq + ElementOpApply,
pub fn execute_uninit<T>(
&self,
dest: &mut ErasedRawStridedUninitMut<'_>,
src: &ErasedRawStridedPtr<'_>,
alpha: T,
op: UpdateOp,
exec: Exec<'_>,
) -> Result<(), StridedError>where
T: Copy + Send + Sync + KernelStorageElement + Mul<Output = T> + One + PartialEq + ElementOpApply,
dest = alpha * op(src) into an uninitialized erased destination.
This is execute with beta = 0: the destination is
never read, so a NaN-filled or uninitialized output cannot contaminate
the result. On success every reachable destination element is written;
validation errors are returned before any write. A panic during
execution may leave a partially initialized MaybeUninit destination,
which is still safely droppable; no readable value is promised for
unwritten reachable slots.
§Examples
use core::mem::MaybeUninit;
use strided_basic::{
ErasedRawStridedPtr, ErasedRawStridedRef, ErasedRawStridedUninitMut, ErasedUpdatePlan,
Exec, KernelDType, UpdateOp,
};
let plan = ErasedUpdatePlan::compile(KernelDType::F64, &[2], &[1], &[1]).unwrap();
let src_data = [1.0_f64, 2.0];
let mut dst_data = [MaybeUninit::<f64>::uninit(); 2];
let src = ErasedRawStridedRef::from_slice(&src_data, &[2], &[1], 0).unwrap();
let src_ptr = ErasedRawStridedPtr::from_ref(&src);
let mut dst =
ErasedRawStridedUninitMut::from_uninit_slice(&mut dst_data, &[2], &[1], 0).unwrap();
// dst = 2 * src
plan.execute_uninit(&mut dst, &src_ptr, 2.0, UpdateOp::Identity, Exec::serial())
.unwrap();
let values: Vec<f64> = dst_data.iter().map(|v| unsafe { v.assume_init() }).collect();
assert_eq!(values, [2.0, 4.0]);§Errors
Returns DTypeMismatch or PlanLayoutMismatch when a descriptor does
not match the plan, and OverlappingInputOutput when the source
overlaps the destination allocation, all before any destination write.
Trait Implementations§
Source§impl Clone for ErasedUpdatePlan
impl Clone for ErasedUpdatePlan
Source§fn clone(&self) -> ErasedUpdatePlan
fn clone(&self) -> ErasedUpdatePlan
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl Freeze for ErasedUpdatePlan
impl RefUnwindSafe for ErasedUpdatePlan
impl Send for ErasedUpdatePlan
impl Sync for ErasedUpdatePlan
impl Unpin for ErasedUpdatePlan
impl UnsafeUnpin for ErasedUpdatePlan
impl UnwindSafe for ErasedUpdatePlan
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more