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<Self>
pub fn compile( dtype: KernelDType, dims: &[usize], dst_strides: &[isize], src_strides: &[isize], ) -> Result<Self>
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,
ctx: &ExecContext,
dest: &mut ErasedRawStridedMut<'_>,
src: &ErasedRawStridedRef<'_>,
alpha: T,
beta: T,
op: UpdateOp,
) -> Result<()>where
T: Copy + MaybeSendSync + KernelStorageElement + Add<Output = T> + Mul<Output = T> + Zero + One + PartialEq + ElementOpApply,
pub fn execute<T>(
&self,
ctx: &ExecContext,
dest: &mut ErasedRawStridedMut<'_>,
src: &ErasedRawStridedRef<'_>,
alpha: T,
beta: T,
op: UpdateOp,
) -> Result<()>where
T: Copy + MaybeSendSync + 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, ExecContext, 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(&ExecContext::serial(), &mut dst, &src, 2.0, 3.0, UpdateOp::Identity)
.unwrap();
drop(dst);
assert_eq!(dst_data, [32.0, 64.0]);Sourcepub fn execute_uninit<T>(
&self,
ctx: &ExecContext,
dest: &mut ErasedRawStridedUninitMut<'_>,
src: &ErasedRawStridedPtr<'_>,
alpha: T,
op: UpdateOp,
) -> Result<()>where
T: Copy + MaybeSendSync + KernelStorageElement + Mul<Output = T> + One + PartialEq + ElementOpApply,
pub fn execute_uninit<T>(
&self,
ctx: &ExecContext,
dest: &mut ErasedRawStridedUninitMut<'_>,
src: &ErasedRawStridedPtr<'_>,
alpha: T,
op: UpdateOp,
) -> Result<()>where
T: Copy + MaybeSendSync + 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,
ExecContext, 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(&ExecContext::serial(), &mut dst, &src_ptr, 2.0, UpdateOp::Identity)
.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.