|
|
| _kill (popen) |
| |
|
| _handle_signal (signum, _frame) |
| |
|
| _mem_wrapper (model_id) |
| |
| | _memory_capped_available () |
| |
|
| already_done (model_id) |
| |
| | run_one (mesh_path) |
| |
| | _describe_exit (code, work) |
| |
|
| _prune (work) |
| |
|
| _read_status (d) |
| |
| | _parse_success (d) |
| |
| | _histogram (title, values, edges, fmt="{:g}") |
| |
|
| _esc (s) |
| |
|
| _fmt (v, nd=2) |
| |
|
| _bucket (values, edges) |
| |
|
| _bars (labels, counts, unit, alt=False) |
| |
|
| _html_hist (values, edges, unit) |
| |
|
| _stat (k, v, u="", cls="") |
| |
|
| _table (headers, rows, reason_col=None, empty="(none)") |
| |
| | generate_html_report (rows, stats, report_dir, out_dir, dataset_dir=None, mesh_extensions=()) |
| |
|
| generate_report () |
| |
|
| _reason_bucket (reason) |
| |
| | _order_models (meshes) |
| |
|
| run_sweep () |
| |
| | stop_sweep () |
| |
|
|
| SWEEP_ROOT = Path(os.environ.get("SIMWILD_ROOT", "/u/3/daniele/simwild-thingi10k-sweep")) |
| |
|
str | WMTK_APP = SWEEP_ROOT / "build/app/wmtk_app" |
| |
|
str | DATASET_DIR = SWEEP_ROOT / "data" |
| |
|
| OUT_DIR = Path(os.environ.get("SIMWILD_OUT", str(SWEEP_ROOT / "runs/full"))) |
| |
|
tuple | MESH_EXTENSIONS = ("*.stl", "*.obj", "*.ply", "*.off") |
| |
|
| PARALLEL = max(1, int(os.environ.get("SIMWILD_PARALLEL", "8"))) |
| |
|
| THREADS = max(1, int(os.environ.get("SIMWILD_THREADS", "8"))) |
| |
|
| JOB_TIMEOUT = int(os.environ.get("SIMWILD_JOB_TIMEOUT", "10800")) |
| |
|
| MEM_GB = int(os.environ.get("SIMWILD_MEM_GB", "128")) |
| |
|
| LIMIT = int(os.environ.get("SIMWILD_LIMIT", "0")) |
| |
|
| SAMPLE = os.environ.get("SIMWILD_SAMPLE", "smallest") |
| |
|
| SEED = int(os.environ.get("SIMWILD_SEED", "0")) |
| |
|
| REPORT_ONLY = bool(os.environ.get("SIMWILD_REPORT_ONLY")) |
| |
| dict | PARAMS |
| |
|
list | KEEP_GLOBS = ["*.log", "*.json", "status.txt"] |
| |
|
str | SUCCESS_DIR = OUT_DIR / "success" |
| |
|
str | FAILURE_DIR = OUT_DIR / "failure" |
| |
|
str | WORK_DIR = OUT_DIR / ".work" |
| |
|
str | REPORT_DIR = OUT_DIR / "report" |
| |
|
str | PIDFILE = OUT_DIR / "sweep.pid" |
| |
|
| _STOP = threading.Event() |
| |
|
dict | _children = {} |
| |
|
| _children_lock = threading.Lock() |
| |
|
| IT_RE = re.compile(r"========it (\d+)========") |
| |
|
str | _CSS |
| |
| str | _JS |
| |
Batch-run simwild over the Thingi10K dataset -- kirby.cs.nyu.edu edition.
Adapted from tetwild's run_tetwild_sweep.py: same contract, environment layout and
output shape (only the TETWILD_* variables become SIMWILD_*), so a simwild sweep and
a tetwild sweep can run side by side on the same machine without either one's settings
leaking into the other. Run it with no arguments to start (or resume) the sweep; it
skips every model already in success/ or failure/. Stop it cleanly with:
run_simwild_sweep.py stop
which signals the running sweep to abandon whatever is in flight (those models are
left unpublished, so a later resume reprocesses them -- no spurious failures), drain,
write the report, and exit.
Each model is a single closed surface mesh, fed through simwild with
tag_from_winding_number left at its default (true): the arrangement's one cell is
tagged inside/outside by winding number, so no curve network or pre-tagged .msh is
needed -- the same single-input shape tetwild's Thingi10K sweep uses.
What changed from tetwild's version:
* application is "simwild", not "tetwild";
* simwild has no `filter` knob (that is tetwild's post-insertion outside-removal
pass; simwild's single-input case is tagged by winding number instead), so it is
dropped from PARAMS rather than pinned;
* `eps_rel` is pinned at simwild's own spec default (2e-3), not tetwild's (1e-3) --
the two applications do not share a default;
* paths point at /u/3/daniele/simwild-thingi10k-sweep, a separate root from
tetwild's sweep so the two never share a success/failure namespace;
* SIMWILD_SAMPLE picks *which* models a truncated run gets -- 'smallest' is the
original behaviour, 'spread' covers the whole size range, which is what you want
from a 100-model trial;
* the report tells OOM kills apart from other signals.
Per model:
* write a simwild JSON (eps_rel 2e-3, single-input winding-number tagging);
* run wmtk_app in a scratch dir under the output volume, capped in time and memory;
* exit 0 -> move the run into <OUT>/success/<id>/
nonzero / timeout / OOM -> move the run into <OUT>/failure/<id>/ (with a reason)
Configuration -- environment variables:
SIMWILD_ROOT sweep root: build/ data/ runs/ live here
SIMWILD_OUT output directory (default runs/full)
SIMWILD_PARALLEL models to run concurrently (default 8)
SIMWILD_THREADS threads per model (default 8)
SIMWILD_JOB_TIMEOUT per-model seconds (default 10800 = 3h)
SIMWILD_MEM_GB per-model memory cap, GB (default 128, 0 disables)
SIMWILD_LIMIT process at most N new models (default 0 = all)
SIMWILD_SAMPLE name | smallest | spread | random (default smallest)
SIMWILD_SEED seed for SIMWILD_SAMPLE=random (default 0)
SIMWILD_REPORT_ONLY if set, only regenerate the report and exit
Memory note: the cap is PER MODEL, not a budget for the sweep. 8 x 128G is more than
kirby has, so the cap is a runaway-killer, not an admission control -- it stops one
pathological mesh from swapping the box, and does nothing in the normal case. Lower
SIMWILD_MEM_GB if the sweep has to coexist with someone else's job.