Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,72 @@ set(CMAKE_CXX_STANDARD_REQUIRED true)

if(SD_CUDA)
message("-- Use CUDA as backend stable-diffusion")

# Keep NVCC's host ABI aligned with the selected C++ compiler. This is
# essential for libc++ consumers (such as QVAC's Linux triplet), where
# letting NVCC fall back to g++ makes CMake's CUDA probes use incompatible
# standard-library flags. An explicit CMAKE_CUDA_HOST_COMPILER always wins.
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND
(NOT DEFINED CMAKE_CUDA_HOST_COMPILER OR CMAKE_CUDA_HOST_COMPILER STREQUAL ""))
set(CMAKE_CUDA_HOST_COMPILER "${CMAKE_CXX_COMPILER}" CACHE FILEPATH
"Host compiler used by NVCC" FORCE)
message(STATUS "CUDA host compiler defaulted to ${CMAKE_CUDA_HOST_COMPILER}")
endif()

# CUDA 13 packages headers below targets/<platform>/include. Prefer an
# explicitly configured compiler; otherwise prefer well-known CUDA roots
# before PATH. This prevents an older distro nvcc (for example CUDA 12 in
# /usr/bin) from winning over CUDA 13 installed at /usr/local/cuda.
if(DEFINED CMAKE_CUDA_COMPILER AND NOT CMAKE_CUDA_COMPILER STREQUAL "")
set(SD_NVCC_EXECUTABLE "${CMAKE_CUDA_COMPILER}")
else()
find_program(SD_NVCC_EXECUTABLE NAMES nvcc

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Honor CUDAToolkit_ROOT when selecting NVCC. When CMAKE_CUDA_COMPILER is unset, this search ignores an explicit toolkit root and can force nvcc from /usr/local/cuda or PATH. GGML then runs FindCUDAToolkit, which prioritizes CMAKE_CUDA_COMPILER over CUDAToolkit_ROOT; for example, -DCUDAToolkit_ROOT=/opt/cuda-13 with CUDA 12 on PATH resolves the compiler/toolkit search to CUDA 12 and can fail or mix installations. I reproduced this with separate explicit-root and PATH toolkit locations. Please search ${CUDAToolkit_ROOT}/bin first (including the environment form), or leave CMAKE_CUDA_COMPILER unset so FindCUDAToolkit can honor the explicit root.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right: an explicit CUDAToolkit_ROOT must take precedence over the convenience probe. I will change the order to honor an explicit CMAKE_CUDA_COMPILER, then CUDAToolkit_ROOT/bin (including its environment form), before /usr/local/cuda, CUDA_PATH/CUDA_HOME, and PATH; I will validate it with an explicit-root/PATH-version mismatch.

The need for this PR is independently reproducible on the NV5090 host. The unmodified 2026-08-11 branch, configured with Clang 20 and CUDA 13.3 installed, found CUDA 13.3 headers but selected /usr/bin/nvcc from CUDA 12.4 with GNU 13.4 as NVCC's host compiler. It then failed while building GGML CUDA with nvcc fatal: Unsupported gpu architecture 'compute_120a'. #39 makes the intended CUDA 13.3 compiler and Clang host compiler selection deterministic; after that selection, the engine builds and the CUDA smoke runs complete.

PATHS /usr/local/cuda/bin
NO_DEFAULT_PATH)
if(NOT SD_NVCC_EXECUTABLE)
find_program(SD_NVCC_EXECUTABLE NAMES nvcc
HINTS
"$ENV{CUDA_PATH}/bin"
"$ENV{CUDA_HOME}/bin"
NO_DEFAULT_PATH)
endif()
if(NOT SD_NVCC_EXECUTABLE)
find_program(SD_NVCC_EXECUTABLE NAMES nvcc)
endif()
if(SD_NVCC_EXECUTABLE)
set(CMAKE_CUDA_COMPILER "${SD_NVCC_EXECUTABLE}" CACHE FILEPATH
"CUDA compiler used by stable-diffusion.cpp" FORCE)
message(STATUS "CUDA compiler defaulted to ${CMAKE_CUDA_COMPILER}")
endif()
endif()

# Seed FindCUDAToolkit without overriding an explicit toolkit selection.
if(NOT DEFINED CUDAToolkit_ROOT OR CUDAToolkit_ROOT STREQUAL "")
if(SD_NVCC_EXECUTABLE)
get_filename_component(SD_CUDA_BIN_DIR "${SD_NVCC_EXECUTABLE}" DIRECTORY)
get_filename_component(SD_CUDA_TOOLKIT_ROOT "${SD_CUDA_BIN_DIR}" DIRECTORY)
set(CUDAToolkit_ROOT "${SD_CUDA_TOOLKIT_ROOT}" CACHE PATH
"CUDA toolkit root used by stable-diffusion.cpp" FORCE)
endif()
endif()

if(CUDAToolkit_ROOT AND
(NOT DEFINED CUDAToolkit_TARGET_DIR OR CUDAToolkit_TARGET_DIR STREQUAL "") AND
(NOT DEFINED CUDAToolkit_INCLUDE_DIRECTORIES OR CUDAToolkit_INCLUDE_DIRECTORIES STREQUAL ""))
file(GLOB SD_CUDA_TARGET_DIRS LIST_DIRECTORIES true
"${CUDAToolkit_ROOT}/targets/*")
foreach(SD_CUDA_TARGET_DIR IN LISTS SD_CUDA_TARGET_DIRS)
if(EXISTS "${SD_CUDA_TARGET_DIR}/include/cuda_runtime.h")
set(CUDAToolkit_TARGET_DIR "${SD_CUDA_TARGET_DIR}" CACHE PATH
"CUDA target directory used by stable-diffusion.cpp" FORCE)
set(CUDAToolkit_INCLUDE_DIRECTORIES "${SD_CUDA_TARGET_DIR}/include" CACHE PATH
"CUDA target include directories used by stable-diffusion.cpp" FORCE)
message(STATUS "CUDA target include directory: ${CUDAToolkit_INCLUDE_DIRECTORIES}")
break()
endif()
endforeach()
endif()

set(GGML_CUDA ON)
endif()

Expand Down
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,23 @@ API and command-line option may change frequently.***
- Download pre-built binaries from the [releases page](https://github.com/leejet/stable-diffusion.cpp/releases)
- Or build from source by following the [build guide](./docs/build.md)

### CUDA on Linux

Build with NVIDIA CUDA support using `-DSD_CUDA=ON`. CUDA 13 installations
that place headers under `targets/<platform>/include` are discovered
automatically. When the C++ compiler is Clang, it is also used as NVCC's host
compiler unless `CMAKE_CUDA_HOST_COMPILER` is supplied explicitly. On Linux,
an installation at `/usr/local/cuda` is preferred over an older `nvcc` found
only through `PATH`.

```sh
cmake -S . -B build -DSD_CUDA=ON
cmake --build build --config Release
```

See the [CUDA build guide](./docs/build.md#build-with-cuda) for prerequisites
and explicit toolkit overrides.

### Download model weights

- download weights(.ckpt or .safetensors or .gguf). For example
Expand Down
9 changes: 9 additions & 0 deletions docs/build.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,15 @@ cmake --build . --config Release

This provides GPU acceleration using NVIDIA GPU. Make sure to have the CUDA toolkit installed. You can download it from your Linux distro's package manager (e.g. `apt install nvidia-cuda-toolkit`) or from here: [CUDA Toolkit](https://developer.nvidia.com/cuda-downloads). Recommended to have at least 4 GB of VRAM.

When building with Clang (including libc++ toolchains), `SD_CUDA` uses the
selected C++ compiler as NVCC's host compiler unless
`CMAKE_CUDA_HOST_COMPILER` is set explicitly. CUDA 13 target-layout installs
are discovered automatically; no `CUDACXX` or `CMAKE_PREFIX_PATH` workaround
is required. Explicit `CUDAToolkit_ROOT`, `CMAKE_CUDA_COMPILER`, and
`CMAKE_CUDA_HOST_COMPILER` settings remain authoritative. On Linux, an
installation at `/usr/local/cuda` is preferred over an older `nvcc` found only
through `PATH`.

```shell
mkdir build && cd build
cmake .. -DSD_CUDA=ON
Expand Down
Loading