1use crate::coefcode::{KB, NE};
32use crate::gpuwav::{ESC0, LOW0, MAG0, SGN0, SIG0};
33use crate::lmodel3::{AB, AC};
34use tang_expr::int::{Elem, IId, IType, IntGraph};
35
36pub const BUFS: [(&str, Elem); 2] = [("mt", Elem::U32), ("stream", Elem::U32)];
38pub const STATIC_PARAMS: [IType; 8] = [IType::U32; 8];
40pub const LEARNED_PARAMS: [IType; 10] = [
42 IType::U32,
43 IType::U32,
44 IType::U32,
45 IType::I32,
46 IType::I32,
47 IType::I32,
48 IType::I32,
49 IType::I32,
50 IType::U32,
51 IType::U32,
52];
53pub const OUTS: [IType; 3] = [IType::U32, IType::U32, IType::I32];
55pub const LEARNED_AD_PARAMS: [IType; 14] = [
57 IType::U32,
58 IType::U32,
59 IType::U32,
60 IType::I32,
61 IType::I32,
62 IType::I32,
63 IType::I32,
64 IType::I32,
65 IType::U32,
66 IType::U32,
67 IType::U32,
68 IType::U32,
69 IType::U32,
70 IType::U32,
71];
72pub const OUTS_AD: [IType; 4] = [IType::U32, IType::U32, IType::I32, IType::U32];
74pub const RW_AD: [(&str, Elem, u32, &str); 1] = [("adt", Elem::U32, (AC * AB) as u32, "ad_b")];
77
78#[derive(Clone, Copy)]
80struct St {
81 x: IId,
82 pos: IId,
83}
84
85#[derive(Clone, Copy)]
87struct Ad {
88 buf: u16,
89 so: IId,
90 wa: IId,
91 lim: IId,
92 en: [IId; 4],
94}
95
96struct B {
97 g: IntGraph,
98 mt: u16,
99 stream: u16,
100 end: IId,
101 ad: Option<Ad>,
102}
103
104impl B {
105 fn new() -> Self {
106 let mut g = IntGraph::new();
107 let mt = g.buffer(BUFS[0].0, BUFS[0].1);
108 let stream = g.buffer(BUFS[1].0, BUFS[1].1);
109 let end = g.param(2, IType::U32);
110 Self {
111 g,
112 mt,
113 stream,
114 end,
115 ad: None,
116 }
117 }
118 fn u(&mut self, v: u32) -> IId {
119 self.g.u32(v)
120 }
121 fn i(&mut self, v: i32) -> IId {
122 self.g.i32(v)
123 }
124 fn word(&mut self, i: IId) -> IId {
125 let g = &mut self.g;
126 let inb = g.lt(i, self.end);
127 let one = g.u32(1);
128 let w = g.shr(i, one);
129 let w = g.load(self.stream, w);
130 let par = g.and(i, one);
131 let sixteen = g.u32(16);
132 let sh = g.mul(par, sixteen);
133 let v = g.shr(w, sh);
134 let m = g.u32(0xFFFF);
135 let v = g.and(v, m);
136 let z = g.u32(0);
137 g.select(inb, v, z)
138 }
139 fn step(&mut self, s: St, cum: IId, f: IId, on: Option<IId>) -> St {
141 let sixteen = self.u(16);
142 let m = self.u(0xFFFF);
143 let lim = self.u(65536);
144 let one = self.u(1);
145 let g = &mut self.g;
146 let hi = g.shr(s.x, sixteen);
147 let lo = g.and(s.x, m);
148 let a = g.mul(f, hi);
149 let b = g.sub(lo, cum);
150 let x1 = g.add(a, b);
151 let ren = g.lt(x1, lim);
152 let w = self.word(s.pos);
153 let g = &mut self.g;
154 let xs = g.shl(x1, sixteen);
155 let xr = g.or(xs, w);
156 let x2 = g.select(ren, xr, x1);
157 let p1 = g.add(s.pos, one);
158 let p2 = g.select(ren, p1, s.pos);
159 match on {
160 None => St { x: x2, pos: p2 },
161 Some(c) => St {
162 x: g.select(c, x2, s.x),
163 pos: g.select(c, p2, s.pos),
164 },
165 }
166 }
167 fn bit(&mut self, s: St, p1: IId, on: Option<IId>) -> (St, IId) {
169 let k = self.u(65536);
170 let m = self.u(0xFFFF);
171 let z = self.u(0);
172 let g = &mut self.g;
173 let f0 = g.sub(k, p1);
174 let lo = g.and(s.x, m);
175 let b = g.le(f0, lo);
176 let cum = g.select(b, f0, z);
177 let f = g.select(b, p1, f0);
178 let s = self.step(s, cum, f, on);
179 let b = match on {
180 None => b,
181 Some(c) => self.g.and(b, c),
182 };
183 (s, b)
184 }
185 fn ad_bit(
191 &mut self,
192 s: St,
193 tok: IId,
194 ctx: IId,
195 grp: usize,
196 p1: IId,
197 on: Option<IId>,
198 ) -> (St, IId, IId) {
199 let a = self.ad.expect("adaptive graph");
200 let g = &mut self.g;
201 let (one, four, eight) = (g.u32(1), g.u32(4), g.u32(8));
202 let si = g.shr(p1, four);
203 let si = g.add(a.so, si);
204 let z = g.load(self.mt, si);
205 let z = g.bitcast(IType::I32, z);
206 let (lo, hi, off) = (g.i32(-2048), g.i32(2047), g.i32(2048));
207 let z = g.clamp(z, lo, hi);
208 let z = g.add(z, off);
209 let st = g.bitcast(IType::U32, z);
210 let j = g.shr(st, eight);
211 let m255 = g.u32(255);
212 let w = g.and(st, m255);
213 let kab = g.u32(AB as u32);
214 let b = g.mul(ctx, kab);
215 let b = g.add(b, j);
216 let b1 = g.add(b, one);
217 let e0 = g.load_rw(a.buf, b, tok);
218 let e1 = g.load_rw(a.buf, b1, tok);
219 let t0 = g.shr(e0, eight);
220 let t1 = g.shr(e1, eight);
221 let k256 = g.u32(256);
222 let wi = g.sub(k256, w);
223 let x = g.mul(t0, wi);
224 let y = g.mul(t1, w);
225 let pr = g.add(x, y);
226 let pr = g.shr(pr, eight);
227 let x = g.mul(pr, a.wa);
228 let k16 = g.u32(16);
229 let wb = g.sub(k16, a.wa);
230 let y = g.mul(p1, wb);
231 let pf = g.add(x, y);
232 let pf = g.shr(pf, four);
233 let (c32, c65504) = (g.u32(32), g.u32(65504));
234 let pf = g.clamp(pf, c32, c65504);
235 let en = a.en[grp];
236 let pu = g.select(en, pf, p1);
237 let (s, got) = self.bit(s, pu, on);
238 let g = &mut self.g;
239 let k128 = g.u32(128);
240 let near = g.lt(w, k128);
241 let k = g.select(near, b, b1);
242 let e = g.select(near, e0, e1);
243 let t = g.shr(e, eight);
244 let t = g.bitcast(IType::I32, t);
245 let n = g.and(e, m255);
246 let (zi, top) = (g.i32(0), g.i32(65535));
247 let tg = g.select(got, top, zi);
248 let d = g.sub(tg, t);
249 let two = g.u32(2);
251 let n2 = g.add(n, two);
252 let lz = g.clz(n2);
253 let c31 = g.u32(31);
254 let sh = g.sub(c31, lz);
255 let dd = g.shr(d, sh);
256 let t2 = g.add(t, dd);
257 let t2 = g.bitcast(IType::U32, t2);
258 let t2 = g.shl(t2, eight);
259 let more = g.lt(n, a.lim);
260 let n1 = g.add(n, one);
261 let nn = g.select(more, n1, n);
262 let ne = g.or(t2, nn);
263 let wr = match on {
264 None => en,
265 Some(c) => g.and(en, c),
266 };
267 let v = g.select(wr, ne, e);
268 let tok = g.store(a.buf, k, v, tok);
269 (s, got, tok)
270 }
271 fn raw(&mut self, s: St, n: IId, on: Option<IId>) -> (St, IId) {
273 let sixteen = self.u(16);
274 let m = self.u(0xFFFF);
275 let one = self.u(1);
276 let g = &mut self.g;
277 let sh = g.sub(sixteen, n);
278 let lo = g.and(s.x, m);
279 let v = g.shr(lo, sh);
280 let cum = g.shl(v, sh);
281 let f = g.shl(one, sh);
282 (self.step(s, cum, f, on), v)
283 }
284 fn raw_n(&mut self, s: St, n: IId) -> (St, IId) {
286 let z = self.u(0);
287 let mut b = std::mem::take(&mut self.g);
288 let (stream, end, mt) = (self.stream, self.end, self.mt);
289 let out = b.while_loop(&[n, z, s.x, s.pos], |g, st| {
290 let mut me = B {
291 g: std::mem::take(g),
292 mt,
293 stream,
294 end,
295 ad: None,
296 };
297 let zero = me.u(0);
298 let sixteen = me.u(16);
299 let go = me.g.lt(zero, st[0]);
300 let c = me.g.min(st[0], sixteen);
301 let (s2, v) = me.raw(
302 St {
303 x: st[2],
304 pos: st[3],
305 },
306 c,
307 None,
308 );
309 let o = me.g.shl(st[1], c);
310 let o = me.g.or(o, v);
311 let n2 = me.g.sub(st[0], c);
312 *g = me.g;
313 (go, vec![n2, o, s2.x, s2.pos])
314 });
315 b.cap_loop(out[0], 3);
316 self.g = b;
317 (
318 St {
319 x: out[2],
320 pos: out[3],
321 },
322 out[1],
323 )
324 }
325 fn prior(&mut self, idx: IId, off: IId) -> IId {
326 let g = &mut self.g;
327 let a = g.add(off, idx);
328 let m = g.load(self.mt, a);
329 let mask = g.u32(0xFFFF);
330 let sixteen = g.u32(16);
331 let one = g.u32(1);
332 let lo = g.and(m, mask);
333 let hi = g.shr(m, sixteen);
334 let s = g.add(lo, hi);
335 let s = g.shr(s, one);
336 let (a, b) = (g.u32(32), g.u32(65504));
337 g.clamp(s, a, b)
338 }
339 fn sbit(&mut self, s: St, idx: IId, off: IId, on: Option<IId>) -> (St, IId) {
340 let p = self.prior(idx, off);
341 self.bit(s, p, on)
342 }
343 fn unary(&mut self, s: St, base: IId, off: IId, max: u32, on: IId) -> (St, IId) {
346 let z = self.u(0);
347 let mut b = std::mem::take(&mut self.g);
348 let (stream, end, mt) = (self.stream, self.end, self.mt);
349 let out = b.while_loop(&[z, s.x, s.pos, on], |g, st| {
350 let mut me = B {
351 g: std::mem::take(g),
352 mt,
353 stream,
354 end,
355 ad: None,
356 };
357 let mx = me.u(max);
358 let more = me.g.lt(st[0], mx);
359 let go = me.g.and(st[3], more);
360 let idx = me.g.add(base, st[0]);
361 let (s2, bit) = me.sbit(
362 St {
363 x: st[1],
364 pos: st[2],
365 },
366 idx,
367 off,
368 None,
369 );
370 let one = me.u(1);
371 let h1 = me.g.add(st[0], one);
372 let h = me.g.select(bit, h1, st[0]);
373 *g = me.g;
374 (go, vec![h, s2.x, s2.pos, bit])
375 });
376 b.cap_loop(out[0], max + 1);
377 self.g = b;
378 (
379 St {
380 x: out[1],
381 pos: out[2],
382 },
383 out[0],
384 )
385 }
386}
387
388pub fn static_graph() -> (IntGraph, Vec<IId>) {
390 let mut b = B::new();
391 let g = &mut b.g;
392 let x = g.param(0, IType::U32);
393 let pos = g.param(1, IType::U32);
394 let sig = g.param(3, IType::U32);
395 let e = g.param(4, IType::U32);
396 let cls = g.param(5, IType::U32);
397 let sctx = g.param(6, IType::U32);
398 let off = g.param(7, IType::U32);
399 let s = St { x, pos };
400 let sig0 = b.u(SIG0 as u32);
401 let si = b.g.add(sig0, sig);
402 let (s, en) = b.sbit(s, si, off, None);
403 let two = b.u(2);
405 let k = b.g.max(e, two);
406 let k = b.g.sub(k, two);
407 let ne = b.u(NE as u32);
409 let kb = b.u(KB as u32);
410 let mag0 = b.u(MAG0 as u32);
411 let t = b.g.mul(cls, ne);
412 let t = b.g.add(t, e);
413 let t = b.g.mul(t, kb);
414 let mbase = b.g.add(mag0, t);
415 let (s, h) = b.unary(s, mbase, off, KB as u32, en);
416 let full = b.g.eq(h, kb);
418 let esc = b.g.and(en, full);
419 let esc0 = b.u(ESC0 as u32);
420 let c32 = b.u(32);
421 let t = b.g.mul(cls, c32);
422 let ebase = b.g.add(esc0, t);
423 let (s, nb) = b.unary(s, ebase, off, 31, esc);
424 let (s, glo) = b.raw_n(s, nb);
425 let one = b.u(1);
426 let p = b.g.shl(one, nb);
427 let p = b.g.or(p, glo);
428 let p = b.g.sub(p, one);
429 let hp = b.g.add(h, p);
430 let hv = b.g.select(esc, hp, h);
431 let low0 = b.u(LOW0 as u32);
433 let four = b.u(4);
434 let e4 = b.g.mul(e, four);
435 let lb = b.g.add(low0, e4);
436 let ge1 = b.g.le(one, k);
437 let on1 = b.g.and(en, ge1);
438 let (s, b1) = b.sbit(s, lb, off, Some(on1));
439 let z = b.u(0);
440 let lo1 = b.g.select(b1, one, z);
441 let ge2 = b.g.le(two, k);
442 let on2 = b.g.and(en, ge2);
443 let lb2 = b.g.add(lb, two);
444 let lb2 = b.g.add(lb2, lo1);
445 let (s, b2) = b.sbit(s, lb2, off, Some(on2));
446 let l2 = b.g.shl(lo1, one);
447 let bv = b.g.select(b2, one, z);
448 let l2 = b.g.or(l2, bv);
449 let lo = b.g.select(on2, l2, lo1);
450 let three = b.u(3);
451 let ge3 = b.g.le(three, k);
452 let on3 = b.g.and(en, ge3);
453 let km2 = b.g.sub(k, two);
454 let nraw = b.g.select(on3, km2, z);
455 let (s, rv) = b.raw_n(s, nraw);
456 let l3 = b.g.shl(lo, nraw);
457 let l3 = b.g.or(l3, rv);
458 let lo = b.g.select(on3, l3, lo);
459 let mv = b.g.shl(hv, k);
460 let mv = b.g.or(mv, lo);
461 let mv = b.g.add(mv, one);
462 let sgn0 = b.u(SGN0 as u32);
464 let si = b.g.add(sgn0, sctx);
465 let (s, neg) = b.sbit(s, si, off, Some(en));
466 let mi = b.g.bitcast(IType::I32, mv);
467 let nm = b.g.neg(mi);
468 let r = b.g.select(neg, nm, mi);
469 let zi = b.i(0);
470 let r = b.g.select(en, r, zi);
471 (b.g, vec![s.x, s.pos, r])
472}
473
474impl B {
475 fn sig16(&mut self, z: IId, off_sig: IId) -> IId {
476 let zero = self.i(0);
477 let g = &mut self.g;
478 let neg = g.lt(z, zero);
479 let nz = g.neg(z);
480 let a = g.select(neg, nz, z);
481 let a = g.bitcast(IType::U32, a);
482 let cap = g.u32(4096);
483 let a = g.min(a, cap);
484 let i = g.add(off_sig, a);
485 let s = g.load(self.mt, i);
486 let k = g.u32(65536);
487 let c = g.sub(k, s);
488 g.select(neg, c, s)
489 }
490 fn zval(&mut self, d0: IId, ls0: IId, off_pow: IId) -> IId {
491 let c = |b: &mut B, v: i32| b.i(v);
492 let (lo, hi) = (c(self, -4096), c(self, 6144));
493 let ls = self.g.clamp(ls0, lo, hi);
494 let eight = self.u(8);
495 let i = self.g.shr(ls, eight);
496 let m255 = c(self, 255);
497 let f = self.g.and(ls, m255);
498 let k256 = c(self, 256);
499 let fi = self.g.sub(k256, f);
500 let fu = self.g.bitcast(IType::U32, fi);
501 let pi = self.g.add(off_pow, fu);
502 let m = self.g.load(self.mt, pi);
503 let m = self.g.bitcast(IType::I32, m);
504 let (dl_, dh_) = (c(self, -33554432), c(self, 33554432));
505 let d = self.g.clamp(d0, dl_, dh_);
506 let sixteen = self.u(16);
507 let dh = self.g.shr(d, sixteen);
508 let du = self.g.bitcast(IType::U32, d);
509 let mask = self.u(0xFFFF);
510 let dl = self.g.and(du, mask);
511 let a = self.g.mul(dh, m);
512 let dli = self.g.bitcast(IType::I32, dl);
513 let a = self.g.add(a, dli);
514 let k65536 = c(self, 65536);
515 let mm = self.g.sub(m, k65536);
516 let mmu = self.g.bitcast(IType::U32, mm);
517 let t2 = self.g.mul(dl, mmu);
518 let h = self.u(32768);
519 let t2 = self.g.add(t2, h);
520 let t2 = self.g.shr(t2, sixteen);
521 let t2 = self.g.bitcast(IType::I32, t2);
522 let t = self.g.add(a, t2);
523 let one = c(self, 1);
524 let sh = self.g.add(i, one);
525 let zero = c(self, 0);
526 let pos = self.g.le(zero, sh);
527 let c31 = c(self, 31);
528 let shm = self.g.min(sh, c31);
529 let shu = self.g.bitcast(IType::U32, shm);
530 let rp = self.g.shr(t, shu);
531 let nsh = self.g.neg(sh);
532 let k = self.g.bitcast(IType::U32, nsh);
533 let c4097 = c(self, 4097);
534 let lim = self.g.shr(c4097, k);
535 let tl = self.g.shl(t, k);
536 let n4097 = c(self, -4097);
537 let nlim = self.g.neg(lim);
538 let below = self.g.lt(t, nlim);
539 let sat = self.g.select(below, n4097, tl);
540 let above = self.g.lt(lim, t);
541 let sat = self.g.select(above, c4097, sat);
542 self.g.select(pos, rp, sat)
543 }
544}
545
546struct Mix {
547 pi: IId,
548 mu: [IId; 2],
549 ls: [IId; 2],
550 off_sig: IId,
551 off_pow: IId,
552}
553
554impl B {
555 fn lcdf(&mut self, mx: &Mix, m: IId) -> IId {
556 let (a, b) = (self.i(-65535), self.i(65535));
557 let t = self.g.clamp(m, a, b);
558 let k256 = self.i(256);
559 let t = self.g.mul(t, k256);
560 let k128 = self.i(128);
561 let t = self.g.add(t, k128);
562 let mut c = Vec::with_capacity(2);
563 for j in 0..2 {
564 let d = self.g.sub(t, mx.mu[j]);
565 let z = self.zval(d, mx.ls[j], mx.off_pow);
566 c.push(self.sig16(z, mx.off_sig));
567 }
568 let k = self.u(32768);
569 let a = self.g.mul(mx.pi, c[0]);
570 let w = self.g.sub(k, mx.pi);
571 let b = self.g.mul(w, c[1]);
572 let s = self.g.add(a, b);
573 let f = self.u(15);
574 self.g.shr(s, f)
575 }
576 fn ratio16(&mut self, num: IId, den: IId) -> IId {
577 let g = &mut self.g;
578 let z = g.u32(0);
579 let nz = g.cmp(tang_expr::int::CmpOp::Ne, den, z);
580 let mn = g.min(num, den);
581 let k = g.u32(65535);
582 let p = g.mul(mn, k);
583 let p = g.div(p, den);
584 let h = g.u32(32768);
585 let p = g.select(nz, p, h);
586 let (a, b) = (g.u32(32), g.u32(65504));
587 g.clamp(p, a, b)
588 }
589 fn ltail(&mut self, mx: &Mix, m: IId, neg: IId) -> IId {
590 let mi = self.g.bitcast(IType::I32, m);
591 let nmi = self.g.neg(mi);
592 let one = self.i(1);
593 let mm1 = self.g.sub(mi, one);
594 let arg = self.g.select(neg, nmi, mm1);
595 let c = self.lcdf(mx, arg);
596 let k = self.u(65536);
597 let up = self.g.sub(k, c);
598 let v = self.g.select(neg, c, up);
599 let big = self.u(1 << 30);
600 let over = self.g.lt(big, m);
601 let z = self.u(0);
602 self.g.select(over, z, v)
603 }
604}
605
606pub fn learned_graph() -> (IntGraph, Vec<IId>) {
608 learned_graph_with(false)
609}
610
611pub fn learned_ad_graph() -> (IntGraph, Vec<IId>) {
614 learned_graph_with(true)
615}
616
617fn learned_graph_with(adaptive: bool) -> (IntGraph, Vec<IId>) {
618 let mut b = B::new();
619 let x = b.g.param(0, IType::U32);
620 let pos = b.g.param(1, IType::U32);
621 let o: Vec<IId> = (0..5).map(|k| b.g.param(3 + k, IType::I32)).collect();
622 let off_sig = b.g.param(8, IType::U32);
623 let off_pow = b.g.param(9, IType::U32);
624 let one = b.u(1);
625 let z = b.u(0);
626 let mut tok = z;
627 if adaptive {
628 let g = &mut b.g;
629 let buf = g.buffer_rw(RW_AD[0].0, RW_AD[0].1, RW_AD[0].2, RW_AD[0].3);
630 let so = g.param(10, IType::U32);
631 let wa = g.param(11, IType::U32);
632 let lim = g.param(12, IType::U32);
633 let mask = g.param(13, IType::U32);
634 let on = g.cmp(tang_expr::int::CmpOp::Ne, wa, z);
635 let en = std::array::from_fn(|k| {
636 let kk = g.u32(k as u32);
637 let m = g.shr(mask, kk);
638 let m = g.and(m, one);
639 let m = g.cmp(tang_expr::int::CmpOp::Ne, m, z);
640 g.and(on, m)
641 });
642 b.ad = Some(Ad {
643 buf,
644 so,
645 wa,
646 lim,
647 en,
648 });
649 tok = b.g.token();
650 }
651 let ad = b.ad;
652 let dec = |b: &mut B,
654 s: St,
655 tok: IId,
656 ctx: IId,
657 grp: usize,
658 p: IId,
659 on: Option<IId>|
660 -> (St, IId, IId) {
661 if adaptive {
662 b.ad_bit(s, tok, ctx, grp, p, on)
663 } else {
664 let (s, bit) = b.bit(s, p, on);
665 (s, bit, tok)
666 }
667 };
668 let pi = b.sig16(o[0], off_sig);
669 let pi = b.g.shr(pi, one);
670 let mx = Mix {
671 pi,
672 mu: [o[1], o[2]],
673 ls: [o[3], o[4]],
674 off_sig,
675 off_pow,
676 };
677 let s = St { x, pos };
678 let zi = b.i(0);
679 let m1 = b.i(-1);
680 let c0 = b.lcdf(&mx, zi);
681 let cm1 = b.lcdf(&mx, m1);
682 let gt = b.g.lt(cm1, c0);
683 let d = b.g.sub(c0, cm1);
684 let pz = b.g.select(gt, d, z);
685 let k = b.u(65536);
686 let nzm = b.g.sub(k, pz);
687 let p = b.ratio16(nzm, k);
688 let (s, en, tok) = dec(&mut b, s, tok, z, 0, p, None);
689 let posm = b.g.sub(k, c0);
690 let den = b.g.add(cm1, posm);
691 let p = b.ratio16(cm1, den);
692 let (s, neg, tok) = dec(&mut b, s, tok, one, 1, p, Some(en));
693 let ta0 = b.g.select(neg, cm1, posm);
695 let mut gb = std::mem::take(&mut b.g);
697 let (stream, end, mt) = (b.stream, b.end, b.mt);
698 let mxr = &mx;
699 let out = gb.while_loop(&[z, ta0, z, s.x, s.pos, en, tok], |g, st| {
700 let mut me = B {
701 g: std::mem::take(g),
702 mt,
703 stream,
704 end,
705 ad,
706 };
707 let c30 = me.u(30);
708 let more = me.g.lt(st[0], c30);
709 let go = me.g.and(st[5], more);
710 let one = me.u(1);
711 let k1 = me.g.add(st[0], one);
712 let m = me.g.shl(one, k1);
713 let tb = me.ltail(mxr, m, neg);
714 let p = me.ratio16(tb, st[1]);
715 let (two, three) = (me.u(2), me.u(3));
716 let ctx = me.g.min(st[0], three);
717 let ctx = me.g.add(ctx, two);
718 let (s2, bit, tk) = dec(
719 &mut me,
720 St {
721 x: st[3],
722 pos: st[4],
723 },
724 st[6],
725 ctx,
726 2,
727 p,
728 None,
729 );
730 let ta = me.g.select(bit, tb, st[1]);
731 let kk = me.g.select(bit, k1, st[0]);
732 *g = me.g;
733 (go, vec![kk, ta, tb, s2.x, s2.pos, bit, tk])
734 });
735 gb.cap_loop(out[0], 31);
736 b.g = gb;
737 let (kq, ta, tb, tok) = (out[0], out[1], out[2], out[6]);
738 let s = St {
739 x: out[3],
740 pos: out[4],
741 };
742 let lo = b.g.shl(one, kq);
743 let lm1 = b.g.sub(lo, one);
744 let hi = b.g.add(lo, lm1);
745 let c30 = b.u(30);
746 let lt30 = b.g.lt(kq, c30);
747 let endv = b.g.select(lt30, tb, z);
748 let first = b.g.bool(true);
750 let mut gb = std::mem::take(&mut b.g);
751 let out = gb.while_loop(&[lo, hi, ta, endv, s.x, s.pos, tok, first], |g, st| {
752 let mut me = B {
753 g: std::mem::take(g),
754 mt,
755 stream,
756 end,
757 ad,
758 };
759 let lt = me.g.lt(st[0], st[1]);
760 let go = me.g.and(en, lt);
761 let one = me.u(1);
762 let w = me.g.sub(st[1], st[0]);
763 let w = me.g.add(w, one);
764 let w = me.g.shr(w, one);
765 let mid = me.g.add(st[0], w);
766 let tm = me.ltail(mxr, mid, neg);
767 let z = me.u(0);
768 let gt = me.g.lt(st[3], tm);
769 let d = me.g.sub(tm, st[3]);
770 let up = me.g.select(gt, d, z);
771 let gt = me.g.lt(st[3], st[2]);
772 let d = me.g.sub(st[2], st[3]);
773 let all = me.g.select(gt, d, z);
774 let p = me.ratio16(up, all);
775 let (c6, c7) = (me.u(6), me.u(7));
776 let ctx = me.g.select(st[7], c6, c7);
777 let (s2, bit, tk) = dec(
778 &mut me,
779 St {
780 x: st[4],
781 pos: st[5],
782 },
783 st[6],
784 ctx,
785 3,
786 p,
787 None,
788 );
789 let mm1 = me.g.sub(mid, one);
790 let nlo = me.g.select(bit, mid, st[0]);
791 let ntl = me.g.select(bit, tm, st[2]);
792 let nhi = me.g.select(bit, st[1], mm1);
793 let nend = me.g.select(bit, st[3], tm);
794 let nf = me.g.bool(false);
795 *g = me.g;
796 (go, vec![nlo, nhi, ntl, nend, s2.x, s2.pos, tk, nf])
797 });
798 gb.cap_loop(out[0], 31);
799 b.g = gb;
800 let s = St {
801 x: out[4],
802 pos: out[5],
803 };
804 let li = b.g.bitcast(IType::I32, out[0]);
805 let nl = b.g.neg(li);
806 let r = b.g.select(neg, nl, li);
807 let r = b.g.select(en, r, zi);
808 let mut outs = vec![s.x, s.pos, r];
809 if adaptive {
810 outs.push(out[6]);
811 }
812 (b.g, outs)
813}
814
815pub fn wgsl(stat: (&IntGraph, &[IId]), learned: (&IntGraph, &[IId]), guarded: bool) -> String {
820 let body = |g: &IntGraph, o: &[IId], p: &[&str], d: &[&str]| {
821 if guarded {
822 g.to_wgsl_body_guarded(o, p, d, 1)
823 } else {
824 g.to_wgsl_body(o, p, d, 1)
825 }
826 };
827 let res = ["rx", "rpos", "r", "adk"];
828 let mut s = String::from(
829 "fn res_static_gen(sig: u32, e: u32, cls: u32, sctx: u32) -> i32 {\n var r: i32;\n",
830 );
831 s += &body(
832 stat.0,
833 stat.1,
834 &[
835 "rx",
836 "rpos",
837 "rend",
838 "sig",
839 "e",
840 "cls",
841 "sctx",
842 "P.off_init",
843 ],
844 &res[..3],
845 );
846 s += " return r;\n}\n\nfn res_learned_gen(o0: i32, o1: i32, o2: i32, o3: i32, o4: i32) -> i32 {\n var r: i32;\n";
847 let mut p = vec![
848 "rx",
849 "rpos",
850 "rend",
851 "o0",
852 "o1",
853 "o2",
854 "o3",
855 "o4",
856 "mt[P.pad4]",
857 "mt[P.pad4 + 1u]",
858 ];
859 if learned.1.len() == OUTS_AD.len() {
860 s += " var adk: u32;\n";
861 p.extend(["ad_so", "ad_wa", "ad_lim", "ad_mask"]);
862 }
863 s += &body(learned.0, learned.1, &p, &res[..learned.1.len()]);
864 s += " return r;\n}\n";
865 s
866}
867
868pub fn builtin_wgsl() -> &'static str {
870 static S: std::sync::OnceLock<String> = std::sync::OnceLock::new();
871 S.get_or_init(|| {
872 let (a, ao) = static_graph();
873 let (b, bo) = learned_graph();
874 wgsl((&a, &ao), (&b, &bo), false)
875 })
876}
877
878pub fn builtin_wgsl_ad() -> &'static str {
880 static S: std::sync::OnceLock<String> = std::sync::OnceLock::new();
881 S.get_or_init(|| {
882 let (a, ao) = static_graph();
883 let (b, bo) = learned_ad_graph();
884 wgsl((&a, &ao), (&b, &bo), false)
885 })
886}
887
888pub fn splice_res(src: &str, res: &str) -> String {
890 let a = src.find("// RES_BEGIN").expect("RES_BEGIN");
891 let b = src.find("// RES_END").expect("RES_END");
892 let mut out = format!("{}// RES_BEGIN\n{}{}", &src[..a], res, &src[b..]);
893 if out.contains("tx_mulhi_") && !out.contains("fn tx_mulhi_u32") {
894 out.push_str(tang_expr::int::WGSL_PRELUDE);
895 }
896 out
897}
898
899pub fn stream_words(bytes: &[u8]) -> Vec<u32> {
901 bytes
902 .chunks(4)
903 .map(|c| {
904 let mut b = [0u8; 4];
905 b[..c.len()].copy_from_slice(c);
906 u32::from_le_bytes(b)
907 })
908 .collect()
909}
910
911#[derive(Clone, Copy, Debug)]
913pub struct Lane {
914 pub x: u32,
916 pub pos: u32,
918 pub end: u32,
920 lo: u32,
921}
922
923impl Lane {
924 pub fn new(stream: &[u32], lo: u32, hi: u32) -> Self {
926 let w = |i: u32| {
927 if i < hi {
928 (stream.get((i >> 1) as usize).copied().unwrap_or(0) >> ((i & 1) * 16)) & 0xFFFF
929 } else {
930 0
931 }
932 };
933 let x = if hi.wrapping_sub(lo) >= 2 && hi >= lo {
934 w(lo) | w(lo + 1) << 16
935 } else {
936 1 << 16
937 };
938 Self {
939 x,
940 pos: lo + 2,
941 end: hi,
942 lo,
943 }
944 }
945 pub fn overrun(&self) -> bool {
947 self.end >= self.lo + 2 && self.pos > self.end
948 }
949}
950
951#[derive(Clone)]
953pub struct CpuRes {
954 prog: tang_expr::int::Program,
955 learned: bool,
956 off: [u32; 2],
957 ad: Option<[u32; 4]>,
959}
960
961impl CpuRes {
962 pub fn new(g: &IntGraph, outs: &[IId], learned: bool, off: [u32; 2]) -> Self {
965 Self {
966 prog: tang_expr::int::Program::new(g, outs),
967 learned,
968 off,
969 ad: None,
970 }
971 }
972 pub fn new_ad(g: &IntGraph, outs: &[IId], off: [u32; 2], ad: crate::lmodel3::AdCfg) -> Self {
975 let so = off[1] + crate::lmodel3::tables().1.len() as u32;
976 Self {
977 prog: tang_expr::int::Program::new(g, outs),
978 learned: true,
979 off,
980 ad: Some([so, ad.wa, ad.lim, ad.mask]),
981 }
982 }
983 pub fn learned(&self) -> bool {
985 self.learned
986 }
987 #[allow(clippy::too_many_arguments)]
989 pub fn res_static(
990 &mut self,
991 l: &mut Lane,
992 mt: &[u32],
993 stream: &[u32],
994 sig: u32,
995 e: u32,
996 cls: u32,
997 sctx: u32,
998 ) -> i32 {
999 let p = [l.x, l.pos, l.end, sig, e, cls, sctx, self.off[0]];
1000 self.run(l, &p, mt, stream)
1001 }
1002 pub fn res_learned(
1005 &mut self,
1006 l: &mut Lane,
1007 mt: &[u32],
1008 stream: &[u32],
1009 o: &[i32; 5],
1010 adt: &mut [u32],
1011 ) -> i32 {
1012 let a = self.ad.unwrap_or_default();
1013 let p = [
1014 l.x,
1015 l.pos,
1016 l.end,
1017 o[0] as u32,
1018 o[1] as u32,
1019 o[2] as u32,
1020 o[3] as u32,
1021 o[4] as u32,
1022 self.off[0],
1023 self.off[1],
1024 a[0],
1025 a[1],
1026 a[2],
1027 a[3],
1028 ];
1029 let mut out = [0u32; 4];
1030 self.prog.run_rw(&p, &[mt, stream], &mut [adt], &mut out);
1031 l.x = out[0];
1032 l.pos = out[1];
1033 out[2] as i32
1034 }
1035 fn run(&mut self, l: &mut Lane, p: &[u32], mt: &[u32], stream: &[u32]) -> i32 {
1036 let mut o = [0u32; 3];
1037 self.prog.run(p, &[mt, stream], &mut o);
1038 l.x = o[0];
1039 l.pos = o[1];
1040 o[2] as i32
1041 }
1042}
1043
1044pub fn cpu_mt(init: &[u32]) -> (Vec<u32>, [u32; 2]) {
1047 let (sig, pw) = crate::lmodel3::tables();
1048 let mut v = init.to_vec();
1049 let os = v.len() as u32;
1050 v.extend_from_slice(sig);
1051 let op = v.len() as u32;
1052 v.extend_from_slice(pw);
1053 v.extend(crate::lmodel3::stretch_tab().iter().map(|&z| z as u32));
1054 (v, [os, op])
1055}
1056
1057#[cfg(test)]
1058mod tests {
1059 use super::*;
1060 use crate::gpuwav::{code_res, rans_encode, Feats, RecSink, NMODEL};
1061 use crate::lmodel3::{code_learned, Mix3};
1062
1063 fn rng(s: &mut u64) -> u32 {
1064 *s = s
1065 .wrapping_mul(6364136223846793005)
1066 .wrapping_add(1442695040888963407);
1067 (*s >> 33) as u32
1068 }
1069
1070 fn to_bytes(w: &[u16]) -> Vec<u8> {
1071 w.iter().flat_map(|v| v.to_le_bytes()).collect()
1072 }
1073
1074 #[test]
1075 fn static_graph_decodes_native_encoding() {
1076 let mut s = 1u64;
1077 let init: Vec<u32> = (0..NMODEL)
1078 .map(|_| (rng(&mut s) & 0xFFFF) | (rng(&mut s) & 0xFFFF) << 16)
1079 .collect();
1080 let mut syms = RecSink {
1081 syms: vec![Vec::new()],
1082 };
1083 let mut items = Vec::new();
1084 for _ in 0..4000 {
1085 let e = (rng(&mut s) % NE as u32) as usize;
1086 let cls = (rng(&mut s) % 10) as usize;
1087 let f = Feats {
1088 taps: [0; crate::gpuwav::NTAP],
1089 sig: (rng(&mut s) % 240) as usize,
1090 e,
1091 sctx: cls * 9 + (rng(&mut s) % 9) as usize,
1092 raw: [0; 18],
1093 };
1094 let r = match rng(&mut s) % 4 {
1095 0 => 0,
1096 1 => (rng(&mut s) % 7) as i32 - 3,
1097 2 => (rng(&mut s) % 70000) as i32 - 35000,
1098 _ => (rng(&mut s) as i32) >> (rng(&mut s) % 31),
1099 };
1100 let mut m = init.clone();
1101 let got = code_res::<RecSink, false>(&mut syms, 0, &mut m, cls, &f, r);
1102 assert_eq!(got, r);
1103 items.push((f, cls, r));
1104 }
1105 let words = rans_encode(&syms.syms[0]);
1106 let mut bytes = vec![0u8, 0, 0, 0, 0, 0]; bytes.extend(to_bytes(&words));
1108 let sw = stream_words(&bytes);
1109 let (g, o) = static_graph();
1110 let mut cr = CpuRes::new(&g, &o, false, [0, 0]);
1111 let mut l = Lane::new(&sw, 3, 3 + words.len() as u32);
1112 for (f, cls, r) in items {
1113 assert_eq!(
1114 cr.res_static(
1115 &mut l,
1116 &init,
1117 &sw,
1118 f.sig as u32,
1119 f.e as u32,
1120 cls as u32,
1121 f.sctx as u32
1122 ),
1123 r
1124 );
1125 }
1126 assert!(!l.overrun());
1127 assert_eq!(l.pos, l.end);
1128 }
1129
1130 #[test]
1131 fn learned_graph_decodes_native_encoding() {
1132 let mut s = 2u64;
1133 let mut syms = RecSink {
1134 syms: vec![Vec::new()],
1135 };
1136 let mut items = Vec::new();
1137 for _ in 0..3000 {
1138 let o = [
1139 (rng(&mut s) % 4000) as i32 - 2000,
1140 (rng(&mut s) % 6000) as i32 - 3000,
1141 (rng(&mut s) % 6000) as i32 - 3000,
1142 (rng(&mut s) % 9000) as i32 - 4096,
1143 (rng(&mut s) % 9000) as i32 - 4096,
1144 ];
1145 let r = match rng(&mut s) % 3 {
1146 0 => 0,
1147 1 => (rng(&mut s) % 41) as i32 - 20,
1148 _ => (rng(&mut s) as i32) >> (rng(&mut s) % 31 + 1),
1149 };
1150 let got = code_learned(&mut syms, 0, &Mix3::new(&o), r);
1151 assert_eq!(got, r);
1152 items.push((o, r));
1153 }
1154 let words = rans_encode(&syms.syms[0]);
1155 let sw = stream_words(&to_bytes(&words));
1156 let (mt, off) = cpu_mt(&[]);
1157 let (g, go) = learned_graph();
1158 let mut cr = CpuRes::new(&g, &go, true, off);
1159 let mut l = Lane::new(&sw, 0, words.len() as u32);
1160 for (o, r) in items {
1161 assert_eq!(cr.res_learned(&mut l, &mt, &sw, &o, &mut []), r);
1162 }
1163 assert_eq!(l.pos, l.end);
1164 }
1165
1166 #[test]
1167 fn learned_ad_graph_decodes_native_encoding() {
1168 use crate::lmodel3::{ad_init, code_learned_ad, AdCfg, Adapt};
1169 let (g, go) = learned_ad_graph();
1170 let w = g.to_bytes(&go);
1172 let (g2, go2) = IntGraph::from_bytes_rw(
1173 &w,
1174 &LEARNED_AD_PARAMS,
1175 &BUFS,
1176 &RW_AD,
1177 &OUTS_AD,
1178 &tang_expr::int::Limits::default(),
1179 )
1180 .unwrap();
1181 for c in [
1182 AdCfg {
1183 wa: 10,
1184 lim: 14,
1185 mask: 15,
1186 },
1187 AdCfg {
1188 wa: 16,
1189 lim: 3,
1190 mask: 5,
1191 },
1192 AdCfg {
1193 wa: 0,
1194 lim: 0,
1195 mask: 0,
1196 },
1197 ] {
1198 let mut s = 3u64;
1199 let mut syms = RecSink {
1200 syms: vec![Vec::new()],
1201 };
1202 let mut ad = Adapt::new(c);
1203 let mut items = Vec::new();
1204 for i in 0..4000 {
1205 if i % 1000 == 0 {
1206 ad = Adapt::new(c);
1207 }
1208 let o = [
1209 (rng(&mut s) % 4000) as i32 - 2000,
1210 (rng(&mut s) % 600) as i32 - 300,
1211 (rng(&mut s) % 6000) as i32 - 3000,
1212 (rng(&mut s) % 3000) as i32 - 1000,
1213 (rng(&mut s) % 9000) as i32 - 4096,
1214 ];
1215 let r = match rng(&mut s) % 3 {
1216 0 => 0,
1217 1 => (rng(&mut s) % 41) as i32 - 20,
1218 _ => (rng(&mut s) as i32) >> (rng(&mut s) % 31 + 1),
1219 };
1220 assert_eq!(code_learned_ad(&mut syms, 0, &Mix3::new(&o), r, &mut ad), r);
1221 items.push((o, r));
1222 }
1223 let words = rans_encode(&syms.syms[0]);
1224 let sw = stream_words(&to_bytes(&words));
1225 let (mt, off) = cpu_mt(&[]);
1226 for (g, go) in [(&g, &go), (&g2, &go2)] {
1227 let mut cr = CpuRes::new_ad(g, go, off, c);
1228 let mut l = Lane::new(&sw, 0, words.len() as u32);
1229 let mut adt = ad_init();
1230 for (i, (o, r)) in items.iter().enumerate() {
1231 if i % 1000 == 0 {
1232 adt = ad_init();
1233 }
1234 assert_eq!(
1235 cr.res_learned(&mut l, &mt, &sw, o, &mut adt),
1236 *r,
1237 "{c:?} item {i}"
1238 );
1239 }
1240 assert_eq!(l.pos, l.end);
1241 }
1242 }
1243 }
1244}