|
| 1 | +--- |
| 2 | +name: generate-scripts |
| 3 | +description: Generate libEnsemble calling scripts based on user requirements |
| 4 | +--- |
| 5 | + |
| 6 | +You are generating libEnsemble scripts. libEnsemble coordinates parallel simulations |
| 7 | +with generator-directed optimization or sampling. You will produce a calling script |
| 8 | +and, when an external application is involved, a sim function file. |
| 9 | + |
| 10 | +libEnsemble repository: https://github.com/Libensemble/libensemble |
| 11 | +If not running inside the libEnsemble repo, find examples and source code there. |
| 12 | + |
| 13 | +## Workflow |
| 14 | + |
| 15 | +1. If converting an existing Xopt or Optimas workflow to libEnsemble, use the |
| 16 | + existing generator and VOCS settings exactly as-is — even if it is a sampling |
| 17 | + or exploration generator. Do not switch to a classic generator unless the user |
| 18 | + specifically asks. |
| 19 | + Otherwise, if there is not a clear generator to use, read `references/generators.md` |
| 20 | + to determine which generator and |
| 21 | + style to use. If a specific generator is identified (e.g., APOSMM), read its |
| 22 | + dedicated guide (e.g., `references/aposmm.md`). |
| 23 | + |
| 24 | +2. Find a relevant example in `libensemble/tests/regression_tests/` and read it as a |
| 25 | + reference. Some examples: |
| 26 | + - Xopt Bayesian optimization (VOCS): `test_xopt_EI_initial_sample.py` — best Xopt |
| 27 | + example as it demonstrates the initial sampling approach Xopt generators need |
| 28 | + - Optimas Ax optimization (VOCS): `test_optimas_ax_sf.py` |
| 29 | + - APOSMM with NLopt (classic): `test_persistent_aposmm_nlopt.py` |
| 30 | + - Random uniform sampling (classic): `test_1d_sampling.py` |
| 31 | + Use glob and grep to find others matching the generator or pattern needed. |
| 32 | + The regression tests have clear descriptions in the docstring. |
| 33 | + |
| 34 | +3. Write the calling script adapting the example to the user's requirements. |
| 35 | + Do not copy test boilerplate from examples |
| 36 | + (e.g., "Execute via one of the following commands..." headers). Set nworkers |
| 37 | + directly in the script (in LibeSpecs) — do not use parse_args or command-line |
| 38 | + arguments unless the user asks for that. If parse_args is not used and no |
| 39 | + options are taken, then do not ever suggest running with "-n/nworkers" or comms. |
| 40 | + Those optins are used only with parse_args (used in tests). |
| 41 | + |
| 42 | +4. If the user has an external application (executable), also write a sim function file |
| 43 | + that uses the executor to run it. |
| 44 | + |
| 45 | +5. If the user provides an input file, check whether it has Jinja2 template markers |
| 46 | + (`{{ varname }}`). If not, create a templated copy: replace parameter values with |
| 47 | + `{{ name }}` markers matching `input_names` in sim_specs (case-sensitive). The sim |
| 48 | + function uses `jinja2.Template` to render the file before each simulation. Never |
| 49 | + modify the user's original file. |
| 50 | + |
| 51 | +6. Verify the scripts: |
| 52 | + - Bounds and dimension match the user's request |
| 53 | + - Executable path is correct |
| 54 | + - For VOCS: variable names are consistent between VOCS definition and sim function |
| 55 | + - For APOSMM: gen_specs outputs include all required fields |
| 56 | + - Input file template markers match input_names (case-sensitive) |
| 57 | + - The app_name in submit() matches register_app() |
| 58 | + |
| 59 | +7. Present a concise summary highlighting: generator choice, bounds, parameters, |
| 60 | + sim_max, and objective field. Do NOT suggest `mpirun` or other MPI |
| 61 | + runner (srun, mpiexec, etc.) to launch libEnsemble unless the user explicitly |
| 62 | + asks for MPI-based comms. |
| 63 | + |
| 64 | +8. Ask the user if they want to run the scripts. |
| 65 | + |
| 66 | +9. If running: execute with `python script.py`. Do not use `mpirun` or other MPI |
| 67 | + runner (srun, mpiexec, etc.) to launch libEnsemble unless the user explicitly |
| 68 | + asks for MPI-based comms for distributing workers. This is unrelated to |
| 69 | + MPIExecutor, which workers use to launch simulation applications across nodes |
| 70 | + — libEnsemble manages node allocation. |
| 71 | + If scripts fail, retry if you can see a fix, otherwise stop. After a successful |
| 72 | + run, read `references/results_metadata.md` and |
| 73 | + `references/finding_objectives.md` to interpret the output. |
| 74 | + |
| 75 | +## Generator style |
| 76 | + |
| 77 | +VOCS (gest-api) is the default style. It uses a VOCS object to define variables and |
| 78 | +objectives, and a generator object from Xopt or Optimas. Use VOCS unless the user |
| 79 | +explicitly asks for the classic style or the generator only exists in classic form |
| 80 | +(e.g., APOSMM, persistent_sampling). |
| 81 | + |
| 82 | +## Defaults |
| 83 | + |
| 84 | +- nworkers defaults to 4 unless the user specifies otherwise (or 1 for sequential |
| 85 | + generators like Nelder-Mead) |
| 86 | +- All nworkers are available for simulations |
| 87 | +- No alloc_specs needed — all allocator options are available as GenSpecs parameters |
| 88 | +- Use `async_return=True` in GenSpecs unless there is a reason to use batch returns |
| 89 | + |
| 90 | +## VOCS generators (Xopt / Optimas) |
| 91 | + |
| 92 | +Key patterns: |
| 93 | +- Variables named individually in VOCS: `{"x0": [lb, ub], "x1": [lb, ub]}` |
| 94 | +- Objectives named in VOCS: `{"f": "MINIMIZE"}` |
| 95 | +- GenSpecs uses `generator=`, `vocs=`, `batch_size=` |
| 96 | +- SimSpecs uses `vocs=` or `simulator=` for gest-api style sim functions |
| 97 | +- No `add_random_streams()` needed |
| 98 | +- Xopt generators need `initial_sample_method="uniform"` and `initial_batch_size=` |
| 99 | + for initial evaluated data. Optimas handles its own sampling. |
| 100 | + |
| 101 | +See `references/generators.md` for the full generator selection guide. |
| 102 | + |
| 103 | +## Classic generators |
| 104 | + |
| 105 | +Used only when the generator has no VOCS version or the user explicitly requests it. |
| 106 | +- One worker is consumed by the persistent generator |
| 107 | +- Requires `add_random_streams()` |
| 108 | +- APOSMM: see `references/aposmm.md` for full configuration details |
| 109 | + |
| 110 | +## Sim function patterns |
| 111 | + |
| 112 | +**Inline sim function** (no external app): Takes `(H, persis_info, sim_specs, libE_info)` |
| 113 | +and returns `(H_o, persis_info)`. Or for VOCS gest-api style, takes `input_dict: dict` |
| 114 | +and returns a dict. See `libensemble/sim_funcs/` for built-in examples. |
| 115 | + |
| 116 | +**Executor-based sim function** (external app): Uses MPIExecutor to run an application. |
| 117 | +Pattern: |
| 118 | +1. Register app in calling script: `exctr.register_app(full_path=..., app_name=...)` |
| 119 | +2. In sim function: get executor from `libE_info["executor"]`, submit with |
| 120 | + `exctr.submit(app_name=...)`, wait with `task.wait()` |
| 121 | +3. Read output file to get objective value |
| 122 | +4. Set `sim_dirs_make=True` in LibeSpecs |
| 123 | +5. If using input file templating, set `sim_dir_copy_files=[input_file]` |
| 124 | + |
| 125 | +## Results interpretation |
| 126 | + |
| 127 | +After a successful run: |
| 128 | +- Load the .npy output file with `np.load()` |
| 129 | +- Always filter by `sim_ended == True` before analyzing — rows where sim_ended is False |
| 130 | + contain uninitialized values (often zeros) that are NOT real results |
| 131 | +- For APOSMM: check rows where `local_min == True` to find identified minima |
| 132 | +- Report the count, location, and objective value of minima or best points found |
| 133 | +- If the best objective value is exactly 0.0, verify those rows have sim_ended == True |
| 134 | +- See `references/results_metadata.md` for full details |
| 135 | + |
| 136 | +## Reference docs (read as needed) |
| 137 | + |
| 138 | +All paths relative to this skill's directory: |
| 139 | + |
| 140 | +- `references/generators.md` — Generator selection guide, VOCS vs classic |
| 141 | +- `references/aposmm.md` — APOSMM configuration, optimizer options, tuning |
| 142 | +- `references/finding_objectives.md` — Identifying objective fields in results |
| 143 | +- `references/results_metadata.md` — Interpreting history array, filtering results |
| 144 | + |
| 145 | +## User request |
| 146 | + |
| 147 | +$ARGUMENTS |
0 commit comments