← Back to C-Kernel-Engine Docs Doxygen Source Documentation
 
Loading...
Searching...
No Matches
rmsnorm_q8_k_fused.c File Reference

Fused RMSNorm + Q8_K Quantization kernel. More...

#include <immintrin.h>
#include <math.h>
#include <stdint.h>
#include <string.h>
#include "ckernel_quant.h"

Go to the source code of this file.

Functions

void rmsnorm_q8_k_fused (const float *input, const float *gamma, void *vy, int tokens, int d_model, int aligned_embed_dim, float eps)
 

Detailed Description

Fused RMSNorm + Q8_K Quantization kernel.

CK-ENGINE KERNEL RULES:

  1. NO malloc/free - memory via bump allocator, pointers passed in
  2. NO OpenMP - parallelization at orchestrator/codegen layer
  3. API must define: inputs, outputs, workspace, and memory layouts
  4. Pure computation - deterministic, no side effects

After changes: make test && make llamacpp-parity-full

FUSION BENEFIT: Eliminates intermediate FP32 buffer between RMSNorm and quantization, keeping normalized values in registers/L1.

Definition in file rmsnorm_q8_k_fused.c.

Function Documentation

◆ rmsnorm_q8_k_fused()

void rmsnorm_q8_k_fused ( const float *  input,
const float *  gamma,
void *  vy,
int  tokens,
int  d_model,
int  aligned_embed_dim,
float  eps 
)

Definition at line 144 of file rmsnorm_q8_k_fused.c.

151{
152 const int T = tokens;
153 const int D = d_model;
154 block_q8_K *y = (block_q8_K *)vy;
155
156 for (int t = 0; t < T; ++t) {
157 const float *x = input + (size_t)t * (size_t)aligned_embed_dim;
158
159 float sum_sq = 0.0f;
160 for (int d = 0; d < D; ++d) {
161 sum_sq += x[d] * x[d];
162 }
163 const float rstd = 1.0f / sqrtf(sum_sq / (float)D + eps);
164
165 for (int b = 0; b < D / QK_K; ++b) {
166 const float *xb = x + b * QK_K;
167 const float *gb = gamma + b * QK_K;
168 block_q8_K *out_block = &y[t * (D / QK_K) + b];
169
170 float norm_buf[QK_K];
171 float max_val = 0.0f;
172 for (int d = 0; d < QK_K; ++d) {
173 const float normalized = xb[d] * rstd * gb[d];
174 norm_buf[d] = normalized;
175 const float abs_val = fabsf(normalized);
176 if (abs_val > max_val) {
177 max_val = abs_val;
178 }
179 }
180
181 if (max_val == 0.0f) {
182 out_block->d = 0.0f;
183 memset(out_block->qs, 0, QK_K);
184 memset(out_block->bsums, 0, sizeof(out_block->bsums));
185 continue;
186 }
187
188 const float iscale = -127.0f / max_val;
189 out_block->d = 1.0f / iscale;
190 for (int j = 0; j < QK_K; j += 16) {
191 int bsum = 0;
192 for (int k = 0; k < 16; ++k) {
193 int q = (int)lrintf(norm_buf[j + k] * iscale);
194 if (q < -128) q = -128;
195 if (q > 127) q = 127;
196 out_block->qs[j + k] = (int8_t)q;
197 bsum += q;
198 }
199 out_block->bsums[j / 16] = (int16_t)bsum;
200 }
201 }
202 }
203}
#define QK_K
int8_t qs[256]
int16_t bsums[256/16]

References block_q8_K::bsums, block_q8_K::d, QK_K, and block_q8_K::qs.