From 41737afb22df35131f73af9972da4e4d2a673d34 Mon Sep 17 00:00:00 2001 From: Transaction Science Date: Fri, 9 Oct 2026 17:19:39 -0400 Subject: [PATCH 01/15] wai-ops: the reference crate for wai-ops/1 (WHG1, plans, interpreter, stage operators, lowerings) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A new crate, wai/wai-ops: no_std with alloc, no dependencies. - xint: a 512-bit signed integer with the saturation of integer-operators §8.1. - json: a reader that keeps numbers as written, and the canonical writer of §8.5. - graph: WHG1 parse and write, load steps 1–6 of §10.5. - plan: the load-time plan (step 7) and the run-time plan (§4). - interp: every graph operator of §5, exact in i128, with the policies and the sequence state of §10.3. - stage: E1–E13; E1 with both escapes, both end rules and both table rules, E8 total with every refusal stream_exhausted. - lower: int_synth/1, whm1/1, wam1/1, wmb1/1, world/1 and jpegai-int/1 (§13.6.1), each writing §13.0's canonical bytes. Load step 8 (the bounds pass and the verdict) is not built: without the `uncertified` feature every graph is refused at step 8; with it, step 8 is skipped. tests/goldens.rs lowers every committed set and decodes its committed payload through the interpreter and the stage operators, and every output digest reproduces: the four int_synth sets, both world clips frame by frame, the int_hyper tiny set, splat, audio and int_mlicpp. Opt-in, against data that is not committed: the jpegai scale path and both mANS decodes equal the legacy decoder's every intermediate on a real codestream, and E8 equals the reference encoder's streams and tables. Co-Authored-By: Claude Opus 5.5 --- wai/wai-ops/Cargo.lock | 7 + wai/wai-ops/Cargo.toml | 43 ++ wai/wai-ops/src/bin/wai-ops.rs | 1 + wai/wai-ops/src/code.rs | 78 +++ wai/wai-ops/src/generate/mod.rs | 1 + wai/wai-ops/src/graph.rs | 1001 +++++++++++++++++++++++++++++++ wai/wai-ops/src/interp.rs | 611 +++++++++++++++++++ wai/wai-ops/src/json.rs | 471 +++++++++++++++ wai/wai-ops/src/lib.rs | 39 ++ wai/wai-ops/src/lower/jpegai.rs | 136 +++++ wai/wai-ops/src/lower/mod.rs | 110 ++++ wai/wai-ops/src/lower/synth.rs | 74 +++ wai/wai-ops/src/lower/whm.rs | 395 ++++++++++++ wai/wai-ops/src/plan.rs | 259 ++++++++ wai/wai-ops/src/sha256.rs | 78 +++ wai/wai-ops/src/stage/mans.rs | 305 ++++++++++ wai/wai-ops/src/stage/mod.rs | 253 ++++++++ wai/wai-ops/src/stage/rans64.rs | 220 +++++++ wai/wai-ops/src/vectors.rs | 323 ++++++++++ wai/wai-ops/src/xint.rs | 435 ++++++++++++++ wai/wai-ops/tests/goldens.rs | 450 ++++++++++++++ 21 files changed, 5290 insertions(+) create mode 100644 wai/wai-ops/Cargo.lock create mode 100644 wai/wai-ops/Cargo.toml create mode 100644 wai/wai-ops/src/bin/wai-ops.rs create mode 100644 wai/wai-ops/src/code.rs create mode 100644 wai/wai-ops/src/generate/mod.rs create mode 100644 wai/wai-ops/src/graph.rs create mode 100644 wai/wai-ops/src/interp.rs create mode 100644 wai/wai-ops/src/json.rs create mode 100644 wai/wai-ops/src/lib.rs create mode 100644 wai/wai-ops/src/lower/jpegai.rs create mode 100644 wai/wai-ops/src/lower/mod.rs create mode 100644 wai/wai-ops/src/lower/synth.rs create mode 100644 wai/wai-ops/src/lower/whm.rs create mode 100644 wai/wai-ops/src/plan.rs create mode 100644 wai/wai-ops/src/sha256.rs create mode 100644 wai/wai-ops/src/stage/mans.rs create mode 100644 wai/wai-ops/src/stage/mod.rs create mode 100644 wai/wai-ops/src/stage/rans64.rs create mode 100644 wai/wai-ops/src/vectors.rs create mode 100644 wai/wai-ops/src/xint.rs create mode 100644 wai/wai-ops/tests/goldens.rs diff --git a/wai/wai-ops/Cargo.lock b/wai/wai-ops/Cargo.lock new file mode 100644 index 000000000..b89c00775 --- /dev/null +++ b/wai/wai-ops/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "wai-ops" +version = "0.1.0" diff --git a/wai/wai-ops/Cargo.toml b/wai/wai-ops/Cargo.toml new file mode 100644 index 000000000..24b413384 --- /dev/null +++ b/wai/wai-ops/Cargo.toml @@ -0,0 +1,43 @@ +# The reference implementation of `wai-ops/1`, the integer operator set +# (`extensions/integer-operators.md`): the `WHG1` graph form, the load and run-time +# plans, the interpreter, the stage operators, the canonical lowerings of the +# registered integer network forms, and the conformance vectors of +# `../ops-conformance/`. +# +# `no_std` with `alloc`, and no dependencies, so that a model checker can include +# its sources by `#[path]` the way `wai-verify` includes the other integer sources. +[package] +name = "wai-ops" +version = "0.1.0" +edition = "2024" +rust-version = "1.97" +license = "Apache-2.0" +publish = false +description = "WAI integer operator set wai-ops/1: WHG1 graphs, plans, interpreter, stage operators, lowerings and conformance vectors" + +[lib] +name = "wai_ops" +path = "src/lib.rs" + +# The vector and lowering tool. It reads and writes files, so it is `std`; the +# library it drives is not. +[[bin]] +name = "wai-ops" +path = "src/bin/wai-ops.rs" +required-features = ["uncertified"] + +[features] +# Load step 8 (the bounds pass and the profile verdict, §10.5) is not built yet. +# Without this switch a graph cannot complete its load; with it, step 8 is skipped, +# so the vectors and the lowerings run before the certifier exists. Tests and the +# conformance tool only. +uncertified = [] + +[lints.rust] +unexpected_cfgs = { level = "warn", check-cfg = ["cfg(kani)"] } + +[dependencies] +# none + +[profile.release] +debug = false diff --git a/wai/wai-ops/src/bin/wai-ops.rs b/wai/wai-ops/src/bin/wai-ops.rs new file mode 100644 index 000000000..f328e4d9d --- /dev/null +++ b/wai/wai-ops/src/bin/wai-ops.rs @@ -0,0 +1 @@ +fn main() {} diff --git a/wai/wai-ops/src/code.rs b/wai/wai-ops/src/code.rs new file mode 100644 index 000000000..adfd43426 --- /dev/null +++ b/wai/wai-ops/src/code.rs @@ -0,0 +1,78 @@ +//! Refusal codes (§4, §5E) and where a refusal arose. + +/// The codes this extension gives. A capability whose payload extension reports one +/// code for every refusal maps these onto it (§4). +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub enum Code { + ModelMismatch, + TooLarge, + FieldRange, + GeometryMismatch, + StreamExhausted, + StreamNoncanonical, +} + +impl Code { + /// The code as the vector files write it. + pub fn as_str(self) -> &'static str { + match self { + Code::ModelMismatch => "model_mismatch", + Code::TooLarge => "too_large", + Code::FieldRange => "field_range", + Code::GeometryMismatch => "geometry_mismatch", + Code::StreamExhausted => "stream_exhausted", + Code::StreamNoncanonical => "stream_noncanonical", + } + } + + /// The inverse of [`Code::as_str`]. + pub fn parse(s: &str) -> Option { + Some(match s { + "model_mismatch" => Code::ModelMismatch, + "too_large" => Code::TooLarge, + "field_range" => Code::FieldRange, + "geometry_mismatch" => Code::GeometryMismatch, + "stream_exhausted" => Code::StreamExhausted, + "stream_noncanonical" => Code::StreamNoncanonical, + _ => return None, + }) + } +} + +/// Where a refusal arose. Informational: two conforming implementations agree on +/// the [`Code`], and on the symbol or element index a stage vector records. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Site { + /// A load step of §10.5 (1–8). + Load(u8), + /// A graph input, by its position in the input table. + Input(u32), + /// A scalar, by its position in the scalar table. + Scalar(u32), + /// An operator, by its position in graph order. + Op(u32), + /// A stage operator's symbol or element, by its index. + Symbol(u64), + /// A stage operator's table, refused before any symbol. + Table(u32), + /// A lowering (§13). + Lowering, +} + +/// A refusal: its code and its site. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct Refusal { + pub code: Code, + pub at: Site, +} + +impl Refusal { + pub const fn new(code: Code, at: Site) -> Refusal { + Refusal { code, at } + } +} + +/// Shorthand for a load refusal at `step`. +pub(crate) const fn at_load(code: Code, step: u8) -> Refusal { + Refusal { code, at: Site::Load(step) } +} diff --git a/wai/wai-ops/src/generate/mod.rs b/wai/wai-ops/src/generate/mod.rs new file mode 100644 index 000000000..a28168cc6 --- /dev/null +++ b/wai/wai-ops/src/generate/mod.rs @@ -0,0 +1 @@ +//! The generator of `../ops-conformance/` (placeholder). diff --git a/wai/wai-ops/src/graph.rs b/wai/wai-ops/src/graph.rs new file mode 100644 index 000000000..10616c0cd --- /dev/null +++ b/wai/wai-ops/src/graph.rs @@ -0,0 +1,1001 @@ +//! `WHG1`, the graph form (§10): the records, the operator parameters, parse and +//! write, and load steps 1–6 of §10.5. Every refusal here is `model_mismatch`. + +use alloc::vec; +use alloc::vec::Vec; + +use crate::code::{Code, Refusal, at_load}; + +pub const MAGIC: &[u8; 4] = b"WHG1"; +/// The cap of §3: `2^26` elements. +pub const CAP: u64 = 1 << 26; + +/// A tensor's policy (§3). +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Policy { + Derived, + Clamp, + Check, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct ScalarRec { + pub lo: i64, + pub hi: i64, +} + +/// An input record (§10.2). `kind` 0 is data, 1 is state. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct InputRec { + pub tensor: u32, + pub max_h: u32, + pub max_w: u32, + pub kind: u8, + pub src: u32, + pub init: i64, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct TensorRec { + pub channels: u32, + /// −128 is "no exponent". + pub exponent: i8, + pub policy: Policy, + pub lo: i64, + pub hi: i64, +} + +impl TensorRec { + pub fn derived(channels: u32) -> TensorRec { + TensorRec { channels, exponent: -128, policy: Policy::Derived, lo: 0, hi: 0 } + } + pub fn check(channels: u32, lo: i64, hi: i64) -> TensorRec { + TensorRec { channels, exponent: -128, policy: Policy::Check, lo, hi } + } + pub fn clamp(channels: u32, lo: i64, hi: i64) -> TensorRec { + TensorRec { channels, exponent: -128, policy: Policy::Clamp, lo, hi } + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Round { + Floor, + HalfUp, + HalfEven, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum BiasKind { + None, + Pre, + Post, +} + +/// The requantisation block `RQ` (§5.1, §10.4), over `C` channels. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Rq { + pub round: Round, + pub bias_kind: BiasKind, + /// 0 absent, 1 one value, 2 one per channel. + pub m_kind: u8, + /// 1 one value, 2 one per channel. + pub s_kind: u8, + pub m_bytes: u8, + pub b_bytes: u8, + pub mult: Vec, + pub shift: Vec, + pub bias: Vec, +} + +impl Rq { + /// Channel `o`'s multiplier, or `None` when it is absent (which means 1). + pub fn mult(&self, o: usize) -> Option { + match self.m_kind { + 0 => None, + 1 => Some(self.mult[0]), + _ => Some(self.mult[o]), + } + } + pub fn shift(&self, o: usize) -> u32 { + (if self.s_kind == 1 { self.shift[0] } else { self.shift[o] }) as u32 + } + pub fn pre(&self, o: usize) -> i64 { + if self.bias_kind == BiasKind::Pre { self.bias[o] } else { 0 } + } + pub fn post(&self, o: usize) -> i64 { + if self.bias_kind == BiasKind::Post { self.bias[o] } else { 0 } + } + /// A block with no multiplier, one shift, no bias. + pub fn plain(round: Round, shift: u8) -> Rq { + Rq { round, bias_kind: BiasKind::None, m_kind: 0, s_kind: 1, m_bytes: 0, b_bytes: 0, mult: vec![], shift: vec![shift], bias: vec![] } + } +} + +/// A `crop` operand: a constant, or the index of a scalar. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Operand { + Const(u32), + Scalar(u32), +} + +/// Each operator's parameters (§10.4). +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum Params { + Conv { cout: u32, kh: u32, kw: u32, sh: u32, sw: u32, ph: u32, pw: u32, groups: u32, w_bytes: u8, rq: Rq, w: Vec }, + ConvT { cout: u32, kh: u32, kw: u32, sh: u32, sw: u32, ph: u32, pw: u32, oph: u32, opw: u32, w_bytes: u8, rq: Rq, w: Vec }, + Rescale(Rq), + Chscale { scalar: u32, n_rows: u32, round: Round, m_bytes: u8, shift: u8, m: Vec }, + Mul(Rq), + Lut16 { e_in: i8, e_out: i8, t: Vec }, + /// `add`, `concat`, `chunk_add`, `relu`, `abs`, `crop_to`, `softmax`, `sigmoid`. + None, + Split { start: u32, count: u32 }, + /// `pixel_shuffle` and `pixel_unshuffle`. + Shuffle { r: u32 }, + Clamp { lo: i64, hi: i64 }, + Leaky { a: i64, f: u32 }, + PadRep { m: u32 }, + Crop { y0: Operand, x0: Operand, h: Operand, w: Operand }, + Subpos { order: [u8; 4] }, + /// `kind` 0 a constant `value`, 1 the scalar whose index is `value`. + Fill { kind: u8, value: i64 }, + Igdn { gf: u32, frac: u32, g_bytes: u8, gamma: Vec, beta: Vec }, + LayerNorm { eps: u64, g_bytes: u8, gamma: Vec, beta: Vec }, + L2norm { eps: u64 }, + Elu { alpha: i64 }, + Gram { groups: u32, rq: Rq }, + Apply { groups: u32, rq: Rq }, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Op { + pub code: u8, + pub ins: Vec, + pub outs: Vec, + pub p: Params, +} + +/// A parsed `WHG1` graph. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Graph { + pub max_elems: u32, + pub scalars: Vec, + pub inputs: Vec, + pub outputs: Vec, + pub tensors: Vec, + pub ops: Vec, +} + +pub mod opcode { + pub const CONV: u8 = 0x01; + pub const RESCALE: u8 = 0x02; + pub const CHSCALE: u8 = 0x03; + pub const LUT16: u8 = 0x04; + pub const ADD: u8 = 0x05; + pub const CONCAT: u8 = 0x06; + pub const CHUNK_ADD: u8 = 0x07; + pub const SPLIT: u8 = 0x08; + pub const PIXEL_SHUFFLE: u8 = 0x09; + pub const PIXEL_UNSHUFFLE: u8 = 0x0A; + pub const CLAMP: u8 = 0x0B; + pub const RELU: u8 = 0x0C; + pub const LEAKY: u8 = 0x0D; + pub const PAD_REP: u8 = 0x0E; + pub const CROP_TO: u8 = 0x0F; + pub const MUL: u8 = 0x10; + pub const CONV_TRANSPOSE: u8 = 0x11; + pub const IGDN: u8 = 0x12; + pub const ABS: u8 = 0x13; + pub const CROP: u8 = 0x14; + pub const SUBPOS_SPLIT: u8 = 0x15; + pub const SUBPOS_MERGE: u8 = 0x16; + pub const FILL: u8 = 0x17; + pub const LAYERNORM_C: u8 = 0x18; + pub const L2NORM: u8 = 0x19; + pub const SOFTMAX: u8 = 0x1A; + pub const SIGMOID: u8 = 0x1B; + pub const ELU: u8 = 0x1C; + pub const GRAM: u8 = 0x1D; + pub const APPLY: u8 = 0x1E; +} + +/// An operator's name (§5), or `None` for an opcode that is not one. +pub fn op_name(code: u8) -> Option<&'static str> { + Some(match code { + 0x01 => "conv", + 0x02 => "rescale", + 0x03 => "chscale", + 0x04 => "lut16", + 0x05 => "add", + 0x06 => "concat", + 0x07 => "chunk_add", + 0x08 => "split", + 0x09 => "pixel_shuffle", + 0x0A => "pixel_unshuffle", + 0x0B => "clamp", + 0x0C => "relu", + 0x0D => "leaky", + 0x0E => "pad_rep", + 0x0F => "crop_to", + 0x10 => "mul", + 0x11 => "conv_transpose", + 0x12 => "igdn", + 0x13 => "abs", + 0x14 => "crop", + 0x15 => "subpos_split", + 0x16 => "subpos_merge", + 0x17 => "fill", + 0x18 => "layernorm_c", + 0x19 => "l2norm", + 0x1A => "softmax", + 0x1B => "sigmoid", + 0x1C => "elu", + 0x1D => "gram", + 0x1E => "apply", + _ => return None, + }) +} + +/// Every opcode, in table order. +pub const OPCODES: [u8; 30] = [ + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, +]; + +/// The operator's arity: `(n_in, n_out)`, with `n_in = 0` for `concat` (at least 2). +pub fn arity(code: u8) -> (u8, u8) { + use opcode::*; + match code { + ADD | CROP_TO | MUL | GRAM | APPLY => (2, 1), + CONCAT => (0, 1), + SUBPOS_SPLIT => (1, 4), + SUBPOS_MERGE => (4, 1), + _ => (1, 1), + } +} + +// ---------------------------------------------------------------- reading + +struct R<'a> { + b: &'a [u8], + p: usize, + end: usize, +} + +type Res = Result; + +impl<'a> R<'a> { + fn take(&mut self, n: usize, step: u8) -> Res<&'a [u8]> { + let e = self.p.checked_add(n).filter(|&e| e <= self.end).ok_or(at_load(Code::ModelMismatch, step))?; + let s = &self.b[self.p..e]; + self.p = e; + Ok(s) + } + fn u8(&mut self, st: u8) -> Res { + Ok(self.take(1, st)?[0]) + } + fn i8(&mut self, st: u8) -> Res { + Ok(self.take(1, st)?[0] as i8) + } + fn u16(&mut self, st: u8) -> Res { + let s = self.take(2, st)?; + Ok(u16::from_le_bytes([s[0], s[1]])) + } + fn u32(&mut self, st: u8) -> Res { + let s = self.take(4, st)?; + Ok(u32::from_le_bytes([s[0], s[1], s[2], s[3]])) + } + fn i64(&mut self, st: u8) -> Res { + let s = self.take(8, st)?; + Ok(i64::from_le_bytes([s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7]])) + } + fn u64(&mut self, st: u8) -> Res { + Ok(self.i64(st)? as u64) + } + /// `n` signed integers of `width` bytes each (1, 2, 4 or 8). + fn ints(&mut self, n: u64, width: u8, st: u8) -> Res> { + let len = n.checked_mul(width as u64).and_then(|v| usize::try_from(v).ok()).ok_or(at_load(Code::ModelMismatch, st))?; + let s = self.take(len, st)?; + Ok(s.chunks_exact(width as usize) + .map(|c| match width { + 1 => c[0] as i8 as i64, + 2 => i16::from_le_bytes([c[0], c[1]]) as i64, + 4 => i32::from_le_bytes([c[0], c[1], c[2], c[3]]) as i64, + _ => i64::from_le_bytes([c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]]), + }) + .collect()) + } + fn zero(&mut self, n: usize, st: u8) -> Res<()> { + if self.take(n, st)?.iter().all(|&b| b == 0) { Ok(()) } else { Err(at_load(Code::ModelMismatch, st)) } + } +} + +fn mm(step: u8) -> Res { + Err(at_load(Code::ModelMismatch, step)) +} + +fn round_of(v: u8, st: u8) -> Res { + Ok(match v { + 0 => Round::Floor, + 1 => Round::HalfUp, + 2 => Round::HalfEven, + _ => return mm(st), + }) +} + +fn round_code(r: Round) -> u8 { + match r { + Round::Floor => 0, + Round::HalfUp => 1, + Round::HalfEven => 2, + } +} + +fn read_rq(r: &mut R, c: u64, st: u8) -> Res { + let round = round_of(r.u8(st)?, st)?; + let bias_kind = match r.u8(st)? { + 0 => BiasKind::None, + 1 => BiasKind::Pre, + 2 => BiasKind::Post, + _ => return mm(st), + }; + let m_kind = r.u8(st)?; + let s_kind = r.u8(st)?; + let m_bytes = r.u8(st)?; + let b_bytes = r.u8(st)?; + if r.u16(st)? != 0 { + return mm(st); + } + if m_kind > 2 || !(1..=2).contains(&s_kind) { + return mm(st); + } + let m_ok = if m_kind == 0 { m_bytes == 0 } else { m_bytes == 4 || m_bytes == 8 }; + let b_ok = if bias_kind == BiasKind::None { b_bytes == 0 } else { b_bytes == 4 || b_bytes == 8 }; + if !m_ok || !b_ok { + return mm(st); + } + let nm = match m_kind { + 0 => 0, + 1 => 1, + _ => c, + }; + let mult = r.ints(nm, m_bytes.max(1), st)?; + let ns = if s_kind == 1 { 1 } else { c }; + let shift: Vec = r.take(usize::try_from(ns).map_err(|_| at_load(Code::ModelMismatch, st))?, st)?.to_vec(); + if shift.iter().any(|&s| s > 127) { + return mm(st); + } + let bias = if bias_kind == BiasKind::None { vec![] } else { r.ints(c, b_bytes, st)? }; + Ok(Rq { round, bias_kind, m_kind, s_kind, m_bytes, b_bytes, mult, shift, bias }) +} + +fn read_operand(r: &mut R, n_scalars: usize, st: u8) -> Res { + let kind = r.u8(st)?; + r.zero(3, st)?; + let v = r.u32(st)?; + match kind { + 0 => Ok(Operand::Const(v)), + 1 if (v as usize) < n_scalars => Ok(Operand::Scalar(v)), + _ => mm(st), + } +} + +fn width_ok(w: u8, allowed: &[u8]) -> bool { + allowed.contains(&w) +} + +/// Read one operator's parameters from exactly its `plen` bytes. `cin` is the first +/// input tensor's channel count (§10.4: `cin` and `C`). +fn read_params(code: u8, b: &[u8], cin: u64, n_scalars: usize) -> Res { + use opcode::*; + const ST: u8 = 5; + let mut r = R { b, p: 0, end: b.len() }; + let p = match code { + CONV => { + let (cout, kh, kw, sh, sw, ph, pw, groups) = + (r.u32(ST)?, r.u32(ST)?, r.u32(ST)?, r.u32(ST)?, r.u32(ST)?, r.u32(ST)?, r.u32(ST)?, r.u32(ST)?); + let w_bytes = r.u8(ST)?; + r.zero(3, ST)?; + if cout == 0 || kh == 0 || kw == 0 || sh == 0 || sw == 0 || groups == 0 || !width_ok(w_bytes, &[1, 2, 4, 8]) { + return mm(ST); + } + if cin % groups as u64 != 0 || cout % groups != 0 { + return mm(ST); + } + let rq = read_rq(&mut r, cout as u64, ST)?; + let n = (cout as u64).checked_mul(cin / groups as u64).and_then(|v| v.checked_mul(kh as u64)).and_then(|v| v.checked_mul(kw as u64)); + let w = r.ints(n.ok_or(at_load(Code::ModelMismatch, ST))?, w_bytes, ST)?; + Params::Conv { cout, kh, kw, sh, sw, ph, pw, groups, w_bytes, rq, w } + } + CONV_TRANSPOSE => { + let (cout, kh, kw, sh, sw, ph, pw, oph, opw) = + (r.u32(ST)?, r.u32(ST)?, r.u32(ST)?, r.u32(ST)?, r.u32(ST)?, r.u32(ST)?, r.u32(ST)?, r.u32(ST)?, r.u32(ST)?); + let w_bytes = r.u8(ST)?; + r.zero(3, ST)?; + if cout == 0 || kh == 0 || kw == 0 || sh == 0 || sw == 0 || !width_ok(w_bytes, &[1, 2, 4, 8]) { + return mm(ST); + } + let rq = read_rq(&mut r, cout as u64, ST)?; + let n = cin.checked_mul(cout as u64).and_then(|v| v.checked_mul(kh as u64)).and_then(|v| v.checked_mul(kw as u64)); + let w = r.ints(n.ok_or(at_load(Code::ModelMismatch, ST))?, w_bytes, ST)?; + Params::ConvT { cout, kh, kw, sh, sw, ph, pw, oph, opw, w_bytes, rq, w } + } + RESCALE => Params::Rescale(read_rq(&mut r, cin, ST)?), + CHSCALE => { + let scalar = r.u32(ST)?; + let n_rows = r.u32(ST)?; + let round = round_of(r.u8(ST)?, ST)?; + let m_bytes = r.u8(ST)?; + let shift = r.u8(ST)?; + r.zero(1, ST)?; + if scalar as usize >= n_scalars || n_rows == 0 || !width_ok(m_bytes, &[4, 8]) || shift > 127 { + return mm(ST); + } + let n = (n_rows as u64).checked_mul(cin).ok_or(at_load(Code::ModelMismatch, ST))?; + let m = r.ints(n, m_bytes, ST)?; + Params::Chscale { scalar, n_rows, round, m_bytes, shift, m } + } + MUL => { + let rq = read_rq(&mut r, cin, ST)?; + if rq.bias_kind != BiasKind::None { + return mm(ST); + } + Params::Mul(rq) + } + LUT16 => { + let e_in = r.i8(ST)?; + let e_out = r.i8(ST)?; + r.zero(2, ST)?; + let t: Vec = r.ints(65536, 2, ST)?.into_iter().map(|v| v as i16).collect(); + if t[0] != 0 { + return mm(ST); + } + Params::Lut16 { e_in, e_out, t } + } + ADD | CONCAT | CHUNK_ADD | RELU | ABS | CROP_TO | SOFTMAX | SIGMOID => Params::None, + SPLIT => { + let (start, count) = (r.u32(ST)?, r.u32(ST)?); + if count == 0 { + return mm(ST); + } + Params::Split { start, count } + } + PIXEL_SHUFFLE | PIXEL_UNSHUFFLE => { + let rr = r.u32(ST)?; + if rr == 0 { + return mm(ST); + } + Params::Shuffle { r: rr } + } + CLAMP => { + let (lo, hi) = (r.i64(ST)?, r.i64(ST)?); + if lo > hi { + return mm(ST); + } + Params::Clamp { lo, hi } + } + LEAKY => { + let a = r.i64(ST)?; + let f = r.u32(ST)?; + if f > 63 { + return mm(ST); + } + Params::Leaky { a, f } + } + PAD_REP => { + let m = r.u32(ST)?; + if m == 0 { + return mm(ST); + } + Params::PadRep { m } + } + CROP => { + let y0 = read_operand(&mut r, n_scalars, ST)?; + let x0 = read_operand(&mut r, n_scalars, ST)?; + let h = read_operand(&mut r, n_scalars, ST)?; + let w = read_operand(&mut r, n_scalars, ST)?; + Params::Crop { y0, x0, h, w } + } + SUBPOS_SPLIT | SUBPOS_MERGE => { + let s = r.take(4, ST)?; + let order = [s[0], s[1], s[2], s[3]]; + let mut seen = [false; 4]; + for &o in &order { + if o > 3 || seen[o as usize] { + return mm(ST); + } + seen[o as usize] = true; + } + Params::Subpos { order } + } + FILL => { + let kind = r.u8(ST)?; + r.zero(7, ST)?; + let value = r.i64(ST)?; + match kind { + 0 => {} + 1 if value >= 0 && (value as u64) < n_scalars as u64 => {} + _ => return mm(ST), + } + Params::Fill { kind, value } + } + IGDN => { + let (gf, frac) = (r.u32(ST)?, r.u32(ST)?); + let g_bytes = r.u8(ST)?; + r.zero(7, ST)?; + if gf > 127 || frac > 127 || !width_ok(g_bytes, &[4, 8]) { + return mm(ST); + } + let n = cin.checked_mul(cin).ok_or(at_load(Code::ModelMismatch, ST))?; + let gamma = r.ints(n, g_bytes, ST)?; + let beta = r.ints(cin, 8, ST)?; + Params::Igdn { gf, frac, g_bytes, gamma, beta } + } + LAYERNORM_C => { + let eps = r.u64(ST)?; + let g_bytes = r.u8(ST)?; + r.zero(7, ST)?; + if eps == 0 || !width_ok(g_bytes, &[4, 8]) { + return mm(ST); + } + let gamma = r.ints(cin, g_bytes, ST)?; + let beta = r.ints(cin, 8, ST)?; + Params::LayerNorm { eps, g_bytes, gamma, beta } + } + L2NORM => { + let eps = r.u64(ST)?; + if eps == 0 { + return mm(ST); + } + Params::L2norm { eps } + } + ELU => Params::Elu { alpha: r.i64(ST)? }, + GRAM | APPLY => { + let groups = r.u32(ST)?; + let rq = read_rq(&mut r, cin, ST)?; + if groups == 0 || rq.m_kind != 0 || rq.bias_kind != BiasKind::None || rq.s_kind != 1 { + return mm(ST); + } + if code == GRAM { Params::Gram { groups, rq } } else { Params::Apply { groups, rq } } + } + _ => return mm(ST), + }; + if r.p != b.len() { + return mm(ST); + } + Ok(p) +} + +impl Graph { + /// Parse `b` and make load steps 1–6 of §10.5. Step 7 is [`crate::plan::load_plan`], + /// and [`load`] runs both. + pub fn parse(b: &[u8]) -> Res { + // 1. magic, version, operator set. + if b.len() < 32 || &b[0..4] != MAGIC || b[4] != 1 || b[5] != 1 { + return mm(1); + } + let mut r = R { b, p: 6, end: b.len() }; + // 2. the header's reserved fields. + let res0 = r.u16(2)?; + let n_tensors = r.u32(2)?; + let n_ops = r.u32(2)?; + let n_inputs = r.u16(2)?; + let n_outputs = r.u16(2)?; + let n_scalars = r.u16(2)?; + let res1 = r.u16(2)?; + let max_elems = r.u32(2)?; + let res2 = r.u32(2)?; + if res0 != 0 || res1 != 0 || res2 != 0 { + return mm(2); + } + // 3. the counts against the file's length. + if n_tensors == 0 || n_ops == 0 || n_inputs == 0 || n_outputs == 0 || max_elems == 0 || max_elems as u64 > CAP { + return mm(3); + } + let fixed = 32u64 + 16 * n_scalars as u64 + 32 * n_inputs as u64 + 4 * n_outputs as u64 + 24 * n_tensors as u64 + 12 * n_ops as u64; + if fixed > b.len() as u64 { + return mm(3); + } + // 4. each table's records. + let mut scalars = Vec::with_capacity(n_scalars as usize); + for _ in 0..n_scalars { + let (lo, hi) = (r.i64(4)?, r.i64(4)?); + if lo > hi { + return mm(4); + } + scalars.push(ScalarRec { lo, hi }); + } + let mut inputs = Vec::with_capacity(n_inputs as usize); + for _ in 0..n_inputs { + let tensor = r.u32(4)?; + let (max_h, max_w) = (r.u32(4)?, r.u32(4)?); + let kind = r.u8(4)?; + r.zero(3, 4)?; + let src = r.u32(4)?; + r.zero(4, 4)?; + let init = r.i64(4)?; + if (max_h == 0) != (max_w == 0) || kind > 1 || tensor >= n_tensors { + return mm(4); + } + if kind == 0 && (src != 0 || init != 0) { + return mm(4); + } + inputs.push(InputRec { tensor, max_h, max_w, kind, src, init }); + } + let mut outputs = Vec::with_capacity(n_outputs as usize); + for _ in 0..n_outputs { + let t = r.u32(4)?; + if t >= n_tensors { + return mm(4); + } + outputs.push(t); + } + let mut tensors = Vec::with_capacity(n_tensors as usize); + for _ in 0..n_tensors { + let channels = r.u32(4)?; + let exponent = r.i8(4)?; + let policy = match r.u8(4)? { + 0 => Policy::Derived, + 1 => Policy::Clamp, + 2 => Policy::Check, + _ => return mm(4), + }; + r.zero(2, 4)?; + let (lo, hi) = (r.i64(4)?, r.i64(4)?); + if channels == 0 { + return mm(4); + } + match policy { + Policy::Derived if lo != 0 || hi != 0 => return mm(4), + Policy::Clamp | Policy::Check if lo > hi => return mm(4), + _ => {} + } + tensors.push(TensorRec { channels, exponent, policy, lo, hi }); + } + // 5. each operator: opcode, arity, parameter length, parameter ranges. + let mut ops = Vec::with_capacity(n_ops as usize); + for _ in 0..n_ops { + let code = r.u8(5)?; + let n_in = r.u8(5)?; + let n_out = r.u8(5)?; + r.zero(1, 5)?; + if op_name(code).is_none() { + return mm(5); + } + let (ai, ao) = arity(code); + if n_out != ao || (ai == 0 && n_in < 2) || (ai != 0 && n_in != ai) { + return mm(5); + } + let mut ins = Vec::with_capacity(n_in as usize); + for _ in 0..n_in { + let t = r.u32(5)?; + if t >= n_tensors { + return mm(5); + } + ins.push(t); + } + let mut outs = Vec::with_capacity(n_out as usize); + for _ in 0..n_out { + let t = r.u32(5)?; + if t >= n_tensors { + return mm(5); + } + outs.push(t); + } + let plen = r.u32(5)?; + let pb = r.take(plen as usize, 5)?; + let cin = tensors[ins[0] as usize].channels as u64; + let p = read_params(code, pb, cin, scalars.len())?; + ops.push(Op { code, ins, outs, p }); + } + // Nothing follows the last operator. + if r.p != b.len() { + return mm(5); + } + let g = Graph { max_elems, scalars, inputs, outputs, tensors, ops }; + g.rules()?; + Ok(g) + } + + /// Load step 6: the graph rules (§10.3), the state rules and the exponent rules. + fn rules(&self) -> Res<()> { + use opcode::*; + const ST: u8 = 6; + let nt = self.tensors.len(); + // Every tensor is a graph input or the output of exactly one operator; an + // operator reads only graph inputs and earlier operators' outputs. + let mut defined = vec![false; nt]; + for i in &self.inputs { + if defined[i.tensor as usize] { + return mm(ST); + } + defined[i.tensor as usize] = true; + if self.tensors[i.tensor as usize].policy == Policy::Derived { + return mm(ST); + } + } + if self.inputs[0].kind != 0 { + return mm(ST); + } + let sized = self.inputs[0].max_h != 0; + if self.inputs.iter().any(|i| (i.max_h != 0) != sized) { + return mm(ST); + } + for op in &self.ops { + if op.ins.iter().any(|&t| !defined[t as usize]) { + return mm(ST); + } + for &t in &op.outs { + if defined[t as usize] { + return mm(ST); + } + defined[t as usize] = true; + } + } + if defined.iter().any(|&d| !d) { + return mm(ST); + } + // State inputs. + for i in &self.inputs { + if i.kind == 1 { + if i.src as usize >= self.outputs.len() { + return mm(ST); + } + let rec = &self.tensors[i.tensor as usize]; + let out = &self.tensors[self.outputs[i.src as usize] as usize]; + if out.channels != rec.channels || i.init < rec.lo || i.init > rec.hi { + return mm(ST); + } + } + } + // Each operator's output channel count, and the exponent rules. + let ch = |t: u32| self.tensors[t as usize].channels as u64; + let ex = |t: u32| self.tensors[t as usize].exponent; + for op in &self.ops { + let c = ch(op.ins[0]); + let want: Option = match (&op.p, op.code) { + (Params::Conv { cout, .. }, _) | (Params::ConvT { cout, .. }, _) => Some(*cout as u64), + (_, ADD) => (ch(op.ins[1]) == c).then_some(c), + (_, MUL) => (ch(op.ins[1]) == c || ch(op.ins[1]) == 1).then_some(c), + (_, CONCAT) => Some(op.ins.iter().map(|&t| ch(t)).sum()), + (_, CHUNK_ADD) => (c % 2 == 0).then_some(c / 2), + (Params::Split { start, count }, _) => ((*start as u64) + (*count as u64) <= c).then_some(*count as u64), + (Params::Shuffle { r }, PIXEL_SHUFFLE) => { + let r2 = (*r as u64) * (*r as u64); + (c % r2 == 0).then_some(c / r2) + } + (Params::Shuffle { r }, _) => c.checked_mul((*r as u64) * (*r as u64)), + (_, SUBPOS_MERGE) => op.ins.iter().all(|&t| ch(t) == c).then_some(c), + (_, FILL) => Some(ch(op.outs[0])), + (Params::Gram { groups, .. }, _) => (ch(op.ins[1]) == c && c % *groups as u64 == 0).then_some(c), + (Params::Apply { groups, .. }, _) => (ch(op.ins[1]) == c && c % *groups as u64 == 0).then_some(c), + (Params::Chscale { scalar, n_rows, .. }, _) => { + let s = self.scalars[*scalar as usize]; + (s.lo >= 0 && s.hi <= *n_rows as i64 - 1).then_some(c) + } + _ => Some(c), + }; + match want { + Some(w) if op.outs.iter().all(|&t| ch(t) == w) => {} + _ => return mm(ST), + } + let all_or_none = |ts: &mut dyn Iterator| -> bool { + let v: Vec = ts.map(ex).collect(); + v.iter().all(|&e| e == -128) || (v.iter().all(|&e| e != -128) && v.windows(2).all(|w| w[0] == w[1])) + }; + match op.code { + ADD | CONCAT | CHUNK_ADD => { + if !all_or_none(&mut op.ins.iter().copied().chain(op.outs.iter().copied())) { + return mm(ST); + } + } + LUT16 => { + if let Params::Lut16 { e_in, e_out, .. } = op.p { + if e_in != ex(op.ins[0]) || e_out != ex(op.outs[0]) { + return mm(ST); + } + } + } + _ => {} + } + } + Ok(()) + } + + /// The graph's bytes. + pub fn to_bytes(&self) -> Vec { + let mut o = Vec::new(); + o.extend_from_slice(MAGIC); + o.extend_from_slice(&[1, 1, 0, 0]); + o.extend_from_slice(&(self.tensors.len() as u32).to_le_bytes()); + o.extend_from_slice(&(self.ops.len() as u32).to_le_bytes()); + o.extend_from_slice(&(self.inputs.len() as u16).to_le_bytes()); + o.extend_from_slice(&(self.outputs.len() as u16).to_le_bytes()); + o.extend_from_slice(&(self.scalars.len() as u16).to_le_bytes()); + o.extend_from_slice(&[0, 0]); + o.extend_from_slice(&self.max_elems.to_le_bytes()); + o.extend_from_slice(&[0, 0, 0, 0]); + for s in &self.scalars { + o.extend_from_slice(&s.lo.to_le_bytes()); + o.extend_from_slice(&s.hi.to_le_bytes()); + } + for i in &self.inputs { + o.extend_from_slice(&i.tensor.to_le_bytes()); + o.extend_from_slice(&i.max_h.to_le_bytes()); + o.extend_from_slice(&i.max_w.to_le_bytes()); + o.extend_from_slice(&[i.kind, 0, 0, 0]); + o.extend_from_slice(&i.src.to_le_bytes()); + o.extend_from_slice(&[0, 0, 0, 0]); + o.extend_from_slice(&i.init.to_le_bytes()); + } + for t in &self.outputs { + o.extend_from_slice(&t.to_le_bytes()); + } + for t in &self.tensors { + o.extend_from_slice(&t.channels.to_le_bytes()); + o.push(t.exponent as u8); + o.push(match t.policy { + Policy::Derived => 0, + Policy::Clamp => 1, + Policy::Check => 2, + }); + o.extend_from_slice(&[0, 0]); + o.extend_from_slice(&t.lo.to_le_bytes()); + o.extend_from_slice(&t.hi.to_le_bytes()); + } + for op in &self.ops { + o.extend_from_slice(&[op.code, op.ins.len() as u8, op.outs.len() as u8, 0]); + for t in op.ins.iter().chain(&op.outs) { + o.extend_from_slice(&t.to_le_bytes()); + } + let p = write_params(&op.p); + o.extend_from_slice(&(p.len() as u32).to_le_bytes()); + o.extend_from_slice(&p); + } + o + } +} + +fn put_ints(o: &mut Vec, v: &[i64], w: u8) { + for &x in v { + o.extend_from_slice(&x.to_le_bytes()[..w as usize]); + } +} + +fn write_rq(o: &mut Vec, rq: &Rq) { + o.push(round_code(rq.round)); + o.push(match rq.bias_kind { + BiasKind::None => 0, + BiasKind::Pre => 1, + BiasKind::Post => 2, + }); + o.extend_from_slice(&[rq.m_kind, rq.s_kind, rq.m_bytes, rq.b_bytes, 0, 0]); + put_ints(o, &rq.mult, rq.m_bytes); + o.extend_from_slice(&rq.shift); + put_ints(o, &rq.bias, rq.b_bytes); +} + +fn write_operand(o: &mut Vec, x: Operand) { + let (k, v) = match x { + Operand::Const(v) => (0u8, v), + Operand::Scalar(v) => (1u8, v), + }; + o.extend_from_slice(&[k, 0, 0, 0]); + o.extend_from_slice(&v.to_le_bytes()); +} + +/// One operator's parameter bytes (§10.4). +pub fn write_params(p: &Params) -> Vec { + let mut o = Vec::new(); + let u = |o: &mut Vec, v: u32| o.extend_from_slice(&v.to_le_bytes()); + match p { + Params::Conv { cout, kh, kw, sh, sw, ph, pw, groups, w_bytes, rq, w } => { + for v in [*cout, *kh, *kw, *sh, *sw, *ph, *pw, *groups] { + u(&mut o, v); + } + o.extend_from_slice(&[*w_bytes, 0, 0, 0]); + write_rq(&mut o, rq); + put_ints(&mut o, w, *w_bytes); + } + Params::ConvT { cout, kh, kw, sh, sw, ph, pw, oph, opw, w_bytes, rq, w } => { + for v in [*cout, *kh, *kw, *sh, *sw, *ph, *pw, *oph, *opw] { + u(&mut o, v); + } + o.extend_from_slice(&[*w_bytes, 0, 0, 0]); + write_rq(&mut o, rq); + put_ints(&mut o, w, *w_bytes); + } + Params::Rescale(rq) | Params::Mul(rq) => write_rq(&mut o, rq), + Params::Chscale { scalar, n_rows, round, m_bytes, shift, m } => { + u(&mut o, *scalar); + u(&mut o, *n_rows); + o.extend_from_slice(&[round_code(*round), *m_bytes, *shift, 0]); + put_ints(&mut o, m, *m_bytes); + } + Params::Lut16 { e_in, e_out, t } => { + o.extend_from_slice(&[*e_in as u8, *e_out as u8, 0, 0]); + for &v in t { + o.extend_from_slice(&v.to_le_bytes()); + } + } + Params::None => {} + Params::Split { start, count } => { + u(&mut o, *start); + u(&mut o, *count); + } + Params::Shuffle { r } => u(&mut o, *r), + Params::Clamp { lo, hi } => { + o.extend_from_slice(&lo.to_le_bytes()); + o.extend_from_slice(&hi.to_le_bytes()); + } + Params::Leaky { a, f } => { + o.extend_from_slice(&a.to_le_bytes()); + u(&mut o, *f); + } + Params::PadRep { m } => u(&mut o, *m), + Params::Crop { y0, x0, h, w } => { + for x in [*y0, *x0, *h, *w] { + write_operand(&mut o, x); + } + } + Params::Subpos { order } => o.extend_from_slice(order), + Params::Fill { kind, value } => { + o.extend_from_slice(&[*kind, 0, 0, 0, 0, 0, 0, 0]); + o.extend_from_slice(&value.to_le_bytes()); + } + Params::Igdn { gf, frac, g_bytes, gamma, beta } => { + u(&mut o, *gf); + u(&mut o, *frac); + o.extend_from_slice(&[*g_bytes, 0, 0, 0, 0, 0, 0, 0]); + put_ints(&mut o, gamma, *g_bytes); + put_ints(&mut o, beta, 8); + } + Params::LayerNorm { eps, g_bytes, gamma, beta } => { + o.extend_from_slice(&eps.to_le_bytes()); + o.extend_from_slice(&[*g_bytes, 0, 0, 0, 0, 0, 0, 0]); + put_ints(&mut o, gamma, *g_bytes); + put_ints(&mut o, beta, 8); + } + Params::L2norm { eps } => o.extend_from_slice(&eps.to_le_bytes()), + Params::Elu { alpha } => o.extend_from_slice(&alpha.to_le_bytes()), + Params::Gram { groups, rq } | Params::Apply { groups, rq } => { + u(&mut o, *groups); + write_rq(&mut o, rq); + } + } + o +} + +/// The smallest width of `allowed` (ascending) that holds every value of `v`. +pub fn smallest_width(v: &[i64], allowed: &[u8]) -> u8 { + for &w in allowed { + let (lo, hi) = if w == 8 { (i64::MIN, i64::MAX) } else { (-(1i64 << (8 * w - 1)), (1i64 << (8 * w - 1)) - 1) }; + if v.iter().all(|&x| lo <= x && x <= hi) { + return w; + } + } + 8 +} + +/// Load a graph: steps 1–7 of §10.5, then step 8. +/// +/// Step 8 (the bounds pass, `lut16`'s range check, and the capability's profile +/// against the verdict) is not built yet. Without the `uncertified` feature it +/// refuses every graph (`model_mismatch` at step 8), so nothing outside tests decodes +/// through an uncertified graph; with the feature it is skipped. +pub fn load(b: &[u8]) -> Res { + let g = Graph::parse(b)?; + crate::plan::load_plan(&g)?; + step8(&g)?; + Ok(g) +} + +#[cfg(feature = "uncertified")] +fn step8(_g: &Graph) -> Res<()> { + Ok(()) +} + +#[cfg(not(feature = "uncertified"))] +fn step8(_g: &Graph) -> Res<()> { + Err(Refusal::new(Code::ModelMismatch, crate::code::Site::Load(8))) +} diff --git a/wai/wai-ops/src/interp.rs b/wai/wai-ops/src/interp.rs new file mode 100644 index 000000000..2aec02649 --- /dev/null +++ b/wai/wai-ops/src/interp.rs @@ -0,0 +1,611 @@ +//! The reference interpreter of the graph operators (§5). +//! +//! Tensors hold `i64`. Every intermediate is formed in `i128`, which holds every +//! value a graph certified for `acc64` forms (§7.1), and every step is checked: a +//! graph whose arithmetic would leave `i128`, or whose producer result would leave +//! `i64`, is one that load step 8 refuses once the certifier exists, and here, where +//! step 8 is not built yet, the decode is refused (`model_mismatch`) at that operator +//! instead of wrapping. No certified graph reaches that refusal. + +use alloc::vec; +use alloc::vec::Vec; + +use crate::code::{Code, Refusal, Site}; +use crate::graph::{Graph, Operand, Params, Policy, Rq, Round, opcode::*}; +use crate::plan::run_plan; + +/// A tensor `[c, h, w]`, its elements in CHW order. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Tensor { + pub c: u32, + pub h: u32, + pub w: u32, + pub data: Vec, +} + +impl Tensor { + pub fn new(c: u32, h: u32, w: u32, data: Vec) -> Tensor { + Tensor { c, h, w, data } + } + pub fn filled(c: u32, h: u32, w: u32, v: i64) -> Tensor { + Tensor { c, h, w, data: vec![v; c as usize * h as usize * w as usize] } + } + fn at(&self, c: usize, y: usize, x: usize) -> i64 { + self.data[(c * self.h as usize + y) * self.w as usize + x] + } +} + +/// The state of a sequence of decodes (§10.3): the tensors carried into the state +/// inputs, or nothing before the first decode. +#[derive(Clone, Debug, Default)] +pub struct Sequence { + state: Option>, +} + +impl Sequence { + pub fn new() -> Sequence { + Sequence { state: None } + } +} + +type Res = Result; + +/// The refusal an uncertified graph meets where its arithmetic leaves the widths a +/// certified one keeps to. See the module documentation. +fn wide(at: u32) -> Refusal { + Refusal::new(Code::ModelMismatch, Site::Op(at)) +} + +/// `R_round(p, s)` (§2). +pub fn round(p: i128, s: u32, r: Round) -> Option { + if s == 0 { + return Some(p); + } + match r { + Round::Floor => Some(p >> s), + Round::HalfUp => Some(p.checked_add(1i128 << (s - 1))? >> s), + Round::HalfEven => { + let q = p >> s; + let rem = (p as u128) & (u128::MAX >> (128 - s)); + let h = 1u128 << (s - 1); + Some(if rem > h || (rem == h && q & 1 == 1) { q + 1 } else { q }) + } + } +} + +/// `rq_o(v)` (§5.1). +fn rq_apply(rq: &Rq, o: usize, v: i128) -> Option { + let t = v.checked_add(rq.pre(o) as i128)?; + let p = match rq.mult(o) { + Some(m) => t.checked_mul(m as i128)?, + None => t, + }; + let q = round(p, rq.shift(o), rq.round)?; + q.checked_add(rq.post(o) as i128) +} + +/// `exp_neg_q16(x)` (§2), for `x ≤ 0`. +pub fn exp_neg_q16(x: i128) -> i128 { + let u = -x; + let n = u / 45426; + let g = 45426 * n; + let r = x + g; + let t = r + 88670; + let t2 = t * t; + let q = t2 >> 16; + let c = 23495 * q; + let y = (c >> 16) + 22544; + if n >= 63 { 0 } else { y >> n } +} + +/// `rsqrt_q16(v)` (§2), for `v ≥ 0`. +pub fn rsqrt_q16(v: u128) -> i128 { + let r = v.isqrt(); + if r == 0 { 0 } else { ((1u128 << 32) / r) as i128 } +} + +fn to64(v: i128, at: u32) -> Res { + i64::try_from(v).map_err(|_| wide(at)) +} + +/// Run one decode of `g`. `inputs` holds the data inputs, in input-table order; each +/// state input is taken from `seq` (§10.3). `scalars` holds every scalar's value. +/// Returns the graph's outputs, in output-table order. +pub fn run(g: &Graph, inputs: &[Tensor], scalars: &[i64], seq: &mut Sequence) -> Res> { + // The inputs, data and state, in input-table order. + let n_data = g.inputs.iter().filter(|i| i.kind == 0).count(); + if inputs.len() != n_data { + return Err(Refusal::new(Code::ModelMismatch, Site::Input(inputs.len().min(n_data) as u32))); + } + let mut all: Vec = Vec::with_capacity(g.inputs.len()); + let (mut d, mut s) = (0usize, 0usize); + for rec in &g.inputs { + if rec.kind == 0 { + all.push(inputs[d].clone()); + d += 1; + } else { + let t = match &seq.state { + Some(st) => st[s].clone(), + None => { + let i0 = &inputs[0]; + Tensor::filled(g.tensors[rec.tensor as usize].channels, i0.h, i0.w, rec.init) + } + }; + all.push(t); + s += 1; + } + } + for (k, t) in all.iter().enumerate() { + if t.data.len() as u64 != t.c as u64 * t.h as u64 * t.w as u64 { + return Err(Refusal::new(Code::ModelMismatch, Site::Input(k as u32))); + } + } + let shapes: Vec<(u64, u64, u64)> = all.iter().map(|t| (t.c as u64, t.h as u64, t.w as u64)).collect(); + let hw = run_plan(g, &shapes, scalars)?; + + let mut vals: Vec> = vec![None; g.tensors.len()]; + // Step 4 begins with the inputs: each input's policy applies to it. + for (k, (rec, mut t)) in g.inputs.iter().zip(all).enumerate() { + let tr = &g.tensors[rec.tensor as usize]; + if !apply_policy(tr.policy, tr.lo, tr.hi, &mut t.data) { + return Err(Refusal::new(Code::FieldRange, Site::Input(k as u32))); + } + vals[rec.tensor as usize] = Some(t); + } + for (i, op) in g.ops.iter().enumerate() { + let outs = eval(g, op, i as u32, &vals, &hw, scalars)?; + for (&t, mut ten) in op.outs.iter().zip(outs) { + let tr = &g.tensors[t as usize]; + if !apply_policy(tr.policy, tr.lo, tr.hi, &mut ten.data) { + return Err(Refusal::new(Code::FieldRange, Site::Op(i as u32))); + } + vals[t as usize] = Some(ten); + } + } + let outputs: Vec = g.outputs.iter().map(|&t| vals[t as usize].clone().expect("every tensor is defined")).collect(); + let next: Vec = g.inputs.iter().filter(|i| i.kind == 1).map(|i| outputs[i.src as usize].clone()).collect(); + seq.state = Some(next); + Ok(outputs) +} + +/// Apply a policy: clamp in place, or report whether every element lies in range. +fn apply_policy(p: Policy, lo: i64, hi: i64, d: &mut [i64]) -> bool { + match p { + Policy::Derived => true, + Policy::Clamp => { + for v in d.iter_mut() { + *v = (*v).clamp(lo, hi); + } + true + } + Policy::Check => d.iter().all(|&v| lo <= v && v <= hi), + } +} + +fn get<'a>(vals: &'a [Option], t: u32) -> &'a Tensor { + vals[t as usize].as_ref().expect("an operator reads only defined tensors") +} + +/// Map every element of `x` through `f`. +fn map(x: &Tensor, at: u32, f: impl Fn(i128) -> Option) -> Res { + let mut d = Vec::with_capacity(x.data.len()); + for &v in &x.data { + d.push(to64(f(v as i128).ok_or(wide(at))?, at)?); + } + Ok(Tensor::new(x.c, x.h, x.w, d)) +} + +/// Map every element of channel `c` of `x` through `f(c, v)`. +fn map_c(x: &Tensor, at: u32, f: impl Fn(usize, i128) -> Option) -> Res { + let plane = x.h as usize * x.w as usize; + let mut d = Vec::with_capacity(x.data.len()); + for (k, &v) in x.data.iter().enumerate() { + d.push(to64(f(k / plane.max(1), v as i128).ok_or(wide(at))?, at)?); + } + Ok(Tensor::new(x.c, x.h, x.w, d)) +} + +fn eval(g: &Graph, op: &crate::graph::Op, at: u32, vals: &[Option], hw: &[(u64, u64)], sc: &[i64]) -> Res> { + let x = get(vals, op.ins[0]); + let (c, h, w) = (x.c as usize, x.h as usize, x.w as usize); + let out_c = |k: usize| g.tensors[op.outs[k] as usize].channels; + let (oh, ow) = hw[op.outs[0] as usize]; + let (oh, ow) = (oh as usize, ow as usize); + let one = |t: Tensor| Ok(vec![t]); + match (&op.p, op.code) { + (Params::Conv { cout, kh, kw, sh, sw, ph, pw, groups, rq, w: wt, .. }, _) => { + let (cout, kh, kw, sh, sw, ph, pw, groups) = + (*cout as usize, *kh as usize, *kw as usize, *sh as usize, *sw as usize, *ph as usize, *pw as usize, *groups as usize); + let (cg, og) = (c / groups, cout / groups); + let mut d = vec![0i64; cout * oh * ow]; + for o in 0..cout { + let base = (o / og) * cg; + for y in 0..oh { + for xx in 0..ow { + let mut acc: i128 = 0; + for ci in 0..cg { + for i in 0..kh { + let iy = y * sh + i; + if iy < ph || iy - ph >= h { + continue; + } + for j in 0..kw { + let ix = xx * sw + j; + if ix < pw || ix - pw >= w { + continue; + } + let wv = wt[((o * cg + ci) * kh + i) * kw + j] as i128; + let term = wv * x.at(base + ci, iy - ph, ix - pw) as i128; + acc = acc.checked_add(term).ok_or(wide(at))?; + } + } + } + d[(o * oh + y) * ow + xx] = to64(rq_apply(rq, o, acc).ok_or(wide(at))?, at)?; + } + } + } + one(Tensor::new(cout as u32, oh as u32, ow as u32, d)) + } + (Params::ConvT { cout, kh, kw, sh, sw, ph, pw, oph, opw, rq, w: wt, .. }, _) => { + let (cout, kh, kw, sh, sw, ph, pw) = + (*cout as usize, *kh as usize, *kw as usize, *sh as usize, *sw as usize, *ph as usize, *pw as usize); + let uh = (h - 1) * sh + kh + *oph as usize; + let uw = (w - 1) * sw + kw + *opw as usize; + // The scatter form: the same products as §5.3's gather, summed exactly. + let mut plane = vec![0i128; cout * uh * uw]; + for ci in 0..c { + for u in 0..h { + for v in 0..w { + let xv = x.at(ci, u, v) as i128; + if xv == 0 { + continue; + } + for o in 0..cout { + for i in 0..kh { + let row = (o * uh + u * sh + i) * uw + v * sw; + for j in 0..kw { + let wv = wt[((ci * cout + o) * kh + i) * kw + j] as i128; + let cell = &mut plane[row + j]; + *cell = cell.checked_add(wv * xv).ok_or(wide(at))?; + } + } + } + } + } + } + let mut d = vec![0i64; cout * oh * ow]; + for o in 0..cout { + for y in 0..oh { + for xx in 0..ow { + let acc = plane[(o * uh + y + ph) * uw + xx + pw]; + d[(o * oh + y) * ow + xx] = to64(rq_apply(rq, o, acc).ok_or(wide(at))?, at)?; + } + } + } + one(Tensor::new(cout as u32, oh as u32, ow as u32, d)) + } + (Params::Rescale(rq), _) => one(map_c(x, at, |o, v| rq_apply(rq, o, v))?), + (Params::Chscale { scalar, round: r, shift, m, .. }, _) => { + let row = sc[*scalar as usize] as usize; + one(map_c(x, at, |o, v| round(v.checked_mul(m[row * c + o] as i128)?, *shift as u32, *r))?) + } + (Params::Mul(rq), _) => { + let b = get(vals, op.ins[1]); + let plane = h * w; + let mut d = Vec::with_capacity(x.data.len()); + for o in 0..c { + let bo = if b.c as usize == c { o } else { 0 }; + for k in 0..plane { + let p = (x.data[o * plane + k] as i128) * (b.data[bo * plane + k] as i128); + d.push(to64(rq_apply(rq, o, p).ok_or(wide(at))?, at)?); + } + } + one(Tensor::new(x.c, x.h, x.w, d)) + } + (Params::Lut16 { t, .. }, _) => one(map(x, at, |v| { + let i = v + 32768; + if (0..65536).contains(&i) { Some(t[i as usize] as i128) } else { None } + })?), + (_, ADD) => { + let b = get(vals, op.ins[1]); + let mut d = Vec::with_capacity(x.data.len()); + for (&p, &q) in x.data.iter().zip(&b.data) { + d.push(to64(p as i128 + q as i128, at)?); + } + one(Tensor::new(x.c, x.h, x.w, d)) + } + (_, CONCAT) => { + let mut d = Vec::new(); + for &t in &op.ins { + d.extend_from_slice(&get(vals, t).data); + } + one(Tensor::new(out_c(0), x.h, x.w, d)) + } + (_, CHUNK_ADD) => { + let half = (c / 2) * h * w; + let mut d = Vec::with_capacity(half); + for k in 0..half { + d.push(to64(x.data[k] as i128 + x.data[k + half] as i128, at)?); + } + one(Tensor::new((c / 2) as u32, x.h, x.w, d)) + } + (Params::Split { start, count }, _) => { + let plane = h * w; + let s = *start as usize * plane; + one(Tensor::new(*count, x.h, x.w, x.data[s..s + *count as usize * plane].to_vec())) + } + (Params::Shuffle { r }, PIXEL_SHUFFLE) => { + let r = *r as usize; + let co = c / (r * r); + let mut d = vec![0i64; c * h * w]; + for cc in 0..co { + for y in 0..h { + for xx in 0..w { + for i in 0..r { + for j in 0..r { + d[(cc * oh + y * r + i) * ow + xx * r + j] = x.at(cc * r * r + i * r + j, y, xx); + } + } + } + } + } + one(Tensor::new(co as u32, oh as u32, ow as u32, d)) + } + (Params::Shuffle { r }, _) => { + let r = *r as usize; + let mut d = vec![0i64; c * h * w]; + for cc in 0..c { + for y in 0..oh { + for xx in 0..ow { + for i in 0..r { + for j in 0..r { + d[((cc * r * r + i * r + j) * oh + y) * ow + xx] = x.at(cc, y * r + i, xx * r + j); + } + } + } + } + } + one(Tensor::new((c * r * r) as u32, oh as u32, ow as u32, d)) + } + (Params::Clamp { lo, hi }, _) => one(map(x, at, |v| Some(v.clamp(*lo as i128, *hi as i128)))?), + (_, RELU) => one(map(x, at, |v| Some(v.max(0)))?), + (Params::Leaky { a, f }, _) => one(map(x, at, |v| Some(if v >= 0 { v } else { (v * *a as i128) >> *f } ))?), + (_, ABS) => one(map(x, at, |v| Some(v.abs()))?), + (Params::PadRep { .. }, _) => { + let mut d = Vec::with_capacity(c * oh * ow); + for cc in 0..c { + for y in 0..oh { + for xx in 0..ow { + d.push(x.at(cc, y.min(h - 1), xx.min(w - 1))); + } + } + } + one(Tensor::new(x.c, oh as u32, ow as u32, d)) + } + (_, CROP_TO) => one(crop(x, 0, 0, oh, ow)), + (Params::Crop { y0, x0, .. }, _) => { + let v = |o: &Operand| match *o { + Operand::Const(k) => k as usize, + Operand::Scalar(s) => sc[s as usize] as usize, + }; + one(crop(x, v(y0), v(x0), oh, ow)) + } + (Params::Subpos { order }, SUBPOS_SPLIT) => { + let mut outs = Vec::with_capacity(4); + for &o in order { + let (a, b) = ((o >> 1) as usize, (o & 1) as usize); + let mut d = Vec::with_capacity(c * oh * ow); + for cc in 0..c { + for y in 0..oh { + for xx in 0..ow { + d.push(x.at(cc, 2 * y + a, 2 * xx + b)); + } + } + } + outs.push(Tensor::new(x.c, oh as u32, ow as u32, d)); + } + Ok(outs) + } + (Params::Subpos { order }, _) => { + let mut d = vec![0i64; c * oh * ow]; + for (k, &o) in order.iter().enumerate() { + let (a, b) = ((o >> 1) as usize, (o & 1) as usize); + let t = get(vals, op.ins[k]); + for cc in 0..c { + for y in 0..h { + for xx in 0..w { + d[(cc * oh + 2 * y + a) * ow + 2 * xx + b] = t.at(cc, y, xx); + } + } + } + } + one(Tensor::new(x.c, oh as u32, ow as u32, d)) + } + (Params::Fill { kind, value }, _) => { + let v = if *kind == 0 { *value } else { sc[*value as usize] }; + one(Tensor::filled(out_c(0), x.h, x.w, v)) + } + (Params::Igdn { gf, frac, gamma, beta, .. }, _) => { + let mut d = vec![0i64; c * h * w]; + let plane = h * w; + let mut x2 = vec![0i128; c]; + for p in 0..plane { + for j in 0..c { + let v = x.data[j * plane + p] as i128; + x2[j] = v * v; + } + for i in 0..c { + let mut n = beta[i] as i128; + for j in 0..c { + let gx2 = (gamma[i * c + j] as i128).checked_mul(x2[j]).ok_or(wide(at))?; + n = n.checked_add(gx2 >> *gf).ok_or(wide(at))?; + } + let r = (n.max(0) as u128).isqrt() as i128; + let xr = (x.data[i * plane + p] as i128).checked_mul(r).ok_or(wide(at))?; + d[i * plane + p] = to64(xr >> *frac, at)?; + } + } + one(Tensor::new(x.c, x.h, x.w, d)) + } + (Params::LayerNorm { eps, gamma, beta, .. }, _) => { + let plane = h * w; + let mut d = vec![0i64; c * plane]; + let ci = c as i128; + for p in 0..plane { + let mut s: i128 = 0; + for k in 0..c { + s = s.checked_add(x.data[k * plane + p] as i128).ok_or(wide(at))?; + } + let m_num = s.checked_add((ci / 2) * s.signum()).ok_or(wide(at))?; + let m = m_num / ci; + let mut t: i128 = 0; + let mut dev = vec![0i128; c]; + for k in 0..c { + let dk = (x.data[k * plane + p] as i128) - m; + dev[k] = dk; + t = t.checked_add(dk.checked_mul(dk).ok_or(wide(at))?).ok_or(wide(at))?; + } + let v = t / ci; + let u = v.checked_add(*eps as i128).ok_or(wide(at))?; + let k = rsqrt_q16(u as u128); + for kk in 0..c { + let n = dev[kk].checked_mul(k).ok_or(wide(at))? >> 16; + let ng = n.checked_mul(gamma[kk] as i128).ok_or(wide(at))?; + d[kk * plane + p] = to64((ng >> 16).checked_add(beta[kk] as i128).ok_or(wide(at))?, at)?; + } + } + one(Tensor::new(x.c, x.h, x.w, d)) + } + (Params::L2norm { eps }, _) => { + let plane = h * w; + let mut d = vec![0i64; c * plane]; + for cc in 0..c { + let mut t: i128 = 0; + for p in 0..plane { + let v = x.data[cc * plane + p] as i128; + t = t.checked_add(v * v).ok_or(wide(at))?; + } + let u = t.checked_add(*eps as i128).ok_or(wide(at))?; + let k = rsqrt_q16(u as u128); + for p in 0..plane { + let vk = (x.data[cc * plane + p] as i128).checked_mul(k).ok_or(wide(at))?; + d[cc * plane + p] = to64(vk >> 16, at)?; + } + } + one(Tensor::new(x.c, x.h, x.w, d)) + } + (_, SOFTMAX) => { + let mut d = vec![0i64; c * h * w]; + let mut e = vec![0i128; w]; + for row in 0..c * h { + let r = &x.data[row * w..(row + 1) * w]; + let m = *r.iter().max().expect("a row has at least one element") as i128; + let mut sum: i128 = 0; + for (k, &v) in r.iter().enumerate() { + e[k] = exp_neg_q16(v as i128 - m); + sum += e[k]; + } + for k in 0..w { + d[row * w + k] = to64(((e[k] << 16) + (sum >> 1)) / sum, at)?; + } + } + one(Tensor::new(x.c, x.h, x.w, d)) + } + (_, SIGMOID) => one(map(x, at, |v| { + Some(if v >= 0 { + let e = exp_neg_q16(-v); + (1i128 << 32) / ((1 << 16) + e) + } else { + let e = exp_neg_q16(v); + (e << 16) / ((1 << 16) + e) + }) + })?), + (Params::Elu { alpha }, _) => one(map(x, at, |v| { + Some(if v > 0 { v } else { ((*alpha as i128).checked_mul(exp_neg_q16(v) - (1 << 16))?) >> 16 }) + })?), + (Params::Gram { groups, rq }, _) => { + let b = get(vals, op.ins[1]); + let d_ = c / *groups as usize; + let plane = h * w; + let mut d = vec![0i64; c * d_]; + for gi in 0..*groups as usize { + for i in 0..d_ { + for j in 0..d_ { + let (ca, cb) = (gi * d_ + i, gi * d_ + j); + let mut acc: i128 = 0; + for p in 0..plane { + let t = (x.data[ca * plane + p] as i128) * (b.data[cb * plane + p] as i128); + acc = acc.checked_add(t).ok_or(wide(at))?; + } + d[ca * d_ + j] = to64(round(acc, rq.shift(0), rq.round).ok_or(wide(at))?, at)?; + } + } + } + one(Tensor::new(x.c, 1, d_ as u32, d)) + } + (Params::Apply { groups, rq }, _) => { + let v = get(vals, op.ins[1]); + let d_ = c / *groups as usize; + let plane = v.h as usize * v.w as usize; + let mut d = vec![0i64; c * plane]; + for gi in 0..*groups as usize { + for i in 0..d_ { + for p in 0..plane { + let mut acc: i128 = 0; + for j in 0..d_ { + let t = (x.data[(gi * d_ + i) * d_ + j] as i128) * (v.data[(gi * d_ + j) * plane + p] as i128); + acc = acc.checked_add(t).ok_or(wide(at))?; + } + d[(gi * d_ + i) * plane + p] = to64(round(acc, rq.shift(0), rq.round).ok_or(wide(at))?, at)?; + } + } + } + one(Tensor::new(v.c, v.h, v.w, d)) + } + _ => Err(wide(at)), + } +} + +fn crop(x: &Tensor, y0: usize, x0: usize, oh: usize, ow: usize) -> Tensor { + let mut d = Vec::with_capacity(x.c as usize * oh * ow); + for cc in 0..x.c as usize { + for y in 0..oh { + for xx in 0..ow { + d.push(x.at(cc, y0 + y, x0 + xx)); + } + } + } + Tensor::new(x.c, oh as u32, ow as u32, d) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn rounding_modes() { + // floor, half up, half even, at shift 1: −3/2 = −1.5. + assert_eq!(round(-3, 1, Round::Floor), Some(-2)); + assert_eq!(round(-3, 1, Round::HalfUp), Some(-1)); + assert_eq!(round(-3, 1, Round::HalfEven), Some(-2)); + assert_eq!(round(-1, 1, Round::HalfEven), Some(0)); + assert_eq!(round(5, 1, Round::HalfEven), Some(2)); + assert_eq!(round(7, 1, Round::HalfEven), Some(4)); + assert_eq!(round(i128::MIN, 127, Round::HalfEven), Some(-1)); + assert_eq!(round(i128::MAX, 127, Round::Floor), Some(0)); + assert_eq!(round(-(1 << 126), 127, Round::HalfEven), Some(0)); + // p + 2^(s−1) = 2^127 leaves i128: rq.p's interval fails its class under acc64, + // so no certified graph forms it, and the uncertified run refuses. + assert_eq!(round(1 << 126, 127, Round::HalfUp), None); + assert_eq!(round((1 << 126) - 1, 127, Round::HalfUp), Some(0)); + } + + #[test] + fn exp_constants() { + assert_eq!(exp_neg_q16(0), 65553); + assert_eq!(exp_neg_q16(-(45426 * 63)), 0); + assert!(exp_neg_q16(-(45426 * 62)) >= 0); + assert_eq!(rsqrt_q16(0), 0); + assert_eq!(rsqrt_q16(1), 1 << 32); + } +} diff --git a/wai/wai-ops/src/json.rs b/wai/wai-ops/src/json.rs new file mode 100644 index 000000000..e175a59d8 --- /dev/null +++ b/wai/wai-ops/src/json.rs @@ -0,0 +1,471 @@ +//! JSON: a reader for the JSON source forms and the vector files, and the canonical +//! writer of §8.5 and §14.1. +//! +//! The reader keeps a number as it was written. [`Value::as_int`] reads an integer +//! (no fraction, no exponent) of any size up to 511 bits; a number with a fraction or +//! an exponent is a value the integer forms never read, so it is not converted, and +//! members such forms ignore may hold one. + +use alloc::boxed::Box; +use alloc::string::String; +use alloc::vec::Vec; + +use crate::xint::I512; + +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum Value { + Null, + Bool(bool), + /// A number exactly as written. + Num(String), + Str(String), + Arr(Vec), + /// Members in the order written. + Obj(Vec<(String, Value)>), +} + +/// Why a JSON text did not parse. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct JsonError { + pub at: usize, +} + +const MAX_DEPTH: usize = 256; + +struct P<'a> { + b: &'a [u8], + i: usize, +} + +impl<'a> P<'a> { + fn err(&self) -> Result { + Err(JsonError { at: self.i }) + } + fn ws(&mut self) { + while let Some(&c) = self.b.get(self.i) { + if c == b' ' || c == b'\t' || c == b'\n' || c == b'\r' { + self.i += 1; + } else { + break; + } + } + } + fn lit(&mut self, s: &[u8]) -> bool { + if self.b.get(self.i..self.i + s.len()) == Some(s) { + self.i += s.len(); + true + } else { + false + } + } + fn value(&mut self, depth: usize) -> Result { + if depth > MAX_DEPTH { + return self.err(); + } + self.ws(); + match self.b.get(self.i) { + None => self.err(), + Some(b'n') => if self.lit(b"null") { Ok(Value::Null) } else { self.err() }, + Some(b't') => if self.lit(b"true") { Ok(Value::Bool(true)) } else { self.err() }, + Some(b'f') => if self.lit(b"false") { Ok(Value::Bool(false)) } else { self.err() }, + Some(b'"') => Ok(Value::Str(self.string()?)), + Some(b'[') => { + self.i += 1; + let mut v = Vec::new(); + self.ws(); + if self.b.get(self.i) == Some(&b']') { + self.i += 1; + return Ok(Value::Arr(v)); + } + loop { + v.push(self.value(depth + 1)?); + self.ws(); + match self.b.get(self.i) { + Some(b',') => self.i += 1, + Some(b']') => { + self.i += 1; + return Ok(Value::Arr(v)); + } + _ => return self.err(), + } + } + } + Some(b'{') => { + self.i += 1; + let mut v = Vec::new(); + self.ws(); + if self.b.get(self.i) == Some(&b'}') { + self.i += 1; + return Ok(Value::Obj(v)); + } + loop { + self.ws(); + if self.b.get(self.i) != Some(&b'"') { + return self.err(); + } + let k = self.string()?; + self.ws(); + if self.b.get(self.i) != Some(&b':') { + return self.err(); + } + self.i += 1; + let val = self.value(depth + 1)?; + v.push((k, val)); + self.ws(); + match self.b.get(self.i) { + Some(b',') => self.i += 1, + Some(b'}') => { + self.i += 1; + return Ok(Value::Obj(v)); + } + _ => return self.err(), + } + } + } + Some(&c) if c == b'-' || c.is_ascii_digit() => self.number(), + _ => self.err(), + } + } + fn digits(&mut self) -> usize { + let s = self.i; + while self.b.get(self.i).is_some_and(|c| c.is_ascii_digit()) { + self.i += 1; + } + self.i - s + } + fn number(&mut self) -> Result { + let s = self.i; + if self.b.get(self.i) == Some(&b'-') { + self.i += 1; + } + match self.b.get(self.i) { + Some(b'0') => self.i += 1, + Some(c) if c.is_ascii_digit() => { + self.digits(); + } + _ => return self.err(), + } + if self.b.get(self.i) == Some(&b'.') { + self.i += 1; + if self.digits() == 0 { + return self.err(); + } + } + if matches!(self.b.get(self.i), Some(b'e') | Some(b'E')) { + self.i += 1; + if matches!(self.b.get(self.i), Some(b'+') | Some(b'-')) { + self.i += 1; + } + if self.digits() == 0 { + return self.err(); + } + } + // The slice is ASCII by construction. + let raw = core::str::from_utf8(&self.b[s..self.i]).map_err(|_| JsonError { at: s })?; + Ok(Value::Num(String::from(raw))) + } + fn hex4(&mut self) -> Result { + let mut v = 0u32; + for _ in 0..4 { + let c = *self.b.get(self.i).ok_or(JsonError { at: self.i })?; + let d = match c { + b'0'..=b'9' => c - b'0', + b'a'..=b'f' => c - b'a' + 10, + b'A'..=b'F' => c - b'A' + 10, + _ => return self.err(), + }; + v = v * 16 + d as u32; + self.i += 1; + } + Ok(v) + } + fn string(&mut self) -> Result { + self.i += 1; // the opening quote + let mut out: Vec = Vec::new(); + loop { + let c = *self.b.get(self.i).ok_or(JsonError { at: self.i })?; + match c { + b'"' => { + self.i += 1; + return String::from_utf8(out).map_err(|_| JsonError { at: self.i }); + } + b'\\' => { + self.i += 1; + let e = *self.b.get(self.i).ok_or(JsonError { at: self.i })?; + self.i += 1; + match e { + b'"' => out.push(b'"'), + b'\\' => out.push(b'\\'), + b'/' => out.push(b'/'), + b'b' => out.push(8), + b'f' => out.push(12), + b'n' => out.push(b'\n'), + b'r' => out.push(b'\r'), + b't' => out.push(b'\t'), + b'u' => { + let mut cp = self.hex4()?; + if (0xD800..0xDC00).contains(&cp) { + if !self.lit(b"\\u") { + return self.err(); + } + let lo = self.hex4()?; + if !(0xDC00..0xE000).contains(&lo) { + return self.err(); + } + cp = 0x10000 + ((cp - 0xD800) << 10) + (lo - 0xDC00); + } else if (0xDC00..0xE000).contains(&cp) { + return self.err(); + } + let ch = char::from_u32(cp).ok_or(JsonError { at: self.i })?; + let mut buf = [0u8; 4]; + out.extend_from_slice(ch.encode_utf8(&mut buf).as_bytes()); + } + _ => return self.err(), + } + } + 0..=0x1F => return self.err(), + _ => { + out.push(c); + self.i += 1; + } + } + } + } +} + +/// Parse one JSON text. Whitespace may surround it; nothing else may follow. +pub fn parse(b: &[u8]) -> Result { + let mut p = P { b, i: 0 }; + let v = p.value(0)?; + p.ws(); + if p.i != b.len() { + return p.err(); + } + Ok(v) +} + +impl Value { + /// The first member named `k` of an object. + pub fn get(&self, k: &str) -> Option<&Value> { + match self { + Value::Obj(m) => m.iter().find(|(n, _)| n == k).map(|(_, v)| v), + _ => None, + } + } + pub fn as_arr(&self) -> Option<&[Value]> { + match self { + Value::Arr(a) => Some(a), + _ => None, + } + } + pub fn as_obj(&self) -> Option<&[(String, Value)]> { + match self { + Value::Obj(m) => Some(m), + _ => None, + } + } + pub fn as_str(&self) -> Option<&str> { + match self { + Value::Str(s) => Some(s), + _ => None, + } + } + pub fn as_bool(&self) -> Option { + match self { + Value::Bool(b) => Some(*b), + _ => None, + } + } + /// A JSON number written as an integer: no fraction and no exponent. + pub fn as_int(&self) -> Option { + match self { + Value::Num(r) if !r.bytes().any(|c| c == b'.' || c == b'e' || c == b'E') => I512::from_dec(r), + _ => None, + } + } + pub fn as_i64(&self) -> Option { + self.as_int()?.to_i64() + } + pub fn as_i128(&self) -> Option { + self.as_int()?.to_i128() + } + pub fn as_u64(&self) -> Option { + let v = self.as_int()?.to_i128()?; + u64::try_from(v).ok() + } + pub fn as_u32(&self) -> Option { + u32::try_from(self.as_u64()?).ok() + } + /// A JSON string holding a canonical decimal integer (§8.5): digits, no leading + /// zero, a `-` only before a nonzero value. + pub fn as_dec(&self) -> Option { + let s = self.as_str()?; + if !is_canonical_dec(s) { + return None; + } + I512::from_dec(s) + } + pub fn as_dec_i64(&self) -> Option { + self.as_dec()?.to_i64() + } + pub fn as_dec_i128(&self) -> Option { + self.as_dec()?.to_i128() + } +} + +/// Whether `s` is a canonical decimal integer: `0`, or an optional `-` followed by a +/// nonzero digit and further digits. +pub fn is_canonical_dec(s: &str) -> bool { + let d = s.strip_prefix('-').unwrap_or(s); + if d.is_empty() || !d.bytes().all(|c| c.is_ascii_digit()) { + return false; + } + if d.len() > 1 && d.starts_with('0') { + return false; + } + !(s.starts_with('-') && d == "0") +} + +/// A canonical JSON value (§8.5): integers are written as decimal strings by the +/// caller, so a value is a string, a boolean, null, an array or an object. +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum C { + Null, + Bool(bool), + Str(String), + Arr(Vec), + /// Members in any order; [`write`] sorts them by their keys' bytes. + Obj(Vec<(String, C)>), +} + +impl C { + pub fn int(v: i128) -> C { + C::Str(alloc::format!("{v}")) + } + pub fn big(v: I512) -> C { + C::Str(v.to_dec()) + } + pub fn s(v: &str) -> C { + C::Str(String::from(v)) + } + pub fn ints>(it: I) -> C { + C::Arr(it.into_iter().map(C::int).collect()) + } + pub fn obj(members: Vec<(&str, C)>) -> C { + C::Obj(members.into_iter().map(|(k, v)| (String::from(k), v)).collect()) + } + pub fn boxed(self) -> Box { + Box::new(self) + } +} + +/// Write `c` canonically into `out`: no whitespace, object members in ascending order +/// of their keys' bytes, strings with `"` written `\"` and `\` written `\\` and no +/// other escape. +pub fn write(c: &C, out: &mut String) { + match c { + C::Null => out.push_str("null"), + C::Bool(true) => out.push_str("true"), + C::Bool(false) => out.push_str("false"), + C::Str(s) => write_str(s, out), + C::Arr(a) => { + out.push('['); + for (i, v) in a.iter().enumerate() { + if i > 0 { + out.push(','); + } + write(v, out); + } + out.push(']'); + } + C::Obj(m) => { + let mut idx: Vec = (0..m.len()).collect(); + idx.sort_by(|&a, &b| m[a].0.as_bytes().cmp(m[b].0.as_bytes())); + out.push('{'); + for (i, &j) in idx.iter().enumerate() { + if i > 0 { + out.push(','); + } + write_str(&m[j].0, out); + out.push(':'); + write(&m[j].1, out); + } + out.push('}'); + } + } +} + +fn write_str(s: &str, out: &mut String) { + out.push('"'); + for ch in s.chars() { + debug_assert!((' '..='~').contains(&ch), "a canonical string holds printable ASCII only"); + match ch { + '"' => out.push_str("\\\""), + '\\' => out.push_str("\\\\"), + _ => out.push(ch), + } + } + out.push('"'); +} + +/// `c`, written canonically. +pub fn to_string(c: &C) -> String { + let mut s = String::new(); + write(c, &mut s); + s +} + +/// Lowercase hexadecimal. +pub fn hex(b: &[u8]) -> String { + const D: &[u8; 16] = b"0123456789abcdef"; + let mut s = String::with_capacity(b.len() * 2); + for &x in b { + s.push(D[(x >> 4) as usize] as char); + s.push(D[(x & 15) as usize] as char); + } + s +} + +/// Lowercase hexadecimal back to bytes; `None` on an odd length or another character. +pub fn unhex(s: &str) -> Option> { + let b = s.as_bytes(); + if b.len() % 2 != 0 { + return None; + } + let d = |c: u8| match c { + b'0'..=b'9' => Some(c - b'0'), + b'a'..=b'f' => Some(c - b'a' + 10), + _ => None, + }; + b.chunks(2).map(|p| Some(d(p[0])? << 4 | d(p[1])?)).collect() +} + +#[cfg(test)] +mod tests { + use super::*; + use alloc::vec; + + #[test] + fn parse_and_read() { + let v = parse(br#" {"a": [1, -2, 3.5, 1e3, 99999999999999999999999], "b": "x\"\u00e9", "c": true, "d": null} "#).unwrap(); + let a = v.get("a").unwrap().as_arr().unwrap(); + assert_eq!(a[0].as_i64(), Some(1)); + assert_eq!(a[1].as_i64(), Some(-2)); + assert_eq!(a[2].as_int(), None); + assert_eq!(a[3].as_int(), None); + assert_eq!(a[4].as_i128(), Some(99999999999999999999999)); + assert_eq!(v.get("b").unwrap().as_str(), Some("x\"é")); + assert!(parse(b"[1,]").is_err()); + assert!(parse(b"01").is_err()); + assert!(parse(b"{} x").is_err()); + assert!(parse(b"\"\\ud800\"").is_err()); + } + + #[test] + fn canonical() { + let c = C::obj(vec![("b", C::int(-5)), ("a", C::Arr(vec![C::Bool(true), C::Null, C::s("q\"\\")]))]); + assert_eq!(to_string(&c), r#"{"a":[true,null,"q\"\\"],"b":"-5"}"#); + assert!(is_canonical_dec("0") && is_canonical_dec("-12") && !is_canonical_dec("-0") && !is_canonical_dec("012")); + assert_eq!(unhex(&hex(&[0, 255, 16])), Some(vec![0, 255, 16])); + } +} diff --git a/wai/wai-ops/src/lib.rs b/wai/wai-ops/src/lib.rs new file mode 100644 index 000000000..52c20aa1a --- /dev/null +++ b/wai/wai-ops/src/lib.rs @@ -0,0 +1,39 @@ +//! `wai-ops/1`, the WAI integer operator set (`extensions/integer-operators.md`). +//! +//! - [`xint`]: a 512-bit signed integer with the saturation of §8.1. +//! - [`json`]: a JSON reader (integers of any size, numbers kept as written) and the +//! canonical writer of §8.5. +//! - [`graph`]: `WHG1` (§10), parsed and written, with load steps 1–6 of §10.5. +//! - [`plan`]: the load-time plan (§10.5 step 7) and the run-time plan (§4). +//! - [`interp`]: the reference interpreter of the graph operators (§5). +//! - [`stage`]: the stage operators E1–E13 (§5E). +//! - [`lower`]: the canonical lowerings of §13. +//! - [`vectors`]: the conformance vector files of §14.1, recomputed from their inputs. +//! - [`generate`]: the generator of `../ops-conformance/`, which writes those files. +//! +//! Every value is an exact integer. Nothing here uses floating point, wraps, or +//! depends on the target's word size. +//! +//! **Load step 8**, the bounds pass and the profile verdict (§8, §10.5 step 8), is +//! not built yet. Without the `uncertified` feature a graph never completes its load; +//! with it, step 8 is skipped. See [`graph::load`]. +#![no_std] +#![forbid(unsafe_code)] + +extern crate alloc; + +pub mod code; +pub mod generate; +pub mod graph; +pub mod interp; +pub mod json; +pub mod lower; +pub mod plan; +pub mod sha256; +pub mod stage; +pub mod vectors; +pub mod xint; + +pub use code::{Code, Refusal, Site}; +pub use graph::Graph; +pub use interp::{Sequence, Tensor, run}; diff --git a/wai/wai-ops/src/lower/jpegai.rs b/wai/wai-ops/src/lower/jpegai.rs new file mode 100644 index 000000000..f9da1174a --- /dev/null +++ b/wai/wai-ops/src/lower/jpegai.rs @@ -0,0 +1,136 @@ +//! `jpegai-int/1` (§13.6.1): the scale graphs `hs_y` and `hs_uv` of +//! `wai.image.jpegai`, from the bundle's `norm.json` and `weights/hs_{y,uv}.json`. + +use alloc::vec; +use alloc::vec::Vec; + +use super::{Builder, Lowered, Res, refuse}; +use crate::graph::{BiasKind, Graph, Params, Round, Rq, TensorRec, opcode, smallest_width}; +use crate::json::{self, Value}; + +fn ints(v: &Value) -> Res> { + let a = v.as_arr().ok_or(()).or_else(|_| refuse())?; + a.iter().map(|x| x.as_i64().ok_or(()).or_else(|_| refuse())).collect() +} + +fn member<'a>(o: &'a Value, k: &str) -> Res<&'a Value> { + o.get(k).ok_or(()).or_else(|_| refuse()) +} + +/// The load checks of §13.6.1 on `norm.json`; returns `(gain_y, gain_uv)`. +fn norm_checks(norm: &Value) -> Res<(Vec, Vec)> { + if norm.as_obj().is_none() { + return refuse(); + } + let pmf = member(norm, "pmf")?.as_arr().ok_or(()).or_else(|_| refuse())?; + if pmf.len() < 32 { + return refuse(); + } + let mut width = None; + for row in pmf { + let r = ints(row)?; + if r.is_empty() || r.iter().any(|&p| p < 0) || r.iter().sum::() != 256 || width.is_some_and(|w| w != r.len()) { + return refuse(); + } + width = Some(r.len()); + } + let bounds = ints(member(norm, "bounds")?)?; + if bounds.len() < 32 || bounds.iter().any(|&b| !(0..=255).contains(&b)) { + return refuse(); + } + if member(norm, "per_channel")?.as_i64() != Some(16) { + return refuse(); + } + for (k, rows) in [("cdfs_y", 160usize), ("cdfs_uv", 96)] { + let c = ints(member(norm, k)?)?; + if c.len() != rows * 63 || c.iter().any(|&v| !(0..=255).contains(&v)) || c.chunks(63).any(|r| r.windows(2).any(|p| p[0] > p[1])) { + return refuse(); + } + } + let gy = ints(member(norm, "gain_y")?)?; + let guv = ints(member(norm, "gain_uv")?)?; + if gy.len() != 160 || guv.len() != 96 { + return refuse(); + } + Ok((gy, guv)) +} + +/// A member `{ "dims": [...], "v": [...] }` with the dims `want`. +fn tensor(o: &Value, k: &str, want: &[u64]) -> Res> { + let m = member(o, k)?; + let dims: Vec = member(m, "dims")?.as_arr().ok_or(()).or_else(|_| refuse())? + .iter().map(|d| d.as_u64().ok_or(()).or_else(|_| refuse())).collect::>()?; + if dims.as_slice() != want { + return refuse(); + } + let v = ints(member(m, "v")?)?; + if v.len() as u64 != want.iter().product::() { + return refuse(); + } + Ok(v) +} + +/// The width of one dimension, read from the member's dims before checking it. +fn dim(o: &Value, k: &str, i: usize) -> Res { + member(member(o, k)?, "dims")?.as_arr().and_then(|d| d.get(i)).and_then(Value::as_u64).filter(|&d| d >= 1 && d <= u32::MAX as u64) + .ok_or(()).or_else(|_| refuse()) +} + +fn plane(hs: &Value, cz: u64, gains: &[i64]) -> Res { + if hs.as_obj().is_none() { + return refuse(); + } + let c1 = dim(hs, "conv1.weight", 0)?; + let c2 = dim(hs, "depthwise.weight", 0)?; + let c3 = 16 * cz; + let blocks = [ + ("conv1", c1, cz, 1u32, 0u32, "onnx::Pow_85"), + ("depthwise", c2, c1, 3, 1, "onnx::Pow_91"), + ("pointwise", c3, c2, 1, 0, "onnx::Pow_97"), + ]; + let mut b = Builder::new(); + let mut x = b.input(TensorRec::check(cz as u32, -31, 32), 4, 4); + for (i, (name, cout, cin, k, pad, sh)) in blocks.iter().enumerate() { + let w = tensor(hs, &alloc::format!("{name}.weight"), &[*cout, *cin, *k as u64, *k as u64])?; + let bias = tensor(hs, &alloc::format!("{name}.bias"), &[*cout])?; + let shifts = tensor(hs, sh, &[1, *cout, 1, 1])?; + if shifts.iter().any(|&s| !(0..=127).contains(&s)) { + return refuse(); + } + let cin_t = b.channels(x); + x = b.op(opcode::CLAMP, vec![x], TensorRec::derived(cin_t), Params::Clamp { lo: -128, hi: 127 }); + let rq = Rq { + round: Round::Floor, + bias_kind: BiasKind::Pre, + m_kind: 0, + s_kind: 2, + m_bytes: 0, + b_bytes: smallest_width(&bias, &[4, 8]), + mult: vec![], + shift: shifts.iter().map(|&s| s as u8).collect(), + bias, + }; + let w_bytes = smallest_width(&w, &[1, 2, 4, 8]); + let p = Params::Conv { cout: *cout as u32, kh: *k, kw: *k, sh: 1, sw: 1, ph: *pad, pw: *pad, groups: 1, w_bytes, rq, w }; + x = b.op(opcode::CONV, vec![x], TensorRec::derived(*cout as u32), p); + if i < 2 { + x = b.op(opcode::RELU, vec![x], TensorRec::derived(*cout as u32), Params::None); + } + } + let c = cz as u32; + x = b.op(opcode::PIXEL_SHUFFLE, vec![x], TensorRec::derived(c), Params::Shuffle { r: 4 }); + x = b.op(opcode::ABS, vec![x], TensorRec::derived(c), Params::None); + x = b.op(opcode::CLAMP, vec![x], TensorRec::derived(c), Params::Clamp { lo: 0, hi: 3967 }); + let rq = Rq { round: Round::Floor, bias_kind: BiasKind::Pre, m_kind: 0, s_kind: 1, m_bytes: 0, b_bytes: smallest_width(gains, &[4, 8]), mult: vec![], shift: vec![0], bias: gains.to_vec() }; + x = b.op(opcode::RESCALE, vec![x], TensorRec::derived(c), Params::Rescale(rq)); + b.finish(vec![x]) +} + +/// Lower a `wai.image.jpegai` bundle's scale path: `hs_y`, then `hs_uv`. +pub fn jpegai(norm: &[u8], hs_y: &[u8], hs_uv: &[u8]) -> Res { + let nv = json::parse(norm).or_else(|_| refuse())?; + let (gy, guv) = norm_checks(&nv)?; + let y = json::parse(hs_y).or_else(|_| refuse())?; + let uv = json::parse(hs_uv).or_else(|_| refuse())?; + Ok(Lowered { roles: vec![("hs_y", plane(&y, 160, &gy)?), ("hs_uv", plane(&uv, 96, &guv)?)] }) +} diff --git a/wai/wai-ops/src/lower/mod.rs b/wai/wai-ops/src/lower/mod.rs new file mode 100644 index 000000000..1299d09f8 --- /dev/null +++ b/wai/wai-ops/src/lower/mod.rs @@ -0,0 +1,110 @@ +//! The canonical lowerings of §13: each maps a parameter set in a registered form to +//! `WHG1` graphs, writing exactly one byte sequence for a set (§13.0). +//! +//! Every refusal of a lowering is `model_mismatch`; a capability whose payload +//! extension reports one code for every refusal (`int_synth`) maps it. + +use alloc::vec; +use alloc::vec::Vec; + +use crate::code::{Code, Refusal, Site}; +use crate::graph::{CAP, Graph, InputRec, Op, Params, ScalarRec, TensorRec, op_name}; + +mod jpegai; +mod synth; +mod whm; + +pub use jpegai::jpegai; +pub use synth::int_synth; +pub use whm::{Net, NetLayer, int_hyper, parse_wam1, parse_whm1, splat, wam1, whm1, wmb1, world}; + +/// A lowered set: its graphs by role, in §13.0's order. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Lowered { + pub roles: Vec<(&'static str, Graph)>, +} + +impl Lowered { + pub fn get(&self, role: &str) -> Option<&Graph> { + self.roles.iter().find(|(r, _)| *r == role).map(|(_, g)| g) + } +} + +pub(crate) type Res = Result; + +pub(crate) fn refuse() -> Res { + Err(Refusal::new(Code::ModelMismatch, Site::Lowering)) +} + +/// A graph under construction with §13.0's numbering: input `i` is tensor `i`, and +/// each operator's outputs take the next unused indices as the operator is added. +pub(crate) struct Builder { + pub scalars: Vec, + pub inputs: Vec, + pub tensors: Vec, + pub ops: Vec, +} + +impl Builder { + pub fn new() -> Builder { + Builder { scalars: vec![], inputs: vec![], tensors: vec![], ops: vec![] } + } + /// A data input of `rec`, with the driver contract's sizes. + pub fn input(&mut self, rec: TensorRec, max_h: u32, max_w: u32) -> u32 { + let t = self.tensors.len() as u32; + self.tensors.push(rec); + self.inputs.push(InputRec { tensor: t, max_h, max_w, kind: 0, src: 0, init: 0 }); + t + } + pub fn scalar(&mut self, lo: i64, hi: i64) -> u32 { + self.scalars.push(ScalarRec { lo, hi }); + (self.scalars.len() - 1) as u32 + } + /// Add an operator writing one tensor of `out`; returns that tensor. + pub fn op(&mut self, code: u8, ins: Vec, out: TensorRec, p: Params) -> u32 { + let t = self.tensors.len() as u32; + self.tensors.push(out); + self.ops.push(Op { code, ins, outs: vec![t], p }); + t + } + pub fn channels(&self, t: u32) -> u32 { + self.tensors[t as usize].channels + } + /// The graph with `outputs`, after checking that it loads (steps 1–7): a lowering + /// writes only graphs that parse and plan. + pub fn finish(self, outputs: Vec) -> Res { + let g = Graph { max_elems: CAP as u32, scalars: self.scalars, inputs: self.inputs, outputs, tensors: self.tensors, ops: self.ops }; + let b = g.to_bytes(); + match Graph::parse(&b) { + Ok(back) if back == g => {} + _ => return refuse(), + } + crate::plan::load_plan(&g).map_err(|_| Refusal::new(Code::ModelMismatch, Site::Lowering))?; + debug_assert!(g.ops.iter().all(|o| op_name(o.code).is_some())); + Ok(g) + } +} + +/// The largest `X ∈ [0, 2^63]` for which `p(X)` holds, `p` monotone (it holds at `X` +/// whenever it holds at a larger value); `None` when `p(0)` fails. +pub(crate) fn largest(p: impl Fn(u128) -> bool) -> Option { + if !p(0) { + return None; + } + let (mut lo, mut hi) = (0u128, 1u128 << 63); + if p(hi) { + return Some(hi); + } + while hi - lo > 1 { + let mid = lo + (hi - lo) / 2; + if p(mid) { lo = mid } else { hi = mid } + } + Some(lo) +} + +/// `check [−X, min(X, 2^63 − 1)]` over `channels`. +pub(crate) fn check_x(channels: u32, x: u128) -> TensorRec { + let lo = -(x as i128) as i64; + let hi = x.min(i64::MAX as u128) as i64; + TensorRec::check(channels, lo, hi) +} diff --git a/wai/wai-ops/src/lower/synth.rs b/wai/wai-ops/src/lower/synth.rs new file mode 100644 index 000000000..a4b576964 --- /dev/null +++ b/wai/wai-ops/src/lower/synth.rs @@ -0,0 +1,74 @@ +//! `int_synth/1` (§13.1): `int_synth.json` (integer-payloads §13) to the graph +//! `synth`. + +use alloc::vec; +use alloc::vec::Vec; + +use super::{Builder, Lowered, Res, refuse}; +use crate::graph::{BiasKind, Params, Round, Rq, TensorRec, opcode}; +use crate::json::{self, Value}; + +fn uint(l: &Value, k: &str, default: Option) -> Res { + match l.get(k) { + None => default.ok_or(()).or_else(|_| refuse()), + Some(v) => v.as_u32().ok_or(()).or_else(|_| refuse()), + } +} + +fn i32s(l: &Value, k: &str) -> Res> { + let a = l.get(k).and_then(Value::as_arr).ok_or(()).or_else(|_| refuse())?; + let mut v = Vec::with_capacity(a.len()); + for x in a { + match x.as_i64() { + Some(n) if i32::try_from(n).is_ok() => v.push(n), + _ => return refuse(), + } + } + Ok(v) +} + +/// Lower `int_synth.json`. +pub fn int_synth(bytes: &[u8]) -> Res { + let root = json::parse(bytes).or_else(|_| refuse())?; + let layers = root.get("layers").and_then(Value::as_arr).ok_or(()).or_else(|_| refuse())?; + if layers.is_empty() { + return refuse(); + } + let mut b = Builder::new(); + let c0 = uint(&layers[0], "in_ch", None)?; + if c0 == 0 { + return refuse(); + } + let mut x = b.input(TensorRec::check(c0, -128, 127), 0, 0); + let mut c = c0; + for l in layers { + if l.as_obj().is_none() { + return refuse(); + } + let (in_ch, out_ch, k, stride, pad) = (uint(l, "in_ch", None)?, uint(l, "out_ch", None)?, uint(l, "k", None)?, uint(l, "stride", None)?, uint(l, "pad", None)?); + let out_pad = uint(l, "out_pad", Some(0))?; + let shift = uint(l, "shift", Some(0))?; + let relu = match l.get("relu") { + None => false, + Some(v) => v.as_bool().ok_or(()).or_else(|_| refuse())?, + }; + let weight = i32s(l, "weight")?; + let bias = i32s(l, "bias")?; + if in_ch != c || out_ch == 0 || k == 0 || stride == 0 || shift > 127 { + return refuse(); + } + let nw = in_ch as u64 * out_ch as u64 * k as u64 * k as u64; + if weight.len() as u64 != nw || bias.len() as u64 != out_ch as u64 { + return refuse(); + } + let rq = Rq { round: Round::Floor, bias_kind: BiasKind::Pre, m_kind: 0, s_kind: 1, m_bytes: 0, b_bytes: 4, mult: vec![], shift: vec![shift as u8], bias }; + let p = Params::ConvT { cout: out_ch, kh: k, kw: k, sh: stride, sw: stride, ph: pad, pw: pad, oph: out_pad, opw: out_pad, w_bytes: 4, rq, w: weight }; + x = b.op(opcode::CONV_TRANSPOSE, vec![x], TensorRec::derived(out_ch), p); + if relu { + x = b.op(opcode::RELU, vec![x], TensorRec::derived(out_ch), Params::None); + } + c = out_ch; + } + let out = b.op(opcode::CLAMP, vec![x], TensorRec::derived(c), Params::Clamp { lo: 0, hi: 255 }); + Ok(Lowered { roles: vec![("synth", b.finish(vec![out])?)] }) +} diff --git a/wai/wai-ops/src/lower/whm.rs b/wai/wai-ops/src/lower/whm.rs new file mode 100644 index 000000000..3e900d8a0 --- /dev/null +++ b/wai/wai-ops/src/lower/whm.rs @@ -0,0 +1,395 @@ +//! `whm1/1` (§13.2), `wam1/1` (§13.3), `wmb1/1` (§13.4) and `world/1` (§13.5). + +use alloc::vec; +use alloc::vec::Vec; + +use super::{Builder, Lowered, Res, check_x, largest, refuse}; +use crate::graph::{BiasKind, Graph, Operand, Params, Round, Rq, TensorRec, opcode}; +use crate::xint::I512; + +/// One layer of a `WHM1` or `WAM1` network, as the file holds it. +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum NetLayer { + /// Tag 0. For `WAM1`, `k` is the one-dimensional kernel and the weights are + /// `[inc][out][k]`. + ConvT { inc: u32, out: u32, k: u32, stride: u32, pad: u32, opad: u32, w: Vec, mult: Vec, bias: Vec }, + /// Tag 1 (`WHM1` only); weights `[out][inc][k][k]`. + Conv { inc: u32, out: u32, k: u32, stride: u32, pad: u32, w: Vec, mult: Vec, bias: Vec }, + /// Tag 2. + Igdn { c: u32, gamma: Vec, beta: Vec }, + /// Tag 3 (`WHM1` only). + Relu, + /// Tag 4 (`WHM1` only). + Leaky { slope_q: i64, slope_frac: u32 }, +} + +/// A parsed `WHM1` or `WAM1` network. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Net { + pub afrac: u32, + pub gf: u32, + pub shift: u32, + pub layers: Vec, + /// `WAM1`: one-dimensional transposed convolutions. + pub audio: bool, +} + +struct Cur<'a> { + b: &'a [u8], + p: usize, +} + +impl<'a> Cur<'a> { + fn take(&mut self, n: u64) -> Res<&'a [u8]> { + let e = usize::try_from(n).ok().and_then(|n| self.p.checked_add(n)).filter(|&e| e <= self.b.len()); + match e { + Some(e) => { + let s = &self.b[self.p..e]; + self.p = e; + Ok(s) + } + None => refuse(), + } + } + fn u8(&mut self) -> Res { + Ok(self.take(1)?[0]) + } + fn u32(&mut self) -> Res { + let s = self.take(4)?; + Ok(u32::from_le_bytes([s[0], s[1], s[2], s[3]])) + } + fn ints(&mut self, n: u64, w: u64) -> Res> { + let s = self.take(n.checked_mul(w).map_or(u64::MAX, |v| v))?; + Ok(s.chunks_exact(w as usize) + .map(|c| match w { + 2 => i16::from_le_bytes([c[0], c[1]]) as i64, + 4 => i32::from_le_bytes([c[0], c[1], c[2], c[3]]) as i64, + _ => i64::from_le_bytes([c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]]), + }) + .collect()) + } +} + +fn prod(d: &[u32]) -> u64 { + d.iter().fold(1u64, |a, &x| a.saturating_mul(x as u64)) +} + +fn parse(b: &[u8], magic: &[u8; 4], audio: bool) -> Res { + if b.get(0..4) != Some(&magic[..]) { + return refuse(); + } + let mut c = Cur { b, p: 4 }; + let (afrac, gf, shift, n) = (c.u32()?, c.u32()?, c.u32()?, c.u32()?); + let mut layers = Vec::new(); + for _ in 0..n { + let tag = c.u8()?; + layers.push(match (tag, audio) { + (0, _) => { + let (inc, out) = (c.u32()?, c.u32()?); + let (k, stride, pad, opad) = (c.u32()?, c.u32()?, c.u32()?, c.u32()?); + let nw = if audio { prod(&[inc, out, k]) } else { prod(&[inc, out, k, k]) }; + let w = c.ints(nw, 2)?; + let mult = c.ints(out as u64, 8)?; + let bias = c.ints(out as u64, 8)?; + NetLayer::ConvT { inc, out, k, stride, pad, opad, w, mult, bias } + } + (1, false) => { + let (inc, out) = (c.u32()?, c.u32()?); + let (k, stride, pad) = (c.u32()?, c.u32()?, c.u32()?); + let w = c.ints(prod(&[out, inc, k, k]), 2)?; + let mult = c.ints(out as u64, 8)?; + let bias = c.ints(out as u64, 8)?; + NetLayer::Conv { inc, out, k, stride, pad, w, mult, bias } + } + (2, _) => { + let cc = c.u32()?; + let gamma = c.ints(prod(&[cc, cc]), 4)?; + let beta = c.ints(cc as u64, 8)?; + NetLayer::Igdn { c: cc, gamma, beta } + } + (3, false) => NetLayer::Relu, + (4, false) => { + let slope_q = c.ints(1, 8)?[0]; + NetLayer::Leaky { slope_q, slope_frac: c.u32()? } + } + _ => return refuse(), + }); + } + if c.p != b.len() { + return refuse(); + } + Ok(Net { afrac, gf, shift, layers, audio }) +} + +/// Parse a `WHM1` network (integer-payloads §9). +pub fn parse_whm1(b: &[u8]) -> Res { + parse(b, b"WHM1", false) +} + +/// Parse a `WAM1` network (integer-payloads §9). +pub fn parse_wam1(b: &[u8]) -> Res { + parse(b, b"WAM1", true) +} + +fn maxabs(v: &[i64]) -> I512 { + v.iter().map(|&x| I512::from_i128((x as i128).abs())).max().unwrap_or(I512::ZERO) +} + +const I64: I512 = I512::from_i128(i64::MAX as i128); +const I128: I512 = I512::from_i128(i128::MAX); + +/// `X_ℓ` for a layer reading `c` channels (§13.2), or `None` for a layer no `check` +/// range precedes (a ReLU). Refuses when `P_ℓ(0)` fails. +fn x_of(net: &Net, l: &NetLayer, c: u32) -> Res> { + let le = |a: I512, b: I512| a <= b; + let x = match l { + NetLayer::ConvT { k, w, mult, bias, .. } | NetLayer::Conv { k, w, mult, bias, .. } => { + let kk = if net.audio { *k as u64 } else { *k as u64 * *k as u64 }; + let terms = I512::from_u64(c as u64).mul(I512::from_u64(kk)); + let (wm, mm, bm) = (maxabs(w), maxabs(mult), maxabs(bias)); + let s = net.shift; + largest(|x| { + let a = terms.mul(wm).mul(I512::from_u128(x)); + le(a, I64) && le(a.mul(mm).shr_floor(s).add(I512::ONE).add(bm), I64) + }) + } + NetLayer::Igdn { gamma, beta, .. } => { + let (g, bb, cc) = (maxabs(gamma), maxabs(beta), I512::from_u64(c as u64)); + let (gf, af) = (net.gf, net.afrac); + largest(|x| { + let x = I512::from_u128(x); + let gx2 = g.mul(x).mul(x); + if !le(gx2, I128) { + return false; + } + let n = bb.add(cc.mul(gx2.shr_floor(gf).add(I512::ONE))); + if !le(n, I128) { + return false; + } + let r = n.isqrt(); + le(r, I64) && le(x.mul(r).shr_floor(af).add(I512::ONE), I64) + }) + } + NetLayer::Leaky { slope_q, .. } => { + let a = I512::from_i128((*slope_q as i128).abs()); + largest(|x| le(I512::from_u128(x).mul(a), I64)) + } + NetLayer::Relu => return Ok(None), + }; + match x { + Some(x) => Ok(Some(x)), + None => refuse(), + } +} + +/// The input channel count of the first layer of tag 0, 1 or 2. +fn in_channels(net: &Net) -> Res { + for l in &net.layers { + match l { + NetLayer::ConvT { inc, .. } | NetLayer::Conv { inc, .. } => return Ok(*inc), + NetLayer::Igdn { c, .. } => return Ok(*c), + _ => {} + } + } + refuse() +} + +/// The layers' load checks (§13.2): `shift < 128`, `gf < 128`, `afrac` in `1..=30`. +fn header_ok(net: &Net) -> Res<()> { + if net.shift > 127 || net.gf > 127 || !(1..=30).contains(&net.afrac) { + return refuse(); + } + Ok(()) +} + +/// The range check of the tensor read by layer `l` on `c` channels: `check` at +/// `[−X_ℓ, min(X_ℓ, I64)]`, or `[−2^63, I64]` before a ReLU. +fn read_check(net: &Net, l: &NetLayer, c: u32) -> Res { + Ok(match x_of(net, l, c)? { + Some(x) => check_x(c, x), + None => TensorRec::check(c, i64::MIN, i64::MAX), + }) +} + +/// Append the network's layers to `b`, reading `x0`, whose record the caller wrote +/// with [`read_check`] of layer 0. Returns the last tensor. +fn layers(b: &mut Builder, net: &Net, x0: u32) -> Res { + let mut x = x0; + for (i, l) in net.layers.iter().enumerate() { + let c = b.channels(x); + let out_c = match l { + NetLayer::ConvT { out, .. } | NetLayer::Conv { out, .. } => *out, + _ => c, + }; + let rec = match net.layers.get(i + 1) { + Some(next) => read_check(net, next, out_c)?, + None => TensorRec::derived(out_c), + }; + let rq = |mult: &[i64], bias: &[i64]| Rq { + round: Round::Floor, + bias_kind: BiasKind::Post, + m_kind: 2, + s_kind: 1, + m_bytes: 8, + b_bytes: 8, + mult: mult.to_vec(), + shift: vec![net.shift as u8], + bias: bias.to_vec(), + }; + x = match l { + NetLayer::ConvT { inc, out, k, stride, pad, opad, w, mult, bias } => { + if *inc != c || *out == 0 || *k == 0 || *stride == 0 { + return refuse(); + } + let p = if net.audio { + Params::ConvT { cout: *out, kh: 1, kw: *k, sh: 1, sw: *stride, ph: 0, pw: *pad, oph: 0, opw: *opad, w_bytes: 2, rq: rq(mult, bias), w: w.clone() } + } else { + Params::ConvT { cout: *out, kh: *k, kw: *k, sh: *stride, sw: *stride, ph: *pad, pw: *pad, oph: *opad, opw: *opad, w_bytes: 2, rq: rq(mult, bias), w: w.clone() } + }; + b.op(opcode::CONV_TRANSPOSE, vec![x], rec, p) + } + NetLayer::Conv { inc, out, k, stride, pad, w, mult, bias } => { + if *inc != c || *out == 0 || *k == 0 || *stride == 0 { + return refuse(); + } + let p = Params::Conv { cout: *out, kh: *k, kw: *k, sh: *stride, sw: *stride, ph: *pad, pw: *pad, groups: 1, w_bytes: 2, rq: rq(mult, bias), w: w.clone() }; + b.op(opcode::CONV, vec![x], rec, p) + } + NetLayer::Igdn { c: cc, gamma, beta } => { + if *cc != c { + return refuse(); + } + let p = Params::Igdn { gf: net.gf, frac: net.afrac, g_bytes: 4, gamma: gamma.clone(), beta: beta.clone() }; + b.op(opcode::IGDN, vec![x], rec, p) + } + NetLayer::Relu => b.op(opcode::RELU, vec![x], rec, Params::None), + NetLayer::Leaky { slope_q, slope_frac } => { + if *slope_frac > 63 { + return refuse(); + } + b.op(opcode::LEAKY, vec![x], rec, Params::Leaky { a: *slope_q, f: *slope_frac }) + } + }; + } + Ok(x) +} + +/// The RGB8 step (§13.0): `clamp(0, 2^afrac)`, then `rescale` by 255 with shift +/// `afrac`, rounding half up. +fn rgb8(b: &mut Builder, x: u32, afrac: u32) -> u32 { + let c = b.channels(x); + let t = b.op(opcode::CLAMP, vec![x], TensorRec::derived(c), Params::Clamp { lo: 0, hi: 1i64 << afrac }); + let rq = Rq { round: Round::HalfUp, bias_kind: BiasKind::None, m_kind: 1, s_kind: 1, m_bytes: 4, b_bytes: 0, mult: vec![255], shift: vec![afrac as u8], bias: vec![] }; + b.op(opcode::RESCALE, vec![t], TensorRec::derived(c), Params::Rescale(rq)) +} + +fn net_graph(net: &Net, output_step: bool) -> Res { + header_ok(net)?; + let c0 = in_channels(net)?; + let mut b = Builder::new(); + let first = net.layers.first().ok_or(()).or_else(|_| refuse())?; + let x0 = b.input(read_check(net, first, c0)?, 0, 0); + let mut x = layers(&mut b, net, x0)?; + if output_step { + x = rgb8(&mut b, x, net.afrac); + } + b.finish(vec![x]) +} + +/// `whm1/1`: one `WHM1` network, with the RGB8 step when `output_step` is set. +pub fn whm1(bytes: &[u8], output_step: bool) -> Res { + net_graph(&parse_whm1(bytes)?, output_step) +} + +/// `whm1/1` for `wai.neural.int_hyper` and the keyframe of `wai.video.int_hyper`: +/// `h_s`, then `g_s` with the RGB8 step. +pub fn int_hyper(h_s: &[u8], g_s: &[u8]) -> Res { + Ok(Lowered { roles: vec![("h_s", whm1(h_s, false)?), ("g_s", whm1(g_s, true)?)] }) +} + +/// `whm1/1` for `wai.splat.int_codec`: `g_s` with the RGB8 step. +pub fn splat(g_s: &[u8]) -> Res { + Ok(Lowered { roles: vec![("g_s", whm1(g_s, true)?)] }) +} + +/// `wam1/1` (§13.3): the `WAM1` synthesis with the PCM step. +pub fn wam1(bytes: &[u8]) -> Res { + let net = parse_wam1(bytes)?; + header_ok(&net)?; + let c0 = in_channels(&net)?; + let mut b = Builder::new(); + let first = net.layers.first().ok_or(()).or_else(|_| refuse())?; + let x0 = b.input(read_check(&net, first, c0)?, 0, 0); + let t_out = b.scalar(1, 1 << 26); + let x = layers(&mut b, &net, x0)?; + let c = b.channels(x); + // The range in which v·32767 + 2^(afrac−1) fits i64. + let lo = -((1i128 << 63) / 32767) as i64; // ⌈−2^63 / 32767⌉ + let hi = ((i64::MAX as i128 - (1i128 << (net.afrac - 1))) / 32767) as i64; + let crop = Params::Crop { y0: Operand::Const(0), x0: Operand::Const(0), h: Operand::Const(1), w: Operand::Scalar(t_out) }; + let t = b.op(opcode::CROP, vec![x], TensorRec::check(c, lo, hi), crop); + let rq = Rq { round: Round::HalfUp, bias_kind: BiasKind::None, m_kind: 1, s_kind: 1, m_bytes: 4, b_bytes: 0, mult: vec![32767], shift: vec![net.afrac as u8], bias: vec![] }; + let t = b.op(opcode::RESCALE, vec![t], TensorRec::derived(c), Params::Rescale(rq)); + let t = b.op(opcode::CLAMP, vec![t], TensorRec::derived(c), Params::Clamp { lo: -32768, hi: 32767 }); + b.finish(vec![t]) +} + +/// `wmb1/1` (§13.4): a `WMB1` bundle's `h_s`, `entropy` and `g_s` (with the RGB8 +/// step). The tables section is the stage operators' data; its `afrac` must be the +/// networks'. +pub fn wmb1(bytes: &[u8]) -> Res { + if bytes.get(0..4) != Some(&b"WMB1"[..]) { + return refuse(); + } + let mut c = Cur { b: bytes, p: 4 }; + let mut sec = || -> Res<&[u8]> { + let n = c.u32()?; + c.take(n as u64) + }; + let (h, e, g, t) = (sec()?, sec()?, sec()?, sec()?); + if c.p != bytes.len() { + return refuse(); + } + let (hn, en, gn) = (parse_whm1(h)?, parse_whm1(e)?, parse_whm1(g)?); + if hn.afrac != gn.afrac || en.afrac != gn.afrac { + return refuse(); + } + let tables = crate::json::parse(t).or_else(|_| refuse())?; + match tables.get("afrac").and_then(|a| a.as_u32()) { + Some(a) if a == gn.afrac && tables.as_obj().is_some() => {} + _ => return refuse(), + } + Ok(Lowered { roles: vec![("h_s", net_graph(&hn, false)?), ("entropy", net_graph(&en, false)?), ("g_s", net_graph(&gn, true)?)] }) +} + +/// `world/1` (§13.5, informative): the transition `T` with `A` action planes, then +/// the synthesis `g_s` with the RGB8 step. `c` is the latent's channel count. +pub fn world(t: &[u8], g_s: &[u8], c: u32) -> Res { + let tn = parse_whm1(t)?; + let gn = parse_whm1(g_s)?; + header_ok(&tn)?; + header_ok(&gn)?; + if tn.afrac != gn.afrac { + return refuse(); + } + let cin = in_channels(&tn)?; + if c == 0 || cin <= c { + return refuse(); + } + let a = cin - c; + let mut b = Builder::new(); + let z = b.input(TensorRec::check(c, i64::MIN, i64::MAX), 0, 0); + let mut parts = vec![z]; + for _ in 0..a { + let s = b.scalar(i64::MIN, i64::MAX); + parts.push(b.op(opcode::FILL, vec![z], TensorRec::derived(1), Params::Fill { kind: 1, value: s as i64 })); + } + let first = tn.layers.first().ok_or(()).or_else(|_| refuse())?; + let x0 = b.op(opcode::CONCAT, parts, read_check(&tn, first, cin)?, Params::None); + let x = layers(&mut b, &tn, x0)?; + let one = 1i64 << tn.afrac; + let cc = b.channels(x); + let out = b.op(opcode::CLAMP, vec![x], TensorRec::derived(cc), Params::Clamp { lo: -one, hi: one }); + let tg = b.finish(vec![out])?; + Ok(Lowered { roles: vec![("T", tg), ("g_s", net_graph(&gn, true)?)] }) +} diff --git a/wai/wai-ops/src/plan.rs b/wai/wai-ops/src/plan.rs new file mode 100644 index 000000000..37c565300 --- /dev/null +++ b/wai/wai-ops/src/plan.rs @@ -0,0 +1,259 @@ +//! Shapes: the load-time plan (§10.5 step 7) and the run-time plan (§4, run step 3). +//! +//! One walk serves both. At load it runs on the inputs' declared sizes, and a shape +//! rule that fails is `model_mismatch`; at run time it runs on the sizes and scalar +//! values of one decode, and a shape rule that fails is `geometry_mismatch`. In both, +//! for each operator in graph order, the sizes it forms before its shape rule can be +//! read (a padded side; a transposed convolution's uncropped side and its uncropped +//! output, `cout` channels of that side's plane; an upsampled side) are checked +//! against the cap first (`too_large`), then the shape rule, then each output tensor +//! against the graph's `max_elems` (`too_large`). Every size is formed in 64-bit +//! arithmetic with overflow checked, and a size past 64 bits is past the cap. + +use alloc::vec; +use alloc::vec::Vec; + +use crate::code::{Code, Refusal, Site, at_load}; +use crate::graph::{CAP, Graph, Operand, Params, opcode::*}; + +type Res = Result; + +/// How a scalar is seen by the plan: at load, its declared range; at run time, its +/// value. +#[derive(Clone, Copy)] +enum Mode<'a> { + Load, + Run(&'a [i64]), +} + +/// The sizes `(H, W)` of every tensor, indexed by tensor. +pub type Sizes = Vec<(u64, u64)>; + +#[derive(Clone, Copy)] +enum Fail { + Big, + Shape, +} + +fn mul(a: u64, b: u64) -> Result { + a.checked_mul(b).ok_or(Fail::Big) +} +fn add(a: u64, b: u64) -> Result { + a.checked_add(b).ok_or(Fail::Big) +} +fn capped(v: u64) -> Result { + if v > CAP { Err(Fail::Big) } else { Ok(v) } +} + +/// One operator's output sizes from its inputs' sizes. +fn op_sizes(g: &Graph, op: &crate::graph::Op, hw: &[(u64, u64)], mode: Mode) -> Result, Fail> { + let (h, w) = hw[op.ins[0] as usize]; + let ch = |t: u32| g.tensors[t as usize].channels as u64; + let same = |o: (u64, u64)| o.0 == h && o.1 == w; + let shape = Err(Fail::Shape); + Ok(match (&op.p, op.code) { + (Params::Conv { kh, kw, sh, sw, ph, pw, .. }, _) => { + let hp = capped(add(h, mul(2, *ph as u64)?)?)?; + let wp = capped(add(w, mul(2, *pw as u64)?)?)?; + if hp < *kh as u64 || wp < *kw as u64 { + return shape; + } + vec![((hp - *kh as u64) / *sh as u64 + 1, (wp - *kw as u64) / *sw as u64 + 1)] + } + (Params::ConvT { cout, kh, kw, sh, sw, ph, pw, oph, opw, .. }, _) => { + let uh = capped(add(add(mul(h - 1, *sh as u64)?, *kh as u64)?, *oph as u64)?)?; + let uw = capped(add(add(mul(w - 1, *sw as u64)?, *kw as u64)?, *opw as u64)?)?; + capped(mul(mul(*cout as u64, uh)?, uw)?)?; + let (ch2, cw2) = (2 * *ph as u64, 2 * *pw as u64); + if uh <= ch2 || uw <= cw2 { + return shape; + } + vec![(uh - ch2, uw - cw2)] + } + (_, ADD) | (_, MUL) => { + if !same(hw[op.ins[1] as usize]) { + return shape; + } + vec![(h, w)] + } + (_, CONCAT) => { + if !op.ins.iter().all(|&t| same(hw[t as usize])) { + return shape; + } + vec![(h, w)] + } + (Params::Shuffle { r }, PIXEL_SHUFFLE) => { + let r = *r as u64; + vec![(capped(mul(h, r)?)?, capped(mul(w, r)?)?)] + } + (Params::Shuffle { r }, _) => { + let r = *r as u64; + if h % r != 0 || w % r != 0 { + return shape; + } + vec![(h / r, w / r)] + } + (Params::PadRep { m }, _) => { + let m = *m as u64; + vec![(capped(mul(h.div_ceil(m), m)?)?, capped(mul(w.div_ceil(m), m)?)?)] + } + (_, CROP_TO) => { + let (rh, rw) = hw[op.ins[1] as usize]; + if rh > h || rw > w { + return shape; + } + vec![(rh, rw)] + } + (Params::Crop { y0, x0, h: ch_, w: cw_ }, _) => { + let side = |start: &Operand, len: &Operand, n: u64| -> Result { + match mode { + Mode::Run(sv) => { + let v = |o: &Operand| -> i128 { + match *o { + Operand::Const(c) => c as i128, + Operand::Scalar(s) => sv[s as usize] as i128, + } + }; + let (s0, l) = (v(start), v(len)); + if s0 < 0 || l < 1 || s0 + l > n as i128 { + return Err(Fail::Shape); + } + Ok(l as u64) + } + Mode::Load => { + // The output is planned on the largest length the scalar's range + // allows within the input, from the smallest start. + let s0 = match *start { + Operand::Const(c) => c as i128, + Operand::Scalar(_) => 0, + }; + let l = match *len { + Operand::Const(c) => c as i128, + Operand::Scalar(s) => (g.scalars[s as usize].hi as i128).min(n as i128 - s0), + }; + if l < 1 || s0 + l > n as i128 { + return Err(Fail::Shape); + } + Ok(l as u64) + } + } + }; + vec![(side(y0, ch_, h)?, side(x0, cw_, w)?)] + } + (_, SUBPOS_SPLIT) => { + if h % 2 != 0 || w % 2 != 0 { + return shape; + } + vec![(h / 2, w / 2); 4] + } + (_, SUBPOS_MERGE) => { + if !op.ins.iter().all(|&t| same(hw[t as usize])) { + return shape; + } + vec![(capped(mul(h, 2)?)?, capped(mul(w, 2)?)?)] + } + (Params::Gram { groups, .. }, _) => { + if !same(hw[op.ins[1] as usize]) { + return shape; + } + vec![(1, ch(op.ins[0]) / *groups as u64)] + } + (Params::Apply { groups, .. }, _) => { + let d = ch(op.ins[0]) / *groups as u64; + if (h, w) != (1, d) { + return shape; + } + vec![hw[op.ins[1] as usize]] + } + // Every other operator keeps its first input's sizes. + _ => vec![(h, w)], + }) +} + +/// Walk the operators on `hw` (the inputs' sizes filled in), filling every output. +fn walk(g: &Graph, hw: &mut Sizes, mode: Mode) -> Res<()> { + let shape_code = match mode { + Mode::Load => Code::ModelMismatch, + Mode::Run(_) => Code::GeometryMismatch, + }; + for (i, op) in g.ops.iter().enumerate() { + let at = match mode { + Mode::Load => Site::Load(7), + Mode::Run(_) => Site::Op(i as u32), + }; + let outs = op_sizes(g, op, hw, mode).map_err(|f| match f { + Fail::Big => Refusal::new(Code::TooLarge, at), + Fail::Shape => Refusal::new(shape_code, at), + })?; + for (&t, &(oh, ow)) in op.outs.iter().zip(&outs) { + let n = (g.tensors[t as usize].channels as u64).checked_mul(oh).and_then(|v| v.checked_mul(ow)); + if n.is_none_or(|n| n > g.max_elems as u64) { + return Err(Refusal::new(Code::TooLarge, at)); + } + hw[t as usize] = (oh, ow); + } + } + Ok(()) +} + +/// Whether the graph has an operator that reduces over a picture-sized length. +fn reduces(g: &Graph) -> bool { + g.ops.iter().any(|o| matches!(o.code, GRAM | L2NORM | SOFTMAX)) +} + +/// Load step 7. Channel counts were checked with the graph rules (step 6). When the +/// inputs declare their sizes, every shape is planned on `max_h` and `max_w`. +pub fn load_plan(g: &Graph) -> Res> { + let sized = g.inputs[0].max_h != 0; + if !sized { + if reduces(g) { + return Err(at_load(Code::ModelMismatch, 7)); + } + return Ok(None); + } + let mut hw: Sizes = vec![(0, 0); g.tensors.len()]; + for i in &g.inputs { + let c = g.tensors[i.tensor as usize].channels as u64; + let n = c.checked_mul(i.max_h as u64).and_then(|v| v.checked_mul(i.max_w as u64)); + if n.is_none_or(|n| n > g.max_elems as u64) { + return Err(at_load(Code::TooLarge, 7)); + } + hw[i.tensor as usize] = (i.max_h as u64, i.max_w as u64); + } + walk(g, &mut hw, Mode::Load)?; + Ok(Some(hw)) +} + +/// Run steps 1 to 3 of §4 for one decode: every input's channel count and size +/// (`input_shapes[i]` is input `i`'s `(C, H, W)`, state inputs included), every +/// scalar against its range, then the run-time plan. Returns every tensor's sizes. +pub fn run_plan(g: &Graph, input_shapes: &[(u64, u64, u64)], scalars: &[i64]) -> Res { + if input_shapes.len() != g.inputs.len() { + return Err(Refusal::new(Code::ModelMismatch, Site::Input(input_shapes.len() as u32))); + } + let mut hw: Sizes = vec![(0, 0); g.tensors.len()]; + for (k, (i, &(c, h, w))) in g.inputs.iter().zip(input_shapes).enumerate() { + let at = Site::Input(k as u32); + if c != g.tensors[i.tensor as usize].channels as u64 || h == 0 || w == 0 { + return Err(Refusal::new(Code::ModelMismatch, at)); + } + if i.max_h != 0 && (h > i.max_h as u64 || w > i.max_w as u64) { + return Err(Refusal::new(Code::TooLarge, at)); + } + let n = c.checked_mul(h).and_then(|v| v.checked_mul(w)); + if n.is_none_or(|n| n > g.max_elems as u64) { + return Err(Refusal::new(Code::TooLarge, at)); + } + hw[i.tensor as usize] = (h, w); + } + if scalars.len() != g.scalars.len() { + return Err(Refusal::new(Code::ModelMismatch, Site::Scalar(scalars.len() as u32))); + } + for (k, (s, &v)) in g.scalars.iter().zip(scalars).enumerate() { + if v < s.lo || v > s.hi { + return Err(Refusal::new(Code::FieldRange, Site::Scalar(k as u32))); + } + } + walk(g, &mut hw, Mode::Run(scalars))?; + Ok(hw) +} diff --git a/wai/wai-ops/src/sha256.rs b/wai/wai-ops/src/sha256.rs new file mode 100644 index 000000000..1663ca0ae --- /dev/null +++ b/wai/wai-ops/src/sha256.rs @@ -0,0 +1,78 @@ +//! SHA-256 (FIPS 180-4): a graph's identity (§10.5), a set's digest (SPEC §3.1). + +use alloc::vec::Vec; + +const K: [u32; 64] = [ + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2, +]; + +/// The SHA-256 of `data`. +pub fn sha256(data: &[u8]) -> [u8; 32] { + let mut h: [u32; 8] = [ + 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19, + ]; + let mut m: Vec = Vec::with_capacity(data.len() + 72); + m.extend_from_slice(data); + m.push(0x80); + while m.len() % 64 != 56 { + m.push(0); + } + m.extend_from_slice(&((data.len() as u64).wrapping_mul(8)).to_be_bytes()); + for block in m.chunks_exact(64) { + let mut w = [0u32; 64]; + for i in 0..16 { + w[i] = u32::from_be_bytes([block[4 * i], block[4 * i + 1], block[4 * i + 2], block[4 * i + 3]]); + } + for i in 16..64 { + let s0 = w[i - 15].rotate_right(7) ^ w[i - 15].rotate_right(18) ^ (w[i - 15] >> 3); + let s1 = w[i - 2].rotate_right(17) ^ w[i - 2].rotate_right(19) ^ (w[i - 2] >> 10); + w[i] = w[i - 16].wrapping_add(s0).wrapping_add(w[i - 7]).wrapping_add(s1); + } + let [mut a, mut b, mut c, mut d, mut e, mut f, mut g, mut hh] = h; + for i in 0..64 { + let s1 = e.rotate_right(6) ^ e.rotate_right(11) ^ e.rotate_right(25); + let ch = (e & f) ^ (!e & g); + let t1 = hh.wrapping_add(s1).wrapping_add(ch).wrapping_add(K[i]).wrapping_add(w[i]); + let s0 = a.rotate_right(2) ^ a.rotate_right(13) ^ a.rotate_right(22); + let maj = (a & b) ^ (a & c) ^ (b & c); + let t2 = s0.wrapping_add(maj); + hh = g; + g = f; + f = e; + e = d.wrapping_add(t1); + d = c; + c = b; + b = a; + a = t1.wrapping_add(t2); + } + for (x, v) in h.iter_mut().zip([a, b, c, d, e, f, g, hh]) { + *x = x.wrapping_add(v); + } + } + let mut out = [0u8; 32]; + for (i, v) in h.iter().enumerate() { + out[4 * i..4 * i + 4].copy_from_slice(&v.to_be_bytes()); + } + out +} + +#[cfg(test)] +mod tests { + use super::sha256; + use crate::json::hex; + + #[test] + fn known_digests() { + assert_eq!(hex(&sha256(b"")), "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"); + assert_eq!(hex(&sha256(b"abc")), "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"); + let long = [b'a'; 1000]; + assert_eq!(hex(&sha256(&long)), "41edece42d63e8d9bf515a9ba6932e1c20cbc9f5a5d134645adb5db1b9737ea3"); + } +} diff --git a/wai/wai-ops/src/stage/mans.rs b/wai/wai-ops/src/stage/mans.rs new file mode 100644 index 000000000..6e9daf69c --- /dev/null +++ b/wai/wai-ops/src/stage/mans.rs @@ -0,0 +1,305 @@ +//! E8 `mans_decode` (§5E): a two-state masked table-ANS decode over a backward +//! 64-bit bit window. Every refusal during a decode is `stream_exhausted`; a table +//! that breaks its load check is `model_mismatch`, before any symbol. + +use alloc::vec; +use alloc::vec::Vec; + +use crate::code::Code; +use crate::stage::rans64::StageRefusal; + +/// The window and the two states. +struct Win { + m: Vec, + p: usize, + h: u64, + b: u32, + s: [u8; 2], + /// The index of the last position whose `in` step was reached. + pos: i64, +} + +type R = Result; + +impl Win { + fn le64(&self, i: usize) -> u64 { + let mut b = [0u8; 8]; + b.copy_from_slice(&self.m[i..i + 8]); + u64::from_le_bytes(b) + } + fn init(stream: &[u8]) -> R { + let mut m = vec![0u8; 8]; + m.extend_from_slice(stream); + let mut w = Win { m, p: stream.len(), h: 0, b: 0, s: [0, 0], pos: 0 }; + w.h = w.le64(w.p); + if w.h == 0 { + return Err(()); + } + w.b = 63 - w.h.leading_zeros(); + w.h -= 1u64 << w.b; + w.s[0] = w.read(8)? as u8; + w.s[1] = w.read(8)? as u8; + w.flush()?; + Ok(w) + } + fn read(&mut self, k: u32) -> R { + if k > self.b { + return Err(()); + } + self.b -= k; + let r = self.h >> self.b; + self.h -= r << self.b; + Ok(r) + } + fn flush(&mut self) -> R<()> { + let d = (7 ^ (self.b / 8)) as usize; + if d > self.p { + return Err(()); + } + self.p -= d; + let keep = 56 + (self.b % 8); + self.h = self.le64(self.p) & ((1u64 << keep) - 1); + self.b = keep; + Ok(()) + } + /// One transition: `t` from the state's table entry; the new state and the low bits. + fn step(&mut self, which: usize, t: u32) -> R<()> { + let r = self.read(t >> 24)?; + self.s[which] = (((t >> 16) as u64 | r) % 256) as u8; + Ok(()) + } +} + +fn wrap16(v: i64) -> i64 { + (v + 32768).rem_euclid(65536) - 32768 +} + +/// The `sgm` tables built from the rows `pmf` (§5E E8, *Building the latent tables*): +/// 256 entries of 32 bits per row. `None` when a row breaks the load checks: every row +/// of one width `w ≥ 1`, non-negative, summing to exactly 256. +pub fn build_latent_tables(pmf: &[Vec]) -> Option> { + let w = pmf.first()?.len(); + if w == 0 { + return None; + } + let mut out = Vec::with_capacity(pmf.len()); + for row in pmf { + if row.len() != w || row.iter().any(|&p| p < 0) || row.iter().sum::() != 256 { + return None; + } + let mut c = vec![0i64; w + 1]; + for k in 0..w { + c[k + 1] = c[k] + row[k]; + } + let f = |k: usize| c[k] - c[k] / 2; + let g = |k: usize| c[k] / 2 + 128; + let sym = |k: usize| -> i64 { if k % 2 == 0 { (k / 2) as i64 } else { -(((k + 1) / 2) as i64) } }; + let mut symbols = [0i64; 256]; + let mut next = [0i64; 256]; + let mut k = 0; + while c[k] < 256 { + for u in f(k)..f(k + 1) { + symbols[u as usize] = sym(k); + next[u as usize] = row[k] + (u - f(k)); + } + for u in g(k)..g(k + 1) { + symbols[u as usize] = sym(k); + next[u as usize] = row[k] + (f(k + 1) - f(k)) + (u - g(k)); + } + k += 1; + } + let mut t = [0u32; 256]; + for u in 0..256 { + // Every slot is written and next ∈ [1, 511], so nb ≤ 8; the bound only keeps + // the loop total. + let mut nb = 0u32; + while nb < 9 && next[u] << nb < 256 { + nb += 1; + } + let base = ((next[u] << nb) ^ 256) as u32; + t[u] = (nb << 24) | (base << 16) | (symbols[u].rem_euclid(65536) as u32); + } + out.push(t); + } + Some(out) +} + +/// One `sgm` span: the masked positions and their distributions. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Span { + pub mask: Vec, + pub sigma: Vec, +} + +/// The latent decode (`sgm`): `pmf` (the rows), `bounds` (`B_y`, each in `[0, 255]`), +/// and the spans, decoded in order from one window. Returns one array per span. +pub fn decode_sgm(stream: &[u8], pmf: &[Vec], bounds: &[i64], spans: &[Span]) -> Result>, StageRefusal> { + let before = StageRefusal { code: Code::ModelMismatch, at: -1 }; + let tables = build_latent_tables(pmf).ok_or(before)?; + if bounds.iter().any(|&b| !(0..=255).contains(&b)) { + return Err(before); + } + let nd = tables.len().min(bounds.len()); + for s in spans { + if s.mask.len() != s.sigma.len() || s.sigma.iter().any(|&g| g >= nd) { + return Err(before); + } + } + let mut w = Win::init(stream).map_err(|_| StageRefusal { code: Code::StreamExhausted, at: 0 })?; + let mut out = Vec::with_capacity(spans.len()); + let mut base: i64 = 0; + for s in spans { + let r = sgm_span(&mut w, &tables, bounds, s, base); + match r { + Ok(v) => out.push(v), + Err(()) => return Err(StageRefusal { code: Code::StreamExhausted, at: w.pos }), + } + base += s.mask.len() as i64; + } + Ok(out) +} + +fn sgm_span(w: &mut Win, t: &[[u32; 256]], bounds: &[i64], s: &Span, base: i64) -> R> { + let n = s.mask.len(); + let mut sym = vec![0i64; n]; + let inb = |w: &mut Win, which: usize, i: usize, sym: &mut [i64]| -> R<()> { + w.pos = base + i as i64; + if !s.mask[i] { + return Ok(()); + } + let e = t[s.sigma[i]][w.s[which] as usize]; + w.step(which, e)?; + sym[i] = wrap16((e % 65536) as i64); + Ok(()) + }; + let outb = |w: &mut Win, i: usize, sym: &mut [i64]| -> R<()> { + if !s.mask[i] { + return Ok(()); + } + let beta = bounds[s.sigma[i]]; + if sym[i] + beta == 0 { + let f = w.read(1)?; + let v = w.read(if f == 1 { 3 } else { 16 })? as i64; + sym[i] = if v % 2 == 0 { wrap16(v / 2 + beta) } else { wrap16(-(v / 2) - beta) }; + w.flush()?; + } + Ok(()) + }; + let mut i = 0; + while i + 3 < n { + inb(w, 0, i, &mut sym)?; + inb(w, 1, i + 1, &mut sym)?; + inb(w, 0, i + 2, &mut sym)?; + inb(w, 1, i + 3, &mut sym)?; + w.flush()?; + for k in 0..4 { + outb(w, i + k, &mut sym)?; + } + i += 4; + } + if n % 4 >= 2 { + inb(w, 0, i, &mut sym)?; + outb(w, i, &mut sym)?; + inb(w, 1, i + 1, &mut sym)?; + outb(w, i + 1, &mut sym)?; + i += 2; + w.flush()?; + } + if n % 2 == 1 { + inb(w, 0, i, &mut sym)?; + outb(w, i, &mut sym)?; + w.flush()?; + } + Ok(sym) +} + +/// The preprocessing table `Zp[1..=511]` (§5E E8, *Hyper-latent decode*). +fn zp() -> [u32; 512] { + let mut z = [0u32; 512]; + let mut nb = 0u32; + for i in (1..512u32).rev() { + if (i << nb) < 256 { + nb += 1; + } + z[i as usize] = ((i << nb) ^ 256) + 256 * nb; + } + z +} + +/// The hyper-latent decode (`fac`): `rows`, each 63 cumulative counts, and +/// `lengths`, the symbols of each row. Returns one array per row. +pub fn decode_fac(stream: &[u8], rows: &[Vec], lengths: &[usize]) -> Result>, StageRefusal> { + let before = StageRefusal { code: Code::ModelMismatch, at: -1 }; + if rows.len() != lengths.len() { + return Err(before); + } + for r in rows { + if r.len() != 63 || r[0] < 0 || r[62] > 255 || r.windows(2).any(|p| p[0] > p[1]) { + return Err(before); + } + } + let z = zp(); + let mut w = Win::init(stream).map_err(|_| StageRefusal { code: Code::StreamExhausted, at: 0 })?; + let mut tz = [0u32; 256]; + let mut out = Vec::with_capacity(rows.len()); + let mut base: i64 = 0; + for (r, &n) in rows.iter().zip(lengths) { + let mut prev = 0i64; + for (a, &ca) in r.iter().enumerate() { + let k = ca - prev; + for j in prev..ca { + tz[j as usize] = (z[(k + j - prev) as usize] << 16) + a as u32; + } + prev = ca; + } + tz[255] = (z[1] << 16) + 63; + match fac_row(&mut w, &tz, n, base) { + Ok(v) => out.push(v), + Err(()) => return Err(StageRefusal { code: Code::StreamExhausted, at: w.pos }), + } + base += n as i64; + } + Ok(out) +} + +fn fac_row(w: &mut Win, tz: &[u32; 256], n: usize, base: i64) -> R> { + let mut sym = vec![0i64; n]; + let inb = |w: &mut Win, which: usize, i: usize, sym: &mut [i64]| -> R<()> { + w.pos = base + i as i64; + let e = tz[w.s[which] as usize]; + w.step(which, e)?; + sym[i] = (e % 256) as i64; + Ok(()) + }; + let outb = |w: &mut Win, i: usize, sym: &mut [i64]| -> R<()> { + if sym[i] == 63 { + sym[i] = w.read(6)? as i64; + } + Ok(()) + }; + let mut i = 0; + while i + 3 < n { + inb(w, 0, i, &mut sym)?; + inb(w, 1, i + 1, &mut sym)?; + inb(w, 0, i + 2, &mut sym)?; + inb(w, 1, i + 3, &mut sym)?; + for k in 0..4 { + outb(w, i + k, &mut sym)?; + } + w.flush()?; + i += 4; + } + if n % 4 >= 2 { + inb(w, 0, i, &mut sym)?; + outb(w, i, &mut sym)?; + inb(w, 1, i + 1, &mut sym)?; + outb(w, i + 1, &mut sym)?; + i += 2; + } + if n % 2 == 1 { + inb(w, 0, i, &mut sym)?; + outb(w, i, &mut sym)?; + } + w.flush()?; + Ok(sym) +} diff --git a/wai/wai-ops/src/stage/mod.rs b/wai/wai-ops/src/stage/mod.rs new file mode 100644 index 000000000..d0a56149b --- /dev/null +++ b/wai/wai-ops/src/stage/mod.rs @@ -0,0 +1,253 @@ +//! The stage operators E1–E13 (§5E). They run in a capability's driver, outside any +//! graph, at the widths §5E lists; here every value is formed in `i128` or narrower +//! where it provably fits. + +use alloc::vec; +use alloc::vec::Vec; + +use crate::code::Code; +use crate::graph::Round; +use crate::interp::{Tensor, round}; + +pub mod mans; +pub mod rans64; + +pub use rans64::StageRefusal; + +/// E2 `dequantize(sym, f, base)`: `sym·2^f + base`, refused (`field_range`) when `f` +/// is past 62 or the value does not fit `i64`. +pub fn dequantize(sym: i64, f: u32, base: i64) -> Result { + if f > 62 { + return Err(Code::FieldRange); + } + i64::try_from(((sym as i128) << f) + base as i128).map_err(|_| Code::FieldRange) +} + +/// E3 `bucket`, rule `ceil`: `N ≥ 1` edges `e_0 … e_{N−1}`. +pub fn bucket_ceil(sigma: i64, edges: &[i64]) -> Option { + let n = edges.len(); + if n == 0 { + return None; + } + let s = sigma.max(edges[0]); + Some((n - 1) - edges[..n - 1].iter().filter(|&&e| s <= e).count()) +} + +/// E3 `bucket`, rule `floor`: `N − 1 ≥ 1` edges `e_1 … e_{N−1}`, non-decreasing. +pub fn bucket_floor(sigma: i64, edges: &[i64]) -> Option { + if edges.is_empty() || edges.windows(2).any(|p| p[0] > p[1]) { + return None; + } + Some(edges.iter().filter(|&&e| e <= sigma).count()) +} + +/// E4 `coded(v, thr)`. +pub fn coded(v: i64, thr: i64) -> bool { + v > thr +} + +/// E5 `scale_index(v, s, n) = clamp(R_half_up(v, s), 0, n − 1)`. +pub fn scale_index(v: i64, s: u32, n: i64) -> Option { + if n < 1 || s > 127 { + return None; + } + let r = round(v as i128, s, Round::HalfUp)?; + Some(r.clamp(0, (n - 1) as i128) as i64) +} + +/// E6 `block_stat(x; b, s, lo, hi)`. +pub fn block_stat(x: &Tensor, b: u32, s: u32, lo: i64, hi: i64) -> Option { + if b == 0 || s > 127 || lo > hi { + return None; + } + let (c, h, w, b) = (x.c as usize, x.h as usize, x.w as usize, b as usize); + let mut d = vec![0i64; c * h * w]; + for cc in 0..c { + for by in (0..h).step_by(b) { + for bx in (0..w).step_by(b) { + let mut sum: i128 = 0; + for y in by..(by + b).min(h) { + for xx in bx..(bx + b).min(w) { + sum += x.data[(cc * h + y) * w + xx] as i128; + } + } + let v = round(sum, s, Round::HalfUp)?.clamp(lo as i128, hi as i128) as i64; + for y in by..(by + b).min(h) { + for xx in bx..(bx + b).min(w) { + d[(cc * h + y) * w + xx] = v; + } + } + } + } + } + Some(Tensor::new(x.c, x.h, x.w, d)) +} + +/// E7 `band_lookup(v, e, table, row)`: `table[row][#{k : v ≥ e_k}]`. +pub fn band_lookup(v: i64, edges: &[i64], table: &[Vec], row: usize) -> Option { + let r = table.get(row)?; + if r.len() != edges.len() + 1 { + return None; + } + Some(r[edges.iter().filter(|&&e| v >= e).count()]) +} + +/// E9 `residual_step(pred, r, q, lo, hi) = clamp(pred + r·q, lo, hi)`, for `lo < hi`, +/// `pred ∈ [lo, hi]`, `q ∈ [1, 65535]`, `r` fitting `i32`. +pub fn residual_step(pred: i64, r: i64, q: i64, lo: i64, hi: i64) -> Option { + if lo >= hi || pred < lo || pred > hi || !(1..=65535).contains(&q) || r < i32::MIN as i64 || r > i32::MAX as i64 { + return None; + } + Some(((pred as i128) + (r as i128) * (q as i128)).clamp(lo as i128, hi as i128) as i64) +} + +/// E9's 32-bit form: `clamp(pred + clamp(r, −R, R)·q, lo, hi)` with +/// `R = ⌊(hi − lo)/q⌋ + 1`, every value in `i32` when `hi − lo ≤ 65535`. +pub fn residual_step_i32(pred: i32, r: i32, q: i32, lo: i32, hi: i32) -> i32 { + let big_r = (hi - lo) / q + 1; + (pred + r.clamp(-big_r, big_r) * q).clamp(lo, hi) +} + +/// E10 `mc_predict` (integer-payloads §3) for one sample: `frame` is the previous +/// decoded frame `[3, h, w]`, `(y, x)` the pixel, `c` the channel, `(dy, dx)` its +/// vector in units of `1/precision` pel. +#[allow(clippy::too_many_arguments)] +pub fn mc_predict(frame: &Tensor, y: i64, x: i64, c: usize, dy: i64, dx: i64, precision: u32) -> Option { + let (h, w) = (frame.h as i64, frame.w as i64); + if c >= frame.c as usize || !(0..h).contains(&y) || !(0..w).contains(&x) { + return None; + } + let p = |yy: i64, xx: i64| frame.data[(c * frame.h as usize + yy.clamp(0, h - 1) as usize) * frame.w as usize + xx.clamp(0, w - 1) as usize] as i64; + match precision { + 1 => Some(p(y + dy, x + dx)), + 2 => { + let (iy, fy, ix, fx) = (y + (dy >> 1), dy & 1, x + (dx >> 1), dx & 1); + Some(match (fy, fx) { + (0, 0) => p(iy, ix), + (0, _) => (p(iy, ix) + p(iy, ix + 1) + 1) >> 1, + (_, 0) => (p(iy, ix) + p(iy + 1, ix) + 1) >> 1, + _ => (p(iy, ix) + p(iy, ix + 1) + p(iy + 1, ix) + p(iy + 1, ix + 1) + 2) >> 2, + }) + } + _ => None, + } +} + +/// E11 `up2_predict` (staged-delivery A.4, `Up2`): `prev` is `[c, ⌈d0/2⌉, ⌈d1/2⌉]`; +/// the prediction is `[c, d0, d1]`. +pub fn up2_predict(prev: &Tensor, d0: u32, d1: u32) -> Option { + let (hp, wp) = (d0.div_ceil(2), d1.div_ceil(2)); + if d0 == 0 || d1 == 0 || prev.h != hp || prev.w != wp { + return None; + } + let (c, hp, wp) = (prev.c as usize, hp as usize, wp as usize); + let p = |cc: usize, yy: usize, xx: usize| prev.data[(cc * hp + yy.min(hp - 1)) * wp + xx.min(wp - 1)] as i64; + let mut d = Vec::with_capacity(c * d0 as usize * d1 as usize); + for cc in 0..c { + for y in 0..d0 as usize { + for x in 0..d1 as usize { + let (iy, fy, ix, fx) = (y >> 1, y & 1, x >> 1, x & 1); + d.push(match (fy, fx) { + (0, 0) => p(cc, iy, ix), + (0, _) => (p(cc, iy, ix) + p(cc, iy, ix + 1) + 1) >> 1, + (_, 0) => (p(cc, iy, ix) + p(cc, iy + 1, ix) + 1) >> 1, + _ => (p(cc, iy, ix) + p(cc, iy, ix + 1) + p(cc, iy + 1, ix) + p(cc, iy + 1, ix + 1) + 2) >> 2, + }); + } + } + } + Some(Tensor::new(prev.c, d0, d1, d)) +} + +/// `rdiv(n, d)` (E12): 0 for `d < 1`, else `sgn(n)·⌊(2|n| + d) / 2d⌋`. +pub fn rdiv(n: i128, d: i128) -> i128 { + if d < 1 { + return 0; + } + n.signum() * ((2 * n.abs() + d) / (2 * d)) +} + +/// E12 `rate_predict` (staged-delivery A.4, `Rate`): `prev` is `[c, 1, n′]`, `n′` +/// samples of `c` channels; the prediction is `[c, 1, d0]`, with +/// `⌊n′·rate_num/rate_den⌋ = d0`. +pub fn rate_predict(prev: &Tensor, rate_num: u32, rate_den: u32, d0: u32) -> Option { + let n = prev.w as u64; + if prev.h != 1 || rate_num == 0 || rate_den == 0 || n * rate_num as u64 / rate_den as u64 != d0 as u64 { + return None; + } + let (num, den) = (rate_num as i128, rate_den as i128); + let mut d = Vec::with_capacity(prev.c as usize * d0 as usize); + for cc in 0..prev.c as usize { + let row = &prev.data[cc * n as usize..(cc + 1) * n as usize]; + for i in 0..d0 as i128 { + let s = i * den; + let lo = s / num; + let rho = s % num; + let hi = (lo + 1).min(n as i128 - 1); + let (a, b) = (row[lo as usize] as i128, row[hi as usize] as i128); + d.push(rdiv(a * num + (b - a) * rho, num) as i64); + } + } + Some(Tensor::new(prev.c, 1, d0, d)) +} + +/// E13 `coding_order`: the CHW indices of `[c, h, w]` in `raster` order, or those of +/// one `checkerboard` pass (`anchor`: `(row + col)` even), each in raster order. +pub fn coding_order(c: u32, h: u32, w: u32, checkerboard: Option) -> Vec { + let mut v = Vec::new(); + for cc in 0..c as u64 { + for y in 0..h as u64 { + for x in 0..w as u64 { + let keep = match checkerboard { + None => true, + Some(anchor) => ((y + x) % 2 == 0) == anchor, + }; + if keep { + v.push((cc * h as u64 + y) * w as u64 + x); + } + } + } + } + v +} + +/// A stage refusal before any element, for a table or operand that breaks a load +/// check. +pub fn before(code: Code) -> StageRefusal { + StageRefusal { code, at: -1 } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn residual_identity_holds() { + for &(lo, hi) in &[(0i32, 255i32), (-32768, 32767)] { + for &q in &[1i32, 2, 3, 255, 256, 1000, 65535] { + let big_r = (hi - lo) / q + 1; + for &r in &[0i32, 1, -1, big_r, -big_r, big_r + 1, -big_r - 1, i32::MAX, i32::MIN, 12345, -54321] { + for &pred in &[lo, hi, (lo + hi) / 2] { + let a = residual_step(pred as i64, r as i64, q as i64, lo as i64, hi as i64).unwrap(); + assert_eq!(a, residual_step_i32(pred, r, q, lo, hi) as i64); + } + } + } + } + } + + #[test] + fn buckets() { + assert_eq!(bucket_ceil(5, &[1, 5, 9]), Some(1)); + assert_eq!(bucket_ceil(-100, &[1, 5, 9]), Some(0)); + assert_eq!(bucket_ceil(100, &[1, 5, 9]), Some(2)); + assert_eq!(bucket_floor(5, &[1, 5, 9]), Some(2)); + assert_eq!(bucket_floor(4, &[1, 5, 9]), Some(1)); + assert_eq!(bucket_floor(4, &[5, 1]), None); + assert_eq!(rdiv(-3, 2), -2); + assert_eq!(rdiv(3, 2), 2); + assert_eq!(rdiv(1, 2), 1); + assert_eq!(rdiv(-1, 2), -1); + assert_eq!(rdiv(5, 0), 0); + } +} diff --git a/wai/wai-ops/src/stage/rans64.rs b/wai/wai-ops/src/stage/rans64.rs new file mode 100644 index 000000000..5a9cc2499 --- /dev/null +++ b/wai/wai-ops/src/stage/rans64.rs @@ -0,0 +1,220 @@ +//! E1 `rans64_decode` (§5E): integer-payloads §2's decode, with the table, escape and +//! end modes a capability fixes. + +use alloc::vec::Vec; + +use crate::code::{Code, Refusal, Site}; + +/// The table rule. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum TableRule { + /// `3 ≤ n ≤ 4097`. + T4097, + /// `2 ≤ n ≤ 65537`. + T2, +} + +/// The escape rule. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Escape { + Lenient, + /// `strict(lo, hi)`, both fitting `i32`. + Strict { lo: i32, hi: i32 }, +} + +/// The end rule. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum End { + Canonical, + FinalOnly, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct Modes { + pub table: TableRule, + pub escape: Escape, + pub end: End, +} + +/// A table: its cumulative counts `cdf[0..n)` and its offset `o`. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Table { + pub cdf: Vec, + pub offset: i64, +} + +/// Whether `cdf` is a table under `rule`: its length, `cdf[0] = 0`, +/// `cdf[n − 1] = 65536`, strictly increasing. +pub fn table_ok(cdf: &[i64], rule: TableRule) -> bool { + let n = cdf.len(); + let len_ok = match rule { + TableRule::T4097 => (3..=4097).contains(&n), + TableRule::T2 => (2..=65537).contains(&n), + }; + len_ok && cdf[0] == 0 && cdf[n - 1] == 65536 && cdf.windows(2).all(|p| p[0] < p[1]) +} + +const L: u64 = 1 << 31; + +/// The decoder state of integer-payloads §2. +pub struct Rans<'a> { + words: &'a [u8], + idx: usize, + x: u64, + /// Set when a renormalisation found no word left. + ran_out: bool, +} + +impl<'a> Rans<'a> { + /// Seed from a stream of `L` bytes, `L` a multiple of 4 and at least 8. + pub fn new(words: &'a [u8]) -> Option> { + if words.len() < 8 || words.len() % 4 != 0 { + return None; + } + let w = |k: usize| u32::from_le_bytes([words[4 * k], words[4 * k + 1], words[4 * k + 2], words[4 * k + 3]]) as u64; + Some(Rans { words, idx: 2, x: (w(1) << 32) | w(0), ran_out: false }) + } + fn renorm(&mut self) { + if self.x < L { + let off = self.idx * 4; + match self.words.get(off..off + 4) { + Some(b) => { + self.x = (self.x << 32) | u32::from_le_bytes([b[0], b[1], b[2], b[3]]) as u64; + self.idx += 1; + } + None => self.ran_out = true, + } + } + } + fn bits(&mut self, n: u32) -> u64 { + let v = self.x & ((1u64 << n) - 1); + self.x >>= n; + self.renorm(); + v + } + pub fn ran_out(&self) -> bool { + self.ran_out + } + /// Every word read, and the state `2^31`. + pub fn ends_canonically(&self) -> bool { + !self.ran_out && self.x == L && self.idx * 4 == self.words.len() + } + + /// One symbol against `t`. Under `strict`, returns the refusal the symbol's own + /// checks 2–4 give (check 1, the end rule's, is the caller's). + pub fn symbol(&mut self, t: &Table, escape: Escape) -> Result { + let n = t.cdf.len(); + let cum = (self.x & 0xFFFF) as i64; + // The largest s in [0, n − 2] with cdf[s] ≤ cum. + let (mut lo, mut hi) = (0usize, n - 1); + while hi - lo > 1 { + let mid = (lo + hi) / 2; + if t.cdf[mid] <= cum { lo = mid } else { hi = mid } + } + let s = lo; + let (start, freq) = (t.cdf[s] as u64, (t.cdf[s + 1] - t.cdf[s]) as u64); + self.x = freq * (self.x >> 16) + (cum as u64) - start; + self.renorm(); + let n2 = (n - 2) as i64; + if (s as i64) < n2 { + let sym = s as i64 + t.offset; + return match escape { + Escape::Lenient => Ok(sym.clamp(i32::MIN as i64, i32::MAX as i64)), + Escape::Strict { lo, hi } => { + if sym < lo as i64 || sym > hi as i64 { Err(Code::FieldRange) } else { Ok(sym) } + } + }; + } + match escape { + Escape::Lenient => { + let mut v = self.bits(4); + let mut count = v; + let mut groups = 0; + while v == 15 && groups < 8 && !self.ran_out { + v = self.bits(4); + count += v; + groups += 1; + } + let count = count.min(8); + let mut raw: u64 = 0; + for j in 0..count { + raw |= self.bits(4) << (4 * j); + } + let value: i64 = if raw & 1 == 1 { -((raw >> 1) as i64) - 1 } else { (raw >> 1) as i64 + n2 }; + let value = value.clamp(i32::MIN as i64, i32::MAX as i64); + Ok((value + t.offset).clamp(i32::MIN as i64, i32::MAX as i64)) + } + Escape::Strict { lo, hi } => { + let count = self.bits(4); + let mut raw: u64 = 0; + let mut last = 0; + if count <= 8 { + for j in 0..count { + last = self.bits(4); + raw |= last << (4 * j); + } + } + let value: i64 = if raw & 1 == 1 { -((raw >> 1) as i64) - 1 } else { (raw >> 1) as i64 + n2 }; + let sym = value + t.offset; + if count > 8 || (count >= 1 && last == 0) { + // Check 1 (run-out under `canonical`) is the caller's and comes first. + return Err(Code::StreamNoncanonical); + } + if sym < lo as i64 || sym > hi as i64 { Err(Code::FieldRange) } else { Ok(sym) } + } + } + } +} + +/// A refusal of the decode at symbol `at` (`at` = the number of symbols for a +/// refusal after the last one, −1 for one before the first). +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct StageRefusal { + pub code: Code, + pub at: i64, +} + +impl StageRefusal { + pub fn refusal(&self) -> Refusal { + let at = if self.at < 0 { Site::Table(0) } else { Site::Symbol(self.at as u64) }; + Refusal::new(self.code, at) + } +} + +/// Decode the symbols `reads` names (each the index of the table it decodes against) +/// from `stream`, under `modes`. +pub fn decode(stream: &[u8], tables: &[Table], reads: &[usize], modes: Modes) -> Result, StageRefusal> { + let before = |code| StageRefusal { code, at: -1 }; + for t in tables { + if !table_ok(&t.cdf, modes.table) || t.offset < i32::MIN as i64 || t.offset > i32::MAX as i64 { + return Err(before(Code::ModelMismatch)); + } + } + if let Escape::Strict { lo, hi } = modes.escape + && lo > hi + { + return Err(before(Code::ModelMismatch)); + } + if reads.iter().any(|&r| r >= tables.len()) { + return Err(before(Code::ModelMismatch)); + } + let mut d = Rans::new(stream).ok_or(StageRefusal { code: Code::StreamExhausted, at: 0 })?; + let mut out = Vec::with_capacity(reads.len()); + for (i, &r) in reads.iter().enumerate() { + let at = i as i64; + let res = d.symbol(&tables[r], modes.escape); + if modes.end == End::Canonical && d.ran_out() { + return Err(StageRefusal { code: Code::StreamExhausted, at }); + } + match res { + Ok(v) => out.push(v), + Err(code) => return Err(StageRefusal { code, at }), + } + } + let end = reads.len() as i64; + match modes.end { + End::Canonical if !d.ends_canonically() => Err(StageRefusal { code: Code::StreamNoncanonical, at: end }), + End::FinalOnly if d.ran_out() => Err(StageRefusal { code: Code::StreamExhausted, at: end }), + _ => Ok(out), + } +} diff --git a/wai/wai-ops/src/vectors.rs b/wai/wai-ops/src/vectors.rs new file mode 100644 index 000000000..89eb15ca2 --- /dev/null +++ b/wai/wai-ops/src/vectors.rs @@ -0,0 +1,323 @@ +//! The vector files of §14.1, recomputed from their inputs. +//! +//! [`recompute_file`] reads a JSON Lines file, keeps every line's inputs, recomputes +//! every line's `load` and `expect` values, and writes the file again canonically. A +//! conforming implementation's file is byte-identical to the committed one; every leg +//! of CI runs this same function, natively, under WASI and under a browser engine. + +use alloc::string::{String, ToString}; +use alloc::vec; +use alloc::vec::Vec; + +use crate::code::Code; +use crate::graph; +use crate::interp::{self, Sequence, Tensor}; +use crate::json::{self, C, Value, hex, unhex}; +use crate::stage::{self, rans64, mans, StageRefusal}; + +/// Which directory a file belongs to: `vectors/` and `graphs/` share the graph +/// vector format, `stage/` has its own. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Kind { + Graph, + Stage, +} + +/// Why a line could not be recomputed: it is not a vector of its kind. +pub type Bad = String; + +fn bad(what: &str) -> Result { + Err(what.to_string()) +} + +fn dec(v: &Value) -> Result { + v.as_dec_i64().ok_or_else(|| "an integer outside i64".to_string()) +} +fn dec_u(v: &Value) -> Result { + let d = dec(v)?; + u64::try_from(d).map_err(|_| "a negative size".to_string()) +} +fn get<'a>(v: &'a Value, k: &str) -> Result<&'a Value, Bad> { + v.get(k).ok_or_else(|| alloc::format!("no member {k}")) +} +fn arr<'a>(v: &'a Value, k: &str) -> Result<&'a [Value], Bad> { + get(v, k)?.as_arr().ok_or_else(|| alloc::format!("{k} is not an array")) +} +fn decs(v: &Value, k: &str) -> Result, Bad> { + arr(v, k)?.iter().map(dec).collect() +} + +/// A tensor `{ "data": [...], "shape": [C, H, W] }`. +pub fn read_tensor(v: &Value) -> Result { + let s = arr(v, "shape")?; + if s.len() != 3 { + return bad("a shape has three dimensions"); + } + let (c, h, w) = (dec_u(&s[0])?, dec_u(&s[1])?, dec_u(&s[2])?); + let data = decs(v, "data")?; + let (c, h, w) = (u32::try_from(c).map_err(|_| "size")?, u32::try_from(h).map_err(|_| "size")?, u32::try_from(w).map_err(|_| "size")?); + Ok(Tensor::new(c, h, w, data)) +} + +pub fn tensor_c(t: &Tensor) -> C { + C::obj(vec![ + ("data", C::ints(t.data.iter().map(|&v| v as i128))), + ("shape", C::ints([t.c as i128, t.h as i128, t.w as i128])), + ]) +} + +/// Recompute one graph vector (§14.1): `load`, and every decode's `expect`. +pub fn graph_line(v: &Value) -> Result { + let hexg = get(v, "graph")?.as_str().ok_or("graph is not a string")?; + let bytes = unhex(hexg).ok_or("graph is not lowercase hexadecimal")?; + let id = get(v, "id")?.as_str().ok_or("id is not a string")?; + let profiles = arr(v, "profiles")?; + let decodes = arr(v, "decodes")?; + let loaded = graph::load(&bytes); + let load = match &loaded { + Ok(_) => C::s("ok"), + Err(r) => C::s(r.code.as_str()), + }; + let mut out = Vec::new(); + if let Ok(g) = &loaded { + let mut seq = Sequence::new(); + for d in decodes { + let inputs: Vec = arr(d, "inputs")?.iter().map(read_tensor).collect::>()?; + let scalars = decs(d, "scalars")?; + let expect = match interp::run(g, &inputs, &scalars, &mut seq) { + Ok(outs) => C::obj(vec![("outputs", C::Arr(outs.iter().map(tensor_c).collect()))]), + Err(r) => C::obj(vec![("refuse", C::s(r.code.as_str()))]), + }; + out.push(C::obj(vec![ + ("expect", expect), + ("inputs", C::Arr(inputs.iter().map(tensor_c).collect())), + ("scalars", C::ints(scalars.iter().map(|&s| s as i128))), + ])); + } + } + Ok(C::obj(vec![ + ("decodes", C::Arr(out)), + ("graph", C::Str(hex(&bytes))), + ("id", C::s(id)), + ("load", load), + ("profiles", C::Arr(profiles.iter().map(|p| C::s(p.as_str().unwrap_or("?"))).collect())), + ])) +} + +fn refused(r: StageRefusal) -> C { + C::obj(vec![("at", C::int(r.at as i128)), ("refuse", C::s(r.code.as_str()))]) +} + +fn str_of<'a>(v: &'a Value, k: &str) -> Result<&'a str, Bad> { + get(v, k)?.as_str().ok_or_else(|| alloc::format!("{k} is not a string")) +} + +/// The modes of E1 from a vector's `modes`. +pub fn rans_modes(m: &Value) -> Result { + let table = match str_of(m, "table")? { + "t4097" => rans64::TableRule::T4097, + "t2" => rans64::TableRule::T2, + _ => return bad("table rule"), + }; + let escape = match str_of(m, "escape")? { + "lenient" => rans64::Escape::Lenient, + "strict" => { + let lo = i32::try_from(dec(get(m, "lo")?)?).map_err(|_| "lo")?; + let hi = i32::try_from(dec(get(m, "hi")?)?).map_err(|_| "hi")?; + rans64::Escape::Strict { lo, hi } + } + _ => return bad("escape rule"), + }; + let end = match str_of(m, "end")? { + "canonical" => rans64::End::Canonical, + "final_only" => rans64::End::FinalOnly, + _ => return bad("end rule"), + }; + Ok(rans64::Modes { table, escape, end }) +} + +/// Compute a stage vector's `expect` from its `op`, `in` and `modes`. +pub fn stage_expect(op: &str, i: &Value, m: &Value) -> Result { + let one = |k: &str, v: C| C::obj(vec![(k, v)]); + let before = |code: Code| refused(stage::before(code)); + let at0 = |code: Code| refused(StageRefusal { code, at: 0 }); + Ok(match op { + "rans64_decode" => { + let modes = rans_modes(m)?; + let stream = unhex(str_of(i, "stream")?).ok_or("stream hex")?; + let tables: Vec = arr(i, "tables")? + .iter() + .map(|t| Ok(rans64::Table { cdf: decs(t, "cdf")?, offset: dec(get(t, "offset")?)? })) + .collect::>()?; + let reads: Vec = decs(i, "reads")?.iter().map(|&r| usize::try_from(r).unwrap_or(usize::MAX)).collect(); + match rans64::decode(&stream, &tables, &reads, modes) { + Ok(s) => one("symbols", C::ints(s.iter().map(|&v| v as i128))), + Err(r) => refused(r), + } + } + "dequantize" => { + let (f, sym, base) = (dec(get(i, "f")?)?, dec(get(i, "sym")?)?, dec(get(i, "base")?)?); + match u32::try_from(f).ok().map(|f| stage::dequantize(sym, f, base)) { + Some(Ok(v)) => one("value", C::int(v as i128)), + _ => at0(Code::FieldRange), + } + } + "bucket" => { + let sigma = dec(get(i, "sigma")?)?; + let edges = decs(i, "edges")?; + let r = match str_of(m, "bucket")? { + "ceil" => stage::bucket_ceil(sigma, &edges), + "floor" => stage::bucket_floor(sigma, &edges), + _ => return bad("bucket rule"), + }; + match r { + Some(b) => one("index", C::int(b as i128)), + None => before(Code::ModelMismatch), + } + } + "coded" => one("coded", C::Bool(stage::coded(dec(get(i, "v")?)?, dec(get(i, "thr")?)?))), + "scale_index" => { + let s = u32::try_from(dec(get(i, "s")?)?).unwrap_or(u32::MAX); + match stage::scale_index(dec(get(i, "v")?)?, s, dec(get(i, "n")?)?) { + Some(v) => one("index", C::int(v as i128)), + None => before(Code::ModelMismatch), + } + } + "block_stat" => { + let x = read_tensor(get(i, "x")?)?; + let b = u32::try_from(dec(get(i, "b")?)?).unwrap_or(0); + let s = u32::try_from(dec(get(i, "s")?)?).unwrap_or(u32::MAX); + match stage::block_stat(&x, b, s, dec(get(i, "lo")?)?, dec(get(i, "hi")?)?) { + Some(t) => one("out", tensor_c(&t)), + None => before(Code::ModelMismatch), + } + } + "band_lookup" => { + let table: Vec> = arr(i, "table")?.iter().map(|r| r.as_arr().ok_or("row").map(|r| r.iter().map(dec).collect::, _>>())).collect::, _>>()??; + let row = usize::try_from(dec(get(i, "row")?)?).unwrap_or(usize::MAX); + match stage::band_lookup(dec(get(i, "v")?)?, &decs(i, "edges")?, &table, row) { + Some(v) => one("value", C::int(v as i128)), + None => before(Code::ModelMismatch), + } + } + "mans_decode" => { + let mem = unhex(str_of(i, "memory")?).ok_or("memory hex")?; + let r = match str_of(i, "mode")? { + "sgm" => { + let pmf: Vec> = arr(i, "pmf")?.iter().map(|r| r.as_arr().ok_or("pmf").map(|r| r.iter().map(dec).collect::, _>>())).collect::, _>>()??; + let spans: Vec = arr(i, "spans")? + .iter() + .map(|s| { + let mask = arr(s, "mask")?.iter().map(|b| b.as_bool().ok_or_else(|| "mask".to_string())).collect::, _>>()?; + let sigma = decs(s, "sigma")?.iter().map(|&g| usize::try_from(g).unwrap_or(usize::MAX)).collect(); + Ok(mans::Span { mask, sigma }) + }) + .collect::>()?; + mans::decode_sgm(&mem, &pmf, &decs(i, "bounds")?, &spans) + } + "fac" => { + let rows: Vec> = arr(i, "rows")?.iter().map(|r| r.as_arr().ok_or("rows").map(|r| r.iter().map(dec).collect::, _>>())).collect::, _>>()??; + let lengths: Vec = decs(i, "lengths")?.iter().map(|&l| usize::try_from(l).unwrap_or(usize::MAX)).collect(); + mans::decode_fac(&mem, &rows, &lengths) + } + _ => return bad("mans mode"), + }; + match r { + Ok(s) => one("symbols", C::Arr(s.iter().map(|row| C::ints(row.iter().map(|&v| v as i128))).collect())), + Err(r) => refused(r), + } + } + "residual_step" => { + let g = |k| dec(get(i, k)?); + match stage::residual_step(g("pred")?, g("r")?, g("q")?, g("lo")?, g("hi")?) { + Some(v) => one("value", C::int(v as i128)), + None => before(Code::ModelMismatch), + } + } + "mc_predict" => { + let f = read_tensor(get(i, "frame")?)?; + let g = |k| dec(get(i, k)?); + let c = usize::try_from(g("c")?).unwrap_or(usize::MAX); + let p = u32::try_from(g("precision")?).unwrap_or(0); + match stage::mc_predict(&f, g("y")?, g("x")?, c, g("dy")?, g("dx")?, p) { + Some(v) => one("value", C::int(v as i128)), + None => before(Code::ModelMismatch), + } + } + "up2_predict" => { + let p = read_tensor(get(i, "prev")?)?; + let d0 = u32::try_from(dec(get(i, "d0")?)?).unwrap_or(0); + let d1 = u32::try_from(dec(get(i, "d1")?)?).unwrap_or(0); + match stage::up2_predict(&p, d0, d1) { + Some(t) => one("out", tensor_c(&t)), + None => before(Code::GeometryMismatch), + } + } + "rate_predict" => { + let p = read_tensor(get(i, "prev")?)?; + let u = |k| u32::try_from(dec(get(i, k)?)?).map_err(|_| "u32".to_string()); + match stage::rate_predict(&p, u("rate_num")?, u("rate_den")?, u("d0")?) { + Some(t) => one("out", tensor_c(&t)), + None => before(Code::GeometryMismatch), + } + } + "coding_order" => { + let s = decs(i, "shape")?; + if s.len() != 3 || s.iter().any(|&d| !(1..=u32::MAX as i64).contains(&d)) { + return bad("shape"); + } + let cb = match str_of(i, "order")? { + "raster" => None, + "checkerboard" => Some(get(i, "anchor")?.as_bool().ok_or("anchor")?), + _ => return bad("order"), + }; + one("indices", C::ints(stage::coding_order(s[0] as u32, s[1] as u32, s[2] as u32, cb).iter().map(|&v| v as i128))) + } + _ => return bad("an unknown stage operator"), + }) +} + +/// Recompute one stage vector. +pub fn stage_line(v: &Value) -> Result { + let op = str_of(v, "op")?; + let i = get(v, "in")?; + let m = get(v, "modes")?; + let id = str_of(v, "id")?; + let expect = stage_expect(op, i, m)?; + Ok(C::obj(vec![("expect", expect), ("id", C::s(id)), ("in", value_to_c(i)?), ("modes", value_to_c(m)?), ("op", C::s(op))])) +} + +/// A canonical value read back: strings, booleans, arrays, objects and null. A JSON +/// number cannot appear in a canonical file. +pub fn value_to_c(v: &Value) -> Result { + Ok(match v { + Value::Null => C::Null, + Value::Bool(b) => C::Bool(*b), + Value::Str(s) => C::s(s), + Value::Num(_) => return bad("a number in a canonical file"), + Value::Arr(a) => C::Arr(a.iter().map(value_to_c).collect::>()?), + Value::Obj(m) => C::Obj(m.iter().map(|(k, x)| Ok((k.clone(), value_to_c(x)?))).collect::>()?), + }) +} + +/// Recompute one line. +pub fn recompute_line(kind: Kind, line: &str) -> Result { + let v = json::parse(line.as_bytes()).map_err(|e| alloc::format!("JSON at byte {}", e.at))?; + let c = match kind { + Kind::Graph => graph_line(&v)?, + Kind::Stage => stage_line(&v)?, + }; + Ok(json::to_string(&c)) +} + +/// Recompute every line of a file. Every line, the last included, ends with one +/// line feed. +pub fn recompute_file(kind: Kind, text: &str) -> Result { + let mut out = String::with_capacity(text.len()); + for (n, line) in text.split_terminator('\n').enumerate() { + let r = recompute_line(kind, line).map_err(|e| alloc::format!("line {}: {e}", n + 1))?; + out.push_str(&r); + out.push('\n'); + } + Ok(out) +} diff --git a/wai/wai-ops/src/xint.rs b/wai/wai-ops/src/xint.rs new file mode 100644 index 000000000..53fc45721 --- /dev/null +++ b/wai/wai-ops/src/xint.rs @@ -0,0 +1,435 @@ +//! A 512-bit signed integer, two's complement, eight little-endian 64-bit limbs. +//! +//! The bounds pass of §8.1 saturates after every primitive operation at `±2^255`, so +//! every operand it meets lies in `[−2^255, 2^255]`; a product then lies in +//! `[−2^510, 2^510]` and a sum in `[−2^256, 2^256]`, and 512 bits hold each exactly. +//! The lowerings of §13.2 evaluate their predicates `P_ℓ` here too: every value they +//! form is below `2^255`. +//! +//! The arithmetic operations are exact while their result lies in +//! `[−2^511, 2^511 − 1]`. Every caller in this crate stays inside that range, which +//! [`I512::sat`] and the argument above guarantee; the operations themselves never +//! panic, and outside the range they wrap, which no caller relies on. + +use alloc::string::String; +use alloc::vec::Vec; +use core::cmp::Ordering; + +const N: usize = 8; + +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +pub struct I512([u64; N]); + +impl Default for I512 { + fn default() -> Self { + I512::ZERO + } +} + +impl I512 { + pub const ZERO: I512 = I512([0; N]); + pub const ONE: I512 = I512([1, 0, 0, 0, 0, 0, 0, 0]); + + pub const fn from_i128(v: i128) -> I512 { + let u = v as u128; + let e = if v < 0 { u64::MAX } else { 0 }; + I512([u as u64, (u >> 64) as u64, e, e, e, e, e, e]) + } + pub const fn from_u128(v: u128) -> I512 { + I512([v as u64, (v >> 64) as u64, 0, 0, 0, 0, 0, 0]) + } + pub const fn from_i64(v: i64) -> I512 { + I512::from_i128(v as i128) + } + pub const fn from_u64(v: u64) -> I512 { + I512::from_u128(v as u128) + } + + pub fn is_neg(&self) -> bool { + self.0[N - 1] >> 63 == 1 + } + pub fn is_zero(&self) -> bool { + self.0.iter().all(|&l| l == 0) + } + + fn not(self) -> I512 { + let mut r = self.0; + for l in &mut r { + *l = !*l; + } + I512(r) + } + + fn wadd(a: I512, b: I512) -> I512 { + let mut r = [0u64; N]; + let mut carry = 0u128; + for (i, slot) in r.iter_mut().enumerate() { + let s = a.0[i] as u128 + b.0[i] as u128 + carry; + *slot = s as u64; + carry = s >> 64; + } + I512(r) + } + + pub fn add(self, o: I512) -> I512 { + I512::wadd(self, o) + } + pub fn neg(self) -> I512 { + I512::wadd(self.not(), I512::ONE) + } + pub fn sub(self, o: I512) -> I512 { + I512::wadd(self, o.neg()) + } + pub fn abs(self) -> I512 { + if self.is_neg() { self.neg() } else { self } + } + + /// The low 512 bits of the product of two magnitudes. + fn mul_mag(a: &[u64; N], b: &[u64; N]) -> [u64; N] { + let mut r = [0u64; N]; + for i in 0..N { + if a[i] == 0 { + continue; + } + let mut carry = 0u128; + for j in 0..(N - i) { + let cur = r[i + j] as u128 + (a[i] as u128) * (b[j] as u128) + carry; + r[i + j] = cur as u64; + carry = cur >> 64; + } + } + r + } + + pub fn mul(self, o: I512) -> I512 { + let neg = self.is_neg() != o.is_neg(); + let m = I512(I512::mul_mag(&self.abs().0, &o.abs().0)); + if neg { m.neg() } else { m } + } + + /// `self · 2^k`. + pub fn shl(self, k: u32) -> I512 { + if k >= 512 { + return I512::ZERO; + } + let (w, b) = ((k / 64) as usize, k % 64); + let mut r = [0u64; N]; + for i in (w..N).rev() { + let lo = self.0[i - w]; + r[i] = if b == 0 { lo } else { (lo << b) | if i > w { self.0[i - w - 1] >> (64 - b) } else { 0 } }; + } + I512(r) + } + + /// `⌊self / 2^k⌋`: an arithmetic shift right. + pub fn shr_floor(self, k: u32) -> I512 { + let fill = if self.is_neg() { u64::MAX } else { 0 }; + if k >= 512 { + return I512([fill; N]); + } + let (w, b) = ((k / 64) as usize, k % 64); + let mut r = [fill; N]; + for (i, slot) in r.iter_mut().enumerate().take(N - w) { + let lo = self.0[i + w]; + let hi = if i + w + 1 < N { self.0[i + w + 1] } else { fill }; + *slot = if b == 0 { lo } else { (lo >> b) | (hi << (64 - b)) }; + } + I512(r) + } + + /// `2^k`, for `k ≤ 510`. + pub fn pow2(k: u32) -> I512 { + I512::ONE.shl(k) + } + + fn bit(&self, i: u32) -> bool { + (self.0[(i / 64) as usize] >> (i % 64)) & 1 == 1 + } + + /// The number of significant bits of a non-negative value (0 for 0). + fn bit_len(&self) -> u32 { + for i in (0..N).rev() { + if self.0[i] != 0 { + return 64 * i as u32 + (64 - self.0[i].leading_zeros()); + } + } + 0 + } + + /// Quotient and remainder of two non-negative values, `b > 0`. + fn divmod_mag(a: I512, b: I512) -> (I512, I512) { + let mut q = I512::ZERO; + let mut r = I512::ZERO; + let n = a.bit_len(); + for i in (0..n).rev() { + r = r.shl(1); + if a.bit(i) { + r.0[0] |= 1; + } + if r.cmp(&b) != Ordering::Less { + r = r.sub(b); + q.0[(i / 64) as usize] |= 1u64 << (i % 64); + } + } + (q, r) + } + + /// `⌊self / d⌋`, for `d > 0`. + pub fn div_floor(self, d: I512) -> I512 { + debug_assert!(!d.is_neg() && !d.is_zero()); + let (q, r) = I512::divmod_mag(self.abs(), d); + if !self.is_neg() { + q + } else if r.is_zero() { + q.neg() + } else { + q.neg().sub(I512::ONE) + } + } + + /// `trunc(self / d)`, for `d > 0`. + pub fn div_trunc(self, d: I512) -> I512 { + let (q, _) = I512::divmod_mag(self.abs(), d); + if self.is_neg() { q.neg() } else { q } + } + + /// `isqrt(self)`, for `self ≥ 0`: the largest `r ≥ 0` with `r² ≤ self`. + pub fn isqrt(self) -> I512 { + debug_assert!(!self.is_neg()); + if self.is_zero() { + return I512::ZERO; + } + let mut x = self; + let mut r = I512::ZERO; + let top = (self.bit_len() - 1) & !1; + let mut bit = I512::pow2(top); + while !bit.is_zero() { + let t = r.add(bit); + if x.cmp(&t) != Ordering::Less { + x = x.sub(t); + r = r.shr_floor(1).add(bit); + } else { + r = r.shr_floor(1); + } + bit = bit.shr_floor(2); + } + r + } + + /// `isqrt_ceil(self)`, for `self ≥ 0`: the smallest `r ≥ 0` with `r² ≥ self`. + pub fn isqrt_ceil(self) -> I512 { + let r = self.isqrt(); + if r.mul(r) == self { r } else { r.add(I512::ONE) } + } + + pub fn min(self, o: I512) -> I512 { + if self.cmp(&o) == Ordering::Greater { o } else { self } + } + pub fn max(self, o: I512) -> I512 { + if self.cmp(&o) == Ordering::Less { o } else { self } + } + + /// The value as an `i128`, if it fits. + pub fn to_i128(self) -> Option { + let lo = (self.0[0] as u128) | ((self.0[1] as u128) << 64); + let v = lo as i128; + let e = if v < 0 { u64::MAX } else { 0 }; + if self.0[2..].iter().all(|&l| l == e) { Some(v) } else { None } + } + pub fn to_i64(self) -> Option { + self.to_i128().and_then(|v| i64::try_from(v).ok()) + } + + /// Whether the value fits iN (§2): `−2^(N−1) ≤ v ≤ 2^(N−1) − 1`. + pub fn fits(self, n: u32) -> bool { + self.bits_one() <= n + } + + /// The smallest `N ≥ 1` such that the value fits iN. + pub fn bits_one(self) -> u32 { + let m = if self.is_neg() { self.not() } else { self }; + m.bit_len() + 1 + } + + /// `bits([lo, hi])` (§2). + pub fn bits(lo: I512, hi: I512) -> u32 { + lo.bits_one().max(hi.bits_one()) + } + + /// `sat(v) = clamp(v, −2^255, 2^255)` (§8.1), and whether it changed `v`. + pub fn sat(self) -> (I512, bool) { + let cap = I512::pow2(255); + if self.cmp(&cap) == Ordering::Greater { + (cap, true) + } else if self.cmp(&cap.neg()) == Ordering::Less { + (cap.neg(), true) + } else { + (self, false) + } + } + + /// Divide a non-negative value by a small divisor, returning the remainder. + fn divrem_small(&mut self, d: u64) -> u64 { + let mut rem = 0u128; + for i in (0..N).rev() { + let cur = (rem << 64) | self.0[i] as u128; + self.0[i] = (cur / d as u128) as u64; + rem = cur % d as u128; + } + rem as u64 + } + + /// The decimal form: digits, with `-` before a negative value. + pub fn to_dec(self) -> String { + let neg = self.is_neg(); + let mut m = self.abs(); + if m.is_zero() { + return String::from("0"); + } + let mut chunks: Vec = Vec::new(); + while !m.is_zero() { + chunks.push(m.divrem_small(10_000_000_000_000_000_000)); + } + let mut s = String::new(); + if neg { + s.push('-'); + } + for (i, c) in chunks.iter().rev().enumerate() { + let digits = alloc::format!("{c}"); + if i > 0 { + for _ in digits.len()..19 { + s.push('0'); + } + } + s.push_str(&digits); + } + s + } + + /// Parse `-?[0-9]+`. `None` on any other character, an empty digit string, or a + /// magnitude of `2^511` or more. + pub fn from_dec(s: &str) -> Option { + let (neg, d) = match s.strip_prefix('-') { + Some(r) => (true, r), + None => (false, s), + }; + if d.is_empty() { + return None; + } + let mut m = I512::ZERO; + let ten = I512::from_u64(10); + let limit = I512::pow2(510); + for ch in d.bytes() { + if !ch.is_ascii_digit() { + return None; + } + // m·10 + digit stays below 2^511 only if m < 2^510 / 5 roughly; check exactly. + if m.cmp(&limit) != Ordering::Less { + return None; + } + m = m.mul(ten).add(I512::from_u64((ch - b'0') as u64)); + if m.is_neg() { + return None; + } + } + Some(if neg { m.neg() } else { m }) + } +} + +impl PartialOrd for I512 { + fn partial_cmp(&self, o: &I512) -> Option { + Some(self.cmp(o)) + } +} + +impl Ord for I512 { + fn cmp(&self, o: &I512) -> Ordering { + match (self.is_neg(), o.is_neg()) { + (true, false) => Ordering::Less, + (false, true) => Ordering::Greater, + _ => { + for i in (0..N).rev() { + match self.0[i].cmp(&o.0[i]) { + Ordering::Equal => continue, + x => return x, + } + } + Ordering::Equal + } + } + } +} + +#[cfg(test)] +mod tests { + use super::I512; + use alloc::string::ToString; + + fn x(v: i128) -> I512 { + I512::from_i128(v) + } + + #[test] + fn arithmetic_matches_i128() { + let vals = [0i128, 1, -1, 7, -7, 1 << 62, -(1 << 62), i64::MAX as i128, i64::MIN as i128, 123456789012345678, -98765432109876543]; + for &a in &vals { + for &b in &vals { + assert_eq!(x(a).add(x(b)).to_i128(), a.checked_add(b)); + assert_eq!(x(a).sub(x(b)).to_i128(), a.checked_sub(b)); + if let Some(p) = a.checked_mul(b) { + assert_eq!(x(a).mul(x(b)).to_i128(), Some(p)); + } + if b > 0 { + assert_eq!(x(a).div_floor(x(b)).to_i128(), Some(floor_div(a, b))); + assert_eq!(x(a).div_trunc(x(b)).to_i128(), Some(a / b)); + } + assert_eq!(x(a).cmp(&x(b)), a.cmp(&b)); + } + for k in [0u32, 1, 5, 63, 64, 65, 100] { + assert_eq!(x(a).shr_floor(k).to_i128(), Some(a >> k.min(127))); + } + } + } + + fn floor_div(a: i128, b: i128) -> i128 { + let q = a / b; + if (a % b != 0) && ((a < 0) != (b < 0)) { q - 1 } else { q } + } + + #[test] + fn wide_values() { + let p = I512::pow2(255); + assert_eq!(p.mul(p), I512::pow2(510)); + assert_eq!(p.neg().mul(p), I512::pow2(510).neg()); + assert_eq!(I512::pow2(300).shr_floor(299), x(2)); + assert_eq!(I512::pow2(300).neg().shr_floor(400), x(-1)); + assert_eq!(I512::pow2(300).isqrt(), I512::pow2(150)); + assert_eq!(I512::pow2(300).sub(I512::ONE).isqrt(), I512::pow2(150).sub(I512::ONE)); + assert_eq!(x(17).isqrt(), x(4)); + assert_eq!(x(17).isqrt_ceil(), x(5)); + assert_eq!(x(16).isqrt_ceil(), x(4)); + assert_eq!(x(0).isqrt_ceil(), x(0)); + assert_eq!(I512::pow2(256).sat(), (I512::pow2(255), true)); + assert_eq!(I512::pow2(255).sat(), (I512::pow2(255), false)); + assert_eq!(I512::from_dec("-115792089237316195423570985008687907853269984665640564039457584007913129639936").unwrap(), I512::pow2(256).neg()); + assert_eq!(I512::pow2(256).to_dec(), "115792089237316195423570985008687907853269984665640564039457584007913129639936"); + assert_eq!(x(-1000000000000000000000).to_dec(), "-1000000000000000000000"); + assert_eq!(x(0).to_dec(), "0"); + assert_eq!(x(i64::MIN as i128).to_dec(), (i64::MIN).to_string()); + assert!(I512::from_dec("12a").is_none()); + assert!(I512::from_dec("").is_none()); + assert!(I512::from_dec("-").is_none()); + } + + #[test] + fn bits_rule() { + assert_eq!(I512::bits(x(0), x(0)), 1); + assert_eq!(I512::bits(x(-1), x(0)), 1); + assert_eq!(I512::bits(x(-128), x(127)), 8); + assert_eq!(I512::bits(x(-129), x(127)), 9); + assert_eq!(I512::bits(x(0), x(128)), 9); + assert_eq!(I512::bits(x(i32::MIN as i128), x(i32::MAX as i128)), 32); + assert!(x(i64::MAX as i128).fits(64)); + assert!(!x(i64::MAX as i128 + 1).fits(64)); + } +} diff --git a/wai/wai-ops/tests/goldens.rs b/wai/wai-ops/tests/goldens.rs new file mode 100644 index 000000000..6519b5fd8 --- /dev/null +++ b/wai/wai-ops/tests/goldens.rs @@ -0,0 +1,450 @@ +//! Every committed parameter set, lowered (§13) and decoded through the interpreter +//! and the stage operators, reproduces its committed output digest. +//! +//! The drivers here are test drivers, written from the payload extensions: they are +//! what a capability's driver does around its graphs (§13.5). They check the lowerings +//! and the operators against outputs that were fixed before either existed. +#![cfg(feature = "uncertified")] + +use std::path::{Path, PathBuf}; + +use wai_ops::interp::{Sequence, Tensor, run}; +use wai_ops::json::{self, Value, hex}; +use wai_ops::lower; +use wai_ops::sha256::sha256; +use wai_ops::stage::{self, rans64}; + +fn wai() -> PathBuf { + PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("..") +} +fn read(p: &str) -> Vec { + std::fs::read(wai().join(p)).unwrap_or_else(|e| panic!("{p}: {e}")) +} +fn jread(p: &str) -> Value { + json::parse(&read(p)).unwrap() +} +fn sha(b: &[u8]) -> String { + hex(&sha256(b)) +} +fn hwc(t: &Tensor) -> Vec { + let (c, h, w) = (t.c as usize, t.h as usize, t.w as usize); + let mut o = vec![0u8; c * h * w]; + for cc in 0..c { + for p in 0..h * w { + o[p * c + cc] = u8::try_from(t.data[cc * h * w + p]).unwrap(); + } + } + o +} +fn one(g: &wai_ops::Graph, x: Tensor, sc: &[i64]) -> Tensor { + run(g, &[x], sc, &mut Sequence::new()).unwrap().remove(0) +} +fn u32le(b: &[u8], o: usize) -> u32 { + u32::from_le_bytes(b[o..o + 4].try_into().unwrap()) +} +fn i64s(v: &Value) -> Vec { + v.as_arr().unwrap().iter().map(|x| x.as_i64().unwrap()).collect() +} +fn sidecar(p: &str, name: &str) -> String { + jread(p).get(name).unwrap().get("sha256").unwrap().as_str().unwrap().to_string() +} + +#[test] +fn int_synth_sets_reproduce_their_digests() { + for name in ["gradient", "bloom", "facade", "photo"] { + let set = lower::int_synth(&read(&format!("neural-conformance/vectors/{name}/int_synth.json"))).unwrap(); + let g = set.get("synth").unwrap(); + let p = read(&format!("neural-conformance/vectors/{name}/latent.bin")); + let (h, w, c, s) = (u32le(&p, 0), u32le(&p, 4), u16::from_le_bytes([p[8], p[9]]) as u32, 1u32 << p[10]); + let lat: Vec = p[12..].iter().map(|&b| b as i8 as i64).collect(); + let out = one(g, Tensor::new(c, s, s, lat), &[]); + assert_eq!((out.c, out.h, out.w), (3, h, w), "{name}: output shape"); + assert_eq!(sha(&hwc(&out)), sidecar("neural-conformance/sha256.json", name), "{name}"); + } +} + +fn world_clip(dir: &str, json_name: &str, t: &str, gs: &str, two: bool) -> Vec { + const ACTIONS: [(i64, i64); 5] = [(0, 0), (1, 0), (-1, 0), (0, 1), (0, -1)]; + let j = jread(&format!("{dir}/{json_name}")); + let c = j.get("c").unwrap().as_u32().unwrap(); + let lat = j.get("lat").unwrap().as_u32().unwrap(); + let afrac = j.get("afrac").unwrap().as_u32().unwrap(); + let set = lower::world(&read(&format!("{dir}/{t}")), &read(&format!("{dir}/{gs}")), c).unwrap(); + let (tg, gg) = (set.get("T").unwrap(), set.get("g_s").unwrap()); + let q = |d: i64| stage::dequantize(d, afrac, 0).unwrap(); + let rows: Vec> = if two { + j.get("pairs").unwrap().as_arr().unwrap().iter().map(|p| { + let a = i64s(p); + let ((xa, ya), (xb, yb)) = (ACTIONS[a[0] as usize], ACTIONS[a[1] as usize]); + vec![q(xa), q(ya), q(xb), q(yb)] + }).collect() + } else { + i64s(j.get("actions").unwrap()).iter().map(|&a| { + let (dx, dy) = ACTIONS[a as usize]; + vec![q(dx), q(dy), 0] + }).collect() + }; + let mut z = Tensor::new(c, lat, lat, i64s(j.get("z0").unwrap())); + let mut frames = vec![sha(&hwc(&one(gg, z.clone(), &[])))]; + for r in &rows { + z = one(tg, z, r); + frames.push(sha(&hwc(&one(gg, z.clone(), &[])))); + } + frames +} + +#[test] +fn world_sets_reproduce_every_frame() { + for (dir, js, t, gs, two, key) in [ + ("wai-rs/tests/vectors/int_world", "world.json", "world_T.bin", "world_gs.bin", false, "world"), + ("wai-rs/tests/vectors/int_world2", "world2.json", "world2_T.bin", "world2_gs.bin", true, "world2"), + ] { + let got = world_clip(dir, js, t, gs, two); + let want: Vec = jread(&format!("{dir}/sha256.json")).get(key).unwrap().get("frames_sha256").unwrap() + .as_arr().unwrap().iter().map(|v| v.as_str().unwrap().to_string()).collect(); + assert_eq!(got, want, "{dir}"); + } +} + +/// A `t4097`/`lenient`/`canonical` stream of `n` symbols, each against `tables[pick(i)]`. +fn decode_stream(stream: &[u8], tables: &[rans64::Table], reads: &[usize], modes: rans64::Modes) -> Vec { + rans64::decode(stream, tables, reads, modes).unwrap() +} + +const WIH1_MODES: rans64::Modes = rans64::Modes { table: rans64::TableRule::T4097, escape: rans64::Escape::Lenient, end: rans64::End::Canonical }; + +fn table(cdf: &[i64], len: usize, off: i64) -> rans64::Table { + rans64::Table { cdf: cdf[..len].to_vec(), offset: off } +} + +#[test] +fn int_hyper_tiny_reproduces_its_digest() { + let d = "wai-rs/tests/vectors/int_hyper"; + let set = lower::int_hyper(&read(&format!("{d}/tiny_h_s.bin")), &read(&format!("{d}/tiny_g_s.bin"))).unwrap(); + let afrac = lower::parse_whm1(&read(&format!("{d}/tiny_g_s.bin"))).unwrap().afrac; + let e = jread(&format!("{d}/tiny_entropy.json")); + let p = read(&format!("{d}/tiny_bitstream.wih1")); + assert_eq!(&p[0..4], b"WIH1"); + let f = |k: usize| u32le(&p, 8 + 4 * k); + let (m, sh, sw, nz, zh, zw) = (f(0), f(1), f(2), f(3), f(4), f(5)); + let lz = u32le(&p, 32) as usize; + let zs = &p[36..36 + lz]; + let ly = u32le(&p, 36 + lz) as usize; + let ys = &p[40 + lz..40 + lz + ly]; + let rows = |k: &str| -> Vec> { e.get(k).unwrap().as_arr().unwrap().iter().map(i64s).collect() }; + let (zc, zl, zo, zm) = (rows("z_cdfs"), i64s(e.get("z_cdf_lengths").unwrap()), i64s(e.get("z_offsets").unwrap()), i64s(e.get("z_median_q").unwrap())); + let ztabs: Vec<_> = (0..nz as usize).map(|k| table(&zc[k], zl[k] as usize, zo[k])).collect(); + let reads: Vec = (0..nz as usize).flat_map(|k| std::iter::repeat_n(k, (zh * zw) as usize)).collect(); + let zsym = decode_stream(zs, &ztabs, &reads, WIH1_MODES); + let z: Vec = zsym.iter().enumerate().map(|(i, &s)| stage::dequantize(s, afrac, zm[i / (zh * zw) as usize]).unwrap()).collect(); + let hyper = one(set.get("h_s").unwrap(), Tensor::new(nz, zh, zw, z), &[]); + assert_eq!((hyper.c, hyper.h, hyper.w), (2 * m, sh, sw)); + let n = (m * sh * sw) as usize; + let (sigma, mu) = hyper.data.split_at(n); + let (yc, yl, yo, edges) = (rows("cdfs"), i64s(e.get("cdf_lengths").unwrap()), i64s(e.get("offsets").unwrap()), i64s(e.get("scale_edges").unwrap())); + let ytabs: Vec<_> = (0..edges.len()).map(|b| table(&yc[b], yl[b] as usize, yo[b])).collect(); + let yreads: Vec = sigma.iter().map(|&s| stage::bucket_ceil(s, &edges).unwrap()).collect(); + let ysym = decode_stream(ys, &ytabs, &yreads, WIH1_MODES); + let y: Vec = ysym.iter().zip(mu).map(|(&r, &u)| stage::dequantize(r, afrac, u).unwrap()).collect(); + let rgb = one(set.get("g_s").unwrap(), Tensor::new(m, sh, sw, y), &[]); + assert_eq!(sha(&hwc(&rgb)), sidecar(&format!("{d}/sha256.json"), "tiny")); +} + +#[test] +fn splat_reproduces_its_digest() { + let d = "wai-rs/tests/vectors/int_splat"; + let set = lower::splat(&read(&format!("{d}/splat_gs.bin"))).unwrap(); + let p = read(&format!("{d}/splat.wis1")); + assert_eq!(&p[0..4], b"WIS1"); + let afrac = p[5] as u32; + let f = |k: usize| u32le(&p, 8 + 4 * k); + let (c, sh, sw, s, attr) = (f(0), f(1), f(2), f(3), f(4)); + let mut o = 32 + 8 * attr as usize; + let lens: Vec = (0..c as usize).map(|k| u16::from_le_bytes([p[o + 2 * k], p[o + 2 * k + 1]]) as usize).collect(); + o += 2 * c as usize; + let offs: Vec = (0..c as usize).map(|k| i32::from_le_bytes(p[o + 4 * k..o + 4 * k + 4].try_into().unwrap()) as i64).collect(); + o += 4 * c as usize; + let meds: Vec = (0..c as usize).map(|k| i64::from_le_bytes(p[o + 8 * k..o + 8 * k + 8].try_into().unwrap())).collect(); + o += 8 * c as usize; + let mut tabs = Vec::new(); + for k in 0..c as usize { + let cdf: Vec = (0..lens[k]).map(|j| u32le(&p, o + 4 * j) as i64).collect(); + o += 4 * lens[k]; + tabs.push(rans64::Table { cdf, offset: offs[k] }); + } + let l = u32le(&p, o) as usize; + let st = &p[o + 4..o + 4 + l]; + let per = (sh * sw) as usize; + let reads: Vec = (0..c as usize).flat_map(|k| std::iter::repeat_n(k, per)).collect(); + let sym = decode_stream(st, &tabs, &reads, WIH1_MODES); + let y: Vec = sym.iter().enumerate().map(|(i, &v)| stage::dequantize(v, afrac, meds[i / per]).unwrap()).collect(); + let out = one(set.get("g_s").unwrap(), Tensor::new(c, sh, sw, y), &[]); + assert_eq!((out.c, out.h, out.w), (attr, s, s)); + let bytes: Vec = out.data.iter().map(|&v| u8::try_from(v).unwrap()).collect(); + assert_eq!(sha(&bytes), sidecar(&format!("{d}/sha256.json"), "splat")); +} + +#[test] +fn audio_reproduces_its_digest() { + let d = "wai-rs/tests/vectors/int_audio"; + let g = lower::wam1(&read(&format!("{d}/audio_model.bin"))).unwrap(); + let p = read(&format!("{d}/audio_bitstream.wia1")); + assert_eq!(&p[0..4], b"WIA1"); + let afrac = p[5] as u32; + let (n_ch, lat_len, t_out) = (u32le(&p, 12), u32le(&p, 16), u32le(&p, 20)); + let offset = i32::from_le_bytes(p[24..28].try_into().unwrap()) as i64; + let cdf_len = u16::from_le_bytes([p[28], p[29]]) as usize; + let mut o = 32; + let meds: Vec = (0..n_ch as usize).map(|k| i64::from_le_bytes(p[o + 8 * k..o + 8 * k + 8].try_into().unwrap())).collect(); + o += 8 * n_ch as usize; + let mut tabs = Vec::new(); + for _ in 0..n_ch { + tabs.push(rans64::Table { cdf: (0..cdf_len).map(|j| u32le(&p, o + 4 * j) as i64).collect(), offset }); + o += 4 * cdf_len; + } + let l = u32le(&p, o) as usize; + let st = &p[o + 4..o + 4 + l]; + let per = lat_len as usize; + let reads: Vec = (0..n_ch as usize).flat_map(|k| std::iter::repeat_n(k, per)).collect(); + let sym = decode_stream(st, &tabs, &reads, WIH1_MODES); + let y: Vec = sym.iter().enumerate().map(|(i, &v)| stage::dequantize(v, afrac, meds[i / per]).unwrap()).collect(); + let out = one(&g, Tensor::new(n_ch, 1, lat_len, y), &[t_out as i64]); + assert_eq!((out.c, out.h, out.w), (1, 1, t_out)); + let pcm: Vec = out.data.iter().flat_map(|&v| i16::try_from(v).unwrap().to_le_bytes()).collect(); + assert_eq!(sha(&pcm), sidecar(&format!("{d}/sha256.json"), "audio")); +} + +#[test] +fn int_mlicpp_reproduces_its_digest() { + let d = "wai-rs/tests/vectors/int_mlicpp"; + let bundle = read(&format!("{d}/model.wmb")); + let set = lower::wmb1(&bundle).unwrap(); + let exp = jread(&format!("{d}/expected.json")); + // The tables section. + let mut o = 4; + let mut secs = Vec::new(); + for _ in 0..4 { + let n = u32le(&bundle, o) as usize; + secs.push(&bundle[o + 4..o + 4 + n]); + o += 4 + n; + } + let t = json::parse(secs[3]).unwrap(); + let afrac = t.get("afrac").unwrap().as_u32().unwrap(); + let rows = |k: &str| -> Vec> { t.get(k).unwrap().as_arr().unwrap().iter().map(i64s).collect() }; + // The payload: a WAI1 envelope holds its manifest, then the payload, each after + // its u32 length. + let env = read(&format!("{d}/stream.wai")); + let ml = u32le(&env, 4) as usize; + let pl = u32le(&env, 8 + ml) as usize; + let p = &env[12 + ml..12 + ml + pl]; + assert_eq!(sha(p), exp.get("payload_sha256").unwrap().as_str().unwrap()); + assert_eq!(&p[0..4], b"WIM1"); + let h16 = |k: usize| u16::from_le_bytes([p[k], p[k + 1]]) as u32; + let (cz, zh, zw, cy, yh, yw, kk) = (h16(12), h16(14), h16(16), h16(18), h16(20), h16(22), h16(24)); + let (lz, ly) = (u32le(p, 28) as usize, u32le(p, 32) as usize); + let (zs, ys) = (&p[36..36 + lz], &p[36 + lz..36 + lz + ly]); + let modes = rans64::Modes { table: rans64::TableRule::T2, escape: rans64::Escape::Lenient, end: rans64::End::FinalOnly }; + let (zc, zl, zo, zm) = (rows("z_cdfs"), i64s(t.get("z_cdf_lengths").unwrap()), i64s(t.get("z_offsets").unwrap()), i64s(t.get("z_median_q").unwrap())); + let ztabs: Vec<_> = (0..cz as usize).map(|k| table(&zc[k], zl[k] as usize, zo[k])).collect(); + let per = (zh * zw) as usize; + let reads: Vec = (0..cz as usize).flat_map(|k| std::iter::repeat_n(k, per)).collect(); + let zsym = rans64::decode(zs, &ztabs, &reads, modes).unwrap(); + let z: Vec = zsym.iter().enumerate().map(|(i, &s)| stage::dequantize(s, afrac, zm[i / per]).unwrap()).collect(); + let hyper = one(set.get("h_s").unwrap(), Tensor::new(cz, zh, zw, z), &[]); + // The y stream: every slice's two passes from one decoder, in order. + let (yc, yl, yo, edges) = (rows("cdfs"), i64s(t.get("cdf_lengths").unwrap()), i64s(t.get("offsets").unwrap()), i64s(t.get("scale_edges").unwrap())); + let ytabs: Vec<_> = (0..edges.len()).map(|b| table(&yc[b], yl[b] as usize, yo[b])).collect(); + let mut dec = rans64::Rans::new(ys).unwrap(); + let plane = (yh * yw) as usize; + let mut y = vec![0i64; cy as usize * plane]; + let per_slice = (cy / kk) as usize; + for j in 0..kk as usize { + for anchor in [true, false] { + let mut inp = y.clone(); + inp.extend_from_slice(&hyper.data); + let sm = one(set.get("entropy").unwrap(), Tensor::new(3 * cy, yh, yw, inp), &[]); + let n = cy as usize * plane; + for ch in j * per_slice..(j + 1) * per_slice { + for idx in stage::coding_order(1, yh, yw, Some(anchor)) { + let e = ch * plane + idx as usize; + let b = stage::bucket_ceil(sm.data[e], &edges).unwrap(); + let r = dec.symbol(&ytabs[b], rans64::Escape::Lenient).unwrap(); + y[e] = stage::dequantize(r, afrac, sm.data[n + e]).unwrap(); + } + } + } + } + assert!(!dec.ran_out()); + let rgb = one(set.get("g_s").unwrap(), Tensor::new(cy, yh, yw, y), &[]); + assert_eq!(sha(&hwc(&rgb)), exp.get("rgb_sha256").unwrap().as_str().unwrap()); +} + +/// The jpegai scale path on the real bundle, where one is supplied: lowered, and run on +/// every hyper-latent value in range, against the legacy decoder's arithmetic restated. +/// The bundle is not committed; `WAI_OPS_JPEGAI_BUNDLE` names a directory holding +/// `norm.json`, `hs_y.json` and `hs_uv.json`. +#[test] +fn jpegai_scale_path_on_a_supplied_bundle() { + let Ok(dir) = std::env::var("WAI_OPS_JPEGAI_BUNDLE") else { + eprintln!("skipped: WAI_OPS_JPEGAI_BUNDLE is not set"); + return; + }; + let rd = |n: &str| std::fs::read(Path::new(&dir).join(n)).unwrap(); + let set = lower::jpegai(&rd("norm.json"), &rd("hs_y.json"), &rd("hs_uv.json")).unwrap(); + for (role, file, cz) in [("hs_y", "hs_y.json", 160u32), ("hs_uv", "hs_uv.json", 96)] { + let g = set.get(role).unwrap(); + let net = json::parse(&rd(file)).unwrap(); + let norm = json::parse(&rd("norm.json")).unwrap(); + let gains = i64s(norm.get(if role == "hs_y" { "gain_y" } else { "gain_uv" }).unwrap()); + let z: Vec = (0..cz as i64 * 16).map(|i| (i * 7919 + 13) % 64 - 31).collect(); + let got = one(g, Tensor::new(cz, 4, 4, z.clone()), &[]); + let want = legacy_scale(&net, &z, cz as usize, &gains); + assert_eq!(got.data, want, "{role}"); + eprintln!("{role}: {} values equal", want.len()); + } +} + +/// The hyper-scale arithmetic as the legacy decoder writes it: clip, integer +/// convolution with its bias, an arithmetic right shift per channel, ReLU, depth to +/// space (CRD), abs, clip to 3967, then the gain. +fn legacy_scale(net: &Value, z: &[i64], cz: usize, gains: &[i64]) -> Vec { + let t = |k: &str| i64s(net.get(k).unwrap().get("v").unwrap()); + let block = |x: &[i64], cin: usize, name: &str, k: usize, pad: usize, sh: &str, relu: bool| -> (Vec, usize) { + let (w, b, s) = (t(&format!("{name}.weight")), t(&format!("{name}.bias")), t(sh)); + let cout = b.len(); + let mut y = vec![0i64; cout * 16]; + for o in 0..cout { + for oy in 0..4 { + for ox in 0..4 { + let mut acc = b[o]; + for i in 0..cin { + for ky in 0..k { + for kx in 0..k { + let (iy, ix) = (oy as i64 + ky as i64 - pad as i64, ox as i64 + kx as i64 - pad as i64); + if (0..4).contains(&iy) && (0..4).contains(&ix) { + acc += w[((o * cin + i) * k + ky) * k + kx] * x[i * 16 + (iy * 4 + ix) as usize].clamp(-128, 127); + } + } + } + } + let mut r = acc >> s[o]; + if relu && r < 0 { + r = 0; + } + y[o * 16 + oy * 4 + ox] = r; + } + } + } + (y, cout) + }; + let (x1, c1) = block(z, cz, "conv1", 1, 0, "onnx::Pow_85", true); + let (x2, c2) = block(&x1, c1, "depthwise", 3, 1, "onnx::Pow_91", true); + let (x3, _) = block(&x2, c2, "pointwise", 1, 0, "onnx::Pow_97", false); + let mut out = vec![0i64; cz * 256]; + for c in 0..cz { + for y in 0..16 { + for x in 0..16 { + let src = (c * 16 + (y % 4) * 4 + (x % 4)) * 16 + (y / 4) * 4 + (x / 4); + out[(c * 16 + y) * 16 + x] = x3[src].abs().clamp(0, 3967) + gains[c]; + } + } + } + out +} + +/// §13.6.1 end to end against the legacy decoder's intermediates on a real codestream: +/// the latent tables, then for each plane the hyper-latent (`fac`), the scale graph, +/// `coded`, `block_stat`, `band_lookup`, `scale_index` and the latent (`sgm`). Neither +/// the bundle nor the codestream is committed: `WAI_OPS_JPEGAI_BUNDLE` names the bundle +/// and `WAI_OPS_JPEGAI_DUMP` a JSON file of the legacy decoder's values for one +/// codestream (its segment payloads and every intermediate above). +#[test] +fn jpegai_entropy_path_matches_the_legacy_decoder() { + let (Ok(dir), Ok(dump)) = (std::env::var("WAI_OPS_JPEGAI_BUNDLE"), std::env::var("WAI_OPS_JPEGAI_DUMP")) else { + eprintln!("skipped: WAI_OPS_JPEGAI_BUNDLE or WAI_OPS_JPEGAI_DUMP is not set"); + return; + }; + let rd = |n: &str| std::fs::read(Path::new(&dir).join(n)).unwrap(); + let norm = json::parse(&rd("norm.json")).unwrap(); + let d = json::parse(&std::fs::read(&dump).unwrap()).unwrap(); + let set = lower::jpegai(&rd("norm.json"), &rd("hs_y.json"), &rd("hs_uv.json")).unwrap(); + let pmf: Vec> = norm.get("pmf").unwrap().as_arr().unwrap().iter().map(i64s).collect(); + let tables = stage::mans::build_latent_tables(&pmf).unwrap(); + let want: Vec> = d.get("tables").unwrap().as_arr().unwrap().iter().map(i64s).collect(); + for (s, (t, w)) in tables.iter().zip(&want).enumerate() { + assert_eq!(t.iter().map(|&v| v as i64).collect::>(), *w, "table {s}"); + } + let bounds = i64s(norm.get("bounds").unwrap()); + let seg = |k: &str| -> Vec { i64s(d.get("segments").unwrap().get(k).unwrap()).iter().map(|&b| b as u8).collect() }; + let rows_of = |k: &str| -> Vec> { i64s(norm.get(k).unwrap()).chunks(63).map(|r| r.to_vec()).collect() }; + let (ry, ruv) = (rows_of("cdfs_y"), rows_of("cdfs_uv")); + for (plane, role, c, skip, gain_k, lat) in [("y", "hs_y", 160usize, 0usize, "gain_y", "SORP"), ("uv", "hs_uv", 96, 160, "gain_uv", "SORS")] { + let p = d.get("planes").unwrap().get(plane).unwrap(); + let gains = i64s(norm.get(gain_k).unwrap()); + let mut rows: Vec> = ry[..skip].to_vec(); + rows.extend_from_slice(if plane == "y" { &ry[..c] } else { &ruv[..c] }); + let lens = vec![16usize; skip + c]; + let syms = stage::mans::decode_fac(&seg("SOZ"), &rows, &lens).unwrap(); + let z: Vec = syms[skip..].iter().flatten().map(|&s| s - 31).collect(); + assert_eq!(z, i64s(p.get("z").unwrap()), "{plane}: z"); + let v = one(set.get(role).unwrap(), Tensor::new(c as u32, 4, 4, z), &[]); + let is: Vec = v.data.iter().enumerate().map(|(i, &x)| x - gains[i / 256]).collect(); + assert_eq!(is, i64s(p.get("i_s").unwrap()), "{plane}: I_s"); + let vt = Tensor::new(c as u32, 16, 16, v.data.clone()); + let likely = stage::block_stat(&vt, 8, 6, 0, 4351).unwrap(); + assert_eq!(likely.data, i64s(p.get("likely").unwrap()), "{plane}: likely"); + let grfs: Vec = p.get("grfs").unwrap().as_arr().unwrap().iter().map(|b| b.as_bool().unwrap()).collect(); + let table = vec![vec![-31, 20, 122, 181], vec![-80, -31, 71, 130]]; + let rvs: Vec = likely.data.iter().enumerate().map(|(i, &l)| stage::band_lookup(l, &[1003, 1352, 1937], &table, if grfs[i / 256] { 0 } else { 1 }).unwrap()).collect(); + assert_eq!(rvs, i64s(p.get("rvs").unwrap()), "{plane}: rvs"); + let sigma: Vec = v.data.iter().zip(&rvs).map(|(&x, &r)| stage::scale_index(x + r, 7, 32).unwrap()).collect(); + assert_eq!(sigma, i64s(p.get("sigma").unwrap()), "{plane}: sigma"); + let mask: Vec = v.data.iter().map(|&x| stage::coded(x, 382)).collect(); + let want_mask: Vec = p.get("mask").unwrap().as_arr().unwrap().iter().map(|b| b.as_bool().unwrap()).collect(); + assert_eq!(mask, want_mask, "{plane}: mask"); + let spans: Vec = (0..c).map(|ch| stage::mans::Span { + mask: mask[ch * 256..(ch + 1) * 256].to_vec(), + sigma: sigma[ch * 256..(ch + 1) * 256].iter().map(|&s| s as usize).collect(), + }).collect(); + let yq: Vec = stage::mans::decode_sgm(&seg(lat), &pmf, &bounds[..32], &spans).unwrap().concat(); + assert_eq!(yq, i64s(p.get("y_q").unwrap()), "{plane}: y_q"); + eprintln!("{plane}: z, I_s, likely, rvs, sigma, mask and y_q equal the legacy decoder's"); + } +} + +/// E8 against streams the reference encoder wrote, and the decode tables it built: +/// `WAI_OPS_MANS_GOLDENS` names the fixture (`jpegai_mans_goldens.json`, not +/// committed). +#[test] +fn mans_matches_reference_encoder_streams() { + let Ok(f) = std::env::var("WAI_OPS_MANS_GOLDENS") else { + eprintln!("skipped: WAI_OPS_MANS_GOLDENS is not set"); + return; + }; + let v = json::parse(&std::fs::read(f).unwrap()).unwrap(); + let pmf: Vec> = v.get("pmf").unwrap().as_arr().unwrap().iter().map(i64s).collect(); + let built = stage::mans::build_latent_tables(&pmf).unwrap(); + let want: Vec> = v.get("decode_transitions").unwrap().as_arr().unwrap().iter().map(i64s).collect(); + for (t, w) in built.iter().zip(&want) { + assert_eq!(t.iter().map(|&x| x as i64).collect::>(), *w); + } + let bounds = i64s(v.get("bounds").unwrap()); + let bytes = |x: &Value| -> Vec { i64s(x).iter().map(|&b| b as u8).collect() }; + let y = v.get("y").unwrap(); + let mask: Vec = y.get("masks").unwrap().as_arr().unwrap().iter().map(|b| b.as_bool().unwrap()).collect(); + let sigma: Vec = i64s(y.get("sigma").unwrap()).iter().map(|&s| s as usize).collect(); + let got = stage::mans::decode_sgm(&bytes(y.get("memory").unwrap()), &pmf, &bounds, &[stage::mans::Span { mask: mask.clone(), sigma }]).unwrap(); + let exp = i64s(y.get("expected").unwrap()); + for i in 0..exp.len() { + if mask[i] { + assert_eq!(got[0][i], exp[i] as i16 as i64, "y symbol {i}"); + } + } + let z = v.get("z").unwrap(); + let rows: Vec> = z.get("cdfs").unwrap().as_arr().unwrap().iter().map(i64s).collect(); + let exp: Vec> = z.get("expected").unwrap().as_arr().unwrap().iter().map(i64s).collect(); + let lens: Vec = exp.iter().map(Vec::len).collect(); + let got = stage::mans::decode_fac(&bytes(z.get("memory").unwrap()), &rows, &lens).unwrap(); + assert_eq!(got, exp); + eprintln!("mans: tables, the sgm stream and the fac stream equal the reference encoder's"); +} -- 2.54.0 (Apple Git-157) From 608a1bea8d6f554fe5f1e6496729dda35b3bb17b Mon Sep 17 00:00:00 2001 From: Transaction Science Date: Fri, 9 Oct 2026 17:41:45 -0400 Subject: [PATCH 02/15] wai-ops: the conformance corpus, its generator, and the WASI and browser-engine legs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit wai/ops-conformance/, in integer-operators §14.1's format, written by `wai-ops vectors gen`: - vectors/.jsonl: one-operator graph vectors for every graph operator: random cases over several magnitudes, and the coverage classes of §14.1: bound-attaining inputs, rounding ties at every mode and the shifts the class names, geometry, the i32 limits and one past them, check and scalar ranges at their ends and one past, every run-time shape refusal, and the distinguishing cases (per-term igdn floors, leaky floors, softmax rows, elu(0), a half mean in layernorm_c, ε = 2^64 − 1, exp at n = 62 and 63). - stage/.jsonl: E1–E13. E1 under every mode, with each strict refusal alone and in each pair one symbol can give, under both end rules; E8 with zero tails, short streams, and escapes at bounds of 128 and 255. - graphs/: the phase form against conv_transpose (the generator checks the two outputs agree), a state carried across three decodes, a refusal at each load check (steps 1–7) and at each run step, and every lowering on a small set. - certificates///.whg1: the lowered graphs of every committed set and of the small sets, with certificates/index.json. Every vector's `profiles` is the profiles its graph meets under §7 and §8.3, from the generator's own tagger; a case that meets neither is not written (its load refusal is a D2b vector). The certifier must agree with every tag. `wai-ops vectors verify` recomputes every vector file, re-lowers every set and regenerates the corpus, and requires every byte to match. It passes natively, as the same binary built for wasm32-wasip2 under wasmtime, and through wai-ops/node, the recomputation as a wasm32-unknown-unknown module run by Node. Co-Authored-By: Claude Opus 5.5 --- wai/ops-conformance/.gitattributes | 2 + wai/ops-conformance/certificates/index.json | 1 + .../g_s.whg1 | Bin 0 -> 12893 bytes .../g_s.whg1 | Bin 0 -> 647 bytes .../hs_uv.whg1 | Bin 0 -> 15237 bytes .../hs_y.whg1 | Bin 0 -> 25157 bytes .../g_s.whg1 | Bin 0 -> 1147 bytes .../h_s.whg1 | Bin 0 -> 1230 bytes .../g_s.whg1 | Bin 0 -> 765 bytes .../h_s.whg1 | Bin 0 -> 866 bytes .../entropy.whg1 | Bin 0 -> 725 bytes .../g_s.whg1 | Bin 0 -> 562 bytes .../h_s.whg1 | Bin 0 -> 317 bytes .../entropy.whg1 | Bin 0 -> 20538 bytes .../g_s.whg1 | Bin 0 -> 9124 bytes .../h_s.whg1 | Bin 0 -> 8694 bytes .../synth.whg1 | Bin 0 -> 930 bytes .../synth.whg1 | Bin 0 -> 3090 bytes .../synth.whg1 | Bin 0 -> 3705 bytes .../synth.whg1 | Bin 0 -> 1160412 bytes .../synth.whg1 | Bin 0 -> 5819 bytes .../g_s.whg1 | Bin 0 -> 79123 bytes .../g_s.whg1 | Bin 0 -> 1147 bytes .../h_s.whg1 | Bin 0 -> 1230 bytes .../T.whg1 | Bin 0 -> 23946 bytes .../g_s.whg1 | Bin 0 -> 45556 bytes .../T.whg1 | Bin 0 -> 1110 bytes .../g_s.whg1 | Bin 0 -> 562 bytes .../T.whg1 | Bin 0 -> 23438 bytes .../g_s.whg1 | Bin 0 -> 45556 bytes wai/ops-conformance/graphs/load.jsonl | 55 + .../graphs/lower_int_synth.jsonl | 2 + wai/ops-conformance/graphs/lower_jpegai.jsonl | 4 + wai/ops-conformance/graphs/lower_wam1.jsonl | 6 + wai/ops-conformance/graphs/lower_whm1.jsonl | 4 + wai/ops-conformance/graphs/lower_wmb1.jsonl | 6 + wai/ops-conformance/graphs/lower_world.jsonl | 3 + wai/ops-conformance/graphs/phase.jsonl | 18 + wai/ops-conformance/graphs/run.jsonl | 16 + wai/ops-conformance/graphs/state.jsonl | 5 + wai/ops-conformance/sets/audio/model.wam | Bin 0 -> 199 bytes wai/ops-conformance/sets/hyper/entropy.json | 1 + wai/ops-conformance/sets/hyper/g_s.whm | Bin 0 -> 366 bytes wai/ops-conformance/sets/hyper/h_s.whm | Bin 0 -> 627 bytes wai/ops-conformance/sets/jpegai/norm.json | 1 + .../sets/jpegai/weights/hs_uv.json | 1 + .../sets/jpegai/weights/hs_y.json | 1 + wai/ops-conformance/sets/mlicpp/model.wmb | Bin 0 -> 1292 bytes wai/ops-conformance/sets/synth/int_synth.json | 1 + wai/ops-conformance/sets/world/T.whm | Bin 0 -> 547 bytes wai/ops-conformance/sets/world/g_s.whm | Bin 0 -> 266 bytes wai/ops-conformance/stage/band_lookup.jsonl | 22 + wai/ops-conformance/stage/block_stat.jsonl | 32 + wai/ops-conformance/stage/bucket.jsonl | 88 ++ wai/ops-conformance/stage/coded.jsonl | 7 + wai/ops-conformance/stage/coding_order.jsonl | 12 + wai/ops-conformance/stage/dequantize.jsonl | 67 ++ wai/ops-conformance/stage/mans_decode.jsonl | 128 +++ wai/ops-conformance/stage/mc_predict.jsonl | 60 + wai/ops-conformance/stage/rans64_decode.jsonl | 439 ++++++++ wai/ops-conformance/stage/rate_predict.jsonl | 28 + wai/ops-conformance/stage/residual_step.jsonl | 103 ++ wai/ops-conformance/stage/scale_index.jsonl | 48 + wai/ops-conformance/stage/up2_predict.jsonl | 31 + wai/ops-conformance/vectors/abs.jsonl | 42 + wai/ops-conformance/vectors/add.jsonl | 70 ++ wai/ops-conformance/vectors/apply.jsonl | 42 + wai/ops-conformance/vectors/chscale.jsonl | 64 ++ wai/ops-conformance/vectors/chunk_add.jsonl | 43 + wai/ops-conformance/vectors/clamp.jsonl | 54 + wai/ops-conformance/vectors/concat.jsonl | 42 + wai/ops-conformance/vectors/conv.jsonl | 122 ++ .../vectors/conv_transpose.jsonl | 113 ++ wai/ops-conformance/vectors/crop.jsonl | 41 + wai/ops-conformance/vectors/crop_to.jsonl | 31 + wai/ops-conformance/vectors/elu.jsonl | 35 + wai/ops-conformance/vectors/fill.jsonl | 34 + wai/ops-conformance/vectors/gram.jsonl | 41 + wai/ops-conformance/vectors/igdn.jsonl | 66 ++ wai/ops-conformance/vectors/l2norm.jsonl | 41 + wai/ops-conformance/vectors/layernorm_c.jsonl | 54 + wai/ops-conformance/vectors/leaky.jsonl | 55 + wai/ops-conformance/vectors/lut16.jsonl | 5 + wai/ops-conformance/vectors/mul.jsonl | 75 ++ wai/ops-conformance/vectors/pad_rep.jsonl | 34 + .../vectors/pixel_shuffle.jsonl | 41 + .../vectors/pixel_unshuffle.jsonl | 41 + wai/ops-conformance/vectors/relu.jsonl | 42 + wai/ops-conformance/vectors/rescale.jsonl | 162 +++ wai/ops-conformance/vectors/sigmoid.jsonl | 31 + wai/ops-conformance/vectors/softmax.jsonl | 44 + wai/ops-conformance/vectors/split.jsonl | 31 + .../vectors/subpos_merge.jsonl | 32 + .../vectors/subpos_split.jsonl | 32 + wai/wai-ops/node/Cargo.lock | 14 + wai/wai-ops/node/Cargo.toml | 20 + wai/wai-ops/node/src/lib.rs | 58 + wai/wai-ops/node/verify.mjs | 46 + wai/wai-ops/src/bin/wai-ops.rs | 226 +++- wai/wai-ops/src/generate/build.rs | 109 ++ wai/wai-ops/src/generate/graphs.rs | 463 ++++++++ wai/wai-ops/src/generate/mod.rs | 85 +- wai/wai-ops/src/generate/ops.rs | 1003 +++++++++++++++++ wai/wai-ops/src/generate/rng.rs | 59 + wai/wai-ops/src/generate/sets.rs | 456 ++++++++ wai/wai-ops/src/generate/stages.rs | 638 +++++++++++ wai/wai-ops/src/generate/tag.rs | 510 +++++++++ wai/wai-ops/src/lib.rs | 1 + 108 files changed, 6438 insertions(+), 2 deletions(-) create mode 100644 wai/ops-conformance/.gitattributes create mode 100644 wai/ops-conformance/certificates/index.json create mode 100644 wai/ops-conformance/certificates/wai.audio.int_codec/132958122b251869ad6725d24a2bb96e2733daaf3e09ef65ebc7af6f46030855/g_s.whg1 create mode 100644 wai/ops-conformance/certificates/wai.audio.int_codec/8eca5bfdc1d8098ccdcfb8e3a7280c0550c4120ea87f224f0d4269e8fd4d1896/g_s.whg1 create mode 100644 wai/ops-conformance/certificates/wai.image.jpegai/60020d0657c4561db336a42f2d359b254a3f12348e8122aeb7bbb91d63b180ad/hs_uv.whg1 create mode 100644 wai/ops-conformance/certificates/wai.image.jpegai/60020d0657c4561db336a42f2d359b254a3f12348e8122aeb7bbb91d63b180ad/hs_y.whg1 create mode 100644 wai/ops-conformance/certificates/wai.neural.int_hyper/13e8b0d18e001eb9f0160309a02755b35a14f71ba0bcaa13f373e32b931ab818/g_s.whg1 create mode 100644 wai/ops-conformance/certificates/wai.neural.int_hyper/13e8b0d18e001eb9f0160309a02755b35a14f71ba0bcaa13f373e32b931ab818/h_s.whg1 create mode 100644 wai/ops-conformance/certificates/wai.neural.int_hyper/7aceaa1aad145d6131a92804d5f6979e5971a4f12cd173dc6828befe2d397e8a/g_s.whg1 create mode 100644 wai/ops-conformance/certificates/wai.neural.int_hyper/7aceaa1aad145d6131a92804d5f6979e5971a4f12cd173dc6828befe2d397e8a/h_s.whg1 create mode 100644 wai/ops-conformance/certificates/wai.neural.int_mlicpp/07e1835da60333d5c5a586da7fc27f2db78b8ccd146b100c61362d4ce768fc1c/entropy.whg1 create mode 100644 wai/ops-conformance/certificates/wai.neural.int_mlicpp/07e1835da60333d5c5a586da7fc27f2db78b8ccd146b100c61362d4ce768fc1c/g_s.whg1 create mode 100644 wai/ops-conformance/certificates/wai.neural.int_mlicpp/07e1835da60333d5c5a586da7fc27f2db78b8ccd146b100c61362d4ce768fc1c/h_s.whg1 create mode 100644 wai/ops-conformance/certificates/wai.neural.int_mlicpp/7ef44f3b1fc4a2df6c3e3b68460f595cae3d31cb7f9018699e29e738340272a4/entropy.whg1 create mode 100644 wai/ops-conformance/certificates/wai.neural.int_mlicpp/7ef44f3b1fc4a2df6c3e3b68460f595cae3d31cb7f9018699e29e738340272a4/g_s.whg1 create mode 100644 wai/ops-conformance/certificates/wai.neural.int_mlicpp/7ef44f3b1fc4a2df6c3e3b68460f595cae3d31cb7f9018699e29e738340272a4/h_s.whg1 create mode 100644 wai/ops-conformance/certificates/wai.neural.int_synth/00c2274be6b49039365a16a357f41162095db65ed4166a4c70f5ddb97e16b4d1/synth.whg1 create mode 100644 wai/ops-conformance/certificates/wai.neural.int_synth/1c4705d17c01f865b20d785191c7f63b5c18dcc8fce77e15852cf8240b7368be/synth.whg1 create mode 100644 wai/ops-conformance/certificates/wai.neural.int_synth/21f092964e1319eca7e494ba3f6794e3166886d50e9dd74d00935c5b317055a9/synth.whg1 create mode 100644 wai/ops-conformance/certificates/wai.neural.int_synth/50868e72f5f1599569c413ed1f67ab8610fa0b3c17919162cbf370f49275125c/synth.whg1 create mode 100644 wai/ops-conformance/certificates/wai.neural.int_synth/c6a362696d61605931ef4da98ae630362dcd73ea6be7864db6e61d6c5abbcd24/synth.whg1 create mode 100644 wai/ops-conformance/certificates/wai.splat.int_codec/033a37c9d29d7ea9675a0b4a3e269d74f2ab874b5a3b1425eec69bf3bad8b26f/g_s.whg1 create mode 100644 wai/ops-conformance/certificates/wai.video.int_hyper/13e8b0d18e001eb9f0160309a02755b35a14f71ba0bcaa13f373e32b931ab818/g_s.whg1 create mode 100644 wai/ops-conformance/certificates/wai.video.int_hyper/13e8b0d18e001eb9f0160309a02755b35a14f71ba0bcaa13f373e32b931ab818/h_s.whg1 create mode 100644 wai/ops-conformance/certificates/wai.world.model/34986fa89648e03500ade7804e9267adc860202c114bc567fa83ed5693bd38fb/T.whg1 create mode 100644 wai/ops-conformance/certificates/wai.world.model/34986fa89648e03500ade7804e9267adc860202c114bc567fa83ed5693bd38fb/g_s.whg1 create mode 100644 wai/ops-conformance/certificates/wai.world.model/5291a52bdbf2279c3350eda96b515bde66d73700c73ccb207e714cb2c6a4c45e/T.whg1 create mode 100644 wai/ops-conformance/certificates/wai.world.model/5291a52bdbf2279c3350eda96b515bde66d73700c73ccb207e714cb2c6a4c45e/g_s.whg1 create mode 100644 wai/ops-conformance/certificates/wai.world.model/da046216ff9495a47fbfdf14788510bc951a266896b47234bb174cef8769ab88/T.whg1 create mode 100644 wai/ops-conformance/certificates/wai.world.model/da046216ff9495a47fbfdf14788510bc951a266896b47234bb174cef8769ab88/g_s.whg1 create mode 100644 wai/ops-conformance/graphs/load.jsonl create mode 100644 wai/ops-conformance/graphs/lower_int_synth.jsonl create mode 100644 wai/ops-conformance/graphs/lower_jpegai.jsonl create mode 100644 wai/ops-conformance/graphs/lower_wam1.jsonl create mode 100644 wai/ops-conformance/graphs/lower_whm1.jsonl create mode 100644 wai/ops-conformance/graphs/lower_wmb1.jsonl create mode 100644 wai/ops-conformance/graphs/lower_world.jsonl create mode 100644 wai/ops-conformance/graphs/phase.jsonl create mode 100644 wai/ops-conformance/graphs/run.jsonl create mode 100644 wai/ops-conformance/graphs/state.jsonl create mode 100644 wai/ops-conformance/sets/audio/model.wam create mode 100644 wai/ops-conformance/sets/hyper/entropy.json create mode 100644 wai/ops-conformance/sets/hyper/g_s.whm create mode 100644 wai/ops-conformance/sets/hyper/h_s.whm create mode 100644 wai/ops-conformance/sets/jpegai/norm.json create mode 100644 wai/ops-conformance/sets/jpegai/weights/hs_uv.json create mode 100644 wai/ops-conformance/sets/jpegai/weights/hs_y.json create mode 100644 wai/ops-conformance/sets/mlicpp/model.wmb create mode 100644 wai/ops-conformance/sets/synth/int_synth.json create mode 100644 wai/ops-conformance/sets/world/T.whm create mode 100644 wai/ops-conformance/sets/world/g_s.whm create mode 100644 wai/ops-conformance/stage/band_lookup.jsonl create mode 100644 wai/ops-conformance/stage/block_stat.jsonl create mode 100644 wai/ops-conformance/stage/bucket.jsonl create mode 100644 wai/ops-conformance/stage/coded.jsonl create mode 100644 wai/ops-conformance/stage/coding_order.jsonl create mode 100644 wai/ops-conformance/stage/dequantize.jsonl create mode 100644 wai/ops-conformance/stage/mans_decode.jsonl create mode 100644 wai/ops-conformance/stage/mc_predict.jsonl create mode 100644 wai/ops-conformance/stage/rans64_decode.jsonl create mode 100644 wai/ops-conformance/stage/rate_predict.jsonl create mode 100644 wai/ops-conformance/stage/residual_step.jsonl create mode 100644 wai/ops-conformance/stage/scale_index.jsonl create mode 100644 wai/ops-conformance/stage/up2_predict.jsonl create mode 100644 wai/ops-conformance/vectors/abs.jsonl create mode 100644 wai/ops-conformance/vectors/add.jsonl create mode 100644 wai/ops-conformance/vectors/apply.jsonl create mode 100644 wai/ops-conformance/vectors/chscale.jsonl create mode 100644 wai/ops-conformance/vectors/chunk_add.jsonl create mode 100644 wai/ops-conformance/vectors/clamp.jsonl create mode 100644 wai/ops-conformance/vectors/concat.jsonl create mode 100644 wai/ops-conformance/vectors/conv.jsonl create mode 100644 wai/ops-conformance/vectors/conv_transpose.jsonl create mode 100644 wai/ops-conformance/vectors/crop.jsonl create mode 100644 wai/ops-conformance/vectors/crop_to.jsonl create mode 100644 wai/ops-conformance/vectors/elu.jsonl create mode 100644 wai/ops-conformance/vectors/fill.jsonl create mode 100644 wai/ops-conformance/vectors/gram.jsonl create mode 100644 wai/ops-conformance/vectors/igdn.jsonl create mode 100644 wai/ops-conformance/vectors/l2norm.jsonl create mode 100644 wai/ops-conformance/vectors/layernorm_c.jsonl create mode 100644 wai/ops-conformance/vectors/leaky.jsonl create mode 100644 wai/ops-conformance/vectors/lut16.jsonl create mode 100644 wai/ops-conformance/vectors/mul.jsonl create mode 100644 wai/ops-conformance/vectors/pad_rep.jsonl create mode 100644 wai/ops-conformance/vectors/pixel_shuffle.jsonl create mode 100644 wai/ops-conformance/vectors/pixel_unshuffle.jsonl create mode 100644 wai/ops-conformance/vectors/relu.jsonl create mode 100644 wai/ops-conformance/vectors/rescale.jsonl create mode 100644 wai/ops-conformance/vectors/sigmoid.jsonl create mode 100644 wai/ops-conformance/vectors/softmax.jsonl create mode 100644 wai/ops-conformance/vectors/split.jsonl create mode 100644 wai/ops-conformance/vectors/subpos_merge.jsonl create mode 100644 wai/ops-conformance/vectors/subpos_split.jsonl create mode 100644 wai/wai-ops/node/Cargo.lock create mode 100644 wai/wai-ops/node/Cargo.toml create mode 100644 wai/wai-ops/node/src/lib.rs create mode 100644 wai/wai-ops/node/verify.mjs create mode 100644 wai/wai-ops/src/generate/build.rs create mode 100644 wai/wai-ops/src/generate/graphs.rs create mode 100644 wai/wai-ops/src/generate/ops.rs create mode 100644 wai/wai-ops/src/generate/rng.rs create mode 100644 wai/wai-ops/src/generate/sets.rs create mode 100644 wai/wai-ops/src/generate/stages.rs create mode 100644 wai/wai-ops/src/generate/tag.rs diff --git a/wai/ops-conformance/.gitattributes b/wai/ops-conformance/.gitattributes new file mode 100644 index 000000000..289b89b5e --- /dev/null +++ b/wai/ops-conformance/.gitattributes @@ -0,0 +1,2 @@ +# Compared as bytes: a line-ending conversion on checkout would change every file. +* -text diff --git a/wai/ops-conformance/certificates/index.json b/wai/ops-conformance/certificates/index.json new file mode 100644 index 000000000..33515420d --- /dev/null +++ b/wai/ops-conformance/certificates/index.json @@ -0,0 +1 @@ +{"format":"wai-ops-lowered/1","sets":[{"capability":"wai.neural.int_synth","lowering":"int_synth/1","members":{"int_synth.json":"neural-conformance/vectors/gradient/int_synth.json"},"name":"gradient","note":"neural-conformance, generated","roles":["ops-conformance/certificates/wai.neural.int_synth/1c4705d17c01f865b20d785191c7f63b5c18dcc8fce77e15852cf8240b7368be/synth.whg1"],"set_sha256":"1c4705d17c01f865b20d785191c7f63b5c18dcc8fce77e15852cf8240b7368be","synthetic":false},{"capability":"wai.neural.int_synth","lowering":"int_synth/1","members":{"int_synth.json":"neural-conformance/vectors/bloom/int_synth.json"},"name":"bloom","note":"neural-conformance, generated","roles":["ops-conformance/certificates/wai.neural.int_synth/21f092964e1319eca7e494ba3f6794e3166886d50e9dd74d00935c5b317055a9/synth.whg1"],"set_sha256":"21f092964e1319eca7e494ba3f6794e3166886d50e9dd74d00935c5b317055a9","synthetic":false},{"capability":"wai.neural.int_synth","lowering":"int_synth/1","members":{"int_synth.json":"neural-conformance/vectors/facade/int_synth.json"},"name":"facade","note":"neural-conformance, generated","roles":["ops-conformance/certificates/wai.neural.int_synth/c6a362696d61605931ef4da98ae630362dcd73ea6be7864db6e61d6c5abbcd24/synth.whg1"],"set_sha256":"c6a362696d61605931ef4da98ae630362dcd73ea6be7864db6e61d6c5abbcd24","synthetic":false},{"capability":"wai.neural.int_synth","lowering":"int_synth/1","members":{"int_synth.json":"neural-conformance/vectors/photo/int_synth.json"},"name":"photo","note":"neural-conformance; its decoder was trained on images the corpus does not record (see that corpus's provenance)","roles":["ops-conformance/certificates/wai.neural.int_synth/50868e72f5f1599569c413ed1f67ab8610fa0b3c17919162cbf370f49275125c/synth.whg1"],"set_sha256":"50868e72f5f1599569c413ed1f67ab8610fa0b3c17919162cbf370f49275125c","synthetic":false},{"capability":"wai.neural.int_hyper","lowering":"whm1/1","members":{"entropy.json":"wai-rs/tests/vectors/int_hyper/tiny_entropy.json","g_s.whm":"wai-rs/tests/vectors/int_hyper/tiny_g_s.bin","h_s.whm":"wai-rs/tests/vectors/int_hyper/tiny_h_s.bin"},"name":"tiny","note":"int-payload-conformance `tiny`","roles":["ops-conformance/certificates/wai.neural.int_hyper/13e8b0d18e001eb9f0160309a02755b35a14f71ba0bcaa13f373e32b931ab818/h_s.whg1","ops-conformance/certificates/wai.neural.int_hyper/13e8b0d18e001eb9f0160309a02755b35a14f71ba0bcaa13f373e32b931ab818/g_s.whg1"],"set_sha256":"13e8b0d18e001eb9f0160309a02755b35a14f71ba0bcaa13f373e32b931ab818","synthetic":false},{"capability":"wai.video.int_hyper","lowering":"whm1/1","members":{"entropy.json":"wai-rs/tests/vectors/int_hyper/tiny_entropy.json","g_s.whm":"wai-rs/tests/vectors/int_hyper/tiny_g_s.bin","h_s.whm":"wai-rs/tests/vectors/int_hyper/tiny_h_s.bin"},"name":"tiny","note":"int-payload-conformance `video_nk`, whose keyframe decodes against `tiny`","roles":["ops-conformance/certificates/wai.video.int_hyper/13e8b0d18e001eb9f0160309a02755b35a14f71ba0bcaa13f373e32b931ab818/h_s.whg1","ops-conformance/certificates/wai.video.int_hyper/13e8b0d18e001eb9f0160309a02755b35a14f71ba0bcaa13f373e32b931ab818/g_s.whg1"],"set_sha256":"13e8b0d18e001eb9f0160309a02755b35a14f71ba0bcaa13f373e32b931ab818","synthetic":false},{"capability":"wai.audio.int_codec","lowering":"wam1/1","members":{"model.wam":"wai-rs/tests/vectors/int_audio/audio_model.bin"},"name":"audio","note":"int-payload-conformance `audio`","roles":["ops-conformance/certificates/wai.audio.int_codec/132958122b251869ad6725d24a2bb96e2733daaf3e09ef65ebc7af6f46030855/g_s.whg1"],"set_sha256":"132958122b251869ad6725d24a2bb96e2733daaf3e09ef65ebc7af6f46030855","synthetic":false},{"capability":"wai.splat.int_codec","lowering":"whm1/1","members":{"g_s.whm":"wai-rs/tests/vectors/int_splat/splat_gs.bin"},"name":"splat","note":"int-payload-conformance `splat`","roles":["ops-conformance/certificates/wai.splat.int_codec/033a37c9d29d7ea9675a0b4a3e269d74f2ab874b5a3b1425eec69bf3bad8b26f/g_s.whg1"],"set_sha256":"033a37c9d29d7ea9675a0b4a3e269d74f2ab874b5a3b1425eec69bf3bad8b26f","synthetic":false},{"capability":"wai.neural.int_mlicpp","lowering":"wmb1/1","members":{"model.wmb":"wai-rs/tests/vectors/int_mlicpp/model.wmb"},"name":"int_mlicpp","note":"wai-rs/tests/vectors/int_mlicpp","roles":["ops-conformance/certificates/wai.neural.int_mlicpp/7ef44f3b1fc4a2df6c3e3b68460f595cae3d31cb7f9018699e29e738340272a4/h_s.whg1","ops-conformance/certificates/wai.neural.int_mlicpp/7ef44f3b1fc4a2df6c3e3b68460f595cae3d31cb7f9018699e29e738340272a4/entropy.whg1","ops-conformance/certificates/wai.neural.int_mlicpp/7ef44f3b1fc4a2df6c3e3b68460f595cae3d31cb7f9018699e29e738340272a4/g_s.whg1"],"set_sha256":"7ef44f3b1fc4a2df6c3e3b68460f595cae3d31cb7f9018699e29e738340272a4","synthetic":false},{"c":"24","capability":"wai.world.model","lowering":"world/1","members":{"T.whm":"wai-rs/tests/vectors/int_world/world_T.bin","g_s.whm":"wai-rs/tests/vectors/int_world/world_gs.bin"},"name":"world","note":"wai-rs/tests/vectors/int_world, one agent","roles":["ops-conformance/certificates/wai.world.model/da046216ff9495a47fbfdf14788510bc951a266896b47234bb174cef8769ab88/T.whg1","ops-conformance/certificates/wai.world.model/da046216ff9495a47fbfdf14788510bc951a266896b47234bb174cef8769ab88/g_s.whg1"],"set_sha256":"da046216ff9495a47fbfdf14788510bc951a266896b47234bb174cef8769ab88","synthetic":false},{"c":"24","capability":"wai.world.model","lowering":"world/1","members":{"T.whm":"wai-rs/tests/vectors/int_world2/world2_T.bin","g_s.whm":"wai-rs/tests/vectors/int_world2/world2_gs.bin"},"name":"world2","note":"wai-rs/tests/vectors/int_world2, two agents","roles":["ops-conformance/certificates/wai.world.model/34986fa89648e03500ade7804e9267adc860202c114bc567fa83ed5693bd38fb/T.whg1","ops-conformance/certificates/wai.world.model/34986fa89648e03500ade7804e9267adc860202c114bc567fa83ed5693bd38fb/g_s.whg1"],"set_sha256":"34986fa89648e03500ade7804e9267adc860202c114bc567fa83ed5693bd38fb","synthetic":false},{"capability":"wai.neural.int_synth","lowering":"int_synth/1","members":{"int_synth.json":"ops-conformance/sets/synth/int_synth.json"},"name":"synth","note":"synthetic","roles":["ops-conformance/certificates/wai.neural.int_synth/00c2274be6b49039365a16a357f41162095db65ed4166a4c70f5ddb97e16b4d1/synth.whg1"],"set_sha256":"00c2274be6b49039365a16a357f41162095db65ed4166a4c70f5ddb97e16b4d1","synthetic":true},{"capability":"wai.neural.int_hyper","lowering":"whm1/1","members":{"entropy.json":"ops-conformance/sets/hyper/entropy.json","g_s.whm":"ops-conformance/sets/hyper/g_s.whm","h_s.whm":"ops-conformance/sets/hyper/h_s.whm"},"name":"hyper","note":"synthetic","roles":["ops-conformance/certificates/wai.neural.int_hyper/7aceaa1aad145d6131a92804d5f6979e5971a4f12cd173dc6828befe2d397e8a/h_s.whg1","ops-conformance/certificates/wai.neural.int_hyper/7aceaa1aad145d6131a92804d5f6979e5971a4f12cd173dc6828befe2d397e8a/g_s.whg1"],"set_sha256":"7aceaa1aad145d6131a92804d5f6979e5971a4f12cd173dc6828befe2d397e8a","synthetic":true},{"capability":"wai.audio.int_codec","lowering":"wam1/1","members":{"model.wam":"ops-conformance/sets/audio/model.wam"},"name":"audio","note":"synthetic","roles":["ops-conformance/certificates/wai.audio.int_codec/8eca5bfdc1d8098ccdcfb8e3a7280c0550c4120ea87f224f0d4269e8fd4d1896/g_s.whg1"],"set_sha256":"8eca5bfdc1d8098ccdcfb8e3a7280c0550c4120ea87f224f0d4269e8fd4d1896","synthetic":true},{"capability":"wai.neural.int_mlicpp","lowering":"wmb1/1","members":{"model.wmb":"ops-conformance/sets/mlicpp/model.wmb"},"name":"mlicpp","note":"synthetic","roles":["ops-conformance/certificates/wai.neural.int_mlicpp/07e1835da60333d5c5a586da7fc27f2db78b8ccd146b100c61362d4ce768fc1c/h_s.whg1","ops-conformance/certificates/wai.neural.int_mlicpp/07e1835da60333d5c5a586da7fc27f2db78b8ccd146b100c61362d4ce768fc1c/entropy.whg1","ops-conformance/certificates/wai.neural.int_mlicpp/07e1835da60333d5c5a586da7fc27f2db78b8ccd146b100c61362d4ce768fc1c/g_s.whg1"],"set_sha256":"07e1835da60333d5c5a586da7fc27f2db78b8ccd146b100c61362d4ce768fc1c","synthetic":true},{"c":"2","capability":"wai.world.model","lowering":"world/1","members":{"T.whm":"ops-conformance/sets/world/T.whm","g_s.whm":"ops-conformance/sets/world/g_s.whm"},"name":"world","note":"synthetic","roles":["ops-conformance/certificates/wai.world.model/5291a52bdbf2279c3350eda96b515bde66d73700c73ccb207e714cb2c6a4c45e/T.whg1","ops-conformance/certificates/wai.world.model/5291a52bdbf2279c3350eda96b515bde66d73700c73ccb207e714cb2c6a4c45e/g_s.whg1"],"set_sha256":"5291a52bdbf2279c3350eda96b515bde66d73700c73ccb207e714cb2c6a4c45e","synthetic":true},{"capability":"wai.image.jpegai","lowering":"jpegai-int/1","members":{"norm.json":"ops-conformance/sets/jpegai/norm.json","weights/hs_uv.json":"ops-conformance/sets/jpegai/weights/hs_uv.json","weights/hs_y.json":"ops-conformance/sets/jpegai/weights/hs_y.json"},"name":"jpegai","note":"synthetic","roles":["ops-conformance/certificates/wai.image.jpegai/60020d0657c4561db336a42f2d359b254a3f12348e8122aeb7bbb91d63b180ad/hs_y.whg1","ops-conformance/certificates/wai.image.jpegai/60020d0657c4561db336a42f2d359b254a3f12348e8122aeb7bbb91d63b180ad/hs_uv.whg1"],"set_sha256":"60020d0657c4561db336a42f2d359b254a3f12348e8122aeb7bbb91d63b180ad","synthetic":true}]} diff --git a/wai/ops-conformance/certificates/wai.audio.int_codec/132958122b251869ad6725d24a2bb96e2733daaf3e09ef65ebc7af6f46030855/g_s.whg1 b/wai/ops-conformance/certificates/wai.audio.int_codec/132958122b251869ad6725d24a2bb96e2733daaf3e09ef65ebc7af6f46030855/g_s.whg1 new file mode 100644 index 0000000000000000000000000000000000000000..a691be4798e77f538324f419c3f20c4aca6c55a0 GIT binary patch literal 12893 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 literal 0 HcmV?d00001 diff --git a/wai/ops-conformance/certificates/wai.audio.int_codec/8eca5bfdc1d8098ccdcfb8e3a7280c0550c4120ea87f224f0d4269e8fd4d1896/g_s.whg1 b/wai/ops-conformance/certificates/wai.audio.int_codec/8eca5bfdc1d8098ccdcfb8e3a7280c0550c4120ea87f224f0d4269e8fd4d1896/g_s.whg1 new file mode 100644 index 0000000000000000000000000000000000000000..daad0990ca377a87fce025ba47c3f963bc1259c5 GIT binary patch literal 647 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≶=iOtZWee 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

#AQwS)4+byTi146}@t07UL>b8YKlwml89kOnvf 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 literal 0 HcmV?d00001 diff --git a/wai/ops-conformance/certificates/wai.neural.int_hyper/13e8b0d18e001eb9f0160309a02755b35a14f71ba0bcaa13f373e32b931ab818/g_s.whg1 b/wai/ops-conformance/certificates/wai.neural.int_hyper/13e8b0d18e001eb9f0160309a02755b35a14f71ba0bcaa13f373e32b931ab818/g_s.whg1 new file mode 100644 index 0000000000000000000000000000000000000000..8ac94809bbb615e9deab9c7fe0daa419aa54ddbc GIT binary patch literal 1147 zcmb7ETS$~q5dL;`O>?yp6Rn8uQjlay*N3n`qo^QID<6_H%oV{*%uGR2@|GJ`T2NVr zSrFayMO%`v3sh(zf?XgiN$aIRBT1{T@9er!Jp`To=X`r+=FH4L-|QxDOo+Bv06zdW ziAA4@Ckwx)ibk;RJ zFKxHM$HbBRz5Z7}&AgD7*=x0#`b-QXD$^~-_PZE8tX7M^Kd?2)cmkbYJ=p5!!O*3w`gKt#NjgI$h|lEg{CpmdMb^jMvHWLqvQmo9iR z;F7*K0I1M?*TPbFoTPV^Zj2o0bK{lJJ8m=sVsab)Rx5@Il6jbk7>!UW<|7ve=!YKW zi^y&flz_9$LKQ1f$^hkRVF(szVA3^!gDlVpHShusvV{#AzhO>61{Nb5`FNxZC3wYp r4TF#Bzr+pLrBMh}BTWkoao!(+X^i(^mEG9PzeJEkv|G$sGXeWg5kyPL literal 0 HcmV?d00001 diff --git a/wai/ops-conformance/certificates/wai.neural.int_hyper/13e8b0d18e001eb9f0160309a02755b35a14f71ba0bcaa13f373e32b931ab818/h_s.whg1 b/wai/ops-conformance/certificates/wai.neural.int_hyper/13e8b0d18e001eb9f0160309a02755b35a14f71ba0bcaa13f373e32b931ab818/h_s.whg1 new file mode 100644 index 0000000000000000000000000000000000000000..e4edbefc79cef0cf821b9f8adffea10735473b20 GIT binary patch literal 1230 zcmaize`r=^6vw~so6A)Oj!ND%jaq0nEi9EN%0jAHs33)+fvas!bm+F!taQ$eaI2w9 zH|KsS*!qPQmL*1|kt9@D!-UApkf=stHqpJqnV-JTd+$R0r*rRf&pqcn&-w8^=b4@V z*n~tv8YJlouY{kNg6e-MoJo3B`Sa_MJu~|1&oVM^+WUi_yC&l^=qsQ7G@0%@M0Lm1 zf3gSP{hz+SbLM%!WX;nG^(JEw;PVp*pRmM(6=m8zz z8+sV4(Hg2}Xx43N*LuqNiO(6LlvdKuUTRft=>?r+j!IR-QPLE0hysmQgLRBTHdDdlP>r3Ue8Tb|S&HmQpl`h)AWP)}$r zpRvk-*4aKwAMy^HS*l+sFuW&e(?;cJotCMcH<;>Eg|^+LK9*5WLi;IVEw^Z!&)=&& z{Yi_#y}&klnXD<9?3=h>!`zf6D*4L$N2*B6IY^PZ8KpUDV7O1_=_z$kuJe?56przO zhoPC3%5tnGPP0y(9N>(1Jg5C2*;-Pwv z?H;#U)hJCJ&ubs=((MNp((WusM9j23^9+*nkeUn~ixuv5X*;h2y7odYua=oXRO&;<2`i**{J=;BhjYX`` zozA3(R#od~V}6=0UzK}YO@)?v+^4IGRu(w(uic07_I{iR_Bu{CI?I>b?H^gjxM!fqV1hd-FW zD>m>Dr5xC-0F7g+PU7C9=L=`r0mRZLpb~8Qf>`|B4n_(Okek{{)<`-qzRdn6c%+5gl|(IYv_*PFt>24)h3r2qf` literal 0 HcmV?d00001 diff --git a/wai/ops-conformance/certificates/wai.neural.int_hyper/7aceaa1aad145d6131a92804d5f6979e5971a4f12cd173dc6828befe2d397e8a/h_s.whg1 b/wai/ops-conformance/certificates/wai.neural.int_hyper/7aceaa1aad145d6131a92804d5f6979e5971a4f12cd173dc6828befe2d397e8a/h_s.whg1 new file mode 100644 index 0000000000000000000000000000000000000000..b87cf598be938264e0b53bd8afa510502251a74c GIT binary patch literal 866 zcmah{T}YEr7=F&?+>&7!24yyh+WNh)gvv{^XhqV`&7h0u2ORApF_I`l4Ka#XFd|lB z7Gy;iVG?0w-4q%H6~fR-VObFo-dHxVZRhDd`@Vs9y&vy6-+A8myzg_Kb3(!G>y-iu z064{!e6|_rzh?G0#M@+;ZTvg-aeS8UORm83Wrew#2Dhz^mbIF~1|Nwe2FibCxaP{* ztzQ>9t^9oUoLL!yVrI;W=eb&ZE!@QNo@?oFD31pS7D+&?#%0Z~?Nh~zt+jX9s*T=^ z#jf6-2W`9or7D7>9H0;1@fL+@Mh{_v3Cu?dN!`gHpK%+{)6W@x(FKg*DORh1lJ06V zI(U-}EaY|GLzZLuJ!`lZ8r9sxGGz2P;+$j$qpU|C6ZEThh#`qe1X;myb}^~bf<9&= zR;Vs|MGQkNuWN~{&A$;NCV{!)7~HtYpX<53wm>Ocpe^$xNo+|j2<&%TYp=2eIhnNt zO4|wFtT-He!e;!yZ&b-qYEi*%`0$pg5;tfn=0tfL&`*9pqj3bJRxX)Ie!ESV7 z630-+el+t9eOxLBaH&x?@fMwE=Q#wJLXql6ge%pg{-mpMM5H+k7ayQSI`uJxDZXNf z`lVm+06H+rI<6vAF^3sonj;M38ZHZ)4;(@*uHvCw$tmd@MiZzju@MVIV5ihN&Bdye zQ@S0G(92zLtF!zpHKW{#Zr(B#DR!BEx*CSyGBmdx-f^C`AwE!cj1UL6k-G zP)Q7eB9waaL6V?)kgQ0E2*Vzh3uao3T7UF@ox81-qdx8IlsMto-?6*?$ zY`*Qw!g7DZ)`sIqX({k)i4A~go>bahh|3F-@En|H-c}XQN~@|iRE$rvi*@Kklr?PN zO^)C`HY19lmQAx;qrJRC7kh98A9$VZT#F3P@h*pO8ExpHmn$Wpm@|GR@d{h<7%9&2 z1j?lkJCqq_gk5-oAe)hdBO_?xMrp+Xe&QQ5057xVojHru%&`_Lc#m#;Wt!8bonfA2 z0*8@c%3R=#c?u7j5RfDXa9pdd5n|E|GKXW@s}~a9;@+ literal 0 HcmV?d00001 diff --git a/wai/ops-conformance/certificates/wai.neural.int_mlicpp/07e1835da60333d5c5a586da7fc27f2db78b8ccd146b100c61362d4ce768fc1c/g_s.whg1 b/wai/ops-conformance/certificates/wai.neural.int_mlicpp/07e1835da60333d5c5a586da7fc27f2db78b8ccd146b100c61362d4ce768fc1c/g_s.whg1 new file mode 100644 index 0000000000000000000000000000000000000000..2ef60c28d8d936df472f73c1e3db8def08e3ab72 GIT binary patch literal 562 zcmb7BO(;ZR6g}UY!DPk^N|cQ#VP)19Sh0|W1!Y1?`732*C1Vy-ldWQ5BP$C#HkvFH zWr0$Zl?4`-N(ti~=Xx_G8#%9Y@B7aE-o5Ah-bjC6(m9|EKv;Boim>IMuuYzrRyfIA zUN=3wv1_@r;Bg1VZ+$0yV%UT`I#+%^* z(Y)E^mHtXzC-qeP)TX$&qxFXBS><8rGtyG?5`^i^ARinDIjY{)*Dk9%kb-Cf1y6OW O*{mv2PMp0{jC=vD16s@g literal 0 HcmV?d00001 diff --git a/wai/ops-conformance/certificates/wai.neural.int_mlicpp/07e1835da60333d5c5a586da7fc27f2db78b8ccd146b100c61362d4ce768fc1c/h_s.whg1 b/wai/ops-conformance/certificates/wai.neural.int_mlicpp/07e1835da60333d5c5a586da7fc27f2db78b8ccd146b100c61362d4ce768fc1c/h_s.whg1 new file mode 100644 index 0000000000000000000000000000000000000000..9e1822889bc1d182c3cdb322e110399b6e0b0825 GIT binary patch literal 317 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 literal 0 HcmV?d00001 diff --git a/wai/ops-conformance/certificates/wai.neural.int_mlicpp/7ef44f3b1fc4a2df6c3e3b68460f595cae3d31cb7f9018699e29e738340272a4/g_s.whg1 b/wai/ops-conformance/certificates/wai.neural.int_mlicpp/7ef44f3b1fc4a2df6c3e3b68460f595cae3d31cb7f9018699e29e738340272a4/g_s.whg1 new file mode 100644 index 0000000000000000000000000000000000000000..0b120b030f29929840893ccc458bf1437d73aeee GIT binary patch literal 9124 zcmbVy2b9(|({FlKR;u(Oy_cm6(xppL5u`0eq!)K7OYc=Wq97u|D(wm8m2AJLcd?!S zlRZxU+(7?X{$KTJlNTVAKX#+k-jE9}j01U-qKi|aZ>F}PY?GD1jeuX#&MzKiI$7V8x#YM5) zcCx!v1Y2n;n6CV^kMrGRan@9%W>t6^6M;{&>bMA+AuhS&Xf-;9hoB<%wH+v$s2TPL zRUMC1Pkd`9@g@AVs!W!G0wAaZ!^@v|_(KtW9g>Uk+{+LPS%Sz8v zshT1SDrX9r&F&J{G^@X)8k(W_-|~Wd?5f$<;Jm&H+p(^yIQy5ppl_(UxP-lB3;SJo z3@fJ#i2G(89c4P&@%j%s&@7VE(Nmodrg8W6NOZ!F;9dAA5y6J)%jOozVubAno6&#c z{wxE2N|(EuyeG>G_OMt{)yBIXKEkwh+>Pg-;7xR?Z{W()tT;7j;p_U^K1nua!{sfM zk)08#`Di{D*CSpJQ!-qx~rGO67n87pD(o15ZF(G*q2X8Cgjb$$%@(+sLBs0xAW%y4Bz({G(-} zk>3K!vfkF%>>xGynN|@EMO8HyencX|O4Vko@jdoCxat*MYo_qYZV@^ps)+vnoGK@V z$wTN5KM&n-4@~mPw??hdKBHw1T~OYGr}Y816-R?u(9O3~dsR8t$h|~y>LK5uf9J)0 zO+6h|Bd3r7H~m=K4=1SUCKWk~`{7rhnAnSnm`l5fB)!WX=bxhX^fXzHGTRDxFn?|z z+EpM9l$6=|e7qCi7j;cZR|W5;Y28&(lH_6g!zj=A3W42u-JSRF%?Ts9OaYsZJyBn{ zBr_HMLF?Mpu&jQ~THxtuB&=k!l2r1Lj)tH5l6IPWZHDsNXfb}rX9ay2kkfEM+6ip8 zm%$>ji#5fFl*VgZ2Rs#J#y_zgeu<2;18@w?4Q`snsD*oCcKPB)C?sy`?7phdd<^@7 zC!j|9rCdVa;Y(#zxKSK4-SjqjKkVB@D6QM>Tg!uJrtNN4p#thOTN7q+SUqw(#8@{} zH-z0m4;s(A>Xc%jXa-BlG`bPJN!F6Kz5{zsQ|Sfbpe#Ws*hviC3^EXcwMf6WIoz;=_EcDkCtzLAufF zGM0BTz0D3Vk3W@E4+SIH7(ADKqH2(dDl04vqFrsZRA!_bX{>vXaP`Doh4rmx5v&Cp z2jlEG^ff6(sqEr6uoCtYUqf`D`9-{G$EMNMVh%{h7pfj&8?1;qt)aW}XSN6)=BlE1 z>`DHFMZvQqg^w2q-iNbnBsoV8m~3*kc!2JL622+yz%KDod=@F`H`2X)HNK)6>&iZp zWd0ZP1D}X;qQjs9mi8mq(G4Z%*f<|)Yx1M;q>n>D?UeWF0#^_pHvME1-;VXCt5kOW z3Cm*ol8^km@UYBamatJcH*QLE!3wM>ZzAXUmh3n2t2^sY`h4;vJQ5I z{7RgYer(#nvEm+zc0Ji=tTOC{Zm?FS1&-pogJ&$rR??y3KHs9++Qsyi{mFT9z)y#D zT^I44UIjE5Yb=}CeV~)BD4fdeT7qwQJ$ZxPKtow` z{0WQGJ9K7w1=kiA7zOim33r9&5!q>K5MjJpp_ZyyYA!w>{C7GQ#ShV1dL#ae?Y7JG zS3VkLV1qfPP@L00We3*=)Y3)V9CMj@IUG#$ zSj@6VTt@o9eyVoz24*lQWSY}V@*Mg!d@r}-@BJ>3n|_C$s2a+uAv7&6ZTpI4q@5Z; z&S4He;O+bceu;d97SZQ28+-{8-4Eg^S_VH9BVB3P7_TK+@H3K{#M7ZBH))0>o2|F; z`szboNEV~jxaX}!D~HIJCO@7_TcE-2b8rvL@pt3|-o`2Y1%FK+fxlcXS{v>qD?v$L z1uJt?cLoR8F&J#b6RufZlG+V2$7NS^5O-Cx_>XKA+ljiHyl#-+i<-$@Q>KbKGykJvM^c!a?-Q#C-7SB)YoV^G1h-- z7V?QIC*fhYU!skJ*PaPuoCHU0BV5WfA_K`rc)^W?gkSR?unrKp0kApEK+3SjG9Io0 zGf5=Nr3--ctTXykmy(rnv`A;}sKKZL9Et{_E+7+LuQHzR#Z8Sw$1f<8mS^i&VSX?uWgG*v-Le^%dN)AcacjNOzS z^bSUJM|q6CPin9;q&JMQW%vlyi*D65;6&Gp72bcrcD=QxE-$ z(}ox;w~G=V=vrnaeM}jiKyHzT`~?SUH&`xvs=WLI{XoQ#-OiD;b_YnK`NMT$ck`;YFkDDp z%INUD=we3LlIk3tqO&14opkH_a+d2rDGZhMN~ z{b`pQjgZI9a=8v=SC_(*E{2if6Ma!a+yGzl-S7~R$>njU=ue^={5RZe9Q@T^X0yY0 zEf#&GCh&L66TU+fwQIpNUBLcJ(I3=TX+bm0^+!o^ zD?SMS@UN8cWyv7+1b6eX>LpG9O~Nkv5{E_w`pq)Do z^P2~}D4s1mFQ(rmYyBx)7yRZ95e#n8TxuZAMicBGC^AI+b=VAF!*ylzT*a`LTC*sf zAFT&{R8=)lJ`#zl8L7w?*~%oZpUoQ6=RS+uDzcC*yroTK8{%`>@?g2YN`ZMS??9)!W`0bOgH0`q&Pl?H27Vm3jpdLQ1odK(ga-cZlHe< z?C+MGsalQ<4o6ye%{!`E;IYq~z*+Kqf__4v zxG;9NKx+bZ38aFJ57aIj0Odme#X(*c>}rO7Es|{mj|g)~?*GgCVXRO;6liy_{XE#F z2>RNgJ}1<31i5>d^Q+S-L(edm0-4|N54({!yxqAxZ+MeZ+28O2-QIh{_k5e-4bOh7 z)Ek}*P{Yt54EO&9P!p0nhVl>a{0E5s15|InZNK#&cK`ItT;=cnpvzm}dEzZE`$eDViIAv?W`c+6I{eV46gO=tJjld=RH~*Ks1nXFsEJ8lZAwx}?x48>x-+6Mc?|RNyE;+}m5D@=o+<$yfl(oByCw#*TVRP; zp^lQ4q7Ex2tMl*ayCLXos?Na{B!xSU)6z5ip?@3>!=Fh62{6P!5ryv4hIR#;MLMDt zrU|)>7n;drrvKax#!c8hoI~|tli~gVTz*n{@G&*Z4A=GTL-4{};D=yiJc&#s#02qKIRAEAo3b-0R3EJk`i4a&VCj^drDdX#mk9s z2kXqE-8iv~D_t}=+gy4q{6-Bix8!cHS$ET4%4IB)y`=A}2f&h6c(NVjQnJ~`;&pCy za4m(+G+qrf!2S3{nTl?5FU4FofWM$jbk@yyEp^u}Q>sc%@k*6db{E~C3~M<~FgBKb4E_~Dhra3@o0}XGz$)xRF^ujOXT?@k9$WxFnrYw; zoyRY+6zqY>tMZF2Zk$f1UdYyP3M?Da4?93A($W^fh2ZZ#L0^{bY*T1qc+<2dXfOK1 z>wK>J%QmDd^g915NvFH&i@1*d92SSiaUZdWl$U357P()ogUwWVdWXc|GO95-jfSi9 z2C;SQ6L25$5Q;uyt;imdKn=gmhUh%(y52?`f%k#r) zlsy8Z&r4dvqOdHDp^v@r%B?cP{Cx4bSnBGs5j+>~i7SNU#1U2n#hAtJGVkS%n31%< zEicC5Cvv(Tg-)2UG@ILOr?Rs!gvOwf+zs2p;vk>M4-!EGxxq@@mQ*$k$N;+DFVV|s ze>f+ANEY_%O?6pPe%n>$6;u>TCknZ+et0VXQxkUzZ1;QEc$GvJu+4e^dZKgclDwH8 z0Xo^e?u7cljC3(Bk1a}flOwJadl4Y&NxhdmC;N0p^U`_u01Z;{u)QA@j>I4RcwbVD z^R0a=w3ZH$ABtXRgD%FS(RMuwu4M=9Dfx|AV~c_aTMzz8N1NYSmXO%`+ROrpAw|%O z73Ld#2RV}7F^_FZ*xatdbyy8o-Jaqj$XTCc{}KyflBzA5f~CZPE_i_)%Cfse*h9}V zyC~x=Py`zgz+E(+Yrf%ggJ0Yqf|W0AI58*M?8jSK$b|JaTNBV~1f{=QJ z-YhRG?6>=Eune7G_L3&#HMqihx=XTyiZ-cSS+fNFA!~^2L)pk(CyXUq(NwQD)KKQ;^h)?2W`aROr6>P!9D| zIk450?JuS!SjZZ|ZmO@{1=5+uz=4`5i|l0nU>Rgu`!jl51P`y}$U{RA};wQ*** zn|wsya~>a{1!yT*KO|$?g|lode~c5+O1_Ksc2nqKehYoTCSwMNleOT8^ZX2+Bg@dO zqyb*5_K_i=v^lA}xJKp%-Y=$!El8PTaymE-ez1@HF*J>>hSs;?O=VtmOb@4x>$4Odd(R*Z%>Y!Wr7w~F06IQve=t8u?XN4`)QH5z5aK?=A?dVB*NX$S{a)@bc z4w!;$C(o^ZvO>3zmQ{D(fMaNkT|{TNrTTNZQWi6v#aLQ{pZ7CZcOCB^P_FNa<76S9 zqI&a>=|yveEdd|94_GJov;M;FQSEs~m54{UQ!1_PEN|IFAIA%tXmMH`)aA$|GuYO~ zcXScb61L`J*DAGtJn!6Tm30@z-YE$)6Z6M!?ntCA@Fq}oK zre$1H_b%=xXZTU3rQEMO$&d;%n@l!aOrN*)cs_O#&1J_?6;O;~Ul6BN8NhHf$6d2Y z!NZ?fLxfEauun}3p#u1^i{*3d9CFqC&ST*#>Xh*l=tWgazJ^E0 zA-K)gvzx$Q_JTR!*Rv>W$T_%%zpta^K>8`jL|e+fy1CoH@9CT>fhC6Tz*nx2u1^oa z^{6rF%+sh7ziuT$+Cj` z3~iAq!g`h^Q|vKERT|w~b+C>W_R;W&K0-3H3E`C9O_qz|c8l8uIN1p9(bn!YSZ!Md z0JBStP*dqQNUC^Mjl}V)=#}`zw+Si5v-~FAXo|81ex5#K`pS4T74#vADi>dfdoaT4 zgtT}YoXH=zBV9^A3|Gc6W}eAR_sNVhN%k=JeGwv1Yn4?j088{aaD<;y{nZ+oR}Qmx zNKUl|?&S4ZF;E^XU{R=?D=O--Lv|pKW~oUAb&q}oD%k}x7S13GL&9d5tizwdg1WCR z;97|+E(?uBz4aP(0PZ%is3n>o_VP}2M!sMd;UDIK+lfAek5nN%&d-n^v1v@HR;~&B z0dzE*0@(Cwc8Hcvik%@jcRNt9Ykwa$`1jAANG6HT7+?FbkW|Xnc!9ao$Sm$L!YbP z^dM23{OabBks)cB)%FUB$e&Fo(w87#4^6d8Kxg?xx8x&SW0o8CGZ$7d z%TRMyfh>*gz)mQ*s$<=3ATK&E*8rO%FBCRAcoX&H_8~ z<2*@~qM7VHSr!$+?ZgDJG62Grej&MT+S>2*XfZ{7DB{>Tnu|O^SK(7dNqL)zwqjq4 z+rAeYLdLOjX%_M%Z@u^G$e(!b=!keJ#B$E#ALhn&gxsCV_(BsQe9 zx{_ponv87%CIkN`fckC#awh}AdJxD5!}Y-~GVo!co-=^Gm{6}BKx3Mq`z_GRKm!7$ z2?J&g?G1w6kWhaVz+N&CJQw7Ff&UfYTQUf(82XP2a;m`Bh0ppf@L@rpH}u;V^pk_! zB=o5rXm60`1`xY3*mMl-$=E7+EF9XN2Z{*tkwC@5d`5@%G=Y*q>ViNg0v!+bmqUB* zz{>;>`zXj;f*c>(&W6uA8YpKNr)ki~2mP&JQ#Gbg&;qbZ{0%rCCggZizneeP8$Kzq zUkmn7dehq8~(bTj;5)>YTU&q*D(1Ai>WGU9IIhj0_mFP6I; zvX6TNW(Eh_P3N>I9QK7~>82Ui@8bDiXikax@htK()w%L}kVxFt!Um-&)p1P64t+ODH?YluJz>_t~{ z2Q)`x{SnYIWKMfpCF=(`xt$$%`R!WMk{(d)+!5Z`byIhIKc3G*T~Ztfk^U=%)jgkE zHsG=BFiyu|2(0_7+H5-azJz6F5G_OF;SK(q7{X&sdwkHnYi8>u{-HkTl2kj{m3ESQ z-F!0~c-G#Xl<$X`FQwafb^Z`!=8JG7zlcwm%zQd56LMBxq3gT}S_%HN`%FKy!XB|V zU>E&`J3(UAIQA5MZg$Cm{w}FS&eEPC`xJ%8xRkc3*l!MS3H!pjG*R7j^>GAT%rENv zI@})et7?t@#NO}^kg#9yr=kr1)@xhH7GPf>k214u{$q1bPY^f2S@nfUr(2o3IM%nJ z(R#SAW>4w->ZR-^%JQ>l9pB0B;OG#9U6V07AL#ENg1sP7bVqsBep?*M(?dxb}t zrLL!phU3E;bx?V9Ya0{p22RM{xMm3Bn(%d!@oKURYN%7G`W%X>0pg~oF><%=tiJSh z*g|;8o04+Tw6Q34%tdvydY=4RNJWUnkty2}{VQMF>Reuu2VKLpwJ z0C!t!EzIG2W#T9*5n#g_>qd^hz zSoPwC=`ZGd02^_By1C5r^3=XN8H9G*kKAe;O^Tx;JQpjV)3c#I8!so5z)g7_9EZUv5G?+lvna#QYuO#}4 z?Yb@Qh<}nBSOJwAeCOul$lxH8ondmeFgZK=zslPR3hl{l$?h%u0wp*}2$LPE5A^PT E0oe+fJ^%m! literal 0 HcmV?d00001 diff --git a/wai/ops-conformance/certificates/wai.neural.int_mlicpp/7ef44f3b1fc4a2df6c3e3b68460f595cae3d31cb7f9018699e29e738340272a4/h_s.whg1 b/wai/ops-conformance/certificates/wai.neural.int_mlicpp/7ef44f3b1fc4a2df6c3e3b68460f595cae3d31cb7f9018699e29e738340272a4/h_s.whg1 new file mode 100644 index 0000000000000000000000000000000000000000..b364ecbb95010ac3caf2e2a3c06ade347a4d705b GIT binary patch literal 8694 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 IN|Iso3-j+VdH?_b literal 0 HcmV?d00001 diff --git a/wai/ops-conformance/certificates/wai.neural.int_synth/1c4705d17c01f865b20d785191c7f63b5c18dcc8fce77e15852cf8240b7368be/synth.whg1 b/wai/ops-conformance/certificates/wai.neural.int_synth/1c4705d17c01f865b20d785191c7f63b5c18dcc8fce77e15852cf8240b7368be/synth.whg1 new file mode 100644 index 0000000000000000000000000000000000000000..ac77dbbce60bfab2d4c6edc4734756398634a028 GIT binary patch literal 3090 zcmajgNm3R;5C!1=WpIHD3{T=IfF&yq;1OIKas_YU6jG{1|! zh^YG&asM8X%a;3l)^OFUlP?Y%K{{$OxVyTih#a~4xr<*$!x6igeey}dV+s1>gTMSA z5k1)Q*m&s$OWYj#;AwV8y}n|Ox^luxT)lYbV=wl3Fkm%|SOzFfWa>1<+lu2=1?;@zxa+2l?KYmXBw5z^5m_dIwLo zoR}k@zj6Hav2S&H;8O1PjZ?oLoO4~?jUO(~Y#i*_ogcrxZT)=q;cm9(s`Z_9ceGmb z;(;eoV=lIyaM*BgC1!9}>%fuMy{3HmWeI~{KYPGIKJ5;xczD3=?qQZMPTezYSA2F{ zPWY&G#MeJpYYV8F1x!EYcD?Y>4~3y=79|d4?gwwZx2KbPTj8^v+Yzrb@H9=ipEbZ z!9jn$MyDoZM+M z)BO5(*LupAr>B|mHm}`8jksF8%*_^;4~Go{2Ym66r)v{o4yaY&Kjx zVdLIi!xML4mb;$t-Ek1ZhtEvif6B)%Eq#maTeVAh@(KQMa0;htOLjV8( literal 0 HcmV?d00001 diff --git a/wai/ops-conformance/certificates/wai.neural.int_synth/21f092964e1319eca7e494ba3f6794e3166886d50e9dd74d00935c5b317055a9/synth.whg1 b/wai/ops-conformance/certificates/wai.neural.int_synth/21f092964e1319eca7e494ba3f6794e3166886d50e9dd74d00935c5b317055a9/synth.whg1 new file mode 100644 index 0000000000000000000000000000000000000000..21e56857c2b1e3d4c79ee72c7630bffbc6187c4f GIT binary patch literal 3705 zcmaLaZEn|95XJF-5ebPg!KJtgeBoaZ8}`B&gK$x$U><3*?gNJlvTxXXgIe zgkOGo{^QlvjPIE9JTJ@sgXbP0`JdBn0Ux{%*Do&mjCTU zEnna2X5Mtic5omL+<&KWiVHrlX|k(}oyAE^zP;8bPWEF?JjBdJ)QjoY`Fp+@>w|x9 z0LL7(JaKchH~rP}<-q7I^y2G}vsw9iPu=&!r?(Jyk89lV5wi=J%`3AT&%XVdUzWLc^rSVw$`Td8{ zH_OHWCQ&D*1}`(Q^)kOc;&S@Nlv*6+sqLPIW2gGX0e>Rj!HG@G z(Y|J$x1!g2a)_X*zi;~SYed2BPQq1EYyuO96y?H%3Y z%C-}Boba#YQ-&X4@a!;_`42$6sFGIv(Cd+>B;$;LB5MXYkaR9XGS^ zY5S4`OAMZz=5!CceexZ>Xfw(6E{+~F{;*);f)k$l5PMfUb$H++u21{1e>kvlR72P} z+DU!cY6%Xo+M7Fqhq|d_^XDF4&-$q|lY638PqXOnPM`4AimTUGO}iF*m}>`Oc$i=9 z+~fD1rt8xV#Fu_%gHgRVfuT2BzCPYa4j(5mn0o6ghWE_#4cMibXfu01nDXPxch`4W zZ#D3|qrUR+wKrVd;~`FyaP7yT;mL;)7x7{^@%56+hS~cpbiP-2W~*;J<;PEre3-;c zu!tFnI&TR_JRa`M;FuHFey`x$vzS`Bz8!CYw-_EBn7H&-dU~tAHNBgK#uX-tCoCea56*J+YIo*#Cx@7mjstG6iF*0f%ZnRcdOGIEkKIn&!NT`{BXNc2j`${U z!C!wI+oc%6!A$b)Q@%W0_`5o1=JEAcho1|4VVHr~rF*vid^=}5Y^OQ&hzCr2!2zeZ z^d4&Dm=nI4rVgfjI}(Fw4|3&+i{Uc!aB?RHw*DP^;Oo)8%!ijA^6`MDmt1*r*!sCQ ouNrq^^7{_lFLeHHsB1UA4KvHt-&;A~?LTwP@l4^}IUuwD1MEw{!vFvP literal 0 HcmV?d00001 diff --git a/wai/ops-conformance/certificates/wai.neural.int_synth/50868e72f5f1599569c413ed1f67ab8610fa0b3c17919162cbf370f49275125c/synth.whg1 b/wai/ops-conformance/certificates/wai.neural.int_synth/50868e72f5f1599569c413ed1f67ab8610fa0b3c17919162cbf370f49275125c/synth.whg1 new file mode 100644 index 0000000000000000000000000000000000000000..9f7ea372280e6939b74dd109d67165dd59fe540b GIT binary patch literal 1160412 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�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 z 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∾D)wdvDKla@!zNc^czUT5|OFVP-&dTij9SnYkx(vOgcRsJY`NbQ07)Sfg zJDt6LlPzzJvwZf|3mgCLthpYkEnengw>*7z7`XGX#(@vn^6nyzKF{F$yu*b*I~y$c zVx7&F-@lDuOR9m6ue_TMOPuFE-0rFv(tTz3GpjnCCmb9+>(=pbUfmOQiI-O$F!&mM zW_G`4x*m#W=WEEv2FIGnW zpQ&W3lWL1MpL%nS`#<;)KDZKRONvt?K7>u3oh?jU*ta}9`?t^by(_l-`cXc4_}H7_ zSofU$G*P#BIvDXb%V(w+*L|7lICbygu<_N4M9fsDw}!)yKi}?{wfgX2Hr_+$#fR0m!LJAZoTM%)+N z+Qs;gaH^|G8|@DM|14dd4vaB(5(Ve|8&+0VK@Kh#X{ ztPf^=h3EH+`saJQziB$R^6;xpdVX>n-Fa(%>AgSo9|wY;8Nd3gM)|76y@hS~d)q>e zx7cvS_<6)$PrTD`laJ65+~;!l!Cv3xvBuLN_Vw0Y9NzNu{J2y6#pBK{e|TbubAW{p z(NldF!-w7IclCV3@m}q-H9Zd9dl>Th?-%~_&-(5CqH$< z%7*t;myZrd7>0FzFzKc`pDizkxtMxpmP@SuIb%9J>^l!}o+I~+FCYBMz2*73D|`u` z#_#gv?|Zczo^AaoU$xNd4GwY|czNdK-tzGEOCIm=*6{KXzwPa<)nR6ri%p#T^1(8b z`WTk{1Q#}b_SRur=Z6P-x#WOP+(G%vM+Y}fF!U21J$$tjF)-ZbnQ zpS^3?;lYK)2Y1}eaQKqW#=RgtmwXJpq{E-oXV1e-hbzUHv_s#~sV$q!dj z?ezRfICOIK_jCSq_{A$6`rcXb@;tH|IQe;3oacd$^I!{;4qy0w9^dkwY5JEZy_o8> zHq==zcRam3)+GFDl#4ANcA}P!iztS<%AoT&St8s=jCrLrX1qjIeVP!XFlw5#2p5S2wZd ztKa4Zy}b3t9ySh}j#IhVdUnK%VWV&E9HzclIQY8DbYcvCL~ft6d~h?IKOgso-Cn+8 zw*1!hlZ`K-vvx+}(r zda>>F$Qy1h#$<@n&~{h^h2$*Y`k}zN3{>touk`EwK1^PJG{53GyrSk=zPA1=N7059Av@7(J@AH19?j6{Fz#Txc}aPRM>;^4Avx@Wt(rn-1D@iPyJ zr{}PoV%XrotFHRMPv6RegR_Cff73nJdL;%PTfK!R#vHzTPkPSH{0R)T@t51oUo0Mk zkGE#ef5e_o7vB=_~7lVy=T6lYmoC-=7ZH+NWSv)3zgb=K!T`{dJ` zdSDixo(&I!o}DfHYKYHF$4g$%UiVGEh*&bX6L_5sJskC_i{Kp>w&JY~&(Ee?heMBR z{Z20yHXH14*{fT=`s%K}GSk^$h;dv+bUtj^*~FW}GOL@g zdDm4}KG`~Z+zh!p%kuCsejw&B@?<$ld{|9%($Uu?YZ zVebHVQ=iz!&s^BO2Z4D0&W zGohaPGV|H(ogZ$*zGtbtu;~1J#FtNbaTmAgFxcYXGXaOht9L|xZ*Taii?20YIrw_N z!0KGKJ-s|^au)+LZsm_NpKP6b`+7F0%j;Q?4_>_Ug$G-I;W$J420a}7k~bgRYONPj z-I>ba9pdNq{`ROoeW^|}KbQ$l>G9e2-i7pfq>lJ_cUB8OKJ27>sTMx4|s^`duv`NNfqkHH@^EpJUvXLNqf)!KJw7lN`icO>BJRq8AI}{Wqa; zVTb#>eW6Rl!*b8c!9NT$-*ocZi{o#WM}OLz8~oXcSuP_SxcZ^*n{F*9+_+Wi)TeiE z==iw<@86&F&G%=*)^mwZwUi4!9WL;;J>km-FP!^%w49y;^^z@5dJl`0(;ja3!J5sC zBRy>Ow`Lg+*O~k_T?D=i>o=Xn78|n&Q%v`QkI=-YkN(W!8 zb>CUy{`yy=I@n=sd3|lKo@x%$Tn+rhz;Lego32;%>e2&#&d3?U<5yjD;W#U2K?hGR zHS;xK#T$;hHTUoL1!^v4ri-CVFOT<%J4aU?>SXg=!c-5xKiW*_-2I++vwq@K z|J3@wx8HPF?zDPgyFb2rb_VwN>61LfY)o~}x16MNl_#Ocmrjh_{OPL8`u*%G56;ER z_t)$TbK!*|p5NUZzdXPSQRC;sIPL;ikN##wzNerEdmUJOoZ z;=k#BM`#usSL=AHonC(9^?|{!cypfx^nF%zUhHwgf!M1bw*98BFV^v3b3XQB2zx!I zi;G$P_?a7W@T-n(&!(63@avBmPC0ReQx1DIymwu1>QBD>2s}CFav1FN`kODi{@ELZ zj@ZLa>YwMsv*E6go~dd{XYP5e4{A|+9O26+mz;hs-16R!_THIv;_4y28pPp*2S4?S zh3Vbtdx!k=YUFF+E1y2X@JzV>o^!EmVu-c8hBY3|?C{x$8D1Ft+S7@(=VwjA>)DW( z-Hhj^@BH}S>KT0b`Te@O)FUT9`S@(Qcd9%+SA6sf_ww4mvCa}#@$}BinxEMjiiK&g z^ON^|$H>bjj-C(P^xIyIbo`uII#`C<*gL;C^P?l)b$p4l)+7Dv4)Eh677z9LtkDC0 z34Vr}aP%H=9(4A2)cfu+>^S`}A2I&@F1;Afi=6oVyA2q4;X~lF^M!*G-%S@UkDQ%n zzWfb&_|RMHV|`Pndx3+#u!)hwnOOIoUd`KHZ^ZO{4em^LzBu5|R}JvwCUTqO7Z1K- z^cgSxu~#=+Sk*W6^#nIUUq9@{nw<#@HP%Bq_Rfpmvpv-bz1m?@nE5pKH#zyr%hp~D zeEp%*JMr|JZtf1-tF8Wti@OSzxIb#K@9wAvuT9^*#}zNVhbi}_ ztJzH0;fOcz?^)dT;;X$HC_-6 zKUj3Qh;_!BPWSeucMY95{ewfQLmrZ^eD-F(?pK_q`o15FgDL-epZMY@*4p1M^AkhQ zzvsbPj@}XREWi61@A|J^eO6bwszV$d!A(AUcEjHmdsiN+2l&#Ig|P> z9u8b`z#IUJbsv6&m}Y=)ZQdk3lUUvKpJOSkRu zFsrlA$}KMrPk#qtQ?tJ%dKbV_i#>c24;-!e%Yg?U`h58(u=vR1*{CKMdTZ|9#sfAy z`}|&PXM?-@wCVmWhJMRK@4UqE>#XeAakj2Tf9vYZo$0n`gJbP};p2BWIE1(52|HYU z_w#c#;4haLHTyXfU%3Usp@Us6oP4K&>F#xhroLL`fJI+D_TuHy-%XcK59DCS&)L)I z367*VIg@P81fDo+`OL6j62AQ#uFf!CbN&ARm8#KMi^CHSy&zkjzMA;Ri6?<)h$Ci$ z9S(s%m*a&KyBXJCZm83G)78{Fda66?a>3!}9QeqKH!S>!cR4)v?!0rC6K^_m9K^zX z^audDO2Y0}%$9>*AEB8jsrjspitsipZjnn_w4AZms_7H!cb-4N8>c=&{ z{N1y3;`pn<+@77US-;FUnY%CPyBqpkU*Ylh8B&kzeb<2DSyaD#o(FxRbEn1V%Ue@x z_o^B^e|iEJcerHg^MQ#Qo^Wx)OCFpOI^6jh@Wh5GAGdsw|A ziosEwod0}-?;mcq-|}k4O&&Jq{jau$qYi%Ta&CFKx4gB_NgR4-iLVBqwfx!XiCG?N zet7Y*w>GjDBR>qiB-Ubx&z3OCBMx76>**``&e(I~4P7d`~FMpVL z%S~Us{N+-gduCsLe2IQ$vyc1K=g(&FhYiatSNL0AU7ZUI9O7uLPYe6*ymfaJ&dhf| z;ETuGTpSF3hP$!t@sdMc`hL%$C+wXw{_0L|Z|!cG-AnP_i}8lbMz80%SnHSBeT2E~ zo$HpjW=n4t8&(+h`dM%J5V7jTL9AS2!qXEreZ$RcPuRr5fDcn#cDYDBb$&gUbny6! zH}o_NcyZ@9)7`cDlTKXs%DXHs>_i+adb#NIo*uur%EgvXcLC>m5hlE;PdYz+5CgM% zVOfh8QyiSIw!9viyYKk%?fXG}=oxfI?0RV}x4oG!o!s);lP<+RJZUZR%`Kr(X$u zoINYs-gCo8&1~|&y|*tHF1V4NS9@no_udmR{P~&Za&^HY^;oXzrjLWU9Qw)M9Dn%R zUN2y7d;8uCX4szVa`M52zICzw?p|&-Ycso;?z8X1Q=JWOez@p0pZHC6_Z)9_IrWE+ zIJKxxoO?ppBV}t z!4yj$4t)2yzUm8{xP<9hcsY5`#sPn8vtE(z9KC(-wQRoI)T=EoKQ8j?z2`vx^^3h) z;@KW9AF<-%f(QIfUw`>l7fks2f}{G}Np||)OZ0Ndi&NjT%VmCZ<3IPq69b!%wV93h zz6RHKh~lTZ`px0WnZ26jz_A|lQL9{Z+g@I^sF{t>o4apjKX=MiUpg;2<1eos^V8SP z*`9yAw!O13!}We;H*ki@7a#dZXQv)Momub8V)Tpd7n|iL;?;|%cp?{G{qNfJuI3{S zp4^*`YrMn|-!E`1|CZl7M7$w~dtr@leQH1T<(TQdBbOVl{BqHWh1K`Zo)LEv7C%F- z`o8V;NgN%#dZboyn?5OzT!#Cbk2tzbcekss4ff81AH0M=%E93EnUg_3D#2eqwt6vH86Zy;{_ZkJx4baLRM-s<7wcV=|>^7r$lbKu)|6npvO!ykWKy_dRs_Wa<} zd5-m&|E9y&M}u@%y2J9|%9m6t3_gU9c=+~w;D|HJEuX#_)vOQr&vZSnW;(nLv2f(F z7H{rZq?aF-TYau=nd*3lDMo+dXpJjBJ+yLH!)OzOg)kkr3Vhw)kRAZn2^6-OgZCIDL-aCJ}@$Wqz7k3=K9*f^}vlu#lW`me} zukyF%6Av6a4;XPM9~)m%O>p@Br2Q!;KQi@6{iDOVTAj6ig_~bFJUe_zcTg^3))V%6 z-WlWFI}Vl}(Iwm7JCCgxHvM7ij^X9G6puH-k?6_G4WG_~zxR~bdZ%BlVYmn0yL!;) zLC*zFM7~5WxYf^2*ASC0n|%BeHu(*8(~ITjS)J;8E^x=uyM5F3u2_3(_IeyAwa~+Y zZEYmp#7=FX0fy;ykVaF^+Q2Q%w! zwN{sUIxjOl9BUF**mxPR_}~cJO!&z`=smmjqZ-%^F)+6L?xg$#jvhAiXPf(%*P0G) zy!gv0H@#=Ay6p9e@FV<)cp?v*dyt54luMi;uJx9eQ#?IiqK7!y^WE}tnAyGS)WODA ztlBqyXB=NTKH1|l)t!5soU3P<9-eryaizCc7aKi+XCE#*UuWf6wX~rJw5JJty^QVaKm`CYv}h)yk(ej`sQm!;p)_O}x8+3p-(NhQ-!%zy?pvJzwl< zVuNQ*_~1}Z_-rt7XQLC7w5IP)Z~5I#Yc~F^`N5UXu*R(#@iWNOm(NUK8RFpNbIy-{ z`)ZX#-|?-_zDszgvhioDc5(8k-5~b#y$hYISUl>xdE2XL%c}$Cn;*uD!*0|UdA2>l zNi3;X@uFk*?t<6P9O~0gHa^yL-8;EpG|S6Jo_b?Fx9>g0zkb&bIj6p!z!D=T3^SdX zSo3G=?{IVm47FK@!Ph%295x*AEUz`4^T3I3yxF!r;bZV&hs9UiwuiapVeo-Z_=xlT zSo?Qv^xm^@__3=ArvAY6^Cf?O(^LaY&!ZagVzU-+i1R)Y8`hSG>1SDMlD#-HEP890 z?z4fK^m)M_PCe^8LeC3qaq=W|dQiXhq5C18-Z^hN{$k}2$B#c==6bG2 zQ(Ya|;OL3F%@caiO0#_IjF(!H3|OW`}czN zhRs?|eG&ts^9rAjcz(u~mzy3py{F^zo{@ET&(A@y>3T2W>Q0*B57$-KR@E`z~RfU!ABnF)Ol}t9C0A@*3Ln^-)C6Es~$Mw)S%|h z@Z}_yUp?l7cX#9Mn>crg@Us`sN4&jQI^3+Q&;4>I?E9Hz%llc?ze$A`CLHy99$#Vi z?`z;1^=QjGD>?BnstFf%J#P));76>9eivuWUz|1G*6eCA>o*?ia_;OfH{Gm<+n(Sm zhL3!dFx4bh4}HdZ_T|-Q`|#-ECa;|K-Er#%{GMaDV#Cy;*>NLpF81<@ZQ#|w zQyBmVVn4wuG-96IgyZT z2b}5TA)QTqEJyc~UJjV@>6^h0_jmEDeWs5OKSLezoB8RTJ17TCJ#xP6c(8lUx4b^+ zkIxJ?d2uobyl`7P3*tFoBj(NkzCq}`d%~a(KR-NsR^{iLA3cA$yJz)E6 zUo+h906Q#s;>L%4({IUp2ltAiK(ZTlq+w}eZnVuiKW_J2w#P#m>`OdF* z4O{qO`5Q6*_Ui0@^PB2$J1>6vXeRG0P7mc1#|GoYql>3`+uL^r;^M*AGX?|iO&=CM zgub=BgihbW-}Zd$VTGrM*5bv=_2S9T#)tGBzx&}?ELMEAb^gAq6w8Lkrmq(H==gYN z$gO__uJ?%9+jtq&i>BZSV7w4sK^*4I7qtd(SSr=R198YKBqYx$r6t8F2IBdG}fMZQ3r!$~S55t-9A=%7oGSs2>B;MA1Iwvzpv>bv@u=L0LTmJ?V0Ti&_g zNaCz7)~^n>^CI%YF}6HEYr>D{nYlA-Z6?{R@iN4#S8ege#lGM7;l)-D-dHv~*!)aO zdj8@IiylvNb=F_8grBu%g5U+CXM~R3(9iV#n>v2}jRx#+)EieZ^3l1UeCm1c>6z|X z;Mez4Icmo7t2`=zWKTH_VI8B^rBYj4qdu7X_Z?ygJhOA|*>HE@PId3s>f;NOpB~X?qo4ZAO%Jnk#Dfpc zo4)&HO>giw*8_Nj4tJd3cGmo?%{a@o?RU52l9%9KP4qC$)zF#I@ujzJ-+N4+eEAvi z33IA@-sN*{^aPeV@b$A?_g8#(m>p){1-3jt=LN4m^xyP&pTPgkhIb6?Ek91ygwIS@ zn|$#que$iq)8SwZPhO%Y)$4l+8yzwGZ{*pD_YV2xPt$!4Sa!zp!B9^+yy)b|1%CbC z@_YW+=<#yqcp7qVI$b{Roe(2$v0~)hbg^4rPIso?S;zqkCvk?epo8u2{mx2m*!;xk zhY=4khVKVcf6q$&sup-~iN2Wm#}yv=v!AB>jJ1@@I}gA1#nOqB!@!XZrZ^n|&gkXM>+ugRR=FiM=^~*3}{g7lTy4XC#Ru9Pddu{LJ>aTkEme;A`f$ z<@X(fFR5SF@XhW+xbB~Q+^ykl`kpT~dZX_x>Qc+5-}37YmET^xA*Vf@w;p$@`z4MY z*Xp%4Iwx4Y^XC4&FYpmF^Tn!7T)me+96p_+9l=aB zU7;6iZwV(hESn%>^L>FoO0J>`SHVci{rMLdUQ`h-n>dClaFwdPCD2e$lt zt?_}e?QzSF6CXW;k#t^kaQMT8Vc45{w>f|NA2)Bh|8`bf_ehTL#rn+T&qq(?GyY(s z8n^u3aeV8&I~x~ub?4(6C)hJzjxFyV^Qm^+;P#xw&pr(Co?CfHIbaZbT=<*c_g1*- z!rf;E;b#!IdczJAC%g^V^@x9KdUx2o>HhadVB}+lm0cVOZ|1|wzkGbM^{k2^W;tN7 zsVP2j4&VC%7U4(mo%;0oshJK=SaQ^BHP{neJ5RoTzVV)B=a)?^Ut;FdyGmR&I~zQ3 zpfljaqn?=KYu)!bdBZZ7UoQsp-P>)iZ*+X%6Y=hC_H6j5p`17wd|P*)#3thD;cmK` z+(kI>*qs|O=f}?9zVpZ~C%wIO_40>JFP`AWPA3=1#y=gseYX1j_N6<+Pad)C-pR#n zdC#r9IJysfoww)AInaxPC(biU$~E=r?cuQLRsFYD54+k7IQDu4f75q{_C!82AKVT7 zqo*rBpVqyH;q%9Vts3aN1I3u@dwt+9RxWmN?t1IE`MxJcEpck9`(AIwz_Z?Tb^3QR{Qqu){TCa0 z*Lm?J?h9SK`mQ|JkDvAXoZzHpvmB&W{Tt`mD~r^IGGz={U!Sj?K^FYBKVH zr3UX4e)j2bVdG0DkGjf1&qp2faOEL>?q(Cmzuz&k(UEE}tDRqWgI|4Z<|nrOmba#B z(DCc8!l7fQlgD>#>)yxPUW_>W?TNj!;A`((iD%BU!LCMs+lOy$;Ai$8-*f^;|IB>l z@!yM)ZEtU8OJ|=y9qwj2=OVwJi=l&QpN(EjQY>zrA+FX2|9Vsn&X&LLxaEOw?Yn(B zVW+oFFV>mHkFDPiS9Q^HUc*=O;J3YBkU0e)jsLCVtLLetGzr*{tc|_usRpbB1{1!nZT^ zd1DXLd8xbKeTe0!4w%+><0Gd*U`};*&x19a876!CHx?dTHgy_e%4Llk3~T42KAgSR zaK=roq|XdJ_ns1~Z~te5Z+ZC2p&#n8mc!cluy6X#pI^e3k2q3o`t}cJ*EhN0mD64y z#Hh1aGaEm(ST|c6dN%Xb12Ykm54$~Ix@zMO52t+O=fj_07`TM5U$C5!^``Id{^I!R zna?FsJ>sW6v4&l}W-&&&*gZpXI9uX;#Tqyma=v-hM4!OJwYvDW#!;Po#Ko0eUjH6( z%X@Zkpc4<@o*(Yy{ru#Q*-GIDHo9^J>%i z(DCi_nEmBikLPmy+3DcPhXa4_Fg%FwcJ<1>|NT;aK0jcv#}9|@F)q~z&z?=5Z7-Hx ztXi#!n!Km@h*7tmxG%)_W&Zxo5#KGZcg_P2|1i|X@Ao&$Wxwh8!~W9^{Ob3Q+v^K~ z!^V#tPHTB!v8#zM9nSRTdd@c0_snj4IO+J|2H)o!9P7RtJ5v~*6|>KHz4zH+?*Gpp z46*#=cOH26`__Jrn(2Gat6M&?M(@mOGdsKPn7!dy7ccLo?^%OEuUFNvD-rspF^LPz+u z=93*hUcDnaBlpU>dntzSZ`ivpxVua05K}+oB=r6_tm>h7XXRbQpPe6(r=P*5zWQ(w z^YRuGXL@_W52kw|Kb^hWdr#0Mbn(Z>p1{^u!nc~N<&v|0cdmTZC9eA!UflDE6D;pF zez<#Yz%{#jQ{8E#!MAsicP|Wsf4w!U z2XFYeip9;qb<^eKE1o~Gb`QeE9R|O?*V|3Ak0h$UkA z;N{FZPh73jhuQlPH{#vp^QC;@Rwo}eGS~Zg5*EJZdZr#Rbo~6>pM9$Dealv^xQq3B zE;gTk^zR+$obqFb?{3yV_tJCRd%~<1cb2$2_{5Kn)NlE!h2HaI@80TT-!0@6!>(Sq zTi%)q^OQ$NDRlg{255x!=*;CiOu zh_m-^)XL{RZ2R%p_VC3T1P_?v4Z@~&=b-QM>xaRg(5a8Ot2l_G6T_DeY|mu%`gyrL zGhHrz>cHExA#XzGGi1{VeYn0uv&$(@pEK4l^pD+;|NYJ|^Toy+cWZuZ_FH~G|IpPZ z`S}vFvv=3U>V@2Lis4J(@za}P=wb4uC-z4FHj*!WHNYvR^I!{~zxztZ4<|Dn8$Q*x z<>_WVKX|=&tla@3E*$Z=`pynh&&9y3FP;(kowKv|`!luww+(uCdeg08$JyDt=l|sA z`26rE@Zs?1>wOR}KAvBD{N&+JZ{Wu!mTddsxj#M=*sZ&}J`dIR<7NVn5Aj`2eSQwK z_q|ff4!=I`O>M6h{374@uBYw!^I1pJ-nU;wYZOZN%%DMkDod` zE3LOYf$80>4tBhVpBf7?ZOTqc;pY7Iq$V`Qz%jv8Kbbdf;{zX74~a*0?)U`2GJvQinSn zXISvzSoe(4@pb0JS?3G0`nSC2K~5s3_oMvmgbk)yjdAlC2Cv@exjgXrs2gAW*wkgn z!_S-#jC#uU>+PL|&lhLVGiI(XSpR8zeY2LM-<|LyxWKMwc-7;DoUn`MV}5J*4pBQB zKZBiLYqs!xU%}t-T=V&_8^jux_+rgIpVTCVba&lH7|uk#|GT}qU=TXB*mw4wJ3DOi zrknX2xZ>a*$mtB_w-=Li|H6?+yfYOC!|2{mby&_6FI?%^#mZ}M-Lq@Y4zF`juQTPB z@E1>qE4|$6rK<)w_^O4^FE;b*8LXGx$KU(eUtRogcCW4JaDut%YNCgav$NqNH#=d& z30Kb@JTU}s{`lIfDSSTqN-tJUex9B1U=uOF+E9Z#A_t$ivBMy^`TX2;x#;;5cg9*S zv4)&<4HZTg3+^_JgfMD?kSouAn9YF_ITTk`+>C@561DkH!t7FUW zp0JmnKcVX#;Jpzh4C1_C);qfD?u=p4nduBY*>v1t6(2Ww`M^$kM)V8@VSjrho=psl zc-r$7ONWoUF0Y@HowFfl9N37xIM0){IQ^#!ui9q5@96GFJ>=_IFthvLH)6xPzL@oy z4o`Xb7`;=~g@f}Yoqf4xx|rVUYJpoFaIN))bO+%i{N)zwooFqubB8Oo=Yh_e4^FQ|IOL6HY_TYB$^kb%@1#%kv9Q4nKqH8-EgizWLGnzQ%^TS^myS{lp$WH8>CX zecr&~k7G9V6TeRsBmbs*PkNT=yfghSMqK~9Me3RAeB&oC4*J4|-+M3Z`^?IZFOKSg z?=vF5ZSUDJv**jNTxOijge|f6>^0+QFSi_V@HazsiiPDY_=Y|8^~>LT>5J!UFRnW6 zJ8PT?-tzXo=F@W{78hs44~~BD6@weWkIvd%-12hcV!&kU`$T{9po^zjf9Z&QeUwvv z-vg#TA2$5dAvX?mxO)%QLq6M{oedw@?4Eh?`C8-Z{_*SQYdScd53xkPYQwD{a-#gX0*~<@?@PkLnX}0%_1N+|^!ndy{KfQs7sRJ? zEvNd@*W|2D|Ih1XfZ*!JT6Jm|d$$NLSI zpZ&zXwTkH-KhvF|bF=0vUJvEjbb9^e6DKpBLG;R6PHRJNVClX3)ZzV0-~DG72M;fM z_s?Dpa(c!HO#Q=+pIqL=~GoZq&`1r~q82H#pvdxPK;mi>Fq>EU}f zn7zYZ{kGRrJYcGeAK_=Xm+Gpn;1&|`zJnPKt4gH4b0kI;8s@Y$TRHM>|i>cm6; zeZO$Oy?=hQnJ*0ZY82xg;9QBj|H}>W?l$RJXQww{r~wCa?|5A0H|P!0+!>~$k8{1p zn_r*ZYT!d>?r!q0W_9(<)>GKkhjVfD5Z1yDW6P_HpBni1tapaqH|4MX-ZwLS&ySkr zsQ<9x;D(Fe;o(e&*B@>jo_!pxXS$!2`8q%O^`#o>)l}ze?;S2zetgTf<%#n$;L2ys zPtNYfw&$acAE)Q*=QMivgP&)azR$HjcY1bzIUCL}IN5QmHVC5GQyN9(_v9v(k)vhb@@4)OXZ#=x&$nvK3&n$_Y=;qe!5@Pp%i z;|rTFJbHG1V#IoP(6iSocS8)Dnegd;TI&Zaq7U95&IpcPdsf_Iz9e7vzuSQ2?&0S< ziadM_ym1j1e}5avUd{D#uICHedk~hP#!a8F!=UfK(_wV?>D3eu`l;`o#a|tK2ySX- zfBVdilRSD+?NeV)Ha_*)o=v?5n^-)|28{krESG&e@xs@ApyyBEguy32zOV=^er#sC zO*i8eUU##*1=rxuM@;W+_{FlrwTI!Z>bZ0GIZ%JL{65Fv(Tg$4#V2uA>Wp_j)vm6% z!XS8wBh}2u8M=ezGRs4cvm8CMJ#%z?ijm*h$)C>JGr$j4?^Ze4aA*zhhYcL9@!#@< zFMj;JTf`7OBJz2MiS-%J51;tsC63AW+dVb>sgN|L@@`dSd0PuQd*zgV$ zA2~g*^xgsZxg+r8*z!cIIDZfRgAJJ88)w%%O{6eKH}y07n?Vo zZp&MXCG>hOH(&hS!+5%@^7HlF8hXP&e)ZQZKYxOU`(xkt$NCa}waFtd{7n}tK6`V| zIv+gr1aHF`cK$xE#k&J|dhT$;Q4V_V-F{yBVK%WpZr*fv&a5A1{Mp44`OMDR+%v%6 zU8Gl&ob28^c(_M+(Gh)syXoEy`pWJzNUiV)U+3i934GYumgop!e{rpSUk5p&UE%~JUqQ~E(Bhfblcv0POLb;JEK!mdGruJ+;Of3G3tUx#NcS? zKf5)7#gAT$0gI0rzMh)(I*y$I4ti-HCLg{AVY8n4c*0h{+4C5dc)cc5fA1-4`O9Gs zk4~?=EA`hiiL(I(JP#0I@$8#==h5x#fv3sfp4zw>Jj5UW#><4Z)|yY_X@u-LT*IvKb4Y+2U++C6%Y&O!_b_d|; zjXv|SXEW@54#MefbS`p;agLsgO~)}^_lu3LUckqp`e9oeL{769pZD-_;n&QbzrN!H zx8A}h_P!%n>nZFXH>}yjs>5DBnDpK&a=~oVw`LeSSGn{&t?yW-{ zeCKB-dM8$Hz1nntgBC|`;OQ(3F>-8q&#}4wt63bbeCs7_1HbO9T;Yj-&&l5VrLMoi|gIXS8YB!tZ_6GT;bp$hTbd(J-%Vl8R7}v^4rht z{NS`Vi>7&6-_tO|>yF`)`2B$RUu>A26+3J-(N&A*2v+a4eAwme z^FW+46&pwO)yFMQ9}Yi#CH(phm7YI+zmHOj&pSF8V&%bujov%G@5Z>{WM<>Tf2xx$ zzcmcPuQTmFo7w33^|K7D#986SZb%@nIlOJpCZ4~cR=h~~ox2$ZAARkafJvsl`z799 zUgu;MW5&@t(QLqJ#Gfx|w)WW}zITAWz~*DdCA{vq=Z)W{H7l2e>}!e1SH>B?yh zr_UtylouDa7r%O^K0kIt{iIlP_YoKC1YR8J#KOP{zV{l=V&D)M?%^x^*u?j&z)*{4 zySy;Ay}f&Hjf3;zTQ9}p!7j$I$5rm0H?eToVerSBuJ2}^Z-Sed5242^J=-g=6E*PT zPbU`Na`Nrprt~hu0T=H}--&S)uLhzXLoM&VpC5f!5z~439!}uu4?Vnic4qeC{OrYt z{`IQ{x$)y4&oKD(nZ~9jm_8@y)opJrUK~+NcY{s-;_Kg3zxDj!0Sk`2?tpdgJN|tZyU%rJst53Vm&6-C z_V`y%&pscbCv&~`27i0KDvpgzbz)tOVcM6I9R^!x%HF=`zZiAM z&*ABle-laMVf*D~d$?-ggG;q+d9^yLnXX@Ai&ukKXR6OI;1WJ^8+7*ijr+EDF8rOH zeKvK$wTHdwzW3lo*om6h?djzg=T7jIla7>A41ZjF$6&+3p4h9Mp8*GE{HqC`Uhz@8 z*>^MX@x-6Mfu~V#s(GfXReXML41af5?2CsJzn(FEF!-6(7{@IyhZtgh*VS9hIqm<* z$4@=5Q>!U4BHn1g9AQc_Uyt|2RklXo{!I8 zc=%SQy66Z$0;fA9^%`=HB4(@K4?9~NB58M?)E!p82eCgHCciXE0 zws`#Dv-6XuzVNr!KR&dyy%?DFp|fTqddyx8{BWYJQ3_iw(oy;!*P{N=GWh*D2-gD)&TZ0?`g`&xZr*>C&xK>wX>_ar~DYJ|zIr}DCIx_a0MUu${bb&kcq zJ}~I{nC-YFpZv^8I)3#R zfARVzH&L58oZeNi`4U_RpU%)8F3e)}Q=Gw1E!Nef4}9fdH^gr`!POoPG27!Rm$R`q z{H=f6@4X_{NcxQR%*(Us;)=%urZd8kUMyX_=!n^!@N8J)uO@u9y_&>rdo|T3e(Zc< z#;3Xv-;ri57*3|yWT^`%o}X-#CitOygJ&!h=EQxhj_!Jn*T9owZzQWEW@OJB&U*HaW!8!_pVEZuxze ztKNRUC61rLuNv!-?|0U4VX~8Wn$-bEFZg?g)Grslbk+uaXSU_x(Tg{FFZC{#ud|W| z7hJ84nJH3Gae@8+O8#i{m%3o|8`Ieu}8NWJb zCDz@pm;O$}hrc1Oe02KA&s}4qGw^7JY0uA`FaJ3Adz&{NXM29}q^noq=LgF>g5Xat z7FV3@2|nG)sjn8ix`$@I@s86}U$4d4yBF}~G3fb=rGM`Yo4Z5!#wq@EY7pZN-~r2d z8T>Zgb8X)Cp5@kN{`}zRGY*D#4g7xomBU`2)E)FoLCLx&@LqxXYYew#k->igBtI?oI&u?8HX zXJOl0_Z)@S@4CgX=fBYJd#~S#6FT_$!Izhf9;VsfUg=521Wk4JxRpZeYr zda6(H{l)fb_8ryyn~mOEK9juf@M5cOd*|vrt#KtU?|Q{9pP7%jvurKSAk}TAgCh?f z_T8aob0y8?VXpQUOAh$ytC;0qvsEn zdt-*jS03@i-aV4PT>6xcIK468x;J8BZFzTb%j>6o-(#I=?_U_si_P5F^3GpgbvP3> zvR69{_W&PuSom#uzPRu&&dknFj6EOt`C79RvmAWi0W%+Xa16cjoWXL&gddw327mqR z?rnQ~)d`oBGcI)E>|xjwJ+B^j##x?W|7Xj~8x}oY-aYa-TLU+-Y{VSrddG*}um54y|vl>z#X2m!`Yf1XX|uw+w&JoFQ@tK5gi}>&R=iD7~#z2^77}GjV~YH zL(SdqEia${t|k4JcmKq|==r7RuYY{yfX~O;cNQGgNc5XuJk3+xIf}u7gu^aA9(oW4 z4$l95F63tK{Ut9<@Ayr})yz)n1>AUA%SZCD7Snr(-4FxA=PB_%E5Cj38oqk;KKJZX ze`nWP9(NWGq8It5^SuY2T=Lt)#s^3F#PuH1M|(Xsyfgf6tN!X!y?_CaxEt~g}`K+>-SDm7hhNgzfC8-hs8U00*0uvd3+=54>8v#SfvOm|LZcvF4-w8w`HCpI<6(fi1m z5q5a?>aN#uaEAQMeBH4v@BHl5uSaI_^~8C@;$!r^m))MI2d7Q>;0xq zda>#G+Nay{`bW>d{?qf3D_`$4d%Xxlz0MQ!kPM>AG!I-Czm+B^;HZzo3$aH$Z4;p{PBWG+%0-OI65=Fdge~)4SxQOt9w(e zGac`#u6Fr5$7+OYkb2=PoiFLTbI%uFysOpwPMmt#ti|#XW54OR<3*-Ad+)P)DxOa~ z_|j$fZ>jZw-RBhPb4Px91OMK4>ctfnsW|7rEpePHtp>96|$o3EbtZucxr z{rCO<>fQGC-X-{m?R@#+i4JesSjVnp1toI{Ntj}aENmu?wWJ) zvx|7Ta;hJ1_i0d5r(Q;YjXigkbNH+{W=<4n`r6S(5!fZf^3uQzg<*{3>TGx!tvXTI|Zhu+!I z%LRj&JMVPrz=Pmo4PPBZPx;cp%D(04apqG$=({W8tI^u~0!O}b@w0}@p58g>7hitt zX7cVkZ#9Xy;Yx@8zps{G0_FZtjkEN_@o;aWj4A+PSBX zk3F2;mtysW?(Kyhw}-_}@bFyLQ#@drjV+IhHSTPNIA@&?8tws!{naPO?`eScDu zei-~o^?GJ;WK%1A-0by=^zVDc;6w)pS9^UTacP~8y5Zts4ySdza1m2)V5@!*mT(8PIdX!gh%gbcZl#OdWtulpYwbE{Co;qAJ_@(_}a7M zLHHPYOZed>Mou>VX7%G#uf%k=;qmF-f3{6m3w$^@^8LKI9>LCeRF{|I8$K9RRv+AfO^}>GV ztel+z96ogX41DRrMCd%|C>X1MTtR>zqQN4fPH4|lTq_|u8ylOCSE`Qrv3KO5j_owS!vEPqlg zeERwpJ|8i#=&F^@=$=^fh0B-T+R$V5CG}80`-~TZL(i#P1V7mJeDE{Jd&|3<<=1-x zi?DZ3?BDp|RC~PQEvI$8vxh;pynghaZjTp#e9Q)kyLHcxwPzPz_SSId3|M+aa5a4X zn)L(6P1h%Te)e)#JKy@qM${vZ7;9&tfA-GH*z)kogO7Zq@9Oo*%--G|5Kq^fPuTQy zX8w3?x*0c|>FNiL?YBJN?iamWxO%?D7SE?qz4BC-_Z-0`9I>4tKmPKklZ%gj)Mq)8 zeh&!`uJ5N}2wmsqY{OyaN91Yd`>z|snxEe_i-TRS=-CZ6_dS2MxR`PFIjlCh*a@38 zo%;X>KAifs<=Lmc^Qb5KdS|Uqo1S|i$GhJ4aO(Y*cR!1BhuHBo_`z+q zhLbMt_G;O5y|Xr8;J^_-01&$`bc-;34(oMe>cItUQT^E%=##v zO@7#PM2#dL7}nX@^cM#qCzd5KIo*e4%JXa$O zSaf`>*^+Y8v3q{me$%i1sGpy@&G3o2v-91=9%nv(x;0$&61J(&M_zZM8r(0Rw|wgv zI~;h#%w}CJF!fqJV(py+p0MQ?XU~UCjeKFS6M5|6Tf1lF<8So&IrH<(ylaxrK5Ty0 zVOtyY1g09RiA|1d;@}y4&FR!4pSr?Pi}-BCOm&$2yZ63h^k@D(qv|h*wRe~p{e?^D z={h62ZBOE%4r{&!&iv`j?i6h6&I1R&gkL=~+ovzT9BjCl{f>c+uNuPAAA5sM9c=Q7 zGs{iS$G<}tFMA?~wVAK)M&6s=i!j*4u**T<>2W^?`1_XOuy;Sj+vCKi_qRP;Iow5g z=o|L(b$&D5Gg5EZ<-rXP;yLblU~kZOm-xvI2WRKSZ_|_8T5edI4o4o`dPno2<412c z2>j~6-(D^`4Enan|H1~j(xvl^X%xUJnZxVqn$5 zZC0Be!{v)ped~89`0|HiRO6NxYxZZj3%&nOBfZimXW4rOH~P-AbCXw}JtMeOyYsRa zXU5H)@o&)D>!}!Z;RKf+ci)Y0?%%83^7%b?_l!=Ds>dE@HRI__Veu#WqHg{;^*Mr(0c=x+=l)*&+_UIPCiFr5d7p3$9L0n$KkTcftz*rTbwoF zhmSd7H|Y2kUv23Jc{Q2gtC7vHCR<)^{Pj#d&Y5g^?|%H%ufFDb$4_m}1+Lod{XIwA zw!9ksoogKQ4R`rB-E%6=U9@N8N9WzQ{v?B()1MY+`i15bMSiL+BHAMcc&6Fz#z zkB`_b&rfc{xv{CkT~jB${CHZ^@uRDDxN?czbbPkF9Aa=#zk2QU2M;sZ^8T9@XUQ(N zH5)%a^H}@)QMh#;X1e~nl{mQr{oLv-@pONxSq?JQ;lacO&)$=2kz0(>8G4`c)dRlt z^2wp+bk4*b>oeQA!|rop%ye6xZOf;hacAyRq%{-shEG^f{__{bBDu;7QyeIyvOmx9+by^w#t1Gtt`l z@z-Nq@hQ(gY(4Y6195?gyLfx=LjRuu>c_?J@!-kVGZ=5Ri|u_W4?kip-nn{r(f1sR z!H3TGx=r`|=&d+=HF`g*ov-`AA20E^x(jq_we~EFmq$HQ-T63QV$WZ1)!=@@CuVih z%Uy5eYw(lD-Gft&daf7E);Pn0DF!~f;Y`@!(95NE_eak>&p5;PY+AEzx>;Q3#fSYr zHm3fq&JJex83#W0-3M`Mh(q-kV?URBhWN<`Loe9Wq?T<@!uE57yU*A6Pd)IC@-9}h zGgTwZ;{99T;+-4b`Y(R!d*}4uw9&((H{$`fnsAewEuR0jHLU!ti9GI+H62d)gom>; zp;Np27pHCS*>cYHcILZ3-C4eP!8OB@QxCr1%#J^7X934vUOMOEy=c#lD=zxhdBEL;D&9fq9Mr&sZ3#|xHs6F)X}{?*oE;PoDnSD*C>j@W+Q#Mk+G zkIm)k|Ld*QC=U!+;>nihuNU(9Jm72K%%{&bc75V22a&HHx%X_iSHFGz-17AJi>Y7M z?i*2$eLTg8?~L>ZK07^;YunqK>C}Ov90?npp~v;y`MGbns!yHxl*9W?jGnq%`17;o z7x$h89Nj-LeBBL#cm0#QJH&?_jx$Qc$FZKXci-u7clJ1|Rj%G0-Yq!!PEP#&xNYy= znBn&v;$;wc`U4v`czlW38TF3q-g%Dsvde3&e`-{h{?Zwpy?zoHa?AN)>wfuOVL$cZSR3&9lkQ>9 zjWxf=*sUd8bs|z`OMB4R@mj6>M-mLy~KxK zJ%=j~KIO58%RlT7Ta)VHW389goxSHk3>`eV+!aGS8$JJW^Mzv&e%9u2_*>)TZmCBN z`bLL;XVQDd^TAIZ^<=jv_5_Z-nLp0*sZSgo;e$gw)WU95fBv1XT<~zL7u8wMF68wbSAWF%Eb0a|U+!wOt=yWDU8c$7bXIoRxB>9IXN@fSnr zjO<%pPuQ&Kama4=-tS!GAoRGwh35?9iiBO{_8z-|qu(jUu_Vr9&BDb{>PIs?A!=UHaS?Ckoeqa1?>+!n_{cEbb3pmK(PO8-qLtoDNDZjOQBL;8c=S((nL>@W$ znd7Zj;>`qxJh;-!M{tB8o@6t_<0r1qrQYjsdQ${vE3p z=hidAmyRF2Y6-8t;3U8Ad;IhRE;}rrX`4>(O!Y7|pDq9Acc!OJ?6%4uYJ=Ubon6srbnxb))0Z@PQrj%|B-pOb}7z>hT$Yx6cyi>9bu=`Nor3z55bIx!GU487#!%!c4b;G@& z{f|BoI`wAj{Q0q))c~81Gl!?{dMbap_!w+Pz1Z@4Ku2I$!!`G;+gC^N_{m`=eC-WF z&)3=vo6T&%GkX_py1LZQ$1^C#UJb;)9`bP()kP1>9f*&;yTFHRdG7~nwtj}UrgP@j zarJvSxN+&dT5s6!5Q`(OhJ5;K%?BQFU*OYKd;Or}6W`7ah8VLy%k)0NBMf@@hC5>R zZ)0t`-~YH5boju;O@G`Ixs&qvvndh}{^IfFYmJXHW3x8YW>509mM8x$@4En=`I_x} z4|mV&k67FidV6Q37tUL5wbetl_WVwL?+!7=@u!ES2mICLKA7u^-1u~E;>C2o_==?~ zUp`Y^?Pj^);M%#CPi$u-5Al0ZcK6%+h+coxr(b6F>gj#g^9GY&`_3Ltcf9XNa*H>r z!>qUJCvq8TaGvHaMl2d+m zabfxXP2$AIo=;`+E@p{qs>F$#{6X&Zo`TFyF+zfwyg}Zg! z<$|LQgRMSodp$I>&Ght4TruqMyjS#^9~&OdBwWuu!7YyJ2@6JCx{tUxFTH1nFJ2CD z)^u>h8e-H*>H`jX*=Nm`&vT9oEaF}jZSPQb7h3ya`I&ku&b%VE|>diTM3sey=d zM(y>7zCSZ6pE_o`=fbQ;Jk2mXFLA-aXPmt8k(b>&!S9*$6Sg{fPi%SjfuDD`nCh1+ zteK7@KYF#9-C;4f>NCM%+pE3r31)it6nFmiV)Q~y_`$_bZ>*;}AG!2$)9KmzxeJB? zqx$7YPe;@Tqo1{^1*WyZ4%=+R)tVn32|xWbZ{QFs-&V3Un9$)_YPUO^oYwsEP#28{W zJ$dUly?X>lJRfuCZ=WqZoUP@@Z_^1s_4XW6(#d5FS5IN%1Ve7K;X4dl+~UASez{@o z_odmo)AVY=srTuYS5N22hfbf(L<~EfynJx7W>agqwmiX|^o;WPqWM3Juddf8@oFdj zo&tYAPkC>^qL)jrybI-KgRj5hdse3U=Iq6YHLA~j5$g`fD;6f%_W5sw+&k|<&m=oP zc=SXs<;H;xH+=cWslMCyyvff8PW@!JpXuJcTb{`0{<6mrC;QH1%j+3?LtSDGLJyl> z9PvEXS9&_V7ZacM>gyixC3w*Dh2?XT&i!KNCvS0jqwn@TQ+k&_Ua;in!xsPY^X13B z>G+$8*zSkA4r9yXV`htAe(>aC-*oeP zk9XYRiZ{P`#6>T&<122i$5B25XZXFp+#!B2!!`5e!{6Q3eVW9+U%4In8~B`2WPJKC#uO9(u9*2aD~8 z4KtltjG-nXPrZT>PP236Q=DE|v)4CvdHJf1UM_X>GZSm0`@l!+ro-CuIq!VUf5i4ol-F$N?WX%)=6N7JC*3``IOvC3^#)gZdpLb3&}Z@Z z^?4ySzIcg+#aE6nyx$2O4E5$K2MoUS;?3~jvzzJWay4yvIqY#R9)7;!V97&#AB2Gm zKOFhGLk1h1-V5qB=-}{m7S%TO#nTh~;lii07fXD$u;El4=D4XrjGFlsE1q5)eIk}l z9A9fabT6`=+N)?DoalzrUx5BlUIW%iG;D8~P2Sym(pD)i?Lv zdkz-8efIEYI{Qp_H|b%+(tGeqV9O?7vtUQBhuk3XO80-X^*vyo2jxZ;Pa*iDCp zYdUs%vgP@DcaUP7A-{gM;tSt1DK9Lu_W)tTh3IoWFx1D^JHvgN>U3tl;)uOx#rI@G z9(Z~YCLKIFJiW*1#KzaT5PICKH=Q3HPWFVY^I)@vFRtA5bbOu7mUoWftCNVS-p=)X z@A&go3p{f<#D>F<;9~7u%D(`|{On;HaOLC2#;@;J_5=qpgs=M%Z?pG^?~3tLyMDldFWx?#yzuDzZxqC+ zebdFkWXHi=Kjjxc)zt%&O>OeQwKjWi@azA_mT&j3JJeatboKX6ge8}F`HA}IaFT-# zPQ2L+x;U8m8(ZGm9kGUI;402+@6X&jU+*HZ`Nf+roO= zV{No%cgA!?9K867ql>c|#o$6$t#tC)H~6|^@QR=6dMTee;5gGQpFWC#AzmCmGfuFG zv&5Usbf1}T-eLIsVi${}p>}!cX zvk{*S>i6u?>6Lx;*uVScu6ri+K8(5CS@3gyGd&_#8@QcS_uKtX)Ww&NKG?&wcNXI7 zFFkubR6kDkln>xk%@9^;@ z^zz|r&)3jvLJyyx5#E;H?BDNCHo{jdyu>-RX2-|C!N3_eYXaB3pvNWOo)6e`bGbZb zxN0qb?*m-u#F+I=9<`dCkKFRG6TW7(%L9X*pS`<4NBH0gSG;|-+w=2G$Q5o}_)dNG zmm?j$n0Q&sFOOL-=x_-eh8}D>A8U9<{H8kLgP&MK9`TI!VyYQmHBR---M~W(8-IJl zzFKjxCi%cE@7ynjj?jA-#K}2!&-msCD~X%jbHC4mxP?;w8SeuK^VRD-oK^$FkX zFbF>4^aC%kX8#rvU%2w%qaWh()q|dGYjJ+&hiT6b_NMz;e#?thSO5M9O!)PL@3vQq z+(f8wK^~Lhb0FtafNM9%BhyAFGgGg z2R_vjF1xk5;5v7@a=4pp)yB7VJ@8JL+ud6_KJtXa*3TQ(;`<)TFaPlLwD>Jgio=JZ z?@sjbldtok50}o*`f+3Py%Uc_J~iu;9L}9s>pOq(u=oe6 zb~?CvG6UUx;_@Z_xD`p1V@feO(EUQN>+m?4;^4qHgufN>v%zxYrcgy2pP3r5X zt>KY+!3TyJ7vl5HUFWMlHZ^W~gpO~0vWF?gT)(zFKf3&_)h5>2(Qmq3YSIgMFp3M0 zozRndVD>XmykK?*aMv#}2CPjddLt%WduMtpv7PG=iu z{_g%vSGzrq@>V-rv9R-{gCiFyryAJ8a&EBbNPB+bXSzFLX2-Ys=m=~&T&>gLY3OPF z$qwIW?^%XT#L%JZIfMf1%#OY7wE5HAy1C~Lyz54`99Ko>~`1#IcW-FI> zmYSwMPQ}2H$8ZQ%*A;Y{h%;yK6Az*mN=cw|$ujv^?JTBx&KK`6gT*a#hbqyCAZH^dt4-AN)|KEpFg*Z19O62l(8d;jKI9zKJ3?zA%r zo8GgG102|d-MYGQcdm5hEW5QF>Q`@liBFv9;nL?* z9`E?6pSx|X4)yVsi*&D?CH-7ZIuF?D;D>V@I}bI}<2lzy7H1d^!(* zmf*bygQ%CkcM6X9m^+8|{yk~>?vizWe2l5??;YraeC`Pz^$e!Z65<_XjZb~d*WPnr zFNfarPF0Uw_M4vHIl~r5=zTBaTixGJuV)5KKATSH{C6Sp`0i8f^0Sfdi`@L&BfaKB z=+)Whv+s}gdd(lsraK#Z=Y@ywj{3x(;0w#Z!?2d0zkZq3#@4@w3X{lVz#;VF`@O8b z+3OX41{|1taS@x|Ob@f?g+Ga_*;&%-2Y+$((z}na@neHU@Q_ms@i}4bF7xeooOJNz z64O1{^8C&9NsaEcSzU0u8_ukH>7AD|=x0H7%F9N!eB^C|7pA+c9(7eeex!Ts`R!cX z9bDA}+}ZZt-|}qL*S7aPhJ~kG_VU2o_ORU-cOl<;S>N)T+hNh;j!VxEojUn$y4uwW zi*M&IhMg@g%|A^4)9GP3Tl!76|Gc%mGxL4GJ^jP2^_|{1!tQ+ZEnIrT-Z^f0XJ#*# zy)_@b>7LSgpV?ch1%CIGZ}&%y{QQpBS{`_Rwn6yXyYGIsC3+6e+WX2~RzDy0`8f?g zd+|6pYdFr6Y% zmOS!?VNItl{`P9uGixz0-BIHAVL110!WkA@{(KEK_rvoEhx~lHa&CDNXB%Aj_5Hm1 z<#_Ywr$2bWbN2S{KG|nu7f%;Ay|IqlAW!Vs^563M)%y*``_HLxlSf~~vEzkH-x=zW z9^(#MjJdPoBbLvm!|N{N$={xhh~4(igB`9x_*uKxcx1!dS<6-5dzR?<+2bLfczSr@ zyyN)8+jKE%Aw6?A!lTn0LgyV+{pr*oZ@F8;gkQXKAma4A_o+PcigV|EFQ9Y({M^dM zAD(*T_jk$rZ06r{#1Brrz_~HgQ!AYwHS10M;S)MTA91kOw@v4}<#CaV=tG!&p5P2m zY`FZw6u0fYpUnBj-<|4g==3s9-AOg$MPLv(@3Vj3kGI_#o<4}d%OLc6EN^|MW6NjT zi=k7O8BXV^r*!b+2rGeSWD8eKMDFehA9{7eC0jnV^CkS`^F1}8@4o0EUuOlU@9}tv z?F?|S?+ndw)y9UmnyW#a&mh=1vQ-D4sZQc&qc)iJ03U--`Q;<^7d{^`?=$1WMkn67 zxjUjpb=w++c6Q!RMYiIGQt>dTh5HjAys>Wp{&V{fqGB+g85rpKRO ze8QRPdVzeJhcmjj3Ht+hBg3GQU7^Jfz)&PdPCh->k9hOy=4 z64M#rz@Cmif3|mz>E+fdv$G@lnG?@*HNx;5hfP1#Q@0qk!0S60oj6iX@pR?GgPq>Y zkG*>M(QkUVSnCZx-(T4I+skh@^v(B;&Zqkbv$~o+TR4#Xtl`k}a~}yj!p~>!rh68O zdvg#kmcKZIzZnm+T5wG|Z?zGA-38e2!eVpx&0*+;Jzs13E$=(MTEyZ-$HuRI(y2qd zXUn|le8sTYw-!t2hkD?}S$=DSjkNFQ$a*lSE;I;t^kVwbX}V zJX3P{jwxTg!Pj2jVd$sWeufl7-#eU*^el%{e!b{k!?iZETaz%Y;mKKEKJD4X5_Ph{ zv6q*Q-P(-PmdCy4)t;ZT*8_g=ao|IbgORPC>9d^Ts;dMy*TxK?y|*W>gRsYmDdc%-`ywt)ank{v-vYuB0n3Uv&S`VIQtn(&E@VrDJMVg z!`6Jd8*tgx29u3W&o&*N+4rXYnHptwMrx^wx*l^TqkGFL>t;O;;!l#3azdEdEzJJFDhGCzG z;|Es^kylPN3-?hN>*;#*K@H2~1bNu|<*YAGP^TR`q?>Eb5A!d3tR69E{ z%Vmb&{edecyV~ToH>}wW`1RACz~STfSn1&FPdOHLyy^jNy(`3s7n5JJ{OX0{etz8W zb0r>ln+>?`jeoz@JIfxXes?F};|`Nl-_%ztPGaE6hZi4vYq8ZA_o<$Ki041o2d{ke z{vLN2+g>g)`V>cc&mz5du{d>!^W5o0zb{n3ns73#ag8&K>Y%ree|5^sUp<|HKEvvs zZF%RykH9g+nthM2PI;^i@x4=uF|!ft_?Ua1w!H8BW}J-PRn}@Ea^Y#;+6)I*{NS2> zKG5~O^oOl`#$k(N_iS2w#);3nxbepwUccY^ldY>2w|asX9&|)3fo-pLHnY5RY@~Cf zvxd(njB@Z5!w!ePJE0%t74Hnxu<3m0_|((<-GOlUd(PzbEX7l9qntB6eEH3Eb?}$R z@cTPB*7Ue-I-yeoyPsX;?PoV@HZkFqm(8&6&%*MV>UzTNci3{ci}G5t%jZ3@?Q!x< ziFf|tvcb2H107C!3J;ER(L3w-@srccu4noqmf+$079V;(^-n(jW`l2k?&wav`NWHl z0mDp>k2Tryx#QN|d3gxm_=&~SP!F568DBFFY;ep(E^~gxn9FDFzKL-*`EGl?n(Fx; z0?*(}Uq7w+6YKf}+x{)Z)F=4}K6LQS`NdgI1J_N@dx1{R_!Va_-mtDFzI4vk8c#N7 z>F)Fy!baRFYiA4}H)m3ud;|tRb2>9WQYgGph#`l(I_uefHha?3&Z z!Vur@Uz~@WzAMVV=|o@b`5Vrbp}u+ts?S|8`+3dZ-}k=uXKne3#laqrO?TE?USG_K zobEBPR;yYF9De=Tta{Z~U)5Cq%-(x=@sqdQTR!IupKtbZ>4!MdcQU^G>c4#UK3B#4 z_SWj8x5wXJU-0bzAFlUC_UcrhbnBh7vocps(`1tY_Ur*@d*9WrYNuPl* z)KXr)bmsK(y>Z$49w9D1=7k=Xo)9yi?xniv^~dP*sm~I8>FwbWdpPP6OZV=-7{0LR z4fWU4e9hHqw%5meaoqOeerTsrT=_97lwOjU;Wl%*ows$rW|w$o!+X& zeT$>s)8R?Pzt2OweDw$>Kiu?yz%%;}vgOlVMzP|lBulgrP_WH(VZO8?a55YyQ-bw6qZ1r#3^Xc4@rCI=n>QVX_YXehz{j&7hgg3GB1iS}W$XJ&pFen6 ztDn!dcZcf(41COV{Ozl0s?(VXyZrpEi8X1j4g()LGfX_h`ZSo8OGj=9w4_h1` z`S{^0mOno^?a7w+d*gE2yUXILU3`4$`M{~a^3rX3?jS#Q9OB(~9r*OV^O=bp*0}Sx z_uPiF>a^}&A?~Vam9x}-0G*( zH-7kg-@u7~eB^c?>B9|AtekxDa!>idBl6+(t_K!jcPH%S#tR=<@WsJw(0Tvy(Fd4f z#o-|@pYXT5dz+n2KC%3(-Rxe&(EU|@3H>`af4zW@iy1y2HafE9^ZC;6_F(g4 zH&@@5r-OqN4EAbO2f>N`-J9+gUw$ydFniYM;|tf_!DZ9)nc6c7PaR_9aqnT0sgECA z{siZI=?VYx`fduRTEy{_pU&{#c!{x=Lw~L7SNi%h(}TyRCIZ)R_i^$$R-T^Ish`@# z;pQ&EQLEV?V(W*syW{?y++dDTo-3K=PA@*i@e_tkn+J_g6T2wdq6+c;jo$*9=qNoE?tzo+UW-$C`fA z^Sp?y-)il1pt~YZ&%bxS^EL2fgJ%tgpLKUeAEr9KIB$D?*5cT4D(6%uaN(#$&+T#a z+>3!P-u?2fRJ%UG>0My14`T59xY1o@`)+&K;&6gvCiSXXVaSJ<_p1E($%`AmV)?>y zZt|8t-uz~|`?KZUS9_fBA?E(gDOm9_%SGfR_I%t!`3OJ!;J~HdbiYp(*YnVSQ|avR zCHU6YsjpU_)8Y)+e5z9q^o8gVEO(cr7o%>^f^|PfoYVdXPuOO5nB77A`+lbH1P*_D zwTTgHuOFKZ%evax^au}l<=OHC9$)fdyJ`cK!p!1^~uyfY!{b4R-i zaO;&BH+(jo@Plc_N39I-@~i~}F{&3O>dPMqjr%VCH!w!A)DtDUerd$GQciX(F3 zZ}y(yt1q~Fp5zxtV43+Ra*#Nb4>vXOQ==gVe;k~r828h#mY*H|rn?((tT$bKVsYZ9 zKlFTH%gt7QI#)JpISu~h$IJ5~zk3=tdg83(?ww=Z`8o?&-phRTjj)?xx!-0Sya(`L zhqLKw+Va+X3}Oz)-g&86Pt~YaK0UMY^j@pS@`~dppBl~m{s@kq^E2bG7iy};?tndi z1BPD2r)R~Uo$!hOT<;yjuXmw7;KNrOe>(N~eX?5o{L_6>ACXrMvGA)&4fNej@o-80 z`Nli0Vf9St1?>J#3T}qJYwOKc&#*Yne6jr4 zaif!$4;5FruVy|yiyyXz&rjWK zW_k24-rF8ub~rO#FZdY5%qFJ03AZ!G5w5#oF5k9Sr@r+3iswT*3pLaSe(>P`4W~){ z#IfhtIpEaZ**R1A^5Htw<>v=O{Cha#&K(zVgs;7L_I?*fPyDX19Q>`%u>UEKI2bsE zZB|$B3cl_huId-#4$#}z_ifLQT`v74TRt4E*~Ie8N4@Z2nb~@Vw>&(&46*JPKQo

5T7`0KlQZifli*_R6^{$%QV4$W}s`LV(68I{XB#XYC9e`AU>roKP# z-SWO)n*V+}*!r&q=gQX^mD7yZRL^~<yc3ds+_fT{!&Nx;J$8X0du*@Ac2#o!E4F?dv~mKBU5>=*d*a z-EvmEr+VbS49 zwme~nXB5xSSy=P8uQq2HZ)^IuPF{KVun`rkmO2r*o$5w>%tYK_}L1FIEm%o1Wa(L=9|4-vi=1 z)y2Tl!|tQ{dtT}7`>q#Xy{_-<+de&#t25^ZR}Qk};niEZdScBNo;Vnuhq!HdI5_ab zkuSeKi`{Mgq31{Bj)yre;&9C`-u7_hFvQSRZ+OjY&bQA!xz)Gn>96y&=PQr1i(`4= zIh)RhZya&p?;O0hsMlUa$e{%?iIGFV8FxAu3}3u|#^ccb_3`*S?LV)cYC9X`z8mAn4$F6sO(*vB@Zr=uI$Yw>S;_nE z2|v8t8(76yCot;|y?AGd6M6TtH6MdNKRnb$x8*%o&Ji|le8Q8;;IEFzH!^~ zu+98nc9!Dl3^4=`!@fSkuD&g=miKvD6L{kKeHIRS?|lQayzloTJs+3Ka=e0u-|li_~ApW_3JkKA2AJQ;V$N@ zFZGwM8u_Vl(>K5KvsbJ4us*`YMNhn2?CI&$3BLi8op1TeJ@@-uuCFlaIliPC>1TfK zlr58r@6Uz{_M7Z2xK|MN8yXOZvR&R_rG@quBe%h_0mp+5Q4MfAb`|8Dn9}*@T3_>S{uGswK=-%Wqw6@e!X7TX!u#_l&RaK3g7E z{lbBcFD~|kfB5}bpcp=Kb%*O8y)`kz;pZ&kTz%}l->l^kuRrys{;9=)$JekotILeL zp7H4!f@d8M=dJ#p4|;>lbONI@>VDS;zWtd^F><%YNuBWN{&Z`#>j@ur@43!E4E?67K^^vn_rRvZ!`XKidb!^*Dv5&quk^zgeoc(dUN4^MvbyL)X;&EVy<1At6F`b^$i^CTu{&ae&4`JyayO}S}q}YXAjrv*-*x$X3 zPciU1S2a}!4t(YD4$vFif84(RhLmlp>w{S=U)=S|neriQ?i9Z`RHIyKaVB*5=&c_4 z%)?*)O;>++876-=>-vU+J%OuMdwKibRn2jk`LOkae>t2tT*Ai;iw`}XV(88C!K7EO zJo(3ijxX-@Kpu8_=Pt&%PyKx7(FgtX`7eil;UErX{?5s|_r{jTiB2578CQ9>yxQWx zruX^s;Y;MJAJrw^8uw2dVd7=*@6RW2SA%DUzB^>jACA5IXuau#4z@p!@QmsmyBU`I zhO^$s!Ly(iz0+5p5t}X--}uql^S3tZS2^GjJ?b;jb4cVi;tGd9zH$<4c+N~tdw$ir z<MY1FW5w;k*s8r1RrL zXLbkmtab00nGTZ4HyF6|XC?6Y)I&Br)TYi&w}yo;4xObnu4*a{m--cF z_`U1icdxu~=5qbg8&dy!C*o%i_&Bh^(|c<=cJD7W_#Et6G#h;7@O~DnA7YJIlGkyPknLOg~lE;04@nLIm_<8pex%9aj`0A6h zRFgaHeWiA`ZJ*~=Zr``y;pBNzXP+x#^~c?ESHyQuJrC^q;qR8?r)FHt_I%WWkI_Ao z7jJ_f%-&^U=+#f}zR4jT_Le8=;S+DZu=v6!?9Qgo2)*n6>MMVJ6T>ElHGN_|_1%kj z<0#&F@xzzk$H&kEGrc}pckki=TdaG*Z__t%a^T}k^am!PW7~AOVC!=>=M*Qp*6su> zvF-#O_IiM$e!0W?z$a-h4?P?lipNVlVTZ#`=s2oSUu=&z9J9 z`tSV3{_5*`)AKV*=ch(z?|$;vLwWlAwwBAg!9B9?eSmX!%x9Gvafe6LYfUeov;Vw7 z;8e3*?)|2#rL*8CPA#z90eE8N5l_z_4?6WbD{=mQQO}Hjvpn&>!xtZ-N9rTa)?Uq? z7ve1FVAp4{#k(J#jXn$U!BM}$6>qS8+?e_Lf{R?etMm#k{)QN}@w47^&!c{|mz!NK zoMFJ!8~gmk>Y2L_Q(f$IVsNhJc&Ha2J~+aX%buub+v8?0FCXH(*z$HlBB zxb`15)A2Ln2ismAywuL-J;PsoHM2V#c4tAtq~i-qKls9S{)E4K9;Un1*~`_L@TZ3* z-cYZ*A~$^Zkv|(eb;e`r(|1qtayJPKd))ZJqVpLH1E##y;@?xihd!>(SUmA_sNV1q z$A)Y77r*)d!+GlspZHt5m-vg9yR#@BN6#$Z`o@>Q5i5?)^K8HAeohu+?_A+^pS<^o zJ#0J;^*F0vZe)97!|+_t!L@I#2fgp;aq#yz&6{o(!_Qry^Nic$X(su@z(@AB7Qdbx3O7I4JLYu@(Gk54?S zZ{~-8aj@z6idQFGy^0$w{&Jh~+Vc9f<@0l1nBv9yjDTM}&T{Z0Y=pmc9O(GC19Ix6 zIOnWaJ{!e&24LdK-@DT~k(anH;y-P``^OD?woSL@3kwILXG9)3J%2bFa>)&YYBN1ikDeoZ)M3U|ezEq|QXVzNzh2YL{mu{%v77EJ;B}^+ z)9~=YK`foUwHbbV%g3jDTb|GrLm>{&a%_3h+4G@LA1uCR7}oVrzw%{Q4@|wZR|kGc zcL5GNUqTPpv$g4jjjo(<;Cp{_V7Cs3A00pZ>I*LP{OGKWFwF7cL*ymJz>CKh%NL*S z#>|&b9Bg;h5U)0NYdEBH=U)%&-Bjm~H+(+sg?OZ;j^A(QVk0=g@%d<7PvrE@ z;$saLA2WabO7vQ+@4G}Ue)-_VZqW64zzEziuUG8uD!%OX1CDy* zN-t+|aj4&X-Ni7(Sy#hM7cWjsaq#%nFP!VCeAZ@t(7)o$^zh{+FzD+o-OPtCueF(& z<;4?s0>`>qt@Vu$e>34{_8#th_~PgL)Rw2`gCl_%E{^KrD;~D^-evsQ>ByGnPbDe@ACtu?*#tMN}Ric@Qm)+OjnC{FcHs=4?H~LCy%=8fBN=f;5ZM`_fvi|T^zkN zo%+;M{FbMahmK8tLMO)OEL-vN)hBuRsBme|WXm*Ze2{0Se}#2&s_bG?$ooh0JetI4y|dq^HOas0%XJ6rEa?=$CEP3r#D z2F~Kd;9OnuxD)XeC!f8~ReQ4K#o~ZFJkOe3zV8_Q93+-r4t&eK<>85=!-Ji_HGXo_ z#c#`}SNY;xFVx(CBzITaJhdWqb=!||AlXu(W1`}}ge2o{g<()4-5;yhfwLIR9d|~s8 z=P$O#ANHmbKGn44eMZ?EIKeUC1Rfm0tm1NL&U!x12s&>6qCH6Q(lL156?Z@St0++FIwHDvF1hTcbU5L-P{ zU!CSeU3~I46EVcvc@a8ywza)FoC!ZOyx#lusb0+d+!1+j=1aHn(f_9{lKmB z#5+G6h#tBNV!W@#=xurR2d;B7%Sp$dkMFMbKiMdTt#j5(T-fjsZ{7DAz3tyd(J$}G zxOJCthQp6+dHrP}UJQoLH|Ha#;OdzkuP@96l-NvfIMoiM}nclhLTe?M==)jh+5 zk7pD=;@(evcf+~5EA;xq-+i%Gx4y_}#*vOswbv(Hh+M{8j&r%ZH;Fhly&=w$zxtdr z@v{~`nDpwB+gdD4cF(C;e)-VT*;|{{Lg&ozfML&`*n2O^;~DQ6>^Yh0@{551OONf1 z?wj5jaNs!`ex#gwNUsk3^j{wDQ$D>n+$$0WJR&zg?_fN8|2p692|H|9_|eNt@65M6 z!IK}3c#wMFUGMpqPY!j#ab`q**!FC6_WV05+%G z>W3J^-e;QJe9C8r<4%aPcVFcoYPIeTt6Ls=b>qk`&N*B2DR*_ML2ZPuc>Z|d?sp7& z&Blk0!19dxGc@O*4{$n%ZO>mG9AW60Key!5UH)!+eO9M)m!Cf@+&ufv2PYV6)DJ%T z$A?W_K3A%huYs=_9xn9_2Q`^DJvG|@@O3W-`Stc@HiL+T312Op<+g{(M_qF2mA_8} zk8e4}x|{ZIUTRF_X~3cH&cPG6>7>s^ImO`Qdx)ObW4)+`EpP34bpL>`n{jZ5th@Jm zZP3eQtsc)*-=})l;nscN!`FMx`E2`q)~Jci45K^ko#Nd6PL`b>N4fd=UWlXh`%dCw z@bCMsKB(CpsW)m8kE31@*mB^a4+b2u?i@T^)D|apHJio5g=a1&f4T62Bj=XS{rt4G zb5ye!91PEkXF@KbW_ir-bE*cs#r57&D;_ZTjV`%>>{O~b>}=g z_|e1Q<6duh_s`kk`_9A9a3?n1-wSg`)g~XFaPUwAJsdgcdT!mHZSQ-xJ8JJ)!beV0 zo$=6{gg*{+p6Nax#nQonXDzSK6g+X)cT&IY@#fpP(aEbHF!9z`Gm%eyVu*ZVK5edk z9L4zV!ba~N>SscyPI=^p=g%JX1b+8jZ^enX7T1}{?fKFVdVYN5wD+Y~pEm6Aaew;R2e&Zl1v|fYkKo|C>1IAS_}(w4 zd}8$xQ`*wywH{?6jZ&2q!% z2Nw=I;Uf=QpAq%L&s2QG;^98z4@VE+s7bu<53o8%zG~4Ex=q(3u?F9Ai#Pb_yR~yH z4?mK>+%uoQXM@<|Bfj^oTEyVeGuc^n-}`LkOZdv|%;^j@nB%?W(?`1AfA1O=^5kWg z4?n$>qkXloHQ43TKbX#dAFgcrsg6xopP7H}`|he|3#L2A?in!~1a>*C)3ednJ9>QO zRSVzlsd|WePOl&Q3_jJl<=GZ~{e`WjJ_qD;2MHg0vpPLH?z(d!V(GirTR!K{?lTQ% ze)!^2PvNrJZ#sT>(35KJSvIR{(~0$a56j*&$iW(RcxJ=9deie=iyz@j^vNC$XMXEW2m^*)VH{`P#>_0n@(E_itL&J5e^Jq%A@`6brI)K>>z@5iv- z_0q*(9`zPWZyjGVEP68>c60hIpWYYi%*n!z4}HBhvo*uA<`ZUjMxAu;dU3)Tr$$(2 zgHN2RWvb&t?^%XP%5Bf5I5vCF1s|N)f zJwP8vcEYA_ILM(!G2U19>~!i8YY_g{`de>1Gxpxs-m`d%_gsaCGrhi;)gzy0oliXF z#?|aR_^_GfD{kA<^JT9;BEJe)0W%}35`X88O_pO@aVBrHBg zxy@odL)QGaeQMVaXW|^4gYOi2;qLIK7mtrUY-{=0%Dd&=1GbqiXR+=>wR9)hVCkip z@bTI9-rsP1uD*pXEPQ$wSeKg}exg^-O03%0%Uc~`s+CSJU^+8mO{TtBexBXxpw~w@ z{LH`Jz{wpk!|XG=`_}J3;q(l_uFr6KX7Iwp@VO_y^AZPNOupuAuLeC83#z;LZadC&l(!o(5n?Wa* zebaGQU+)#%`KZa*_Ie?ftyp`#G{?nSjQHyA4B@bwaU#`^Us!mkNiKS|izC$`PEOco z*#F3@CPNR&mgm>~DXzMF?}@)2_+5y2xO{NHN8kPTz;HHQUitAcyN~?6_r1&H(Svud z;rnxc`JAtM2kNoY>7|F4q@pdDO#Zz|Oz(rPBjr%X?4anQrQ{$wBAtemLp+;v^nKWf>pySp`BaNR%hG3^+dVe-vyFIudI=XNb;I8B*7brPJs)fS>XIAB&W5d_7M$#@ixa!;b5F_*Lm%{Y z)8WE*FW8(D4)Th5-z^-xW6b?s9y#sB!%?UD==x0WoZUY<`NhGP6K8sBx!e1WWz2k> z;NT6Luez<@wc~Bi=Dk+0-C3g7`YR8<>QfWm^z|Nw@jkb0uP5T_FCQ4`uA^bfj8wqI0G= zg-_2PAHrW8J<%sQNj7^nSY|wNgX{M_V(}6y=ihFK?Y;8d_C)=1J71XaV0DK*7kI*= z-}Z9C>TIUIo`}bRu=^dV*tlEkKR$4J&f)Se&$jpX4n4PiC&gC`J6}D9DTY|%XQ-Rr zn$6vexBkNM>=C}(UJqdFoqg{YKCldZ5lhT+;@>(xW`lIs+VjOlUNdQC>siHr+DGhyTjSa1C!04&EQ}Ui*N567<}cmudeilT?fugU65Y6g4_Sn|pl_n9s)8!Q4}Kg%cH5a<1#UM_hI zePxHkx98T+B<@=H;yqu^RWH0-t>uK{9^r;B4&ur|U)}tFcm8ajzWT874~su+-|ywB zW&MC7@Gg+s;H#eA0o$GrY~LyC6}z8R#BaLu!=s-3u(cR@oS*Sw18;S^ zr})9FA7;H5lOJE}AE%3-IC=YV3ZR-zGk&pZ+Ug#!cUyFp)UN*o)x{v)&0;LK4#qMJnTln{ z5tcX{(szF1tBap!3wK<8++fp_`j@}>nV)~_#{I*!zhBIsz=12bIy~FnYx-V3wrauG zXEPojzRsQ1wugn2JGkk3u6K0o^(Pw~J;qI5IpN8_>G_$@pF6_9MQ!$kKfM|Dr;Xz6 zKW?~Fel~D7oxStq?;O-3*Sin!2pn~bvG;zIU#$J6o2~hpiJI)4H-GgJYeVnl>kPzf zdr~jz*Zj4(ep^g940HWr*MD`^ z<|U-8h>W=6Gjpx`-uro~%DJ)232(V0-f!*!y*%`M8+BeKQEJEGd`%|K2yIIEr)nDUa# zOQ#QbGf|5rzB|K?@a8(x+4Uj^qH`bN`kX8eyLfVRXZ&8q9L**@+q>5XqIW)U{aj?$ zY-3k{_qiJNP|w{>@#qkoGje`%>Z7@m+1<%%gN4(h*#4cVo;`EZ^Vt1P(_G}V%ur5P zGGAxvKFFuHZO`UAlRH`M>ge4uqZ`rGH;>|~oVp{Zm7OW3vqX#61JFXu(ernW< zciOh!`%9fuosP^`Z{o?JA6$%yH%Ayc`0l>C%>s_i3de8TZ!do5$7a5W%*TxR!|B8M z{H}BA%Yj#~n(fiV?^)r?hFfBquX$K(V#w+4sSOTS%h;WZ+Sp;);gRn-y%XuYTYFzr z+f-Mlz5McuCkNtZPcJqZ(NFb#R+h7xVaWNC>6`~Su3scSyF6n3<5s!Y+$}_B@mG)g zi;7R~9WwLXHU922?rxUDEaVcWnmYftzrk+yIGpDfFAg8ii8xb#wrUbf{qobv zV_%P+4SMkqZm-^Y7pHi*8pJ^`o!`rQ7XJA#d@ONMan&XcKhKOj^-(O}P1NN30-ZC& z#jwy+*C%~8{nb-CI5Msl7&XwTZ|u9{VymrsJOgs`f!7~mhkfPzs*#WSkv{o5*ZQw_ zG5D%QT%=BRxyO#2zZh}2>esWpaX5tc{TKcvHnn(u`IFQCPYE(aB zL*^6)&(2njIG^&g7sJvUT``k!@ABqjW}dz3g!ete*}dnaH+yzG+qTztwzpQc`tWQt zGdlV3slPwZuhywAhuNzav6&a{J?P!ZC{faTu}L%c1sk)dGt; z6Lx!dvHMI1uOB_ylaZL&aC1o4tklrw1s}d|-Q8`m`M5JMmO7Bn?Cvue#{A3%(eW>q zS(zCeQk#3x=Q3>h)MD{Pu=aedZSQQ@>!UpO@Mz-2saElO@9PE589O)rex^{9p3|AR zm=@~$35?p|#8Q{|`b6rj4*G4sdm~0a*RVBPe)jz6+O+^4qh$lYu}mRa?r~wemSdOuI>(dy@`u@uK6K;aNHx7%^ z!K#N&4Ds2_$lU1o>KoCq(eo3Ju3YX*cNE5AhYRcbg)_2OzkCSJJ|FsIHfQ3#mLHqBE#@6mpI!VhOB{OIyg zi)X;kCF(TmVmL>!^v%x<%-!F~p(9)H+0{?RQ9kMsTRyeg>jU*OPJU`dIK1B-@ztw* zWIk+Scz*T%@5aaOp4;n541V=u#$@ErpZLGOUlm^+V|TXh3Y}b$`kTEz$>PB23%B4} zaALSO^=XEK97c`hEf!yK`1q^}FP}W-uAi6unGYXWG5Pwum79L-yXWD|%4e>aV|S0j z>)-t_^Z)e^JIueI3@?w~=;|w3jD8+xv-l)WJQ?>aAvN(6vwG;ms6)N_BAbzYlu!OJ zW+bQBR`ufU5i%>ja*IXwuBcX=&CD%l6se(iLAsua>Y3}+TA%E6NNl7Y_ccymzV!0a z%gJWG+uj|Vcs3X@^y*y6$jsQPoz7ii?>QxlPhVa9^lpyLP;PP95UjgG9=m7PO!>J# z;^yCsoy{9>+v|%?J=KCEdgo;p)keqWcMfXuY@4xnl>FwzUrs*cslM57dvkG4u=d>v zvHAV3L*H<0auyRF;q(@qI#4y>5j}qxv+Vce#Z@zm8RF*B%)4_i%_A&-bE+>nqRt_I zKJ4($gkBDPsEZ#R3_GeWd;0cb$ZbY)_g;Z{Q$OtGpZLAQ2Dvj)3ykw|&Yn+a z*6idf?$noGukdE>cgE^0ADuXAt!IATY4tPl-Zymcu(;Zrg&g))^M3bg>TXTEIfxH~ zvo~*bl!p(@%=a$Td;RH|J))Oe9RBq1?n`r_=Lf3~M5hnfdLz@zO>WQr*3&HMs()@@ zUvk;Yhs0Eic!(?pJ&x$u)D)H;hCVD=Ua>85G1$x|th1vVyWI7l4!&xSR}WkB;EVL* zvs7*Nu&rW>W#;c4@=S=&pT0AwzV>496|?&S!xuLXWRIHT-0qC3q5EzR%Z|f~Ltk8a z-}{h$EjXX4aQ3KN>T*YYKG3PX8B9E~*E8RVU%zCww-$S3uJoP1Job_IpM0LRv3s}i ztrs}6txj=z7RYe$WHH26BQgubmmb#Y4)sjJhyh=2x?>S;hHP3)wv2`tG0>%iV=j$HdEP z)?(AC3C??1T`gxzZ_i(UxY^O;YIUBLe~(El7_q~ti(VYx=@I|8$Nc!vv%CL%QUe|8c?%2ES&3JEdHFb3I&~v{)!%v0yGQ)l;`H?^ z4!zHR7&Xb!+|=uQ+%v@PeRiAu!~5~=!*>+l1L(yu4{`M?PxELNYUST~k>8&9!-!E2 z_6VQ)v(uT0JmRtADBtd*Jh08MGqi{0YpHkaX6}sC4J(dk#HttE_jYzYh$WAEjKVit zG1OX4{>Z*_nRxkO+3a6`H6nWNkp3*cIg5|-7)VhvYO=ec~+0r1t$)F z^2B>*t3N$mXHD+kdv@2;^N(OqJ>khPayB0|ptv5J5uP8}zhlLYCVuB*7Ts~U{P>b1 zIrQ|_V;+2qVGrM3*!I3l)4La)!y5tAY$4thK>S3xo58P*Yvm(p&QaSV_ml*n? zx9I8IAvD$1M6Zt5uUg^Fj1SpNt+4#;*~CL+@0oZ0YITyrLerMF*0rdA5#p#UH zU~eJw;;TP4INX}*Z~pVY{oA{r&FG(PPj;UF&Hwnff8+myO71S`qosH2eE)Xhg#XMJ zEWeoch1msh03LEqUK|Ew$X*6s;s)@4Zn-@FYRg|-qgQzUBB%ermWv~iVKsCY0Znzy zG$cA0Brn3lRrG5+(EcHYWl-$-so7Bd@EW#ZPjx;wh(C;Uda)(zhris_#wORR+x8Bp zI^@^qi>ao3#o>qO5bi~*MsnQc(wh$sXF=bC`^F_ZbarRum#jUAc<0EjFS^0+A)R<6 zzq;jz2`g^>ux)!i>eKQA6ufz=BONk7_*FEendH(%meZY-hZ+kV;i{&njogU{aj`;2? zOwS!XnXVq-#h|mg-OS<1@;eVPCm!)PM>sZpF%+ws*~=w2{Yz^2eQxq1 zG1Y~{?f!^C|HfidpSh9Q)zu5#jJLfS#Z}W(_d|%iI{V>y+l%A5l-J&~L57v1p5+wF zVvG6!w^yg0idB8~kvRNu=U|cb(JxBsNnP^s$Mxt7o%zz`2j4T|^8-2G!7mT2KM+=1 zKPc!+?&hf`XOvI1!|011RZDk9EwJ=->V&5=YqI+I;_d*P*;YTF{Ny96&)W7oJ9~cY z-oInt4>D%c+~j7{lO@Jm8<`%liHGaI+U;T3@Oqf|CmEg{XN#+quX<6j#HF{w(y?dj z`GIktaq-MJoINr_Y6v{Y`Xyt?p(st}ptiJBGvco-haV=$!E4bw7Ll#G3i~CzoF>YPDxC zzkNNteCj{p;E{Y{sgJA{yz?W&!HZ{+`4mHct%)B7cCfD=w)Vw(_syeN;u-^0u6V7;ME;gS~TWKH{4ZY;}u8kLbvJ<&=*csZAaB zY>3>v$;H6oQMI$nM^9#}7P4H~#D}3%6F->j+g@HeHq`mI=Sz;O>D`mxJ-c|gy42vi zf}FjFXFAMO-yG=ry!SH)ymupV20lNLnDVI;ryKjzb7l|syXMX!4o4P8KE#i{`spoq zXzb+j^Yy$UT%E;JJ0CUhuU2)_!ODU7I3N4;FbJMae0H)L#dc?LdiTSE_uifAba=J1 zBejTMYUVHhQlupxXl3^wu2GAe?umHn$B}yLslMr_zS+U5Q!F}uc>8U? z^DZWxoZ{)J^J@QY4I2^H|u-WkZvcb_c58NtO``_?HBrcmWv^_ zrDy(fx?A0GcM+DpdF2}yTdqOwEa+jyCAZ+}MLcK3CU5T#GO8w@V`62;J?qi7-*c6& zI_;~$y+QEkXZKH^d2s0tuz#p6A2N)($#J@u)W(j~s>kNpXHs$5^y~A7T&?AdyVsVS z;={qSqh>bMH%~cW_`t)d$2q}IJlU-5Ei%H{5xh9{)NI3tg-hlque(PtZ#Hq*_*cus zKjpS(uWq=xTtCTd2)F9Dy%_9rq3#hqoqDQCF7xHvJ6F%W`}sIS=hylA86U>`IN}dm zY&F>Ef{Bn-u(7@_g;as*LxT? ztNcD+#fHbnz8UvRf4(yviP;&bp}ly{LOeSAboN&Bp6UDSh7n&);*k+94_RH#kZg7c zw*05~W3Pt#C|-4h$HhW?x5xkIq@j zEf!)&{sja!IQN&`cRIYg-&w1--&>kN=P~tt9}z=t`}*~lo8kP&RQY>`OwUM_!z*Saf8)s7GA6>DA8$Pgh*M(whk!AA2<-`)%)cec8l+ z&jlW~y48imgXL%Osor=vc35lT)qo?Ia#TYcUY_Q44u9cL9UGjca7lOgzaWwI(x7y%giu)S_r%raySwpiu!jFH8($oWq^ zeZ9T7bU3|Soew`cGo1P;9ZvDimk#lXVC-=@5L zS5tM1W%+%bdfiobfzIzFBC~X-efGh?hI6+U@;ghu?zetB19t-PRRe#R=D?^;W3O+v zcWrw$z&W$AI|K7lk27WK`xRex<80LoW9dgOyz`oP=iwgoXWqqOL$J=mp9}K$GetAR z>Bg>BzCL5+^JkFu(Ny1ACbNm5R&mS;xA>~HK8l6IRl^{M#gXrI`P#$c`RlbD^eBuz z*j_!DP=rzjqI- zXS_cvl&8NRL@$oI%)~vk&xhW-ruU85aQ1LxNA$n<)icw@4`a`%Ga<|K&W0`=o^Nxo zZ!Vpk{M~yp41%+NsW^0S<IVH1KXFXIq%*+>;u4OLj z6_czU#Qu`Fh`u=O`KvpOcNAGHGN10NcWt@7-@U)Zs|LJy^kH8<$YJQh)OY8@R{mxz zF8tUL3^KPjr~6tR;+b>L9c<6FUgXWzU(h!T{yxj}=Y5RGYT?saS9iVmtV8mOVMgM^ z!O&av=I%_Y+e2^T7FYYdt2iHe&)y$_mM5eRXr+oFrriQ8S*(?vvre3wPH^=&{ zetR+^!{G?;-C*`~fA>c$Go&+X{`}0>J+n8zbm~z*QoESt9PH}E5eyz)jAqiz=)|nv ze8TD5YR+nc>AN}E9L=*@_=+#KbHm}}&=*^O)=91wn4YDnkNEZ@)Zyn4{rbGrTfN)M2kW~3o86YuXXnKxNImgl2>>0!lp2gQ{e&nBk&^QUJQm!G}QMSJH` zzx6CGy=A7(MsMQb-6OO2osiCVXmyGq7pgb=zn@JHV!-zIvBI;#Ie)W}SA4zIi+C{X z`XJ-&Ys>=vR^A5w4nVmVKG3&u>;B(|F6L3*dFemcJJ=7x73WI5UC#88)bVwX!T z+kW2-s!bk#;vjoGd$SRzoa|`Oo7Kd!J3M zzX?uE`tBF*9MQz@^Ft3}S?+}znu|TZm*B)kuiRd4vN&Xvjvu-CoN@mUhpt}os}43l zyW+5Yo{0z3dyUPkroJ;WW6!Z3^Mzq=rta}n*VF4u2d5S@5DUSZ3#v{y@ev!n+M1=D zboR||+ix!P_UN@&EZa|>}o>h7@nQaTZPN3$4Q7Y@js&(oo0;0^%~xGLtNg@Qo4N9rCmbI(K4OZ4_;36Dxdu5* zpOJ9%IGbmnUg+$Rce8#hI5{ofSJdCX@F;Hg12$YWmET#g)wBBLQ2*FBV=-ReZNKl; z{JmRY)DX7%*~Ozbud(}HsRl9a$FASA0_0!MYK1bNZ(>os| zc7Dz>U;Q)}_-f=s=2zZ&(?6^w&)9vJ3oHJ6R`eEvMa_^*?;b_+Ry$q!@{v<~dlX)r zu=Mq#?)ErbWM8eF0h@ZoZ3g+lSYqn4XQSSyx;fjksX=@`V$_#9Vd#5?CSG53?|IX| zpWEW0;>O>8$>PWXD~3INOK)sqHzPXny7T-I-=5w4`Fao9BOJcF70&%Ki#``|q({H6 zU_)~I{A2f-ORp}=XPnPjGq>#d_q(Tw=U~*nW&v!JT&oSzHDYiw#;YjJ0E*_t!nVT zpyw;58D*nma~^Vx=UJmifJMreIH@@PkubgUp&q6$V zdUswt^F(x3{Y*T9kId-B(dR?vz+cVHfW8>n>0Zhw9h|uOXjU+E_6Xnh@};Y9d-I12 z!-mYD&zmst?D?zL9V`c*`b^iH?8#%_U7!n(vmr8)7v)P%SFC1;s|z+=wNCZf)R-Pt zOnvZ)=#XiL>?jP`|id;Vs`~#H=2*L}FAw-HUl;wihSv+fzNm zAvQIbwK(kh!>x&Thtv+EKA#y;I)8@&*1Os{@imKnc5FuS@nu(=c=2k1o#}g?$n`MO z+3br!XOG0v$EzzheX}YDzw8q)Ck$OVvfEqlJ+YT7eEX@t7~LCj)r|9jNoU_#!FRXC zbBFW6ecqU@SUn?roe|>S8M2FE&Nw|Rj@12f@xzE!Ke&9j#SfM&cKvUAx~UFpU+sEw zH{7@8pbz=z)hdp7sCx~y%g>BX!D zoX)K2$=&y6BX)K9obRmkABNvdcNRDwHaW#b;l*M%A9gk9p|ce$%BORohp%^g_leG* zGyCu26xZi+b;((;WclLTelwc-qw3bLe4RT#by;TYbB+y%Ww*!G=Jzma(K9^i4Ap1$ zZ0fVrFQ1-~|L%e_@f}Y*oWK11d^dxYf2zaE{SRB>Tm12S2L0x*RyH~$CSB(@)78b6 zY<}GrSar*fs}ZrY)mvxi??J#>h@DN};*ztAWv@P5{d${t`RVN0J1;siUjFWj{h&t^ zFP~hnI32P_xW%D9aq-jHx57{L`I2Ai&s3U|XJ7BA-kdR#hh1Dfb~bRY-1&-OhU!5$ z-|9;j7oY7nrz?JZDX$K`NZhE|(KXNTVkP5z!m%NHOOJ>Sg;Ss9dk7zQ&CJ{f9F9D8 z{r5f%+lpk+ zxyv=v_iXUvF9&-v%(mBKoK7sc>59k4La!W7?B6}Hxo?Qw9Gw9iQoB8F?l9heW8c}U zrTP0VY)0bJj~(Y{7UfcNb{KZcdtdGUW*o8E^Rq0X&3 z_^J;_F!IIuW&0ndXOq)H;#8lXqv@-g{C)?56OY|p|39|)o3Z(NXUH}2{>L?bjwO$s zo=rS+CyS*YbHIDo^6~j1k28hqtkg8<_pEGtdpg9fCWOmFhv<;KB`#iUd%q*-9S_Uj zpI@j$oy|ti>cwBYyEN!GLpG~-1RI*_>cBe_I5o4Y%ic`Qrkd^LsCM(@U$1=C$OmWB zgZwbz#EW3UC9}!%8)py0K6Z8B)lD{+;)OHgo=F%~92m9gsX3{+y2T^w33sp50dFsN z|FfWew=>fh%Xgm6jh+uOyW%uQwtD7c-%KXnOkw3j-JN<9pIjWZ_ni=)9m&BL&fZzO zUu1dvel^wAgZJlXe>WM%JmA^swC&mL`NsLd@wL>`@_hush=*qWW)Y5`+1u-*+4Gy~t5F{H%MXY1!N)GH z^HZB1*zoQXITBl*a^T{;vBdEm_{}9gEE{eiXGo{U^zo^_=UV;r-mB^pk3U_#;Jt_F z5kB?(yF%VsFt3mKveT)TOs6I}^DzUM>SW*cbb3d0?;OZ{oDn;cA8*d?l6>^t|7zsx zjB!i+<~Z@ry;|ks*UZ_`)aRFscb?_d6Mw#JFv;?g<*hDudYtXWR-bbapAD8?{bFqU z-4}V~#M$dJ&TpopiC4Qhk;Q)f`8Y3jtGM(CxA?Z_pPr75E`86Zz51;F{6ei`o$r`Hyihh4i%rD*!iW$Ew&$zpPpZR zXZ>OZzy9SfE}v>FKi*u64@WL9%v4u@dV6G+{#%D~kkS9XB`@;cRv(+bizyCU-}@(? zjo<&a_10BiF#PPRSv=U{;;nFD_^KsJ7Rwzl8{9p?>5(|aQlCZ7pB~|Ka`B^6m-WW- zEO=kyK0n#az`NPvE5GGC0XwWk_6)JfEf;;iUtu%nvHLufn-2G#vD(E^FFjt(IE;AY zeBsRI?UAlI%yeh`J1#q%Sh#p(amZsgEB9jC?>$gWeDbI3yy(2k{G97~HV-5pOnJq% z{>@f8JgQ#)V#umNtNAA8q>(iIBz~Aq_a=EKbWbH*uxpELcC?M=`d&{Q7{$tKC`H zr<-^fJnC%3smC|2nDlgbIq;VG$<-Y5&#xMBJ`o(EgSFJtvj^Y(ET$an=EBcBEHYoz zjBs~ZT=&hMeKn~(}yF=UH*yp9&(;$&$qt#r0-oVuDYrb77q7ZHv_t! zG4f1zhbMkAojv;9Q@ZqGAo+`DUtBmf)Hl6a=*eoZa8|MX=A77;~dOI zFV07f&WVk$8KGjRPb~H~KTNfgdxq3Z9=rR`7vUDYycU0Wamnd%dc2$yzkKvjK7(Jc z^si4?It#rRebJdioDccM_ukW6efKWKVSD$Nt2<*qxBIN*>lx~9W%FH_&5Ur=?2=)t zmmF>`NA_yx*IdbT@Nqb2-Hh$w#=dhPyEA<7v9s5+yTztwcJ~TLzxQUQZshj|Kd7IW zVp#P;u2ylnt9;Z;r-pjP^OdKwnEJbiWHj^5MlF^+d~p5aa!mYYL5Fa;)yLO;p{ss# z*!EBU_T}k3>`~{E&pRV__f0;(uW?`MkxpK#?<^B<2K_Fy*wyN6P`wq4o=$Fa7CS!G z_0x9)?;Cg4f1`>IoH+D&{lSp+`CpE!)6aF=UJkYO-(7&C*PmM9nytOxhdIx&n>jrH zm+a|L`kq65(PvkiTGO-f=`7#aZ1(D}KG^Pn`pf`_Yo-$qV{fsUvpDwQak^^LH#;5b z{V?^-MjZMuaAEnfi^(s74@0I;SDbWsI&sKIedKU-$ll!E-nvKZ)f-M6tNTk|Tsr66 zY$o2mXX@>>e$rK+eR8?z>PZfIdB={IpRTxUNG%Ar|1HxYdR)Kap>+AunHB22>+Z-& zUmf*ers6f*`qD!yog8$Y!-+?1&67f`mi^3^TV8iZ40if(I2&Eh3w(OD@k8C+{!D~V zIKJwELB+}rn_c{5Sn-+RLBJCEve?qVV_&C?>JawW@6FX^RtQvCnsEWhzpBbzDJ6$p0^J&-+G+*osque{l_hR z^Yt@R_mm&K_~piZ2SQ@X>mK&=04%CzxaI`cyv)e*Jn~_KrK`vKpXvK-H5Ybu{>v@+ ze;8MX-&=_zU-89oSCRQ5KU?U{>U}Wre#eWer=KPH)RS4N-`|5W2f35p)0f}J;ryMCSbWridq~g5DGaC`Y$)mUrdB&6N^qi)&BBw!>F$q_I&KezW&?Op>X(*<|hxCzf}%--3|AI zPQJ0r(X#MVc#zID(Ias(%TxR(RebC~8t?-`d@O*q|4 zbntyPRF@p#>u;*7Nu4j1U!89c_NYE_apTE<4M(TWvGb`e&yKn*b-Bj~UXQ(p?LE`# z;Y$y1p{dWt4*T|K-`R_~?NRfhYAvpq)>Kz3ygjP7WHw~azkPU|4?BWM zM~{9i|1?9oYJqwEVeRz+*SXM(OZW2fnVmbwhV0F&*y7OPK4o3S$<@ zxV=>`@RnNG%bmU)o@KIknV+ZB`PTp9;rjPKCVsej5CgSW3;&2*UjAgda?<5Xrf+V= zpeN&q-8)kp-$T^i=e+!KSk0$*K+kG5vZFz77PwdlcMkco$*W&^Epft&1+SNIWV6Qk zS@!r;ch33{r}~?eH+ zUOq&I7svNidwG!>?8{p%`W4gj+}x7o&^LlXaai)$@nYlj*~&u?i(5zxJRh}^s{{V8 z5uY$*m~>_o(INXdxx94hRHLPDdv%D@nQwbB+%=yG{Nd}7PF#4rc92hCtqjR9O&t+&M%$s{BVd}Pi7)E?tb;T zE)Rd)eGbR(ca7D?1|Kz#@b8S0Va-u|)H6#@X7jy+O&m3PhWSTuosT<1uND|RbWZe$ z4bj8=?0)<@f4S(#{&Xjb%l_72Z?-+E#MGzxqv{o> zob+T%jN&Tt$58~W#4{P^tLh;qtYIwXY94#3%mx)5)11-{P^6 zi_5RrY^Ye}^E)51dAU!ozdY`+KFmT~y52#s%`N@Rhr?(7>~d5$o0#JH{)5;MTy+$m zPM+?2beSKU*6@11nrD?aJS3;E3+#*%{# zx5`1T=ZSY0?0qKn`K}kwEq}6p{hq`-R)4(%*#Fs<``a_%y;pDIHXnZVs0J~-GsE!f z@44#D=iJL@zPP?udv3&)XX4ErSA&`mUp@C;&L7q+*~KP{(|Pl$FTQ362T!)x%@2p+?|BhReg0eH z-Cwg2TkUZFYBE1{!cTQE`H2l9U-8wx?cHN%%&tbJb-5%?%FTpPe`dGiQ?r z-cldjL1j=F!>Hc|WQ}ocEmVs|()qi_0M%tUZ}cEy!MtbnerCy`>L7 z58^QN=C3w$H#7f^nHYcBGME2qcCqaF@o@&ecd^SMzkB6;#;y;&m=zs=#9!~#@4ZD2 zBQBeI#rNlY>}uoZ-@z~k|J^D${hJvXS36!!f499px(}WOGM)TlS1z*>V{EOvYG*<0zRI?4~{1Me)vX*TlkM`oxd zI=$%GIW-qJ^-lG@JL;J~J*q!B!{hXp+-jn8hpR0-+Z#jPbbP9ro{V~?=zcW+)Ynv> z4_OR23*qv~Z=v#tYX;7qT)lGW1I~TxEX`x8BQ|$S?WnoRCk`$qJ1#fgsumo!IQA|2 zR`{ttyIA&U;+?g-?tR6tcVXx4Sx4~Ya}UI(*AsHTk)Gs$dFic*4}UuJ)^5+<{EJa9 z;={;6C$GBn;6C$1?zIKSX1;!=gmrds^5fnc;)>_o)Xvtds(tEjc68N5uC9qU7dCjd zW@M&e>BL85{@J#@*z9V_Mh`R9SD$|9;Kq)`3xgvuEHU3a9Mt;0I|exny*rJIY4Lq) zfSu~jL2OGNuqaL! z9#=OVvUhF>S06vzQgd~b19s}e;nhbEL)SZ^SUqR*!NKrzAMs2F7aFrHh_usypt z^mz5DwPymR`^d-gobX{Y@3GTYhckh*hiS<{k6Y%#Hul8`O9wOa`NP_)W$e?-L0@fb zF!o}pQ$K1p7kfStx$ijs&bep58rj0qxr1YOrs?Gt-**T#7Rx!w$qs8Tx7yqrd%QZu zP_KRe?tVY_{kPNge0Mfe-RH~Pu7B~==lMi($&We@@zq1;If|3naQ1rY-l_@B^qr@k zs<#=pSL2VzPd+ultY7+yo zo0B~BWD9kkhU-nEcwShcCVQ;mJ7t8<&juifLbtbog)o_G;I+x%e5U zJFbSQzRwpJv3u@{O;4uhL#9J&@87vCo_y6`t$ZxR4-XeMj6DnrheztrL-F)w_1;&L zQ(RN zX4PZyyMNvp^)Ak!-yFr^TTkp}Nkoyux!LKugX*l`YR1(Ojt^aN+2q1|*1F4Z z7J^6Rj{j(X;=eevV9OuAyk^ZNFCxG6>d5@MC-&+yBR=h6?CHt!i4Qw=d;PT!gSX(* z>$m#o?Bm67rp;yM@BYD6Z*zM47uUSSLFC`{7K5JM-aX<&*Qyr0c!OSD)!%*Pqb@jg zll9OYrrY*>>9@U@;*j&Neq3x^ee7anr{mXWvv)%8tbDpBaCE5p(!r>e-J&16873D` zPX6rbsXj7NUv<_mEb{r|dG9>bEv|UD@0>7tfEoK!E;W`%9q&wF%UjIu553jAVA+aM z&Gc%KM{V{nNIiV|{^2=*>Gwp{_8f=b zsm25CA8caL|K`n+-g=2&KH2q4esjavH#47IX7YYV-S#^pa@2DuhCbBO(hnK2qqiP% zt3F=e7hC=H$cEY{tLxRhF<$vM{`Fx)=3xfzKf9TX-RGNF&XwMsQ+M|fo*llNxEY&? z@3{7T2c7!vOxT(3%+0wt9pZxi?#}OOe{ZgM=of#Wa6S?_!KVa2|>jN$luU@l@ z@h-9L>!BLM*jrKO{_4W;LFzF-q!vE!9qT(6yFRMl9#*aTSHGC%fI44tImsxS81~I8 zx!KywVGrAUnt@un5A1OEaOCC-zwLK+?fH=3v#__+jEnKE;;_AS(oc1<$PryQvRLVG zBvyEG1lw7>XUJYnot?crY|ZR1+cz_u4Mr@yT=1wE#lh(!vRT23hsbd@G1Y^ z-C&1vuVLEvT;M*(oAbmkruayXdbe+8)hljwSEoGe7XRwq_OR?^{Zv=+@V;BH>E9gH zAP-;hCSH7>-D57_k{e;qFy_Peul6YU){d@ zAvUBw@%*eUFIir)Ro$|rk!{dArJ^CG&U7WWDxc13nsLh`I z+Ue!4zw(*^8!R$wb;yVKu)j3bkr;5lG4}Zb+FPhIAd4x66{gwPr%(4AE5~4m%O>Wl zBd5cCUlvdN?u~m{T`=a&CVqdG)LaL>?-es$-}cD;MAcls)m4A(@#^^P$0k1h`q9Cn zY{~86$tc~sPX|}La`2(kzXglC8!%?@o<(;Cj%)^GbHhC&WdCnYcU=r~ZPsl3@Q5E7 zmW;@#+~jO=I&pFF_&8V3>%u1vYuaEbhebT;NeU z^;JKeT=mOV{o!9uMxI&cpjNVXZs#KxS#4q?G1aL)XF#7_&)M~CvC}nQIyG9|>)yXJ z9S)XmkRv{C40itXzE_(qyIHW|{K@874T9Oz!`mbM=({?aAwJkQV{&oDkiVR4?^&>0 z>FT%qY9dGKL2%^G-~269AN~V zc~NojW&oRAk8ntR^1+f}$jy`NPS}g#@5jKnms5Rt)r(-^?9D6UFORvPa#oYSzZlWM z@UhzWd88)s#gL1B+pC3)V2Uk9I=E`U+2U;F6h9lgeSTr4I-S_;EqZmS0au5*$YQuF zX8q>SznOYxG;iO{$~p0SFUlXLTHq|WXxr<-o-99ZuQr6!A$F85OgbD6N96K{)oU^v zI`AL(}2n)zx#x?pg8Y{^r%6q2k-#&q`*^*E~EMW{M_$XDX)p znp-kl=R)R#>hsmn+v`~zXTq24ZmQ2-uPyqi4%2z?x2mCgJ=OP|vC~%vj`AVPo8A7E z#iILbyjbi=tzyBl$?a!Qqz3OVf5%5}_0x0D#t#?Axrk-aHJ|3;-08Y|6OXD%EDHGU zNPW`PBVD!dLHs)B;?c>6$|(+i6wemFfPcgki_baiANKjZa`p5cWP9VhK4QrwE{fB^ z@kPC(?ajko7oXnWLBXv)tE!6{!WTeeWAF z%$+Zpj~dkm568DN_vd8pi_ccXrY12ES)5|^9S*J@CZ1h0s^o%E^yTePh=zteIqkN7YG&LB%US9eh6QuOB@f9O7ruj~%CnsYbGMGHbZ>;q8k9 z+oHGZt1lgn7VdKW?0)|F*K|Ge;lxyrv+y3|<2yjU?Df=~s~^U_x37-+vKKQwE|&91 zwzu>|7nbfNc~H7n4ok;BTd~{Y=#BBC`STgGhjUhX?z>g@iB2EgEqi|Ko*O@p>d79b zYd`V-bMMX15`!IYj^yU@&WQ{Q*ZDLHdHK;J^@&lipn4clG$5J?J+Ve$BmiDjh5mpR5Petg5AY*x=ZkVKZ>gX8Iey7p)gP z%M*pI2l{m4!HQ8`Y~3HV*znwz-(InbRX@WTtfb786Du+`eZapJMk6 z(Oa-SW0KjYy1Mj49~WPoo@ZR`?CS5Hz*+7Hf3=!1Ztr`I-uTrAe==S5liSzhAYW|p z&7QA(=3*v(HmlExr}J~1dgb7U=PR~Fr#^j%Cr1B{w;b>mtUT;|$m;CQ=uI4U= z&n6xxSaT(h-FLHW>SDvK<|LlF_@d55F23c2W0Sku+V|ZU_g&6i?)xL&8OYHL2Ki<# zraXAxwdC&ZHE+IhJ*JqsWD{3c#a{Z63oS@MXPzwe3ps9hYsp6`iA z{u}f#=A%zB>|x)UvcVyFlI`=E+tq6h>Yx|1zR5lB`4xwa&R)IEV(N=yFR%UB5gokv z`OAsu-BWwGF#NkG{W}j~%tjn{q1e?T-e0B{hppbWy&P(zvloNxS*Pb?P5j;w+a3<~ zjc1SeqnDQhrW|w@A9!`9vrk_?_W84m&quBFapy-yK2xg$md#w)^_7pg!ui~Xb8qbX zcP;4LE43i`-g%}o|N49H3mt+}gTAp>!I*O~ z+jkakt$g{ZQ;coDd6LyyY?#i<{WaU_6B|{ZIq`dYg|&yV?0f#bPsC>z%V#Q*kM6I{ zk*+%U$R{R!?}hStpY+a!YbN50!G`GT5f_i%%*b@)vCGrX>GC)`_eoEk4eT3-UomGo zEFEfw)kmincs4Udbe*Bk0lE3eTRu9(&mzO{HETHadKZWFS?~R5nM3cIY7k#7Z2BAf zW+8`objV)cd|UkF9sBMH8Hvq~cdzU{x46%gvGZ52*keb0kb32kn~%M7mD6)yO>Fhi zS%|@I=}jCuzSZ34n*3(uj*`t#Og>}xT^l#=?%c$iKfmgugOdjq`A*h504{$RcD2y! zjgS2K>IJdEv(Ys}xsf{G`Po+&-h9kK9Q8O8{qu9@)aCA@ZIAd`;#u;mmkgkmYOZH` zXJgL}i{z10E#g>oR(-OGuRn3euEy-;6Ccj+9>pBH8S>Mkm|`{SzI*T?tBoI0hrK$@ z!&z8j&`)*o>P39>vQOvFqxi^=oR?UZoOEON4#VYYZftzjBVY4oZ&v!8>CTB>T)Fvq z*RfTPv-LfVO>X`5+{oK`z{?3IPxBJLzWC}*&+KtAM6Rk9~cqL(a}>;?1v|>|&^ut-9^AnE`*qPcG*`SFJGg)j#)(OGg&VLSjVl z<%z#J!s7a~$|1%ZubIgC`qA@2`O4Luu5R)4)b~z%&&PY;${`jKkIuQ1aeiZ`XR|Lq zS-z-R)m#63+3UfcY>~xcFJ|$=hjXX(!%lWaeDZ@+Uw5Cr7-aPfawLXW*>Ur${y~pm zA__QX_Ug08%@|J3?x8dAt`NiX=4S)-!_lj`zU|doz3`or^WbBT!o+8~95`Gt>kIBZ zLpTI$so5(2tB0d6mOZTf>r;+!%{k1QUwpJM-yKP&7b83@TXj|&jD@oEVOI;A+~MJT zf6Ax$Qyqq$j*s(e{`}0}o=t4a^Td`8M|5(M#jB=t)x$35yBDJx#IetAUybgf8j#w0 zpTPLcGJ8G1!;Bpsua4g~dbyEa?QuSI@>NUEOus*q&;50`;d)m1k&COJY+~8>4z{lk zdP@(uo^W<`*Some-ubYLp%yY6ns}J%;9Cs#`XZ|(;wMh~W>OqBWG^p!HZj#E&sztb z9Q7^+U7XB@^!$4dC&$>;WiOXGxsRya?uFdmOUT*OgFTzSuOQyrw|zfrdw<#YEc1Ww z7C*Z5{u^a#?)wU;O9rJmR< zH6ii36V?3c*u=suzH+Gzv5|2kKW>h2FycjY@Y+#zBUi40n%gZ0%_9&ek`Mvegp>*VMV)3K<|D%~NXV~`Qm77kSFgT*? zJlelFx)+-qF9&X3`HEQ&#bB!kHZv8+9mx-t++4-wLyzR}KJa~kA3N@h5MQ#@@74Od zgK+ZkfwPJ)-nN(5XJbEaz}Lsre>xYw&F;Gt z&XN5+Du1`6-x2Wfv#ocXpO;|G4$eDCJ>F5`wmcIStpD!iOn0}&Ier(lKe^cMR&=Ws>$Y;L%>dk!XRb28^hsWLh@O;Ix7b~niU$vVxy?Jc= zeV6#Rlhvv|8**U6Q_F&XYsS@5ta{sxe%EzJSwK|Vd~`jKW*ttEV^pl z_GaZ>CAS*=IX@EDIrI$Ko1OmTvggxt;+-Xjcg26)Qq$O-)8CD&!@KGq$K78f4n1C9 z6R$VFH>)o-!;6bM3$^gm6P$j70IyIi>Z z=7`MO9**qpc%Ix-^&x)SUO##vcgNVxL*Ga&{5`w3NBQOI@3F|m-d$=ogIxdl(yOPt zB1U^L4_-enMr<)6KI$?@ zvN*n1zB8fg8G`Y7B4&Tb*gVB3-?rByKK0i#pZaSiI321^yk}etbG689u=8(C1#8wwOa)<2oK^BkPTwut>gDr+!gMQ?hM(}VJvgcEMW@qv5a}}q9&0j6$ns~ML zGlF{9VI$v9nqTvD7UGH%-d$5meiLuzV(A@KJDj_~7r~G%^JN#CpJiYDxV?P&!>DKM zbn-Y$u@F6dNzAYeclzl z_v`uZr}HfE(eK#(J3HbPUo17M)z4$$)Y92Ct898mCof-A9yb2nC3|`3)MhV+8tmZ^ zna;C8?lY-)Q{6r2{>W=q>J+aWYU1zyr7L%5CLbBG*>^VfNG)QEVGk3pCOVW4eG3+` z<8K@ogokOac=#}Iy-U=jcR9tZr`I2r&7By#=enOcxJ`L>5KJFzAn zITLegUv3~g>%*jM-N;eSv+catq2@yyPBQxlsy&DUN`?{+^wA$MH;dgIs6=@aie5*;5LuJ=Xy z-U~Aw=}CR+ppe_DSMpnb^3+#fIPuG|P&cRgQIA^q%1@8By}cUQ-q>*La7do^xR~_C zBv>y**rY(Agt0vM0CXDVJG07Z~$~aTeW^{#{RJ1duP)5OuU}+vq$jN)Ewy4tas!+Xb*?T`fRTH zg=OQb*56=|~VfAbe6E7z&zWUj^Q{u}lzC2{VBl4N0-?6K+n%UJYUa|E_@AqY5 zoA+zjJ`=b5abk)mWY0N9uvAUN|KG|Gd@g+57J|I5&22Cit#&r`S^VB!)bp1u82|q%@%cym)q-H;u!C2_8`N~~QV!+xLyS=%*{$ktXbGw}ROm)w1 zd%W6kvGn5%f}QX z%O5TsyBy8sjUjG+uMAsVp6ljJZ&v2SZZ5c(bVwXC^<3~{PnK)j^Gmj`HhyH3FPwKF zT^tVe?7$SSKI{?ho_GK95s#fsT-0|AI)3ut-cj)O;)p@^85&02a^rl+mj0WcxYalD zdo~97&QLu22u@DE%?8FhO>F03@4k7?5ze2?mmR4~uj<#UJ-hzM@7nhK_{z(N-Ciwv z5=%e!^psXsb%LUOau2XX5uvlaW}ke9DnL)y>45Vd}LSIwLs!cxKd9K6=W*a+MjD8>F&;IF~qnOBi<>{GtXU-orLv>kV=(V$9M|#J{E>HgU z=Br0o{=a?vxhyJ|n)t|v#1g+f{?1xVdmOep#S>@jV&HUY2|x2!H@|$uVdIbZys_ZI z;|NaNpWP3h4;|uTAv5GhUtD^7Jj#xnxpQVKkDi?yUjK6V3=^LX=j;2dy@l!#xA@g> zHBWW9?5oo(kT`t!BKF_0>h}ln^Uq@8Z%+Q@6}x;e;nEHI%}>p3+K z?@ON>p2PZQ7pwctkH6W{RdYSCm0N9aQ(e67u^8~pi5w2+C$`*VcFQ|~FP&Jucl9Qx z+@5iKs+&jk@aH$v)kiNEJsmlsi^L_=TZi!O{hynC`uJilfyM!mDutDg(~PRe`9 zcVLT-U*}_1zT5geeErdx1Dx+>7Fix^rke#FQm45ha-V&@OS>Cv^(IF(h-2n`4;0hA z#MLAxg0cAW!O!r=Kg4d{)ymY|;E|Yg`P-A#m#&(pI%0cqlysFIxybC|nG1cn zJQx44rDm~FKj%+%XC59`vl%&S{Wk;tYLRQ~2v*Fov*G9u^XbWO2+yC~9+xMqy;{^h z@r%dTdFm6U^W&>NoLwCJ{rO8jQ+;#NOa9`yN4T?xm79#4hkR(;qs~cQHcNfISM1eb zk;U}c*m?37zx^OrKWt|`^Y=TT;=|DwQ%V_YW05a`E ziACou^yv3fV!ctxIsWp&iK(Y%*}1BLzPlw>wZqPI??#^wW?>E% ze?EwhyE1m4BRHL2EO;@I^CuUFtVW#AJ0CgJQ13AIc(U5zrn>&<<)kCy$ShFL96$LG zTs6M&&-lkbU@p)f{|IkeeRT4?Sh_dQwugaJ1JW}+KedZj%!w!Kqu){KL0sev+yS3o z`LbD^pBT+Z4suwv6$_3`=l&pjda;@fy*O+Z8I>blJ+yx@a+pCjzU1l=(>u?e4TU!^ zJ-c&qn4{X*-<IO^BOIMYE}vLaT}--SS5w&Z;hU43h@K2z9<^?Jx!9bC zr8hX|I`vnR7~;~yi{ty4XHq@(TIU(e3JQ)TlOeBe{;|~z5H}7IyN<0?gKJMb-vJ z<$;G)TlbgT{b1{!;r!f}=4J2wfyB1h^b2RfOm)PrW*n)Bzx&^3GNAmZoOb=y~i`{g}VeYm)C zt6xkQy!q&jzd9^w|sldgd>_JiW)^^MOThVsr=T)PwV_o~e%L;j58SOoX$uMajhx)1s$)_r=81Pds{c z%^${j+3UZ#PQ0_?_@1BoVC6N#@Xfcr_#yGddWjy+LiTFQHyhr$!pLpktmx_~8JDxU zyfY)C*Vc^k`9b`|72E18d%xDdI(iqtZF_sazY-@Lxt!tTs~5U@7Sk;8vCGenrn?D^~12Ea*>-^b-=6dJ;UO;2leIN*Js~Ns@pSz__;%GzG{{m$(LO`a<#D2!N`lF zsSanKKfQN~pWoE!_asQ2;)$y+zq?YG9=qQYFNa*t5{V(U_XK}<#An;9OTYB|#8hKF z$k$oSbQF$W49e;t^Fd<0z0&c8CHHQIL)qIGU%Vg0KRr|8z=t8jg|%lZznFB{#cQ5@ z2V$d(_`J1<#Shm58z00fVeI={6y3+Ae6Al}h zx7gX#V6k^5_Tq@^?jZPNdod6$H$03xqIjKdy=0LWP*gaQ04^v%F;_+!#e9A@7*F5Qp4QuhWCLVRqr@9^~ z`TI^$9Dd^TZuI@c@1c?0_}InAJ15*s%mWpt*{VYhvBz%SdWM5xS6{vO4&|)ntdDve z^lEU9@Nu)_CvM*d)n0BrIZHXoYLP?D@|0`hfBJv6`2FKJT(S8^a@Ug{W?1bbnl`^V&m$`E*80X+g|<`M@Ib21U_8PkozbWoH;ckdVA+%(c@yNC+^)) zeK7xTTlezwdwbP&yiFWBF`iGb%dv7Ov>XLIRKdg;69!7^z&O)^(TNV7m>3g{jx^4U z$AOB+C?Kt+h=~L!ssIM?|0vOKfB~$ zCMRZn$pM|)W%U$`U%vHLuTvc;CONoie7%U3Ob&eU`4%e~J>Pn?Yijk`jyh+{t{UwS zUJiE7Bd4!=Yp(5Y@n(8hP4;a>h%J!H*X&E+M>iy@ygJ)f~p zee`r8TYo1OxIZ!67ufOm-f_tJ)C(JD*bJKkT7GtN^Sk4*p+oHfsy6Y+?NDdF?tqS+ zc+HBgI>f=#@y~}0?{gR0MO43Z{L)oRJ3Q6tg&i5HK6a?M>fs;tI}~;Lw=(nq>W3V% zQD=XKKK9v#?9C9c2l%=oo_bIp85Qo$%~Kr zHwMh4nE9~WQy8@?&2d{-F8r1Lccm zbN6%G-8tEcAE=>xWYsQb@sqh@bN7s~y=SD>?8iPJK6^RX@XO9wZ4h4`RBUp5Iy_%z z$R-}8;{)V-;a+kklRsdq&wC#1$imz2o)bNt{=E0<;my42vcv598PPN94Ag9=*g4m4 zecf^S&+LHwVziH)YH$Yh+2QH+V!rt~H`Dr+6WANP+5_>~^H)>-s>$backMj| z%juq>ovNm2`NR{u`(dvpxx|5NQBWUz>VeF=jb8japW3R&=L?(Wfx_k|9)C7Lb<(LV z+p(u7@$IiT`QxjfzaG^D)Z)wr-@BcT4STscB*wY(7 zda>0B^imD%^P%U<-aUw+HhL7WQJ1q>iccnf?;f#}Pj!67G?V^byE*&w%bA|L5o^a| zt3Mz{zdKSx|CXItdO+0+=*`JJmb-TVTe;b&{q9q(WbQ{#_8}W_?)aT2ex9>_hR}~# zX3%|!%B$qJEgkRAfNBZz`uXORz9)BXvS>aJDr&1Y*1&jGkNW{PKwD7 zetbTj74ng1FLpe8!-j8v-YG6S_U)_s*i-`>cjGSbovW2Cou16pyF?6jy?exG7l;SQ z@F<_|RxChf4$dfG-~H1EH%}%P8GG0nbwBENM{lXESF< zE+?L>y5&+svGC;;yE~_W5Sx9NshGOAhz~XS2HRt$EOATW@soklPV_GePYs z>gPS6KRvmBa=Dz{yY~U)QyjWJx9y3%WT;xlo?4yNj5e#W=h+Y|do*OHhGtVdyC;`g zi|4N08~b*XeY1&IgL~vxZ+roNdi9ixygK-hi;uD!IY0-gl2v5#H${OOw|ImoB@WM)|peZR?0zI(3zyJ)ezJNmguz3fqU z3aWYHXE({czvKdUt@!T2JjAmn;y8~y{j+m6XF9d;SLcprwkY4uV^93<4u$;O4gTJT z9iRUXI()ifiU*2w_gmcb{K=fNlQ%muX9zs+W{J|ZJM8_AkX+AZWR^P~82kKumM?|c z%?XMtkGR#uZ{njPZ@y&C0EJ@k%U2C#+3k2h9(y%%^061UIWnpi6coSS#Jy{G))xvr zV|{+wMgC&hLA+g+$9vb$3F7k8zuf}Pa+sqS>f}qt&Y4Z0rOlh}CnpCzA99-qU*A>u z`aCcPy5f?H!`9sbyxy9{edlz5UhMqGKHn9@hH~lC=Q`V-#~sg^Pqt)g_h)|WoV~Bg zfy${@-(CD}Y2^7g@XSRlHM1T2>|*aeHtMP7V)Jo-@}l&7NaO*yysqxbnci=eUMBpJR8)UlgD>Q=4%J%a&kAL ziH@xL_ye&)XZG_MtcH_S8PhIdc5vVQ+@wK{gPuWuq?lBnNx(COW>(u(;&v;a7j+@@+@y znin0Oj*Z;TVC>UtJy)}HbF4-_;?ap0Klb72)C-zrRGc6iJ;+1nUDNO6oW-CsKkqj@ zKh%uOUk&23x2N8BVv^}oJ)n8GFMkh{9~6rpJ2AdE+I)H+ni)UHzMA={t(u(a#5HSY zpLJ?cFI#$fobjl$80k=XAh~+v26UbW;Eb9B+s^e>ZE^s0BvT(>HI@rCKWN_7=KH|R z&cFM^1~|JbXEBN=w;XJIcB)qoK5u~Yj%POHd{J@usj>dq)9W2oPd;?FT`|N_10A0} z7ulPmSpzouBy+!Fdk2(%?CD8v_Uz1AT)D{f>`A^&tn!M;*>`tDnr-eSxv3PW}O(a;c3iS)fLGAiti~FRt2e-0=as z0qB8uh`Z8@dSTDuC&#mqAIe$JY86XOBS(ko4Fz=a@FV9-rpEh@^yZz3ipy3$G~L)o zHr3e)dhvf@XED_+7hj)4=50o7#QFC_KA#^2=2gG^`nk2b)jRX!TmS6noyEnEJu`FG zmzc#M1MQ*Rrnl2<^eZM{S5J63AbV6VC|^{+c>a(Kv=?OJkfGjla`JQMeAQJIVPW{!00=e+@ z#~vi-hY#*~c#hNt_&bZm#+{2rmVfoziR{Fk$+2-CZ0v>@_NRKpqSuE6d88P$>?67;qvuA^fCk~#yd5Q(q z;>@P_^NZ%!ez%n@pX$j@KK}Y-3!JlOr(SilLBs5vZc6`Mw zo^$cY=$di6ln{(_fwtCdd=H{D=nC#q<&pZF8990AoW(RV`Q;WLt=_Tc{a7u< z=F7)Bl#b8cL+@F!XL9yY-Nk3`GeVsHevUZeu?yW@-;F*qzR!%AyvyGyeoV_#N z9NDlX$5;Q@!xvMXbm~r4O%oj;=jXr{#FwW!oayvgUb^l`P4sl)(m^$&=49ULF$?wk zUI6$szwFUw&Yz7K_;T@O7wDNCPy--yt}bU7(A_{TFB>(Y#bVdY@Kc?9(Q@;l?~I1z z0l$D=U!dnk96jr?XRK#~yziOK1no21-g*wq)!t{bfZUu%f38fh^apB<9qjui}K5-^F*fxF>a`4R6HPe^*f6t zW;-UgxmLe-02^}#=_h*bq0c@tw&o1olUQVacQ3CzpC9Ve4vw7MYG6CjnH#%iB)49h zxf<}~o-=3hAYdz}`HKPSnQZ3IeAznZTc7F|qq(pVW1_Qbc*w69&gEuT{bKp93dq@c z2jc-bnR%Eyd$VYN{QX_${#zOPnVsiFjpi?}+MTOOOrPr$o%)8Vt>otE+#RT0 zoaVw_efB}^^v<3KHh6%_OQwDxrn=;)z9<{dhWKRSx=*~?fwOxiQzH<+_k@|br|M@X zE*rJTuTHf4WRoA6&!pbjV^0tAw!8uvMLGXc=#Hm8yqZz@Mvks{WO7%txH}$M_tSiw&43SHPG`P&ahk{2 zBcIu`hh%pR&Vl-XT)-J0np?krm)oYN*Uw#> z+0gZ~i}`?d7(ex~sSjszameZg-~Hgl9XWdRKI8eRxgJpU>W3cnT#&PMXFEPSa@T{` zi+FhGoqp#`E|xeWr(W>^Ib>IyTgFa*`O*RQ|n zn^Ez|=$v6b%{e<%4v_5Tr#^dfm@+8Kba9%s9VlDR*%7l({qF16EVBOW`tnVj#EeI~VEbl$zq z1-;(~?KXdP0r}zmEZy~rp{HW0$1}!8KKtEF>DY-Uesd6;eB{i&y35Ia>Zdonp2RN? zUuRG)cT9HbMA?iyd%%uwJ=3!_5ARR;Jx64qociHM=AG2pXIRi|@-_eFz(#IB2IR_C zY<-f!-ZSc?Qy-w)@tLif>C4T}Ox=ro?5iPPI`QcJJTh|rUU}zYu>}Mg2s{Cw^kxK78*!*cA`Y zHfV>)_#{X3!Rv=j^Gk+iM=w4Zp4^!)APcL{jNAjNPgG5O*f@J0M~=T;B{w@z?0EYs z2dD-$t0i#mPH)>=#{R~9v%lk!iJ6YAGX&&eIrt}I*I6GsK4&&&kY4Y4HZyi$?3oFf z@BPIkr{`m) z5r4hv3lygw^hO885FfC;W&E7$Nx#L)2jw?%pxEm5GlDZeXZ!1&)bHcG*VJ4NJiQ&2 z=YNg5FLwjIv)#3NoW<+eS4VO5&PLAOfn?Rjmn|e4Ir~H2{qv^>^^c$V*@fGVoGl&N zOvuH&&((>Fd+Yd?D>~6Tc9FcgM|$5UM|qx(DPR(U`uxAC1(%y6jam9PY?2w z0aUE=IO`wSn|8~-%FPZnhjzQqCG%B}ovQ{llc4|))zCcjVJ?tw&&1d>ll1)5M~;T- zAscyqXVICjTJBlVfn@x%t3R>qx3gYRzz(+4Y9g-}_4}?araKTL8&n*9`Wd+IB)(7f zKA8B~139KTpZnzPqdB`Hu^>A!LGv~ncIp7?0?z#olV5r^`c$J>?w-H*ki6bOV)}dG z{HndVIP>+pMEai{PITU5b_kSbFm9%(*)zClkX=M^3L}k6cbN@!0u$ zbbuc@zF2s2`Q)J2GrngdU4KTPhho*v?IW4R$a5REt6-m88G@4KK_;*7uCXEZZ?3u`pDSA z>O<+p(GMH5A=5vIS5NlUHq&Rv$;7!SoPYvZDN9E)ru6M}D`FnB2Q43ppRV;Dz zz`vjM`%LVaoBDa4%&DC9oqi!se))iU-Z&WBDcb8&BKPz!sqYMST(TgX-nz0BtjM`zGh7 zH?{hn!AH&Br~P*TYGtdw?8M`zUZ1<_aE3dc`I-?u1pKQ(9de;!v2CW+NUne9a_x9} zCF{Qr^n8nJzv;{2&t}DtpG-bEfODu{bFiCifcX6QJF^{o^m;9py3E~N*f@i`7q)cb z)tfUAQ#|%4IeT%SGade>J02N-kY7{`xzvV&V)))quV<)7s0a3VpG$z9ymlCWg!>;d z_9F+%!A2gmeY|VpPY0s63@?@%g8cd1GhindD4(2qdh?FhL9uS+Cy!^F9M~tjNji0sn^}ULYoDaD?0iUosodLV*j4zJa9i#ov*mH-?gpGTU zR}Fwabmog!4_kT3%jKQrOxJwbbRT}+H8(Nj5r>cbVvHQ1xBKpwPF}r! z^iZskQxodl;vUrmnRL$yB)7WF9KlbjNjT-o>2h|I?*lhWm58i#r-R#QM z9FpfF$IPF1tNl@%dek76`G|vuV~^gf)J6}`dPeO)vvQW3zn;yV-k$lp(SX04a`~L| zndwZYUbCl@v(I@x;)=zFPE2SXa>*&bJ4fk8PTY2eoSiu4>kj20GmGv=UGj(_uRHPg zslG6@AD&e;vlmmnY7~pDdCS2D(y?WyKCyjgL(R8caE4-{z-+~``#=t{oW<*|&i6uwxb#=+R&3qP||zxZU%>Nan={5$h}e{8&bYIV=-KRcvj>t|znv#LjRt5rNy z9zD~Sd+f2{E5CbUr*5(J*R$qKKh>#)y;x%NN1X%qz&SfMkX$VNz8OAsDJZuroVe2=PO4jCRsi5D>iDz&6y5@`1(%XoSf-^Iu_>a zd4BceUd8X3V0WDMKiTlNALM4rJ{_6oxcwzpLwm|LAN9y@55zPNcFl<|TXrKyP6y~< zG3qb-7ps^0_^RRVU!3}6i!X*d>{+2JPj}zhyAIEno!n3ylx*aHGrN4#iJ2{W$77R@ zT|UJ?LHnsk_TD+bv+CbFHdA01?HN!bx#t_WukOAX^HH-n@)w7me|^fS2KA`H{?eIu z{fSNH%!Vy=u8*x>7@^v=&ljb!MK&)p>xd#V$U z%xuJh_dM){ngZ`NeZqD{4l^Hl{;bAlW6wZyV$+=Y0H@65@r=!L&}?VZmlXZFQF0XYO>2XgoKp83)9Q42fu0&+5F z7rU#z*O9Ry2V#gVCZD@Uy1O3F$VA7MT;7o*(_1~DkREORa^TbRQHNM$pyx*&s5-=Sk9@k1?Cg2( z2zi=$Kc6{^0qw(%XC`X!%!tjOPQCQLACUj((A<7$Xb$RE!*3b#@%I||nO8mG*#JDf z+u$!LnEb?w%CqA+mHid*prLDdl1ha17|f=BOZeC7N@$&>*K}p<$uj!s-r{2q(S-eyTQ2}Y=E=A z)0q+89TY3u<}=kZ%X_Be?YJE=Gc^J{y_xuqZVsMLx%9>lc!tERU(Y8nlj>3rbT0le z+W*|K$k>PnirG$8J6-pT*c#S9&D?vePKtA@zZS zxNPcA+-gM4S*&^{Yi<*tcx2rne{wbfJwVkQ)B6?lnb~I#J9x12nCy!j7_43N+`L~6@)zF>-9K6`pSA4j&)w>W4FvS&!Im8)v(IeUn{T1^D!M@q_HjAr>?v`P*l^9^VZ3uxS?N zW*#VHCodb%65g{WC%bZ?o{7%vc6|2W&7N;NeEp6+z*i1BP|qkpt38|Qr1u^XLtlNC zuq%%5h|c+l6^?z!4mi`z{MiFCKvqrF(fP&V<$tqN59n-W=BR%)**{?JZ1AYNWMlSx z@ zCjq_K>BxFttC=kX#S(*${n3;9s!1HrK<8%b_cnZdKl85Y?<@6p_lx6qb!zL`P=h_G z?s7-PR2Mry9yMP&K*qMXWOR@Ze>nCzfx1%=oUw%-NHHY|((64ag?hT??De`0g=E2J_XsJ(%d+U2-G^TW-E{dw^dxR7dl<>%MK0qxpyv6udLau6e4b9CUaxP`q1TpDz}_)=%$O zKK8|abayB;D?itWVSb(oxjb{`-1ii|a*9JvUoF+!nH|2GcYH@ba?*_)=zbjdiVx~h zU67BO$ss>IsvS>PTr$0|<4fQ3&4ypL?US0pRL@Q)d(phiOYCaHx2w0TS%?MLd0(>0 zUw(gw0;s{+&rN2mR&n*DcJDfVbYie|Cw?B2%YBrePS50hPv8eoai%_hK3sof^3e0o zUR~-Kd3KateN1(LzP^ejPBqapl&>84V&}__+!@A;1Dw&3Q)hO`*vU(72JC`-QFftz z*tj1&usf(&?jT=hx^^aedb1um-;>40tE2c6ot$V;T()HV_yDu1Rur&NLp)ox(5n;V z*S2;#hPqEdLjJ^6{ zJb&P37pj*tAFvAyjXWS6fv&T3PWGrxAES|)mG z^nHj;^O3uF^&n2amlK~2on0C^x$28fJivx;vBy5|sQM8P$SEFqeRLmmY(~yJ#N+3z z&-%J)_VhQh>730(Pn>e0)nV3b0eSt|i5<^#uAbg^{LI65?(VmGQ8ES^2`9&u>vgVLntYmm{Sj_v37YE?=464l?`L1MkWb`OopUvu3n>qR1 zChHj)d*acF1KI_=IQg?ByJyguU2=8-8J-;~77FNq=fW9JU;XM(7n!+KN6!QwHgd;1 z_Y7oDXBJ@UcifRPd2?;HWS~2G)4wwtG1S!OwsYTi@4t_&&w5g`cN{!}-?JIn%><^oDw4Uw!VTXTi*Y8hd8gRkK*;1o7?(&jtlP>+jjC+}U@tmyO)$~D*XdklTCbEfa}v|dm% zl?QE3*~!IM45&un9q#v6{MkCwt404K2h;_{rY~=^QZG3ed%(FE*^_0LPn2AIw(5T! z=6UAGCqDl7-I$F!P~S2A-bcUe$%`YtTzW^v0Oa@m?0DwKpDnw7&y|j!S&{Q^ZqD8@ zsQvU#(Gye?+wPLCT@Vk*Cog}`g}TN*pPTXkpEY8!7tinSoS}OXLytfXXQ&s{T*%c$ zhL3iq@{19wh0RRQy!o(|lN_%;_H?j%COUDFe{wo9Ihq|mG04f-_Kc7PV&X>*<&z&B za4tWp=W?^bi}7Zxi679@Ju|!-$zhNU9sbwD+ec0|-L)A=+8proAl@CTSsZq#IL*w? zWi$3b{dPv1i`dnfU3HP;L$-X`k%4^aKxcK~)pgH`tQnwo>6Y#I#E9oFAA31_ru9i@ zerWZxaW+pr>`=1m^KA62)AdX?mpfKFg#y0xVl@lA8b?lza#hpB$DXYi^0_;D&wkJL z*b{@Ddt}$|vDuLE!PAK)4l2JsN1l1Iz3alic@_uG^~@t5vTXB1+36E+?&_D{@7Mjz zZ{}u6ch~D(tS_?@+jrie_|9*>3;E3a=~;aC?AVX|e_%eoWALp$IlW6!^|rq|o-=v( z*9_#z4qq*EKj57Sd|tAHY@%b&eHAY%fBB*dfBJG}hst?Vy@P70KJnDjdxRX2r_0xD z#CH#71k+7)KCkQ)J2vKLZhZ6>-SL@CJ?NWUys?Kz^TUgava7f1B@-hXy!z=Oo{gHv zp6}{nK%idru|t8})gwmrdsd(vJ!9P`8%QU1HSBm`q9c=!56TvQ?`8F;^K-GELBwl6 z)h8aBo%zT6`$6E%8O`L(1*I3Wd8$V|J|hRj18mUZ@iPZ!HX|pOnK|nRj6F6zL%u6| z&gBxbSvEKRzT^9EugLg~oS0*ek2Byej+yA4pLYqc(`fzai#{KI-ZNx=HmI+$=XdDr zfZwmHSzX{G)T$T zY>U&Jt5+%{x)-`OS0)||{-J!&uy??wN;wZ9MC zvx@h3QrR_QcD*nB+X8gmlfBlbKFH-4d*lH!y;qx`C)M+FL$TSb4X}a5ln?J+Dn7qr zne{~H*%F7{UmsOVJ&rx{VzLMBnVt79n=ksGf!JmTdk>N~Px-~-JM!#hKBzhXDjq(H z2hCIObkLubkDR}2$mXr_=1V6Q9p2|2@Et=fdJ)flj+`AV?nKWl#V|v2V_P45#O)5J zdTiLz@f$fn4;;kMv;5+t&OR5N-OI@Hvx#_SE*{EO{djrk$?P8Ny=m^wY{is!? zEZq}7b%XYDq7x%MA9ixFV^1fx+@Rjc%SYF}>cMCC$azMqi=1z>?$4*#vblF_q7z#k zJ+pkxj12HmuR8Sa=Q26eQ67|iHSG9~e$0VhE&bg36O)NYCbrK~_wnC{VtaSF6TEw{ zC*ptcHT}%!j?bTs(5sV=xX|3(yWCKZYE=)N*b|?-@cj=z@{appFBWPps2RRJWG`;> z=x0`TKR-QNwaeqaOEZaaLCoITrxKK0ykwbR=}cR;6K_Q1J5(D-6zZ@zW|)n{ntY~h`ECa0F@ZIkU> zPR;xPN@rG}T3${sbEiws7SP|kGaEW`=i;JwK00>5toXSfGx8kZ`IukN5C5r7edb~3 z+56dmo%fM5;12oFOVJpKTNUlV2kUlSAD5dTrxjw zk+Icl3*^P-LkO)8FTS4{cA4b=bog(Fa_Iew!+-r6#rEZZkALjthlX;R@8^bovG&%m zi{t;X;fIG_K3@E4_`AcuG5n?BPY*vn{0Bo{vc531F%Tp*UvY zFU9`s@RLI?7K^8k?;r9v2QRe$`TG3NN4=DM0Tk;;hW}!y2fe9Z&+?ho+B@-!t^^$ZaNM?tzTY?;Dca4Re9+7TOhGj>+thKFHmH{_KHWMXxS1WG|-P$vq=bZqI|<>KZw} zcraUc;*R8ad(@r$mL-{3k>8 zxHB@(&EFaR=b_!y2fM#NB>O)@b9{UF(?dRd-LbiwpZhd>^R-9jYB$s}@~)Ay2d~Dn z(VxEEvAZy5_dyQWkO8^K)!RZ!(92Bg+AWD^Y0(3PtEq+49rho;(pE0+4C^f*`u-NOP_r5njhX> zs@r_zApiQEziG(MyF(tevBSIPZyb6S>CMDljy+%g^+IMx%p3OU`STTr-VyHQ14DV`^G+b6ch|+%2VeW7FFJeXe(VnU$A)Tf zSLzo>PP2UP&|T=EyPoRILR`DW&(6ykx@S5$?c_&>>c+cI^X^&xrt#hpo`desXQ-VJ zLl5G*Yj@?2oJYqo?m3{?*}M8QL-X^(Tjaarl>q-#k0Akzq{@;;9JL=mtNg7xt`SSnQ%9D$nK#%JHIsk?V9`9p&!rva!JKG~NJK}xhbKz%(_Q*Wd{Zr$8=P?7d!T+}NzZ;q< zU%9@2_#;EJR=XTOI{f@lAMRc6YX8Zh9Cpc_vipZavCP0eh$W_2_FsSha_HGo3tKb! z*zi+BJN)j+j~($Ws0HfXGxZ0Do;9)c?4HyKya(SN+U54uuBzEPT+h({^sd*3 zxlerVNKNMJx$+$R`0#!nzPR%b4L>}zf4?wvw{H*M8roBHGC#ZFnbe;i+EFw8mLZ*e z_No?bt64KRfii>djr*QGK&<$9&x}YR+#DKRWy`!;cNs^qJv*8ve)E)ZW{@ z9~}O`@P~(=9-0{n`IsZ{d1&7t-t%IvY6d9O%l{pkx9?r-+!JIE`N!*(A0Pd=6SHLR ztcK6NMm_7_Ow@KAK%$svj6s-?Yg}(kGF>A zB(B}_yqT*U^v?RUTRvCKR(;~J`M#leAAc=l>+^)Ye$Bux@Do=b-ap=VzPG7aFJ$)E zGpJ7Q5We0w_L+>0J975!WJ6|t=0@gzo!yBVJOl14nRkoNx8`AwzHR4k8ma^8+q=Sh zPd{?9b8lZhw14V`X78P%KRMWW&#AlTN8g@DF~yR@%-QIfox0iSL7sBhXTV-R?i25w zAr4#bDE)qX_=TbQzkg_N?6*61ck+qhPTh&x-JQEvKk%7vcg)QG>+u6S%cHl?4dwdY zo&WIAdyJiXAp77@4*l58SL5xucw&t`cOtKOxkGW)*8A$yJM;hJli61@(3g0gB{DUd zrQF_y-hXDJ9&vr%keh)$Gb1|(-#7HEdH;XeYxK_Uy{%3?cu&ariJ`sqeD^N5n{vrZ zj?$@BF0p-(IB%26M$#?R&KgS#|`uN{ipU73d(^l9f&w(3@c zXJ3EhV%r1nQ+wt)HOD?bdTzbb!A#HW_~~EmYSpJbFatHSH3PBjja=f2XRhu|&uS4{ z{o<(4ez=n_AAZSD9RAMUVP8M=KH?*`Ufr+0^{Xy3mm9C1uO9OCjuI38iQ$Kae`@%? zq22p4!@o5A3q$W|eah!~g!**X=3`&fcTk=B6`LO$ zd&W;+bY`X3@YQ&=iS<>(cHR8g>(!l`sT#~d&t?Mowtvn&L+-+zijkZxz1>uscd|K) zKk|HL>8G6Xishd5;f~a%4rg_LU}$H=FPD9O|FC;S+3@T6boQ=MkGYDcF1hWK`t7s) z;-Yju=e!%bA2Z|s_K=AH@7d$84$l!8f3>l<`@I*` zq6T2M^$*n9Ga@cu^{DxC!!HcU<@G-Goz^>BA8N#Ze#l-FCOJ9j(zjls;RG{{v42&hP*L literal 0 HcmV?d00001 diff --git a/wai/ops-conformance/certificates/wai.neural.int_synth/c6a362696d61605931ef4da98ae630362dcd73ea6be7864db6e61d6c5abbcd24/synth.whg1 b/wai/ops-conformance/certificates/wai.neural.int_synth/c6a362696d61605931ef4da98ae630362dcd73ea6be7864db6e61d6c5abbcd24/synth.whg1 new file mode 100644 index 0000000000000000000000000000000000000000..b01629e7bd57f217f9853b70ca5ba61217658530 GIT binary patch literal 5819 zcmaLaJFeYD5X9kQumK5!U@1gM1V}_cNQ6X8$R1!5WDeO15n>B0f%p4e-}wHH4hS=- znf~{5S5^1Sy;pwstv6q}ckgm}_HwyAGrPC{?$-UB|J&6(J^SdX*hj#_fiQoCR z+mqt3{wx1U@xyxyeCIzY{<225{QsSS(xFK<`Ny{XV>vrRnREZe`Jb=H_h(RKi>KH-K^xgi292grg_mImv%X3DaQ`0T6y|Xx9!xJDSb4k!KFqY=3rhHT$<#| zfvrcoT04BTOiaEUHQNq0ewgxM((l`xaGDRC-iN;Em&b<(U(G^iCiKg3-rF;4_(Lkp@;LpA4g++_ql4CCLa9en*bHA|7LYz)9oH%f1^}f(KU+P6Z za|RQyd>ZtEpJw|$kFL2F{mQ{gdJ?lQlDZdNf3+CBFnHx!{^0Q8y#4U;?+$oOyu7*B z<*YwA4_=u6`s}lTzc<#sC@!OgV;ZiNjmy zaEO=dF&I8>nD7i#z6+qciI4k+uK5lt< zX=5Y4PoysEb>^bGYfAd)~tB-RrTt!b5|3(4`({y5Tz$SBDFh z-sRL6O=gXkF1x;ZC+S}J`Ud6UtS|Mr+nvXQyE*IAck@xt*N1%Hbi%e-Gc)Z)aUcXOkK)^Oy|tCkLV&efQaeI@5-9u{2l#$#8@X!Q+;Z^6MQmu5R& zGk`@8!-IR_^XA3qlB>o!UJGU#(4v1VBo?H z!>(Q*&hVMJxEMU&df#^KQ!XBP@SHabn#@FusqZ~j<6KXA>t}~vKD@bSu6A)4dZ9;- zS?0sUNxNRu)W18#BStgdEaHXX&f(EYmov*5-LT})g_{mB2G0yEx%GvsxEjkY2M-O- zVe!olKE3sVQ$K3j^(wc!H5Y#K=)P%_2T!eqhjpKDmvZ{-F4UN#x)vX0jv8&OuT@CE+hUVrX22Z`^EG)Y-7_`9XojOxXFW-BUCx4&U-$68(!|mMUbRTM* z!I7sQSTOY>msY;GzU7BWk41|dc-xLPapz*q&W^)9m=kQ4FOIuj)Wc?Cz5ClZ?VZu+ zUf`t{pL%gKG-E$U{-Gg{Z~2D?-)uge2xpnz*uU4Q_3xEA_a6=T;~6p+cH6vfA~nl5 z2+acAb{%jJS}q*Jkf#X`$>13b=X^EJU|KM76Kq$nd1CR)<*QW_j(y?t%f!WN-Y}TK zpJwNa%Z1ZW4BNR}yL#t%JsACncY$JbiR*bd;J9o+kD{i8D4zuL!BPQ;CqO^UoH)L)(b7q?@_}Ndui4>Ap7_m;~7cL literal 0 HcmV?d00001 diff --git a/wai/ops-conformance/certificates/wai.splat.int_codec/033a37c9d29d7ea9675a0b4a3e269d74f2ab874b5a3b1425eec69bf3bad8b26f/g_s.whg1 b/wai/ops-conformance/certificates/wai.splat.int_codec/033a37c9d29d7ea9675a0b4a3e269d74f2ab874b5a3b1425eec69bf3bad8b26f/g_s.whg1 new file mode 100644 index 0000000000000000000000000000000000000000..5c9ca5022e39dc5f82825a0de10e1ec124f01b6c GIT binary patch literal 79123 zcmb5WWw=&V*ET%Hoa+Kf>5v9Ny1NljT9A|uDN#Bkq+39`5m2PNI|U>p1ql(POS<;8 z<{aZYeV_gO_`V=t`m6?^>Ozsn!{^P1RW#n@w+*yGmNWA4~vk=SFa*kkqBW5?LzqS#~8 z*yF(1W3Sj_quAqTvBz4m$49Zp3bDs}vB#>h$DOgqG)FzI7QVXvcT({6;s5-or~c%8I;osQb?;ZR2(AdX!{GYQ*^uN#7I`;AEvClU+_UBZw&pRged2+@6-Okv@ z55+$IS?uqxkA0ouvA^eIe@+tR?&Ctdz~2qux}El>-=bx>IgRAwlH1$~ zUegeMpI5uFZWzwiMXJWa2Q(4C7iW(q3>s5>)7)j$+q%m3=F(bUU(%CsJ0Io_REH~5 zMHi#DyrF5qbDu2cgx#;7xGU~om)g!WW&K+vvn7b?W4;&GrtX}_Zl|+cOK!?g$>eTH zBG*h`*%35@s)ngFCvD=KrjPsO-4V(eIZWs2ed?%hw7Y2BZ8FTv*H)3UCWkF;|I)@Z zC)$+WGb`zYFKV&|JGfTZmC6OJgGKtxo{y}wZ}?;FVNOVHNf9)%+g)Z~G)!)c^a#}z zu&bEgSx%&N>`7`P$!Q?}>Muzn`-Pt759m4%lOOyp%7yi{$Hk++^$+=0hROBF5P9X3 z_%`;c=HNd~LE3LFm`>5*eo%N$4%q$jv%9U2+Jnp&H2=Bjxe9q(7#PkcEY!$y9ks(bm-~1#op7;c_^(n8E65Qp~Suzr6A)Ua!9+Z zQVDJ9CQ>RlfGP(|u-3~_Lq6(PYr60U{#;4pNm2SpXUR2sr6+w1<<#X=FL*`I+<|Zu ze@(CTfX=5wn$MM!g0{9MkM!esv|bNU9=;H?qDIoxoi)9wrf!pl_7_PhBWRvnpk(qQ zJV*)oFYc+m-5lv=MKf>`b4Z%&RJx{r_&)ZXDJ~oJ4(HV+o;ALiW7nIW(cxyXxj+?k ztexc(;5xmQqtSx8i*E%H8DQsWZ=FPO`LT5LtFX(O`FPZgp73m~=WkIvo-DO#w%jov zQ6X7GS%PiBOH-Ra(e_y9+hi%fpp{`te~nV`EpyV&Kp&lKMsrE*-5uul=p4DJ9c84P z*3eFqLQ>p+gF2AXKbDUu3Hcf0p0e4*L&JG7F`Mq@>QYg*usGe347Wq%++k zam*2F?#`h0>bqbS^+!#Mi|4E2Lo