# Configuration

csauto reads its configuration from a TOML file and environment variables.

## Config file lookup order

csauto finds `csauto.toml` in this order (first match wins):

1. `--config /path/to/csauto.toml` (CLI flag)
2. `CSAUTO_CONFIG` environment variable
3. `./csauto.toml` (current working directory)
4. `<repo_root>/csauto.toml` (repository root, i.e. parent of the `csauto/` package)

If no file is found, all default values are used.

---

## Complete annotated configurations

### Local workstation (native)

```toml
# Use the code_saturne binary installed on the machine
runtime = "native"
solver_bin = "/opt/code_saturne/bin/code_saturne"

# No Slurm; csauto run launches at most 2 cases at a time
use_slurm = false
max_parallel = 2

# Web UI: accessible only from this machine
host = "127.0.0.1"
port = 8000
```

### HPC cluster with Slurm

```toml
# Native code_saturne on the compute nodes
runtime = "native"
solver_bin = "/opt/code_saturne/bin/code_saturne"

# Submit each case as a Slurm job
use_slurm = true

# MPI options injected via CS_MPIEXEC_OPTIONS for each sbatch job
mpi_exec_options = "--mca btl vader,self,tcp --bind-to core"

# csauto run keeps at most 20 jobs submitted (queued or running) at a time
max_parallel = 20

# Serve UI on login node, tunnel with: ssh -L 8000:127.0.0.1:8000 login-node
host = "127.0.0.1"
port = 8000
```

### Singularity / Apptainer container

```toml
runtime = "singularity"
singularity_image = "/opt/images/code_saturne.sif"
singularity_bin = "/usr/bin/apptainer"   # optional: auto-detected if in PATH

use_slurm = false
max_parallel = 2

host = "127.0.0.1"
port = 8000
```

For code_saturne with `use_slurm = true`, `csauto` submits a dedicated batch
script for the Singularity runtime (`.csauto.slurm.sh` in the case folder). The
job follows the same pattern as a manual HPC launch:
`code_saturne run --stage --initialize`, then `srun ./cs_solver --mpi`, then
`code_saturne run --finalize`. Other runs are submitted with `sbatch --wrap`.

### Docker container

```toml
runtime = "docker"
docker_image = "simvia/code_saturne"   # optional: the solver's own image by default

use_slurm = false
max_parallel = 2

host = "127.0.0.1"
port = 8000
```

Containers mount the campaign folder at `/csauto` and start the solver inside the
case folder (`docker run --rm ...`). Any image works:

- an image whose ENTRYPOINT is the solver, or a script that sets up the
  environment and starts it (modules, spack, conda, a switch to another user),
  gets only the solver's arguments, as before;
- an image whose ENTRYPOINT runs the command it is given (`tini --`,
  `exec "$@"` scripts) gets the full solver command;
- an image without ENTRYPOINT gets the solver as `--entrypoint`, so it must be
  on the image's `PATH`.

csauto tells the first two apart by starting the image once with `true` (one
short container per image, the first time a csauto process launches it).

### code_aster

```toml
solver = "code_aster"
runtime = "docker"   # docker_image defaults to simvia/code_aster:17.4.0

max_parallel = 2
```

For the `native` runtime, `run_aster` must be in `PATH`, or `solver_bin` must
point to it.

In containers, csauto starts `run_aster` with `bash`, after sourcing
`/opt/activate.sh` when the image has it (the `simvia/code_aster` images do). A
custom image needs `bash`, and `run_aster` on its `PATH` once that file is
sourced (or from the start, when the image has no such file). An image whose
ENTRYPOINT starts `run_aster` itself only gets its arguments.

### Remote access with authentication

```toml
runtime = "native"
solver_bin = "/opt/code_saturne/bin/code_saturne"
use_slurm = false
max_parallel = 4

# Expose UI to all interfaces
host = "0.0.0.0"
port = 8000

# Required when host is not 127.0.0.1 or localhost
[api]
token = "your-secret-token"
```

---

## All configuration keys

| Key | Default | Description |
|---|---|---|
| `solver` | `code_saturne` | The campaign's solver: `code_saturne`, `code_aster`, or `stub` (a fake solver for tests). `csauto prepare` records it in `RUNS/campaign.json` (see [architecture.md](/architecture#solver-adapter-boundary)) |
| `runtime` | `auto` | Execution backend: `auto`, `native`, `docker`, or `singularity` |
| `solver_bin` | (auto-detected) | Path to the native solver executable (`code_saturne`, or `run_aster` for code_aster) for `native` runtime |
| `docker_image` | (the solver's own image) | Docker image name for `docker` runtime; defaults to `simvia/code_saturne` for code_saturne, `simvia/code_aster:17.4.0` for code_aster. csauto keeps the image's own ENTRYPOINT (see [Docker container](#docker-container)) |
| `singularity_image` | (none) | Path or URI to `.sif` image for `singularity` runtime |
| `singularity_bin` | (auto-detected) | Path to `apptainer` or `singularity` binary |
| `use_slurm` | (auto-detected) | `true` to force Slurm submission, `false` to force local |
| `mpi_exec_options` | (none) | MPI options for Slurm jobs, passed to code_saturne as `CS_MPIEXEC_OPTIONS` (code_aster ignores it) |
| `max_parallel` | `1` | Default of `csauto run --max-parallel`. The web UI does not read it: set Max Parallel in the Run or Restart dialog (left empty, local runs are capped to `cpu_count // (n * nt)` at once, a scheduler receives every selected case) |
| `mesh_mode` | `symlink` | How `prepare` places the solver's shared dirs (`MESH`, plus `POST` for code_saturne) into `RUNS/`: `symlink` or `copy` (see [concepts.md](/concepts#shared-meshpost-directories)) |
| `host` | `127.0.0.1` | Bind address for `serve` |
| `port` | `8000` | Bind port for `serve` |
| `[api].token` | (none) | API authentication token |

---

## Environment variables

| Variable | Description |
|---|---|
| `CSAUTO_CONFIG` | Explicit path to `csauto.toml` |
| `CSAUTO_MIN_FREE_MEMORY_PERCENT` | Local runs only: a queued case waits for a launch slot while less than this share of the RAM is available and another case is running (default `10`, `0` disables; Linux only) |
| `CSAUTO_USE_SLURM` | Override Slurm mode: `1`/`true`/`yes`/`on` or `0`/`false`/`no`/`off` |
| `DISPLAY` | Required for GUI launch (`Open GUI` from the web UI) |

---

## Priority rules

**Runtime**: CLI flags (`--runtime`, `--solver-bin`, etc.) override the TOML values.

**Solver**: commands on an existing campaign use the solver recorded in
`RUNS/campaign.json` by `prepare`, whatever directory they run from; a different
`solver` in `csauto.toml` is ignored with a warning. `prepare` refuses to add
cases to a folder prepared for another solver.

**Slurm detection order**:
1. `use_slurm` in `csauto.toml`: if set, this is authoritative
2. `CSAUTO_USE_SLURM` environment variable
3. Auto-detection: checks if `sbatch` is in `PATH` and Slurm environment variables are set

**API token**: `serve --token` overrides `[api].token` from config.

---

## Auto runtime resolution

When `runtime = "auto"`, csauto tries backends in this order, among the
runtimes the solver supports (code_saturne and code_aster support all three):

1. Explicit `solver_bin` set → use `native`
2. Explicit `singularity_image` set → use `singularity`
3. `docker` command available → use `docker`
4. The solver's executable (`code_saturne`, `run_aster`) in `PATH` → use `native`
5. None found → error

Asking explicitly for a runtime the solver does not support is refused before
anything starts.

---

## `mpi_exec_options` and Slurm

When Slurm submission is active and `mpi_exec_options` is set, code_saturne
receives the value as:

```bash
CS_MPIEXEC_OPTIONS="<mpi_exec_options>" <code_saturne run command>
```

With a container runtime, the variable is set inside the container instead. If
not set, no `CS_MPIEXEC_OPTIONS` is injected. code_aster ignores this option.
