cuda-dll: make the Windows CUDA build work as shipped — MSVC host flags, CUDA_PATH defaults, POSIX shim in kernel test (#158, #157)
* cuda-dll: fix Windows build — MSVC host flags, CUDA_PATH default, POSIX setenv shim in the kernel test (#157) First hardware validation of the #131 CUDA_DLL path (RTX PRO 6000 Blackwell sm_120, MSVC 14.44 + CUDA 13.2, MSYS2 UCRT64 host build) found three blockers that made 'make cuda-dll' unbuildable as shipped: - NVCCFLAGS passed GCC-style -Xcompiler=-Wall,-Wextra to the MSVC host compiler (hard error D8021). Use -Xcompiler=-W3 on Windows — dash form, since MSYS make mangles /W3 into a filesystem path. - NVCC defaulted to $(CUDA_HOME)/bin/nvcc with CUDA_HOME=/usr/local/cuda; on Windows default CUDA_HOME from the installer's CUDA_PATH and NVCC to plain 'nvcc' from PATH (CUDA_PATH contains spaces, which the unquoted recipe checks cannot survive; an MSVC PATH environment is already required). - tests/test_backend_cuda.cu used POSIX setenv/unsetenv (undefined under MSVC); add a two-line _putenv_s shim. Also corrects the stale '11 API symbols' comment (the header exports 15 and backend_loader.c resolves all 15). Validated: make cuda-dll (stock flags) + make glm CUDA_DLL=1 ARCH=native → [CUDA] device init on sm_120, tiny oracle TF 32/32 + greedy 20/20, kernel suite 'q8/q4/q2/f32 correctness ok', graceful no-dll fallback, plain build byte-identical CPU behavior. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * cuda: fix heap corruption in expert_host_release on Windows (CUDA_RELEASE_HOST=1) expert_host_release() freed the expert slab with plain free(), but the slab is posix_memalign'd — which compat.h maps to _aligned_malloc on Windows, so free() corrupts the CRT heap: instant 0xC0000374 crash on the first released expert. This is the exact pattern the compat.h audit fixed at the original expert_load site ("l'unico sito che libera memoria aligned e' free(s->slab)"); this call site was added later and reintroduced it. compat_aligned_free is plain free on POSIX, so non-Windows behavior is unchanged. fslab stays plain free (malloc/falloc on the CPU path). Found running the VRAM expert tier on real hardware (80 GB resident on an RTX PRO 6000, CUDA_RELEASE_HOST=1 to avoid 80 GB of host double-residency — reproducible crash before, clean generation after). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: lEWFkRAD <186512915+lEWFkRAD@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: JustVugg <JustVugg@users.noreply.github.com>
This commit is contained in:
+21
-1
@@ -105,10 +105,30 @@ INSTALL ?= install
|
||||
# clean. See backend_loader.c and README "cuda-dll" below.
|
||||
CUDA ?= 0
|
||||
CUDA_DLL ?= 0
|
||||
ifneq ($(IS_WIN),)
|
||||
# the CUDA installer sets CUDA_PATH system-wide (e.g. C:\Program Files\NVIDIA
|
||||
# GPU Computing Toolkit\CUDA\v13.2); fall back to it before the POSIX default.
|
||||
# NVCC defaults to plain `nvcc` from PATH: CUDA_PATH contains spaces, which the
|
||||
# unquoted recipe checks cannot survive — and the cuda-dll recipe already
|
||||
# requires an MSVC environment (vcvars64) on PATH, so requiring the CUDA bin
|
||||
# directory too is symmetric. The installer adds it by default.
|
||||
CUDA_HOME ?= $(subst \,/,$(CUDA_PATH))
|
||||
NVCC ?= nvcc
|
||||
else
|
||||
CUDA_HOME ?= /usr/local/cuda
|
||||
NVCC ?= $(CUDA_HOME)/bin/nvcc
|
||||
endif
|
||||
CUDA_ARCH ?= native
|
||||
ifneq ($(IS_WIN),)
|
||||
# nvcc's host compiler on Windows is MSVC cl.exe: the GCC-style
|
||||
# -Xcompiler=-Wall,-Wextra is rejected ("D8021 invalid numeric argument
|
||||
# '/Wextra'"), which made `make cuda-dll` unbuildable as shipped. -W3 is
|
||||
# the MSVC warning level (dash form, NOT /W3: MSYS make would mangle the
|
||||
# slash-form into a filesystem path).
|
||||
NVCCFLAGS ?= -O3 -std=c++17 -arch=$(CUDA_ARCH) -Xcompiler=-W3
|
||||
else
|
||||
NVCCFLAGS ?= -O3 -std=c++17 -arch=$(CUDA_ARCH) -Xcompiler=-Wall,-Wextra
|
||||
endif
|
||||
ifeq ($(IS_WIN),)
|
||||
PYTHON ?= python3
|
||||
else
|
||||
@@ -169,7 +189,7 @@ backend_loader.o: backend_loader.c backend_cuda.h compat.h
|
||||
# compiler, required by nvcc on Windows) into coli_cuda.dll. Run this from a
|
||||
# shell that has the MSVC environment set (e.g. after vcvars64.bat, or from a
|
||||
# "x64 Native Tools Command Prompt"). COLI_CUDA_BUILDING_DLL enables
|
||||
# __declspec(dllexport) so the 11 API symbols are exported.
|
||||
# __declspec(dllexport) so the 15 API symbols are exported.
|
||||
cuda-dll: backend_cuda.cu backend_cuda.h
|
||||
@command -v $(NVCC) >/dev/null 2>&1 || { echo "nvcc not found: set CUDA_HOME or NVCC" >&2; exit 1; }
|
||||
@command -v cl >/dev/null 2>&1 || { echo "cl.exe (MSVC) not in PATH — run vcvars64.bat first" >&2; exit 1; }
|
||||
|
||||
@@ -1497,7 +1497,12 @@ static void expert_host_release(Model *m, ESlot *s){
|
||||
if(s->fslab) compat_munlock(s->fslab,(size_t)s->fslab_cap*sizeof(float));
|
||||
#endif
|
||||
int64_t bytes=qt_bytes(&s->g)+qt_bytes(&s->u)+qt_bytes(&s->d);
|
||||
free(s->slab); free(s->fslab); s->slab=NULL; s->fslab=NULL; s->slab_cap=s->fslab_cap=0;
|
||||
/* slab is posix_memalign'd: on Windows that is _aligned_malloc, and plain
|
||||
* free() corrupts the CRT heap (0xC0000374) — same bug the compat.h audit
|
||||
* fixed at the original expert_load site. fslab is plain malloc/falloc
|
||||
* on the CPU path, so its free() stays plain (Metal path frees it before
|
||||
* re-alloc and never reaches here with an aligned fslab on _WIN32). */
|
||||
compat_aligned_free(s->slab); free(s->fslab); s->slab=NULL; s->fslab=NULL; s->slab_cap=s->fslab_cap=0;
|
||||
QT *q[3]={&s->g,&s->u,&s->d};
|
||||
for(int k=0;k<3;k++){ q[k]->qf=NULL; q[k]->q8=NULL; q[k]->q4=NULL; q[k]->s=NULL; }
|
||||
m->resident_bytes-=bytes; if(m->resident_bytes<0) m->resident_bytes=0;
|
||||
|
||||
@@ -5,6 +5,14 @@
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
|
||||
#ifdef _WIN32
|
||||
/* MSVC has no POSIX setenv/unsetenv */
|
||||
static int setenv(const char *name, const char *value, int overwrite) {
|
||||
(void)overwrite; return _putenv_s(name, value);
|
||||
}
|
||||
static int unsetenv(const char *name) { return _putenv_s(name, ""); }
|
||||
#endif
|
||||
|
||||
static int close_enough(const float *got, const float *want, int n) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (std::fabs(got[i] - want[i]) > 1e-4f) {
|
||||
|
||||
Reference in New Issue
Block a user