Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Pprof Profiling to Existing Benchmarks #273

Merged
merged 24 commits into from
Nov 11, 2022
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions CONTRIBUTE.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ let sol = decomp

## Benchmarking

### Building Benchmarks
It is important to the project that we have benchmarks in place to evaluate the benefit of performance related changes. To make that process easier we provide some guidelines for writing benchmarks.

1. Test for a variety of sample sizes for most algorithms [1_000, 10_000, 20_000] will be sufficient. For algorithms where it's not too slow, use 100k instead of 20k.
Expand All @@ -169,3 +170,34 @@ It is important to the project that we have benchmarks in place to evaluate the
6. When benchmarking multi-target the target count should be within the following range: [2, 4].
7. In `BenchmarkId` include the values used to parametrize the benchmark. For example if we're doing Pls then we may have something like `Canonical-Nipals-5feats-1_000samples`
8. Pass data as an argument to the function being benched. This will prevent Criterion from including data creation time as part of the benchmark.
9. Add a profiler see [here](https://github.com/tikv/pprof-rs#integrate-with-criterion) for an example on how to do so with pprof, Criterion, and Flamegraph.

### Running Benchmarks
When running benchmarks sometimes you will want to profile the code execution. Assuming you have followed step 9 to add a pprof profiling hook for the linfa-ica package you can run the following to get your profiling results as a flamegraph.

`cargo bench -p linfa-ica --bench fast_ica -q -- --profile-time 30`

If you are interested in running a regular criterion bench for linfa-ica then you can run the following

`cargo bench -p linfa-ica`

### Reporting Benchmark Metrics
It is important that we have a consistent methodology for reporting benchmarks below is a template that should aid reviewers.

```
### Context
In a bullet list describe the following:
1. Run on battery charge or while plugged in
2. Power saving mode
3. If the computer was idle during benchmark
4. If the computer was overheating
5. Hardware specs

### Bench Command Run (Non Blas)
bench results (code format)

### Bench Command Run (Blas)
bench results (code format)
oojo12 marked this conversation as resolved.
Show resolved Hide resolved

[Attached Flamegraphs if profile runs were also done]
```
3 changes: 3 additions & 0 deletions algorithms/linfa-clustering/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ serde_json = "1"
approx = "0.4"
lax = "0.15.0"

[target.'cfg(not(windows))'.dev-dependencies]
pprof = { version = "0.11.0", features = ["flamegraph", "criterion"] }

[[bench]]
name = "k_means"
harness = false
Expand Down
15 changes: 12 additions & 3 deletions algorithms/linfa-clustering/benches/appx_dbscan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use ndarray::Array2;
use ndarray_rand::rand::SeedableRng;
use ndarray_rand::rand_distr::Uniform;
use ndarray_rand::RandomExt;
#[cfg(not(target_os = "windows"))]
use pprof::criterion::{Output, PProfProfiler};
use rand_xoshiro::Xoshiro256Plus;

fn appx_dbscan_bench(c: &mut Criterion) {
Expand Down Expand Up @@ -48,9 +50,16 @@ fn appx_dbscan_bench(c: &mut Criterion) {
benchmark.finish();
}

#[cfg(not(target_os = "windows"))]
criterion_group! {
name = benches;
config = Criterion::default();
name = not_win_benches;
config = Criterion::default().with_profiler(PProfProfiler::new(100, Output::Flamegraph(None)));
targets = appx_dbscan_bench
}
criterion_main!(benches);
#[cfg(target_os = "windows")]
criterion_group!(win_benches, appx_dbscan_bench);

#[cfg(not(target_os = "windows"))]
criterion_main!(not_win_benches);
#[cfg(target_os = "windows")]
criterion_main!(win_benches);
15 changes: 12 additions & 3 deletions algorithms/linfa-clustering/benches/dbscan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use ndarray::Array2;
use ndarray_rand::rand::SeedableRng;
use ndarray_rand::rand_distr::Uniform;
use ndarray_rand::RandomExt;
#[cfg(not(target_os = "windows"))]
use pprof::criterion::{Output, PProfProfiler};
use rand_xoshiro::Xoshiro256Plus;

fn dbscan_bench(c: &mut Criterion) {
Expand Down Expand Up @@ -44,9 +46,16 @@ fn dbscan_bench(c: &mut Criterion) {
benchmark.finish()
}

#[cfg(not(target_os = "windows"))]
criterion_group! {
name = benches;
config = Criterion::default();
name = not_win_benches;
config = Criterion::default().with_profiler(PProfProfiler::new(100, Output::Flamegraph(None)));
targets = dbscan_bench
}
criterion_main!(benches);
#[cfg(target_os = "windows")]
criterion_group!(win_benches, dbscan_bench);

#[cfg(not(target_os = "windows"))]
criterion_main!(not_win_benches);
#[cfg(target_os = "windows")]
criterion_main!(win_benches);
15 changes: 12 additions & 3 deletions algorithms/linfa-clustering/benches/gaussian_mixture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ use ndarray::Array2;
use ndarray_rand::rand::SeedableRng;
use ndarray_rand::rand_distr::Uniform;
use ndarray_rand::RandomExt;
#[cfg(not(target_os = "windows"))]
use pprof::criterion::{Output, PProfProfiler};
use rand_xoshiro::Xoshiro256Plus;

fn gaussian_mixture_bench(c: &mut Criterion) {
Expand Down Expand Up @@ -46,9 +48,16 @@ fn gaussian_mixture_bench(c: &mut Criterion) {
benchmark.finish();
}

#[cfg(not(target_os = "windows"))]
criterion_group! {
name = benches;
config = Criterion::default();
name = not_win_benches;
config = Criterion::default().with_profiler(PProfProfiler::new(100, Output::Flamegraph(None)));
targets = gaussian_mixture_bench
}
criterion_main!(benches);
#[cfg(target_os = "windows")]
criterion_group!(win_benches, gaussian_mixture_bench);
oojo12 marked this conversation as resolved.
Show resolved Hide resolved

#[cfg(target_os = "windows")]
criterion_main!(win_benches);
#[cfg(not(target_os = "windows"))]
criterion_main!(not_win_benches);
20 changes: 17 additions & 3 deletions algorithms/linfa-clustering/benches/k_means.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use linfa_datasets::generate;
use ndarray::Array2;
use ndarray_rand::RandomExt;
use ndarray_rand::{rand::SeedableRng, rand_distr::Uniform};
#[cfg(not(target_os = "windows"))]
use pprof::criterion::{Output, PProfProfiler};
use rand_xoshiro::Xoshiro256Plus;

#[derive(Default)]
Expand Down Expand Up @@ -155,9 +157,21 @@ fn k_means_init_bench(c: &mut Criterion) {
}
}

#[cfg(not(target_os = "windows"))]
criterion_group! {
name = benches;
config = Criterion::default();
name = not_win_benches;
config = Criterion::default().with_profiler(PProfProfiler::new(100, Output::Flamegraph(None)));
targets = k_means_bench, k_means_init_bench, k_means_incr_bench
}
criterion_main!(benches);
#[cfg(target_os = "windows")]
criterion_group!(
win_benches,
k_means_bench,
k_means_init_bench,
k_means_incr_bench
);

#[cfg(not(target_os = "windows"))]
criterion_main!(not_win_benches);
#[cfg(target_os = "windows")]
criterion_main!(win_benches);
3 changes: 3 additions & 0 deletions algorithms/linfa-ica/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ ndarray-npy = { version = "0.8", default-features = false }
paste = "1.0"
criterion = "0.4.0"

[target.'cfg(not(windows))'.dev-dependencies]
pprof = { version = "0.11.0", features = ["flamegraph", "criterion"] }

[[bench]]
name = "fast_ica"
harness = false
18 changes: 16 additions & 2 deletions algorithms/linfa-ica/benches/fast_ica.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use linfa_ica::fast_ica::{FastIca, GFunc};
use ndarray::{array, concatenate};
use ndarray::{Array, Array2, Axis};
use ndarray_rand::{rand::SeedableRng, rand_distr::Uniform, RandomExt};
#[cfg(not(target_os = "windows"))]
use pprof::criterion::{Output, PProfProfiler};
use rand_xoshiro::Xoshiro256Plus;

fn perform_ica(size: usize, gfunc: GFunc) {
Expand Down Expand Up @@ -64,5 +66,17 @@ fn bench(c: &mut Criterion) {
}
}

criterion_group!(benches, bench);
criterion_main!(benches);
#[cfg(not(target_os = "windows"))]
criterion_group! {
name = not_win_benches;
config = Criterion::default().with_profiler(PProfProfiler::new(100, Output::Flamegraph(None)));
targets = bench
}

#[cfg(target_os = "windows")]
criterion_group!(win_benches, bench);

#[cfg(not(target_os = "windows"))]
criterion_main!(not_win_benches);
#[cfg(target_os = "windows")]
criterion_main!(win_benches);
3 changes: 3 additions & 0 deletions algorithms/linfa-linear/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ approx = "0.4"
criterion = "0.4.0"
statrs = "0.16.0"

[target.'cfg(not(windows))'.dev-dependencies]
pprof = { version = "0.11.0", features = ["flamegraph", "criterion"] }

[[bench]]
name = "ols_bench"
harness = false
16 changes: 14 additions & 2 deletions algorithms/linfa-linear/benches/ols_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use linfa::Dataset;
use linfa_datasets::generate::make_dataset;
use linfa_linear::{LinearRegression, TweedieRegressor};
use ndarray::Ix1;
#[cfg(not(target_os = "windows"))]
use pprof::criterion::{Output, PProfProfiler};
use statrs::distribution::{DiscreteUniform, Laplace};

#[allow(unused_must_use)]
Expand Down Expand Up @@ -57,5 +59,15 @@ fn bench(c: &mut Criterion) {
group.finish();
}

criterion_group!(benches, bench);
criterion_main!(benches);
#[cfg(not(target_os = "windows"))]
criterion_group! {
name = not_win_benches;
config = Criterion::default().with_profiler(PProfProfiler::new(100, Output::Flamegraph(None)));
targets = bench
}
#[cfg(not(target_os = "windows"))]
criterion_main!(not_win_benches);
#[cfg(target_os = "windows")]
criterion_group!(win_benches, bench);
#[cfg(target_os = "windows")]
criterion_main!(win_benches);
oojo12 marked this conversation as resolved.
Show resolved Hide resolved
3 changes: 3 additions & 0 deletions algorithms/linfa-pls/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ rand_xoshiro = "0.6"
criterion = "0.4.0"
statrs = "0.16.0"

[target.'cfg(not(windows))'.dev-dependencies]
pprof = { version = "0.11.0", features = ["flamegraph", "criterion"] }

[[bench]]
name = "pls"
harness = false
17 changes: 15 additions & 2 deletions algorithms/linfa-pls/benches/pls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use linfa::Dataset;
use linfa_datasets::generate::make_dataset;
use linfa_pls::Algorithm;
use linfa_pls::{PlsCanonical, PlsCca, PlsRegression};
#[cfg(not(target_os = "windows"))]
use pprof::criterion::{Output, PProfProfiler};
use statrs::distribution::{DiscreteUniform, Laplace};

#[allow(unused_must_use)]
Expand Down Expand Up @@ -86,5 +88,16 @@ fn bench(c: &mut Criterion) {
group.finish();
}

criterion_group!(benches, bench);
criterion_main!(benches);
#[cfg(not(target_os = "windows"))]
criterion_group! {
name = not_win_benches;
config = Criterion::default().with_profiler(PProfProfiler::new(100, Output::Flamegraph(None)));
targets = bench
}
#[cfg(target_os = "windows")]
criterion_group!(win_benches, bench);

#[cfg(not(target_os = "windows"))]
criterion_main!(not_win_benches);
#[cfg(target_os = "windows")]
criterion_main!(win_benches);