ember.cpp 0.1.0
C++ inference engine for Llama-family and paperkiln models (CPU, CUDA, WebAssembly)
Loading...
Searching...
No Matches
ember_ir::cpu Namespace Reference

Functions

void conv1d_causal_row (const float *x, const float *w, const float *bias, float *state, float *out, int C, int K)
 
void selective_scan_row (const float *x, const float *dt, const float *B, const float *C, const float *A, const float *d, float *s, float *y, int D, int N, bool softplus)
 
void sub (const float *a, const float *b, float *out, size_t n)
 
void relu (const float *x, float *out, size_t n)
 
void sigmoid (const float *x, float *out, size_t n)
 
void affine (const float *x, float *out, size_t n, float scale, float shift)
 
void mor_route (const float *l, int R, int &depth, float &gate)
 
void mor_gate (const float *x_in, float *x, size_t n, float g)
 
void scale (const float *x, const float *g, const float *b, float *out, int T, int w)
 
void mul_col (const float *x, const float *c, float *out, int T, int w)
 
void rms_row (const float *x, float *out, int T, int w, float eps)
 
void depth_attend (const std::vector< const float * > &sources, const float *w, float *out, int T, int d, float eps)
 
void mla_attention (const float *qn, const float *qr, const float *kv, float *out, int T, const std::vector< std::vector< int > > &rows, int H, int r, int dn, int dr, int dv, const float *Kb, const float *Vb, float scale)
 
void split_groups (const float *x, int T, const std::vector< int > &sizes, int g, const std::vector< float * > &outs)
 

Function Documentation

◆ affine()

void ember_ir::cpu::affine ( const float *  x,
float *  out,
size_t  n,
float  scale,
float  shift 
)

Definition at line 26 of file graph_ir_ops.cpp.

26 {
27 for (size_t i = 0; i < n; ++i) {
28 const float p = x[i] * scale;
29 out[i] = p + shift;
30 }
31}
const float * p[kIrDepthSourcesMax]
int n
node out
node scale
size_t j

References j, n, out, p, and scale.

◆ conv1d_causal_row()

void ember_ir::cpu::conv1d_causal_row ( const float *  x,
const float *  w,
const float *  bias,
float *  state,
float *  out,
int  C,
int  K 
)

Definition at line 10 of file graph_ir_mamba.cpp.

10 {
11 for (int c = 0; c < C; ++c) {
12 float acc = 0.0f;
13 for (int k = 0; k < K; ++k) {
14 const float v = k < K - 1 ? state[static_cast<size_t>(k) * C + c] : x[c];
15 acc = acc + w[static_cast<size_t>(c) * K + k] * v;
16 }
17 out[c] = bias ? acc + bias[c] : acc;
18 }
19 if (K > 1) { // the state becomes the last K - 1 rows of [state; x]
20 std::memmove(state, state + C, static_cast<size_t>(K - 2) * C * sizeof(float));
21 std::memcpy(state + static_cast<size_t>(K - 2) * C, x, static_cast<size_t>(C) * sizeof(float));
22 }
23}
std::vector< float > v
float c

References c, j, k, out, state, and v.

◆ depth_attend()

void ember_ir::cpu::depth_attend ( const std::vector< const float * > &  sources,
const float *  w,
float *  out,
int  T,
int  d,
float  eps 
)

Definition at line 81 of file graph_ir_ops.cpp.

81 {
82 const size_t S = sources.size();
83 const size_t n = static_cast<size_t>(T) * d;
84 if (S == 1) { // softmax over one source is the identity mixture: s_0 bit for bit
85 std::memcpy(out, sources[0], n * sizeof(float));
86 return;
87 }
88 std::vector<float> a(S);
89 for (int t = 0; t < T; ++t) {
90 const size_t row = static_cast<size_t>(t) * d;
91 // Logits: w . rmsnorm(s_i) (ops::rmsnorm with unit weight, ops::mul_row,
92 // then the matmul with a ones column).
93 for (size_t i = 0; i < S; ++i) {
94 const float* s = sources[i] + row;
95 float ss = 0.0f;
96 for (int j = 0; j < d; ++j) {
97 const float sq = s[j] * s[j];
98 ss += sq;
99 }
100 ss /= static_cast<float>(d);
101 const float r = 1.0f / std::sqrt(ss + eps);
102 float l = 0.0f;
103 for (int j = 0; j < d; ++j) {
104 const float normed = s[j] * r;
105 const float p = normed * w[j];
106 l += p;
107 }
108 a[i] = l;
109 }
110 // Softmax over the sources (Matrix::apply_softmax): max-shifted, z in
111 // ascending i, a_i = e_i / z.
112 float mx = -std::numeric_limits<float>::infinity();
113 for (size_t i = 0; i < S; ++i) mx = std::max(mx, a[i]);
114 float z = 0.0f;
115 for (size_t i = 0; i < S; ++i) {
116 a[i] = std::exp(a[i] - mx);
117 z += a[i];
118 }
119 for (size_t i = 0; i < S; ++i) a[i] /= z;
120 // out = s_0 a_0 + s_1 a_1 + ... (ops::mul_col per source, ops::add in order).
121 float* o = out + row;
122 const float* s0 = sources[0] + row;
123 for (int j = 0; j < d; ++j) o[j] = s0[j] * a[0];
124 for (size_t i = 1; i < S; ++i) {
125 const float* s = sources[i] + row;
126 for (int j = 0; j < d; ++j) {
127 const float p = s[j] * a[i];
128 o[j] = o[j] + p;
129 }
130 }
131 }
132}
std::vector< E > a

References a, j, n, out, and p.

◆ mla_attention()

void ember_ir::cpu::mla_attention ( const float *  qn,
const float *  qr,
const float *  kv,
float *  out,
int  T,
const std::vector< std::vector< int > > &  rows,
int  H,
int  r,
int  dn,
int  dr,
int  dv,
const float *  Kb,
const float *  Vb,
float  scale 
)

Definition at line 134 of file graph_ir_ops.cpp.

136 {
137 const size_t w = static_cast<size_t>(r) + dr;
138#pragma omp parallel for schedule(dynamic)
139 for (int t = 0; t < T; ++t) {
140 const std::vector<int>& vis = rows[t];
141 std::vector<float> qa(static_cast<size_t>(r)), u(static_cast<size_t>(r)), s(vis.size());
142 for (int h = 0; h < H; ++h) {
143 const float* qnh = qn + (static_cast<size_t>(t) * H + h) * dn;
144 const float* qrh = qr + (static_cast<size_t>(t) * H + h) * dr;
145 const float* K = Kb + static_cast<size_t>(h) * r * dn;
146 const float* V = Vb + static_cast<size_t>(h) * dv * r;
147 for (int i = 0; i < r; ++i) { // qa = K[h] qn_h
148 float acc = 0.0f;
149 for (int k = 0; k < dn; ++k) {
150 const float p = K[static_cast<size_t>(i) * dn + k] * qnh[k];
151 acc += p;
152 }
153 qa[i] = acc;
154 }
155 float mx = -std::numeric_limits<float>::infinity();
156 for (size_t j = 0; j < vis.size(); ++j) {
157 const float* c = kv + static_cast<size_t>(vis[j]) * w;
158 float a = 0.0f, b = 0.0f;
159 for (int i = 0; i < r; ++i) {
160 const float p = qa[i] * c[i];
161 a += p;
162 }
163 for (int e = 0; e < dr; ++e) {
164 const float p = qrh[e] * c[r + e];
165 b += p;
166 }
167 const float sum = a + b;
168 s[j] = sum * scale;
169 mx = std::max(mx, s[j]);
170 }
171 float z = 0.0f;
172 for (size_t j = 0; j < vis.size(); ++j) {
173 s[j] = std::exp(s[j] - mx);
174 z += s[j];
175 }
176 std::fill(u.begin(), u.end(), 0.0f);
177 for (size_t j = 0; j < vis.size(); ++j) {
178 const float a = s[j] / z;
179 const float* c = kv + static_cast<size_t>(vis[j]) * w;
180 for (int i = 0; i < r; ++i) {
181 const float p = a * c[i];
182 u[i] += p;
183 }
184 }
185 float* o = out + (static_cast<size_t>(t) * H + h) * dv;
186 for (int k = 0; k < dv; ++k) { // out = V[h] u
187 float acc = 0.0f;
188 for (int i = 0; i < r; ++i) {
189 const float p = V[static_cast<size_t>(k) * r + i] * u[i];
190 acc += p;
191 }
192 o[k] = acc;
193 }
194 }
195 }
196}

References a, c, j, k, out, p, and scale.

◆ mor_gate()

void ember_ir::cpu::mor_gate ( const float *  x_in,
float *  x,
size_t  n,
float  g 
)

Definition at line 43 of file graph_ir_ops.cpp.

43 {
44 for (size_t i = 0; i < n; ++i) {
45 const float diff = x[i] - x_in[i];
46 const float p = g * diff;
47 x[i] = x_in[i] + p;
48 }
49}

References j, n, and p.

◆ mor_route()

void ember_ir::cpu::mor_route ( const float *  l,
int  R,
int &  depth,
float &  gate 
)

Definition at line 33 of file graph_ir_ops.cpp.

33 {
34 int j_max = 0;
35 for (int j = 1; j < R; ++j)
36 if (l[j] > l[j_max]) j_max = j; // strict: a tie keeps the lower index
37 float z = 0.0f;
38 for (int j = 0; j < R; ++j) z += std::exp(l[j] - l[j_max]);
39 depth = j_max + 1;
40 gate = std::exp(l[j_max] - l[j_max]) / z;
41}

References j.

◆ mul_col()

void ember_ir::cpu::mul_col ( const float *  x,
const float *  c,
float *  out,
int  T,
int  w 
)

Definition at line 61 of file graph_ir_ops.cpp.

61 {
62 for (int t = 0; t < T; ++t) {
63 const float ct = c[t];
64 const size_t r = static_cast<size_t>(t) * w;
65 for (int j = 0; j < w; ++j) out[r + j] = x[r + j] * ct;
66 }
67}

References c, j, and out.

◆ relu()

void ember_ir::cpu::relu ( const float *  x,
float *  out,
size_t  n 
)

Definition at line 18 of file graph_ir_ops.cpp.

18 {
19 for (size_t i = 0; i < n; ++i) out[i] = std::max(0.0f, x[i]);
20}

References j, n, and out.

◆ rms_row()

void ember_ir::cpu::rms_row ( const float *  x,
float *  out,
int  T,
int  w,
float  eps 
)

Definition at line 69 of file graph_ir_ops.cpp.

69 {
70 for (int t = 0; t < T; ++t) {
71 const float* r = x + static_cast<size_t>(t) * w;
72 float ss = 0.0f;
73 for (int j = 0; j < w; ++j) {
74 const float sq = r[j] * r[j];
75 ss += sq;
76 }
77 out[t] = std::sqrt(ss / static_cast<float>(w) + eps);
78 }
79}

References j, and out.

◆ scale()

void ember_ir::cpu::scale ( const float *  x,
const float *  g,
const float *  b,
float *  out,
int  T,
int  w 
)

Definition at line 51 of file graph_ir_ops.cpp.

51 {
52 for (int t = 0; t < T; ++t) {
53 const size_t r = static_cast<size_t>(t) * w;
54 if (b)
55 for (int j = 0; j < w; ++j) out[r + j] = x[r + j] * g[j] + b[j];
56 else
57 for (int j = 0; j < w; ++j) out[r + j] = x[r + j] * g[j];
58 }
59}

References j, and out.

◆ selective_scan_row()

void ember_ir::cpu::selective_scan_row ( const float *  x,
const float *  dt,
const float *  B,
const float *  C,
const float *  A,
const float *  d,
float *  s,
float *  y,
int  D,
int  N,
bool  softplus 
)

Definition at line 25 of file graph_ir_mamba.cpp.

26 {
27 for (int c = 0; c < D; ++c) {
28 const float delta = softplus ? (dt[c] <= 20.0f ? std::log1p(std::exp(dt[c])) : dt[c]) : dt[c];
29 const float xd = x[c] * delta;
30 float* sc = s + static_cast<size_t>(c) * N;
31 const float* ac = A + static_cast<size_t>(c) * N;
32 float acc = 0.0f;
33 for (int n = 0; n < N; ++n) {
34 const float decay = sc[n] * std::exp(delta * ac[n]);
35 sc[n] = decay + B[n] * xd;
36 acc = acc + sc[n] * C[n];
37 }
38 y[c] = d ? acc + d[c] * x[c] : acc;
39 }
40}

References c, j, and n.

◆ sigmoid()

void ember_ir::cpu::sigmoid ( const float *  x,
float *  out,
size_t  n 
)

Definition at line 22 of file graph_ir_ops.cpp.

22 {
23 for (size_t i = 0; i < n; ++i) out[i] = 1.0f / (1.0f + std::exp(-x[i]));
24}

References j, n, and out.

◆ split_groups()

void ember_ir::cpu::split_groups ( const float *  x,
int  T,
const std::vector< int > &  sizes,
int  g,
const std::vector< float * > &  outs 
)

Definition at line 198 of file graph_ir_ops.cpp.

198 {
199 int group = 0;
200 for (int s : sizes) group += s;
201 const size_t width = static_cast<size_t>(group) * g;
202 for (int t = 0; t < T; ++t) {
203 const float* row = x + static_cast<size_t>(t) * width;
204 for (int q = 0; q < g; ++q) {
205 int col = 0;
206 for (size_t k = 0; k < sizes.size(); ++k) {
207 float* dst = outs[k] + (static_cast<size_t>(t) * g + q) * sizes[k];
208 std::memcpy(dst, row + static_cast<size_t>(q) * group + col, static_cast<size_t>(sizes[k]) * sizeof(float));
209 col += sizes[k];
210 }
211 }
212 }
213}
const float * col[expr::kMaxColumns]
std::vector< int > sizes

References col, j, k, and sizes.

◆ sub()

void ember_ir::cpu::sub ( const float *  a,
const float *  b,
float *  out,
size_t  n 
)

Definition at line 14 of file graph_ir_ops.cpp.

14 {
15 for (size_t i = 0; i < n; ++i) out[i] = a[i] - b[i];
16}

References a, j, n, and out.