Skip to content

Add easy_rules for exponentially scaled Bessel functions (besselix etc.)#3365

Merged
wsmoses merged 1 commit into
EnzymeAD:mainfrom
cossio:besselix-rule
Jul 20, 2026
Merged

Add easy_rules for exponentially scaled Bessel functions (besselix etc.)#3365
wsmoses merged 1 commit into
EnzymeAD:mainfrom
cossio:besselix-rule

Conversation

@cossio

@cossio cossio commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Fixes #2880.

SpecialFunctions.besselix (and the other exponentially scaled Bessel functions besseljx, besselyx, besselkx) lower to AMOS routines (zbesi_, ...) that Enzyme cannot differentiate through, producing EnzymeNoDerivativeError: No augmented forward pass found for zbesi_.

As suggested in the issue, this adds EnzymeRules.@easy_rule definitions for all four scaled Bessel functions in EnzymeSpecialFunctionsExt, for real arguments, using the standard recurrence identities plus the derivative of the scaling factor:

  • besselix(ν, x) = besseli(ν, x) * exp(-|x|)(besselix(ν-1, x) + besselix(ν+1, x))/2 - sign(x)*Ω
  • besseljx(ν, x) = besselj(ν, x) * exp(-|imag(x)|) (scaling constant for real x) → (besseljx(ν-1, x) - besseljx(ν+1, x))/2
  • besselyx(ν, x) = bessely(ν, x) * exp(-|imag(x)|) (scaling constant for real x) → (besselyx(ν-1, x) - besselyx(ν+1, x))/2
  • besselkx(ν, x) = besselk(ν, x) * exp(x)Ω - (besselkx(ν-1, x) + besselkx(ν+1, x))/2

These match the corresponding ChainRules.jl rules. The order argument ν is marked @Constant (no order derivatives, same as the existing cmplx_known_ops handling of the unscaled Bessel functions).

Tests: added test_scalar coverage for all four functions in test/ext/specialfunctions.jl. Verified locally that the issue reproducer now works and that reverse- and forward-mode derivatives match finite differences for ν ∈ (0, 1, 2, 2.5) over positive/negative/zero real arguments (138 checks), including the sign(0) = 0 branch of besselix at x = 0 where the scaled function is only C¹ but the derivative is exact.

🤖 Generated with Claude Code

https://claude.ai/code/session_01TwgPLpFcdimYWqW6MVYQqK

Copilot AI review requested due to automatic review settings July 19, 2026 06:56

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@cossio

cossio commented Jul 19, 2026

Copy link
Copy Markdown
Contributor Author

@wsmoses Can we approve CI here?

@cossio

cossio commented Jul 19, 2026

Copy link
Copy Markdown
Contributor Author

The runic failure is unrelated to this PR: since the actions/checkout@v7 bump (#3209), the format job fails at the checkout step for every fork PR (pull_request_target now requires an explicit allow-unsafe-pr-checkout opt-in) — same failure on #3363 and #3354. The diff here passes git runic --diff locally.

@codecov

codecov Bot commented Jul 19, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 77.00%. Comparing base (4c8b1c0) to head (4d8d945).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3365      +/-   ##
==========================================
- Coverage   77.00%   77.00%   -0.01%     
==========================================
  Files          66       66              
  Lines       22285    22289       +4     
==========================================
+ Hits        17161    17163       +2     
- Misses       5124     5126       +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@cossio

cossio commented Jul 20, 2026

Copy link
Copy Markdown
Contributor Author

The test-job failures also look unrelated: they're Malt.TerminatedWorkerException() worker crashes in testsets this PR doesn't touch (threads, make_zero, finalizers, optimize, ...), plus the usual 1.13 pre-release breakage. The CI run on main at this PR's merge base (15f43c9) fails the same 7 jobs with the same exception.

The suite this PR actually adds to, ext/specialfunctions, passes 38548/38548 on every job where it ran (ubuntu 1.11/1.12/1.13, macOS 1.10/1.11/1.12; skipped on Windows per #2620).

@cossio cossio mentioned this pull request Jul 20, 2026
Adds Enzyme rules for SpecialFunctions.besselix, besseljx, besselyx and
besselkx (real arguments), which lower to AMOS routines (e.g. zbesi_)
that Enzyme cannot differentiate through.

Fixes EnzymeAD#2880

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TwgPLpFcdimYWqW6MVYQqK
@wsmoses
wsmoses merged commit 55cd63f into EnzymeAD:main Jul 20, 2026
80 of 84 checks passed
@cossio
cossio deleted the besselix-rule branch July 20, 2026 15:58
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

Successfully merging this pull request may close these issues.

besselix missing rule

3 participants