57def _add_run_parser(subparsers):
58 """!
59 @brief Attach `run` parser with staged execution and dry-run support.
60 @param[in] subparsers Argument passed to `_add_run_parser()`.
61 @return Value returned by `_add_run_parser()`.
62 """
63 p_run = subparsers.add_parser(
64 "run",
65 help="Execute a simulation workflow (solve and/or post-process).",
66 formatter_class=argparse.RawTextHelpFormatter,
67 description=(
68 "Execute solver and/or post-processing stages.\n\n"
69 "Notes:\n"
70 " - --num-procs applies to solver and post-processing stage launches.\n"
71 " - With --solve, --continue resumes the existing run directory in-place.\n"
72 " - --post-process processes only the steps whose output is missing or stale: no output,\n"
73 " a changed recipe, or a changed checkpoint. Steps without a committed checkpoint\n"
74 " wait for the solver. --recompute regenerates every step.\n\n"
75 "Diagnostics:\n"
76 " - PETSc and runtime memory diagnostics live under monitor.yml -> diagnostics.\n"
77 " - Use --dry-run to inspect resolved PETSc flags and expected log destinations.\n\n"
78 "Examples:\n"
79 " picurv run --solve -n 8 --case case.yml --solver solver.yml --monitor monitor.yml\n"
80 " picurv run --solve --restart-from runs/old_run --case case.yml --solver solver.yml --monitor monitor.yml\n"
81 " picurv run --solve --continue --run-dir runs/my_run --case case.yml --solver solver.yml --monitor monitor.yml\n"
82 " picurv run --post-process --run-dir runs/my_run --post post.yml\n"
83 " picurv run --post-process --recompute --run-dir runs/my_run --post post.yml\n"
84 " picurv run --solve --case case.yml --solver solver.yml --monitor monitor.yml --dry-run"
85 ),
86 epilog="Next: run `picurv validate ...` first for config-only checks.",
87 )
88 run_group = p_run.add_argument_group("stages")
89 run_group.add_argument("--solve", action="store_true", help="Execute the solver stage (creates a new run directory).")
90 run_group.add_argument("--post-process", action="store_true", help="Execute the post-processing stage on a run directory.")
91
92 solver_group = p_run.add_argument_group("solver inputs (required for --solve)")
93 solver_group.add_argument("--case", help="Path to the case definition file (e.g., case.yml).")
94 solver_group.add_argument("--solver", help="Path to the solver settings profile (e.g., solver.yml).")
95 solver_group.add_argument("--monitor", help="Path to the monitoring, diagnostics, and I/O profile (e.g., monitor.yml).")
96 solver_group.add_argument(
97 "--restart-from", "--from",
98 dest="restart_from",
99 help="Path to an existing run directory to restart from.\n"
100 "Use 'latest' to select the newest compatible local workspace run.",
101 )
102 solver_group.add_argument(
103 "--statistics-state",
104 choices=RESTART_STATISTICS_MODES,
105 default=None,
106 help="For a branched restart with field statistics enabled, this is required:\n"
107 "'reset' discards the parent's accumulated windows, 'carry' resumes compatible\n"
108 "saved window state. Ignored when field statistics are disabled.",
109 )
110 solver_group.add_argument(
111 "--require-precomputed",
112 action="store_true",
113 help="Refuse to build missing or stale deterministic assets while staging the run.",
114 )
115 solver_group.add_argument(
116 "--fetch-missing",
117 action="store_true",
118 help="Try the configured storage profile before rebuilding a missing workspace asset.",
119 )
120 run_group.add_argument(
121 "--continue",
122 action="store_true",
123 dest="continue_run",
124 help="Extend an existing run's solve in place. Requires --solve and --run-dir,\n"
125 "and start_step > 0; appends to existing solver output/logs.\n"
126 "Post-processing needs no flag: it always skips up-to-date steps.",
127 )
128
129 post_group = p_run.add_argument_group("post-processor inputs (required for --post-process)")
130 post_group.add_argument("--run-dir", help="Path to an existing run directory.\n(Used with --post-process or --solve --continue).")
131 post_group.add_argument("--post", help="Path to the post-processing recipe file (e.g., post.yml).")
132 post_group.add_argument(
133 "--only",
134 help="Comma-separated post stages to run: 'fields' (the field post-processor),\n"
135 "'spectra', and 'reducers' (the post.yml reducers tasks, on profiles the\n"
136 "field stage wrote). Defaults to every stage.\n"
137 "Use --only spectra to measure spectra without running the field stage.",
138 )
139 post_group.add_argument(
140 "--recompute",
141 action="store_true",
142 dest="recompute_post",
143 help="Regenerate every requested step that has a committed checkpoint, including\n"
144 "steps whose output is up to date (for example, after rebuilding the\n"
145 "postprocessor). Applies to every selected stage.",
146 )
147
148 p_run.add_argument(
149 "-n",
150 "--num-procs",
151 type=int,
152 default=None,
153 help="Number of MPI processes for solver and post-processing stages (default 1, or\n"
154 "the product of --ni --nj --nk). The decomposition is chosen from the grid and\n"
155 "its boundary conditions unless given.",
156 )
157 for axis in ("i", "j", "k"):
158 p_run.add_argument(
159 f"--n{axis}", type=int, default=None,
160 help=f"MPI ranks along the grid's {axis} axis. Give --ni, --nj and --nk together.",
161 )
162 p_run.add_argument("--cluster", help="Path to cluster.yml for Slurm execution mode.")
163 p_run.add_argument("--scheduler", help="Explicit scheduler selector (currently 'slurm').")
164 p_run.add_argument("--no-submit", action="store_true", help="Stage run artifacts without starting local execution or Slurm submission.")
165 _add_executable_pinning_arguments(p_run)
166 p_run.add_argument(
167 "--dry-run",
168 action="store_true",
169 help="Resolve and print planned commands/artifacts, including diagnostic flags and log paths, without writing files.",
170 )
171 p_run.add_argument(
172 "--format",
173 dest="output_format",
174 choices=
list(CLI_OUTPUT_FORMATS),
175 default="text",
176 help="Output format for --dry-run (default: text).",
177 )
178 return p_run
179
180
Head of a generic C-style linked list.