@@ -25,6 +25,12 @@ int turbo3_cpu_wht_group_size = 0;
2525#define TURBO_D 128 /* rotation group size = head_dim (independent of block size) */
2626#define TURBO_QJL_CONST 1.2533141373155003f /* sqrt(pi/2) */
2727
28+ /* TURBO_D must match QK_TURBO3_GROUP from ggml-common.h — they represent
29+ * the same rotation group size but are defined separately. Guard against
30+ * silent divergence so GPU kernels and CPU reference stay in sync. */
31+ static_assert (TURBO_D == QK_TURBO3_GROUP ,
32+ "TURBO_D must equal QK_TURBO3_GROUP (rotation group size)" );
33+
2834/* Optimal centroids from paper (scaled by 1/sqrt(d)) */
2935/* 2-bit: {±0.453, ±1.51} / sqrt(d) */
3036static const float CENTROIDS_2BIT [4 ] = { -0.133462f , -0.039994f , 0.039994f , 0.133462f };
@@ -63,16 +69,18 @@ static void turbo_init_rotation(void) {
6369
6470 const int d = TURBO_D ;
6571
66- /* Generate random Gaussian matrix */
72+ /* Generate random Gaussian matrix directly into turbo_rotation.
73+ * Previous code used a 64KB stack-local G[128*128] then memcpy'd —
74+ * this segfaults on llama.cpp worker threads with reduced stack
75+ * sizes (512KB macOS, 64KB some Linux configs). Writing directly
76+ * into the static array avoids the stack allocation entirely. */
6777 turbo_prng_seed (TURBO_SEED_ROTATION );
68- float G [TURBO_D * TURBO_D ];
6978 for (int i = 0 ; i < d * d ; i ++ ) {
70- G [i ] = (float )turbo_prng_normal ();
79+ turbo_rotation [i ] = (float )turbo_prng_normal ();
7180 }
7281
7382 /* QR decomposition via modified Gram-Schmidt */
7483 /* Q stored column-major in turbo_rotation */
75- memcpy (turbo_rotation , G , d * d * sizeof (float ));
7684
7785 for (int j = 0 ; j < d ; j ++ ) {
7886 /* Normalize column j */
0 commit comments