Skip to content

Commit

Permalink
error instead of widening index types in sparse (#33083)
Browse files Browse the repository at this point in the history
Followup to https://github.com/JuliaLang/julia/pull/31724/files#r317686891; instead of widening the index type dynamically based upon the index vector length, just throw an error in the case where the index type cannot hold all the indices in a CSC format. This previously was an OOB access (and likely segfault) in 1.2, so throwing an error here is not a breaking change -- and throwing an error restores type stability, addressing the performance regression flagged in #32985.

(cherry picked from commit 9725fb4)
  • Loading branch information
mbauman authored and KristofferC committed Aug 27, 2019
1 parent 9f39733 commit f69b057
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 8 deletions.
9 changes: 4 additions & 5 deletions stdlib/SparseArrays/src/sparsematrix.jl
Original file line number Diff line number Diff line change
Expand Up @@ -630,9 +630,8 @@ function sparse(I::AbstractVector{Ti}, J::AbstractVector{Ti}, V::AbstractVector{
"length(I) (=$(length(I))) == length(J) (= $(length(J))) == length(V) (= ",
"$(length(V)))")))
end
Tj = Ti
while isbitstype(Tj) && coolen >= typemax(Tj)
Tj = widen(Tj)
if Base.hastypemax(Ti) && coolen >= typemax(Ti)
throw(ArgumentError("the index type $Ti cannot hold $coolen elements; use a larger index type"))
end
if m == 0 || n == 0 || coolen == 0
if coolen != 0
Expand All @@ -645,13 +644,13 @@ function sparse(I::AbstractVector{Ti}, J::AbstractVector{Ti}, V::AbstractVector{
SparseMatrixCSC(m, n, fill(one(Ti), n+1), Vector{Ti}(), Vector{Tv}())
else
# Allocate storage for CSR form
csrrowptr = Vector{Tj}(undef, m+1)
csrrowptr = Vector{Ti}(undef, m+1)
csrcolval = Vector{Ti}(undef, coolen)
csrnzval = Vector{Tv}(undef, coolen)

# Allocate storage for the CSC form's column pointers and a necessary workspace
csccolptr = Vector{Ti}(undef, n+1)
klasttouch = Vector{Tj}(undef, n)
klasttouch = Vector{Ti}(undef, n)

# Allocate empty arrays for the CSC form's row and nonzero value arrays
# The parent method called below automagically resizes these arrays
Expand Down
6 changes: 3 additions & 3 deletions stdlib/SparseArrays/test/sparse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2662,14 +2662,14 @@ end
J1 = Int8.(rand(1:10, 500))
V1 = ones(500)
# m * n < typemax(Ti) and length(I) >= typemax(Ti) - combining values
@test sparse(I1, J1, V1, 10, 10) !== nothing
@test_throws ArgumentError sparse(I1, J1, V1, 10, 10)
# m * n >= typemax(Ti) and length(I) >= typemax(Ti)
@test sparse(I1, J1, V1, 12, 13) !== nothing
@test_throws ArgumentError sparse(I1, J1, V1, 12, 13)
I1 = Int8.(rand(1:10, 126))
J1 = Int8.(rand(1:10, 126))
V1 = ones(126)
# m * n >= typemax(Ti) and length(I) < typemax(Ti)
@test sparse(I1, J1, V1, 100, 100) !== nothing
@test size(sparse(I1, J1, V1, 100, 100)) == (100,100)
end

@testset "Typecheck too strict #31435" begin
Expand Down

0 comments on commit f69b057

Please sign in to comment.