File size: 4,363 Bytes
51defdc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#!/usr/bin/env python3
# SPDX-License-Identifier: Apache-2.0
"""Run the served model (``METEOR.from_pretrained``: the ``frame`` trace, ETH 12x10) on the public-dataset frames of
``research/meteor/public_data`` and write the TT outputs in the layout of the CPU goldens (``fNNNN.npz`` compact +
``fNNNN.json`` decoded, ``run_public_reference.save_frame``), so ``compare_tt.py`` scores them against the CPU
goldens and ``make_demo.py`` renders them. Development tool of the workspace (needs the research scripts and the
converted public inputs, which never ship; nuScenes is CC BY-NC-SA: local validation only).

    bin/devrun -t 1800 -- python -u code/scripts/run_public_frames.py --out logs/public_tt [--ids ps019,ps090,ns0103]

Every frame's graph feed is checked against the golden's ``input_sha256`` first (the same pixels, K, T and v0 as the
CPU reference). Frames are processed per sequence (one rig each: the lift tables are written once per sequence).
Also writes ``<out>/run.json`` (versions, device, per-frame seconds) and, with ``--full`` frames, the 19 outputs.
"""
from __future__ import annotations

import argparse
import glob
import json
import os
import sys
import time
from pathlib import Path

import numpy as np

ROOT = Path(os.environ.get("TT_MODELS_ROOT", "/home/ubuntu/experiments/tt-models"))
PUBLIC = ROOT / "research" / "meteor" / "public_data"
sys.path.insert(0, str(PUBLIC / "scripts"))
sys.path.insert(0, str(ROOT / "research" / "meteor" / "scripts"))


def main() -> None:
    ap = argparse.ArgumentParser()
    ap.add_argument("--out", required=True, type=Path)
    ap.add_argument("--ids", default="ps019,ps090,ns0103")
    ap.add_argument("--full", default="ps019:20,ps090:20,ns0103:9", help="id:frame pairs that also get full_fNNNN.npz")
    a = ap.parse_args()
    import me_public_common as C  # noqa: F401  (research decode, metrics)
    import meteor_io
    from run_public_reference import save_frame

    from tt_meteor import METEOR, __version__
    from tt_meteor.host.preprocess import MeteorFrame

    full = {tuple(p.split(":")) for p in a.full.split(",") if p}
    jobs = []
    for gid in a.ids.split(","):
        gdir = PUBLIC / "golden" / gid
        frames = sorted(int(Path(f).stem[1:]) for f in glob.glob(str(gdir / "f[0-9][0-9][0-9][0-9].json")))
        jobs.append((gid, frames))
    run = {"bundle_version": __version__, "frames": {}, "started": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())}
    t_load = time.time()
    with METEOR.from_pretrained() as model:
        run["load_s"] = round(time.time() - t_load, 1)
        run["device"] = {k: model.device_info.get(k) for k in ("dispatch", "grid", "num_command_queues", "cores")}
        print("device", run["device"], "load", run["load_s"], "s", flush=True)
        for gid, frames in jobs:
            root = PUBLIC / "inputs" / gid
            sd = meteor_io.scene_dir_of(str(root)) if hasattr(meteor_io, "scene_dir_of") else \
                str(root / (root / "scenes.txt").read_text().split()[0])
            man = meteor_io.load_manifest(sd)
            ego_gt = dict(np.load(os.path.join(sd, "ego_motion.npz")))
            present = np.asarray(man.get("present_mask", [1] * 8), bool)
            out_dir = a.out / gid
            out_dir.mkdir(parents=True, exist_ok=True)
            for i in frames:
                feed = meteor_io.load_frame(sd, i, man)
                gold = json.loads((PUBLIC / "golden" / gid / f"f{i:04d}.json").read_text())
                sha = {k: C.sha256_array(v) for k, v in feed.items()}
                if sha != gold["input_sha256"]:
                    raise SystemExit(f"{gid} f{i}: the feed differs from the golden's input_sha256")
                fr = MeteorFrame(feed["imgs"], feed["K"], feed["T_cam_ego"], feed["v0"], present)
                t0 = time.time()
                o = {k: np.asarray(v) for k, v in model._forward({"frame": fr}).items()}
                dt = time.time() - t0
                save_frame(str(out_dir), i, o, feed, man, ego_gt, full=(gid, str(i)) in full)
                run["frames"][f"{gid}/f{i:04d}"] = round(dt, 3)
                print(f"{gid} f{i:04d}: {dt * 1e3:.0f} ms", flush=True)
    run["finished"] = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
    (a.out / "run.json").write_text(json.dumps(run, indent=1) + "\n")


if __name__ == "__main__":
    main()