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//! - [`ExecutionPolicy`] / [`with_execution_policy`]: optional bounds on
16//! strided-owned CPU fanout without creating a Rayon pool
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 ambient pool width only under the sequential
39//! policy; `dot` never enters a parallel branch, so its result does not depend
40//! on the pool at all. See each entry's evaluation-order section.
41//!
42//! ## Basic Operations
43//!
44//! - [`copy_into`]: Copy array contents
45//! - [`add`], [`mul`]: Element-wise arithmetic
46//! - [`axpy`]: y = alpha*x + y (array version)
47//! - [`sum`], [`dot`]: Reductions
48//! - [`symmetrize_into`], [`symmetrize_conj_into`]: Matrix symmetrization
49//!
50//! # Example
51//!
52//! ```rust
53//! use strided_basic::{StridedView, StridedViewMut, StridedArray, Identity, map_into};
54//!
55//! // Create a column-major array (Julia default)
56//! let src = StridedArray::<f64>::from_fn_col_major(&[2, 3], |idx| {
57//! (idx[0] * 10 + idx[1]) as f64
58//! });
59//! let mut dest = StridedArray::<f64>::col_major(&[2, 3]);
60//!
61//! // Map with view-based API
62//! map_into(&mut dest.view_mut(), &src.view(), |x| x * 2.0).unwrap();
63//! assert_eq!(dest.get(&[1, 2]), 24.0); // (1*10 + 2) * 2
64//! ```
65//!
66//! # Cache Optimization
67//!
68//! The library uses Julia's blocking strategy for cache efficiency:
69//! - Dimensions are sorted by stride magnitude for optimal memory access
70//! - Operations are blocked into tiles fitting L1 cache ([`BLOCK_MEMORY_SIZE`] = 32KB)
71//! - Contiguous arrays use fast paths bypassing the blocking machinery
72
73mod block;
74mod complex_div;
75mod copy_plan;
76mod dense_update;
77mod erased;
78mod erased_common;
79mod exec_context;
80pub mod execution;
81mod execution_policy;
82mod fuse;
83mod inline;
84mod kernel;
85mod layout_check;
86mod map_view;
87mod maybe_sync;
88mod nan_select;
89mod ops_view;
90mod order;
91mod raw_ops;
92mod reduce_view;
93mod simd;
94mod threading;
95mod update_view;
96pub use complex_div::{robust_complex_divide_f32, robust_complex_divide_f64};
97pub use copy_plan::{CopyPlan, UpdatePlan};
98pub use dense_update::{axpby_accum, embed_diagonal_into_uninit, triangular_mask_into_uninit};
99pub use erased::{
100 ArgReduceOp, ErasedArgReducePlan, ErasedConcatenatePlan, ErasedCopyPlan, ErasedNormPlan,
101 ErasedReducePlan, ErasedScanPlan, ErasedUpdatePlan, NormKind, NormSpec, ReduceOp, ScanOp,
102 ScanOptions, UpdateOp,
103};
104#[cfg(feature = "parallel")]
105pub use exec_context::with_execution_pool;
106pub use exec_context::ExecContext;
107pub use execution_policy::{with_execution_policy, ExecutionPolicy};
108pub use inline::{InlineVec, OperandVec, OPERAND_CAP};
109pub use map_view::{
110 broadcast_mul_into, broadcast_mul_into_uninit, compare_into, compare_into_uninit, map_into,
111 map_into_uninit_with_kernel, mul_into, mul_into_uninit, zip_map2_into, zip_map3_into,
112 zip_map4_into, CompareOp,
113};
114pub use maybe_sync::{MaybeSend, MaybeSendSync, MaybeSync};
115pub use nan_select::{nan_propagating_maximum, nan_propagating_minimum};
116pub use ops_view::{
117 add, axpy, copy_conj, copy_into, copy_into_col_major, copy_into_uninit, copy_scale,
118 copy_transpose_scale_into, dot, fma, mul, sum, symmetrize_conj_into, symmetrize_into,
119};
120pub use raw_ops::{
121 axpy_conj_raw, axpy_raw, copy_scale_conj_raw, copy_scale_raw, RAW_FUSED_RANK_LIMIT,
122};
123pub use reduce_view::{reduce, reduce_axis, reduce_axis_into, zip_reduce};
124pub use simd::MaybeSimdOps;
125pub use strided_view::view;
126pub use strided_view::*;
127pub use update_view::{map_update_into, zip_update2_into, zip_update3_into};
128/// Block memory size for cache-optimized iteration (L1 cache target).
129///
130/// Operations are blocked into tiles that fit within this size to maximize cache hits.
131/// Default: 32KB (typical L1 data cache size).
132pub const BLOCK_MEMORY_SIZE: usize = 32 * 1024;
133
134/// Cache line size in bytes.
135///
136/// Used for memory region calculations in block size computation.
137pub const CACHE_LINE_SIZE: usize = 64;
138
139mod gather_plan;
140mod outer_product;
141mod static_indexing_plan;
142pub use gather_plan::{
143 DynamicSlicePlan, DynamicUpdateSlicePlan, GatherIndex, GatherPlan, GatherSpec, ScatterPlan,
144 ScatterSpec,
145};
146pub use outer_product::{
147 batched_outer_product_into, batched_outer_product_into_uninit, plan_lazy_outer_product,
148 LazyOuterProductLayout,
149};
150pub use static_indexing_plan::{ConcatenatePlan, PadPlan, ReversePlan, SlicePlan};