Skip to main content

encode_fast_f32

Function encode_fast_f32 

Source
pub fn encode_fast_f32(
    x: &[f32],
    dims: &[usize],
    cfg: &WavConfig,
) -> (Vec<u8>, Candidate)
Expand description

Fast encode (tc --fast): the single candidate fast_pick names, coded with encode_candidate_fast_f32. Same tagged stream format as encode_auto_f32.

Examples found in repository?
examples/tc.rs (line 125)
34fn main() {
35    let args: Vec<String> = std::env::args().skip(1).collect();
36    match args.first().map(String::as_str) {
37        Some("encode") if args.len() >= 3 => {
38            let x = read_f32(&args[1]);
39            let range = {
40                let (a, b) = x
41                    .iter()
42                    .fold((f32::INFINITY, f32::NEG_INFINITY), |(a, b), &v| {
43                        (a.min(v), b.max(v))
44                    });
45                (b - a) as f64
46            };
47            let mut dims = vec![x.len()];
48            let mut bound = None;
49            let mut codec = "wavelet".to_string();
50            let mut rho = None;
51            let mut model = "hand".to_string();
52            let mut i = 3;
53            while i < args.len() {
54                if args[i] == "--fast" {
55                    codec = "fast".to_string();
56                    i += 1;
57                    continue;
58                }
59                let v = args.get(i + 1).cloned().unwrap_or_else(|| usage());
60                match args[i].as_str() {
61                    "--dims" => dims = v.split('x').map(|s| s.parse().unwrap()).collect(),
62                    "--psnr" => bound = Some(ErrorBound::Psnr(v.parse().unwrap())),
63                    "--rmse" => bound = Some(ErrorBound::Rmse(v.parse().unwrap())),
64                    "--max-abs" => bound = Some(ErrorBound::MaxAbs(v.parse().unwrap())),
65                    "--max-rel" => {
66                        bound = Some(ErrorBound::MaxAbs(v.parse::<f64>().unwrap() * range))
67                    }
68                    "--codec" => codec = v,
69                    "--rho" => rho = Some(v.parse().unwrap()),
70                    "--model" => model = v,
71                    _ => usage(),
72                }
73                i += 2;
74            }
75            let bound = bound.unwrap_or_else(|| usage());
76            let t = Instant::now();
77            let (bytes, json) = match codec.as_str() {
78                "wavelet" => {
79                    let mut cfg = wavcodec::WavConfig::new(bound);
80                    if let Some(r) = rho {
81                        cfg.rho = r;
82                    }
83                    cfg.model = cram_codec::learned::parse_model_arg(&model);
84                    let (b, s) = wavcodec::encode_f32(&x, &dims, &cfg);
85                    let j = format!(
86                        "\"coef_bytes\":{},\"model_bytes\":{},\"outlier_bytes\":{},\"n_outliers\":{},\"delta\":{},\"rmse\":{},\"max_abs\":{},\"passes\":{}",
87                        s.coef_bytes, s.model_bytes, s.outlier_bytes, s.n_outliers, s.delta, s.rmse, s.max_abs, s.passes
88                    );
89                    (b, j)
90                }
91                "tucker" => {
92                    let (b, s) = cram_codec::tucker::encode_f32(&x, &dims, bound);
93                    let j = format!(
94                        "\"core_bytes\":{},\"factor_bytes\":{},\"ranks\":{:?},\"delta\":{},\"rmse\":{},\"max_abs\":{}",
95                        s.core_bytes, s.factor_bytes, s.ranks, s.delta, s.rmse, s.max_abs
96                    );
97                    (b, j)
98                }
99                "auto" | "portfolio-all" => {
100                    let mut cfg = wavcodec::WavConfig::new(bound);
101                    if let Some(r) = rho {
102                        cfg.rho = r;
103                    }
104                    cfg.model = cram_codec::learned::parse_model_arg(&model);
105                    let (b, rep) =
106                        cram_codec::encode_portfolio_f32(&x, &dims, &cfg, codec == "auto");
107                    let tried: Vec<String> = rep
108                        .tried
109                        .iter()
110                        .map(|(c, n, t)| format!("\"{}:{n}:{t:.3}\"", c.name()))
111                        .collect();
112                    (
113                        b,
114                        format!(
115                            "\"chose\":\"{}\",\"probe_rank\":{},\"tried\":[{}]",
116                            rep.pick.name(),
117                            rep.probe_rank,
118                            tried.join(",")
119                        ),
120                    )
121                }
122                "fast" => {
123                    let mut cfg = wavcodec::WavConfig::new(bound);
124                    cfg.model = cram_codec::learned::parse_model_arg(&model);
125                    let (b, c) = cram_codec::encode_fast_f32(&x, &dims, &cfg);
126                    (b, format!("\"chose\":\"{}\"", c.name()))
127                }
128                "qtt-probe" => {
129                    let env = |k: &str, d: usize| {
130                        std::env::var(k)
131                            .ok()
132                            .and_then(|v| v.parse().ok())
133                            .unwrap_or(d)
134                    };
135                    let (n, r, t) = cram_codec::qtt_probe(
136                        &x,
137                        &dims,
138                        bound,
139                        env("PROBE_STRIDE", 2),
140                        env("PROBE_CAP", 32),
141                    );
142                    (
143                        vec![0u8; n],
144                        format!("\"probe_bytes\":{n},\"probe_rank\":{r},\"probe_s\":{t}"),
145                    )
146                }
147                "interp" | "lorenzo" | "qtt" | "qtt-sparse" => {
148                    let cfg = wavcodec::WavConfig::new(bound);
149                    let c = match codec.as_str() {
150                        "qtt" => cram_codec::Candidate::Qtt,
151                        "qtt-sparse" => cram_codec::Candidate::QttSparse,
152                        "lorenzo" => cram_codec::Candidate::Lorenzo,
153                        _ => cram_codec::Candidate::Interp,
154                    };
155                    let mut b = vec![c.tag()];
156                    b.extend(cram_codec::encode_candidate_f32(c, &x, &dims, &cfg));
157                    (b, format!("\"chose\":\"{codec}\""))
158                }
159                _ => usage(),
160            };
161            let enc = t.elapsed().as_secs_f64();
162            std::fs::write(&args[2], &bytes).unwrap();
163            println!(
164                "{{\"bytes\":{},\"bpv\":{},\"encode_s\":{enc},{json}}}",
165                bytes.len(),
166                8.0 * bytes.len() as f64 / x.len() as f64
167            );
168        }
169        Some("decode") if args.len() == 3 || (args.len() == 5 && args[3] == "--model") => {
170            if args.len() == 5 {
171                // registers a pretrained network so the decoder can resolve it
172                let _ = cram_codec::learned::parse_model_arg(&args[4]);
173            }
174            let bytes = std::fs::read(&args[1]).unwrap();
175            let t = Instant::now();
176            let Decoded::F32 { data, .. } = decode_any(&bytes).expect("decode") else {
177                panic!("not an f32 stream")
178            };
179            let dec = t.elapsed().as_secs_f64();
180            let out: Vec<u8> = data.iter().flat_map(|v| v.to_le_bytes()).collect();
181            std::fs::write(&args[2], out).unwrap();
182            println!("{{\"decode_s\":{dec}}}");
183        }
184        _ => usage(),
185    }
186}