engine: Super Resolution models from a one-frame weight dump
The dumps are one harness frame per preset (11/13/12) with D4R_CUDA_REPLAY_DUMP_DIR set. The K/M/L models built from them are byte-identical to k-def/m-def/l-def.
This commit is contained in:
1 parent
5f520a186d
commit
11a3511120
3 files changed
+36
-2
No files matched your search
@@ -83,6 +83,26 @@ It fails for missing/wrong-sized results, nonfinite values, or PSNR below its th
|
|||||||
`test_k.py --chain` remains available for isolated-layer diagnosis; it now selects the first launch consistently and
|
`test_k.py --chain` remains available for isolated-layer diagnosis; it now selects the first launch consistently and
|
||||||
fails on dispatch errors rather than continuing with a broken chain.
|
fails on dispatch errors rather than continuing with a broken chain.
|
||||||
|
|
||||||
|
## Models on the user's machine (install.sh)
|
||||||
|
|
||||||
|
A release's `install.sh` builds every model the shim loads, from the user's own DLLs, with
|
||||||
|
`d4r/tools/build-engine-models.sh` (`packaging/build_engine_models.sh`; `scripts/stage_engine_kit.sh` puts it and
|
||||||
|
d4r's compilers, shaders, the D3D12 harness and glslang into the release):
|
||||||
|
|
||||||
|
- Ray Reconstruction needs no capture. `nvngx_dlssd.dll` 310.9.1 holds presets D and E (the kernels and weights of
|
||||||
|
310.7) and F. `engine/rr/build_native_model.sh --dll DLL D|E OUT` and `engine/compile_rr2.py --dll DLL OUT
|
||||||
|
--ptx-dir DIR` take the PTX from the DLL (`kernels/tools/extract_dlss_ptx.py`), the weights as before
|
||||||
|
(`dll_weights.py`, `rr2_pack.py`) and what the capture used to supply from the DLL too: the argument-block
|
||||||
|
constants (`engine/rr/rr_templates.py`, `rr2_templates.py`, which replays the routine that builds NGX's model
|
||||||
|
description), encoder 0's second table of preset F and its arena regions. Built this way, D, E and F are
|
||||||
|
byte-identical to the capture-built models (every file, and `d4r-rr`'s outputs on the reference inputs).
|
||||||
|
- Super Resolution weights are packed inside `nvngx_dlss.dll`; they are read where NGX unpacks them. The harness
|
||||||
|
renders one frame per preset (11, 13, 12) through the release's own d4r folder under GE-Proton with
|
||||||
|
`D4R_CUDA_REPLAY_DUMP_DIR` set; `extract_k.py`, `prepare_k.py --lut-only` and `compile_k.py` / `compile_m.py`
|
||||||
|
build K, M and L from that, and `--ldr` their LDR variants from the same frame (NGX's HDR and LDR stages read the
|
||||||
|
same weights). About a minute per preset, ~280 MB of dumps that are deleted afterwards. The results are identical
|
||||||
|
to the models built from full captures.
|
||||||
|
|
||||||
## Ordinary frames, without a capture
|
## Ordinary frames, without a capture
|
||||||
|
|
||||||
Create a JSON description with raw linear HDR color, inverse depth, and render-resolution motion vectors:
|
Create a JSON description with raw linear HDR color, inverse depth, and render-resolution motion vectors:
|
||||||
|
|||||||
+5
-1
@@ -50,7 +50,7 @@ def blob_of(directory, ptr_offset=0):
|
|||||||
def main():
|
def main():
|
||||||
ap = argparse.ArgumentParser(description=__doc__)
|
ap = argparse.ArgumentParser(description=__doc__)
|
||||||
ap.add_argument('capture'); ap.add_argument('output', type=Path); ap.add_argument('--frame', type=int, default=0)
|
ap.add_argument('capture'); ap.add_argument('output', type=Path); ap.add_argument('--frame', type=int, default=0)
|
||||||
ap.add_argument('--ldr', action='store_true', help="NGX's *_ldr_* stages, for games without the HDR flag (capture such a frame)")
|
ap.add_argument('--ldr', action='store_true', help="NGX's *_ldr_* stages, for games without the HDR flag (the weights may come from an HDR capture)")
|
||||||
ap.add_argument('--hip', type=Path, metavar='KERNEL_DIR', help='also package the network for the native HIP layers: the layer '
|
ap.add_argument('--hip', type=Path, metavar='KERNEL_DIR', help='also package the network for the native HIP layers: the layer '
|
||||||
'weights as NGX uploads them (hipnet.bin) and the rrlite_*_4x4.hsaco kernels of KERNEL_DIR (kernels/build.sh output)')
|
'weights as NGX uploads them (hipnet.bin) and the rrlite_*_4x4.hsaco kernels of KERNEL_DIR (kernels/build.sh output)')
|
||||||
a = ap.parse_args()
|
a = ap.parse_args()
|
||||||
@@ -60,6 +60,10 @@ def main():
|
|||||||
if len(d) <= a.frame: raise ValueError(f'no launch of {kernel} for frame {a.frame}')
|
if len(d) <= a.frame: raise ValueError(f'no launch of {kernel} for frame {a.frame}')
|
||||||
return d[a.frame]
|
return d[a.frame]
|
||||||
R = 'ldr' if a.ldr else 'hdr'
|
R = 'ldr' if a.ldr else 'hdr'
|
||||||
|
# NGX's HDR and LDR stages read the same weights and constants (RE Requiem's m / m-ldr and l / l-ldr packages,
|
||||||
|
# built from separate captures, are identical but for the shaders): an LDR model can come from an HDR capture
|
||||||
|
if a.ldr and not glob.glob(f'{a.capture}/replay/replay-*-rrlite_enc0_4x4_mvlo_ldr*'):
|
||||||
|
R = 'hdr'
|
||||||
preset_l = bool(glob.glob(f'{a.capture}/replay/replay-*-rrlite_enc0_4x4_mvlo_{R}'))
|
preset_l = bool(glob.glob(f'{a.capture}/replay/replay-*-rrlite_enc0_4x4_mvlo_{R}'))
|
||||||
if preset_l == bool(glob.glob(f'{a.capture}/replay/replay-*-rrlite_enc0_4x4_mvlo_{R}_folded')):
|
if preset_l == bool(glob.glob(f'{a.capture}/replay/replay-*-rrlite_enc0_4x4_mvlo_{R}_folded')):
|
||||||
raise ValueError(f'the capture must hold the input stage of exactly one of preset M or L ({R})')
|
raise ValueError(f'the capture must hold the input stage of exactly one of preset M or L ({R})')
|
||||||
|
|||||||
+11
-1
@@ -2,7 +2,9 @@
|
|||||||
"""Prepare a full-frame native K replay from a capture. Does not translate kernels.
|
"""Prepare a full-frame native K replay from a capture. Does not translate kernels.
|
||||||
|
|
||||||
prepare_k.py CAPTURE_DIR OUTPUT_DIR [--frames N] [--start FRAME]
|
prepare_k.py CAPTURE_DIR OUTPUT_DIR [--frames N] [--start FRAME]
|
||||||
The model's reconstruction tables can be packaged using OUTPUT_DIR/lut.bin.
|
prepare_k.py CAPTURE_DIR OUTPUT_DIR --lut-only
|
||||||
|
The model's reconstruction tables can be packaged using OUTPUT_DIR/lut.bin. --lut-only writes only that, from the
|
||||||
|
first output launch's replay (a capture without the launch dumps: install.sh's weight dump).
|
||||||
"""
|
"""
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
@@ -21,7 +23,15 @@ def main():
|
|||||||
parser.add_argument('output', type=Path)
|
parser.add_argument('output', type=Path)
|
||||||
parser.add_argument('--frames', type=int, default=0, help='0 = all captured frames')
|
parser.add_argument('--frames', type=int, default=0, help='0 = all captured frames')
|
||||||
parser.add_argument('--start', type=int, default=0)
|
parser.add_argument('--start', type=int, default=0)
|
||||||
|
parser.add_argument('--lut-only', action='store_true', help='write only lut.bin')
|
||||||
a = parser.parse_args()
|
a = parser.parse_args()
|
||||||
|
if a.lut_only:
|
||||||
|
outputs = launches(a.capture, OUTPUT)
|
||||||
|
if not outputs:
|
||||||
|
raise ValueError('capture holds no K output launch')
|
||||||
|
a.output.mkdir(parents=True, exist_ok=True)
|
||||||
|
(a.output / 'lut.bin').write_bytes(outputs[0].allocation(280, 16 * 32768))
|
||||||
|
return
|
||||||
inputs, outputs = launches(a.capture, INPUT), launches(a.capture, OUTPUT)
|
inputs, outputs = launches(a.capture, INPUT), launches(a.capture, OUTPUT)
|
||||||
if not inputs or not outputs or len(outputs) > len(inputs):
|
if not inputs or not outputs or len(outputs) > len(inputs):
|
||||||
raise ValueError('capture must contain complete K input/output frame pairs')
|
raise ValueError('capture must contain complete K input/output frame pairs')
|
||||||
|
|||||||
Reference in new issue
Block a user