#!/usr/bin/env python3 """Generate an official PyTorch reference for the browser-controlled flow loop.""" from __future__ import annotations import argparse import json import os import time from pathlib import Path from dit_common import ( CAMERA_SHAPE, FEATURE1_SHAPE, FEATURE2_SHAPE, LATENT_SHAPE, choose_torch_device, load_official_flow_model, resolved_file, sha256_file, source_revision, synchronize_torch, ) def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--triposplat-repo", type=Path, required=True) parser.add_argument("--weights", type=Path, required=True) parser.add_argument("--input-fixture-dir", type=Path, required=True) parser.add_argument("--output-fixture-dir", type=Path, required=True) parser.add_argument("--device", choices=("cpu", "mps", "cuda", "auto"), default="cpu") parser.add_argument( "--internal-precision", choices=("fp16", "fp32"), default="fp16", help="Official flow-model precision used for the reference (default: %(default)s).", ) parser.add_argument("--steps", type=int, default=4) parser.add_argument("--guidance-scale", type=float, default=3.0) parser.add_argument("--shift", type=float, default=3.0) parser.add_argument( "--record-trajectory", action="store_true", help="Record official per-invocation sample, timestep, and raw predictions.", ) args = parser.parse_args() if args.steps <= 0: parser.error("--steps must be positive") if args.guidance_scale <= 1: parser.error("--guidance-scale must be greater than one to exercise CFG") if args.shift <= 0: parser.error("--shift must be positive") return args def hard_link(source: Path, destination: Path) -> None: destination.parent.mkdir(parents=True, exist_ok=True) if destination.exists(): if os.path.samefile(source, destination): return destination.unlink() os.link(source, destination) def main() -> None: try: import numpy as np import torch except ImportError as exc: raise SystemExit(f"PyTorch and NumPy are required: {exc}") from exc args = parse_args() repository = args.triposplat_repo.expanduser().resolve() weights = resolved_file(args.weights, "TripoSplat flow-model weights") input_dir = args.input_fixture_dir.expanduser().resolve() output_dir = args.output_fixture_dir.expanduser().resolve() shapes = { "latent": LATENT_SHAPE, "camera": CAMERA_SHAPE, "feature1": FEATURE1_SHAPE, "feature2": FEATURE2_SHAPE, } arrays = {} for name, shape in shapes.items(): path = resolved_file(input_dir / f"{name}.f32", f"fixture {name}") array = np.fromfile(path, dtype="