@@ -10,6 +10,7 @@ import LinearAlgebra
1010import LinearAlgebra: tr, diag, triu, tril, Transpose, Adjoint, norm, opnorm, mul!, ldlt, BLAS, issymmetric, UniformScaling, dot, Symmetric
1111
1212export SparseMatrixMPI, MatrixMPI, VectorMPI, clear_plan_cache!, uniform_partition, repartition
13+ export VectorMPI_CPU, MatrixMPI_CPU, SparseMatrixMPI_CPU # Type aliases for CPU-backed types
1314export SparseMatrixCSR # Type alias for Transpose{SparseMatrixCSC} (CSR storage format)
1415export map_rows # Row-wise map over distributed vectors/matrices
1516export VectorMPI_local, MatrixMPI_local, SparseMatrixMPI_local # Local constructors
@@ -959,6 +960,141 @@ function map_rows(f, A...)
959960end
960961
961962
963+ # ============================================================================
964+ # Base.zeros for Distributed Types
965+ # ============================================================================
966+
967+ # Helper to create a zero array with the correct backend type
968+ # Base case: CPU arrays
969+ _zeros_like (:: Type{Vector{T}} , dims... ) where T = zeros (T, dims... )
970+ _zeros_like (:: Type{Matrix{T}} , dims... ) where T = zeros (T, dims... )
971+
972+ # For GPU arrays, extensions will define additional methods
973+
974+ """
975+ Base.zeros(::Type{VectorMPI{T,AV}}, n::Integer; comm=MPI.COMM_WORLD) where {T,AV}
976+
977+ Create a distributed zero vector of length `n` with element type `T` and storage type `AV`.
978+
979+ The vector is uniformly partitioned across MPI ranks.
980+
981+ # Examples
982+ ```julia
983+ # CPU zero vector
984+ v = zeros(VectorMPI{Float64,Vector{Float64}}, 100)
985+
986+ # Using type alias
987+ v = zeros(VectorMPI_CPU{Float64}, 100)
988+
989+ # GPU zero vector (requires Metal.jl loaded)
990+ using Metal
991+ v = zeros(VectorMPI{Float32,MtlVector{Float32}}, 100)
992+ ```
993+ """
994+ function Base. zeros (:: Type{VectorMPI{T,AV}} , n:: Integer ;
995+ comm:: MPI.Comm = MPI. COMM_WORLD) where {T,AV<: AbstractVector{T} }
996+ nranks = MPI. Comm_size (comm)
997+ rank = MPI. Comm_rank (comm)
998+
999+ partition = uniform_partition (n, nranks)
1000+ local_size = partition[rank + 2 ] - partition[rank + 1 ]
1001+
1002+ local_v = _zeros_like (AV, local_size)
1003+ hash = compute_partition_hash (partition)
1004+
1005+ return VectorMPI {T,AV} (hash, partition, local_v)
1006+ end
1007+
1008+ """
1009+ Base.zeros(::Type{MatrixMPI{T,AM}}, m::Integer, n::Integer; comm=MPI.COMM_WORLD) where {T,AM}
1010+
1011+ Create a distributed zero matrix of size `m × n` with element type `T` and storage type `AM`.
1012+
1013+ The matrix is row-partitioned across MPI ranks.
1014+
1015+ # Examples
1016+ ```julia
1017+ # CPU zero matrix
1018+ A = zeros(MatrixMPI{Float64,Matrix{Float64}}, 100, 50)
1019+
1020+ # Using type alias
1021+ A = zeros(MatrixMPI_CPU{Float64}, 100, 50)
1022+
1023+ # GPU zero matrix (requires Metal.jl loaded)
1024+ using Metal
1025+ A = zeros(MatrixMPI{Float32,MtlMatrix{Float32}}, 100, 50)
1026+ ```
1027+ """
1028+ function Base. zeros (:: Type{MatrixMPI{T,AM}} , m:: Integer , n:: Integer ;
1029+ comm:: MPI.Comm = MPI. COMM_WORLD) where {T,AM<: AbstractMatrix{T} }
1030+ nranks = MPI. Comm_size (comm)
1031+ rank = MPI. Comm_rank (comm)
1032+
1033+ row_partition = uniform_partition (m, nranks)
1034+ col_partition = uniform_partition (n, nranks) # Used for transpose operations
1035+ local_nrows = row_partition[rank + 2 ] - row_partition[rank + 1 ]
1036+
1037+ local_A = _zeros_like (AM, local_nrows, n)
1038+ # Structural hash computed lazily
1039+
1040+ return MatrixMPI {T,AM} (nothing , row_partition, col_partition, local_A)
1041+ end
1042+
1043+ """
1044+ Base.zeros(::Type{SparseMatrixMPI{T,Ti,AV}}, m::Integer, n::Integer; comm=MPI.COMM_WORLD) where {T,Ti,AV}
1045+
1046+ Create a distributed zero sparse matrix of size `m × n`.
1047+
1048+ A zero sparse matrix has no nonzero entries, so the resulting matrix has:
1049+ - Empty `rowptr` (all ones)
1050+ - Empty `colval` and `nzval`
1051+
1052+ # Examples
1053+ ```julia
1054+ # CPU zero sparse matrix
1055+ A = zeros(SparseMatrixMPI{Float64,Int,Vector{Float64}}, 100, 100)
1056+
1057+ # Using type alias
1058+ A = zeros(SparseMatrixMPI_CPU{Float64,Int}, 100, 100)
1059+ ```
1060+ """
1061+ function Base. zeros (:: Type{SparseMatrixMPI{T,Ti,AV}} , m:: Integer , n:: Integer ;
1062+ comm:: MPI.Comm = MPI. COMM_WORLD) where {T,Ti<: Integer ,AV<: AbstractVector{T} }
1063+ nranks = MPI. Comm_size (comm)
1064+ rank = MPI. Comm_rank (comm)
1065+
1066+ row_partition = uniform_partition (m, nranks)
1067+ col_partition = uniform_partition (n, nranks)
1068+ local_nrows = row_partition[rank + 2 ] - row_partition[rank + 1 ]
1069+
1070+ # Empty sparse structure
1071+ rowptr = ones (Ti, local_nrows + 1 ) # All rows have 0 entries
1072+ colval = Ti[]
1073+ nzval = _zeros_like (AV, 0 ) # Empty but correct type
1074+ col_indices = Int[] # No columns referenced
1075+
1076+ # For CPU, rowptr_target/colval_target are the same as rowptr/colval
1077+ # For GPU, they would be GPU copies (but empty arrays don't matter)
1078+ rowptr_target = rowptr
1079+ colval_target = colval
1080+
1081+ return SparseMatrixMPI {T,Ti,AV} (
1082+ nothing , # Hash computed lazily
1083+ row_partition,
1084+ col_partition,
1085+ col_indices,
1086+ rowptr,
1087+ colval,
1088+ nzval,
1089+ local_nrows,
1090+ 0 , # ncols_compressed = 0 (no columns referenced)
1091+ nothing , # cached_transpose
1092+ true , # cached_symmetric (zero matrix is symmetric)
1093+ rowptr_target,
1094+ colval_target
1095+ )
1096+ end
1097+
9621098# ============================================================================
9631099# Precompilation Workload
9641100# ============================================================================
0 commit comments