pub struct Nc1hwc2Layout { /* private fields */ }Expand description
Precomputed NC1HWC2 tensor layout for efficient, division-free access.
NC1HWC2 is the RKNN NPU’s native output format where channels are packed
into blocks of c2 (typically 16). This struct precomputes the layout
parameters at model load time so the per-frame hot path needs zero
division operations.
§Construction
let layout = Nc1hwc2Layout::from_attr(&model.output_attrs()[0])?;Or use the convenience method on RknnModel:
let layout = model.output_nc1hwc2_layout(0)?;§Channel access
Each channel has a fixed offset relative to a prediction’s base address.
For channels 0..c2-1 they live in block 0 (offsets 0..c2-1).
Channel ch lives at offset (ch/c2)*hw_c2 + (ch%c2).
Precompute offsets for a range of channels once at load time, then use them in the hot loop with zero division:
// Precompute at load time (once):
let class_offsets = layout.precompute_channel_offsets(4, num_classes);
// Hot loop (per frame):
let raw = model.output_raw(0)?;
let stride = layout.prediction_stride();
let mut p_off = 0;
for _p in 0..layout.num_predictions() {
for (c, &off) in class_offsets.iter().enumerate() {
let v = raw[off + p_off];
// ...
}
p_off += stride;
}Implementations§
Source§impl Nc1hwc2Layout
impl Nc1hwc2Layout
Sourcepub fn from_attr(attr: &TensorAttr) -> Result<Self, Error>
pub fn from_attr(attr: &TensorAttr) -> Result<Self, Error>
Create a layout from a tensor attribute.
Validates that the tensor is NC1HWC2 with a 5D shape.
§Errors
Returns crate::Error::InvalidFormat if the tensor is not NC1HWC2
or has an unexpected shape.
Sourcepub fn channel_offset(&self, ch: usize) -> usize
pub fn channel_offset(&self, ch: usize) -> usize
Compute the raw-data offset for channel ch relative to a prediction base.
Equivalent to (ch / c2) * hw_c2 + (ch % c2).
Sourcepub fn precompute_channel_offsets(
&self,
start_ch: usize,
count: usize,
) -> Vec<usize>
pub fn precompute_channel_offsets( &self, start_ch: usize, count: usize, ) -> Vec<usize>
Precompute offsets for count consecutive channels starting from start_ch.
Returns a Vec where result[i] is the offset for channel start_ch + i.
Use this at load time to build a lookup table for the hot loop.
Sourcepub fn prediction_stride(&self) -> usize
pub fn prediction_stride(&self) -> usize
Stride (in i8 elements) between consecutive spatial predictions.
In the hot loop, increment p_offset += stride instead of
multiplying p * stride each iteration.
Sourcepub fn num_predictions(&self) -> usize
pub fn num_predictions(&self) -> usize
Number of spatial predictions (H * W).
Sourcepub fn dequant(&self, raw: i8) -> f32
pub fn dequant(&self, raw: i8) -> f32
Dequantize a single raw i8 value to f32.
f32_value = (raw_i8 - zp) * scale
Sourcepub fn threshold_i8(&self, conf: f32) -> i8
pub fn threshold_i8(&self, conf: f32) -> i8
Convert a f32 confidence threshold to i8 space for fast rejection.
When scale > 0, the affine mapping is monotonically increasing,
so we can compare raw i8 values directly without dequantization.
This rejects ~99% of predictions with zero float math.
Returns i8::MIN if scale <= 0 (passes everything through).
Trait Implementations§
Source§impl Clone for Nc1hwc2Layout
impl Clone for Nc1hwc2Layout
Source§fn clone(&self) -> Nc1hwc2Layout
fn clone(&self) -> Nc1hwc2Layout
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more