Skip to main content

strided_basic/
lib.rs

1#![doc = include_str!("../README.md")]
2
3//! Cache-optimized kernels for strided multidimensional array operations.
4//!
5//! This crate is a Rust port of Julia's [Strided.jl](https://github.com/Jutho/Strided.jl)
6//! and [StridedViews.jl](https://github.com/Jutho/StridedViews.jl) libraries, providing
7//! efficient operations on strided multidimensional array views.
8//!
9//! # Core Types
10//!
11//! - [`StridedView`] / [`StridedViewMut`]: Dynamic-rank strided views over existing data
12//! - [`StridedArray`]: Owned strided multidimensional array
13//! - [`ElementOp`] trait and implementations ([`Identity`], [`Conj`], [`Transpose`], [`Adjoint`]):
14//!   Type-level element operations applied lazily on access
15//! - [`Exec`] / [`Pool`]: the placement token every fan-out entry takes as its
16//!   last parameter (re-exported from `strided-exec`)
17//!
18//! # Primary API (view-based, Julia-compatible)
19//!
20//! ## Map Operations
21//!
22//! - [`map_into`]: Apply a function element-wise from source to destination
23//! - [`zip_map2_into`], [`zip_map3_into`], [`zip_map4_into`]: Multi-array element-wise operations
24//!
25//! ## In-place Update Operations
26//!
27//! - [`map_update_into`], [`zip_update2_into`], [`zip_update3_into`]: `dest[i] = f(dest[i], inputs...)`,
28//!   reading the old destination without a second view of it
29//!
30//! ## Reduce Operations
31//!
32//! - [`reduce`]: Full reduction with map function
33//! - [`zip_reduce`]: Two-input full reduction with a map function (the
34//!   widening route, e.g. `f32` operands accumulated in `f64`)
35//! - [`reduce_axis`]: Reduce along a single axis
36//!
37//! A reduction that can fan out (`reduce`, `zip_reduce`, `sum`) gives a result
38//! that is independent of the token's budget only for a serial token; `dot`
39//! never enters a parallel branch, so its result does not depend on the token at
40//! all. See each entry's evaluation-order section.
41//!
42//! # Threading
43//!
44//! Every operation that can fan out takes `exec: Exec<'_>` by value as its last
45//! parameter. [`Exec::serial`] runs on the calling thread; a token minted from a
46//! [`Pool`] with [`Exec::new`] splits the work within its budget. Operations
47//! below the repository threshold (`execution::MINTHREADLENGTH` elements) stay on
48//! the calling thread whatever the budget. Without the `parallel` feature every
49//! token runs inline.
50//!
51//! ## Basic Operations
52//!
53//! - [`copy_into`]: Copy array contents
54//! - [`add`], [`mul`]: Element-wise arithmetic
55//! - [`axpy`]: y = alpha*x + y (array version)
56//! - [`sum`], [`dot`]: Reductions
57//! - [`symmetrize_into`], [`symmetrize_conj_into`]: Matrix symmetrization
58//!
59//! # Example
60//!
61//! ```rust
62//! use strided_basic::{StridedView, StridedViewMut, StridedArray, Identity, Exec, map_into};
63//!
64//! // Create a column-major array (Julia default)
65//! let src = StridedArray::<f64>::from_fn_col_major(&[2, 3], |idx| {
66//!     (idx[0] * 10 + idx[1]) as f64
67//! });
68//! let mut dest = StridedArray::<f64>::col_major(&[2, 3]);
69//!
70//! // Map with view-based API
71//! map_into(&mut dest.view_mut(), &src.view(), |x| x * 2.0, Exec::serial()).unwrap();
72//! assert_eq!(dest.get(&[1, 2]), 24.0); // (1*10 + 2) * 2
73//! ```
74//!
75//! # Cache Optimization
76//!
77//! The library uses Julia's blocking strategy for cache efficiency:
78//! - Dimensions are sorted by stride magnitude for optimal memory access
79//! - Operations are blocked into tiles fitting L1 cache ([`BLOCK_MEMORY_SIZE`] = 32KB)
80//! - Contiguous arrays use fast paths bypassing the blocking machinery
81
82mod block;
83mod complex_div;
84mod copy_plan;
85mod dense_update;
86mod erased;
87mod erased_common;
88pub mod execution;
89mod fuse;
90mod inline;
91mod kernel;
92mod layout_check;
93mod map_view;
94mod nan_select;
95mod ops_view;
96mod order;
97mod raw_ops;
98mod reduce_view;
99mod simd;
100mod threading;
101mod update_view;
102pub use complex_div::{robust_complex_divide_f32, robust_complex_divide_f64};
103pub use copy_plan::{CopyPlan, UpdatePlan};
104pub use dense_update::{
105    axpby_accum, embed_diagonal_into_uninit, embed_diagonal_view_into_uninit,
106    triangular_mask_into_uninit, triangular_mask_view_into_uninit,
107};
108pub use erased::{
109    ArgReduceOp, ErasedArgReducePlan, ErasedConcatenatePlan, ErasedCopyPlan, ErasedNormPlan,
110    ErasedReducePlan, ErasedScanPlan, ErasedUpdatePlan, NormKind, NormSpec, ReduceOp, ScanOp,
111    ScanOptions, UpdateOp,
112};
113pub use inline::{InlineVec, OperandVec, OPERAND_CAP};
114pub use map_view::{
115    broadcast_mul_into, broadcast_mul_into_uninit, compare_into, compare_into_uninit, map_into,
116    map_into_uninit_with_kernel, mul_into, mul_into_uninit, zip_map2_into, zip_map3_into,
117    zip_map4_into, CompareOp,
118};
119pub use nan_select::{nan_propagating_maximum, nan_propagating_minimum};
120pub use ops_view::{
121    add, axpy, copy_conj, copy_into, copy_into_col_major, copy_into_uninit, copy_scale,
122    copy_transpose_scale_into, dot, fma, mul, sum, symmetrize_conj_into, symmetrize_into,
123};
124pub use raw_ops::{
125    axpy_conj_raw, axpy_raw, copy_scale_conj_raw, copy_scale_raw, RAW_FUSED_RANK_LIMIT,
126};
127pub use reduce_view::{reduce, reduce_axis, reduce_axis_into, zip_reduce};
128pub use simd::MaybeSimdOps;
129pub use strided_exec::{Exec, Pool, PoolBuilder};
130pub use strided_view::view;
131pub use strided_view::*;
132pub use update_view::{map_update_into, zip_update2_into, zip_update3_into};
133/// Block memory size for cache-optimized iteration (L1 cache target).
134///
135/// Operations are blocked into tiles that fit within this size to maximize cache hits.
136/// Default: 32KB (typical L1 data cache size).
137pub const BLOCK_MEMORY_SIZE: usize = 32 * 1024;
138
139/// Cache line size in bytes.
140///
141/// Used for memory region calculations in block size computation.
142pub const CACHE_LINE_SIZE: usize = 64;
143
144mod gather_plan;
145mod outer_product;
146mod static_indexing_plan;
147pub use gather_plan::{
148    DynamicSlicePlan, DynamicUpdateSlicePlan, GatherIndex, GatherPlan, GatherSpec, ScatterPlan,
149    ScatterSpec,
150};
151pub use outer_product::{
152    batched_outer_product_into, batched_outer_product_into_uninit, plan_lazy_outer_product,
153    LazyOuterProductLayout,
154};
155pub use static_indexing_plan::{ConcatenatePlan, PadPlan, ReversePlan, SlicePlan};