substrate_data/wire/frame/lanes/mod.rs
1//! Numbers bit-packed in lanes: what a frame's list of ints is made of.
2//!
3//! A list of `n` numbers `width` bits each (1..=32) is `n / GROUP` groups,
4//! then the rest packed one after another (little-endian bits). A group is
5//! [`GROUP`] numbers in [`LANES`] lanes of 32-bit words: number `j` goes to
6//! lane `j % LANES`, the `j / LANES`-th in it; a lane's numbers are packed
7//! one after another into its words, and word `k` of lane `l` is the group's
8//! `k * LANES + l`-th. A row of `LANES` numbers is shifted and merged as one
9//! 256-bit vector, so packing and unpacking run a group at a time — with the
10//! best instruction set the processor has ([`Backend`]: SSE4.2, AVX2, AVX-512,
11//! NEON), chosen once at start; the same bytes whichever. Numbers wider than 32 bits go one after another, no groups.
12//!
13//! Number `i` is found in O(1) ([`get`]), so views read in place.
14
15#[cfg(all(target_arch = "x86_64", target_endian = "little"))]
16mod avx2;
17#[cfg(all(target_arch = "x86_64", target_endian = "little"))]
18mod avx512;
19mod backend;
20mod dispatch;
21mod kernel;
22#[cfg(all(target_arch = "aarch64", target_endian = "little"))]
23mod neon;
24mod packing;
25mod portable;
26mod row;
27#[cfg(all(target_arch = "x86_64", target_endian = "little"))]
28mod sse42;
29
30pub use backend::Backend;
31pub use packing::{GROUP, GROUP_MAX_BITS, LANES, get, group_bytes, pack, packed_bytes, unpack};
32use packing::{ROWS, WORD_BYTES, mask};