#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum QuantizationScheme {
Int8,
Int16,
Dynamic,
Fake,
}
#[derive(Debug, Clone)]
pub struct QuantizationParams {
pub scheme: QuantizationScheme,
pub scale: f32,
pub zero_point: i32,
pub qmin: i32,
pub qmax: i32,
}
impl QuantizationParams {
pub fn new(scheme: QuantizationScheme, scale: f32, zero_point: i32) -> Self {
let (qmin, qmax) = match scheme {
QuantizationScheme::Int8 => (-128, 127),
QuantizationScheme::Int16 => (-32768, 32767),
_ => (0, 255), };
Self {
scheme,
scale,
zero_point,
qmin,
qmax,
}
}
pub fn symmetric(scheme: QuantizationScheme, scale: f32) -> Self {
Self::new(scheme, scale, 0)
}
pub fn asymmetric(scheme: QuantizationScheme, scale: f32, zero_point: i32) -> Self {
Self::new(scheme, scale, zero_point)
}
}
#[derive(Debug, Clone)]
pub struct QuantizationAnnotation {
pub input_params: Vec<Option<QuantizationParams>>,
pub output_params: Option<QuantizationParams>,
pub calibration_data: Option<CalibrationData>,
}
#[derive(Debug, Clone)]
pub struct CalibrationData {
pub min_val: f32,
pub max_val: f32,
pub histogram: Vec<u64>,
pub sample_count: usize,
}
impl CalibrationData {
pub fn new() -> Self {
Self {
min_val: f32::INFINITY,
max_val: f32::NEG_INFINITY,
histogram: vec![0; 256],
sample_count: 0,
}
}
pub fn update(&mut self, values: &[f32]) {
for &val in values {
self.min_val = self.min_val.min(val);
self.max_val = self.max_val.max(val);
let bin = ((val - self.min_val) / (self.max_val - self.min_val) * 255.0)
.clamp(0.0, 255.0) as usize;
if bin < self.histogram.len() {
self.histogram[bin] += 1;
}
}
self.sample_count += values.len();
}
pub fn compute_params(&self, scheme: QuantizationScheme) -> QuantizationParams {
let range = self.max_val - self.min_val;
let scale = match scheme {
QuantizationScheme::Int8 => range / 255.0,
QuantizationScheme::Int16 => range / 65535.0,
_ => range / 255.0,
};
let zero_point = (-self.min_val / scale).round() as i32;
QuantizationParams::new(scheme, scale, zero_point)
}
}
impl Default for CalibrationData {
fn default() -> Self {
Self::new()
}
}