Skip to content

Compression silently produces all-zero output on Blackwell (SM 12.0 / RTX 50-series): default NTC_CUDA_ARCHITECTURES has no SM 120 target #9

Description

@HiroGitea

Summary

On a GeForce RTX 5070 Ti (compute capability 12.0), ntc-cli compression looks like it succeeds but silently produces garbage: the output file is roughly 100x smaller than the requested bitrate, every training progress report shows PSNR: inf dB, and all decompressed textures come out pure black. The tool exits with code 0 and prints no warning.

The default architecture list in libraries/RTXNTC-Library/src/CMakeLists.txt:18 is "75-virtual;89-virtual;86;89", which has no SM 120 target. On Blackwell the CUDA module therefore fails to load — but nothing checks that failure, so compression runs to completion against device memory that was never written.

Adding 120 to the list fixes it completely.

Environment

RTXNTC 0ffc326 — current main, one doc-only commit past the v0.10.0-beta tag
LibNTC 0.10.0 HEAD-35ec039 — current main of RTXNTC-Library
GPU NVIDIA GeForce RTX 5070 Ti, compute capability 12.0
Driver 596.36
OS Windows 11 x64, build 26220
CUDA Toolkit 13.3 (the version the README lists as tested)
Host compiler MSVC from Visual Studio 2026 (v18)

A note on the host compiler: the README specifies VS 2022 and I used VS 2026. That is not the cause. The A/B test below changes only NTC_CUDA_ARCHITECTURES — compiler, CUDA toolkit, driver and source tree are identical across both builds, and the source tree is unmodified (the architecture list is overridden through a CMake cache variable, not an edit).

Steps to reproduce

Build with a plain cmake .., then run against the sample material shipped in the repo:

cd assets/materials/MetalPlates013
ntc-cli Manifest.json -c -b 5 -S 1000 -o test.ntc
mkdir decoded
ntc-cli test.ntc -D --saveImages=decoded -F png --bcFormat none

-S 1000 only shortens the repro; the default 100000-step run behaves the same.

Observed behavior

Using NVIDIA GeForce RTX 5070 Ti with CUDA API. Compute capability 12.0
Selected latent shape for 5.000 bpp: --gridSizeScale 4 --numFeatures 16
Training: 1000 steps, 0.1380 ms/step, intermediate PSNR: inf dB
Saved 'test.ntc'
File size: 27884 bytes, 0.05 bits per pixel.
  • 5 bpp requested, 0.05 bpp produced — 27,884 bytes instead of roughly 2.6 MB.
  • intermediate PSNR: inf dB on every progress report, for the entire run.
  • All six decompressed PNGs are exactly 692 bytes, and every pixel sampled is (0, 0, 0).
  • Exit code 0, no warning, no error.

The inf PSNR is what makes this easy to miss: the tool reports a perfect reconstruction while writing out an empty one.

Expected behavior

Either a valid compressed texture set, or a hard failure stating that no device code is available for this GPU.

Root cause

compute-sanitizer surfaces the module load failure that the library discards:

========= CUDA API Error: Error handling fatbinary, to get more information when using CUDA Driver APIs use the CU_JIT_ERROR_LOG_BUFFER and CU_JIT_ERROR_LOG_BUFFER_SIZE_BYTES parameters
=========     Saved host backtrace up to driver entry point at error
=========         Host Frame: cuLibraryLoadData [...] in nvcuda64.dll
=========         Host Frame:  [0x3549] in libntc.dll
...
========= CUDA API Error: No available relocatable PTX entries for GPU
=========         Host Frame: cuLibraryLoadData [...] in nvcuda64.dll
=========         Host Frame:  [0x3549] in libntc.dll
...
========= CUDA API Error: No device code available for GPU ISA 120
=========         Host Frame: cuLibraryLoadData [...] in nvcuda64.dll
=========         Host Frame:  [0x3549] in libntc.dll

The relevant line is libraries/RTXNTC-Library/src/CMakeLists.txt:18:

set(NTC_CUDA_ARCHITECTURES "75-virtual;89-virtual;86;89"
    CACHE STRING "List of CUDA device architectures to generate code for")

No SM 120 target means no SASS for Blackwell, and the two -virtual entries cannot cover the gap. The same file sets CUDA_SEPARABLE_COMPILATION ON / CUDA_RESOLVE_DEVICE_SYMBOLS ON, and the driver reports No available relocatable PTX entries for GPU: the relocatable PTX that separable compilation emits is not JIT-compiled by the driver, so 75-virtual / 89-virtual provide no fallback on an architecture that is not listed explicitly.

That leaves RTX 50-series GPUs unable to compress at all, which contradicts the README — it lists Turing as the minimum for NTC compression and "Ada (RTX 4000 series) and newer" as recommended.

Verification

Only NTC_CUDA_ARCHITECTURES differs between the two builds.

75-virtual;89-virtual;86;89 (default) 75-virtual;89-virtual;86;89;120
Final PSNR (100k steps) inf dB 40.14 dB
Output size (-b 5) 27,884 bytes (0.05 bpp) 2,642,972 bytes (5.04 bpp)
Decompressed textures all 692 bytes, pure black correct images

Reconfiguring with cmake -DNTC_CUDA_ARCHITECTURES="75-virtual;89-virtual;86;89;120" .. is a complete workaround.

Suggested fix

  1. Add the Blackwell targets to the default NTC_CUDA_ARCHITECTURES120 for the GeForce RTX 50-series, plus the datacenter Blackwell targets if those are meant to be supported.
  2. Separately from the architecture list: check the status returned when the CUDA module loads, and fail loudly on error. An unsupported GPU ISA currently produces a successful-looking run, an inf dB PSNR, and a silently corrupt .ntc file — considerably worse than an outright failure. A check around cuLibraryLoadData (or the corresponding runtime API call) would reduce this entire class of problem to a single clear diagnostic.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions