Skip to content

v0.3.0

Choose a tag to compare

@github-actions github-actions released this 04 Aug 12:07
64444a7

stable-diffusion-go v0.3.0 — pure-Go binding + prebuilt native libraries.

Built from leejet/stable-diffusion.cpp @ e92e86f (upstream pin: master-802-e92e86f).

go get github.com/Pendra-Cloud/stable-diffusion-go@v0.3.0 for the
binding; the lib archives attached here match this exact tag. Each archive
contains a self-contained libstable-diffusion (ggml statically linked,
hidden visibility — exports only the sd_* symbols pkg/sd/load.go registers).

CUDA archives require a matching host CUDA runtime; Vulkan archives require
a Vulkan loader/ICD on the host. The Windows archive carries the per-CPU/GPU
(avx2/avx512/avx/noavx/vulkan/cuda13) subdir tree the binding selects from.

What & why

Adds whitelisted sd_*-prefixed wrappers around ggml's device-memory registry, compiled into libstable-diffusion, plus a GpuDevices() binding.

This lets a host that only dlopens libstable-diffusion (which statically links ggml with hidden visibility) read per-device free/total VRAM in-process — the same measurement llama.cpp / whisper.cpp already expose through their own libggml.

Without it, a Pendra worker measuring a stable-diffusion model's footprint on a discrete GPU has no per-device VRAM reading, falls back to a process-RSS delta that misses dedicated VRAM, and reports ~0.1 GB — so the model's real weights land un-attributed in the console memory map (Pendra-Cloud/pendra#1489). The worker-side consumer of GpuDevices() is a follow-up PR in the pendra repo.

Changes

  • csrc/sd_devmem.cppSD_API wrappers: sd_backend_dev_count / get / memory / name / type, thin passthroughs to the hidden ggml_backend_dev_*.
  • scripts/inject-devmem-wrapper.sh — drops the wrapper into upstream/src before the build; picked up by upstream's src/*.cpp CONFIGURE_DEPENDS glob (no CMakeLists edit, survives upstream refactors).
  • build-libs.yml — inject step in all four build jobs (linux, linux-cuda, macos, windows).
  • lib/expected-symbols.txt — the fail-closed gate now requires the 5 new symbols and still forbids any exported ggml_*, so ggml stays static + hidden (no base-name collision with another in-process ggml backend).
  • pkg/sdregisterDevMemFunctions (optional: recovers so it never fails Load against an older lib, e.g. a PENDRA_SD_LIB override) + GpuDevices() (panic-safe enumeration).

Verification

Built locally on Apple Silicon (Metal) with the wrapper injected:

  • nm -gU shows all 5 _sd_backend_dev_* exported; no ggml_* leak (only the allowed ggml_metallib_start/end markers).
  • scripts/check-symbols.shOK — all 54 expected symbols exported, no ggml leakage.
  • Runtime: sd.Load() + sd.GpuDevices() returns real MTL0 free/total (~12.1 GiB), plus BLAS/CPU devices with correct types.
  • go test ./pkg/sd -run TestExpectedSymbolsMatchBinding (drift gate) passes.

The full CI matrix build is the remaining gate. Recommend a workflow_dispatch gating run (only=linux-amd64-cuda) to validate the injection on the CUDA leg before merge.

🤖 Generated with Claude Code

What's Changed

  • feat(devmem): export sd_backend_dev_* wrappers for in-process VRAM reads by @tomcrawf90 in #29

Full Changelog: v0.2.4...v0.3.0