Skip to content

Commit

Permalink
chore: add devcontainer setup (#70)
Browse files Browse the repository at this point in the history
* docs: fix whitespace in README

* docs: fix whitespace in CONTRIBUTING.md

* chore: add dev container definition

* docs: document dev containers for contributors

* chore: enable autocomplete in dev container

* chore: remove useless WORKDIR from dev container Dockerfile

* chore: add missing cmake,clang to devcontainer

* chore: add system setup script

* chore: use system setup script in dev container

* chore: use system setup script in CI

* docs: rework contribution guide about dev containers

* docs: fix title case in contribution guide

* chore: use bundled SCIP in CI

* chore: drop conda setup from CI

* build: respect new scip_bundled feature everywhere

* build: require `scip` for `scip_bundled`

* docs: update scip usage docs

* chore: fix typo in Cargo.toml

* chore: fix scip feature usage in CI

* chore: no need to sudo in Dockerfile

* chore: do not run `cargo install` as root

* docs: be more specific about the dev container setup command
  • Loading branch information
KnorpelSenf authored Dec 26, 2024
1 parent a64ab42 commit 5bd41e9
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 49 deletions.
6 changes: 6 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM mcr.microsoft.com/devcontainers/rust:1-1-bookworm

RUN apt-get update && apt-get install -y vim curl

COPY ./build/ ./build/
RUN ./build/setup.sh && rm -r ./build
17 changes: 17 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "Existing Dockerfile",
"build": {
"context": "..",
"dockerfile": "./Dockerfile"
},
"customizations": {
"vscode": {
"extensions": [
"ms-azuretools.vscode-docker",
"ms-vscode-remote.remote-containers",
"rust-lang.rust-analyzer"
]
}
},
"postCreateCommand": "./build/postsetup.sh && P=~/.local/share/bash-completion/completions && mkdir -p $P && rustup completions bash > $P/rustup && rustup completions bash cargo > $P/cargo"
}
21 changes: 2 additions & 19 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,28 +21,11 @@ jobs:
- uses: Swatinem/rust-cache@v2
- name: Check formatting
run: cargo fmt -- --check
- uses: conda-incubator/setup-miniconda@v2
with:
activate-environment: test
allow-softlinks: true
- uses: actions/setup-node@v4
with:
node-version: 22
- name: install deps
run: |
sudo apt-get install coinor-cbc coinor-libcbc-dev libgsl-dev
# Install SCIP
conda install -y --prefix $CONDA/envs/test --channel conda-forge scip
echo "LD_LIBRARY_PATH=$CONDA/envs/test/lib" >> "${GITHUB_ENV}"
echo "DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:$CONDA/envs/test/lib" >> "${GITHUB_ENV}"
echo "PATH=$CONDA/envs/test/bin:$PATH" >> "${GITHUB_ENV}"
echo "CONDA_PREFIX=$CONDA/envs/test" >> "${GITHUB_ENV}"
# install CPLEX
curl -LO https://github.com/rust-or/good_lp/releases/download/cplex/cplex.bin
chmod u+x cplex.bin
./cplex.bin -f ./.github/cplex/response.properties
# Install wasm-pack
cargo install wasm-pack
run: ./build/setup.sh && ./build/postsetup.sh
- name: Build with all default solvers (no cplex)
run: cargo build --features all_default_solvers --tests
- name: Run tests with all default solvers (no cplex)
Expand All @@ -57,7 +40,7 @@ jobs:
- name: Run tests with lp_solvers
run: cargo test --no-default-features --features lp-solvers
- name: Run tests with SCIP
run: cargo test --no-default-features --features scip
run: cargo test --no-default-features --features "scip,scip_bundled"
- name: Run tests with CPLEX
run: cargo test --no-default-features --features cplex-rs
- name: Run tests with Clarabel
Expand Down
40 changes: 26 additions & 14 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,33 @@
# General guidelines
# General Guidelines

Contribution happens through github.
Contribution happens through GitHub.

Please format your code with `cargo fmt`, and if you add a new feature, update the README, the doc comments, and the doc tests accordingly.

# Adding a new solver
## Adding a New Solver

Adding a new solver should not take more than a few hundred lines of code, tests included.

- add the solver as an optional dependency in `Cargo.toml`
- add a file named after your solver in the [solvers](./src/solvers) folder
- you can copy microlp, our smallest solver interface, as a starting point.
- create a struct to store linear problems in a way that will make it cheap to dynamically add new constraints to the problem,
and easy to pass the problem to the solver once it has been fully constructed.
This generally means constructing vectors to which you can push values for each new constraint.
You can generally reuse data structures provided by the library for which you are creating a wrapper.
- implement a function named after your solver that takes an [`UnsolvedProblem`](https://docs.rs/good_lp/latest/good_lp/variable/struct.UnsolvedProblem.html) and returns the struct you defined above.
- implement the [`SolverModel`](https://docs.rs/good_lp/latest/good_lp/index.html#reexport.SolverModel) trait for your new problem type.
- add your solver to `lib.rs` and to the `all_default_solvers` feature in Cargo.toml.
- open a [pull request](https://github.com/rust-or/good_lp/pulls)
- add the solver as an optional dependency in `Cargo.toml`
- add a file named after your solver in the [solvers](./src/solvers) folder
- you can copy microlp, our smallest solver interface, as a starting point.
- create a struct to store linear problems in a way that will make it cheap to dynamically add new constraints to the problem,
and easy to pass the problem to the solver once it has been fully constructed.
This generally means constructing vectors to which you can push values for each new constraint.
You can generally reuse data structures provided by the library for which you are creating a wrapper.
- implement a function named after your solver that takes an [`UnsolvedProblem`](https://docs.rs/good_lp/latest/good_lp/variable/struct.UnsolvedProblem.html) and returns the struct you defined above.
- implement the [`SolverModel`](https://docs.rs/good_lp/latest/good_lp/index.html#reexport.SolverModel) trait for your new problem type.
- add your solver to `lib.rs` and to the `all_default_solvers` feature in Cargo.toml.
- open a [pull request](https://github.com/rust-or/good_lp/pulls)

## Dev Container Setup

This repository contains a dev container definition.
This gives you a working system setup with all solvers installed with a single command.
It will also give you the entire Rust toolchain as well as all necessary VS Code extensions.

1. Make sure you have [Docker](https://docs.docker.com/engine/install/) installed on your system
2. Make sure you have the [Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension installed in VS Code
3. Run the command `Dev Containers: Reopen in Container` in VS Code

Done.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ categories = ["mathematics", "algorithms", "science", "api-bindings", "data-stru
default = ["coin_cbc", "singlethread-cbc"]
singlethread-cbc = ["coin_cbc?/singlethread-cbc"]
scip = ["russcip"]
scip_bundled = ["russcip/bundled"]
all_default_solvers = ["coin_cbc", "microlp", "lpsolve", "highs", "russcip/bundled", "lp-solvers", "clarabel"] # cplex-rs is not included because it is incompatible with lpsolve
scip_bundled = ["russcip?/bundled"]
all_default_solvers = ["coin_cbc", "microlp", "lpsolve", "highs", "russcip", "russcip/bundled", "lp-solvers", "clarabel"] # cplex-rs is not included because it is incompatible with lpsolve
clarabel-wasm = ["clarabel/wasm"]
minilp = ["microlp"] # minilp is not maintained anymore, we use the microlp fork instead

Expand Down
28 changes: 14 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,20 +67,20 @@ You can find a resource allocation problem example in
This library offers an abstraction over multiple solvers. By default, it uses [cbc][cbc], but
you can also activate other solvers using cargo features.

| solver feature name | integer variables | no C compiler\* | no additional libs\*\* | fast | WASM |
| ---------------------- |-------------------| --------------- | ---------------------- | ---- |---------|
| [`coin_cbc`][cbc] | |||||
| [`highs`][highs] | ||\+ |||
| [`lpsolve`][lpsolve] | |||||
| [`microlp`][microlp] | |||||
| [`lp-solvers`][lps] | |||||
| [`scip`][scip] | |||||
| [`cplex-rs`][cplex] | ||\+\+ |||
| [`clarabel`][clarabel] | ||||\+\+\+ |
| solver feature name | integer variables | no C compiler\* | no additional libs\*\* | fast | WASM |
| ---------------------- | ----------------- | --------------- | ---------------------- | ---- | -------- |
| [`coin_cbc`][cbc] ||||||
| [`highs`][highs] |||\+ |||
| [`lpsolve`][lpsolve] ||||||
| [`microlp`][microlp] ||||||
| [`lp-solvers`][lps] ||||||
| [`scip`][scip] ||||||
| [`cplex-rs`][cplex] |||\+\+ |||
| [`clarabel`][clarabel] |||||\+\+\+ |

- \* no C compiler: builds with only cargo, without requiring you to install a C compiler
- \*\* no additional libs: works without additional libraries at runtime, all the dependencies are statically linked
- \+ highs itself is statically linked and does not require manual installation. However, on some systems, you may have to [install dependencies of highs itself](https://github.com/rust-or/good_lp/issues/29).
- \+ highs itself is statically linked and does not require manual installation. However, on some systems, you may have to [install dependencies of highs itself](https://github.com/rust-or/good_lp/issues/29).
- \+\+ the cplex_rs crate links statically to a local installation of the IBM ILOG CPLEX Optimizer.
- \+\+\+ to use clarabel for WASM targets, set the `clarabel-wasm` feature flag

Expand Down Expand Up @@ -171,9 +171,9 @@ Additionally, the end user of your program will have to install the desired solv

SCIP is currently one of the fastest open-source solvers for mixed integer programming (MIP) and mixed integer nonlinear programming (MINLP). It is also a framework for constraint integer programming and branch-cut-and-price. It allows for total control of the solution process and the access of detailed information down to the guts of the solver.

`good_lp` uses SCIP through its rust interface [russcip](https://github.com/mmghannam/russcip) which can ship a precompiled binary. The easiest way to use SCIP with `good_lp` is therefore to enable the `scip_bundled` feature.
`good_lp` uses SCIP through its rust interface [russcip](https://github.com/mmghannam/russcip) which can ship a precompiled binary. The easiest way to use SCIP with `good_lp` is therefore to enable both the `scip` and the `scip_bundled` features.

You can also use a custom installation of SCIP by enabling the `scip` feature instead. A good way of installing SCIP is by downloading a precompiled package from [here](https://scipopt.org/index.php#download) or through conda by running
You can also use a custom installation of SCIP by enabling only the `scip` feature. A good way of installing SCIP is by downloading a precompiled package from [here](https://scipopt.org/index.php#download) or through conda by running
```
conda install --channel conda-forge scip
```
Expand All @@ -194,7 +194,7 @@ Since cplex-rs-sys uses [bindgen](https://github.com/rust-lang/rust-bindgen) to

### [Clarabel][clarabel]

**Clarabel** is a free
**Clarabel** is a free
([Apache 2.0](https://github.com/oxfordcontrol/Clarabel.rs/blob/main/LICENSE.md))
linear programming solver written in Rust by the
[Oxford Control group](https://eng.ox.ac.uk/control/).
Expand Down
7 changes: 7 additions & 0 deletions build/postsetup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env bash

# Print commands, exit upon error
set -ex

# Install wasm-pack
cargo install wasm-pack
File renamed without changes.
15 changes: 15 additions & 0 deletions build/setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env bash

# Print commands, exit upon error
set -ex

# Change CWD to script location
cd "${0%/*}"

# Install CBC, HiGHS, lp_solve
DEBIAN_FRONTEND=noninteractive sudo apt-get install -y coinor-cbc coinor-libcbc-dev libgsl-dev build-essential cmake clang

# Install CPLEX
curl -LO https://github.com/rust-or/good_lp/releases/download/cplex/cplex.bin
chmod u+x cplex.bin
./cplex.bin -f ./response.properties

0 comments on commit 5bd41e9

Please sign in to comment.