torchode 0.2.0__tar.gz → 1.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. {torchode-0.2.0 → torchode-1.0.1}/CHANGELOG.md +4 -0
  2. torchode-1.0.1/CITATION.cff +28 -0
  3. {torchode-0.2.0 → torchode-1.0.1}/PKG-INFO +4 -3
  4. torchode-1.0.1/docs/backprop.md +24 -0
  5. torchode-1.0.1/docs/requirements.in +2 -0
  6. torchode-1.0.1/docs/requirements.txt +226 -0
  7. {torchode-0.2.0 → torchode-1.0.1}/mkdocs.yml +1 -0
  8. {torchode-0.2.0 → torchode-1.0.1}/pyproject.toml +1 -1
  9. {torchode-0.2.0 → torchode-1.0.1}/torchode/__init__.py +1 -1
  10. {torchode-0.2.0 → torchode-1.0.1}/torchode/adjoints.py +5 -4
  11. {torchode-0.2.0 → torchode-1.0.1}/torchode/step_size_controllers.py +1 -1
  12. torchode-0.2.0/docs/requirements.in +0 -2
  13. torchode-0.2.0/docs/requirements.txt +0 -154
  14. {torchode-0.2.0 → torchode-1.0.1}/.github/workflows/python-package.yml +0 -0
  15. {torchode-0.2.0 → torchode-1.0.1}/.gitignore +0 -0
  16. {torchode-0.2.0 → torchode-1.0.1}/.readthedocs.yaml +0 -0
  17. {torchode-0.2.0 → torchode-1.0.1}/LICENSE +0 -0
  18. {torchode-0.2.0 → torchode-1.0.1}/README.md +0 -0
  19. {torchode-0.2.0 → torchode-1.0.1}/docs/README.md +0 -0
  20. {torchode-0.2.0 → torchode-1.0.1}/docs/comparison.md +0 -0
  21. {torchode-0.2.0 → torchode-1.0.1}/docs/extra-args.md +0 -0
  22. {torchode-0.2.0 → torchode-1.0.1}/docs/extra-stats.ipynb +0 -0
  23. {torchode-0.2.0 → torchode-1.0.1}/docs/jit.ipynb +0 -0
  24. {torchode-0.2.0 → torchode-1.0.1}/docs/nd-data.md +0 -0
  25. {torchode-0.2.0 → torchode-1.0.1}/docs/step-size-controllers.md +0 -0
  26. {torchode-0.2.0 → torchode-1.0.1}/docs/torchdiffeq.ipynb +0 -0
  27. {torchode-0.2.0 → torchode-1.0.1}/torchode/interface.py +0 -0
  28. {torchode-0.2.0 → torchode-1.0.1}/torchode/interpolation.py +0 -0
  29. {torchode-0.2.0 → torchode-1.0.1}/torchode/problems.py +0 -0
  30. {torchode-0.2.0 → torchode-1.0.1}/torchode/single_step_methods/__init__.py +0 -0
  31. {torchode-0.2.0 → torchode-1.0.1}/torchode/single_step_methods/base.py +0 -0
  32. {torchode-0.2.0 → torchode-1.0.1}/torchode/single_step_methods/dopri5.py +0 -0
  33. {torchode-0.2.0 → torchode-1.0.1}/torchode/single_step_methods/euler.py +0 -0
  34. {torchode-0.2.0 → torchode-1.0.1}/torchode/single_step_methods/heun.py +0 -0
  35. {torchode-0.2.0 → torchode-1.0.1}/torchode/single_step_methods/runge_kutta.py +0 -0
  36. {torchode-0.2.0 → torchode-1.0.1}/torchode/single_step_methods/tsit5.py +0 -0
  37. {torchode-0.2.0 → torchode-1.0.1}/torchode/solution.py +0 -0
  38. {torchode-0.2.0 → torchode-1.0.1}/torchode/status_codes.py +0 -0
  39. {torchode-0.2.0 → torchode-1.0.1}/torchode/terms.py +0 -0
  40. {torchode-0.2.0 → torchode-1.0.1}/torchode/typing.py +0 -0
@@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## 1.0.0 - 2024-09-22
9
+
10
+ After almost a year without any bugs found, we mark this as the first stable release!
11
+
8
12
  ## 0.2.0 - 2023-11-10
9
13
 
10
14
  ### Changed
@@ -0,0 +1,28 @@
1
+ cff-version: 1.2.0
2
+ title: torchode
3
+ message: >-
4
+ If you use this software, please cite it using the
5
+ metadata from this file.
6
+ type: software
7
+ authors:
8
+ - given-names: Marten
9
+ family-names: Lienen
10
+ email: m.lienen@tum.de
11
+ - given-names: Stephan
12
+ family-names: Günnemann
13
+ email: s.guennemann@tum.de
14
+ repository-code: "https://github.com/martenlienen/torchode"
15
+ license: MIT
16
+ preferred-citation:
17
+ type: conference-paper
18
+ title: "torchode: A Parallel ODE Solver for PyTorch"
19
+ authors:
20
+ - given-names: Marten
21
+ family-names: Lienen
22
+ email: m.lienen@tum.de
23
+ - given-names: Stephan
24
+ family-names: Günnemann
25
+ email: s.guennemann@tum.de
26
+ collection-title: "The Symbiosis of Deep Learning and Differential Equations II, NeurIPS"
27
+ year: 2022
28
+ url: "https://openreview.net/forum?id=uiKVKTiUYB0"
@@ -1,16 +1,17 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: torchode
3
- Version: 0.2.0
3
+ Version: 1.0.1
4
4
  Summary: A parallel ODE solver for PyTorch
5
5
  Author-email: Marten Lienen <m.lienen@tum.de>
6
6
  Requires-Python: >= 3.8
7
7
  Description-Content-Type: text/markdown
8
- Classifier: Development Status :: 4 - Beta
8
+ Classifier: Development Status :: 5 - Production/Stable
9
9
  Classifier: Intended Audience :: Developers
10
10
  Classifier: Intended Audience :: Science/Research
11
11
  Classifier: License :: OSI Approved :: MIT License
12
12
  Classifier: Operating System :: OS Independent
13
13
  Classifier: Programming Language :: Python
14
+ License-File: LICENSE
14
15
  Requires-Dist: sympy ~= 1.10
15
16
  Requires-Dist: torch >= 2.0
16
17
  Requires-Dist: torchtyping ~= 0.1.4
@@ -0,0 +1,24 @@
1
+ # Gradients & Backpropagation
2
+
3
+ There are two ways to compute gradients of the dynamics of an ODE, so the neural network
4
+ in the case of neural ODEs, with respect to the solution of the ODE. The first is to
5
+ backpropagate straight through the solver. After all, an ODE solver is just a series of
6
+ simple operations that define a dynamic computation graph that can be backpropagated
7
+ through with pytorch's autograd. This is implemented in `to.AutoDiffAdjoint`, so called
8
+ because it uses the autodiff/autograd mechanism. In general, this is the preferred method
9
+ as long as you have enough memory, because it is fast and gives accurate gradients.
10
+
11
+ If you run out of memory, you can compute gradients by solving the so called adjoint
12
+ equations, which basically solve the ODE backwards and track gradients along the way. This
13
+ is implemented in `to.BacksolveAdjoint`. Solving the adjoint equations requires the
14
+ computation of gradients of the model at different steps in time, which
15
+ `to.BacksolveAdjoint` implements with `torch.func`. If your model is not compatible and
16
+ you get errors because of this, you can fall back to `to.JointBacksolveAdjoint`. This
17
+ computes the model gradients with pytorch's usual autograd and should always work but
18
+ comes with two caveats. However, to make this work, `to.JointBacksolveAdjoint` needs to
19
+ solve the `n` independent adjoint equations jointly as one joint system that is jointly
20
+ discretized. This breaks with torchode's approach of solving each ODE completely
21
+ independently, because the joint discretization introduces a subtle coupling between the
22
+ solutions of your batch of ODEs. Therefore, `to.JointBacksolveAdjoint` should be your
23
+ backpropagation choice of last resort. Furthermore, it is only applicable if all ODEs in
24
+ your batch have the same evaluation points.
@@ -0,0 +1,2 @@
1
+ mkdocs==1.6.1
2
+ mkdocs-jupyter~=0.25
@@ -0,0 +1,226 @@
1
+ #
2
+ # This file is autogenerated by pip-compile with Python 3.14
3
+ # by the following command:
4
+ #
5
+ # pip-compile --output-file=docs/requirements.txt docs/requirements.in
6
+ #
7
+ asttokens==3.0.1
8
+ # via stack-data
9
+ attrs==25.4.0
10
+ # via
11
+ # jsonschema
12
+ # referencing
13
+ babel==2.18.0
14
+ # via mkdocs-material
15
+ backrefs==6.2
16
+ # via mkdocs-material
17
+ beautifulsoup4==4.14.3
18
+ # via nbconvert
19
+ bleach[css]==6.3.0
20
+ # via nbconvert
21
+ certifi==2026.2.25
22
+ # via requests
23
+ charset-normalizer==3.4.6
24
+ # via requests
25
+ click==8.3.1
26
+ # via mkdocs
27
+ colorama==0.4.6
28
+ # via mkdocs-material
29
+ comm==0.2.3
30
+ # via ipykernel
31
+ debugpy==1.8.20
32
+ # via ipykernel
33
+ decorator==5.2.1
34
+ # via ipython
35
+ defusedxml==0.7.1
36
+ # via nbconvert
37
+ executing==2.2.1
38
+ # via stack-data
39
+ fastjsonschema==2.21.2
40
+ # via nbformat
41
+ ghp-import==2.1.0
42
+ # via mkdocs
43
+ idna==3.11
44
+ # via requests
45
+ ipykernel==6.31.0
46
+ # via mkdocs-jupyter
47
+ ipython==9.11.0
48
+ # via ipykernel
49
+ ipython-pygments-lexers==1.1.1
50
+ # via ipython
51
+ jedi==0.19.2
52
+ # via ipython
53
+ jinja2==3.1.6
54
+ # via
55
+ # mkdocs
56
+ # mkdocs-material
57
+ # nbconvert
58
+ jsonschema==4.26.0
59
+ # via nbformat
60
+ jsonschema-specifications==2025.9.1
61
+ # via jsonschema
62
+ jupyter-client==8.8.0
63
+ # via
64
+ # ipykernel
65
+ # nbclient
66
+ jupyter-core==5.9.1
67
+ # via
68
+ # ipykernel
69
+ # jupyter-client
70
+ # nbclient
71
+ # nbconvert
72
+ # nbformat
73
+ jupyterlab-pygments==0.3.0
74
+ # via nbconvert
75
+ jupytext==1.19.1
76
+ # via mkdocs-jupyter
77
+ markdown==3.10.2
78
+ # via
79
+ # mkdocs
80
+ # mkdocs-material
81
+ # pymdown-extensions
82
+ markdown-it-py==4.0.0
83
+ # via
84
+ # jupytext
85
+ # mdit-py-plugins
86
+ markupsafe==3.0.3
87
+ # via
88
+ # jinja2
89
+ # mkdocs
90
+ # nbconvert
91
+ matplotlib-inline==0.2.1
92
+ # via
93
+ # ipykernel
94
+ # ipython
95
+ mdit-py-plugins==0.5.0
96
+ # via jupytext
97
+ mdurl==0.1.2
98
+ # via markdown-it-py
99
+ mergedeep==1.3.4
100
+ # via
101
+ # mkdocs
102
+ # mkdocs-get-deps
103
+ mistune==3.2.0
104
+ # via nbconvert
105
+ mkdocs==1.6.1
106
+ # via
107
+ # -r docs/requirements.in
108
+ # mkdocs-jupyter
109
+ # mkdocs-material
110
+ mkdocs-get-deps==0.2.2
111
+ # via mkdocs
112
+ mkdocs-jupyter==0.25.1
113
+ # via -r docs/requirements.in
114
+ mkdocs-material==9.7.5
115
+ # via mkdocs-jupyter
116
+ mkdocs-material-extensions==1.3.1
117
+ # via mkdocs-material
118
+ nbclient==0.10.4
119
+ # via nbconvert
120
+ nbconvert==7.17.0
121
+ # via mkdocs-jupyter
122
+ nbformat==5.10.4
123
+ # via
124
+ # jupytext
125
+ # nbclient
126
+ # nbconvert
127
+ nest-asyncio==1.6.0
128
+ # via ipykernel
129
+ packaging==26.0
130
+ # via
131
+ # ipykernel
132
+ # jupytext
133
+ # mkdocs
134
+ # nbconvert
135
+ paginate==0.5.7
136
+ # via mkdocs-material
137
+ pandocfilters==1.5.1
138
+ # via nbconvert
139
+ parso==0.8.6
140
+ # via jedi
141
+ pathspec==1.0.4
142
+ # via mkdocs
143
+ pexpect==4.9.0
144
+ # via ipython
145
+ platformdirs==4.9.4
146
+ # via
147
+ # jupyter-core
148
+ # mkdocs-get-deps
149
+ prompt-toolkit==3.0.52
150
+ # via ipython
151
+ psutil==7.2.2
152
+ # via ipykernel
153
+ ptyprocess==0.7.0
154
+ # via pexpect
155
+ pure-eval==0.2.3
156
+ # via stack-data
157
+ pygments==2.19.2
158
+ # via
159
+ # ipython
160
+ # ipython-pygments-lexers
161
+ # mkdocs-jupyter
162
+ # mkdocs-material
163
+ # nbconvert
164
+ pymdown-extensions==10.21
165
+ # via mkdocs-material
166
+ python-dateutil==2.9.0.post0
167
+ # via
168
+ # ghp-import
169
+ # jupyter-client
170
+ pyyaml==6.0.3
171
+ # via
172
+ # jupytext
173
+ # mkdocs
174
+ # mkdocs-get-deps
175
+ # pymdown-extensions
176
+ # pyyaml-env-tag
177
+ pyyaml-env-tag==1.1
178
+ # via mkdocs
179
+ pyzmq==27.1.0
180
+ # via
181
+ # ipykernel
182
+ # jupyter-client
183
+ referencing==0.37.0
184
+ # via
185
+ # jsonschema
186
+ # jsonschema-specifications
187
+ requests==2.32.5
188
+ # via mkdocs-material
189
+ rpds-py==0.30.0
190
+ # via
191
+ # jsonschema
192
+ # referencing
193
+ six==1.17.0
194
+ # via python-dateutil
195
+ soupsieve==2.8.3
196
+ # via beautifulsoup4
197
+ stack-data==0.6.3
198
+ # via ipython
199
+ tinycss2==1.4.0
200
+ # via bleach
201
+ tornado==6.5.5
202
+ # via
203
+ # ipykernel
204
+ # jupyter-client
205
+ traitlets==5.14.3
206
+ # via
207
+ # ipykernel
208
+ # ipython
209
+ # jupyter-client
210
+ # jupyter-core
211
+ # matplotlib-inline
212
+ # nbclient
213
+ # nbconvert
214
+ # nbformat
215
+ typing-extensions==4.15.0
216
+ # via beautifulsoup4
217
+ urllib3==2.6.3
218
+ # via requests
219
+ watchdog==6.0.0
220
+ # via mkdocs
221
+ wcwidth==0.6.0
222
+ # via prompt-toolkit
223
+ webencodings==0.5.1
224
+ # via
225
+ # bleach
226
+ # tinycss2
@@ -12,6 +12,7 @@ plugins:
12
12
  nav:
13
13
  - "Introduction": README.md
14
14
  - step-size-controllers.md
15
+ - backprop.md
15
16
  - jit.ipynb
16
17
  - extra-args.md
17
18
  - extra-stats.ipynb
@@ -10,7 +10,7 @@ requires-python = ">= 3.8"
10
10
  license = {file = "LICENSE"}
11
11
  authors = [{name = "Marten Lienen", email = "m.lienen@tum.de"}]
12
12
  classifiers = [
13
- "Development Status :: 4 - Beta",
13
+ "Development Status :: 5 - Production/Stable",
14
14
  "Intended Audience :: Developers",
15
15
  "Intended Audience :: Science/Research",
16
16
  "License :: OSI Approved :: MIT License",
@@ -1,6 +1,6 @@
1
1
  """A parallel ODE solver for PyTorch"""
2
2
 
3
- __version__ = "0.2.0"
3
+ __version__ = "1.0.1"
4
4
 
5
5
  from .adjoints import AutoDiffAdjoint, BacksolveAdjoint, JointBacksolveAdjoint
6
6
  from .interface import register_method, solve_ivp
@@ -207,10 +207,11 @@ class AutoDiffAdjoint(nn.Module):
207
207
  # Evaluate the solution at all evaluation points that have been passed in
208
208
  # this step.
209
209
  #
210
- # We always build the interpolation and evaluate it, even if no evaluation
211
- # points have actually been passed, because this avoids a CPU-GPU
212
- # synchronization and for time series models we expect that most steps will
213
- # pass at least one evaluation point across the whole batch (usually more).
210
+ # This causes a blocking CPU-GPU sync point at to_be_evaluated.any
211
+ # when t_eval is not None, but deferring this sync doesn't seem to
212
+ # yield a speedup. A sync is necessary at each evaluation point anyway
213
+ # since nonzero produces a variable-shape result.
214
+ # See https://github.com/martenlienen/torchode/issues/46
214
215
  if t_eval is not None:
215
216
  to_be_evaluated = (
216
217
  torch.addcmul(
@@ -478,7 +478,7 @@ class IntegralController(nn.Module):
478
478
  args,
479
479
  )
480
480
 
481
- d2 = norm((f1 - f0) * inv_scale) / dt0
481
+ d2 = torch.where(dt0 == 0, torch.inf, norm((f1 - f0) * inv_scale) / dt0)
482
482
 
483
483
  maxd1d2 = torch.maximum(d1, d2)
484
484
  dt1 = torch.where(
@@ -1,2 +0,0 @@
1
- mkdocs==1.4.1
2
- mkdocs-jupyter~=0.21
@@ -1,154 +0,0 @@
1
- #
2
- # This file is autogenerated by pip-compile with python 3.10
3
- # To update, run:
4
- #
5
- # pip-compile --output-file=docs/requirements.txt docs/requirements.in
6
- #
7
- attrs==22.1.0
8
- # via jsonschema
9
- beautifulsoup4==4.11.1
10
- # via nbconvert
11
- bleach==5.0.1
12
- # via nbconvert
13
- certifi==2022.12.7
14
- # via requests
15
- charset-normalizer==2.1.1
16
- # via requests
17
- click==8.1.3
18
- # via mkdocs
19
- defusedxml==0.7.1
20
- # via nbconvert
21
- entrypoints==0.4
22
- # via
23
- # jupyter-client
24
- # nbconvert
25
- fastjsonschema==2.16.2
26
- # via nbformat
27
- ghp-import==2.1.0
28
- # via mkdocs
29
- idna==3.4
30
- # via requests
31
- jinja2==3.1.2
32
- # via
33
- # mkdocs
34
- # mkdocs-material
35
- # nbconvert
36
- jsonschema==4.17.0
37
- # via nbformat
38
- jupyter-client==7.4.4
39
- # via nbclient
40
- jupyter-core==4.11.2
41
- # via
42
- # jupyter-client
43
- # nbconvert
44
- # nbformat
45
- jupyterlab-pygments==0.2.2
46
- # via nbconvert
47
- jupytext==1.14.1
48
- # via mkdocs-jupyter
49
- lxml==4.9.1
50
- # via nbconvert
51
- markdown==3.3.7
52
- # via
53
- # mkdocs
54
- # mkdocs-material
55
- # pymdown-extensions
56
- markdown-it-py==2.2.0
57
- # via
58
- # jupytext
59
- # mdit-py-plugins
60
- markupsafe==2.1.1
61
- # via
62
- # jinja2
63
- # nbconvert
64
- mdit-py-plugins==0.3.1
65
- # via jupytext
66
- mdurl==0.1.2
67
- # via markdown-it-py
68
- mergedeep==1.3.4
69
- # via mkdocs
70
- mistune==0.8.4
71
- # via nbconvert
72
- mkdocs==1.4.1
73
- # via
74
- # -r requirements.in
75
- # mkdocs-jupyter
76
- # mkdocs-material
77
- mkdocs-jupyter==0.22.0
78
- # via -r requirements.in
79
- mkdocs-material==8.5.7
80
- # via mkdocs-jupyter
81
- mkdocs-material-extensions==1.1
82
- # via mkdocs-material
83
- nbclient==0.7.0
84
- # via nbconvert
85
- nbconvert==6.5.4
86
- # via mkdocs-jupyter
87
- nbformat==5.7.0
88
- # via
89
- # jupytext
90
- # nbclient
91
- # nbconvert
92
- nest-asyncio==1.5.6
93
- # via
94
- # jupyter-client
95
- # nbclient
96
- packaging==21.3
97
- # via
98
- # mkdocs
99
- # nbconvert
100
- pandocfilters==1.5.0
101
- # via nbconvert
102
- pygments==2.13.0
103
- # via
104
- # mkdocs-jupyter
105
- # mkdocs-material
106
- # nbconvert
107
- pymdown-extensions==9.7
108
- # via mkdocs-material
109
- pyparsing==3.0.9
110
- # via packaging
111
- pyrsistent==0.19.1
112
- # via jsonschema
113
- python-dateutil==2.8.2
114
- # via
115
- # ghp-import
116
- # jupyter-client
117
- pyyaml==6.0
118
- # via
119
- # jupytext
120
- # mkdocs
121
- # pyyaml-env-tag
122
- pyyaml-env-tag==0.1
123
- # via mkdocs
124
- pyzmq==24.0.1
125
- # via jupyter-client
126
- requests==2.28.1
127
- # via mkdocs-material
128
- six==1.16.0
129
- # via
130
- # bleach
131
- # python-dateutil
132
- soupsieve==2.3.2.post1
133
- # via beautifulsoup4
134
- tinycss2==1.2.1
135
- # via nbconvert
136
- toml==0.10.2
137
- # via jupytext
138
- tornado==6.2
139
- # via jupyter-client
140
- traitlets==5.5.0
141
- # via
142
- # jupyter-client
143
- # jupyter-core
144
- # nbclient
145
- # nbconvert
146
- # nbformat
147
- urllib3==1.26.12
148
- # via requests
149
- watchdog==2.1.9
150
- # via mkdocs
151
- webencodings==0.5.1
152
- # via
153
- # bleach
154
- # tinycss2
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes