patrick-kidger / patrick-kidger/diffrax
Taking more than one gradient fails with default RecursiveCheckpointAdjoint
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 2.1k
- Forks
- 189
- Avg merge
- 3d 18h
- Merged PRs (30d)
- 1
Description
I am a total beginner with Jax and diffrax, not sure if this is a bug or expected, but if i try to find the second or higher derivative of a solution from diffeqsolve() I get an error. Changing the adjoint to DirectAdjoint() seems to fix the problem.
Minimal working example (using the default ODE example from the diffrax introduction):
import jax.numpy as jnp
import numpy as np
import jax
from diffrax import diffeqsolve, ODETerm, Dopri5, DirectAdjoint
z = 2.3
t = 1.
def rhot(z):
def f(t, y, args):
return -z*y
term = ODETerm(f)
solver = Dopri5()
y0 = jnp.array([2., 3.])
solution = diffeqsolve(term, solver, t0=0, t1=t, dt0=0.1, y0=y0)
#solution = diffeqsolve(term, solver, t0=0, t1=t, dt0=0.1, y0=y0, adjoint = DirectAdjoint()) #changing the adjoint fixes it
return solution.ys[0][0]
drhozdz = jax.grad(rhot,argnums = 0)
d2rhozdz = jax.grad(drhozdz,argnums = 0)
print("expected state ", np.exp(-z*t)*2.)
print("found state ", rhot(z))
print("expected ", -2.*t*np.exp(-z*t))
print("found 1st deriative ", drhozdz(z))
print("expected 2nd ", 2.*t**2*np.exp(-z*t))
print("found 2nd derivative ", d2rhozdz(z)) #fails with default adjoint
The error returned is:
"print("found 2nd deriative ", d2rhozdz(z)) #fails with default adjoint
^^^^^^^^^^^
ValueError: Reverse-mode differentiation does not work for lax.while_loop or lax.fori_loop with dynamic start/stop values. Try using lax.scan, or using fori_loop with static start/stop."
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the minimal working example in the issue and reproduce the second derivative using the default RecursiveCheckpointAdjoint, then compare it with DirectAdjoint. Trace the differentiation path involved in diffeqsolve and identify whether nested reverse-mode differentiation should be supported; done means the failure is fixed or the supported behavior is clearly documented and tested.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- machine-learning
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100