← Back to C-Kernel-Engine Docs Doxygen Source Documentation
 
Loading...
Searching...
No Matches
hyper_connection_kernels.c File Reference
#include "ckernel_engine.h"
#include "bf16_utils.h"
#include <math.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>

Go to the source code of this file.

Typedefs

typedef void(* ck_hyper_q8k_gemm_fn) (const void *, const void *, const float *, float *, int, int, int)
 

Functions

static float ck_bf16_round (float value)
 
static float ck_sigmoid_bf16 (float value)
 
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)
 
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)
 
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)
 
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_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)
 
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)
 
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)
 
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 hyper_stream_expand_bf16 (const float *input, float *output, int rows, int streams, int hidden_dim)
 
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_stream_inject_f32 (const float *hyper_input, const float *block_output, const float *injection_weight, float *output, int rows, int streams, int hidden_dim)
 

Typedef Documentation

◆ ck_hyper_q8k_gemm_fn

typedef void(* ck_hyper_q8k_gemm_fn) (const void *, const void *, const float *, float *, int, int, int)

Definition at line 174 of file hyper_connection_kernels.c.

Function Documentation

◆ ck_bf16_round()

static float ck_bf16_round ( float  value)
inlinestatic

Definition at line 26 of file hyper_connection_kernels.c.

26 {
27 return bf16_to_float(float_to_bf16(value));
28}
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

References bf16_to_float(), and float_to_bf16().

Referenced by ck_sigmoid_bf16(), hyper_connection_mix_bf16(), hyper_stream_expand_bf16(), and hyper_stream_inject_bf16().

◆ ck_sigmoid_bf16()

static float ck_sigmoid_bf16 ( float  value)
inlinestatic

Definition at line 30 of file hyper_connection_kernels.c.

30 {
31 return ck_bf16_round(1.0f / (1.0f + expf(-value)));
32}
static float ck_bf16_round(float value)

References ck_bf16_round().

Referenced by hyper_connection_mix_bf16().

◆ gemm_nt_q4_k_q8_k_pairwise_split_min_parallel_dispatch()

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 
)

◆ gemm_nt_q5_0_q8_0_parallel_dispatch()

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 
)

◆ gemm_nt_q6_k_q8_k_parallel_dispatch()

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 
)

◆ gemv_q4_k_q8_k_avx2()

void gemv_q4_k_q8_k_avx2 ( float *  y,
const void *  W,
const void *  x_q8,
int  M,
int  K 
)

Definition at line 118 of file gemm_kernels_q4k_q8k_avx2.c.

122{
123#if defined(__AVX2__)
124 if (!y || !W || !x_q8 || M <= 0 || K <= 0) {
125 return;
126 }
127
128 const block_q4_K *blocks = (const block_q4_K *)W;
129 const block_q8_K *x = (const block_q8_K *)x_q8;
130 const int blocks_per_row = K / QK_K;
131
132 for (int row = 0; row < M; ++row) {
133 const block_q4_K *w_row = blocks + (size_t)row * (size_t)blocks_per_row;
134 y[row] = dot_q4_k_q8_k_avx2(w_row, x, K);
135 }
136#else
137 gemv_q4_k_q8_k_ref(y, W, x_q8, M, K);
138#endif
139}
#define QK_K
void gemv_q4_k_q8_k_ref(float *y, const void *W, const void *x_q8, int M, int K)

Referenced by hyper_injection_q4k_q8k_llama_dispatch().

◆ hyper_connection_mix_bf16()

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 
)

Definition at line 73 of file hyper_connection_kernels.c.

88 {
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}
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)
static float ck_sigmoid_bf16(float value)

References bf16_to_float(), ck_bf16_round(), ck_sigmoid_bf16(), and rmsnorm_forward_qwen3next_pytorch_bf16_storage().

◆ hyper_connection_mix_q4k_q5_0_q4k()

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 
)

Definition at line 350 of file hyper_connection_kernels.c.

365 {
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}
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)
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)

References gemm_nt_q4_k_q8_k_pairwise_split_min_parallel_dispatch(), hyper_connection_mix_quantized(), and hyper_injection_q4k_q8k_llama_dispatch().

◆ hyper_connection_mix_q6k_q5_0_q4k()

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 
)

Definition at line 374 of file hyper_connection_kernels.c.

389 {
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}
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)

References gemm_nt_q6_k_q8_k_parallel_dispatch(), hyper_connection_mix_quantized(), and hyper_injection_q4k_q8k_llama_dispatch().

◆ hyper_connection_mix_quantized()

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 
)
static

Definition at line 210 of file hyper_connection_kernels.c.

227 {
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}
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
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)

References gemm_nt_q5_0_q8_0_parallel_dispatch(), QK8_0, QK_K, quantize_row_q8_0(), quantize_row_q8_k(), recurrent_sigmoid_forward_ggml(), and recurrent_silu_forward_ggml().

Referenced by hyper_connection_mix_q4k_q5_0_q4k(), and hyper_connection_mix_q6k_q5_0_q4k().

◆ hyper_injection_q4k_q8k_llama_dispatch()

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 
)
static

Definition at line 177 of file hyper_connection_kernels.c.

184 {
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}
void gemv_q4_k_q8_k(float *y, const void *W, const void *x_q8, int M, int K)
void gemv_q4_k_q8_k_avx2(float *y, const void *W, const void *x_q8, int M, int K)

References gemv_q4_k_q8_k(), gemv_q4_k_q8_k_avx2(), and QK_K.

Referenced by hyper_connection_mix_q4k_q5_0_q4k(), and hyper_connection_mix_q6k_q5_0_q4k().

◆ hyper_stream_expand_bf16()

void hyper_stream_expand_bf16 ( const float *  input,
float *  output,
int  rows,
int  streams,
int  hidden_dim 
)

Definition at line 53 of file hyper_connection_kernels.c.

57 {
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}

References ck_bf16_round().

◆ hyper_stream_expand_f32()

void hyper_stream_expand_f32 ( const float *  input,
float *  output,
int  rows,
int  streams,
int  hidden_dim 
)

Definition at line 34 of file hyper_connection_kernels.c.

38 {
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}

◆ hyper_stream_inject_bf16()

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 
)

Definition at line 398 of file hyper_connection_kernels.c.

404 {
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}

References ck_bf16_round().

◆ hyper_stream_inject_f32()

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 
)

Definition at line 429 of file hyper_connection_kernels.c.

435 {
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}