@@ -22,8 +22,8 @@ mpiexec -n 4 julia --project=. test/test_local_constructors.jl
2222mpiexec -n 4 julia --project=. test/test_indexing.jl
2323mpiexec -n 4 julia --project=. test/test_factorization.jl
2424
25- # Run GPU tests (requires Metal.jl on macOS)
26- mpiexec -n 2 julia --project=. test/test_gpu.jl
25+ # GPU tests run automatically when Metal.jl is available
26+ # Tests are parameterized over (scalar type, backend) configurations
2727
2828# Precompile the package
2929julia --project=. -e ' using Pkg; Pkg.precompile()'
@@ -37,7 +37,8 @@ GPU acceleration is supported via Metal.jl (macOS) as a package extension.
3737
3838- ` VectorMPI{T,AV} ` where ` AV ` is ` Vector{T} ` (CPU) or ` MtlVector{T} ` (GPU)
3939- ` MatrixMPI{T,AM} ` where ` AM ` is ` Matrix{T} ` (CPU) or ` MtlMatrix{T} ` (GPU)
40- - Type aliases: ` VectorMPI_CPU{T} ` , ` MatrixMPI_CPU{T} ` for CPU-backed types
40+ - ` SparseMatrixMPI{T,Ti,AV} ` where ` AV ` is ` Vector{T} ` (CPU) or ` MtlVector{T} ` (GPU) for the ` nzval ` array
41+ - Type aliases: ` VectorMPI_CPU{T} ` , ` MatrixMPI_CPU{T} ` , ` SparseMatrixMPI_CPU{T,Ti} ` for CPU-backed types
4142
4243### CPU Staging
4344
@@ -88,18 +89,21 @@ Many operations in this module are collective and should not be run on a subset
8889- ` SparseMatrixCSC(A::SparseMatrixCSR) ` converts CSR to CSC representing the ** same** matrix
8990- For ` B = SparseMatrixCSR(A) ` , ` B[i,j] == A[i,j] ` (same matrix, different storage)
9091
91- ** SparseMatrixMPI{T}**
92+ ** SparseMatrixMPI{T,Ti,AV }**
9293- Rows are partitioned across MPI ranks
93- - ` A::SparseMatrixCSR{T,Int} ` : Local rows in CSR format for efficient row-wise iteration
94- - ` A.parent ` is the underlying CSC storage with shape ` (length(col_indices), local_nrows) `
95- - ` A.parent.colptr ` acts as row pointers for the CSR format
96- - ` A.parent.rowval ` contains LOCAL column indices (1: length (col_indices)), not global
97- - Storage is ** compressed** to avoid hypersparse issues
94+ - Type parameters: ` T ` = element type, ` Ti ` = index type, ` AV ` = array type for values (` Vector{T} ` or ` MtlVector{T} ` )
95+ - Local rows stored in CSR-like format with separate arrays:
96+ - ` rowptr::Vector{Ti} ` - row pointers (always CPU)
97+ - ` colval::Vector{Ti} ` - LOCAL column indices (1: ncols_compressed , always CPU)
98+ - ` nzval::AV ` - nonzero values (can be CPU or GPU)
99+ - ` nrows_local::Int ` - number of local rows
100+ - ` ncols_compressed::Int ` - = length(col_indices)
98101- ` row_partition ` : Array of size ` nranks + 1 ` defining which rows each rank owns (1-indexed boundaries)
99102- ` col_partition ` : Array of size ` nranks + 1 ` defining column partition (used for transpose operations)
100103- ` col_indices ` : Sorted global column indices that appear in the local part (local→global mapping)
101104- ` structural_hash ` : Optional Blake3 hash of the matrix structure (computed lazily via ` _ensure_hash ` )
102105- ` cached_transpose ` : Cached materialized transpose (invalidated on modification)
106+ - ` cached_symmetric ` : Cached result of ` issymmetric ` check
103107
104108** MatrixMPI{T,AM}**
105109- Distributed dense matrix partitioned by rows across MPI ranks
@@ -139,9 +143,11 @@ Many operations in this module are collective and should not be run on a subset
139143
140144Factorization uses MUMPS (MUltifrontal Massively Parallel Solver) with distributed matrix input (ICNTL(18)=3).
141145
142- ** MUMPSFactorizationMPI{T }** (internal type, not exported)
146+ ** MUMPSFactorizationMPI{Tin, AVin, Tinternal }** (internal type, not exported)
143147- Wraps a MUMPS object for distributed factorization
148+ - Type parameters: ` Tin ` = input element type, ` AVin ` = input array type, ` Tinternal ` = MUMPS-compatible type (Float64 or ComplexF64)
144149- Created by ` lu(A) ` for general matrices or ` ldlt(A) ` for symmetric matrices
150+ - Automatically converts input to MUMPS-compatible types and back (e.g., Float32 GPU → Float64 CPU → solve → Float32 GPU)
145151- Stores COO arrays (irn_loc, jcn_loc, a_loc) to prevent GC while MUMPS holds pointers
146152
147153``` julia
@@ -179,7 +185,7 @@ For `y = A * x` where `A::SparseMatrixMPI` and `x::VectorMPI`:
179185
1801861 . ** Plan creation** (` VectorPlan ` constructor): Uses ` Alltoall ` to exchange element request counts, then point-to-point to exchange indices
1811872 . ** Value exchange** (` execute_plan! ` ): Point-to-point ` Isend ` /` Irecv ` to gather ` x[A.col_indices] ` into a local ` gathered ` vector
182- 3 . ** Local computation** : Compute ` transpose(A.A.parent) * gathered ` (A.A.parent already uses local indices)
188+ 3 . ** Local computation** : Compute ` transpose(_get_csc(A)) * gathered ` where ` _get_csc(A) ` reconstructs a SparseMatrixCSC from the internal CSR arrays
1831894 . ** Result construction** : Result vector ` y ` inherits ` A.row_partition `
184190
185191Note: Uses ` transpose() ` (not adjoint ` ' ` ) to correctly handle complex values without conjugation.
@@ -195,7 +201,7 @@ Note: Uses `transpose()` (not adjoint `'`) to correctly handle complex values wi
195201
196202### Lazy Transpose
197203
198- ` transpose(A) ` returns ` Transpose{T, SparseMatrixMPI{T}} ` (lazy wrapper). Materialization happens automatically when needed:
204+ ` transpose(A) ` returns ` Transpose{T, SparseMatrixMPI{T,Ti,AV }} ` (lazy wrapper). Materialization happens automatically when needed:
199205- ` transpose(A) * transpose(B) ` → ` transpose(B * A) ` (stays lazy)
200206- ` transpose(A) * B ` or ` A * transpose(B) ` → materializes via ` TransposePlan `
201207- ` SparseMatrixMPI(transpose(A)) ` → explicitly materialize the transpose (cached bidirectionally)
0 commit comments