use super::conv_dense_requant;
use crate::model::Layer;
pub fn uniform_requant(layer: &Layer) -> Option<(i32, i32)> {
let table = conv_dense_requant(layer)?;
let first = *table.first()?;
if table.iter().all(|&p| p == first) {
Some(first)
} else {
None
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::model::Layer;
use crate::quant::quantize_multiplier;
fn dense_with_requant(table: Vec<(i32, i32)>) -> Layer {
Layer::Dense {
name: "d",
in_features: 4,
out_features: table.len(),
x_zp: 0,
w_zp: 0,
out_zp: 0,
weight_bits: 8,
weight_encoding: crate::model::WeightEncoding::SignedInt,
requant: table,
weights: vec![1; 4 * 4],
bias: None,
}
}
#[test]
fn uniform_table_detected() {
let (m0, sh) = quantize_multiplier(0.5);
let l = dense_with_requant(vec![(m0, sh); 4]);
assert_eq!(uniform_requant(&l), Some((m0, sh)));
}
#[test]
fn nonuniform_table_rejected() {
let (m0a, sha) = quantize_multiplier(0.5);
let (m0b, shb) = quantize_multiplier(0.25);
let l = dense_with_requant(vec![(m0a, sha), (m0b, shb)]);
assert_eq!(uniform_requant(&l), None);
}
}