-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Lazy addition? #8
Comments
I don't think it's needed as we already have |
Nice. Does |
They way I would support that is via the syntax: y .= α .* Mul(A .+ B, x) .+ β .* y This could by made to lower to the non-allocating version by having
|
OK. I guess shouldn't be referring to the implementation too much at this point. But I suppose that there is no direct support for lmul!(β, y)
mul!(y, A, x, α, 1)
mul!(y, B, x, α, 1) at the moment in LazyArrays.jl but you agree that it's nice to have? |
BTW, IIUC, I don't think we can use julia> Meta.lower(Main, :(y .= α .* Mul(A .+ B, x) .+ β .* y))
:($(Expr(:thunk, CodeInfo(
1 ─ %1 = (Base.broadcasted)(+, A, B)
│ %2 = (Base.materialize)(%1)
│ %3 = Mul(%2, x)
│ %4 = (Base.broadcasted)(*, α, %3)
│ %5 = (Base.broadcasted)(*, β, y)
│ %6 = (Base.broadcasted)(+, %4, %5)
│ %7 = (Base.materialize!)(y, %6)
└── return %7
)))) |
Yes you are right. We can use y .= α .* Mul(Add(A , B), x) .+ β .* y Note that this is lowered to the following, which perhaps you prefer: materialize!(MulAdd(α, Add(A,B), x, β, y)) |
Got it, thanks for the explanation. I'll be trying to write it (unless you can do it in 10 minutes or something). |
It would take a bit more than 10 minutes but the steps are roughly:
struct BroadcastLayout{F, LAY} <: MemoryLayout
f::F
layouts::LAY
end
MemoryLayout(A::BroadcastArray) = BroadcastLayout(A.broadcasted.f, MemoryLayout.(A.broadcasted.args))
function materialize!(M::MulAdd{<:BroadcastLayout{typeof(+)}})
lmul!(M.β, M.y)
for A in M.A.broadcasted.args
M.y .= M.α .* Mul(A, M.x) .+ M.y
end
M.y
end If you prefer a more explicit style, the main line could look like This should actually support more than two additions. |
By the way, I consider this package still "experimental" and am happy to redesign things if there are any good suggestions. The current design is a bit esoteric but there was good reasons for it, and its proven very successful in BlockBandedMatrices.jl. |
Thanks for the guideline! I was looking at the code and my answer so far was const Add = BroadcastArray{<:Any, <:Any, <:Broadcasted{<:Any, <:Any, typeof(+)}}
function default_blasmul!(α, A::AbstractMatrix, B::Add, β, C::AbstractVecOrMat)
if iszero(β)
fill!(C, 0)
else
lmul!(β, C)
end
for b in B.broadcasted.args
default_blasmul!(α, A, B, true, C)
end
return C
end I should learn how
I like
I'm new to this library so I better be learning "LazyArrays.jl way" for a while. But I'd suggest things anyway :) (1) I think it still would be nice to provide an "adapter" interface for |
In the currently tagged version it's the other way around: The catch is that it's better to fall back on the 5-argument version, but there is no 5-argument
LinearAlgebra doesn't have a 5-argument But this is an easy fix to support the 5-argument one by just adding it to the
Yes! The only reason this hasn't been added is its good to get the "right" syntax. I'm not sure what the "right" one is. |
What I mean by compositionality is something like the following. Suppose that I wrote some code before knowing LazyArrays.jl: function f(du, u, A, t)
du .= .- u .+ tanh.(mul!(du, A, u))
end
A = sprand(100, 100, 0.1)
ode = ODEProblem(f, u0, tspan, A) If LazyArrays.jl exposes B = -0.1 * Eye(100)
M = Add(A, B) # This is a highly structured matrix so I don't want to materialize it.
ode = ODEProblem(f, u0, tspan, M) Of course, since it's my code, I can rewrite my function
Great. So why not just do const Add = BroadcastArray{<:Any, <:Any, <:Broadcasted{<:Any, <:Any, typeof(+)}}
@lazymul Add{<:Any, 2} ? |
I’ve sent a message to @mbauman to discuss the long term plan for Note there’s currently a debate in BlockArrays.jl whether to use LazyArrays.jl JuliaArrays/BlockArrays.jl#31 |
Thanks for being open for suggestion. But I'm still puzzled with
Wouldn't just defining mul!(C::AbstractVecOrMat, A::Mul, B::AbstractVecOrMat) = (C .= Mul(A, B); C) provide a
Thanks, I actually was about to ask this next :) |
Actually, I found that |
Let me reply to your comment #9 (comment) here (as it's not implementation-specific)
I thought about it, but
I'm OK with writing |
I think PR JuliaLang/julia#9 is definitely worth having, the question is whether it's restricted to |
Great. Thanks a lot for merging JuliaLang/julia#9 and all the discussion! I still want an easier API/alias but I guess that would be JuliaLang/julia#10. |
Are you planning to implement lazy addition
Add(A, B)
similar toMul(A, B)
? By that I mean a lazy object such thatmul!(y, Add(A, B), x, α, β)
lowers intoIf you are OK with it, I think I can write up a PR.
(In fact, I've written something like this a while ago https://github.com/tkf/MatrixCombinators.jl but I thought I'd better contribute to this package since it's much more feature complete.)
The text was updated successfully, but these errors were encountered: