mirror of
https://github.com/cberner/raptorq.git
synced 2024-06-28 09:41:41 +00:00
Separate binary and octet matrix classes
This commit is contained in:
parent
dbb0a7f7d3
commit
5d57d3751e
@ -2,13 +2,13 @@ use raptorq::generate_constraint_matrix;
|
||||
use raptorq::IntermediateSymbolDecoder;
|
||||
use raptorq::Octet;
|
||||
use raptorq::Symbol;
|
||||
use raptorq::{extended_source_block_symbols, OctetMatrix, SparseOctetMatrix};
|
||||
use raptorq::{extended_source_block_symbols, BinaryMatrix, SparseBinaryMatrix};
|
||||
|
||||
fn main() {
|
||||
for elements in [10, 100, 1000, 10000, 40000, 56403].iter() {
|
||||
let num_symbols = extended_source_block_symbols(*elements);
|
||||
let indices: Vec<u32> = (0..num_symbols).collect();
|
||||
let (a, hdpc) = generate_constraint_matrix::<SparseOctetMatrix>(num_symbols, &indices);
|
||||
let (a, hdpc) = generate_constraint_matrix::<SparseBinaryMatrix>(num_symbols, &indices);
|
||||
let mut density = 0;
|
||||
let mut row_density = vec![0; a.height()];
|
||||
for i in 0..a.height() {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::base::intermediate_tuple;
|
||||
use crate::matrix::DenseOctetMatrix;
|
||||
use crate::matrix::OctetMatrix;
|
||||
use crate::matrix::BinaryMatrix;
|
||||
use crate::octet::Octet;
|
||||
use crate::octet_matrix::DenseOctetMatrix;
|
||||
use crate::octets::{add_assign, fused_addassign_mul_scalar};
|
||||
use crate::rng::rand;
|
||||
use crate::systematic_constants::extended_source_block_symbols;
|
||||
@ -129,7 +129,7 @@ fn generate_hdpc_rows(Kprime: usize, S: usize, H: usize) -> DenseOctetMatrix {
|
||||
// Returns the HDPC rows separately. These logically replace the rows S..(S + H) of the constraint
|
||||
// matrix. They are returned separately to allow easier optimizations.
|
||||
#[allow(non_snake_case)]
|
||||
pub fn generate_constraint_matrix<T: OctetMatrix>(
|
||||
pub fn generate_constraint_matrix<T: BinaryMatrix>(
|
||||
source_block_symbols: u32,
|
||||
encoded_symbol_indices: &[u32],
|
||||
) -> (T, DenseOctetMatrix) {
|
||||
|
@ -5,9 +5,10 @@ use crate::base::ObjectTransmissionInformation;
|
||||
use crate::constraint_matrix::enc_indices;
|
||||
use crate::constraint_matrix::generate_constraint_matrix;
|
||||
use crate::encoder::SPARSE_MATRIX_THRESHOLD;
|
||||
use crate::matrix::{DenseOctetMatrix, OctetMatrix};
|
||||
use crate::matrix::{BinaryMatrix, DenseBinaryMatrix};
|
||||
use crate::octet_matrix::DenseOctetMatrix;
|
||||
use crate::pi_solver::fused_inverse_mul_symbols;
|
||||
use crate::sparse_matrix::SparseOctetMatrix;
|
||||
use crate::sparse_matrix::SparseBinaryMatrix;
|
||||
use crate::symbol::Symbol;
|
||||
use crate::systematic_constants::num_hdpc_symbols;
|
||||
use crate::systematic_constants::num_ldpc_symbols;
|
||||
@ -146,7 +147,7 @@ impl SourceBlockDecoder {
|
||||
|
||||
fn try_pi_decode(
|
||||
&mut self,
|
||||
constraint_matrix: impl OctetMatrix,
|
||||
constraint_matrix: impl BinaryMatrix,
|
||||
hdpc_rows: DenseOctetMatrix,
|
||||
symbols: Vec<Symbol>,
|
||||
) -> Option<Vec<u8>> {
|
||||
@ -253,13 +254,13 @@ impl SourceBlockDecoder {
|
||||
}
|
||||
|
||||
if extended_source_block_symbols(self.source_block_symbols) >= self.sparse_threshold {
|
||||
let (constraint_matrix, hdpc) = generate_constraint_matrix::<SparseOctetMatrix>(
|
||||
let (constraint_matrix, hdpc) = generate_constraint_matrix::<SparseBinaryMatrix>(
|
||||
self.source_block_symbols,
|
||||
&encoded_indices,
|
||||
);
|
||||
return self.try_pi_decode(constraint_matrix, hdpc, d);
|
||||
} else {
|
||||
let (constraint_matrix, hdpc) = generate_constraint_matrix::<DenseOctetMatrix>(
|
||||
let (constraint_matrix, hdpc) = generate_constraint_matrix::<DenseBinaryMatrix>(
|
||||
self.source_block_symbols,
|
||||
&encoded_indices,
|
||||
);
|
||||
|
@ -3,9 +3,9 @@ use crate::base::partition;
|
||||
use crate::base::EncodingPacket;
|
||||
use crate::base::PayloadId;
|
||||
use crate::constraint_matrix::generate_constraint_matrix;
|
||||
use crate::matrix::DenseOctetMatrix;
|
||||
use crate::matrix::DenseBinaryMatrix;
|
||||
use crate::pi_solver::fused_inverse_mul_symbols;
|
||||
use crate::sparse_matrix::SparseOctetMatrix;
|
||||
use crate::sparse_matrix::SparseBinaryMatrix;
|
||||
use crate::symbol::Symbol;
|
||||
use crate::systematic_constants::extended_source_block_symbols;
|
||||
use crate::systematic_constants::num_hdpc_symbols;
|
||||
@ -190,11 +190,11 @@ fn gen_intermediate_symbols(
|
||||
let indices: Vec<u32> = (0..extended_source_symbols).collect();
|
||||
if extended_source_symbols >= sparse_threshold {
|
||||
let (A, hdpc) =
|
||||
generate_constraint_matrix::<SparseOctetMatrix>(extended_source_symbols, &indices);
|
||||
generate_constraint_matrix::<SparseBinaryMatrix>(extended_source_symbols, &indices);
|
||||
return fused_inverse_mul_symbols(A, hdpc, D, extended_source_symbols).unwrap();
|
||||
} else {
|
||||
let (A, hdpc) =
|
||||
generate_constraint_matrix::<DenseOctetMatrix>(extended_source_symbols, &indices);
|
||||
generate_constraint_matrix::<DenseBinaryMatrix>(extended_source_symbols, &indices);
|
||||
return fused_inverse_mul_symbols(A, hdpc, D, extended_source_symbols).unwrap();
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::octet::Octet;
|
||||
use crate::sparse_vec::{SparseOctetVec, SparseValuelessVec};
|
||||
use crate::sparse_vec::{SparseBinaryVec, SparseValuelessVec};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||
@ -158,7 +158,7 @@ pub struct OctetIter<'a> {
|
||||
end_col: usize,
|
||||
dense_elements: Option<&'a Vec<u8>>,
|
||||
dense_index: usize,
|
||||
sparse_elements: Option<&'a SparseOctetVec>,
|
||||
sparse_elements: Option<&'a SparseBinaryVec>,
|
||||
sparse_index: usize,
|
||||
sparse_physical_col_to_logical: Option<&'a [usize]>,
|
||||
}
|
||||
@ -167,7 +167,7 @@ impl<'a> OctetIter<'a> {
|
||||
pub fn new_sparse(
|
||||
start_col: usize,
|
||||
end_col: usize,
|
||||
sparse_elements: &'a SparseOctetVec,
|
||||
sparse_elements: &'a SparseBinaryVec,
|
||||
sparse_physical_col_to_logical: &'a [usize],
|
||||
) -> OctetIter<'a> {
|
||||
OctetIter {
|
||||
|
@ -8,6 +8,7 @@ mod encoder;
|
||||
mod iterators;
|
||||
mod matrix;
|
||||
mod octet;
|
||||
mod octet_matrix;
|
||||
mod octets;
|
||||
mod pi_solver;
|
||||
mod rng;
|
||||
@ -28,15 +29,15 @@ pub use crate::encoder::SourceBlockEncoder;
|
||||
#[cfg(feature = "benchmarking")]
|
||||
pub use crate::constraint_matrix::generate_constraint_matrix;
|
||||
#[cfg(feature = "benchmarking")]
|
||||
pub use crate::matrix::DenseOctetMatrix;
|
||||
pub use crate::matrix::BinaryMatrix;
|
||||
#[cfg(feature = "benchmarking")]
|
||||
pub use crate::matrix::OctetMatrix;
|
||||
pub use crate::matrix::DenseBinaryMatrix;
|
||||
#[cfg(feature = "benchmarking")]
|
||||
pub use crate::octet::Octet;
|
||||
#[cfg(feature = "benchmarking")]
|
||||
pub use crate::pi_solver::IntermediateSymbolDecoder;
|
||||
#[cfg(feature = "benchmarking")]
|
||||
pub use crate::sparse_matrix::SparseOctetMatrix;
|
||||
pub use crate::sparse_matrix::SparseBinaryMatrix;
|
||||
#[cfg(feature = "benchmarking")]
|
||||
pub use crate::symbol::Symbol;
|
||||
#[cfg(feature = "benchmarking")]
|
||||
|
@ -5,7 +5,7 @@ use crate::octets::{add_assign, count_ones_and_nonzeros, mulassign_scalar};
|
||||
use crate::util::get_both_indices;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub trait OctetMatrix: Clone {
|
||||
pub trait BinaryMatrix: Clone {
|
||||
fn new(height: usize, width: usize, trailing_dense_column_hint: usize) -> Self;
|
||||
|
||||
fn set(&mut self, i: usize, j: usize, value: Octet);
|
||||
@ -58,36 +58,19 @@ pub trait OctetMatrix: Clone {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Serialize, Deserialize, Hash)]
|
||||
pub struct DenseOctetMatrix {
|
||||
pub struct DenseBinaryMatrix {
|
||||
height: usize,
|
||||
width: usize,
|
||||
elements: Vec<Vec<u8>>,
|
||||
}
|
||||
|
||||
impl DenseOctetMatrix {
|
||||
pub fn fma_sub_row(&mut self, row: usize, start_col: usize, scalar: &Octet, other: &[u8]) {
|
||||
if *scalar == Octet::one() {
|
||||
add_assign(
|
||||
&mut self.elements[row][start_col..(start_col + other.len())],
|
||||
other,
|
||||
);
|
||||
} else {
|
||||
fused_addassign_mul_scalar(
|
||||
&mut self.elements[row][start_col..(start_col + other.len())],
|
||||
other,
|
||||
scalar,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl OctetMatrix for DenseOctetMatrix {
|
||||
fn new(height: usize, width: usize, _: usize) -> DenseOctetMatrix {
|
||||
impl BinaryMatrix for DenseBinaryMatrix {
|
||||
fn new(height: usize, width: usize, _: usize) -> DenseBinaryMatrix {
|
||||
let mut elements: Vec<Vec<u8>> = Vec::with_capacity(height);
|
||||
for _ in 0..height {
|
||||
elements.push(vec![0; width]);
|
||||
}
|
||||
DenseOctetMatrix {
|
||||
DenseBinaryMatrix {
|
||||
height,
|
||||
width,
|
||||
elements,
|
||||
@ -159,7 +142,7 @@ impl OctetMatrix for DenseOctetMatrix {
|
||||
|
||||
// other must be a rows x rows matrix
|
||||
// sets self[0..rows][..] = X * self[0..rows][..]
|
||||
fn mul_assign_submatrix(&mut self, other: &DenseOctetMatrix, rows: usize) {
|
||||
fn mul_assign_submatrix(&mut self, other: &DenseBinaryMatrix, rows: usize) {
|
||||
assert_eq!(rows, other.height());
|
||||
assert_eq!(rows, other.width());
|
||||
assert!(rows <= self.height());
|
||||
@ -210,29 +193,29 @@ impl OctetMatrix for DenseOctetMatrix {
|
||||
mod tests {
|
||||
use rand::Rng;
|
||||
|
||||
use crate::matrix::{DenseOctetMatrix, OctetMatrix};
|
||||
use crate::matrix::{BinaryMatrix, DenseBinaryMatrix};
|
||||
use crate::octet::Octet;
|
||||
use crate::sparse_matrix::SparseOctetMatrix;
|
||||
use crate::sparse_matrix::SparseBinaryMatrix;
|
||||
|
||||
fn dense_identity(size: usize) -> DenseOctetMatrix {
|
||||
let mut result = DenseOctetMatrix::new(size, size, 0);
|
||||
fn dense_identity(size: usize) -> DenseBinaryMatrix {
|
||||
let mut result = DenseBinaryMatrix::new(size, size, 0);
|
||||
for i in 0..size {
|
||||
result.set(i, i, Octet::one());
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn sparse_identity(size: usize) -> SparseOctetMatrix {
|
||||
let mut result = SparseOctetMatrix::new(size, size, 0);
|
||||
fn sparse_identity(size: usize) -> SparseBinaryMatrix {
|
||||
let mut result = SparseBinaryMatrix::new(size, size, 0);
|
||||
for i in 0..size {
|
||||
result.set(i, i, Octet::one());
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn rand_dense_and_sparse(size: usize) -> (DenseOctetMatrix, SparseOctetMatrix) {
|
||||
let mut dense = DenseOctetMatrix::new(size, size, 0);
|
||||
let mut sparse = SparseOctetMatrix::new(size, size, 1);
|
||||
fn rand_dense_and_sparse(size: usize) -> (DenseBinaryMatrix, SparseBinaryMatrix) {
|
||||
let mut dense = DenseBinaryMatrix::new(size, size, 0);
|
||||
let mut sparse = SparseBinaryMatrix::new(size, size, 1);
|
||||
// Generate 50% filled random matrices
|
||||
for _ in 0..(size * size / 2) {
|
||||
let i = rand::thread_rng().gen_range(0, size);
|
||||
@ -245,7 +228,7 @@ mod tests {
|
||||
return (dense, sparse);
|
||||
}
|
||||
|
||||
fn assert_matrices_eq<T: OctetMatrix, U: OctetMatrix>(matrix1: &T, matrix2: &U) {
|
||||
fn assert_matrices_eq<T: BinaryMatrix, U: BinaryMatrix>(matrix1: &T, matrix2: &U) {
|
||||
assert_eq!(matrix1.height(), matrix2.height());
|
||||
assert_eq!(matrix1.width(), matrix2.width());
|
||||
for i in 0..matrix1.height() {
|
||||
|
78
src/octet_matrix.rs
Normal file
78
src/octet_matrix.rs
Normal file
@ -0,0 +1,78 @@
|
||||
use crate::octet::Octet;
|
||||
use crate::octets::fused_addassign_mul_scalar;
|
||||
use crate::octets::{add_assign, mulassign_scalar};
|
||||
use crate::util::get_both_indices;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Serialize, Deserialize, Hash)]
|
||||
pub struct DenseOctetMatrix {
|
||||
height: usize,
|
||||
width: usize,
|
||||
elements: Vec<Vec<u8>>,
|
||||
}
|
||||
|
||||
impl DenseOctetMatrix {
|
||||
pub fn new(height: usize, width: usize, _: usize) -> DenseOctetMatrix {
|
||||
let mut elements: Vec<Vec<u8>> = Vec::with_capacity(height);
|
||||
for _ in 0..height {
|
||||
elements.push(vec![0; width]);
|
||||
}
|
||||
DenseOctetMatrix {
|
||||
height,
|
||||
width,
|
||||
elements,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fma_sub_row(&mut self, row: usize, start_col: usize, scalar: &Octet, other: &[u8]) {
|
||||
if *scalar == Octet::one() {
|
||||
add_assign(
|
||||
&mut self.elements[row][start_col..(start_col + other.len())],
|
||||
other,
|
||||
);
|
||||
} else {
|
||||
fused_addassign_mul_scalar(
|
||||
&mut self.elements[row][start_col..(start_col + other.len())],
|
||||
other,
|
||||
scalar,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set(&mut self, i: usize, j: usize, value: Octet) {
|
||||
self.elements[i][j] = value.byte();
|
||||
}
|
||||
|
||||
pub fn height(&self) -> usize {
|
||||
self.height
|
||||
}
|
||||
|
||||
pub fn mul_assign_row(&mut self, row: usize, value: &Octet) {
|
||||
mulassign_scalar(&mut self.elements[row], value);
|
||||
}
|
||||
|
||||
pub fn get(&self, i: usize, j: usize) -> Octet {
|
||||
Octet::new(self.elements[i][j])
|
||||
}
|
||||
|
||||
pub fn swap_rows(&mut self, i: usize, j: usize) {
|
||||
self.elements.swap(i, j);
|
||||
}
|
||||
|
||||
pub fn swap_columns(&mut self, i: usize, j: usize, start_row_hint: usize) {
|
||||
for row in start_row_hint..self.elements.len() {
|
||||
self.elements[row].swap(i, j);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fma_rows(&mut self, dest: usize, multiplicand: usize, scalar: &Octet) {
|
||||
assert_ne!(dest, multiplicand);
|
||||
let (dest_row, temp_row) = get_both_indices(&mut self.elements, dest, multiplicand);
|
||||
|
||||
if *scalar == Octet::one() {
|
||||
add_assign(dest_row, temp_row);
|
||||
} else {
|
||||
fused_addassign_mul_scalar(dest_row, temp_row, scalar);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
use crate::arraymap::UsizeArrayMap;
|
||||
use crate::arraymap::{ArrayMap, BoolArrayMap};
|
||||
use crate::matrix::DenseOctetMatrix;
|
||||
use crate::matrix::OctetMatrix;
|
||||
use crate::matrix::BinaryMatrix;
|
||||
use crate::octet::Octet;
|
||||
use crate::octet_matrix::DenseOctetMatrix;
|
||||
use crate::symbol::Symbol;
|
||||
use crate::systematic_constants::num_hdpc_symbols;
|
||||
use crate::systematic_constants::num_intermediate_symbols;
|
||||
@ -45,7 +45,7 @@ struct FirstPhaseRowSelectionStats {
|
||||
impl FirstPhaseRowSelectionStats {
|
||||
#[inline(never)]
|
||||
#[allow(non_snake_case)]
|
||||
pub fn new<T: OctetMatrix>(matrix: &T, end_col: usize) -> FirstPhaseRowSelectionStats {
|
||||
pub fn new<T: BinaryMatrix>(matrix: &T, end_col: usize) -> FirstPhaseRowSelectionStats {
|
||||
let mut result = FirstPhaseRowSelectionStats {
|
||||
original_degree: UsizeArrayMap::new(0, 0),
|
||||
non_zeros_per_row: UsizeArrayMap::new(0, matrix.height()),
|
||||
@ -87,7 +87,7 @@ impl FirstPhaseRowSelectionStats {
|
||||
}
|
||||
|
||||
// Recompute all stored statistics for the given row
|
||||
pub fn recompute_row<T: OctetMatrix>(&mut self, row: usize, matrix: &T) {
|
||||
pub fn recompute_row<T: BinaryMatrix>(&mut self, row: usize, matrix: &T) {
|
||||
let (ones, non_zero) = matrix.count_ones_and_nonzeros(row, self.start_col, self.end_col);
|
||||
self.rows_with_single_nonzero.retain(|x| *x != row);
|
||||
if non_zero == 1 {
|
||||
@ -119,7 +119,7 @@ impl FirstPhaseRowSelectionStats {
|
||||
// Set the valid columns, and recalculate statistics
|
||||
// All values in column "start_col - 1" in rows start_row..end_row must be zero
|
||||
#[inline(never)]
|
||||
pub fn resize<T: OctetMatrix>(
|
||||
pub fn resize<T: BinaryMatrix>(
|
||||
&mut self,
|
||||
start_row: usize,
|
||||
end_row: usize,
|
||||
@ -162,7 +162,7 @@ impl FirstPhaseRowSelectionStats {
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn first_phase_graph_substep_build_adjacency<T: OctetMatrix>(
|
||||
fn first_phase_graph_substep_build_adjacency<T: BinaryMatrix>(
|
||||
&mut self,
|
||||
rows_with_two_ones: &[usize],
|
||||
matrix: &T,
|
||||
@ -209,7 +209,7 @@ impl FirstPhaseRowSelectionStats {
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn first_phase_graph_substep<T: OctetMatrix>(
|
||||
fn first_phase_graph_substep<T: BinaryMatrix>(
|
||||
&mut self,
|
||||
start_row: usize,
|
||||
end_row: usize,
|
||||
@ -306,7 +306,7 @@ 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<T: OctetMatrix>(
|
||||
pub fn first_phase_selection<T: BinaryMatrix>(
|
||||
&mut self,
|
||||
start_row: usize,
|
||||
end_row: usize,
|
||||
@ -359,7 +359,7 @@ impl FirstPhaseRowSelectionStats {
|
||||
// See section 5.4.2.1
|
||||
#[allow(non_snake_case)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||
pub struct IntermediateSymbolDecoder<T: OctetMatrix> {
|
||||
pub struct IntermediateSymbolDecoder<T: BinaryMatrix> {
|
||||
A: T,
|
||||
// If present, these are treated as replacing the last rows of A
|
||||
// Errata 3 guarantees that these do not need to be included in X
|
||||
@ -381,7 +381,7 @@ pub struct IntermediateSymbolDecoder<T: OctetMatrix> {
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
impl<T: OctetMatrix> IntermediateSymbolDecoder<T> {
|
||||
impl<T: BinaryMatrix> IntermediateSymbolDecoder<T> {
|
||||
pub fn new(
|
||||
matrix: T,
|
||||
hdpc_rows: DenseOctetMatrix,
|
||||
@ -1150,7 +1150,7 @@ impl<T: OctetMatrix> IntermediateSymbolDecoder<T> {
|
||||
|
||||
// Fused implementation for self.inverse().mul_symbols(symbols)
|
||||
// See section 5.4.2.1
|
||||
pub fn fused_inverse_mul_symbols<T: OctetMatrix>(
|
||||
pub fn fused_inverse_mul_symbols<T: BinaryMatrix>(
|
||||
matrix: T,
|
||||
hdpc_rows: DenseOctetMatrix,
|
||||
symbols: Vec<Symbol>,
|
||||
@ -1163,8 +1163,8 @@ pub fn fused_inverse_mul_symbols<T: OctetMatrix>(
|
||||
mod tests {
|
||||
use super::IntermediateSymbolDecoder;
|
||||
use crate::constraint_matrix::generate_constraint_matrix;
|
||||
use crate::matrix::DenseOctetMatrix;
|
||||
use crate::matrix::OctetMatrix;
|
||||
use crate::matrix::BinaryMatrix;
|
||||
use crate::matrix::DenseBinaryMatrix;
|
||||
use crate::symbol::Symbol;
|
||||
use crate::systematic_constants::{
|
||||
extended_source_block_symbols, num_ldpc_symbols, num_lt_symbols,
|
||||
@ -1178,7 +1178,7 @@ mod tests {
|
||||
{
|
||||
let num_symbols = extended_source_block_symbols(elements);
|
||||
let indices: Vec<u32> = (0..num_symbols).collect();
|
||||
let (a, hdpc) = generate_constraint_matrix::<DenseOctetMatrix>(num_symbols, &indices);
|
||||
let (a, hdpc) = generate_constraint_matrix::<DenseBinaryMatrix>(num_symbols, &indices);
|
||||
let symbols = vec![Symbol::zero(1usize); a.width()];
|
||||
let mut decoder = IntermediateSymbolDecoder::new(a, hdpc, symbols, num_symbols);
|
||||
decoder.execute();
|
||||
|
@ -1,9 +1,9 @@
|
||||
use crate::iterators::{BorrowedKeyIter, OctetIter};
|
||||
use crate::matrix::OctetMatrix;
|
||||
use crate::matrix::BinaryMatrix;
|
||||
use crate::octet::Octet;
|
||||
use crate::octets::fused_addassign_mul_scalar;
|
||||
use crate::octets::{add_assign, mulassign_scalar};
|
||||
use crate::sparse_vec::{SparseOctetVec, SparseValuelessVec};
|
||||
use crate::sparse_vec::{SparseBinaryVec, SparseValuelessVec};
|
||||
use crate::util::get_both_indices;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::cmp::min;
|
||||
@ -16,10 +16,10 @@ use std::cmp::min;
|
||||
// | | columns |
|
||||
// |---------------------------------------|
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Serialize, Deserialize, Hash)]
|
||||
pub struct SparseOctetMatrix {
|
||||
pub struct SparseBinaryMatrix {
|
||||
height: usize,
|
||||
width: usize,
|
||||
sparse_elements: Vec<SparseOctetVec>,
|
||||
sparse_elements: Vec<SparseBinaryVec>,
|
||||
// Note these are stored with the right-most element first in the vec.
|
||||
// That is, for a matrix with width 10 and num_dense 3, the last three will be stored in these
|
||||
// Vecs, and will be in the order: [9, 8, 7]
|
||||
@ -37,7 +37,7 @@ pub struct SparseOctetMatrix {
|
||||
num_dense_columns: usize,
|
||||
}
|
||||
|
||||
impl SparseOctetMatrix {
|
||||
impl SparseBinaryMatrix {
|
||||
#[cfg(debug_assertions)]
|
||||
fn verify(&self) {
|
||||
if self.column_index_disabled {
|
||||
@ -53,10 +53,10 @@ impl SparseOctetMatrix {
|
||||
}
|
||||
}
|
||||
|
||||
impl OctetMatrix for SparseOctetMatrix {
|
||||
fn new(height: usize, width: usize, trailing_dense_column_hint: usize) -> SparseOctetMatrix {
|
||||
impl BinaryMatrix for SparseBinaryMatrix {
|
||||
fn new(height: usize, width: usize, trailing_dense_column_hint: usize) -> SparseBinaryMatrix {
|
||||
let mut col_mapping = vec![0; width];
|
||||
let elements = vec![SparseOctetVec::with_capacity(10); height];
|
||||
let elements = vec![SparseBinaryVec::with_capacity(10); height];
|
||||
let mut row_mapping = vec![0; height];
|
||||
#[allow(clippy::needless_range_loop)]
|
||||
for i in 0..height {
|
||||
@ -70,7 +70,7 @@ impl OctetMatrix for SparseOctetMatrix {
|
||||
for i in 0..width {
|
||||
col_mapping[i] = i;
|
||||
}
|
||||
SparseOctetMatrix {
|
||||
SparseBinaryMatrix {
|
||||
height,
|
||||
width,
|
||||
sparse_elements: elements,
|
||||
@ -248,7 +248,7 @@ impl OctetMatrix for SparseOctetMatrix {
|
||||
|
||||
// other must be a rows x rows matrix
|
||||
// sets self[0..rows][..] = X * self[0..rows][..]
|
||||
fn mul_assign_submatrix(&mut self, other: &SparseOctetMatrix, rows: usize) {
|
||||
fn mul_assign_submatrix(&mut self, other: &SparseBinaryMatrix, rows: usize) {
|
||||
assert_eq!(rows, other.height());
|
||||
assert_eq!(rows, other.width());
|
||||
assert!(rows <= self.height());
|
||||
@ -256,7 +256,7 @@ impl OctetMatrix for SparseOctetMatrix {
|
||||
unimplemented!();
|
||||
}
|
||||
// Note: rows are logically indexed
|
||||
let mut temp_sparse = vec![SparseOctetVec::with_capacity(10); rows];
|
||||
let mut temp_sparse = vec![SparseBinaryVec::with_capacity(10); rows];
|
||||
let mut temp_dense = vec![vec![0; self.num_dense_columns]; rows];
|
||||
for row in 0..rows {
|
||||
for (i, scalar) in other.get_row_iter(row, 0, rows) {
|
||||
|
@ -3,14 +3,14 @@ use serde::{Deserialize, Serialize};
|
||||
use std::cmp::Ordering;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Serialize, Deserialize, Hash)]
|
||||
pub struct SparseOctetVec {
|
||||
pub struct SparseBinaryVec {
|
||||
// Kept sorted by the usize (key)
|
||||
elements: Vec<(usize, Octet)>,
|
||||
}
|
||||
|
||||
impl SparseOctetVec {
|
||||
pub fn with_capacity(capacity: usize) -> SparseOctetVec {
|
||||
SparseOctetVec {
|
||||
impl SparseBinaryVec {
|
||||
pub fn with_capacity(capacity: usize) -> SparseBinaryVec {
|
||||
SparseBinaryVec {
|
||||
elements: Vec::with_capacity(capacity),
|
||||
}
|
||||
}
|
||||
@ -30,7 +30,7 @@ impl SparseOctetVec {
|
||||
}
|
||||
|
||||
// Returns a vector of new column indices that this row contains
|
||||
pub fn fma(&mut self, other: &SparseOctetVec, scalar: &Octet) -> Vec<usize> {
|
||||
pub fn fma(&mut self, other: &SparseBinaryVec, scalar: &Octet) -> Vec<usize> {
|
||||
// Fast path for a single value that's being eliminated
|
||||
// TODO: Probably wouldn't need this if we implemented "Furthermore, the row operations
|
||||
// required for the HDPC rows may be performed for all such rows in one
|
||||
@ -198,13 +198,13 @@ mod tests {
|
||||
use rand::Rng;
|
||||
|
||||
use crate::octet::Octet;
|
||||
use crate::sparse_vec::SparseOctetVec;
|
||||
use crate::sparse_vec::SparseBinaryVec;
|
||||
|
||||
#[test]
|
||||
fn sparse_vec() {
|
||||
let size = 100;
|
||||
let mut dense = vec![0; size];
|
||||
let mut sparse = SparseOctetVec::with_capacity(size);
|
||||
let mut sparse = SparseBinaryVec::with_capacity(size);
|
||||
for _ in 0..size {
|
||||
let i = rand::thread_rng().gen_range(0, size);
|
||||
let value = rand::thread_rng().gen();
|
||||
@ -219,7 +219,7 @@ mod tests {
|
||||
#[test]
|
||||
fn sparse_vec_fma() {
|
||||
let mut dense1 = vec![Octet::zero(); 8];
|
||||
let mut sparse1 = SparseOctetVec::with_capacity(8);
|
||||
let mut sparse1 = SparseBinaryVec::with_capacity(8);
|
||||
for i in 0..4 {
|
||||
let value = rand::thread_rng().gen();
|
||||
dense1[i * 2] = Octet::new(value);
|
||||
@ -237,7 +237,7 @@ mod tests {
|
||||
}
|
||||
|
||||
let mut dense2 = vec![Octet::zero(); 8];
|
||||
let mut sparse2 = SparseOctetVec::with_capacity(8);
|
||||
let mut sparse2 = SparseBinaryVec::with_capacity(8);
|
||||
for i in 0..4 {
|
||||
let value = rand::thread_rng().gen();
|
||||
dense2[i] = Octet::new(value);
|
||||
|
Loading…
Reference in New Issue
Block a user