API
Featured functions and macros
LazyBroadcast defines two exported functions:
lazy_broadcast- the main feature of LazyBroadcast, which turns broadcast expressions into lazy broadcasted objects.@lazy_broadcast- which allows users to calllazy_broadcastwithout parenthesis.
and two un-exported functions (un-exported intentionally to avoid name collisions)
lazy- an alias oflazy_broadcast@lazy- an alias of@lazy_broadcast
lazy_broadcast
LazyBroadcast.lazy_broadcast — Functionfunction lazy_broadcast end # exported
const lazy = lazy_broadcast # not exportedThis function has no methods and is only meant to be used to consume a broadcast expression, causing it to not materialize, allowing it to be used in a lazy manner and be consumed later.
For example, consider the situation where one wants to break up a complicated broadcast expression into multiple steps, and then sum up all of the components:
julia> using BenchmarkTools
julia> function foo(x)
           y = x .+ x
           z = 2 .* y
           sum(z)
       end;
julia> @btime foo(v) setup=(v=rand(10))
  43.096 ns (2 allocations: 288 bytes)
20.37839658590829This is significantly slower than it needs to be because new arrays need to be allocated for y and z, and the data needs to be passed over multiple times because the broadcast kernels are not 'fused'.
DontMaterialize gives a simple way to avoid these allocations and retain broadcast fusion:
julia> using BenchmarkTools, LazyBroadcast
julia> function foo_lazy(x)
           y = lazy_broadcast.(x .+ x)
           z = lazy_broadcast.(2 .* y)
           sum(z)
       end;
julia> @btime foo_lazy(v) setup=(v=rand(10))
  5.958 ns (0 allocations: 0 bytes)
23.002907370961225the result of a lazy_broadcast call can be collected into an array with the materialize function (re-exported here from Base.Broadcast):
julia> lazy_broadcast.(2 .* [1,2,3])
Broadcasted{Base.Broadcast.DefaultArrayStyle{1}}(*, (2, [1, 2, 3]))
julia> materialize(ans)
3-element Vector{Int64}:
 2
 4
 6