(config_path: Path, grid_config_path: Path, out_root: Path)
| 131 | |
| 132 | |
| 133 | def run_grid(config_path: Path, grid_config_path: Path, out_root: Path) -> Path: |
| 134 | base_cfg = _read_config(config_path) |
| 135 | grid_cfg = _read_config(grid_config_path) |
| 136 | runs = list(grid_cfg.get("runs", [])) |
| 137 | if not runs: |
| 138 | raise ValueError("grid config must define at least one [[runs]] entry") |
| 139 | |
| 140 | dataset, dataset_meta = _dataset_from_cfg(base_cfg) |
| 141 | base_run_cfg = _merged_run_cfg(base_cfg) |
| 142 | run_cfgs: list[dict] = [] |
| 143 | run_names: list[str] = [] |
| 144 | |
| 145 | for idx, run_item in enumerate(runs): |
| 146 | item = dict(run_item) |
| 147 | run_name = str(item.pop("name", f"run_{idx:02d}")) |
| 148 | cfg = dict(base_run_cfg) |
| 149 | cfg.update(item) |
| 150 | run_cfgs.append(cfg) |
| 151 | run_names.append(run_name) |
| 152 | |
| 153 | grid_out = openquant.research.run_flywheel_grid(dataset, run_cfgs, run_names=run_names) |
| 154 | digest = openquant.research.research_run_manifest( |
| 155 | {"base_config": base_cfg, "grid_config": grid_cfg} |
| 156 | )["config_digest"] |
| 157 | run_set_name = str(base_cfg.get("meta", {}).get("name", config_path.stem)) |
| 158 | run_dir = out_root / f"{run_set_name}-grid-{digest}" |
| 159 | run_dir.mkdir(parents=True, exist_ok=True) |
| 160 | |
| 161 | leaderboard: pl.DataFrame = grid_out["leaderboard"] |
| 162 | leaderboard.write_parquet(run_dir / "leaderboard.parquet") |
| 163 | |
| 164 | for run in grid_out["runs"]: |
| 165 | per_run_name = str(run["run_name"]) |
| 166 | per_run_cfg = dict(run["config"]) |
| 167 | per_run_out = run["output"] |
| 168 | per_digest = openquant.research.research_run_manifest(per_run_cfg)["config_digest"] |
| 169 | per_dir = run_dir / f"{per_run_name}-{per_digest}" |
| 170 | _write_run_artifacts( |
| 171 | per_dir, |
| 172 | run_name=per_run_name, |
| 173 | config_path=config_path, |
| 174 | manifest_cfg={"base_config_path": str(config_path), "grid_entry": per_run_cfg}, |
| 175 | dataset_meta=dataset_meta, |
| 176 | out=per_run_out, |
| 177 | ) |
| 178 | |
| 179 | run_manifest = { |
| 180 | "mode": "grid", |
| 181 | "config_path": str(config_path), |
| 182 | "grid_config_path": str(grid_config_path), |
| 183 | "config_digest": digest, |
| 184 | "git_sha": _git_sha(REPO_ROOT), |
| 185 | "python": sys.version.split()[0], |
| 186 | "run_count": len(run_cfgs), |
| 187 | "run_names": run_names, |
| 188 | } |
| 189 | (run_dir / "run_manifest.json").write_text(json.dumps(run_manifest, indent=2), encoding="utf-8") |
| 190 | print(run_dir) |
no test coverage detected