Skip to main content

Gpu3Config

Struct Gpu3Config 

Source
pub struct Gpu3Config {
    pub bound: ErrorBound,
    pub block: usize,
    pub block2d: usize,
    pub tile: usize,
    pub resctx: bool,
    pub rho: f64,
    pub lanes: usize,
    pub model: Model3,
    pub compact: bool,
    pub axis: bool,
    pub adapt: Option<AdCfg>,
}
Expand description

v3 options.

Fields§

§bound: ErrorBound

Error target.

§block: usize

Code-block edge for 3D data (in coefficients).

§block2d: usize

Code-block edge for 2D data.

§tile: usize

Outlier-tile edge (3D; 2D tiles are 4× this).

§resctx: bool

Residual-based contexts.

§rho: f64

Deadzone rounding offset.

§lanes: usize

rANS lanes per code-block: 1 = raster order (best ratio); more splits a block’s lines into parity passes dealt to the lanes (more GPU parallelism, TCG1’s rule inside the block).

§model: Model3

Coefficient probability model.

§compact: bool

Compact lanes: a multi-lane block of v coefficients uses clamp(8·v·lanes / V, 1, lanes) lanes, V the full block volume (small coarse-level blocks stop paying lanes lanes of rANS framing, while no lane runs longer than 1/8 of a full block’s lane), and the last lane’s length is implied by the block size.

§axis: bool

Axis-grouped line taps (crate::gpuwav::BandInfo::ax).

§adapt: Option<AdCfg>

Per-lane adaptive probability maps over the learned model (crate::lmodel3::Adapt); ignored by static models.

Implementations§

Source§

impl Gpu3Config

Source

pub fn new(bound: ErrorBound) -> Self

Defaults: 32³ / 128² blocks, 64³ outlier tiles, residual contexts.

Examples found in repository?
examples/gpubench.rs (line 44)
14fn cfg3_of(bound: ErrorBound, bk: usize, args: &[String]) -> Gpu3Config {
15    let m = opt(args, "--model3", "static");
16    let model = if m == "static" {
17        Model3::Static
18    } else if let Some(h) = m.strip_prefix("overfit") {
19        let hidden = h.strip_prefix(':').map_or(vec![16], |h| {
20            h.split(',').map(|v| v.parse().unwrap()).collect()
21        });
22        Model3::Overfit {
23            hidden,
24            per_epoch: 200_000,
25            epochs: 4,
26        }
27    } else if let Some(p) = m.strip_prefix("pretrained:") {
28        let net = std::sync::Arc::new(
29            cram_codec::learned::Net::from_bytes(&std::fs::read(p).expect("model")).expect("parse"),
30        );
31        cram_codec::learned::register(net.clone());
32        Model3::Pretrained(net)
33    } else {
34        panic!("model3 {m}")
35    };
36    Gpu3Config {
37        block: bk,
38        block2d: bk,
39        resctx: !args.iter().any(|a| a == "--nores"),
40        lanes: opt(args, "--l3", "1").parse().unwrap(),
41        compact: !args.iter().any(|a| a == "--nocompact"),
42        axis: !args.iter().any(|a| a == "--noaxis"),
43        model,
44        ..Gpu3Config::new(bound)
45    }
46}
More examples
Hide additional examples
examples/pretrain3.rs (line 48)
17fn main() {
18    let args: Vec<String> = std::env::args().skip(1).collect();
19    let out = &args[0];
20    let hidden: Vec<usize> = opt(&args, "--hidden", "32,16")
21        .split(',')
22        .map(|v| v.parse().unwrap())
23        .collect();
24    let psnr: Vec<f64> = opt(&args, "--psnr", "40,50,60,70,80,90,100")
25        .split(',')
26        .map(|v| v.parse().unwrap())
27        .collect();
28    let lanes: usize = opt(&args, "--lanes", "8").parse().unwrap();
29    let block: usize = opt(&args, "--block", "32").parse().unwrap();
30    let per: usize = opt(&args, "--per", "100000").parse().unwrap();
31    let epochs: usize = opt(&args, "--epochs", "8").parse().unwrap();
32    let mut smp = Vec::new();
33    for a in args.iter().filter(|a| a.contains(".f32:")) {
34        let (path, d) = a.split_once(':').unwrap();
35        let dims: Vec<usize> = d.split('x').map(|s| s.parse().unwrap()).collect();
36        let b = std::fs::read(path).unwrap();
37        let x: Vec<f32> = b
38            .as_chunks::<4>()
39            .0
40            .iter()
41            .map(|&c| f32::from_le_bytes(c))
42            .collect();
43        for &p in &psnr {
44            let cfg = Gpu3Config {
45                block,
46                block2d: block * 4,
47                lanes,
48                ..Gpu3Config::new(ErrorBound::Psnr(p))
49            };
50            let s = samples3(&x, &dims, &cfg, 16, per);
51            eprintln!("{path} {p} dB: {} samples", s.len());
52            smp.extend(s);
53        }
54    }
55    let tc = TrainConfig {
56        hidden,
57        epochs,
58        per_epoch: 3_000_000,
59        batch: 256,
60        lr: 3e-3,
61        apm: false,
62        seed: 7,
63    };
64    let t = std::time::Instant::now();
65    let net = train(&smp, &tc);
66    eprintln!(
67        "trained on {} samples in {:.1}s: {:.4} bits/sample (float view), {} params",
68        smp.len(),
69        t.elapsed().as_secs_f64(),
70        mean_bits_float(&net, &smp),
71        net.num_params()
72    );
73    std::fs::write(out, net.to_bytes()).unwrap();
74}
examples/sweep3.rs (line 130)
26fn main() {
27    let args: Vec<String> = std::env::args().skip(1).collect();
28    let root = std::path::PathBuf::from(&args[0]);
29    let threads: usize = opt(&args, "--threads", "16").parse().unwrap();
30    let lanes: usize = opt(&args, "--l3", "8").parse().unwrap();
31    let m = opt(&args, "--model3", "static");
32    let model = if m == "static" {
33        Model3::Static
34    } else if let Some(p) = m.strip_prefix("pretrained:") {
35        let net = std::sync::Arc::new(
36            cram_codec::learned::Net::from_bytes(&std::fs::read(p).expect("model")).expect("parse"),
37        );
38        cram_codec::learned::register(net.clone());
39        Model3::Pretrained(net)
40    } else {
41        panic!("model3 {m}")
42    };
43    let mut fields: Vec<(String, std::path::PathBuf, Vec<usize>)> = ORIG
44        .iter()
45        .map(|n| {
46            (
47                n.to_string(),
48                root.join(format!("out/{n}-64x128x128.f32")),
49                vec![64, 128, 128],
50            )
51        })
52        .collect();
53    let man = std::fs::read_to_string(root.join("data/heldout/manifest.json")).unwrap();
54    // minimal manifest parse: [{"name": "...", "shape": [..]}, ...]
55    for obj in man.split('{').skip(1) {
56        let name = obj
57            .split("\"name\"")
58            .nth(1)
59            .unwrap()
60            .split('"')
61            .nth(1)
62            .unwrap()
63            .to_string();
64        let sh = obj
65            .split("\"shape\"")
66            .nth(1)
67            .unwrap()
68            .split('[')
69            .nth(1)
70            .unwrap()
71            .split(']')
72            .next()
73            .unwrap();
74        let shape: Vec<usize> = sh.split(',').map(|v| v.trim().parse().unwrap()).collect();
75        fields.push((
76            name.clone(),
77            root.join(format!("data/heldout/{name}.f32")),
78            shape,
79        ));
80    }
81    let only = opt(&args, "--only", "");
82    let ser: std::collections::HashMap<(String, String), f64> =
83        std::fs::read_to_string(root.join("out/gpu_ratio.jsonl"))
84            .unwrap()
85            .lines()
86            .filter(|l| l.contains("\"tc-wavelet\""))
87            .map(|l| {
88                let g = |k: &str| {
89                    l.split(&format!("\"{k}\":"))
90                        .nth(1)
91                        .unwrap()
92                        .split([',', '}'])
93                        .next()
94                        .unwrap()
95                        .trim()
96                        .trim_matches('"')
97                        .to_string()
98                };
99                (
100                    (g("field").replace("-64x128x128", ""), g("target")),
101                    g("bpv").parse().unwrap(),
102                )
103            })
104            .collect();
105    let mut acc: std::collections::HashMap<(String, String), Vec<f64>> = Default::default();
106    for t in opt(&args, "--targets", "p80").split(',') {
107        for (name, path, dims) in &fields {
108            if !only.is_empty() && !only.split(',').any(|o| name.contains(o)) {
109                continue;
110            }
111            let b = std::fs::read(path).unwrap();
112            let x: Vec<f32> = b
113                .as_chunks::<4>()
114                .0
115                .iter()
116                .map(|&c| f32::from_le_bytes(c))
117                .collect();
118            let range = x.iter().fold(f32::NEG_INFINITY, |a, &b| a.max(b)) as f64
119                - x.iter().fold(f32::INFINITY, |a, &b| a.min(b)) as f64;
120            let bound = if let Some(p) = t.strip_prefix('p') {
121                ErrorBound::Psnr(p.parse().unwrap())
122            } else {
123                ErrorBound::MaxAbs(t[1..].parse::<f64>().unwrap() * range)
124            };
125            let cfg = Gpu3Config {
126                lanes,
127                compact: !args.iter().any(|a| a == "--nocompact"),
128                axis: !args.iter().any(|a| a == "--noaxis"),
129                model: model.clone(),
130                ..Gpu3Config::new(bound)
131            };
132            let (s, _) = gpuwav3::encode3_f32(&x, dims, &cfg, threads);
133            let bpv = s.len() as f64 * 8.0 / x.len() as f64;
134            let r = ser.get(&(name.clone(), t.to_string())).map(|sb| bpv / sb);
135            println!(
136                "{{\"field\": \"{name}\", \"target\": \"{t}\", \"bpv\": {bpv}, \"vs_serial\": {}}}",
137                r.map_or("null".into(), |v| format!("{v:.4}"))
138            );
139            if let Some(r) = r {
140                let g = if ORIG.contains(&name.as_str()) {
141                    "orig"
142                } else {
143                    "held"
144                };
145                acc.entry((t.to_string(), "all".into()))
146                    .or_default()
147                    .push(r);
148                acc.entry((t.to_string(), g.into())).or_default().push(r);
149            }
150        }
151    }
152    let mut keys: Vec<_> = acc.keys().cloned().collect();
153    keys.sort();
154    for k in keys {
155        let v = &acc[&k];
156        let gm = (v.iter().map(|x| x.ln()).sum::<f64>() / v.len() as f64).exp();
157        println!("GEOMEAN {} {} n={} {:.4}", k.0, k.1, v.len(), gm);
158    }
159}

Trait Implementations§

Source§

impl Clone for Gpu3Config

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Gpu3Config

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> ByRef<T> for T

Source§

fn by_ref(&self) -> &T

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Imply<T> for U
where T: ?Sized, U: ?Sized,

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.