{"id":4808,"library":"torchdiffeq","title":"torchdiffeq","description":"torchdiffeq is a Python library providing ordinary differential equation (ODE) solvers implemented in PyTorch. It supports backpropagation through ODE solutions using the adjoint method, ensuring constant memory cost. The library offers a clean API for usage in deep learning applications, fully supporting GPU execution. The current version is 0.2.5, last released in November 2024, indicating an active development and maintenance cadence.","status":"active","version":"0.2.5","language":"en","source_language":"en","source_url":"https://github.com/rtqichen/torchdiffeq","tags":["PyTorch","ODE solvers","deep learning","differentiable programming","adjoint method","neural ODEs"],"install":[{"cmd":"pip install torchdiffeq","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Core deep learning framework dependency.","package":"torch","optional":false},{"reason":"Used for additional solver wrappers and numerical utilities.","package":"scipy","optional":false}],"imports":[{"note":"Standard ODE solver for direct backpropagation.","symbol":"odeint","correct":"from torchdiffeq import odeint"},{"note":"The common pattern is to alias `odeint_adjoint` to `odeint` for easy switching. When using `odeint_adjoint`, the ODE function (`func`) *must* be an `nn.Module` to collect parameters.","wrong":"from torchdiffeq import odeint_adjoint","symbol":"odeint_adjoint","correct":"from torchdiffeq import odeint_adjoint as odeint"}],"quickstart":{"code":"import torch\nimport torch.nn as nn\nfrom torchdiffeq import odeint\n\n# Define the ODE function as an nn.Module\nclass ODEFunc(nn.Module):\n    def forward(self, t, y):\n        # Example ODE: dy/dt = -0.1y + t\n        # y and t are torch.Tensor\n        return -0.1 * y + t\n\n# Initial state y(t=0)\ny0 = torch.tensor([0.7])\n\n# Time points at which to evaluate the solution\nt = torch.linspace(0., 10., 100) # 100 points from t=0 to t=10\n\n# Solve the ODE using the default (dopri5) solver\nsolution = odeint(ODEFunc(), y0, t)\n\nprint(\"Shape of solution (time_steps, initial_dim):\")\nprint(solution.shape) # Expected: (100, 1)\nprint(\"\\nFirst 5 values of the solution:\")\nprint(solution[:5])","lang":"python","description":"This quickstart demonstrates how to define a simple ODE function as an `nn.Module` and use `torchdiffeq.odeint` to solve it over a specified time interval. The output `solution` tensor contains the evaluated states at each time point."},"warnings":[{"fix":"Ensure your ODE dynamics `func` inherits from `torch.nn.Module` if you intend to use `odeint_adjoint`.","message":"When using `odeint_adjoint` for O(1) memory backpropagation, the ODE function (`func`) must be an instance of `torch.nn.Module`. This is crucial for the adjoint method to correctly identify and collect parameters for gradient computation.","severity":"gotcha","affected_versions":"All versions"},{"fix":"For memory-efficient training, import and use `odeint_adjoint` (often aliased as `odeint`) instead of the default `odeint`.","message":"Direct backpropagation through `odeint` (without `odeint_adjoint`) can be memory-intensive, especially for complex ODE trajectories or long integration times, as it stores all intermediate states. For O(1) memory cost, use the adjoint method (`odeint_adjoint`).","severity":"gotcha","affected_versions":"All versions"},{"fix":"Experiment with `rtol` and `atol` (e.g., `odeint(..., rtol=1e-3, atol=1e-5)`) to find a balance between speed and desired accuracy for your specific problem. Higher values mean faster but less accurate solutions.","message":"Adaptive ODE solvers (like the default `dopri5`) use `rtol` (relative tolerance) and `atol` (absolute tolerance) to control the accuracy and number of steps. Incorrectly set tolerances can lead to either excessively slow computations or inaccurate solutions.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Consider setting `options={'dtype': torch.float32}` within the `odeint` call if you need higher performance and have verified numerical stability with single-precision floats.","message":"The `dtype` for timelike quantities in solvers defaults to `torch.float64`. While more stable, using `torch.float32` can significantly improve speed but might lead to numerical instability or underflow issues in certain scenarios.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-12T00:00:00.000Z","next_check":"2026-07-11T00:00:00.000Z"}