tomtom
February 27, 2020, 4:25am
1
docs said:
f.(args...) is equivalent to broadcast(f, args...)
however, I found that f.() is not calling broadcast(f, ):
Base.broadcast(::typeof(exp), x) = println("exp ", x);
x = [1.0, 2.0];
julia> Base.broadcast(exp, x)
exp [1.0, 2.0]
julia> exp.(x)
2-element Array{Float64,1}:
2.718281828459045
7.3890560989306495
in above, exp.() is not calling the broadcast() I tried to override. Is there any method to enforce it? thanks.
tomtom
February 27, 2020, 6:49am
3
I mean, why f.() not compiled into broadcast(f, ) ?
I donβt know the answer to that, but in case you didnβt know, hereβs how to check what is being called:
julia> @code_lowered (()->f.(x))()
CodeInfo(
1 β %1 = Base.broadcasted(Main.f, Main.x)
β %2 = Base.materialize(%1)
βββ return %2
tkf
February 27, 2020, 7:35am
5
Alternatively:
julia> Meta.@lower f.(x)
:($(Expr(:thunk, CodeInfo(
@ none within `top-level scope'
1 β %1 = Base.broadcasted(f, x)
β %2 = Base.materialize(%1)
βββ return %2
))))
broadcast(f, x) needs to return an array if x is an array. If f.(g.(x)) is lowered to broadcast(f, broadcast(g, x)), it would need to create intermediate array. Instead, julia does
julia> Meta.@lower f.(g.(x))
:($(Expr(:thunk, CodeInfo(
@ none within `top-level scope'
1 β %1 = Base.broadcasted(g, x)
β %2 = Base.broadcasted(f, %1)
β %3 = Base.materialize(%2)
βββ return %3
))))
If you read the manual youβd notice that broadcasted (note ed) does not do the actual computation. Rather, the actual computation is done in materialize without creating any intermediate arrays.
Itβs actually broadcast(f, ) that calls (the lowered version of) f.():
julia> string.(("one","two","three","four"), ": ", 1:4)
4-element Array{String,1}:
"one: 1"
"two: 2"
"three: 3"
"four: 4"
```
"""
broadcast(f::Tf, As...) where {Tf} = materialize(broadcasted(f, As...))
# special cases defined for performance
@inline broadcast(f, x::Number...) = f(x...)
@inline broadcast(f, t::NTuple{N,Any}, ts::Vararg{NTuple{N,Any}}) where {N} = map(f, t, ts...)
"""
broadcast!(f, dest, As...)
Like [`broadcast`](@ref), but store the result of
`broadcast(f, As...)` in the `dest` array.
3 Likes