Skip to content

Commit 0d21078

Browse files
committed
added doc for GPU solving
1 parent b988182 commit 0d21078

5 files changed

Lines changed: 85 additions & 17 deletions

File tree

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,4 @@ ExaModels = "0.8"
2727
julia = "1.10"
2828

2929
[sources]
30-
CTDirect = {url = "https://github.com/control-toolbox/CTDirect.jl", rev = "jbcaillau-patch-1"}
30+
CTDirect = {url = "https://github.com/control-toolbox/CTDirect.jl", rev = "main"}

docs/Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,4 @@ Suppressor = "0.2"
4646
julia = "1"
4747

4848
[sources]
49-
CTDirect = {url = "https://github.com/control-toolbox/CTDirect.jl", rev = "jbcaillau-patch-1"}
49+
CTDirect = {url = "https://github.com/control-toolbox/CTDirect.jl", rev = "main"}

docs/src/manual-abstract.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ A variable (only one is allowed) is a finite dimensional vector or reals that wi
2222
end
2323
```
2424

25-
!!! caveat
25+
!!! warning
2626
Note that the full code of the definition above is not provided (hence the `...`) The same is true for most examples below (only those without `...` are indeed complete). Also note that problem definitions must at least include definitions for time, state, control, and dynamics.
2727

2828

@@ -227,10 +227,10 @@ The dynamics can also be declared coordinate by coordinate. The previous example
227227
end
228228
```
229229

230-
!!! caveat
230+
!!! warning
231231
Declaring the dynamics coordinate by coordinate is **compulsory** when solving with the option `:exa` to rely on the ExaModels modeller (check the [solve section](@ref manual-solve)), for instance to [solve on GPU](@ref manual-solve-gpu).
232232

233-
## Constraints
233+
## [Constraints](@id manual-abstract-constraints)
234234

235235
```julia
236236
:( $e1 == $e2 )
@@ -288,7 +288,7 @@ end
288288
end
289289
```
290290

291-
!!! caveat
291+
!!! warning
292292
Write either `u(t)^2` or `(u^2)(t)`, not `u^2(t)` since in Julia the latter means `u^(2t)`. Moreover,
293293
in the case of equalities or of one-sided inequalities, the control and / or the state must belong to the *left-hand side*. The following will error:
294294

@@ -309,7 +309,7 @@ using OptimalControl
309309
end
310310
```
311311

312-
!!! caveat
312+
!!! warning
313313
Constraint bounds must be *effective*, that is must not depend on a variable. For instance, instead of
314314
```julia
315315
o = @def begin
@@ -341,7 +341,7 @@ o = @def begin
341341
end
342342
```
343343

344-
!!! caveat
344+
!!! warning
345345
When solving with the option `:exa` to rely on the ExaModels modeller (check the [solve section](@ref manual-solve)), for instance to [solve on GPU](@ref manual-solve-gpu), it is **compulsory** that *nonlinear* constraints (not ranges) are *scalar*, whatever the type (boundary, variable, controle, state, mixed).
346346

347347
## [Mayer cost](@id manual-abstract-mayer)
@@ -449,7 +449,7 @@ Quite readily, Mayer and Lagrange costs can be combined into general Bolza costs
449449
end
450450
```
451451

452-
!!! caveat
452+
!!! warning
453453
The expression must be the sum of two terms (plus, possibly, a scalar factor before the integral), not *more*, so mind the parentheses. For instance, the following errors:
454454

455455
```julia
@@ -495,7 +495,7 @@ The single `=` symbol is used to define not a constraint but an alias, that is a
495495
end
496496
```
497497

498-
!!! caveat
498+
!!! warning
499499
Such aliases do *not* define any additional function and are just replaced textually by the parser. In particular, they cannot be used outside the `@def` `begin ... end` block.
500500

501501
!!! hint
@@ -513,7 +513,7 @@ end
513513
end true;
514514
```
515515

516-
!!! caveat
516+
!!! warning
517517
The dynamics of an OCP is indeed a particular constraint, be careful to use `==` and not a single `=` that would try to define an alias:
518518

519519
```@repl main-repl
@@ -554,4 +554,4 @@ end
554554

555555
## Known issues
556556

557-
- [Constants and (reverse over forward) AD](https://github.com/control-toolbox/OptimalControl.jl/issues/481)
557+
- [Reverse over forward AD issues with ADNLP](https://github.com/control-toolbox/OptimalControl.jl/issues/481)

docs/src/manual-solve-gpu.md

Lines changed: 72 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,78 @@
44
CollapsedDocStrings = false
55
```
66

7-
In this manual, we explain how to use the [`solve`](@ref) function from [OptimalControl.jl](https://control-toolbox.org/OptimalControl.jl) on GPU. We rely on [MadNLP](https://github.com/MadNLP/MadNLP.jl) and currently only provide support for NVIDIA thanks to [CUDA.jl](https://github.com/JuliaGPU/CUDA.jl).
7+
In this manual, we explain how to use the [`solve`](@ref) function from [OptimalControl.jl](https://control-toolbox.org/OptimalControl.jl) on GPU. We rely on [ExaModels.jl](https://exanauts.github.io/ExaModels.jl/stable) and [MadNLPGPU.jl](https://github.com/MadNLP/MadNLP.jl) and currently only provide support for NVIDIA thanks to [CUDA.jl](https://github.com/JuliaGPU/CUDA.jl). Consider the following simple Lagrange optimal control problem:
88

9-
```@docs; canonical=false
10-
solve(::CTModels.Model, ::Symbol...)
9+
```julia
10+
using OptimalControl
11+
using MadNLPGPU
12+
using CUDA
13+
14+
ocp = @def begin
15+
t [0, 1], time
16+
x R², state
17+
u R, control
18+
v R, variable
19+
x(0) == [0, 1]
20+
x(1) == [0, -1]
21+
(x₁)(t) == x₂(t)
22+
(x₂)(t) == u(t)
23+
0 x₁(t) + v^2 1.1
24+
-10 u(t) 10
25+
1 v 2
26+
(u(t)^2 + v) min
27+
end
1128
```
1229

13-
TBC
30+
!!! note
31+
We have used MadNLPGPU instead of MadNLP, that is able to solve on GPU (leveraging [CUDSS.jl](https://github.com/exanauts/CUDSS.jl)) optimisation problems modelled with ExaModels.jl. As a direct transcription towards an `ExaModels.ExaModel` is performed, there are limitations on the syntax:
32+
- dynamics must be declared coordinate by coordinate (not globally as a vector valued expression)
33+
- nonlinear constraints (boundary, variable, control, state, mixed ones, see [Constraints](@ref manual-abstract-constraints) must also be scalar expressions (linear constraints *aka.* ranges, on the other hand, can be vectors)
34+
- all expressions must only involve algebraic operations that are known to ExaModels (check the [documentation](https://exanauts.github.io/ExaModels.jl/stable)), although one can provide additional user defined functions through *registration* (check [ExaModels API](https://exanauts.github.io/ExaModels.jl/stable/core/#ExaModels.@register_univariate-Tuple%7BAny,%2520Any,%2520Any%7D))
35+
36+
Computation on GPU is currently only tested with CUDA, and the associated backend must be passed to ExaModels as is done below (also note the `:exa` keyword to indicate the modeller, and `:madnlp` for the solver):
37+
38+
```julia
39+
julia> sol = solve(ocp, :exa, :madnlp; exa_backend=CUDABackend())
40+
▫ This is OptimalControl version v1.1.0 running with: direct, exa, madnlp.
41+
42+
▫ The optimal control problem is solved with CTDirect version v0.16.0.
43+
44+
┌─ The NLP is modelled with ExaModels and solved with MadNLP.
45+
46+
├─ Number of time steps: 250
47+
└─ Discretisation scheme: trapeze
48+
49+
▫ This is MadNLP version v0.8.7, running with cuDSS v0.4.0
50+
51+
Number of nonzeros in constraint Jacobian............: 2506
52+
Number of nonzeros in Lagrangian Hessian.............: 2006
53+
54+
Total number of variables............................: 754
55+
variables with only lower bounds: 0
56+
variables with lower and upper bounds: 252
57+
variables with only upper bounds: 0
58+
Total number of equality constraints.................: 504
59+
Total number of inequality constraints...............: 251
60+
inequality constraints with only lower bounds: 0
61+
inequality constraints with lower and upper bounds: 251
62+
inequality constraints with only upper bounds: 0
63+
64+
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
65+
0 1.0200000e+00 1.10e+00 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0
66+
...
67+
26 9.8902986e+00 2.22e-16 7.11e-15 -9.0 1.32e-04 - 1.00e+00 1.00e+00h 1
68+
69+
Number of Iterations....: 26
70+
71+
(scaled) (unscaled)
72+
Objective...............: 9.8902986337530514e+00 9.8902986337530514e+00
73+
Dual infeasibility......: 7.1054273576010019e-15 7.1054273576010019e-15
74+
Constraint violation....: 2.2204460492503131e-16 2.2204460492503131e-16
75+
Complementarity.........: 4.8363494304578671e-09 4.8363494304578671e-09
76+
Overall NLP error.......: 4.8363494304578671e-09 4.8363494304578671e-09
77+
78+
...
79+
80+
EXIT: Optimal Solution Found (tol = 1.0e-08).
81+
```

docs/src/manual-solve.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ This is because the default method uses a direct approach, which transforms the
4848
\text{minimize}\quad F(y), \quad\text{subject to the constraints}\quad g(y) \le 0, \quad h(y) = 0.
4949
```
5050

51-
!!! caveat
51+
!!! warning
5252

5353
Calling `solve` without loading a NLP solver package first will notify the user:
5454

0 commit comments

Comments
 (0)