Skip to main content

UpdatePlan

Struct UpdatePlan 

Source
pub struct UpdatePlan { /* private fields */ }
Expand description

A compiled read-modify-write traversal for one (dims, dst_strides, src_strides) layout pair.

execute computes dest = alpha * f(src) + beta * dest by replaying the same fused pair traversal as CopyPlan: compile proves the layout facts once (rank agreement, extent overflow, destination injectivity) and each call only re-checks that the supplied views carry the compiled layout before running monomorphized loops. Execute is allocation-free for fused ranks at most RAW_FUSED_RANK_LIMIT, and the injective destination makes a large replay parallel-safe exactly as in CopyPlan.

Overlapping src/dest memory is not supported, matching the rest of the crate.

§Example

use strided_basic::{RawStridedMut, RawStridedRef, UpdatePlan};

let dims = [2usize, 2];
let dst_strides = [1isize, 2];
let src_strides = [1isize, 2];
let plan = UpdatePlan::compile(&dims, &dst_strides, &src_strides).unwrap();

let src = [1.0f64, 2.0, 3.0, 4.0];
let mut dst = [10.0f64, 20.0, 30.0, 40.0];
let src_ref = RawStridedRef::new(&src, &dims, &src_strides, 0).unwrap();
let mut dst_mut = RawStridedMut::new(&mut dst, &dims, &dst_strides, 0).unwrap();
// dst = 2 * src + 3 * dst
plan.execute(&mut dst_mut, &src_ref, 2.0, 3.0, |x| x).unwrap();
assert_eq!(dst, [32.0, 64.0, 96.0, 128.0]);

Implementations§

Source§

impl UpdatePlan

Source

pub fn compile( dims: &[usize], dst_strides: &[isize], src_strides: &[isize], ) -> Result<Self>

Compile an update plan for the given layout pair.

Performs the same layout validation as CopyPlan::compile:

Source

pub fn execute<T, F>( &self, dest: &mut RawStridedMut<'_, T>, src: &RawStridedRef<'_, T>, alpha: T, beta: T, f: F, ) -> Result<()>
where T: Copy + MaybeSendSync + Add<Output = T> + Mul<Output = T> + Zero + One + PartialEq, F: Fn(T) -> T + MaybeSendSync,

dest = alpha * f(src) + beta * dest.

f is applied to the source element before scaling. When beta is zero (-0.0 included; NaN is not zero) the replay is write-only: the old destination element is never read, so a NaN-filled or uninitialized destination cannot contaminate the result, matching BLAS beta = 0 semantics. Otherwise the old destination element is read through the destination layout. Allocation-free for fused ranks at most RAW_FUSED_RANK_LIMIT.

§Errors

StridedError::PlanLayoutMismatch when the supplied views do not carry the compiled layout, before any write.

Source

pub fn execute_uninit<T, F>( &self, dest: &mut RawStridedMut<'_, MaybeUninit<T>>, src: &RawStridedRef<'_, T>, alpha: T, f: F, ) -> Result<()>
where T: Copy + MaybeSendSync + Mul<Output = T> + One + PartialEq, F: Fn(T) -> T + MaybeSendSync,

dest = alpha * f(src) into a potentially uninitialized destination.

This is execute with beta = 0: the destination is never read. On success every reachable logical destination element is initialized; non-reachable holes in the backing allocation are not written. Allocation-free for fused ranks at most RAW_FUSED_RANK_LIMIT.

§Errors

StridedError::PlanLayoutMismatch when the supplied views do not carry the compiled layout, before any write.

§Examples
use core::mem::MaybeUninit;
use strided_basic::{RawStridedMut, RawStridedRef, UpdatePlan};

let dims = [2usize, 2];
let strides = [1isize, 2];
let plan = UpdatePlan::compile(&dims, &strides, &strides).unwrap();
let src = [1.0f64, 2.0, 3.0, 4.0];
let mut storage = [MaybeUninit::<f64>::uninit(); 4];
let mut dst = RawStridedMut::new(&mut storage, &dims, &strides, 0).unwrap();
let source = RawStridedRef::new(&src, &dims, &strides, 0).unwrap();
// dst = 2 * src
plan.execute_uninit(&mut dst, &source, 2.0, |x| x).unwrap();
drop(dst);
// SAFETY: every reachable destination slot was initialized above.
let values: Vec<f64> = storage.iter().map(|v| unsafe { v.assume_init() }).collect();
assert_eq!(values, [2.0, 4.0, 6.0, 8.0]);

Trait Implementations§

Source§

impl Clone for UpdatePlan

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for UpdatePlan

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> MaybeSend for T

Source§

impl<T> MaybeSendSync for T

Source§

impl<T> MaybeSync for T

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.