Pipelines
In one minuteChain analyses into reproducible workflows with a small YAML vocabulary. Stages are cached by content, so re-running a pipeline recomputes only what changed.
gyre pipeline run pipelines/airfoil-characterisation.yaml
gyre pipeline run pipelines/airfoil-characterisation.yaml --force # ignore the cache
gyre pipeline run pipelines/airfoil-characterisation.yaml --param NAME=VALUE --record FILE
gyre pipeline run pipelines/airfoil-characterisation.yaml --param-json 'NAME=JSON'
--param overrides a pipeline parameter: the value is read as JSON, otherwise as text, and a
number or boolean given for a parameter whose default is text stays text. --param-json (also
repeatable) takes a value that must be valid JSON and uses it exactly as given, whatever the
declared default is; it wins over --param for the same name. --record also writes this
run’s record to FILE.
Pipelines can also be started through the service (POST /api/v1/pipelines/{name}/runs) and
by agents (run_pipeline, get_pipeline_run). The definitions of a deployment are listed by
GET /api/v1/pipelines, each with runnable: a definition with shell stages cannot be
started through the service or MCP unless the operator sets GYRE_PIPELINES_ALLOW_SHELL=1.
Runs of the same pipeline in the same work directory execute one after another.
The service lists the *.yaml files of the directory named by GYRE_PIPELINES_DIR (default:
pipelines in the service’s working directory). The container image ships the analysis
definitions in /app/pipelines; the CI pipeline is not part of the image.
A run started through the service takes a stage’s case as a preset name or a CaseSpec
object. The check is made on every stage’s case after the run’s parameters are substituted,
whatever the parameter is called: a string that is not a preset name, or a case that cannot
be determined before the run (a reference to another stage’s output), is refused with 404
UnknownPreset. The stages of such a run also refuse to read a case file
(GYRE_PIPELINE_CASE_FILES=0 in their environment). Paths work with gyre pipeline run on the
host. A run leads its own process group and is terminated, with its stage processes, when the
service shuts down.
A definition that is not runnable answers 403 PipelineNotRunnable, with the reason as the
hint. A string parameter stays a string ("123" is not turned into a number). The record of
a run is the record of its status document (GET /api/v1/pipelines/runs/{id}).
A complete example#
name: airfoil-characterisation
params:
case: naca0012_euler
stages:
- id: baseline
uses: solve
with:
case: "${params.case}"
gradients: {of: [cl, cd], wrt: [alpha, mach]}
error_estimate: [cd]
- id: polar
uses: sweep
with:
case: "${params.case}"
parameter: alpha_deg
values: [0.0, 1.0, 2.0, 3.0, 4.0]
outputs: [cl, cd, cm]
gradients_wrt: [alpha]
- id: gates
uses: assert
with:
checks:
- {name: lift at 2 deg, value: "${stages.baseline.outputs.outputs.cl}", min: 0.25, max: 0.32}
- {name: polar converged, value: "${stages.polar.outputs.all_converged}", equals: true}
- id: summary
uses: report
needs: [gates]
with:
title: NACA 0012 characterisation
values:
cl: "${stages.baseline.outputs.outputs.cl}"
dcl_dalpha: "${stages.baseline.outputs.gradients.cl.alpha}"
| Key | Meaning |
|---|---|
params |
pipeline-level values, referenced as ${params.name} |
stages[].id |
unique name; outputs are referenced as ${stages.<id>.outputs.<path>} |
stages[].uses |
solve, sweep, order_study, verify, docs, shell, assert, report |
stages[].with |
inputs of the stage |
stages[].needs |
explicit dependencies (references add implicit ones) |
stages[].device |
auto, cpu or gpu for compute stages |
stages[].cache |
false to always run |
A reference that is the whole value keeps its type (number, boolean, list); inside a longer string it is formatted as text.
An assert stage takes a non-empty checks list. A check is {value, name} (the name is
optional) with at least one of the criteria min, max, abs_max and equals. Unknown keys,
a check without a criterion and a missing or empty checks list are rejected when the pipeline
is loaded, before any stage runs. min, max and abs_max compare numbers: a value that is
not a number (null from a diverged solve, a string, a list) or a criterion that is not a
number fails the check, and the check result says why in reason. equals compares values of
any type. A failed gate ends the stage with PipelineError: gate failed: […].
A solve stage takes case, overrides, gradients, error_estimate,
require_converged (default true: the stage fails if the solve does not converge) and
adapt:
- id: accurate
uses: solve
with:
case: bump_euler
overrides: {discretization.order: 1}
adapt: {output: cd, tolerance: 1.0e-4, max_order: 4}
- id: accuracy-gate
uses: assert
with:
checks:
- {name: tolerance met, value: "${stages.accurate.outputs.adaptation.met}", equals: true}
adapt selects the polynomial degree by the estimated error of output
(max_order defaults to 5). Unknown keys, a missing output or tolerance and a value that
is not a mapping are errors before the solve. The stage does not fail when the solve converged
but the tolerance was not met at max_order; adaptation.met is then false, which is what the
gate above tests. met is true only for a finite estimate whose adjoint solve converged, and
the selection ends at the first degree that does not converge; the level records in
adaptation.levels are described under Service.
Keys marked required have no default; a stage without them fails when it runs. case is a
preset name, the path of a specification file, or an inline specification (through the
service: a preset name or an inline specification only). overrides is a mapping of dotted
paths, as with gyre run --set.
solve — one analysis (the files of gyre run -o are written to the stage directory).
| Key | Type | Default | Meaning |
|---|---|---|---|
case |
name, path or mapping | required | the case to solve |
overrides |
mapping | {} |
changes to the case |
gradients |
{of: [...], wrt: [...]} |
none | total derivatives of scalar outputs; wrt accepts alpha_deg |
error_estimate |
list of output names | none | adjoint-based error estimates |
require_converged |
boolean | true |
fail the stage if the solve does not converge |
adapt |
{output, tolerance, max_order} |
none | order selection, see below; max_order defaults to 5 |
sweep — one warm-started solve per value, in one solver process.
| Key | Type | Default | Meaning |
|---|---|---|---|
case |
name, path or mapping | required | the case |
overrides |
mapping | {} |
changes to the case |
parameter |
input name | required | the swept input: a flow input of the discipline (mach, alpha, …) or alpha_deg |
values |
list of numbers | required | the values, in the order they are solved |
outputs |
list of output names | [cl, cd, cm] |
outputs recorded per row; may include f_surface |
gradients_wrt |
list of input names | none | adds d<output>/d<input> columns for the scalar outputs |
order_study — the same case at several polynomial degrees, each solved from scratch.
| Key | Type | Default | Meaning |
|---|---|---|---|
case |
name, path or mapping | required | the case |
orders |
list of integers | required | polynomial degrees; each replaces discretization.order |
overrides |
mapping | {} |
changes to the case (applied before the degree) |
error_estimate |
list of output names | none | adds <output>_corrected and <output>_error_estimate to each row |
verify — the verification suite.
| Key | Type | Default | Meaning |
|---|---|---|---|
suite |
quick or full |
quick |
the level of the studies |
output |
directory | the stage directory | where the study records and index.json are written |
only |
list of study ids | all studies | run a subset |
strict |
boolean | true |
fail the stage if a study of this invocation fails |
docs — build the documentation site.
| Key | Type | Default | Meaning |
|---|---|---|---|
output |
directory | site |
where the site is written |
verification |
directory | var/verification |
the study records the pages render |
shell — a command on the host (not startable through the service unless the operator
sets GYRE_PIPELINES_ALLOW_SHELL=1).
| Key | Type | Default | Meaning |
|---|---|---|---|
run |
string | required | the command line, run by the shell; a non-zero exit code fails the stage |
cwd |
directory | the directory gyre pipeline run was started in |
working directory of the command |
timeout |
number, seconds | none | the command and everything it started are stopped, and the stage fails, when it runs longer |
assert — a gate.
| Key | Type | Default | Meaning |
|---|---|---|---|
checks |
non-empty list | required | each {value, name?, min?, max?, abs_max?, equals?} with at least one criterion; rules below |
report — a Markdown and JSON summary (report.md, report.json in the stage directory).
| Key | Type | Default | Meaning |
|---|---|---|---|
title |
string | Pipeline report |
heading of the report |
values |
mapping name → value | {} |
the rows, usually references to outputs of other stages |
- id: degrees
uses: order_study
with: {case: bump_euler, orders: [1, 2, 3], error_estimate: [cd]}
- id: studies
uses: verify
with: {suite: quick, only: [free_stream, entropy_conservation], output: var/verification}
- id: site
uses: docs
needs: [studies]
with: {output: site, verification: var/verification}
- id: lint
uses: shell
with: {run: ".venv/bin/ruff check src tests", timeout: 600}
| Stage | Outputs |
|---|---|
solve |
converged, outputs, residual_norm, timing, case, optional gradients, error_estimate; with adapt also adaptation (output, tolerance, met, order, value, corrected, error, levels), and case describes the final degree |
sweep |
parameter, rows (one per value: parameter, converged, iterations, outputs, optional slopes d<output>/d<input>), all_converged |
order_study |
rows per polynomial degree, with corrected outputs if error estimates were requested |
verify |
studies (per-study pass/fail and wall time) and failed, both of this invocation; stale_failed (ids of failing results that earlier invocations left in the output directory) and skipped (studies not run, each {id, reason}). Pass or fail refers to this invocation only |
shell |
return code, duration, log tail |
assert |
the evaluated checks (fails the pipeline if any check fails) |
report |
path of the Markdown report and the collected values |
In a sweep, outputs may name the field output f_surface and gradients_wrt the shape
input x_surface; the rows then hold the loads and the shape derivatives
(d<output>/dx_surface) as lists. Slopes exist for scalar outputs only. Unknown names in
outputs or gradients_wrt are rejected before the first solve, as is gradients_wrt together
with outputs that contain no scalar output. gradients_wrt accepts alpha_deg (column
d<output>/dalpha_deg, the derivative per degree), like the solve stage’s gradients.wrt.
A point that does not converge reports the outputs of its failed iterate (null where they are
not finite) and null in every derivative column; derivatives are computed for converged
points only.
Each run writes var/pipelines/<name>/pipeline.json (status of every stage, keys, timings) and,
per stage, stage.json, a log (compute and shell stages), and whatever artefacts the stage
produces (a solve stage leaves the same files as gyre run -o). -o selects another
directory than var/pipelines.
pipeline.json is replaced by the next run of the pipeline; use --record FILE for a per-run
copy. A stage whose execution fails writes stage.json with status: failed. var/pipelines/<name>/
also contains a .lock file, which serialises the runs of the pipeline in that directory. See
Pipelines and provenance for the caching rules.