pub enum Candidate {
Wavelet,
Tucker,
Qtt,
Interp,
QttSparse,
Lorenzo,
}Expand description
A portfolio candidate.
Variants§
Wavelet
wavcodec with the configured coefficient model.
Tucker
tucker (PSNR/RMSE targets, 2D/3D).
Qtt
The QTT codec in row-major digit order.
Interp
QttSparse
The QTT codec’s residual-only stream (max-abs; QTT tag and format).
Lorenzo
Implementations§
Source§impl Candidate
impl Candidate
Sourcepub fn tag(self) -> u8
pub fn tag(self) -> u8
Stream tag.
Examples found in repository?
examples/tc.rs (line 155)
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}Sourcepub fn name(self) -> &'static str
pub fn name(self) -> &'static str
Short name.
Examples found in repository?
examples/tc.rs (line 110)
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}Trait Implementations§
impl Copy for Candidate
impl Eq for Candidate
impl StructuralPartialEq for Candidate
Auto Trait Implementations§
impl Freeze for Candidate
impl RefUnwindSafe for Candidate
impl Send for Candidate
impl Sync for Candidate
impl Unpin for Candidate
impl UnsafeUnpin for Candidate
impl UnwindSafe for Candidate
Blanket Implementations§
impl<T> Boilerplate for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more