avarok_core/kimi_k3/
ops.rs1pub fn matvec(w: &[f32], x: &[f32], out: usize, inn: usize) -> Vec<f32> {
7 assert_eq!(
8 w.len(),
9 out * inn,
10 "matvec weight {} vs {out}x{inn}",
11 w.len()
12 );
13 assert_eq!(x.len(), inn);
14 let mut y = vec![0.0f32; out];
15 let grouped = out / 4 * 4;
18 for o in (0..grouped).step_by(4) {
19 let a = &w[o * inn..(o + 1) * inn];
20 let b = &w[(o + 1) * inn..(o + 2) * inn];
21 let c = &w[(o + 2) * inn..(o + 3) * inn];
22 let d = &w[(o + 3) * inn..(o + 4) * inn];
23 let mut acc = [0.0f32; 4];
24 for i in 0..inn {
25 let value = x[i];
26 acc[0] += a[i] * value;
27 acc[1] += b[i] * value;
28 acc[2] += c[i] * value;
29 acc[3] += d[i] * value;
30 }
31 y[o..o + 4].copy_from_slice(&acc);
32 }
33 for o in grouped..out {
34 let row = &w[o * inn..(o + 1) * inn];
35 let mut acc = 0.0f32;
36 for i in 0..inn {
37 acc += row[i] * x[i];
38 }
39 y[o] = acc;
40 }
41 y
42}
43
44pub fn matvec_column_tp(
50 w: &[f32],
51 x: &[f32],
52 out: usize,
53 inn: usize,
54 world: usize,
55 drop_rank: Option<usize>,
56) -> Vec<f32> {
57 match world {
58 1 => {
59 assert!(
60 drop_rank.is_none(),
61 "C7 drop_rank requires TP=2, got {drop_rank:?}"
62 );
63 matvec(w, x, out, inn)
64 }
65 2 => matvec_column_tp2(w, x, out, inn, drop_rank),
66 other => panic!("C7 dummy implements TP=1/2, got {other}"),
67 }
68}
69
70fn matvec_column_tp2(
73 w: &[f32],
74 x: &[f32],
75 out: usize,
76 inn: usize,
77 drop_rank: Option<usize>,
78) -> Vec<f32> {
79 assert_eq!(w.len(), out * inn, "TP=2 weight {} vs {out}x{inn}", w.len());
80 assert_eq!(x.len(), inn);
81 assert!(
82 inn.is_multiple_of(2),
83 "TP=2 o_proj inner dim must be even, got {inn}"
84 );
85 let half = inn / 2;
86 let shard = |rank: usize| -> Vec<f32> {
87 if drop_rank == Some(rank) {
88 return vec![0.0f32; out];
89 }
90 let start = rank * half;
91 let mut y = vec![0.0f32; out];
92 for o in 0..out {
93 let row = &w[o * inn + start..o * inn + start + half];
94 let xr = &x[start..start + half];
95 let mut acc = 0.0f32;
96 for i in 0..half {
97 acc += row[i] * xr[i];
98 }
99 y[o] = acc;
100 }
101 y
102 };
103 std::thread::scope(|s| {
105 let t0 = s.spawn(|| shard(0));
106 let t1 = s.spawn(|| shard(1));
107 let y0 = t0.join().expect("C7 rank 0");
108 let y1 = t1.join().expect("C7 rank 1");
109 y0.iter().zip(y1).map(|(a, b)| a + b).collect()
110 })
111}
112
113pub fn embed_token(table: &[f32], token: u32, hidden: usize, vocab: usize) -> Vec<f32> {
115 let t = token as usize;
116 assert!(t < vocab, "token {token} >= vocab {vocab}");
117 table[t * hidden..(t + 1) * hidden].to_vec()
118}
119
120pub fn argmax(logits: &[f32]) -> u32 {
122 assert!(!logits.is_empty());
123 let mut best_i = 0usize;
124 let mut best = logits[0];
125 for (i, &v) in logits.iter().enumerate().skip(1) {
126 if v > best {
127 best = v;
128 best_i = i;
129 }
130 }
131 best_i as u32
132}
133
134pub fn fill(n: usize, seed: u32, scale: f32) -> Vec<f32> {
136 (0..n)
137 .map(|i| {
138 let h = seed
139 .wrapping_mul(1664525)
140 .wrapping_add(1013904223)
141 .wrapping_add((i as u32).wrapping_mul(2654435761));
142 ((h % 1000) as f32 / 1000.0 - 0.5) * scale
143 })
144 .collect()
145}
146
147pub fn ones(n: usize) -> Vec<f32> {
149 vec![1.0; n]
150}
151
152pub fn ident(out: usize, inn: usize) -> Vec<f32> {
154 let mut w = vec![0.0f32; out * inn];
155 for i in 0..out.min(inn) {
156 w[i * inn + i] = 1.0;
157 }
158 w
159}
160
161#[cfg(test)]
162#[path = "ops_matvec_tests.rs"]
163mod matvec_tests;