Skip to content
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

Support ChainRulesCore.Tangent? #20

Closed
oschulz opened this issue Aug 7, 2021 · 9 comments
Closed

Support ChainRulesCore.Tangent? #20

oschulz opened this issue Aug 7, 2021 · 9 comments

Comments

@oschulz
Copy link
Contributor

oschulz commented Aug 7, 2021

I realized that currently, Functors doesn't support ChainRulesCore.Tangent:

using Functors, ChainRulesCore
x = (a = 2, b = 3)
dx = Tangent{typeof(x)](a = 4, b = 9)
Functors.functor(dx)

results in

((), Functors.var"#1#2"{Tangent{NamedTuple{(:a, :b), Tuple{Int64, Int64}}, NamedTuple{(:a, :b), Tuple{Int64, Int64}}}}(Tangent{NamedTuple{(:a, :b), Tuple{Int64, Int64}}}(a = 4, b = 9)))

Typical use cases of Functors will usually use re of x instead of dx of course - still, it might be nice to support functor for tangents.

@darsnack
Copy link
Member

darsnack commented Aug 7, 2021

This is something ChainRulesCore.jl has to do by calling @functor Tangent. Functors.jl itself doesn't define any functors.

cc @oxinabox

@DhairyaLGandhi
Copy link
Member

This is where the NamedTuple versions make a lot more sense since those are implicitly functors themselves. Or at least have the same underlying tree as the original.

@ToucheSir
Copy link
Member

This is the dual of FluxML/Zygote.jl#1042. One could imagine a Functor{T} type that works much like Tangent, but the question is whether the two are similar enough that they can be unified. Either way, the type will require a custom functor implementation because the list of fields is dynamic.

@oschulz
Copy link
Contributor Author

oschulz commented Aug 16, 2021

I guess I should move this issue to ChainRulesCore - I thought it might be doable with some generic magic, like Functors does for some other things - if it needs a custom functor implementation, that should go into CRC, or course.

@oschulz
Copy link
Contributor Author

oschulz commented Aug 16, 2021

Moved to JuliaDiff/ChainRulesCore.jl#439

@DhairyaLGandhi
Copy link
Member

DhairyaLGandhi commented Aug 16, 2021

Well, since Tangent is a very generic container of sorts, one can imagine it does share the same representation of the tree as regular models would. That is, after all, its job. It may only have incomplete information because not all fields would have a corresponding bit in the Tangent, but that can be handled in the function doing the operation itself. At the very least, one would expect that all the leaves are present.

We make use of the fact that the trees are similar to do structural optimisation in the upcoming DDP stuff too and that works with the way zygote returns the gradients just fine, so a tangent also ought to be able to.

@oschulz
Copy link
Contributor Author

oschulz commented Aug 16, 2021

Just curious, what upcoming DDP stuff?

@ToucheSir
Copy link
Member

@oxinabox
Copy link
Member

Well, since Tangent is a very generic container of sorts, one can imagine it does share the same representation of the tree as regular models would. That is, after all, it's job. It may only have incomplete information because not all fields would have a corresponding bit in the Tangent

If you call canonicalize on a Tangent then it will fill in all the fields that don't have a tangent in them with ZeroTangent().
So it will have same structure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants