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

Handle Statistics and SparseArrays as extensions #286

Merged
merged 6 commits into from
Aug 23, 2023
Merged

Handle Statistics and SparseArrays as extensions #286

merged 6 commits into from
Aug 23, 2023

Conversation

dkarrasch
Copy link
Contributor

I went ahead and just did it. The only "disturbing" thing is that kron method which is not an extension, strictly speaking. So it would be great to resolve it and make the dependencies weak.

@jishnub
Copy link
Member

jishnub commented Jul 26, 2023

The Aqua formatting error on v1.6 should be fixed by #287

@jishnub
Copy link
Member

jishnub commented Jul 26, 2023

Locally, I can get around the kron issue using
fillalgebra.jl:

abstract type KronStyle end
struct SparseKronStyle <: KronStyle end
struct UnknownKronStyle <: KronStyle end
KronStyle(A) = UnknownKronStyle()
kron(A::RectDiagonalFill, B::RectDiagonalFill) =
    maybesparsekron(KronStyle(A), KronStyle(B), A, B)

function maybesparsekron(::UnknownKronStyle, ::UnknownKronStyle, A::AbstractMatrix, B::AbstractMatrix)
    invoke(kron, Tuple{AbstractMatrix, AbstractMatrix}, A, B)
end

FillArraysSparseArraysExt.jl:

FillArrays.KronStyle(A::RectDiagonalFill) = FillArrays.SparseKronStyle()

function FillArrays.maybesparsekron(::SparseKronStyle, ::SparseKronStyle, A, B)
    kron(sparse(A), sparse(B))
end

I've updated the code in https://github.com/jishnub/FillArrays.jl/tree/kronextension

But, this is a more serious variant of type-piracy, where behavior is altered based on whether a library is loaded (and is potentially also a regression, as currently working code may lead to OOM errors if one doesn't load SparseArrays). Nonetheless, this may not be a widely used code path, so maybe such a change is acceptable?

@dlfivefifty
Copy link
Member

The kron overload is a bit funny. It might be better to make a custom type if this is actually needed. Otherwise deprecate it and users can write kron(sparse(A), sparse(B)) instead?

@dkarrasch
Copy link
Contributor Author

In fact, one should really go with a lazy Kronecker product, as in LazyArrays.jl, or Kronecker.jl, or LinearMaps.jl if you don't need the result to subtype AbstractMatrix. With the "vec trick" and fast multiplication, this should be superior in most applications.

@codecov
Copy link

codecov bot commented Jul 26, 2023

Codecov Report

Merging #286 (7c7a333) into master (41715aa) will decrease coverage by 99.89%.
Report is 3 commits behind head on master.
The diff coverage is 0.00%.

❗ Current head 7c7a333 differs from pull request most recent head 6147c9e. Consider uploading reports for the commit 6147c9e to get more accurate results

@@            Coverage Diff             @@
##           master    #286       +/-   ##
==========================================
- Coverage   99.88%   0.00%   -99.89%     
==========================================
  Files           5       7        +2     
  Lines         851     868       +17     
==========================================
- Hits          850       0      -850     
- Misses          1     868      +867     
Files Changed Coverage Δ
ext/FillArraysSparseArraysExt.jl 0.00% <0.00%> (ø)
ext/FillArraysStatisticsExt.jl 0.00% <0.00%> (ø)
src/FillArrays.jl 0.00% <0.00%> (-99.74%) ⬇️
src/fillalgebra.jl 0.00% <0.00%> (-100.00%) ⬇️

... and 3 files with indirect coverage changes

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

@dkarrasch
Copy link
Contributor Author

How do we proceed here? Did you mean to release one version with a deprecation only, and then a subsequent version with the Pkg extension stuff like here? An alternative would be to release v2, which may take a while to propagate through the ecosystem.

@dlfivefifty
Copy link
Member

Technically for SEMVAR: if we wanted to drop support we could deprecate in a 1.x release and then remove in a 2.0 release. But then this means there's no actual benefit until 2.0!

BUT: I take the view that a change is non-breaking if it doesn't break anything. @jishnub why was kron added? Do you need it or could you use kron(sparse(A), sparse(B))?

@jishnub
Copy link
Member

jishnub commented Jul 27, 2023

kron was added because there was an issue about this: #265. I don't have strong opinions either way.

cc: @amilsted for your use case, would you be ok with this change?

@dlfivefifty
Copy link
Member

How about this: just have kron throw an error when SparseArrays.jl is not loaded? I.e.

# in FillArrays.jl
kron(A::RectDiagonalFill, B::RectDiagonalFill) = kron_fill(A, B)
kron_fill(A, B) = error("Load SparseArrays.jl")

# in FillArraysSparseArraysExt.jl
kron_fill(A::RectDiagonalFill, B::RectDiagonalFill) = kron(sparse(A), sparse(B))

@jishnub
Copy link
Member

jishnub commented Jul 27, 2023

This would be breaking, though. The hack-y solution that I had presented above was trying to work around this breakage.

@dlfivefifty
Copy link
Member

It's not really "breaking" as downstream one just has to do using SparseArrays. I'd be shocked if there's any extant code that's impacted

@jishnub
Copy link
Member

jishnub commented Jul 28, 2023

Alright, perhaps we may go ahead with making this error without SparseArrays.

Edit: the current design in this PR seems fine to me.

julia> kron(E, E)
4×4 Matrix{Float64}:
 1.0  0.0  0.0  0.0
 0.0  1.0  0.0  0.0
 0.0  0.0  1.0  0.0
 0.0  0.0  0.0  1.0

julia> using SparseArrays

julia> kron(E, E)
4×4 SparseMatrixCSC{Float64, Int64} with 4 stored entries:
 1.0            
     1.0        
         1.0    
             1.0

The method is deprecated anyway, and if this impacts anyone, they may be warned against using this.

@dkarrasch
Copy link
Contributor Author

Oh, I missed your update @jishnub. If everyone is happy with the last but one commit, I can revert the "error or load" commit.

This reverts commit 7c7a333.
@jishnub
Copy link
Member

jishnub commented Aug 22, 2023

I think this should be good to merge?

@amilsted
Copy link

Do I understand right that kron will now be deprecated for these arrays regardless of whether SparseArrays is loaded? That seems fair enough. It's a bit weird that the extension package changes the output type of kron, but if it's going away I suppose it's not a big deal.

@jishnub
Copy link
Member

jishnub commented Aug 22, 2023

Yes, that's the status quo

@dlfivefifty dlfivefifty merged commit 5abd5f6 into JuliaArrays:master Aug 23, 2023
6 checks passed
@dkarrasch dkarrasch deleted the dk/extension branch August 23, 2023 09:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants