80 __m256 vsum = _mm256_setzero_ps();
82 for (; i + 7 < n; i += 8) {
83 __m256 vx = _mm256_loadu_ps(x + i);
84 vsum = _mm256_fmadd_ps(vx, vx, vsum);
86 __m128 vlow = _mm256_castps256_ps128(vsum);
87 __m128 vhigh = _mm256_extractf128_ps(vsum, 1);
88 vlow = _mm_add_ps(vlow, vhigh);
89 vlow = _mm_hadd_ps(vlow, vlow);
90 vlow = _mm_hadd_ps(vlow, vlow);
91 sum_sq = _mm_cvtss_f32(vlow);
93 sum_sq += x[i] * x[i];
96 for (
int i = 0; i < n; i++) {
97 sum_sq += x[i] * x[i];
101 float rms = sqrtf(sum_sq / (
float)n + eps);
110 return x / (1.0f + expf(-x));
114static inline __m256 silu_avx2(__m256 x) {
116 _mm256_storeu_ps(lanes, x);
117 for (
int i = 0; i < 8; i++) {
120 return _mm256_loadu_ps(lanes);
129 float max_val = x[0];
130 for (
int i = 1; i < n; i++) {
131 if (x[i] > max_val) max_val = x[i];
135 for (
int i = 0; i < n; i++) {
136 x[i] = expf(x[i] - max_val);
140 float inv_sum = 1.0f / sum;
141 for (
int i = 0; i < n; i++) {
156 const float *k_cache,
157 const float *v_cache,
168 const float *residual_1,
171 const float *rms_weight,
184 int intermediate_dim,
189 const int heads_per_kv = num_heads / num_kv_heads;
190 const int q_dim = num_heads * head_dim;
191 const int kv_dim = num_kv_heads * head_dim;
194 float attn_out[4096];
195 float hidden_after_attn[4096];
197 float gate_out[16384];
200 if (embed_dim > 4096 || intermediate_dim > 16384) {
208 memset(attn_out, 0, q_dim *
sizeof(
float));
210 for (
int h = 0; h < num_heads; h++) {
211 int kv_h = h / heads_per_kv;
213 const float *q_head = q + h * head_dim;
214 float *out_head = attn_out + h * head_dim;
218 if (seq_len > 8192)
return;
220 for (
int t = 0; t < seq_len; t++) {
221 const float *k_t = k_cache + t * kv_dim + kv_h * head_dim;
223 for (
int d = 0; d < head_dim; d++) {
224 score += q_head[d] * k_t[d];
226 scores[t] =
score * attn_scale;
233 for (
int t = 0; t < seq_len; t++) {
234 const float *v_t = v_cache + t * kv_dim + kv_h * head_dim;
236 for (
int d = 0; d < head_dim; d++) {
237 out_head[d] += w * v_t[d];
246 for (
int i = 0; i < embed_dim; i++) {
248 const float *wo_row = wo + i * q_dim;
249 for (
int j = 0; j < q_dim; j++) {
250 sum += wo_row[j] * attn_out[j];
252 hidden_after_attn[i] = sum + residual_1[i];
262 __m256 vscale = _mm256_set1_ps(rms_scale);
264 for (; i + 7 < embed_dim; i += 8) {
265 __m256 vh = _mm256_loadu_ps(hidden_after_attn + i);
266 __m256 vw = _mm256_loadu_ps(rms_weight + i);
267 __m256 vn = _mm256_mul_ps(_mm256_mul_ps(vh, vw), vscale);
268 _mm256_storeu_ps(normed + i, vn);
270 for (; i < embed_dim; i++) {
271 normed[i] = hidden_after_attn[i] * rms_weight[i] * rms_scale;
274 for (
int i = 0; i < embed_dim; i++) {
275 normed[i] = hidden_after_attn[i] * rms_weight[i] * rms_scale;
284 for (
int i = 0; i < intermediate_dim; i++) {
286 const float *wg_row = w_gate + i * embed_dim;
287 for (
int j = 0; j < embed_dim; j++) {
288 sum += wg_row[j] * normed[j];
294 for (
int i = 0; i < intermediate_dim; i++) {
296 const float *wu_row = w_up + i * embed_dim;
297 for (
int j = 0; j < embed_dim; j++) {
298 sum += wu_row[j] * normed[j];
309 for (; i + 7 < intermediate_dim; i += 8) {
310 __m256 vg = _mm256_loadu_ps(gate_out + i);
311 __m256 vu = _mm256_loadu_ps(up_out + i);
312 __m256 vsilu = silu_avx2(vg);
313 __m256 vswiglu = _mm256_mul_ps(vsilu, vu);
314 _mm256_storeu_ps(gate_out + i, vswiglu);
316 for (; i < intermediate_dim; i++) {
317 gate_out[i] =
silu_scalar(gate_out[i]) * up_out[i];
320 for (
int i = 0; i < intermediate_dim; i++) {
321 gate_out[i] =
silu_scalar(gate_out[i]) * up_out[i];
329 for (
int i = 0; i < embed_dim; i++) {
331 const float *wd_row = w_down + i * intermediate_dim;
332 for (
int j = 0; j < intermediate_dim; j++) {
333 sum += wd_row[j] * gate_out[j];
335 hidden_out[i] = sum + hidden_after_attn[i];
352static inline float gemv_fp32_row_avx2(
357 __m256 acc = _mm256_setzero_ps();
360 for (; k + 7 < K; k += 8) {
361 __m256 vw = _mm256_loadu_ps(row + k);
362 __m256 vx = _mm256_loadu_ps(x + k);
363 acc = _mm256_fmadd_ps(vw, vx, acc);
367 __m128 vlow = _mm256_castps256_ps128(acc);
368 __m128 vhigh = _mm256_extractf128_ps(acc, 1);
369 vlow = _mm_add_ps(vlow, vhigh);
370 __m128 shuf = _mm_movehdup_ps(vlow);
371 vlow = _mm_add_ps(vlow, shuf);
372 shuf = _mm_movehl_ps(shuf, vlow);
373 vlow = _mm_add_ss(vlow, shuf);
374 float sum = _mm_cvtss_f32(vlow);
378 sum += row[k] * x[k];
387 const float *hidden_in,
390 const float *rms_weight,
400 int intermediate_dim,
409 if (embed_dim > 4096 || intermediate_dim > 16384) {
420 __m256 vscale = _mm256_set1_ps(rms_scale);
422 for (; i + 7 < embed_dim; i += 8) {
423 __m256 vh = _mm256_loadu_ps(hidden_in + i);
424 __m256 vw = _mm256_loadu_ps(rms_weight + i);
425 __m256 vn = _mm256_mul_ps(_mm256_mul_ps(vh, vw), vscale);
426 _mm256_storeu_ps(normed + i, vn);
428 for (; i < embed_dim; i++) {
429 normed[i] = hidden_in[i] * rms_weight[i] * rms_scale;
432 for (
int i = 0; i < embed_dim; i++) {
433 normed[i] = hidden_in[i] * rms_weight[i] * rms_scale;
445 for (
int j = 0; j < intermediate_dim; j++) {
447 const float *wg_row = w_gate + j * embed_dim;
448 const float *wu_row = w_up + j * embed_dim;
450 __m256 gate_acc = _mm256_setzero_ps();
451 __m256 up_acc = _mm256_setzero_ps();
454 for (; k + 7 < embed_dim; k += 8) {
455 __m256 vn = _mm256_loadu_ps(normed + k);
456 __m256 vwg = _mm256_loadu_ps(wg_row + k);
457 __m256 vwu = _mm256_loadu_ps(wu_row + k);
459 gate_acc = _mm256_fmadd_ps(vwg, vn, gate_acc);
460 up_acc = _mm256_fmadd_ps(vwu, vn, up_acc);
464 __m128 glow = _mm256_castps256_ps128(gate_acc);
465 __m128 ghigh = _mm256_extractf128_ps(gate_acc, 1);
466 glow = _mm_add_ps(glow, ghigh);
467 __m128 gshuf = _mm_movehdup_ps(glow);
468 glow = _mm_add_ps(glow, gshuf);
469 gshuf = _mm_movehl_ps(gshuf, glow);
470 glow = _mm_add_ss(glow, gshuf);
471 float gate_val = _mm_cvtss_f32(glow);
473 __m128 ulow = _mm256_castps256_ps128(up_acc);
474 __m128 uhigh = _mm256_extractf128_ps(up_acc, 1);
475 ulow = _mm_add_ps(ulow, uhigh);
476 __m128 ushuf = _mm_movehdup_ps(ulow);
477 ulow = _mm_add_ps(ulow, ushuf);
478 ushuf = _mm_movehl_ps(ushuf, ulow);
479 ulow = _mm_add_ss(ulow, ushuf);
480 float up_val = _mm_cvtss_f32(ulow);
483 for (; k < embed_dim; k++) {
484 gate_val += wg_row[k] * normed[k];
485 up_val += wu_row[k] * normed[k];
492 for (
int j = 0; j < intermediate_dim; j++) {
493 const float *wg_row = w_gate + j * embed_dim;
494 const float *wu_row = w_up + j * embed_dim;
495 float gate_val = 0.0f, up_val = 0.0f;
497 for (
int k = 0; k < embed_dim; k++) {
498 gate_val += wg_row[k] * normed[k];
499 up_val += wu_row[k] * normed[k];
511 for (
int j = 0; j < embed_dim; j++) {
512 float sum = gemv_fp32_row_avx2(w_down + j * intermediate_dim, swiglu, intermediate_dim);
513 hidden_out[j] = sum + hidden_in[j];
516 for (
int j = 0; j < embed_dim; j++) {
518 const float *wd_row = w_down + j * intermediate_dim;
519 for (
int k = 0; k < intermediate_dim; k++) {
520 sum += wd_row[k] * swiglu[k];
522 hidden_out[j] = sum + hidden_in[j];
543 const float *hidden_in,
544 const float *rms_weight,
550 int intermediate_dim,
555 float gate_out[16384];
558 if (embed_dim > 4096 || intermediate_dim > 16384) {
569 __m256 vscale = _mm256_set1_ps(rms_scale);
571 for (; i + 7 < embed_dim; i += 8) {
572 __m256 vh = _mm256_loadu_ps(hidden_in + i);
573 __m256 vw = _mm256_loadu_ps(rms_weight + i);
574 __m256 vn = _mm256_mul_ps(_mm256_mul_ps(vh, vw), vscale);
575 _mm256_storeu_ps(normed + i, vn);
577 for (; i < embed_dim; i++) {
578 normed[i] = hidden_in[i] * rms_weight[i] * rms_scale;
581 for (
int i = 0; i < embed_dim; i++) {
582 normed[i] = hidden_in[i] * rms_weight[i] * rms_scale;
591 for (
int j = 0; j < intermediate_dim; j++) {
592 gate_out[j] = gemv_fp32_row_avx2(w_gate + j * embed_dim, normed, embed_dim);
595 for (
int j = 0; j < intermediate_dim; j++) {
597 const float *wg_row = w_gate + j * embed_dim;
598 for (
int k = 0; k < embed_dim; k++) {
599 sum += wg_row[k] * normed[k];
613 for (
int j = 0; j < intermediate_dim; j++) {
614 float up_val = gemv_fp32_row_avx2(w_up + j * embed_dim, normed, embed_dim);
619 for (
int j = 0; j < intermediate_dim; j++) {
621 const float *wu_row = w_up + j * embed_dim;
622 for (
int k = 0; k < embed_dim; k++) {
623 up_val += wu_row[k] * normed[k];
634 for (
int j = 0; j < embed_dim; j++) {
635 float sum = gemv_fp32_row_avx2(w_down + j * intermediate_dim, swiglu, intermediate_dim);
636 hidden_out[j] = sum + hidden_in[j];
639 for (
int j = 0; j < embed_dim; j++) {
641 const float *wd_row = w_down + j * intermediate_dim;
642 for (
int k = 0; k < intermediate_dim; k++) {
643 sum += wd_row[k] * swiglu[k];
645 hidden_out[j] = sum + hidden_in[j];
658 const float *hidden_in,
659 const float *rms_weight,
668 int intermediate_dim,
673 for (
int i = 0; i < embed_dim; i++) {
674 normed_buf[i] = hidden_in[i] * rms_weight[i] * rms_scale;
678 for (
int j = 0; j < intermediate_dim; j++) {
680 const float *wg_row = w_gate + j * embed_dim;
681 for (
int k = 0; k < embed_dim; k++) {
682 sum += wg_row[k] * normed_buf[k];
688 for (
int j = 0; j < intermediate_dim; j++) {
690 const float *wu_row = w_up + j * embed_dim;
691 for (
int k = 0; k < embed_dim; k++) {
692 sum += wu_row[k] * normed_buf[k];
698 for (
int j = 0; j < intermediate_dim; j++) {
699 gate_buf[j] =
silu_scalar(gate_buf[j]) * up_buf[j];
703 for (
int j = 0; j < embed_dim; j++) {
705 const float *wd_row = w_down + j * intermediate_dim;
706 for (
int k = 0; k < intermediate_dim; k++) {
707 sum += wd_row[k] * gate_buf[k];
709 hidden_out[j] = sum + hidden_in[j];
723 const float *k_cache,
724 const float *v_cache,
735 const float *residual_1,
738 const float *rms_weight,
748 int intermediate_dim,
753 const int heads_per_kv = num_heads / num_kv_heads;
754 const int q_dim = num_heads * head_dim;
755 const int kv_dim = num_kv_heads * head_dim;
758 float attn_out[4096];
759 float hidden_after_attn[4096];
763 if (embed_dim > 4096)
return;
769 memset(attn_out, 0, q_dim *
sizeof(
float));
771 for (
int h = 0; h < num_heads; h++) {
772 int kv_h = h / heads_per_kv;
773 const float *q_head = q + h * head_dim;
774 float *out_head = attn_out + h * head_dim;
777 if (seq_len > 8192)
return;
779 for (
int t = 0; t < seq_len; t++) {
780 const float *k_t = k_cache + t * kv_dim + kv_h * head_dim;
782 for (
int d = 0; d < head_dim; d++) {
783 score += q_head[d] * k_t[d];
785 scores[t] =
score * attn_scale;
790 for (
int t = 0; t < seq_len; t++) {
791 const float *v_t = v_cache + t * kv_dim + kv_h * head_dim;
793 for (
int d = 0; d < head_dim; d++) {
794 out_head[d] += w * v_t[d];
803 extern void gemv_q4_k(
float *y,
const void *W,
const float *x,
int M,
int K);
805 gemv_q4_k(hidden_after_attn, wo, attn_out, embed_dim, q_dim);
808 for (
int i = 0; i < embed_dim; i++) {
809 hidden_after_attn[i] += residual_1[i];
818 for (
int i = 0; i < embed_dim; i++) {
819 normed[i] = hidden_after_attn[i] * rms_weight[i] * rms_scale;
831 float gate_out[16384];
834 if (intermediate_dim > 16384)
return;
837 gemv_q4_k(gate_out, w_gate, normed, intermediate_dim, embed_dim);
840 gemv_q4_k(up_out, w_up, normed, intermediate_dim, embed_dim);
845 for (; i + 7 < intermediate_dim; i += 8) {
846 __m256 vg = _mm256_loadu_ps(gate_out + i);
847 __m256 vu = _mm256_loadu_ps(up_out + i);
848 __m256 vsilu = silu_avx2(vg);
849 __m256 vswiglu = _mm256_mul_ps(vsilu, vu);
850 _mm256_storeu_ps(gate_out + i, vswiglu);
852 for (; i < intermediate_dim; i++) {
853 gate_out[i] =
silu_scalar(gate_out[i]) * up_out[i];
856 for (
int i = 0; i < intermediate_dim; i++) {
857 gate_out[i] =
silu_scalar(gate_out[i]) * up_out[i];
862 gemv_q4_k(mlp_out, w_down, gate_out, embed_dim, intermediate_dim);
865 for (
int i = 0; i < embed_dim; i++) {
866 hidden_out[i] = mlp_out[i] + hidden_after_attn[i];
882 const float *k_cache,
883 const float *v_cache,
889 const float *rms_weight_mlp,
895 const float *rms_weight_attn,
901 const float *residual_in,
905 int intermediate_dim,
917 extern void gemv_q4_k(
float *y,
const void *W,
const float *x,
int M,
int K);
919 const int heads_per_kv = num_heads / num_kv_heads;
920 const int q_dim = num_heads * head_dim;
921 const int kv_dim = num_kv_heads * head_dim;
925 float attn_out[4096];
926 float hidden_after_attn[4096];
927 float normed_mlp[4096];
928 float gate_out[16384];
931 float normed_attn[4096];
933 if (embed_dim > 4096 || intermediate_dim > 16384)
return;
939 memset(attn_out, 0, q_dim *
sizeof(
float));
941 for (
int h = 0; h < num_heads; h++) {
942 int kv_h = h / heads_per_kv;
943 const float *q_head = q + h * head_dim;
944 float *out_head = attn_out + h * head_dim;
947 if (seq_len > 8192)
return;
949 for (
int t = 0; t < seq_len; t++) {
950 const float *k_t = k_cache + t * kv_dim + kv_h * head_dim;
952 for (
int d = 0; d < head_dim; d++) {
953 score += q_head[d] * k_t[d];
955 scores[t] =
score * attn_scale;
959 float max_score = scores[0];
960 for (
int t = 1; t < seq_len; t++) {
961 if (scores[t] > max_score) max_score = scores[t];
963 float sum_exp = 0.0f;
964 for (
int t = 0; t < seq_len; t++) {
965 scores[t] = expf(scores[t] - max_score);
966 sum_exp += scores[t];
968 float inv_sum = 1.0f / sum_exp;
969 for (
int t = 0; t < seq_len; t++) {
970 scores[t] *= inv_sum;
974 for (
int t = 0; t < seq_len; t++) {
975 const float *v_t = v_cache + t * kv_dim + kv_h * head_dim;
977 for (
int d = 0; d < head_dim; d++) {
978 out_head[d] += w * v_t[d];
987 gemv_q4_k(hidden_after_attn, wo, attn_out, embed_dim, q_dim);
989 for (
int i = 0; i < embed_dim; i++) {
990 hidden_after_attn[i] += residual_in[i];
998 for (
int i = 0; i < embed_dim; i++) {
999 sum_sq += hidden_after_attn[i] * hidden_after_attn[i];
1001 float rms_scale = 1.0f / sqrtf(sum_sq / embed_dim + eps);
1003 for (
int i = 0; i < embed_dim; i++) {
1004 normed_mlp[i] = hidden_after_attn[i] * rms_weight_mlp[i] * rms_scale;
1011 gemv_q4_k(gate_out, w_gate, normed_mlp, intermediate_dim, embed_dim);
1012 gemv_q4_k(up_out, w_up, normed_mlp, intermediate_dim, embed_dim);
1015 for (
int i = 0; i < intermediate_dim; i++) {
1016 float g = gate_out[i];
1017 float silu_g = g / (1.0f + expf(-g));
1018 gate_out[i] = silu_g * up_out[i];
1022 gemv_q4_k(hidden_out, w_down, gate_out, embed_dim, intermediate_dim);
1025 for (
int i = 0; i < embed_dim; i++) {
1026 hidden_out[i] += hidden_after_attn[i];
1035 for (
int i = 0; i < embed_dim; i++) {
1036 sum_sq += hidden_out[i] * hidden_out[i];
1038 rms_scale = 1.0f / sqrtf(sum_sq / embed_dim + eps);
1040 for (
int i = 0; i < embed_dim; i++) {
1041 normed_attn[i] = hidden_out[i] * rms_weight_attn[i] * rms_scale;
1051 gemv_q4_k(q_next, wq_next, normed_attn, q_dim, embed_dim);
1052 gemv_q4_k(k_next, wk_next, normed_attn, kv_dim, embed_dim);
1053 gemv_q4_k(v_next, wv_next, normed_attn, kv_dim, embed_dim);
1063 const float *q,
const float *k_cache,
const float *v_cache,
1064 int seq_len,
int num_heads,
int num_kv_heads,
int head_dim,
1066 const float *wo,
const float *residual_1,
1067 const float *rms_weight,
float eps,
1068 const float *w_gate,
const float *w_up,
const float *w_down,
1069 int embed_dim,
int intermediate_dim,
1071 float *attn_out_buf,
1072 float *hidden_after_attn_buf,
1083 const int heads_per_kv = num_heads / num_kv_heads;
1084 const int q_dim = num_heads * head_dim;
1085 const int kv_dim = num_kv_heads * head_dim;
1088 memset(attn_out_buf, 0, q_dim *
sizeof(
float));
1092 if (seq_len > 8192)
return;
1094 for (
int h = 0; h < num_heads; h++) {
1095 int kv_h = h / heads_per_kv;
1096 const float *q_head = q + h * head_dim;
1097 float *out_head = attn_out_buf + h * head_dim;
1099 for (
int t = 0; t < seq_len; t++) {
1100 const float *k_t = k_cache + t * kv_dim + kv_h * head_dim;
1102 for (
int d = 0; d < head_dim; d++) {
1103 score += q_head[d] * k_t[d];
1105 scores[t] =
score * attn_scale;
1110 for (
int t = 0; t < seq_len; t++) {
1111 const float *v_t = v_cache + t * kv_dim + kv_h * head_dim;
1112 float w = scores[t];
1113 for (
int d = 0; d < head_dim; d++) {
1114 out_head[d] += w * v_t[d];
1120 for (
int i = 0; i < embed_dim; i++) {
1122 const float *wo_row = wo + i * q_dim;
1123 for (
int j = 0; j < q_dim; j++) {
1124 sum += wo_row[j] * attn_out_buf[j];
1126 hidden_after_attn_buf[i] = sum + residual_1[i];
1131 for (
int i = 0; i < embed_dim; i++) {
1132 normed_buf[i] = hidden_after_attn_buf[i] * rms_weight[i] * rms_scale;
1136 for (
int i = 0; i < intermediate_dim; i++) {
1138 const float *wg_row = w_gate + i * embed_dim;
1139 for (
int j = 0; j < embed_dim; j++) {
1140 sum += wg_row[j] * normed_buf[j];
1146 for (
int i = 0; i < intermediate_dim; i++) {
1148 const float *wu_row = w_up + i * embed_dim;
1149 for (
int j = 0; j < embed_dim; j++) {
1150 sum += wu_row[j] * normed_buf[j];
1156 for (
int i = 0; i < intermediate_dim; i++) {
1157 gate_buf[i] =
silu_scalar(gate_buf[i]) * up_buf[i];
1161 for (
int i = 0; i < embed_dim; i++) {
1163 const float *wd_row = w_down + i * intermediate_dim;
1164 for (
int j = 0; j < intermediate_dim; j++) {
1165 sum += wd_row[j] * gate_buf[j];
1167 mlp_out_buf[i] = sum;
1171 for (
int i = 0; i < embed_dim; i++) {
1172 hidden_out[i] = mlp_out_buf[i] + hidden_after_attn_buf[i];
void attention_mlp_fused_q4k(const float *q, const float *k_cache, const float *v_cache, int seq_len, int num_heads, int num_kv_heads, int head_dim, float attn_scale, const void *wo, const float *residual_1, const float *rms_weight, float eps, const void *w_gate, const void *w_up, const void *w_down, int embed_dim, int intermediate_dim, float *hidden_out)
void mlp_fused_fp32_v2(const float *hidden_in, const float *rms_weight, float eps, const float *w_gate, const float *w_up, const float *w_down, int embed_dim, int intermediate_dim, float *hidden_out)
static float silu_scalar(float x)
void mlp_separate_fp32(const float *hidden_in, const float *rms_weight, float eps, const float *w_gate, const float *w_up, const float *w_down, float *normed_buf, float *gate_buf, float *up_buf, int embed_dim, int intermediate_dim, float *hidden_out)
static float compute_rms_scale_internal(const float *x, int n, float eps)
void mlp_fused_fp32_v3(const float *hidden_in, const float *rms_weight, float eps, const float *w_gate, const float *w_up, const float *w_down, int embed_dim, int intermediate_dim, float *hidden_out)
static void softmax_inplace(float *x, int n)
void layer_fused_attn_mlp_qkv_q4k(const float *q, const float *k_cache, const float *v_cache, int seq_len, float attn_scale, const void *wo, const float *rms_weight_mlp, const void *w_gate, const void *w_up, const void *w_down, const float *rms_weight_attn, const void *wq_next, const void *wk_next, const void *wv_next, const float *residual_in, int embed_dim, int intermediate_dim, int num_heads, int num_kv_heads, int head_dim, float eps, float *q_next, float *k_next, float *v_next, float *hidden_out)
void attention_mlp_separate_fp32(const float *q, const float *k_cache, const float *v_cache, int seq_len, int num_heads, int num_kv_heads, int head_dim, float attn_scale, const float *wo, const float *residual_1, const float *rms_weight, float eps, const float *w_gate, const float *w_up, const float *w_down, int embed_dim, int intermediate_dim, float *attn_out_buf, float *hidden_after_attn_buf, float *normed_buf, float *gate_buf, float *up_buf, float *mlp_out_buf, float *hidden_out)
void attention_mlp_fused_fp32(const float *q, const float *k_cache, const float *v_cache, int seq_len, int num_heads, int num_kv_heads, int head_dim, float attn_scale, const float *wo, const float *residual_1, const float *rms_weight, float eps, const float *w_gate, const float *w_up, const float *w_down, int embed_dim, int intermediate_dim, float *hidden_out)
void gemv_q4_k(float *y, const void *W, const float *x, int M, int K)
Auto-dispatch GEMV based on available SIMD.
Quantization block structures for weight-only quantization.