Skip to content

Commit

Permalink
simd (avx) - ppp: milestone 1 (#10)
Browse files Browse the repository at this point in the history
* xxxx

* fix/ci: adjust CI uris

* chore: fmt

* x

* 8x

* criterion

* alignment

* more identical checks

* criterion fixes

* fix padding zero calc

* update concourse yml

* enable privileged

* test: add foundation tests for identical results for faster8 methods

* add higher level tests and a few lines of documentation

* make it work for constant input

* x

* fix

* Revert "x"

This reverts commit 0693a3c.

* moar tests, fix borked `fn mul`

* fix addition in avx2

* madness

* more fuzz targets and regressions

* format + remove dbg! statements

* fix clipping

* speedup walsh

* x

* remvoe dbg

* remove more dbg! statements

* fix compile

* clippy

* fix the last remaining bug, let's fuzz

* fuzz it really

* missing file

* add concourse

* more ci

* refactor concourse.yml

* hongg

* hongg

* hongg

* move to hongg

* bumpy

* ci

* hongg 0.5.61

* ci fixins

* fix feature

* minor

* relative dep

* Revert "relative dep"

This reverts commit dfd565f.

* Revert "minor"

This reverts commit 2f67d33.

* just inline

* faster eq

* correction + simplify

* chore; add single pager, make a few things private

* adhoc conversion

* full criterion

* fix/ci: adjust criterion run timeout for PR

* ignore if target_feature not present

* gating, fixed

* f256 dummy 8x (unused, experimental impl anyways)

* chore

* fmt

* mac os x CI failure

* cfg(target_feature)

* fix

* chore: fmt

* lock
  • Loading branch information
drahnr authored Sep 28, 2023
1 parent 3e687ab commit f0ab4e9
Show file tree
Hide file tree
Showing 33 changed files with 2,901 additions and 544 deletions.
880 changes: 783 additions & 97 deletions .concourse.yml

Large diffs are not rendered by default.

44 changes: 22 additions & 22 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ debug = true
[workspace]
resolver = "2"
members = [
"./reed-solomon-tester",
"./reed-solomon-novelpoly",
"./reed-solomon-novelpoly-fuzzit",
"./reed-solomon-benches",
"./reed-solomon-tester",
"./reed-solomon-novelpoly",
"./reed-solomon-novelpoly-fuzzit",
"./reed-solomon-benches",
]
6 changes: 4 additions & 2 deletions reed-solomon-benches/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ edition = "2021"
publish = false

[dependencies]
reed-solomon-erasure = { version = "6.0.0", features = ["simd-accel"], optional = true }
reed-solomon-erasure = { version = "6.0.0", features = [
"simd-accel",
], optional = true }
reed-solomon-novelpoly = { package = "reed-solomon-novelpoly", path = "../reed-solomon-novelpoly" }
reed-solomon-tester = { package = "reed-solomon-tester", path = "../reed-solomon-tester" }

Expand All @@ -28,4 +30,4 @@ harness = false
default = []
novelpoly-cxx = ["reed-solomon-novelpoly/with-alt-cxx-impl"]
naive = ["reed-solomon-erasure"]
upperbounds=["naive"]
upperbounds = ["naive"]
4 changes: 2 additions & 2 deletions reed-solomon-benches/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,6 @@ Currently `honggfuzz` is used.

To build that a `clang` based toolchain is required.

Install `cargo install honggfuzz` and run with
Install `cargo install hongg` and run with

Run the fuzzer with `cargo hfuzz run fuzzit`.
Run the fuzzer with `cargo-hongg run fuzzit`.
92 changes: 90 additions & 2 deletions reed-solomon-benches/benches/criterion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,11 +223,98 @@ pub mod parameterized {
);
}
}

fn encode_guts_add_to_group<M: criterion::measurement::Measurement>(
group: &mut criterion::BenchmarkGroup<M>,
param: impl ToString,
n: usize,
k: usize,
rng: &mut SmallRng,
) {
use reed_solomon_novelpoly::f2e16::Additive;
use rand::Rng;
{
group.bench_with_input(
BenchmarkId::new("novel-poly-guts-encode-faster8", param.to_string()),
&(),
|b, _| {
let dist = rand::distributions::Uniform::new_inclusive(u16::MIN, u16::MAX);
let data = Vec::from_iter(rng.sample_iter::<u16, _>(dist).take(n).map(Additive));
let mut codeword = vec![Additive::zero(); n];
b.iter(|| {
reed_solomon_novelpoly::f2e16::encode_low_faster8(
black_box(&data),
black_box(k),
black_box(&mut codeword[..]),
black_box(n),
);
})
},
);
}
{
group.bench_with_input(BenchmarkId::new("novel-poly-guts-encode-plain", param.to_string()), &(), |b, _| {
let dist = rand::distributions::Uniform::new_inclusive(u16::MIN, u16::MAX);
let data = Vec::from_iter(rng.sample_iter::<u16, _>(dist).take(n).map(Additive));
let mut codeword = vec![Additive::zero(); n];
b.iter(|| {
reed_solomon_novelpoly::f2e16::encode_low_plain(
black_box(&data),
black_box(k),
black_box(&mut codeword[..]),
black_box(n),
);
})
});
}
{
group.bench_with_input(
BenchmarkId::new("novel-poly-encode-sub-faster8", param.to_string()),
&(),
|b, _| {
let dist = rand::distributions::Uniform::new_inclusive(u8::MIN, u8::MAX);
let data = Vec::from_iter(rng.sample_iter::<u8, _>(dist).take(k * 2));
b.iter(|| {
reed_solomon_novelpoly::f2e16::encode_sub_faster8(black_box(&data), black_box(n), black_box(k));
})
},
);
}
{
group.bench_with_input(BenchmarkId::new("novel-poly-encode-sub-plain", param.to_string()), &(), |b, _| {
let dist = rand::distributions::Uniform::new_inclusive(u8::MIN, u8::MAX);
let data = Vec::from_iter(rng.sample_iter::<u8, _>(dist).take(k * 2));
b.iter(|| {
reed_solomon_novelpoly::f2e16::encode_sub_plain(black_box(&data), black_box(n), black_box(k));
})
});
}
}

pub fn bench_encode_guts(crit: &mut Criterion) {
let mut rng = SmallRng::from_seed(SMALL_RNG_SEED);
use reed_solomon_novelpoly::f2e16::{Additive8x};

// factors of 1/2..1/8 are reasonable
for f_exp in 1..3 {
let f = 1 << f_exp;
let mut group = crit.benchmark_group(format!("encode guts n/k={}", f));
for k_exp in 4..10 {
let k = 1 << k_exp;
let n = k * f;
assert!(n > k);
assert_eq!(n % Additive8x::LANE, 0);
assert_eq!(k % Additive8x::LANE, 0);
let param = format!("n={n} k={k} (n/k = {f})");
encode_guts_add_to_group(&mut group, param, n, k, &mut rng);
}
group.finish();
}
}
}

fn parameterized_criterion() -> Criterion {
let crit = Criterion::default().sample_size(10).warm_up_time(Duration::from_millis(100));
crit
Criterion::default().sample_size(10).warm_up_time(Duration::from_millis(100))
}

criterion_group!(
Expand All @@ -238,6 +325,7 @@ targets =
parameterized::bench_reconstruct_2d,
parameterized::bench_encode_fixed_1mb_payload,
parameterized::bench_reconstruct_fixed_1mb_payload,
parameterized::bench_encode_guts,
);

#[cfg(feature = "upperbounds")]
Expand Down
14 changes: 13 additions & 1 deletion reed-solomon-benches/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,25 @@ pub use reed_solomon_novelpoly as novelpoly;
#[cfg(feature = "naive")]
pub mod naive;

pub use reed_solomon_tester::{BYTES, N_SHARDS, TEST_DATA_CHUNK_SIZE};
pub use reed_solomon_tester::{
BYTES, N_SHARDS, TEST_DATA_CHUNK_SIZE, N_SHARDS_JUST_ENOUGH, TEST_DATA_CHUNK_SIZE_JUST_ENOUGH,
};

#[cfg(test)]
mod test {

use super::*;

#[test]
fn novelpoly_roundtrip_tiny() -> std::result::Result<(), novelpoly::Error> {
reed_solomon_tester::roundtrip(
novelpoly::encode::<WrappedShard>,
novelpoly::reconstruct::<WrappedShard>,
&BYTES[..TEST_DATA_CHUNK_SIZE_JUST_ENOUGH],
N_SHARDS_JUST_ENOUGH,
)
}

#[test]
fn novelpoly_roundtrip() -> std::result::Result<(), novelpoly::Error> {
reed_solomon_tester::roundtrip(
Expand Down
19 changes: 17 additions & 2 deletions reed-solomon-novelpoly-fuzzit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ edition = "2021"
publish = false

[dependencies]
honggfuzz = "=0.5.55"
hongg = "=0.5.61"
#hongg = { path = "../../hongg-rs/hongg", package = "hongg", version = "0.5.61" }
arbitrary = { version = "1", features = ["derive"] }
rstester = { path = "../reed-solomon-tester", package = "reed-solomon-tester" }
novelpoly = { path = "../reed-solomon-novelpoly", package = "reed-solomon-novelpoly" }
novelpoly = { path = "../reed-solomon-novelpoly", package = "reed-solomon-novelpoly", features = [
"mock",
] }
rand_chacha = "0.3.0"
rand = "0.8.3"

Expand All @@ -20,3 +23,15 @@ path = "src/reconstruct.rs"
[[bin]]
name = "fuzz_roundtrip"
path = "src/roundtrip.rs"

[[bin]]
name = "fuzz_additive_mpy"
path = "src/additive_mpy.rs"

[[bin]]
name = "fuzz_afft"
path = "src/afft.rs"

[[bin]]
name = "fuzz_inverse_afft"
path = "src/inverse_afft.rs"
55 changes: 55 additions & 0 deletions reed-solomon-novelpoly-fuzzit/src/additive_mpy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#![allow(dead_code)]
#![allow(unused_imports)]

use hongg::fuzz;

use novelpoly::f2e16::*;

use arbitrary::*;

#[derive(Debug, Clone)]
struct FieldMpyParams {
additive: Additive,
mpy: Multiplier,
idx_to_test: usize,
}

#[cfg(target_feature = "avx")]
impl<'a> Arbitrary<'a> for FieldMpyParams {
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
let additive = Additive(u.int_in_range(0..=u16::MAX)?);
let mpy = Multiplier(u.int_in_range(0..=u16::MAX)?);
let idx_to_test = u.choose_index(Additive8x::LANE)?;

Ok(Self { additive, mpy, idx_to_test })
}
}

fn main() {
#[cfg(target_feature = "avx")]
run();

#[cfg(not(target_feature = "avx"))]
panic!("Nothing to do for non avx enabled targets")
}

#[cfg(target_feature = "avx")]
fn run() {
// You have full control over the loop but
// you're supposed to call `fuzz` ad vitam aeternam
loop {
// The fuzz macro gives an arbitrary object (see `arbitrary crate`)
// to a closure-like block of code.
// For performance reasons, it is recommended that you use the native type
// `&[u8]` when possible.
// Here, this slice will contain a "random" quantity of "random" data.
fuzz!(|params: FieldMpyParams| {
let FieldMpyParams { idx_to_test, additive, mpy } = params;
let values = [additive; 8];
let values8x = Additive8x::from(values);
let res_faster8 = values8x.mul(mpy);
let res_plain = values[idx_to_test].mul(mpy);
assert_eq!(res_plain, Additive8x::unpack(&res_faster8)[idx_to_test]);
});
}
}
Loading

0 comments on commit f0ab4e9

Please sign in to comment.