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

[Containers] use OrderedDict as the data structure for SparseAxisArray #3681

Merged
merged 7 commits into from
Feb 29, 2024

Conversation

odow
Copy link
Member

@odow odow commented Feb 17, 2024

Closes #3678
Closes #3680

The issue is still really that SparseAxisArray is not a regular n-dimensional Array. Each slice can have a different length with different axes. It doesn't make sense to support a lot of operations with it.

The only thing that we should support are vectors.

This PR has the problem that the current iteration order is the transpose of what it "should" be (row-major, instead of column-major).

This is needed because the second and subsequent dimensions can depend on the first and prior. So it isn't really meaningful to iterate "down" the first index holding all else constant.

I can see this being a constant source of future problems.

Copy link

codecov bot commented Feb 17, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (a21e616) 98.33% compared to head (57eb71c) 98.36%.
Report is 1 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #3681      +/-   ##
==========================================
+ Coverage   98.33%   98.36%   +0.03%     
==========================================
  Files          43       43              
  Lines        5696     5698       +2     
==========================================
+ Hits         5601     5605       +4     
+ Misses         95       93       -2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@joaquimg
Copy link
Member

Shouldnt the iteration ordering comment be part of docs?

@odow
Copy link
Member Author

odow commented Feb 17, 2024

Yeah. I guess my first question is: should we do this?

If we do, we need more docs on the specifics of the order and slicing, and when things can go wrong.

Also: https://github.com/jump-dev/JuMP.jl/actions/runs/7944311147

@joaquimg
Copy link
Member

The slicing issues you showed seem pretty dangerous.

The only downside would be the performance penalty? Did you benchmark it?

@odow
Copy link
Member Author

odow commented Feb 18, 2024

The only downside would be the performance penalty? Did you benchmark it?

I didn't benchmark it, but I think the risk of incorrect usage outweighs the cost.

It's probably slower because creating an ordered dict is slower. But it shouldn't be too bad.

@joaquimg
Copy link
Member

I agree correctness must come first.

Is there any other downside?

@odow
Copy link
Member Author

odow commented Feb 18, 2024

I added a warning.

I guess the main downside is that existing iteration orders may change. But that could have happened anyway, because we used a Dict.

Copy link
Member

@blegat blegat left a comment

Choose a reason for hiding this comment

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

The change of order of eachindex is indeed sub-optimal since we want SparseAxisArrays to match the behavior of Array it is dense and it's indices are Base.OneTo. However, it doesn't seem that this could be done in general and it's still a strict improvement to the behavior before this PR.

@odow
Copy link
Member Author

odow commented Feb 22, 2024

Before merging, we should check if we can trigger issues like
JuliaCollections/OrderedCollections.jl#87

We should also audit open issues in OrderedCollections for other potential problems.

@odow
Copy link
Member Author

odow commented Feb 22, 2024

I audited all the open issues. I think we're safe from the delete segfault because you cannot delete elements in a SparseAxisArray.

The most up for debate issue is: JuliaCollections/OrderedCollections.jl#82

julia> Containers.@container(x[k in 1:2], k, container = SparseAxisArray)
JuMP.Containers.SparseAxisArray{Int64, 1, Tuple{Int64}} with 2 entries:
  [1]  =  1
  [2]  =  2

julia> Containers.@container(y[k in 2:-1:1], k, container = SparseAxisArray)
JuMP.Containers.SparseAxisArray{Int64, 1, Tuple{Int64}} with 2 entries:
  [2]  =  2
  [1]  =  1

julia> x == y
true

But this coincidentally just reproduces the behavior of the current JuMP:

julia> Containers.@container(x[k in 1:2], k, container = SparseAxisArray)
JuMP.Containers.SparseAxisArray{Int64, 1, Tuple{Int64}} with 2 entries:
  [1]  =  1
  [2]  =  2

julia> Containers.@container(y[k in 2:-1:1], k, container = SparseAxisArray)
JuMP.Containers.SparseAxisArray{Int64, 1, Tuple{Int64}} with 2 entries:
  [1]  =  1
  [2]  =  2

julia> x == y
true

@mlubin
Copy link
Member

mlubin commented Feb 29, 2024

JuliaCollections/OrderedCollections.jl#82 isn't too concerning to me.

@odow
Copy link
Member Author

odow commented Feb 29, 2024

So good to merge then?

@odow odow merged commit 1195695 into master Feb 29, 2024
11 checks passed
@odow odow deleted the od/sparse-order branch February 29, 2024 03:21
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

Iterating SparseAxisArray does not preserve order
4 participants