47 const void *
const input_rows[4],
54 const void *
const input_rows[4],
60 const void *weights_packed,
68 const void *source,
void *destination,
int output_dim,
int input_dim);
71 const void *packed_weight,
110 if (!y || !x || n <= 0) {
117 __m512 valpha = _mm512_set1_ps(alpha);
118 for (; i + 16 <= n; i += 16) {
119 __m512 vy = _mm512_loadu_ps(&y[i]);
120 __m512 vx = _mm512_loadu_ps(&x[i]);
121 vy = _mm512_fmadd_ps(vx, valpha, vy);
122 _mm512_storeu_ps(&y[i], vy);
127 __m256 valpha256 = _mm256_set1_ps(alpha);
128 for (; i + 8 <= n; i += 8) {
129 __m256 vy = _mm256_loadu_ps(&y[i]);
130 __m256 vx = _mm256_loadu_ps(&x[i]);
131 vy = _mm256_fmadd_ps(vx, valpha256, vy);
132 _mm256_storeu_ps(&y[i], vy);
138 y[i] += alpha * x[i];
161 if (!y || !x || n <= 0) {
168 __m512 valpha = _mm512_set1_ps(alpha);
169 for (; i + 16 <= n; i += 16) {
170 __m512 vx = _mm512_loadu_ps(&x[i]);
171 __m512 vy = _mm512_mul_ps(vx, valpha);
172 _mm512_storeu_ps(&y[i], vy);
177 __m256 valpha256 = _mm256_set1_ps(alpha);
178 for (; i + 8 <= n; i += 8) {
179 __m256 vx = _mm256_loadu_ps(&x[i]);
180 __m256 vy = _mm256_mul_ps(vx, valpha256);
181 _mm256_storeu_ps(&y[i], vy);
207 const float **vectors,
208 const float *weights,
212 if (!y || !vectors || !weights || k <= 0 || n <= 0) {
220 for (
int i = 1; i < k; i++) {
221 axpy_f32(y, vectors[i], weights[i], n);
248 memset(y, 0, n *
sizeof(
float));
280 if (!Y || !X || num_tokens <= 0 || dim <= 0) {
285 if (y_stride <= 0) y_stride = dim;
286 if (x_stride <= 0) x_stride = dim;
288 for (
int t = 0; t < num_tokens; t++) {
289 axpy_f32(Y + t * y_stride, X + t * x_stride, alpha, dim);
308 const float *expert_output,
309 float routing_weight,
312 axpy_f32(output, expert_output, routing_weight, hidden_dim);
323static inline size_t ck_moe_up_idx(
int e,
int i,
int h,
int intermediate_dim,
int hidden_dim)
325 return ((
size_t)e * (
size_t)intermediate_dim + (
size_t)i) * (size_t)hidden_dim + (
size_t)h;
328static inline size_t ck_moe_down_idx(
int e,
int h,
int i,
int hidden_dim,
int intermediate_dim)
330 return ((
size_t)e * (
size_t)hidden_dim + (
size_t)h) * (size_t)intermediate_dim + (
size_t)i;
335 const char *v = getenv(
"CK_DEBUG_MOE");
336 return v && v[0] && v[0] !=
'0';
350 for (
size_t i = 0; i < n; ++i) {
351 const float v = x[i];
354 }
else if (isinf(v)) {
358 if (!have || v < min_v) min_v = v;
359 if (!have || v > max_v) max_v = v;
364 "[CK_DEBUG_MOE] %s finite=%zu/%zu nan=%zu inf=%zu min=%g max=%g\n",
371 have ? max_v : 0.0f);
376 const float *routing_weights,
377 const float *expert_up,
378 const float *expert_down,
382 int intermediate_dim,
386 if (!hidden || !indices || !routing_weights || !expert_up || !expert_down || !output ||
387 rows <= 0 || hidden_dim <= 0 || intermediate_dim <= 0 || n_experts <= 0 || top_k <= 0) {
391 const size_t out_count = (size_t)rows * (
size_t)hidden_dim;
392 for (
size_t p = 0; p < out_count; ++p) output[p] = 0.0f;
394 float pre[intermediate_dim];
395 float gate[intermediate_dim];
396 float up[intermediate_dim];
397 float act[intermediate_dim];
399 for (
int r = 0; r < rows; ++r) {
400 const float *x = hidden + (size_t)r * (
size_t)hidden_dim;
401 float *y = output + (size_t)r * (
size_t)hidden_dim;
402 for (
int slot = 0; slot < top_k; ++slot) {
403 const int e = indices[(size_t)r * (
size_t)top_k + (size_t)slot];
404 if (e < 0 || e >= n_experts)
continue;
405 const float route_w = routing_weights[(size_t)r * (
size_t)top_k + (size_t)slot];
407 for (
int i = 0; i < intermediate_dim; ++i) {
409 for (
int h = 0; h < hidden_dim; ++h) {
410 v += expert_up[
ck_moe_up_idx(e, i, h, intermediate_dim, hidden_dim)] * x[h];
413 act[i] = (v > 0.0f) ? v * v : 0.0f;
416 for (
int h = 0; h < hidden_dim; ++h) {
418 for (
int i = 0; i < intermediate_dim; ++i) {
419 v += expert_down[
ck_moe_down_idx(e, h, i, hidden_dim, intermediate_dim)] * act[i];
431 return 1.0f / (1.0f + expf(-x));
447 return sig + x * sig * (1.0f - sig);
452 const float *routing_weights,
453 const float *expert_gate,
454 const float *expert_up,
455 const float *expert_down,
459 int intermediate_dim,
463 if (!hidden || !indices || !routing_weights || !expert_gate || !expert_up || !expert_down || !output ||
464 rows <= 0 || hidden_dim <= 0 || intermediate_dim <= 0 || n_experts <= 0 || top_k <= 0) {
468 for (
size_t p = 0; p < (size_t)rows * (
size_t)hidden_dim; ++p) output[p] = 0.0f;
470 float gate[intermediate_dim];
471 float up[intermediate_dim];
472 float act[intermediate_dim];
474 for (
int r = 0; r < rows; ++r) {
475 const float *x = hidden + (size_t)r * (
size_t)hidden_dim;
476 float *y = output + (size_t)r * (
size_t)hidden_dim;
477 for (
int slot = 0; slot < top_k; ++slot) {
478 const int e = indices[(size_t)r * (
size_t)top_k + (size_t)slot];
479 if (e < 0 || e >= n_experts)
continue;
480 const float route_w = routing_weights[(size_t)r * (
size_t)top_k + (size_t)slot];
482 for (
int i = 0; i < intermediate_dim; ++i) {
485 for (
int h = 0; h < hidden_dim; ++h) {
486 gv += expert_gate[
ck_moe_up_idx(e, i, h, intermediate_dim, hidden_dim)] * x[h];
487 uv += expert_up[
ck_moe_up_idx(e, i, h, intermediate_dim, hidden_dim)] * x[h];
494 for (
int h = 0; h < hidden_dim; ++h) {
496 for (
int i = 0; i < intermediate_dim; ++i) {
497 v += expert_down[
ck_moe_down_idx(e, h, i, hidden_dim, intermediate_dim)] * act[i];
508 const float *routing_weights,
509 const uint16_t *expert_gate,
510 const uint16_t *expert_up,
511 const uint16_t *expert_down,
515 int intermediate_dim,
521 if (!hidden || !indices || !routing_weights || !expert_gate || !expert_up || !expert_down || !output ||
522 rows <= 0 || hidden_dim <= 0 || intermediate_dim <= 0 || n_experts <= 0 || top_k <= 0 ||
523 row_begin < 0 || row_begin >= row_end || row_end > rows) {
527 float gate[intermediate_dim];
528 float up[intermediate_dim];
529 float act[intermediate_dim];
531 for (
int r = row_begin; r < row_end; ++r) {
532 const float *x = hidden + (size_t)r * (
size_t)hidden_dim;
533 float *y = output + (size_t)r * (
size_t)hidden_dim;
534 for (
int h = 0; h < hidden_dim; ++h) y[h] = 0.0f;
535 for (
int slot = 0; slot < top_k; ++slot) {
536 const int e = indices[(size_t)r * (
size_t)top_k + (size_t)slot];
537 if (e < 0 || e >= n_experts)
continue;
538 const float route_w = routing_weights[(size_t)r * (
size_t)top_k + (size_t)slot];
540 for (
int i = 0; i < intermediate_dim; ++i) {
543 for (
int h = 0; h < hidden_dim; ++h) {
552 for (
int h = 0; h < hidden_dim; ++h) {
554 for (
int i = 0; i < intermediate_dim; ++i) {
565 const float *routing_weights,
566 const uint16_t *expert_gate,
567 const uint16_t *expert_up,
568 const uint16_t *expert_down,
572 int intermediate_dim,
576 if (rows <= 0)
return;
578 hidden, indices, routing_weights, expert_gate, expert_up, expert_down,
579 output, rows, hidden_dim, intermediate_dim, n_experts, top_k, 0, rows);
585 const float *routing_weights,
586 const uint16_t *expert_gate_up,
587 const uint16_t *expert_down,
591 int intermediate_dim,
595 if (!hidden || !indices || !routing_weights || !expert_gate_up ||
596 !expert_down || !output || rows <= 0 || hidden_dim <= 0 ||
597 intermediate_dim <= 0 || n_experts <= 0 || top_k <= 0) {
601 float projection[2 * intermediate_dim];
602 float activation[intermediate_dim];
603 const size_t packed_expert_stride =
604 (size_t)2 * (
size_t)intermediate_dim * (size_t)hidden_dim;
605 const size_t packed_up_offset =
606 (size_t)intermediate_dim * (
size_t)hidden_dim;
607 for (
int row = 0; row < rows; ++row) {
608 float *y = output + (size_t)row * (
size_t)hidden_dim;
609 for (
int hidden_col = 0; hidden_col < hidden_dim; ++hidden_col) {
610 y[hidden_col] = 0.0f;
613 for (
int row = 0; row < rows; ++row) {
614 const float *x = hidden + (size_t)row * (
size_t)hidden_dim;
615 float *y = output + (size_t)row * (
size_t)hidden_dim;
616 for (
int slot = 0; slot < top_k; ++slot) {
617 const size_t route_index =
618 (size_t)row * (
size_t)top_k + (size_t)slot;
619 const int expert = indices[route_index];
620 if (expert < 0 || expert >= n_experts)
continue;
621 const uint16_t *packed =
622 expert_gate_up + (size_t)expert * packed_expert_stride;
623 const uint16_t *gate = packed;
624 const uint16_t *up = packed + packed_up_offset;
625 for (
int intermediate = 0; intermediate < intermediate_dim;
627 float gate_value = 0.0f;
628 float up_value = 0.0f;
629 const size_t row_offset =
630 (size_t)intermediate * (
size_t)hidden_dim;
631 for (
int hidden_col = 0; hidden_col < hidden_dim;
640 projection[intermediate] =
642 projection[intermediate_dim + intermediate] =
646 projection, activation, 1, intermediate_dim);
648 const float route_weight =
650 for (
int hidden_col = 0; hidden_col < hidden_dim;
653 for (
int intermediate = 0;
654 intermediate < intermediate_dim; ++intermediate) {
657 hidden_dim, intermediate_dim)]) *
658 activation[intermediate];
662 down_stored * route_weight);
663 y[hidden_col] += weighted;
666 for (
int hidden_col = 0; hidden_col < hidden_dim; ++hidden_col) {
674 return (value + 63u) & ~(size_t)63u;
678 int output_dim,
int input_dim)
680#if defined(__AVX512F__) && defined(__AVX512BW__) && defined(__AVX512DQ__)
681 if (output_dim <= 0 || input_dim <= 0 || output_dim % 16 != 0 ||
682 input_dim % 256 != 0) {
686 (
size_t)((output_dim + 7) / 8) * (
size_t)(input_dim / 256) *
698 const void *input_q8,
703#if defined(__AVX512F__) && defined(__AVX512BW__) && defined(__AVX512DQ__)
704 if (scratch && output_dim > 0 && input_dim > 0 &&
705 output_dim % 16 == 0 && input_dim % 256 == 0) {
708 input_q8, scratch, NULL, output, 1, output_dim, input_dim);
719 float *output,
const float *expert_output,
float route_weight,
int n)
721 for (
int i = 0; i < n; ++i) {
722 volatile float weighted = expert_output[i] * route_weight;
723 output[i] += weighted;
728 int intermediate_dim)
730 if (hidden_dim <= 0 || intermediate_dim <= 0 ||
731 hidden_dim % 256 != 0 || intermediate_dim % 256 != 0) {
736 bytes +=
ck_moe_align64(2u * (
size_t)intermediate_dim *
sizeof(
float));
743 int intermediate_dim)
745 if (hidden_dim <= 0 || intermediate_dim <= 0 ||
746 hidden_dim % 256 != 0 || intermediate_dim %
QK8_0 != 0) {
752 bytes +=
ck_moe_align64(2u * (
size_t)intermediate_dim *
sizeof(
float));
757 intermediate_dim, hidden_dim);
762 int hidden_dim,
int intermediate_dim)
764 enum { batch_rows = 4 };
765 if (hidden_dim <= 0 || intermediate_dim <= 0 ||
766 hidden_dim % 256 != 0 || intermediate_dim %
QK8_0 != 0) {
773 batch_rows * (
size_t)intermediate_dim *
sizeof(
float));
777 batch_rows * (
size_t)hidden_dim *
sizeof(
float));
784 const float *routing_weights,
785 const void *expert_gate,
786 const void *expert_up,
787 const void *expert_down,
791 int intermediate_dim,
795 size_t workspace_bytes)
798 hidden_dim, intermediate_dim);
799 if (!hidden || !indices || !routing_weights || !expert_gate || !expert_up ||
800 !expert_down || !output || !workspace || required == 0 ||
801 workspace_bytes < required || rows <= 0 || n_experts <= 0 ||
802 top_k <= 0 || top_k > n_experts) {
809 2u * (
size_t)intermediate_dim *
sizeof(
float));
812 uint8_t *cursor = (uint8_t *)workspace;
813 void *hidden_q8 = cursor;
814 cursor += hidden_q8_bytes;
815 float *gate_up = (
float *)cursor;
816 cursor += gate_up_bytes;
817 void *act_q8 = cursor;
818 cursor += act_q8_bytes;
819 float *expert_output = (
float *)cursor;
823 const uint8_t *gate_base = (
const uint8_t *)expert_gate;
824 const uint8_t *up_base = (
const uint8_t *)expert_up;
825 const uint8_t *down_base = (
const uint8_t *)expert_down;
827 memset(output, 0, (
size_t)rows * (
size_t)hidden_dim *
sizeof(
float));
828 for (
int row = 0; row < rows; ++row) {
829 const float *x = hidden + (size_t)row * (
size_t)hidden_dim;
830 float *y = output + (size_t)row * (
size_t)hidden_dim;
833 for (
int slot = 0; slot < top_k; ++slot) {
834 const size_t route_index = (size_t)row * (
size_t)top_k + (size_t)slot;
835 const int expert = indices[route_index];
836 if (expert < 0 || expert >= n_experts) {
840 const size_t up_expert_offset =
841 (size_t)expert * (
size_t)intermediate_dim * q4_row_bytes;
842 const size_t down_expert_offset =
843 (size_t)expert * (
size_t)hidden_dim * q5_row_bytes;
845 gate_base + up_expert_offset,
850 up_base + up_expert_offset,
857 down_base + down_expert_offset,
862 const float route_weight = routing_weights[route_index];
863 axpy_f32(y, expert_output, route_weight, hidden_dim);
872 const float *routing_weights,
873 const void *expert_gate,
874 const void *expert_up,
875 const void *expert_down,
879 int intermediate_dim,
883 size_t workspace_bytes)
886 hidden_dim, intermediate_dim);
887 if (!hidden || !indices || !routing_weights || !expert_gate ||
888 !expert_up || !expert_down || !output || !workspace || required == 0 ||
889 workspace_bytes < required || rows <= 0 || n_experts <= 0 ||
890 top_k <= 0 || top_k > n_experts) {
897 2u * (
size_t)intermediate_dim *
sizeof(
float));
900 uint8_t *cursor = (uint8_t *)workspace;
901 void *hidden_q8 = cursor;
902 cursor += hidden_q8_bytes;
903 float *gate_up = (
float *)cursor;
904 cursor += gate_up_bytes;
905 void *act_q8 = cursor;
906 cursor += act_q8_bytes;
907 float *expert_output = (
float *)cursor;
913 const uint8_t *gate_base = (
const uint8_t *)expert_gate;
914 const uint8_t *up_base = (
const uint8_t *)expert_up;
915 const uint8_t *down_base = (
const uint8_t *)expert_down;
917 memset(output, 0, (
size_t)rows * (
size_t)hidden_dim *
sizeof(
float));
918 for (
int row = 0; row < rows; ++row) {
919 const float *x = hidden + (size_t)row * (
size_t)hidden_dim;
920 float *y = output + (size_t)row * (
size_t)hidden_dim;
922 for (
int slot = 0; slot < top_k; ++slot) {
923 const size_t route_index =
924 (size_t)row * (
size_t)top_k + (size_t)slot;
925 const int expert = indices[route_index];
926 if (expert < 0 || expert >= n_experts)
return -2;
927 const size_t up_offset =
928 (size_t)expert * (
size_t)intermediate_dim * q4_row_bytes;
929 const size_t down_offset =
930 (size_t)expert * (
size_t)hidden_dim * q6_row_bytes;
932 intermediate_dim, hidden_dim);
934 up_base + up_offset, hidden_q8,
935 intermediate_dim, hidden_dim);
939 hidden_dim, intermediate_dim);
940 axpy_f32(y, expert_output, routing_weights[route_index], hidden_dim);
949 const float *routing_weights,
950 const void *expert_gate,
951 const void *expert_up,
952 const void *expert_down,
956 int intermediate_dim,
960 size_t workspace_bytes)
963 hidden_dim, intermediate_dim);
964 if (!hidden || !indices || !routing_weights || !expert_gate ||
965 !expert_up || !expert_down || !output || !workspace || required == 0 ||
966 workspace_bytes < required || rows <= 0 || n_experts <= 0 ||
967 top_k <= 0 || top_k > n_experts) {
974 2u * (
size_t)intermediate_dim *
sizeof(
float));
977 uint8_t *cursor = (uint8_t *)workspace;
978 void *hidden_q8 = cursor;
979 cursor += hidden_q8_bytes;
980 float *gate_up = (
float *)cursor;
981 cursor += gate_up_bytes;
982 void *act_q8 = cursor;
983 cursor += act_q8_bytes;
984 float *expert_output = (
float *)cursor;
986 void *projection_scratch = cursor;
992 const uint8_t *gate_base = (
const uint8_t *)expert_gate;
993 const uint8_t *up_base = (
const uint8_t *)expert_up;
994 const uint8_t *down_base = (
const uint8_t *)expert_down;
996 memset(output, 0, (
size_t)rows * (
size_t)hidden_dim *
sizeof(
float));
997 for (
int row = 0; row < rows; ++row) {
998 const float *x = hidden + (size_t)row * (
size_t)hidden_dim;
999 float *y = output + (size_t)row * (
size_t)hidden_dim;
1001 for (
int slot = 0; slot < top_k; ++slot) {
1002 const size_t route_index =
1003 (size_t)row * (
size_t)top_k + (size_t)slot;
1004 const int expert = indices[route_index];
1005 if (expert < 0 || expert >= n_experts)
return -2;
1006 const size_t gate_offset =
1007 (size_t)expert * (
size_t)intermediate_dim * gate_row_bytes;
1008 const size_t down_offset =
1009 (size_t)expert * (
size_t)hidden_dim * down_row_bytes;
1011 gate_up, gate_base + gate_offset, hidden_q8,
1012 intermediate_dim, hidden_dim, projection_scratch);
1014 gate_up + intermediate_dim, up_base + gate_offset, hidden_q8,
1015 intermediate_dim, hidden_dim, projection_scratch);
1019 hidden_dim, intermediate_dim);
1021 y, expert_output, routing_weights[route_index], hidden_dim);
1028 const float *hidden,
1030 const float *routing_weights,
1031 const void *expert_gate,
1032 const void *expert_up,
1033 const void *expert_down,
1037 int intermediate_dim,
1041 size_t workspace_bytes)
1044 hidden_dim, intermediate_dim);
1045 if (!hidden || !indices || !routing_weights || !expert_gate ||
1046 !expert_up || !expert_down || !output || !workspace || required == 0 ||
1047 workspace_bytes < required || rows <= 0 || n_experts <= 0 ||
1048 top_k <= 0 || top_k > n_experts) {
1055 2u * (
size_t)intermediate_dim *
sizeof(
float));
1058 uint8_t *cursor = (uint8_t *)workspace;
1059 void *hidden_q8 = cursor;
1060 cursor += hidden_q8_bytes;
1061 float *gate_up = (
float *)cursor;
1062 cursor += gate_up_bytes;
1063 void *act_q8 = cursor;
1064 cursor += act_q8_bytes;
1065 float *expert_output = (
float *)cursor;
1067 void *projection_scratch = cursor;
1073 const uint8_t *gate_base = (
const uint8_t *)expert_gate;
1074 const uint8_t *up_base = (
const uint8_t *)expert_up;
1075 const uint8_t *down_base = (
const uint8_t *)expert_down;
1077 memset(output, 0, (
size_t)rows * (
size_t)hidden_dim *
sizeof(
float));
1078 for (
int row = 0; row < rows; ++row) {
1079 const float *x = hidden + (size_t)row * (
size_t)hidden_dim;
1080 float *y = output + (size_t)row * (
size_t)hidden_dim;
1082 for (
int slot = 0; slot < top_k; ++slot) {
1083 const size_t route_index =
1084 (size_t)row * (
size_t)top_k + (size_t)slot;
1085 const int expert = indices[route_index];
1086 if (expert < 0 || expert >= n_experts)
return -2;
1087 const size_t gate_offset =
1088 (size_t)expert * (
size_t)intermediate_dim * gate_row_bytes;
1089 const size_t down_offset =
1090 (size_t)expert * (
size_t)hidden_dim * down_row_bytes;
1092 gate_up, gate_base + gate_offset, hidden_q8,
1093 intermediate_dim, hidden_dim, projection_scratch);
1095 gate_up + intermediate_dim, up_base + gate_offset, hidden_q8,
1096 intermediate_dim, hidden_dim, projection_scratch);
1100 hidden_dim, intermediate_dim);
1102 y, expert_output, routing_weights[route_index], hidden_dim);
1109 const float *hidden,
1111 const float *routing_weights,
1112 const void *expert_gate,
1113 const void *expert_up,
1114 const void *expert_down,
1118 int intermediate_dim,
1122 size_t workspace_bytes)
1125 hidden_dim, intermediate_dim);
1126 if (!hidden || !indices || !routing_weights || !expert_gate ||
1127 !expert_up || !expert_down || !output || !workspace || required == 0 ||
1128 workspace_bytes < required || rows <= 0 || n_experts <= 0 ||
1129 top_k <= 0 || top_k > n_experts) {
1136 2u * (
size_t)intermediate_dim *
sizeof(
float));
1139 uint8_t *cursor = (uint8_t *)workspace;
1140 void *hidden_q8 = cursor;
1141 cursor += hidden_q8_bytes;
1142 float *gate_up = (
float *)cursor;
1143 cursor += gate_up_bytes;
1144 void *act_q8 = cursor;
1145 cursor += act_q8_bytes;
1146 float *expert_output = (
float *)cursor;
1152 const uint8_t *gate_base = (
const uint8_t *)expert_gate;
1153 const uint8_t *up_base = (
const uint8_t *)expert_up;
1154 const uint8_t *down_base = (
const uint8_t *)expert_down;
1156 memset(output, 0, (
size_t)rows * (
size_t)hidden_dim *
sizeof(
float));
1157 for (
int row = 0; row < rows; ++row) {
1158 const float *x = hidden + (size_t)row * (
size_t)hidden_dim;
1159 float *y = output + (size_t)row * (
size_t)hidden_dim;
1161 for (
int slot = 0; slot < top_k; ++slot) {
1162 const size_t route_index =
1163 (size_t)row * (
size_t)top_k + (size_t)slot;
1164 const int expert = indices[route_index];
1165 if (expert < 0 || expert >= n_experts)
return -2;
1166 const size_t up_offset =
1167 (size_t)expert * (
size_t)intermediate_dim * gate_row_bytes;
1168 const size_t down_offset =
1169 (size_t)expert * (
size_t)hidden_dim * down_row_bytes;
1171 intermediate_dim, hidden_dim);
1173 up_base + up_offset, hidden_q8,
1174 intermediate_dim, hidden_dim);
1178 hidden_dim, intermediate_dim);
1179 axpy_f32(y, expert_output, routing_weights[route_index], hidden_dim);
1186 const float *hidden,
1187 const float *routed,
1188 const void *shared_gate,
1189 const void *shared_up,
1190 const void *shared_down,
1194 int intermediate_dim,
1196 size_t workspace_bytes)
1199 hidden_dim, intermediate_dim);
1200 if (!hidden || !shared_gate || !shared_up || !shared_down || !output ||
1201 !workspace || required == 0 || workspace_bytes < required || rows <= 0) {
1208 2u * (
size_t)intermediate_dim *
sizeof(
float));
1211 uint8_t *cursor = (uint8_t *)workspace;
1212 void *hidden_q8 = cursor;
1213 cursor += hidden_q8_bytes;
1214 float *gate_up = (
float *)cursor;
1215 cursor += gate_up_bytes;
1216 void *act_q8 = cursor;
1217 cursor += act_q8_bytes;
1218 float *shared_output = (
float *)cursor;
1220 for (
int row = 0; row < rows; ++row) {
1221 const float *x = hidden + (size_t)row * (
size_t)hidden_dim;
1222 float *y = output + (size_t)row * (
size_t)hidden_dim;
1225 intermediate_dim, hidden_dim);
1227 intermediate_dim, hidden_dim);
1231 hidden_dim, intermediate_dim);
1232 const float *route = routed
1233 ? routed + (size_t)row * (
size_t)hidden_dim
1235 for (
int col = 0; col < hidden_dim; ++col) {
1236 y[col] = shared_output[col] + (route ? route[col] : 0.0f);
1243 const float *hidden,
1244 const float *routed,
1245 const void *shared_gate,
1246 const void *shared_up,
1247 const void *shared_down,
1251 int intermediate_dim,
1253 size_t workspace_bytes)
1256 hidden_dim, intermediate_dim);
1257 if (!hidden || !shared_gate || !shared_up || !shared_down || !output ||
1258 !workspace || required == 0 || workspace_bytes < required || rows <= 0) {
1265 2u * (
size_t)intermediate_dim *
sizeof(
float));
1268 uint8_t *cursor = (uint8_t *)workspace;
1269 void *hidden_q8 = cursor;
1270 cursor += hidden_q8_bytes;
1271 float *gate_up = (
float *)cursor;
1272 cursor += gate_up_bytes;
1273 void *act_q8 = cursor;
1274 cursor += act_q8_bytes;
1275 float *shared_output = (
float *)cursor;
1277 for (
int row = 0; row < rows; ++row) {
1278 const float *x = hidden + (size_t)row * (
size_t)hidden_dim;
1279 float *y = output + (size_t)row * (
size_t)hidden_dim;
1282 intermediate_dim, hidden_dim);
1284 intermediate_dim, hidden_dim);
1288 hidden_dim, intermediate_dim);
1289 const float *route = routed
1290 ? routed + (size_t)row * (
size_t)hidden_dim
1292 for (
int col = 0; col < hidden_dim; ++col) {
1293 y[col] = shared_output[col] + (route ? route[col] : 0.0f);
1300 const float *hidden;
1302 const float *routing_weights;
1303 const void *expert_gate;
1304 const void *expert_up;
1305 const void *expert_down;
1309 int intermediate_dim;
1313 size_t workspace_stride;
1315} ck_moe_q4k_q5k_parallel_args_t;
1319 ck_moe_q4k_q5k_parallel_args_t *args =
1320 (ck_moe_q4k_q5k_parallel_args_t *)opaque;
1321 const int begin = (args->rows * ith) / nth;
1322 const int end = (args->rows * (ith + 1)) / nth;
1324 args->status[ith] = 0;
1328 args->hidden + (
size_t)begin * (
size_t)args->hidden_dim,
1329 args->indices + (
size_t)begin * (
size_t)args->top_k,
1330 args->routing_weights + (
size_t)begin * (
size_t)args->top_k,
1334 args->output + (
size_t)begin * (
size_t)args->hidden_dim,
1337 args->intermediate_dim,
1340 args->workspace + (
size_t)ith * args->workspace_stride,
1341 args->workspace_stride);
1346 const void *expert_gate;
1347 const void *expert_up;
1348 const void *expert_down;
1349 const void *hidden_q8;
1351 size_t workspace_stride;
1352 size_t hidden_q8_bytes;
1354 int intermediate_dim;
1359} ck_moe_q4k_q5k_route_args_t;
1363 ck_moe_q4k_q5k_route_args_t *args =
1364 (ck_moe_q4k_q5k_route_args_t *)opaque;
1365 if (ith >= nth || ith >= args->top_k)
return;
1367 const int expert = args->indices[ith];
1368 if (expert < 0 || expert >= args->n_experts) {
1369 args->status[ith] = -2;
1374 2u * (
size_t)args->intermediate_dim *
sizeof(
float));
1377 uint8_t *cursor = args->workspace + (size_t)ith * args->workspace_stride;
1378 cursor += args->hidden_q8_bytes;
1379 float *gate_up = (
float *)cursor;
1380 cursor += gate_up_bytes;
1381 void *act_q8 = cursor;
1382 cursor += act_q8_bytes;
1383 float *expert_output = (
float *)cursor;
1384 args->expert_output[ith] = expert_output;
1390 const size_t q4_expert_offset =
1391 (size_t)expert * (
size_t)args->intermediate_dim * q4_row_bytes;
1392 const size_t q5_expert_offset =
1393 (size_t)expert * (
size_t)args->hidden_dim * q5_row_bytes;
1397 (
const uint8_t *)args->expert_gate + q4_expert_offset,
1398 args->hidden_q8, args->intermediate_dim, args->hidden_dim);
1400 gate_up + args->intermediate_dim,
1401 (
const uint8_t *)args->expert_up + q4_expert_offset,
1402 args->hidden_q8, args->intermediate_dim, args->hidden_dim);
1407 (
const uint8_t *)args->expert_down + q5_expert_offset,
1408 act_q8, args->hidden_dim, args->intermediate_dim);
1409 args->status[ith] = 0;
1413 const float *hidden,
1415 const float *routing_weights,
1416 const void *expert_gate,
1417 const void *expert_up,
1418 const void *expert_down,
1421 int intermediate_dim,
1425 size_t workspace_bytes,
1426 size_t workspace_stride,
1427 ck_threadpool_t *pool)
1431 workspace_bytes < workspace_stride * (
size_t)top_k) {
1437 void *hidden_q8 = workspace;
1440 ck_moe_q4k_q5k_route_args_t args = {
1442 .expert_gate = expert_gate,
1443 .expert_up = expert_up,
1444 .expert_down = expert_down,
1445 .hidden_q8 = hidden_q8,
1446 .workspace = (uint8_t *)workspace,
1447 .workspace_stride = workspace_stride,
1448 .hidden_q8_bytes = hidden_q8_bytes,
1449 .hidden_dim = hidden_dim,
1450 .intermediate_dim = intermediate_dim,
1451 .n_experts = n_experts,
1453 .expert_output = {0},
1459 memset(output, 0, (
size_t)hidden_dim *
sizeof(
float));
1460 for (
int slot = 0; slot < top_k; ++slot) {
1461 if (args.status[slot] != 0 || !args.expert_output[slot]) {
1462 return args.status[slot] != 0 ? args.status[slot] : -1;
1465 output, args.expert_output[slot], routing_weights[slot], hidden_dim);
1471 const float *hidden,
1473 const float *routing_weights,
1474 const void *expert_gate,
1475 const void *expert_up,
1476 const void *expert_down,
1480 int intermediate_dim,
1484 size_t workspace_bytes)
1487 hidden_dim, intermediate_dim);
1488 if (!hidden || !indices || !routing_weights || !expert_gate || !expert_up ||
1489 !expert_down || !output || !workspace || stride == 0 || rows <= 0 ||
1490 n_experts <= 0 || top_k <= 0 || top_k > n_experts) {
1497 hidden, indices, routing_weights,
1498 expert_gate, expert_up, expert_down, output,
1499 hidden_dim, intermediate_dim, n_experts, top_k,
1500 workspace, workspace_bytes, stride, pool);
1501 if (route_status <= 0)
return route_status;
1505 if (active > rows) active = rows;
1507 const size_t workspace_workers = workspace_bytes / stride;
1508 if (workspace_workers == 0)
return -1;
1509 if ((
size_t)active > workspace_workers) active = (int)workspace_workers;
1512 hidden, indices, routing_weights, expert_gate, expert_up, expert_down,
1513 output, rows, hidden_dim, intermediate_dim, n_experts, top_k,
1517 ck_moe_q4k_q5k_parallel_args_t args = {
1520 .routing_weights = routing_weights,
1521 .expert_gate = expert_gate,
1522 .expert_up = expert_up,
1523 .expert_down = expert_down,
1526 .hidden_dim = hidden_dim,
1527 .intermediate_dim = intermediate_dim,
1528 .n_experts = n_experts,
1530 .workspace = (uint8_t *)workspace,
1531 .workspace_stride = stride,
1535 for (
int ith = 0; ith < active; ++ith) {
1536 if (args.status[ith] != 0)
return args.status[ith];
1542 const float *,
const int *,
const float *,
const void *,
const void *,
1543 const void *,
float *, int, int, int, int, int,
void *, size_t);
1553 const float *hidden;
1555 const float *routing_weights;
1556 const void *expert_gate;
1557 const void *expert_up;
1558 const void *expert_down;
1562 int intermediate_dim;
1566 size_t workspace_stride;
1569} ck_moe_q4k_mixed_parallel_args_t;
1573 ck_moe_q4k_mixed_parallel_args_t *args =
1574 (ck_moe_q4k_mixed_parallel_args_t *)opaque;
1575 const int begin = (args->rows * ith) / nth;
1576 const int end = (args->rows * (ith + 1)) / nth;
1578 args->status[ith] = 0;
1581 args->status[ith] = args->serial_fn(
1582 args->hidden + (
size_t)begin * (size_t)args->hidden_dim,
1583 args->indices + (
size_t)begin * (size_t)args->top_k,
1584 args->routing_weights + (
size_t)begin * (size_t)args->top_k,
1588 args->output + (
size_t)begin * (size_t)args->hidden_dim,
1591 args->intermediate_dim,
1594 args->workspace + (
size_t)ith * args->workspace_stride,
1595 args->workspace_stride);
1600 const void *expert_gate;
1601 const void *expert_up;
1602 const void *expert_down;
1603 const void *hidden_q8;
1605 size_t workspace_stride;
1606 size_t hidden_q8_bytes;
1608 int intermediate_dim;
1614} ck_moe_q4k_mixed_route_args_t;
1618 ck_moe_q4k_mixed_route_args_t *args =
1619 (ck_moe_q4k_mixed_route_args_t *)opaque;
1620 if (ith >= nth || ith >= args->top_k)
return;
1622 const int expert = args->indices[ith];
1623 if (expert < 0 || expert >= args->n_experts) {
1624 args->status[ith] = -2;
1629 2u * (
size_t)args->intermediate_dim *
sizeof(
float));
1630 const int q8_0_activation =
1635 (size_t)args->intermediate_dim));
1636 uint8_t *cursor = args->workspace + (size_t)ith * args->workspace_stride;
1637 cursor += args->hidden_q8_bytes;
1638 float *gate_up = (
float *)cursor;
1639 cursor += gate_up_bytes;
1640 void *act_q8 = cursor;
1641 cursor += act_q8_bytes;
1642 float *expert_output = (
float *)cursor;
1643 args->expert_output[ith] = expert_output;
1644 cursor +=
ck_moe_align64((
size_t)args->hidden_dim *
sizeof(
float));
1645 void *projection_scratch = cursor;
1649 const size_t gate_offset =
1650 (size_t)expert * (
size_t)args->intermediate_dim * gate_row_bytes;
1651 if (q8_0_activation) {
1653 gate_up, (
const uint8_t *)args->expert_gate + gate_offset,
1654 args->hidden_q8, args->intermediate_dim, args->hidden_dim,
1655 projection_scratch);
1657 gate_up + args->intermediate_dim,
1658 (
const uint8_t *)args->expert_up + gate_offset,
1659 args->hidden_q8, args->intermediate_dim, args->hidden_dim,
1660 projection_scratch);
1663 gate_up, (
const uint8_t *)args->expert_gate + gate_offset,
1664 args->hidden_q8, args->intermediate_dim, args->hidden_dim);
1666 gate_up + args->intermediate_dim,
1667 (
const uint8_t *)args->expert_up + gate_offset,
1668 args->hidden_q8, args->intermediate_dim, args->hidden_dim);
1671 if (q8_0_activation) {
1680 const size_t offset =
1681 (size_t)expert * (
size_t)args->hidden_dim * row_bytes;
1683 expert_output, (
const uint8_t *)args->expert_down + offset,
1684 act_q8, args->hidden_dim, args->intermediate_dim);
1688 const size_t offset =
1689 (size_t)expert * (
size_t)args->hidden_dim * row_bytes;
1691 expert_output, (
const uint8_t *)args->expert_down + offset,
1692 act_q8, args->hidden_dim, args->intermediate_dim);
1696 const size_t offset =
1697 (size_t)expert * (
size_t)args->hidden_dim * row_bytes;
1699 expert_output, (
const uint8_t *)args->expert_down + offset,
1700 act_q8, args->hidden_dim, args->intermediate_dim);
1704 const size_t offset =
1705 (size_t)expert * (
size_t)args->hidden_dim * row_bytes;
1707 expert_output, (
const uint8_t *)args->expert_down + offset,
1708 act_q8, args->hidden_dim, args->intermediate_dim);
1710 args->status[ith] = 0;
1714 const float *hidden,
1716 const float *routing_weights,
1717 const void *expert_gate,
1718 const void *expert_up,
1719 const void *expert_down,
1722 int intermediate_dim,
1726 size_t workspace_bytes,
1727 size_t workspace_stride,
1728 ck_threadpool_t *pool,
1733 workspace_bytes < workspace_stride * (
size_t)top_k) {
1739 void *hidden_q8 = workspace;
1742 ck_moe_q4k_mixed_route_args_t args = {
1744 .expert_gate = expert_gate,
1745 .expert_up = expert_up,
1746 .expert_down = expert_down,
1747 .hidden_q8 = hidden_q8,
1748 .workspace = (uint8_t *)workspace,
1749 .workspace_stride = workspace_stride,
1750 .hidden_q8_bytes = hidden_q8_bytes,
1751 .hidden_dim = hidden_dim,
1752 .intermediate_dim = intermediate_dim,
1753 .n_experts = n_experts,
1755 .down_kind = down_kind,
1756 .expert_output = {0},
1762 memset(output, 0, (
size_t)hidden_dim *
sizeof(
float));
1763 for (
int slot = 0; slot < top_k; ++slot) {
1764 if (args.status[slot] != 0 || !args.expert_output[slot]) {
1765 return args.status[slot] != 0 ? args.status[slot] : -1;
1770 output, args.expert_output[slot], routing_weights[slot],
1774 output, args.expert_output[slot], routing_weights[slot],
1782 const float *hidden,
1784 const float *routing_weights,
1785 const void *expert_gate,
1786 const void *expert_up,
1787 const void *expert_down,
1791 int intermediate_dim,
1795 size_t workspace_bytes,
1799 const int q8_0_activation =
1801 const size_t stride = q8_0_activation
1804 if (!hidden || !indices || !routing_weights || !expert_gate || !expert_up ||
1805 !expert_down || !output || !workspace || !serial_fn || stride == 0 ||
1806 rows <= 0 || n_experts <= 0 || top_k <= 0 || top_k > n_experts) {
1813 hidden, indices, routing_weights, expert_gate, expert_up,
1814 expert_down, output, hidden_dim, intermediate_dim, n_experts,
1815 top_k, workspace, workspace_bytes, stride, pool, down_kind);
1816 if (route_status <= 0)
return route_status;
1820 if (active > rows) active = rows;
1822 const size_t workspace_workers = workspace_bytes / stride;
1823 if (workspace_workers == 0)
return -1;
1824 if ((
size_t)active > workspace_workers) active = (int)workspace_workers;
1827 hidden, indices, routing_weights, expert_gate, expert_up,
1828 expert_down, output, rows, hidden_dim, intermediate_dim, n_experts,
1829 top_k, workspace, stride);
1832 ck_moe_q4k_mixed_parallel_args_t args = {
1835 .routing_weights = routing_weights,
1836 .expert_gate = expert_gate,
1837 .expert_up = expert_up,
1838 .expert_down = expert_down,
1841 .hidden_dim = hidden_dim,
1842 .intermediate_dim = intermediate_dim,
1843 .n_experts = n_experts,
1845 .workspace = (uint8_t *)workspace,
1846 .workspace_stride = stride,
1847 .serial_fn = serial_fn,
1852 for (
int ith = 0; ith < active; ++ith) {
1853 if (args.status[ith] != 0)
return args.status[ith];
1859 const float *hidden,
1861 const float *routing_weights,
1862 const void *expert_gate,
1863 const void *expert_up,
1864 const void *expert_down,
1868 int intermediate_dim,
1872 size_t workspace_bytes)
1875 hidden, indices, routing_weights, expert_gate, expert_up, expert_down,
1876 output, rows, hidden_dim, intermediate_dim, n_experts, top_k,
1877 workspace, workspace_bytes,
1882 const float *hidden,
1884 const float *routing_weights,
1885 const void *expert_gate,
1886 const void *expert_up,
1887 const void *expert_down,
1891 int intermediate_dim,
1895 size_t workspace_bytes)
1898 hidden, indices, routing_weights, expert_gate, expert_up, expert_down,
1899 output, rows, hidden_dim, intermediate_dim, n_experts, top_k,
1900 workspace, workspace_bytes,
1905 const float *hidden,
1907 const float *routing_weights,
1908 const void *expert_gate,
1909 const void *expert_up,
1910 const void *expert_down,
1914 int intermediate_dim,
1918 size_t workspace_bytes)
1921 hidden, indices, routing_weights, expert_gate, expert_up, expert_down,
1922 output, rows, hidden_dim, intermediate_dim, n_experts, top_k,
1923 workspace, workspace_bytes,
1928 const float *hidden,
1930 const float *routing_weights,
1931 const void *expert_gate,
1932 const void *expert_up,
1933 const void *expert_down,
1937 int intermediate_dim,
1941 size_t workspace_bytes)
1944 hidden, indices, routing_weights, expert_gate, expert_up, expert_down,
1945 output, rows, hidden_dim, intermediate_dim, n_experts, top_k,
1946 workspace, workspace_bytes,
1951 const float *,
const float *,
const void *,
const void *,
const void *,
1952 float *, int, int, int,
void *, size_t);
1955 const float *hidden;
1956 const float *routed;
1957 const void *shared_gate;
1958 const void *shared_up;
1959 const void *shared_down;
1963 int intermediate_dim;
1965 size_t workspace_stride;
1968} ck_moe_shared_q4k_parallel_args_t;
1972 ck_moe_shared_q4k_parallel_args_t *args =
1973 (ck_moe_shared_q4k_parallel_args_t *)opaque;
1974 const int begin = (args->rows * ith) / nth;
1975 const int end = (args->rows * (ith + 1)) / nth;
1977 args->status[ith] = 0;
1980 args->status[ith] = args->serial_fn(
1981 args->hidden + (
size_t)begin * (size_t)args->hidden_dim,
1983 ? args->routed + (
size_t)begin * (size_t)args->hidden_dim
1988 args->output + (size_t)begin * (
size_t)args->hidden_dim,
1991 args->intermediate_dim,
1992 args->workspace + (size_t)ith * args->workspace_stride,
1993 args->workspace_stride);
1997 const float *hidden,
1998 const float *routed,
1999 const void *shared_gate,
2000 const void *shared_up,
2001 const void *shared_down,
2005 int intermediate_dim,
2007 size_t workspace_bytes,
2011 hidden_dim, intermediate_dim);
2012 if (!hidden || !shared_gate || !shared_up || !shared_down || !output ||
2013 !workspace || !serial_fn || stride == 0 || rows <= 0) {
2018 if (active > rows) active = rows;
2020 const size_t workspace_workers = workspace_bytes / stride;
2021 if (workspace_workers == 0)
return -1;
2022 if ((
size_t)active > workspace_workers) active = (int)workspace_workers;
2025 hidden, routed, shared_gate, shared_up, shared_down, output, rows,
2026 hidden_dim, intermediate_dim, workspace, stride);
2029 ck_moe_shared_q4k_parallel_args_t args = {
2032 .shared_gate = shared_gate,
2033 .shared_up = shared_up,
2034 .shared_down = shared_down,
2037 .hidden_dim = hidden_dim,
2038 .intermediate_dim = intermediate_dim,
2039 .workspace = (uint8_t *)workspace,
2040 .workspace_stride = stride,
2041 .serial_fn = serial_fn,
2046 for (
int ith = 0; ith < active; ++ith) {
2047 if (args.status[ith] != 0)
return args.status[ith];
2053 const float *hidden,
2054 const float *routed,
2055 const void *shared_gate,
2056 const void *shared_up,
2057 const void *shared_down,
2061 int intermediate_dim,
2063 size_t workspace_bytes)
2066 hidden, routed, shared_gate, shared_up, shared_down, output, rows,
2067 hidden_dim, intermediate_dim, workspace, workspace_bytes,
2072 const float *hidden,
2073 const float *routed,
2074 const void *shared_gate,
2075 const void *shared_up,
2076 const void *shared_down,
2080 int intermediate_dim,
2082 size_t workspace_bytes)
2085 hidden, routed, shared_gate, shared_up, shared_down, output, rows,
2086 hidden_dim, intermediate_dim, workspace, workspace_bytes,
2091 size_t hidden_q8_offset;
2092 size_t route_rows_offset;
2093 size_t slot_offsets_offset;
2094 size_t counts_offset;
2095 size_t cursors_offset;
2096 size_t workers_offset;
2097 size_t hidden_q8_row_bytes;
2098 size_t worker_stride;
2100} ck_moe_q4k_q5k_bucket_layout_t;
2104 if (!result || a > SIZE_MAX - b)
return -1;
2111 if (!result || (a != 0 && b > SIZE_MAX / a))
return -1;
2118 int intermediate_dim,
2121 ck_moe_q4k_q5k_bucket_layout_t *layout)
2123 if (!layout || rows <= 0 || hidden_dim <= 0 || intermediate_dim <= 0 ||
2124 n_experts <= 0 || top_k <= 0 || top_k > n_experts ||
2125 hidden_dim % 256 != 0 || intermediate_dim % 256 != 0) {
2129 memset(layout, 0,
sizeof(*layout));
2133 size_t gate_up_bytes = 0;
2134 size_t worker_bytes = 0;
2136 &gate_up_bytes) != 0) {
2144 &worker_bytes) != 0 ||
2149 &worker_bytes) != 0 ||
2153 &worker_bytes) != 0) {
2156 layout->worker_stride = worker_bytes;
2160 layout->hidden_q8_offset = cursor;
2161 if (
ck_moe_size_mul((
size_t)rows, layout->hidden_q8_row_bytes, &bytes) != 0 ||
2166 layout->route_rows_offset = cursor;
2173 layout->slot_offsets_offset = cursor;
2174 if (
ck_moe_size_mul((
size_t)top_k, (
size_t)n_experts + 1u, &bytes) != 0 ||
2180 layout->counts_offset = cursor;
2186 layout->cursors_offset = cursor;
2192 layout->workers_offset = cursor;
2194 layout->worker_stride, &bytes) != 0 ||
2198 layout->total_bytes = cursor;
2205 int intermediate_dim,
2209 ck_moe_q4k_q5k_bucket_layout_t layout;
2211 top_k, &layout) != 0) {
2214 return layout.total_bytes;
2218 const float *hidden;
2222 size_t hidden_q8_row_bytes;
2223} ck_moe_q4k_q5k_quantize_args_t;
2227 ck_moe_q4k_q5k_quantize_args_t *args =
2228 (ck_moe_q4k_q5k_quantize_args_t *)opaque;
2229 const int begin = (args->rows * ith) / nth;
2230 const int end = (args->rows * (ith + 1)) / nth;
2231 for (
int row = begin; row <
end; ++row) {
2233 args->hidden + (
size_t)row * (
size_t)args->hidden_dim,
2234 args->hidden_q8 + (
size_t)row * args->hidden_q8_row_bytes,
2240 const int *bucket_rows;
2241 const int *bucket_offsets;
2242 const float *routing_weights;
2243 const uint8_t *hidden_q8;
2244 const uint8_t *gate_base;
2245 const uint8_t *up_base;
2246 const uint8_t *gate_packed_base;
2247 const uint8_t *up_packed_base;
2248 const uint8_t *down_base;
2251 size_t worker_stride;
2252 size_t hidden_q8_row_bytes;
2253 size_t q4_expert_stride;
2254 size_t q4_packed_expert_stride;
2255 size_t q5_expert_stride;
2257 int intermediate_dim;
2262 atomic_int next_task;
2263} ck_moe_q4k_q5k_bucket_work_t;
2274 const int mid = lo + (hi - lo) / 2;
2275 if (
offsets[mid + 1] <= position) {
2287 ck_moe_q4k_q5k_bucket_work_t *args =
2288 (ck_moe_q4k_q5k_bucket_work_t *)opaque;
2289 uint8_t *cursor = args->workers + (size_t)ith * args->worker_stride;
2290 float *gate_up = (
float *)cursor;
2292 8u * (
size_t)args->intermediate_dim *
sizeof(
float));
2293 uint8_t *hidden_q8_batch = cursor;
2297 void *act_q8 = cursor;
2300 float *expert_output = (
float *)cursor;
2305 const int task = atomic_fetch_add_explicit(
2306 &args->next_task, 1, memory_order_relaxed);
2307 if (task >= args->total_tasks)
break;
2311 args->bucket_offsets[args->n_experts]
2313 : args->bucket_offsets[args->n_experts];
2315 args->bucket_offsets, args->n_experts, position);
2317 while (position < task_end && expert < args->n_experts) {
2318 const int expert_end = args->bucket_offsets[expert + 1];
2319 const int segment_end = expert_end < task_end
2320 ? expert_end : task_end;
2321 const uint8_t *gate = args->gate_base +
2322 (size_t)expert * args->q4_expert_stride;
2323 const uint8_t *up = args->up_base +
2324 (size_t)expert * args->q4_expert_stride;
2325 const uint8_t *gate_packed = args->gate_packed_base
2326 ? args->gate_packed_base +
2327 (size_t)expert * args->q4_packed_expert_stride
2329 const uint8_t *up_packed = args->up_packed_base
2330 ? args->up_packed_base +
2331 (size_t)expert * args->q4_packed_expert_stride
2333 const uint8_t *down = args->down_base +
2334 (size_t)expert * args->q5_expert_stride;
2336 for (
int i = position; i < segment_end; i += 4) {
2337 const int batch_rows = segment_end - i < 4
2338 ? segment_end - i : 4;
2339 const void *hidden_rows[4] = {NULL, NULL, NULL, NULL};
2340 const void *activation_rows[4] = {NULL, NULL, NULL, NULL};
2341 int output_rows[4] = {0, 0, 0, 0};
2342 for (
int batch_row = 0; batch_row < batch_rows; ++batch_row) {
2343 const int row = args->bucket_rows[i + batch_row];
2344 output_rows[batch_row] = row;
2345 hidden_rows[batch_row] = args->hidden_q8 +
2346 (size_t)row * args->hidden_q8_row_bytes;
2347 if (gate_packed && up_packed) {
2350 (
size_t)batch_row * hidden_q8_batch_row_bytes,
2351 hidden_rows[batch_row],
2352 args->hidden_q8_row_bytes);
2355 for (
int batch_row = batch_rows; batch_row < 4; ++batch_row) {
2356 hidden_rows[batch_row] = hidden_rows[0];
2359 if (gate_packed && up_packed) {
2360 float *up_rows = gate_up +
2361 4u * (size_t)args->intermediate_dim;
2363 gate_up, gate_packed, hidden_q8_batch,
2364 batch_rows, args->intermediate_dim,
2367 up_rows, up_packed, hidden_q8_batch,
2368 batch_rows, args->intermediate_dim,
2371 gate_up, up_rows, gate_up, batch_rows,
2372 args->intermediate_dim);
2374 const int gate_up_stride = 2 * args->intermediate_dim;
2376 gate_up, gate_up_stride, gate, hidden_rows, batch_rows,
2377 args->intermediate_dim, args->hidden_dim);
2379 gate_up + args->intermediate_dim, gate_up_stride, up,
2380 hidden_rows, batch_rows,
2381 args->intermediate_dim, args->hidden_dim);
2383 gate_up, gate_up, batch_rows, args->intermediate_dim);
2385 for (
int batch_row = 0; batch_row < batch_rows; ++batch_row) {
2386 void *activation = (uint8_t *)act_q8 +
2387 (
size_t)batch_row * act_q8_row_bytes;
2389 gate_up + (
size_t)batch_row *
2390 (
size_t)args->intermediate_dim,
2391 activation, args->intermediate_dim);
2392 activation_rows[batch_row] = activation;
2394 for (
int batch_row = batch_rows; batch_row < 4; ++batch_row) {
2395 activation_rows[batch_row] = activation_rows[0];
2398 expert_output, args->hidden_dim, down, activation_rows,
2399 batch_rows, args->hidden_dim, args->intermediate_dim);
2401 for (
int batch_row = 0; batch_row < batch_rows; ++batch_row) {
2402 const int row = output_rows[batch_row];
2403 const size_t route_index = (size_t)row *
2404 (
size_t)args->top_k + (size_t)args->slot;
2406 args->output + (
size_t)row *
2407 (
size_t)args->hidden_dim,
2408 expert_output + (
size_t)batch_row *
2409 (
size_t)args->hidden_dim,
2410 args->routing_weights[route_index], args->hidden_dim);
2413 position = segment_end;
2420 const float *hidden,
2422 const float *routing_weights,
2423 const void *expert_gate,
2424 const void *expert_up,
2425 const void *expert_down,
2426 const void *expert_gate_packed,
2427 const void *expert_up_packed,
2431 int intermediate_dim,
2435 size_t workspace_bytes)
2437 ck_moe_q4k_q5k_bucket_layout_t layout;
2438 if (!hidden || !indices || !routing_weights || !expert_gate || !expert_up ||
2439 !expert_down || !output || !workspace ||
2440 ((expert_gate_packed == NULL) != (expert_up_packed == NULL)) ||
2442 top_k, &layout) != 0 ||
2443 workspace_bytes < layout.total_bytes) {
2447 uint8_t *base = (uint8_t *)workspace;
2448 uint8_t *hidden_q8 = base + layout.hidden_q8_offset;
2449 int *route_rows = (
int *)(base + layout.route_rows_offset);
2450 int *slot_offsets = (
int *)(base + layout.slot_offsets_offset);
2451 int *counts = (
int *)(base + layout.counts_offset);
2452 int *cursors = (
int *)(base + layout.cursors_offset);
2453 uint8_t *workers = base + layout.workers_offset;
2455 for (
int slot = 0; slot < top_k; ++slot) {
2456 memset(counts, 0, (
size_t)n_experts *
sizeof(*counts));
2457 for (
int row = 0; row < rows; ++row) {
2458 const int expert = indices[(size_t)row * (
size_t)top_k +
2460 if (expert < 0 || expert >= n_experts)
return -2;
2461 counts[expert] += 1;
2464 int *
offsets = slot_offsets + (size_t)slot * ((
size_t)n_experts + 1u);
2466 for (
int expert = 0; expert < n_experts; ++expert) {
2468 cursors[expert] =
offsets[expert];
2470 int *rows_for_slot = route_rows + (size_t)slot * (
size_t)rows;
2471 for (
int row = 0; row < rows; ++row) {
2472 const int expert = indices[(size_t)row * (
size_t)top_k +
2474 rows_for_slot[cursors[expert]++] = row;
2478 memset(output, 0, (
size_t)rows * (
size_t)hidden_dim *
sizeof(
float));
2481 if (active > rows) active = rows;
2483 if (active < 1) active = 1;
2485 ck_moe_q4k_q5k_quantize_args_t quantize_args = {
2487 .hidden_q8 = hidden_q8,
2489 .hidden_dim = hidden_dim,
2490 .hidden_q8_row_bytes = layout.hidden_q8_row_bytes,
2492 if (active > 1 && pool) {
2499 const size_t q4_expert_stride = (size_t)intermediate_dim *
2501 const size_t q4_packed_expert_stride =
2502 (size_t)((intermediate_dim + 7) / 8) *
2504 const size_t q5_expert_stride = (size_t)hidden_dim *
2506 for (
int slot = 0; slot < top_k; ++slot) {
2507 ck_moe_q4k_q5k_bucket_work_t args = {
2508 .bucket_rows = route_rows + (size_t)slot * (
size_t)rows,
2509 .bucket_offsets = slot_offsets +
2510 (size_t)slot * ((
size_t)n_experts + 1u),
2511 .routing_weights = routing_weights,
2512 .hidden_q8 = hidden_q8,
2513 .gate_base = (
const uint8_t *)expert_gate,
2514 .up_base = (
const uint8_t *)expert_up,
2515 .gate_packed_base = (
const uint8_t *)expert_gate_packed,
2516 .up_packed_base = (
const uint8_t *)expert_up_packed,
2517 .down_base = (
const uint8_t *)expert_down,
2520 .worker_stride = layout.worker_stride,
2521 .hidden_q8_row_bytes = layout.hidden_q8_row_bytes,
2522 .q4_expert_stride = q4_expert_stride,
2523 .q4_packed_expert_stride = q4_packed_expert_stride,
2524 .q5_expert_stride = q5_expert_stride,
2525 .hidden_dim = hidden_dim,
2526 .intermediate_dim = intermediate_dim,
2527 .n_experts = n_experts,
2533 atomic_init(&args.next_task, 0);
2534 int task_threads = active;
2535 if (task_threads > args.total_tasks) task_threads = args.total_tasks;
2536 if (active > 1 && pool) {
2547 const float *hidden,
2549 const float *routing_weights,
2550 const void *expert_gate,
2551 const void *expert_up,
2552 const void *expert_down,
2556 int intermediate_dim,
2560 size_t workspace_bytes)
2563 hidden, indices, routing_weights,
2564 expert_gate, expert_up, expert_down, NULL, NULL, output,
2565 rows, hidden_dim, intermediate_dim, n_experts, top_k,
2566 workspace, workspace_bytes);
2570 const float *hidden,
2572 const float *routing_weights,
2573 const void *expert_gate,
2574 const void *expert_up,
2575 const void *expert_down,
2576 const void *expert_gate_packed,
2577 const void *expert_up_packed,
2581 int intermediate_dim,
2585 size_t workspace_bytes)
2588 hidden, indices, routing_weights,
2589 expert_gate, expert_up, expert_down,
2590 expert_gate_packed, expert_up_packed, output,
2591 rows, hidden_dim, intermediate_dim, n_experts, top_k,
2592 workspace, workspace_bytes);
2596 const float *hidden,
2598 const float *routing_weights,
2599 const void *expert_gate,
2600 const void *expert_up,
2601 const void *expert_down,
2605 int intermediate_dim,
2609 size_t workspace_bytes)
2613 hidden, indices, routing_weights,
2614 expert_gate, expert_up, expert_down, output,
2615 rows, hidden_dim, intermediate_dim, n_experts, top_k,
2616 workspace, workspace_bytes);
2619 hidden, indices, routing_weights,
2620 expert_gate, expert_up, expert_down, output,
2621 rows, hidden_dim, intermediate_dim, n_experts, top_k,
2622 workspace, workspace_bytes);
2626 int intermediate_dim)
2628 if (hidden_dim <= 0 || intermediate_dim <= 0 ||
2629 hidden_dim % 32 != 0 || intermediate_dim % 32 != 0) {
2635 bytes +=
ck_moe_align64(2u * (
size_t)intermediate_dim *
sizeof(
float));
2643 const float *hidden,
2644 const float *routed,
2645 const void *shared_gate,
2646 const void *shared_up,
2647 const void *shared_down,
2648 const float *shared_gate_input,
2652 int intermediate_dim,
2654 size_t workspace_bytes)
2657 hidden_dim, intermediate_dim);
2658 if (!hidden || !shared_gate || !shared_up || !shared_down ||
2659 !shared_gate_input || !output || !workspace || required == 0 ||
2660 workspace_bytes < required || rows <= 0) {
2667 2u * (
size_t)intermediate_dim *
sizeof(
float));
2670 uint8_t *cursor = (uint8_t *)workspace;
2671 void *hidden_q8 = cursor;
2672 cursor += hidden_q8_bytes;
2673 float *gate_up = (
float *)cursor;
2674 cursor += gate_up_bytes;
2675 void *activation_q8 = cursor;
2676 cursor += activation_q8_bytes;
2677 float *shared_output = (
float *)cursor;
2679 for (
int row = 0; row < rows; ++row) {
2680 const float *x = hidden + (size_t)row * (
size_t)hidden_dim;
2681 const float *routed_row = routed
2682 ? routed + (size_t)row * (
size_t)hidden_dim
2684 float *output_row = output + (size_t)row * (
size_t)hidden_dim;
2688 intermediate_dim, hidden_dim);
2690 intermediate_dim, hidden_dim);
2694 hidden_dim, intermediate_dim);
2696 float gate_value = 0.0f;
2698 x, shared_gate_input, NULL, &gate_value, 1, 1, hidden_dim);
2699 const float gate_scale = 1.0f / (1.0f + expf(-gate_value));
2700 for (
int h = 0; h < hidden_dim; ++h) {
2701 const float routed_value = routed_row ? routed_row[h] : 0.0f;
2702 volatile float gated_shared = shared_output[h] * gate_scale;
2703 output_row[h] = routed_value + gated_shared;
2710 const float *hidden,
2711 const float *routed,
2712 const void *shared_gate,
2713 const void *shared_up,
2714 const void *shared_down,
2715 const float *shared_gate_input,
2719 int intermediate_dim,
2721 size_t workspace_bytes,
2722 void (*down_projection)(
float *,
const void *,
const void *,
int,
int))
2725 hidden_dim, intermediate_dim);
2726 if (!hidden || !shared_gate || !shared_up || !shared_down ||
2727 !shared_gate_input || !output || !workspace || required == 0 ||
2728 workspace_bytes < required || rows <= 0) {
2732 enum { CK_SHARED_Q4K_BATCH_ROWS = 4 };
2733 const size_t hidden_q8_stride =
2735 const size_t activation_q8_stride =
2738 CK_SHARED_Q4K_BATCH_ROWS * hidden_q8_stride);
2740 CK_SHARED_Q4K_BATCH_ROWS * (
size_t)intermediate_dim *
sizeof(
float));
2742 CK_SHARED_Q4K_BATCH_ROWS * activation_q8_stride);
2743 uint8_t *cursor = (uint8_t *)workspace;
2744 void *hidden_q8 = cursor;
2745 cursor += hidden_q8_bytes;
2746 float *gate_values = (
float *)cursor;
2747 cursor += projection_bytes;
2748 float *up_values = (
float *)cursor;
2749 cursor += projection_bytes;
2750 void *activation_q8 = cursor;
2751 cursor += activation_q8_bytes;
2752 float *shared_output = (
float *)cursor;
2758 for (
int row0 = 0; row0 < rows; row0 += CK_SHARED_Q4K_BATCH_ROWS) {
2759 int batch_rows = rows - row0;
2760 if (batch_rows > CK_SHARED_Q4K_BATCH_ROWS) {
2761 batch_rows = CK_SHARED_Q4K_BATCH_ROWS;
2763 for (
int local_row = 0; local_row < batch_rows; ++local_row) {
2764 const float *x = hidden +
2765 (size_t)(row0 + local_row) * (size_t)hidden_dim;
2768 (uint8_t *)hidden_q8 +
2769 (
size_t)local_row * hidden_q8_stride,
2773 hidden_q8, shared_gate, NULL, gate_values,
2774 batch_rows, intermediate_dim, hidden_dim);
2776 hidden_q8, shared_up, NULL, up_values,
2777 batch_rows, intermediate_dim, hidden_dim);
2779 gate_values, up_values, gate_values, batch_rows, intermediate_dim);
2781 for (
int local_row = 0; local_row < batch_rows; ++local_row) {
2782 const int row = row0 + local_row;
2783 const float *x = hidden + (size_t)row * (
size_t)hidden_dim;
2784 const float *routed_row = routed
2785 ? routed + (size_t)row * (
size_t)hidden_dim
2787 float *output_row = output + (size_t)row * (
size_t)hidden_dim;
2788 void *activation_q8_row = (uint8_t *)activation_q8 +
2789 (
size_t)local_row * activation_q8_stride;
2790 float *shared_output_row = shared_output +
2791 (size_t)local_row * (
size_t)hidden_dim;
2794 gate_values + (
size_t)local_row * (
size_t)intermediate_dim,
2795 activation_q8_row, intermediate_dim);
2797 shared_output_row, shared_down, activation_q8_row,
2798 hidden_dim, intermediate_dim);
2800 float gate_value = 0.0f;
2802 x, shared_gate_input, NULL, &gate_value, 1, 1, hidden_dim);
2803 const float gate_scale = 1.0f / (1.0f + expf(-gate_value));
2804 for (
int h = 0; h < hidden_dim; ++h) {
2805 const float routed_value = routed_row ? routed_row[h] : 0.0f;
2806 volatile float gated_shared =
2807 shared_output_row[h] * gate_scale;
2808 output_row[h] = routed_value + gated_shared;
2816 const float *hidden,
const float *routed,
2817 const void *shared_gate,
const void *shared_up,
const void *shared_down,
2818 const float *shared_gate_input,
float *output,
2819 int rows,
int hidden_dim,
int intermediate_dim,
2820 void *workspace,
size_t workspace_bytes)
2823 hidden, routed, shared_gate, shared_up, shared_down, shared_gate_input,
2824 output, rows, hidden_dim, intermediate_dim, workspace, workspace_bytes,
2829 const float *hidden,
2830 const float *routed,
2831 const void *shared_gate,
2832 const void *shared_up,
2833 const void *shared_down,
2834 const float *shared_gate_input,
2838 int intermediate_dim,
2840 size_t workspace_bytes)
2843 hidden, routed, shared_gate, shared_up, shared_down, shared_gate_input,
2844 output, rows, hidden_dim, intermediate_dim, workspace, workspace_bytes,
2849 const float *,
const float *,
const void *,
const void *,
const void *,
2850 const float *,
float *, int, int, int,
void *, size_t);
2853 const float *hidden;
2854 const float *routed;
2855 const void *shared_gate;
2856 const void *shared_up;
2857 const void *shared_down;
2858 const float *shared_gate_input;
2862 int intermediate_dim;
2864 size_t workspace_stride;
2867} ck_moe_shared_q8_0_parallel_args_t;
2871 ck_moe_shared_q8_0_parallel_args_t *args =
2872 (ck_moe_shared_q8_0_parallel_args_t *)opaque;
2873 const int begin = (args->rows * ith) / nth;
2874 const int end = (args->rows * (ith + 1)) / nth;
2876 args->status[ith] = 0;
2880 args->status[ith] = args->serial_fn(
2881 args->hidden + (
size_t)begin * (size_t)args->hidden_dim,
2883 ? args->routed + (
size_t)begin * (size_t)args->hidden_dim
2888 args->shared_gate_input,
2889 args->output + (size_t)begin * (
size_t)args->hidden_dim,
2892 args->intermediate_dim,
2893 args->workspace + (size_t)ith * args->workspace_stride,
2894 args->workspace_stride);
2898 const float *hidden,
2899 const float *routed,
2900 const void *shared_gate,
2901 const void *shared_up,
2902 const void *shared_down,
2903 const float *shared_gate_input,
2907 int intermediate_dim,
2909 size_t workspace_bytes,
2913 if (!hidden || !shared_gate || !shared_up || !shared_down ||
2914 !shared_gate_input || !output || !workspace || !serial_fn ||
2915 stride == 0 || rows <= 0) {
2921 if (active > rows) active = rows;
2923 const size_t workspace_workers = workspace_bytes / stride;
2924 if (workspace_workers == 0)
return -1;
2925 if ((
size_t)active > workspace_workers) active = (int)workspace_workers;
2928 hidden, routed, shared_gate, shared_up, shared_down,
2929 shared_gate_input, output, rows, hidden_dim, intermediate_dim,
2933 ck_moe_shared_q8_0_parallel_args_t args = {
2936 .shared_gate = shared_gate,
2937 .shared_up = shared_up,
2938 .shared_down = shared_down,
2939 .shared_gate_input = shared_gate_input,
2942 .hidden_dim = hidden_dim,
2943 .intermediate_dim = intermediate_dim,
2944 .workspace = (uint8_t *)workspace,
2945 .workspace_stride = stride,
2946 .serial_fn = serial_fn,
2951 for (
int ith = 0; ith < active; ++ith) {
2952 if (args.status[ith] != 0)
return args.status[ith];
2958 const float *hidden,
2959 const float *routed,
2960 const void *shared_gate,
2961 const void *shared_up,
2962 const void *shared_down,
2963 const float *shared_gate_input,
2967 int intermediate_dim,
2969 size_t workspace_bytes)
2972 hidden, routed, shared_gate, shared_up, shared_down, shared_gate_input,
2973 output, rows, hidden_dim, intermediate_dim, workspace, workspace_bytes,
2979 const float *hidden,
2980 const float *routed,
2981 const void *shared_gate,
2982 const void *shared_up,
2983 const void *shared_down,
2984 const float *shared_gate_input,
2988 int intermediate_dim,
2990 size_t workspace_bytes)
2995 hidden, routed, shared_gate, shared_up, shared_down, shared_gate_input,
2996 output, rows, hidden_dim, intermediate_dim, workspace, workspace_bytes);
3000 const float *hidden,
3001 const float *routed,
3002 const void *shared_gate,
3003 const void *shared_up,
3004 const void *shared_down,
3005 const float *shared_gate_input,
3009 int intermediate_dim,
3011 size_t workspace_bytes)
3016 hidden, routed, shared_gate, shared_up, shared_down, shared_gate_input,
3017 output, rows, hidden_dim, intermediate_dim, workspace, workspace_bytes);
3021 const float *hidden,
3023 const float *routing_weights,
3024 const float *expert_gate,
3025 const float *expert_up,
3026 const float *expert_down,
3028 float *d_routing_weights,
3029 float *d_expert_gate,
3031 float *d_expert_down,
3034 int intermediate_dim,
3038 if (!d_output || !hidden || !indices || !routing_weights || !expert_gate || !expert_up || !expert_down ||
3039 !d_hidden || !d_routing_weights || !d_expert_gate || !d_expert_up || !d_expert_down ||
3040 rows <= 0 || hidden_dim <= 0 || intermediate_dim <= 0 || n_experts <= 0 || top_k <= 0) {
3044 for (
size_t p = 0; p < (size_t)rows * (
size_t)hidden_dim; ++p) d_hidden[p] = 0.0f;
3045 for (
size_t p = 0; p < (size_t)rows * (
size_t)top_k; ++p) d_routing_weights[p] = 0.0f;
3046 for (
size_t p = 0; p < (size_t)n_experts * (
size_t)intermediate_dim * (size_t)hidden_dim; ++p) {
3047 d_expert_gate[p] = 0.0f;
3048 d_expert_up[p] = 0.0f;
3050 for (
size_t p = 0; p < (size_t)n_experts * (
size_t)hidden_dim * (size_t)intermediate_dim; ++p) d_expert_down[p] = 0.0f;
3052 float gate[intermediate_dim];
3053 float up[intermediate_dim];
3054 float silu_gate[intermediate_dim];
3055 float act[intermediate_dim];
3056 float d_act[intermediate_dim];
3057 float expert_out[hidden_dim];
3059 for (
int r = 0; r < rows; ++r) {
3060 const float *x = hidden + (size_t)r * (
size_t)hidden_dim;
3061 const float *dy = d_output + (size_t)r * (
size_t)hidden_dim;
3062 float *dx = d_hidden + (size_t)r * (
size_t)hidden_dim;
3064 for (
int slot = 0; slot < top_k; ++slot) {
3065 const int e = indices[(size_t)r * (
size_t)top_k + (size_t)slot];
3066 if (e < 0 || e >= n_experts)
continue;
3067 const float route_w = routing_weights[(size_t)r * (
size_t)top_k + (size_t)slot];
3069 for (
int i = 0; i < intermediate_dim; ++i) {
3072 for (
int h = 0; h < hidden_dim; ++h) {
3073 gv += expert_gate[
ck_moe_up_idx(e, i, h, intermediate_dim, hidden_dim)] * x[h];
3074 uv += expert_up[
ck_moe_up_idx(e, i, h, intermediate_dim, hidden_dim)] * x[h];
3079 act[i] = silu_gate[i] * uv;
3083 for (
int h = 0; h < hidden_dim; ++h) {
3085 for (
int i = 0; i < intermediate_dim; ++i) {
3086 v += expert_down[
ck_moe_down_idx(e, h, i, hidden_dim, intermediate_dim)] * act[i];
3091 float d_route = 0.0f;
3092 for (
int h = 0; h < hidden_dim; ++h) {
3093 const float d_expert_out = dy[h] * route_w;
3094 d_route += dy[h] * expert_out[h];
3095 for (
int i = 0; i < intermediate_dim; ++i) {
3096 d_expert_down[
ck_moe_down_idx(e, h, i, hidden_dim, intermediate_dim)] += d_expert_out * act[i];
3097 d_act[i] += d_expert_out * expert_down[
ck_moe_down_idx(e, h, i, hidden_dim, intermediate_dim)];
3100 d_routing_weights[(size_t)r * (
size_t)top_k + (size_t)slot] += d_route;
3102 for (
int i = 0; i < intermediate_dim; ++i) {
3103 const float d_up = d_act[i] * silu_gate[i];
3105 for (
int h = 0; h < hidden_dim; ++h) {
3106 d_expert_up[
ck_moe_up_idx(e, i, h, intermediate_dim, hidden_dim)] += d_up * x[h];
3107 d_expert_gate[
ck_moe_up_idx(e, i, h, intermediate_dim, hidden_dim)] += d_gate * x[h];
3108 dx[h] += d_up * expert_up[
ck_moe_up_idx(e, i, h, intermediate_dim, hidden_dim)] +
3109 d_gate * expert_gate[
ck_moe_up_idx(e, i, h, intermediate_dim, hidden_dim)];
3117 const float *routed,
3118 const float *shared_gate,
3119 const float *shared_up,
3120 const float *shared_down,
3124 int intermediate_dim)
3126 if (!hidden || !shared_gate || !shared_up || !shared_down || !output || rows <= 0 || hidden_dim <= 0 || intermediate_dim <= 0) {
3130 float gate[intermediate_dim];
3131 float up[intermediate_dim];
3132 float act[intermediate_dim];
3134 for (
int r = 0; r < rows; ++r) {
3135 const float *x = hidden + (size_t)r * (
size_t)hidden_dim;
3136 const float *route = routed ? (routed + (size_t)r * (
size_t)hidden_dim) : NULL;
3137 float *y = output + (size_t)r * (
size_t)hidden_dim;
3138 for (
int i = 0; i < intermediate_dim; ++i) {
3141 for (
int h = 0; h < hidden_dim; ++h) {
3142 gv += shared_gate[(size_t)i * (
size_t)hidden_dim + (size_t)h] * x[h];
3143 uv += shared_up[(size_t)i * (
size_t)hidden_dim + (size_t)h] * x[h];
3147 for (
int h = 0; h < hidden_dim; ++h) {
3148 float v = route ? route[h] : 0.0f;
3149 for (
int i = 0; i < intermediate_dim; ++i) {
3150 v += shared_down[(size_t)h * (
size_t)intermediate_dim + (size_t)i] * act[i];
3158 const float *hidden,
3159 const float *routed,
3160 const uint16_t *shared_gate,
3161 const uint16_t *shared_up,
3162 const uint16_t *shared_down,
3166 int intermediate_dim,
3170 if (!hidden || !shared_gate || !shared_up || !shared_down || !output ||
3171 rows <= 0 || hidden_dim <= 0 || intermediate_dim <= 0 ||
3172 row_begin < 0 || row_begin >= row_end || row_end > rows) {
3176 float gate[intermediate_dim];
3177 float up[intermediate_dim];
3178 float act[intermediate_dim];
3180 for (
int r = row_begin; r < row_end; ++r) {
3181 const float *x = hidden + (size_t)r * (
size_t)hidden_dim;
3182 const float *route = routed ? (routed + (size_t)r * (
size_t)hidden_dim) : NULL;
3183 float *y = output + (size_t)r * (
size_t)hidden_dim;
3184 for (
int i = 0; i < intermediate_dim; ++i) {
3187 for (
int h = 0; h < hidden_dim; ++h) {
3188 gv +=
bf16_to_float(shared_gate[(
size_t)i * (
size_t)hidden_dim + (
size_t)h]) * x[h];
3189 uv +=
bf16_to_float(shared_up[(
size_t)i * (
size_t)hidden_dim + (
size_t)h]) * x[h];
3195 for (
int h = 0; h < hidden_dim; ++h) {
3196 float v = route ? route[h] : 0.0f;
3197 for (
int i = 0; i < intermediate_dim; ++i) {
3198 v +=
bf16_to_float(shared_down[(
size_t)h * (
size_t)intermediate_dim + (
size_t)i]) * act[i];
3206 const float *routed,
3207 const uint16_t *shared_gate,
3208 const uint16_t *shared_up,
3209 const uint16_t *shared_down,
3213 int intermediate_dim)
3215 if (rows <= 0)
return;
3217 hidden, routed, shared_gate, shared_up, shared_down, output,
3218 rows, hidden_dim, intermediate_dim, 0, rows);
3222 const float *hidden,
3223 const float *routed,
3224 const uint16_t *shared_gate,
3225 const uint16_t *shared_up,
3226 const uint16_t *shared_down,
3227 const uint16_t *shared_router,
3231 int intermediate_dim,
3235 if (!hidden || !shared_gate || !shared_up || !shared_down ||
3236 !shared_router || !output || rows <= 0 || hidden_dim <= 0 ||
3237 intermediate_dim <= 0 || row_begin < 0 || row_begin >= row_end ||
3242 float activation[intermediate_dim];
3243 for (
int row = row_begin; row < row_end; ++row) {
3244 const float *x = hidden + (size_t)row * (
size_t)hidden_dim;
3245 const float *route = routed
3246 ? routed + (size_t)row * (
size_t)hidden_dim
3248 float *y = output + (size_t)row * (
size_t)hidden_dim;
3250 for (
int intermediate = 0; intermediate < intermediate_dim;
3252 float gate_sum = 0.0f;
3253 float up_sum = 0.0f;
3254 const size_t weight_base =
3255 (size_t)intermediate * (
size_t)hidden_dim;
3256 for (
int hidden_col = 0; hidden_col < hidden_dim; ++hidden_col) {
3259 shared_gate[weight_base + (
size_t)hidden_col]) * value;
3261 shared_up[weight_base + (
size_t)hidden_col]) * value;
3270 float router_sum = 0.0f;
3271 for (
int hidden_col = 0; hidden_col < hidden_dim; ++hidden_col) {
3278 for (
int hidden_col = 0; hidden_col < hidden_dim; ++hidden_col) {
3279 float down_sum = 0.0f;
3280 const size_t weight_base =
3281 (size_t)hidden_col * (
size_t)intermediate_dim;
3282 for (
int intermediate = 0; intermediate < intermediate_dim;
3285 shared_down[weight_base + (
size_t)intermediate]) *
3286 activation[intermediate];
3290 const float routed_value = route
3299 const float *hidden,
3300 const float *routed,
3301 const uint16_t *shared_gate,
3302 const uint16_t *shared_up,
3303 const uint16_t *shared_down,
3304 const uint16_t *shared_router,
3308 int intermediate_dim)
3310 if (rows <= 0)
return;
3312 hidden, routed, shared_gate, shared_up, shared_down, shared_router,
3313 output, rows, hidden_dim, intermediate_dim, 0, rows);
3329 const float *hidden,
3330 const float *routed,
3331 const float *post_attn_residual,
3332 const uint16_t *shared_gate,
3333 const uint16_t *shared_up,
3334 const uint16_t *shared_down,
3336 float *routed_free_output,
3339 int intermediate_dim,
3343 if (!hidden || !routed || !post_attn_residual || !shared_gate || !shared_up ||
3344 !shared_down || !main_output || !routed_free_output || rows <= 0 ||
3345 hidden_dim <= 0 || intermediate_dim <= 0 || row_begin < 0 ||
3346 row_begin >= row_end || row_end > rows) {
3350 float act[intermediate_dim];
3352 for (
int r = row_begin; r < row_end; ++r) {
3353 const float *x = hidden + (size_t)r * (
size_t)hidden_dim;
3354 const float *route = routed + (size_t)r * (
size_t)hidden_dim;
3355 const float *residual = post_attn_residual + (size_t)r * (
size_t)hidden_dim;
3356 float *
main = main_output + (size_t)r * (
size_t)hidden_dim;
3357 float *routed_free = routed_free_output + (size_t)r * (
size_t)hidden_dim;
3359 for (
int i = 0; i < intermediate_dim; ++i) {
3362 for (
int h = 0; h < hidden_dim; ++h) {
3363 gv +=
bf16_to_float(shared_gate[(
size_t)i * (
size_t)hidden_dim + (
size_t)h]) * x[h];
3364 uv +=
bf16_to_float(shared_up[(
size_t)i * (
size_t)hidden_dim + (
size_t)h]) * x[h];
3369 for (
int h = 0; h < hidden_dim; ++h) {
3370 float shared = 0.0f;
3371 for (
int i = 0; i < intermediate_dim; ++i) {
3372 shared +=
bf16_to_float(shared_down[(
size_t)h * (
size_t)intermediate_dim + (
size_t)i]) * act[i];
3374 const float mlp_output = route[h] + shared;
3375 routed_free[h] = residual[h] + shared;
3376 main[h] = residual[h] + mlp_output;
3382 const float *routed,
3383 const float *post_attn_residual,
3384 const uint16_t *shared_gate,
3385 const uint16_t *shared_up,
3386 const uint16_t *shared_down,
3388 float *routed_free_output,
3391 int intermediate_dim)
3393 if (rows <= 0)
return;
3395 hidden, routed, post_attn_residual, shared_gate, shared_up, shared_down,
3396 main_output, routed_free_output, rows, hidden_dim, intermediate_dim,
3401 const float *hidden,
3402 const float *shared_gate,
3403 const float *shared_up,
3404 const float *shared_down,
3407 float *d_shared_gate,
3409 float *d_shared_down,
3412 int intermediate_dim)
3414 if (!d_output || !hidden || !shared_gate || !shared_up || !shared_down ||
3415 !d_hidden || !d_routed || !d_shared_gate || !d_shared_up || !d_shared_down ||
3416 rows <= 0 || hidden_dim <= 0 || intermediate_dim <= 0) {
3420 for (
size_t p = 0; p < (size_t)rows * (
size_t)hidden_dim; ++p) {
3422 d_routed[p] = d_output[p];
3424 for (
size_t p = 0; p < (size_t)intermediate_dim * (
size_t)hidden_dim; ++p) {
3425 d_shared_gate[p] = 0.0f;
3426 d_shared_up[p] = 0.0f;
3428 for (
size_t p = 0; p < (size_t)hidden_dim * (
size_t)intermediate_dim; ++p) d_shared_down[p] = 0.0f;
3430 float gate[intermediate_dim];
3431 float up[intermediate_dim];
3432 float silu_gate[intermediate_dim];
3433 float act[intermediate_dim];
3434 float d_act[intermediate_dim];
3436 for (
int r = 0; r < rows; ++r) {
3437 const float *x = hidden + (size_t)r * (
size_t)hidden_dim;
3438 const float *dy = d_output + (size_t)r * (
size_t)hidden_dim;
3439 float *dx = d_hidden + (size_t)r * (
size_t)hidden_dim;
3441 for (
int i = 0; i < intermediate_dim; ++i) {
3444 for (
int h = 0; h < hidden_dim; ++h) {
3445 gv += shared_gate[(size_t)i * (
size_t)hidden_dim + (size_t)h] * x[h];
3446 uv += shared_up[(size_t)i * (
size_t)hidden_dim + (size_t)h] * x[h];
3451 act[i] = silu_gate[i] * uv;
3455 for (
int h = 0; h < hidden_dim; ++h) {
3456 for (
int i = 0; i < intermediate_dim; ++i) {
3457 d_shared_down[(size_t)h * (
size_t)intermediate_dim + (size_t)i] += dy[h] * act[i];
3458 d_act[i] += dy[h] * shared_down[(size_t)h * (
size_t)intermediate_dim + (size_t)i];
3462 for (
int i = 0; i < intermediate_dim; ++i) {
3463 const float d_up = d_act[i] * silu_gate[i];
3465 for (
int h = 0; h < hidden_dim; ++h) {
3466 d_shared_up[(size_t)i * (
size_t)hidden_dim + (size_t)h] += d_up * x[h];
3467 d_shared_gate[(size_t)i * (
size_t)hidden_dim + (size_t)h] += d_gate * x[h];
3468 dx[h] += d_up * shared_up[(size_t)i * (
size_t)hidden_dim + (size_t)h] +
3469 d_gate * shared_gate[(
size_t)i * (size_t)hidden_dim + (
size_t)h];
3477 const float *routing_weights,
3478 const void *expert_up,
3479 const void *expert_down,
3483 int intermediate_dim,
3487 if (!hidden || !indices || !routing_weights || !expert_up || !expert_down || !output ||
3488 rows <= 0 || hidden_dim <= 0 || intermediate_dim <= 0 || n_experts <= 0 || top_k <= 0) {
3492 const size_t out_count = (size_t)rows * (
size_t)hidden_dim;
3493 for (
size_t p = 0; p < out_count; ++p) output[p] = 0.0f;
3497 const uint8_t *up_base = (
const uint8_t *)expert_up;
3498 const uint8_t *down_base = (
const uint8_t *)expert_down;
3500 float up_row[hidden_dim];
3501 float down_row[intermediate_dim];
3502 float act[intermediate_dim];
3504 for (
int r = 0; r < rows; ++r) {
3505 const float *x = hidden + (size_t)r * (
size_t)hidden_dim;
3506 float *y = output + (size_t)r * (
size_t)hidden_dim;
3509 "[CK_DEBUG_MOE] routed_q5q8 rows=%d hidden=%d intermediate=%d experts=%d top_k=%d up_row_bytes=%zu down_row_bytes=%zu\n",
3517 fprintf(stderr,
"[CK_DEBUG_MOE] routed slots:");
3518 for (
int dbg_slot = 0; dbg_slot < top_k; ++dbg_slot) {
3521 indices[(
size_t)r * (
size_t)top_k + (
size_t)dbg_slot],
3522 routing_weights[(
size_t)r * (
size_t)top_k + (
size_t)dbg_slot]);
3524 fprintf(stderr,
"\n");
3528 for (
int slot = 0; slot < top_k; ++slot) {
3529 const int e = indices[(size_t)r * (
size_t)top_k + (size_t)slot];
3530 if (e < 0 || e >= n_experts)
continue;
3531 const float route_w = routing_weights[(size_t)r * (
size_t)top_k + (size_t)slot];
3532 const uint8_t *expert_up_base = up_base + (size_t)e * (
size_t)intermediate_dim * up_row_bytes;
3533 const uint8_t *expert_down_base = down_base + (size_t)e * (
size_t)hidden_dim * down_row_bytes;
3535 for (
int i = 0; i < intermediate_dim; ++i) {
3536 dequant_q5_0_row(expert_up_base + (
size_t)i * up_row_bytes, up_row, (
size_t)hidden_dim);
3538 for (
int h = 0; h < hidden_dim; ++h) v += up_row[h] * x[h];
3539 act[i] = (v > 0.0f) ? v * v : 0.0f;
3542 for (
int h = 0; h < hidden_dim; ++h) {
3543 dequant_q8_0_row(expert_down_base + (
size_t)h * down_row_bytes, down_row, (
size_t)intermediate_dim);
3545 for (
int i = 0; i < intermediate_dim; ++i) v += down_row[i] * act[i];
3546 y[h] += route_w * v;
3559 const float *routing_weights,
3560 const void *expert_up,
3561 const void *expert_down,
3565 int intermediate_dim,
3569 if (!hidden || !indices || !routing_weights || !expert_up || !expert_down || !output ||
3570 rows <= 0 || hidden_dim <= 0 || intermediate_dim <= 0 || n_experts <= 0 || top_k <= 0) {
3574 const size_t out_count = (size_t)rows * (
size_t)hidden_dim;
3575 for (
size_t p = 0; p < out_count; ++p) output[p] = 0.0f;
3579 const uint8_t *up_base = (
const uint8_t *)expert_up;
3580 const uint8_t *down_base = (
const uint8_t *)expert_down;
3582 float up_row[hidden_dim];
3583 float down_row[intermediate_dim];
3584 float act[intermediate_dim];
3586 for (
int r = 0; r < rows; ++r) {
3587 const float *x = hidden + (size_t)r * (
size_t)hidden_dim;
3588 float *y = output + (size_t)r * (
size_t)hidden_dim;
3591 "[CK_DEBUG_MOE] routed_q5q5 rows=%d hidden=%d intermediate=%d experts=%d top_k=%d up_row_bytes=%zu down_row_bytes=%zu\n",
3599 fprintf(stderr,
"[CK_DEBUG_MOE] routed slots:");
3600 for (
int dbg_slot = 0; dbg_slot < top_k; ++dbg_slot) {
3603 indices[(
size_t)r * (
size_t)top_k + (
size_t)dbg_slot],
3604 routing_weights[(
size_t)r * (
size_t)top_k + (
size_t)dbg_slot]);
3606 fprintf(stderr,
"\n");
3610 for (
int slot = 0; slot < top_k; ++slot) {
3611 const int e = indices[(size_t)r * (
size_t)top_k + (size_t)slot];
3612 if (e < 0 || e >= n_experts)
continue;
3613 const float route_w = routing_weights[(size_t)r * (
size_t)top_k + (size_t)slot];
3614 const uint8_t *expert_up_base = up_base + (size_t)e * (
size_t)intermediate_dim * up_row_bytes;
3615 const uint8_t *expert_down_base = down_base + (size_t)e * (
size_t)hidden_dim * down_row_bytes;
3617 for (
int i = 0; i < intermediate_dim; ++i) {
3618 dequant_q5_0_row(expert_up_base + (
size_t)i * up_row_bytes, up_row, (
size_t)hidden_dim);
3620 for (
int h = 0; h < hidden_dim; ++h) v += up_row[h] * x[h];
3621 act[i] = (v > 0.0f) ? v * v : 0.0f;
3624 for (
int h = 0; h < hidden_dim; ++h) {
3625 dequant_q5_0_row(expert_down_base + (
size_t)h * down_row_bytes, down_row, (
size_t)intermediate_dim);
3627 for (
int i = 0; i < intermediate_dim; ++i) v += down_row[i] * act[i];
3628 y[h] += route_w * v;
3639 const float *routed,
3640 const void *shared_up,
3641 const void *shared_down,
3645 int intermediate_dim)
3647 if (!hidden || !shared_up || !shared_down || !output || rows <= 0 || hidden_dim <= 0 || intermediate_dim <= 0) {
3653 const uint8_t *up_base = (
const uint8_t *)shared_up;
3654 const uint8_t *down_base = (
const uint8_t *)shared_down;
3656 float up_row[hidden_dim];
3657 float down_row[intermediate_dim];
3658 float act[intermediate_dim];
3660 for (
int r = 0; r < rows; ++r) {
3661 const float *x = hidden + (size_t)r * (
size_t)hidden_dim;
3662 const float *route = routed ? (routed + (size_t)r * (
size_t)hidden_dim) : NULL;
3663 float *y = output + (size_t)r * (
size_t)hidden_dim;
3664 float x_alias[hidden_dim];
3665 if (output == hidden) {
3666 memcpy(x_alias, x, (
size_t)hidden_dim *
sizeof(
float));
3672 "[CK_DEBUG_MOE] shared_q5q8 rows=%d hidden=%d intermediate=%d up_row_bytes=%zu down_row_bytes=%zu alias=%d\n",
3682 if (routed)
ck_moe_debug_finite(
"shared.routed_all", routed, (
size_t)rows * (
size_t)hidden_dim);
3685 for (
int i = 0; i < intermediate_dim; ++i) {
3686 dequant_q5_1_row(up_base + (
size_t)i * up_row_bytes, up_row, (
size_t)hidden_dim);
3688 for (
int h = 0; h < hidden_dim; ++h) v += up_row[h] * x[h];
3689 act[i] = (v > 0.0f) ? v * v : 0.0f;
3692 for (
int h = 0; h < hidden_dim; ++h) {
3693 dequant_q8_0_row(down_base + (
size_t)h * down_row_bytes, down_row, (
size_t)intermediate_dim);
3694 float v = route ? route[h] : 0.0f;
3695 for (
int i = 0; i < intermediate_dim; ++i) v += down_row[i] * act[i];
3707 const float *hidden,
3709 const float *routing_weights,
3710 const float *expert_up,
3711 const float *expert_down,
3713 float *d_routing_weights,
3715 float *d_expert_down,
3718 int intermediate_dim,
3722 if (!d_output || !hidden || !indices || !routing_weights || !expert_up || !expert_down ||
3723 !d_hidden || !d_routing_weights || !d_expert_up || !d_expert_down ||
3724 rows <= 0 || hidden_dim <= 0 || intermediate_dim <= 0 || n_experts <= 0 || top_k <= 0) {
3728 for (
size_t p = 0; p < (size_t)rows * (
size_t)hidden_dim; ++p) d_hidden[p] = 0.0f;
3729 for (
size_t p = 0; p < (size_t)rows * (
size_t)top_k; ++p) d_routing_weights[p] = 0.0f;
3730 for (
size_t p = 0; p < (size_t)n_experts * (
size_t)intermediate_dim * (size_t)hidden_dim; ++p) d_expert_up[p] = 0.0f;
3731 for (
size_t p = 0; p < (size_t)n_experts * (
size_t)hidden_dim * (size_t)intermediate_dim; ++p) d_expert_down[p] = 0.0f;
3733 float pre[intermediate_dim];
3734 float act[intermediate_dim];
3735 float d_act[intermediate_dim];
3736 float d_pre[intermediate_dim];
3737 float expert_out[hidden_dim];
3739 for (
int r = 0; r < rows; ++r) {
3740 const float *x = hidden + (size_t)r * (
size_t)hidden_dim;
3741 const float *dy = d_output + (size_t)r * (
size_t)hidden_dim;
3742 float *dx = d_hidden + (size_t)r * (
size_t)hidden_dim;
3744 for (
int slot = 0; slot < top_k; ++slot) {
3745 const int e = indices[(size_t)r * (
size_t)top_k + (size_t)slot];
3746 if (e < 0 || e >= n_experts)
continue;
3747 const float route_w = routing_weights[(size_t)r * (
size_t)top_k + (size_t)slot];
3749 for (
int i = 0; i < intermediate_dim; ++i) {
3751 for (
int h = 0; h < hidden_dim; ++h) {
3752 v += expert_up[
ck_moe_up_idx(e, i, h, intermediate_dim, hidden_dim)] * x[h];
3755 act[i] = (v > 0.0f) ? v * v : 0.0f;
3759 for (
int h = 0; h < hidden_dim; ++h) {
3761 for (
int i = 0; i < intermediate_dim; ++i) {
3762 v += expert_down[
ck_moe_down_idx(e, h, i, hidden_dim, intermediate_dim)] * act[i];
3767 float d_route = 0.0f;
3768 for (
int h = 0; h < hidden_dim; ++h) {
3769 const float d_expert_out = dy[h] * route_w;
3770 d_route += dy[h] * expert_out[h];
3771 for (
int i = 0; i < intermediate_dim; ++i) {
3772 d_expert_down[
ck_moe_down_idx(e, h, i, hidden_dim, intermediate_dim)] += d_expert_out * act[i];
3773 d_act[i] += d_expert_out * expert_down[
ck_moe_down_idx(e, h, i, hidden_dim, intermediate_dim)];
3776 d_routing_weights[(size_t)r * (
size_t)top_k + (size_t)slot] += d_route;
3778 for (
int i = 0; i < intermediate_dim; ++i) {
3779 d_pre[i] = (pre[i] > 0.0f) ? d_act[i] * 2.0f * pre[i] : 0.0f;
3782 for (
int i = 0; i < intermediate_dim; ++i) {
3783 const float dpi = d_pre[i];
3784 for (
int h = 0; h < hidden_dim; ++h) {
3785 d_expert_up[
ck_moe_up_idx(e, i, h, intermediate_dim, hidden_dim)] += dpi * x[h];
3786 dx[h] += dpi * expert_up[
ck_moe_up_idx(e, i, h, intermediate_dim, hidden_dim)];
static float ck_moe_silu_f32(float x)
void axpy_f32(float *y, const float *x, float alpha, int n)
In-place AXPY: y += alpha * x.
size_t moe_swiglu_expert_q4k_q5k_workspace_bytes(int hidden_dim, int intermediate_dim)
static void ck_moe_q4k_q5k_route_work(int ith, int nth, void *opaque)
void moe_accumulate_expert_f32(float *output, const float *expert_output, float routing_weight, int hidden_dim)
Accumulate expert output: output += routing_weight * expert_output.
static int ck_moe_q4k_mixed_route_parallel(const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes, size_t workspace_stride, ck_threadpool_t *pool, ck_moe_down_kind_t down_kind)
static void ck_moe_q4k_q5k_parallel_work(int ith, int nth, void *opaque)
static size_t ck_moe_align64(size_t value)
static float ck_moe_bf16_round(float x)
static int ck_moe_debug_enabled(void)
static size_t ck_moe_up_idx(int e, int i, int h, int intermediate_dim, int hidden_dim)
int(* ck_moe_shared_workspace_fn)(const float *, const float *, const void *, const void *, const void *, float *, int, int, int, void *, size_t)
void moe_swiglu_shared_forward_bf16(const float *hidden, const float *routed, const uint16_t *shared_gate, const uint16_t *shared_up, const uint16_t *shared_down, float *output, int rows, int hidden_dim, int intermediate_dim)
void moe_relu2_expert_forward_q5_0_q8_0(const float *hidden, const int *indices, const float *routing_weights, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k)
static size_t ck_moe_down_idx(int e, int h, int i, int hidden_dim, int intermediate_dim)
int moe_swiglu_expert_forward_q4k_q8_0_workspace(const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)
void moe_swiglu_shared_forward_f32(const float *hidden, const float *routed, const float *shared_gate, const float *shared_up, const float *shared_down, float *output, int rows, int hidden_dim, int intermediate_dim)
static void ck_moe_q4k_llama_projection(float *output, const void *weights, const void *input_q8, int output_dim, int input_dim, void *scratch)
void gemm_q5_k_q8_k_compact_rows4(float *output, int output_stride, const void *weights, const void *const input_rows[4], int rows, int output_dim, int input_dim)
void axpy_zero_f32(float *y, const float *x, float alpha, int n)
Zero output then accumulate: y = 0; y += alpha * x.
int moe_swiglu_shared_forward_q8_0_gated_workspace(const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, const float *shared_gate_input, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes)
void moe_swiglu_shared_forward_bf16_row_range(const float *hidden, const float *routed, const uint16_t *shared_gate, const uint16_t *shared_up, const uint16_t *shared_down, float *output, int rows, int hidden_dim, int intermediate_dim, int row_begin, int row_end)
void moe_swiglu_shared_backward_f32(const float *d_output, const float *hidden, const float *shared_gate, const float *shared_up, const float *shared_down, float *d_hidden, float *d_routed, float *d_shared_gate, float *d_shared_up, float *d_shared_down, int rows, int hidden_dim, int intermediate_dim)
static int ck_moe_size_mul(size_t a, size_t b, size_t *result)
void pack_q4_k_to_packed_meta_x8(const void *source, void *destination, int output_dim, int input_dim)
void moe_swiglu_expert_forward_bf16(const float *hidden, const int *indices, const float *routing_weights, const uint16_t *expert_gate, const uint16_t *expert_up, const uint16_t *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k)
static void ck_moe_q4k_mixed_parallel_work(int ith, int nth, void *opaque)
void moe_relu2_expert_backward_f32(const float *d_output, const float *hidden, const int *indices, const float *routing_weights, const float *expert_up, const float *expert_down, float *d_hidden, float *d_routing_weights, float *d_expert_up, float *d_expert_down, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k)
int moe_swiglu_expert_forward_q4k_q4k_workspace(const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)
int moe_swiglu_shared_forward_q4k_q6k_workspace(const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes)
int moe_swiglu_expert_forward_q4k_q8_0_parallel_workspace(const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)
int moe_swiglu_expert_forward_q4k_q5_0_workspace(const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)
static float ck_moe_dsilu_f32(float x)
static void ck_moe_shared_q4k_parallel_work(int ith, int nth, void *opaque)
int moe_swiglu_expert_forward_q4k_q5k_parallel_workspace(const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)
void moe_swiglu_shared_forward_bf16_gated(const float *hidden, const float *routed, const uint16_t *shared_gate, const uint16_t *shared_up, const uint16_t *shared_down, const uint16_t *shared_router, float *output, int rows, int hidden_dim, int intermediate_dim)
void moe_relu2_expert_forward_f32(const float *hidden, const int *indices, const float *routing_weights, const float *expert_up, const float *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k)
void gemm_q4_k_q8_k_packed_vnni_x8_compact_order_rows4(float *output, const void *weights_packed, const void *input_q8, int rows, int output_dim, int input_dim)
static int ck_moe_q4k_mixed_parallel_workspace(const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes, ck_moe_expert_workspace_fn serial_fn, ck_moe_down_kind_t down_kind)
void weighted_sum_f32(float *y, const float **vectors, const float *weights, int k, int n)
Weighted sum of k vectors: y = sum_i(weights[i] * vectors[i])
size_t q4_k_packed_meta_x8_block_size(void)
static int ck_moe_shared_gated_parallel_workspace(const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, const float *shared_gate_input, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes, size_t stride, ck_moe_shared_gated_workspace_fn serial_fn)
void gemm_nt_q4_k_q8_k_pairwise_split_min_parallel_dispatch(const void *input, const void *weight, const float *bias, float *output, int rows, int output_dim, int input_dim)
int moe_swiglu_expert_forward_q4k_q4k_parallel_workspace(const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)
void moe_swiglu_shared_forward_bf16_gated_row_range(const float *hidden, const float *routed, const uint16_t *shared_gate, const uint16_t *shared_up, const uint16_t *shared_down, const uint16_t *shared_router, float *output, int rows, int hidden_dim, int intermediate_dim, int row_begin, int row_end)
static int ck_moe_bucket_expert_for_position(const int *offsets, int n_experts, int position)
static int ck_moe_swiglu_expert_forward_q4k_q5k_bucketed_impl(const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, const void *expert_gate_packed, const void *expert_up_packed, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)
int moe_swiglu_expert_forward_q4k_q5_0_parallel_workspace(const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)
void axpy_2d_f32(float *Y, const float *X, float alpha, int num_tokens, int dim, int y_stride, int x_stride)
Batched AXPY for 2D tensors: Y[t,:] += alpha * X[t,:].
void moe_swiglu_expert_forward_bf16_row_range(const float *hidden, const int *indices, const float *routing_weights, const uint16_t *expert_gate, const uint16_t *expert_up, const uint16_t *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, int row_begin, int row_end)
size_t moe_swiglu_shared_q8_0_gated_workspace_bytes(int hidden_dim, int intermediate_dim)
void moe_relu2_shared_forward_q5_1_q8_0(const float *hidden, const float *routed, const void *shared_up, const void *shared_down, float *output, int rows, int hidden_dim, int intermediate_dim)
static void ck_moe_llama_weighted_accumulate(float *output, const float *expert_output, float route_weight, int n)
void moe_relu2_expert_forward_q5_0_q5_0(const float *hidden, const int *indices, const float *routing_weights, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k)
static int ck_moe_size_add(size_t a, size_t b, size_t *result)
size_t q4_k_packed_vnni_x8_block_size(void)
static size_t ck_moe_q4k_llama_projection_scratch_bytes(int output_dim, int input_dim)
int moe_swiglu_expert_forward_q4k_q5k_workspace(const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)
int moe_swiglu_shared_forward_q8_0_gated_parallel_workspace(const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, const float *shared_gate_input, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes)
int moe_swiglu_shared_forward_q4k_q4k_parallel_workspace(const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes)
static void ck_moe_shared_q8_0_parallel_work(int ith, int nth, void *opaque)
static int ck_moe_shared_q4k_parallel_workspace(const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes, ck_moe_shared_workspace_fn serial_fn)
static void ck_moe_q4k_q5k_bucket_work(int ith, int nth, void *opaque)
static int ck_moe_shared_q4k_gated_workspace(const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, const float *shared_gate_input, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes, void(*down_projection)(float *, const void *, const void *, int, int))
int moe_swiglu_expert_forward_q4k_q5k_bucketed_workspace(const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)
static int ck_moe_q4k_q5k_route_parallel(const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes, size_t workspace_stride, ck_threadpool_t *pool)
int(* ck_moe_expert_workspace_fn)(const float *, const int *, const float *, const void *, const void *, const void *, float *, int, int, int, int, int, void *, size_t)
void gemm_nt_q4_k_packed_meta_x8_q8_k_gemv_order(const void *input, const void *packed_weight, const float *bias, float *output, int rows, int output_dim, int input_dim)
static void ck_moe_debug_finite(const char *name, const float *x, size_t n)
int moe_swiglu_expert_forward_q4k_q5k_auto_workspace(const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)
size_t moe_swiglu_expert_q4k_q8_0_workspace_bytes(int hidden_dim, int intermediate_dim)
size_t moe_swiglu_shared_q4k_q8_0_gated_workspace_bytes(int hidden_dim, int intermediate_dim)
void farskip_swiglu_shared_combine_bf16(const float *hidden, const float *routed, const float *post_attn_residual, const uint16_t *shared_gate, const uint16_t *shared_up, const uint16_t *shared_down, float *main_output, float *routed_free_output, int rows, int hidden_dim, int intermediate_dim)
void farskip_swiglu_shared_combine_bf16_row_range(const float *hidden, const float *routed, const float *post_attn_residual, const uint16_t *shared_gate, const uint16_t *shared_up, const uint16_t *shared_down, float *main_output, float *routed_free_output, int rows, int hidden_dim, int intermediate_dim, int row_begin, int row_end)
static void ck_moe_q4k_q5k_quantize_work(int ith, int nth, void *opaque)
int moe_swiglu_shared_forward_q4k_q5_0_gated_parallel_workspace(const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, const float *shared_gate_input, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes)
int moe_swiglu_shared_forward_q4k_q5_0_gated_workspace(const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, const float *shared_gate_input, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes)
static float ck_moe_sigmoid_f32(float x)
size_t moe_swiglu_expert_q4k_q5k_bucketed_workspace_bytes(int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k)
int moe_swiglu_shared_forward_q4k_q4k_workspace(const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes)
void moe_swiglu_expert_forward_f32(const float *hidden, const int *indices, const float *routing_weights, const float *expert_gate, const float *expert_up, const float *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k)
static int ck_moe_bucket_layout(int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, ck_moe_q4k_q5k_bucket_layout_t *layout)
void moe_swiglu_packed_expert_forward_bf16(const float *hidden, const int *indices, const float *routing_weights, const uint16_t *expert_gate_up, const uint16_t *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k)
@ CK_MOE_Q4K_Q5K_TASK_ROWS
int moe_swiglu_shared_forward_q4k_q8_0_gated_parallel_workspace(const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, const float *shared_gate_input, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes)
int moe_swiglu_expert_forward_q4k_q6k_parallel_workspace(const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)
void gemm_q4_k_q8_k_compact_rows4(float *output, int output_stride, const void *weights, const void *const input_rows[4], int rows, int output_dim, int input_dim)
void moe_swiglu_expert_backward_f32(const float *d_output, const float *hidden, const int *indices, const float *routing_weights, const float *expert_gate, const float *expert_up, const float *expert_down, float *d_hidden, float *d_routing_weights, float *d_expert_gate, float *d_expert_up, float *d_expert_down, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k)
int moe_swiglu_shared_forward_q4k_q6k_parallel_workspace(const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes)
int moe_swiglu_expert_forward_q4k_q5k_bucketed_prepared_workspace(const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, const void *expert_gate_packed, const void *expert_up_packed, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)
static void ck_moe_q4k_mixed_route_work(int ith, int nth, void *opaque)
int(* ck_moe_shared_gated_workspace_fn)(const float *, const float *, const void *, const void *, const void *, const float *, float *, int, int, int, void *, size_t)
void scal_copy_f32(float *y, const float *x, float alpha, int n)
Scaled copy: y = alpha * x.
int moe_swiglu_expert_forward_q4k_q6k_workspace(const float *hidden, const int *indices, const float *routing_weights, const void *expert_gate, const void *expert_up, const void *expert_down, float *output, int rows, int hidden_dim, int intermediate_dim, int n_experts, int top_k, void *workspace, size_t workspace_bytes)
int moe_swiglu_shared_forward_q4k_q8_0_gated_workspace(const float *hidden, const float *routed, const void *shared_gate, const void *shared_up, const void *shared_down, const float *shared_gate_input, float *output, int rows, int hidden_dim, int intermediate_dim, void *workspace, size_t workspace_bytes)
static uint16_t float_to_bf16(float f)
static float bf16_to_float(uint16_t v)
int main(int argc, char **argv)
Persistent pthread thread pool for CK-Engine inference.
#define CK_THREADPOOL_MAX_THREADS
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_n_threads(const ck_threadpool_t *pool)
static size_t ck_dtype_row_bytes(CKDataType dt, size_t n_elements)
Calculate total bytes for n_elements of given dtype.
void swiglu_forward_pytorch_bf16_storage(const float *input, float *output, int tokens, int dim)
void dequant_q5_0_row(const void *src, float *dst, size_t n_elements)
Dequantize Q5_0 row (multiple blocks)
void gemv_q5_0_q8_0(float *y, const void *W, const void *x_q8, int M, int K)
Matrix-vector multiply with Q5_0 weights and Q8_0 input.
void gemv_q5_k_q8_k(float *y, const void *W, const void *x_q8, int M, int K)
void gemv_q6_k_q8_k(float *y, const void *W, const void *x_q8, int M, int K)
GEMV: y = W @ x where W is Q6_K and x is Q8_K.
void quantize_row_q8_k(const float *x, void *y, int k)
void dequant_q8_0_row(const void *src, float *dst, size_t n_elements)
Dequantize Q8_0 row (multiple blocks)
void quantize_row_q8_0(const float *x, void *y, int k)
Quantize FP32 to Q8_0 format (scalar reference)
void gemv_q8_0_q8_0(float *y, const void *W, const void *x_q8, int M, int K)
Matrix-vector multiply with Q8_0 weights and Q8_0 input.
void gemv_q4_k_q8_k(float *y, const void *W, const void *x_q8, int M, int K)
void dequant_q5_1_row(const void *src, float *dst, size_t n_elements)
Dequantize Q5_1 row (multiple blocks)
void swiglu_forward_ggml(const float *input, float *output, int tokens, int dim)
void swiglu_forward_ggml_split(const float *gate, const float *up, float *output, int tokens, int dim)
void gemm_nt_f32_llama_production(const float *A, const float *B, const float *bias, float *C, int M, int N, int K)
int const int32_t * offsets
static void silu(float *x, int n)