Skip to content

New autodiff rule from DifferentiateWith #804

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

Open
yebai opened this issue May 26, 2025 · 2 comments
Open

New autodiff rule from DifferentiateWith #804

yebai opened this issue May 26, 2025 · 2 comments
Labels
backend Related to one or more autodiff backends core Related to the core utilities of the package

Comments

@yebai
Copy link
Contributor

yebai commented May 26, 2025

As explored in discussions (e.g., #68), we can introduce a flexible "rule switch" mechanism into DifferentiationInterface.jl (DI) by generalising the existing DifferentiateWith functionality.

The central concept is a macro that allows for the dynamic generation of differentiation rules:

Targtypes = (typeof(x), typeof(y), Constant{typeof(z)}, Cache{typeof(c)})
Tfunc_sig =Tuple{typeof(f), Targtypes...}
@rule_from_DifferentiateWith(AutoTargetAD, ::Tfunc_sig, backend_to_use::AbstractADType)

In this definition:

  • @rule_from_DifferentiateWith is a macro designed to generate new differentiation rules.
  • AutoTargetAD specifies the automatic differentiation (AD) package for which the new rule is being created (e.g., AutoChainRules).
  • func_sig represents the signature of the function f along with its argument types (argtypes...) for which the rule is being defined.
  • backend_to_use indicates another AD package (the "backend") whose capabilities will be leveraged to define the rule for AutoTargetAD.

This approach provides a powerful and general way to establish a "rule switch mechanism." It avoids imposing strict assumptions on the rule interface, unlike systems such as ChainRules, offering greater flexibility.

After #806, we could also do

dw = DifferentiateWith(Tfunc_sig, backend_to_use::AbstractADType)
@rule_from_DifferentiateWith(AutoTargetAD, dw)
@yebai yebai changed the title Backend rule from DifferentiateWith New autodiff rule from DifferentiateWith Jun 1, 2025
@gdalle gdalle added backend Related to one or more autodiff backends core Related to the core utilities of the package labels Jun 2, 2025
@gdalle
Copy link
Member

gdalle commented Jun 2, 2025

I'm not sure I understand where you're going with the last part. To me, the whole purpose of having a macro generate rules is to dispense the user from creating a DifferentiateWith object, by making the naked function f differentiable directly?

Essentially, what I envisioned was a macro

@rule_from_DifferentiateWith(target_backend, DifferentiateWith(f, source_backend))

which would generate code like this when target_backend isa AutoChainRules for example

function ChainRulesCore.rrule(::typeof(f), x)
    dw = DifferentiateWith(f, source_backend)
    return rrule(dw, x)  # already implemented
end

@yebai
Copy link
Contributor Author

yebai commented Jun 3, 2025

I'm not sure I understand where you're going with the last part.

It is a syntax sugar that allows us to reuse a pre-defined diffwith instance. For example

Tfunc_sig = (typeof(f), typeof(x), typeof(y), Constant{typeof(z)}, Cache{typeof(c)})

# Approach 1
@rule_from_DifferentiateWith(target_backend, ::Tfunc_sig, source_backend)

# Approach 2: equivalent but in two steps
dw = DifferentiateWith(::Tfunc_sig, source_backend)
@rule_from_DifferentiateWith(target_backend, dw)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend Related to one or more autodiff backends core Related to the core utilities of the package
Projects
None yet
Development

No branches or pull requests

2 participants