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