11#if defined(__AVX__) || defined(__AVX2__) || defined(__AVX512F__)
22 return ((
size_t)h * (
size_t)num_tokens + (
size_t)t) * (size_t)aligned_head_dim
31 int output_token_major)
33 if (output_token_major) {
34 return ((
size_t)t * (
size_t)num_heads + (
size_t)h)
35 * (size_t)aligned_head_dim;
37 return qkv_index(h, t, 0, num_tokens, aligned_head_dim);
41static inline float hsum256_ps_flash(__m256 v) {
42 __m128 hi = _mm256_extractf128_ps(v, 1);
43 __m128 lo = _mm256_castps256_ps128(v);
44 __m128 sum128 = _mm_add_ps(lo, hi);
45 sum128 = _mm_hadd_ps(sum128, sum128);
46 sum128 = _mm_hadd_ps(sum128, sum128);
47 return _mm_cvtss_f32(sum128);
51#if defined(__AVX__) && !defined(__AVX2__)
52static inline float hsum256_ps_flash_avx(__m256 v) {
53 __m128 hi = _mm256_extractf128_ps(v, 1);
54 __m128 lo = _mm256_castps256_ps128(v);
55 __m128 sum128 = _mm_add_ps(lo, hi);
56 sum128 = _mm_hadd_ps(sum128, sum128);
57 sum128 = _mm_hadd_ps(sum128, sum128);
58 return _mm_cvtss_f32(sum128);
77#if defined(__AVX512F__)
78static void attention_flash_query_sliding_avx512(
const float *q_vec,
94 if (sliding_window > 0) {
95 window_start = query_pos - sliding_window + 1;
96 if (window_start < 0) window_start = 0;
101 for (; d + 16 <= aligned_head_dim; d += 16) {
102 _mm512_storeu_ps(&out_vec[d], _mm512_setzero_ps());
104 for (; d < aligned_head_dim; ++d) {
109 int effective_kv_end = query_pos < kv_tokens ? query_pos : kv_tokens - 1;
110 for (
int j = window_start; j <= effective_kv_end; ++j) {
111 const float *k_vec = k_head + (size_t)j * (
size_t)aligned_head_dim;
112 const float *v_vec = v_head + (size_t)j * (
size_t)aligned_head_dim;
115 __m512 dot_acc = _mm512_setzero_ps();
117 for (; d + 16 <= head_dim; d += 16) {
118 __m512 q_v = _mm512_loadu_ps(&q_vec[d]);
119 __m512 k_v = _mm512_loadu_ps(&k_vec[d]);
120 dot_acc = _mm512_fmadd_ps(q_v, k_v, dot_acc);
122 float dot = _mm512_reduce_add_ps(dot_acc);
123 for (; d < head_dim; ++d) {
124 dot += q_vec[d] * k_vec[d];
126 float score = dot * scale;
129 float exp_m = (m == -INFINITY) ? 0.0f : expf(m -
score);
132 __m512 exp_m_vec = _mm512_set1_ps(exp_m);
134 for (; d + 16 <= head_dim; d += 16) {
135 __m512 out_v = _mm512_loadu_ps(&out_vec[d]);
136 __m512 v_v = _mm512_loadu_ps(&v_vec[d]);
137 out_v = _mm512_fmadd_ps(out_v, exp_m_vec, v_v);
138 _mm512_storeu_ps(&out_vec[d], out_v);
140 for (; d < head_dim; ++d) {
141 out_vec[d] = out_vec[d] * exp_m + v_vec[d];
147 float e = expf(
score - m);
150 __m512 e_vec = _mm512_set1_ps(e);
152 for (; d + 16 <= head_dim; d += 16) {
153 __m512 out_v = _mm512_loadu_ps(&out_vec[d]);
154 __m512 v_v = _mm512_loadu_ps(&v_vec[d]);
155 out_v = _mm512_fmadd_ps(e_vec, v_v, out_v);
156 _mm512_storeu_ps(&out_vec[d], out_v);
158 for (; d < head_dim; ++d) {
159 out_vec[d] += e * v_vec[d];
165 float inv_s = 1.0f / s;
166 __m512 inv_s_vec = _mm512_set1_ps(inv_s);
168 for (; d + 16 <= head_dim; d += 16) {
169 __m512 out_v = _mm512_loadu_ps(&out_vec[d]);
170 _mm512_storeu_ps(&out_vec[d], _mm512_mul_ps(out_v, inv_s_vec));
172 for (; d < head_dim; ++d) {
177 for (d = head_dim; d < aligned_head_dim; ++d) {
187static void attention_flash_query_sliding_avx2(
const float *q_vec,
193 int aligned_head_dim,
201 int window_start = 0;
202 if (sliding_window > 0) {
203 window_start = query_pos - sliding_window + 1;
204 if (window_start < 0) window_start = 0;
208 for (; d + 8 <= aligned_head_dim; d += 8) {
209 _mm256_storeu_ps(&out_vec[d], _mm256_setzero_ps());
211 for (; d < aligned_head_dim; ++d) {
215 int effective_kv_end = query_pos < kv_tokens ? query_pos : kv_tokens - 1;
216 for (
int j = window_start; j <= effective_kv_end; ++j) {
217 const float *k_vec = k_head + (size_t)j * (
size_t)aligned_head_dim;
218 const float *v_vec = v_head + (size_t)j * (
size_t)aligned_head_dim;
220 __m256 dot_acc = _mm256_setzero_ps();
222 for (; d + 8 <= head_dim; d += 8) {
223 __m256 q_v = _mm256_loadu_ps(&q_vec[d]);
224 __m256 k_v = _mm256_loadu_ps(&k_vec[d]);
225 dot_acc = _mm256_fmadd_ps(q_v, k_v, dot_acc);
227 float dot = hsum256_ps_flash(dot_acc);
228 for (; d < head_dim; ++d) {
229 dot += q_vec[d] * k_vec[d];
231 float score = dot * scale;
234 float exp_m = (m == -INFINITY) ? 0.0f : expf(m -
score);
237 __m256 exp_m_vec = _mm256_set1_ps(exp_m);
239 for (; d + 8 <= head_dim; d += 8) {
240 __m256 out_v = _mm256_loadu_ps(&out_vec[d]);
241 __m256 v_v = _mm256_loadu_ps(&v_vec[d]);
242 out_v = _mm256_fmadd_ps(out_v, exp_m_vec, v_v);
243 _mm256_storeu_ps(&out_vec[d], out_v);
245 for (; d < head_dim; ++d) {
246 out_vec[d] = out_vec[d] * exp_m + v_vec[d];
252 float e = expf(
score - m);
255 __m256 e_vec = _mm256_set1_ps(e);
257 for (; d + 8 <= head_dim; d += 8) {
258 __m256 out_v = _mm256_loadu_ps(&out_vec[d]);
259 __m256 v_v = _mm256_loadu_ps(&v_vec[d]);
260 out_v = _mm256_fmadd_ps(e_vec, v_v, out_v);
261 _mm256_storeu_ps(&out_vec[d], out_v);
263 for (; d < head_dim; ++d) {
264 out_vec[d] += e * v_vec[d];
269 float inv_s = 1.0f / s;
270 __m256 inv_s_vec = _mm256_set1_ps(inv_s);
272 for (; d + 8 <= head_dim; d += 8) {
273 __m256 out_v = _mm256_loadu_ps(&out_vec[d]);
274 _mm256_storeu_ps(&out_vec[d], _mm256_mul_ps(out_v, inv_s_vec));
276 for (; d < head_dim; ++d) {
280 for (d = head_dim; d < aligned_head_dim; ++d) {
289#if defined(__AVX__) && !defined(__AVX2__)
290static void attention_flash_query_sliding_avx(
const float *q_vec,
296 int aligned_head_dim,
304 int window_start = 0;
305 if (sliding_window > 0) {
306 window_start = query_pos - sliding_window + 1;
307 if (window_start < 0) window_start = 0;
311 for (; d + 8 <= aligned_head_dim; d += 8) {
312 _mm256_storeu_ps(&out_vec[d], _mm256_setzero_ps());
314 for (; d < aligned_head_dim; ++d) {
318 int effective_kv_end = query_pos < kv_tokens ? query_pos : kv_tokens - 1;
319 for (
int j = window_start; j <= effective_kv_end; ++j) {
320 const float *k_vec = k_head + (size_t)j * (
size_t)aligned_head_dim;
321 const float *v_vec = v_head + (size_t)j * (
size_t)aligned_head_dim;
323 __m256 dot_acc = _mm256_setzero_ps();
325 for (; d + 8 <= head_dim; d += 8) {
326 __m256 q_v = _mm256_loadu_ps(&q_vec[d]);
327 __m256 k_v = _mm256_loadu_ps(&k_vec[d]);
328 dot_acc = _mm256_add_ps(dot_acc, _mm256_mul_ps(q_v, k_v));
330 float dot = hsum256_ps_flash_avx(dot_acc);
331 for (; d < head_dim; ++d) {
332 dot += q_vec[d] * k_vec[d];
334 float score = dot * scale;
337 float exp_m = (m == -INFINITY) ? 0.0f : expf(m -
score);
340 __m256 exp_m_vec = _mm256_set1_ps(exp_m);
342 for (; d + 8 <= head_dim; d += 8) {
343 __m256 out_v = _mm256_loadu_ps(&out_vec[d]);
344 __m256 v_v = _mm256_loadu_ps(&v_vec[d]);
345 out_v = _mm256_add_ps(_mm256_mul_ps(out_v, exp_m_vec), v_v);
346 _mm256_storeu_ps(&out_vec[d], out_v);
348 for (; d < head_dim; ++d) {
349 out_vec[d] = out_vec[d] * exp_m + v_vec[d];
355 float e = expf(
score - m);
358 __m256 e_vec = _mm256_set1_ps(e);
360 for (; d + 8 <= head_dim; d += 8) {
361 __m256 out_v = _mm256_loadu_ps(&out_vec[d]);
362 __m256 v_v = _mm256_loadu_ps(&v_vec[d]);
363 out_v = _mm256_add_ps(out_v, _mm256_mul_ps(e_vec, v_v));
364 _mm256_storeu_ps(&out_vec[d], out_v);
366 for (; d < head_dim; ++d) {
367 out_vec[d] += e * v_vec[d];
372 float inv_s = 1.0f / s;
373 __m256 inv_s_vec = _mm256_set1_ps(inv_s);
375 for (; d + 8 <= head_dim; d += 8) {
376 __m256 out_v = _mm256_loadu_ps(&out_vec[d]);
377 _mm256_storeu_ps(&out_vec[d], _mm256_mul_ps(out_v, inv_s_vec));
379 for (; d < head_dim; ++d) {
383 for (d = head_dim; d < aligned_head_dim; ++d) {
398 int aligned_head_dim,
406 int window_start = 0;
407 if (sliding_window > 0) {
408 window_start = query_pos - sliding_window + 1;
409 if (window_start < 0) window_start = 0;
412 for (
int d = 0; d < head_dim; ++d) {
416 int effective_kv_end = query_pos < kv_tokens ? query_pos : kv_tokens - 1;
417 for (
int j = window_start; j <= effective_kv_end; ++j) {
418 const float *k_vec = k_head + (size_t)j * (
size_t)aligned_head_dim;
419 const float *v_vec = v_head + (size_t)j * (
size_t)aligned_head_dim;
422 for (
int d = 0; d < head_dim; ++d) {
423 dot += q_vec[d] * k_vec[d];
425 float score = dot * scale;
428 float exp_m = (m == -INFINITY) ? 0.0f : expf(m -
score);
430 for (
int d = 0; d < head_dim; ++d) {
434 for (
int d = 0; d < head_dim; ++d) {
435 out_vec[d] += v_vec[d];
439 float e = expf(
score - m);
441 for (
int d = 0; d < head_dim; ++d) {
442 out_vec[d] += e * v_vec[d];
447 float inv_s = 1.0f / s;
448 for (
int d = 0; d < head_dim; ++d) {
451 for (
int d = head_dim; d < aligned_head_dim; ++d) {
465 int aligned_head_dim;
466 int kv_stride_tokens;
468 int output_token_major;
470} ck_sliding_attention_args_t;
474 const char *v = getenv(name);
475 if (!v || !v[0])
return fallback;
477 long parsed = strtol(v, &
end, 10);
478 if (
end == v || (
end && *
end !=
'\0'))
return fallback;
479 if (parsed < 0) parsed = 0;
480 if (parsed > 1 << 20) parsed = 1 << 20;
486 const char *v = getenv(
"CK_DISABLE_SLIDING_ATTN_PARALLEL");
487 return v && v[0] && v[0] !=
'0';
495 if (!pool || total_jobs <= 0)
return 1;
499 const int min_tokens =
ck_env_int_default(
"CK_SLIDING_ATTN_PARALLEL_MIN_TOKENS", 128);
500 if (num_tokens < min_tokens || head_dim < 8)
return 1;
504 if (cap > 0 && active > cap) active = cap;
505 if (active > total_jobs) active = total_jobs;
506 return active > 1 ? active : 1;
512 if (!a || job < 0)
return;
514 const int T = a->num_tokens;
515 const size_t kv_head_stride = (size_t)a->kv_stride_tokens * (
size_t)a->aligned_head_dim;
517#if defined(__AVX512F__)
518 #define CK_SLIDING_FLASH_IMPL attention_flash_query_sliding_avx512
519#elif defined(__AVX2__)
520 #define CK_SLIDING_FLASH_IMPL attention_flash_query_sliding_avx2
521#elif defined(__AVX__)
522 #define CK_SLIDING_FLASH_IMPL attention_flash_query_sliding_avx
524 #define CK_SLIDING_FLASH_IMPL attention_flash_query_sliding
527 const int h = job / T;
528 const int i = job - h * T;
529 const int kv_head = (int)((
long long)h * (
long long)a->num_kv_heads /
530 (
long long)a->num_heads);
531 const float *k_head = a->k + (size_t)kv_head * kv_head_stride;
532 const float *v_head = a->v + (size_t)kv_head * kv_head_stride;
533 const float *q_vec = a->q +
qkv_index(h, i, 0, T, a->aligned_head_dim);
535 h, i, a->num_heads, T, a->aligned_head_dim, a->output_token_major);
540 a->head_dim, a->aligned_head_dim,
544#undef CK_SLIDING_FLASH_IMPL
549 const ck_sliding_attention_args_t *a = (
const ck_sliding_attention_args_t *)args;
550 if (!a || ith < 0 || nth <= 0 || ith >= nth)
return;
551 const int total_jobs = a->num_heads * a->num_tokens;
552 for (
int job = ith; job < total_jobs; job += nth) {
575 int aligned_head_dim,
576 int kv_stride_tokens,
579 if (!q || !k || !v || !output) {
582 if (num_heads <= 0 || num_kv_heads <= 0 || num_tokens <= 0) {
585 if (kv_stride_tokens < num_tokens) {
593 if (getenv(
"CK_FORCE_NONSLIDING_ATTN")) {
595 q, k, v, output, num_heads, num_kv_heads, num_tokens,
596 head_dim, aligned_head_dim, kv_stride_tokens
601 const float scale = 1.0f / sqrtf((
float)head_dim);
602 const int T = num_tokens;
603 const size_t kv_head_stride = (size_t)kv_stride_tokens * (
size_t)aligned_head_dim;
605 const int total_jobs = num_heads * T;
608 if (pool && active > 1) {
609 ck_sliding_attention_args_t args = {
614 .num_heads = num_heads,
615 .num_kv_heads = num_kv_heads,
617 .head_dim = head_dim,
618 .aligned_head_dim = aligned_head_dim,
619 .kv_stride_tokens = kv_stride_tokens,
620 .sliding_window = sliding_window,
621 .output_token_major = 0,
628#if defined(__AVX512F__)
629 #define SLIDING_FLASH_IMPL attention_flash_query_sliding_avx512
630#elif defined(__AVX2__)
631 #define SLIDING_FLASH_IMPL attention_flash_query_sliding_avx2
632#elif defined(__AVX__)
633 #define SLIDING_FLASH_IMPL attention_flash_query_sliding_avx
635 #define SLIDING_FLASH_IMPL attention_flash_query_sliding
638 for (
int h = 0; h < num_heads; ++h) {
639 int kv_head = (int)((
long long)h * (
long long)num_kv_heads / (
long long)num_heads);
640 const float *k_head = k + (size_t)kv_head * kv_head_stride;
641 const float *v_head = v + (size_t)kv_head * kv_head_stride;
643 for (
int i = 0; i < T; ++i) {
644 const float *q_vec = q +
qkv_index(h, i, 0, T, aligned_head_dim);
646 h, i, num_heads, T, aligned_head_dim, 0);
650 head_dim, aligned_head_dim,
656#undef SLIDING_FLASH_IMPL
677 int aligned_head_dim,
678 int kv_stride_tokens,
680 int output_token_major)
682 if (!q || !k || !v || !output) {
685 if (num_heads <= 0 || num_kv_heads <= 0 || num_tokens <= 0) {
688 if (kv_stride_tokens < num_tokens) {
692 if (getenv(
"CK_FORCE_NONSLIDING_ATTN")) {
693 if (output_token_major) {
695 q, k, v, output, num_heads, num_kv_heads, num_tokens,
696 head_dim, aligned_head_dim, kv_stride_tokens);
699 q, k, v, output, num_heads, num_kv_heads, num_tokens,
700 head_dim, aligned_head_dim, kv_stride_tokens);
705 const float scale = 1.0f;
706 const int T = num_tokens;
707 const size_t kv_head_stride = (size_t)kv_stride_tokens * (
size_t)aligned_head_dim;
709 const int total_jobs = num_heads * T;
712 if (pool && active > 1) {
713 ck_sliding_attention_args_t args = {
718 .num_heads = num_heads,
719 .num_kv_heads = num_kv_heads,
721 .head_dim = head_dim,
722 .aligned_head_dim = aligned_head_dim,
723 .kv_stride_tokens = kv_stride_tokens,
724 .sliding_window = sliding_window,
725 .output_token_major = output_token_major,
732#if defined(__AVX512F__)
733 #define SLIDING_FLASH_IMPL_GEMMA4 attention_flash_query_sliding_avx512
734#elif defined(__AVX2__)
735 #define SLIDING_FLASH_IMPL_GEMMA4 attention_flash_query_sliding_avx2
736#elif defined(__AVX__)
737 #define SLIDING_FLASH_IMPL_GEMMA4 attention_flash_query_sliding_avx
739 #define SLIDING_FLASH_IMPL_GEMMA4 attention_flash_query_sliding
742 for (
int h = 0; h < num_heads; ++h) {
743 int kv_head = (int)((
long long)h * (
long long)num_kv_heads / (
long long)num_heads);
744 const float *k_head = k + (size_t)kv_head * kv_head_stride;
745 const float *v_head = v + (size_t)kv_head * kv_head_stride;
747 for (
int i = 0; i < T; ++i) {
748 const float *q_vec = q +
qkv_index(h, i, 0, T, aligned_head_dim);
750 h, i, num_heads, T, aligned_head_dim, output_token_major);
754 head_dim, aligned_head_dim,
760#undef SLIDING_FLASH_IMPL_GEMMA4
772 int aligned_head_dim,
773 int kv_stride_tokens,
777 q, k, v, output, num_heads, num_kv_heads, num_tokens, head_dim,
778 aligned_head_dim, kv_stride_tokens, sliding_window,
791 int aligned_head_dim,
792 int kv_stride_tokens,
796 q, k, v, output, num_heads, num_kv_heads, num_tokens, head_dim,
797 aligned_head_dim, kv_stride_tokens, sliding_window,
807 int aligned_head_dim,
808 int kv_stride_tokens,
812 q, q, q, output, num_heads, num_heads, num_tokens,
813 head_dim, aligned_head_dim, kv_stride_tokens, sliding_window
818 const float *q_token,
819 const float *k_cache,
820 const float *v_cache,
827 int aligned_head_dim,
830 if (!q_token || !k_cache || !v_cache || !out_token) {
833 if (num_heads <= 0 || num_kv_heads <= 0 || cache_capacity <= 0) {
836 if (kv_tokens <= 0 || kv_tokens > cache_capacity || head_dim <= 0 || aligned_head_dim <= 0) {
844 if (getenv(
"CK_FORCE_NONSLIDING_ATTN")) {
846 q_token, k_cache, v_cache, out_token,
847 num_heads, num_kv_heads, kv_tokens, cache_capacity,
848 head_dim, aligned_head_dim
853 const float scale = 1.0f / sqrtf((
float)head_dim);
854 const size_t head_stride = (size_t)cache_capacity * (
size_t)aligned_head_dim;
857 int effective_kv_tokens = kv_tokens;
858 if (sliding_window > 0 && sliding_window < kv_tokens) {
859 effective_kv_tokens = sliding_window;
863 if (effective_kv_tokens <= 0) {
868 int kv_start_offset = kv_tokens - effective_kv_tokens;
870#if defined(__AVX512F__)
871 #define SLIDING_DECODE_IMPL attention_flash_query_sliding_avx512
872#elif defined(__AVX2__)
873 #define SLIDING_DECODE_IMPL attention_flash_query_sliding_avx2
874#elif defined(__AVX__)
875 #define SLIDING_DECODE_IMPL attention_flash_query_sliding_avx
877 #define SLIDING_DECODE_IMPL attention_flash_query_sliding
880 for (
int h = 0; h < num_heads; ++h) {
881 int kv_head = (int)((
long long)h * (
long long)num_kv_heads / (
long long)num_heads);
882 const float *q_head = q_token + (size_t)h * (
size_t)aligned_head_dim;
884 const float *k_head = k_cache + (size_t)kv_head * head_stride
885 + (
size_t)kv_start_offset * (size_t)aligned_head_dim;
886 const float *v_head = v_cache + (size_t)kv_head * head_stride
887 + (
size_t)kv_start_offset * (size_t)aligned_head_dim;
888 float *out_head = out_token + (size_t)h * (
size_t)aligned_head_dim;
893 effective_kv_tokens - 1,
895 head_dim, aligned_head_dim,
900#undef SLIDING_DECODE_IMPL
904 const float *q_token,
905 const float *k_cache,
906 const float *v_cache,
913 int aligned_head_dim,
916 if (!q_token || !k_cache || !v_cache || !out_token) {
919 if (num_heads <= 0 || num_kv_heads <= 0 || cache_capacity <= 0) {
922 if (kv_tokens <= 0 || kv_tokens > cache_capacity || head_dim <= 0 || aligned_head_dim <= 0) {
926 if (getenv(
"CK_FORCE_NONSLIDING_ATTN")) {
928 q_token, k_cache, v_cache, out_token,
929 num_heads, num_kv_heads, kv_tokens, cache_capacity,
930 head_dim, aligned_head_dim
935 const float scale = 1.0f;
936 const size_t head_stride = (size_t)cache_capacity * (
size_t)aligned_head_dim;
937 int effective_kv_tokens = kv_tokens;
938 if (sliding_window > 0 && sliding_window < kv_tokens) {
939 effective_kv_tokens = sliding_window;
941 if (effective_kv_tokens <= 0) {
944 int kv_start_offset = kv_tokens - effective_kv_tokens;
946#if defined(__AVX512F__)
947 #define SLIDING_DECODE_IMPL_GEMMA4 attention_flash_query_sliding_avx512
948#elif defined(__AVX2__)
949 #define SLIDING_DECODE_IMPL_GEMMA4 attention_flash_query_sliding_avx2
950#elif defined(__AVX__)
951 #define SLIDING_DECODE_IMPL_GEMMA4 attention_flash_query_sliding_avx
953 #define SLIDING_DECODE_IMPL_GEMMA4 attention_flash_query_sliding
956 for (
int h = 0; h < num_heads; ++h) {
957 int kv_head = (int)((
long long)h * (
long long)num_kv_heads / (
long long)num_heads);
958 const float *q_head = q_token + (size_t)h * (
size_t)aligned_head_dim;
959 const float *k_head = k_cache + (size_t)kv_head * head_stride
960 + (
size_t)kv_start_offset * (size_t)aligned_head_dim;
961 const float *v_head = v_cache + (size_t)kv_head * head_stride
962 + (
size_t)kv_start_offset * (size_t)aligned_head_dim;
963 float *out_head = out_token + (size_t)h * (
size_t)aligned_head_dim;
966 effective_kv_tokens - 1,
968 head_dim, aligned_head_dim,
973#undef SLIDING_DECODE_IMPL_GEMMA4
977 const float *q_token,
978 const float *k_cache,
979 const float *v_cache,
985 int aligned_head_dim,
989 q_token, k_cache, v_cache, out_token, num_heads, num_heads,
990 kv_tokens, cache_capacity, head_dim, aligned_head_dim, sliding_window
static size_t qkv_index(int h, int t, int d, int num_tokens, int aligned_head_dim)
void attention_forward_causal_head_major_gqa_flash_strided_sliding_gemma4(const float *q, const float *k, const float *v, float *output, int num_heads, int num_kv_heads, int num_tokens, int head_dim, int aligned_head_dim, int kv_stride_tokens, int sliding_window)
static int ck_env_int_default(const char *name, int fallback)
void attention_forward_decode_head_major_gqa_flash_sliding_gemma4(const float *q_token, const float *k_cache, const float *v_cache, float *out_token, int num_heads, int num_kv_heads, int kv_tokens, int cache_capacity, int head_dim, int aligned_head_dim, int sliding_window)
static int ck_sliding_attention_pick_threads(ck_threadpool_t *pool, int total_jobs, int num_tokens, int head_dim)
void attention_forward_causal_head_major_gqa_flash_strided_sliding(const float *q, const float *k, const float *v, float *output, int num_heads, int num_kv_heads, int num_tokens, int head_dim, int aligned_head_dim, int kv_stride_tokens, int sliding_window)
static int ck_sliding_attention_parallel_disabled(void)
void attention_forward_decode_head_major_gqa_flash_sliding(const float *q_token, const float *k_cache, const float *v_cache, float *out_token, int num_heads, int num_kv_heads, int kv_tokens, int cache_capacity, int head_dim, int aligned_head_dim, int sliding_window)
void attention_forward_causal_head_major_gqa_flash_strided_sliding_gemma4_token_output(const float *q, const float *k, const float *v, float *output, int num_heads, int num_kv_heads, int num_tokens, int head_dim, int aligned_head_dim, int kv_stride_tokens, int sliding_window)
#define CK_SLIDING_FLASH_IMPL
#define SLIDING_DECODE_IMPL_GEMMA4
#define SLIDING_DECODE_IMPL
static void attention_flash_query_sliding(const float *q_vec, const float *k_head, const float *v_head, int query_pos, int kv_tokens, int head_dim, int aligned_head_dim, float scale, float *out_vec, int sliding_window)
static void ck_sliding_attention_compute_one(const ck_sliding_attention_args_t *a, int job)
void attention_forward_decode_head_major_shared_kv_sliding_gemma4(const float *q_token, const float *k_cache, const float *v_cache, float *out_token, int num_heads, int kv_tokens, int cache_capacity, int head_dim, int aligned_head_dim, int sliding_window)
#define SLIDING_FLASH_IMPL_GEMMA4
#define SLIDING_FLASH_IMPL
void attention_forward_causal_head_major_shared_kv_sliding_gemma4(const float *q, float *output, int num_heads, int num_tokens, int head_dim, int aligned_head_dim, int kv_stride_tokens, int sliding_window)
static size_t attention_output_index(int h, int t, int num_heads, int num_tokens, int aligned_head_dim, int output_token_major)
static void attention_forward_causal_head_major_gqa_flash_strided_sliding_gemma4_impl(const float *q, const float *k, const float *v, float *output, int num_heads, int num_kv_heads, int num_tokens, int head_dim, int aligned_head_dim, int kv_stride_tokens, int sliding_window, int output_token_major)
static void ck_sliding_attention_work_fn(int ith, int nth, void *args)
Persistent pthread thread pool for CK-Engine inference.
void ck_threadpool_dispatch_n(ck_threadpool_t *pool, int active_threads, ck_work_fn_t fn, void *args)
ck_threadpool_t * ck_threadpool_global(void)
int ck_threadpool_thread_id(const ck_threadpool_t *pool)
int ck_threadpool_n_threads(const ck_threadpool_t *pool)
void attention_forward_causal_head_major_gqa_flash_strided(const float *q, const float *k, const float *v, float *output, int num_heads, int num_kv_heads, int num_tokens, int head_dim, int aligned_head_dim, int kv_stride_tokens)
void attention_forward_decode_head_major_gqa_flash_gemma4(const float *q_token, const float *k_cache, const float *v_cache, float *out_token, int num_heads, int num_kv_heads, int kv_tokens, int cache_capacity, int head_dim, int aligned_head_dim)
void attention_forward_causal_head_major_gqa_flash_strided_gemma4(const float *q, const float *k, const float *v, float *output, int num_heads, int num_kv_heads, int num_tokens, int head_dim, int aligned_head_dim, int kv_stride_tokens)
void attention_forward_decode_head_major_gqa_flash(const float *q_token, const float *k_cache, const float *v_cache, float *out_token, int num_heads, int num_kv_heads, int kv_tokens, int cache_capacity, int head_dim, int aligned_head_dim)
void attention_forward_causal_head_major_gqa_flash_strided_gemma4_token_output(const float *q, const float *k, const float *v, float *output, int num_heads, int num_kv_heads, int num_tokens, int head_dim, int aligned_head_dim, int kv_stride_tokens)