Skip to content

Commit 0a04074

Browse files
mudlerlocalai-org-maint-bot
authored andcommitted
fix(buun-llama-cpp): shim atomicAdd(double*,double) for pre-sm_60 CUDA
Buun's Q² calibration path in ggml/src/ggml-cuda/fattn.cu calls atomicAdd with a double* destination. Native double atomicAdd is only available on CUDA compute capability 6.0 and later — LocalAI's CUDA 12 Docker image builds for the full published arch range (which includes sm_50/sm_52), so nvcc fails with: fattn.cu:812: error: no instance of overloaded function "atomicAdd" matches the argument list, argument types are: (double *, double) Add the canonical CAS-loop shim from the CUDA C Programming Guide (B.15 Atomic Functions) guarded on __CUDA_ARCH__ < 600. On sm_60+ the guard is false and nvcc picks up the native intrinsic as before. Patch file lives under backend/cpp/buun-llama-cpp/patches/ and is applied to the cloned fork tree by apply-patches.sh (the infrastructure already put in place for exactly this class of backport). Assisted-by: Claude:claude-opus-4-7 Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
1 parent 74bf9ec commit 0a04074

1 file changed

Lines changed: 46 additions & 0 deletions

File tree

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
Subject: [PATCH] ggml-cuda/fattn: provide atomicAdd(double*,double) shim for pre-sm_60
2+
3+
Buun's Q² calibration path in ggml_cuda_turbo_scale_q calls
4+
atomicAdd(&d_q_channel_sq_fattn[threadIdx.x], (double)(val * val));
5+
but native double atomicAdd is only available on compute capability 6.0
6+
and newer. Compiling against a CUDA arch list that includes older
7+
architectures (LocalAI's CUDA 12 Docker image builds for the full
8+
published arch range) fails with:
9+
10+
fattn.cu(812): error: no instance of overloaded function "atomicAdd"
11+
matches the argument list, argument types are: (double *, double)
12+
13+
Add the canonical CUDA-programming-guide shim at the top of fattn.cu so
14+
pre-sm_60 codegen has a definition to call. On sm_60+ the native CUDA
15+
intrinsic is used and the shim is elided via __CUDA_ARCH__.
16+
17+
--- a/ggml/src/ggml-cuda/fattn.cu
18+
+++ b/ggml/src/ggml-cuda/fattn.cu
19+
@@ -7,6 +7,27 @@
20+
21+
#include <atomic>
22+
23+
+// Pre-sm_60 double atomicAdd shim. Native double atomicAdd(double*,double)
24+
+// is only available on CUDA compute capability 6.0+ (see CUDA C Programming
25+
+// Guide, B.15 Atomic Functions). Buun's Q² calibration path below calls
26+
+// atomicAdd with a double*; without this definition, nvcc fails to find a
27+
+// matching overload whenever the compile target list includes pre-sm_60
28+
+// architectures. The standard CAS loop implementation below matches the
29+
+// semantics of the native intrinsic.
30+
+#if defined(__CUDA_ARCH__) && __CUDA_ARCH__ < 600
31+
+static __device__ double atomicAdd(double * address, double val) {
32+
+ unsigned long long int * address_as_ull = (unsigned long long int *)address;
33+
+ unsigned long long int old = *address_as_ull;
34+
+ unsigned long long int assumed;
35+
+ do {
36+
+ assumed = old;
37+
+ old = atomicCAS(address_as_ull, assumed,
38+
+ __double_as_longlong(val + __longlong_as_double(assumed)));
39+
+ } while (assumed != old);
40+
+ return __longlong_as_double(old);
41+
+}
42+
+#endif
43+
+
44+
// InnerQ: update the fattn-side inverse scale array from host (all devices)
45+
void turbo_innerq_update_fattn_scales(const float * scale_inv) {
46+
int cur_device;

0 commit comments

Comments
 (0)