From ae53abad7c42d5eded5fbb75e673c605a714d14a Mon Sep 17 00:00:00 2001 From: termi-official Date: Fri, 10 Nov 2023 16:14:34 +0100 Subject: [PATCH 1/7] Hotfix WR form ambiguity. --- src/ldiv.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ldiv.jl b/src/ldiv.jl index 77ffd94..e34f21e 100644 --- a/src/ldiv.jl +++ b/src/ldiv.jl @@ -150,7 +150,8 @@ macro _layoutldiv(Typ) LinearAlgebra.ldiv!(A::Factorization, x::$Typ; kwds...) = ArrayLayouts.ldiv!(A,x; kwds...) LinearAlgebra.ldiv!(A::LU, x::$Typ; kwds...) = ArrayLayouts.ldiv!(A,x; kwds...) LinearAlgebra.ldiv!(A::Cholesky, x::$Typ; kwds...) = ArrayLayouts.ldiv!(A,x; kwds...) - LinearAlgebra.ldiv!(A::LinearAlgebra.QRCompactWY, x::$Typ; kwds...) = ArrayLayouts.ldiv!(A,x; kwds...) + # Type restriction to disambiguiate calls, see https://github.com/JuliaArrays/BlockArrays.jl/issues/319 + LinearAlgebra.ldiv!(A::LinearAlgebra.QRCompactWY{T2}, x::$Typ{T2}; kwds...) where T2<:BlasFloat = ArrayLayouts.ldiv!(A,x; kwds...) LinearAlgebra.ldiv!(A::Bidiagonal, B::$Typ; kwds...) = ArrayLayouts.ldiv!(A,B; kwds...) From bcef18344974fec62e8dfbf7a089582158d90c52 Mon Sep 17 00:00:00 2001 From: termi-official Date: Fri, 10 Nov 2023 16:25:21 +0100 Subject: [PATCH 2/7] Add back old dispatch. --- src/ldiv.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ldiv.jl b/src/ldiv.jl index e34f21e..c9ec3a5 100644 --- a/src/ldiv.jl +++ b/src/ldiv.jl @@ -150,6 +150,7 @@ macro _layoutldiv(Typ) LinearAlgebra.ldiv!(A::Factorization, x::$Typ; kwds...) = ArrayLayouts.ldiv!(A,x; kwds...) LinearAlgebra.ldiv!(A::LU, x::$Typ; kwds...) = ArrayLayouts.ldiv!(A,x; kwds...) LinearAlgebra.ldiv!(A::Cholesky, x::$Typ; kwds...) = ArrayLayouts.ldiv!(A,x; kwds...) + LinearAlgebra.ldiv!(A::LinearAlgebra.QRCompactWY, x::$Typ; kwds...) = ArrayLayouts.ldiv!(A,x; kwds...) # Type restriction to disambiguiate calls, see https://github.com/JuliaArrays/BlockArrays.jl/issues/319 LinearAlgebra.ldiv!(A::LinearAlgebra.QRCompactWY{T2}, x::$Typ{T2}; kwds...) where T2<:BlasFloat = ArrayLayouts.ldiv!(A,x; kwds...) From efd9bd454104559bc05e34d532e855fc4ece5e07 Mon Sep 17 00:00:00 2001 From: termi-official Date: Fri, 10 Nov 2023 18:07:19 +0100 Subject: [PATCH 3/7] Sparse matrix ambiguitiy --- src/ldiv.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ldiv.jl b/src/ldiv.jl index c9ec3a5..571eb19 100644 --- a/src/ldiv.jl +++ b/src/ldiv.jl @@ -165,6 +165,7 @@ macro _layoutldiv(Typ) (\)(A::$Typ, x::AbstractMatrix; kwds...) = ArrayLayouts.ldiv(A,x; kwds...) (\)(x::AbstractMatrix, A::$Typ; kwds...) = ArrayLayouts.ldiv(x,A; kwds...) + (\)(x::AbstractSparseMatrix, A::$Typ; kwds...) = ArrayLayouts.ldiv(x,A; kwds...) (\)(x::LinearAlgebra.HermOrSym, A::$Typ; kwds...) = ArrayLayouts.ldiv(x,A; kwds...) if VERSION < v"1.9-" # disambiguation \(x::LinearAlgebra.HermOrSym{<:Any,<:StridedMatrix}, A::$Typ; kwds...) = ArrayLayouts.ldiv(x,A; kwds...) From be66ca24c18bf0727de27a9a4bf7d75c8d4d316d Mon Sep 17 00:00:00 2001 From: termi-official Date: Fri, 10 Nov 2023 18:17:35 +0100 Subject: [PATCH 4/7] Move sparse matrix dispatch to extension. --- ext/ArrayLayoutsSparseArraysExt.jl | 56 ++++++++++++++++++++++++++---- src/ldiv.jl | 1 - 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/ext/ArrayLayoutsSparseArraysExt.jl b/ext/ArrayLayoutsSparseArraysExt.jl index 21d4a64..3d74958 100644 --- a/ext/ArrayLayoutsSparseArraysExt.jl +++ b/ext/ArrayLayoutsSparseArraysExt.jl @@ -1,25 +1,69 @@ module ArrayLayoutsSparseArraysExt using ArrayLayouts -using ArrayLayouts: _copyto! +using ArrayLayouts: _copyto!, Factorization using SparseArrays # Specifying the full namespace is necessary because of https://github.com/JuliaLang/julia/issues/48533 # See https://github.com/JuliaStats/LogExpFunctions.jl/pull/63 import ArrayLayouts.LinearAlgebra -import Base: copyto! +import Base: copyto!, \, / # ambiguity from sparsematrix.jl copyto!(dest::LayoutMatrix, src::SparseArrays.AbstractSparseMatrixCSC) = - _copyto!(dest, src) + _copyto!(dest, src) copyto!(dest::SubArray{<:Any,2,<:LayoutMatrix}, src::SparseArrays.AbstractSparseMatrixCSC) = - _copyto!(dest, src) + _copyto!(dest, src) @inline LinearAlgebra.dot(a::LayoutArray{<:Number}, b::SparseArrays.SparseVectorUnion{<:Number}) = - ArrayLayouts.dot(a,b) + ArrayLayouts.dot(a,b) @inline LinearAlgebra.dot(a::SparseArrays.SparseVectorUnion{<:Number}, b::LayoutArray{<:Number}) = - ArrayLayouts.dot(a,b) + ArrayLayouts.dot(a,b) + +# disambiguiate sparse matrix dispatches +macro _layoutldivsp(Typ) + ret = quote + (\)(x::SparseArrays.AbstractSparseMatrixCSC, A::$Typ; kwds...) = ArrayLayouts.ldiv(x,A; kwds...) + (/)(x::SparseArrays.AbstractSparseMatrixCSC, A::$Typ; kwds...) = ArrayLayouts.ldiv(x,A; kwds...) + end + esc(ret) +end + +macro layoutldivsp(Typ) + esc(quote + ArrayLayoutsSparseArraysExt.@_layoutldivsp $Typ + ArrayLayoutsSparseArraysExt.@_layoutldivsp LinearAlgebra.UpperTriangular{T, <:$Typ{T}} where T + ArrayLayoutsSparseArraysExt.@_layoutldivsp LinearAlgebra.UnitUpperTriangular{T, <:$Typ{T}} where T + ArrayLayoutsSparseArraysExt.@_layoutldivsp LinearAlgebra.LowerTriangular{T, <:$Typ{T}} where T + ArrayLayoutsSparseArraysExt.@_layoutldivsp LinearAlgebra.UnitLowerTriangular{T, <:$Typ{T}} where T + + ArrayLayoutsSparseArraysExt.@_layoutldivsp LinearAlgebra.UpperTriangular{T, <:SubArray{T,2,<:$Typ{T}}} where T + ArrayLayoutsSparseArraysExt.@_layoutldivsp LinearAlgebra.UnitUpperTriangular{T, <:SubArray{T,2,<:$Typ{T}}} where T + ArrayLayoutsSparseArraysExt.@_layoutldivsp LinearAlgebra.LowerTriangular{T, <:SubArray{T,2,<:$Typ{T}}} where T + ArrayLayoutsSparseArraysExt.@_layoutldivsp LinearAlgebra.UnitLowerTriangular{T, <:SubArray{T,2,<:$Typ{T}}} where T + + ArrayLayoutsSparseArraysExt.@_layoutldivsp LinearAlgebra.UpperTriangular{T, <:LinearAlgebra.Adjoint{T,<:$Typ{T}}} where T + ArrayLayoutsSparseArraysExt.@_layoutldivsp LinearAlgebra.UnitUpperTriangular{T, <:LinearAlgebra.Adjoint{T,<:$Typ{T}}} where T + ArrayLayoutsSparseArraysExt.@_layoutldivsp LinearAlgebra.LowerTriangular{T, <:LinearAlgebra.Adjoint{T,<:$Typ{T}}} where T + ArrayLayoutsSparseArraysExt.@_layoutldivsp LinearAlgebra.UnitLowerTriangular{T, <:LinearAlgebra.Adjoint{T,<:$Typ{T}}} where T + + ArrayLayoutsSparseArraysExt.@_layoutldivsp LinearAlgebra.UpperTriangular{T, <:LinearAlgebra.Transpose{T,<:$Typ{T}}} where T + ArrayLayoutsSparseArraysExt.@_layoutldivsp LinearAlgebra.UnitUpperTriangular{T, <:LinearAlgebra.Transpose{T,<:$Typ{T}}} where T + ArrayLayoutsSparseArraysExt.@_layoutldivsp LinearAlgebra.LowerTriangular{T, <:LinearAlgebra.Transpose{T,<:$Typ{T}}} where T + ArrayLayoutsSparseArraysExt.@_layoutldivsp LinearAlgebra.UnitLowerTriangular{T, <:LinearAlgebra.Transpose{T,<:$Typ{T}}} where T + end) +end + +@_layoutldivsp LayoutVector + +macro layoutmatrixsp(Typ) + esc(quote + ArrayLayoutsSparseArraysExt.@layoutldivsp $Typ + end) +end + +@layoutmatrixsp LayoutMatrix end diff --git a/src/ldiv.jl b/src/ldiv.jl index 571eb19..c9ec3a5 100644 --- a/src/ldiv.jl +++ b/src/ldiv.jl @@ -165,7 +165,6 @@ macro _layoutldiv(Typ) (\)(A::$Typ, x::AbstractMatrix; kwds...) = ArrayLayouts.ldiv(A,x; kwds...) (\)(x::AbstractMatrix, A::$Typ; kwds...) = ArrayLayouts.ldiv(x,A; kwds...) - (\)(x::AbstractSparseMatrix, A::$Typ; kwds...) = ArrayLayouts.ldiv(x,A; kwds...) (\)(x::LinearAlgebra.HermOrSym, A::$Typ; kwds...) = ArrayLayouts.ldiv(x,A; kwds...) if VERSION < v"1.9-" # disambiguation \(x::LinearAlgebra.HermOrSym{<:Any,<:StridedMatrix}, A::$Typ; kwds...) = ArrayLayouts.ldiv(x,A; kwds...) From 94261a20e662a549261bef4ad6b5d4dd3afd3840 Mon Sep 17 00:00:00 2001 From: termi-official Date: Fri, 10 Nov 2023 19:03:44 +0100 Subject: [PATCH 5/7] Some more tests for regression. --- test/test_layoutarray.jl | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/test/test_layoutarray.jl b/test/test_layoutarray.jl index ee66e17..e6e9175 100644 --- a/test/test_layoutarray.jl +++ b/test/test_layoutarray.jl @@ -140,11 +140,7 @@ MemoryLayout(::Type{MyVector}) = DenseColumnMajor() else @test ldiv!(lu(A), MyVector(copy(c))) ≈ A \ c end - if VERSION < v"1.9" || VERSION >= v"1.10-" - @test_throws ErrorException ldiv!(qr(A), MyVector(copy(c))) - else - @test_throws MethodError ldiv!(qr(A), MyVector(copy(c))) - end + @test_throws ErrorException ldiv!(qr(A), MyVector(copy(c))) # Missing materialize! overload @test_throws ErrorException ldiv!(eigen(randn(5,5)), c) @test ArrayLayouts.ldiv!(svd(A.A), copy(c)) ≈ ArrayLayouts.ldiv!(similar(c), svd(A.A), c) ≈ A \ c if VERSION ≥ v"1.8" @@ -213,6 +209,7 @@ MemoryLayout(::Type{MyVector}) = DenseColumnMajor() @testset "layoutldiv" begin A = MyMatrix(randn(5,5)) + Asym = A'*A x = randn(5) X = randn(5,5) t = view(randn(10),[1,3,4,6,7]) @@ -221,8 +218,11 @@ MemoryLayout(::Type{MyVector}) = DenseColumnMajor() T̃ = copy(T) B = Bidiagonal(randn(5),randn(4),:U) D = Diagonal(randn(5)) + S = sprand(5, 5, 0.8) + @test ldiv!(A, copy(x)) ≈ A\x @test A\t ≈ A\t̃ + @test A\t ≈ A\SparseVector(t̃) # QR is not general enough @test_broken ldiv!(A, t) ≈ A\t @test ldiv!(A, copy(X)) ≈ A\X @@ -238,6 +238,18 @@ MemoryLayout(::Type{MyVector}) = DenseColumnMajor() @test A\MyVector(x) ≈ A\x @test A\MyMatrix(X) ≈ A\X + @test qr(A)\MyVector(x) ≈ A\x + @test qr(A)\MyMatrix(X) ≈ A\X + + @test lu(A)\MyVector(x) ≈ A\x + @test lu(A)\MyMatrix(X) ≈ A\X + + @test cholesky(Asym)\MyVector(x) ≈ Asym\x + @test cholesky(Asym)\MyMatrix(X) ≈ Asym\X + + @test S\MyVector(x) ≈ S\x + @test S\MyMatrix(X) ≈ S\X + if VERSION >= v"1.9" @test A/A ≈ A.A / A.A @test x' / A ≈ x' / A.A From b279a3ce0b8cede475e45f7ccb84628eea705a1b Mon Sep 17 00:00:00 2001 From: termi-official Date: Fri, 10 Nov 2023 19:19:40 +0100 Subject: [PATCH 6/7] Make codecov happy. --- test/test_layoutarray.jl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/test_layoutarray.jl b/test/test_layoutarray.jl index e6e9175..17707c5 100644 --- a/test/test_layoutarray.jl +++ b/test/test_layoutarray.jl @@ -249,6 +249,13 @@ MemoryLayout(::Type{MyVector}) = DenseColumnMajor() @test S\MyVector(x) ≈ S\x @test S\MyMatrix(X) ≈ S\X + @test MyMatrix(S)\MyVector(x) ≈ S\x + @test MyMatrix(S)\MyMatrix(X) ≈ S\X + + @test MyVector(x)'/MyMatrix(S) ≈ x'/S + @test X/MyMatrix(S) ≈ X/S + @test MyVector(x)'/MyMatrix(S) ≈ x'/S + @test X/MyMatrix(S) ≈ X/S if VERSION >= v"1.9" @test A/A ≈ A.A / A.A From 300ceafde37888320e89781becc9cd341ba3cc6d Mon Sep 17 00:00:00 2001 From: termi-official Date: Fri, 10 Nov 2023 19:30:34 +0100 Subject: [PATCH 7/7] Increase test coverage and include actual regression test. --- test/test_layoutarray.jl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/test_layoutarray.jl b/test/test_layoutarray.jl index 17707c5..4f77376 100644 --- a/test/test_layoutarray.jl +++ b/test/test_layoutarray.jl @@ -238,14 +238,21 @@ MemoryLayout(::Type{MyVector}) = DenseColumnMajor() @test A\MyVector(x) ≈ A\x @test A\MyMatrix(X) ≈ A\X + # Regression for https://github.com/JuliaArrays/BlockArrays.jl/issues/319 @test qr(A)\MyVector(x) ≈ A\x + @test ldiv!(qr(A), MyVector(copy(x))) ≈ A\x @test qr(A)\MyMatrix(X) ≈ A\X + @test ldiv!(qr(A), MyMatrix(copy(X))) ≈ A\X @test lu(A)\MyVector(x) ≈ A\x + @test ldiv!(lu(A), MyVector(copy(x))) ≈ A\x @test lu(A)\MyMatrix(X) ≈ A\X + @test ldiv!(lu(A), MyMatrix(copy(X))) ≈ A\X @test cholesky(Asym)\MyVector(x) ≈ Asym\x + @test ldiv!(cholesky(Asym), MyVector(copy(x))) ≈ Asym\x @test cholesky(Asym)\MyMatrix(X) ≈ Asym\X + @test ldiv!(cholesky(Asym), MyMatrix(copy(X))) ≈ Asym\X @test S\MyVector(x) ≈ S\x @test S\MyMatrix(X) ≈ S\X