Skip to content

Commit

Permalink
[SparseArrays] similar on sparse matrix returned uninitialized space (#…
Browse files Browse the repository at this point in the history
…40444)

Co-authored-by: Klaus Crusius <klaus.crusius@web.de>
  • Loading branch information
vtjnash and KlausC authored Apr 19, 2021
1 parent 671bccb commit 28a3312
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 26 deletions.
12 changes: 6 additions & 6 deletions stdlib/SparseArrays/src/sparsematrix.jl
Original file line number Diff line number Diff line change
Expand Up @@ -469,17 +469,17 @@ function _sparsesimilar(S::AbstractSparseMatrixCSC, ::Type{TvNew}, ::Type{TiNew}
newrowval = copyto!(similar(rowvals(S), TiNew), rowvals(S))
return SparseMatrixCSC(size(S, 1), size(S, 2), newcolptr, newrowval, similar(nonzeros(S), TvNew))
end
# parent methods for similar that preserves only storage space (for when new and old dims differ)
# parent methods for similar that preserves only storage space (for when new dims are 2-d)
_sparsesimilar(S::AbstractSparseMatrixCSC, ::Type{TvNew}, ::Type{TiNew}, dims::Dims{2}) where {TvNew,TiNew} =
SparseMatrixCSC(dims..., fill(one(TiNew), last(dims)+1), similar(rowvals(S), TiNew), similar(nonzeros(S), TvNew))
# parent method for similar that allocates an empty sparse vector (when new dims are single)
SparseMatrixCSC(dims..., fill(one(TiNew), last(dims)+1), similar(rowvals(S), TiNew, 0), similar(nonzeros(S), TvNew, 0))
# parent method for similar that allocates an empty sparse vector (for when new dims are 1-d)
_sparsesimilar(S::AbstractSparseMatrixCSC, ::Type{TvNew}, ::Type{TiNew}, dims::Dims{1}) where {TvNew,TiNew} =
SparseVector(dims..., similar(rowvals(S), TiNew, 0), similar(nonzeros(S), TvNew, 0))
#

# The following methods hook into the AbstractArray similar hierarchy. The first method
# covers similar(A[, Tv]) calls, which preserve stored-entry structure, and the latter
# methods cover similar(A[, Tv], shape...) calls, which preserve storage space when the shape
# calls for a two-dimensional result.
# methods cover similar(A[, Tv], shape...) calls, which partially preserve
# storage space when the shape calls for a two-dimensional result.
similar(S::AbstractSparseMatrixCSC{<:Any,Ti}, ::Type{TvNew}) where {Ti,TvNew} = _sparsesimilar(S, TvNew, Ti)
similar(S::AbstractSparseMatrixCSC{<:Any,Ti}, ::Type{TvNew}, dims::Union{Dims{1},Dims{2}}) where {Ti,TvNew} =
_sparsesimilar(S, TvNew, Ti, dims)
Expand Down
13 changes: 6 additions & 7 deletions stdlib/SparseArrays/src/sparsevector.jl
Original file line number Diff line number Diff line change
Expand Up @@ -89,25 +89,24 @@ indtype(x::SparseVectorView) = indtype(parent(x))
# parent method for similar that preserves stored-entry structure (for when new and old dims match)
_sparsesimilar(S::SparseVector, ::Type{TvNew}, ::Type{TiNew}) where {TvNew,TiNew} =
SparseVector(length(S), copyto!(similar(nonzeroinds(S), TiNew), nonzeroinds(S)), similar(nonzeros(S), TvNew))
# parent method for similar that preserves nothing (for when old and new dims differ, and new is 1d)
# parent method for similar that preserves nothing (for when new dims are 1-d)
_sparsesimilar(S::SparseVector, ::Type{TvNew}, ::Type{TiNew}, dims::Dims{1}) where {TvNew,TiNew} =
SparseVector(dims..., similar(nonzeroinds(S), TiNew, 0), similar(nonzeros(S), TvNew, 0))
# parent method for similar that preserves storage space (for old and new dims differ, and new is 2d)
# parent method for similar that preserves storage space (for when new dims are 2-d)
_sparsesimilar(S::SparseVector, ::Type{TvNew}, ::Type{TiNew}, dims::Dims{2}) where {TvNew,TiNew} =
SparseMatrixCSC(dims..., fill(one(TiNew), last(dims)+1), similar(nonzeroinds(S), TiNew), similar(nonzeros(S), TvNew))
SparseMatrixCSC(dims..., fill(one(TiNew), last(dims)+1), similar(nonzeroinds(S), TiNew, 0), similar(nonzeros(S), TvNew, 0))

# The following methods hook into the AbstractArray similar hierarchy. The first method
# covers similar(A[, Tv]) calls, which preserve stored-entry structure, and the latter
# methods cover similar(A[, Tv], shape...) calls, which preserve nothing if the dims
# specify a SparseVector result and storage space if the dims specify a SparseMatrixCSC result.
# specify a SparseVector or a SparseMatrixCSC result.
similar(S::SparseVector{<:Any,Ti}, ::Type{TvNew}) where {Ti,TvNew} =
_sparsesimilar(S, TvNew, Ti)
similar(S::SparseVector{<:Any,Ti}, ::Type{TvNew}, dims::Union{Dims{1},Dims{2}}) where {Ti,TvNew} =
_sparsesimilar(S, TvNew, Ti, dims)
# The following methods cover similar(A, Tv, Ti[, shape...]) calls, which specify the
# result's index type in addition to its entry type, and aren't covered by the hooks above.
# The calls without shape again preserve stored-entry structure, whereas those with
# one-dimensional shape preserve nothing, and those with two-dimensional shape
# preserve storage space.
# The calls without shape again preserve stored-entry structure but no storage space.
similar(S::SparseVector, ::Type{TvNew}, ::Type{TiNew}) where{TvNew,TiNew} =
_sparsesimilar(S, TvNew, TiNew)
similar(S::SparseVector, ::Type{TvNew}, ::Type{TiNew}, dims::Union{Dims{1},Dims{2}}) where {TvNew,TiNew} =
Expand Down
14 changes: 7 additions & 7 deletions stdlib/SparseArrays/test/sparse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2487,22 +2487,22 @@ end
@test typeof(simA) == typeof(A)
@test size(simA) == (6,6)
@test getcolptr(simA) == fill(1, 6+1)
@test length(rowvals(simA)) == length(rowvals(A))
@test length(nonzeros(simA)) == length(nonzeros(A))
# test similar with entry type and Dims{2} specification (preserves storage space only)
@test length(rowvals(simA)) == 0
@test length(nonzeros(simA)) == 0
# test similar with entry type and Dims{2} specification (empty storage space)
simA = similar(A, Float32, (6,6))
@test typeof(simA) == SparseMatrixCSC{Float32,eltype(getcolptr(A))}
@test size(simA) == (6,6)
@test getcolptr(simA) == fill(1, 6+1)
@test length(rowvals(simA)) == length(rowvals(A))
@test length(nonzeros(simA)) == length(nonzeros(A))
@test length(rowvals(simA)) == 0
@test length(nonzeros(simA)) == 0
# test similar with entry type, index type, and Dims{2} specification (preserves storage space only)
simA = similar(A, Float32, Int8, (6,6))
@test typeof(simA) == SparseMatrixCSC{Float32, Int8}
@test size(simA) == (6,6)
@test getcolptr(simA) == fill(1, 6+1)
@test length(rowvals(simA)) == length(rowvals(A))
@test length(nonzeros(simA)) == length(nonzeros(A))
@test length(rowvals(simA)) == 0
@test length(nonzeros(simA)) == 0
# test similar with Dims{1} specification (preserves nothing)
simA = similar(A, (6,))
@test typeof(simA) == SparseVector{eltype(nonzeros(A)),eltype(getcolptr(A))}
Expand Down
12 changes: 6 additions & 6 deletions stdlib/SparseArrays/test/sparsevector.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1424,22 +1424,22 @@ end
@test typeof(simA) == SparseMatrixCSC{eltype(nonzeros(A)),eltype(nonzeroinds(A))}
@test size(simA) == (6,6)
@test getcolptr(simA) == fill(1, 6+1)
@test length(rowvals(simA)) == length(nonzeroinds(A))
@test length(nonzeros(simA)) == length(nonzeros(A))
@test length(rowvals(simA)) == 0
@test length(nonzeros(simA)) == 0
# test similar with entry type and Dims{2} specification (preserves storage space only)
simA = similar(A, Float32, (6,6))
@test typeof(simA) == SparseMatrixCSC{Float32,eltype(nonzeroinds(A))}
@test size(simA) == (6,6)
@test getcolptr(simA) == fill(1, 6+1)
@test length(rowvals(simA)) == length(nonzeroinds(A))
@test length(nonzeros(simA)) == length(nonzeros(A))
@test length(rowvals(simA)) == 0
@test length(nonzeros(simA)) == 0
# test similar with entry type, index type, and Dims{2} specification (preserves storage space only)
simA = similar(A, Float32, Int8, (6,6))
@test typeof(simA) == SparseMatrixCSC{Float32, Int8}
@test size(simA) == (6,6)
@test getcolptr(simA) == fill(1, 6+1)
@test length(rowvals(simA)) == length(nonzeroinds(A))
@test length(nonzeros(simA)) == length(nonzeros(A))
@test length(rowvals(simA)) == 0
@test length(nonzeros(simA)) == 0
end

@testset "Fast operations on full column views" begin
Expand Down

0 comments on commit 28a3312

Please sign in to comment.