Skip to content
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 setindex! for sparse matrices and vectors not purge stored entries on zero assignment #17404

Merged
merged 10 commits into from
Jul 19, 2016

Conversation

Sacha0
Copy link
Member

@Sacha0 Sacha0 commented Jul 13, 2016

This pull request makes setindex! for SparseMatrixCSCs: (1) not purge allocated entries on zero assignment; and (2) not introduce new allocated entries on zero assignment. See the proposal in #15568 (comment) / extensive discussion in #15568, #9928, #9906, #6769, #5538, #5454, and probably others. Thanks to @KristofferC for getting the ball rolling with #15568!

TODO: Expand tests for new behavior. Now with expanded tests!

@Sacha0 Sacha0 force-pushed the reworksetindex branch 2 times, most recently from e4169e0 to e22fe8f Compare July 13, 2016 23:36
@Sacha0 Sacha0 changed the title WIP: Make setindex! not purge stored entries on zero assignment Make setindex! not purge stored entries on zero assignment Jul 13, 2016
… expunges stored entries on zero assignment, throws a more explicit BoundsError when needed, and also for simplicity and clarity. Also add tests.
@tkelman
Copy link
Contributor

tkelman commented Jul 14, 2016

Please see the test failures, can you reproduce them locally? This is a bit of a behavior change but IMO could be okay for before feature freeze if you hurry.

@tkelman tkelman added the sparse Sparse arrays label Jul 14, 2016
@Sacha0
Copy link
Member Author

Sacha0 commented Jul 14, 2016

The test/show.jl failure should be fixed. Also added a note to NEWS.md. Thanks!

@tkelman
Copy link
Contributor

tkelman commented Jul 14, 2016

@nanosoldier runbenchmarks(ALL, vs = ":master")

@Sacha0
Copy link
Member Author

Sacha0 commented Jul 14, 2016

AppVeyor i686 string test failure seems unrelated?

@tkelman
Copy link
Contributor

tkelman commented Jul 14, 2016

I would assume so, but I've never seen that before

From worker 5:       * string               Test Failed
    From worker 5:    Expression: [i for i = eachindex("ḟøøƀäṙ")] == [1,4,6,8,10,12]
    From worker 5:     Evaluated: Array{Dict{VersionNumber,Array{VersionNumber,1}},1}[Dict{VersionNumber,Array{VersionNumber,1}}[#undef],Dict{VersionNumber,Array{VersionNumber,1}}[#undef,#undef,#undef,#undef],Dict{VersionNumber,Array{VersionNumber,1}}[#undef,#undef,#undef,#undef,#undef,#undef],Dict{VersionNumber,Array{VersionNumber,1}}[#undef,#undef,#undef,#undef,#undef,#undef,#undef,#undef],Dict{VersionNumber,Array{VersionNumber,1}}[#undef,#undef,#undef,#undef,#undef,#undef,#undef,#undef,#undef,#undef],Dict{VersionNumber,Array{VersionNumber,1}}[#undef,#undef,#undef,#undef,#undef,#undef,#undef,#undef,#undef,#undef,#undef,#undef]] == [1,4,6,8,10,12]
... snip ...
Exception running test string :
On worker 5:
LoadError: LoadError: There was an error during testing
 in record at .\test.jl:397
 in do_test at .\test.jl:281
 in include_string at .\loading.jl:380
 in include_from_node1 at .\loading.jl:429
 in include_string at .\loading.jl:380
 in include_from_node1 at .\loading.jl:429
 in macro expansion at .\util.jl:180 [inlined]
 in runtests at C:\projects\julia\test\testdefs.jl:7
 in #16 at C:\projects\julia\test\runtests.jl:44
 in #503 at .\multi.jl:1193
 in run_work_thunk at .\multi.jl:844
 in macro expansion at .\multi.jl:1193 [inlined]
 in #502 at .\event.jl:46
while loading C:\projects\julia\test\strings/basic.jl, in expression starting on line 251
while loading C:\projects\julia\test\string.jl, in expression starting on line 5

@nanosoldier
Copy link
Collaborator

Your benchmark job has completed - no performance regressions were detected. A full report can be found here. cc @jrevels

@Sacha0
Copy link
Member Author

Sacha0 commented Jul 15, 2016

Am I misreading BaseBenchmarks/SparseBenchmarks.jl, or does Nanosoldier not cover sparse setindex! performance?

@tkelman
Copy link
Contributor

tkelman commented Jul 15, 2016

It might not.

lenI = length(I)

if (!isempty(I) && (I[1] < 1 || I[end] > m)) || (!isempty(J) && (J[1] < 1 || J[end] > n))
function setindex!{TvA,Tx<:Number,TiI<:Integer,TiJ<:Integer}(A::SparseMatrixCSC{TvA}, x::Tx,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tx doesn't need to be a type parameter

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! Related question: To fix the show test failure I reverted comparisons of the form x == zero(Tx) to the former implementation's x == 0, the test failure being due to lack of a zero method for some <:Number. Is zero part of the implicit Number interface? That is, in the long run would keeping x == zero(Tx) and requiring all <:Numbers to implement zero be better than using x == 0, or is x == 0 the preferred expression? Thanks!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather continue allowing sparse matrices with value types that don't implement zero if at all possible

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cheers, the most recent version should make that so. Thanks!

@tkelman
Copy link
Contributor

tkelman commented Jul 15, 2016

Is there an API (unexported?) for deleting a specific value from the nonzero structure? dropzeros! does the whole array, is there something more targeted available if you happen to need it?

Sacha0 and others added 4 commits July 15, 2016 10:48
…expunges stored entries on zero assignment. Also add tests.
…hat, when an assigning zero to entry A[i,j], if A[i,j] is not presently stored, the method does not introduce storage for A[i,j]. Also add tests.
… that it no longer expunges stored entries on zero assignment. Also add tests.
…it no longer expunges stored entries on zero assignment. Also add tests.
@Sacha0
Copy link
Member Author

Sacha0 commented Jul 15, 2016

Is there an API (unexported?) for deleting a specific value from the nonzero structure? dropzeros! does the whole array, is there something more targeted available if you happen to need it?

Not at the moment, but we could introduce one now if you would like that facility to appear in the same PR. If so, name? dropstored! is the best I've thought of so far. Methods? Perhaps introduce a dropstored!(A, i, j) method and rename the existing spdelete!(A, I, J) to dropstored!(A, I, J) for now? Other forms that should exist immediately? Best!

@tkelman
Copy link
Contributor

tkelman commented Jul 15, 2016

dropstored! does sound like a nicer name than spdelete! I suppose. The implementation should be the same or very close, right?

@Sacha0
Copy link
Member Author

Sacha0 commented Jul 15, 2016

dropstored! does sound like a nicer name than spdelete! I suppose. The implementation should be the same or very close, right?

Prototype implementation of dropstored! (lacking linear and logical indexing) now included. Thoughts? Thanks!

@Sacha0
Copy link
Member Author

Sacha0 commented Jul 15, 2016

The most recent commits should make SparseVector behavior consistent with the new SparseMatrixCSC behavior. Best!

@Sacha0 Sacha0 changed the title Make setindex! not purge stored entries on zero assignment Make setindex! for sparse matrices and vectors not purge stored entries on zero assignment Jul 15, 2016
…arseVectors. Also introduce associated tests.
…ger purges allocated entries on zero assignment and that dropstored! now exists to drop stored entries.
@tkelman
Copy link
Contributor

tkelman commented Jul 16, 2016

this may not be all that useful given the likely lack of sparse setindex tests, but it's otherwise probably idle right now so
@nanosoldier runbenchmarks(ALL, vs = ":master")

@nanosoldier
Copy link
Collaborator

Your benchmark job has completed - possible performance regressions were detected. A full report can be found here. cc @jrevels


if ndel > 0
A.colptr[n+1] = rowidx
deleteat!(rowvalA, rowidx:nnzA)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could use resize! instead?

@Sacha0
Copy link
Member Author

Sacha0 commented Jul 19, 2016

Apologies for the slow response (travel Saturday through Monday).

Re. dropstored!(A, I, J), the implementation is cut-and-paste from the former spdelete!. That code would benefit from a thorough rewrite. And likewise for the similarly-written setindex! code. Which is to say that I wholeheartedly agree with the corresponding comments. I forwent most such rewriting to minimize replacement of well-exercised code with unexercised code just prior to the anticipated release candidate freeze and alongside related breaking changes. If such rewriting would be better in this rather than a later PR, however, I can take a shot at it now (timescale unclear). Thanks and best!

@tkelman
Copy link
Contributor

tkelman commented Jul 19, 2016

I think we'd be fine to merge this now and do cleanup later. Couldn't tell from the diffs that this was reused code.

@Sacha0
Copy link
Member Author

Sacha0 commented Jul 19, 2016

Couldn't tell from the diffs that this was reused code.

Sorry about that. Reshuffling the contents of the commits such that spdelete! clearly transforms into dropstored! might be possible. Should I attempt that?

@tkelman
Copy link
Contributor

tkelman commented Jul 19, 2016

No, I don't think that's worth the hassle right now. There are other more pressing issues that could use your input.

@KristofferC
Copy link
Member

+1 for merge as is

@tkelman tkelman merged commit 3647de6 into JuliaLang:master Jul 19, 2016
@Sacha0 Sacha0 deleted the reworksetindex branch July 19, 2016 22:50
@Sacha0
Copy link
Member Author

Sacha0 commented Jul 19, 2016

Thanks for the reviews and merge!

return A
end
"""
dropstored!(A::SparseMatrix, I::AbstractVector{<:Integer}, J::AbstractVector{<:Integer})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this say SparseMatrixCSC ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#20664. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
sparse Sparse arrays
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants