Skip to main content

scirs2_linalg/distrib_algorithms/
mod.rs

1//! Communication-avoiding distributed dense linear algebra algorithms.
2//!
3//! This module provides implementations of ScaLAPACK-style distributed algorithms
4//! for dense linear algebra, including:
5//!
6//! - **SUMMA**: Scalable Universal Matrix Multiply Algorithm with 2D block-cyclic layout
7//! - **CAQR**: Communication-Avoiding QR via Householder with tournament tree reduction
8//! - **Distributed Lanczos SVD**: Randomized Lanczos bidiagonalization with thick restart
9//!
10//! All algorithms operate in a *simulation mode*: a single process models all virtual
11//! processors in the grid, making these implementations useful for algorithm validation,
12//! cost-model analysis, and portability testing without requiring an actual MPI cluster.
13//!
14//! # References
15//!
16//! - Van De Geijn & Watts (1997): *SUMMA: Scalable Universal Matrix Multiply Algorithm*
17//! - Demmel et al. (2012): *Communication-optimal parallel and sequential QR and LU factorizations*
18//! - Larsen (1998): *Lanczos bidiagonalization with partial reorthogonalization*
19
20pub mod gemm;
21pub mod qr;
22pub mod svd;
23
24pub use gemm::{distributed_gemm_simulate, BlockCyclicMatrix, CommCost};
25pub use qr::{caqr_simulate, HouseholderReflector};
26pub use svd::{distributed_svd_simulate, thick_restart_lanczos, LanczosSvdConfig};
27
28use crate::error::LinalgResult;
29use scirs2_core::ndarray::Array2;
30
31/// Configuration for distributed linear algebra operations.
32///
33/// Controls block size and virtual processor grid dimensions used
34/// by SUMMA and CAQR simulations.
35#[derive(Debug, Clone)]
36pub struct DistribConfig {
37    /// Tile / block size (rows and columns) used for data partitioning.
38    pub block_size: usize,
39    /// Number of virtual processor rows in the 2-D process grid.
40    pub n_proc_rows: usize,
41    /// Number of virtual processor columns in the 2-D process grid.
42    pub n_proc_cols: usize,
43}
44
45impl Default for DistribConfig {
46    fn default() -> Self {
47        Self {
48            block_size: 64,
49            n_proc_rows: 2,
50            n_proc_cols: 2,
51        }
52    }
53}
54
55/// Trait for distributed dense linear algebra operations.
56///
57/// Implementors provide distributed GEMM, QR, and SVD that mirror the
58/// interface expected by ScaLAPACK-style driver routines.
59pub trait DistributedLinearAlgebra {
60    /// Distributed general matrix multiply: `C = A * B`.
61    ///
62    /// # Arguments
63    ///
64    /// * `a` - Left operand matrix (m × k)
65    /// * `b` - Right operand matrix (k × n)
66    /// * `config` - Distribution configuration
67    ///
68    /// # Returns
69    ///
70    /// Result matrix C (m × n)
71    fn distributed_gemm(
72        a: &Array2<f64>,
73        b: &Array2<f64>,
74        config: &DistribConfig,
75    ) -> LinalgResult<Array2<f64>>;
76
77    /// Distributed QR decomposition: `A = Q * R`.
78    ///
79    /// Uses communication-avoiding Householder QR with binary-tree tournament
80    /// reduction to achieve O(log P) communication rounds.
81    ///
82    /// # Returns
83    ///
84    /// Tuple `(Q, R)` where `Q` is orthogonal and `R` is upper triangular.
85    fn distributed_qr(
86        a: &Array2<f64>,
87        config: &DistribConfig,
88    ) -> LinalgResult<(Array2<f64>, Array2<f64>)>;
89
90    /// Distributed truncated SVD via Lanczos bidiagonalization.
91    ///
92    /// Returns the top-`k` singular triplets of `A`.
93    ///
94    /// # Returns
95    ///
96    /// Tuple `(U_k, sigma_k, V_k)` where `sigma_k` are the largest `k` singular
97    /// values in descending order.
98    fn distributed_svd(
99        a: &Array2<f64>,
100        k: usize,
101    ) -> LinalgResult<(Array2<f64>, Vec<f64>, Array2<f64>)>;
102}
103
104/// Concrete implementation that delegates to simulation functions in sub-modules.
105pub struct SimulatedDistributed;
106
107impl DistributedLinearAlgebra for SimulatedDistributed {
108    fn distributed_gemm(
109        a: &Array2<f64>,
110        b: &Array2<f64>,
111        config: &DistribConfig,
112    ) -> LinalgResult<Array2<f64>> {
113        distributed_gemm_simulate(a, b, config)
114    }
115
116    fn distributed_qr(
117        a: &Array2<f64>,
118        config: &DistribConfig,
119    ) -> LinalgResult<(Array2<f64>, Array2<f64>)> {
120        caqr_simulate(a, config)
121    }
122
123    fn distributed_svd(
124        a: &Array2<f64>,
125        k: usize,
126    ) -> LinalgResult<(Array2<f64>, Vec<f64>, Array2<f64>)> {
127        distributed_svd_simulate(a, k)
128    }
129}