Download tests/test_engine_config.py from kimjunhan/vkgs-sim: direct link, hf CLI and curl.
- Browser
- Download file 6.32 kB
-
https://huggingface.co/kimjunhan/vkgs-sim/resolve/main/tests/test_engine_config.py
- Command line
-
hf download hf://kimjunhan/vkgs-sim/tests/test_engine_config.py
-
curl -L -o test_engine_config.py https://huggingface.co/kimjunhan/vkgs-sim/resolve/main/tests/test_engine_config.py
6.32 kB
| """μ€μ νμΌ β μμ§ μ½λ μΌκ΄μ± (GPU μμ΄). 2026-10-05 μ 체 μ¬κ²ν μμ λμ¨ 'μ‘°μ©ν 무μλλ μ€μ ' λ°©μ§. | |
| - configs/sim.json μ ν€λ₯Ό viewer.cpp load_sim_config κ° μ€μ λ‘ μ½λκ° | |
| - configs/render_graph.json μ μ°Έμ‘°(νμ΄νλΌμΈΒ·μ€ν기·그리기 νλͺ©Β·λ λ λμΒ·μ °μ΄λ λΉλ)κ° λ€ μλκ° | |
| - bindless μ¬λ‘― μμκ° μ °μ΄λμ C++ μμ κ°μκ° | |
| - λΉλ λͺ©λ‘μ μ °μ΄λκ° λͺ¨λ μ»΄νμΌλλκ° (glslc κ° μμΌλ©΄) | |
| """ | |
| import json | |
| import re | |
| import shutil | |
| import subprocess | |
| from pathlib import Path | |
| import pytest | |
| ROOT = Path(__file__).resolve().parents[1] | |
| VIEWER = (ROOT / "src/vkgs/src/viewer.cpp").read_text() | |
| CMAKE = (ROOT / "src/vkgs/CMakeLists.txt").read_text() | |
| SHADERS = ROOT / "src/vkgs/shaders" | |
| def _strip_doc(d): | |
| return {k: v for k, v in d.items() if not k.startswith("_")} | |
| def _load_sim_config_src() -> str: | |
| i = VIEWER.index("void load_sim_config(") | |
| return VIEWER[i: VIEWER.index("\n}\n", i)] | |
| PY_ONLY = {"drive.start_offset_m"} # νμ΄μ¬(nusim render map μΆλ° νλ μ)μ΄ μ½λ ν€ | |
| def test_sim_json_keys_are_read(): | |
| src = _load_sim_config_src() | |
| read = set(re.findall(r'"([a-z_0-9]+)"', src)) | |
| sim = json.loads((ROOT / "configs/sim.json").read_text()) | |
| missing = [] | |
| for sec, val in _strip_doc(sim).items(): | |
| if sec == "ego": # νμ΄μ¬(nusim render view)μ΄ μ½λλ€ | |
| continue | |
| if sec not in read: | |
| missing.append(sec) | |
| if isinstance(val, dict) and sec not in ("shader_graphs", "passes"): # μ΄ λμ μ΄λ¦μ΄ λ°μ΄ν° | |
| for k, v in _strip_doc(val).items(): | |
| if k == "presets": | |
| continue | |
| if k not in read and f"{sec}.{k}" not in PY_ONLY: | |
| missing.append(f"{sec}.{k}") | |
| if isinstance(v, dict) and k != "defaults": | |
| missing += [f"{sec}.{k}.{kk}" for kk in _strip_doc(v) if kk not in read] | |
| assert not missing, f"viewer.cpp load_sim_config κ° μ½μ§ μλ sim.json ν€: {missing}" | |
| def test_weather_preset_fields_and_aug_weather_names(): | |
| i = VIEWER.index("void set_weather_field(") | |
| fields = set(re.findall(r'k == "([a-z_]+)"', VIEWER[i: VIEWER.index("\n}\n", i)])) | |
| sim = json.loads((ROOT / "configs/sim.json").read_text()) | |
| names = set() | |
| for p in sim["weather"]["presets"]: | |
| names.add(p["name"]) | |
| bad = set(p["values"]) - fields | |
| assert not bad, f"ν리μ {p['name']} μ λͺ¨λ₯΄λ κ° {bad} (set_weather_field: {sorted(fields)})" | |
| assert set(sim["weather"]["defaults"]) <= fields | |
| assert sim["weather"].get("start", "clear") in names | |
| variants = json.loads((ROOT / "configs/aug/rig_variants.json").read_text())["variants"] | |
| for v in variants: | |
| if v.get("weather"): | |
| assert v["weather"] in names, f"rig λ³ν {v['name']} μ λ μ¨ {v['weather']} κ° sim.json ν리μ μ μμ" | |
| def _registered(kind: str) -> set: | |
| return set(re.findall(kind + r'\["([a-z_0-9]+)"\]\s*=', VIEWER)) | |
| def test_render_graph_references(): | |
| g = json.loads((ROOT / "configs/render_graph.json").read_text()) | |
| pipes = _strip_doc(g["pipelines"]) | |
| res = _strip_doc(g["resources"]) | |
| targets = _strip_doc(g.get("targets", {})) | |
| pass_kinds, draws = _registered("pass_exec_"), _registered("draw_exec_") | |
| built = set(re.findall(r"vkgs_add_shader\(shaders/([^)]+)\)", CMAKE)) | |
| graphs = {p.stem + ".comp" for p in (ROOT / "configs/shader_graphs").glob("*.json")} | |
| for name, p in pipes.items(): | |
| for stage in ("vertex", "fragment", "compute"): | |
| if stage in p: | |
| assert p[stage] in built | graphs, f"νμ΄νλΌμΈ {name}: {p[stage]} κ° CMake λΉλ λͺ©λ‘μ μμ" | |
| if p.get("target", "scene") != "scene": | |
| assert p["target"] in targets, f"νμ΄νλΌμΈ {name}: λͺ¨λ₯΄λ target {p['target']}" | |
| for t, d in targets.items(): | |
| for c in d["color"]: | |
| assert c in res and res[c].get("type") == "image" and "create" in res[c], f"target {t}: {c} λ create μ΄λ―Έμ§μ¬μΌ ν¨" | |
| names = [p["name"] for p in g["passes"]] | |
| assert len(names) == len(set(names)) | |
| for p in g["passes"]: | |
| assert p["kind"] in pass_kinds, f"ν¨μ€ {p['name']}: μ€νκΈ° '{p['kind']}' κ° λ±λ‘λΌ μμ§ μμ ({sorted(pass_kinds)})" | |
| for r, _ in p.get("uses", []): | |
| assert r in res, f"ν¨μ€ {p['name']}: λͺ¨λ₯΄λ 리μμ€ {r}" | |
| prm = p.get("params", {}) | |
| for key in ("pipeline", "hist", "scan", "scatter", "fallback_pipeline"): | |
| if key in prm: | |
| assert prm[key] in pipes, f"ν¨μ€ {p['name']}: {key}={prm[key]} νμ΄νλΌμΈ μμ" | |
| for d in prm.get("draws", []): | |
| assert d in draws, f"ν¨μ€ {p['name']}: 그리기 νλͺ© '{d}' μ€νκΈ° μμ" | |
| if prm.get("target", "scene") != "scene": | |
| assert prm["target"] in targets | |
| if p.get("follows"): | |
| assert p["follows"] in names | |
| if p["kind"] == "radix_sort": | |
| assert prm.get("key_bits", 32) == 32 | |
| hist = res[prm["histogram"]]["create"]["bytes"] | |
| assert hist >= prm.get("groups", 512) * 256 * 4, "sort_hist κ° groups Γ 256 Γ 4 λ³΄λ€ μμ" | |
| def test_bindless_slots_match(): | |
| glsl = (SHADERS / "bindless.glsl").read_text() | |
| consts = {k: int(v) for k, v in re.findall(r"(k(?:Ssbo|Ubo|Img)\w+) = (\d+)u", glsl)} | |
| cpp = {k: int(v) for k, v in re.findall(r"(k(?:Ssbo|Ubo|Img)\w+) = (\d+)", VIEWER)} | |
| assert consts, "bindless.glsl μμ μ¬λ‘― μμλ₯Ό λͺ» μ°Ύμ" | |
| for k, v in consts.items(): | |
| assert cpp.get(k) == v, f"{k}: bindless.glsl {v} vs viewer.cpp {cpp.get(k)}" | |
| def test_all_shaders_compile(tmp_path): | |
| bad = [] | |
| for name in sorted(set(re.findall(r"vkgs_add_shader\(shaders/([^)]+)\)", CMAKE))): | |
| r = subprocess.run(["glslc", "--target-env=vulkan1.2", "-O", "-I", str(SHADERS), str(SHADERS / name), | |
| "-o", str(tmp_path / (name + ".spv"))], capture_output=True, text=True) | |
| if r.returncode: | |
| bad.append(f"{name}: {r.stderr.strip()[:300]}") | |
| assert not bad, "\n".join(bad) | |