Skip to content

Commit 0a067bd

Browse files
authored
update criterion settings (#276)
* update criterion settings * add benches to all targets * add benchmarks feature * use config for profiling * mention configurable defaults * update to use cargo criterion * add cargo criterion note * note about profiling and windows
1 parent 11c4d5b commit 0a067bd

File tree

22 files changed

+105
-57
lines changed

22 files changed

+105
-57
lines changed

CONTRIBUTE.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,12 @@ It is important to the project that we have benchmarks in place to evaluate the
171171
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`
172172
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.
173173
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.
174+
10. Use the `benchmarks` feature of the linfa crate to configure your benchmark groups and profiler. See the bench in linfa-pls as an example of this. In most cases you can just copy and paste the configuration portions of the code. If other configurations are desired it is still easily customizable and explained in the pprof and Criterion documentations.
175+
176+
Feel free to use the pls bench as a guideline. Note that it uses the config::set_default_benchmark_configs and config::get_default_profiling_configs functions to configure benchmarking and profiling respectively.
174177

175178
### Running Benchmarks
176-
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.
179+
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. Be advised that at the time of writing this profiling will not work on Windows machines.
177180

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

Cargo.toml

+6-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ exclude = [".github/"]
2121

2222
[features]
2323
default = []
24-
24+
benchmarks = ["criterion", "pprof"]
2525
netlib-static = ["blas", "ndarray-linalg/netlib-static"]
2626
netlib-system = ["blas", "ndarray-linalg/netlib-system"]
2727

@@ -45,6 +45,8 @@ ndarray-linalg = { version = "0.15", optional = true }
4545

4646
thiserror = "1.0"
4747

48+
criterion = { version = "0.4.0", optional = true}
49+
4850
[dependencies.serde_crate]
4951
package = "serde"
5052
optional = true
@@ -57,6 +59,9 @@ ndarray-rand = "0.14"
5759
linfa-datasets = { path = "datasets", features = ["winequality", "iris", "diabetes", "generate"] }
5860
statrs = "0.16.0"
5961

62+
[target.'cfg(not(windows))'.dependencies]
63+
pprof = { version = "0.11.0", features = ["flamegraph", "criterion"], optional = true}
64+
6065
[workspace]
6166
members = [
6267
"algorithms/*",

algorithms/linfa-clustering/Cargo.toml

+1-3
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,7 @@ criterion = "0.4.0"
4949
serde_json = "1"
5050
approx = "0.4"
5151
lax = "0.15.0"
52-
53-
[target.'cfg(not(windows))'.dev-dependencies]
54-
pprof = { version = "0.11.0", features = ["flamegraph", "criterion"] }
52+
linfa = { version = "0.6.0", path = "../..", features = ["benchmarks"] }
5553

5654
[[bench]]
5755
name = "k_means"

algorithms/linfa-clustering/benches/appx_dbscan.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@ use criterion::{
22
black_box, criterion_group, criterion_main, AxisScale, BenchmarkId, Criterion,
33
PlotConfiguration,
44
};
5+
use linfa::benchmarks::config;
56
use linfa::traits::Transformer;
67
use linfa_clustering::AppxDbscan;
78
use linfa_datasets::generate;
89
use ndarray::Array2;
910
use ndarray_rand::rand::SeedableRng;
1011
use ndarray_rand::rand_distr::Uniform;
1112
use ndarray_rand::RandomExt;
12-
#[cfg(not(target_os = "windows"))]
13-
use pprof::criterion::{Output, PProfProfiler};
1413
use rand_xoshiro::Xoshiro256Plus;
1514

1615
fn appx_dbscan_bench(c: &mut Criterion) {
@@ -23,7 +22,9 @@ fn appx_dbscan_bench(c: &mut Criterion) {
2322
];
2423

2524
let mut benchmark = c.benchmark_group("appx_dbscan");
25+
config::set_default_benchmark_configs(&mut benchmark);
2626
benchmark.plot_config(PlotConfiguration::default().summary_scale(AxisScale::Logarithmic));
27+
2728
for cluster_size_and_slack in cluster_sizes_and_slacks {
2829
let rng = &mut rng;
2930
benchmark.bench_with_input(
@@ -53,7 +54,7 @@ fn appx_dbscan_bench(c: &mut Criterion) {
5354
#[cfg(not(target_os = "windows"))]
5455
criterion_group! {
5556
name = benches;
56-
config = Criterion::default().with_profiler(PProfProfiler::new(100, Output::Flamegraph(None)));
57+
config = config::get_default_profiling_configs();
5758
targets = appx_dbscan_bench
5859
}
5960
#[cfg(target_os = "windows")]

algorithms/linfa-clustering/benches/dbscan.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,24 @@ use criterion::{
22
black_box, criterion_group, criterion_main, AxisScale, BenchmarkId, Criterion,
33
PlotConfiguration,
44
};
5+
use linfa::benchmarks::config;
56
use linfa::prelude::{ParamGuard, Transformer};
67
use linfa_clustering::Dbscan;
78
use linfa_datasets::generate;
89
use ndarray::Array2;
910
use ndarray_rand::rand::SeedableRng;
1011
use ndarray_rand::rand_distr::Uniform;
1112
use ndarray_rand::RandomExt;
12-
#[cfg(not(target_os = "windows"))]
13-
use pprof::criterion::{Output, PProfProfiler};
1413
use rand_xoshiro::Xoshiro256Plus;
1514

1615
fn dbscan_bench(c: &mut Criterion) {
1716
let mut rng = Xoshiro256Plus::seed_from_u64(40);
1817
let cluster_sizes = vec![10, 100, 1000, 10000];
1918

2019
let mut benchmark = c.benchmark_group("dbscan");
20+
config::set_default_benchmark_configs(&mut benchmark);
2121
benchmark.plot_config(PlotConfiguration::default().summary_scale(AxisScale::Logarithmic));
22+
2223
for cluster_size in cluster_sizes {
2324
let rng = &mut rng;
2425
benchmark.bench_with_input(
@@ -49,7 +50,7 @@ fn dbscan_bench(c: &mut Criterion) {
4950
#[cfg(not(target_os = "windows"))]
5051
criterion_group! {
5152
name = benches;
52-
config = Criterion::default().with_profiler(PProfProfiler::new(100, Output::Flamegraph(None)));
53+
config = config::get_default_profiling_configs();
5354
targets = dbscan_bench
5455
}
5556
#[cfg(target_os = "windows")]

algorithms/linfa-clustering/benches/gaussian_mixture.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use criterion::{
22
black_box, criterion_group, criterion_main, AxisScale, BenchmarkId, Criterion,
33
PlotConfiguration,
44
};
5+
use linfa::benchmarks::config;
56
use linfa::traits::Fit;
67
use linfa::DatasetBase;
78
use linfa_clustering::GaussianMixtureModel;
@@ -10,16 +11,16 @@ use ndarray::Array2;
1011
use ndarray_rand::rand::SeedableRng;
1112
use ndarray_rand::rand_distr::Uniform;
1213
use ndarray_rand::RandomExt;
13-
#[cfg(not(target_os = "windows"))]
14-
use pprof::criterion::{Output, PProfProfiler};
1514
use rand_xoshiro::Xoshiro256Plus;
1615

1716
fn gaussian_mixture_bench(c: &mut Criterion) {
1817
let mut rng = Xoshiro256Plus::seed_from_u64(40);
1918
let cluster_sizes = vec![10, 100, 1000, 10000];
2019

2120
let mut benchmark = c.benchmark_group("gaussian_mixture");
21+
config::set_default_benchmark_configs(&mut benchmark);
2222
benchmark.plot_config(PlotConfiguration::default().summary_scale(AxisScale::Logarithmic));
23+
2324
for cluster_size in cluster_sizes {
2425
let rng = &mut rng;
2526
benchmark.bench_with_input(
@@ -51,7 +52,7 @@ fn gaussian_mixture_bench(c: &mut Criterion) {
5152
#[cfg(not(target_os = "windows"))]
5253
criterion_group! {
5354
name = benches;
54-
config = Criterion::default().with_profiler(PProfProfiler::new(100, Output::Flamegraph(None)));
55+
config = config::get_default_profiling_configs();
5556
targets = gaussian_mixture_bench
5657
}
5758
#[cfg(target_os = "windows")]

algorithms/linfa-clustering/benches/k_means.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@ use criterion::{
22
black_box, criterion_group, criterion_main, AxisScale, BenchmarkId, Criterion,
33
PlotConfiguration,
44
};
5+
use linfa::benchmarks::config;
56
use linfa::prelude::*;
67
use linfa::DatasetBase;
78
use linfa_clustering::{IncrKMeansError, KMeans, KMeansInit};
89
use linfa_datasets::generate;
910
use ndarray::Array2;
1011
use ndarray_rand::RandomExt;
1112
use ndarray_rand::{rand::SeedableRng, rand_distr::Uniform};
12-
#[cfg(not(target_os = "windows"))]
13-
use pprof::criterion::{Output, PProfProfiler};
1413
use rand_xoshiro::Xoshiro256Plus;
1514

1615
#[derive(Default)]
@@ -40,7 +39,9 @@ fn k_means_bench(c: &mut Criterion) {
4039
let n_features = 3;
4140

4241
let mut benchmark = c.benchmark_group("naive_k_means");
42+
config::set_default_benchmark_configs(&mut benchmark);
4343
benchmark.plot_config(PlotConfiguration::default().summary_scale(AxisScale::Logarithmic));
44+
4445
for &(cluster_size, n_clusters) in &cluster_sizes {
4546
let rng = &mut rng;
4647
let centroids =
@@ -73,7 +74,9 @@ fn k_means_incr_bench(c: &mut Criterion) {
7374
let n_features = 3;
7475

7576
let mut benchmark = c.benchmark_group("incremental_k_means");
77+
config::set_default_benchmark_configs(&mut benchmark);
7678
benchmark.plot_config(PlotConfiguration::default().summary_scale(AxisScale::Logarithmic));
79+
7780
for &(cluster_size, n_clusters) in &cluster_sizes {
7881
let rng = &mut rng;
7982
let centroids =
@@ -124,6 +127,7 @@ fn k_means_init_bench(c: &mut Criterion) {
124127
let n_features = 3;
125128

126129
let mut benchmark = c.benchmark_group("k_means_init");
130+
config::set_default_benchmark_configs(&mut benchmark);
127131
benchmark.plot_config(PlotConfiguration::default().summary_scale(AxisScale::Logarithmic));
128132
for init in &init_methods {
129133
for &(cluster_size, n_clusters) in &cluster_sizes {
@@ -160,7 +164,7 @@ fn k_means_init_bench(c: &mut Criterion) {
160164
#[cfg(not(target_os = "windows"))]
161165
criterion_group! {
162166
name = benches;
163-
config = Criterion::default().with_profiler(PProfProfiler::new(100, Output::Flamegraph(None)));
167+
config = config::get_default_profiling_configs();
164168
targets = k_means_bench, k_means_init_bench, k_means_incr_bench
165169
}
166170
#[cfg(target_os = "windows")]

algorithms/linfa-ftrl/Cargo.toml

+1-3
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@ linfa = { version = "0.6.0", path = "../.."}
2828
criterion = "0.4.0"
2929
approx = "0.4"
3030
linfa-datasets = { version = "0.6.0", path = "../../datasets", features = ["winequality"] }
31-
32-
[target.'cfg(not(windows))'.dev-dependencies]
33-
pprof = { version = "0.11.0", features = ["flamegraph", "criterion"] }
31+
linfa = { version = "0.6.0", path = "../..", features = ["benchmarks"] }
3432

3533
[[bench]]
3634
name = "ftrl"

algorithms/linfa-ftrl/benches/ftrl.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
2+
use linfa::benchmarks::config;
23
use linfa::prelude::Predict;
34
use linfa::traits::FitWith;
45
use linfa::{Dataset, DatasetBase, ParamGuard};
@@ -7,13 +8,14 @@ use ndarray::{Array1, Array2};
78
use ndarray_rand::{
89
rand::distributions::Uniform, rand::rngs::SmallRng, rand::SeedableRng, RandomExt,
910
};
10-
#[cfg(not(target_os = "windows"))]
11-
use pprof::criterion::{Output, PProfProfiler};
1211

1312
fn fit_without_prior_model(c: &mut Criterion) {
1413
let mut rng = SmallRng::seed_from_u64(42);
1514
let params = Ftrl::params();
15+
1616
let mut group = c.benchmark_group("Ftrl with no initial model");
17+
config::set_default_benchmark_configs(&mut group);
18+
1719
let sizes: Vec<(usize, usize)> = vec![(10, 1_000), (50, 5_000), (100, 10_000)];
1820

1921
for (nfeatures, nrows) in sizes.iter() {
@@ -34,7 +36,10 @@ fn fit_with_prior_model(c: &mut Criterion) {
3436
let mut rng = SmallRng::seed_from_u64(42);
3537
let params = Ftrl::params();
3638
let valid_params = params.clone().check().unwrap();
39+
3740
let mut group = c.benchmark_group("Ftrl incremental model training");
41+
config::set_default_benchmark_configs(&mut group);
42+
3843
let sizes: Vec<(usize, usize)> = vec![(10, 1_000), (50, 5_000), (100, 10_000)];
3944

4045
for (nfeatures, nrows) in sizes.iter() {
@@ -57,8 +62,11 @@ fn fit_with_prior_model(c: &mut Criterion) {
5762
fn predict(c: &mut Criterion) {
5863
let mut rng = SmallRng::seed_from_u64(42);
5964
let params = Ftrl::params();
65+
6066
let valid_params = params.clone().check().unwrap();
6167
let mut group = c.benchmark_group("Ftrl");
68+
config::set_default_benchmark_configs(&mut group);
69+
6270
let sizes: Vec<(usize, usize)> = vec![(10, 1_000), (50, 5_000), (100, 10_000)];
6371
for (nfeatures, nrows) in sizes.iter() {
6472
let model = Ftrl::new(valid_params.clone(), *nfeatures);
@@ -91,7 +99,7 @@ fn get_dataset(
9199
#[cfg(not(target_os = "windows"))]
92100
criterion_group! {
93101
name = benches;
94-
config = Criterion::default().with_profiler(PProfProfiler::new(100, Output::Flamegraph(None)));
102+
config = config::get_default_profiling_configs();
95103
targets = fit_without_prior_model, fit_with_prior_model, predict
96104
}
97105
#[cfg(target_os = "windows")]

algorithms/linfa-ica/Cargo.toml

+1-3
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,7 @@ linfa = { version = "0.6.0", path = "../.." }
4040
ndarray-npy = { version = "0.8", default-features = false }
4141
paste = "1.0"
4242
criterion = "0.4.0"
43-
44-
[target.'cfg(not(windows))'.dev-dependencies]
45-
pprof = { version = "0.11.0", features = ["flamegraph", "criterion"] }
43+
linfa = { version = "0.6.0", path = "../..", features = ["benchmarks"] }
4644

4745
[[bench]]
4846
name = "fast_ica"

algorithms/linfa-ica/benches/fast_ica.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
2+
use linfa::benchmarks::config;
23
use linfa::{dataset::DatasetBase, traits::Fit};
34
use linfa_ica::fast_ica::{FastIca, GFunc};
45
use ndarray::{array, concatenate};
56
use ndarray::{Array, Array2, Axis};
67
use ndarray_rand::{rand::SeedableRng, rand_distr::Uniform, RandomExt};
7-
#[cfg(not(target_os = "windows"))]
8-
use pprof::criterion::{Output, PProfProfiler};
98
use rand_xoshiro::Xoshiro256Plus;
109

1110
fn perform_ica(size: usize, gfunc: GFunc) {
@@ -55,6 +54,8 @@ fn bench(c: &mut Criterion) {
5554
(GFunc::Exp, "Exp"),
5655
] {
5756
let mut group = c.benchmark_group("Fast ICA");
57+
config::set_default_benchmark_configs(&mut group);
58+
5859
let sizes: [usize; 3] = [1_000, 10_000, 100_000];
5960
for size in sizes {
6061
let input = (size, gfunc);
@@ -69,7 +70,7 @@ fn bench(c: &mut Criterion) {
6970
#[cfg(not(target_os = "windows"))]
7071
criterion_group! {
7172
name = benches;
72-
config = Criterion::default().with_profiler(PProfProfiler::new(100, Output::Flamegraph(None)));
73+
config = config::get_default_profiling_configs();
7374
targets = bench
7475
}
7576
#[cfg(target_os = "windows")]

algorithms/linfa-linear/Cargo.toml

+1-3
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,7 @@ linfa-datasets = { version = "0.6.0", path = "../../datasets", features = ["diab
3535
approx = "0.4"
3636
criterion = "0.4.0"
3737
statrs = "0.16.0"
38-
39-
[target.'cfg(not(windows))'.dev-dependencies]
40-
pprof = { version = "0.11.0", features = ["flamegraph", "criterion"] }
38+
linfa = { version = "0.6.0", path = "../..", features = ["benchmarks"] }
4139

4240
[[bench]]
4341
name = "ols_bench"

algorithms/linfa-linear/benches/ols_bench.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
2+
use linfa::benchmarks::config;
23
use linfa::traits::Fit;
34
use linfa::Dataset;
45
use linfa_datasets::generate::make_dataset;
56
use linfa_linear::{LinearRegression, TweedieRegressor};
67
use ndarray::Ix1;
7-
#[cfg(not(target_os = "windows"))]
8-
use pprof::criterion::{Output, PProfProfiler};
98
use statrs::distribution::{DiscreteUniform, Laplace};
109

1110
#[allow(unused_must_use)]
@@ -22,6 +21,8 @@ fn perform_glm(dataset: &Dataset<f64, f64, Ix1>) {
2221

2322
fn bench(c: &mut Criterion) {
2423
let mut group = c.benchmark_group("Linfa_linear");
24+
config::set_default_benchmark_configs(&mut group);
25+
2526
let params: [(usize, usize); 4] = [(1_000, 5), (10_000, 5), (100_000, 5), (100_000, 10)];
2627

2728
let feat_distr = Laplace::new(0.5, 5.).unwrap();
@@ -62,7 +63,7 @@ fn bench(c: &mut Criterion) {
6263
#[cfg(not(target_os = "windows"))]
6364
criterion_group! {
6465
name = benches;
65-
config = Criterion::default().with_profiler(PProfProfiler::new(100, Output::Flamegraph(None)));
66+
config = config::get_default_profiling_configs();
6667
targets = bench
6768
}
6869
#[cfg(target_os = "windows")]

algorithms/linfa-nn/Cargo.toml

+1-3
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,7 @@ approx = "0.4"
4040
criterion = "0.4.0"
4141
rand_xoshiro = "0.6"
4242
ndarray-rand = "0.14"
43-
44-
[target.'cfg(not(windows))'.dev-dependencies]
45-
pprof = { version = "0.11.0", features = ["flamegraph", "criterion"] }
43+
linfa = { version = "0.6.0", path = "../..", features = ["benchmarks"] }
4644

4745
[[bench]]
4846
name = "nn"

0 commit comments

Comments
 (0)