#!/usr/bin/env python3 """Extract the PTX modules embedded in NVIDIA's nvngx_dlss.dll. usage: extract_dlss_ptx.py NVNGX_DLSS_DLL OUT_DIR Writes OUT_DIR/dlss-NNNN-MM.ptx for PTX entry MM of the NNNN-th CUDA fatbin found in the DLL (in file order). The texture-kernel build (kernels/tex) edits some of these modules; the DLL is NVIDIA's and is never part of this repository, and neither are the extracted files. """ import os import struct import sys FATBIN_MAGIC = 0xBA55ED50 def lz4_block(src: bytes, size: int) -> bytes: dst = bytearray() i = 0 while i < len(src): token = src[i] i += 1 literals = token >> 4 if literals == 15: while True: b = src[i] i += 1 literals += b if b != 255: break dst += src[i:i + literals] i += literals if i >= len(src) or len(dst) >= size: break offset = src[i] | (src[i + 1] << 8) i += 2 match = token & 15 if match == 15: while True: b = src[i] i += 1 match += b if b != 255: break match += 4 for _ in range(match): dst.append(dst[-offset]) return bytes(dst[:size]) def fatbins(data: bytes): """Yields (offset, bytes) of every fatbin container (magic, version 1) in file order.""" magic = struct.pack('= 0: _, version, header_size, size = struct.unpack_from('= 64 else 0 payload = fatbin[offset + entry_header:offset + entry_header + entry_size] if kind == 1: # PTX yield lz4_block(payload, decompressed) if (flags & 0x2000 and decompressed) else payload offset += entry_header + entry_size def main(argv): if len(argv) != 3: sys.exit(__doc__) data = open(argv[1], 'rb').read() os.makedirs(argv[2], exist_ok=True) total = 0 for index, (_, fatbin) in enumerate(fatbins(data)): for entry, ptx in enumerate(ptx_entries(fatbin)): ptx = ptx.rstrip(b'\0') with open(os.path.join(argv[2], f'dlss-{index:04d}-{entry:02d}.ptx'), 'wb') as out: out.write(ptx) total += 1 print(f'{total} PTX modules written to {argv[2]}') if __name__ == '__main__': main(sys.argv)