picurv is the workflow orchestrator for PICurv. It validates YAML inputs, generates C runtime artifacts, and runs or schedules solver/postprocessing stages. It is also the primary user-facing contract layer: many defaults, aliases, and translation rules are enforced here before the C solver starts.
After make all, bin/picurv is a launcher for the stable picurv_cli/picurv source-tree entrypoint. The implementation lives in picurv_cli/. The launcher uses .picurv-venv/bin/python when bootstrap created a managed environment, then a bootstrap-recorded or user-provided PICURV_PYTHON, and finally python3. Source etc/picurv.sh to add bin/ to your PATH and expose picurv_cli/ as a fallback so picurv works from any directory even if bin/picurv is temporarily absent before make conductor recreates the launcher. If bin/picurv does not exist yet, run ./picurv_cli/picurv build or make conductor.
Primary commands:
initbuildversion, versions, and sourceinputssync-configrunprecomputestoragesummarizesubmitcancelsweepvalidateCore idea:
case.yml, solver.yml, monitor.yml, and post.yml are modular profiles.case.yml can be paired with a quieter monitor.yml, a different solver strategy, or a different post recipe without changing the physical setup file.Help:
Behavior:
examples/<template_name>/ into a new working directory,<workspace>/config/, <workspace>/inputs/, <workspace>/assets/, <workspace>/runs/, and <workspace>/studies/ tree,<workspace>/config/, preserving colliding variants below <workspace>/config/variants/,.picurv-workspace.yml; software.picurv is empty by default and therefore means the latest active installation,--dest,.picurv-origin.json with the source repo path and template name,.picurv-execution.yml for optional site-specific launcher overrides,.picurv-execution.yml when the source clone already has one, otherwise from inert defaults,bin/ directory via PATH.Binary pinning (--pin-binaries, superseded by run-time pinning):
--pin-binaries is passed, simulator and postprocessor are copied into the case directory,resolve_runtime_executable uses a copy only when it is a sibling of the picurv script that was invoked. init places no launcher in the case, so the picurv on PATH ignores these copies and launches the installation's bin/,picurv itself is never copied — it is always used from PATH and is safe to update mid-run since it only launches the C binaries.Examples:
Behavior:
Makefile via make,make all when you do not provide an explicit make target,.picurv-origin.json when run from an initialized case,<repo>/logs/build.log in the source repo,make manually.Direct make all keeps the traditional stdout-only behavior. When you want the same source-repo build plus a warnings-only artifact, use:
This writes:
<repo>/logs/build.log<repo>/logs/build.warnings.logExamples:
picurv version prints the release, Git commit, and dirty-tree build identity of the Python conductor, then reads back what simulator --version and postprocessor --version actually report. Those two identities are not the same fact: the conductor's says which source staged a run, the binaries' says which build produced its checkpoints, and an edited C tree that was never rebuilt makes them disagree. The run manifest records both, and run warns at staging when a binary is stale.
Each executable's --version has a second line naming the PETSc it was compiled against, petsc <version> <debug|optimized> <arch> <dir>, taken from PETSc's own headers. The same text is stamped into the binary, so picurv version still shows it when the executable cannot start - for example undefined symbol: petscstack, a debug-PETSc build launched with an optimized PETSc on the library path. Where ldd exists, it also shows the libpetsc the current shell would load and marks it when that library lies outside the PETSc the binary was built against. Binaries built before the stamp show PETSc: not recorded.
picurv version status reports the same thing and then validates it, exiting 1 when the conductor, either executable, or the workspace's software.picurv requirement disagree, and naming each disagreement. Bare picurv version always exits 0: it is an informational surface, and a job script that must refuse an incoherent build should ask for the validating form explicitly. Both accept --format json, which adds coherent and problems to the payload.
make delivers the identity through a generated include/picurv_build_identity.h rather than command-line defines, so ordinary header-dependency tracking rebuilds the two translation units that stamp it whenever the commit or dirty state changes. A binary reporting release 0.0.0 was built outside make and carries no identity.
picurv source update fetches branches and tags without changing the active checkout. picurv versions list reports tags; versions install <version> or versions activate [version] requires a clean source checkout, selects the exact Git version, and rebuilds. A bare release such as 0.1.0 resolves to its v0.1.0 tag when no ref carries the bare name. With no argument, activate reads the workspace's exact software.picurv value and refuses ranges.
Make variables and options after the version reach make exactly as they do for picurv build, so a cluster install names its build configuration:
With no version, the first word after activate may be a make assignment or, after --, a make option; neither is a tag or commit, so it goes to make rather than to Git.
A make target is refused, because the install verifies the default build. Success is reported only after simulator and postprocessor report the identity of the commit just checked out; the conductor re-reads that identity rather than using the one it computed at startup, which still names the previous commit.
versions activate rewrites by git checkout --detach <tag> followed by the default make build. It does not install side-by-side versioned prefixes such as /software/picurv/0.2.0/, and picurv is not a version multiplexer.That is a deliberate trade, and it has three consequences worth knowing before you rely on a version pin:
software.picurv requirement fail. There is one active release per installation, not one per workspace.bin/ runs whatever was built last when it starts. Every generated job script refuses to launch an executable whose identity differs from the one read at staging, and a run staged with --pin-executables keeps its own copies (12. Binary Resolution and Rebuild Safety).activate refuses a dirty checkout, so uncommitted work must be committed or stashed first.These commands are tested in tests/test_workspace_lifecycle.py against real Git repositories and stubbed builds: source update against a live origin and an unreachable remote, versions list ordering, install and activate argument routing, and the refusal of a build that does not carry the new identity. Rebuilding a real release is not part of the suite.
Both versions activate and a failed workspace version check name the installation they would change, so the effect is stated rather than discovered. If you need concurrent releases — several people on one filesystem, or reproducing a published result while developing against a newer tree — install PICurv more than once and select between them with your shell or your site's module system.
pull-source and status-source remain legacy maintenance surfaces. New workspaces normally use the active installation and the version commands instead of copying executables into every case.
sync-config refreshes files from examples/<template_name>/ into the case directory. It compares against the template as init lays it out - canonical <workspace>/config/ names, variants under <workspace>/config/variants/, rewritten paths - so each case file is matched with the template file it was made from. By default it preserves user-modified files and only copies missing files:
Run from inside the workspace, --case-dir can be omitted.
--prune is conservative: it removes only files previously recorded as template-managed that no longer exist in the source template. User-created case files are not pruned. sync-config does not copy execution.example.yml into a case; instead it creates .picurv-execution.yml only when the case does not already have one.
pull-source refreshes every local branch with a configured upstream, then restores the branch you started on, so you can update code without leaving the case directory. It refuses a checkout detached by versions install or versions activate: restoring that commit after the pull would leave the code that runs unchanged while the branches moved.
status-source inspects source commit drift, copied binary drift, and template-file drift before you decide what to sync. Template files are compared the same way sync-config compares them, so a file reported modified is one sync-config would skip:
For older cases that do not yet have .picurv-origin.json, pass --source-root /path/to/PICurv. For sync-config, also pass --template-name <example_name> if the template cannot be inferred.
init, sync-config and status-source are tested in tests/test_case_maintenance.py, and make smoke initializes, validates and dry-runs every shipped template. On a fresh flat_channel workspace with one edited <workspace>/config/solver.yml, status-source reported exactly that file modified and none missing, sync-config skipped it and left the case root unchanged, and sync-config --overwrite restored it in place.
status-source --format json payload highlights:
source_repo_root, case_dirlast_known_source_git_commit, current_source_git_commit, source_commit_changedbinaries:case_bin_current, case_bin_different, case_bin_missingconfig:case_current_files, case_modified_files, case_missing_filestemplate_removed_since_last_sync (when template-managed tracking is available)Stages:
--solve--post-processInputs for --solve:
--case <case.yml>--solver <solver.yml>--monitor <monitor.yml> (logging, diagnostics, profiling, output cadence, directories)Inputs for --post-process:
--post <post.yml>--solve, or --run-dir <existing_run_dir>MPI/local options:
-n, --num-procsPICURV_MPI_LAUNCHER, MPI_LAUNCHER, nearest .picurv-execution.yml, nearest legacy .picurv-local.yml, then default mpiexec.Staging/execution options:
--cluster <cluster.yml>--scheduler slurm (optional explicit selector)--no-submit (stage run artifacts without starting the local or Slurm backend)Preflight options:
--dry-run (resolve and print launch/artifact plan only, including PETSc diagnostic flags and log paths)--format json (machine-readable output for --dry-run)Local example:
In this command, the solver and field postprocessor both run with 8 ranks.
Slurm example (generate + submit):
Stage artifacts without starting execution:
Add --cluster my_case/cluster.yml to stage Slurm scripts instead of local commands.
Follow-up execution/submission from existing artifacts:
Post-only continuation examples:
post.yml -> io.paraview_series optionally adds physical-time .pvd collections to this workflow. With enabled: true, scope: lineage, the conductor follows the existing manifest ancestry and indexes matching ancestor VTK recipes together with the current run's frames. Prepare ancestor output first. Post catch-up refreshes the collection even when the field window is already complete; solve-only and spectra-only invocations do not refresh it. See Configuration Reference: Postprocessor YAML for recipe compatibility and Tutorial: A Guide to Visualizing Your Results for opening the result.
post.yml; each run processes only the steps whose output is missing or stale, and launches nothing when every step is up to date:state.json with the recipe fingerprint and its checkpoint's commit marker. A step is processed again when any of its output files is missing, when the recipe changed, or when its checkpoint changed. Output written before these records existed is kept when it is newer than its checkpoint. Steps need not be contiguous: a single deleted file is reprocessed alone.--recompute regenerates every requested step that has a committed checkpoint, for every selected stage.420, a run over 0..1000 processes the committed steps; a later run picks up the rest once the solver writes them.--continue belongs to --solve; on a post-only command it is ignored with a warning.Qcrit_nodal, changing the statistics output prefix, or changing step_interval, PICurv treats it as a new recipe with its own output directory and processes its whole window.<run.visualization>/ or <run.analysis.statistics>/.Graceful shutdown note:
cluster.yml -> execution.extra_sbatch.signal requests an early warning signal, PICurv also traps SIGUSR1, SIGTERM, and SIGINT, then writes one last snapshot at the next safe checkpoint even when the normal recording interval has not been reached.cluster.yml -> execution.walltime_guard; keep execution.extra_sbatch.signal as fallback protection for preemption/manual termination or jobs that may not reach the warmup window.signal: "USR1@300" for srun-launched jobs, or signal: "B:USR1@300" plus exec mpirun ... for direct mpirun batch launches.Runtime stream logs:
<run.runtime_logs>/.<run.scheduler>/ for both local and Slurm launches.Behavior:
--overview reports run metadata plus curated case, solver, and monitor summaries,--case, --solver, and --monitor are additive selectors for individual copied configs,summarize --run-dir ... preserves the implicit latest-step health behavior,--list-plot-series discovers numeric scalar histories available to --plot,--plot <qualified-series> delegates time-history rendering to generators/plot.gen,matplotlib, which bootstrap installs in the managed PICurv environment by default,# Continuation from step <N> separators into append-only logs,--last <n> keeps its last N chronological records per line,--plot-output <path> saves without opening a window; headless interactive requests save under <run.analysis>/plots/,Examples:
Configuration summaries include configured values plus useful normalized and derived values such as Reynolds number, nondimensional timestep, normalized solver selections, effective monitoring cadence, and enabled diagnostics. Text output uses glanceable dashboards with aligned field groups and compact tables; use --format json for structured automation output.
Plotting supports numeric scalar histories from continuity, particle metrics, momentum, Poisson, profiling, runtime memory, and solution-convergence logs. Block-based histories render one line per block and profiling histories render one line per function. Residual/norm series use logarithmic scaling when all values are positive; --linear-y forces linear scaling. Plot mode is standalone and does not combine with overview/config/selected-step selectors.
generators/plot.gen is the standalone rendering layer. It accepts the versioned, normalized JSON request produced by picurv through stdin, and can also render a saved request directly:
The normalized request contains plot labels, scale selection, window metadata, and ordered labeled lines of numeric [timestep, value] points. plot.gen does not parse PICurv run directories or logs.
Typical sources:
<run.runtime_logs>/Continuity_Metrics.log<run.runtime_logs>/Particle_Metrics.log (per-step Lost plus run-local Lost Total when available)<run.runtime_logs>/Momentum_Solver_Convergence_History_Block_*.log<run.runtime_logs>/Poisson_Solver_Convergence_History_Block_*.log<run.runtime_logs>/solution_convergence.log (mode-specific speed/KE drift and L2 norms)<run.runtime_logs>/Profiling_Timestep_Summary.csv when enabled<run.runtime_logs>/Runtime_Memory.log when monitor.diagnostics.runtime_memory_log.enabled is true<run.analysis.metrics>/les_coefficient.csv when case.yml -> models.physics.turbulence.les.diagnostics.enabled is true; the les.* series carry the effective coefficient, its spread, eddy-viscosity levels, the modelled subgrid energy, and the pre-clipping backscattering and limited fractions<run.runtime_logs>/PETSc_*_Solver.log / <run.runtime_logs>/PETSc_*_PostProcessor.log when file-backed PETSc diagnostics are enabled<run.scheduler>/*_solver.log or <run.scheduler>/solver_*.out for sampled particle snapshot previewsWhen particle snapshots are available, summarize reports sampled diagnostics such as:
Dry-run example (no file writes):
Common run use cases:
--solve --post-process--solve--post-process --run-dir ...--no-submitsubmit --run-dir ...--dry-runprecompute creates immutable, content-addressed workspace assets without launching the solver. It uses exactly the same provider graph as run --solve: grids build before any Python initial condition or inlet slice that consumes them. Provider settings, referenced-file checksums, and software identity determine reuse.
The build occurs under assets/.precompute-* and publishes to assets/objects/ only after the whole requested dependency closure succeeds. The mutable pointer in assets/sets/ records which objects match the current case file. A normal run reuses those objects automatically and writes the exact selection to inputs/assets.lock.yml. When the case file's set has no match - a new, copied, or renamed case file - the run looks for a published object with the same provider identity before building, adopts it, and records it in that case file's set. Generated payloads are byte-reproducible (their summaries record paths relative to themselves), so rebuilding an unchanged provider publishes the same object rather than a duplicate.
Providers owned by the C runtime are reported but never approximated by Python. A selected C-only provider makes precompute fail before publication. See Run Artifact Lifecycle Contract for the directory and dependency contracts.
Behavior:
--no-submit artifacts without regenerating configs or scripts,<run.scheduler>/submission.json to locate staged Slurm scripts or local command tokens,solve, post-process, or both,all is selected,launch_mode: local,--force is explicitly provided,sweep --continue --no-submit staged; the metrics aggregation job follows the post array (afterany), as sweep chains it,Examples:
Notes:
--run-dir supports local and Slurm staged runs,--study-dir remains Slurm-only,--dry-run prints the exact local command or sbatch plan,--force is the opt-in path for deliberate resubmission.Behavior:
<run.scheduler>/submission.json from an existing run directory,solve and/or post-process,scancel <job_id> for the selected stage set by default,--graceful, sends scancel --signal=USR1 --full <job_id> for solver jobs, reaching the batch process and MPI children so the runtime can write the latest safe off-cadence step at the next checkpoint,--graceful is present,Examples:
Notes:
<run.scheduler>/submission.json,--graceful requests solver shutdown and final output; if a job is wedged or not reaching runtime checkpoints, rerun without --graceful to hard-cancel it,--dry-run is useful when you want to confirm the recorded stage/job mapping first.Behavior (new study):
study.ymlstudies/<study_id>/cases/solver_array.sbatch, post_array.sbatch, and metrics_aggregate.sbatchpost_array.sbatch with the same cluster allocation as the solver arrayafterok) → metrics (afterany) chain (unless --no-submit)Behavior (--continue):
resolve_restart_source)Behavior (--reaggregate):
validate does not launch solver/post and does not create run/study artifacts.
What validate is for:
picurv preserves a C-side default intentionally.The table below is generated by introspecting the assembled argparse parser - build_main_parser() in picurv_cli/cli.py together with the registrars delegated from other modules, such as add_storage_parser() in picurv_cli/storage/. Reading cli.py alone understates the command set, which is why the generator exercises the built parser rather than pattern-matching the source.
It is regenerated by make docs-cli-reference and checked by make audit-cli-reference, so a parser change makes it stale and fails CI. The narrative guidance in the sections above is hand-written and complements it; this section is the exhaustive reference.
17 top-level commands.
picurv buildCalls the project's Makefile directly through `make`.
positional arguments
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
make_args (positional) | yes | — | — | Arguments to pass directly to the make command (e.g., 'clean-project'). |
options
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
--source-root | no | — | — | Optional override for the PICurv source repository root. |
--case-dir | no | — | — | Optional case directory used to resolve .picurv-origin.json when not running from that case. |
picurv cancelLook up scheduler/submission.json inside an existing run directory and cancel
options
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
--run-dir | yes | — | — | Path to the run directory whose Slurm job(s) should be canceled. |
--stage | no | all, post-process, solve | all | Which recorded stage job(s) to cancel (default: all). |
--dry-run | no | — | False | Show which `scancel` command(s) would run without actually canceling anything. |
--graceful | no | — | False | For solver jobs, request a clean runtime shutdown by sending SIGUSR1 to the process tree instead of hard-canceling immediately. The solver writes the latest safe off-cadence step at the next checkpoint. Non-solver stages still use ordinary scancel. |
picurv initCreate a case workspace from examples/<template_name>.
positional arguments
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
template_name (positional) | yes | — | — | Name of the case template directory to copy (e.g., 'flat_channel'). |
options
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
--dest | no | — | — | Optional name for the new directory. Defaults to the template name. Path is relative to your current working directory. |
--source-root | no | — | — | Optional override for the PICurv source repository root. Useful when running from a copied case without metadata. |
--pin-binaries | no | — | False | Copy simulator and postprocessor into the case directory. Use this to freeze specific binary versions for reproducibility or to protect running jobs from concurrent rebuilds. |
picurv inputsoptions
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
picurv inputs importpositional arguments
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
kind (positional) | yes | grid, initial-condition, inlet-profile, reference-field | — | |
source (positional) | yes | — | — | Existing source file. |
options
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
--name | no | — | — | Destination name; defaults to the source basename. |
--mode | no | copy, hardlink, reference, reflink | copy | How to retain the input. Reference mode records but does not copy an external path. |
--workspace | no | — | — | Workspace root; defaults to discovery from the current directory. |
picurv precomputeGenerate configured deterministic artifacts, such as grid_gen grids,
options
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
--case | yes | — | — | Path to case.yml containing grid/profile/IC generator settings. |
--only | no | — | all | Comma-separated asset kinds (grid, initial-condition, inlet-profiles), or all. |
picurv pull-sourceLegacy maintenance command; new workspaces use `picurv source update` and
options
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
--case-dir | no | — | — | Optional case directory used to resolve .picurv-origin.json. |
--source-root | no | — | — | Optional override for the PICurv source repository root. |
--remote | no | — | — | Optional git remote name (e.g., origin). |
--branch | no | — | — | Optional branch name. If provided without --remote, origin is assumed. |
--current-branch-only | no | — | False | Only pull the currently checked out branch instead of iterating across all local tracking branches. |
--no-rebase | no | — | False | Use plain git pull instead of git pull --rebase. |
picurv runExecute solver and/or post-processing stages.
options
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
-n, --num-procs | no | — | 1 | Number of MPI processes for solver and post-processing stages. |
--cluster | no | — | — | Path to cluster.yml for Slurm execution mode. |
--scheduler | no | — | — | Explicit scheduler selector (currently 'slurm'). |
--no-submit | no | — | False | Stage run artifacts without starting local execution or Slurm submission. |
--pin-executables | no | — | — | Copy simulator and postprocessor into the run's config/bin/ at staging, so a later rebuild of the installation cannot change what the job runs. On a pinned run, re-pins it to the current build. |
--no-pin-executables | no | — | — | Launch the installation's executables even when the workspace sets reproducibility.pin_executables. Slurm jobs still check at start that they report the build identity read at staging. |
--dry-run | no | — | False | Resolve and print planned commands/artifacts, including diagnostic flags and log paths, without writing files. |
--format | no | json, text | text | Output format for --dry-run (default: text). |
stages
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
--solve | no | — | False | Execute the solver stage (creates a new run directory). |
--post-process | no | — | False | Execute the post-processing stage on a run directory. |
--continue | no | — | False | Extend an existing run's solve in place. Requires --solve and --run-dir, and start_step > 0; appends to existing solver output/logs. Post-processing needs no flag: it always skips up-to-date steps. |
solver inputs (required for --solve)
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
--case | no | — | — | Path to the case definition file (e.g., case.yml). |
--solver | no | — | — | Path to the solver settings profile (e.g., solver.yml). |
--monitor | no | — | — | Path to the monitoring, diagnostics, and I/O profile (e.g., monitor.yml). |
--restart-from, --from | no | — | — | Path to an existing run directory to restart from. Use 'latest' to select the newest compatible local workspace run. |
--statistics-state | no | carry, reset | — | For a branched restart with field statistics enabled, this is required: 'reset' discards the parent's accumulated windows, 'carry' resumes compatible saved window state. Ignored when field statistics are disabled. |
--require-precomputed | no | — | False | Refuse to build missing or stale deterministic assets while staging the run. |
--fetch-missing | no | — | False | Try the configured storage profile before rebuilding a missing workspace asset. |
post-processor inputs (required for --post-process)
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
--run-dir | no | — | — | Path to an existing run directory. (Used with --post-process or --solve --continue). |
--post | no | — | — | Path to the post-processing recipe file (e.g., post.yml). |
--only | no | — | — | Comma-separated post stages to run: 'fields' (the field post-processor) and/or 'spectra'. Defaults to every stage. Use --only spectra to measure spectra without running the field stage. |
--recompute | no | — | False | Regenerate every requested step that has a committed checkpoint, including steps whose output is up to date (for example, after rebuilding the postprocessor). Applies to every selected stage. |
picurv sourceoptions
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
picurv source updateoptions
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
--remote | no | — | origin |
picurv status-sourceLegacy maintenance command; `picurv version status` reports build coherence for
options
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
--case-dir | no | — | — | Optional case directory used to resolve .picurv-origin.json. |
--source-root | no | — | — | Optional override for the PICurv source repository root. |
--template-name | no | — | — | Optional template name override when metadata is absent. |
--format | no | json, text | text | Output format (default: text). |
picurv storageManage PICurv run and study data through a configured rclone remote.
options
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
picurv storage listoptions
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
--profile | no | — | — | Configured storage profile name. |
--storage-config | no | — | — | Explicit storage YAML path. |
--search | no | — | — | Case-insensitive search across IDs, labels, identities, and tags. |
--workspace-label | no | — | — | Show only archives belonging to this workspace identity. |
--format | no | json, text | text |
picurv storage offloadoptions
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
--run-dir | no | — | — | Standalone run directory. |
--study-dir | no | — | — | Sweep study directory. |
--workspace | no | — | — | Workspace root: its configuration, catalog, and assets, not its runs and studies, which are their own artifacts. |
--case-id | no | — | — | One numbered study member, such as case_0003; repeat to select several. |
--completed | no | — | False | With --study-dir, select every finished member and skip the rest. |
--profile | no | — | — | Configured storage profile name. |
--storage-config | no | — | — | Explicit storage YAML path. |
--include-inputs | no | — | False | With --workspace, also archive user-supplied files under inputs/. |
--label | no | — | — | Human-readable searchable label. |
--notes | no | — | — | Free-text note recorded with the archive and shown by `show`. |
--tag | no | — | — | Repeatable KEY=VALUE catalog tag. |
--compression | no | auto, balanced, fast, maximum, none | — | |
--policy | no | analysis-ready, metadata-only, restart-ready | — | |
--retain | no | — | — | Keep this component local regardless of --policy; repeatable and comma-separated. One of: checkpoints, logs, analysis, visualization, inputs, raw-output. |
--drop | no | — | — | Prune this component locally regardless of --policy; same names as --retain. |
--workers | no | — | — | |
--keep-latest-checkpoint | no | — | — | |
--drop-all-checkpoints | no | — | — | |
--dry-run | no | — | False |
picurv storage planoptions
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
--run-dir | no | — | — | Standalone run directory. |
--study-dir | no | — | — | Sweep study directory. |
--workspace | no | — | — | Workspace root: its configuration, catalog, and assets, not its runs and studies, which are their own artifacts. |
--case-id | no | — | — | One numbered study member, such as case_0003; repeat to select several. |
--completed | no | — | False | With --study-dir, select every finished member and skip the rest. |
--profile | no | — | — | Configured storage profile name. |
--storage-config | no | — | — | Explicit storage YAML path. |
--compression | no | auto, balanced, fast, maximum, none | — | |
--policy | no | analysis-ready, metadata-only, restart-ready | — | |
--retain | no | — | — | Keep this component local regardless of --policy; repeatable and comma-separated. One of: checkpoints, logs, analysis, visualization, inputs, raw-output. |
--drop | no | — | — | Prune this component locally regardless of --policy; same names as --retain. |
--workers | no | — | — | |
--keep-latest-checkpoint | no | — | — | |
--drop-all-checkpoints | no | — | — |
picurv storage protectoptions
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
--run-dir | no | — | — | Standalone run directory. |
--study-dir | no | — | — | Sweep study directory. |
--workspace | no | — | — | Workspace root: its configuration, catalog, and assets, not its runs and studies, which are their own artifacts. |
--case-id | no | — | — | One numbered study member, such as case_0003; repeat to select several. |
--completed | no | — | False | With --study-dir, select every finished member and skip the rest. |
--profile | no | — | — | Configured storage profile name. |
--storage-config | no | — | — | Explicit storage YAML path. |
--include-inputs | no | — | False | With --workspace, also archive user-supplied files under inputs/. |
--label | no | — | — | Human-readable searchable label. |
--notes | no | — | — | Free-text note recorded with the archive and shown by `show`. |
--tag | no | — | — | Repeatable KEY=VALUE catalog tag. |
--compression | no | auto, balanced, fast, maximum, none | — | |
--policy | no | analysis-ready, metadata-only, restart-ready | — | |
--retain | no | — | — | Keep this component local regardless of --policy; repeatable and comma-separated. One of: checkpoints, logs, analysis, visualization, inputs, raw-output. |
--drop | no | — | — | Prune this component locally regardless of --policy; same names as --retain. |
--workers | no | — | — | |
--keep-latest-checkpoint | no | — | — | |
--drop-all-checkpoints | no | — | — | |
--dry-run | no | — | False |
picurv storage pruneoptions
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
--workspace | no | — | — | Workspace root; defaults to discovery from the cwd. |
--assets | yes | — | False | Select the workspace asset store. Required: prune removes nothing else. |
--unused-locally | yes | — | False | Confirm that only objects with no active local run are removed. |
--dry-run | no | — | False | Report the decision only. |
--profile | no | — | — | Configured storage profile name. |
--storage-config | no | — | — | Explicit storage YAML path. |
picurv storage restoreoptions
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
--archive-id | no | — | — | Globally unique remote archive ID. |
--workspace-id | no | — | — | Restore a workspace archive by its recorded workspace identity. |
--run-dir | no | — | — | Cold run containing a local storage marker. |
--study-dir | no | — | — | Cold study containing a local storage marker. |
--case-id | no | — | — | |
--profile | no | — | — | Configured storage profile name. |
--storage-config | no | — | — | Explicit storage YAML path. |
--to | no | — | — | Optional alternate restore destination. |
--checkpoint | no | — | — | One committed step; repeat to select several. |
--checkpoints | no | — | — | An inclusive step range as START:END or START:END:STRIDE; repeatable. |
--component | no | analysis, assets, inputs, logs, raw-output, unclassified, visualization, workspace-config, workspace-inputs | — | Restore one semantic component; repeat as needed. |
--force | no | — | False | Allow merge into a non-matching existing destination. |
--workers | no | — | — | Parallel download/extraction workers. |
picurv storage setupoptions
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
--remote | yes | — | — | Rclone remote and base path, such as labstore:picurv-data. |
--profile | no | — | archive | Profile name (default: archive). |
--storage-config | no | — | — | Storage YAML path (default: ./.picurv-storage.yml). |
--compression | no | auto, balanced, fast, maximum, none | auto | |
--chunk-size-gib | no | — | 8.0 | |
--workers | no | — | <local CPU count, capped 1-8> | CPU workers for compression and restoration. |
--offload-policy | no | analysis-ready, metadata-only, restart-ready | metadata-only | |
--keep-latest-checkpoint | no | — | False | Retain the newest committed checkpoint after offload. |
--staging-directory | no | — | — | Optional local directory for one archive chunk at a time. |
--dry-run | no | — | False |
picurv storage showoptions
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
--archive-id | yes | — | — | |
--profile | no | — | — | Configured storage profile name. |
--storage-config | no | — | — | Explicit storage YAML path. |
picurv storage statusoptions
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
--run-dir | no | — | — | Standalone run directory. |
--study-dir | no | — | — | Sweep study directory. |
--workspace | no | — | — | Workspace root: its configuration, catalog, and assets, not its runs and studies, which are their own artifacts. |
--case-id | no | — | — | One numbered study member, such as case_0003; repeat to select several. |
--completed | no | — | False | With --study-dir, select every finished member and skip the rest. |
--format | no | json, text | text |
picurv storage verifyoptions
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
--archive-id | no | — | — | |
--run-dir | no | — | — | |
--study-dir | no | — | — | |
--workspace | no | — | — | Workspace whose own archive to verify. |
--case-id | no | — | — | |
--profile | no | — | — | Configured storage profile name. |
--storage-config | no | — | — | Explicit storage YAML path. |
picurv submitConsume an existing artifact set created by picurv --no-submit and
options
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
--run-dir | no | — | — | Path to a staged run directory created by `picurv run ... --no-submit`. |
--study-dir | no | — | — | Path to a staged study directory created by `picurv sweep --cluster ... --no-submit`. |
--stage | no | all, post-process, solve | all | Which staged job(s) to submit (default: all). |
--force | no | — | False | Allow re-submitting a stage already marked as submitted in scheduler/submission.json. |
--dry-run | no | — | False | Show which local command(s) or `sbatch` command(s) would run without starting anything. |
picurv summarizeBuild read-only configuration overviews, run-health summaries, and scalar time-history plots.
options
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
--run-dir | yes | — | — | Path to the run directory to inspect. |
--overview | no | — | False | Summarize run metadata plus copied case, solver, and monitor configs without implicitly requesting health. |
--case | no | — | False | Summarize the copied run-local case.yml. |
--solver | no | — | False | Summarize the copied run-local solver.yml. |
--monitor | no | — | False | Summarize the copied run-local monitor.yml. |
--list-plot-series | no | — | False | List scalar histories available to --plot. |
--list-series | no | — | False | ==SUPPRESS== |
--plot | no | — | — | Plot one qualified scalar history, such as momentum.residual_norm (requires matplotlib). |
--plot-spectrum | no | — | — | Plot up to six representative measured energy spectra, including the first and last states, overlaid on the initial-condition spectrum. Takes an optional task-name substring when the recipe measured more than one spectrum (requires matplotlib). |
--last | no | — | — | Plot only the last N chronological records per line. |
--plot-output | no | — | — | Save the plot to this path instead of opening an interactive window. |
--linear-y | no | — | False | Force linear y-axis scaling instead of automatic residual/norm log scaling. |
--step | no | — | — | Specific completed timestep to summarize. |
--latest | no | — | False | Summarize the most recently appended completed step found in available artifacts (default behavior). |
--max-step | no | — | False | Summarize the numerically largest timestep found in available artifacts. |
--snapshot-rows | no | — | 5 | Number of sampled particle snapshot rows to preview when solver stream output contains them. |
--format | no | json, text | text | Output format (default: text). |
picurv sweepLaunch studies from study.yml + cluster.yml, whether the study uses
options
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
--study | no | — | — | Path to study.yml defining either a `parameters` cross-product expansion or explicit parameter_sets, plus metrics. |
--cluster | no | — | — | Path to cluster.yml defining Slurm resources. |
--no-submit | no | — | False | Generate all study artifacts without submitting jobs. |
--pin-executables | no | — | — | Copy simulator and postprocessor into the run's config/bin/ at staging, so a later rebuild of the installation cannot change what the job runs. On a pinned run, re-pins it to the current build. |
--no-pin-executables | no | — | — | Launch the installation's executables even when the workspace sets reproducibility.pin_executables. Slurm jobs still check at start that they report the build identity read at staging. |
--study-dir | no | — | — | Path to an existing study directory (for --continue/--reaggregate). |
--continue | no | — | False | Continue a partially-completed study. Requires --study-dir. |
--reaggregate | no | — | False | Re-run metrics aggregation on a completed study. Requires --study-dir. |
--auto-fetch | no | — | False | Restore cold-storage study members automatically instead of refusing. Requires a configured storage profile. |
picurv sync-configCopy updated example template files into an existing case directory.
options
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
--case-dir | no | — | — | Optional case directory to refresh. Defaults to the current case. |
--source-root | no | — | — | Optional override for the PICurv source repository root. |
--template-name | no | — | — | Optional template name override (e.g., flat_channel). Required when metadata is absent. |
--overwrite | no | — | False | Overwrite case files even when they differ from the template. |
--prune | no | — | False | Remove stale files that were previously tracked as template-managed but no longer exist in the source template. |
picurv validateValidate one or more config roles. No solver/post execution and no run/study artifact writes.
options
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
--case | no | — | — | Path to case.yml |
--solver | no | — | — | Path to solver.yml |
--monitor | no | — | — | Path to monitor.yml (logging, diagnostics, profiling, and I/O) |
--restart-from | no | — | — | Path to a run directory to validate restart from. |
--continue | no | — | False | Validate continue-in-place mode. Requires --run-dir. |
--run-dir | no | — | — | Path to an existing run directory (for --continue validation). |
--post | no | — | — | Path to post.yml |
--cluster | no | — | — | Path to cluster.yml |
--study | no | — | — | Path to study.yml |
--strict | no | — | False | Enable additional strict checks for selected roles. |
picurv versionReport the build identity shared by the Python conductor and the native
positional arguments
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
version_action (positional) | no | status | — | 'status' validates conductor/executable/workspace coherence and exits 1 on disagreement. |
options
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
--format | no | json, text | text |
picurv versionsoptions
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
picurv versions activatepositional arguments
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
version (positional) | no | — | — | Version/tag; defaults to the workspace requirement. |
make_args (positional) | yes | — | — | Make variables and options passed to the build, as with 'picurv build' (for example SYSTEM=cluster). Place them after every picurv option. |
options
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
--workspace | no | — | — | Workspace root; defaults to discovery from the current directory. |
picurv versions installpositional arguments
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
version (positional) | yes | — | — | Tag, bare release (resolved to v<release>), or commit. |
make_args (positional) | yes | — | — | Make variables and options passed to the build, as with 'picurv build' (for example SYSTEM=cluster). Place them after every picurv option. |
options
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
picurv versions listoptions
| Flag | Required | Choices | Default | Description |
|---|---|---|---|---|
-h, --help | no | — | — | show this help message and exit |
run:
--solve (requires --case, --solver, --monitor)--post-process (requires --post; requires --run-dir when --solve is not selected)--case <path>--solver <path>--monitor <path> (logging, diagnostics, profiling, output cadence)--post <path>--run-dir <path>--restart-from <run-dir|latest> (alias --from; latest picks the newest compatible workspace run)--statistics-state {reset,carry} (branched restart only; entries at 8.6 Restart Statistics State Entries)--require-precomputed (refuse to build a missing or stale workspace asset)--fetch-missing (try the configured storage profile before rebuilding one)-n, --num-procs <int> (solver and field postprocessor stages)--cluster <cluster.yml> (enables Slurm mode)--scheduler <name> (must be used with --cluster; must match cluster.yml:scheduler.type)--no-submit (stage files and submission metadata without starting execution)--dry-run (no file writes; plan only, including diagnostic artifacts)--format {text,json} (dry-run output format)validate:
--case <path>--solver <path>--monitor <path>--post <path>--cluster <path>--study <path>--strict (adds additional checks for selected roles; documented below)precompute:
--case <path>--only <grid,initial-condition,inlet-profiles> (defaults to all configured providers)summarize:
--run-dir <path>--overview--case--solver--monitor--step <n>, --latest, or --max-step--snapshot-rows <positive-int>--list-plot-series or --plot <qualified-series>--last <positive-int> (requires --plot)--plot-output <path> (requires --plot)--linear-y (requires --plot)--format {text,json} (--list-plot-series supports JSON; --plot rejects JSON)submit:
--run-dir <path> or --study-dir <path>--stage {all,solve,post-process}--force--dry-runcancel:
--run-dir <path>--stage {all,solve,post-process}--dry-runsweep:
--study <study.yml> (required)--cluster <cluster.yml> (required)--no-submit (optional)--continue (required)--study-dir <path> (required)--cluster <cluster.yml> (optional; overrides original cluster resources)--reaggregate (required)--study-dir <path> (required)init:
<template_name>--dest <dir>--source-root <repo>--pin-binaries (legacy; copies simulator/postprocessor into the case, used only when that directory's own picurv is invoked)build:
--source-root <repo>--case-dir <case_dir>MAKE_ARGS... are passed directly to makesync-config:
--case-dir <case_dir>--source-root <repo>--template-name <template>--overwrite--prunepull-source:
--case-dir <case_dir>--source-root <repo>--remote <git_remote>--branch <git_branch>--no-rebasestatus-source:
--case-dir <case_dir>--source-root <repo>--template-name <template>--format {text,json}--strict does not change baseline schema validation, but it adds file-system consistency checks for selected roles:
--study:study.base_configs are loaded and revalidated as real case/solver/monitor/post bundles.Use --strict in CI/pre-submit checks when validating reusable profile libraries or study manifests.
picurv run --dry-run --format json emits a deterministic plan payload with these top-level keys:
mode ("dry-run")created_at (ISO timestamp)launch_mode (local or slurm)warnings (list)inputs (resolved absolute paths)stages (stage-specific launch plans)artifacts (predicted files/directories, deduplicated)run_id_preview / run_dir_preview (when known)solver_num_procs_effectivepost_num_procs_effectivenum_procs_effective (currently mirrors solver count)For file-backed grid modes, artifacts includes the planned staged grid path (<run.inputs>/grid/grid.run). For grid.mode: grid_gen, it also includes the generated PICGRID path (<run.inputs>/grid/grid.generated.picgrid), its quality report (<run.analysis.metrics>/grid.info), and its .vts preview (<run.visualization>/precompute/grid.vts) - all three unconditionally, since picurv chooses the destination rather than accepting stats_file/vts_file config keys. Dry-run still does not run generators/grid.gen or write these files. For generated prescribed-flow profiles, artifacts includes the dimensional generated .picslice, the solver-scale staged .picslice, and profile.info.
Stage entries under stages.solve and stages.post-process include:
mode (local or slurm)num_procs_effectivelaunch_command (tokenized command list)launch_command_string (shell-ready display string)Additional stage fields:
script (Slurm script path in cluster mode)command / command_string (local staged command tokens/display string)source_data_directory (post stage source directory resolution)restart_source_directory (solve stage, when restart source is resolved)Dry-run guarantees:
Validation and CLI usage errors are emitted as one-line, machine-parseable records:
Current normalized error code set:
CLI_USAGE_INVALIDCFG_MISSING_SECTIONCFG_MISSING_KEYCFG_INVALID_TYPECFG_INVALID_VALUECFG_FILE_NOT_FOUNDCFG_GRID_PARSECFG_INCONSISTENT_COMBOThis contract is exercised by Python tests and should remain stable for wrappers and CI parsers.
PICurv is intended to be used with reusable profile libraries.
Typical pattern:
case.yml focused on physics, grid, BCs, and run duration,solver.yml focused on numerical strategy,monitor.yml focused on logging, diagnostics, profiling, and I/O cadence,post.yml focused on analysis outputs,Examples:
case.yml + a lighter monitor.yml for fast debug runs,case.yml + a stricter solver.yml for convergence checks,case.yml + multiple post.yml recipes for different analysis outputs,solver.yml reused across many cases when the discretization strategy is stable.This is why picurv treats these roles as separate inputs instead of one monolithic file.
For prebuilt reusable profiles, also see the local guides under:
config/solvers/config/monitors/config/postprocessors/config/schedulers/examples/master_template/picurv resolves simulator and postprocessor for a run using this precedence:
<run.config>/active.json records executables, every stage of that run launches those copies.picurv script (e.g. case-local copies from --pin-binaries), it is used next.bin/ directory — the default location after make all.Run-time pinning (opt-in). Staging a solve with --pin-executables copies both executables into <run.config.bin> and records each copy's path, SHA-256, and build identity in active.json. The run manifest and software lock then describe those copies, not the installation. Without the switch a run launches the installation's bin/.
| Setting | Pins |
|---|---|
| neither switch, no workspace setting | no |
--pin-executables on run or sweep | yes |
reproducibility.pin_executables: true in the workspace | yes, for every staging in it |
--no-pin-executables | no, even when the workspace sets it |
--pin-executables on a pinned run re-pins it to the current build under that continuation's revision in <run.config.history>; --no-pin-executables on a pinned run is refused, so the run's records never name a build it did not launch.$RUN_DIR's copy. A study whose members disagree about pinning is refused.Job-start identity check. Every generated Slurm script, pinned or not, runs the executable's --version after module setup and before the launcher, and exits before any rank starts when the reported identity, including the PETSc line, differs from the one read at staging. When staging could not read an identity, the job logs the one it finds and launches.
bin/picurv is a launcher for picurv_cli/picurv. This means:
picurv_cli/ package,make conductor recreates the launcher (idempotent),.picurv-venv Python,etc/picurv.sh adds bin/ to PATH so picurv works from any directory.Rebuilding while jobs are running:
picurv (the Python script) mid-run is always safe — it is only used to launch jobs, not during solver execution.simulator/postprocessor (make all) overwrites the binaries in bin/. A pinned run is unaffected. An unpinned Slurm job that has not started fails its job-start identity check instead of running the new build, and has to be restaged.picurv version checks the currently active identity.Recommended workflow for concurrent development and production:
| Value | Maps to |
|---|---|
copy | copy |
hardlink | hardlink |
reference | reference |
reflink | reflink |
Every mode below is supported. They were exercised locally (asset-store-local-2026-09-21) and on the cluster's Lustre scratch (asset-lifecycle-grace-2026-10-01), where copy, hardlink and reference imports each fed a precompute that a second precompute reused, and reflink was refused with the filesystem's reason. Object accumulation at campaign scale and remote-backed pruning have not been exercised.
Identity. picurv inputs import <kind> <source> --mode copy.
What it does. Copies the source into its canonical workspace inputs/ home and catalogues the source checksum, size, and new relative path.
When to choose it. Default to copy when portability and independent ownership matter more than local disk duplication. Unlike links, the workspace remains valid if the source is moved or deleted.
Parameters it owns. Optional --name supplies the destination basename.
Interactions. Storage includes the copied file when a run locks and materializes an asset derived from it.
Diagnostics. Success prints the catalog ID and relative path; an existing target or missing source fails before the catalog changes.
Evidence. Unit verified — tests/test_workspace_lifecycle.py checks the copied bytes and catalog entry. Integration verified - asset-store-local-2026-09-21: a copied field became an initial-condition object that a second precompute reused unchanged. Production verified - asset-lifecycle-grace-2026-10-01: on Lustre a copied grid got its own inode, and a precompute from it was reused by the next precompute.
Limitations. Uses additional disk space equal to the imported file.
Identity. picurv inputs import <kind> <source> --mode reflink.
What it does. Requests a copy-on-write clone through cp --reflink=always, then catalogues it like a copy.
When to choose it. Prefer it for very large local inputs on a filesystem that supports reflinks: it begins space-efficiently but remains independently writable, unlike hardlink.
Parameters it owns. Optional --name supplies the destination basename.
Interactions. Failure does not fall back silently; choose copy explicitly when the filesystem reports that reflinks are unsupported.
Diagnostics. The import fails with the native copy error if reflink creation is unavailable and writes no catalog record.
Evidence. Integration verified - asset-store-local-2026-09-21: on a filesystem without reflink support the import failed with cp's "Operation not supported", left no temporary file, and wrote no catalog record. A successful reflink import has not been exercised; that needs a filesystem that supports it. Production verified - asset-lifecycle-grace-2026-10-01: Lustre scratch refused it the same way. Supported on the owner's decision, since the refusal path is the one most users meet.
Limitations. A successful clone needs a copy-on-write filesystem with reflink support, such as Btrfs or XFS; none has been tested.
Identity. picurv inputs import <kind> <source> --mode hardlink.
What it does. Creates a second directory entry for the same inode and catalogues the imported path.
When to choose it. Use it only for immutable, same-filesystem inputs when avoiding a full copy matters and every owner agrees not to modify the bytes.
Parameters it owns. Optional --name supplies the destination basename.
Interactions. Source and destination share mutations. Asset checksums detect a changed provider input and prevent stale object reuse, but cannot undo the mutation.
Diagnostics. Cross-filesystem or permission failures are reported before the catalog changes.
Evidence. Integration verified - asset-store-local-2026-09-21: the imported path shares the source's inode, the catalog records the source checksum, and after one byte of the shared file changed the next precompute built a new object rather than reusing the old one. Production verified - asset-lifecycle-grace-2026-10-01: on Lustre the imported grid shared the source's inode (2 links), and its precompute was reused.
Limitations. Shared-inode ownership is easy to misuse, and it cannot cross filesystems.
Identity. picurv inputs import <kind> <source> --mode reference.
What it does. Writes a small .reference.yml containing the absolute target, registration checksum, and byte count; it does not copy the target.
When to choose it. Use it for an authoritative shared dataset that should remain externally owned. Choose copy when the workspace or storage archive must be portable.
Parameters it owns. Optional --name names the reference record.
Interactions. Resolution fails loudly when the target is missing. A target whose bytes changed since registration is used as it now is: its current checksum selects a new asset object, so nothing stale is reused, but no warning is printed and the registration checksum is not compared. Storage records the dependency but neither archives nor prunes the external file.
Diagnostics. Registration prints an external-reference warning; missing targets fail when registered or consumed.
Evidence. Unit verified — tests/test_workspace_lifecycle.py checks reference content and catalog identity. Integration verified - asset-store-local-2026-09-21: a reference import fed a solver run, and changing one byte of its target built a new object. Production verified - asset-lifecycle-grace-2026-10-01: on Lustre a 280-byte reference record fed a precompute that the next precompute reused.
Limitations. Restoring the workspace cannot restore an external target; its owner must make the same path available or the reference must be replaced.
Single run (run):
<run.config>/*.control, bcs*.run, immutable YAML snapshots, plus optional whitelist.run / profile.run sidecars when enabled<run.config.history>/<revision>/ (new active config snapshots for continuation)<run.post_recipes>/<recipe-id>/{post.yml,post.run,state.json}<run.inputs>/{grid,initial_condition,inlet_profiles,restart}/ and <run.asset_lock><run.checkpoints>/, <run.analysis>/, and <run.visualization>/<run.runtime_logs>/ and <run.scheduler>/ (scripts, stream logs, and submission state)runs/<run_id>/manifest.jsonSweep (sweep):
studies/<study_id>/cases/<case_i>/...studies/<study_id>/scheduler/case_index.tsvstudies/<study_id>/scheduler/solver_array.sbatchstudies/<study_id>/scheduler/post_array.sbatchstudies/<study_id>/scheduler/solver_<array_jobid>_<taskid>.out/.err, post_<array_jobid>_<taskid>.out/.errstudies/<study_id>/scheduler/submission.jsonstudies/<study_id>/output/analysis/metrics_table.csvstudies/<study_id>/output/analysis/plots/*.png (if plotting enabled and matplotlib available)studies/<study_id>/study_manifest.jsonstorage is a top-level command registered from picurv_cli/storage/, and is the one command family this page does not detail. Subcommands: setup, plan, protect, offload, restore, verify, list, show, status.
Full semantics, retention model, and rclone configuration are documented in Storage Management Guide.