-
Notifications
You must be signed in to change notification settings - Fork 56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make length(A.nzval)==nnz(A) #44
Comments
Ref. JuliaLang/julia#20464 for previous discussion of this topic. Decoupling of buffer length and number of stored entries is a well established property of compressed sparse data structures, and is regularly exploited in sparse linear algebra libraries; ref. JuliaLang/julia#20464 (comment) particularly for expansion on use cases. Best! |
The point is that this is already possible because the buffer size of a |
The most that seems necessary is the ability to ask a Vector how much underlying storage it has, which we can surely do in a stdlib. We'll need an official API for that if we ever move SparseArrays out of stdlib, but until then, we can violate abstraction boundaries as necessary. |
Yes, had we control over the buffer size of a |
To clarify, last I checked |
If I read the code correctly in |
Perhaps we would benefit from an API that provides a stronger contract than that of Another consideration mentioned in JuliaLang/julia#20464 (comment) (that I forgot when responding over the weekend) is symbolic stages of sparse matrix operations. There the traditional decoupling is used to save roughly a factor of two of storage by keeping |
I just hit a bug where we blindly map an operation over all values of julia> using SparseArrays
julia> # create a sparse matrix with extra entries in nzval
B = SparseMatrixCSC(Complex{BigInt}[1 2]')'[1:1, 2:2]
1×1 SparseMatrixCSC{Complex{BigInt},Int64} with 1 stored entry:
[1, 1] = 2+0im
julia> dump(B)
SparseMatrixCSC{Complex{BigInt},Int64}
m: Int64 1
n: Int64 1
colptr: Array{Int64}((2,)) [1, 2]
rowval: Array{Int64}((3,)) [1, 140548820313728, 9]
nzval: Array{Complex{BigInt}}((3,)) Complex{BigInt}[2 + 0im, #undef, #undef]
julia> -B
ERROR: UndefRefError: access to undefined reference
Stacktrace:
[1] getindex at ./array.jl:728 [inlined]
[2] iterate at ./array.jl:704 [inlined]
[3] iterate at ./generator.jl:44 [inlined]
[4] collect_to!(::Array{Complex{BigInt},1}, ::Base.Generator{Array{Complex{BigInt},1},typeof(-)}, ::Int64, ::Int64) at ./array.jl:651
[5] collect_to_with_first! at ./array.jl:630 [inlined]
[6] _collect(::Array{Complex{BigInt},1}, ::Base.Generator{Array{Complex{BigInt},1},typeof(-)}, ::Base.EltypeUnknown, ::Base.HasShape{1}) at ./array.jl:624
[7] map at ./array.jl:548 [inlined]
[8] -(::SparseMatrixCSC{Complex{BigInt},Int64}) at ./stdlib/v1.2/SparseArrays/src/sparsematrix.jl:1507
[9] top-level scope at REPL[4]:1
julia> conj(B)
ERROR: UndefRefError: access to undefined reference
Stacktrace:
[1] getindex at ./array.jl:728 [inlined]
[2] _broadcast_getindex at ./broadcast.jl:590 [inlined]
[3] _getindex at ./broadcast.jl:621 [inlined]
[4] _broadcast_getindex at ./broadcast.jl:596 [inlined]
[5] getindex at ./broadcast.jl:557 [inlined]
[6] macro expansion at ./broadcast.jl:887 [inlined]
[7] macro expansion at ./simdloop.jl:73 [inlined]
[8] copyto! at ./broadcast.jl:886 [inlined]
[9] copyto! at ./broadcast.jl:841 [inlined]
[10] copy at ./broadcast.jl:817 [inlined]
[11] materialize at ./broadcast.jl:797 [inlined]
[12] broadcast(::typeof(conj), ::Array{Complex{BigInt},1}) at ./broadcast.jl:751
[13] conj at ./arraymath.jl:30 [inlined]
[14] conj(::SparseMatrixCSC{Complex{BigInt},Int64}) at ./stdlib/v1.2/SparseArrays/src/sparsematrix.jl:1510
[15] top-level scope at REPL[5]:1 The existence of these bugs makes me think that the general idea of not having extra entries in |
* Add sizehint!(::SparseMatrixCSC, args...), * Fix illegal SparseMatrixCSC construction in cholmod and linalg. * Remove tests targetting now illegal buffers
* Add sizehint!(::SparseMatrixCSC, args...), * Fix illegal SparseMatrixCSC construction in cholmod and linalg. * Remove tests targetting now illegal buffers
* Add sizehint!(::SparseMatrixCSC, args...), * Fix illegal SparseMatrixCSC construction in cholmod and linalg. * Remove tests targetting now illegal buffers * Fix invalid buffer creation in kron and more
* Add sizehint!(::SparseMatrixCSC, args...), * Fix illegal SparseMatrixCSC construction in cholmod and linalg. * Remove tests targetting now illegal buffers * Fix invalid buffer creation in kron and more
* Add sizehint!(::SparseMatrixCSC, args...), * Fix illegal SparseMatrixCSC construction in cholmod and linalg. * Remove tests targetting now illegal buffers * Fix invalid buffer creation in kron and more
* Add sizehint!(::SparseMatrixCSC, args...), * Fix illegal SparseMatrixCSC construction in cholmod and linalg. * Remove tests targetting now illegal buffers * Fix invalid buffer creation in kron and more
Make length(A.nzval)==nnz(A) and add strict buffer checking (#30662) * Add sizehint!(::SparseMatrixCSC, args...), * Fix illegal SparseMatrixCSC construction in cholmod and linalg. * Remove tests targetting now illegal buffers * Fix invalid buffer creation in kron and more * use widelength in sizehint! to cope with large matrices in 32 bit systems
Make length(A.nzval)==nnz(A) and add strict buffer checking (#30662) * Add sizehint!(::SparseMatrixCSC, args...), * Fix illegal SparseMatrixCSC construction in cholmod and linalg. * Remove tests targetting now illegal buffers * Fix invalid buffer creation in kron and more * use widelength in sizehint! to cope with large matrices in 32 bit systems
Make length(A.nzval)==nnz(A) and add strict buffer checking (#30662) * Add sizehint!(::SparseMatrixCSC, args...), * Fix illegal SparseMatrixCSC construction in cholmod and linalg. * Remove tests targetting now illegal buffers * Fix invalid buffer creation in kron and more * use widelength in sizehint! to cope with large matrices in 32 bit systems
Make length(A.nzval)==nnz(A) and add strict buffer checking (#30662) * Add sizehint!(::SparseMatrixCSC, args...), * Fix illegal SparseMatrixCSC construction in cholmod and linalg. * Remove tests targetting now illegal buffers * Fix invalid buffer creation in kron and more * use widelength in sizehint! to cope with large matrices in 32 bit systems
Make length(A.nzval)==nnz(A) and add strict buffer checking (#30662) * Add sizehint!(::SparseMatrixCSC, args...), * Fix illegal SparseMatrixCSC construction in cholmod and linalg. * Remove tests targetting now illegal buffers * Fix invalid buffer creation in kron and more * use widelength in sizehint! to cope with large matrices in 32 bit systems
Fixed by JuliaLang/julia#40523 I think |
We currently allow that
length(A.nzval)>nnz(A)
such that memory for future elements in the matrix can be preallocated. Insteadnnz(A)=A.colptr[n+1]-1
. However, as pointed out in JuliaLang/julia#30435 (comment), this could simply be handled bysizehint!
and having two different mechanisms for ensuring extras allocations seems superfluous. Hence, it might be worth simplifying the sparse matrix code and enforce thatnnz(A)==length(A.nzval)
.The text was updated successfully, but these errors were encountered: