Spaces:
Sleeping
Sleeping
Download scripts/run_experiments.py from REBELLION2002/traffix-live: direct link, hf CLI and curl.
- Browser
- Download file 4.66 kB
-
https://huggingface.co/spaces/REBELLION2002/traffix-live/resolve/main/scripts/run_experiments.py
- Command line
-
hf download hf://spaces/REBELLION2002/traffix-live/scripts/run_experiments.py
-
curl -L -o run_experiments.py https://huggingface.co/spaces/REBELLION2002/traffix-live/resolve/main/scripts/run_experiments.py
4.66 kB
| """ | |
| Runs controllers x scenarios x seeds and saves results/results.csv. | |
| python scripts/run_experiments.py | |
| python scripts/run_experiments.py --scenario emergency --controller traffix --seeds 1 | |
| python scripts/run_experiments.py --gui --scenario rain --controller traffix --seeds 1 | |
| Results are saved after every run. If it stops (crash, Ctrl+C, laptop off), run the same | |
| command again: finished runs are skipped. Use --fresh to start over. | |
| """ | |
| import argparse | |
| import csv | |
| import os | |
| from multiprocessing import Pool | |
| import _path # noqa: F401 | |
| from traffix.core import config | |
| def job(args): | |
| """Runs one simulation. A failure is returned as a row (never raised), so one bad run | |
| can't stop the batch, and the error message survives the trip back from the worker.""" | |
| import traceback | |
| from traffix.evaluation.runner import run_one | |
| try: | |
| return run_one(*args) | |
| except Exception as e: | |
| c, s, seed, _ = args | |
| return {"controller": c, "scenario": s, "seed": seed, | |
| "error": f"{e.__class__.__name__}: {e}", "traceback": traceback.format_exc()[-1500:]} | |
| def done_keys(path): | |
| """Runs already saved in the results file (for resuming).""" | |
| if not os.path.exists(path): | |
| return set(), [] | |
| with open(path, newline="") as f: | |
| rows = [r for r in csv.DictReader(f) if not r.get("error")] | |
| return {(r["controller"], r["scenario"], int(r["seed"])) for r in rows}, rows | |
| def save(rows, path): | |
| keys = list(dict.fromkeys(k for r in rows for k in r)) | |
| tmp = path + ".tmp" | |
| with open(tmp, "w", newline="") as f: | |
| w = csv.DictWriter(f, fieldnames=keys) | |
| w.writeheader() | |
| w.writerows(rows) | |
| os.replace(tmp, path) | |
| if __name__ == "__main__": | |
| sim, sc = config.simulation(), config.scenarios() | |
| p = argparse.ArgumentParser() | |
| p.add_argument("--controller", nargs="+", default=sim["controllers"], choices=sim["controllers"]) | |
| p.add_argument("--scenario", nargs="+", default=list(sc), choices=list(sc)) | |
| p.add_argument("--seeds", nargs="+", type=int, default=sim["seeds"]) | |
| p.add_argument("--workers", type=int, default=sim["workers"]) | |
| p.add_argument("--gui", action="store_true") | |
| p.add_argument("--out", default=config.path("results", "results.csv")) | |
| p.add_argument("--fresh", action="store_true", help="ignore existing results and start over") | |
| a = p.parse_args() | |
| os.makedirs(os.path.dirname(a.out), exist_ok=True) | |
| if a.fresh and os.path.exists(a.out): | |
| os.remove(a.out) | |
| done, rows = done_keys(a.out) | |
| jobs = [(c, s, seed, a.gui) for s in a.scenario for c in a.controller for seed in a.seeds | |
| if (c, s, seed) not in done] | |
| from traffix.evaluation.runner import GEN, demand_is_current | |
| stale = sorted({(s, seed) for _, s, seed, _ in jobs | |
| if not demand_is_current(os.path.join(GEN, f"{s}_seed{seed}"))}) | |
| if stale: # traffic missing or built for another map | |
| from traffix.demand.generator import DemandGenerator | |
| print(f"Building traffic for the {config.network_name()} map ({len(stale)} scenario/seed pairs)") | |
| gen = DemandGenerator(config.network_files()[0]) | |
| for s, seed in stale: | |
| gen.build(s, sc[s], seed, GEN) | |
| print(f"Running {len(jobs)} simulations" + (f" ({len(done)} already saved in {a.out}, skipped)" if done else "")) | |
| failures = [] | |
| if a.gui or a.workers <= 1: | |
| results = map(job, jobs) | |
| else: | |
| results = Pool(a.workers).imap(job, jobs) | |
| for r in results: | |
| if r.get("error"): | |
| failures.append(r) | |
| print(f"{r['scenario']:18s} {r['controller']:14s} seed {r['seed']}: FAILED {r['error']}", flush=True) | |
| with open(os.path.join(os.path.dirname(a.out), "failed_runs.log"), "a") as f: | |
| f.write(f"{r['controller']} {r['scenario']} seed {r['seed']}\n{r['traceback']}\n\n") | |
| continue | |
| rows.append(r) | |
| save(rows, a.out) # saved after every run | |
| print(f"{r['scenario']:18s} {r['controller']:14s} seed {r['seed']}: car wait " | |
| f"{r['veh_mean_wait_s']:6.1f}s ped wait {r['ped_mean_wait_s']:6.1f}s " | |
| f"unfinished {r['veh_unfinished']:3d} truncations {r['clearance_truncations']:4d}", flush=True) | |
| print(f"Saved {len(rows)} runs to {a.out}") | |
| if failures: | |
| print(f"{len(failures)} run(s) failed; details in results/failed_runs.log. " | |
| f"Rerun the same command to retry only those.") | |