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

Go to the source code of this file.

Functions

void recurrent_norm_gate_backward (const float *d_out, const float *x, const float *gate, const float *weight, float *d_x, float *d_gate, float *d_weight, int rows, int num_heads, int head_dim, float eps)
 
void recurrent_norm_gate_forward (const float *x, const float *gate, const float *weight, float *out, int rows, int num_heads, int head_dim, float eps)
 
void recurrent_norm_gate_llama_avx2_forward (const float *x, const float *gate, const float *weight, float *out, int rows, int num_heads, int head_dim, float eps)
 
void recurrent_norm_gate_pytorch_bf16_storage (const float *x, const float *gate, const float *weight, float *out, int rows, int num_heads, int head_dim, float eps)
 
void recurrent_norm_sigmoid_gate_llama_avx2_forward (const float *x, const float *gate, const float *weight, float *out, int rows, int num_heads, int head_dim, float eps)
 
void recurrent_norm_sigmoid_gate_pytorch_bf16_storage (const float *x, const float *gate, const float *weight, float *out, int rows, int num_heads, int head_dim, float eps)
 
static float recurrent_sigmoid_local (float x)
 

Function Documentation

◆ recurrent_norm_gate_backward()

void recurrent_norm_gate_backward ( const float *  d_out,
const float *  x,
const float *  gate,
const float *  weight,
float *  d_x,
float *  d_gate,
float *  d_weight,
int  rows,
int  num_heads,
int  head_dim,
float  eps 
)

Definition at line 182 of file recurrent_norm_kernels.c.

192 {
193 const int inner_dim = num_heads * head_dim;
194 memset(d_weight, 0, (size_t) head_dim * sizeof(float));
195
196 for (int row = 0; row < rows; ++row) {
197 const float *d_out_row = d_out + (size_t) row * (size_t) inner_dim;
198 const float *x_row = x + (size_t) row * (size_t) inner_dim;
199 const float *gate_row = gate + (size_t) row * (size_t) inner_dim;
200 float *d_x_row = d_x + (size_t) row * (size_t) inner_dim;
201 float *d_gate_row = d_gate + (size_t) row * (size_t) inner_dim;
202
203 for (int head = 0; head < num_heads; ++head) {
204 const float *x_head = x_row + (size_t) head * (size_t) head_dim;
205 const float *gate_head = gate_row + (size_t) head * (size_t) head_dim;
206 const float *d_out_head = d_out_row + (size_t) head * (size_t) head_dim;
207 float *d_x_head = d_x_row + (size_t) head * (size_t) head_dim;
208 float *d_gate_head = d_gate_row + (size_t) head * (size_t) head_dim;
209
210 float ms = 0.0f;
211 for (int col = 0; col < head_dim; ++col) {
212 ms += x_head[col] * x_head[col];
213 }
214 ms /= (float) head_dim;
215 const float inv_rms = 1.0f / sqrtf(ms + eps);
216 const float inv_rms3_over_dim = (inv_rms * inv_rms * inv_rms) / (float) head_dim;
217
218 float dot = 0.0f;
219 for (int col = 0; col < head_dim; ++col) {
220 const float g = gate_head[col];
221 const float sig = recurrent_sigmoid_local(g);
222 const float silu = g * sig;
223 dot += d_out_head[col] * weight[col] * silu * x_head[col];
224 }
225
226 for (int col = 0; col < head_dim; ++col) {
227 const float g = gate_head[col];
228 const float sig = recurrent_sigmoid_local(g);
229 const float silu = g * sig;
230 const float scaled = inv_rms * weight[col] * silu;
231 d_x_head[col] = d_out_head[col] * scaled - x_head[col] * inv_rms3_over_dim * dot;
232 d_weight[col] += d_out_head[col] * (x_head[col] * inv_rms) * silu;
233 d_gate_head[col] = d_out_head[col] * (x_head[col] * inv_rms * weight[col]) *
234 (sig + g * sig * (1.0f - sig));
235 }
236 }
237 }
238}
static float recurrent_sigmoid_local(float x)
static void silu(float *x, int n)

References recurrent_sigmoid_local(), and silu().

◆ recurrent_norm_gate_forward()

void recurrent_norm_gate_forward ( const float *  x,
const float *  gate,
const float *  weight,
float *  out,
int  rows,
int  num_heads,
int  head_dim,
float  eps 
)

Definition at line 18 of file recurrent_norm_kernels.c.

25 {
26 const int inner_dim = num_heads * head_dim;
27 for (int row = 0; row < rows; ++row) {
28 const float *x_row = x + (size_t) row * (size_t) inner_dim;
29 const float *gate_row = gate + (size_t) row * (size_t) inner_dim;
30 float *out_row = out + (size_t) row * (size_t) inner_dim;
31
32 for (int head = 0; head < num_heads; ++head) {
33 const float *x_head = x_row + (size_t) head * (size_t) head_dim;
34 const float *gate_head = gate_row + (size_t) head * (size_t) head_dim;
35 float *out_head = out_row + (size_t) head * (size_t) head_dim;
36
37 float ms = 0.0f;
38 for (int col = 0; col < head_dim; ++col) {
39 ms += x_head[col] * x_head[col];
40 }
41 ms /= (float) head_dim;
42 const float inv_rms = 1.0f / sqrtf(ms + eps);
43
44 for (int col = 0; col < head_dim; ++col) {
45 const float g = gate_head[col];
46 const float silu = g * recurrent_sigmoid_local(g);
47 out_head[col] = x_head[col] * inv_rms * weight[col] * silu;
48 }
49 }
50 }
51}

References recurrent_sigmoid_local(), and silu().

Referenced by ck_test_recurrent_norm_gate().

◆ recurrent_norm_gate_llama_avx2_forward()

void recurrent_norm_gate_llama_avx2_forward ( const float *  x,
const float *  gate,
const float *  weight,
float *  out,
int  rows,
int  num_heads,
int  head_dim,
float  eps 
)

Definition at line 53 of file recurrent_norm_kernels.c.

60 {
61 if (!x || !gate || !weight || !out || rows <= 0 || num_heads <= 0 ||
62 head_dim <= 0 || head_dim > 4096) {
63 return;
64 }
65 const int inner_dim = num_heads * head_dim;
66 float normalized[4096];
67 float silu[4096];
68 for (int row = 0; row < rows; ++row) {
69 for (int head = 0; head < num_heads; ++head) {
70 const size_t offset = (size_t) row * (size_t) inner_dim
71 + (size_t) head * (size_t) head_dim;
73 x + offset, weight, normalized, NULL, 1, head_dim, head_dim, eps);
74 recurrent_silu_forward_ggml(gate + offset, silu, 1, head_dim);
75 for (int col = 0; col < head_dim; ++col) {
76 out[offset + (size_t) col] = normalized[col] * silu[col];
77 }
78 }
79 }
80}
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 recurrent_silu_forward_ggml(const float *x, float *out, int rows, int dim)

References recurrent_silu_forward_ggml(), rmsnorm_forward_llama_production(), and silu().

◆ recurrent_norm_gate_pytorch_bf16_storage()

void recurrent_norm_gate_pytorch_bf16_storage ( const float *  x,
const float *  gate,
const float *  weight,
float *  out,
int  rows,
int  num_heads,
int  head_dim,
float  eps 
)

Definition at line 111 of file recurrent_norm_kernels.c.

119{
120 if (!x || !gate || !weight || !out || rows <= 0 || num_heads <= 0 ||
121 head_dim <= 0 || head_dim > 4096) {
122 return;
123 }
124 const int inner_dim = num_heads * head_dim;
125 float normalized[4096];
126 float silu[4096];
127 for (int row = 0; row < rows; ++row) {
128 for (int head = 0; head < num_heads; ++head) {
129 const size_t offset = (size_t)row * (size_t)inner_dim +
130 (size_t)head * (size_t)head_dim;
131 /*
132 * Qwen3Next order:
133 * FP32 RMS statistics -> BF16 normalized value -> BF16 weight
134 * multiply -> FP32 SiLU(gate) -> BF16 final output.
135 */
137 x + offset, weight, normalized, NULL,
138 1, head_dim, head_dim, eps);
140 gate + offset, silu, 1, head_dim);
141 for (int col = 0; col < head_dim; ++col) {
142 out[offset + (size_t)col] = bf16_to_float(float_to_bf16(
143 normalized[col] * silu[col]));
144 }
145 }
146 }
147}
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 recurrent_silu_forward_pytorch_bf16_input_fp32_output(const float *x, float *out, int rows, int dim)
void rmsnorm_forward_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)

References bf16_to_float(), float_to_bf16(), recurrent_silu_forward_pytorch_bf16_input_fp32_output(), rmsnorm_forward_pytorch_bf16_storage(), and silu().

◆ recurrent_norm_sigmoid_gate_llama_avx2_forward()

void recurrent_norm_sigmoid_gate_llama_avx2_forward ( const float *  x,
const float *  gate,
const float *  weight,
float *  out,
int  rows,
int  num_heads,
int  head_dim,
float  eps 
)

Definition at line 82 of file recurrent_norm_kernels.c.

89 {
90 if (!x || !gate || !weight || !out || rows <= 0 || num_heads <= 0 ||
91 head_dim <= 0 || head_dim > 4096) {
92 return;
93 }
94 const int inner_dim = num_heads * head_dim;
95 float normalized[4096];
96 float sigmoid[4096];
97 for (int row = 0; row < rows; ++row) {
98 for (int head = 0; head < num_heads; ++head) {
99 const size_t offset = (size_t) row * (size_t) inner_dim
100 + (size_t) head * (size_t) head_dim;
102 x + offset, weight, normalized, NULL, 1, head_dim, head_dim, eps);
103 recurrent_sigmoid_forward_ggml(gate + offset, sigmoid, 1, head_dim);
104 for (int col = 0; col < head_dim; ++col) {
105 out[offset + (size_t) col] = normalized[col] * sigmoid[col];
106 }
107 }
108 }
109}
void recurrent_sigmoid_forward_ggml(const float *x, float *out, int rows, int dim)

References recurrent_sigmoid_forward_ggml(), and rmsnorm_forward_llama_production().

◆ recurrent_norm_sigmoid_gate_pytorch_bf16_storage()

void recurrent_norm_sigmoid_gate_pytorch_bf16_storage ( const float *  x,
const float *  gate,
const float *  weight,
float *  out,
int  rows,
int  num_heads,
int  head_dim,
float  eps 
)

Definition at line 149 of file recurrent_norm_kernels.c.

157{
158 if (!x || !gate || !weight || !out || rows <= 0 || num_heads <= 0 ||
159 head_dim <= 0 || head_dim > 4096) {
160 return;
161 }
162 const int inner_dim = num_heads * head_dim;
163 float normalized[4096];
164 float sigmoid[4096];
165 for (int row = 0; row < rows; ++row) {
166 for (int head = 0; head < num_heads; ++head) {
167 const size_t offset = (size_t)row * (size_t)inner_dim +
168 (size_t)head * (size_t)head_dim;
170 x + offset, weight, normalized, NULL,
171 1, head_dim, head_dim, eps);
173 gate + offset, sigmoid, 1, head_dim);
174 for (int col = 0; col < head_dim; ++col) {
175 out[offset + (size_t)col] = bf16_to_float(float_to_bf16(
176 normalized[col] * sigmoid[col]));
177 }
178 }
179 }
180}
void recurrent_sigmoid_forward_pytorch_bf16_input_fp32_output(const float *x, float *out, int rows, int dim)

References bf16_to_float(), float_to_bf16(), recurrent_sigmoid_forward_pytorch_bf16_input_fp32_output(), and rmsnorm_forward_pytorch_bf16_storage().

◆ recurrent_sigmoid_local()

static float recurrent_sigmoid_local ( float  x)
inlinestatic

Definition at line 7 of file recurrent_norm_kernels.c.

7 {
8 if (x >= 0.0f) {
9 const float z = expf(-x);
10 return 1.0f / (1.0f + z);
11 }
12 {
13 const float z = expf(x);
14 return z / (1.0f + z);
15 }
16}

Referenced by recurrent_norm_gate_backward(), and recurrent_norm_gate_forward().