13 union {
float f; uint32_t u; } bits = {value};
14 const uint32_t bias = UINT32_C(0x7fff) + ((bits.u >> 16) & 1u);
15 bits.u = (bits.u + bias) & UINT32_C(0xffff0000);
20 union { uint32_t u;
float f; } bits = {(uint32_t)(*value) << 16};
31 if (shift == 0)
return tokens[row];
32 for (
int step = 1; step <= shift; ++step) {
33 const int index = row - step;
34 const int32_t prior = index >= 0
36 : (position == 0 ? eos_token_id : (int32_t)state[state_len + index]);
37 if (prior == eos_token_id)
return eos_token_id;
39 const int source = row - shift;
42 : (position == 0 ? eos_token_id : (int32_t)state[state_len + source]);
46 const void *embedding,
47 const int64_t *layer_multipliers,
48 const int64_t *head_offsets,
49 const int64_t *head_vocab_sizes,
51 const float *token_state_in,
52 float *token_state_out,
59 int embedding_is_q5_0) {
60 if (!token_ids || !embedding || !layer_multipliers || !head_offsets ||
61 !head_vocab_sizes || !output || !token_state_in || !token_state_out || rows <= 0 ||
62 ngram_size < 2 || heads_per_ngram <= 0 || head_dim <= 0)
return;
64 const int state_len = ngram_size - 1;
65 const int embed_dim = state_len * heads_per_ngram * head_dim;
66 for (
int row = 0; row < rows; ++row) {
67 float *out_row = output + (size_t)row * embed_dim;
68 for (
int ngram = 2; ngram <= ngram_size; ++ngram) {
69 uint64_t mixed = (uint64_t)(int64_t)token_ids[row] *
70 (uint64_t)layer_multipliers[0];
71 for (
int gram_position = 1; gram_position < ngram; ++gram_position) {
73 token_ids, token_state_in, row, gram_position, state_len,
74 eos_token_id, position_offset);
75 mixed ^= (uint64_t)(int64_t)
token *
76 (uint64_t)layer_multipliers[gram_position];
78 const int head_begin = (ngram - 2) * heads_per_ngram;
79 for (
int local_head = 0; local_head < heads_per_ngram; ++local_head) {
80 const int head = head_begin + local_head;
81 const int64_t vocab = head_vocab_sizes[head];
82 int64_t remainder = (int64_t)mixed % vocab;
83 if (remainder < 0) remainder += vocab;
84 const int64_t embedding_row = head_offsets[head] + remainder;
85 float *target = out_row + (size_t)head * head_dim;
86 if (embedding_is_q5_0) {
88 const uint8_t *source = (
const uint8_t *)embedding +
89 (
size_t)embedding_row * row_bytes;
92 const uint16_t *source = (
const uint16_t *)embedding +
93 (
size_t)embedding_row * head_dim;
94 for (
int col = 0; col < head_dim; ++col) {
102 if (rows >= state_len) {
103 for (
int index = 0; index < state_len; ++index) {
104 token_state_out[index] = (float)token_ids[rows - state_len + index];
107 if (position_offset == 0) {
108 for (
int index = 0; index < state_len - rows; ++index) {
109 token_state_out[index] = (float)eos_token_id;
112 memmove(token_state_out, token_state_in + rows,
113 (
size_t)(state_len - rows) *
sizeof(*token_state_out));
115 for (
int index = 0; index < rows; ++index) {
116 token_state_out[state_len - rows + index] = (float)token_ids[index];
122 const uint16_t *embedding,
123 const int64_t *layer_multipliers,
124 const int64_t *head_offsets,
125 const int64_t *head_vocab_sizes,
127 const float *token_state_in,
128 float *token_state_out,
134 int position_offset) {
136 token_ids, embedding, layer_multipliers, head_offsets,
137 head_vocab_sizes, output, token_state_in, token_state_out, rows,
138 ngram_size, heads_per_ngram, head_dim, eos_token_id, position_offset, 0);
142 const void *embedding,
143 const int64_t *layer_multipliers,
144 const int64_t *head_offsets,
145 const int64_t *head_vocab_sizes,
147 const float *token_state_in,
148 float *token_state_out,
154 int position_offset) {
156 token_ids, embedding, layer_multipliers, head_offsets,
157 head_vocab_sizes, output, token_state_in, token_state_out, rows,
158 ngram_size, heads_per_ngram, head_dim, eos_token_id, position_offset, 1);
167 for (
int group = 0; group < groups; ++group) {
168 const float *in_group = input + (size_t)group * hidden_dim;
169 const float *w_group = weight + (size_t)group * hidden_dim;
170 float *out_group = output + (size_t)group * hidden_dim;
172 in_group, w_group, out_group, NULL, 1, hidden_dim, hidden_dim, eps);
182 for (
int group = 0; group < groups; ++group) {
183 const float *in_group = input + (size_t)group * hidden_dim;
184 const float *w_group = weight + (size_t)group * hidden_dim;
185 float *out_group = output + (size_t)group * hidden_dim;
187 in_group, w_group, out_group, NULL, 1, hidden_dim, hidden_dim, eps);
196 __m256 streams[4] = {
197 _mm256_setzero_ps(), _mm256_setzero_ps(),
198 _mm256_setzero_ps(), _mm256_setzero_ps()
201 for (; col + 32 <= dim; col += 32) {
202 for (
int stream = 0; stream < 4; ++stream) {
203 _Alignas(32)
float products[8];
204 const int offset = col + stream * 8;
205 for (
int lane = 0; lane < 8; ++lane) {
207 left[offset + lane] *
right[offset + lane]);
209 streams[stream] = _mm256_add_ps(
210 streams[stream], _mm256_load_ps(products));
213 __m256 reduced = _mm256_add_ps(streams[0], streams[1]);
214 reduced = _mm256_add_ps(reduced, streams[2]);
215 reduced = _mm256_add_ps(reduced, streams[3]);
216 _Alignas(32)
float lanes[8];
217 _mm256_store_ps(lanes, reduced);
218 volatile float sum = 0.0f;
219 for (
int lane = 0; lane < 8; ++lane) sum = sum + lanes[lane];
220 for (; col < dim; ++col) {
226 volatile float sum = 0.0f;
227 for (
int col = 0; col < dim; ++col) {
237 volatile double sum = 0.0;
238 for (
int col = 0; col < dim; ++col) {
239 const float product =
left[col] *
right[col];
240 sum = sum + (double)product;
246 const float *hyper_input,
247 const float *key_projected,
248 const float *value_projected,
249 const float *norm_key_weight,
250 const float *norm_query_weight,
251 const float *norm_conv_weight,
252 const void *conv_weight,
254 float *key_norm_scratch,
255 float *query_norm_scratch,
256 float *gated_scratch,
257 float *conv_norm_scratch,
258 const float *conv_state_in,
259 float *conv_state_out,
266 int conv_weight_is_fp16,
267 int llama_fp32_arithmetic) {
268 if (!hyper_input || !key_projected || !value_projected || !norm_key_weight ||
269 !norm_query_weight || !norm_conv_weight || !conv_weight || !hyper_output ||
270 !key_norm_scratch || !query_norm_scratch || !gated_scratch ||
271 !conv_norm_scratch || !conv_state_in || !conv_state_out || rows <= 0 || streams <= 0 ||
272 hidden_dim <= 0 || kernel_size <= 0 || dilation <= 0)
return;
274 const int channels = streams * hidden_dim;
275 const int history = (kernel_size - 1) * dilation;
276 const float inv_sqrt_hidden = 1.0f / sqrtf((
float)hidden_dim);
277 for (
int row = 0; row < rows; ++row) {
278 const float *hyper_row = hyper_input + (size_t)row * channels;
279 const float *key_row = key_projected + (size_t)row * channels;
280 const float *value_row = value_projected + (size_t)row * hidden_dim;
281 float *key_norm = key_norm_scratch + (size_t)row * channels;
282 float *query_norm = query_norm_scratch + (size_t)row * channels;
283 float *gated = gated_scratch + (size_t)row * channels;
284 float *conv_norm = conv_norm_scratch + (size_t)row * channels;
285 if (llama_fp32_arithmetic) {
287 key_row, norm_key_weight, key_norm, streams, hidden_dim, eps);
289 hyper_row, norm_query_weight, query_norm, streams, hidden_dim, eps);
292 key_row, norm_key_weight, key_norm, streams, hidden_dim, eps);
294 hyper_row, norm_query_weight, query_norm, streams, hidden_dim, eps);
296 for (
int stream = 0; stream < streams; ++stream) {
297 const size_t base = (size_t)stream * hidden_dim;
298 const float dot = llama_fp32_arithmetic
300 key_norm + base, query_norm + base, hidden_dim)
302 key_norm + base, query_norm + base, hidden_dim);
303 const float scaled_gate = llama_fp32_arithmetic
304 ? dot * inv_sqrt_hidden
306 const float signed_root = copysignf(
307 sqrtf(fmaxf(fabsf(scaled_gate), 1.0e-6f)), scaled_gate);
308 const float gate = llama_fp32_arithmetic
311 const float sigmoid = 1.0f / (1.0f + expf(-gate));
312 const float sigmoid_gate = llama_fp32_arithmetic
315 for (
int col = 0; col < hidden_dim; ++col) {
316 const float product = sigmoid_gate * value_row[col];
317 gated[base + col] = llama_fp32_arithmetic
322 if (llama_fp32_arithmetic) {
324 gated, norm_conv_weight, conv_norm, streams, hidden_dim, eps);
327 gated, norm_conv_weight, conv_norm, streams, hidden_dim, eps);
331 for (
int row = 0; row < rows; ++row) {
332 const float *hyper_row = hyper_input + (size_t)row * channels;
333 const float *gated = gated_scratch + (size_t)row * channels;
334 float *out_row = hyper_output + (size_t)row * channels;
335 for (
int channel0 = 0; channel0 < channels; channel0 += 16) {
336 const int active = channel0 + 16 <= channels
338 : channels - channel0;
340 for (
int lane = 0; lane < active; ++lane) {
341 const int channel = channel0 + lane;
342 volatile float sum = 0.0f;
343 for (
int tap = 0; tap < kernel_size; ++tap) {
344 const int source_row =
345 row - (kernel_size - 1 - tap) * dilation;
346 const float source = source_row >= 0
348 (size_t)source_row * channels + channel]
350 (size_t)(history + source_row) * channels + channel];
351 const size_t weight_index =
352 (size_t)channel * kernel_size + tap;
353 const float weight = conv_weight_is_fp16
355 ((
const uint16_t *)conv_weight)[weight_index])
357 ((
const uint16_t *)conv_weight) + weight_index);
358 volatile float product = source * weight;
361 conv_tile[lane] = llama_fp32_arithmetic
365 if (llama_fp32_arithmetic) {
367 conv_tile, conv_tile, 1, active);
369 for (
int lane = 0; lane < active; ++lane) {
370 const int channel = channel0 + lane;
371 if (llama_fp32_arithmetic) {
372 const float ple = gated[channel] + conv_tile[lane];
373 out_row[channel] = hyper_row[channel] + ple;
375 const float conv = conv_tile[lane];
376 const float silu_raw = conv / (1.0f + expf(-conv));
387 if (rows >= history) {
388 memcpy(conv_state_out,
389 conv_norm_scratch + (
size_t)(rows - history) * channels,
390 (
size_t)history * channels *
sizeof(*conv_state_out));
392 memmove(conv_state_out,
393 conv_state_in + (
size_t)rows * channels,
394 (
size_t)(history - rows) * channels *
sizeof(*conv_state_out));
395 memcpy(conv_state_out + (
size_t)(history - rows) * channels,
397 (
size_t)rows * channels *
sizeof(*conv_state_out));
403 const float *hyper_input,
const float *key_projected,
404 const float *value_projected,
const float *norm_key_weight,
405 const float *norm_query_weight,
const float *norm_conv_weight,
406 const uint16_t *conv_weight,
float *hyper_output,
407 float *key_norm_scratch,
float *query_norm_scratch,
float *gated_scratch,
408 float *conv_norm_scratch,
const float *conv_state_in,
409 float *conv_state_out,
int rows,
int streams,
int hidden_dim,
410 int kernel_size,
int dilation,
float eps) {
412 hyper_input, key_projected, value_projected, norm_key_weight,
413 norm_query_weight, norm_conv_weight, conv_weight, hyper_output,
414 key_norm_scratch, query_norm_scratch, gated_scratch, conv_norm_scratch,
415 conv_state_in, conv_state_out, rows, streams, hidden_dim, kernel_size,
416 dilation, eps, 0, 0);
420 const float *hyper_input,
const float *key_projected,
421 const float *value_projected,
const float *norm_key_weight,
422 const float *norm_query_weight,
const float *norm_conv_weight,
423 const uint16_t *conv_weight,
float *hyper_output,
424 float *key_norm_scratch,
float *query_norm_scratch,
float *gated_scratch,
425 float *conv_norm_scratch,
const float *conv_state_in,
426 float *conv_state_out,
int rows,
int streams,
int hidden_dim,
427 int kernel_size,
int dilation,
float eps) {
429 hyper_input, key_projected, value_projected, norm_key_weight,
430 norm_query_weight, norm_conv_weight, conv_weight, hyper_output,
431 key_norm_scratch, query_norm_scratch, gated_scratch, conv_norm_scratch,
432 conv_state_in, conv_state_out, rows, streams, hidden_dim, kernel_size,
433 dilation, eps, 1, 0);
437 const float *hyper_input,
const float *key_projected,
438 const float *value_projected,
const float *norm_key_weight,
439 const float *norm_query_weight,
const float *norm_conv_weight,
440 const uint16_t *conv_weight,
float *hyper_output,
441 float *key_norm_scratch,
float *query_norm_scratch,
float *gated_scratch,
442 float *conv_norm_scratch,
const float *conv_state_in,
443 float *conv_state_out,
int rows,
int streams,
int hidden_dim,
444 int kernel_size,
int dilation,
float eps) {
446 hyper_input, key_projected, value_projected, norm_key_weight,
447 norm_query_weight, norm_conv_weight, conv_weight, hyper_output,
448 key_norm_scratch, query_norm_scratch, gated_scratch, conv_norm_scratch,
449 conv_state_in, conv_state_out, rows, streams, hidden_dim, kernel_size,
450 dilation, eps, 1, 1);
459 for (
int head = 0; head < heads; ++head) {
460 const float *in_head = input + (size_t)head * head_dim;
461 float *out_head = output + (size_t)head * head_dim;
463 for (
int col = 0; col < head_dim; ++col) sum_sq += in_head[col] * in_head[col];
464 const float scale = 1.0f / sqrtf(sum_sq / (
float)head_dim + eps);
465 for (
int col = 0; col < head_dim; ++col) {
475 const int half = rotary_dim / 2;
476 for (
int index = 0; index < half; ++index) {
477 const float inverse_frequency = powf(theta, -2.0f * (
float)index / (
float)rotary_dim);
478 const float angle = (float)position * inverse_frequency;
479 const float cosine = cosf(angle);
480 const float sine = sinf(angle);
481 const float first = vector[index];
482 const float second = vector[index + half];
489 const float *projected_qk,
490 const float *index_key_cache_in,
491 const float *q_norm_weight,
492 const float *k_norm_weight,
493 float *selected_indices,
494 float *index_key_cache_out,
495 float *q_norm_scratch,
496 float *pooled_key_scratch,
497 float *block_score_scratch,
498 int32_t *block_index_scratch,
509 if (!projected_qk || !index_key_cache_in || !q_norm_weight || !k_norm_weight ||
510 !selected_indices || !index_key_cache_out || !q_norm_scratch ||
511 !pooled_key_scratch || !block_score_scratch || !block_index_scratch ||
512 rows <= 0 || query_heads <= 0 || index_head_dim <= 0 || token_budget <= 0 ||
513 compress_ratio <= 0 || rotary_dim <= 0 || rotary_dim > index_head_dim ||
514 context_length <= 0 || position < 0 || rows > context_length - position)
return;
516 const int projected_dim = (query_heads + 1) * index_head_dim;
517 const int selection_width = token_budget + compress_ratio - 1;
518 const int block_topk = token_budget / compress_ratio;
519 if (index_key_cache_out != index_key_cache_in && position > 0) {
520 memcpy(index_key_cache_out, index_key_cache_in,
521 (
size_t)position * index_head_dim *
sizeof(*index_key_cache_out));
524 for (
int row = 0; row < rows; ++row) {
525 const int absolute_position = position + row;
526 const float *projected = projected_qk + (size_t)row * projected_dim;
527 float *query_normed = q_norm_scratch;
529 query_heads, index_head_dim, eps);
530 for (
int head = 0; head < query_heads; ++head) {
532 rotary_dim, absolute_position, rope_theta);
534 float *raw_key = index_key_cache_out + (size_t)absolute_position * index_head_dim;
535 const float *projected_key = projected + (size_t)query_heads * index_head_dim;
536 for (
int col = 0; col < index_head_dim; ++col) {
540 float *selected_row = selected_indices + (size_t)row * selection_width;
541 for (
int slot = 0; slot < selection_width; ++slot) selected_row[slot] = -1.0f;
542 const int visible = absolute_position + 1;
543 const int complete_blocks = visible / compress_ratio;
544 const int selected_blocks = complete_blocks < block_topk ? complete_blocks : block_topk;
545 for (
int slot = 0; slot < selected_blocks; ++slot) {
546 block_score_scratch[slot] = -INFINITY;
547 block_index_scratch[slot] = -1;
550 for (
int block = 0; block < complete_blocks; ++block) {
551 const int block_start = block * compress_ratio;
552 for (
int col = 0; col < index_head_dim; ++col) {
555 sum += index_key_cache_out[
556 (size_t)(block_start +
token) * index_head_dim + col];
561 pooled_key_scratch, 1, index_head_dim, eps);
564 for (
int head = 0; head < query_heads; ++head) {
565 const float *query_head = query_normed + (size_t)head * index_head_dim;
567 for (
int col = 0; col < index_head_dim; ++col) {
568 dot += query_head[col] * pooled_key_scratch[col];
570 if (dot > 0.0f)
score += dot;
572 score /= sqrtf((
float)index_head_dim);
574 for (
int slot = 0; slot < selected_blocks; ++slot) {
575 if (target < 0 || block_score_scratch[slot] < block_score_scratch[target]) target = slot;
577 if (target >= 0 &&
score > block_score_scratch[target]) {
578 block_score_scratch[target] =
score;
579 block_index_scratch[target] = block;
583 for (
int outer = 1; outer < selected_blocks; ++outer) {
584 const int32_t value = block_index_scratch[outer];
585 int inner = outer - 1;
586 while (inner >= 0 && block_index_scratch[inner] > value) {
587 block_index_scratch[inner + 1] = block_index_scratch[inner];
590 block_index_scratch[inner + 1] = value;
592 int output_count = 0;
593 for (
int slot = 0; slot < selected_blocks; ++slot) {
594 const int block = block_index_scratch[slot];
595 if (block < 0)
continue;
597 selected_row[output_count++] = (float)(block * compress_ratio +
token);
600 for (
int token = complete_blocks * compress_ratio;
601 token < visible && output_count < selection_width; ++
token) {
602 selected_row[output_count++] = (float)
token;
static size_t ck_dtype_row_bytes(CKDataType dt, size_t n_elements)
Calculate total bytes for n_elements of given dtype.
void rmsnorm_forward_qwen3next_pytorch_bf16_storage(const float *input, const float *gamma, float *output, float *rstd_cache, int tokens, int d_model, int aligned_embed_dim, float eps)
void rmsnorm_forward_llama_production(const float *input, const float *gamma, float *output, float *rstd_cache, int tokens, int d_model, int aligned_embed_dim, float eps)
void dequant_q5_0_row(const void *src, float *dst, size_t n_elements)
Dequantize Q5_0 row (multiple blocks)
void recurrent_silu_forward_ggml(const float *x, float *out, int rows, int dim)
static float ck_fp16_to_fp32(ck_half h)
static float qwen4_bf16_load(const uint16_t *value)
static void qwen4_ple_gate_conv_inject_impl(const float *hyper_input, const float *key_projected, const float *value_projected, const float *norm_key_weight, const float *norm_query_weight, const float *norm_conv_weight, const void *conv_weight, float *hyper_output, float *key_norm_scratch, float *query_norm_scratch, float *gated_scratch, float *conv_norm_scratch, const float *conv_state_in, float *conv_state_out, int rows, int streams, int hidden_dim, int kernel_size, int dilation, float eps, int conv_weight_is_fp16, int llama_fp32_arithmetic)
void qwen4_ple_gate_conv_inject_bf16(const float *hyper_input, const float *key_projected, const float *value_projected, const float *norm_key_weight, const float *norm_query_weight, const float *norm_conv_weight, const uint16_t *conv_weight, float *hyper_output, float *key_norm_scratch, float *query_norm_scratch, float *gated_scratch, float *conv_norm_scratch, const float *conv_state_in, float *conv_state_out, int rows, int streams, int hidden_dim, int kernel_size, int dilation, float eps)
void qwen4_ple_gate_conv_inject_llama_fp16(const float *hyper_input, const float *key_projected, const float *value_projected, const float *norm_key_weight, const float *norm_query_weight, const float *norm_conv_weight, const uint16_t *conv_weight, float *hyper_output, float *key_norm_scratch, float *query_norm_scratch, float *gated_scratch, float *conv_norm_scratch, const float *conv_state_in, float *conv_state_out, int rows, int streams, int hidden_dim, int kernel_size, int dilation, float eps)
static void qwen4_group_rmsnorm_llama(const float *input, const float *weight, float *output, int groups, int hidden_dim, float eps)
static float qwen4_bf16_round(float value)
static float qwen4_llama_mul_sum_rows(const float *left, const float *right, int dim)
void qwen4_qsa_index_select_bf16(const float *projected_qk, const float *index_key_cache_in, const float *q_norm_weight, const float *k_norm_weight, float *selected_indices, float *index_key_cache_out, float *q_norm_scratch, float *pooled_key_scratch, float *block_score_scratch, int32_t *block_index_scratch, int rows, int query_heads, int index_head_dim, int token_budget, int compress_ratio, int rotary_dim, int context_length, int position, float rope_theta, float eps)
static void qwen4_group_rmsnorm_pytorch_bf16(const float *input, const float *weight, float *output, int groups, int hidden_dim, float eps)
void qwen4_ple_gate_conv_inject_fp16(const float *hyper_input, const float *key_projected, const float *value_projected, const float *norm_key_weight, const float *norm_query_weight, const float *norm_conv_weight, const uint16_t *conv_weight, float *hyper_output, float *key_norm_scratch, float *query_norm_scratch, float *gated_scratch, float *conv_norm_scratch, const float *conv_state_in, float *conv_state_out, int rows, int streams, int hidden_dim, int kernel_size, int dilation, float eps)
void qwen4_ple_ngram_embed_q5_0(const int32_t *token_ids, const void *embedding, const int64_t *layer_multipliers, const int64_t *head_offsets, const int64_t *head_vocab_sizes, float *output, const float *token_state_in, float *token_state_out, int rows, int ngram_size, int heads_per_ngram, int head_dim, int eos_token_id, int position_offset)
void qwen4_ple_ngram_embed_bf16(const int32_t *token_ids, const uint16_t *embedding, const int64_t *layer_multipliers, const int64_t *head_offsets, const int64_t *head_vocab_sizes, float *output, const float *token_state_in, float *token_state_out, int rows, int ngram_size, int heads_per_ngram, int head_dim, int eos_token_id, int position_offset)
static int32_t qwen4_history_token(const int32_t *tokens, const float *state, int row, int shift, int state_len, int eos_token_id, int position)
static void qwen4_rope_split_inplace(float *vector, int rotary_dim, int position, float theta)
static float qwen4_pytorch_bf16_dot(const float *left, const float *right, int dim)
static void qwen4_ple_ngram_embed_impl(const int32_t *token_ids, const void *embedding, const int64_t *layer_multipliers, const int64_t *head_offsets, const int64_t *head_vocab_sizes, float *output, const float *token_state_in, float *token_state_out, int rows, int ngram_size, int heads_per_ngram, int head_dim, int eos_token_id, int position_offset, int embedding_is_q5_0)
static void qwen4_shared_head_rmsnorm(const float *input, const float *weight, float *output, int heads, int head_dim, float eps)
const char const char * right
static void silu(float *x, int n)