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

Function-based ChainRules rule transferring to Enzyme rules #855

Open
ChrisRackauckas opened this issue Jul 30, 2023 · 3 comments
Open

Function-based ChainRules rule transferring to Enzyme rules #855

ChrisRackauckas opened this issue Jul 30, 2023 · 3 comments

Comments

@ChrisRackauckas
Copy link
Member

As mentioned in EnzymeAD/Enzyme.jl#805 (comment)

Define a macro that defines the Enzyme rules for a given function based on the ChainRules. For example, @ruletransfer conv(x)

@ruletransfer conv(x) would define an EnzymeRule that naively calls a ChainRules.jl rule for all of the activity types. This would then serve as a suboptimal fallback that can be applied on a single function basis. The purpose of this macro would be to make it easier to setup the adoption of Zygote throughout the deep learning community by allowing any Zygote rule to trivially port to Enzyme, making Enzyme at least as good as Zygote as quickly as possible. The reason to do it on a function by function basis is that not all rules are necessary, with the main ones being the ones over cudnn kernels. They should of course be replaced with lower level rules that more optimize memory usage as needed, but I think such a simple macro would be a great first step.

This means the rule transfer can be pretty naïve. It could just call the ChainRule and then realout .= chainrulesout , i.e. many ChainRules rules will allocate the output while Enzyme can in theory omit the extra allocation, but for the macro it can ignore such optimizations and just ensure it hits coverage first.

@oxinabox
Copy link
Contributor

oxinabox commented Aug 4, 2023

I will try and find time to do this, but it will probably be a few weeks at least.

@sharanry
Copy link
Member

sharanry commented Sep 2, 2023

@ChrisRackauckas To check my understanding of what is needed, we need a macro that can generically define Zygote rules functions like below, right?

using Enzyme
import .EnzymeRules: forward
using ChainRules
function EnzymeRules.forward(func::Const{typeof(sin)}, ::Type{<:Duplicated}, x::Duplicated)
    println("Using custom rule!")
    (ret, dret) = ChainRules.frule((0.0, x.dval), func.val, x.val)
    return Duplicated(ret, dret)
end

x = 1.0
dx = 1.0
@show Enzyme.autodiff(Forward, sin, Duplicated, Duplicated(x, dx))
Using custom rule!
autodiff(Forward, sin, Duplicated, Duplicated(x, dx)) = (0.8414709848078965, 0.5403023058681398)

@ChrisRackauckas
Copy link
Member Author

I think we may not go this route anymore? Talking with Billy more directly, we might just start writing rules for Lux. I'll invite you to the channel.

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

3 participants