Skip to main content

Nc1hwc2Layout

Struct Nc1hwc2Layout 

Source
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

Source

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.

Source

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).

Source

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.

Source

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.

Source

pub fn num_predictions(&self) -> usize

Number of spatial predictions (H * W).

Source

pub fn c2(&self) -> usize

Channel block size (typically 16).

Source

pub fn zp(&self) -> i32

Quantization zero-point.

Source

pub fn scale(&self) -> f32

Quantization scale factor.

Source

pub fn dequant(&self, raw: i8) -> f32

Dequantize a single raw i8 value to f32.

f32_value = (raw_i8 - zp) * scale

Source

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

Source§

fn clone(&self) -> Nc1hwc2Layout

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Nc1hwc2Layout

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.