← Back to C-Kernel-Engine Docs Doxygen Source Documentation
 
Loading...
Searching...
No Matches
embedding_kernels_bf16.c
Go to the documentation of this file.
1/**
2 * @file embedding_kernels_bf16.c
3 * @brief Token/position embedding lookup kernels for BF16
4 *
5 * CK-ENGINE KERNEL RULES:
6 * =======================
7 * 1. NO malloc/free - memory via bump allocator, pointers passed in
8 * 2. NO OpenMP - parallelization at orchestrator/codegen layer
9 * 3. API must define: inputs, outputs, workspace, and memory layouts
10 * 4. Pure computation - deterministic, no side effects
11 *
12 * After changes: make test && make llamacpp-parity-full
13 */
14
15#include <stdint.h>
16#include <string.h>
17
18#include "bf16_utils.h"
19#include "ckernel_engine.h"
20
21void embedding_forward_bf16(const int32_t *token_ids,
22 int token_count,
23 int vocab_size,
24 const uint16_t *token_embeddings,
25 const uint16_t *pos_embeddings,
26 uint16_t *output,
27 int embed_dim,
28 int aligned_embed_dim,
29 int context_window,
30 int add_pos)
31{
32 if (!token_ids || !token_embeddings || !output) {
33 return;
34 }
35
36 int tokens = token_count;
37 if (tokens < 0) tokens = 0;
38 if (tokens > context_window) tokens = context_window;
39
40 for (int t = 0; t < tokens; ++t) {
41 int id = token_ids[t];
42 if (id < 0 || id >= vocab_size) {
43 id = 0;
44 }
45
46 const uint16_t *tok = token_embeddings + (size_t)id * (size_t)aligned_embed_dim;
47 const uint16_t *pos = pos_embeddings ? (pos_embeddings + (size_t)t * (size_t)aligned_embed_dim) : NULL;
48 uint16_t *out = output + (size_t)t * (size_t)aligned_embed_dim;
49
50 if (add_pos && pos) {
51 for (int d = 0; d < embed_dim; ++d) {
52 float v = bf16_to_float(tok[d]) + bf16_to_float(pos[d]);
53 out[d] = float_to_bf16(v);
54 }
55 } else {
56 for (int d = 0; d < embed_dim; ++d) {
57 out[d] = tok[d];
58 }
59 }
60
61 for (int d = embed_dim; d < aligned_embed_dim; ++d) {
62 out[d] = 0;
63 }
64 }
65
66 for (int t = tokens; t < context_window; ++t) {
67 uint16_t *out = output + (size_t)t * (size_t)aligned_embed_dim;
68 memset(out, 0, (size_t)aligned_embed_dim * sizeof(uint16_t));
69 }
70}
71
72
73void embedding_forward_bf16_fp32(const int32_t *token_ids,
74 int token_count,
75 int vocab_size,
76 const uint16_t *token_embeddings,
77 const float *pos_embeddings,
78 float *output,
79 int embed_dim,
80 int aligned_embed_dim,
81 int context_window,
82 int add_pos)
83{
84 if (!token_ids || !token_embeddings || !output) {
85 return;
86 }
87
88 int tokens = token_count;
89 if (tokens < 0) tokens = 0;
90 if (tokens > context_window) tokens = context_window;
91
92 for (int t = 0; t < tokens; ++t) {
93 int id = token_ids[t];
94 if (id < 0 || id >= vocab_size) {
95 id = 0;
96 }
97
98 const uint16_t *tok = token_embeddings + (size_t)id * (size_t)aligned_embed_dim;
99 const float *pos = pos_embeddings ? (pos_embeddings + (size_t)t * (size_t)aligned_embed_dim) : NULL;
100 float *out = output + (size_t)t * (size_t)aligned_embed_dim;
101
102 if (add_pos && pos) {
103 for (int d = 0; d < embed_dim; ++d) {
104 out[d] = bf16_to_float(tok[d]) + pos[d];
105 }
106 } else {
107 for (int d = 0; d < embed_dim; ++d) {
108 out[d] = bf16_to_float(tok[d]);
109 }
110 }
111
112 for (int d = embed_dim; d < aligned_embed_dim; ++d) {
113 out[d] = 0.0f;
114 }
115 }
116
117 for (int t = tokens; t < context_window; ++t) {
118 float *out = output + (size_t)t * (size_t)aligned_embed_dim;
119 memset(out, 0, (size_t)aligned_embed_dim * sizeof(float));
120 }
121}
122
123void embedding_backward_bf16(const int32_t *token_ids,
124 int token_count,
125 const uint16_t *d_output,
126 uint16_t *d_token_embeddings,
127 uint16_t *d_pos_embeddings,
128 int vocab_size,
129 int embed_dim,
130 int aligned_embed_dim,
131 int context_window,
132 int add_pos)
133{
134 if (!token_ids || !d_output || !d_token_embeddings) {
135 return;
136 }
137
138 int tokens = token_count;
139 if (tokens < 0) tokens = 0;
140 if (tokens > context_window) tokens = context_window;
141
142 for (int t = 0; t < tokens; ++t) {
143 int id = token_ids[t];
144 if (id < 0 || id >= vocab_size) {
145 id = 0;
146 }
147
148 const uint16_t *d_out = d_output + (size_t)t * (size_t)aligned_embed_dim;
149 uint16_t *d_tok = d_token_embeddings + (size_t)id * (size_t)aligned_embed_dim;
150 uint16_t *d_pos = d_pos_embeddings ? (d_pos_embeddings + (size_t)t * (size_t)aligned_embed_dim) : NULL;
151
152 for (int d = 0; d < embed_dim; ++d) {
153 float grad = bf16_to_float(d_out[d]);
154
155 float cur_tok = bf16_to_float(d_tok[d]);
156 d_tok[d] = float_to_bf16(cur_tok + grad);
157
158 if (add_pos && d_pos) {
159 float cur_pos = bf16_to_float(d_pos[d]);
160 d_pos[d] = float_to_bf16(cur_pos + grad);
161 }
162 }
163 }
164}
165
166void embedding_backward_bf16_mixed(const int32_t *token_ids,
167 int token_count,
168 const uint16_t *d_output,
169 float *d_token_embeddings,
170 float *d_pos_embeddings,
171 int vocab_size,
172 int embed_dim,
173 int aligned_embed_dim,
174 int context_window,
175 int add_pos)
176{
177 if (!token_ids || !d_output || !d_token_embeddings) {
178 return;
179 }
180
181 int tokens = token_count;
182 if (tokens < 0) tokens = 0;
183 if (tokens > context_window) tokens = context_window;
184
185 for (int t = 0; t < tokens; ++t) {
186 int id = token_ids[t];
187 if (id < 0 || id >= vocab_size) {
188 id = 0;
189 }
190
191 const uint16_t *d_out = d_output + (size_t)t * (size_t)aligned_embed_dim;
192 float *d_tok = d_token_embeddings + (size_t)id * (size_t)aligned_embed_dim;
193 float *d_pos = d_pos_embeddings ? (d_pos_embeddings + (size_t)t * (size_t)aligned_embed_dim) : NULL;
194
195 for (int d = 0; d < embed_dim; ++d) {
196 const float grad = bf16_to_float(d_out[d]);
197 d_tok[d] += grad;
198 if (add_pos && d_pos) {
199 d_pos[d] += grad;
200 }
201 }
202 }
203}
204
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 embedding_forward_bf16(const int32_t *token_ids, int token_count, int vocab_size, const uint16_t *token_embeddings, const uint16_t *pos_embeddings, uint16_t *output, int embed_dim, int aligned_embed_dim, int context_window, int add_pos)
void embedding_backward_bf16(const int32_t *token_ids, int token_count, const uint16_t *d_output, uint16_t *d_token_embeddings, uint16_t *d_pos_embeddings, int vocab_size, int embed_dim, int aligned_embed_dim, int context_window, int add_pos)
void embedding_forward_bf16_fp32(const int32_t *token_ids, int token_count, int vocab_size, const uint16_t *token_embeddings, const float *pos_embeddings, float *output, int embed_dim, int aligned_embed_dim, int context_window, int add_pos)
void embedding_backward_bf16_mixed(const int32_t *token_ids, int token_count, const uint16_t *d_output, float *d_token_embeddings, float *d_pos_embeddings, int vocab_size, int embed_dim, int aligned_embed_dim, int context_window, int add_pos)
int vocab_size
Definition true_bpe.h:193