Skip to content
Draft
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "LazyArrays"
uuid = "5078a376-72f3-5289-bfd5-ec5146d43c02"
version = "2.9.2"
version = "2.9.3"

[deps]
ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a"
Expand Down
9 changes: 8 additions & 1 deletion ext/LazyArraysBandedMatricesExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import LazyArrays: sublayout, symmetriclayout, hermitianlayout, applylayout, cac
PaddedColumns, CachedArray, CachedMatrix, LazyLayout, BroadcastLayout, ApplyLayout,
paddeddata, resizedata!, broadcastlayout, _broadcastarray2broadcasted, _broadcast_sub_arguments,
arguments, call, applybroadcaststyle, simplify, simplifiable, islazy_layout, lazymaterialize, _broadcast_mul_mul, _broadcast_mul_simplifiable,
triangularlayout, AbstractCachedMatrix, cache_layout, _mulbanded_copyto!, ApplyBandedLayout, BroadcastBandedLayout
triangularlayout, AbstractCachedMatrix, cache_layout, _mulbanded_copyto!, ApplyBandedLayout, BroadcastBandedLayout, CachedArrayStyle
import Base: BroadcastStyle, similar, copy, broadcasted, getindex, OneTo, oneto, tail, sign, abs
import BandedMatrices: bandedbroadcaststyle, bandwidths, isbanded, bandedcolumns, bandeddata, BandedStyle,
AbstractBandedLayout, AbstractBandedMatrix, BandedColumns, BandedRows, BandedSubBandedMatrix,
Expand All @@ -25,12 +25,18 @@ hermitianlayout(::Type{<:Complex}, ::AbstractLazyBandedLayout) = HermitianLayout


bandedbroadcaststyle(::AbstractLazyArrayStyle) = LazyArrayStyle{2}()
bandedbroadcaststyle(::CachedArrayStyle) = CachedArrayStyle{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}()

BroadcastStyle(::CachedArrayStyle{1}, ::BandedStyle) = CachedArrayStyle{2}()
BroadcastStyle(::BandedStyle, ::CachedArrayStyle{1}) = CachedArrayStyle{2}()
BroadcastStyle(::CachedArrayStyle{2}, ::BandedStyle) = CachedArrayStyle{2}()
BroadcastStyle(::BandedStyle, ::CachedArrayStyle{2}) = CachedArrayStyle{2}()

bandedcolumns(::AbstractLazyLayout) = BandedColumns{LazyLayout}()
bandedcolumns(::DualLayout{<:AbstractLazyLayout}) = BandedColumns{LazyLayout}()

Expand Down Expand Up @@ -428,6 +434,7 @@ isbanded(::AbstractPaddedLayout, A) = true # always treat as banded
const HcatBandedMatrix{T,N} = Hcat{T,NTuple{N,BandedMatrix{T,Matrix{T},OneTo{Int}}}}
const VcatBandedMatrix{T,N} = Vcat{T,2,NTuple{N,BandedMatrix{T,Matrix{T},OneTo{Int}}}}

BroadcastStyle(::Type{HcatBandedMatrix{T,0}}) where {T} = LazyArrayStyle{2}() # This method is needed for e.g. Hcat(), which would otherwise get recognised as a BandedStyle, giving different behaviour before-and-after loading BandedMatrices
BroadcastStyle(::Type{HcatBandedMatrix{T,N}}) where {T,N} = BandedStyle()
BroadcastStyle(::Type{VcatBandedMatrix{T,N}}) where {T,N} = BandedStyle()

Expand Down
2 changes: 1 addition & 1 deletion src/LazyArrays.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import Base: *, +, -, /, <, ==, >, \, ≤, ≥, (:), @_gc_preserve_begin, @_gc_p
oneto, add_sum, promote_op

import Base.Broadcast: AbstractArrayStyle, BroadcastStyle, Broadcasted, DefaultArrayStyle, broadcasted, combine_eltypes,
instantiate
instantiate, result_style, Unknown

import LinearAlgebra: AbstractQ, AdjOrTrans, StructuredMatrixStyle, checksquare, det, diag, dot, lmul!, logabsdet,
norm1, norm2, normInf, normp, pinv, rmul!, tr, tril, triu
Expand Down
91 changes: 89 additions & 2 deletions src/cache.jl
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ cacheddata(A::Transpose) = transpose(cacheddata(parent(A)))

maybe_cacheddata(A::AbstractCachedArray) = cacheddata(A)
maybe_cacheddata(A::SubArray{<:Any,N,<:AbstractCachedArray}) where N = cacheddata(A)
maybe_cacheddata(A::Adjoint) = adjoint(maybe_cacheddata(parent(A)))
maybe_cacheddata(A::Transpose) = transpose(maybe_cacheddata(parent(A)))
maybe_cacheddata(A) = A # no-op

convert(::Type{AbstractArray{T}}, S::CachedArray{T}) where T = S
Expand Down Expand Up @@ -228,9 +230,13 @@ resizedata!(B::CachedArray, mn...) = resizedata!(MemoryLayout(B.data), MemoryLay
resizedata!(B::AbstractCachedArray, mn...) = resizedata!(MemoryLayout(B.data), UnknownLayout(), B, mn...)
resizedata!(A, mn...) = A # don't do anything
function resizedata!(A::AdjOrTrans, m, n)
m ≤ 0 || resizedata!(parent(A), n)
resizedata!(parent(A), n, m)
A
end
function resizedata!(A::AdjOrTrans{<:Any, <:AbstractVector}, m, n)
resizedata!(parent(A), n)
A
end

function cache_filldata!(B, inds...)
B.data[inds...] .= view(B.array,inds...)
Expand Down Expand Up @@ -611,4 +617,85 @@ CachedArray(data::AbstractMatrix, array::AbstractQ) = CachedArray(data, array, s
CachedArray(data::AbstractMatrix{T}, array::AbstractQ{T}, datasize::NTuple{2,Int}) where T =
CachedMatrix{T,typeof(data),typeof(array)}(data, array, datasize)

length(A::CachedMatrix{<:T,<:AbstractMatrix{T},<:AbstractQ{T}}) where T = prod(size(A.array))
length(A::CachedMatrix{<:T,<:AbstractMatrix{T},<:AbstractQ{T}}) where T = prod(size(A.array))

##
# Tuples of potential cached arrays
# Assumes that the Tuples contain arrays of the same shape
# Some of the complication here is in making sure that we can handle things like mixing vectors and matrices that have one column
##
@inline _tuple_wrap(x::Int) = (x,) # Some CachedArrays mistakenly use Int instead of Tuple for vector sizes (e.g. https://github.com/JuliaApproximation/SemiclassicalOrthogonalPolynomials.jl/blob/a29007f2815134180b8433fdab46a23acfcdcd01/src/neg1c.jl#L19 and https://github.com/DanielVandH/InfiniteRandomArrays.jl/blob/a859d565f5bd8278d3f3499cd26b62916b4867e0/src/vector.jl#L18, to name a couple)
@inline _tuple_wrap(x::Tuple) = x
@inline _datasize(x) = size(x)
@inline _datasize(::Number) = (1,) # Numbers have size (), but we treat them as size (1,) for resizing purposes
@inline _datasize(x::AbstractCachedArray) = x.datasize
@inline _datasize(x::SubArray) = _datasize(parent(x))
@inline _datasize(x::AdjOrTrans) = reverse(_datasize(parent(x)))
@inline _datasize(x::AdjOrTrans{<:Any, <:AbstractVector}) = (sz = only(_datasize(parent(x))); (min(1, sz), sz))
@inline _datasizes(::Tuple{}) = ()
@inline _datasizes(t::Tuple) = (_datasize(first(t)), _datasizes(Base.tail(t))...) # equivalent to _datasize.(t)

@inline _has_vector(::Tuple{}) = false # Numbers have size ()
@inline _has_vector(::Tuple{Any}) = true
@inline _has_vector(::Tuple{Any, Vararg}) = false
@inline has_vector(::Tuple{}) = false
@inline has_vector(t::Tuple) = _has_vector(first(t)) || has_vector(Base.tail(t))
@inline to_vector_size(sz::Tuple{Any}) = sz # Already 1-tuple
@inline to_vector_size(sz::Tuple{Any, Vararg}) = (prod(sz),) # Multi-tuple -> 1-tuple

function max_datasize(sizes::Tuple)
if has_vector(sizes)
normalized = map(to_vector_size, sizes)
return reduce(@inline((a, b) -> max.(a, b)), normalized)
else
return reduce(@inline((a, b) -> max.(a, b)), sizes)
end
end

@inline _expand_size(sz::Tuple{Any}, ::Tuple{Any}) = sz
@inline _expand_size(sz::Tuple{Any}, ::Tuple{Any, Vararg}) = (only(sz), 1)
@inline _expand_size(sz::Tuple{Any, Vararg}, ::Tuple{Any, Vararg}) = sz

@inline _effective_ndims(sz::Int) = 1
@inline function _effective_ndims(sz::Tuple)
length(sz) == 1 && return 1
length(sz) == 2 && minimum(sz) <= 1 && return 1
return length(sz)
end

@inline _all_same_ndims(::Tuple{}) = true
@inline _all_same_ndims(t::Tuple{Any}) = true
@inline function _all_same_ndims(t::Tuple)
first_sz = _arraysize(first(t))
first_ndim = _effective_ndims(first_sz)
_check_same_ndims_args(first_ndim, Base.tail(t))
end

@inline _check_same_ndims_args(::Int, ::Tuple{}) = true
@inline function _check_same_ndims_args(expected_ndim::Int, t::Tuple)
sz = _arraysize(first(t))
_effective_ndims(sz) == expected_ndim && _check_same_ndims_args(expected_ndim, Base.tail(t))
end

@inline _arraysize(x::Number) = (1,)
@inline _arraysize(x) = size(x)

function conforming_resize!(args::Tuple)
isempty(args) && return args
if !_all_same_ndims(args)
throw(ArgumentError("Cannot conform arrays with incompatible dimensions: $(map(_arraysize, args))"))
end
sizes = _datasizes(args)
sz = max_datasize(sizes)
_resize_each!(args, sizes, sz)
return args
end

@inline _resize_each!(::Tuple{}, ::Tuple{}, sz) = nothing
@inline function _resize_each!(args::Tuple, sizes::Tuple, sz)
arg = first(args)
orig_sz = first(sizes)
target_sz = _expand_size(sz, orig_sz)
resizedata!(arg, target_sz...)
_resize_each!(Base.tail(args), Base.tail(sizes), sz)
end
11 changes: 10 additions & 1 deletion src/lazyapplying.jl
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,11 @@ AbstractArray{T,N}(A::ApplyArray{<:Any,N}) where {T,N} = ApplyArray{T,N}(A.f, ma

@inline applied_axes(f, args...) = map(oneto, applied_size(f, args...))


function cacheddata(A::ApplyArray{T, N, F}) where {T, N, F}
args = arguments(A)
conforming_resize!(args)
ApplyArray{T, N}(A.f, map(maybe_cacheddata, args)...)
end

# immutable arrays don't need to copy.
# Some special cases like vcat overload setindex! and therefore
Expand Down Expand Up @@ -329,8 +333,13 @@ function show(io::IO, A::Applied)
print(io, ')')
end

_BroadcastStyle(x...) = BroadcastStyle(x...)
_BroadcastStyle(::Type{<:AbstractQ}) = DefaultArrayStyle{2}()

applybroadcaststyle(::Type{<:AbstractArray{<:Any,N}}, _2) where N = DefaultArrayStyle{N}()
applybroadcaststyle(::Type{<:AbstractArray{<:Any,N}}, ::AbstractLazyLayout) where N = LazyArrayStyle{N}()
applybroadcaststyle(::Type{<:ApplyArray{<:Any,N,<:Any,Args}}, ::AbstractLazyLayout) where {N,Args<:Tuple} = result_style(LazyArrayStyle{N}(), tuple_type_broadcastlayout(Args))
applybroadcaststyle(::Type{<:SubArray{<:Any,<:Any,P}}, lay::AbstractLazyLayout) where {P} = applybroadcaststyle(P, lay)
BroadcastStyle(M::Type{<:ApplyArray}) = applybroadcaststyle(M, MemoryLayout(M))
BroadcastStyle(M::Type{<:SubArray{<:Any,N,<:ApplyArray}}) where N = applybroadcaststyle(M, MemoryLayout(M))

Expand Down
8 changes: 8 additions & 0 deletions src/lazybroadcasting.jl
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ end
const BroadcastVector{T,F,Args} = BroadcastArray{T,1,F,Args}
const BroadcastMatrix{T,F,Args} = BroadcastArray{T,2,F,Args}

BroadcastStyle(::Type{<:BroadcastArray{<:Any,N,<:Any,Args}}) where {N,Args<:Tuple} = result_style(LazyArrayStyle{N}(), tuple_type_broadcastlayout(Args))

LazyArray(bc::Broadcasted) = BroadcastArray(bc)

BroadcastArray{T,N,F,Args}(bc::Broadcasted) where {T,N,F,Args} = BroadcastArray{T,N,F,Args}(bc.f,bc.args)
Expand Down Expand Up @@ -120,6 +122,12 @@ sub_materialize(::BroadcastLayout, A) = converteltype(eltype(A), sub_materialize

copy(bc::Broadcasted{<:AbstractLazyArrayStyle}) = BroadcastArray(bc)

function cacheddata(A::BroadcastArray{T, N, F}) where {T, N, F}
args = arguments(A)
conforming_resize!(args)
BroadcastArray{T, N}(A.f, map(maybe_cacheddata, args)...)
end

# BroadcastArray are immutable
copy(bc::BroadcastArray) = bc
map(::typeof(copy), bc::BroadcastArray) = bc
Expand Down
14 changes: 11 additions & 3 deletions src/lazyconcat.jl
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ function vcat_copyto!(arr::AbstractVector, arrays...)
i = firstindex(arr)
for a in arrays
m = length(a)
copyto!(view(arr, range(i, length=m)), a)
m > 0 && copyto!(view(arr, range(i, length=m)), a)
i += m
end
arr
Expand Down Expand Up @@ -439,8 +439,16 @@ end
# to take advantage of special implementations of the sub-components
######

BroadcastStyle(::Type{<:Vcat{<:Any,N}}) where N = LazyArrayStyle{N}()
BroadcastStyle(::Type{<:Hcat{<:Any}}) = LazyArrayStyle{2}()
@inline tuple_type_broadcastlayout(::Type{I}) where {I<:Tuple} = result_style(_BroadcastStyle(Base.tuple_type_head(I)), tuple_type_broadcastlayout(Base.tuple_type_tail(I)))
@inline tuple_type_broadcastlayout(::Type{Tuple{}}) = Unknown()
@inline tuple_type_broadcastlayout(::Type{Tuple{A}}) where {A} = _BroadcastStyle(A)
@inline tuple_type_broadcastlayout(::Type{Tuple{A,B}}) where {A,B} = result_style(_BroadcastStyle(A), _BroadcastStyle(B))
@inline tuple_type_broadcastlayout(::Type{Tuple{A,B,C}}) where {A,B,C} = result_style(_BroadcastStyle(A), tuple_type_broadcastlayout(Tuple{B,C}))
@inline tuple_type_broadcastlayout(::Type{Tuple{A,B,C,D}}) where {A,B,C,D} = result_style(_BroadcastStyle(A), tuple_type_broadcastlayout(Tuple{B,C,D}))
@inline tuple_type_broadcastlayout(::Type{Tuple{A,B,C,D,E}}) where {A,B,C,D,E} = result_style(_BroadcastStyle(A), tuple_type_broadcastlayout(Tuple{B,C,D,E}))

BroadcastStyle(::Type{<:Vcat{<:Any,N,I}}) where {N,I<:Tuple} = result_style(LazyArrayStyle{N}(), tuple_type_broadcastlayout(I)) # the <:Tuple is to avoid ambiguity
BroadcastStyle(::Type{<:Hcat{<:Any,I}}) where {I<:Tuple} = result_style(LazyArrayStyle{2}(), tuple_type_broadcastlayout(I))

# This is if we broadcast a function on a mixed concat f.([1; [2,3]])
# such that f returns a vector, e.g., f(1) == [1,2], we don't want
Expand Down
26 changes: 18 additions & 8 deletions src/lazyoperations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -438,25 +438,35 @@ copy(Q::Accumulate) = Accumulate(Q.op, copy(Q.data), copy(Q.v), Q.dims, Q.datasi
copyto!(x::AbstractArray{<:Any,N}, C::Cumsum{<:Any,N}) where N = cumsum!(x, C.v)

# How we populate the data
function cache_filldata!(K::Accumulate{<:Any,1}, inds)
copyto!(view(K.data,inds), view(K.v,inds))
function _accumulate_cache_filldata_1d!(data, v, op::F, inds) where {F}
copyto!(view(data,inds), view(v,inds))
@inbounds for k in inds
K.data[k] = K.op(K.data[k-1], K.data[k])
data[k] = op(data[k-1], v[k])
end
end

function cache_filldata!(K::Accumulate{<:Any,2}, kr, jr)
if K.dims == 1
function cache_filldata!(K::Accumulate{<:Any,1}, inds)
_accumulate_cache_filldata_1d!(K.data, K.v, K.op, inds)
end

function _accumulate_cache_filldata_2d!(data, v, op::F, kr, jr, dims) where {F}
if dims == 1
copyto!(view(data, kr, jr), view(v, kr, jr))
@inbounds for j in jr, k in kr
K.data[k,j] = K.op(K.data[k-1,j], K.v[k,j])
data[k,j] = op(data[k-1,j], v[k,j])
end
else # K.dims == 2
else # dims == 2
copyto!(view(data, kr, jr), view(v, kr, jr))
@inbounds for j in jr, k in kr
K.data[k,j] = K.op(K.data[k,j-1], K.v[k,j])
data[k,j] = op(data[k,j-1], v[k,j])
end
end
end

function cache_filldata!(K::Accumulate{<:Any,2}, kr, jr)
_accumulate_cache_filldata_2d!(K.data, K.v, K.op, kr, jr, K.dims)
end


# keep lazy
cumsum(a::LazyArray; kwds...) = Cumsum(a; kwds...)
Expand Down
2 changes: 0 additions & 2 deletions src/padded.jl
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,6 @@ _vcat_resizedata!(_, B, m...) = B # by default we can't resize

resizedata!(B::Vcat, m...) = _vcat_resizedata!(MemoryLayout(B), B, m...)

cacheddata(B::Vcat) = Vcat(map(maybe_cacheddata, arguments(B))...)

function ==(A::CachedVector{<:Any,<:Any,<:Zeros}, B::CachedVector{<:Any,<:Any,<:Zeros})
length(A) == length(B) || return false
n = max(A.datasize[1], B.datasize[1])
Expand Down
19 changes: 14 additions & 5 deletions test/applytests.jl
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
module ApplyTests

using LazyArrays, FillArrays, ArrayLayouts, Test
import LazyArrays: materialize, broadcasted, DefaultApplyStyle, Applied, arguments,
ApplyArray, ApplyMatrix, ApplyVector, LazyArrayApplyStyle, ApplyLayout, call
import ArrayLayouts: StridedLayout
using LinearAlgebra
using LazyArrays, FillArrays, ArrayLayouts, Test
import LazyArrays: materialize, broadcasted, DefaultApplyStyle, Applied, arguments,
ApplyArray, ApplyMatrix, ApplyVector, LazyArrayApplyStyle, ApplyLayout, call,
CachedArrayStyle, CachedArray, LazyArrayStyle
import ArrayLayouts: StridedLayout
import Base.Broadcast: BroadcastStyle
using LinearAlgebra

@testset "Applying" begin
@testset "Applied" begin
Expand Down Expand Up @@ -121,6 +123,13 @@ using LinearAlgebra
end
@test colsupport(M,1) == 1:5
end

@testset "BroadcastStyle with a cached argument" begin
A = ApplyArray(*, rand(10, 2), rand(2, 2))
@test BroadcastStyle(typeof(A)) == BroadcastStyle(typeof(A')) == BroadcastStyle(typeof(view(A, 1:2, 1:2))) == LazyArrayStyle{2}()
A = ApplyArray(*, CachedArray(rand(10, 2)), rand(2, 2))
@test BroadcastStyle(typeof(A)) == BroadcastStyle(typeof(A')) == BroadcastStyle(typeof(view(A, 1:2, 1:2))) == CachedArrayStyle{2}()
end
end # testset

end # module
16 changes: 15 additions & 1 deletion test/bandedtests.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
module LazyBandedTests
using ArrayLayouts, LazyArrays, BandedMatrices, LinearAlgebra, Test
using BandedMatrices: AbstractBandedLayout, _BandedMatrix, isbanded, BandedStyle, BandedColumns, BandedRows, resize, bandeddata
using LazyArrays: PaddedLayout, PaddedRows, PaddedColumns, arguments, call, LazyArrayStyle, ApplyLayout, simplifiable, resizedata!, MulStyle, LazyLayout, BroadcastLayout
using LazyArrays: PaddedLayout, PaddedRows, Accumulate, PaddedColumns, arguments, call, LazyArrayStyle, ApplyLayout, simplifiable, resizedata!, MulStyle, LazyLayout, BroadcastLayout, CachedArrayStyle
using ArrayLayouts: OnesLayout, StridedLayout
import Base.Broadcast: BroadcastStyle
LazyArraysBandedMatricesExt = Base.get_extension(LazyArrays, :LazyArraysBandedMatricesExt)
BroadcastBandedLayout = LazyArraysBandedMatricesExt.BroadcastBandedLayout
ApplyBandedLayout = LazyArraysBandedMatricesExt.ApplyBandedLayout
Expand Down Expand Up @@ -967,6 +968,19 @@ LinearAlgebra.lmul!(β::Number, A::PseudoBandedMatrix) = (lmul!(β, A.data); A)
@test A\D ≈ (B*B)\D
@test D\A ≈ D\(B*B)
end

@testset "BroadcastStyle with cached data" begin
A = _BandedMatrix(Accumulate(*, 1:10)', 1:10, 0, 0)
@test BroadcastStyle(typeof(A)) == CachedArrayStyle{2}()
@test BroadcastStyle(typeof(A')) == CachedArrayStyle{2}()
end

@testset "Combining BandedStyle with CachedArrayStyle" begin
@test BroadcastStyle(CachedArrayStyle{1}(), BandedStyle()) == CachedArrayStyle{2}()
@test BroadcastStyle(BandedStyle(), CachedArrayStyle{1}()) == CachedArrayStyle{2}()
@test BroadcastStyle(CachedArrayStyle{2}(), BandedStyle()) == CachedArrayStyle{2}()
@test BroadcastStyle(BandedStyle(), CachedArrayStyle{2}()) == CachedArrayStyle{2}()
end
end

end # module
10 changes: 9 additions & 1 deletion test/broadcasttests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ module BroadcastTests

using LazyArrays, ArrayLayouts, LinearAlgebra, FillArrays, Base64, Test
using StaticArrays, Tracker
import LazyArrays: BroadcastLayout, arguments, LazyArrayStyle, sub_materialize, simplifiable
import LazyArrays: BroadcastLayout, CachedArrayStyle, arguments, LazyArrayStyle, sub_materialize, simplifiable
import Base: broadcasted
import Base.Broadcast: BroadcastStyle

using ..InfiniteArrays
using Infinities
Expand Down Expand Up @@ -478,6 +479,13 @@ using Infinities
@test_throws "MethodError: no method matching _vec_mul_arguments" LazyArrays._vec_mul_arguments(2, [])
end
end

@testset "BroadcastStyle" begin
@test BroadcastStyle(typeof(BroadcastVector(exp, 1:10))) == LazyArrayStyle{1}()
@test BroadcastStyle(typeof(BroadcastVector(+, 1:10, cache(1:10)))) == CachedArrayStyle{1}()
@test BroadcastStyle(typeof(BroadcastMatrix(*, Accumulate(*, 1:10)', rand(10)'))) == CachedArrayStyle{2}()
@test BroadcastStyle(typeof(BroadcastMatrix(*, rand(5, 5)', LazyArrays.CachedArray(rand(5, 5))))) == CachedArrayStyle{2}()
end
end

end #module
Loading
Loading