pub struct ErasedScanPlan { /* private fields */ }Expand description
Dtype-erased cumulative scan (cumsum / cumprod) along one axis.
The destination has the source dimensions; source and destination strides
are independent, and negative strides and offsets are accepted. Supported
dtypes are f32, f64, i32, i64, c32 and c64; bool is rejected.
§Evaluation order
Every output is the sequential left fold of its inputs in scan order (from the start of the axis, or from its end for a reverse scan), with no reassociation. The result is therefore bitwise identical for every layout, execution context and thread count. Integer scans wrap on overflow.
An empty axis or an empty set of lines writes nothing.
§Examples
use strided_basic::{
ErasedRawStridedMut, ErasedRawStridedRef, ErasedScanPlan, ExecContext, KernelDType,
ScanOp, ScanOptions,
};
// A column-major 3 x 2 matrix, scanned along axis 0.
let src = [1.0_f64, 2.0, 3.0, 10.0, 20.0, 30.0];
let mut out = [0.0_f64; 6];
let plan = ErasedScanPlan::compile(
KernelDType::F64,
ScanOp::Sum,
&[3, 2],
&[1, 3],
&[1, 3],
0,
ScanOptions::new(),
)
.unwrap();
let src_ref = ErasedRawStridedRef::from_slice(&src, &[3, 2], &[1, 3], 0).unwrap();
let mut dest = ErasedRawStridedMut::from_slice_mut(&mut out, &[3, 2], &[1, 3], 0).unwrap();
plan.execute(&ExecContext::serial(), &mut dest, &src_ref).unwrap();
assert_eq!(out, [1.0, 3.0, 6.0, 10.0, 30.0, 60.0]);Implementations§
Source§impl ErasedScanPlan
impl ErasedScanPlan
Sourcepub fn compile(
dtype: KernelDType,
op: ScanOp,
dims: &[usize],
src_strides: &[isize],
dest_strides: &[isize],
axis: usize,
options: ScanOptions,
) -> Result<Self>
pub fn compile( dtype: KernelDType, op: ScanOp, dims: &[usize], src_strides: &[isize], dest_strides: &[isize], axis: usize, options: ScanOptions, ) -> Result<Self>
Validate and store a scan plan for one dtype and fixed layouts.
dims are the shared source and destination dimensions; axis is the
scanned axis.
§Examples
use strided_basic::{ErasedScanPlan, KernelDType, ScanOp, ScanOptions};
let plan = ErasedScanPlan::compile(
KernelDType::I64, ScanOp::Product, &[4], &[1], &[-1], 0, ScanOptions::new(),
)
.unwrap();
assert_eq!(plan.op(), ScanOp::Product);
assert!(ErasedScanPlan::compile(
KernelDType::Bool, ScanOp::Sum, &[4], &[1], &[1], 0, ScanOptions::new(),
)
.is_err());§Errors
Returns UnsupportedDType for bool, InvalidAxis for an axis out of
range, StrideLengthMismatch for inconsistent ranks,
NonInjectiveOutputLayout for an aliasing destination layout, and
OffsetOverflow when a layout’s offsets are not representable.
Sourcepub fn dtype(&self) -> KernelDType
pub fn dtype(&self) -> KernelDType
Element dtype of the source and destination.
§Examples
use strided_basic::{ErasedScanPlan, KernelDType, ScanOp, ScanOptions};
let plan = ErasedScanPlan::compile(
KernelDType::F32, ScanOp::Sum, &[2], &[1], &[1], 0, ScanOptions::new(),
)
.unwrap();
assert_eq!(plan.dtype(), KernelDType::F32);Sourcepub fn op(&self) -> ScanOp
pub fn op(&self) -> ScanOp
Scan operation.
§Examples
use strided_basic::{ErasedScanPlan, KernelDType, ScanOp, ScanOptions};
let plan = ErasedScanPlan::compile(
KernelDType::F32, ScanOp::Sum, &[2], &[1], &[1], 0, ScanOptions::new(),
)
.unwrap();
assert_eq!(plan.op(), ScanOp::Sum);Sourcepub fn options(&self) -> ScanOptions
pub fn options(&self) -> ScanOptions
Direction and inclusivity.
§Examples
use strided_basic::{ErasedScanPlan, KernelDType, ScanOp, ScanOptions};
let options = ScanOptions::new().reverse(true);
let plan =
ErasedScanPlan::compile(KernelDType::F32, ScanOp::Sum, &[2], &[1], &[1], 0, options)
.unwrap();
assert_eq!(plan.options(), options);Sourcepub fn execute(
&self,
ctx: &ExecContext,
dest: &mut ErasedRawStridedMut<'_>,
src: &ErasedRawStridedRef<'_>,
) -> Result<()>
pub fn execute( &self, ctx: &ExecContext, dest: &mut ErasedRawStridedMut<'_>, src: &ErasedRawStridedRef<'_>, ) -> Result<()>
Execute the scan into an initialized destination.
§Examples
use strided_basic::{
ErasedRawStridedMut, ErasedRawStridedRef, ErasedScanPlan, ExecContext, KernelDType,
ScanOp, ScanOptions,
};
let src = [1_i32, 2, 3, 4];
let mut out = [0_i32; 4];
let options = ScanOptions::new().exclusive(true).reverse(true);
let plan =
ErasedScanPlan::compile(KernelDType::I32, ScanOp::Sum, &[4], &[1], &[1], 0, options)
.unwrap();
let src_ref = ErasedRawStridedRef::from_slice(&src, &[4], &[1], 0).unwrap();
let mut dest = ErasedRawStridedMut::from_slice_mut(&mut out, &[4], &[1], 0).unwrap();
plan.execute(&ExecContext::serial(), &mut dest, &src_ref).unwrap();
assert_eq!(out, [9, 7, 4, 0]);§Errors
Returns DTypeMismatch or PlanLayoutMismatch when a descriptor does
not match the plan, before any destination write.
Sourcepub fn execute_uninit(
&self,
ctx: &ExecContext,
dest: &mut ErasedRawStridedUninitMut<'_>,
src: &ErasedRawStridedPtr<'_>,
) -> Result<()>
pub fn execute_uninit( &self, ctx: &ExecContext, dest: &mut ErasedRawStridedUninitMut<'_>, src: &ErasedRawStridedPtr<'_>, ) -> Result<()>
Execute the scan into an uninitialized destination.
On success every reachable destination element is written; validation errors are returned before any write.
§Examples
use core::mem::MaybeUninit;
use strided_basic::{
ErasedRawStridedPtr, ErasedRawStridedRef, ErasedRawStridedUninitMut, ErasedScanPlan,
ExecContext, KernelDType, ScanOp, ScanOptions,
};
let src = [2.0_f32, 3.0, 4.0];
let mut out = [MaybeUninit::<f32>::uninit(); 3];
let plan = ErasedScanPlan::compile(
KernelDType::F32, ScanOp::Product, &[3], &[1], &[1], 0, ScanOptions::new(),
)
.unwrap();
let src_ref = ErasedRawStridedRef::from_slice(&src, &[3], &[1], 0).unwrap();
let src_ptr = ErasedRawStridedPtr::from_ref(&src_ref);
let mut dest =
ErasedRawStridedUninitMut::from_uninit_slice(&mut out, &[3], &[1], 0).unwrap();
plan.execute_uninit(&ExecContext::serial(), &mut dest, &src_ptr).unwrap();
let out: Vec<f32> = out.iter().map(|v| unsafe { v.assume_init() }).collect();
assert_eq!(out, [2.0, 6.0, 24.0]);§Errors
As Self::execute, plus OverlappingInputOutput when the source
overlaps the destination allocation.