strided_kernel/lib.rs
1//! Cache-optimized kernels for strided multidimensional array operations.
2//!
3//! This crate is a Rust port of Julia's [Strided.jl](https://github.com/Jutho/Strided.jl)
4//! and [StridedViews.jl](https://github.com/Jutho/StridedViews.jl) libraries, providing
5//! efficient operations on strided multidimensional array views.
6//!
7//! # Core Types
8//!
9//! - [`StridedView`] / [`StridedViewMut`]: Dynamic-rank strided views over existing data
10//! - [`StridedArray`]: Owned strided multidimensional array
11//! - [`ElementOp`] trait and implementations ([`Identity`], [`Conj`], [`Transpose`], [`Adjoint`]):
12//! Type-level element operations applied lazily on access
13//! - [`ExecutionPolicy`] / [`with_execution_policy`]: optional bounds on
14//! strided-owned CPU fanout without creating a Rayon pool
15//!
16//! # Primary API (view-based, Julia-compatible)
17//!
18//! ## Map Operations
19//!
20//! - [`map_into`]: Apply a function element-wise from source to destination
21//! - [`zip_map2_into`], [`zip_map3_into`], [`zip_map4_into`]: Multi-array element-wise operations
22//!
23//! ## Reduce Operations
24//!
25//! - [`reduce`]: Full reduction with map function
26//! - [`reduce_axis`]: Reduce along a single axis
27//!
28//! ## Basic Operations
29//!
30//! - [`copy_into`]: Copy array contents
31//! - [`add`], [`mul`]: Element-wise arithmetic
32//! - [`axpy`]: y = alpha*x + y (array version)
33//! - [`sum`], [`dot`]: Reductions
34//! - [`symmetrize_into`], [`symmetrize_conj_into`]: Matrix symmetrization
35//!
36//! # Example
37//!
38//! ```rust
39//! use strided_kernel::{StridedView, StridedViewMut, StridedArray, Identity, map_into};
40//!
41//! // Create a column-major array (Julia default)
42//! let src = StridedArray::<f64>::from_fn_col_major(&[2, 3], |idx| {
43//! (idx[0] * 10 + idx[1]) as f64
44//! });
45//! let mut dest = StridedArray::<f64>::col_major(&[2, 3]);
46//!
47//! // Map with view-based API
48//! map_into(&mut dest.view_mut(), &src.view(), |x| x * 2.0).unwrap();
49//! assert_eq!(dest.get(&[1, 2]), 24.0); // (1*10 + 2) * 2
50//! ```
51//!
52//! # Cache Optimization
53//!
54//! The library uses Julia's blocking strategy for cache efficiency:
55//! - Dimensions are sorted by stride magnitude for optimal memory access
56//! - Operations are blocked into tiles fitting L1 cache ([`BLOCK_MEMORY_SIZE`] = 32KB)
57//! - Contiguous arrays use fast paths bypassing the blocking machinery
58
59mod block;
60mod execution_policy;
61mod fuse;
62mod fused;
63mod gather_plan;
64mod kernel;
65mod order;
66mod simd;
67mod static_indexing_plan;
68mod threading;
69
70mod maybe_sync;
71pub use execution_policy::{with_execution_policy, ExecutionPolicy};
72pub use maybe_sync::{MaybeSend, MaybeSendSync, MaybeSync};
73
74// View-based operation modules
75mod copy_plan;
76mod erased;
77mod exec_context;
78mod map_view;
79mod ops_view;
80mod outer_product;
81mod raw_ops;
82mod reduce_view;
83
84// ============================================================================
85// Re-exports from strided_view for backward compatibility
86// ============================================================================
87pub use strided_view::view;
88pub use strided_view::{
89 col_major_strides, row_major_strides, Adjoint, ComposableElementOp, Compose, Conj, ElementOp,
90 ElementOpApply, ErasedRawStridedMut, ErasedRawStridedPtr, ErasedRawStridedRef,
91 ErasedRawStridedUninitMut, Identity, KernelDType, KernelStorageElement, RawStridedMut,
92 RawStridedRef, Result, StridedArray, StridedError, StridedView, StridedViewMut, Transpose,
93};
94
95// ============================================================================
96// Map operations
97// ============================================================================
98pub use map_view::{
99 broadcast_mul_into, broadcast_mul_into_uninit, compare_into, compare_into_uninit, map_into,
100 mul_into, mul_into_uninit, zip_map2_into, zip_map3_into, zip_map4_into, CompareOp,
101};
102
103// ============================================================================
104// Runtime-DAG fused elementwise operations
105// ============================================================================
106pub use fused::{fused_elementwise_into, FusedInst, FusedOp, FusedPlan, FusedScalar};
107
108// ============================================================================
109// Outer-product operations
110// ============================================================================
111pub use outer_product::{batched_outer_product_into, batched_outer_product_into_uninit};
112
113// ============================================================================
114// High-level operations
115// ============================================================================
116pub use ops_view::{
117 add, axpy, copy_conj, copy_into, copy_into_col_major, copy_scale, copy_transpose_scale_into,
118 dot, fma, mul, sum, symmetrize_conj_into, symmetrize_into,
119};
120
121// ============================================================================
122// Raw (borrowed-metadata, allocation-free) operations
123// ============================================================================
124pub use raw_ops::{
125 axpy_conj_raw, axpy_raw, copy_scale_conj_raw, copy_scale_raw, RAW_FUSED_RANK_LIMIT,
126};
127
128// ============================================================================
129// Prepared (compile-once, execute-many) plans
130// ============================================================================
131pub use copy_plan::CopyPlan;
132pub use erased::{
133 erased_map_into, erased_zip_into, ErasedConcatenatePlan, ErasedCopyPlan,
134 ErasedDynamicSlicePlan, ErasedDynamicUpdateSlicePlan, ErasedFusedPlan, ErasedGatherPlan,
135 ErasedMapOp, ErasedPadPlan, ErasedReducePlan, ErasedReversePlan, ErasedScatterPlan,
136 ErasedSlicePlan, ErasedZipOp, ReduceOp,
137};
138pub use exec_context::ExecContext;
139pub use gather_plan::{
140 DynamicSlicePlan, DynamicUpdateSlicePlan, GatherIndex, GatherPlan, GatherSpec, ScatterPlan,
141 ScatterSpec,
142};
143pub use static_indexing_plan::{ConcatenatePlan, PadPlan, ReversePlan, SlicePlan};
144
145// ============================================================================
146// Reduce operations
147// ============================================================================
148pub use reduce_view::{reduce, reduce_axis};
149
150// ============================================================================
151// SIMD trait
152// ============================================================================
153pub use simd::MaybeSimdOps;
154
155// ============================================================================
156// Constants
157// ============================================================================
158
159/// Block memory size for cache-optimized iteration (L1 cache target).
160///
161/// Operations are blocked into tiles that fit within this size to maximize cache hits.
162/// Default: 32KB (typical L1 data cache size).
163pub const BLOCK_MEMORY_SIZE: usize = 32 * 1024;
164
165/// Cache line size in bytes.
166///
167/// Used for memory region calculations in block size computation.
168pub const CACHE_LINE_SIZE: usize = 64;