1use super::*;
4
5impl Gpu<'_> {
6 pub(super) fn group_params(&self, eps: bool, shift: f32) -> GroupParams {
7 let c = &self.p.cfg;
8
9 GroupParams {
10 n: c.hidden_size as u32,
11 groups: c.hc_count as u32,
12 eps: if eps { c.rms_norm_eps as f32 } else { 0.0 },
13 shift,
14 }
15 }
16
17 #[allow(clippy::too_many_arguments)]
20 pub(super) fn group_norm_b(
21 &self,
22 enc: &Enc,
23 x: &Buf,
24 x_off: usize,
25 w: T,
26 y: &Buf,
27 n: u32,
28 groups: u32,
29 shift: f32,
30 nb: usize,
31 ) {
32 let p = GroupParams {
33 n,
34 groups,
35 eps: self.p.cfg.rms_norm_eps as f32,
36 shift,
37 };
38
39 self.dispatch(
40 enc,
41 &self.pipes.group_norm_b,
42 |e| {
43 self.bind(e, 0, x, x_off);
44 self.bind(e, 1, &self.dense, w.0);
45 self.bind(e, 2, y, 0);
46 set_bytes(e, 3, &p);
47 },
48 nb * groups as usize,
49 256,
50 true,
51 );
52 }
53
54 #[allow(clippy::too_many_arguments)]
59 pub(super) fn hc_read_b(
60 &self,
61 enc: &Enc,
62 hc: &Hc,
63 nb: usize,
64 hyper: &Buf,
65 hyper_off: usize,
66 pending: Option<&Buf>,
67 bufs: &HcBufs,
68 inject: bool,
69 ) {
70 let c = &self.p.cfg;
71 let h = c.hidden_size as u32;
72 let nbu = nb as u32;
73 let np = NormPrepParams {
74 n: h,
75 groups: c.hc_count as u32,
76 eps: c.rms_norm_eps as f32,
77 inject: pending.is_some() as u32,
78 };
79 let out = pending.unwrap_or(&self.scratch.mix_out);
80
81 self.dispatch(
82 enc,
83 &self.pipes.norm_prep_b,
84 |e| {
85 self.bind(e, 0, hyper, hyper_off);
86 self.bind(e, 1, &self.dense, hc.norm.0);
87 self.bind(e, 2, &bufs.normed, 0);
88 self.bind(e, 3, &bufs.h1.xe, 0);
89 self.bind(e, 4, &bufs.h1.xo, 0);
90 self.bind(e, 5, &bufs.h1.xsum, 0);
91 self.bind(e, 6, out, 0);
92 self.bind(e, 7, &bufs.inj, 0);
93 set_bytes(e, 8, &np);
94 },
95 nb * c.hc_count,
96 256,
97 true,
98 );
99
100 let div = c.hc_count as f32;
102 let qp = QmvParams {
103 out_dim: hc.down.out,
104 in_dim: hc.down.inp,
105 };
106
107 self.dispatch(
108 enc,
109 &self.pipes.qmv_silu_b[nb - 1],
110 |e| {
111 self.bind(e, 0, &self.dense, hc.down.w);
112 self.bind(e, 1, &self.dense, hc.down.s);
113 self.bind(e, 2, &self.dense, hc.down.b);
114 self.bind(e, 3, &bufs.h1.xe, 0);
115 self.bind(e, 4, &bufs.h1.xo, 0);
116 self.bind(e, 5, &bufs.h1.xsum, 0);
117 self.bind(e, 6, &bufs.d, 0);
118 set_bytes(e, 7, &qp);
119 set_bytes(e, 8, &div);
120 },
121 (hc.down.out as usize).div_ceil(4),
122 128,
123 true,
124 );
125
126 if inject && let Some(inj) = &hc.inject {
128 self.qmv_h(enc, inj, &bufs.inj, nb, &bufs.h1);
129 }
130
131 self.prep_h(enc, &bufs.d, 0, hc.down.out, nb, &bufs.h2);
133 self.qmv_h(enc, &hc.up, &bufs.u, nb, &bufs.h2);
134
135 let gp = self.group_params(false, 0.0);
136
137 self.dispatch(
138 enc,
139 &self.pipes.hc_mix_b,
140 |e| {
141 self.bind(e, 0, &bufs.u, 0);
142 self.bind(e, 1, &bufs.normed, 0);
143 self.bind(e, 2, &bufs.mixed, 0);
144 set_bytes(e, 3, &gp);
145 set_bytes(e, 4, &nbu);
146 },
147 nb * h as usize,
148 256,
149 false,
150 );
151 self.prep_h(enc, &bufs.mixed, 0, h, nb, &bufs.h1);
152 }
153
154 pub(super) fn inject_b(&self, enc: &Enc, hyper: &Buf, out: &Buf, nb: usize) {
155 let c = &self.p.cfg;
156 let gp = self.group_params(false, 0.0);
157 let nbu = nb as u32;
158
159 self.dispatch(
160 enc,
161 &self.pipes.inject_b,
162 |e| {
163 self.bind(e, 0, hyper, 0);
164 self.bind(e, 1, out, 0);
165 self.bind(e, 2, &self.scratch.hc.inj, 0);
166 set_bytes(e, 3, &gp);
167 set_bytes(e, 4, &nbu);
168 },
169 nb * c.hc_hidden(),
170 256,
171 false,
172 );
173 }
174}