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}