diff --git a/Project.toml b/Project.toml index 8c262170..7945150e 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "LazyArrays" uuid = "5078a376-72f3-5289-bfd5-ec5146d43c02" -version = "2.8" +version = "2.9" [deps] ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a" diff --git a/ext/LazyArraysBandedMatricesExt.jl b/ext/LazyArraysBandedMatricesExt.jl index 967065ff..2a68070e 100644 --- a/ext/LazyArraysBandedMatricesExt.jl +++ b/ext/LazyArraysBandedMatricesExt.jl @@ -6,7 +6,7 @@ import ArrayLayouts: colsupport, rowsupport, materialize!, MatMulVecAdd, MatMulM OnesLayout, AbstractFillLayout, mulreduce, inv_layout, _fill_lmul!, copyto!_layout, _copy_oftype, layout_getindex, transtype import LazyArrays: sublayout, symmetriclayout, hermitianlayout, applylayout, cachedlayout, transposelayout, - LazyArrayStyle, ApplyArrayBroadcastStyle, AbstractInvLayout, AbstractLazyLayout, LazyLayouts, + LazyArrayStyle, AbstractLazyArrayStyle, ApplyArrayBroadcastStyle, AbstractInvLayout, AbstractLazyLayout, LazyLayouts, AbstractPaddedLayout, PaddedLayout, AbstractLazyBandedLayout, LazyBandedLayout, PaddedRows, PaddedColumns, CachedArray, CachedMatrix, LazyLayout, BroadcastLayout, ApplyLayout, paddeddata, resizedata!, broadcastlayout, _broadcastarray2broadcasted, _broadcast_sub_arguments, @@ -24,12 +24,12 @@ hermitianlayout(::Type{<:Real}, ::AbstractLazyBandedLayout) = SymmetricLayout{La hermitianlayout(::Type{<:Complex}, ::AbstractLazyBandedLayout) = HermitianLayout{LazyBandedLayout}() -bandedbroadcaststyle(::LazyArrayStyle) = LazyArrayStyle{2}() +bandedbroadcaststyle(::AbstractLazyArrayStyle) = LazyArrayStyle{2}() -BroadcastStyle(::LazyArrayStyle{1}, ::BandedStyle) = LazyArrayStyle{2}() -BroadcastStyle(::BandedStyle, ::LazyArrayStyle{1}) = LazyArrayStyle{2}() -BroadcastStyle(::LazyArrayStyle{2}, ::BandedStyle) = LazyArrayStyle{2}() -BroadcastStyle(::BandedStyle, ::LazyArrayStyle{2}) = LazyArrayStyle{2}() +BroadcastStyle(::AbstractLazyArrayStyle{1}, ::BandedStyle) = LazyArrayStyle{2}() +BroadcastStyle(::BandedStyle, ::AbstractLazyArrayStyle{1}) = LazyArrayStyle{2}() +BroadcastStyle(::AbstractLazyArrayStyle{2}, ::BandedStyle) = LazyArrayStyle{2}() +BroadcastStyle(::BandedStyle, ::AbstractLazyArrayStyle{2}) = LazyArrayStyle{2}() bandedcolumns(::AbstractLazyLayout) = BandedColumns{LazyLayout}() bandedcolumns(::DualLayout{<:AbstractLazyLayout}) = BandedColumns{LazyLayout}() @@ -287,10 +287,10 @@ copyto!_layout(_, ::BroadcastBandedLayout, dest::AbstractMatrix, bc::AbstractMat # _banded_broadcast!(dest::AbstractMatrix, f, (A,B)::Tuple{AbstractMatrix{T},AbstractMatrix{V}}, _, ::Tuple{<:Any,ApplyBandedLayout{typeof(*)}}) where {T,V} = # broadcast!(f, dest, BandedMatrix(A), BandedMatrix(B)) -broadcasted(::LazyArrayStyle, ::typeof(*), c::Number, A::BandedMatrix) = _BandedMatrix(c .* A.data, A.raxis, A.l, A.u) -broadcasted(::LazyArrayStyle, ::typeof(*), A::BandedMatrix, c::Number) = _BandedMatrix(A.data .* c, A.raxis, A.l, A.u) -broadcasted(::LazyArrayStyle, ::typeof(\), c::Number, A::BandedMatrix) = _BandedMatrix(c .\ A.data, A.raxis, A.l, A.u) -broadcasted(::LazyArrayStyle, ::typeof(/), A::BandedMatrix, c::Number) = _BandedMatrix(A.data ./ c, A.raxis, A.l, A.u) +broadcasted(::AbstractLazyArrayStyle, ::typeof(*), c::Number, A::BandedMatrix) = _BandedMatrix(c .* A.data, A.raxis, A.l, A.u) +broadcasted(::AbstractLazyArrayStyle, ::typeof(*), A::BandedMatrix, c::Number) = _BandedMatrix(A.data .* c, A.raxis, A.l, A.u) +broadcasted(::AbstractLazyArrayStyle, ::typeof(\), c::Number, A::BandedMatrix) = _BandedMatrix(c .\ A.data, A.raxis, A.l, A.u) +broadcasted(::AbstractLazyArrayStyle, ::typeof(/), A::BandedMatrix, c::Number) = _BandedMatrix(A.data ./ c, A.raxis, A.l, A.u) copy(M::Mul{BroadcastBandedLayout{typeof(*)}, <:Union{PaddedColumns,PaddedLayout}}) = _broadcast_banded_padded_mul(arguments(BroadcastBandedLayout{typeof(*)}(), M.A), M.B) diff --git a/ext/LazyArraysStaticArraysExt.jl b/ext/LazyArraysStaticArraysExt.jl index 67f30726..6926fc6c 100644 --- a/ext/LazyArraysStaticArraysExt.jl +++ b/ext/LazyArraysStaticArraysExt.jl @@ -1,7 +1,7 @@ module LazyArraysStaticArraysExt using LazyArrays -using LazyArrays: LazyArrayStyle +using LazyArrays: AbstractLazyArrayStyle using StaticArrays using StaticArrays: StaticArrayStyle @@ -10,6 +10,6 @@ function LazyArrays._vcat_layout_broadcasted((Ahead,Atail)::Tuple{SVector{M},Any Vcat(op.(Ahead,Bhead), op.(Atail,Btail)) end -Base.BroadcastStyle(L::LazyArrayStyle{N}, ::StaticArrayStyle{N}) where N = L +Base.BroadcastStyle(L::AbstractLazyArrayStyle{N}, ::StaticArrayStyle{N}) where N = L end diff --git a/src/cache.jl b/src/cache.jl index c250bcc8..f24bc87e 100644 --- a/src/cache.jl +++ b/src/cache.jl @@ -324,11 +324,14 @@ end # MemoryLayout #### -struct CachedLayout{Data,Array} <: MemoryLayout end +abstract type AbstractCachedLayout <: AbstractLazyLayout end +struct CachedLayout{Data,Array} <: AbstractCachedLayout end +struct GenericCachedLayout <: AbstractCachedLayout end cachedlayout(::Data, ::Array) where {Data,Array} = CachedLayout{Data,Array}() MemoryLayout(C::Type{CachedArray{T,N,DAT,ARR}}) where {T,N,DAT,ARR} = cachedlayout(MemoryLayout(DAT), MemoryLayout(ARR)) +MemoryLayout(::Type{<:AbstractCachedArray}) = GenericCachedLayout() ##### # broadcasting @@ -337,9 +340,16 @@ MemoryLayout(C::Type{CachedArray{T,N,DAT,ARR}}) where {T,N,DAT,ARR} = cachedlayo # to take advantage of special implementations of the sub-components ###### -BroadcastStyle(::Type{<:CachedArray{<:Any,N}}) where N = LazyArrayStyle{N}() +struct CachedArrayStyle{N} <: AbstractLazyArrayStyle{N} end +CachedArrayStyle(::Val{N}) where N = CachedArrayStyle{N}() +CachedArrayStyle{M}(::Val{N}) where {N,M} = CachedArrayStyle{N}() -broadcasted(::LazyArrayStyle, op, A::CachedArray) = CachedArray(broadcast(op, cacheddata(A)), broadcast(op, A.array)) +BroadcastStyle(::Type{<:AbstractCachedArray{<:Any,N}}) where N = CachedArrayStyle{N}() +BroadcastStyle(::Type{<:SubArray{<:Any,N,<:AbstractCachedArray{<:Any,M}}}) where {N,M} = CachedArrayStyle{M}() +BroadcastStyle(::CachedArrayStyle{N}, ::LazyArrayStyle{M}) where {N,M} = CachedArrayStyle{max(M, N)}() + + +broadcasted(::AbstractLazyArrayStyle, op, A::CachedArray) = CachedArray(broadcast(op, cacheddata(A)), broadcast(op, A.array)) layout_broadcasted(::CachedLayout, _, op, A::AbstractArray, c::Number) = CachedArray(broadcast(op, cacheddata(A), c), broadcast(op, A.array, c)) layout_broadcasted(_, ::CachedLayout, op, c::Number, A::CachedArray) = CachedArray(broadcast(op, c, cacheddata(A)), broadcast(op, c, A.array)) layout_broadcasted(::CachedLayout, _, op, A::CachedArray, c::Ref) = CachedArray(broadcast(op, cacheddata(A), c), broadcast(op, A.array, c)) @@ -380,7 +390,31 @@ for op in (:*, :\, :+, :-) @eval layout_broadcasted(::ZerosLayout, ::CachedLayout, ::typeof($op), a::AbstractVector, b::AbstractVector) = broadcast(DefaultArrayStyle{1}(), $op, a, b) end +function _bc_resizecacheddata!(::AbstractCachedLayout, a) + resizedata!(a, size(a)...) + view(cacheddata(a), axes(a)...) +end +_bc_resizecacheddata!(_, a) = a +_bc_resizecacheddata!(a) = _bc_resizecacheddata!(MemoryLayout(a), a) +resize_bcargs!(bc::Broadcasted{<:CachedArrayStyle}) = broadcasted(bc.f, map(_bc_resizecacheddata!, bc.args)...) + +similar(bc::Broadcasted{<:CachedArrayStyle}, ::Type{T}) where T = CachedArray(zeros(T, axes(bc))) +function copyto!(dest::AbstractArray, bc::Broadcasted{<:CachedArrayStyle}) + #= + Without flatten, we were observing some stack overflows in some cases for nested broadcasts, e.g. + using SemiclassicalOrthogonalPolynomials, ClassicalOrthogonalPolynomials + Q = Normalized(Legendre()) + P = SemiclassicalOrthogonalPolynomials.RaisedOP(Q, 1) + A, = ClassicalOrthogonalPolynomials.recurrencecoefficients(Q) + d = -inv(A[1] * SemiclassicalOrthogonalPolynomials._p0(Q) * P.ℓ[1]) + κ = d * SemiclassicalOrthogonalPolynomials.normalizationconstant(1, P) + κ[1:2] + leads to a stack overflow. + =# + rsz_bc = resize_bcargs!(Base.Broadcast.flatten(bc)) + copyto!(dest, rsz_bc) +end ### # norm @@ -501,8 +535,8 @@ CachedAbstractVector(array::AbstractVector{T}) where T = CachedAbstractVector{T} CachedAbstractMatrix(array::AbstractMatrix{T}) where T = CachedAbstractMatrix{T}(array) -broadcasted(::LazyArrayStyle, op, A::CachedAbstractArray) = CachedAbstractArray(broadcast(op, cacheddata(A)), broadcast(op, A.array)) -function broadcasted(::LazyArrayStyle, op, A::CachedAbstractVector, B::CachedAbstractVector) +broadcasted(::AbstractLazyArrayStyle, op, A::CachedAbstractArray) = CachedAbstractArray(broadcast(op, cacheddata(A)), broadcast(op, A.array)) +function broadcasted(::AbstractLazyArrayStyle, op, A::CachedAbstractVector, B::CachedAbstractVector) n = max(A.datasize[1],B.datasize[1]) resizedata!(A,n) resizedata!(B,n) @@ -510,10 +544,10 @@ function broadcasted(::LazyArrayStyle, op, A::CachedAbstractVector, B::CachedAbs Bdat = view(cacheddata(B),1:n) CachedAbstractArray(broadcast(op, Adat, Bdat), broadcast(op, A.array, B.array)) end -broadcasted(::LazyArrayStyle, op, A::CachedAbstractArray, c::Number) = CachedAbstractArray(broadcast(op, cacheddata(A), c), broadcast(op, A.array, c)) -broadcasted(::LazyArrayStyle, op, c::Number, A::CachedAbstractArray) = CachedAbstractArray(broadcast(op, c, cacheddata(A)), broadcast(op, c, A.array)) -broadcasted(::LazyArrayStyle, op, A::CachedAbstractArray, c::Ref) = CachedAbstractArray(broadcast(op, cacheddata(A), c), broadcast(op, A.array, c)) -broadcasted(::LazyArrayStyle, op, c::Ref, A::CachedAbstractArray) = CachedAbstractArray(broadcast(op, c, cacheddata(A)), broadcast(op, c, A.array)) +broadcasted(::AbstractLazyArrayStyle, op, A::CachedAbstractArray, c::Number) = CachedAbstractArray(broadcast(op, cacheddata(A), c), broadcast(op, A.array, c)) +broadcasted(::AbstractLazyArrayStyle, op, c::Number, A::CachedAbstractArray) = CachedAbstractArray(broadcast(op, c, cacheddata(A)), broadcast(op, c, A.array)) +broadcasted(::AbstractLazyArrayStyle, op, A::CachedAbstractArray, c::Ref) = CachedAbstractArray(broadcast(op, cacheddata(A), c), broadcast(op, A.array, c)) +broadcasted(::AbstractLazyArrayStyle, op, c::Ref, A::CachedAbstractArray) = CachedAbstractArray(broadcast(op, c, cacheddata(A)), broadcast(op, c, A.array)) ### @@ -532,6 +566,8 @@ end sublayout(::CachedLayout{MLAY,ALAY}, ::Type{I}) where {MLAY,ALAY,I} = cachedlayout(sublayout(MLAY(),I), sublayout(ALAY,I)) +sublayout(::GenericCachedLayout, ::Type{I}) where I = GenericCachedLayout() + function resizedata!(V::SubArray, n::Integer...) resizedata!(parent(V), getindex.(parentindices(V), max.(1,n))...) V diff --git a/src/lazybroadcasting.jl b/src/lazybroadcasting.jl index 3cdb1f0c..5c66ac2b 100644 --- a/src/lazybroadcasting.jl +++ b/src/lazybroadcasting.jl @@ -1,4 +1,6 @@ -struct LazyArrayStyle{N} <: AbstractArrayStyle{N} end +abstract type AbstractLazyArrayStyle{N} <: AbstractArrayStyle{N} end + +struct LazyArrayStyle{N} <: AbstractLazyArrayStyle{N} end LazyArrayStyle(::Val{N}) where N = LazyArrayStyle{N}() LazyArrayStyle{M}(::Val{N}) where {N,M} = LazyArrayStyle{N}() @@ -7,8 +9,8 @@ LazyArrayStyle{M}(::Val{N}) where {N,M} = LazyArrayStyle{N}() layout_broadcasted(_, _, op, A, B) = Base.Broadcast.Broadcasted(Base.Broadcast.combine_styles(A,B), op, (A, B)) layout_broadcasted(op, A, B) = layout_broadcasted(MemoryLayout(A), MemoryLayout(B), op, A, B) -DefaultArrayStyle(::LazyArrayStyle{N}) where N = DefaultArrayStyle{N}() -broadcasted(::LazyArrayStyle, op, A, B) = layout_broadcasted(op, A, B) +DefaultArrayStyle(::AbstractLazyArrayStyle{N}) where N = DefaultArrayStyle{N}() +broadcasted(::AbstractLazyArrayStyle, op, A, B) = layout_broadcasted(op, A, B) for op in (:*, :/, :+, :-) @eval layout_broadcasted(::ZerosLayout, _, ::typeof($op), a, b) = broadcasted(DefaultArrayStyle(Base.Broadcast.combine_styles(a,b)), $op, a, b) @@ -74,10 +76,10 @@ _BroadcastArray(bc::Broadcasted) = BroadcastArray{combine_eltypes(bc.f, bc.args) BroadcastArray(bc::Broadcasted{S}) where S = _BroadcastArray(instantiate(Broadcasted{S}(bc.f, _broadcast2broadcastarray(bc.args...)))) -BroadcastArray(f, A, As...) = BroadcastArray(broadcasted(f, A, As...)) +BroadcastArray(f, A, As...) = BroadcastArray{combine_eltypes(f, (A,As...))}(f, A, As...) BroadcastArray{T}(f, A, As...) where T = BroadcastArray{T}(instantiate(broadcasted(f, A, As...))) -BroadcastMatrix(f, A...) = BroadcastMatrix(broadcasted(f, A...)) -BroadcastVector(f, A...) = BroadcastVector(broadcasted(f, A...)) +BroadcastMatrix(f, A...) = BroadcastMatrix{combine_eltypes(f, A)}(f, A...) +BroadcastVector(f, A...) = BroadcastVector{combine_eltypes(f, A)}(f, A...) BroadcastArray{T,N}(f, A...) where {T,N} = BroadcastArray{T,N,typeof(f),typeof(A)}(f, A) @@ -116,7 +118,7 @@ converteltype(::Type{T}, A::AbstractArray) where T = convert(AbstractArray{T}, A converteltype(::Type{T}, A) where T = convert(T, A) sub_materialize(::BroadcastLayout, A) = converteltype(eltype(A), sub_materialize(_broadcasted(A))) -copy(bc::Broadcasted{<:LazyArrayStyle}) = BroadcastArray(bc) +copy(bc::Broadcasted{<:AbstractLazyArrayStyle}) = BroadcastArray(bc) # BroadcastArray are immutable copy(bc::BroadcastArray) = bc @@ -159,7 +161,7 @@ BroadcastStyle(::Type{<:UpperOrLowerTriangular{<:Any,<:LazyMatrix}}) = LazyArray BroadcastStyle(::Type{<:LinearAlgebra.HermOrSym{<:Any,<:LazyMatrix}}) = LazyArrayStyle{2}() -BroadcastStyle(L::LazyArrayStyle{N}, ::StructuredMatrixStyle) where N = L +BroadcastStyle(L::AbstractLazyArrayStyle{N}, ::StructuredMatrixStyle) where N = L @@ -167,29 +169,29 @@ BroadcastStyle(L::LazyArrayStyle{N}, ::StructuredMatrixStyle) where N = L # Ranges already support smart broadcasting for op in (+, -, big) @eval begin - broadcasted(::LazyArrayStyle{1}, ::typeof($op), r::AbstractRange) = + broadcasted(::AbstractLazyArrayStyle{1}, ::typeof($op), r::AbstractRange) = broadcast(DefaultArrayStyle{1}(), $op, r) end end for op in (-, +, *, /) - @eval broadcasted(::LazyArrayStyle{1}, ::typeof($op), r::AbstractRange, x::Real) = broadcast(DefaultArrayStyle{1}(), $op, r, x) + @eval broadcasted(::AbstractLazyArrayStyle{1}, ::typeof($op), r::AbstractRange, x::Real) = broadcast(DefaultArrayStyle{1}(), $op, r, x) end for op in (-, +, *, \) - @eval broadcasted(::LazyArrayStyle{1}, ::typeof($op), x::Real, r::AbstractRange) = broadcast(DefaultArrayStyle{1}(), $op, x, r) + @eval broadcasted(::AbstractLazyArrayStyle{1}, ::typeof($op), x::Real, r::AbstractRange) = broadcast(DefaultArrayStyle{1}(), $op, x, r) end -broadcasted(::LazyArrayStyle{N}, op, r::AbstractFill{T,N}) where {T,N} = broadcast(DefaultArrayStyle{N}(), op, r) -broadcasted(::LazyArrayStyle{N}, op, r::AbstractFill{T,N}, x::Number) where {T,N} = broadcast(DefaultArrayStyle{N}(), op, r, x) -broadcasted(::LazyArrayStyle{N}, op, x::Number, r::AbstractFill{T,N}) where {T,N} = broadcast(DefaultArrayStyle{N}(), op, x, r) -broadcasted(::LazyArrayStyle{N}, op, r::AbstractFill{T,N}, x::Ref) where {T,N} = broadcast(DefaultArrayStyle{N}(), op, r, x) -broadcasted(::LazyArrayStyle{N}, op, x::Ref, r::AbstractFill{T,N}) where {T,N} = broadcast(DefaultArrayStyle{N}(), op, x, r) -broadcasted(::LazyArrayStyle{N}, op, r1::AbstractFill{T,N}, r2::AbstractFill{V,N}) where {T,V,N} = broadcast(DefaultArrayStyle{N}(), op, r1, r2) -broadcasted(::LazyArrayStyle{1}, ::typeof(*), a::AbstractFill, b::AbstractRange) = broadcast(DefaultArrayStyle{1}(), *, a, b) -broadcasted(::LazyArrayStyle{1}, ::typeof(*), a::AbstractRange, b::AbstractFill) = broadcast(DefaultArrayStyle{1}(), *, a, b) -broadcasted(::LazyArrayStyle{1}, ::typeof(*), a::Zeros{<:Any,1}, b::AbstractRange) = broadcast(DefaultArrayStyle{1}(), *, a, b) -broadcasted(::LazyArrayStyle{1}, ::typeof(*), a::AbstractRange, b::Zeros{<:Any,1}) = broadcast(DefaultArrayStyle{1}(), *, a, b) +broadcasted(::AbstractLazyArrayStyle{N}, op, r::AbstractFill{T,N}) where {T,N} = broadcast(DefaultArrayStyle{N}(), op, r) +broadcasted(::AbstractLazyArrayStyle{N}, op, r::AbstractFill{T,N}, x::Number) where {T,N} = broadcast(DefaultArrayStyle{N}(), op, r, x) +broadcasted(::AbstractLazyArrayStyle{N}, op, x::Number, r::AbstractFill{T,N}) where {T,N} = broadcast(DefaultArrayStyle{N}(), op, x, r) +broadcasted(::AbstractLazyArrayStyle{N}, op, r::AbstractFill{T,N}, x::Ref) where {T,N} = broadcast(DefaultArrayStyle{N}(), op, r, x) +broadcasted(::AbstractLazyArrayStyle{N}, op, x::Ref, r::AbstractFill{T,N}) where {T,N} = broadcast(DefaultArrayStyle{N}(), op, x, r) +broadcasted(::AbstractLazyArrayStyle{N}, op, r1::AbstractFill{T,N}, r2::AbstractFill{V,N}) where {T,V,N} = broadcast(DefaultArrayStyle{N}(), op, r1, r2) +broadcasted(::AbstractLazyArrayStyle{1}, ::typeof(*), a::AbstractFill, b::AbstractRange) = broadcast(DefaultArrayStyle{1}(), *, a, b) +broadcasted(::AbstractLazyArrayStyle{1}, ::typeof(*), a::AbstractRange, b::AbstractFill) = broadcast(DefaultArrayStyle{1}(), *, a, b) +broadcasted(::AbstractLazyArrayStyle{1}, ::typeof(*), a::Zeros{<:Any,1}, b::AbstractRange) = broadcast(DefaultArrayStyle{1}(), *, a, b) +broadcasted(::AbstractLazyArrayStyle{1}, ::typeof(*), a::AbstractRange, b::Zeros{<:Any,1}) = broadcast(DefaultArrayStyle{1}(), *, a, b) ### @@ -308,8 +310,8 @@ arguments(b::BroadcastLayout, A::Transpose) = map(_transpose, arguments(b, paren # broadcasting a transpose is the same as broadcasting it to the array and transposing # this allows us to collapse to one broadcast. -broadcasted(::LazyArrayStyle, op, A::Transpose{<:Any,<:BroadcastArray}) = transpose(broadcast(op, parent(A))) -broadcasted(::LazyArrayStyle, op, A::Adjoint{<:Real,<:BroadcastArray}) = adjoint(broadcast(op, parent(A))) +broadcasted(::AbstractLazyArrayStyle, op, A::Transpose{<:Any,<:BroadcastArray}) = transpose(broadcast(op, parent(A))) +broadcasted(::AbstractLazyArrayStyle, op, A::Adjoint{<:Real,<:BroadcastArray}) = adjoint(broadcast(op, parent(A))) # ensure we benefit from fast linear indexing getindex(A::Transpose{<:Any,<:BroadcastVector}, k::AbstractVector) = parent(A)[k] diff --git a/src/lazyconcat.jl b/src/lazyconcat.jl index 4a04d7bc..04d640dc 100644 --- a/src/lazyconcat.jl +++ b/src/lazyconcat.jl @@ -450,9 +450,9 @@ _flatten_nums(args::Tuple{}, bc::Tuple{}) = () _flatten_nums(args::Tuple, bc::Tuple) = (bc[1], _flatten_nums(tail(args), tail(bc))...) _flatten_nums(args::Tuple{Number, Vararg{Any}}, bc::Tuple{AbstractArray, Vararg{Any}}) = (Fill(bc[1],1), _flatten_nums(tail(args), tail(bc))...) -broadcasted(::LazyArrayStyle, op, A::Vcat) = Vcat(_flatten_nums(A.args, broadcast(x -> broadcast(op, x), A.args))...) -broadcasted(::LazyArrayStyle, op, A::Transpose{<:Any,<:Vcat}) = transpose(broadcast(op, parent(A))) -broadcasted(::LazyArrayStyle, op, A::Adjoint{<:Real,<:Vcat}) = broadcast(op, parent(A))' +broadcasted(::AbstractLazyArrayStyle, op, A::Vcat) = Vcat(_flatten_nums(A.args, broadcast(x -> broadcast(op, x), A.args))...) +broadcasted(::AbstractLazyArrayStyle, op, A::Transpose{<:Any,<:Vcat}) = transpose(broadcast(op, parent(A))) +broadcasted(::AbstractLazyArrayStyle, op, A::Adjoint{<:Real,<:Vcat}) = broadcast(op, parent(A))' for Cat in (:vcat, :hcat) diff --git a/src/linalg/mul.jl b/src/linalg/mul.jl index 6854b016..eb3bcfef 100644 --- a/src/linalg/mul.jl +++ b/src/linalg/mul.jl @@ -284,11 +284,11 @@ permutedims(A::ApplyArray{<:Any,2,typeof(*)}) = ApplyArray(*, reverse(map(permut ## for op in (:*, :\) - @eval broadcasted(::LazyArrayStyle{N}, ::typeof($op), a::Number, b::ApplyArray{<:Number,N,typeof(*)}) where N = + @eval broadcasted(::AbstractLazyArrayStyle{N}, ::typeof($op), a::Number, b::ApplyArray{<:Number,N,typeof(*)}) where N = ApplyArray(*, broadcast($op,a,first(b.args)), tail(b.args)...) end -broadcasted(::LazyArrayStyle{N}, ::typeof(/), b::ApplyArray{<:Number,N,typeof(*)}, a::Number) where N = +broadcasted(::AbstractLazyArrayStyle{N}, ::typeof(/), b::ApplyArray{<:Number,N,typeof(*)}, a::Number) where N = ApplyArray(*, Base.front(b.args)..., broadcast(/,last(b.args),a)) for Typ in (:Lmul, :Rmul) diff --git a/test/broadcasttests.jl b/test/broadcasttests.jl index bfc1c9eb..f148b06a 100644 --- a/test/broadcasttests.jl +++ b/test/broadcasttests.jl @@ -449,6 +449,35 @@ using Infinities @test A*B ≈ Matrix(A)*Matrix(B) @test simplifiable(*,A,B) == Val(false) # TODO: Why False? end + + @testset "misc tests" begin + bc = broadcasted(exp,[1,2,3]) + v = BroadcastArray(exp, [1,2,3]) + @test BroadcastArray(bc) == BroadcastVector(bc) == BroadcastVector{Float64,typeof(exp),typeof(bc.args)}(bc) == + v == BroadcastVector(exp, [1,2,3]) == exp.([1,2,3]) + + @test Base.IndexStyle(typeof(BroadcastVector(exp, [1,2,3]))) == IndexCartesian() + + bc = broadcasted(exp,[1 2; 3 4]) + M = BroadcastArray(exp, [1 2; 3 4]) + @test BroadcastArray(bc) == BroadcastMatrix(bc) == BroadcastMatrix{Float64,typeof(exp),typeof(bc.args)}(bc) == + M == BroadcastMatrix(BroadcastMatrix(bc)) == BroadcastMatrix(exp,[1 2; 3 4]) == exp.([1 2; 3 4]) + + @test exp.(v') isa Adjoint{<:Any,<:BroadcastVector} + @test exp.(transpose(v)) isa Transpose{<:Any,<:BroadcastVector} + @test exp.(M') isa Adjoint{<:Any,<:BroadcastMatrix} + @test exp.(transpose(M)) isa Transpose{<:Any,<:BroadcastMatrix} + + bc = BroadcastArray(broadcasted(+, 1:10, broadcasted(sin, 1:10))) + @test bc[1:10] == (1:10) .+ sin.(1:10) + + bc = BroadcastArray(broadcasted(+,1:10,broadcasted(+,1,2))) + @test bc.args[2] == 3 + + @testset "_vec_mul_arguments method" begin + @test_throws "MethodError: no method matching _vec_mul_arguments" LazyArrays._vec_mul_arguments(2, []) + end + end end end #module diff --git a/test/cachetests.jl b/test/cachetests.jl index 999d6c1b..135ef28f 100644 --- a/test/cachetests.jl +++ b/test/cachetests.jl @@ -459,7 +459,6 @@ using Infinities @test a[1:5] == zeros(5) end - @testset "Issue #327" begin A = cache(Zeros((1:5, OneToInf()))) B = cache(Zeros((1:5, OneToInf()))) @@ -488,6 +487,50 @@ using Infinities @test A == B end + @testset "copyto! with CachedArrayStyle" begin + a = Accumulate(*, 1:5); + b = BroadcastVector(*, 2, a); + dest = Vector{Int}(undef, 3) + src = view(b, 1:3); + bc = LazyArrays._broadcastarray2broadcasted(src); + @test similar(bc, Float32) == cache(zeros(Float32, 3)) && similar(bc, Float32) isa CachedArray{Float32} + @test a.datasize == (1,); + @inferred LazyArrays.resize_bcargs!(bc); + @test a.datasize == (3,) + dest = Vector{Int}(undef, 1) + src = view(b, 5:5); + bc = LazyArrays._broadcastarray2broadcasted(src); + @inferred LazyArrays.resize_bcargs!(bc); + @test a.datasize == (5,) + + a = Accumulate(*, 1:5); # reset to test different resizing + b = BroadcastVector(*, 2, a); + dest = Vector{Int}(undef, 4) + src = view(b,2:5) + bc = LazyArrays._broadcastarray2broadcasted(src); + rbc = LazyArrays.resize_bcargs!(bc); + @test Base.Broadcast.BroadcastStyle(typeof(rbc)) == Base.Broadcast.DefaultArrayStyle{1}() + @test rbc.f === bc.f + @test rbc.args == (2, a[2:5]) + + a = Accumulate(*, 1:5); # reset to ensure copyto! is working as intended + b = BroadcastVector(*, 2, a); + dest = Vector{Int}(undef, 3); + src = view(b,2:4); + copyto!(dest, src) + @test dest == [4,12,48] + + @testset "Matrix" begin + a = view(Accumulate(*, 1:10), 1:2) + b = rand(2, 6) + src = a .\ b + dest = zeros(2, 6) + res = Vector(a) .\ b + copyto!(dest, src) + @test dest == res + end + end + @testset "maybe_cacheddata" begin A = cache(1:10) @test maybe_cacheddata(A) === cacheddata(A) diff --git a/test/runtests.jl b/test/runtests.jl index c0c0cb35..6b68ff9d 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,6 +1,6 @@ using Test, LinearAlgebra, LazyArrays, FillArrays, ArrayLayouts, SparseArrays using StaticArrays -import LazyArrays: CachedArray, colsupport, rowsupport, LazyArrayStyle, broadcasted, +import LazyArrays: CachedArray, colsupport, rowsupport, LazyArrayStyle, broadcasted, resizedata!, ApplyLayout, BroadcastLayout, AddArray, LazyLayout, PaddedLayout, PaddedRows, PaddedColumns import ArrayLayouts: OnesLayout @@ -379,6 +379,9 @@ end @test a[end] ≈ prod(1 .+ (1:10_000_000).^(-2.0)) @test LazyArrays.AccumulateAbstractVector(*, 1:5) == Accumulate(*, 1:5) @test LazyArrays.AccumulateAbstractVector(*, 1:5) isa LazyArrays.AccumulateAbstractVector + + @test MemoryLayout(a) == LazyArrays.GenericCachedLayout() + @test MemoryLayout(view(a, 1:1)) == LazyArrays.GenericCachedLayout() end end @@ -441,35 +444,7 @@ end @test tril(A,1) isa ApplyMatrix{Float64,typeof(tril)} end -@testset "BroadcastArray" begin - bc = broadcasted(exp,[1,2,3]) - v = BroadcastArray(exp, [1,2,3]) - @test BroadcastArray(bc) == BroadcastVector(bc) == BroadcastVector{Float64,typeof(exp),typeof(bc.args)}(bc) == - v == BroadcastVector(exp, [1,2,3]) == exp.([1,2,3]) - - Base.IndexStyle(typeof(BroadcastVector(exp, [1,2,3]))) == IndexLinear() - - bc = broadcasted(exp,[1 2; 3 4]) - M = BroadcastArray(exp, [1 2; 3 4]) - @test BroadcastArray(bc) == BroadcastMatrix(bc) == BroadcastMatrix{Float64,typeof(exp),typeof(bc.args)}(bc) == - M == BroadcastMatrix(BroadcastMatrix(bc)) == BroadcastMatrix(exp,[1 2; 3 4]) == exp.([1 2; 3 4]) - - @test exp.(v') isa Adjoint{<:Any,<:BroadcastVector} - @test exp.(transpose(v)) isa Transpose{<:Any,<:BroadcastVector} - @test exp.(M') isa Adjoint{<:Any,<:BroadcastMatrix} - @test exp.(transpose(M)) isa Transpose{<:Any,<:BroadcastMatrix} - - bc = BroadcastArray(broadcasted(+, 1:10, broadcasted(sin, 1:10))) - @test bc[1:10] == (1:10) .+ sin.(1:10) - - bc = BroadcastArray(broadcasted(+,1:10,broadcasted(+,1,2))) - @test bc.args[2] == 3 - - @testset "_vec_mul_arguments method" begin - @test_throws "MethodError: no method matching _vec_mul_arguments" LazyArrays._vec_mul_arguments(2, []) - end -end include("blocktests.jl") include("bandedtests.jl") -include("blockbandedtests.jl") +include("blockbandedtests.jl") \ No newline at end of file