10def _add_run_parser(subparsers):
11 """!
12 @brief Attach `run` parser with staged execution and dry-run support.
13 @param[in] subparsers Argument passed to `_add_run_parser()`.
14 @return Value returned by `_add_run_parser()`.
15 """
16 p_run = subparsers.add_parser(
17 "run",
18 help="Execute a simulation workflow (solve and/or post-process).",
19 formatter_class=argparse.RawTextHelpFormatter,
20 description=(
21 "Execute solver and/or post-processing stages.\n\n"
22 "Notes:\n"
23 " - --num-procs applies to solver stage launches.\n"
24 " - Post-processing defaults to a single MPI rank/task.\n"
25 " - With --solve, --continue resumes the existing run directory in-place.\n"
26 " - With --post-process, --continue resumes the same recipe from the first unfinished step\n"
27 " and caps the launch to the highest fully available contiguous source frontier.\n\n"
28 "Diagnostics:\n"
29 " - PETSc and runtime memory diagnostics live under monitor.yml -> diagnostics.\n"
30 " - Use --dry-run to inspect resolved PETSc flags and expected log destinations.\n\n"
31 "Examples:\n"
32 " picurv run --solve -n 8 --case case.yml --solver solver.yml --monitor monitor.yml\n"
33 " picurv run --solve --restart-from runs/old_run --case case.yml --solver solver.yml --monitor monitor.yml\n"
34 " picurv run --solve --continue --run-dir runs/my_run --case case.yml --solver solver.yml --monitor monitor.yml\n"
35 " picurv run --post-process --run-dir runs/my_run --post post.yml\n"
36 " picurv run --post-process --continue --run-dir runs/my_run --post post.yml\n"
37 " picurv run --solve --case case.yml --solver solver.yml --monitor monitor.yml --dry-run"
38 ),
39 epilog="Next: run `picurv validate ...` first for config-only checks.",
40 )
41 run_group = p_run.add_argument_group("stages")
42 run_group.add_argument("--solve", action="store_true", help="Execute the solver stage (creates a new run directory).")
43 run_group.add_argument("--post-process", action="store_true", help="Execute the post-processing stage on a run directory.")
44
45 solver_group = p_run.add_argument_group("solver inputs (required for --solve)")
46 solver_group.add_argument("--case", help="Path to the case definition file (e.g., case.yml).")
47 solver_group.add_argument("--solver", help="Path to the solver settings profile (e.g., solver.yml).")
48 solver_group.add_argument("--monitor", help="Path to the monitoring, diagnostics, and I/O profile (e.g., monitor.yml).")
49 solver_group.add_argument(
50 "--restart-from",
51 help="Path to an existing run directory to restart from.\n"
52 "Creates a new run directory and copies/references checkpoint data from the source.",
53 )
54 run_group.add_argument(
55 "--continue",
56 action="store_true",
57 dest="continue_run",
58 help="Resume an existing run directory in-place. Requires --run-dir.\n"
59 "With --solve, appends to existing solver output/logs.\n"
60 "With --post-process, resumes the same recipe from the first unfinished step\n"
61 "and skips already-complete work inside the current live source frontier.",
62 )
63
64 post_group = p_run.add_argument_group("post-processor inputs (required for --post-process)")
65 post_group.add_argument("--run-dir", help="Path to an existing run directory.\n(Used with --post-process or --continue).")
66 post_group.add_argument("--post", help="Path to the post-processing recipe file (e.g., post.yml).")
67
68 p_run.add_argument(
69 "-n",
70 "--num-procs",
71 type=int,
72 default=1,
73 help="Number of MPI processes for the solver stage. Post-processing defaults to 1 rank.",
74 )
75 p_run.add_argument("--cluster", help="Path to cluster.yml for Slurm execution mode.")
76 p_run.add_argument("--scheduler", help="Explicit scheduler selector (currently 'slurm').")
77 p_run.add_argument("--no-submit", action="store_true", help="Stage run artifacts without starting local execution or Slurm submission.")
78 p_run.add_argument(
79 "--dry-run",
80 action="store_true",
81 help="Resolve and print planned commands/artifacts, including diagnostic flags and log paths, without writing files.",
82 )
83 p_run.add_argument(
84 "--format",
85 dest="output_format",
86 choices=["text", "json"],
87 default="text",
88 help="Output format for --dry-run (default: text).",
89 )
90 return p_run
91
92