#[repr(C)]pub struct QuantDesc {
pub len: u64,
pub axis_plus_one: u64,
pub scales: SendConstPtr<f32>,
pub zero_points: SendConstPtr<i32>,
}Expand description
Quantization metadata, in a form that can cross an .so boundary.
crate::TensorDesc deliberately does not carry this: it is the shared
descriptor, pinned by ABI_VERSION and consumed by the C API, where
tensors travel as real ef_tensor handles into one shared
libedgefirst_tensor.so and no reconstruction ever happens. The Python
packages are the only consumers that rebuild a tensor from a descriptor,
so this rides in the capsule payload rather than widening a C ABI that
does not need it.
Variable-length by nature – per-channel quantization carries one scale
(and optionally one zero-point) per channel – so the arrays are
borrowed, not inlined: scales/zero_points point into the
Quantization that TensorCapsulePayload::quant_keepalive owns, on
exactly the terms crate::TensorDesc::ptr borrows the producer’s host
address. A consumer copies the values out during import (see
QuantDesc::to_quantization) while the capsule is still alive, and
never retains the pointers.
Fields§
§len: u64Number of entries in scales (and in zero_points when non-null).
Zero means the tensor carries no quantization – the one field a
consumer must check before reading either pointer.
axis_plus_one: u64Channel axis for per-channel quantization, plus one; 0 means
per-tensor. Encoded this way so the whole struct zeroes to “absent”
rather than needing a separate presence flag for an Option<usize>.
scales: SendConstPtr<f32>len scale factors. Null iff len == 0.
zero_points: SendConstPtr<i32>len zero-points, or null for symmetric quantization.
Implementations§
Source§impl QuantDesc
impl QuantDesc
Sourcepub fn borrowing(quant: &Quantization) -> Self
pub fn borrowing(quant: &Quantization) -> Self
Describe quant, borrowing its arrays.
The caller must keep quant alive for as long as the descriptor is
readable – in the capsule protocol, by storing the same Arc in
TensorCapsulePayload::quant_keepalive.
Sourcepub unsafe fn to_quantization(&self) -> Result<Option<Quantization>>
pub unsafe fn to_quantization(&self) -> Result<Option<Quantization>>
Copy the borrowed arrays into an owned crate::Quantization, or None
when the producer declared no quantization.
Ok(None) means “the producer has none”; a descriptor that declares
quantization but cannot be read back as a valid crate::Quantization is
an Err, not a second spelling of None. Conflating the two is
what made the bug this whole capsule version exists to fix so hard
to place: a tensor that quietly arrives unquantized surfaces much
later as the consumer’s own “requires quantization metadata”, which
names the symptom and not the cause.
§Safety
self must have come from a capsule that is still alive, so the
arrays scales/zero_points point at are still owned by the
producer’s quant_keepalive.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for QuantDesc
impl RefUnwindSafe for QuantDesc
impl Send for QuantDesc
impl Sync for QuantDesc
impl Unpin for QuantDesc
impl UnsafeUnpin for QuantDesc
impl UnwindSafe for QuantDesc
Blanket Implementations§
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more