Skip to content

Commit 594eb36

Browse files
authored
Begin re-organization of MOI docs (#1200)
* Begin re-organization of MOI docs * Remove testing.md * More re-organizing of documentation * Various edits
1 parent e4eef93 commit 594eb36

File tree

15 files changed

+1655
-1440
lines changed

15 files changed

+1655
-1440
lines changed

docs/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
[deps]
22
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
3+
MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
34

45
[compat]
56
Documenter = "0.25"

docs/make.jl

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,24 @@ makedocs(
55
format = Documenter.HTML(
66
# See https://github.com/JuliaDocs/Documenter.jl/issues/868
77
prettyurls = get(ENV, "CI", nothing) == "true",
8-
mathengine = Documenter.MathJax()
8+
mathengine = Documenter.MathJax2(),
9+
collapselevel = 1,
910
),
1011
# See https://github.com/jump-dev/JuMP.jl/issues/1576
1112
strict = true,
1213
pages = [
1314
"Introduction" => "index.md",
14-
"Manual" => "apimanual.md",
15-
"Reference" => "apireference.md",
16-
"Testing" => "testing.md",
15+
"Manual" => [
16+
"manual/basic_usage.md",
17+
"manual/advanced_usage.md",
18+
"manual/implementing.md",
19+
"manual/Benchmarks.md",
20+
"manual/Bridges.md",
21+
"manual/FileFormats.md",
22+
"manual/Test.md",
23+
"manual/Utilities.md",
24+
],
25+
"API Reference" => "apireference.md",
1726
]
1827
)
1928

docs/src/apimanual.md

Lines changed: 0 additions & 1426 deletions
This file was deleted.

docs/src/apireference.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,7 +1084,7 @@ Utilities.side_dimension_for_vectorized_dimension
10841084
## Benchmarks
10851085

10861086
Functions to help benchmark the performance of solver wrappers. See
1087-
[Benchmarking](@ref) for more details.
1087+
[The Benchmarks submodule](@ref) for more details.
10881088

10891089
```@docs
10901090
Benchmarks.suite
@@ -1095,7 +1095,7 @@ Benchmarks.compare_against_baseline
10951095
## File Formats
10961096

10971097
Functions to help read and write MOI models to/from various file formats. See
1098-
[File Formats](@ref) for more details.
1098+
[The FileFormats submodule](@ref) for more details.
10991099

11001100
```@docs
11011101
FileFormats.Model

docs/src/index.md

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,84 @@
11
# MathOptInterface
22

3-
[MathOptInterface.jl](https://github.com/jump-dev/MathOptInterface.jl) is a standardized API for mathematical optimization solvers.
3+
Each mathematical optimization solver API has its own concepts and data
4+
structures for representing optimization models and obtaining results.
5+
However, it is often desirable to represent an instance of an optimization
6+
problem at a higher level so that it is easy to try using different solvers.
47

5-
```@contents
6-
Pages = ["apimanual.md", "apireference.md", "testing.md"]
7-
Depth = 3
8+
[MathOptInterface.jl](https://github.com/jump-dev/MathOptInterface.jl) (MOI) is
9+
an abstraction layer designed to provide a unified interface to mathematical
10+
optimization solvers so that users do not need to understand multiple
11+
solver-specific APIs.
12+
13+
MOI can be used directly, or through a higher-level modeling interface like
14+
[JuMP](https://github.com/jump-dev/JuMP.jl).
15+
16+
## Background
17+
18+
MOI has been designed to replace [MathProgBase](https://github.com/JuliaOpt/MathProgBase.jl),
19+
which was been used by modeling packages such as [JuMP](https://github.com/jump-dev/JuMP.jl)
20+
and [Convex.jl](https://github.com/jump-dev/Convex.jl).
21+
22+
This second-generation abstraction layer addresses a number of limitations of
23+
MathProgBase. MOI is designed to:
24+
- Be simple and extensible, unifying linear, quadratic, and conic optimization,
25+
and seamlessly facilitate extensions to essentially arbitrary constraints and
26+
functions (e.g., indicator constraints, complementarity constraints, and
27+
piecewise-linear functions)
28+
- Be fast by allowing access to a solver's in-memory representation of a problem
29+
without writing intermediate files (when possible) and by using multiple
30+
dispatch and avoiding requiring containers of nonconcrete types
31+
- Allow a solver to return multiple results (e.g., a pool of solutions)
32+
- Allow a solver to return extra arbitrary information via attributes (e.g.,
33+
variable- and constraint-wise membership in an irreducible inconsistent subset
34+
for infeasibility analysis)
35+
- Provide a greatly expanded set of status codes explaining what happened during
36+
the optimization procedure
37+
- Enable a solver to more precisely specify which problem classes it supports
38+
- Enable both primal and dual warm starts
39+
- Enable adding and removing both variables and constraints by indices that are
40+
not required to be consecutive
41+
- Enable any modification that the solver supports to an existing model
42+
- Avoid requiring the solver wrapper to store an additional copy of the problem
43+
data
44+
45+
## Sections of this documentation
46+
47+
There are two main sections to this documentation.
48+
49+
The manual introduces the concepts needed to understand MOI and gives a
50+
high-level picture of how all of the pieces fit together. The primary focus of
51+
[Basic usage](@ref) is on MOI from the perspective of a user of the interface.
52+
The section [Advanced usage](@ref) provides more detail on advanced topics
53+
such as [Duality](@ref). The manual also has a section on [Implementing a solver interface](@ref).
54+
55+
In addition to the basic API, MathOptInterface.jl contains a number of
56+
submodules to help users interact with a model in MathOptInterface form. These
57+
include:
58+
- [The `Benchmarks` submodule](@ref)
59+
- [The `Bridges` submodule](@ref)
60+
- [The `FileFormats` submodule](@ref)
61+
- [The `Utilities` submodule](@ref)
62+
- [The `Test` submodule](@ref)
63+
64+
The [API Reference](@ref) page lists the complete API.
65+
66+
## Further reading
67+
68+
A [paper describing the design and features of MathOptInterface](https://arxiv.org/abs/2002.03447)
69+
is available on [arXiv](https://arxiv.org).
70+
71+
If you find MathOptInterface useful in your work, we kindly request that you
72+
cite the following paper:
73+
```
74+
@misc{
75+
legat2020mathoptinterface,
76+
title = {MathOptInterface: a data structure for mathematical optimization problems},
77+
author = {Beno{\^i}t Legat and Oscar Dowson and Joaquim Dias Garcia and Miles Lubin},
78+
year = {2020},
79+
eprint = {2002.03447},
80+
archivePrefix = {arXiv},
81+
primaryClass = {math.OC},
82+
url = {https://arxiv.org/abs/2002.03447},
83+
}
884
```

docs/src/manual/Benchmarks.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
```@meta
2+
CurrentModule = MathOptInterface
3+
DocTestSetup = quote
4+
using MathOptInterface
5+
const MOI = MathOptInterface
6+
end
7+
DocTestFilters = [r"MathOptInterface|MOI"]
8+
```
9+
10+
# The `Benchmarks` submodule
11+
12+
To aid the development of efficient solver wrappers, MathOptInterface provides
13+
benchmarking functionality. Benchmarking a wrapper follows a two-step process.
14+
15+
First, prior to making changes, run and save the benchmark results on a given
16+
benchmark suite as follows:
17+
18+
```julia
19+
using SolverPackage # Replace with your choice of solver.
20+
21+
using MathOptInterface
22+
const MOI = MathOptInterface
23+
24+
suite = MOI.Benchmarks.suite() do
25+
SolverPackage.Optimizer()
26+
end
27+
28+
MOI.Benchmarks.create_baseline(
29+
suite, "current"; directory = "/tmp", verbose = true
30+
)
31+
```
32+
Use the `exclude` argument to [`Benchmarks.suite`](@ref) to
33+
exclude benchmarks that the solver doesn't support.
34+
35+
Second, after making changes to the package, re-run the benchmark suite and
36+
compare to the prior saved results:
37+
38+
```julia
39+
using SolverPackage, MathOptInterface
40+
41+
const MOI = MathOptInterface
42+
43+
suite = MOI.Benchmarks.suite() do
44+
SolverPackage.Optimizer()
45+
end
46+
47+
MOI.Benchmarks.compare_against_baseline(
48+
suite, "current"; directory = "/tmp", verbose = true
49+
)
50+
```
51+
52+
This comparison will create a report detailing improvements and regressions.

docs/src/manual/Bridges.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
```@meta
2+
CurrentModule = MathOptInterface
3+
DocTestSetup = quote
4+
using MathOptInterface
5+
const MOI = MathOptInterface
6+
end
7+
DocTestFilters = [r"MathOptInterface|MOI"]
8+
```
9+
10+
# The `Bridges` submodule
11+
12+
A constraint can often be written in a number of equivalent formulations. For
13+
example, the constraint ``l \le a^\top x \le u``
14+
([`ScalarAffineFunction`](@ref)-in-[`Interval`](@ref)) could be re-formulated as
15+
two constraints: ``a^\top x \ge l`` ([`ScalarAffineFunction`](@ref)-in-[`GreaterThan`](@ref))
16+
and ``a^\top x \le u`` (`ScalarAffineFunction`-in-`LessThan`). An alternative
17+
re-formulation is to add a dummy variable `y` with the constraints ``l \le y \le u``
18+
([`SingleVariable`](@ref)-in-[`Interval`](@ref)) and ``a^\top x - y = 0``
19+
([`ScalarAffineFunction`](@ref)-in-[`EqualTo`](@ref)).
20+
21+
To avoid each solver having to code these transformations manually,
22+
MathOptInterface provides *bridges*. A bridge is a small transformation from one
23+
constraint type to another (potentially collection of) constraint type. Because
24+
these bridges are included in MathOptInterface, they can be re-used by any
25+
optimizer. Some bridges also implement constraint modifications and constraint
26+
primal and dual translations.
27+
28+
For example, the `SplitIntervalBridge` defines the reformulation of a
29+
`ScalarAffineFunction`-in-`Interval` constraint into a
30+
`ScalarAffineFunction`-in-`GreaterThan` and a
31+
`ScalarAffineFunction`-in-`LessThan` constraint. `SplitInterval` is the
32+
bridge optimizer that applies the `SplitIntervalBridge` rewriting rule. Given
33+
an optimizer `optimizer` implementing `ScalarAffineFunction`-in-`GreaterThan`
34+
and `ScalarAffineFunction`-in-`LessThan`, the optimizer
35+
```jldoctest; setup=:(model = MOI.Utilities.Model{Float64}())
36+
optimizer = MOI.Bridges.Constraint.SplitInterval{Float64}(model)
37+
MOI.supports_constraint(
38+
optimizer, MOI.ScalarAffineFunction{Float64}, MOI.Interval{Float64}
39+
)
40+
41+
# output
42+
43+
true
44+
```
45+
will additionally support [`ScalarAffineFunction`](@ref)-in-[`Interval`](@ref).
46+
Note that these [`Bridges.Constraint.SingleBridgeOptimizer`](@ref)s are mainly
47+
used for testing bridges.
48+
49+
It is recommended to rather use [`Bridges.full_bridge_optimizer`](@ref) which
50+
automatically selects the appropriate constraint bridges for unsupported
51+
constraints.
52+
```julia
53+
optimizer = MOI.Bridges.full_bridge_optimizer(model, Float64)
54+
```
55+
56+
### Variable reformulations
57+
58+
A variable is often created constrained in a set unsupported by the solver while
59+
it could be parametrized by variables constrained in supported sets.
60+
For example, the [`Bridges.Variable.VectorizeBridge`](@ref) defines the
61+
reformulation of a constrained variable in [`GreaterThan`](@ref) into a
62+
constrained vector of one variable in [`Nonnegatives`](@ref).
63+
The `Bridges.Variable.Vectorize` is the bridge optimizer that applies the
64+
[`Bridges.Variable.VectorizeBridge`](@ref) rewriting rule. Given an optimizer
65+
`optimizer` implementing constrained variables in [`Nonnegatives`](@ref),
66+
the optimizer
67+
```jldoctest; setup=:(model = MOI.Utilities.Model{Float64}())
68+
optimizer = MOI.Bridges.Variable.Vectorize{Float64}(model)
69+
MOI.supports_add_constrained_variable(optimizer, MOI.GreaterThan{Float64})
70+
71+
# output
72+
73+
true
74+
```
75+
will additionally support constrained variables in [`GreaterThan`](@ref).
76+
Note that these [`Bridges.Variable.SingleBridgeOptimizer`](@ref) are mainly
77+
used for testing bridges.
78+
79+
It is recommended to rather use [`Bridges.full_bridge_optimizer`](@ref), which
80+
automatically selects the appropriate bridges for unsupported constrained
81+
variables.

docs/src/manual/FileFormats.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
```@meta
2+
CurrentModule = MathOptInterface
3+
DocTestSetup = quote
4+
using MathOptInterface
5+
const MOI = MathOptInterface
6+
end
7+
DocTestFilters = [r"MathOptInterface|MOI"]
8+
```
9+
10+
# The `FileFormats` submodule
11+
12+
The `FileFormats` module provides functionality for reading and writing MOI
13+
models using [`write_to_file`](@ref) and [`read_from_file`](@ref).
14+
15+
To write a model `src` to a MathOptFormat file, use:
16+
```julia
17+
src = # ...
18+
dest = FileFormats.Model(format = FileFormats.FORMAT_MOF)
19+
MOI.copy_to(dest, src)
20+
MOI.write_to_file(dest, "file.mof.json")
21+
```
22+
The list of supported formats is given by the [`FileFormats.FileFormat`](@ref)
23+
enum.
24+
25+
Instead of the `format` keyword, you can also use the `filename` keyword
26+
argument to [`FileFormats.Model`](@ref). This will attempt to automatically
27+
guess the format from the file extension. For example:
28+
```julia
29+
src = # ...
30+
filename = "my_model.cbf.gz"
31+
dest = FileFormats.Model(filename = filename)
32+
MOI.copy_to(dest, src)
33+
MOI.write_to_file(dest, filename)
34+
35+
src_2 = FileFormats.Model(filename = filename)
36+
MOI.read_from_file(src_2, filename)
37+
```
38+
Note how the compression format (GZip) is also automatically detected from the
39+
filename.
40+
41+
In some cases `src` may contain constraints that are not supported by the file
42+
format (e.g., the CBF format supports integer variables but not binary). If so,
43+
you should copy `src` to a bridged model using [`Bridges.full_bridge_optimizer`](@ref):
44+
```julia
45+
src = # ... conic model ...
46+
dest = FileFormats.Model(format = FileFormats.FORMAT_CBF)
47+
bridged = MOI.Bridges.full_bridge_optimizer(dest, Float64)
48+
MOI.copy_to(bridged, src)
49+
MOI.write_to_file(dest, "my_model.cbf")
50+
```
51+
You should also note that even after bridging, it may still not be possible to
52+
write the model to file because of unsupported constraints (e.g., PSD variables
53+
in the LP file format).
54+
55+
In addition to [`write_to_file`](@ref) and [`read_from_file`](@ref), you can
56+
read and write directly from `IO` streams using `Base.write` and `Base.read!`:
57+
```julia
58+
src = # ...
59+
io = IOBuffer()
60+
dest = FileFormats.Model(format = FileFormats.FORMAT_MPS)
61+
MOI.copy_to(dest, src)
62+
write(io, dest)
63+
64+
seekstart(io)
65+
src_2 = FileFormats.Model(format = FileFormats.FORMAT_MPS)
66+
read!(io, src_2)
67+
```

docs/src/testing.md renamed to docs/src/manual/Test.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1-
# Testing
1+
```@meta
2+
CurrentModule = MathOptInterface
3+
DocTestSetup = quote
4+
using MathOptInterface
5+
const MOI = MathOptInterface
6+
end
7+
DocTestFilters = [r"MathOptInterface|MOI"]
8+
```
9+
10+
# The `Test` submodule
211

312
All solvers use the tests in this repository as extra correctness tests for themselves.
413
If we find a bug in one solver, instead of adding a test to that particular repository, we add it here so that all solvers can benefit.

docs/src/manual/Utilities.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
```@meta
2+
CurrentModule = MathOptInterface
3+
DocTestSetup = quote
4+
using MathOptInterface
5+
const MOI = MathOptInterface
6+
end
7+
DocTestFilters = [r"MathOptInterface|MOI"]
8+
```
9+
10+
# The `Utilities` submodule
11+
12+
TODO: document the utilities submodule

0 commit comments

Comments
 (0)