raptorq: rustfmt whole project

This commit is contained in:
Luca Bruno 2019-03-28 21:13:19 +00:00 committed by Christopher Berner
parent a55116e637
commit 38df97cce1
18 changed files with 546 additions and 459 deletions

@ -5,12 +5,11 @@ use criterion::Criterion;
use criterion::Throughput;
use rand::Rng;
use raptorq::SourceBlockEncoder;
use raptorq::SourceBlockDecoder;
use raptorq::Octet;
use raptorq::SourceBlockDecoder;
use raptorq::SourceBlockEncoder;
use raptorq::Symbol;
fn criterion_benchmark(c: &mut Criterion) {
let octet1 = Octet::new(rand::thread_rng().gen_range(1, 255));
let symbol_size = 512;
@ -25,31 +24,48 @@ fn criterion_benchmark(c: &mut Criterion) {
let symbol1_mul_scalar = symbol1.clone();
let octet1_mul_scalar = octet1.clone();
c.bench("Symbol mulassign_scalar()", Benchmark::new("", move |b| b.iter(|| {
let mut temp = symbol1_mul_scalar.clone();
temp.mulassign_scalar(&octet1_mul_scalar);
temp
})).throughput(Throughput::Bytes(symbol1.len() as u32)));
c.bench(
"Symbol mulassign_scalar()",
Benchmark::new("", move |b| {
b.iter(|| {
let mut temp = symbol1_mul_scalar.clone();
temp.mulassign_scalar(&octet1_mul_scalar);
temp
})
})
.throughput(Throughput::Bytes(symbol1.len() as u32)),
);
let symbol1_addassign = symbol1.clone();
let symbol2_addassign = symbol2.clone();
c.bench("Symbol +=", Benchmark::new("", move |b| b.iter(|| {
let mut temp = symbol1_addassign.clone();
temp += &symbol2_addassign;
temp
})).throughput(Throughput::Bytes(symbol1.len() as u32)));
c.bench(
"Symbol +=",
Benchmark::new("", move |b| {
b.iter(|| {
let mut temp = symbol1_addassign.clone();
temp += &symbol2_addassign;
temp
})
})
.throughput(Throughput::Bytes(symbol1.len() as u32)),
);
let symbol1_fma = symbol1.clone();
let symbol2_fma = symbol2.clone();
let octet1_fma = octet1.clone();
c.bench("Symbol FMA", Benchmark::new("", move |b| b.iter(|| {
let mut temp = symbol1_fma.clone();
temp.fused_addassign_mul_scalar(&symbol2_fma, &octet1_fma);
temp
})).throughput(Throughput::Bytes(symbol1.len() as u32)));
c.bench(
"Symbol FMA",
Benchmark::new("", move |b| {
b.iter(|| {
let mut temp = symbol1_fma.clone();
temp.fused_addassign_mul_scalar(&symbol2_fma, &octet1_fma);
temp
})
})
.throughput(Throughput::Bytes(symbol1.len() as u32)),
);
let elements = 10*1024;
let elements = 10 * 1024;
let symbol_size = 512;
let mut data: Vec<u8> = vec![0; elements];
for i in 0..elements {
@ -57,32 +73,50 @@ fn criterion_benchmark(c: &mut Criterion) {
}
let encode_data = data.clone();
c.bench("encode 10KB", Benchmark::new("", move |b| b.iter(|| {
let encoder = SourceBlockEncoder::new(1, symbol_size, &encode_data);
return encoder.source_packets();
})).throughput(Throughput::Bytes(data.len() as u32)));
c.bench(
"encode 10KB",
Benchmark::new("", move |b| {
b.iter(|| {
let encoder = SourceBlockEncoder::new(1, symbol_size, &encode_data);
return encoder.source_packets();
})
})
.throughput(Throughput::Bytes(data.len() as u32)),
);
let roundtrip_data = data.clone();
c.bench("roundtrip 10KB", Benchmark::new("", move |b| b.iter(|| {
let encoder = SourceBlockEncoder::new(1, symbol_size, &roundtrip_data);
let mut decoder = SourceBlockDecoder::new(1, symbol_size, elements as u64);
let mut result = None;
for packet in encoder.source_packets() {
result = decoder.decode(packet);
}
return result
})).throughput(Throughput::Bytes(data.len() as u32)));
c.bench(
"roundtrip 10KB",
Benchmark::new("", move |b| {
b.iter(|| {
let encoder = SourceBlockEncoder::new(1, symbol_size, &roundtrip_data);
let mut decoder = SourceBlockDecoder::new(1, symbol_size, elements as u64);
let mut result = None;
for packet in encoder.source_packets() {
result = decoder.decode(packet);
}
return result;
})
})
.throughput(Throughput::Bytes(data.len() as u32)),
);
let repair_data = data.clone();
c.bench("roundtrip repair 10KB", Benchmark::new("", move |b| b.iter(|| {
let encoder = SourceBlockEncoder::new(1, symbol_size, &repair_data);
let mut decoder = SourceBlockDecoder::new(1, symbol_size, elements as u64);
let mut result = None;
for packet in encoder.repair_packets(0, (elements / symbol_size as usize) as u32) {
result = decoder.decode(packet);
}
return result
})).throughput(Throughput::Bytes(data.len() as u32)));
c.bench(
"roundtrip repair 10KB",
Benchmark::new("", move |b| {
b.iter(|| {
let encoder = SourceBlockEncoder::new(1, symbol_size, &repair_data);
let mut decoder = SourceBlockDecoder::new(1, symbol_size, elements as u64);
let mut result = None;
for packet in encoder.repair_packets(0, (elements / symbol_size as usize) as u32) {
result = decoder.decode(packet);
}
return result;
})
})
.throughput(Throughput::Bytes(data.len() as u32)),
);
}
criterion_group!(benches, criterion_benchmark);

@ -1,9 +1,8 @@
use rand::Rng;
use raptorq::SourceBlockEncoder;
fn main() {
let elements = 10*1024;
let elements = 10 * 1024;
let symbol_size = 512;
let mut data: Vec<u8> = vec![0; elements];
for i in 0..elements {

@ -1,7 +1,7 @@
use raptorq::extended_source_block_symbols;
use raptorq::generate_constraint_matrix;
use raptorq::IntermediateSymbolDecoder;
use raptorq::Octet;
use raptorq::generate_constraint_matrix;
use raptorq::extended_source_block_symbols;
use raptorq::Symbol;
fn main() {
@ -17,18 +17,28 @@ fn main() {
}
}
}
println!("Original density for {}x{}: {} of {}", a.height(), a.width(), density, a.height() * a.width());
println!(
"Original density for {}x{}: {} of {}",
a.height(),
a.width(),
density,
a.height() * a.width()
);
let symbols = vec![Symbol::zero(1); a.width()];
let mut decoder = IntermediateSymbolDecoder::new(a, symbols, num_symbols);
decoder.execute();
println!("Optimized decoder mul ops: {} ({:.1} per symbol), add ops: {} ({:.1} per symbol)",
decoder.get_symbol_mul_ops(),
decoder.get_symbol_mul_ops() as f64 / num_symbols as f64,
decoder.get_symbol_add_ops(),
decoder.get_symbol_add_ops() as f64 / num_symbols as f64);
println!("By phase mul ops: {:?}, add ops: {:?}",
decoder.get_symbol_mul_ops_by_phase(),
decoder.get_symbol_add_ops_by_phase());
println!(
"Optimized decoder mul ops: {} ({:.1} per symbol), add ops: {} ({:.1} per symbol)",
decoder.get_symbol_mul_ops(),
decoder.get_symbol_mul_ops() as f64 / num_symbols as f64,
decoder.get_symbol_add_ops(),
decoder.get_symbol_add_ops() as f64 / num_symbols as f64
);
println!(
"By phase mul ops: {:?}, add ops: {:?}",
decoder.get_symbol_mul_ops_by_phase(),
decoder.get_symbol_add_ops_by_phase()
);
}
}
}

@ -1,5 +1,5 @@
use rand::Rng;
use rand::seq::SliceRandom;
use rand::Rng;
use raptorq::{Decoder, Encoder, EncodingPacket};
fn main() {
@ -13,7 +13,9 @@ fn main() {
let encoder = Encoder::with_defaults(&data, 1400);
// Perform the encoding, and serialize to Vec<u8> for transmission
let mut packets: Vec<Vec<u8>> = encoder.get_encoded_packets(15).iter()
let mut packets: Vec<Vec<u8>> = encoder
.get_encoded_packets(15)
.iter()
.map(|packet| packet.serialize())
.collect();
@ -40,4 +42,4 @@ fn main() {
// Check that even though some of the data was lost we are able to reconstruct the original message
assert_eq!(result.unwrap(), data);
}
}

@ -1,14 +1,14 @@
#[derive(Clone)]
pub struct ArrayMap<T> {
offset: usize,
elements: Vec<Option<T>>
elements: Vec<Option<T>>,
}
impl <T: std::clone::Clone> ArrayMap<T> {
impl<T: std::clone::Clone> ArrayMap<T> {
pub fn new(start_key: usize, end_key: usize) -> ArrayMap<T> {
ArrayMap {
offset: start_key,
elements: vec![None; end_key - start_key]
elements: vec![None; end_key - start_key],
}
}
@ -38,14 +38,14 @@ impl <T: std::clone::Clone> ArrayMap<T> {
#[derive(Clone)]
pub struct UsizeArrayMap {
offset: usize,
elements: Vec<usize>
elements: Vec<usize>,
}
impl UsizeArrayMap {
pub fn new(start_key: usize, end_key: usize) -> UsizeArrayMap {
UsizeArrayMap {
offset: start_key,
elements: vec![0; end_key - start_key]
elements: vec![0; end_key - start_key],
}
}
@ -73,14 +73,14 @@ impl UsizeArrayMap {
#[derive(Clone)]
pub struct BoolArrayMap {
offset: usize,
elements: Vec<bool>
elements: Vec<bool>,
}
impl BoolArrayMap {
pub fn new(start_key: usize, end_key: usize) -> BoolArrayMap {
BoolArrayMap {
offset: start_key,
elements: vec![false; end_key - start_key]
elements: vec![false; end_key - start_key],
}
}

@ -10,7 +10,7 @@ use crate::systematic_constants::SYSTEMATIC_INDICES_AND_PARAMETERS;
#[derive(Clone, Debug, PartialEq)]
pub struct PayloadId {
source_block_number: u8,
encoding_symbol_id: u32
encoding_symbol_id: u32,
}
impl PayloadId {
@ -19,14 +19,14 @@ impl PayloadId {
assert!(encoding_symbol_id < 16777216);
PayloadId {
source_block_number,
encoding_symbol_id
encoding_symbol_id,
}
}
pub fn deserialize(data: &[u8; 4]) -> PayloadId {
PayloadId {
source_block_number: data[0],
encoding_symbol_id: ((data[1] as u32) << 16) + ((data[2] as u32) << 8) + data[3] as u32
encoding_symbol_id: ((data[1] as u32) << 16) + ((data[2] as u32) << 8) + data[3] as u32,
}
}
@ -35,7 +35,7 @@ impl PayloadId {
self.source_block_number,
(self.encoding_symbol_id >> 16) as u8,
((self.encoding_symbol_id >> 8) & 0xFF) as u8,
(self.encoding_symbol_id & 0xFF) as u8
(self.encoding_symbol_id & 0xFF) as u8,
]
}
@ -52,22 +52,19 @@ impl PayloadId {
#[derive(Clone, Debug, PartialEq)]
pub struct EncodingPacket {
payload_id: PayloadId,
data: Vec<u8>
data: Vec<u8>,
}
impl EncodingPacket {
pub fn new(payload_id: PayloadId, data: Vec<u8>) -> EncodingPacket {
EncodingPacket {
payload_id,
data
}
EncodingPacket { payload_id, data }
}
pub fn deserialize(data: &[u8]) -> EncodingPacket {
let payload_data = [data[0], data[1], data[2], data[3]];
EncodingPacket {
payload_id: PayloadId::deserialize(&payload_data),
data: Vec::from(&data[4..])
data: Vec::from(&data[4..]),
}
}
@ -94,11 +91,17 @@ pub struct ObjectTransmissionInformation {
symbol_size: u16,
num_source_blocks: u8,
num_sub_blocks: u16,
symbol_alignment: u8
symbol_alignment: u8,
}
impl ObjectTransmissionInformation {
pub fn new(transfer_length: u64, symbol_size: u16, source_blocks: u8, sub_blocks: u16, alignment: u8) -> ObjectTransmissionInformation {
pub fn new(
transfer_length: u64,
symbol_size: u16,
source_blocks: u8,
sub_blocks: u16,
alignment: u8,
) -> ObjectTransmissionInformation {
assert!(transfer_length <= 946270874880);
assert_eq!(symbol_size % alignment as u16, 0);
ObjectTransmissionInformation {
@ -106,18 +109,21 @@ impl ObjectTransmissionInformation {
symbol_size,
num_source_blocks: source_blocks,
num_sub_blocks: sub_blocks,
symbol_alignment: alignment
symbol_alignment: alignment,
}
}
pub fn deserialize(data: &[u8; 12]) -> ObjectTransmissionInformation {
ObjectTransmissionInformation {
transfer_length: ((data[0] as u64) << 32) + ((data[1] as u64) << 24) +
((data[2] as u64) << 16) + ((data[3] as u64) << 8) + (data[4] as u64),
transfer_length: ((data[0] as u64) << 32)
+ ((data[1] as u64) << 24)
+ ((data[2] as u64) << 16)
+ ((data[3] as u64) << 8)
+ (data[4] as u64),
symbol_size: ((data[6] as u16) << 8) + data[7] as u16,
num_source_blocks: data[8],
num_sub_blocks: ((data[9] as u16) << 8) + data[10] as u16,
symbol_alignment: data[11]
symbol_alignment: data[11],
}
}
@ -134,7 +140,7 @@ impl ObjectTransmissionInformation {
self.num_source_blocks,
(self.num_sub_blocks >> 8) as u8,
(self.num_sub_blocks & 0xFF) as u8,
self.symbol_alignment
self.symbol_alignment,
]
}
@ -158,11 +164,14 @@ impl ObjectTransmissionInformation {
self.symbol_alignment
}
pub fn with_defaults(transfer_length: u64, max_packet_size: u16) -> ObjectTransmissionInformation {
pub fn with_defaults(
transfer_length: u64,
max_packet_size: u16,
) -> ObjectTransmissionInformation {
let alignment = 8;
assert!(max_packet_size >= alignment);
let symbol_size = max_packet_size - (max_packet_size % alignment);
let max_memory = 10*1024*1024;
let max_memory = 10 * 1024 * 1024;
let sub_symbol_size = 8;
let kt = (transfer_length as f64 / symbol_size as f64).ceil();
@ -193,8 +202,7 @@ impl ObjectTransmissionInformation {
symbol_size,
num_source_blocks: num_source_blocks as u8,
num_sub_blocks: n as u16,
symbol_alignment: alignment as u8
symbol_alignment: alignment as u8,
}
}
}
@ -212,9 +220,10 @@ pub fn partition(i: u32, j: u32) -> (u32, u32, u32, u32) {
pub fn deg(v: u32, lt_symbols: u32) -> u32 {
assert!(v < 1048576);
let f: [u32; 31] = [
0, 5243, 529531, 704294, 791675, 844104, 879057, 904023, 922747, 937311, 948962,
958494, 966438, 973160, 978921, 983914, 988283, 992138, 995565, 998631, 1001391,
1003887, 1006157, 1008229, 1010129, 1011876, 1013490, 1014983, 1016370, 1017662, 1048576];
0, 5243, 529531, 704294, 791675, 844104, 879057, 904023, 922747, 937311, 948962, 958494,
966438, 973160, 978921, 983914, 988283, 992138, 995565, 998631, 1001391, 1003887, 1006157,
1008229, 1010129, 1011876, 1013490, 1014983, 1016370, 1017662, 1048576,
];
for d in 1..f.len() {
if v < f[d] {
@ -226,22 +235,25 @@ pub fn deg(v: u32, lt_symbols: u32) -> u32 {
// Tuple[K', X] as defined in section 5.3.5.4
#[allow(non_snake_case)]
pub fn intermediate_tuple(source_block_symbols: u32, internal_symbol_id: u32) -> (u32, u32, u32, u32, u32, u32) {
pub fn intermediate_tuple(
source_block_symbols: u32,
internal_symbol_id: u32,
) -> (u32, u32, u32, u32, u32, u32) {
let J = systematic_index(source_block_symbols);
let W = num_lt_symbols(source_block_symbols);
let P1 = calculate_p1(source_block_symbols);
let mut A = 53591 + J*997;
let mut A = 53591 + J * 997;
if A % 2 == 0 {
A = A + 1
}
let B = 10267*(J + 1);
let B = 10267 * (J + 1);
let y: u32 = ((B as u64 + internal_symbol_id as u64 * A as u64) % 4294967296) as u32;
let v = rand(y, 0, 1048576);
let d = deg(v, W);
let a = 1 + rand(y, 1, W-1);
let a = 1 + rand(y, 1, W - 1);
let b = rand(y, 2, W);
let mut d1 = 2;
@ -249,7 +261,7 @@ pub fn intermediate_tuple(source_block_symbols: u32, internal_symbol_id: u32) ->
d1 = 2 + rand(internal_symbol_id, 3, 2);
}
let a1 = 1 + rand(internal_symbol_id, 4, P1-1);
let a1 = 1 + rand(internal_symbol_id, 4, P1 - 1);
let b1 = rand(internal_symbol_id, 5, P1);
(d, a, b, d1, a1, b1)
@ -257,19 +269,25 @@ pub fn intermediate_tuple(source_block_symbols: u32, internal_symbol_id: u32) ->
#[cfg(test)]
mod tests {
use crate::{EncodingPacket, ObjectTransmissionInformation, PayloadId};
use rand::Rng;
use crate::{PayloadId, EncodingPacket, ObjectTransmissionInformation};
#[test]
fn payload_id_serialization() {
let payload_id = PayloadId::new(rand::thread_rng().gen(), rand::thread_rng().gen_range(0, 256 * 256 * 256));
let payload_id = PayloadId::new(
rand::thread_rng().gen(),
rand::thread_rng().gen_range(0, 256 * 256 * 256),
);
let deserialized = PayloadId::deserialize(&payload_id.serialize());
assert_eq!(deserialized, payload_id);
}
#[test]
fn encoding_packet_serialization() {
let payload_id = PayloadId::new(rand::thread_rng().gen(), rand::thread_rng().gen_range(0, 256 * 256 * 256));
let payload_id = PayloadId::new(
rand::thread_rng().gen(),
rand::thread_rng().gen_range(0, 256 * 256 * 256),
);
let packet = EncodingPacket::new(payload_id, vec![rand::thread_rng().gen()]);
let deserialized = EncodingPacket::deserialize(&packet.serialize());
assert_eq!(deserialized, packet);
@ -277,7 +295,10 @@ mod tests {
#[test]
fn oti_serialization() {
let oti = ObjectTransmissionInformation::with_defaults(rand::thread_rng().gen_range(0, 256 * 256 * 256 * 256 * 256), rand::thread_rng().gen());
let oti = ObjectTransmissionInformation::with_defaults(
rand::thread_rng().gen_range(0, 256 * 256 * 256 * 256 * 256),
rand::thread_rng().gen(),
);
let deserialized = ObjectTransmissionInformation::deserialize(&oti.serialize());
assert_eq!(deserialized, oti);
}

@ -1,14 +1,14 @@
use crate::rng::rand;
use crate::systematic_constants::extended_source_block_symbols;
use crate::systematic_constants::num_hdpc_symbols;
use crate::systematic_constants::num_ldpc_symbols;
use crate::systematic_constants::num_pi_symbols;
use crate::systematic_constants::num_lt_symbols;
use crate::systematic_constants::num_intermediate_symbols;
use crate::base::intermediate_tuple;
use crate::matrix::OctetMatrix;
use crate::octet::Octet;
use crate::rng::rand;
use crate::systematic_constants::calculate_p1;
use crate::base::intermediate_tuple;
use crate::systematic_constants::extended_source_block_symbols;
use crate::systematic_constants::num_hdpc_symbols;
use crate::systematic_constants::num_intermediate_symbols;
use crate::systematic_constants::num_ldpc_symbols;
use crate::systematic_constants::num_lt_symbols;
use crate::systematic_constants::num_pi_symbols;
// Generates the GAMMA matrix
// See section 5.3.3.3
@ -31,8 +31,12 @@ fn generate_mt(H: usize, Kprime: usize, S: usize) -> OctetMatrix {
let mut matrix = OctetMatrix::new(H, Kprime + S);
for i in 0..H {
for j in 0..=(Kprime + S - 2) {
if i == rand((j + 1) as u32, 6, H as u32) as usize ||
i == ((rand((j + 1) as u32, 6, H as u32) + rand((j + 1) as u32, 7, (H - 1) as u32) + 1) % (H as u32)) as usize {
if i == rand((j + 1) as u32, 6, H as u32) as usize
|| i == ((rand((j + 1) as u32, 6, H as u32)
+ rand((j + 1) as u32, 7, (H - 1) as u32)
+ 1)
% (H as u32)) as usize
{
matrix.set(i, j, Octet::one());
}
}
@ -42,8 +46,10 @@ fn generate_mt(H: usize, Kprime: usize, S: usize) -> OctetMatrix {
}
// Simulates Enc[] function to get indices of accessed intermediate symbols, as defined in section 5.3.5.3
pub fn enc_indices(source_block_symbols: u32,
source_tuple: (u32, u32, u32, u32, u32, u32)) -> Vec<usize> {
pub fn enc_indices(
source_block_symbols: u32,
source_tuple: (u32, u32, u32, u32, u32, u32),
) -> Vec<usize> {
let w = num_lt_symbols(source_block_symbols);
let p = num_pi_symbols(source_block_symbols);
let p1 = calculate_p1(source_block_symbols);
@ -82,7 +88,10 @@ pub fn enc_indices(source_block_symbols: u32,
// See section 5.3.3.4.2
#[allow(non_snake_case)]
pub fn generate_constraint_matrix(source_block_symbols: u32, encoded_symbol_indices: &[u32]) -> OctetMatrix {
pub fn generate_constraint_matrix(
source_block_symbols: u32,
encoded_symbol_indices: &[u32],
) -> OctetMatrix {
let Kprime = extended_source_block_symbols(source_block_symbols) as usize;
let S = num_ldpc_symbols(source_block_symbols) as usize;
let H = num_hdpc_symbols(source_block_symbols) as usize;

@ -1,20 +1,20 @@
use std::collections::HashSet;
use crate::base::intermediate_tuple;
use crate::base::partition;
use crate::base::EncodingPacket;
use crate::base::ObjectTransmissionInformation;
use crate::constraint_matrix::enc_indices;
use crate::constraint_matrix::generate_constraint_matrix;
use crate::pi_solver::fused_inverse_mul_symbols;
use crate::symbol::Symbol;
use crate::systematic_constants::extended_source_block_symbols;
use crate::systematic_constants::num_ldpc_symbols;
use crate::systematic_constants::num_hdpc_symbols;
use crate::constraint_matrix::generate_constraint_matrix;
use crate::base::intermediate_tuple;
use crate::pi_solver::fused_inverse_mul_symbols;
use crate::constraint_matrix::enc_indices;
use crate::base::ObjectTransmissionInformation;
use crate::base::partition;
use crate::systematic_constants::num_ldpc_symbols;
use std::collections::HashSet;
pub struct Decoder {
config: ObjectTransmissionInformation,
block_decoders: Vec<SourceBlockDecoder>,
blocks: Vec<Option<Vec<u8>>>
blocks: Vec<Option<Vec<u8>>>,
}
impl Decoder {
@ -24,21 +24,29 @@ impl Decoder {
// TODO: support subblocks
assert_eq!(1, config.sub_blocks());
// let (tl, ts, nl, ns) = partition((config.symbol_size() / config.alignment() as u16) as u32, config.sub_blocks() as u32);
// let (tl, ts, nl, ns) = partition((config.symbol_size() / config.alignment() as u16) as u32, config.sub_blocks() as u32);
let mut decoders = vec![];
for i in 0..zl {
decoders.push(SourceBlockDecoder::new(i as u8, config.symbol_size(), kl as u64 * config.symbol_size() as u64));
decoders.push(SourceBlockDecoder::new(
i as u8,
config.symbol_size(),
kl as u64 * config.symbol_size() as u64,
));
}
for i in 0..zs {
decoders.push(SourceBlockDecoder::new(i as u8, config.symbol_size(), ks as u64 * config.symbol_size() as u64));
decoders.push(SourceBlockDecoder::new(
i as u8,
config.symbol_size(),
ks as u64 * config.symbol_size() as u64,
));
}
Decoder {
config,
block_decoders: decoders,
blocks: vec![None; (zl + zs) as usize]
blocks: vec![None; (zl + zs) as usize],
}
}
@ -46,7 +54,6 @@ impl Decoder {
let block_number = packet.payload_id().source_block_number() as usize;
if self.blocks[block_number].is_none() {
self.blocks[block_number] = self.block_decoders[block_number].decode(packet);
}
for block in self.blocks.iter() {
if block.is_none() {
@ -71,7 +78,7 @@ pub struct SourceBlockDecoder {
repair_packets: Vec<EncodingPacket>,
received_source_symbols: u32,
received_esi: HashSet<u32>,
decoded: bool
decoded: bool,
}
impl SourceBlockDecoder {
@ -89,23 +96,29 @@ impl SourceBlockDecoder {
repair_packets: vec![],
received_source_symbols: 0,
received_esi,
decoded: false
decoded: false,
}
}
pub fn decode(&mut self, packet: EncodingPacket) -> Option<Vec<u8>> {
assert_eq!(self.source_block_id, packet.payload_id().source_block_number());
assert_eq!(
self.source_block_id,
packet.payload_id().source_block_number()
);
let num_extended_symbols = extended_source_block_symbols(self.source_block_symbols);
if self.received_esi.insert(packet.payload_id().encoding_symbol_id()) {
if self
.received_esi
.insert(packet.payload_id().encoding_symbol_id())
{
if packet.payload_id().encoding_symbol_id() >= num_extended_symbols {
// Repair symbol
self.repair_packets.push(packet);
}
else {
} else {
// Check that this is not an extended symbol (which aren't explicitly sent)
assert!(packet.payload_id().encoding_symbol_id() < self.source_block_symbols);
// Source symbol
self.source_symbols[packet.payload_id().encoding_symbol_id() as usize] = Some(Symbol::new(packet.data().clone()));
self.source_symbols[packet.payload_id().encoding_symbol_id() as usize] =
Some(Symbol::new(packet.data().clone()));
self.received_source_symbols += 1;
}
}
@ -147,11 +160,13 @@ impl SourceBlockDecoder {
d.push(Symbol::new(repair_packet.data().clone()));
}
let constraint_matrix = generate_constraint_matrix(self.source_block_symbols, &encoded_indices);
let intermediate_symbols = fused_inverse_mul_symbols(constraint_matrix, d, self.source_block_symbols);
let constraint_matrix =
generate_constraint_matrix(self.source_block_symbols, &encoded_indices);
let intermediate_symbols =
fused_inverse_mul_symbols(constraint_matrix, d, self.source_block_symbols);
if intermediate_symbols == None {
return None
return None;
}
let intermediate_symbols = intermediate_symbols.unwrap();
@ -159,8 +174,7 @@ impl SourceBlockDecoder {
for i in 0..self.source_block_symbols as usize {
if self.source_symbols[i] != None {
result.extend(self.source_symbols[i].clone().unwrap().bytes())
}
else {
} else {
let rebuilt = self.rebuild_source_symbol(&intermediate_symbols, i as u32);
result.extend(rebuilt.bytes());
}
@ -172,7 +186,11 @@ impl SourceBlockDecoder {
None
}
fn rebuild_source_symbol(&self, intermediate_symbols: &Vec<Symbol>, source_symbol_id: u32) -> Symbol {
fn rebuild_source_symbol(
&self,
intermediate_symbols: &Vec<Symbol>,
source_symbol_id: u32,
) -> Symbol {
let tuple = intermediate_tuple(self.source_block_symbols, source_symbol_id);
let mut rebuilt = Symbol::zero(self.symbol_size as usize);
@ -182,4 +200,3 @@ impl SourceBlockDecoder {
rebuilt
}
}

@ -1,63 +1,77 @@
use crate::base::intermediate_tuple;
use crate::base::partition;
use crate::base::EncodingPacket;
use crate::base::PayloadId;
use crate::systematic_constants::extended_source_block_symbols;
use crate::systematic_constants::num_pi_symbols;
use crate::constraint_matrix::generate_constraint_matrix;
use crate::pi_solver::fused_inverse_mul_symbols;
use crate::symbol::Symbol;
use crate::systematic_constants::num_lt_symbols;
use crate::systematic_constants::calculate_p1;
use crate::systematic_constants::extended_source_block_symbols;
use crate::systematic_constants::num_hdpc_symbols;
use crate::systematic_constants::num_intermediate_symbols;
use crate::systematic_constants::num_ldpc_symbols;
use crate::systematic_constants::num_hdpc_symbols;
use crate::constraint_matrix::generate_constraint_matrix;
use crate::base::intermediate_tuple;
use crate::pi_solver::fused_inverse_mul_symbols;
use crate::base::partition;
use crate::systematic_constants::num_lt_symbols;
use crate::systematic_constants::num_pi_symbols;
use crate::ObjectTransmissionInformation;
pub struct Encoder {
config: ObjectTransmissionInformation,
blocks: Vec<SourceBlockEncoder>
blocks: Vec<SourceBlockEncoder>,
}
impl Encoder {
pub fn with_defaults(data: &[u8], maximum_transmission_unit: u16) -> Encoder {
let config = ObjectTransmissionInformation::with_defaults(data.len() as u64, maximum_transmission_unit);
let config = ObjectTransmissionInformation::with_defaults(
data.len() as u64,
maximum_transmission_unit,
);
let kt = (config.transfer_length() as f64 / config.symbol_size() as f64).ceil() as u32;
let (kl, ks, zl, zs) = partition(kt, config.source_blocks() as u32);
// TODO: support subblocks
assert_eq!(1, config.sub_blocks());
// let (tl, ts, nl, ns) = partition((config.symbol_size() / config.alignment() as u16) as u32, config.sub_blocks() as u32);
// let (tl, ts, nl, ns) = partition((config.symbol_size() / config.alignment() as u16) as u32, config.sub_blocks() as u32);
let mut data_index = 0;
let mut blocks = vec![];
for i in 0..zl {
let offset = kl as usize * config.symbol_size() as usize;
blocks.push(SourceBlockEncoder::new(i as u8, config.symbol_size(), &data[data_index..(data_index + offset)]));
blocks.push(SourceBlockEncoder::new(
i as u8,
config.symbol_size(),
&data[data_index..(data_index + offset)],
));
data_index += offset;
}
for i in 0..zs {
let offset = ks as usize * config.symbol_size() as usize;
if data_index + offset < data.len() {
blocks.push(SourceBlockEncoder::new(i as u8, config.symbol_size(), &data[data_index..(data_index + offset)]));
}
else {
blocks.push(SourceBlockEncoder::new(
i as u8,
config.symbol_size(),
&data[data_index..(data_index + offset)],
));
} else {
// Should only be possible when Kt * T > F. See third to last paragraph in section 4.4.1.2
assert!(kt as usize * config.symbol_size() as usize > data.len());
// Zero pad the last symbol
let mut padded = Vec::from(&data[data_index..]);
padded.extend(vec![0; kt as usize * config.symbol_size() as usize - data.len()]);
blocks.push(SourceBlockEncoder::new(i as u8, config.symbol_size(), &padded));
padded.extend(vec![
0;
kt as usize * config.symbol_size() as usize - data.len()
]);
blocks.push(SourceBlockEncoder::new(
i as u8,
config.symbol_size(),
&padded,
));
}
data_index += offset;
}
Encoder {
config,
blocks
}
Encoder { config, blocks }
}
pub fn get_config(&self) -> ObjectTransmissionInformation {
@ -81,43 +95,57 @@ impl Encoder {
pub struct SourceBlockEncoder {
source_block_id: u8,
source_symbols: Vec<Symbol>,
intermediate_symbols: Vec<Symbol>
intermediate_symbols: Vec<Symbol>,
}
impl SourceBlockEncoder {
pub fn new(source_block_id: u8, symbol_size: u16, data: &[u8]) -> SourceBlockEncoder {
assert_eq!(data.len() % symbol_size as usize, 0);
let source_symbols: Vec<Symbol> = data.chunks(symbol_size as usize)
let source_symbols: Vec<Symbol> = data
.chunks(symbol_size as usize)
.map(|x| Symbol::new(Vec::from(x)))
.collect();
let intermediate_symbols = gen_intermediate_symbols(&source_symbols, symbol_size as usize);
SourceBlockEncoder {
source_block_id,
source_symbols,
intermediate_symbols
intermediate_symbols,
}
}
pub fn source_packets(&self) -> Vec<EncodingPacket> {
let mut esi: i32 = -1;
self.source_symbols.iter().map(|symbol| {
esi += 1;
EncodingPacket::new(
PayloadId::new(self.source_block_id, esi as u32),
symbol.bytes().clone()
)
}).collect()
self.source_symbols
.iter()
.map(|symbol| {
esi += 1;
EncodingPacket::new(
PayloadId::new(self.source_block_id, esi as u32),
symbol.bytes().clone(),
)
})
.collect()
}
// See section 5.3.4
pub fn repair_packets(&self, start_repair_symbol_id: u32, packets: u32) -> Vec<EncodingPacket> {
let start_encoding_symbol_id = start_repair_symbol_id + extended_source_block_symbols(self.source_symbols.len() as u32);
let start_encoding_symbol_id = start_repair_symbol_id
+ extended_source_block_symbols(self.source_symbols.len() as u32);
let mut result = vec![];
for i in 0..packets {
let tuple = intermediate_tuple(self.source_symbols.len() as u32, start_encoding_symbol_id + i);
let tuple = intermediate_tuple(
self.source_symbols.len() as u32,
start_encoding_symbol_id + i,
);
result.push(EncodingPacket::new(
PayloadId::new(self.source_block_id, start_encoding_symbol_id + i),
enc(self.source_symbols.len() as u32, &self.intermediate_symbols, tuple).bytes().clone()
enc(
self.source_symbols.len() as u32,
&self.intermediate_symbols,
tuple,
)
.bytes()
.clone(),
));
}
result
@ -151,9 +179,11 @@ fn gen_intermediate_symbols(source_block: &Vec<Symbol>, symbol_size: usize) -> V
}
// Enc[] function, as defined in section 5.3.5.3
fn enc(source_block_symbols: u32,
intermediate_symbols: &Vec<Symbol>,
source_tuple: (u32, u32, u32, u32, u32, u32)) -> Symbol {
fn enc(
source_block_symbols: u32,
intermediate_symbols: &Vec<Symbol>,
source_tuple: (u32, u32, u32, u32, u32, u32),
) -> Symbol {
let w = num_lt_symbols(source_block_symbols);
let p = num_pi_symbols(source_block_symbols);
let p1 = calculate_p1(source_block_symbols);
@ -192,10 +222,10 @@ fn enc(source_block_symbols: u32,
mod tests {
use rand::Rng;
use crate::symbol::Symbol;
use crate::encoder::enc;
use crate::base::intermediate_tuple;
use crate::encoder::enc;
use crate::encoder::gen_intermediate_symbols;
use crate::symbol::Symbol;
use crate::systematic_constants::num_ldpc_symbols;
use crate::systematic_constants::num_lt_symbols;
use crate::systematic_constants::num_pi_symbols;

@ -1,32 +1,32 @@
mod util;
mod arraymap;
mod systematic_constants;
mod rng;
mod base;
mod constraint_matrix;
mod decoder;
mod encoder;
mod matrix;
mod octet;
mod octets;
mod symbol;
mod matrix;
mod constraint_matrix;
mod base;
mod pi_solver;
mod encoder;
mod decoder;
mod rng;
mod symbol;
mod systematic_constants;
mod util;
pub use crate::base::PayloadId;
pub use crate::base::EncodingPacket;
pub use crate::base::ObjectTransmissionInformation;
pub use crate::encoder::SourceBlockEncoder;
pub use crate::encoder::Encoder;
pub use crate::decoder::SourceBlockDecoder;
pub use crate::base::PayloadId;
pub use crate::decoder::Decoder;
pub use crate::decoder::SourceBlockDecoder;
pub use crate::encoder::Encoder;
pub use crate::encoder::SourceBlockEncoder;
#[cfg(feature = "benchmarking")]
pub use crate::constraint_matrix::generate_constraint_matrix;
#[cfg(feature = "benchmarking")]
pub use crate::systematic_constants::extended_source_block_symbols;
pub use crate::octet::Octet;
#[cfg(feature = "benchmarking")]
pub use crate::pi_solver::IntermediateSymbolDecoder;
#[cfg(feature = "benchmarking")]
pub use crate::octet::Octet;
#[cfg(feature = "benchmarking")]
pub use crate::symbol::Symbol;
#[cfg(feature = "benchmarking")]
pub use crate::systematic_constants::extended_source_block_symbols;

@ -1,14 +1,14 @@
use std::ops::Mul;
use crate::octet::Octet;
use crate::octets::fused_addassign_mul_scalar;
use crate::octets::add_assign;
use crate::octets::fused_addassign_mul_scalar;
use crate::util::get_both_indices;
use std::ops::Mul;
#[derive(Clone, Debug, PartialEq)]
pub struct OctetMatrix {
height: usize,
width: usize,
elements: Vec<Vec<u8>>
elements: Vec<Vec<u8>>,
}
impl OctetMatrix {
@ -20,7 +20,7 @@ impl OctetMatrix {
OctetMatrix {
height,
width,
elements
elements,
}
}
@ -48,7 +48,7 @@ impl OctetMatrix {
Octet::new(self.elements[i][j])
}
pub fn swap_rows(&mut self, i: usize, j:usize) {
pub fn swap_rows(&mut self, i: usize, j: usize) {
self.elements.swap(i, j);
}
@ -73,8 +73,7 @@ impl OctetMatrix {
}
if scalar == Octet::one() {
add_assign(&mut temp[row], &self.elements[i]);
}
else {
} else {
fused_addassign_mul_scalar(&mut temp[row], &self.elements[i], &scalar);
}
}
@ -90,8 +89,7 @@ impl OctetMatrix {
if *scalar == Octet::one() {
add_assign(dest_row, temp_row);
}
else {
} else {
fused_addassign_mul_scalar(dest_row, temp_row, scalar);
}
}
@ -122,9 +120,12 @@ impl<'a, 'b> Mul<&'b OctetMatrix> for &'a OctetMatrix {
}
if scalar == Octet::one() {
add_assign(&mut result.elements[row], &rhs.elements[i]);
}
else {
fused_addassign_mul_scalar(&mut result.elements[row], &rhs.elements[i], &scalar);
} else {
fused_addassign_mul_scalar(
&mut result.elements[row],
&rhs.elements[i],
&scalar,
);
}
}
}

@ -1,8 +1,8 @@
use std::ops::Add;
use std::ops::Mul;
use std::ops::Div;
use std::ops::Sub;
use std::ops::AddAssign;
use std::ops::Div;
use std::ops::Mul;
use std::ops::Sub;
// As defined in section 5.7.3
#[rustfmt::skip]
@ -88,7 +88,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(7),
calculate_octet_mul_hi_table_inner(8),
calculate_octet_mul_hi_table_inner(9),
calculate_octet_mul_hi_table_inner(10),
calculate_octet_mul_hi_table_inner(11),
calculate_octet_mul_hi_table_inner(12),
@ -99,7 +98,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(17),
calculate_octet_mul_hi_table_inner(18),
calculate_octet_mul_hi_table_inner(19),
calculate_octet_mul_hi_table_inner(20),
calculate_octet_mul_hi_table_inner(21),
calculate_octet_mul_hi_table_inner(22),
@ -110,7 +108,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(27),
calculate_octet_mul_hi_table_inner(28),
calculate_octet_mul_hi_table_inner(29),
calculate_octet_mul_hi_table_inner(30),
calculate_octet_mul_hi_table_inner(31),
calculate_octet_mul_hi_table_inner(32),
@ -121,7 +118,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(37),
calculate_octet_mul_hi_table_inner(38),
calculate_octet_mul_hi_table_inner(39),
calculate_octet_mul_hi_table_inner(40),
calculate_octet_mul_hi_table_inner(41),
calculate_octet_mul_hi_table_inner(42),
@ -132,7 +128,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(47),
calculate_octet_mul_hi_table_inner(48),
calculate_octet_mul_hi_table_inner(49),
calculate_octet_mul_hi_table_inner(50),
calculate_octet_mul_hi_table_inner(51),
calculate_octet_mul_hi_table_inner(52),
@ -143,7 +138,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(57),
calculate_octet_mul_hi_table_inner(58),
calculate_octet_mul_hi_table_inner(59),
calculate_octet_mul_hi_table_inner(60),
calculate_octet_mul_hi_table_inner(61),
calculate_octet_mul_hi_table_inner(62),
@ -154,7 +148,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(67),
calculate_octet_mul_hi_table_inner(68),
calculate_octet_mul_hi_table_inner(69),
calculate_octet_mul_hi_table_inner(70),
calculate_octet_mul_hi_table_inner(71),
calculate_octet_mul_hi_table_inner(72),
@ -165,7 +158,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(77),
calculate_octet_mul_hi_table_inner(78),
calculate_octet_mul_hi_table_inner(79),
calculate_octet_mul_hi_table_inner(80),
calculate_octet_mul_hi_table_inner(81),
calculate_octet_mul_hi_table_inner(82),
@ -176,7 +168,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(87),
calculate_octet_mul_hi_table_inner(88),
calculate_octet_mul_hi_table_inner(89),
calculate_octet_mul_hi_table_inner(90),
calculate_octet_mul_hi_table_inner(91),
calculate_octet_mul_hi_table_inner(92),
@ -187,7 +178,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(97),
calculate_octet_mul_hi_table_inner(98),
calculate_octet_mul_hi_table_inner(99),
calculate_octet_mul_hi_table_inner(100),
calculate_octet_mul_hi_table_inner(101),
calculate_octet_mul_hi_table_inner(102),
@ -198,7 +188,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(107),
calculate_octet_mul_hi_table_inner(108),
calculate_octet_mul_hi_table_inner(109),
calculate_octet_mul_hi_table_inner(110),
calculate_octet_mul_hi_table_inner(111),
calculate_octet_mul_hi_table_inner(112),
@ -209,7 +198,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(117),
calculate_octet_mul_hi_table_inner(118),
calculate_octet_mul_hi_table_inner(119),
calculate_octet_mul_hi_table_inner(120),
calculate_octet_mul_hi_table_inner(121),
calculate_octet_mul_hi_table_inner(122),
@ -220,7 +208,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(127),
calculate_octet_mul_hi_table_inner(128),
calculate_octet_mul_hi_table_inner(129),
calculate_octet_mul_hi_table_inner(130),
calculate_octet_mul_hi_table_inner(131),
calculate_octet_mul_hi_table_inner(132),
@ -231,7 +218,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(137),
calculate_octet_mul_hi_table_inner(138),
calculate_octet_mul_hi_table_inner(139),
calculate_octet_mul_hi_table_inner(140),
calculate_octet_mul_hi_table_inner(141),
calculate_octet_mul_hi_table_inner(142),
@ -242,7 +228,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(147),
calculate_octet_mul_hi_table_inner(148),
calculate_octet_mul_hi_table_inner(149),
calculate_octet_mul_hi_table_inner(150),
calculate_octet_mul_hi_table_inner(151),
calculate_octet_mul_hi_table_inner(152),
@ -253,7 +238,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(157),
calculate_octet_mul_hi_table_inner(158),
calculate_octet_mul_hi_table_inner(159),
calculate_octet_mul_hi_table_inner(160),
calculate_octet_mul_hi_table_inner(161),
calculate_octet_mul_hi_table_inner(162),
@ -264,7 +248,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(167),
calculate_octet_mul_hi_table_inner(168),
calculate_octet_mul_hi_table_inner(169),
calculate_octet_mul_hi_table_inner(170),
calculate_octet_mul_hi_table_inner(171),
calculate_octet_mul_hi_table_inner(172),
@ -275,7 +258,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(177),
calculate_octet_mul_hi_table_inner(178),
calculate_octet_mul_hi_table_inner(179),
calculate_octet_mul_hi_table_inner(180),
calculate_octet_mul_hi_table_inner(181),
calculate_octet_mul_hi_table_inner(182),
@ -286,7 +268,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(187),
calculate_octet_mul_hi_table_inner(188),
calculate_octet_mul_hi_table_inner(189),
calculate_octet_mul_hi_table_inner(190),
calculate_octet_mul_hi_table_inner(191),
calculate_octet_mul_hi_table_inner(192),
@ -297,7 +278,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(197),
calculate_octet_mul_hi_table_inner(198),
calculate_octet_mul_hi_table_inner(199),
calculate_octet_mul_hi_table_inner(200),
calculate_octet_mul_hi_table_inner(201),
calculate_octet_mul_hi_table_inner(202),
@ -308,7 +288,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(207),
calculate_octet_mul_hi_table_inner(208),
calculate_octet_mul_hi_table_inner(209),
calculate_octet_mul_hi_table_inner(210),
calculate_octet_mul_hi_table_inner(211),
calculate_octet_mul_hi_table_inner(212),
@ -319,7 +298,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(217),
calculate_octet_mul_hi_table_inner(218),
calculate_octet_mul_hi_table_inner(219),
calculate_octet_mul_hi_table_inner(220),
calculate_octet_mul_hi_table_inner(221),
calculate_octet_mul_hi_table_inner(222),
@ -330,7 +308,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(227),
calculate_octet_mul_hi_table_inner(228),
calculate_octet_mul_hi_table_inner(229),
calculate_octet_mul_hi_table_inner(230),
calculate_octet_mul_hi_table_inner(231),
calculate_octet_mul_hi_table_inner(232),
@ -341,7 +318,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(237),
calculate_octet_mul_hi_table_inner(238),
calculate_octet_mul_hi_table_inner(239),
calculate_octet_mul_hi_table_inner(240),
calculate_octet_mul_hi_table_inner(241),
calculate_octet_mul_hi_table_inner(242),
@ -352,7 +328,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(247),
calculate_octet_mul_hi_table_inner(248),
calculate_octet_mul_hi_table_inner(249),
calculate_octet_mul_hi_table_inner(250),
calculate_octet_mul_hi_table_inner(251),
calculate_octet_mul_hi_table_inner(252),
@ -368,42 +343,35 @@ const fn calculate_octet_mul_hi_table_inner(x: usize) -> [u8; 32] {
const_mul(x, 1 << 4),
const_mul(x, 2 << 4),
const_mul(x, 3 << 4),
const_mul(x, 4 << 4),
const_mul(x, 5 << 4),
const_mul(x, 6 << 4),
const_mul(x, 7 << 4),
const_mul(x, 8 << 4),
const_mul(x, 9 << 4),
const_mul(x, 10 << 4),
const_mul(x, 11 << 4),
const_mul(x, 12 << 4),
const_mul(x, 13 << 4),
const_mul(x, 14 << 4),
const_mul(x, 15 << 4),
0,
const_mul(x, 1 << 4),
const_mul(x, 2 << 4),
const_mul(x, 3 << 4),
const_mul(x, 4 << 4),
const_mul(x, 5 << 4),
const_mul(x, 6 << 4),
const_mul(x, 7 << 4),
const_mul(x, 8 << 4),
const_mul(x, 9 << 4),
const_mul(x, 10 << 4),
const_mul(x, 11 << 4),
const_mul(x, 12 << 4),
const_mul(x, 13 << 4),
const_mul(x, 14 << 4),
const_mul(x, 15 << 4),
]
];
}
const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
@ -418,7 +386,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(7),
calculate_octet_mul_low_table_inner(8),
calculate_octet_mul_low_table_inner(9),
calculate_octet_mul_low_table_inner(10),
calculate_octet_mul_low_table_inner(11),
calculate_octet_mul_low_table_inner(12),
@ -429,7 +396,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(17),
calculate_octet_mul_low_table_inner(18),
calculate_octet_mul_low_table_inner(19),
calculate_octet_mul_low_table_inner(20),
calculate_octet_mul_low_table_inner(21),
calculate_octet_mul_low_table_inner(22),
@ -440,7 +406,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(27),
calculate_octet_mul_low_table_inner(28),
calculate_octet_mul_low_table_inner(29),
calculate_octet_mul_low_table_inner(30),
calculate_octet_mul_low_table_inner(31),
calculate_octet_mul_low_table_inner(32),
@ -451,7 +416,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(37),
calculate_octet_mul_low_table_inner(38),
calculate_octet_mul_low_table_inner(39),
calculate_octet_mul_low_table_inner(40),
calculate_octet_mul_low_table_inner(41),
calculate_octet_mul_low_table_inner(42),
@ -462,7 +426,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(47),
calculate_octet_mul_low_table_inner(48),
calculate_octet_mul_low_table_inner(49),
calculate_octet_mul_low_table_inner(50),
calculate_octet_mul_low_table_inner(51),
calculate_octet_mul_low_table_inner(52),
@ -473,7 +436,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(57),
calculate_octet_mul_low_table_inner(58),
calculate_octet_mul_low_table_inner(59),
calculate_octet_mul_low_table_inner(60),
calculate_octet_mul_low_table_inner(61),
calculate_octet_mul_low_table_inner(62),
@ -484,7 +446,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(67),
calculate_octet_mul_low_table_inner(68),
calculate_octet_mul_low_table_inner(69),
calculate_octet_mul_low_table_inner(70),
calculate_octet_mul_low_table_inner(71),
calculate_octet_mul_low_table_inner(72),
@ -495,7 +456,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(77),
calculate_octet_mul_low_table_inner(78),
calculate_octet_mul_low_table_inner(79),
calculate_octet_mul_low_table_inner(80),
calculate_octet_mul_low_table_inner(81),
calculate_octet_mul_low_table_inner(82),
@ -506,7 +466,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(87),
calculate_octet_mul_low_table_inner(88),
calculate_octet_mul_low_table_inner(89),
calculate_octet_mul_low_table_inner(90),
calculate_octet_mul_low_table_inner(91),
calculate_octet_mul_low_table_inner(92),
@ -517,7 +476,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(97),
calculate_octet_mul_low_table_inner(98),
calculate_octet_mul_low_table_inner(99),
calculate_octet_mul_low_table_inner(100),
calculate_octet_mul_low_table_inner(101),
calculate_octet_mul_low_table_inner(102),
@ -528,7 +486,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(107),
calculate_octet_mul_low_table_inner(108),
calculate_octet_mul_low_table_inner(109),
calculate_octet_mul_low_table_inner(110),
calculate_octet_mul_low_table_inner(111),
calculate_octet_mul_low_table_inner(112),
@ -539,7 +496,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(117),
calculate_octet_mul_low_table_inner(118),
calculate_octet_mul_low_table_inner(119),
calculate_octet_mul_low_table_inner(120),
calculate_octet_mul_low_table_inner(121),
calculate_octet_mul_low_table_inner(122),
@ -550,7 +506,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(127),
calculate_octet_mul_low_table_inner(128),
calculate_octet_mul_low_table_inner(129),
calculate_octet_mul_low_table_inner(130),
calculate_octet_mul_low_table_inner(131),
calculate_octet_mul_low_table_inner(132),
@ -561,7 +516,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(137),
calculate_octet_mul_low_table_inner(138),
calculate_octet_mul_low_table_inner(139),
calculate_octet_mul_low_table_inner(140),
calculate_octet_mul_low_table_inner(141),
calculate_octet_mul_low_table_inner(142),
@ -572,7 +526,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(147),
calculate_octet_mul_low_table_inner(148),
calculate_octet_mul_low_table_inner(149),
calculate_octet_mul_low_table_inner(150),
calculate_octet_mul_low_table_inner(151),
calculate_octet_mul_low_table_inner(152),
@ -583,7 +536,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(157),
calculate_octet_mul_low_table_inner(158),
calculate_octet_mul_low_table_inner(159),
calculate_octet_mul_low_table_inner(160),
calculate_octet_mul_low_table_inner(161),
calculate_octet_mul_low_table_inner(162),
@ -594,7 +546,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(167),
calculate_octet_mul_low_table_inner(168),
calculate_octet_mul_low_table_inner(169),
calculate_octet_mul_low_table_inner(170),
calculate_octet_mul_low_table_inner(171),
calculate_octet_mul_low_table_inner(172),
@ -605,7 +556,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(177),
calculate_octet_mul_low_table_inner(178),
calculate_octet_mul_low_table_inner(179),
calculate_octet_mul_low_table_inner(180),
calculate_octet_mul_low_table_inner(181),
calculate_octet_mul_low_table_inner(182),
@ -616,7 +566,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(187),
calculate_octet_mul_low_table_inner(188),
calculate_octet_mul_low_table_inner(189),
calculate_octet_mul_low_table_inner(190),
calculate_octet_mul_low_table_inner(191),
calculate_octet_mul_low_table_inner(192),
@ -627,7 +576,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(197),
calculate_octet_mul_low_table_inner(198),
calculate_octet_mul_low_table_inner(199),
calculate_octet_mul_low_table_inner(200),
calculate_octet_mul_low_table_inner(201),
calculate_octet_mul_low_table_inner(202),
@ -638,7 +586,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(207),
calculate_octet_mul_low_table_inner(208),
calculate_octet_mul_low_table_inner(209),
calculate_octet_mul_low_table_inner(210),
calculate_octet_mul_low_table_inner(211),
calculate_octet_mul_low_table_inner(212),
@ -649,7 +596,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(217),
calculate_octet_mul_low_table_inner(218),
calculate_octet_mul_low_table_inner(219),
calculate_octet_mul_low_table_inner(220),
calculate_octet_mul_low_table_inner(221),
calculate_octet_mul_low_table_inner(222),
@ -660,7 +606,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(227),
calculate_octet_mul_low_table_inner(228),
calculate_octet_mul_low_table_inner(229),
calculate_octet_mul_low_table_inner(230),
calculate_octet_mul_low_table_inner(231),
calculate_octet_mul_low_table_inner(232),
@ -671,7 +616,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(237),
calculate_octet_mul_low_table_inner(238),
calculate_octet_mul_low_table_inner(239),
calculate_octet_mul_low_table_inner(240),
calculate_octet_mul_low_table_inner(241),
calculate_octet_mul_low_table_inner(242),
@ -682,7 +626,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(247),
calculate_octet_mul_low_table_inner(248),
calculate_octet_mul_low_table_inner(249),
calculate_octet_mul_low_table_inner(250),
calculate_octet_mul_low_table_inner(251),
calculate_octet_mul_low_table_inner(252),
@ -698,42 +641,35 @@ const fn calculate_octet_mul_low_table_inner(x: usize) -> [u8; 32] {
const_mul(x, 1),
const_mul(x, 2),
const_mul(x, 3),
const_mul(x, 4),
const_mul(x, 5),
const_mul(x, 6),
const_mul(x, 7),
const_mul(x, 8),
const_mul(x, 9),
const_mul(x, 10),
const_mul(x, 11),
const_mul(x, 12),
const_mul(x, 13),
const_mul(x, 14),
const_mul(x, 15),
0,
const_mul(x, 1),
const_mul(x, 2),
const_mul(x, 3),
const_mul(x, 4),
const_mul(x, 5),
const_mul(x, 6),
const_mul(x, 7),
const_mul(x, 8),
const_mul(x, 9),
const_mul(x, 10),
const_mul(x, 11),
const_mul(x, 12),
const_mul(x, 13),
const_mul(x, 14),
const_mul(x, 15),
]
];
}
const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
@ -748,7 +684,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(7),
calculate_octet_mul_table_inner(8),
calculate_octet_mul_table_inner(9),
calculate_octet_mul_table_inner(10),
calculate_octet_mul_table_inner(11),
calculate_octet_mul_table_inner(12),
@ -759,7 +694,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(17),
calculate_octet_mul_table_inner(18),
calculate_octet_mul_table_inner(19),
calculate_octet_mul_table_inner(20),
calculate_octet_mul_table_inner(21),
calculate_octet_mul_table_inner(22),
@ -770,7 +704,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(27),
calculate_octet_mul_table_inner(28),
calculate_octet_mul_table_inner(29),
calculate_octet_mul_table_inner(30),
calculate_octet_mul_table_inner(31),
calculate_octet_mul_table_inner(32),
@ -781,7 +714,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(37),
calculate_octet_mul_table_inner(38),
calculate_octet_mul_table_inner(39),
calculate_octet_mul_table_inner(40),
calculate_octet_mul_table_inner(41),
calculate_octet_mul_table_inner(42),
@ -792,7 +724,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(47),
calculate_octet_mul_table_inner(48),
calculate_octet_mul_table_inner(49),
calculate_octet_mul_table_inner(50),
calculate_octet_mul_table_inner(51),
calculate_octet_mul_table_inner(52),
@ -803,7 +734,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(57),
calculate_octet_mul_table_inner(58),
calculate_octet_mul_table_inner(59),
calculate_octet_mul_table_inner(60),
calculate_octet_mul_table_inner(61),
calculate_octet_mul_table_inner(62),
@ -814,7 +744,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(67),
calculate_octet_mul_table_inner(68),
calculate_octet_mul_table_inner(69),
calculate_octet_mul_table_inner(70),
calculate_octet_mul_table_inner(71),
calculate_octet_mul_table_inner(72),
@ -825,7 +754,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(77),
calculate_octet_mul_table_inner(78),
calculate_octet_mul_table_inner(79),
calculate_octet_mul_table_inner(80),
calculate_octet_mul_table_inner(81),
calculate_octet_mul_table_inner(82),
@ -836,7 +764,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(87),
calculate_octet_mul_table_inner(88),
calculate_octet_mul_table_inner(89),
calculate_octet_mul_table_inner(90),
calculate_octet_mul_table_inner(91),
calculate_octet_mul_table_inner(92),
@ -847,7 +774,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(97),
calculate_octet_mul_table_inner(98),
calculate_octet_mul_table_inner(99),
calculate_octet_mul_table_inner(100),
calculate_octet_mul_table_inner(101),
calculate_octet_mul_table_inner(102),
@ -858,7 +784,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(107),
calculate_octet_mul_table_inner(108),
calculate_octet_mul_table_inner(109),
calculate_octet_mul_table_inner(110),
calculate_octet_mul_table_inner(111),
calculate_octet_mul_table_inner(112),
@ -869,7 +794,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(117),
calculate_octet_mul_table_inner(118),
calculate_octet_mul_table_inner(119),
calculate_octet_mul_table_inner(120),
calculate_octet_mul_table_inner(121),
calculate_octet_mul_table_inner(122),
@ -880,7 +804,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(127),
calculate_octet_mul_table_inner(128),
calculate_octet_mul_table_inner(129),
calculate_octet_mul_table_inner(130),
calculate_octet_mul_table_inner(131),
calculate_octet_mul_table_inner(132),
@ -891,7 +814,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(137),
calculate_octet_mul_table_inner(138),
calculate_octet_mul_table_inner(139),
calculate_octet_mul_table_inner(140),
calculate_octet_mul_table_inner(141),
calculate_octet_mul_table_inner(142),
@ -902,7 +824,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(147),
calculate_octet_mul_table_inner(148),
calculate_octet_mul_table_inner(149),
calculate_octet_mul_table_inner(150),
calculate_octet_mul_table_inner(151),
calculate_octet_mul_table_inner(152),
@ -913,7 +834,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(157),
calculate_octet_mul_table_inner(158),
calculate_octet_mul_table_inner(159),
calculate_octet_mul_table_inner(160),
calculate_octet_mul_table_inner(161),
calculate_octet_mul_table_inner(162),
@ -924,7 +844,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(167),
calculate_octet_mul_table_inner(168),
calculate_octet_mul_table_inner(169),
calculate_octet_mul_table_inner(170),
calculate_octet_mul_table_inner(171),
calculate_octet_mul_table_inner(172),
@ -935,7 +854,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(177),
calculate_octet_mul_table_inner(178),
calculate_octet_mul_table_inner(179),
calculate_octet_mul_table_inner(180),
calculate_octet_mul_table_inner(181),
calculate_octet_mul_table_inner(182),
@ -946,7 +864,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(187),
calculate_octet_mul_table_inner(188),
calculate_octet_mul_table_inner(189),
calculate_octet_mul_table_inner(190),
calculate_octet_mul_table_inner(191),
calculate_octet_mul_table_inner(192),
@ -957,7 +874,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(197),
calculate_octet_mul_table_inner(198),
calculate_octet_mul_table_inner(199),
calculate_octet_mul_table_inner(200),
calculate_octet_mul_table_inner(201),
calculate_octet_mul_table_inner(202),
@ -968,7 +884,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(207),
calculate_octet_mul_table_inner(208),
calculate_octet_mul_table_inner(209),
calculate_octet_mul_table_inner(210),
calculate_octet_mul_table_inner(211),
calculate_octet_mul_table_inner(212),
@ -979,7 +894,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(217),
calculate_octet_mul_table_inner(218),
calculate_octet_mul_table_inner(219),
calculate_octet_mul_table_inner(220),
calculate_octet_mul_table_inner(221),
calculate_octet_mul_table_inner(222),
@ -990,7 +904,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(227),
calculate_octet_mul_table_inner(228),
calculate_octet_mul_table_inner(229),
calculate_octet_mul_table_inner(230),
calculate_octet_mul_table_inner(231),
calculate_octet_mul_table_inner(232),
@ -1001,7 +914,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(237),
calculate_octet_mul_table_inner(238),
calculate_octet_mul_table_inner(239),
calculate_octet_mul_table_inner(240),
calculate_octet_mul_table_inner(241),
calculate_octet_mul_table_inner(242),
@ -1012,7 +924,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(247),
calculate_octet_mul_table_inner(248),
calculate_octet_mul_table_inner(249),
calculate_octet_mul_table_inner(250),
calculate_octet_mul_table_inner(251),
calculate_octet_mul_table_inner(252),
@ -1034,7 +945,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 7),
const_mul(x, 8),
const_mul(x, 9),
const_mul(x, 10),
const_mul(x, 11),
const_mul(x, 12),
@ -1045,7 +955,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 17),
const_mul(x, 18),
const_mul(x, 19),
const_mul(x, 20),
const_mul(x, 21),
const_mul(x, 22),
@ -1056,7 +965,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 27),
const_mul(x, 28),
const_mul(x, 29),
const_mul(x, 30),
const_mul(x, 31),
const_mul(x, 32),
@ -1067,7 +975,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 37),
const_mul(x, 38),
const_mul(x, 39),
const_mul(x, 40),
const_mul(x, 41),
const_mul(x, 42),
@ -1078,7 +985,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 47),
const_mul(x, 48),
const_mul(x, 49),
const_mul(x, 50),
const_mul(x, 51),
const_mul(x, 52),
@ -1089,7 +995,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 57),
const_mul(x, 58),
const_mul(x, 59),
const_mul(x, 60),
const_mul(x, 61),
const_mul(x, 62),
@ -1100,7 +1005,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 67),
const_mul(x, 68),
const_mul(x, 69),
const_mul(x, 70),
const_mul(x, 71),
const_mul(x, 72),
@ -1111,7 +1015,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 77),
const_mul(x, 78),
const_mul(x, 79),
const_mul(x, 80),
const_mul(x, 81),
const_mul(x, 82),
@ -1122,7 +1025,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 87),
const_mul(x, 88),
const_mul(x, 89),
const_mul(x, 90),
const_mul(x, 91),
const_mul(x, 92),
@ -1133,7 +1035,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 97),
const_mul(x, 98),
const_mul(x, 99),
const_mul(x, 100),
const_mul(x, 101),
const_mul(x, 102),
@ -1144,7 +1045,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 107),
const_mul(x, 108),
const_mul(x, 109),
const_mul(x, 110),
const_mul(x, 111),
const_mul(x, 112),
@ -1155,7 +1055,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 117),
const_mul(x, 118),
const_mul(x, 119),
const_mul(x, 120),
const_mul(x, 121),
const_mul(x, 122),
@ -1166,7 +1065,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 127),
const_mul(x, 128),
const_mul(x, 129),
const_mul(x, 130),
const_mul(x, 131),
const_mul(x, 132),
@ -1177,7 +1075,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 137),
const_mul(x, 138),
const_mul(x, 139),
const_mul(x, 140),
const_mul(x, 141),
const_mul(x, 142),
@ -1188,7 +1085,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 147),
const_mul(x, 148),
const_mul(x, 149),
const_mul(x, 150),
const_mul(x, 151),
const_mul(x, 152),
@ -1199,7 +1095,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 157),
const_mul(x, 158),
const_mul(x, 159),
const_mul(x, 160),
const_mul(x, 161),
const_mul(x, 162),
@ -1210,7 +1105,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 167),
const_mul(x, 168),
const_mul(x, 169),
const_mul(x, 170),
const_mul(x, 171),
const_mul(x, 172),
@ -1221,7 +1115,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 177),
const_mul(x, 178),
const_mul(x, 179),
const_mul(x, 180),
const_mul(x, 181),
const_mul(x, 182),
@ -1232,7 +1125,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 187),
const_mul(x, 188),
const_mul(x, 189),
const_mul(x, 190),
const_mul(x, 191),
const_mul(x, 192),
@ -1243,7 +1135,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 197),
const_mul(x, 198),
const_mul(x, 199),
const_mul(x, 200),
const_mul(x, 201),
const_mul(x, 202),
@ -1254,7 +1145,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 207),
const_mul(x, 208),
const_mul(x, 209),
const_mul(x, 210),
const_mul(x, 211),
const_mul(x, 212),
@ -1265,7 +1155,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 217),
const_mul(x, 218),
const_mul(x, 219),
const_mul(x, 220),
const_mul(x, 221),
const_mul(x, 222),
@ -1276,7 +1165,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 227),
const_mul(x, 228),
const_mul(x, 229),
const_mul(x, 230),
const_mul(x, 231),
const_mul(x, 232),
@ -1287,7 +1175,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 237),
const_mul(x, 238),
const_mul(x, 239),
const_mul(x, 240),
const_mul(x, 241),
const_mul(x, 242),
@ -1298,43 +1185,36 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 247),
const_mul(x, 248),
const_mul(x, 249),
const_mul(x, 250),
const_mul(x, 251),
const_mul(x, 252),
const_mul(x, 253),
const_mul(x, 254),
const_mul(x, 255),
]
];
}
#[derive(Clone, Debug, PartialEq)]
pub struct Octet {
value: u8
value: u8,
}
impl Octet {
pub fn new(value: u8) -> Octet {
Octet {
value
}
Octet { value }
}
pub fn zero() -> Octet {
Octet {
value: 0
}
Octet { value: 0 }
}
pub fn one() -> Octet {
Octet {
value: 1
}
Octet { value: 1 }
}
pub fn alpha(i: u8) -> Octet {
Octet {
value: OCT_EXP[i as usize]
value: OCT_EXP[i as usize],
}
}
@ -1361,7 +1241,7 @@ impl Add for Octet {
fn add(self, other: Octet) -> Octet {
Octet {
// As defined in section 5.7.2, addition on octets is implemented as bitxor
value: self.value ^ other.value
value: self.value ^ other.value,
}
}
}
@ -1372,7 +1252,7 @@ impl<'a, 'b> Add<&'b Octet> for &'a Octet {
fn add(self, other: &'b Octet) -> Octet {
Octet {
// As defined in section 5.7.2, addition on octets is implemented as bitxor
value: self.value ^ other.value
value: self.value ^ other.value,
}
}
}
@ -1395,7 +1275,7 @@ impl Sub for Octet {
fn sub(self, rhs: Octet) -> Octet {
Octet {
// As defined in section 5.7.2, subtraction on octets is implemented as bitxor
value: self.value ^ rhs.value
value: self.value ^ rhs.value,
}
}
}
@ -1414,18 +1294,15 @@ impl<'a, 'b> Mul<&'b Octet> for &'a Octet {
fn mul(self, other: &'b Octet) -> Octet {
// As defined in section 5.7.2, multiplication is implemented via the tables above
if self.value == 0 || other.value == 0 {
Octet {
value: 0
}
}
else {
Octet { value: 0 }
} else {
unsafe {
// This is safe because value is a u8, and OCT_LOG is 256 elements long
let log_u = *OCT_LOG.get_unchecked(self.value as usize) as usize;
let log_v = *OCT_LOG.get_unchecked(other.value as usize) as usize;
// This is safe because the sum of two values in OCT_LOG cannot exceed 509
Octet {
value: *OCT_EXP.get_unchecked(log_u + log_v)
value: *OCT_EXP.get_unchecked(log_u + log_v),
}
}
}
@ -1447,15 +1324,12 @@ impl<'a, 'b> Div<&'b Octet> for &'a Octet {
assert_ne!(0, rhs.value);
// As defined in section 5.7.2, division is implemented via the tables above
if self.value == 0 {
Octet {
value: 0
}
}
else {
Octet { value: 0 }
} else {
let log_u = OCT_LOG[self.value as usize] as usize;
let log_v = OCT_LOG[rhs.value as usize] as usize;
Octet {
value: OCT_EXP[255 + log_u - log_v]
value: OCT_EXP[255 + log_u - log_v],
}
}
}
@ -1466,10 +1340,10 @@ mod tests {
use rand::Rng;
use crate::octet::Octet;
use crate::octet::OCT_LOG;
use crate::octet::OCT_EXP;
use crate::octet::OCTET_MUL_LOW_BITS;
use crate::octet::OCTET_MUL_HI_BITS;
use crate::octet::OCTET_MUL_LOW_BITS;
use crate::octet::OCT_EXP;
use crate::octet::OCT_LOG;
#[test]
fn multiplication_tables() {
@ -1486,7 +1360,7 @@ mod tests {
#[test]
fn addition() {
let octet = Octet {
value: rand::thread_rng().gen()
value: rand::thread_rng().gen(),
};
// See section 5.7.2. u is its own additive inverse
assert_eq!(Octet::zero(), &octet + &octet);
@ -1495,7 +1369,7 @@ mod tests {
#[test]
fn multiplication_identity() {
let octet = Octet {
value: rand::thread_rng().gen()
value: rand::thread_rng().gen(),
};
assert_eq!(octet, &octet * &Octet::one());
}
@ -1503,7 +1377,7 @@ mod tests {
#[test]
fn multiplicative_inverse() {
let octet = Octet {
value: rand::thread_rng().gen_range(1, 255)
value: rand::thread_rng().gen_range(1, 255),
};
let one = Octet::one();
assert_eq!(one, &octet * &(&one / &octet));
@ -1512,7 +1386,7 @@ mod tests {
#[test]
fn division() {
let octet = Octet {
value: rand::thread_rng().gen_range(1, 255)
value: rand::thread_rng().gen_range(1, 255),
};
assert_eq!(Octet::one(), &octet / &octet);
}
@ -1520,7 +1394,7 @@ mod tests {
#[test]
fn unsafe_mul_gaurantees() {
let max_value = *OCT_LOG.iter().max().unwrap() as usize;
assert!(2*max_value < OCT_EXP.len());
assert!(2 * max_value < OCT_EXP.len());
}
#[test]

@ -1,15 +1,17 @@
use crate::octet::Octet;
use crate::octet::OCTET_MUL;
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
use crate::octet::OCTET_MUL_LOW_BITS;
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
use crate::octet::OCTET_MUL_HI_BITS;
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
use crate::octet::OCTET_MUL_LOW_BITS;
fn mulassign_scalar_fallback(octets: &mut [u8], scalar: &Octet) {
let scalar_index = scalar.byte() as usize;
for i in 0..octets.len() {
unsafe {
*octets.get_unchecked_mut(i) = *OCTET_MUL.get_unchecked(scalar_index).get_unchecked(*octets.get_unchecked(i) as usize);
*octets.get_unchecked_mut(i) = *OCTET_MUL
.get_unchecked(scalar_index)
.get_unchecked(*octets.get_unchecked(i) as usize);
}
}
}
@ -22,11 +24,13 @@ unsafe fn mulassign_scalar_avx2(octets: &mut [u8], scalar: &Octet) {
#[cfg(target_arch = "x86_64")]
use std::arch::x86_64::*;
let low_mask =_mm256_set1_epi8(0x0F);
let low_mask = _mm256_set1_epi8(0x0F);
let hi_mask = _mm256_set1_epi8(0xF0 as u8 as i8);
let self_avx_ptr = octets.as_mut_ptr() as *mut __m256i;
let low_table =_mm256_loadu_si256(OCTET_MUL_LOW_BITS[scalar.byte() as usize].as_ptr() as *const __m256i);
let hi_table =_mm256_loadu_si256(OCTET_MUL_HI_BITS[scalar.byte() as usize].as_ptr() as *const __m256i);
let low_table =
_mm256_loadu_si256(OCTET_MUL_LOW_BITS[scalar.byte() as usize].as_ptr() as *const __m256i);
let hi_table =
_mm256_loadu_si256(OCTET_MUL_HI_BITS[scalar.byte() as usize].as_ptr() as *const __m256i);
for i in 0..(octets.len() / 32) {
let self_vec = _mm256_loadu_si256(self_avx_ptr.add(i));
@ -42,7 +46,9 @@ unsafe fn mulassign_scalar_avx2(octets: &mut [u8], scalar: &Octet) {
let remainder = octets.len() % 32;
let scalar_index = scalar.byte() as usize;
for i in (octets.len() - remainder)..octets.len() {
*octets.get_unchecked_mut(i) = *OCTET_MUL.get_unchecked(scalar_index).get_unchecked(*octets.get_unchecked(i) as usize);
*octets.get_unchecked_mut(i) = *OCTET_MUL
.get_unchecked(scalar_index)
.get_unchecked(*octets.get_unchecked(i) as usize);
}
}
@ -62,8 +68,10 @@ pub fn mulassign_scalar(octets: &mut [u8], scalar: &Octet) {
fn fused_addassign_mul_scalar_fallback(octets: &mut [u8], other: &[u8], scalar: &Octet) {
let scalar_index = scalar.byte() as usize;
for i in 0..octets.len() {
unsafe {
*octets.get_unchecked_mut(i) ^= *OCTET_MUL.get_unchecked(scalar_index).get_unchecked(*other.get_unchecked(i) as usize);
unsafe {
*octets.get_unchecked_mut(i) ^= *OCTET_MUL
.get_unchecked(scalar_index)
.get_unchecked(*other.get_unchecked(i) as usize);
}
}
}
@ -76,12 +84,14 @@ unsafe fn fused_addassign_mul_scalar_avx2(octets: &mut [u8], other: &[u8], scala
#[cfg(target_arch = "x86_64")]
use std::arch::x86_64::*;
let low_mask =_mm256_set1_epi8(0x0F);
let low_mask = _mm256_set1_epi8(0x0F);
let hi_mask = _mm256_set1_epi8(0xF0 as u8 as i8);
let self_avx_ptr = octets.as_mut_ptr() as *mut __m256i;
let other_avx_ptr = other.as_ptr() as *const __m256i;
let low_table =_mm256_loadu_si256(OCTET_MUL_LOW_BITS[scalar.byte() as usize].as_ptr() as *const __m256i);
let hi_table =_mm256_loadu_si256(OCTET_MUL_HI_BITS[scalar.byte() as usize].as_ptr() as *const __m256i);
let low_table =
_mm256_loadu_si256(OCTET_MUL_LOW_BITS[scalar.byte() as usize].as_ptr() as *const __m256i);
let hi_table =
_mm256_loadu_si256(OCTET_MUL_HI_BITS[scalar.byte() as usize].as_ptr() as *const __m256i);
for i in 0..(octets.len() / 32) {
// Multiply by scalar
@ -102,13 +112,23 @@ unsafe fn fused_addassign_mul_scalar_avx2(octets: &mut [u8], other: &[u8], scala
let remainder = octets.len() % 32;
let scalar_index = scalar.byte() as usize;
for i in (octets.len() - remainder)..octets.len() {
*octets.get_unchecked_mut(i) ^= *OCTET_MUL.get_unchecked(scalar_index).get_unchecked(*other.get_unchecked(i) as usize);
*octets.get_unchecked_mut(i) ^= *OCTET_MUL
.get_unchecked(scalar_index)
.get_unchecked(*other.get_unchecked(i) as usize);
}
}
pub fn fused_addassign_mul_scalar(octets: &mut [u8], other: &[u8], scalar: &Octet) {
debug_assert_ne!(*scalar, Octet::one(), "Don't call this with one. Use += instead");
debug_assert_ne!(*scalar, Octet::zero(), "Don't call with zero. It's very inefficient");
debug_assert_ne!(
*scalar,
Octet::one(),
"Don't call this with one. Use += instead"
);
debug_assert_ne!(
*scalar,
Octet::zero(),
"Don't call with zero. It's very inefficient"
);
assert_eq!(octets.len(), other.len());
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
@ -191,7 +211,7 @@ unsafe fn count_ones_and_nonzeros_avx2(octets: &[u8]) -> (usize, usize) {
#[cfg(target_arch = "x86_64")]
use std::arch::x86_64::*;
let avx_ones =_mm256_set1_epi8(1);
let avx_ones = _mm256_set1_epi8(1);
let avx_zeros = _mm256_set1_epi8(0);
let avx_ptr = octets.as_ptr() as *const __m256i;
@ -216,7 +236,7 @@ unsafe fn count_ones_and_nonzeros_avx2(octets: &[u8]) -> (usize, usize) {
let mut remainder = octets.len() % 32;
if remainder >= 16 {
remainder -= 16;
let avx_ones =_mm_set1_epi8(1);
let avx_ones = _mm_set1_epi8(1);
let avx_zeros = _mm_set1_epi8(0);
let avx_ptr = octets.as_ptr().add((octets.len() / 32) * 32) as *const __m128i;

@ -1,5 +1,5 @@
use crate::arraymap::{ArrayMap, BoolArrayMap};
use crate::arraymap::UsizeArrayMap;
use crate::arraymap::{ArrayMap, BoolArrayMap};
use crate::matrix::OctetMatrix;
use crate::octet::Octet;
use crate::octets::count_ones_and_nonzeros;
@ -19,13 +19,17 @@ struct FirstPhaseRowSelectionStats {
hdpc_rows: Vec<bool>,
start_col: usize,
end_col: usize,
start_row: usize
start_row: usize,
}
impl FirstPhaseRowSelectionStats {
#[inline(never)]
#[allow(non_snake_case)]
pub fn new(matrix: &OctetMatrix, end_col: usize, num_source_symbols: u32) -> FirstPhaseRowSelectionStats {
pub fn new(
matrix: &OctetMatrix,
end_col: usize,
num_source_symbols: u32,
) -> FirstPhaseRowSelectionStats {
let S = num_ldpc_symbols(num_source_symbols);
let H = num_hdpc_symbols(num_source_symbols);
@ -43,7 +47,7 @@ impl FirstPhaseRowSelectionStats {
hdpc_rows,
start_col: 0,
end_col,
start_row: 0
start_row: 0,
};
for row in 0..matrix.height() {
@ -67,8 +71,10 @@ impl FirstPhaseRowSelectionStats {
// Recompute all stored statistics for the given row
pub fn recompute_row(&mut self, row: usize, matrix: &OctetMatrix) {
let (ones, non_zero) = count_ones_and_nonzeros(&matrix.get_row(row)[self.start_col..self.end_col]);
self.non_zeros_histogram.decrement(self.non_zeros_per_row.get(row));
let (ones, non_zero) =
count_ones_and_nonzeros(&matrix.get_row(row)[self.start_col..self.end_col]);
self.non_zeros_histogram
.decrement(self.non_zeros_per_row.get(row));
self.non_zeros_histogram.increment(non_zero);
self.non_zeros_per_row.insert(row, non_zero);
self.ones_per_row.insert(row, ones);
@ -87,13 +93,21 @@ impl FirstPhaseRowSelectionStats {
// Set the valid columns, and recalculate statistics
#[inline(never)]
pub fn resize(&mut self, start_row: usize, end_row: usize, start_col: usize, end_col: usize, matrix: &OctetMatrix) {
pub fn resize(
&mut self,
start_row: usize,
end_row: usize,
start_col: usize,
end_col: usize,
matrix: &OctetMatrix,
) {
// Only shrinking is supported
assert!(start_col > self.start_col);
assert!(end_col <= self.end_col);
assert_eq!(self.start_row, start_row - 1);
self.non_zeros_histogram.decrement(self.non_zeros_per_row.get(self.start_row));
self.non_zeros_histogram
.decrement(self.non_zeros_per_row.get(self.start_row));
for row in start_row..end_row {
for col in self.start_col..start_col {
@ -127,7 +141,11 @@ impl FirstPhaseRowSelectionStats {
}
#[inline(never)]
fn first_phase_graph_substep_build_adjacency(&self, rows_with_two_ones: &Vec<usize>, matrix: &OctetMatrix) -> ArrayMap<Vec<(usize, usize)>> {
fn first_phase_graph_substep_build_adjacency(
&self,
rows_with_two_ones: &Vec<usize>,
matrix: &OctetMatrix,
) -> ArrayMap<Vec<(usize, usize)>> {
let mut adjacent_nodes = ArrayMap::new(self.start_col, self.end_col);
for row in rows_with_two_ones.iter() {
@ -157,8 +175,7 @@ impl FirstPhaseRowSelectionStats {
let mut new_nodes = Vec::with_capacity(10);
new_nodes.push((ones[1], *row));
adjacent_nodes.insert(ones[0], new_nodes);
}
else {
} else {
first.unwrap().push((ones[1], *row));
}
let second = adjacent_nodes.get_mut(ones[1]);
@ -166,8 +183,7 @@ impl FirstPhaseRowSelectionStats {
let mut new_nodes = Vec::with_capacity(10);
new_nodes.push((ones[0], *row));
adjacent_nodes.insert(ones[1], new_nodes);
}
else {
} else {
second.unwrap().push((ones[0], *row));
}
}
@ -176,8 +192,15 @@ impl FirstPhaseRowSelectionStats {
}
#[inline(never)]
fn first_phase_graph_substep(&self, start_row: usize, end_row: usize, rows_with_two_ones: &Vec<usize>, matrix: &OctetMatrix) -> usize {
let adjacent_nodes = self.first_phase_graph_substep_build_adjacency(rows_with_two_ones, matrix);
fn first_phase_graph_substep(
&self,
start_row: usize,
end_row: usize,
rows_with_two_ones: &Vec<usize>,
matrix: &OctetMatrix,
) -> usize {
let adjacent_nodes =
self.first_phase_graph_substep_build_adjacency(rows_with_two_ones, matrix);
let mut visited = BoolArrayMap::new(start_row, end_row);
let mut examplar_largest_component_row = None;
@ -214,7 +237,12 @@ impl FirstPhaseRowSelectionStats {
}
#[inline(never)]
fn first_phase_original_degree_substep(&self, start_row: usize, end_row: usize, r: usize) -> usize {
fn first_phase_original_degree_substep(
&self,
start_row: usize,
end_row: usize,
r: usize,
) -> usize {
let mut chosen_hdpc = None;
let mut chosen_hdpc_original_degree = std::usize::MAX;
let mut chosen_non_hdpc = None;
@ -228,8 +256,7 @@ impl FirstPhaseRowSelectionStats {
chosen_hdpc = Some(row);
chosen_hdpc_original_degree = row_original_degree;
}
}
else if row_original_degree < chosen_non_hdpc_original_degree {
} else if row_original_degree < chosen_non_hdpc_original_degree {
chosen_non_hdpc = Some(row);
chosen_non_hdpc_original_degree = row_original_degree;
}
@ -237,8 +264,7 @@ impl FirstPhaseRowSelectionStats {
}
if chosen_non_hdpc != None {
return chosen_non_hdpc.unwrap();
}
else {
} else {
return chosen_hdpc.unwrap();
}
}
@ -246,7 +272,12 @@ impl FirstPhaseRowSelectionStats {
// Verify there there are no non-HPDC rows with exactly two non-zero entries, greater than one
#[inline(never)]
#[cfg(debug_assertions)]
fn first_phase_graph_substep_verify(&self, start_row: usize, end_row: usize, rows_with_two_ones: &Vec<usize>) {
fn first_phase_graph_substep_verify(
&self,
start_row: usize,
end_row: usize,
rows_with_two_ones: &Vec<usize>,
) {
for row in start_row..end_row {
if self.non_zeros_per_row.get(row) == 2 {
assert!(rows_with_two_ones.contains(&row) || self.hdpc_rows[row]);
@ -257,7 +288,12 @@ impl FirstPhaseRowSelectionStats {
// Helper method for decoder phase 1
// selects from [start_row, end_row) reading [start_col, end_col)
// Returns (the chosen row, and "r" number of non-zero values the row has)
pub fn first_phase_selection(&self, start_row: usize, end_row: usize, matrix: &OctetMatrix) -> (Option<usize>, Option<usize>) {
pub fn first_phase_selection(
&self,
start_row: usize,
end_row: usize,
matrix: &OctetMatrix,
) -> (Option<usize>, Option<usize>) {
let mut r = None;
for i in 1..(self.end_col - self.start_col + 1) {
if self.non_zeros_histogram.get(i) > 0 {
@ -288,15 +324,24 @@ impl FirstPhaseRowSelectionStats {
if rows_with_two_ones.len() > 0 {
#[cfg(debug_assertions)]
self.first_phase_graph_substep_verify(start_row, end_row, &rows_with_two_ones);
return (Some(self.first_phase_graph_substep(start_row, end_row, &rows_with_two_ones, matrix)), r);
}
else {
return (
Some(self.first_phase_graph_substep(
start_row,
end_row,
&rows_with_two_ones,
matrix,
)),
r,
);
} else {
// See paragraph starting "If r = 2 and there is no row with exactly 2 ones in V"
return (row_with_two_greater_than_one, r);
}
}
else {
return (Some(self.first_phase_original_degree_substep(start_row, end_row, r.unwrap())), r);
} else {
return (
Some(self.first_phase_original_degree_substep(start_row, end_row, r.unwrap())),
r,
);
}
}
}
@ -316,11 +361,15 @@ pub struct IntermediateSymbolDecoder {
debug_symbol_mul_ops: u32,
debug_symbol_add_ops: u32,
debug_symbol_mul_ops_by_phase: Vec<u32>,
debug_symbol_add_ops_by_phase: Vec<u32>
debug_symbol_add_ops_by_phase: Vec<u32>,
}
impl IntermediateSymbolDecoder {
pub fn new(matrix: OctetMatrix, symbols: Vec<Symbol>, num_source_symbols: u32) -> IntermediateSymbolDecoder {
pub fn new(
matrix: OctetMatrix,
symbols: Vec<Symbol>,
num_source_symbols: u32,
) -> IntermediateSymbolDecoder {
assert!(matrix.width() <= symbols.len());
assert_eq!(matrix.height(), symbols.len());
let mut c = Vec::with_capacity(matrix.width());
@ -345,14 +394,20 @@ impl IntermediateSymbolDecoder {
debug_symbol_mul_ops: 0,
debug_symbol_add_ops: 0,
debug_symbol_mul_ops_by_phase: vec![0; 5],
debug_symbol_add_ops_by_phase: vec![0; 5]
debug_symbol_add_ops_by_phase: vec![0; 5],
}
}
// Returns true iff all elements in A between [start_row, end_row)
// and [start_column, end_column) are zero
#[cfg(debug_assertions)]
fn all_zeroes(&self, start_row: usize, end_row: usize, start_column: usize, end_column: usize) -> bool {
fn all_zeroes(
&self,
start_row: usize,
end_row: usize,
start_column: usize,
end_column: usize,
) -> bool {
for row in start_row..end_row {
for column in start_column..end_column {
if self.A.get(row, column) != Octet::zero() {
@ -372,8 +427,7 @@ impl IntermediateSymbolDecoder {
let dest;
if swapped_columns == 0 {
dest = self.i;
}
else {
} else {
dest = self.A.width() - self.u - swapped_columns;
}
// No need to swap the first i rows, as they are all zero (see submatrix above V)
@ -408,13 +462,18 @@ impl IntermediateSymbolDecoder {
// +-----------+-----------------+---------+
// Figure 6: Submatrices of A in the First Phase
let mut selection_helper = FirstPhaseRowSelectionStats::new(&self.A, self.A.width() - self.u, self.num_source_symbols);
let mut selection_helper = FirstPhaseRowSelectionStats::new(
&self.A,
self.A.width() - self.u,
self.num_source_symbols,
);
while self.i + self.u < self.L {
// Calculate r
// "Let r be the minimum integer such that at least one row of A has
// exactly r nonzeros in V."
let (chosen_row, r) = selection_helper.first_phase_selection(self.i, self.A.height(), &self.A);
let (chosen_row, r) =
selection_helper.first_phase_selection(self.i, self.A.height(), &self.A);
if r == None {
return false;
@ -442,8 +501,7 @@ impl IntermediateSymbolDecoder {
// Hot path for r == 1, since it's very common due to maximum connected
// component selection, and recompute_row() is expensive
selection_helper.eliminate_leading_value(row, &leading_value);
}
else {
} else {
selection_helper.recompute_row(row, &self.A);
}
}
@ -451,7 +509,13 @@ impl IntermediateSymbolDecoder {
self.i += 1;
self.u += r - 1;
selection_helper.resize(self.i, self.A.height(), self.i, self.A.width() - self.u, &self.A);
selection_helper.resize(
self.i,
self.A.height(),
self.i,
self.A.width() - self.u,
&self.A,
);
#[cfg(debug_assertions)]
self.first_phase_verify();
}
@ -468,8 +532,7 @@ impl IntermediateSymbolDecoder {
for col in 0..self.i {
if row == col {
assert_eq!(Octet::one(), self.A.get(row, col));
}
else {
} else {
assert_eq!(Octet::zero(), self.A.get(row, col));
}
}
@ -540,8 +603,7 @@ impl IntermediateSymbolDecoder {
self.debug_symbol_add_ops += 1;
let (dest, temp) = get_both_indices(&mut self.D, self.d[row], self.d[col]);
*dest += temp;
}
else {
} else {
self.debug_symbol_mul_ops += 1;
self.debug_symbol_add_ops += 1;
let (dest, temp) = get_both_indices(&mut self.D, self.d[row], self.d[col]);
@ -568,8 +630,7 @@ impl IntermediateSymbolDecoder {
// The rest of A should be identity matrix
if row == col {
assert_eq!(Octet::one(), self.A.get(row, col));
}
else {
} else {
assert_eq!(Octet::zero(), self.A.get(row, col));
}
}
@ -629,8 +690,7 @@ impl IntermediateSymbolDecoder {
for col in (self.A.width() - self.u)..self.A.width() {
if row == col {
assert_eq!(Octet::one(), self.A.get(row, col));
}
else {
} else {
assert_eq!(Octet::zero(), self.A.get(row, col));
}
}
@ -673,8 +733,7 @@ impl IntermediateSymbolDecoder {
for col in 0..self.A.width() {
if row == col {
assert_eq!(Octet::one(), self.A.get(row, col));
}
else {
} else {
assert_eq!(Octet::zero(), self.A.get(row, col));
}
}
@ -774,8 +833,7 @@ impl IntermediateSymbolDecoder {
self.debug_symbol_add_ops += 1;
let (dest, temp) = get_both_indices(&mut self.D, self.d[iprime], self.d[i]);
*dest += temp;
}
else {
} else {
self.debug_symbol_add_ops += 1;
self.debug_symbol_mul_ops += 1;
let (dest, temp) = get_both_indices(&mut self.D, self.d[iprime], self.d[i]);
@ -797,7 +855,7 @@ impl IntermediateSymbolDecoder {
#[inline(never)]
pub fn execute(&mut self) -> Option<Vec<Symbol>> {
if !self.first_phase() {
return None
return None;
}
if !self.second_phase() {
@ -824,7 +882,11 @@ impl IntermediateSymbolDecoder {
// Fused implementation for self.inverse().mul_symbols(symbols)
// See section 5.4.2.1
pub fn fused_inverse_mul_symbols(matrix: OctetMatrix, symbols: Vec<Symbol>, num_source_symbols: u32) -> Option<Vec<Symbol>> {
pub fn fused_inverse_mul_symbols(
matrix: OctetMatrix,
symbols: Vec<Symbol>,
num_source_symbols: u32,
) -> Option<Vec<Symbol>> {
IntermediateSymbolDecoder::new(matrix, symbols, num_source_symbols).execute()
}
@ -837,15 +899,25 @@ mod tests {
#[test]
fn operations_per_symbol() {
for &(elements, expected_mul_ops, expected_add_ops) in [(10, 35.0, 50.0), (100, 16.0, 35.0)].iter() {
for &(elements, expected_mul_ops, expected_add_ops) in
[(10, 35.0, 50.0), (100, 16.0, 35.0)].iter()
{
let num_symbols = extended_source_block_symbols(elements);
let indices: Vec<u32> = (0..num_symbols).collect();
let a = generate_constraint_matrix(num_symbols, &indices);
let symbols = vec![Symbol::zero(1); a.width()];
let mut decoder = IntermediateSymbolDecoder::new(a, symbols, num_symbols);
decoder.execute();
assert!((decoder.get_symbol_mul_ops() as f64 / num_symbols as f64) < expected_mul_ops, "mul ops per symbol = {}", (decoder.get_symbol_mul_ops() as f64 / num_symbols as f64));
assert!((decoder.get_symbol_add_ops() as f64 / num_symbols as f64) < expected_add_ops, "add ops per symbol = {}", (decoder.get_symbol_add_ops() as f64 / num_symbols as f64));
assert!(
(decoder.get_symbol_mul_ops() as f64 / num_symbols as f64) < expected_mul_ops,
"mul ops per symbol = {}",
(decoder.get_symbol_mul_ops() as f64 / num_symbols as f64)
);
assert!(
(decoder.get_symbol_add_ops() as f64 / num_symbols as f64) < expected_add_ops,
"add ops per symbol = {}",
(decoder.get_symbol_add_ops() as f64 / num_symbols as f64)
);
}
}
}

@ -1,24 +1,22 @@
use std::ops::AddAssign;
use crate::octet::Octet;
use crate::octets::mulassign_scalar;
use crate::octets::fused_addassign_mul_scalar;
use crate::octets::add_assign;
use crate::octets::fused_addassign_mul_scalar;
use crate::octets::mulassign_scalar;
use std::ops::AddAssign;
#[derive(Clone, Debug, PartialEq)]
pub struct Symbol {
value: Vec<u8>
value: Vec<u8>,
}
impl Symbol {
pub fn new(value: Vec<u8>) -> Symbol {
Symbol {
value
}
Symbol { value }
}
pub fn zero(size: usize) -> Symbol {
Symbol {
value: vec![0; size]
value: vec![0; size],
}
}

@ -479,7 +479,8 @@ pub const SYSTEMATIC_INDICES_AND_PARAMETERS: [(u32, u32, u32, u32, u32); 477] =
(54735, 233, 877, 16, 55259),
(55289, 362, 883, 16, 55817),
(55843, 963, 907, 16, 56393),
(56403, 471, 907, 16, 56951)];
(56403, 471, 907, 16, 56951),
];
const P1_TABLE: [(u32, u32); 477] = [
(10, 11),
@ -958,7 +959,8 @@ const P1_TABLE: [(u32, u32); 477] = [
(54735, 373),
(55289, 373),
(55843, 373),
(56403, 379)];
(56403, 379),
];
// Calculates, K', the extended source block size, in symbols, for a given source block size
// See section 5.3.1
@ -1023,9 +1025,9 @@ pub fn num_lt_symbols(source_block_symbols: u32) -> u32 {
// Calculates, L, the number of intermediate symbols, for a given number of source block symbols
// See section 5.3.3.3
pub fn num_intermediate_symbols(source_block_symbols: u32) -> u32 {
extended_source_block_symbols(source_block_symbols) +
num_ldpc_symbols(source_block_symbols) +
num_hdpc_symbols(source_block_symbols)
extended_source_block_symbols(source_block_symbols)
+ num_ldpc_symbols(source_block_symbols)
+ num_hdpc_symbols(source_block_symbols)
}
// Calculates, P, the number of PI symbols, for a given number of source block symbols
@ -1047,9 +1049,9 @@ pub fn calculate_p1(source_block_symbols: u32) -> u32 {
#[cfg(test)]
mod tests {
use crate::systematic_constants::{MAX_SOURCE_SYMBOLS_PER_BLOCK, num_pi_symbols, calculate_p1};
use crate::systematic_constants::num_ldpc_symbols;
use crate::systematic_constants::num_lt_symbols;
use crate::systematic_constants::{calculate_p1, num_pi_symbols, MAX_SOURCE_SYMBOLS_PER_BLOCK};
#[test]
fn all_prime() {
@ -1067,8 +1069,7 @@ mod tests {
while !primal::is_prime(p1 as u64) {
if p1 % 2 == 0 {
p1 += 1;
}
else {
} else {
p1 += 2;
}
}

@ -4,10 +4,9 @@ pub fn get_both_indices<T>(vector: &mut Vec<T>, i: usize, j: usize) -> (&mut T,
debug_assert!(j < vector.len());
if i < j {
let (first, last) = vector.split_at_mut(j);
return (&mut first[i], &mut last[0])
}
else {
return (&mut first[i], &mut last[0]);
} else {
let (first, last) = vector.split_at_mut(i);
return (&mut last[0], &mut first[j])
return (&mut last[0], &mut first[j]);
}
}
}

@ -1,11 +1,11 @@
#[cfg(test)]
mod codec_tests {
use rand::Rng;
use rand::seq::SliceRandom;
use raptorq::SourceBlockEncoder;
use raptorq::SourceBlockDecoder;
use raptorq::Encoder;
use rand::Rng;
use raptorq::Decoder;
use raptorq::Encoder;
use raptorq::SourceBlockDecoder;
use raptorq::SourceBlockEncoder;
#[test]
fn random_erasure() {