Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ jobs:
- name: Checkout
uses: actions/checkout@v4

# QEMU emulates arm64 so the image can also be built for it.
- name: Set up QEMU
uses: docker/setup-qemu-action@v3

# Buildx is needed for multi-arch builds and layer caching.
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
Expand Down Expand Up @@ -54,7 +58,6 @@ jobs:
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
# Publish for x86_64 Linux hosts. Add ,linux/arm64 here if you
# also want ARM (e.g. M-series Mac / Pi 4+) — it roughly doubles
# build time because there's no native arm64 runner on public GH.
platforms: linux/amd64
# x86_64 hosts and ARM hosts (e.g. Apple silicon Macs). The arm64
# build runs under QEMU, which roughly doubles the build time.
platforms: linux/amd64,linux/arm64
52 changes: 0 additions & 52 deletions .github/workflows/docker.yml

This file was deleted.

2 changes: 2 additions & 0 deletions DOCKER.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ Run the pre-built image from the GitHub Container Registry (use a release tag su
docker run -p 5000:5000 ghcr.io/kiguli/scen-opt:latest
```

The image is built for both x86_64 and ARM (e.g. Apple silicon) machines.

Or build the image yourself:

```bash
Expand Down
5 changes: 4 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,7 @@ USER appuser

EXPOSE 5000

CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--workers", "2", "--timeout", "7200", "app:app"]
# Default worker count. Override with -e GUNICORN_CMD_ARGS="--workers 4".
ENV GUNICORN_CMD_ARGS="--workers 2"

CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--timeout", "7200", "app:app"]
15 changes: 7 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The tool is implemented as a Python Flask web application with a modern JavaScri

## Installation

**Prerequisites:** Python 3.12+ and pip.
**Prerequisites:** Python 3.10 or newer (3.12 recommended) and pip.

```bash
# Clone the repository
Expand All @@ -26,7 +26,7 @@ python3 app.py

The server starts at `http://127.0.0.1:5000`. Open this URL in a browser to access the web interface.

**Optional:** For best performance on SDP problems, install [MOSEK](https://www.mosek.com/) (free academic license available). See [MOSEK Support](#mosek-support) for license configuration.
**MOSEK:** [MOSEK](https://www.mosek.com/) is the recommended solver: it is the most stable for these problems and was used for all published results. Its Python package is installed by `requirements.txt`, but it needs a licence (free for academics). See [MOSEK Support](#mosek-support) for license configuration.

## Quick Start

Expand Down Expand Up @@ -94,7 +94,7 @@ where the scenario constraints are Linear Matrix Inequalities (LMIs) parameteriz
| Scenarios | delta_i | Sampled uncertainty realizations (N samples) |
| Slack penalty | rho | Penalty on constraint relaxation (rho = 0 means hard scenario constraints) |
| Regularization | tau | Regularization strength toward reference point x_ref |
| Norm type | p | Norm for regularization (1, 2, inf, fro, nuc) |
| Norm type | p | Norm for regularization (any p ≥ 1, inf, or fro) |
| Confidence | beta | Confidence parameter for risk bounds (e.g. beta = 0.01 for 99% confidence) |

### Risk Quantification
Expand Down Expand Up @@ -170,7 +170,6 @@ Each benchmark follows a standardized layout:
│ ├── program_numeric.json Upload-Program definition (numeric mode)
│ ├── scenarios.csv Sampled uncertainty realizations
│ ├── scenarios_numeric.csv Per-row-flattened matrices for numeric mode
│ ├── c.csv Objective vector
│ └── ... Additional problem-specific data
└── results/
├── metrics.json Solver output (cost, risk bounds, complexity)
Expand All @@ -183,13 +182,13 @@ Each benchmark follows a standardized layout:
```bash
cd benchmarks/<benchmark_name>

# Regenerate scenarios (optional, data already provided)
# Regenerate scenarios (optional, data already provided; some generators need extra packages, listed at the top of the script)
python generate.py

# Solve the program
# Solve the program (MOSEK by default; e.g. --solver CLARABEL without a MOSEK licence)
python run.py

# Generate the paper figure
# Generate the paper figure (needs matplotlib: pip install matplotlib)
python plot.py
```

Expand Down Expand Up @@ -269,7 +268,7 @@ Identifies the support list of a solved scenario program: the constraints whose

- **License upload:** When MOSEK is selected as the solver, a modal prompts you to upload your `mosek.lic` file. The license is **not** stored on the server.
- **Browser caching:** After the first upload, the license is cached in your browser's session storage. Subsequent solves skip the modal automatically. A cache indicator and "Clear" button appear below the solver dropdown.
- **Local license:** If MOSEK is installed locally with a system license (e.g., at `~/mosek/mosek.lic`), click "Skip" in the modal to use it directly.
- **Local license:** If MOSEK is installed locally with a system license (e.g., at `~/mosek/mosek.lic`), click "I have a local license" in the modal to use it directly.
- **Concurrent users:** Each MOSEK solve with an uploaded license runs in an isolated subprocess with the license written to an ephemeral `/tmp` directory (RAM-backed, auto-purged). Multiple users can solve simultaneously without conflicts.

## Docker
Expand Down
Loading
Loading