← Back to C-Kernel-Engine Docs Doxygen Source Documentation
 
Loading...
Searching...
No Matches
hyper_connection_kernels.c
Go to the documentation of this file.
1#include "ckernel_engine.h"
2#include "bf16_utils.h"
3
4#include <math.h>
5#include <stddef.h>
6#include <stdint.h>
7#include <string.h>
8
10 const void *A, const void *B, const float *bias, float *C,
11 int M, int N, int K);
12void gemv_q4_k_q8_k_avx2(float *y,
13 const void *W,
14 const void *x_q8,
15 int M,
16 int K);
18 const void *A, const void *B, const float *bias, float *C,
19 int M, int N, int K);
21 const void *A, const void *B, const float *bias, float *C,
22 int M, int N, int K);
23
24static inline float ck_bf16_round(float value) {
25 return bf16_to_float(float_to_bf16(value));
26}
27
28static inline float ck_sigmoid_bf16(float value) {
29 return ck_bf16_round(1.0f / (1.0f + expf(-value)));
30}
31
32void hyper_stream_expand_f32(const float *input,
33 float *output,
34 int rows,
35 int streams,
36 int hidden_dim) {
37 if (!input || !output || rows <= 0 || streams <= 0 || hidden_dim <= 0) {
38 return;
39 }
40 for (int row = 0; row < rows; ++row) {
41 const float *src = input + (size_t)row * (size_t)hidden_dim;
42 float *dst = output + (size_t)row * (size_t)streams * (size_t)hidden_dim;
43 for (int stream = 0; stream < streams; ++stream) {
44 for (int col = 0; col < hidden_dim; ++col) {
45 dst[(size_t)stream * (size_t)hidden_dim + (size_t)col] = src[col];
46 }
47 }
48 }
49}
50
51void hyper_stream_expand_bf16(const float *input,
52 float *output,
53 int rows,
54 int streams,
55 int hidden_dim) {
56 if (!input || !output || rows <= 0 || streams <= 0 || hidden_dim <= 0) {
57 return;
58 }
59 for (int row = 0; row < rows; ++row) {
60 const float *src = input + (size_t)row * (size_t)hidden_dim;
61 float *dst = output + (size_t)row * (size_t)streams * (size_t)hidden_dim;
62 for (int stream = 0; stream < streams; ++stream) {
63 for (int col = 0; col < hidden_dim; ++col) {
64 dst[(size_t)stream * (size_t)hidden_dim + (size_t)col] =
65 ck_bf16_round(src[col]);
66 }
67 }
68 }
69}
70
71void hyper_connection_mix_bf16(const float *hyper_input,
72 const float *norm_weight,
73 const uint16_t *mix_down_weight,
74 const uint16_t *mix_up_weight,
75 const uint16_t *inject_weight,
76 float *mixed_output,
77 float *injection_output,
78 float *normalized_scratch,
79 float *dynamic_scratch,
80 float *mix_scratch,
81 int rows,
82 int streams,
83 int hidden_dim,
84 int dynamic_dim,
85 float eps,
86 int emit_injection) {
87 if (!hyper_input || !norm_weight || !mix_down_weight || !mix_up_weight ||
88 !mixed_output || !normalized_scratch || !dynamic_scratch || !mix_scratch ||
89 rows <= 0 || streams <= 0 || hidden_dim <= 0 || dynamic_dim <= 0) {
90 return;
91 }
92 if (emit_injection && (!inject_weight || !injection_output)) {
93 return;
94 }
95
96 const int hyper_dim = streams * hidden_dim;
97 const float inv_streams = 1.0f / (float)streams;
98
99 for (int row = 0; row < rows; ++row) {
100 const float *input_row =
101 hyper_input + (size_t)row * (size_t)hyper_dim;
102 float *norm_row =
103 normalized_scratch + (size_t)row * (size_t)hyper_dim;
104 float *dynamic_row =
105 dynamic_scratch + (size_t)row * (size_t)dynamic_dim;
106 float *mix_row = mix_scratch + (size_t)row * (size_t)hyper_dim;
107
108 for (int stream = 0; stream < streams; ++stream) {
109 const int base = stream * hidden_dim;
111 input_row + base,
112 norm_weight + base,
113 norm_row + base,
114 NULL,
115 1,
116 hidden_dim,
117 hidden_dim,
118 eps
119 );
120 }
121
122 for (int out = 0; out < dynamic_dim; ++out) {
123 const uint16_t *weight_row =
124 mix_down_weight + (size_t)out * (size_t)hyper_dim;
125 float sum = 0.0f;
126 for (int col = 0; col < hyper_dim; ++col) {
127 sum += norm_row[col] * bf16_to_float(weight_row[col]);
128 }
129 const float projected = ck_bf16_round(sum * inv_streams);
130 dynamic_row[out] = ck_bf16_round(
131 projected / (1.0f + expf(-projected)));
132 }
133
134 for (int out = 0; out < hyper_dim; ++out) {
135 const uint16_t *weight_row =
136 mix_up_weight + (size_t)out * (size_t)dynamic_dim;
137 float sum = 0.0f;
138 for (int col = 0; col < dynamic_dim; ++col) {
139 sum += dynamic_row[col] * bf16_to_float(weight_row[col]);
140 }
141 mix_row[out] = ck_sigmoid_bf16(ck_bf16_round(sum));
142 }
143
144 float *mixed_row =
145 mixed_output + (size_t)row * (size_t)hidden_dim;
146 for (int col = 0; col < hidden_dim; ++col) {
147 float sum = 0.0f;
148 for (int stream = 0; stream < streams; ++stream) {
149 const int index = stream * hidden_dim + col;
150 sum += ck_bf16_round(norm_row[index] * mix_row[index]);
151 }
152 mixed_row[col] = ck_bf16_round(sum * inv_streams);
153 }
154
155 if (emit_injection) {
156 float *injection_row =
157 injection_output + (size_t)row * (size_t)streams;
158 for (int stream = 0; stream < streams; ++stream) {
159 const uint16_t *weight_row =
160 inject_weight + (size_t)stream * (size_t)hyper_dim;
161 float sum = 0.0f;
162 for (int col = 0; col < hyper_dim; ++col) {
163 sum += norm_row[col] * bf16_to_float(weight_row[col]);
164 }
165 injection_row[stream] = ck_bf16_round(
166 2.0f * ck_sigmoid_bf16(ck_bf16_round(sum * inv_streams)));
167 }
168 }
169 }
170}
171
172typedef void (*ck_hyper_q8k_gemm_fn)(
173 const void *, const void *, const float *, float *, int, int, int);
174
176 const void *input,
177 const void *weight,
178 const float *bias,
179 float *output,
180 int rows,
181 int output_dim,
182 int input_dim) {
183 if (!input || !weight || !output || rows <= 0 || output_dim <= 0 ||
184 input_dim <= 0 || input_dim % QK_K != 0) {
185 return;
186 }
187
188 const size_t input_row_bytes =
189 (size_t)(input_dim / QK_K) * sizeof(block_q8_K);
190 for (int row = 0; row < rows; ++row) {
191 float *output_row = output + (size_t)row * (size_t)output_dim;
192 const void *input_row =
193 (const uint8_t *)input + (size_t)row * input_row_bytes;
195 output_row, weight, input_row, output_dim, input_dim);
196 if (bias) {
197 for (int col = 0; col < output_dim; ++col) {
198 output_row[col] += bias[col];
199 }
200 }
201 }
202}
203
204static void hyper_connection_mix_quantized(const float *hyper_input,
205 const float *norm_weight,
206 const void *mix_down_weight,
207 const void *mix_up_weight,
208 const void *inject_weight,
209 float *mixed_output,
210 float *injection_output,
211 float *normalized_scratch,
212 float *dynamic_scratch,
213 float *mix_scratch,
214 int rows,
215 int streams,
216 int hidden_dim,
217 int dynamic_dim,
218 float eps,
219 int emit_injection,
220 ck_hyper_q8k_gemm_fn injection_gemm,
221 ck_hyper_q8k_gemm_fn down_gemm) {
222 if (!hyper_input || !norm_weight || !mix_down_weight || !mix_up_weight ||
223 !mixed_output || !normalized_scratch || !dynamic_scratch || !mix_scratch ||
224 !injection_gemm || !down_gemm || rows <= 0 || streams <= 0 || hidden_dim <= 0 ||
225 dynamic_dim <= 0) {
226 return;
227 }
228 if (emit_injection && (!inject_weight || !injection_output)) {
229 return;
230 }
231
232 const int hyper_dim = streams * hidden_dim;
233 const float inv_streams = 1.0f / (float)streams;
234 if (hyper_dim % QK_K != 0 || dynamic_dim % QK8_0 != 0) {
235 return;
236 }
237
238 const size_t normalized_q8_row_bytes =
239 (size_t)(hyper_dim / QK_K) * sizeof(block_q8_K);
240 const size_t dynamic_q8_row_bytes =
241 (size_t)(dynamic_dim / QK8_0) * sizeof(block_q8_0);
242 block_q8_K *normalized_q8 = (block_q8_K *)mix_scratch;
243 block_q8_0 dynamic_q8[dynamic_dim / QK8_0];
244
245 for (int row = 0; row < rows; ++row) {
246 const float *input_row = hyper_input + (size_t)row * (size_t)hyper_dim;
247 float *norm_row = normalized_scratch + (size_t)row * (size_t)hyper_dim;
248 for (int stream = 0; stream < streams; ++stream) {
249 const int base = stream * hidden_dim;
250 double sum_sq = 0.0;
251 for (int col = 0; col < hidden_dim; ++col) {
252 const float value = input_row[base + col];
253 sum_sq += (double)(value * value);
254 }
255 const float mean = (float)(sum_sq / (double)hidden_dim);
256 const float rstd = 1.0f / sqrtf(mean + eps);
257 for (int col = 0; col < hidden_dim; ++col) {
258 const int index = base + col;
259 norm_row[index] = input_row[index] * rstd * norm_weight[index];
260 }
261 }
262
264 norm_row,
265 (uint8_t *)normalized_q8 + (size_t)row * normalized_q8_row_bytes,
266 hyper_dim);
267 }
268
269 down_gemm(
270 normalized_q8,
271 mix_down_weight,
272 NULL,
273 dynamic_scratch,
274 rows,
275 dynamic_dim,
276 hyper_dim);
277
278 if (emit_injection) {
279 injection_gemm(
280 normalized_q8,
281 inject_weight,
282 NULL,
283 injection_output,
284 rows,
285 streams,
286 hyper_dim);
287 for (int row = 0; row < rows; ++row) {
288 float *injection_row = injection_output + (size_t)row * (size_t)streams;
289 for (int stream = 0; stream < streams; ++stream) {
290 injection_row[stream] *= inv_streams;
291 }
293 injection_row, injection_row, 1, streams);
294 for (int stream = 0; stream < streams; ++stream) {
295 injection_row[stream] *= 2.0f;
296 }
297 }
298 }
299
300 for (int row = 0; row < rows; ++row) {
301 float *dynamic_row = dynamic_scratch + (size_t)row * (size_t)dynamic_dim;
302 for (int col = 0; col < dynamic_dim; ++col) {
303 dynamic_row[col] *= inv_streams;
304 }
306 dynamic_row, dynamic_row, 1, dynamic_dim);
307
308 quantize_row_q8_0(dynamic_row, dynamic_q8, dynamic_dim);
309 memcpy(
310 (uint8_t *)dynamic_scratch + (size_t)row * dynamic_q8_row_bytes,
311 dynamic_q8,
312 dynamic_q8_row_bytes);
313 }
314
316 dynamic_scratch,
317 mix_up_weight,
318 NULL,
319 mix_scratch,
320 rows,
321 hyper_dim,
322 dynamic_dim);
323
324 for (int row = 0; row < rows; ++row) {
325 const float *norm_row =
326 normalized_scratch + (size_t)row * (size_t)hyper_dim;
327 float *mix_row = mix_scratch + (size_t)row * (size_t)hyper_dim;
329 mix_row, mix_row, 1, hyper_dim);
330
331 float *mixed_row = mixed_output + (size_t)row * (size_t)hidden_dim;
332 for (int col = 0; col < hidden_dim; ++col) {
333 float sum = 0.0f;
334 for (int stream = 0; stream < streams; ++stream) {
335 const int index = stream * hidden_dim + col;
336 sum += norm_row[index] * mix_row[index];
337 }
338 mixed_row[col] = sum * inv_streams;
339 }
340
341 }
342}
343
344void hyper_connection_mix_q4k_q5_0_q4k(const float *hyper_input,
345 const float *norm_weight,
346 const void *mix_down_weight,
347 const void *mix_up_weight,
348 const void *inject_weight,
349 float *mixed_output,
350 float *injection_output,
351 float *normalized_scratch,
352 float *dynamic_scratch,
353 float *mix_scratch,
354 int rows,
355 int streams,
356 int hidden_dim,
357 int dynamic_dim,
358 float eps,
359 int emit_injection) {
361 hyper_input, norm_weight, mix_down_weight, mix_up_weight, inject_weight,
362 mixed_output, injection_output, normalized_scratch, dynamic_scratch,
363 mix_scratch, rows, streams, hidden_dim, dynamic_dim, eps,
366}
367
368void hyper_connection_mix_q6k_q5_0_q4k(const float *hyper_input,
369 const float *norm_weight,
370 const void *mix_down_weight,
371 const void *mix_up_weight,
372 const void *inject_weight,
373 float *mixed_output,
374 float *injection_output,
375 float *normalized_scratch,
376 float *dynamic_scratch,
377 float *mix_scratch,
378 int rows,
379 int streams,
380 int hidden_dim,
381 int dynamic_dim,
382 float eps,
383 int emit_injection) {
385 hyper_input, norm_weight, mix_down_weight, mix_up_weight, inject_weight,
386 mixed_output, injection_output, normalized_scratch, dynamic_scratch,
387 mix_scratch, rows, streams, hidden_dim, dynamic_dim, eps,
390}
391
392void hyper_stream_inject_bf16(const float *hyper_input,
393 const float *block_output,
394 const float *injection_weight,
395 float *output,
396 int rows,
397 int streams,
398 int hidden_dim) {
399 if (!hyper_input || !block_output || !injection_weight || !output ||
400 rows <= 0 || streams <= 0 || hidden_dim <= 0) {
401 return;
402 }
403 const int hyper_dim = streams * hidden_dim;
404 for (int row = 0; row < rows; ++row) {
405 const float *hyper_row =
406 hyper_input + (size_t)row * (size_t)hyper_dim;
407 const float *block_row =
408 block_output + (size_t)row * (size_t)hidden_dim;
409 const float *inject_row =
410 injection_weight + (size_t)row * (size_t)streams;
411 float *output_row = output + (size_t)row * (size_t)hyper_dim;
412 for (int stream = 0; stream < streams; ++stream) {
413 for (int col = 0; col < hidden_dim; ++col) {
414 const int index = stream * hidden_dim + col;
415 output_row[index] = ck_bf16_round(
416 hyper_row[index] +
417 ck_bf16_round(block_row[col] * inject_row[stream]));
418 }
419 }
420 }
421}
422
423void hyper_stream_inject_f32(const float *hyper_input,
424 const float *block_output,
425 const float *injection_weight,
426 float *output,
427 int rows,
428 int streams,
429 int hidden_dim) {
430 if (!hyper_input || !block_output || !injection_weight || !output ||
431 rows <= 0 || streams <= 0 || hidden_dim <= 0) {
432 return;
433 }
434 const int hyper_dim = streams * hidden_dim;
435 for (int row = 0; row < rows; ++row) {
436 const float *hyper_row =
437 hyper_input + (size_t)row * (size_t)hyper_dim;
438 const float *block_row =
439 block_output + (size_t)row * (size_t)hidden_dim;
440 const float *inject_row =
441 injection_weight + (size_t)row * (size_t)streams;
442 float *output_row = output + (size_t)row * (size_t)hyper_dim;
443 for (int stream = 0; stream < streams; ++stream) {
444 for (int col = 0; col < hidden_dim; ++col) {
445 const int index = stream * hidden_dim + col;
446 volatile const float weighted =
447 block_row[col] * inject_row[stream];
448 output_row[index] = hyper_row[index] + weighted;
449 }
450 }
451 }
452}
static uint16_t float_to_bf16(float f)
Definition bf16_utils.h:90
static float bf16_to_float(uint16_t v)
Definition bf16_utils.h:38
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 recurrent_sigmoid_forward_ggml(const float *x, float *out, int rows, int dim)
void recurrent_silu_forward_ggml(const float *x, float *out, int rows, int dim)
void quantize_row_q8_k(const float *x, void *y, int k)
void quantize_row_q8_0(const float *x, void *y, int k)
Quantize FP32 to Q8_0 format (scalar reference)
#define QK8_0
#define QK_K
void hyper_connection_mix_q4k_q5_0_q4k(const float *hyper_input, const float *norm_weight, const void *mix_down_weight, const void *mix_up_weight, const void *inject_weight, float *mixed_output, float *injection_output, float *normalized_scratch, float *dynamic_scratch, float *mix_scratch, int rows, int streams, int hidden_dim, int dynamic_dim, float eps, int emit_injection)
static float ck_sigmoid_bf16(float value)
void gemv_q4_k_q8_k_avx2(float *y, const void *W, const void *x_q8, int M, int K)
void hyper_connection_mix_bf16(const float *hyper_input, const float *norm_weight, const uint16_t *mix_down_weight, const uint16_t *mix_up_weight, const uint16_t *inject_weight, float *mixed_output, float *injection_output, float *normalized_scratch, float *dynamic_scratch, float *mix_scratch, int rows, int streams, int hidden_dim, int dynamic_dim, float eps, int emit_injection)
void hyper_stream_expand_f32(const float *input, float *output, int rows, int streams, int hidden_dim)
void hyper_stream_inject_bf16(const float *hyper_input, const float *block_output, const float *injection_weight, float *output, int rows, int streams, int hidden_dim)
void hyper_connection_mix_q6k_q5_0_q4k(const float *hyper_input, const float *norm_weight, const void *mix_down_weight, const void *mix_up_weight, const void *inject_weight, float *mixed_output, float *injection_output, float *normalized_scratch, float *dynamic_scratch, float *mix_scratch, int rows, int streams, int hidden_dim, int dynamic_dim, float eps, int emit_injection)
void gemm_nt_q6_k_q8_k_parallel_dispatch(const void *A, const void *B, const float *bias, float *C, int M, int N, int K)
static float ck_bf16_round(float value)
void hyper_stream_inject_f32(const float *hyper_input, const float *block_output, const float *injection_weight, float *output, int rows, int streams, int hidden_dim)
void(* ck_hyper_q8k_gemm_fn)(const void *, const void *, const float *, float *, int, int, int)
void gemm_nt_q4_k_q8_k_pairwise_split_min_parallel_dispatch(const void *A, const void *B, const float *bias, float *C, int M, int N, int K)
static void hyper_connection_mix_quantized(const float *hyper_input, const float *norm_weight, const void *mix_down_weight, const void *mix_up_weight, const void *inject_weight, float *mixed_output, float *injection_output, float *normalized_scratch, float *dynamic_scratch, float *mix_scratch, int rows, int streams, int hidden_dim, int dynamic_dim, float eps, int emit_injection, ck_hyper_q8k_gemm_fn injection_gemm, ck_hyper_q8k_gemm_fn down_gemm)
void hyper_stream_expand_bf16(const float *input, float *output, int rows, int streams, int hidden_dim)
static void hyper_injection_q4k_q8k_llama_dispatch(const void *input, const void *weight, const float *bias, float *output, int rows, int output_dim, int input_dim)
void gemm_nt_q5_0_q8_0_parallel_dispatch(const void *A, const void *B, const float *bias, float *C, int M, int N, int K)
#define C(color)
Definition show_config.c:39