From 1b14284969624ce22c2700ac56b9c8afa987062c Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Wed, 11 Jun 2025 19:23:32 +0200 Subject: [PATCH 01/12] feat: update and add benchmarks - Fix previous benchmarks - Add new benchmarks --- benchmark/CMakeLists.txt | 9 + benchmark/benchmark_bc.cpp | 84 ++++ benchmark/benchmark_cell.cpp | 187 +++++++++ benchmark/benchmark_cellarray.cpp | 239 ++++++++++++ benchmark/benchmark_celllist_construction.cpp | 197 ++++++++-- benchmark/benchmark_field.cpp | 64 ++++ benchmark/benchmark_interval.cpp | 207 ++++++++++ benchmark/benchmark_level_cell_array.cpp | 308 +++++++++++++++ benchmark/benchmark_mesh.cpp | 292 ++++++++++++++ benchmark/benchmark_search.cpp | 169 +++++++- benchmark/benchmark_set.cpp | 24 +- benchmark/benchmark_stencil.cpp | 40 ++ benchmark/benchmark_subset.cpp | 360 ++++++++++++++++++ 13 files changed, 2133 insertions(+), 47 deletions(-) create mode 100644 benchmark/benchmark_bc.cpp create mode 100644 benchmark/benchmark_cell.cpp create mode 100644 benchmark/benchmark_cellarray.cpp create mode 100644 benchmark/benchmark_field.cpp create mode 100644 benchmark/benchmark_interval.cpp create mode 100644 benchmark/benchmark_level_cell_array.cpp create mode 100644 benchmark/benchmark_mesh.cpp create mode 100644 benchmark/benchmark_stencil.cpp create mode 100644 benchmark/benchmark_subset.cpp diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index 8b1886363..0535a2bc6 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -23,6 +23,15 @@ set(SAMURAI_BENCHMARKS benchmark_celllist_construction.cpp benchmark_search.cpp benchmark_set.cpp + benchmark_interval.cpp + benchmark_cellarray.cpp + benchmark_level_cell_array.cpp + benchmark_mesh.cpp + benchmark_stencil.cpp + benchmark_field.cpp + benchmark_bc.cpp + benchmark_cell.cpp + benchmark_subset.cpp main.cpp ) diff --git a/benchmark/benchmark_bc.cpp b/benchmark/benchmark_bc.cpp new file mode 100644 index 000000000..fbb533347 --- /dev/null +++ b/benchmark/benchmark_bc.cpp @@ -0,0 +1,84 @@ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//////////////////////////////////////////////////////////////////////////////////// +/// utils + +template +auto unitary_box() +{ + using value_t = samurai::default_config::value_t; + using point_t = xt::xtensor_fixed>; + point_t point1; + point_t point2; + if constexpr (dim == 1) + { + point1 = {0}; + point2 = {1}; + } + if constexpr (dim == 2) + { + point1 = {0, 0}; + point2 = {1, 1}; + } + if constexpr (dim == 3) + { + point1 = {0, 0, 0}; + point2 = {1, 1, 1}; + } + + samurai::Box box = samurai::Box(point1, point2); + return box; +} + +// Mesure : Création d'une condition limite scalaire par défaut sur un maillage uniforme +template +void BC_scalar_homogeneous(benchmark::State& state) +{ + samurai::Box box = unitary_box(); + using Config = samurai::UniformConfig; + auto mesh = samurai::UniformMesh(box, state.range(0)); + auto u = make_field("u", mesh); + for (auto _ : state) + { + samurai::make_bc>(u); + } +} + +// Mesure : Création d'une condition limite vectorielle par défaut sur un maillage uniforme +template +void BC_vec_homogeneous(benchmark::State& state) +{ + samurai::Box box = unitary_box(); + using Config = samurai::UniformConfig; + auto mesh = samurai::UniformMesh(box, state.range(0)); + auto u = make_field("u", mesh); + for (auto _ : state) + { + samurai::make_bc>(u); + } +} + +BENCHMARK_TEMPLATE(BC_scalar_homogeneous, 1)->DenseRange(1, 1); +; +// BENCHMARK_TEMPLATE(BC_scalar_homogeneous,2)->DenseRange(1, 1);; // not enough ghost cells +// BENCHMARK_TEMPLATE(BC_scalar_homogeneous,3)->DenseRange(1, 1);; + +BENCHMARK_TEMPLATE(BC_vec_homogeneous, 1)->DenseRange(1, 1); +; diff --git a/benchmark/benchmark_cell.cpp b/benchmark/benchmark_cell.cpp new file mode 100644 index 000000000..08df5b207 --- /dev/null +++ b/benchmark/benchmark_cell.cpp @@ -0,0 +1,187 @@ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +////////////////////////////////////////////////////////////////// +/// utils + +template +auto make_cell() +{ + using value_t = samurai::default_config::value_t; + using point_t = xt::xtensor_fixed>; + point_t indice; + point_t begin; + + if constexpr (dim == 1) + { + indice = {1}; + begin = {0}; + } + if constexpr (dim == 2) + { + indice = {1, 1}; + begin = {0, 0}; + } + if constexpr (dim == 3) + { + indice = {1, 1, 1}; + begin = {0, 0, 0}; + } + + auto indices = xt::xtensor_fixed>(indice); + double scaling_factor = 1.0; + auto c = samurai::Cell>(begin, scaling_factor, 1, indices, 0); + return c; +} + +// Mesure : Construction d'une cellule par défaut +template +void CELL_default(benchmark::State& state) +{ + for (auto _ : state) + { + auto c = samurai::Cell>(); + benchmark::DoNotOptimize(c); + } +} + +// Mesure : Initialisation d'une cellule +template +void CELL_init(benchmark::State& state) +{ + xt::xtensor_fixed> indices; + if constexpr (dim == 1) + { + indices = xt::xtensor_fixed>({1}); + } + else if constexpr (dim == 2) + { + indices = xt::xtensor_fixed>({1, 1}); + } + else if constexpr (dim == 3) + { + indices = xt::xtensor_fixed>({1, 1, 1}); + } + double scaling_factor = 1.0; + for (auto _ : state) + { + if constexpr (dim == 1) + { + auto c = samurai::Cell<1, samurai::Interval>({0}, scaling_factor, 1, indices, 0); + benchmark::DoNotOptimize(c); + } + else if constexpr (dim == 2) + { + auto c = samurai::Cell<2, samurai::Interval>({0, 0}, scaling_factor, 1, indices, 0); + benchmark::DoNotOptimize(c); + } + else if constexpr (dim == 3) + { + auto c = samurai::Cell<3, samurai::Interval>({0, 0, 0}, scaling_factor, 1, indices, 0); + benchmark::DoNotOptimize(c); + } + } +} + +// Mesure : Récupération du centre d'une cellule +template +void CELL_center(benchmark::State& state) +{ + auto c = make_cell(); + for (auto _ : state) + { + auto center = c.center(); + benchmark::DoNotOptimize(center); + } +} + +// Mesure : Récupérayion du centre de la face d'une cellule +template +void CELL_face_center(benchmark::State& state) +{ + auto c = make_cell(); + for (auto _ : state) + { + auto center = c.face_center(); + benchmark::DoNotOptimize(center); + } +} + +// Mesure : Récupération de l'angle d'une cellule +template +void CELL_corner(benchmark::State& state) +{ + auto c = make_cell(); + for (auto _ : state) + { + auto center = c.corner(); + benchmark::DoNotOptimize(center); + } +} + +// Mesure : Test d'égalité entre deux cellules +template +void CELL_equal(benchmark::State& state) +{ + auto c1 = make_cell(); + auto c2 = make_cell(); + for (auto _ : state) + { + auto is_equal = c1 == c2; + benchmark::DoNotOptimize(is_equal); + } +} + +// Mesure : Test d'inégalité entre deux cellules +template +void CELL_different(benchmark::State& state) +{ + auto c1 = make_cell(); + auto c2 = make_cell(); + for (auto _ : state) + { + auto is_equal = c1 != c2; + benchmark::DoNotOptimize(is_equal); + } +} + +BENCHMARK_TEMPLATE(CELL_default, 1); +BENCHMARK_TEMPLATE(CELL_default, 2); +BENCHMARK_TEMPLATE(CELL_default, 3); +BENCHMARK_TEMPLATE(CELL_default, 4); + +BENCHMARK_TEMPLATE(CELL_init, 1); +BENCHMARK_TEMPLATE(CELL_init, 2); +BENCHMARK_TEMPLATE(CELL_init, 3); + +BENCHMARK_TEMPLATE(CELL_center, 1); +BENCHMARK_TEMPLATE(CELL_center, 2); +BENCHMARK_TEMPLATE(CELL_center, 3); + +BENCHMARK_TEMPLATE(CELL_corner, 1); +BENCHMARK_TEMPLATE(CELL_corner, 2); +BENCHMARK_TEMPLATE(CELL_corner, 3); + +BENCHMARK_TEMPLATE(CELL_equal, 1); +BENCHMARK_TEMPLATE(CELL_equal, 2); +BENCHMARK_TEMPLATE(CELL_equal, 3); + +BENCHMARK_TEMPLATE(CELL_different, 1); +BENCHMARK_TEMPLATE(CELL_different, 2); +BENCHMARK_TEMPLATE(CELL_different, 3); diff --git a/benchmark/benchmark_cellarray.cpp b/benchmark/benchmark_cellarray.cpp new file mode 100644 index 000000000..30b37e17d --- /dev/null +++ b/benchmark/benchmark_cellarray.cpp @@ -0,0 +1,239 @@ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// TODO : +// Eviter les maillages aléatoires (biais de répétabilité) + +/////////////////////////////////////////////////////////////////// +// utils + +template +auto cell_list_with_n_intervals(int64_t size) +{ + samurai::CellList cl; + for (int64_t i = 0; i < size; i++) + { + int index = static_cast(i); + cl[0][{}].add_interval({2 * index, 2 * index + 1}); + } + return cl; +} + +template +auto cell_array_with_n_intervals(int64_t size) +{ + auto cl = cell_list_with_n_intervals(size); + samurai::CellArray ca(cl); + return ca; +} + +////////////////////////////////////////////////////////////////// + +// Mesure : Création d'un CellArray par défaut +template +void CELLARRAY_default(benchmark::State& state) +{ + for (auto _ : state) + { + samurai::CellArray ca = samurai::CellArray(); + } +} + +// Mesure : Création d'un CellArray à partir d'un CellList composé de n intervalles sur une dimension +template +void CELLARRAY_cl_ca_multi(benchmark::State& state) +{ + auto cl = cell_list_with_n_intervals(state.range(0)); + for (auto _ : state) + { + samurai::CellArray ca(cl); + benchmark::DoNotOptimize(ca[0]); + } +} + +// Mesure : Récupération du niveau bas d'un CellList +template +void CELLARRAY_min_level(benchmark::State& state) +{ + samurai::CellList cl; + cl[state.range(0)][{}].add_interval({0, 1}); + samurai::CellArray ca(cl); + for (auto _ : state) + { + auto min = ca.min_level(); + benchmark::DoNotOptimize(min); + } +} + +// Mesure : Récupération de l'itérateur begin d'un CellArray +template +void CELLARRAY_begin(benchmark::State& state) +{ + samurai::CellList cl; + cl[state.range(0)][{}].add_interval({0, 1}); + samurai::CellArray ca(cl); + for (auto _ : state) + { + auto begin = ca.begin(); + benchmark::DoNotOptimize(begin); + } +} + +// Mesure : Récupérayion de l'itérateur end d'un CellArray +template +void CELLARRAY_end(benchmark::State& state) +{ + samurai::CellList cl; + cl[state.range(0)][{}].add_interval({0, 1}); + samurai::CellArray ca(cl); + for (auto _ : state) + { + auto end = ca.end(); + benchmark::DoNotOptimize(end); + } +} + +// Mesure : Récupération de l'itérateur reverse begin d'un CellArray +template +void CELLARRAY_rbegin(benchmark::State& state) +{ + samurai::CellList cl; + cl[state.range(0)][{}].add_interval({0, 1}); + samurai::CellArray ca(cl); + for (auto _ : state) + { + auto rbegin = ca.rbegin(); + benchmark::DoNotOptimize(rbegin); + } +} + +// Mesure : Création d'un CellArray 2D à partid d'un CellList composé de n intervalles aléatoires +// Ressemble à CELLARRAY_cl_ca_multi +static void CELLARRAY_CellList2CellArray_2D(benchmark::State& state) +{ + constexpr std::size_t dim = 2; + + std::size_t min_level = 1; + std::size_t max_level = 12; + + samurai::CellList cl; + samurai::CellArray ca; + + for (std::size_t s = 0; s < state.range(0); ++s) + { + auto level = std::experimental::randint(min_level, max_level); + auto x = std::experimental::randint(0, (100 << level) - 1); + auto y = std::experimental::randint(0, (100 << level) - 1); + + cl[level][{y}].add_point(x); + } + + for (auto _ : state) + { + ca = {cl}; + } +} + +BENCHMARK(CELLARRAY_CellList2CellArray_2D)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); + +// Mesure : Création d'un CellArray 3D à partid d'un CellList composé de n intervalles aléatoires +// Ressemble à CELLARRAY_cl_ca_multi +static void CELLARRAY_CellList2CellArray_3D(benchmark::State& state) +{ + constexpr std::size_t dim = 3; + + std::size_t min_level = 1; + std::size_t max_level = 12; + + samurai::CellList cl; + samurai::CellArray ca; + + for (std::size_t s = 0; s < state.range(0); ++s) + { + auto level = std::experimental::randint(min_level, max_level); + auto x = std::experimental::randint(0, (100 << level) - 1); + auto y = std::experimental::randint(0, (100 << level) - 1); + auto z = std::experimental::randint(0, (100 << level) - 1); + + cl[level][{y, z}].add_point(x); + } + + for (auto _ : state) + { + ca = {cl}; + } +} + +BENCHMARK(CELLARRAY_CellList2CellArray_3D)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); + +// Mesure : Comparaison "=" entre deux CellArray aléatoires +// On ne devrait pas utiliser un CellArray aléatoire. +static void CELLARRAY_equal_2D(benchmark::State& state) +{ + constexpr std::size_t dim = 2; + + std::size_t min_level = 1; + std::size_t max_level = 12; + + samurai::CellList cl; + samurai::CellArray ca; + samurai::CellArray ca2; + + for (std::size_t s = 0; s < state.range(0); ++s) + { + auto level = std::experimental::randint(min_level, max_level); + auto x = std::experimental::randint(0, (100 << level) - 1); + auto y = std::experimental::randint(0, (100 << level) - 1); + + cl[level][{y}].add_point(x); + } + ca = {cl}; + ca2 = {cl}; + + for (auto _ : state) + { + auto equal = ca == ca2; + benchmark::DoNotOptimize(equal); + } +} + +BENCHMARK(CELLARRAY_equal_2D)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); + +BENCHMARK_TEMPLATE(CELLARRAY_default, 1, 12); +BENCHMARK_TEMPLATE(CELLARRAY_default, 2, 12); +BENCHMARK_TEMPLATE(CELLARRAY_default, 3, 12); + +BENCHMARK_TEMPLATE(CELLARRAY_cl_ca_multi, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(CELLARRAY_cl_ca_multi, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(CELLARRAY_cl_ca_multi, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); + +BENCHMARK_TEMPLATE(CELLARRAY_min_level, 1)->DenseRange(0, 15); +BENCHMARK_TEMPLATE(CELLARRAY_min_level, 2)->DenseRange(0, 15); +BENCHMARK_TEMPLATE(CELLARRAY_min_level, 3)->DenseRange(0, 15); + +BENCHMARK_TEMPLATE(CELLARRAY_begin, 1)->DenseRange(0, 15); +BENCHMARK_TEMPLATE(CELLARRAY_begin, 2)->DenseRange(0, 15); +BENCHMARK_TEMPLATE(CELLARRAY_begin, 3)->DenseRange(0, 15); + +BENCHMARK_TEMPLATE(CELLARRAY_rbegin, 1)->DenseRange(0, 15); +BENCHMARK_TEMPLATE(CELLARRAY_rbegin, 2)->DenseRange(0, 15); +BENCHMARK_TEMPLATE(CELLARRAY_rbegin, 3)->DenseRange(0, 15); + +BENCHMARK_TEMPLATE(CELLARRAY_end, 1)->DenseRange(0, 15); +BENCHMARK_TEMPLATE(CELLARRAY_end, 2)->DenseRange(0, 15); +BENCHMARK_TEMPLATE(CELLARRAY_end, 3)->DenseRange(0, 15); diff --git a/benchmark/benchmark_celllist_construction.cpp b/benchmark/benchmark_celllist_construction.cpp index 98de53a3d..756fc0a93 100644 --- a/benchmark/benchmark_celllist_construction.cpp +++ b/benchmark/benchmark_celllist_construction.cpp @@ -1,10 +1,97 @@ + #include #include #include #include -static void BM_CellListConstruction_2D(benchmark::State& state) +// Utils : Créer un cell_list composé de n intervales dans une direction +template +auto cell_list_with_n_intervals(int64_t size) +{ + samurai::CellList cl; + for (int64_t i = 0; i < size; i++) + { + int index = static_cast(i); + cl[0][{}].add_interval({2 * index, 2 * index + 1}); + } + return cl; +} + +/////////////////////////////////// + +// Mesure : constructeur CellList par defaut +template +void CELLLIST_default(benchmark::State& state) +{ + for (auto _ : state) + { + samurai::CellList cl = samurai::CellList(); + benchmark::DoNotOptimize(cl); + } +} + +// Mesure : Création d'un CellList construit par n intervales croissants +template +void CELLLIST_cl_add_interval_end(benchmark::State& state) +{ + samurai::CellList cl; + for (auto _ : state) + { + for (int64_t i = 0; i < state.range(0); i++) + { + int index = static_cast(i); + cl[0][{}].add_interval({index, index + 1}); + } + } +} + +// Mesure : Création d'un CellList construit par n intervales décroissants +template +void CELLLIST_cl_add_interval_begin(benchmark::State& state) +{ + samurai::CellList cl; + for (auto _ : state) + { + for (int64_t i = state.range(0); i > 0; i--) + { + int index = static_cast(i); + cl[0][{}].add_interval({index, index + 1}); + } + } +} + +// Mesure : Création d'un CellList composé de n fois le même interval +template +void CELLLIST_cl_add_interval_same(benchmark::State& state) +{ + samurai::CellList cl; + for (auto _ : state) + { + for (int64_t i = state.range(0); i > 0; i--) + { + cl[0][{}].add_interval({0, 1}); + } + } +} + +// Mesure : Création d'un CellList composé de n points (1 seul interval) +template +void CELLLIST_cl_add_point_end(benchmark::State& state) +{ + samurai::CellList cl; + for (auto _ : state) + { + for (int64_t i = 0; i < state.range(0); i++) + { + int index = static_cast(i); + cl[0][{}].add_point({index}); + } + } +} + +// Mesure : Création de n intervales aléatoires - permet de controler le cout du générateur d'aléatoire pour le prochain benchmark +static void CELLLIST_CellListConstruction_2D_rand_control(benchmark::State& state) { constexpr std::size_t dim = 2; @@ -15,6 +102,32 @@ static void BM_CellListConstruction_2D(benchmark::State& state) for (auto _ : state) { + for (std::size_t s = 0; s < state.range(0); ++s) + { + auto level = std::experimental::randint(min_level, max_level); + auto x = std::experimental::randint(0, (100 << level) - 1); + auto y = std::experimental::randint(0, (100 << level) - 1); + + benchmark::DoNotOptimize(level); + benchmark::DoNotOptimize(x); + benchmark::DoNotOptimize(y); + } + } +} + +BENCHMARK(CELLLIST_CellListConstruction_2D_rand_control)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); + +// Mesure : Création d'un CellList composé de n intervales aléatoires en 2D +static void CELLLIST_CellListConstruction_2D(benchmark::State& state) +{ + constexpr std::size_t dim = 2; + + std::size_t min_level = 1; + std::size_t max_level = 12; + + for (auto _ : state) + { + samurai::CellList cl; for (std::size_t s = 0; s < state.range(0); ++s) { auto level = std::experimental::randint(min_level, max_level); @@ -26,19 +139,19 @@ static void BM_CellListConstruction_2D(benchmark::State& state) } } -BENCHMARK(BM_CellListConstruction_2D)->Range(8, 8 << 18); +BENCHMARK(CELLLIST_CellListConstruction_2D)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -static void BM_CellListConstruction_3D(benchmark::State& state) +// Mesure : Création d'un CellList composé de n intervales aléaoires en 3D +static void CELLLIST_CellListConstruction_3D(benchmark::State& state) { constexpr std::size_t dim = 3; std::size_t min_level = 1; std::size_t max_level = 12; - samurai::CellList cl; - for (auto _ : state) { + samurai::CellList cl; for (std::size_t s = 0; s < state.range(0); ++s) { auto level = std::experimental::randint(min_level, max_level); @@ -51,9 +164,16 @@ static void BM_CellListConstruction_3D(benchmark::State& state) } } -BENCHMARK(BM_CellListConstruction_3D)->Range(8, 8 << 18); +BENCHMARK(CELLLIST_CellListConstruction_3D)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -static void BM_CellList2CellArray_2D(benchmark::State& state) +// Not a good way to benchmark +// because the benchmark result depends on the option --benchmark_min_time +// that's because cl is not reinitialized for each state.range measure. +// thus the insertion in std::map is slower because larger and larger +// I provide a fix that puts cl in for state loop. +// We measure the cors of its declaration, you have to substract to have what you really want :-) +/** +static void BM_CellListConstruction_2D(benchmark::State& state) { constexpr std::size_t dim = 2; @@ -61,26 +181,23 @@ static void BM_CellList2CellArray_2D(benchmark::State& state) std::size_t max_level = 12; samurai::CellList cl; - samurai::CellArray ca; - - for (std::size_t s = 0; s < state.range(0); ++s) - { - auto level = std::experimental::randint(min_level, max_level); - auto x = std::experimental::randint(0, (100 << level) - 1); - auto y = std::experimental::randint(0, (100 << level) - 1); - - cl[level][{y}].add_point(x); - } for (auto _ : state) { - ca = {cl}; + for (std::size_t s = 0; s < state.range(0); ++s) + { + auto level = std::experimental::randint(min_level, max_level); + auto x = std::experimental::randint(0, (100 << level) - 1); + auto y = std::experimental::randint(0, (100 << level) - 1); + + cl[level][{y}].add_point(x); + } } } -BENCHMARK(BM_CellList2CellArray_2D)->Range(8, 8 << 18); +BENCHMARK(BM_CellListConstruction_2D)->Range(8, 8 << 18); -static void BM_CellList2CellArray_3D(benchmark::State& state) +static void BM_CellListConstruction_3D(benchmark::State& state) { constexpr std::size_t dim = 3; @@ -88,22 +205,36 @@ static void BM_CellList2CellArray_3D(benchmark::State& state) std::size_t max_level = 12; samurai::CellList cl; - samurai::CellArray ca; - - for (std::size_t s = 0; s < state.range(0); ++s) - { - auto level = std::experimental::randint(min_level, max_level); - auto x = std::experimental::randint(0, (100 << level) - 1); - auto y = std::experimental::randint(0, (100 << level) - 1); - auto z = std::experimental::randint(0, (100 << level) - 1); - - cl[level][{y, z}].add_point(x); - } for (auto _ : state) { - ca = {cl}; + for (std::size_t s = 0; s < state.range(0); ++s) + { + auto level = std::experimental::randint(min_level, max_level); + auto x = std::experimental::randint(0, (100 << level) - 1); + auto y = std::experimental::randint(0, (100 << level) - 1); + auto z = std::experimental::randint(0, (100 << level) - 1); + + cl[level][{y, z}].add_point(x); + } } } -BENCHMARK(BM_CellList2CellArray_3D)->Range(8, 8 << 18); +BENCHMARK(BM_CellListConstruction_3D)->Range(8, 8 << 18); +**/ + +BENCHMARK_TEMPLATE(CELLLIST_default, 1); +BENCHMARK_TEMPLATE(CELLLIST_default, 2); +BENCHMARK_TEMPLATE(CELLLIST_default, 3); + +BENCHMARK_TEMPLATE(CELLLIST_cl_add_interval_end, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(CELLLIST_cl_add_interval_end, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(CELLLIST_cl_add_interval_end, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); + +BENCHMARK_TEMPLATE(CELLLIST_cl_add_interval_begin, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); + +BENCHMARK_TEMPLATE(CELLLIST_cl_add_interval_same, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); + +BENCHMARK_TEMPLATE(CELLLIST_cl_add_point_end, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(CELLLIST_cl_add_point_end, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(CELLLIST_cl_add_point_end, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); diff --git a/benchmark/benchmark_field.cpp b/benchmark/benchmark_field.cpp new file mode 100644 index 000000000..77975b991 --- /dev/null +++ b/benchmark/benchmark_field.cpp @@ -0,0 +1,64 @@ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +template +auto cell_list_with_n_intervals(int64_t size) +{ + samurai::CellList cl; + for (int64_t i = 0; i < size; i++) + { + int index = static_cast(i); + cl[0][{}].add_interval({2 * index, 2 * index + 1}); + } + return cl; +} + +template +void MESH_default(benchmark::State& state) +{ + using Config = samurai::amr::Config; + for (auto _ : state) + { + auto mesh = samurai::amr::Mesh(); + benchmark::DoNotOptimize(mesh); + } +} + +// probablement mal fait puisque add interval au niveau 0 sur des aussi grandes valeurs ... +template +void MESH_cl(benchmark::State& state) +{ + using Config = samurai::amr::Config; + auto cl = cell_list_with_n_intervals(state.range(0)); + auto min_level = 1; + auto max_level = 7; + for (auto _ : state) + { + auto mesh = samurai::amr::Mesh(cl, min_level, max_level); + benchmark::DoNotOptimize(mesh); + } +} + +BENCHMARK_TEMPLATE(MESH_default, 1); +BENCHMARK_TEMPLATE(MESH_default, 2); +BENCHMARK_TEMPLATE(MESH_default, 3); + +BENCHMARK_TEMPLATE(MESH_cl, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(MESH_cl, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 8); +BENCHMARK_TEMPLATE(MESH_cl, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 7); diff --git a/benchmark/benchmark_interval.cpp b/benchmark/benchmark_interval.cpp new file mode 100644 index 000000000..d4d3e2cfd --- /dev/null +++ b/benchmark/benchmark_interval.cpp @@ -0,0 +1,207 @@ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Observation +// - divide is coslty --> verify where and why we use it + +// Mesure : Création d'un intervalle +void INTERVAL_default(benchmark::State& state) +{ + for (auto _ : state) + { + auto interval = samurai::Interval(0, 1, 0); + benchmark::DoNotOptimize(interval); + } +} + +// Mesure : Récupération de la taille d'un intervalle +void INTERVAL_size(benchmark::State& state) +{ + auto interval = samurai::Interval(0, 1, 0); + for (auto _ : state) + { + auto size = interval.size(); + benchmark::DoNotOptimize(size); + } +} + +// Mesure : Test de validité d'un intervalle +void INTERVAL_is_valid(benchmark::State& state) +{ + auto interval = samurai::Interval(0, 1, 0); + for (auto _ : state) + { + auto valid = interval.is_valid(); + benchmark::DoNotOptimize(valid); + } +} + +// Mesure : Test de parité d'un intervalle +void INTERVAL_even_elements(benchmark::State& state) +{ + auto interval = samurai::Interval(0, 1, 0); + for (auto _ : state) + { + auto even = interval.even_elements(); + benchmark::DoNotOptimize(even); + } +} + +// Mesure : Test de parité d'un intervalle +void INTERVAL_odd_elements(benchmark::State& state) +{ + auto interval = samurai::Interval(0, 1, 0); + for (auto _ : state) + { + auto odd = interval.odd_elements(); + benchmark::DoNotOptimize(odd); + } +} + +// Mesure : Multiplication d'un intervalle +void INTERVAL_multiply(benchmark::State& state) +{ + auto interval = samurai::Interval(0, 1, 0); + for (auto _ : state) + { + interval *= 2; + benchmark::DoNotOptimize(interval); + } +} + +// Mesure : divsion d'un intervalle +void INTERVAL_divide(benchmark::State& state) +{ + auto interval = samurai::Interval(0, 1, 0); + for (auto _ : state) + { + interval /= 2; + benchmark::DoNotOptimize(interval); + } +} + +// Here not a redundant test : to be sure that the condition "if start == end" is false. +void INTERVAL_multiply_divide(benchmark::State& state) +{ + auto interval = samurai::Interval(0, 1, 0); + for (auto _ : state) + { + interval *= 2; + interval /= 2; + benchmark::DoNotOptimize(interval); + } +} + +// Mesure : Addition sur un intervalle +void INTERVAL_add(benchmark::State& state) +{ + auto interval = samurai::Interval(0, 1, 0); + for (auto _ : state) + { + interval += 2; + benchmark::DoNotOptimize(interval); + } +} + +// Mesure : Soustraction sur un intervalle +void INTERVAL_sub(benchmark::State& state) +{ + auto interval = samurai::Interval(0, 1, 0); + for (auto _ : state) + { + interval -= 2; + benchmark::DoNotOptimize(interval); + } +} + +// Mesure : Shift sur un intervalle +void INTERVAL_shift_increase(benchmark::State& state) +{ + auto interval = samurai::Interval(0, 1, 0); + for (auto _ : state) + { + interval >>= 2; + benchmark::DoNotOptimize(interval); + } +} + +// Mesure : Shift sur un intervalle +void INTERVAL_shift_decrease(benchmark::State& state) +{ + auto interval = samurai::Interval(0, 1, 0); + for (auto _ : state) + { + interval <<= 2; + benchmark::DoNotOptimize(interval); + } +} + +// Mesure : Test d'egalité d'un intervalle +void INTERVAL_equal(benchmark::State& state) +{ + auto interval1 = samurai::Interval(0, 1, 0); + auto interval2 = samurai::Interval(0, 1, 0); + for (auto _ : state) + { + auto is_equal = interval1 == interval2; + benchmark::DoNotOptimize(is_equal); + } +} + +// Mesure : Test d'inégalité sur un intervalle +void INTERVAL_inequal(benchmark::State& state) +{ + auto interval1 = samurai::Interval(0, 1, 0); + auto interval2 = samurai::Interval(0, 1, 0); + for (auto _ : state) + { + auto is_inequal = interval1 != interval2; + benchmark::DoNotOptimize(is_inequal); + } +} + +// Mesure : Comparaison sur un intervalle +void INTERVAL_less(benchmark::State& state) +{ + auto interval1 = samurai::Interval(0, 1, 0); + auto interval2 = samurai::Interval(0, 1, 0); + for (auto _ : state) + { + auto is_less = interval1 < interval2; + benchmark::DoNotOptimize(is_less); + } +} + +BENCHMARK(INTERVAL_default); +BENCHMARK(INTERVAL_size); +BENCHMARK(INTERVAL_is_valid); +BENCHMARK(INTERVAL_even_elements); +BENCHMARK(INTERVAL_odd_elements); +BENCHMARK(INTERVAL_multiply); +BENCHMARK(INTERVAL_divide); +BENCHMARK(INTERVAL_multiply_divide); + +BENCHMARK(INTERVAL_add); +BENCHMARK(INTERVAL_sub); + +BENCHMARK(INTERVAL_shift_increase); +BENCHMARK(INTERVAL_shift_decrease); + +BENCHMARK(INTERVAL_equal); +BENCHMARK(INTERVAL_inequal); +BENCHMARK(INTERVAL_less); diff --git a/benchmark/benchmark_level_cell_array.cpp b/benchmark/benchmark_level_cell_array.cpp new file mode 100644 index 000000000..3cfa28e86 --- /dev/null +++ b/benchmark/benchmark_level_cell_array.cpp @@ -0,0 +1,308 @@ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Observation : +// Pourquoi -default est plus lent que _empty_lcl_to_lca en 2D/3D ?? +// max_indices et min_indices très couteux : on peut pas faire mieux ?????? + +// Mesure : Constructeur par défaut d'un LevelCellArray +template +void LEVELCELLARRAY_default(benchmark::State& state) +{ + using TInterval = samurai::default_config::interval_t; + for (auto _ : state) + { + auto lcl = samurai::LevelCellArray(); + benchmark::DoNotOptimize(lcl); + } +} + +// Mesure : Constructiuon d'un LevelCellArray à partir d'un LevelCellList vide +template +void LEVELCELLARRAY_empty_lcl_to_lca(benchmark::State& state) +{ + using TInterval = samurai::default_config::interval_t; + samurai::LevelCellList lcl; + for (auto _ : state) + { + auto lca = samurai::LevelCellArray(lcl); + benchmark::DoNotOptimize(lca); + } +} + +// Mesure : Construction d'un LevelCellArray à partir d'un LevelCellList composé de n intervalles dans une direction +template +void LEVELCELLARRAY_lcl_to_lca(benchmark::State& state) +{ + samurai::LevelCellList lcl; + using TInterval = samurai::default_config::interval_t; + for (int64_t i = 0; i < state.range(0); i++) + { + int index = static_cast(i); + lcl[{0}].add_interval({2 * index, 2 * index + 1}); + } + for (auto _ : state) + { + auto lca = samurai::LevelCellArray(lcl); + benchmark::DoNotOptimize(lca); + } +} + +// Mesure : Récupération de l'intérateur begin d'un LevelCellArray +template +void LEVELCELLARRAY_begin(benchmark::State& state) +{ + samurai::LevelCellList lcl; + using TInterval = samurai::default_config::interval_t; + for (int64_t i = 0; i < state.range(0); i++) + { + int index = static_cast(i); + lcl[{0}].add_interval({2 * index, 2 * index + 1}); + } + auto lca = samurai::LevelCellArray(lcl); + for (auto _ : state) + { + auto begin = lca.begin(); + benchmark::DoNotOptimize(begin); + } +} + +// Mesure : Récupération de l'itéateur end d'un LevelCellArray +template +void LEVELCELLARRAY_end(benchmark::State& state) +{ + samurai::LevelCellList lcl; + using TInterval = samurai::default_config::interval_t; + for (int64_t i = 0; i < state.range(0); i++) + { + int index = static_cast(i); + lcl[{0}].add_interval({2 * index, 2 * index + 1}); + } + auto lca = samurai::LevelCellArray(lcl); + for (auto _ : state) + { + auto end = lca.end(); + benchmark::DoNotOptimize(end); + } +} + +// Mesure : Récupération de la taille d'un LevelCellArray +template +void LEVELCELLARRAY_shape(benchmark::State& state) +{ + samurai::LevelCellList lcl; + using TInterval = samurai::default_config::interval_t; + for (int64_t i = 0; i < state.range(0); i++) + { + int index = static_cast(i); + lcl[{0}].add_interval({2 * index, 2 * index + 1}); + } + auto lca = samurai::LevelCellArray(lcl); + for (auto _ : state) + { + auto shape = lca.shape(); + benchmark::DoNotOptimize(shape); + } +} + +// Mesure : Récupération du nombre d'intervalles dans un LevelCellArray +template +void LEVELCELLARRAY_nb_intervals(benchmark::State& state) +{ + samurai::LevelCellList lcl; + using TInterval = samurai::default_config::interval_t; + for (int64_t i = 0; i < state.range(0); i++) + { + int index = static_cast(i); + lcl[{0}].add_interval({2 * index, 2 * index + 1}); + } + auto lca = samurai::LevelCellArray(lcl); + for (auto _ : state) + { + auto nb = lca.nb_intervals(); + benchmark::DoNotOptimize(nb); + } +} + +// Mesure : Récupération du nombre de cellules dans un LevelCellArray +template +void LEVELCELLARRAY_nb_cells(benchmark::State& state) +{ + samurai::LevelCellList lcl; + using TInterval = samurai::default_config::interval_t; + for (int64_t i = 0; i < state.range(0); i++) + { + int index = static_cast(i); + lcl[{0}].add_interval({2 * index, 2 * index + 1}); + } + auto lca = samurai::LevelCellArray(lcl); + for (auto _ : state) + { + auto nb = lca.nb_cells(); + benchmark::DoNotOptimize(nb); + } +} + +// Mesure : Récupération de la taille de cellule d'un LevelCellArray +template +void LEVELCELLARRAY_cell_length(benchmark::State& state) +{ + samurai::LevelCellList lcl; + using TInterval = samurai::default_config::interval_t; + for (int64_t i = 0; i < state.range(0); i++) + { + int index = static_cast(i); + lcl[{0}].add_interval({2 * index, 2 * index + 1}); + } + auto lca = samurai::LevelCellArray(lcl); + for (auto _ : state) + { + auto length = lca.cell_length(); + benchmark::DoNotOptimize(length); + } +} + +// Mesure : Récupération du max d'indice d'un LevelCellArray +template +void LEVELCELLARRAY_max_indices(benchmark::State& state) +{ + samurai::LevelCellList lcl; + using TInterval = samurai::default_config::interval_t; + for (int64_t i = 0; i < state.range(0); i++) + { + int index = static_cast(i); + lcl[{0}].add_interval({2 * index, 2 * index + 1}); + } + auto lca = samurai::LevelCellArray(lcl); + for (auto _ : state) + { + auto max = lca.max_indices(); + benchmark::DoNotOptimize(max); + } +} + +// Mesure : Récupération du min d'indide d'un LevelCellArray +template +void LEVELCELLARRAY_min_indices(benchmark::State& state) +{ + samurai::LevelCellList lcl; + using TInterval = samurai::default_config::interval_t; + for (int64_t i = 0; i < state.range(0); i++) + { + int index = static_cast(i); + lcl[{0}].add_interval({2 * index, 2 * index + 1}); + } + auto lca = samurai::LevelCellArray(lcl); + for (auto _ : state) + { + auto min = lca.min_indices(); + benchmark::DoNotOptimize(min); + } +} + +// Mesure : Récupération du minmax d'indice d'un LevelCellArray +template +void LEVELCELLARRAY_minmax_indices(benchmark::State& state) +{ + samurai::LevelCellList lcl; + using TInterval = samurai::default_config::interval_t; + for (int64_t i = 0; i < state.range(0); i++) + { + int index = static_cast(i); + lcl[{0}].add_interval({2 * index, 2 * index + 1}); + } + auto lca = samurai::LevelCellArray(lcl); + for (auto _ : state) + { + auto minmax = lca.minmax_indices(); + benchmark::DoNotOptimize(minmax); + } +} + +// Mesure : Test d'égalité entre deux LevelCellArrays égaux de taille n +template +void LEVELCELLARRAY_equal(benchmark::State& state) +{ + samurai::LevelCellList lcl; + using TInterval = samurai::default_config::interval_t; + for (int64_t i = 0; i < state.range(0); i++) + { + int index = static_cast(i); + lcl[{0}].add_interval({2 * index, 2 * index + 1}); + } + auto lca = samurai::LevelCellArray(lcl); + auto lca2 = samurai::LevelCellArray(lcl); + for (auto _ : state) + { + auto is_equal = (lca == lca2); + benchmark::DoNotOptimize(is_equal); + } +} + +// manque les LevelCellList_iterator +BENCHMARK_TEMPLATE(LEVELCELLARRAY_default, 1); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_default, 2); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_default, 3); + +BENCHMARK_TEMPLATE(LEVELCELLARRAY_empty_lcl_to_lca, 1); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_empty_lcl_to_lca, 2); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_empty_lcl_to_lca, 3); + +BENCHMARK_TEMPLATE(LEVELCELLARRAY_lcl_to_lca, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_lcl_to_lca, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_lcl_to_lca, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); + +BENCHMARK_TEMPLATE(LEVELCELLARRAY_begin, 1)->RangeMultiplier(2)->Range(1, 1); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_begin, 2)->RangeMultiplier(2)->Range(1, 1); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_begin, 3)->RangeMultiplier(2)->Range(1, 1); + +BENCHMARK_TEMPLATE(LEVELCELLARRAY_end, 1)->RangeMultiplier(2)->Range(1, 1); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_end, 2)->RangeMultiplier(2)->Range(1, 1); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_end, 3)->RangeMultiplier(2)->Range(1, 1); + +BENCHMARK_TEMPLATE(LEVELCELLARRAY_shape, 1)->RangeMultiplier(2)->Range(1, 1); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_shape, 2)->RangeMultiplier(2)->Range(1, 1); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_shape, 3)->RangeMultiplier(2)->Range(1, 1); + +BENCHMARK_TEMPLATE(LEVELCELLARRAY_nb_intervals, 1)->RangeMultiplier(2)->Range(1, 1); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_nb_intervals, 2)->RangeMultiplier(2)->Range(1, 1); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_nb_intervals, 3)->RangeMultiplier(2)->Range(1, 1); + +BENCHMARK_TEMPLATE(LEVELCELLARRAY_nb_cells, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_nb_cells, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_nb_cells, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); + +BENCHMARK_TEMPLATE(LEVELCELLARRAY_cell_length, 1)->RangeMultiplier(2)->Range(1, 1); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_cell_length, 2)->RangeMultiplier(2)->Range(1, 1); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_cell_length, 3)->RangeMultiplier(2)->Range(1, 1); + +BENCHMARK_TEMPLATE(LEVELCELLARRAY_max_indices, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_max_indices, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_max_indices, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); + +BENCHMARK_TEMPLATE(LEVELCELLARRAY_min_indices, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_min_indices, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_min_indices, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); + +BENCHMARK_TEMPLATE(LEVELCELLARRAY_minmax_indices, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_minmax_indices, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_minmax_indices, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); + +BENCHMARK_TEMPLATE(LEVELCELLARRAY_equal, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_equal, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_equal, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); diff --git a/benchmark/benchmark_mesh.cpp b/benchmark/benchmark_mesh.cpp new file mode 100644 index 000000000..1050dd765 --- /dev/null +++ b/benchmark/benchmark_mesh.cpp @@ -0,0 +1,292 @@ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// TODO : + +///////////////////////////////////////////////////////////////////////////// +/// utils +template +auto unitary_box() +{ + using value_t = samurai::default_config::value_t; + using point_t = xt::xtensor_fixed>; + point_t point1; + point_t point2; + if constexpr (dim == 1) + { + point1 = {0}; + point2 = {1}; + } + if constexpr (dim == 2) + { + point1 = {0, 0}; + point2 = {1, 1}; + } + if constexpr (dim == 3) + { + point1 = {0, 0, 0}; + point2 = {1, 1, 1}; + } + + samurai::Box box = samurai::Box(point1, point2); + return box; +} + +//////////////////////////////////////////////////////////////////////////// + +// Mesure : Création d'une Box uniforme de taille de coté n +template +void MESH_uniform(benchmark::State& state) +{ + samurai::Box box = unitary_box(); + using Config = samurai::UniformConfig; + for (auto _ : state) + { + auto mesh = samurai::UniformMesh(box, state.range(0)); + } +} + +// Mesure : Allocation d'un champ 1D d'un maillage uniforme de taille de coté n +template +void FIELD_make_field_uniform(benchmark::State& state) +{ + samurai::Box box = unitary_box(); + using Config = samurai::UniformConfig; + auto mesh = samurai::UniformMesh(box, state.range(0)); + for (auto _ : state) + { + auto u = make_field("u", mesh); + } +} + +// Mesure : Remplissage d'un champ 1D de taille de coté n +template +void FIELD_fill_uniform(benchmark::State& state) +{ + samurai::Box box = unitary_box(); + using Config = samurai::UniformConfig; + auto mesh = samurai::UniformMesh(box, state.range(0)); + auto u = make_field("u", mesh); + for (auto _ : state) + { + u.fill(1.0); + } +} + +// Mesure ; Remplissage d'un champ 1D de taille de coté n ,en utilisant for_each_cell (mesure d'overhead) +template +void FIELD_for_each_cell_uniform(benchmark::State& state) +{ + samurai::Box box = unitary_box(); + using Config = samurai::UniformConfig; + auto mesh = samurai::UniformMesh(box, state.range(0)); + auto u = make_field("u", mesh); + for (auto _ : state) + { + for_each_cell(mesh, + [&](auto cell) + { + u[cell] = 1.0; + }); + } +} + +// Mesure : Test d'égalité entre deux Fields + +// Weird : MPI issue ??? wtf ??? +template +void FIELD_equal_uniform(benchmark::State& state) +{ + samurai::Box box = unitary_box(); + using Config = samurai::UniformConfig; + auto mesh = samurai::UniformMesh(box, state.range(0)); + auto u = make_field("u", mesh); + auto v = make_field("v", mesh); + u.fill(1.0); + for (auto _ : state) + { + v = u; + } +} + +// Mesure : Ajout d'un scalaire à un champ par broadcasting +template +void FIELD_add_scalar_uniform(benchmark::State& state) +{ + samurai::Box box = unitary_box(); + using Config = samurai::UniformConfig; + auto mesh = samurai::UniformMesh(box, state.range(0)); + auto u = make_field("u", mesh); + u.fill(1.0); + auto v = make_field("v", mesh); + for (auto _ : state) + { + v = u + 2.0; + benchmark::DoNotOptimize(v[0]); + } +} + +// Mesure : Ajout d'un scalaire à un champ par "for_each_cell" +template +void FIELD_add_scalar_for_each_cell_uniform(benchmark::State& state) +{ + samurai::Box box = unitary_box(); + using Config = samurai::UniformConfig; + auto mesh = samurai::UniformMesh(box, state.range(0)); + auto u = make_field("u", mesh); + u.fill(1.0); + auto v = make_field("v", mesh); + for (auto _ : state) + { + for_each_cell(mesh, + [&](auto cell) + { + v[cell] = u[cell] + 1.0; + }); + } +} + +/** +template +void FIELD_add_scalar_for_each_interval_uniform(benchmark::State& state){ + samurai::Box box = unitary_box() ; + using Config = samurai::UniformConfig ; + auto mesh = samurai::UniformMesh(box, state.range(0)); + auto u = make_field("u", mesh) ; + u.fill(1.0) ; + auto v = make_field("v", mesh) ; + v.fill(0.0) ; + for (auto _ : state){ + for_each_cell(mesh, + [&](std::size_t level, const auto& interval, const auto& index) + { + auto i = interval ; + auto j = index[0] ; + v(level, i, j) = 1.0 ; + }); + } +} +**/ + +// Mesure : Somme de deux champs 1D par "for_each_cell" +template +void FIELD_add_for_each_cell_uniform(benchmark::State& state) +{ + samurai::Box box = unitary_box(); + using Config = samurai::UniformConfig; + auto mesh = samurai::UniformMesh(box, state.range(0)); + auto u = make_field("u", mesh); + u.fill(1.0); + auto v = make_field("v", mesh); + v.fill(1.0); + auto w = make_field("w", mesh); + w.fill(1.0); + + for (auto _ : state) + { + for_each_cell(mesh, + [&](auto cell) + { + w[cell] = u[cell] + v[cell]; + }); + } +} + +// Mesure : Somme de deux champs 1D par expression +template +void FIELD_add_uniform(benchmark::State& state) +{ + samurai::Box box = unitary_box(); + using Config = samurai::UniformConfig; + auto mesh = samurai::UniformMesh(box, state.range(0)); + auto u = make_field("u", mesh); + u.fill(1.0); + auto v = make_field("v", mesh); + v.fill(1.0); + auto w = make_field("w", mesh); + w.fill(0.0); + for (auto _ : state) + { + w = u + v; + benchmark::DoNotOptimize(w[0]); + } +} + +BENCHMARK_TEMPLATE(MESH_uniform, 1)->DenseRange(1, 16); +; +BENCHMARK_TEMPLATE(MESH_uniform, 2)->DenseRange(1, 14); +; +BENCHMARK_TEMPLATE(MESH_uniform, 3)->DenseRange(1, 9); +; + +BENCHMARK_TEMPLATE(FIELD_make_field_uniform, 1)->DenseRange(1, 16); +; +BENCHMARK_TEMPLATE(FIELD_make_field_uniform, 2)->DenseRange(1, 12); +; +BENCHMARK_TEMPLATE(FIELD_make_field_uniform, 3)->DenseRange(1, 7); +; + +BENCHMARK_TEMPLATE(FIELD_fill_uniform, 1)->DenseRange(1, 16); +; +BENCHMARK_TEMPLATE(FIELD_fill_uniform, 2)->DenseRange(1, 12); +; +BENCHMARK_TEMPLATE(FIELD_fill_uniform, 3)->DenseRange(1, 7); +; + +BENCHMARK_TEMPLATE(FIELD_for_each_cell_uniform, 1)->DenseRange(1, 16); +; +BENCHMARK_TEMPLATE(FIELD_for_each_cell_uniform, 2)->DenseRange(1, 12); +; +BENCHMARK_TEMPLATE(FIELD_for_each_cell_uniform, 3)->DenseRange(1, 7); +; + +BENCHMARK_TEMPLATE(FIELD_equal_uniform, 1)->DenseRange(1, 16); +; +BENCHMARK_TEMPLATE(FIELD_equal_uniform, 2)->DenseRange(1, 12); +; +BENCHMARK_TEMPLATE(FIELD_equal_uniform, 3)->DenseRange(1, 7); +; + +BENCHMARK_TEMPLATE(FIELD_add_scalar_uniform, 1)->DenseRange(1, 16); +; +BENCHMARK_TEMPLATE(FIELD_add_scalar_uniform, 2)->DenseRange(1, 12); +; +BENCHMARK_TEMPLATE(FIELD_add_scalar_uniform, 3)->DenseRange(1, 7); +; + +BENCHMARK_TEMPLATE(FIELD_add_scalar_for_each_cell_uniform, 1)->DenseRange(1, 16); +; +BENCHMARK_TEMPLATE(FIELD_add_scalar_for_each_cell_uniform, 2)->DenseRange(1, 12); +; +BENCHMARK_TEMPLATE(FIELD_add_scalar_for_each_cell_uniform, 3)->DenseRange(1, 7); +; + +BENCHMARK_TEMPLATE(FIELD_add_uniform, 1)->DenseRange(1, 16); +; +BENCHMARK_TEMPLATE(FIELD_add_uniform, 2)->DenseRange(1, 12); +; +BENCHMARK_TEMPLATE(FIELD_add_uniform, 3)->DenseRange(1, 7); +; + +BENCHMARK_TEMPLATE(FIELD_add_for_each_cell_uniform, 1)->DenseRange(1, 16); +; +BENCHMARK_TEMPLATE(FIELD_add_for_each_cell_uniform, 2)->DenseRange(1, 12); +; +BENCHMARK_TEMPLATE(FIELD_add_for_each_cell_uniform, 3)->DenseRange(1, 7); +; diff --git a/benchmark/benchmark_search.cpp b/benchmark/benchmark_search.cpp index 9bb3cbf67..01ce6f1a7 100644 --- a/benchmark/benchmark_search.cpp +++ b/benchmark/benchmark_search.cpp @@ -1,3 +1,4 @@ + #include #include #include @@ -10,6 +11,159 @@ #include #include +//////////////////////////////////////////////////////////// +/// utils + +template +auto cell_list_with_n_intervals(int64_t size) +{ + samurai::CellList cl; + for (int64_t i = 0; i < size; i++) + { + int index = static_cast(i); + cl[0][{}].add_interval({2 * index, 2 * index + 1}); + } + return cl; +} + +template +auto cell_array_with_n_intervals(int64_t size) +{ + auto cl = cell_list_with_n_intervals(size); + samurai::CellArray ca(cl); + return ca; +} + +////////////////////////////////////////////////////////////// + +// Mesure : recherche du premier intervale dans un CellArray nD de taille n en utilisant find +template +void FIND_find_begin(benchmark::State& state) +{ + auto ca = cell_array_with_n_intervals(state.range(0)); + xt::xtensor_fixed> coord = {0}; + for (auto _ : state) + { + auto index = find(ca[0], coord); + benchmark::DoNotOptimize(index); + } +} + +// Mesure : recherche du dernier intervale dans un CellArray nD de taille n en utilisant find +template +void FIND_find_end(benchmark::State& state) +{ + auto ca = cell_array_with_n_intervals(state.range(0)); + xt::xtensor_fixed> coord = {2 * state.range(0)}; + for (auto _ : state) + { + auto index = find(ca[0], coord); + benchmark::DoNotOptimize(index); + } +} + +// Mesure : recherche du premier intervale dans un CellArray nD de taille n en utilisant find_impl +template +void FIND_find_impl_begin(benchmark::State& state) +{ + auto ca = cell_array_with_n_intervals(state.range(0)); + auto lca = ca[0]; + xt::xtensor_fixed> coord = {0}; + auto size = lca[dim - 1].size(); + auto integral = std::integral_constant{}; + for (auto _ : state) + { + auto index = samurai::detail::find_impl(lca, 0, size, coord, integral); + benchmark::DoNotOptimize(index); + } +} + +// Mesure : recherche du dernier intervale dans un CellArray nD de taille n en utilisant find_impl +template +void FIND_find_impl_end(benchmark::State& state) +{ + auto ca = cell_array_with_n_intervals(state.range(0)); + auto lca = ca[0]; + xt::xtensor_fixed> coord = {2 * state.range(0)}; + auto size = lca[dim - 1].size(); + auto integral = std::integral_constant{}; + for (auto _ : state) + { + auto index = samurai::detail::find_impl(lca, 0, size, coord, integral); + benchmark::DoNotOptimize(index); + } +} + +// Mesure : recherche du premier intervale dans un CellArray nD de taille n en utilisant interval_search +template +void FIND_interval_search_begin(benchmark::State& state) +{ + using TInterval = samurai::default_config::interval_t; + using lca_t = const samurai::LevelCellArray; + using diff_t = typename lca_t::const_iterator::difference_type; + + auto ca = cell_array_with_n_intervals(state.range(0)); + auto lca = ca[0]; + xt::xtensor_fixed> coord = {0}; + auto size = lca[dim - 1].size(); + auto integral = std::integral_constant{}; + auto begin = lca[0].cbegin() + static_cast(0); + auto end = lca[0].cend() + static_cast(size); + + for (auto _ : state) + { + auto index = samurai::detail::interval_search(begin, end, coord[0]); + benchmark::DoNotOptimize(index); + } +} + +// Mesure : recherche du dernier intervale dans un CellArray nD de taille n en utilisant interval_search +template +void FIND_interval_search_end(benchmark::State& state) +{ + using TInterval = samurai::default_config::interval_t; + using lca_t = const samurai::LevelCellArray; + using diff_t = typename lca_t::const_iterator::difference_type; + + auto ca = cell_array_with_n_intervals(state.range(0)); + auto lca = ca[0]; + xt::xtensor_fixed> coord = {2 * state.range(0)}; + auto size = lca[dim - 1].size(); + auto integral = std::integral_constant{}; + auto begin = lca[0].cbegin() + static_cast(0); + auto end = lca[0].cend() + static_cast(size); + + for (auto _ : state) + { + auto index = samurai::detail::interval_search(begin, end, coord[0]); + benchmark::DoNotOptimize(index); + } +} + +BENCHMARK_TEMPLATE(FIND_find_begin, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(FIND_find_begin, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(FIND_find_begin, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(FIND_find_end, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(FIND_find_end, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(FIND_find_end, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); + +BENCHMARK_TEMPLATE(FIND_find_impl_begin, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(FIND_find_impl_begin, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(FIND_find_impl_begin, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); + +BENCHMARK_TEMPLATE(FIND_find_impl_end, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(FIND_find_impl_end, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(FIND_find_impl_end, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); + +BENCHMARK_TEMPLATE(FIND_interval_search_begin, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(FIND_interval_search_begin, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(FIND_interval_search_begin, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); + +BENCHMARK_TEMPLATE(FIND_interval_search_end, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(FIND_interval_search_end, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(FIND_interval_search_end, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); + +/** template auto generate_mesh(int bound, std::size_t start_level, std::size_t max_level) { @@ -26,8 +180,8 @@ auto generate_mesh(int bound, std::size_t start_level, std::size_t max_level) samurai::for_each_interval(ca, [&](std::size_t level, const auto& interval, const auto& index) { - auto choice = xt::random::choice(xt::xtensor_fixed>{true, false}, interval.size()); - for (int i = interval.start, ic = 0; i < interval.end; ++i, ++ic) + auto choice = xt::random::choice(xt::xtensor_fixed>{true, false}, +interval.size()); for (int i = interval.start, ic = 0; i < interval.end; ++i, ++ic) { if (choice[ic]) { @@ -51,6 +205,8 @@ auto generate_mesh(int bound, std::size_t start_level, std::size_t max_level) return ca; } + + template class MyFixture : public ::benchmark::Fixture { @@ -69,11 +225,10 @@ class MyFixture : public ::benchmark::Fixture { std::size_t found = 0; for (auto _ : state) - { - for (std::size_t s = 0; s < state.range(0); ++s) { auto level = std::experimental::randint(min_level, max_level); - std::array coord; +// std::array coord; + xt::xtensor_fixed> coord ; for (auto& c : coord) { c = std::experimental::randint(-bound << level, (bound << level) - 1); @@ -99,6 +254,8 @@ BENCHMARK_TEMPLATE_DEFINE_F(MyFixture, Search_1D, 1, 1000) bench(state); } + + BENCHMARK_REGISTER_F(MyFixture, Search_1D)->DenseRange(1, 10, 1); BENCHMARK_TEMPLATE_DEFINE_F(MyFixture, Search_2D, 2, 10) @@ -116,3 +273,5 @@ BENCHMARK_TEMPLATE_DEFINE_F(MyFixture, Search_3D, 3, 1)(benchmark::State& state) } BENCHMARK_REGISTER_F(MyFixture, Search_3D)->DenseRange(1, 10, 1); + +**/ diff --git a/benchmark/benchmark_set.cpp b/benchmark/benchmark_set.cpp index 0b8af64ab..5e34b71d7 100644 --- a/benchmark/benchmark_set.cpp +++ b/benchmark/benchmark_set.cpp @@ -1,10 +1,10 @@ + #include #include #include #include #include -#include template inline auto init_sets_1(S& set1, S& set2, S& set3) @@ -45,6 +45,7 @@ static void BM_SetCreation(benchmark::State& state) } } +/** static void BM_SetOP(benchmark::State& state) { constexpr std::size_t dim = 2; @@ -57,9 +58,11 @@ static void BM_SetOP(benchmark::State& state) [&](auto& interval, auto&) { interval *= 2; + // error in const }); } } +**/ static void BM_SetCreationWithOn(benchmark::State& state) { @@ -72,6 +75,7 @@ static void BM_SetCreationWithOn(benchmark::State& state) } } +/** static void BM_SetOPWithOn(benchmark::State& state) { constexpr std::size_t dim = 2; @@ -84,10 +88,12 @@ static void BM_SetOPWithOn(benchmark::State& state) [&](auto& interval, auto&) { interval *= 2; + // error in const }); } } - +**/ +/** static void BM_SetOPWithOn2(benchmark::State& state) { constexpr std::size_t dim = 2; @@ -97,16 +103,16 @@ static void BM_SetOPWithOn2(benchmark::State& state) for (auto _ : state) { - auto subset = samurai::intersection(samurai::intersection(set1, samurai::translate(set2, stencil)), samurai::translate(set3, stencil)) - .on(15); - subset( + auto subset = samurai::intersection(samurai::intersection(set1, samurai::translate(set2, stencil)), samurai::translate(set3, +stencil)) .on(15); subset( [&](auto& interval, auto&) { interval *= 2; + // error const }); } } - +**/ static void BM_BigDomain(benchmark::State& state) { constexpr std::size_t dim = 2; @@ -131,8 +137,8 @@ static void BM_BigDomain(benchmark::State& state) } BENCHMARK(BM_SetCreation); -BENCHMARK(BM_SetOP); +// BENCHMARK(BM_SetOP); BENCHMARK(BM_SetCreationWithOn); -BENCHMARK(BM_SetOPWithOn); -BENCHMARK(BM_SetOPWithOn2); +// BENCHMARK(BM_SetOPWithOn); +// BENCHMARK(BM_SetOPWithOn2); BENCHMARK(BM_BigDomain); diff --git a/benchmark/benchmark_stencil.cpp b/benchmark/benchmark_stencil.cpp new file mode 100644 index 000000000..b1a5059d0 --- /dev/null +++ b/benchmark/benchmark_stencil.cpp @@ -0,0 +1,40 @@ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** +template +void STENCIL_find_stencil_origin(benchmark::State& state){ + using Stencil = xt::xtensor_fixed>; +//tencil stencil = xt::zeros({stencil_size, dim}); + Stencil stencil = star_stencil() ; + for (auto _ : state){ + auto origin = samurai::find_stencil_origin(stencil) ; + benchmark::DoNotOptimize(origin) ; + } +} + + + + +BENCHMARK_TEMPLATE(STENCIL_find_stencil_origin, 1, 1); +BENCHMARK_TEMPLATE(STENCIL_find_stencil_origin, 2, 1); +BENCHMARK_TEMPLATE(STENCIL_find_stencil_origin, 3, 1); + +**/ diff --git a/benchmark/benchmark_subset.cpp b/benchmark/benchmark_subset.cpp new file mode 100644 index 000000000..f9608f521 --- /dev/null +++ b/benchmark/benchmark_subset.cpp @@ -0,0 +1,360 @@ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Observation : Cela prend environ 10ns par intervalle +// si on compare 2 intervalles de taillen, cela prendra environ 2n * 10ns + +/////////////////////////////////////////////////////////////////// +// utils + +template +auto cell_list_with_n_intervals(int64_t size) +{ + samurai::CellList cl; + for (int64_t i = 0; i < size; i++) + { + int index = static_cast(i); + cl[0][{}].add_interval({2 * index, 2 * index + 1}); + } + return cl; +} + +template +auto cell_array_with_n_intervals(int64_t size) +{ + auto cl = cell_list_with_n_intervals(size); + samurai::CellArray ca(cl); + return ca; +} + +////////////////////////////////////////////////////////////////// + +/** +template +void SUBSET_difference_same_interval_different_level(benchmark::State& state){ + samurai::CellList cl1, cl2 ; + for (int64_t i = 0 ; i < state.range(0); i++){ + int index = static_cast(i) ; + cl1[0][{}].add_interval({2*index, 2*index+1}); + cl2[delta_level][{}].add_interval({pow(2, delta_level+1)*index, pow(2, delta_level+1)*index + pow(2, delta_level)}); + } + samurai::CellArray ca1(cl1); + samurai::CellArray ca2(cl2); + for (auto _ : state){ + if constexpr(delta_level != 0){ + auto subset = samurai::difference(ca1[0], samurai::projection(ca2[delta_level], 0)); + subset([](const auto&, const auto&) {}); // evaluation avec lambda vide + benchmark::DoNotOptimize(subset); + } + else if constexpr (delta_level == 0){ + auto subset = samurai::difference(ca1[0], ca2[0]); + subset([](const auto&, const auto&) {}); // evaluation avec lambda vide + benchmark::DoNotOptimize(subset); + } + } +} +**/ +/** +template +void SUBSET_difference_different_interval_different_level(benchmark::State& state){ + samurai::CellList cl1, cl2 ; + for (int64_t i = 0 ; i < state.range(0); i++){ + int index = static_cast(i) ; + cl1[0][{}].add_interval({2*index, 2*index+1}); + cl2[delta_level][{}].add_interval({pow(2, delta_level+1)*index + pow(2, delta_level), pow(2, delta_level+2)*index}); + } + samurai::CellArray ca1(cl1); + samurai::CellArray ca2(cl2); + for (auto _ : state){ + if constexpr(delta_level != 0){ + auto subset = samurai::difference(ca1[0], samurai::projection(ca2[delta_level], 0)); + subset([](const auto&, const auto&) {}); // evaluation avec lambda vide + benchmark::DoNotOptimize(subset); + } + else if constexpr (delta_level == 0){ + auto subset = samurai::difference(ca1[0], ca2[0]); + subset([](const auto&, const auto&) {}); // evaluation avec lambda vide + benchmark::DoNotOptimize(subset); + } + } +} +**/ + +/** +template +void SUBSET_difference_n1_interval_different_level(benchmark::State& state){ + samurai::CellList cl1, cl2 ; + for (int64_t i = 0 ; i < state.range(0); i++){ + int index = static_cast(i) ; + cl1[0][{}].add_interval({2*index, 2*index+1}); + } + cl2[delta_level][{}].add_interval({static_cast(0), static_cast(pow(2, delta_level))}); + + samurai::CellArray ca1(cl1); + samurai::CellArray ca2(cl2); + for (auto _ : state){ + if constexpr(delta_level != 0){ + auto subset = samurai::difference(ca1[0], samurai::projection(ca2[delta_level], 0)); + subset([](const auto&, const auto&) {}); // evaluation avec lambda vide + benchmark::DoNotOptimize(subset); + } + else if constexpr (delta_level == 0){ + auto subset = samurai::difference(ca1[0], ca2[0]); + subset([](const auto&, const auto&) {}); // evaluation avec lambda vide + benchmark::DoNotOptimize(subset); + } + } +} +**/ + +/** +template +void SUBSET_double_difference_same_interval(benchmark::State& state){ + samurai::CellList cl1, cl2 ; + for (int64_t i = 0 ; i < state.range(0); i++){ + int index = static_cast(i) ; + cl1[0][{}].add_interval({2*index, 2*index+1}); + cl2[delta_level][{}].add_interval({pow(2, delta_level+1)*index, pow(2, delta_level+1)*index + pow(2, delta_level)}); + } + samurai::CellArray ca1(cl1); + samurai::CellArray ca2(cl2); + for (auto _ : state){ + if constexpr(delta_level != 0){ + auto subset = samurai::difference(samurai::difference(ca1[0], samurai::projection(ca2[delta_level], 0)), ca1[0]); + subset([](const auto&, const auto&) {}); // evaluation avec lambda vide + benchmark::DoNotOptimize(subset); + } + else if constexpr (delta_level == 0){ + auto subset = samurai::difference(samurai::difference(ca1[0], ca2[0]), ca1[0]); + subset([](const auto&, const auto&) {}); // evaluation avec lambda vide + benchmark::DoNotOptimize(subset); + } + } +} +**/ + +/** +// why for <2-3, 1-2-10> it is that fast ? error i think +template +void SUBSET_intersection_same_interval_different_level(benchmark::State& state){ + samurai::CellList cl1, cl2 ; + for (int64_t i = 0 ; i < state.range(0); i++){ + int index = static_cast(i) ; + cl1[0][{}].add_interval({2*index, 2*index+1}); + cl2[delta_level][{}].add_interval({pow(2, delta_level+1)*index, pow(2, delta_level+1)*index + pow(2, delta_level)}); + + } + samurai::CellArray ca1(cl1); + samurai::CellArray ca2(cl2); + for (auto _ : state){ + if constexpr(delta_level != 0){ + auto subset = samurai::intersection(ca1[0], samurai::projection(ca2[delta_level], 0)); + subset([](const auto&, const auto&) {}); // evaluation avec lambda vide + benchmark::DoNotOptimize(subset); + } + else if constexpr (delta_level == 0){ + auto subset = samurai::intersection(ca1[0], ca2[0]); + subset([](const auto&, const auto&) {}); // evaluation avec lambda vide + benchmark::DoNotOptimize(subset); + } + } +} +**/ +/** +template +void SUBSET_union_same_interval_different_level(benchmark::State& state){ + samurai::CellList cl1, cl2 ; + for (int64_t i = 0 ; i < state.range(0); i++){ + int index = static_cast(i) ; + cl1[0][{}].add_interval({2*index, 2*index+1}); + cl2[delta_level][{}].add_interval({pow(2, delta_level+1)*index, pow(2, delta_level+1)*index + pow(2, delta_level)}); + + } + samurai::CellArray ca1(cl1); + samurai::CellArray ca2(cl2); + for (auto _ : state){ + if constexpr(delta_level != 0){ + auto subset = samurai::union_(ca1[0], samurai::projection(ca2[delta_level], 0)); + subset([](const auto&, const auto&) {}); // evaluation avec lambda vide + benchmark::DoNotOptimize(subset); + } + else if constexpr (delta_level == 0){ + auto subset = samurai::union_(ca1[0], ca2[0]); + subset([](const auto&, const auto&) {}); // evaluation avec lambda vide + benchmark::DoNotOptimize(subset); + } + } +} +**/ + +template +void SUBSET_translate(benchmark::State& state) +{ + samurai::CellList cl; + for (int64_t i = 0; i < state.range(0); i++) + { + int index = static_cast(i); + cl[0][{}].add_interval({2 * index, 2 * index + 1}); + } + samurai::CellArray ca(cl); + xt::xtensor_fixed> stencil; + if constexpr (dim == 1) + { + stencil = xt::xtensor_fixed>({1}); + } + else if constexpr (dim == 2) + { + stencil = xt::xtensor_fixed>({1, 1}); + } + else if constexpr (dim == 3) + { + stencil = xt::xtensor_fixed>({1, 1, 1}); + } + for (auto _ : state) + { + auto subset = samurai::translate(ca[0], stencil); + subset([](const auto&, const auto&) {}); // evaluation avec lambda vide + benchmark::DoNotOptimize(subset); + } +} + +/** +template +void SUBSET_expand(benchmark::State& state){ + samurai::CellList cl ; + for (int64_t i = 0 ; i < state.range(0); i++){ + int index = static_cast(i) ; + cl[0][{}].add_interval({2*index, 2*index+1}); + } + samurai::CellArray ca(cl); + xt::xtensor_fixed> stencil; + if constexpr (dim == 1) + stencil = xt::xtensor_fixed>({1}) ; + else if constexpr (dim == 2) + stencil = xt::xtensor_fixed>({1,1}) ; + else if constexpr (dim == 3) + stencil = xt::xtensor_fixed>({1,1,1}) ; + for (auto _ : state){ + auto subset = samurai::expand(ca[0]); + subset([](const auto&, const auto&) {}); // evaluation avec lambda vide + benchmark::DoNotOptimize(subset); + } +} +**/ + +/** +template +void SUBSET_contraction(benchmark::State& state){ + samurai::CellList cl ; + for (int64_t i = 0 ; i < state.range(0); i++){ + int index = static_cast(i) ; + cl[0][{}].add_interval({2*index, 2*index+1}); + } + samurai::CellArray ca(cl); + xt::xtensor_fixed> stencil; + if constexpr (dim == 1) + stencil = xt::xtensor_fixed>({1}) ; + else if constexpr (dim == 2) + stencil = xt::xtensor_fixed>({1,1}) ; + else if constexpr (dim == 3) + stencil = xt::xtensor_fixed>({1,1,1}) ; + for (auto _ : state){ + auto subset = samurai::contraction(ca[0]); + subset([](const auto&, const auto&) {}); // evaluation avec lambda vide + benchmark::DoNotOptimize(subset); + } +} +**/ +/** +BENCHMARK_TEMPLATE(SUBSET_difference_same_interval_different_level,1, 0)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(SUBSET_difference_same_interval_different_level,2, 0)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(SUBSET_difference_same_interval_different_level,3, 0)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); + +BENCHMARK_TEMPLATE(SUBSET_difference_same_interval_different_level,1, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(SUBSET_difference_same_interval_different_level,2, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(SUBSET_difference_same_interval_different_level,3, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); + +BENCHMARK_TEMPLATE(SUBSET_difference_same_interval_different_level,1, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(SUBSET_difference_same_interval_different_level,2, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(SUBSET_difference_same_interval_different_level,3, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); + +BENCHMARK_TEMPLATE(SUBSET_difference_same_interval_different_level,1, 10)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(SUBSET_difference_same_interval_different_level,2, 10)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(SUBSET_difference_same_interval_different_level,3, 10)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +**/ +/** +BENCHMARK_TEMPLATE(SUBSET_difference_n1_interval_different_level,1, 0)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(SUBSET_difference_n1_interval_different_level,2, 0)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(SUBSET_difference_n1_interval_different_level,3, 0)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +**/ + +/** +BENCHMARK_TEMPLATE(SUBSET_double_difference_same_interval,1, 0)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(SUBSET_double_difference_same_interval,2, 0)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(SUBSET_double_difference_same_interval,3, 0)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +**/ + +/** +BENCHMARK_TEMPLATE(SUBSET_intersection_same_interval_different_level,1, 0)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(SUBSET_intersection_same_interval_different_level,2, 0)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(SUBSET_intersection_same_interval_different_level,3, 0)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); + +BENCHMARK_TEMPLATE(SUBSET_intersection_same_interval_different_level,1, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(SUBSET_intersection_same_interval_different_level,2, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(SUBSET_intersection_same_interval_different_level,3, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); + +BENCHMARK_TEMPLATE(SUBSET_intersection_same_interval_different_level,1, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(SUBSET_intersection_same_interval_different_level,2, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(SUBSET_intersection_same_interval_different_level,3, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); + +BENCHMARK_TEMPLATE(SUBSET_intersection_same_interval_different_level,1, 10)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(SUBSET_intersection_same_interval_different_level,2, 10)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(SUBSET_intersection_same_interval_different_level,3, 10)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +**/ + +/** +BENCHMARK_TEMPLATE(SUBSET_union_same_interval_different_level,1, 0)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(SUBSET_union_same_interval_different_level,2, 0)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(SUBSET_union_same_interval_different_level,3, 0)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); + +BENCHMARK_TEMPLATE(SUBSET_union_same_interval_different_level,1, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(SUBSET_union_same_interval_different_level,2, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(SUBSET_union_same_interval_different_level,3, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); + +BENCHMARK_TEMPLATE(SUBSET_union_same_interval_different_level,1, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(SUBSET_union_same_interval_different_level,2, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(SUBSET_union_same_interval_different_level,3, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); + +BENCHMARK_TEMPLATE(SUBSET_union_same_interval_different_level,1, 10)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(SUBSET_union_same_interval_different_level,2, 10)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(SUBSET_union_same_interval_different_level,3, 10)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +**/ + +// BENCHMARK_TEMPLATE(SUBSET_translate,1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +// BENCHMARK_TEMPLATE(SUBSET_translate,2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +// BENCHMARK_TEMPLATE(SUBSET_translate,3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); + +/** +BENCHMARK_TEMPLATE(SUBSET_expand,1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(SUBSET_expand,2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(SUBSET_expand,3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +**/ + +// BENCHMARK_TEMPLATE(SUBSET_contraction,1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +// BENCHMARK_TEMPLATE(SUBSET_contraction,2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +// BENCHMARK_TEMPLATE(SUBSET_contraction,3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); From 12a3db9cd7a89923480b0641d1149559d43104f6 Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Wed, 11 Jun 2025 23:31:01 +0200 Subject: [PATCH 02/12] feat: improve benchmark bc --- benchmark/benchmark_bc.cpp | 53 +++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/benchmark/benchmark_bc.cpp b/benchmark/benchmark_bc.cpp index fbb533347..29f06d26d 100644 --- a/benchmark/benchmark_bc.cpp +++ b/benchmark/benchmark_bc.cpp @@ -1,4 +1,3 @@ - #include #include #include @@ -47,38 +46,38 @@ auto unitary_box() return box; } -// Mesure : Création d'une condition limite scalaire par défaut sur un maillage uniforme -template -void BC_scalar_homogeneous(benchmark::State& state) +// Mesure : Création d'une condition limite sur un maillage uniforme +template +void BC_homogeneous(benchmark::State& state) { samurai::Box box = unitary_box(); - using Config = samurai::UniformConfig; - auto mesh = samurai::UniformMesh(box, state.range(0)); - auto u = make_field("u", mesh); + using Config = samurai::UniformConfig; // Utilisation de l'ordre comme paramètre + auto mesh = samurai::UniformMesh(box, state.range(0)); + auto u = make_field("u", mesh); + + u.fill(1.0); + for (auto _ : state) { - samurai::make_bc>(u); + samurai::make_bc(u); } } -// Mesure : Création d'une condition limite vectorielle par défaut sur un maillage uniforme -template -void BC_vec_homogeneous(benchmark::State& state) -{ - samurai::Box box = unitary_box(); - using Config = samurai::UniformConfig; - auto mesh = samurai::UniformMesh(box, state.range(0)); - auto u = make_field("u", mesh); - for (auto _ : state) - { - samurai::make_bc>(u); - } -} +// Tests Dirichlet +BENCHMARK_TEMPLATE(BC_homogeneous, 1, 1, samurai::Dirichlet<1>, 1)->DenseRange(1, 1); +BENCHMARK_TEMPLATE(BC_homogeneous, 2, 1, samurai::Dirichlet<1>, 1)->DenseRange(1, 1); +BENCHMARK_TEMPLATE(BC_homogeneous, 3, 1, samurai::Dirichlet<1>, 1)->DenseRange(1, 1); +BENCHMARK_TEMPLATE(BC_homogeneous, 1, 100, samurai::Dirichlet<1>, 1)->DenseRange(1, 1); + +// Tests Neumann +BENCHMARK_TEMPLATE(BC_homogeneous, 1, 1, samurai::Neumann<1>, 1)->DenseRange(1, 1); +BENCHMARK_TEMPLATE(BC_homogeneous, 2, 1, samurai::Neumann<1>, 1)->DenseRange(1, 1); +BENCHMARK_TEMPLATE(BC_homogeneous, 3, 1, samurai::Neumann<1>, 1)->DenseRange(1, 1); +BENCHMARK_TEMPLATE(BC_homogeneous, 1, 100, samurai::Neumann<1>, 1)->DenseRange(1, 1); -BENCHMARK_TEMPLATE(BC_scalar_homogeneous, 1)->DenseRange(1, 1); -; -// BENCHMARK_TEMPLATE(BC_scalar_homogeneous,2)->DenseRange(1, 1);; // not enough ghost cells -// BENCHMARK_TEMPLATE(BC_scalar_homogeneous,3)->DenseRange(1, 1);; +// Tests Dirichlet ordre 3 +BENCHMARK_TEMPLATE(BC_homogeneous, 1, 1, samurai::Dirichlet<2>, 3)->DenseRange(1, 1); +BENCHMARK_TEMPLATE(BC_homogeneous, 2, 1, samurai::Dirichlet<2>, 3)->DenseRange(1, 1); +BENCHMARK_TEMPLATE(BC_homogeneous, 3, 1, samurai::Dirichlet<2>, 3)->DenseRange(1, 1); +BENCHMARK_TEMPLATE(BC_homogeneous, 1, 100, samurai::Dirichlet<2>, 3)->DenseRange(1, 1); -BENCHMARK_TEMPLATE(BC_vec_homogeneous, 1)->DenseRange(1, 1); -; From 4d64e6df36abba5b6ca7b73321818fd2b544f3d7 Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Wed, 11 Jun 2025 23:37:11 +0200 Subject: [PATCH 03/12] feat: add benchmark bc --- benchmark/benchmark_bc.cpp | 61 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/benchmark/benchmark_bc.cpp b/benchmark/benchmark_bc.cpp index 29f06d26d..16930aadd 100644 --- a/benchmark/benchmark_bc.cpp +++ b/benchmark/benchmark_bc.cpp @@ -63,6 +63,57 @@ void BC_homogeneous(benchmark::State& state) } } +// Test BC sur une direction spécifique +template +void BC_directional(benchmark::State& state) +{ + samurai::Box box = unitary_box(); + using Config = samurai::UniformConfig; + auto mesh = samurai::UniformMesh(box, state.range(0)); + auto u = make_field("u", mesh); + + u.fill(1.0); + + for (auto _ : state) + { + if constexpr (dim == 1) + { + const xt::xtensor_fixed> left{-1}; + samurai::make_bc(u)->on(left); + } + else if constexpr (dim == 2) + { + const xt::xtensor_fixed> left{-1, 0}; + samurai::make_bc(u)->on(left); + } + else if constexpr (dim == 3) + { + const xt::xtensor_fixed> left{-1, 0, 0}; + samurai::make_bc(u)->on(left); + } + } +} + +// Test BC avec une fonction +template +void BC_functional(benchmark::State& state) +{ + samurai::Box box = unitary_box(); + using Config = samurai::UniformConfig; + auto mesh = samurai::UniformMesh(box, state.range(0)); + auto u = make_field("u", mesh); + + u.fill(1.0); + + for (auto _ : state) + { + auto func = [](const auto& d, const auto& cell, const auto& coords) { + return 1.0; + }; + samurai::make_bc(u, func); + } +} + // Tests Dirichlet BENCHMARK_TEMPLATE(BC_homogeneous, 1, 1, samurai::Dirichlet<1>, 1)->DenseRange(1, 1); BENCHMARK_TEMPLATE(BC_homogeneous, 2, 1, samurai::Dirichlet<1>, 1)->DenseRange(1, 1); @@ -81,3 +132,13 @@ BENCHMARK_TEMPLATE(BC_homogeneous, 2, 1, samurai::Dirichlet<2>, 3)->DenseRange(1 BENCHMARK_TEMPLATE(BC_homogeneous, 3, 1, samurai::Dirichlet<2>, 3)->DenseRange(1, 1); BENCHMARK_TEMPLATE(BC_homogeneous, 1, 100, samurai::Dirichlet<2>, 3)->DenseRange(1, 1); +// Tests BC directionnels +BENCHMARK_TEMPLATE(BC_directional, 1, 1, samurai::Dirichlet<1>, 1)->DenseRange(1, 1); +BENCHMARK_TEMPLATE(BC_directional, 2, 1, samurai::Dirichlet<1>, 1)->DenseRange(1, 1); +BENCHMARK_TEMPLATE(BC_directional, 3, 1, samurai::Dirichlet<1>, 1)->DenseRange(1, 1); + +// Tests BC fonctionnels +BENCHMARK_TEMPLATE(BC_functional, 1, 1, samurai::Dirichlet<1>, 1)->DenseRange(1, 1); +BENCHMARK_TEMPLATE(BC_functional, 2, 1, samurai::Dirichlet<1>, 1)->DenseRange(1, 1); +BENCHMARK_TEMPLATE(BC_functional, 3, 1, samurai::Dirichlet<1>, 1)->DenseRange(1, 1); + From 251a6c125ecd1025bc252ccabf631d71ef5fb01d Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Wed, 11 Jun 2025 23:51:16 +0200 Subject: [PATCH 04/12] feat: add new benchmarks --- benchmark/benchmark_bc.cpp | 28 ++-------- benchmark/benchmark_cell.cpp | 32 ++++-------- benchmark/benchmark_search.cpp | 96 ++++++++++------------------------ 3 files changed, 39 insertions(+), 117 deletions(-) diff --git a/benchmark/benchmark_bc.cpp b/benchmark/benchmark_bc.cpp index 16930aadd..26675facf 100644 --- a/benchmark/benchmark_bc.cpp +++ b/benchmark/benchmark_bc.cpp @@ -94,26 +94,6 @@ void BC_directional(benchmark::State& state) } } -// Test BC avec une fonction -template -void BC_functional(benchmark::State& state) -{ - samurai::Box box = unitary_box(); - using Config = samurai::UniformConfig; - auto mesh = samurai::UniformMesh(box, state.range(0)); - auto u = make_field("u", mesh); - - u.fill(1.0); - - for (auto _ : state) - { - auto func = [](const auto& d, const auto& cell, const auto& coords) { - return 1.0; - }; - samurai::make_bc(u, func); - } -} - // Tests Dirichlet BENCHMARK_TEMPLATE(BC_homogeneous, 1, 1, samurai::Dirichlet<1>, 1)->DenseRange(1, 1); BENCHMARK_TEMPLATE(BC_homogeneous, 2, 1, samurai::Dirichlet<1>, 1)->DenseRange(1, 1); @@ -132,13 +112,11 @@ BENCHMARK_TEMPLATE(BC_homogeneous, 2, 1, samurai::Dirichlet<2>, 3)->DenseRange(1 BENCHMARK_TEMPLATE(BC_homogeneous, 3, 1, samurai::Dirichlet<2>, 3)->DenseRange(1, 1); BENCHMARK_TEMPLATE(BC_homogeneous, 1, 100, samurai::Dirichlet<2>, 3)->DenseRange(1, 1); -// Tests BC directionnels +// BC directionnels BENCHMARK_TEMPLATE(BC_directional, 1, 1, samurai::Dirichlet<1>, 1)->DenseRange(1, 1); BENCHMARK_TEMPLATE(BC_directional, 2, 1, samurai::Dirichlet<1>, 1)->DenseRange(1, 1); BENCHMARK_TEMPLATE(BC_directional, 3, 1, samurai::Dirichlet<1>, 1)->DenseRange(1, 1); -// Tests BC fonctionnels -BENCHMARK_TEMPLATE(BC_functional, 1, 1, samurai::Dirichlet<1>, 1)->DenseRange(1, 1); -BENCHMARK_TEMPLATE(BC_functional, 2, 1, samurai::Dirichlet<1>, 1)->DenseRange(1, 1); -BENCHMARK_TEMPLATE(BC_functional, 3, 1, samurai::Dirichlet<1>, 1)->DenseRange(1, 1); + + diff --git a/benchmark/benchmark_cell.cpp b/benchmark/benchmark_cell.cpp index 08df5b207..c8fcda5fd 100644 --- a/benchmark/benchmark_cell.cpp +++ b/benchmark/benchmark_cell.cpp @@ -1,4 +1,3 @@ - #include #include #include @@ -25,32 +24,18 @@ auto make_cell() { using value_t = samurai::default_config::value_t; using point_t = xt::xtensor_fixed>; - point_t indice; - point_t begin; - - if constexpr (dim == 1) - { - indice = {1}; - begin = {0}; - } - if constexpr (dim == 2) - { - indice = {1, 1}; - begin = {0, 0}; - } - if constexpr (dim == 3) - { - indice = {1, 1, 1}; - begin = {0, 0, 0}; - } - - auto indices = xt::xtensor_fixed>(indice); + + // Initialisation générique des indices et du point de départ + point_t indice = xt::ones({dim}); + point_t begin = xt::zeros({dim}); + + auto indices = xt::xtensor_fixed>(indice); double scaling_factor = 1.0; - auto c = samurai::Cell>(begin, scaling_factor, 1, indices, 0); - return c; + return samurai::Cell>(begin, scaling_factor, 1, indices, 0); } // Mesure : Construction d'une cellule par défaut +// Cette fonction mesure le temps nécessaire pour créer une cellule sans paramètres template void CELL_default(benchmark::State& state) { @@ -136,6 +121,7 @@ void CELL_corner(benchmark::State& state) } // Mesure : Test d'égalité entre deux cellules +// Cette fonction mesure le temps nécessaire pour comparer deux cellules identiques template void CELL_equal(benchmark::State& state) { diff --git a/benchmark/benchmark_search.cpp b/benchmark/benchmark_search.cpp index 01ce6f1a7..6801d4619 100644 --- a/benchmark/benchmark_search.cpp +++ b/benchmark/benchmark_search.cpp @@ -1,4 +1,3 @@ - #include #include #include @@ -36,67 +35,36 @@ auto cell_array_with_n_intervals(int64_t size) ////////////////////////////////////////////////////////////// -// Mesure : recherche du premier intervale dans un CellArray nD de taille n en utilisant find -template -void FIND_find_begin(benchmark::State& state) -{ - auto ca = cell_array_with_n_intervals(state.range(0)); - xt::xtensor_fixed> coord = {0}; - for (auto _ : state) - { - auto index = find(ca[0], coord); - benchmark::DoNotOptimize(index); - } -} -// Mesure : recherche du dernier intervale dans un CellArray nD de taille n en utilisant find -template -void FIND_find_end(benchmark::State& state) -{ - auto ca = cell_array_with_n_intervals(state.range(0)); - xt::xtensor_fixed> coord = {2 * state.range(0)}; - for (auto _ : state) - { - auto index = find(ca[0], coord); - benchmark::DoNotOptimize(index); - } -} -// Mesure : recherche du premier intervale dans un CellArray nD de taille n en utilisant find_impl + +// Mesure : recherche du premier intervale dans un CellArray nD de taille n en utilisant interval_search template -void FIND_find_impl_begin(benchmark::State& state) +void FIND_interval_search_begin(benchmark::State& state) { + using TInterval = samurai::default_config::interval_t; + using lca_t = const samurai::LevelCellArray; + using diff_t = typename lca_t::const_iterator::difference_type; + auto ca = cell_array_with_n_intervals(state.range(0)); auto lca = ca[0]; xt::xtensor_fixed> coord = {0}; auto size = lca[dim - 1].size(); auto integral = std::integral_constant{}; - for (auto _ : state) - { - auto index = samurai::detail::find_impl(lca, 0, size, coord, integral); - benchmark::DoNotOptimize(index); - } -} + auto begin = lca[0].cbegin() + static_cast(0); + auto end = lca[0].cend() + static_cast(size); + -// Mesure : recherche du dernier intervale dans un CellArray nD de taille n en utilisant find_impl -template -void FIND_find_impl_end(benchmark::State& state) -{ - auto ca = cell_array_with_n_intervals(state.range(0)); - auto lca = ca[0]; - xt::xtensor_fixed> coord = {2 * state.range(0)}; - auto size = lca[dim - 1].size(); - auto integral = std::integral_constant{}; for (auto _ : state) { - auto index = samurai::detail::find_impl(lca, 0, size, coord, integral); + auto index = samurai::detail::interval_search(begin, end, coord[0]); benchmark::DoNotOptimize(index); } } -// Mesure : recherche du premier intervale dans un CellArray nD de taille n en utilisant interval_search +// Mesure : recherche du dernier intervale dans un CellArray nD de taille n en utilisant interval_search template -void FIND_interval_search_begin(benchmark::State& state) +void FIND_interval_search_end(benchmark::State& state) { using TInterval = samurai::default_config::interval_t; using lca_t = const samurai::LevelCellArray; @@ -104,7 +72,7 @@ void FIND_interval_search_begin(benchmark::State& state) auto ca = cell_array_with_n_intervals(state.range(0)); auto lca = ca[0]; - xt::xtensor_fixed> coord = {0}; + xt::xtensor_fixed> coord = {2 * state.range(0)}; auto size = lca[dim - 1].size(); auto integral = std::integral_constant{}; auto begin = lca[0].cbegin() + static_cast(0); @@ -117,9 +85,9 @@ void FIND_interval_search_begin(benchmark::State& state) } } -// Mesure : recherche du dernier intervale dans un CellArray nD de taille n en utilisant interval_search +// Ajout d'un nouveau benchmark pour les cas intermédiaires template -void FIND_interval_search_end(benchmark::State& state) +void FIND_interval_search_middle(benchmark::State& state) { using TInterval = samurai::default_config::interval_t; using lca_t = const samurai::LevelCellArray; @@ -127,12 +95,13 @@ void FIND_interval_search_end(benchmark::State& state) auto ca = cell_array_with_n_intervals(state.range(0)); auto lca = ca[0]; - xt::xtensor_fixed> coord = {2 * state.range(0)}; + xt::xtensor_fixed> coord = {state.range(0)}; // Point au milieu auto size = lca[dim - 1].size(); auto integral = std::integral_constant{}; auto begin = lca[0].cbegin() + static_cast(0); auto end = lca[0].cend() + static_cast(size); + for (auto _ : state) { auto index = samurai::detail::interval_search(begin, end, coord[0]); @@ -140,28 +109,17 @@ void FIND_interval_search_end(benchmark::State& state) } } -BENCHMARK_TEMPLATE(FIND_find_begin, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(FIND_find_begin, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(FIND_find_begin, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(FIND_find_end, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(FIND_find_end, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(FIND_find_end, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); - -BENCHMARK_TEMPLATE(FIND_find_impl_begin, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(FIND_find_impl_begin, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(FIND_find_impl_begin, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); - -BENCHMARK_TEMPLATE(FIND_find_impl_end, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(FIND_find_impl_end, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(FIND_find_impl_end, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(FIND_interval_search_begin, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 15); +BENCHMARK_TEMPLATE(FIND_interval_search_begin, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 15); +BENCHMARK_TEMPLATE(FIND_interval_search_begin, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 15); -BENCHMARK_TEMPLATE(FIND_interval_search_begin, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(FIND_interval_search_begin, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(FIND_interval_search_begin, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(FIND_interval_search_end, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 15); +BENCHMARK_TEMPLATE(FIND_interval_search_end, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 15); +BENCHMARK_TEMPLATE(FIND_interval_search_end, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 15); -BENCHMARK_TEMPLATE(FIND_interval_search_end, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(FIND_interval_search_end, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(FIND_interval_search_end, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(FIND_interval_search_middle, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 15); +BENCHMARK_TEMPLATE(FIND_interval_search_middle, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 15); +BENCHMARK_TEMPLATE(FIND_interval_search_middle, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 15); /** template From 5164076f0efe178dc84540c1beb5e5d2882dd5f2 Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Thu, 12 Jun 2025 00:24:06 +0200 Subject: [PATCH 05/12] feat: update benchmarks --- benchmark/benchmark_field.cpp | 44 ------------------- benchmark/benchmark_mesh.cpp | 83 +++++++++++++++++++++-------------- 2 files changed, 49 insertions(+), 78 deletions(-) diff --git a/benchmark/benchmark_field.cpp b/benchmark/benchmark_field.cpp index 77975b991..f90e1c74e 100644 --- a/benchmark/benchmark_field.cpp +++ b/benchmark/benchmark_field.cpp @@ -17,48 +17,4 @@ #include #include -template -auto cell_list_with_n_intervals(int64_t size) -{ - samurai::CellList cl; - for (int64_t i = 0; i < size; i++) - { - int index = static_cast(i); - cl[0][{}].add_interval({2 * index, 2 * index + 1}); - } - return cl; -} -template -void MESH_default(benchmark::State& state) -{ - using Config = samurai::amr::Config; - for (auto _ : state) - { - auto mesh = samurai::amr::Mesh(); - benchmark::DoNotOptimize(mesh); - } -} - -// probablement mal fait puisque add interval au niveau 0 sur des aussi grandes valeurs ... -template -void MESH_cl(benchmark::State& state) -{ - using Config = samurai::amr::Config; - auto cl = cell_list_with_n_intervals(state.range(0)); - auto min_level = 1; - auto max_level = 7; - for (auto _ : state) - { - auto mesh = samurai::amr::Mesh(cl, min_level, max_level); - benchmark::DoNotOptimize(mesh); - } -} - -BENCHMARK_TEMPLATE(MESH_default, 1); -BENCHMARK_TEMPLATE(MESH_default, 2); -BENCHMARK_TEMPLATE(MESH_default, 3); - -BENCHMARK_TEMPLATE(MESH_cl, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(MESH_cl, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 8); -BENCHMARK_TEMPLATE(MESH_cl, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 7); diff --git a/benchmark/benchmark_mesh.cpp b/benchmark/benchmark_mesh.cpp index 1050dd765..3c7c03b08 100644 --- a/benchmark/benchmark_mesh.cpp +++ b/benchmark/benchmark_mesh.cpp @@ -1,4 +1,3 @@ - #include #include #include @@ -48,6 +47,20 @@ auto unitary_box() return box; } + +template +auto cell_list_with_n_intervals(int64_t size) +{ + samurai::CellList cl; + for (int64_t i = 0; i < size; i++) + { + int index = static_cast(i); + cl[0][{}].add_interval({2 * index, 2 * index + 1}); + } + return cl; +} + + //////////////////////////////////////////////////////////////////////////// // Mesure : Création d'une Box uniforme de taille de coté n @@ -62,6 +75,19 @@ void MESH_uniform(benchmark::State& state) } } + +template +void MESH_default(benchmark::State& state) +{ + using Config = samurai::UniformConfig; + for (auto _ : state) + { + auto mesh = samurai::UniformMesh(); + benchmark::DoNotOptimize(mesh); + } +} + + // Mesure : Allocation d'un champ 1D d'un maillage uniforme de taille de coté n template void FIELD_make_field_uniform(benchmark::State& state) @@ -91,7 +117,7 @@ void FIELD_fill_uniform(benchmark::State& state) // Mesure ; Remplissage d'un champ 1D de taille de coté n ,en utilisant for_each_cell (mesure d'overhead) template -void FIELD_for_each_cell_uniform(benchmark::State& state) +void FIELD_fill_for_each_cell_uniform(benchmark::State& state) { samurai::Box box = unitary_box(); using Config = samurai::UniformConfig; @@ -108,7 +134,7 @@ void FIELD_for_each_cell_uniform(benchmark::State& state) } // Mesure : Test d'égalité entre deux Fields - +// TODO : change name from equal to fill_equal // Weird : MPI issue ??? wtf ??? template void FIELD_equal_uniform(benchmark::State& state) @@ -143,6 +169,7 @@ void FIELD_add_scalar_uniform(benchmark::State& state) } // Mesure : Ajout d'un scalaire à un champ par "for_each_cell" +// this is really slow template void FIELD_add_scalar_for_each_cell_uniform(benchmark::State& state) { @@ -157,7 +184,7 @@ void FIELD_add_scalar_for_each_cell_uniform(benchmark::State& state) for_each_cell(mesh, [&](auto cell) { - v[cell] = u[cell] + 1.0; + v[cell] = u[cell] + 2.0; }); } } @@ -229,64 +256,52 @@ void FIELD_add_uniform(benchmark::State& state) } BENCHMARK_TEMPLATE(MESH_uniform, 1)->DenseRange(1, 16); -; BENCHMARK_TEMPLATE(MESH_uniform, 2)->DenseRange(1, 14); -; BENCHMARK_TEMPLATE(MESH_uniform, 3)->DenseRange(1, 9); -; + + +BENCHMARK_TEMPLATE(MESH_default, 1); +BENCHMARK_TEMPLATE(MESH_default, 2); +BENCHMARK_TEMPLATE(MESH_default, 3); + + BENCHMARK_TEMPLATE(FIELD_make_field_uniform, 1)->DenseRange(1, 16); -; BENCHMARK_TEMPLATE(FIELD_make_field_uniform, 2)->DenseRange(1, 12); -; BENCHMARK_TEMPLATE(FIELD_make_field_uniform, 3)->DenseRange(1, 7); -; + BENCHMARK_TEMPLATE(FIELD_fill_uniform, 1)->DenseRange(1, 16); -; BENCHMARK_TEMPLATE(FIELD_fill_uniform, 2)->DenseRange(1, 12); -; BENCHMARK_TEMPLATE(FIELD_fill_uniform, 3)->DenseRange(1, 7); -; -BENCHMARK_TEMPLATE(FIELD_for_each_cell_uniform, 1)->DenseRange(1, 16); -; -BENCHMARK_TEMPLATE(FIELD_for_each_cell_uniform, 2)->DenseRange(1, 12); -; -BENCHMARK_TEMPLATE(FIELD_for_each_cell_uniform, 3)->DenseRange(1, 7); -; + +BENCHMARK_TEMPLATE(FIELD_fill_for_each_cell_uniform, 1)->DenseRange(1, 16); +BENCHMARK_TEMPLATE(FIELD_fill_for_each_cell_uniform, 2)->DenseRange(1, 12); +BENCHMARK_TEMPLATE(FIELD_fill_for_each_cell_uniform, 3)->DenseRange(1, 7); + BENCHMARK_TEMPLATE(FIELD_equal_uniform, 1)->DenseRange(1, 16); -; BENCHMARK_TEMPLATE(FIELD_equal_uniform, 2)->DenseRange(1, 12); -; BENCHMARK_TEMPLATE(FIELD_equal_uniform, 3)->DenseRange(1, 7); -; + BENCHMARK_TEMPLATE(FIELD_add_scalar_uniform, 1)->DenseRange(1, 16); -; BENCHMARK_TEMPLATE(FIELD_add_scalar_uniform, 2)->DenseRange(1, 12); -; BENCHMARK_TEMPLATE(FIELD_add_scalar_uniform, 3)->DenseRange(1, 7); -; + BENCHMARK_TEMPLATE(FIELD_add_scalar_for_each_cell_uniform, 1)->DenseRange(1, 16); -; BENCHMARK_TEMPLATE(FIELD_add_scalar_for_each_cell_uniform, 2)->DenseRange(1, 12); -; BENCHMARK_TEMPLATE(FIELD_add_scalar_for_each_cell_uniform, 3)->DenseRange(1, 7); -; + BENCHMARK_TEMPLATE(FIELD_add_uniform, 1)->DenseRange(1, 16); -; BENCHMARK_TEMPLATE(FIELD_add_uniform, 2)->DenseRange(1, 12); -; BENCHMARK_TEMPLATE(FIELD_add_uniform, 3)->DenseRange(1, 7); -; + BENCHMARK_TEMPLATE(FIELD_add_for_each_cell_uniform, 1)->DenseRange(1, 16); -; BENCHMARK_TEMPLATE(FIELD_add_for_each_cell_uniform, 2)->DenseRange(1, 12); -; BENCHMARK_TEMPLATE(FIELD_add_for_each_cell_uniform, 3)->DenseRange(1, 7); -; + From 928503f6fedc626984d1ab02245d0a8b3bbd1189 Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Mon, 16 Jun 2025 09:55:01 +0200 Subject: [PATCH 06/12] feat: update bechmarks --- benchmark/CMakeLists.txt | 1 - benchmark/benchmark_bc.cpp | 56 +- benchmark/benchmark_cell.cpp | 13 +- benchmark/benchmark_cellarray.cpp | 198 ++-- benchmark/benchmark_celllist_construction.cpp | 277 +++--- benchmark/benchmark_field.cpp | 406 ++++++++- benchmark/benchmark_level_cell_array.cpp | 295 +++++- benchmark/benchmark_mesh.cpp | 242 +---- benchmark/benchmark_search.cpp | 170 ++-- benchmark/benchmark_stencil.cpp | 40 +- benchmark/benchmark_subset.cpp | 855 ++++++++++++------ 11 files changed, 1529 insertions(+), 1024 deletions(-) diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index 0535a2bc6..7536be8f3 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -22,7 +22,6 @@ find_package(Threads) set(SAMURAI_BENCHMARKS benchmark_celllist_construction.cpp benchmark_search.cpp - benchmark_set.cpp benchmark_interval.cpp benchmark_cellarray.cpp benchmark_level_cell_array.cpp diff --git a/benchmark/benchmark_bc.cpp b/benchmark/benchmark_bc.cpp index 26675facf..191b4a566 100644 --- a/benchmark/benchmark_bc.cpp +++ b/benchmark/benchmark_bc.cpp @@ -51,46 +51,21 @@ template box = unitary_box(); - using Config = samurai::UniformConfig; // Utilisation de l'ordre comme paramètre - auto mesh = samurai::UniformMesh(box, state.range(0)); - auto u = make_field("u", mesh); - - u.fill(1.0); - - for (auto _ : state) - { - samurai::make_bc(u); - } -} + using Config = samurai::UniformConfig; // Utilisation de l'ordre comme paramètre + auto mesh = samurai::UniformMesh(box, state.range(0)); + auto u = make_field("u", mesh); -// Test BC sur une direction spécifique -template -void BC_directional(benchmark::State& state) -{ - samurai::Box box = unitary_box(); - using Config = samurai::UniformConfig; - auto mesh = samurai::UniformMesh(box, state.range(0)); - auto u = make_field("u", mesh); - u.fill(1.0); - + + // Ajout des compteurs personnalisés + state.counters["Dimension"] = dim; + state.counters["Composantes"] = n_comp; + state.counters["Ordre"] = order; + state.counters["Type BC"] = std::is_same_v> ? 0 : 1; // 0 pour Dirichlet, 1 pour Neumann + for (auto _ : state) { - if constexpr (dim == 1) - { - const xt::xtensor_fixed> left{-1}; - samurai::make_bc(u)->on(left); - } - else if constexpr (dim == 2) - { - const xt::xtensor_fixed> left{-1, 0}; - samurai::make_bc(u)->on(left); - } - else if constexpr (dim == 3) - { - const xt::xtensor_fixed> left{-1, 0, 0}; - samurai::make_bc(u)->on(left); - } + samurai::make_bc(u); } } @@ -111,12 +86,3 @@ BENCHMARK_TEMPLATE(BC_homogeneous, 1, 1, samurai::Dirichlet<2>, 3)->DenseRange(1 BENCHMARK_TEMPLATE(BC_homogeneous, 2, 1, samurai::Dirichlet<2>, 3)->DenseRange(1, 1); BENCHMARK_TEMPLATE(BC_homogeneous, 3, 1, samurai::Dirichlet<2>, 3)->DenseRange(1, 1); BENCHMARK_TEMPLATE(BC_homogeneous, 1, 100, samurai::Dirichlet<2>, 3)->DenseRange(1, 1); - -// BC directionnels -BENCHMARK_TEMPLATE(BC_directional, 1, 1, samurai::Dirichlet<1>, 1)->DenseRange(1, 1); -BENCHMARK_TEMPLATE(BC_directional, 2, 1, samurai::Dirichlet<1>, 1)->DenseRange(1, 1); -BENCHMARK_TEMPLATE(BC_directional, 3, 1, samurai::Dirichlet<1>, 1)->DenseRange(1, 1); - - - - diff --git a/benchmark/benchmark_cell.cpp b/benchmark/benchmark_cell.cpp index c8fcda5fd..e7aa6217d 100644 --- a/benchmark/benchmark_cell.cpp +++ b/benchmark/benchmark_cell.cpp @@ -24,18 +24,18 @@ auto make_cell() { using value_t = samurai::default_config::value_t; using point_t = xt::xtensor_fixed>; - + // Initialisation générique des indices et du point de départ point_t indice = xt::ones({dim}); - point_t begin = xt::zeros({dim}); - - auto indices = xt::xtensor_fixed>(indice); + point_t begin = xt::zeros({dim}); + + auto indices = xt::xtensor_fixed>(indice); double scaling_factor = 1.0; - return samurai::Cell>(begin, scaling_factor, 1, indices, 0); + auto c = samurai::Cell>(begin, scaling_factor, 1, indices, 0); + return c; } // Mesure : Construction d'une cellule par défaut -// Cette fonction mesure le temps nécessaire pour créer une cellule sans paramètres template void CELL_default(benchmark::State& state) { @@ -121,7 +121,6 @@ void CELL_corner(benchmark::State& state) } // Mesure : Test d'égalité entre deux cellules -// Cette fonction mesure le temps nécessaire pour comparer deux cellules identiques template void CELL_equal(benchmark::State& state) { diff --git a/benchmark/benchmark_cellarray.cpp b/benchmark/benchmark_cellarray.cpp index 30b37e17d..de764ca47 100644 --- a/benchmark/benchmark_cellarray.cpp +++ b/benchmark/benchmark_cellarray.cpp @@ -1,6 +1,7 @@ #include #include +#include #include #include @@ -23,21 +24,53 @@ // utils template -auto cell_list_with_n_intervals(int64_t size) +auto gen_regular_intervals = [](int64_t size, unsigned int level = 0) { samurai::CellList cl; + for (int64_t i = 0; i < size; i++) { int index = static_cast(i); - cl[0][{}].add_interval({2 * index, 2 * index + 1}); + + // Calcul des paramètres selon le niveau : + // Niveau L : taille = 2^L, espacement = 2^(L+1) + int interval_size = 1 << level; // 2^level + int spacing = 1 << (level + 1); // 2^(level+1) + int start = index * spacing; + int end = start + interval_size; + + if constexpr (dim == 1) + { + cl[level][{}].add_interval({start, end}); + } + else if constexpr (dim == 2) + { + for (int y = 0; y < size; ++y) + { + xt::xtensor_fixed> coord{y}; + cl[level][coord].add_interval({start, end}); + } + } + else if constexpr (dim == 3) + { + for (int y = 0; y < size; ++y) + { + for (int z = 0; z < size; ++z) + { + xt::xtensor_fixed> coord{y, z}; + cl[level][coord].add_interval({start, end}); + } + } + } } + return cl; -} +}; template auto cell_array_with_n_intervals(int64_t size) { - auto cl = cell_list_with_n_intervals(size); + auto cl = gen_regular_intervals(size); samurai::CellArray ca(cl); return ca; } @@ -58,12 +91,22 @@ void CELLARRAY_default(benchmark::State& state) template void CELLARRAY_cl_ca_multi(benchmark::State& state) { - auto cl = cell_list_with_n_intervals(state.range(0)); + auto cl = gen_regular_intervals(state.range(0)); + + // Le nombre d'intervalles est state.range(0)^dim + std::size_t nb_intervals = static_cast(std::pow(state.range(0), dim)); + for (auto _ : state) { samurai::CellArray ca(cl); benchmark::DoNotOptimize(ca[0]); } + + // Ajouter les compteurs + state.counters["nb_intervals"] = nb_intervals; + state.counters["ns/interval"] = benchmark::Counter(nb_intervals, + benchmark::Counter::kIsIterationInvariantRate | benchmark::Counter::kInvert); + state.counters["dim"] = dim; } // Mesure : Récupération du niveau bas d'un CellList @@ -71,6 +114,7 @@ template void CELLARRAY_min_level(benchmark::State& state) { samurai::CellList cl; + cl[state.range(0)][{}].add_interval({0, 1}); samurai::CellArray ca(cl); for (auto _ : state) @@ -85,7 +129,10 @@ template void CELLARRAY_begin(benchmark::State& state) { samurai::CellList cl; - cl[state.range(0)][{}].add_interval({0, 1}); + for (int level = 0; level <= state.range(0); ++level) + { + cl[level][{}].add_interval({0, 1}); + } samurai::CellArray ca(cl); for (auto _ : state) { @@ -99,141 +146,34 @@ template void CELLARRAY_end(benchmark::State& state) { samurai::CellList cl; - cl[state.range(0)][{}].add_interval({0, 1}); - samurai::CellArray ca(cl); - for (auto _ : state) + for (int level = 0; level <= state.range(0); ++level) { - auto end = ca.end(); - benchmark::DoNotOptimize(end); + cl[level][{}].add_interval({0, 1}); } -} - -// Mesure : Récupération de l'itérateur reverse begin d'un CellArray -template -void CELLARRAY_rbegin(benchmark::State& state) -{ - samurai::CellList cl; - cl[state.range(0)][{}].add_interval({0, 1}); samurai::CellArray ca(cl); for (auto _ : state) { - auto rbegin = ca.rbegin(); - benchmark::DoNotOptimize(rbegin); - } -} - -// Mesure : Création d'un CellArray 2D à partid d'un CellList composé de n intervalles aléatoires -// Ressemble à CELLARRAY_cl_ca_multi -static void CELLARRAY_CellList2CellArray_2D(benchmark::State& state) -{ - constexpr std::size_t dim = 2; - - std::size_t min_level = 1; - std::size_t max_level = 12; - - samurai::CellList cl; - samurai::CellArray ca; - - for (std::size_t s = 0; s < state.range(0); ++s) - { - auto level = std::experimental::randint(min_level, max_level); - auto x = std::experimental::randint(0, (100 << level) - 1); - auto y = std::experimental::randint(0, (100 << level) - 1); - - cl[level][{y}].add_point(x); - } - - for (auto _ : state) - { - ca = {cl}; - } -} - -BENCHMARK(CELLARRAY_CellList2CellArray_2D)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); - -// Mesure : Création d'un CellArray 3D à partid d'un CellList composé de n intervalles aléatoires -// Ressemble à CELLARRAY_cl_ca_multi -static void CELLARRAY_CellList2CellArray_3D(benchmark::State& state) -{ - constexpr std::size_t dim = 3; - - std::size_t min_level = 1; - std::size_t max_level = 12; - - samurai::CellList cl; - samurai::CellArray ca; - - for (std::size_t s = 0; s < state.range(0); ++s) - { - auto level = std::experimental::randint(min_level, max_level); - auto x = std::experimental::randint(0, (100 << level) - 1); - auto y = std::experimental::randint(0, (100 << level) - 1); - auto z = std::experimental::randint(0, (100 << level) - 1); - - cl[level][{y, z}].add_point(x); - } - - for (auto _ : state) - { - ca = {cl}; - } -} - -BENCHMARK(CELLARRAY_CellList2CellArray_3D)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); - -// Mesure : Comparaison "=" entre deux CellArray aléatoires -// On ne devrait pas utiliser un CellArray aléatoire. -static void CELLARRAY_equal_2D(benchmark::State& state) -{ - constexpr std::size_t dim = 2; - - std::size_t min_level = 1; - std::size_t max_level = 12; - - samurai::CellList cl; - samurai::CellArray ca; - samurai::CellArray ca2; - - for (std::size_t s = 0; s < state.range(0); ++s) - { - auto level = std::experimental::randint(min_level, max_level); - auto x = std::experimental::randint(0, (100 << level) - 1); - auto y = std::experimental::randint(0, (100 << level) - 1); - - cl[level][{y}].add_point(x); - } - ca = {cl}; - ca2 = {cl}; - - for (auto _ : state) - { - auto equal = ca == ca2; - benchmark::DoNotOptimize(equal); + auto end = ca.end(); + benchmark::DoNotOptimize(end); } } -BENCHMARK(CELLARRAY_equal_2D)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); - BENCHMARK_TEMPLATE(CELLARRAY_default, 1, 12); BENCHMARK_TEMPLATE(CELLARRAY_default, 2, 12); BENCHMARK_TEMPLATE(CELLARRAY_default, 3, 12); -BENCHMARK_TEMPLATE(CELLARRAY_cl_ca_multi, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(CELLARRAY_cl_ca_multi, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(CELLARRAY_cl_ca_multi, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); - -BENCHMARK_TEMPLATE(CELLARRAY_min_level, 1)->DenseRange(0, 15); -BENCHMARK_TEMPLATE(CELLARRAY_min_level, 2)->DenseRange(0, 15); -BENCHMARK_TEMPLATE(CELLARRAY_min_level, 3)->DenseRange(0, 15); +BENCHMARK_TEMPLATE(CELLARRAY_cl_ca_multi, 1)->RangeMultiplier(8)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(CELLARRAY_cl_ca_multi, 2)->RangeMultiplier(4)->Range(1 << 1, 1 << 6); +BENCHMARK_TEMPLATE(CELLARRAY_cl_ca_multi, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 4); -BENCHMARK_TEMPLATE(CELLARRAY_begin, 1)->DenseRange(0, 15); -BENCHMARK_TEMPLATE(CELLARRAY_begin, 2)->DenseRange(0, 15); -BENCHMARK_TEMPLATE(CELLARRAY_begin, 3)->DenseRange(0, 15); +BENCHMARK_TEMPLATE(CELLARRAY_min_level, 1)->Arg(15); +BENCHMARK_TEMPLATE(CELLARRAY_min_level, 2)->Arg(15); +BENCHMARK_TEMPLATE(CELLARRAY_min_level, 3)->Arg(15); -BENCHMARK_TEMPLATE(CELLARRAY_rbegin, 1)->DenseRange(0, 15); -BENCHMARK_TEMPLATE(CELLARRAY_rbegin, 2)->DenseRange(0, 15); -BENCHMARK_TEMPLATE(CELLARRAY_rbegin, 3)->DenseRange(0, 15); +BENCHMARK_TEMPLATE(CELLARRAY_begin, 1)->Arg(15); +BENCHMARK_TEMPLATE(CELLARRAY_begin, 2)->Arg(15); +BENCHMARK_TEMPLATE(CELLARRAY_begin, 3)->Arg(15); -BENCHMARK_TEMPLATE(CELLARRAY_end, 1)->DenseRange(0, 15); -BENCHMARK_TEMPLATE(CELLARRAY_end, 2)->DenseRange(0, 15); -BENCHMARK_TEMPLATE(CELLARRAY_end, 3)->DenseRange(0, 15); +BENCHMARK_TEMPLATE(CELLARRAY_end, 1)->Arg(15); +BENCHMARK_TEMPLATE(CELLARRAY_end, 2)->Arg(15); +BENCHMARK_TEMPLATE(CELLARRAY_end, 3)->Arg(15); diff --git a/benchmark/benchmark_celllist_construction.cpp b/benchmark/benchmark_celllist_construction.cpp index 756fc0a93..f5f51e142 100644 --- a/benchmark/benchmark_celllist_construction.cpp +++ b/benchmark/benchmark_celllist_construction.cpp @@ -1,240 +1,173 @@ - #include #include +#include + #include #include -// Utils : Créer un cell_list composé de n intervales dans une direction +//////////////////////////////////////////////////////////// +/// Générateur d'intervalles réguliers (adapté de benchmark_search.cpp) + template -auto cell_list_with_n_intervals(int64_t size) +auto gen_regular_intervals = [](int64_t size, unsigned int level = 0) { samurai::CellList cl; + for (int64_t i = 0; i < size; i++) { int index = static_cast(i); - cl[0][{}].add_interval({2 * index, 2 * index + 1}); - } - return cl; -} - -/////////////////////////////////// -// Mesure : constructeur CellList par defaut -template -void CELLLIST_default(benchmark::State& state) -{ - for (auto _ : state) - { - samurai::CellList cl = samurai::CellList(); - benchmark::DoNotOptimize(cl); - } -} + // Calcul des paramètres selon le niveau : + // Niveau L : taille = 2^L, espacement = 2^(L+1) + int interval_size = 1 << level; // 2^level + int spacing = 1 << (level + 1); // 2^(level+1) + int start = index * spacing; + int end = start + interval_size; -// Mesure : Création d'un CellList construit par n intervales croissants -template -void CELLLIST_cl_add_interval_end(benchmark::State& state) -{ - samurai::CellList cl; - for (auto _ : state) - { - for (int64_t i = 0; i < state.range(0); i++) + if constexpr (dim == 1) { - int index = static_cast(i); - cl[0][{}].add_interval({index, index + 1}); + cl[level][{}].add_interval({start, end}); } - } -} - -// Mesure : Création d'un CellList construit par n intervales décroissants -template -void CELLLIST_cl_add_interval_begin(benchmark::State& state) -{ - samurai::CellList cl; - for (auto _ : state) - { - for (int64_t i = state.range(0); i > 0; i--) + else if constexpr (dim == 2) { - int index = static_cast(i); - cl[0][{}].add_interval({index, index + 1}); + for (int y = 0; y < size; ++y) + { + xt::xtensor_fixed> coord{y}; + cl[level][coord].add_interval({start, end}); + } } - } -} - -// Mesure : Création d'un CellList composé de n fois le même interval -template -void CELLLIST_cl_add_interval_same(benchmark::State& state) -{ - samurai::CellList cl; - for (auto _ : state) - { - for (int64_t i = state.range(0); i > 0; i--) + else if constexpr (dim == 3) { - cl[0][{}].add_interval({0, 1}); + for (int y = 0; y < size; ++y) + { + for (int z = 0; z < size; ++z) + { + xt::xtensor_fixed> coord{y, z}; + cl[level][coord].add_interval({start, end}); + } + } } } -} -// Mesure : Création d'un CellList composé de n points (1 seul interval) + return cl; +}; + +// Ancien générateur simple (1D seulement) template -void CELLLIST_cl_add_point_end(benchmark::State& state) +auto cell_list_with_n_intervals(int64_t size) { samurai::CellList cl; - for (auto _ : state) + for (int64_t i = 0; i < size; i++) { - for (int64_t i = 0; i < state.range(0); i++) - { - int index = static_cast(i); - cl[0][{}].add_point({index}); - } + int index = static_cast(i); + cl[0][{}].add_interval({2 * index, 2 * index + 1}); } + return cl; } -// Mesure : Création de n intervales aléatoires - permet de controler le cout du générateur d'aléatoire pour le prochain benchmark -static void CELLLIST_CellListConstruction_2D_rand_control(benchmark::State& state) +// Générateur avec points individuels (1D seulement) - stride de 2 +template +auto cell_list_with_n_points(int64_t size) { - constexpr std::size_t dim = 2; - - std::size_t min_level = 1; - std::size_t max_level = 12; - samurai::CellList cl; - - for (auto _ : state) + for (int64_t i = 0; i < size; i++) { - for (std::size_t s = 0; s < state.range(0); ++s) - { - auto level = std::experimental::randint(min_level, max_level); - auto x = std::experimental::randint(0, (100 << level) - 1); - auto y = std::experimental::randint(0, (100 << level) - 1); - - benchmark::DoNotOptimize(level); - benchmark::DoNotOptimize(x); - benchmark::DoNotOptimize(y); - } + int index = static_cast(i); + cl[0][{}].add_point(2 * index); // stride de 2: 0, 2, 4, 6, etc. } + return cl; } -BENCHMARK(CELLLIST_CellListConstruction_2D_rand_control)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +//////////////////////////////////////////////////////////// +/// Fonction utilitaire pour compter les intervalles -// Mesure : Création d'un CellList composé de n intervales aléatoires en 2D -static void CELLLIST_CellListConstruction_2D(benchmark::State& state) +template +std::size_t count_intervals(const samurai::CellList& cl) { - constexpr std::size_t dim = 2; - - std::size_t min_level = 1; - std::size_t max_level = 12; - - for (auto _ : state) - { - samurai::CellList cl; - for (std::size_t s = 0; s < state.range(0); ++s) - { - auto level = std::experimental::randint(min_level, max_level); - auto x = std::experimental::randint(0, (100 << level) - 1); - auto y = std::experimental::randint(0, (100 << level) - 1); - - cl[level][{y}].add_point(x); - } - } + std::size_t count = 0; + samurai::CellArray ca(cl); + samurai::for_each_interval(ca, + [&](std::size_t, const auto&, const auto&) + { + count++; + }); + return count; } -BENCHMARK(CELLLIST_CellListConstruction_2D)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +/////////////////////////////////// -// Mesure : Création d'un CellList composé de n intervales aléaoires en 3D -static void CELLLIST_CellListConstruction_3D(benchmark::State& state) +// Mesure : constructeur CellList par défaut +template +void CELLLIST_default(benchmark::State& state) { - constexpr std::size_t dim = 3; - - std::size_t min_level = 1; - std::size_t max_level = 12; - for (auto _ : state) { samurai::CellList cl; - for (std::size_t s = 0; s < state.range(0); ++s) - { - auto level = std::experimental::randint(min_level, max_level); - auto x = std::experimental::randint(0, (100 << level) - 1); - auto y = std::experimental::randint(0, (100 << level) - 1); - auto z = std::experimental::randint(0, (100 << level) - 1); - - cl[level][{y, z}].add_point(x); - } + benchmark::DoNotOptimize(cl); } -} -BENCHMARK(CELLLIST_CellListConstruction_3D)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); + state.counters["dimension"] = static_cast(dim); + state.counters["intervals"] = 0; +} -// Not a good way to benchmark -// because the benchmark result depends on the option --benchmark_min_time -// that's because cl is not reinitialized for each state.range measure. -// thus the insertion in std::map is slower because larger and larger -// I provide a fix that puts cl in for state loop. -// We measure the cors of its declaration, you have to substract to have what you really want :-) -/** -static void BM_CellListConstruction_2D(benchmark::State& state) -{ - constexpr std::size_t dim = 2; +// Mesure : Construction CellList avec intervalles réguliers (ordre décroissant - begin) - std::size_t min_level = 1; - std::size_t max_level = 12; +// Mesure : Construction CellList avec le même intervalle répété (same) - samurai::CellList cl; +// Mesure : Construction CellList avec intervalles réguliers +template +void CELLLIST_add_interval_begin(benchmark::State& state) +{ + // Calculer une seule fois pour les métriques + auto cl_sample = gen_regular_intervals(state.range(0), 0); + std::size_t total_intervals = count_intervals(cl_sample); for (auto _ : state) { - for (std::size_t s = 0; s < state.range(0); ++s) - { - auto level = std::experimental::randint(min_level, max_level); - auto x = std::experimental::randint(0, (100 << level) - 1); - auto y = std::experimental::randint(0, (100 << level) - 1); - - cl[level][{y}].add_point(x); - } + auto cl = gen_regular_intervals(state.range(0), 0); + benchmark::DoNotOptimize(cl); } -} -BENCHMARK(BM_CellListConstruction_2D)->Range(8, 8 << 18); + state.counters["dimension"] = static_cast(dim); + state.counters["intervals"] = static_cast(total_intervals); + state.counters["ns/interval"] = benchmark::Counter(total_intervals, + benchmark::Counter::kIsIterationInvariantRate | benchmark::Counter::kInvert); +} -static void BM_CellListConstruction_3D(benchmark::State& state) +// Mesure : Copie de CellList par opérateur d'assignation +template +void CELLLIST_copy_assignment(benchmark::State& state) { - constexpr std::size_t dim = 3; - - std::size_t min_level = 1; - std::size_t max_level = 12; - - samurai::CellList cl; + auto source_cl = gen_regular_intervals(state.range(0), 0); + std::size_t total_intervals = count_intervals(source_cl); for (auto _ : state) { - for (std::size_t s = 0; s < state.range(0); ++s) - { - auto level = std::experimental::randint(min_level, max_level); - auto x = std::experimental::randint(0, (100 << level) - 1); - auto y = std::experimental::randint(0, (100 << level) - 1); - auto z = std::experimental::randint(0, (100 << level) - 1); - - cl[level][{y, z}].add_point(x); - } + samurai::CellList copied_cl; + copied_cl = source_cl; + benchmark::DoNotOptimize(copied_cl); } + + state.counters["dimension"] = static_cast(dim); + state.counters["intervals"] = static_cast(total_intervals); + state.counters["ns/interval"] = benchmark::Counter(total_intervals, + benchmark::Counter::kIsIterationInvariantRate | benchmark::Counter::kInvert); } -BENCHMARK(BM_CellListConstruction_3D)->Range(8, 8 << 18); -**/ +//////////////////////////////////////////////////////////// +/// Enregistrement des benchmarks +// Constructeur par défaut BENCHMARK_TEMPLATE(CELLLIST_default, 1); BENCHMARK_TEMPLATE(CELLLIST_default, 2); BENCHMARK_TEMPLATE(CELLLIST_default, 3); -BENCHMARK_TEMPLATE(CELLLIST_cl_add_interval_end, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(CELLLIST_cl_add_interval_end, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(CELLLIST_cl_add_interval_end, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); - -BENCHMARK_TEMPLATE(CELLLIST_cl_add_interval_begin, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); - -BENCHMARK_TEMPLATE(CELLLIST_cl_add_interval_same, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +// Générateur avec intervalles réguliers (toutes dimensions) +BENCHMARK_TEMPLATE(CELLLIST_add_interval_begin, 1)->RangeMultiplier(64)->Range(1 << 1, 1 << 16); +BENCHMARK_TEMPLATE(CELLLIST_add_interval_begin, 2)->RangeMultiplier(8)->Range(1 << 1, 1 << 8); +BENCHMARK_TEMPLATE(CELLLIST_add_interval_begin, 3)->RangeMultiplier(4)->Range(1 << 1, 1 << 5); -BENCHMARK_TEMPLATE(CELLLIST_cl_add_point_end, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(CELLLIST_cl_add_point_end, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(CELLLIST_cl_add_point_end, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(CELLLIST_copy_assignment, 1)->RangeMultiplier(64)->Range(1 << 1, 1 << 16); +BENCHMARK_TEMPLATE(CELLLIST_copy_assignment, 2)->RangeMultiplier(8)->Range(1 << 1, 1 << 8); +BENCHMARK_TEMPLATE(CELLLIST_copy_assignment, 3)->RangeMultiplier(4)->Range(1 << 1, 1 << 5); diff --git a/benchmark/benchmark_field.cpp b/benchmark/benchmark_field.cpp index f90e1c74e..709e880b5 100644 --- a/benchmark/benchmark_field.cpp +++ b/benchmark/benchmark_field.cpp @@ -1,4 +1,3 @@ - #include #include #include @@ -17,4 +16,409 @@ #include #include +/// utils +template +auto unitary_box() +{ + using value_t = samurai::default_config::value_t; + using point_t = xt::xtensor_fixed>; + point_t point1; + point_t point2; + if constexpr (dim == 1) + { + point1 = {0}; + point2 = {1}; + } + if constexpr (dim == 2) + { + point1 = {0, 0}; + point2 = {1, 1}; + } + if constexpr (dim == 3) + { + point1 = {0, 0, 0}; + point2 = {1, 1, 1}; + } + + samurai::Box box = samurai::Box(point1, point2); + return box; +} + +/// field creation wrapper +template +auto make_field_wrapper(const std::string& name, mesh_t& mesh) +{ + if constexpr (n_comp == 1) + { + return samurai::make_scalar_field(name, mesh); + } + else + { + return samurai::make_vector_field(name, mesh); + } +} + +// Mesure : Allocation d'un champ d'un maillage uniforme de taille de coté n +template +void FIELD_make_field_uniform(benchmark::State& state) +{ + samurai::Box box = unitary_box(); + using Config = samurai::UniformConfig; + auto mesh = samurai::UniformMesh(box, state.range(0)); + + // Ajouter les statistiques + auto total_cells = mesh.nb_cells(); + state.counters["Dimension"] = dim; + state.counters["Mesh_level"] = state.range(0); + state.counters["Total_cells"] = total_cells; + state.counters["Components"] = n_comp; + state.counters["ns/cell"] = benchmark::Counter(total_cells, benchmark::Counter::kIsIterationInvariantRate | benchmark::Counter::kInvert); + + for (auto _ : state) + { + auto u = make_field_wrapper("u", mesh); + benchmark::DoNotOptimize(u.array()); + } +} + +// Mesure : Remplissage d'un champ 1D de taille de coté n +template +void FIELD_fill_uniform(benchmark::State& state) +{ + samurai::Box box = unitary_box(); + using Config = samurai::UniformConfig; + auto mesh = samurai::UniformMesh(box, state.range(0)); + auto u = make_field_wrapper("u", mesh); + + // Ajouter les statistiques + auto total_cells = mesh.nb_cells(); + state.counters["Dimension"] = dim; + state.counters["Mesh_level"] = state.range(0); + state.counters["Total_cells"] = total_cells; + state.counters["Components"] = n_comp; + state.counters["ns/cell"] = benchmark::Counter(total_cells, benchmark::Counter::kIsIterationInvariantRate | benchmark::Counter::kInvert); + + for (auto _ : state) + { + u.fill(1.0); + } +} + +// Mesure ; Remplissage d'un champ 1D de taille de coté n ,en utilisant for_each_cell (mesure d'overhead) +template +void FIELD_for_each_cell_fill_uniform(benchmark::State& state) +{ + samurai::Box box = unitary_box(); + using Config = samurai::UniformConfig; + auto mesh = samurai::UniformMesh(box, state.range(0)); + auto u = make_field_wrapper("u", mesh); + + // Ajouter les statistiques + auto total_cells = mesh.nb_cells(); + state.counters["Dimension"] = dim; + state.counters["Mesh_level"] = state.range(0); + state.counters["Total_cells"] = total_cells; + state.counters["Components"] = n_comp; + state.counters["ns/cell"] = benchmark::Counter(total_cells, benchmark::Counter::kIsIterationInvariantRate | benchmark::Counter::kInvert); + + for (auto _ : state) + { + for_each_cell(mesh, + [&](auto cell) + { + u[cell] = 1.0; + }); + } +} + +// Weird : MPI issue ??? wtf ??? +template +void FIELD_equal_uniform(benchmark::State& state) +{ + samurai::Box box = unitary_box(); + using Config = samurai::UniformConfig; + auto mesh = samurai::UniformMesh(box, state.range(0)); + auto u = make_field_wrapper<1>(std::string("u"), mesh); + auto v = make_field_wrapper<1>(std::string("v"), mesh); + u.fill(1.0); + + // Ajouter les statistiques + auto total_cells = mesh.nb_cells(); + state.counters["Dimension"] = dim; + state.counters["Mesh_level"] = state.range(0); + state.counters["Total_cells"] = total_cells; + state.counters["ns/cell"] = benchmark::Counter(total_cells, benchmark::Counter::kIsIterationInvariantRate | benchmark::Counter::kInvert); + + for (auto _ : state) + { + v = u; + } +} + +// Mesure : Ajout d'un scalaire à un champ par broadcasting +template +void FIELD_add_scalar_uniform(benchmark::State& state) +{ + samurai::Box box = unitary_box(); + using Config = samurai::UniformConfig; + auto mesh = samurai::UniformMesh(box, state.range(0)); + auto u = make_field_wrapper("u", mesh); + u.fill(1.0); + auto v = make_field_wrapper("v", mesh); + + // Ajouter les statistiques + auto total_cells = mesh.nb_cells(); + state.counters["Dimension"] = dim; + state.counters["Mesh_level"] = state.range(0); + state.counters["Total_cells"] = total_cells; + state.counters["Components"] = n_comp; + state.counters["ns/cell"] = benchmark::Counter(total_cells, benchmark::Counter::kIsIterationInvariantRate | benchmark::Counter::kInvert); + + for (auto _ : state) + { + v = u + 2.0; + benchmark::DoNotOptimize(v[0]); + } +} + +// Mesure : Ajout d'un scalaire à un champ par "for_each_cell" +template +void FIELD_for_each_cell_add_scalar_uniform(benchmark::State& state) +{ + samurai::Box box = unitary_box(); + using Config = samurai::UniformConfig; + auto mesh = samurai::UniformMesh(box, state.range(0)); + auto u = make_field_wrapper("u", mesh); + u.fill(1.0); + auto v = make_field_wrapper("v", mesh); + + // Ajouter les statistiques + auto total_cells = mesh.nb_cells(); + state.counters["Dimension"] = dim; + state.counters["Mesh_level"] = state.range(0); + state.counters["Total_cells"] = total_cells; + state.counters["Components"] = n_comp; + state.counters["ns/cell"] = benchmark::Counter(total_cells, benchmark::Counter::kIsIterationInvariantRate | benchmark::Counter::kInvert); + + for (auto _ : state) + { + for_each_cell(mesh, + [&](auto cell) + { + v[cell] = u[cell] + 1.0; + }); + } +} + +// Mesure : Somme de deux champs 1D par expression +template +void FIELD_add_uniform(benchmark::State& state) +{ + samurai::Box box = unitary_box(); + using Config = samurai::UniformConfig; + auto mesh = samurai::UniformMesh(box, state.range(0)); + auto u = make_field_wrapper("u", mesh); + u.fill(1.0); + auto v = make_field_wrapper("v", mesh); + v.fill(1.0); + auto w = make_field_wrapper("w", mesh); + w.fill(0.0); + + // Ajouter les statistiques + auto total_cells = mesh.nb_cells(); + state.counters["Dimension"] = dim; + state.counters["Mesh_level"] = state.range(0); + state.counters["Total_cells"] = total_cells; + state.counters["Components"] = n_comp; + state.counters["ns/cell"] = benchmark::Counter(total_cells, benchmark::Counter::kIsIterationInvariantRate | benchmark::Counter::kInvert); + + for (auto _ : state) + { + w = u + v; + benchmark::DoNotOptimize(w[0]); + } +} + +// Mesure : Somme de deux champs 1D par "for_each_cell" +template +void FIELD_for_each_cell_add_uniform(benchmark::State& state) +{ + samurai::Box box = unitary_box(); + using Config = samurai::UniformConfig; + auto mesh = samurai::UniformMesh(box, state.range(0)); + auto u = make_field_wrapper("u", mesh); + u.fill(1.0); + auto v = make_field_wrapper("v", mesh); + auto w = make_field_wrapper("w", mesh); + w.fill(0.0); + + // Ajouter les statistiques + auto total_cells = mesh.nb_cells(); + state.counters["Dimension"] = dim; + state.counters["Mesh_level"] = state.range(0); + state.counters["Total_cells"] = total_cells; + state.counters["Components"] = n_comp; + state.counters["ns/cell"] = benchmark::Counter(total_cells, benchmark::Counter::kIsIterationInvariantRate | benchmark::Counter::kInvert); + + for (auto _ : state) + { + for_each_cell(mesh, + [&](auto cell) + { + w[cell] = u[cell] + v[cell]; + }); + } +} + +// Mesure : Expression complexe avec plusieurs opérations arithmétiques +template +void FIELD_complex_expression_uniform(benchmark::State& state) +{ + samurai::Box box = unitary_box(); + using Config = samurai::UniformConfig; + auto mesh = samurai::UniformMesh(box, state.range(0)); + + // Création des champs + auto v = make_field_wrapper("v", mesh); + auto w = make_field_wrapper("w", mesh); + auto x = make_field_wrapper("x", mesh); + auto z = make_field_wrapper("z", mesh); + auto u = make_field_wrapper("u", mesh); + + // Initialisation des champs + v.fill(1.0); + w.fill(2.0); + x.fill(3.0); + z.fill(4.0); // z non nul + u.fill(0.0); + + // Ajouter les statistiques + auto total_cells = mesh.nb_cells(); + state.counters["Dimension"] = dim; + state.counters["Mesh_level"] = state.range(0); + state.counters["Total_cells"] = total_cells; + state.counters["Components"] = n_comp; + state.counters["ns/cell"] = benchmark::Counter(total_cells, benchmark::Counter::kIsIterationInvariantRate | benchmark::Counter::kInvert); + + for (auto _ : state) + { + u = 2.0 + v + (w * x) / z; + benchmark::DoNotOptimize(u[0]); + } +} + +// Mesure : Expression complexe avec plusieurs opérations arithmétiques (version for_each_cell) +template +void FIELD_for_each_cell_complex_expression_uniform(benchmark::State& state) +{ + samurai::Box box = unitary_box(); + using Config = samurai::UniformConfig; + auto mesh = samurai::UniformMesh(box, state.range(0)); + + // Création des champs + auto v = make_field_wrapper("v", mesh); + auto w = make_field_wrapper("w", mesh); + auto x = make_field_wrapper("x", mesh); + auto z = make_field_wrapper("z", mesh); + auto u = make_field_wrapper("u", mesh); + + // Initialisation des champs + v.fill(1.0); + w.fill(2.0); + x.fill(3.0); + z.fill(4.0); // z non nul + u.fill(0.0); + + // Ajouter les statistiques + auto total_cells = mesh.nb_cells(); + state.counters["Dimension"] = dim; + state.counters["Mesh_level"] = state.range(0); + state.counters["Total_cells"] = total_cells; + state.counters["Components"] = n_comp; + state.counters["ns/cell"] = benchmark::Counter(total_cells, benchmark::Counter::kIsIterationInvariantRate | benchmark::Counter::kInvert); + + for (auto _ : state) + { + for_each_cell(mesh, + [&](auto cell) + { + u[cell] = 2.0 + v[cell] + (w[cell] * x[cell]) / z[cell]; + }); + } +} + +BENCHMARK_TEMPLATE(FIELD_make_field_uniform, 1, 1)->Arg(16); +BENCHMARK_TEMPLATE(FIELD_make_field_uniform, 2, 1)->Arg(8); +BENCHMARK_TEMPLATE(FIELD_make_field_uniform, 3, 1)->Arg(5); + +BENCHMARK_TEMPLATE(FIELD_make_field_uniform, 1, 4)->Arg(16); +BENCHMARK_TEMPLATE(FIELD_make_field_uniform, 2, 4)->Arg(8); +BENCHMARK_TEMPLATE(FIELD_make_field_uniform, 3, 4)->Arg(5); + +BENCHMARK_TEMPLATE(FIELD_fill_uniform, 1, 1)->Arg(16); +BENCHMARK_TEMPLATE(FIELD_fill_uniform, 2, 1)->Arg(8); +BENCHMARK_TEMPLATE(FIELD_fill_uniform, 3, 1)->Arg(5); + +BENCHMARK_TEMPLATE(FIELD_fill_uniform, 1, 4)->Arg(16); +BENCHMARK_TEMPLATE(FIELD_fill_uniform, 2, 4)->Arg(8); +BENCHMARK_TEMPLATE(FIELD_fill_uniform, 3, 4)->Arg(5); + +BENCHMARK_TEMPLATE(FIELD_for_each_cell_fill_uniform, 1, 1)->Arg(16); +BENCHMARK_TEMPLATE(FIELD_for_each_cell_fill_uniform, 2, 1)->Arg(8); +BENCHMARK_TEMPLATE(FIELD_for_each_cell_fill_uniform, 3, 1)->Arg(5); + +BENCHMARK_TEMPLATE(FIELD_for_each_cell_fill_uniform, 1, 4)->Arg(16); +BENCHMARK_TEMPLATE(FIELD_for_each_cell_fill_uniform, 2, 4)->Arg(8); +BENCHMARK_TEMPLATE(FIELD_for_each_cell_fill_uniform, 3, 4)->Arg(5); + +BENCHMARK_TEMPLATE(FIELD_equal_uniform, 1)->Arg(16); +BENCHMARK_TEMPLATE(FIELD_equal_uniform, 2)->Arg(8); +BENCHMARK_TEMPLATE(FIELD_equal_uniform, 3)->Arg(5); + +BENCHMARK_TEMPLATE(FIELD_add_scalar_uniform, 1, 1)->Arg(16); +BENCHMARK_TEMPLATE(FIELD_add_scalar_uniform, 2, 1)->Arg(8); +BENCHMARK_TEMPLATE(FIELD_add_scalar_uniform, 3, 1)->Arg(5); + +BENCHMARK_TEMPLATE(FIELD_add_scalar_uniform, 1, 4)->Arg(16); +BENCHMARK_TEMPLATE(FIELD_add_scalar_uniform, 2, 4)->Arg(8); +BENCHMARK_TEMPLATE(FIELD_add_scalar_uniform, 3, 4)->Arg(5); + +BENCHMARK_TEMPLATE(FIELD_for_each_cell_add_scalar_uniform, 1, 1)->Arg(16); +BENCHMARK_TEMPLATE(FIELD_for_each_cell_add_scalar_uniform, 2, 1)->Arg(8); +BENCHMARK_TEMPLATE(FIELD_for_each_cell_add_scalar_uniform, 3, 1)->Arg(5); + +BENCHMARK_TEMPLATE(FIELD_for_each_cell_add_scalar_uniform, 1, 4)->Arg(16); +BENCHMARK_TEMPLATE(FIELD_for_each_cell_add_scalar_uniform, 2, 4)->Arg(8); +BENCHMARK_TEMPLATE(FIELD_for_each_cell_add_scalar_uniform, 3, 4)->Arg(5); + +BENCHMARK_TEMPLATE(FIELD_add_uniform, 1, 1)->Arg(16); +BENCHMARK_TEMPLATE(FIELD_add_uniform, 2, 1)->Arg(8); +BENCHMARK_TEMPLATE(FIELD_add_uniform, 3, 1)->Arg(5); + +BENCHMARK_TEMPLATE(FIELD_add_uniform, 1, 4)->Arg(16); +BENCHMARK_TEMPLATE(FIELD_add_uniform, 2, 4)->Arg(8); +BENCHMARK_TEMPLATE(FIELD_add_uniform, 3, 4)->Arg(5); + +BENCHMARK_TEMPLATE(FIELD_for_each_cell_add_uniform, 1, 1)->Arg(16); +BENCHMARK_TEMPLATE(FIELD_for_each_cell_add_uniform, 2, 1)->Arg(8); +BENCHMARK_TEMPLATE(FIELD_for_each_cell_add_uniform, 3, 1)->Arg(5); + +BENCHMARK_TEMPLATE(FIELD_for_each_cell_add_uniform, 1, 4)->Arg(16); +BENCHMARK_TEMPLATE(FIELD_for_each_cell_add_uniform, 2, 4)->Arg(8); +BENCHMARK_TEMPLATE(FIELD_for_each_cell_add_uniform, 3, 4)->Arg(5); + +BENCHMARK_TEMPLATE(FIELD_complex_expression_uniform, 1, 1)->Arg(16); +BENCHMARK_TEMPLATE(FIELD_complex_expression_uniform, 2, 1)->Arg(8); +BENCHMARK_TEMPLATE(FIELD_complex_expression_uniform, 3, 1)->Arg(5); + +BENCHMARK_TEMPLATE(FIELD_complex_expression_uniform, 1, 4)->Arg(16); +BENCHMARK_TEMPLATE(FIELD_complex_expression_uniform, 2, 4)->Arg(8); +BENCHMARK_TEMPLATE(FIELD_complex_expression_uniform, 3, 4)->Arg(5); + +BENCHMARK_TEMPLATE(FIELD_for_each_cell_complex_expression_uniform, 1, 1)->Arg(16); +BENCHMARK_TEMPLATE(FIELD_for_each_cell_complex_expression_uniform, 2, 1)->Arg(8); +BENCHMARK_TEMPLATE(FIELD_for_each_cell_complex_expression_uniform, 3, 1)->Arg(5); +BENCHMARK_TEMPLATE(FIELD_for_each_cell_complex_expression_uniform, 1, 4)->Arg(16); +BENCHMARK_TEMPLATE(FIELD_for_each_cell_complex_expression_uniform, 2, 4)->Arg(8); +BENCHMARK_TEMPLATE(FIELD_for_each_cell_complex_expression_uniform, 3, 4)->Arg(5); diff --git a/benchmark/benchmark_level_cell_array.cpp b/benchmark/benchmark_level_cell_array.cpp index 3cfa28e86..bc1d5153f 100644 --- a/benchmark/benchmark_level_cell_array.cpp +++ b/benchmark/benchmark_level_cell_array.cpp @@ -1,4 +1,3 @@ - #include #include #include @@ -20,6 +19,115 @@ // Pourquoi -default est plus lent que _empty_lcl_to_lca en 2D/3D ?? // max_indices et min_indices très couteux : on peut pas faire mieux ?????? +/////////////////////////////////////////////////////////////////// +// utils + +template +auto gen_regular_intervals = [](auto& lcl, int index, unsigned int level) +{ + // Calcul des paramètres selon le niveau : + // Niveau L : taille = 2^L, espacement = 2^(L+1) + int interval_size = 1 << level; // 2^level + int spacing = 1 << (level + 1); // 2^(level+1) + int start = index * spacing; + int end = start + interval_size; + + if constexpr (dim == 1) + { + lcl[{}].add_interval({start, end}); + } + else if constexpr (dim == 2) + { + for (int y = 0; y < index; ++y) + { + lcl[{y}].add_interval({start, end}); + } + } + else if constexpr (dim == 3) + { + for (int y = 0; y < index; ++y) + { + for (int z = 0; z < index; ++z) + { + lcl[{y, z}].add_interval({start, end}); + } + } + } +}; + +template +auto gen_offset_intervals = [](auto& lcl, int index, unsigned int level) +{ + // Calcul des paramètres selon le niveau + int interval_size = 1 << level; // 2^level + int spacing = 1 << (level + 1); // 2^(level+1) + int start = index * spacing + interval_size; // Décalage d'une taille pour être disjoint des "same" + int end = start + interval_size; + + if constexpr (dim == 1) + { + lcl[{}].add_interval({start, end}); + } + else if constexpr (dim == 2) + { + for (int y = 0; y < index; ++y) + { + lcl[{y}].add_interval({start, end}); + } + } + else if constexpr (dim == 3) + { + for (int y = 0; y < index; ++y) + { + for (int z = 0; z < index; ++z) + { + lcl[{y, z}].add_interval({start, end}); + } + } + } +}; + +template +auto gen_unique_interval = [](auto& lcl, int index, unsigned int level) +{ + // Génère un seul grand intervalle qui grandit avec l'index + // Pour avoir une bounding box similaire aux autres générateurs, + // on crée un intervalle qui couvre plusieurs "espacements" + + int spacing = 1 << (level + 1); // 2^(level+1) + + // Créer un grand intervalle qui couvre (index+1) espacements complets + // Cela donne une taille proportionnelle à l'index, comme les autres générateurs + int interval_size = (index + 1) * spacing; + + if constexpr (dim == 1) + { + if (index == 0) + { + lcl[{}].add_interval({0, interval_size}); + } + } + else if constexpr (dim == 2) + { + for (int y = 0; y < index; ++y) + { + lcl[{y}].add_interval({0, interval_size}); + } + } + else if constexpr (dim == 3) + { + for (int y = 0; y < index; ++y) + { + for (int z = 0; z < index; ++z) + { + lcl[{y, z}].add_interval({0, interval_size}); + } + } + } +}; + +/////////////////////////////////////////////////////////////////// + // Mesure : Constructeur par défaut d'un LevelCellArray template void LEVELCELLARRAY_default(benchmark::State& state) @@ -54,8 +162,18 @@ void LEVELCELLARRAY_lcl_to_lca(benchmark::State& state) for (int64_t i = 0; i < state.range(0); i++) { int index = static_cast(i); - lcl[{0}].add_interval({2 * index, 2 * index + 1}); + gen_regular_intervals(lcl, index, 0); } + + // Créer un LevelCellArray temporaire pour compter les intervalles + auto temp_lca = samurai::LevelCellArray(lcl); + auto total_intervals = temp_lca.nb_intervals(); + + state.counters["Dimension"] = dim; + state.counters["Total_intervals"] = total_intervals; + state.counters["ns/interval"] = benchmark::Counter(total_intervals, + benchmark::Counter::kIsIterationInvariantRate | benchmark::Counter::kInvert); + for (auto _ : state) { auto lca = samurai::LevelCellArray(lcl); @@ -72,9 +190,10 @@ void LEVELCELLARRAY_begin(benchmark::State& state) for (int64_t i = 0; i < state.range(0); i++) { int index = static_cast(i); - lcl[{0}].add_interval({2 * index, 2 * index + 1}); + gen_regular_intervals(lcl, index, 0); } auto lca = samurai::LevelCellArray(lcl); + for (auto _ : state) { auto begin = lca.begin(); @@ -91,9 +210,10 @@ void LEVELCELLARRAY_end(benchmark::State& state) for (int64_t i = 0; i < state.range(0); i++) { int index = static_cast(i); - lcl[{0}].add_interval({2 * index, 2 * index + 1}); + gen_regular_intervals(lcl, index, 0); } auto lca = samurai::LevelCellArray(lcl); + for (auto _ : state) { auto end = lca.end(); @@ -110,9 +230,10 @@ void LEVELCELLARRAY_shape(benchmark::State& state) for (int64_t i = 0; i < state.range(0); i++) { int index = static_cast(i); - lcl[{0}].add_interval({2 * index, 2 * index + 1}); + gen_regular_intervals(lcl, index, 0); } auto lca = samurai::LevelCellArray(lcl); + for (auto _ : state) { auto shape = lca.shape(); @@ -129,9 +250,10 @@ void LEVELCELLARRAY_nb_intervals(benchmark::State& state) for (int64_t i = 0; i < state.range(0); i++) { int index = static_cast(i); - lcl[{0}].add_interval({2 * index, 2 * index + 1}); + gen_regular_intervals(lcl, index, 0); } auto lca = samurai::LevelCellArray(lcl); + for (auto _ : state) { auto nb = lca.nb_intervals(); @@ -148,9 +270,16 @@ void LEVELCELLARRAY_nb_cells(benchmark::State& state) for (int64_t i = 0; i < state.range(0); i++) { int index = static_cast(i); - lcl[{0}].add_interval({2 * index, 2 * index + 1}); + gen_regular_intervals(lcl, index, 0); } auto lca = samurai::LevelCellArray(lcl); + + auto total_intervals = lca.nb_intervals(); + state.counters["Dimension"] = dim; + state.counters["Total_intervals"] = total_intervals; + state.counters["ns/interval"] = benchmark::Counter(total_intervals, + benchmark::Counter::kIsIterationInvariantRate | benchmark::Counter::kInvert); + for (auto _ : state) { auto nb = lca.nb_cells(); @@ -167,7 +296,7 @@ void LEVELCELLARRAY_cell_length(benchmark::State& state) for (int64_t i = 0; i < state.range(0); i++) { int index = static_cast(i); - lcl[{0}].add_interval({2 * index, 2 * index + 1}); + gen_regular_intervals(lcl, index, 0); } auto lca = samurai::LevelCellArray(lcl); for (auto _ : state) @@ -186,9 +315,16 @@ void LEVELCELLARRAY_max_indices(benchmark::State& state) for (int64_t i = 0; i < state.range(0); i++) { int index = static_cast(i); - lcl[{0}].add_interval({2 * index, 2 * index + 1}); + gen_regular_intervals(lcl, index, 0); } auto lca = samurai::LevelCellArray(lcl); + + auto total_intervals = lca.nb_intervals(); + state.counters["Dimension"] = dim; + state.counters["Total_intervals"] = total_intervals; + state.counters["ns/interval"] = benchmark::Counter(total_intervals, + benchmark::Counter::kIsIterationInvariantRate | benchmark::Counter::kInvert); + for (auto _ : state) { auto max = lca.max_indices(); @@ -205,9 +341,16 @@ void LEVELCELLARRAY_min_indices(benchmark::State& state) for (int64_t i = 0; i < state.range(0); i++) { int index = static_cast(i); - lcl[{0}].add_interval({2 * index, 2 * index + 1}); + gen_regular_intervals(lcl, index, 0); } auto lca = samurai::LevelCellArray(lcl); + + auto total_intervals = lca.nb_intervals(); + state.counters["Dimension"] = dim; + state.counters["Total_intervals"] = total_intervals; + state.counters["ns/interval"] = benchmark::Counter(total_intervals, + benchmark::Counter::kIsIterationInvariantRate | benchmark::Counter::kInvert); + for (auto _ : state) { auto min = lca.min_indices(); @@ -224,9 +367,16 @@ void LEVELCELLARRAY_minmax_indices(benchmark::State& state) for (int64_t i = 0; i < state.range(0); i++) { int index = static_cast(i); - lcl[{0}].add_interval({2 * index, 2 * index + 1}); + gen_regular_intervals(lcl, index, 0); } auto lca = samurai::LevelCellArray(lcl); + + auto total_intervals = lca.nb_intervals(); + state.counters["Dimension"] = dim; + state.counters["Total_intervals"] = total_intervals; + state.counters["ns/interval"] = benchmark::Counter(total_intervals, + benchmark::Counter::kIsIterationInvariantRate | benchmark::Counter::kInvert); + for (auto _ : state) { auto minmax = lca.minmax_indices(); @@ -243,10 +393,17 @@ void LEVELCELLARRAY_equal(benchmark::State& state) for (int64_t i = 0; i < state.range(0); i++) { int index = static_cast(i); - lcl[{0}].add_interval({2 * index, 2 * index + 1}); + gen_regular_intervals(lcl, index, 0); } auto lca = samurai::LevelCellArray(lcl); auto lca2 = samurai::LevelCellArray(lcl); + + auto total_intervals = lca.nb_intervals() + lca2.nb_intervals(); + state.counters["Dimension"] = dim; + state.counters["Total_intervals"] = total_intervals; + state.counters["ns/interval"] = benchmark::Counter(total_intervals, + benchmark::Counter::kIsIterationInvariantRate | benchmark::Counter::kInvert); + for (auto _ : state) { auto is_equal = (lca == lca2); @@ -254,6 +411,46 @@ void LEVELCELLARRAY_equal(benchmark::State& state) } } +// Mesure : Récupération du niveau bas d'un LevelCellArray +template +void LEVELCELLARRAY_min_level(benchmark::State& state) +{ + samurai::LevelCellList lcl; + using TInterval = samurai::default_config::interval_t; + for (int64_t i = 0; i < state.range(0); i++) + { + int index = static_cast(i); + gen_regular_intervals(lcl, index, 0); + } + auto lca = samurai::LevelCellArray(lcl); + + for (auto _ : state) + { + auto min = lca.level(); + benchmark::DoNotOptimize(min); + } +} + +// Mesure : Récupération de l'itérateur reverse begin d'un LevelCellArray +template +void LEVELCELLARRAY_rbegin(benchmark::State& state) +{ + samurai::LevelCellList lcl; + using TInterval = samurai::default_config::interval_t; + for (int64_t i = 0; i < state.range(0); i++) + { + int index = static_cast(i); + gen_regular_intervals(lcl, index, 0); + } + auto lca = samurai::LevelCellArray(lcl); + + for (auto _ : state) + { + auto rbegin = lca.rbegin(); + benchmark::DoNotOptimize(rbegin); + } +} + // manque les LevelCellList_iterator BENCHMARK_TEMPLATE(LEVELCELLARRAY_default, 1); BENCHMARK_TEMPLATE(LEVELCELLARRAY_default, 2); @@ -263,46 +460,54 @@ BENCHMARK_TEMPLATE(LEVELCELLARRAY_empty_lcl_to_lca, 1); BENCHMARK_TEMPLATE(LEVELCELLARRAY_empty_lcl_to_lca, 2); BENCHMARK_TEMPLATE(LEVELCELLARRAY_empty_lcl_to_lca, 3); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_lcl_to_lca, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_lcl_to_lca, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_lcl_to_lca, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_lcl_to_lca, 1)->Arg(10000); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_lcl_to_lca, 2)->Arg(141); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_lcl_to_lca, 3)->Arg(32); + +BENCHMARK_TEMPLATE(LEVELCELLARRAY_begin, 1)->Arg(10000); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_begin, 2)->Arg(141); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_begin, 3)->Arg(32); + +BENCHMARK_TEMPLATE(LEVELCELLARRAY_end, 1)->Arg(10000); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_end, 2)->Arg(141); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_end, 3)->Arg(32); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_begin, 1)->RangeMultiplier(2)->Range(1, 1); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_begin, 2)->RangeMultiplier(2)->Range(1, 1); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_begin, 3)->RangeMultiplier(2)->Range(1, 1); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_shape, 1)->Arg(10000); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_shape, 2)->Arg(141); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_shape, 3)->Arg(32); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_end, 1)->RangeMultiplier(2)->Range(1, 1); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_end, 2)->RangeMultiplier(2)->Range(1, 1); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_end, 3)->RangeMultiplier(2)->Range(1, 1); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_nb_intervals, 1)->Arg(10000); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_nb_intervals, 2)->Arg(141); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_nb_intervals, 3)->Arg(32); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_shape, 1)->RangeMultiplier(2)->Range(1, 1); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_shape, 2)->RangeMultiplier(2)->Range(1, 1); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_shape, 3)->RangeMultiplier(2)->Range(1, 1); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_nb_cells, 1)->Arg(10000); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_nb_cells, 2)->Arg(141); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_nb_cells, 3)->Arg(32); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_nb_intervals, 1)->RangeMultiplier(2)->Range(1, 1); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_nb_intervals, 2)->RangeMultiplier(2)->Range(1, 1); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_nb_intervals, 3)->RangeMultiplier(2)->Range(1, 1); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_cell_length, 1)->Arg(10000); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_cell_length, 2)->Arg(141); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_cell_length, 3)->Arg(32); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_nb_cells, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_nb_cells, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_nb_cells, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_max_indices, 1)->Arg(10000); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_max_indices, 2)->Arg(141); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_max_indices, 3)->Arg(32); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_cell_length, 1)->RangeMultiplier(2)->Range(1, 1); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_cell_length, 2)->RangeMultiplier(2)->Range(1, 1); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_cell_length, 3)->RangeMultiplier(2)->Range(1, 1); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_min_indices, 1)->Arg(10000); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_min_indices, 2)->Arg(141); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_min_indices, 3)->Arg(32); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_max_indices, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_max_indices, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_max_indices, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_minmax_indices, 1)->Arg(10000); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_minmax_indices, 2)->Arg(141); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_minmax_indices, 3)->Arg(32); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_min_indices, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_min_indices, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_min_indices, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_equal, 1)->Arg(10000); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_equal, 2)->Arg(141); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_equal, 3)->Arg(32); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_minmax_indices, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_minmax_indices, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_minmax_indices, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_min_level, 1)->Arg(10000); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_min_level, 2)->Arg(141); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_min_level, 3)->Arg(32); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_equal, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_equal, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_equal, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_rbegin, 1)->Arg(10000); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_rbegin, 2)->Arg(141); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_rbegin, 3)->Arg(32); diff --git a/benchmark/benchmark_mesh.cpp b/benchmark/benchmark_mesh.cpp index 3c7c03b08..5054a0af0 100644 --- a/benchmark/benchmark_mesh.cpp +++ b/benchmark/benchmark_mesh.cpp @@ -1,3 +1,4 @@ + #include #include #include @@ -47,20 +48,6 @@ auto unitary_box() return box; } - -template -auto cell_list_with_n_intervals(int64_t size) -{ - samurai::CellList cl; - for (int64_t i = 0; i < size; i++) - { - int index = static_cast(i); - cl[0][{}].add_interval({2 * index, 2 * index + 1}); - } - return cl; -} - - //////////////////////////////////////////////////////////////////////////// // Mesure : Création d'une Box uniforme de taille de coté n @@ -75,233 +62,6 @@ void MESH_uniform(benchmark::State& state) } } - -template -void MESH_default(benchmark::State& state) -{ - using Config = samurai::UniformConfig; - for (auto _ : state) - { - auto mesh = samurai::UniformMesh(); - benchmark::DoNotOptimize(mesh); - } -} - - -// Mesure : Allocation d'un champ 1D d'un maillage uniforme de taille de coté n -template -void FIELD_make_field_uniform(benchmark::State& state) -{ - samurai::Box box = unitary_box(); - using Config = samurai::UniformConfig; - auto mesh = samurai::UniformMesh(box, state.range(0)); - for (auto _ : state) - { - auto u = make_field("u", mesh); - } -} - -// Mesure : Remplissage d'un champ 1D de taille de coté n -template -void FIELD_fill_uniform(benchmark::State& state) -{ - samurai::Box box = unitary_box(); - using Config = samurai::UniformConfig; - auto mesh = samurai::UniformMesh(box, state.range(0)); - auto u = make_field("u", mesh); - for (auto _ : state) - { - u.fill(1.0); - } -} - -// Mesure ; Remplissage d'un champ 1D de taille de coté n ,en utilisant for_each_cell (mesure d'overhead) -template -void FIELD_fill_for_each_cell_uniform(benchmark::State& state) -{ - samurai::Box box = unitary_box(); - using Config = samurai::UniformConfig; - auto mesh = samurai::UniformMesh(box, state.range(0)); - auto u = make_field("u", mesh); - for (auto _ : state) - { - for_each_cell(mesh, - [&](auto cell) - { - u[cell] = 1.0; - }); - } -} - -// Mesure : Test d'égalité entre deux Fields -// TODO : change name from equal to fill_equal -// Weird : MPI issue ??? wtf ??? -template -void FIELD_equal_uniform(benchmark::State& state) -{ - samurai::Box box = unitary_box(); - using Config = samurai::UniformConfig; - auto mesh = samurai::UniformMesh(box, state.range(0)); - auto u = make_field("u", mesh); - auto v = make_field("v", mesh); - u.fill(1.0); - for (auto _ : state) - { - v = u; - } -} - -// Mesure : Ajout d'un scalaire à un champ par broadcasting -template -void FIELD_add_scalar_uniform(benchmark::State& state) -{ - samurai::Box box = unitary_box(); - using Config = samurai::UniformConfig; - auto mesh = samurai::UniformMesh(box, state.range(0)); - auto u = make_field("u", mesh); - u.fill(1.0); - auto v = make_field("v", mesh); - for (auto _ : state) - { - v = u + 2.0; - benchmark::DoNotOptimize(v[0]); - } -} - -// Mesure : Ajout d'un scalaire à un champ par "for_each_cell" -// this is really slow -template -void FIELD_add_scalar_for_each_cell_uniform(benchmark::State& state) -{ - samurai::Box box = unitary_box(); - using Config = samurai::UniformConfig; - auto mesh = samurai::UniformMesh(box, state.range(0)); - auto u = make_field("u", mesh); - u.fill(1.0); - auto v = make_field("v", mesh); - for (auto _ : state) - { - for_each_cell(mesh, - [&](auto cell) - { - v[cell] = u[cell] + 2.0; - }); - } -} - -/** -template -void FIELD_add_scalar_for_each_interval_uniform(benchmark::State& state){ - samurai::Box box = unitary_box() ; - using Config = samurai::UniformConfig ; - auto mesh = samurai::UniformMesh(box, state.range(0)); - auto u = make_field("u", mesh) ; - u.fill(1.0) ; - auto v = make_field("v", mesh) ; - v.fill(0.0) ; - for (auto _ : state){ - for_each_cell(mesh, - [&](std::size_t level, const auto& interval, const auto& index) - { - auto i = interval ; - auto j = index[0] ; - v(level, i, j) = 1.0 ; - }); - } -} -**/ - -// Mesure : Somme de deux champs 1D par "for_each_cell" -template -void FIELD_add_for_each_cell_uniform(benchmark::State& state) -{ - samurai::Box box = unitary_box(); - using Config = samurai::UniformConfig; - auto mesh = samurai::UniformMesh(box, state.range(0)); - auto u = make_field("u", mesh); - u.fill(1.0); - auto v = make_field("v", mesh); - v.fill(1.0); - auto w = make_field("w", mesh); - w.fill(1.0); - - for (auto _ : state) - { - for_each_cell(mesh, - [&](auto cell) - { - w[cell] = u[cell] + v[cell]; - }); - } -} - -// Mesure : Somme de deux champs 1D par expression -template -void FIELD_add_uniform(benchmark::State& state) -{ - samurai::Box box = unitary_box(); - using Config = samurai::UniformConfig; - auto mesh = samurai::UniformMesh(box, state.range(0)); - auto u = make_field("u", mesh); - u.fill(1.0); - auto v = make_field("v", mesh); - v.fill(1.0); - auto w = make_field("w", mesh); - w.fill(0.0); - for (auto _ : state) - { - w = u + v; - benchmark::DoNotOptimize(w[0]); - } -} - BENCHMARK_TEMPLATE(MESH_uniform, 1)->DenseRange(1, 16); BENCHMARK_TEMPLATE(MESH_uniform, 2)->DenseRange(1, 14); BENCHMARK_TEMPLATE(MESH_uniform, 3)->DenseRange(1, 9); - - -BENCHMARK_TEMPLATE(MESH_default, 1); -BENCHMARK_TEMPLATE(MESH_default, 2); -BENCHMARK_TEMPLATE(MESH_default, 3); - - - -BENCHMARK_TEMPLATE(FIELD_make_field_uniform, 1)->DenseRange(1, 16); -BENCHMARK_TEMPLATE(FIELD_make_field_uniform, 2)->DenseRange(1, 12); -BENCHMARK_TEMPLATE(FIELD_make_field_uniform, 3)->DenseRange(1, 7); - - -BENCHMARK_TEMPLATE(FIELD_fill_uniform, 1)->DenseRange(1, 16); -BENCHMARK_TEMPLATE(FIELD_fill_uniform, 2)->DenseRange(1, 12); -BENCHMARK_TEMPLATE(FIELD_fill_uniform, 3)->DenseRange(1, 7); - - -BENCHMARK_TEMPLATE(FIELD_fill_for_each_cell_uniform, 1)->DenseRange(1, 16); -BENCHMARK_TEMPLATE(FIELD_fill_for_each_cell_uniform, 2)->DenseRange(1, 12); -BENCHMARK_TEMPLATE(FIELD_fill_for_each_cell_uniform, 3)->DenseRange(1, 7); - - -BENCHMARK_TEMPLATE(FIELD_equal_uniform, 1)->DenseRange(1, 16); -BENCHMARK_TEMPLATE(FIELD_equal_uniform, 2)->DenseRange(1, 12); -BENCHMARK_TEMPLATE(FIELD_equal_uniform, 3)->DenseRange(1, 7); - - -BENCHMARK_TEMPLATE(FIELD_add_scalar_uniform, 1)->DenseRange(1, 16); -BENCHMARK_TEMPLATE(FIELD_add_scalar_uniform, 2)->DenseRange(1, 12); -BENCHMARK_TEMPLATE(FIELD_add_scalar_uniform, 3)->DenseRange(1, 7); - - -BENCHMARK_TEMPLATE(FIELD_add_scalar_for_each_cell_uniform, 1)->DenseRange(1, 16); -BENCHMARK_TEMPLATE(FIELD_add_scalar_for_each_cell_uniform, 2)->DenseRange(1, 12); -BENCHMARK_TEMPLATE(FIELD_add_scalar_for_each_cell_uniform, 3)->DenseRange(1, 7); - - -BENCHMARK_TEMPLATE(FIELD_add_uniform, 1)->DenseRange(1, 16); -BENCHMARK_TEMPLATE(FIELD_add_uniform, 2)->DenseRange(1, 12); -BENCHMARK_TEMPLATE(FIELD_add_uniform, 3)->DenseRange(1, 7); - - -BENCHMARK_TEMPLATE(FIELD_add_for_each_cell_uniform, 1)->DenseRange(1, 16); -BENCHMARK_TEMPLATE(FIELD_add_for_each_cell_uniform, 2)->DenseRange(1, 12); -BENCHMARK_TEMPLATE(FIELD_add_for_each_cell_uniform, 3)->DenseRange(1, 7); - diff --git a/benchmark/benchmark_search.cpp b/benchmark/benchmark_search.cpp index 6801d4619..85ae68372 100644 --- a/benchmark/benchmark_search.cpp +++ b/benchmark/benchmark_search.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -14,112 +15,141 @@ /// utils template -auto cell_list_with_n_intervals(int64_t size) +auto gen_regular_intervals = [](int64_t size, unsigned int level = 0) { samurai::CellList cl; + for (int64_t i = 0; i < size; i++) { int index = static_cast(i); - cl[0][{}].add_interval({2 * index, 2 * index + 1}); + + // Calcul des paramètres selon le niveau : + // Niveau L : taille = 2^L, espacement = 2^(L+1) + int interval_size = 1 << level; // 2^level + int spacing = 1 << (level + 1); // 2^(level+1) + int start = index * spacing; + int end = start + interval_size; + + if constexpr (dim == 1) + { + cl[level][{}].add_interval({start, end}); + } + else if constexpr (dim == 2) + { + for (int y = 0; y < size; ++y) + { + xt::xtensor_fixed> coord{y}; + cl[level][coord].add_interval({start, end}); + } + } + else if constexpr (dim == 3) + { + for (int y = 0; y < size; ++y) + { + for (int z = 0; z < size; ++z) + { + xt::xtensor_fixed> coord{y, z}; + cl[level][coord].add_interval({start, end}); + } + } + } } + return cl; -} +}; template auto cell_array_with_n_intervals(int64_t size) { - auto cl = cell_list_with_n_intervals(size); + auto cl = gen_regular_intervals(size); samurai::CellArray ca(cl); return ca; } ////////////////////////////////////////////////////////////// - - - -// Mesure : recherche du premier intervale dans un CellArray nD de taille n en utilisant interval_search +// Fonction unifiée pour les benchmarks de recherche template -void FIND_interval_search_begin(benchmark::State& state) +void FIND_find_unified(benchmark::State& state, const std::function>()>& coord_generator) { - using TInterval = samurai::default_config::interval_t; - using lca_t = const samurai::LevelCellArray; - using diff_t = typename lca_t::const_iterator::difference_type; - - auto ca = cell_array_with_n_intervals(state.range(0)); - auto lca = ca[0]; - xt::xtensor_fixed> coord = {0}; - auto size = lca[dim - 1].size(); - auto integral = std::integral_constant{}; - auto begin = lca[0].cbegin() + static_cast(0); - auto end = lca[0].cend() + static_cast(size); - - + auto ca = cell_array_with_n_intervals(state.range(0)); + + // Compter le nombre d'intervalles + std::size_t nb_intervals = 0; + samurai::for_each_interval(ca, + [&](std::size_t level, const auto& interval, const auto& index) + { + nb_intervals++; + }); + + // Compter le nombre d'intervalles dans la direction x + std::size_t nb_intervals_x = state.range(0); + auto coord = coord_generator(); for (auto _ : state) { - auto index = samurai::detail::interval_search(begin, end, coord[0]); + auto index = find(ca[0], coord); benchmark::DoNotOptimize(index); } + + state.counters["nb_intervals"] = nb_intervals; + state.counters["nb_intervals_x"] = nb_intervals_x; + state.counters["dimension"] = dim; } -// Mesure : recherche du dernier intervale dans un CellArray nD de taille n en utilisant interval_search +// Fonctions spécialisées pour chaque politique template -void FIND_interval_search_end(benchmark::State& state) +void FIND_find_start(benchmark::State& state) { - using TInterval = samurai::default_config::interval_t; - using lca_t = const samurai::LevelCellArray; - using diff_t = typename lca_t::const_iterator::difference_type; - - auto ca = cell_array_with_n_intervals(state.range(0)); - auto lca = ca[0]; - xt::xtensor_fixed> coord = {2 * state.range(0)}; - auto size = lca[dim - 1].size(); - auto integral = std::integral_constant{}; - auto begin = lca[0].cbegin() + static_cast(0); - auto end = lca[0].cend() + static_cast(size); - - for (auto _ : state) + auto coord_generator = []() { - auto index = samurai::detail::interval_search(begin, end, coord[0]); - benchmark::DoNotOptimize(index); - } + xt::xtensor_fixed> coord; + coord.fill(0); + return coord; + }; + FIND_find_unified(state, coord_generator); } -// Ajout d'un nouveau benchmark pour les cas intermédiaires template -void FIND_interval_search_middle(benchmark::State& state) +void FIND_find_end(benchmark::State& state) { - using TInterval = samurai::default_config::interval_t; - using lca_t = const samurai::LevelCellArray; - using diff_t = typename lca_t::const_iterator::difference_type; - - auto ca = cell_array_with_n_intervals(state.range(0)); - auto lca = ca[0]; - xt::xtensor_fixed> coord = {state.range(0)}; // Point au milieu - auto size = lca[dim - 1].size(); - auto integral = std::integral_constant{}; - auto begin = lca[0].cbegin() + static_cast(0); - auto end = lca[0].cend() + static_cast(size); - - - for (auto _ : state) + auto coord_generator = [&state]() { - auto index = samurai::detail::interval_search(begin, end, coord[0]); - benchmark::DoNotOptimize(index); - } + xt::xtensor_fixed> coord; + coord.fill(state.range(0) - 1); + coord[0] = 2 * state.range(0) - 2; + return coord; + }; + FIND_find_unified(state, coord_generator); } -BENCHMARK_TEMPLATE(FIND_interval_search_begin, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 15); -BENCHMARK_TEMPLATE(FIND_interval_search_begin, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 15); -BENCHMARK_TEMPLATE(FIND_interval_search_begin, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 15); - -BENCHMARK_TEMPLATE(FIND_interval_search_end, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 15); -BENCHMARK_TEMPLATE(FIND_interval_search_end, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 15); -BENCHMARK_TEMPLATE(FIND_interval_search_end, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 15); +template +void FIND_find_middle(benchmark::State& state) +{ + auto coord_generator = [&state]() + { + xt::xtensor_fixed> coord; + // Coordonnées du milieu pour toutes les dimensions sauf x + for (std::size_t i = 1; i < dim; ++i) + { + coord[i] = (state.range(0) - 1) / 2; + } + // Coordonnée x au milieu, mais assurée d'être un multiple de 2 + int middle_x = (2 * state.range(0) - 1) / 2; // Milieu de la plage [0, 2*state.range(0) - 1] + coord[0] = (middle_x / 2) * 2; // S'assurer que c'est un multiple de 2 + return coord; + }; + FIND_find_unified(state, coord_generator); +} -BENCHMARK_TEMPLATE(FIND_interval_search_middle, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 15); -BENCHMARK_TEMPLATE(FIND_interval_search_middle, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 15); -BENCHMARK_TEMPLATE(FIND_interval_search_middle, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 15); +BENCHMARK_TEMPLATE(FIND_find_start, 1)->Args({2})->Args({4})->Args({32})->Args({64}); +BENCHMARK_TEMPLATE(FIND_find_start, 2)->Args({2})->Args({4})->Args({32})->Args({64}); +BENCHMARK_TEMPLATE(FIND_find_start, 3)->Args({2})->Args({4})->Args({32})->Args({64}); +BENCHMARK_TEMPLATE(FIND_find_end, 1)->Args({2})->Args({4})->Args({32})->Args({64}); +BENCHMARK_TEMPLATE(FIND_find_end, 2)->Args({2})->Args({4})->Args({32})->Args({64}); +BENCHMARK_TEMPLATE(FIND_find_end, 3)->Args({2})->Args({4})->Args({32})->Args({64}); +BENCHMARK_TEMPLATE(FIND_find_middle, 1)->Args({2})->Args({4})->Args({32})->Args({64}); +BENCHMARK_TEMPLATE(FIND_find_middle, 2)->Args({2})->Args({4})->Args({32})->Args({64}); +BENCHMARK_TEMPLATE(FIND_find_middle, 3)->Args({2})->Args({4})->Args({32})->Args({64}); /** template diff --git a/benchmark/benchmark_stencil.cpp b/benchmark/benchmark_stencil.cpp index b1a5059d0..608b51932 100644 --- a/benchmark/benchmark_stencil.cpp +++ b/benchmark/benchmark_stencil.cpp @@ -1,4 +1,3 @@ - #include #include #include @@ -16,25 +15,30 @@ #include #include #include +#include #include -/** -template -void STENCIL_find_stencil_origin(benchmark::State& state){ - using Stencil = xt::xtensor_fixed>; -//tencil stencil = xt::zeros({stencil_size, dim}); - Stencil stencil = star_stencil() ; - for (auto _ : state){ - auto origin = samurai::find_stencil_origin(stencil) ; - benchmark::DoNotOptimize(origin) ; - } +////////////////////////////////////////////////////////////////////////////// +// BENCHMARKS - CRÉATION DE STENCILS FONDAMENTAUX +////////////////////////////////////////////////////////////////////////////// + +// Benchmark de création des stencils star (le plus fondamental) +template +void STENCIL_star_creation(benchmark::State& state) +{ + for (auto _ : state) + { + auto stencil = samurai::star_stencil(); + benchmark::DoNotOptimize(stencil); + } } +////////////////////////////////////////////////////////////////////////////// +// REGISTRATIONS DES BENCHMARKS +////////////////////////////////////////////////////////////////////////////// - - -BENCHMARK_TEMPLATE(STENCIL_find_stencil_origin, 1, 1); -BENCHMARK_TEMPLATE(STENCIL_find_stencil_origin, 2, 1); -BENCHMARK_TEMPLATE(STENCIL_find_stencil_origin, 3, 1); - -**/ +// Benchmarks Star stencil - configurations essentielles +BENCHMARK_TEMPLATE(STENCIL_star_creation, 2, 1); // 2D, largeur 1 (le plus courant) +BENCHMARK_TEMPLATE(STENCIL_star_creation, 3, 1); // 3D, largeur 1 (le plus courant) +BENCHMARK_TEMPLATE(STENCIL_star_creation, 2, 2); // 2D, largeur 2 +BENCHMARK_TEMPLATE(STENCIL_star_creation, 3, 2); // 3D, largeur 2 diff --git a/benchmark/benchmark_subset.cpp b/benchmark/benchmark_subset.cpp index f9608f521..be84eb1cc 100644 --- a/benchmark/benchmark_subset.cpp +++ b/benchmark/benchmark_subset.cpp @@ -1,4 +1,3 @@ - #include #include #include @@ -17,344 +16,610 @@ #include // Observation : Cela prend environ 10ns par intervalle -// si on compare 2 intervalles de taillen, cela prendra environ 2n * 10ns +// si on compare 2 intervalles de taille n, cela prendra environ 2n * 10ns /////////////////////////////////////////////////////////////////// -// utils +// Fonctions utilitaires pour la génération d'intervalles +/////////////////////////////////////////////////////////////////// template -auto cell_list_with_n_intervals(int64_t size) +auto gen_regular_intervals = [](auto& cl, int index, unsigned int level) { - samurai::CellList cl; - for (int64_t i = 0; i < size; i++) + // Calcul des paramètres selon le niveau : + // Niveau L : taille = 2^L, espacement = 2^(L+1) + int interval_size = 1 << level; // 2^level + int spacing = 1 << (level + 1); // 2^(level+1) + int start = index * spacing; + int end = start + interval_size; + + if constexpr (dim == 1) { - int index = static_cast(i); - cl[0][{}].add_interval({2 * index, 2 * index + 1}); + cl[level][{}].add_interval({start, end}); } - return cl; -} + else if constexpr (dim == 2) + { + for (int y = 0; y < index; ++y) + { + xt::xtensor_fixed> coord{y}; + cl[level][coord].add_interval({start, end}); + } + } + else if constexpr (dim == 3) + { + for (int y = 0; y < index; ++y) + { + for (int z = 0; z < index; ++z) + { + xt::xtensor_fixed> coord{y, z}; + cl[level][coord].add_interval({start, end}); + } + } + } +}; template -auto cell_array_with_n_intervals(int64_t size) +auto gen_offset_intervals = [](auto& cl, int index, unsigned int level) { - auto cl = cell_list_with_n_intervals(size); - samurai::CellArray ca(cl); - return ca; -} - -////////////////////////////////////////////////////////////////// + // Calcul des paramètres selon le niveau + int interval_size = 1 << level; // 2^level + int spacing = 1 << (level + 1); // 2^(level+1) + int start = index * spacing + interval_size; // Décalage d'une taille pour être disjoint des "same" + int end = start + interval_size; -/** -template -void SUBSET_difference_same_interval_different_level(benchmark::State& state){ - samurai::CellList cl1, cl2 ; - for (int64_t i = 0 ; i < state.range(0); i++){ - int index = static_cast(i) ; - cl1[0][{}].add_interval({2*index, 2*index+1}); - cl2[delta_level][{}].add_interval({pow(2, delta_level+1)*index, pow(2, delta_level+1)*index + pow(2, delta_level)}); - } - samurai::CellArray ca1(cl1); - samurai::CellArray ca2(cl2); - for (auto _ : state){ - if constexpr(delta_level != 0){ - auto subset = samurai::difference(ca1[0], samurai::projection(ca2[delta_level], 0)); - subset([](const auto&, const auto&) {}); // evaluation avec lambda vide - benchmark::DoNotOptimize(subset); + if constexpr (dim == 1) + { + cl[level][{}].add_interval({start, end}); + } + else if constexpr (dim == 2) + { + for (int y = 0; y < index; ++y) + { + xt::xtensor_fixed> coord{y}; + cl[level][coord].add_interval({start, end}); } - else if constexpr (delta_level == 0){ - auto subset = samurai::difference(ca1[0], ca2[0]); - subset([](const auto&, const auto&) {}); // evaluation avec lambda vide - benchmark::DoNotOptimize(subset); + } + else if constexpr (dim == 3) + { + for (int y = 0; y < index; ++y) + { + for (int z = 0; z < index; ++z) + { + xt::xtensor_fixed> coord{y, z}; + cl[level][coord].add_interval({start, end}); + } } + } +}; + +template +auto gen_unique_interval = [](auto& cl, int index, unsigned int level) +{ + // Génère un seul grand intervalle qui grandit avec l'index + // Pour avoir une bounding box similaire aux autres générateurs, + // on crée un intervalle qui couvre plusieurs "espacements" + + int spacing = 1 << (level + 1); // 2^(level+1) + + // Créer un grand intervalle qui couvre (index+1) espacements complets + // Cela donne une taille proportionnelle à l'index, comme les autres générateurs + int interval_size = (index + 1) * spacing; + + if constexpr (dim == 1) + { + if (index == 0) + { + cl[level][{}].add_interval({0, interval_size}); } -} -**/ -/** -template -void SUBSET_difference_different_interval_different_level(benchmark::State& state){ - samurai::CellList cl1, cl2 ; - for (int64_t i = 0 ; i < state.range(0); i++){ - int index = static_cast(i) ; - cl1[0][{}].add_interval({2*index, 2*index+1}); - cl2[delta_level][{}].add_interval({pow(2, delta_level+1)*index + pow(2, delta_level), pow(2, delta_level+2)*index}); + } + else if constexpr (dim == 2) + { + for (int y = 0; y < index; ++y) + { + xt::xtensor_fixed> coord{y}; + cl[level][coord].add_interval({0, interval_size}); } - samurai::CellArray ca1(cl1); - samurai::CellArray ca2(cl2); - for (auto _ : state){ - if constexpr(delta_level != 0){ - auto subset = samurai::difference(ca1[0], samurai::projection(ca2[delta_level], 0)); - subset([](const auto&, const auto&) {}); // evaluation avec lambda vide - benchmark::DoNotOptimize(subset); - } - else if constexpr (delta_level == 0){ - auto subset = samurai::difference(ca1[0], ca2[0]); - subset([](const auto&, const auto&) {}); // evaluation avec lambda vide - benchmark::DoNotOptimize(subset); - } + } + else if constexpr (dim == 3) + { + for (int y = 0; y < index; ++y) + { + for (int z = 0; z < index; ++z) + { + xt::xtensor_fixed> coord{y, z}; + cl[level][coord].add_interval({0, interval_size}); + } } + } +}; + +template +auto create_translation_stencil() +{ + xt::xtensor_fixed> stencil; + if constexpr (dim == 1) + { + stencil = xt::xtensor_fixed>({1}); + } + else if constexpr (dim == 2) + { + stencil = xt::xtensor_fixed>({1, 1}); + } + else if constexpr (dim == 3) + { + stencil = xt::xtensor_fixed>({1, 1, 1}); + } + return stencil; } -**/ - -/** -template -void SUBSET_difference_n1_interval_different_level(benchmark::State& state){ - samurai::CellList cl1, cl2 ; - for (int64_t i = 0 ; i < state.range(0); i++){ - int index = static_cast(i) ; - cl1[0][{}].add_interval({2*index, 2*index+1}); - } - cl2[delta_level][{}].add_interval({static_cast(0), static_cast(pow(2, delta_level))}); - - samurai::CellArray ca1(cl1); - samurai::CellArray ca2(cl2); - for (auto _ : state){ - if constexpr(delta_level != 0){ - auto subset = samurai::difference(ca1[0], samurai::projection(ca2[delta_level], 0)); - subset([](const auto&, const auto&) {}); // evaluation avec lambda vide - benchmark::DoNotOptimize(subset); - } - else if constexpr (delta_level == 0){ - auto subset = samurai::difference(ca1[0], ca2[0]); - subset([](const auto&, const auto&) {}); // evaluation avec lambda vide - benchmark::DoNotOptimize(subset); - } - } + +/////////////////////////////////////////////////////////////////// +// Opérations ensemblistes +/////////////////////////////////////////////////////////////////// + +auto op_difference = [](const auto& a, const auto& b) +{ + return samurai::difference(a, b); +}; + +auto op_intersection = [](const auto& a, const auto& b) +{ + return samurai::intersection(a, b); +}; + +auto op_union = [](const auto& a, const auto& b) +{ + return samurai::union_(a, b); +}; + +/////////////////////////////////////////////////////////////////// +// Fonction de benchmark unifiée +/////////////////////////////////////////////////////////////////// + +template +void SUBSET_unified_benchmark_mixed_levels(benchmark::State& state, Gen1&& gen1, Gen2&& gen2, Operation&& operation) +{ + samurai::CellList cl1, cl2; + for (int64_t i = 0; i < state.range(0); i++) + { + int index = static_cast(i); + gen1(cl1, index, level1); + gen2(cl2, index, level2); + } + samurai::CellArray ca1(cl1); + samurai::CellArray ca2(cl2); + + // Ajouter les statistiques + auto total_intervals = ca1[level1].nb_intervals() + ca2[level2].nb_intervals(); + state.counters["Dimension"] = dim; + state.counters["Level1"] = level1; + state.counters["Level2"] = level2; + state.counters["Input1_intervals"] = ca1[level1].nb_intervals(); + state.counters["Input2_intervals"] = ca2[level2].nb_intervals(); + state.counters["ns/interval"] = benchmark::Counter(total_intervals, + benchmark::Counter::kIsIterationInvariantRate | benchmark::Counter::kInvert); + + for (auto _ : state) + { + auto total_cells = 0; + auto subset = operation(ca1[level1], ca2[level2]); + subset( + [&total_cells](const auto&, const auto&) + { + total_cells = 1; + }); + benchmark::DoNotOptimize(total_cells); + benchmark::DoNotOptimize(subset); + } } -**/ - -/** -template -void SUBSET_double_difference_same_interval(benchmark::State& state){ - samurai::CellList cl1, cl2 ; - for (int64_t i = 0 ; i < state.range(0); i++){ - int index = static_cast(i) ; - cl1[0][{}].add_interval({2*index, 2*index+1}); - cl2[delta_level][{}].add_interval({pow(2, delta_level+1)*index, pow(2, delta_level+1)*index + pow(2, delta_level)}); - } - samurai::CellArray ca1(cl1); - samurai::CellArray ca2(cl2); - for (auto _ : state){ - if constexpr(delta_level != 0){ - auto subset = samurai::difference(samurai::difference(ca1[0], samurai::projection(ca2[delta_level], 0)), ca1[0]); - subset([](const auto&, const auto&) {}); // evaluation avec lambda vide - benchmark::DoNotOptimize(subset); - } - else if constexpr (delta_level == 0){ - auto subset = samurai::difference(samurai::difference(ca1[0], ca2[0]), ca1[0]); - subset([](const auto&, const auto&) {}); // evaluation avec lambda vide - benchmark::DoNotOptimize(subset); - } - } + +/////////////////////////////////////////////////////////////////// +// Fonction de benchmark unifiée pour les opérations imbriquées +/////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////// +// Benchmarks pour les opérations ensemblistes +/////////////////////////////////////////////////////////////////// + +template +void SUBSET_set_diff_identical(benchmark::State& state) +{ + SUBSET_unified_benchmark_mixed_levels(state, gen_regular_intervals, gen_regular_intervals, op_difference); } -**/ - -/** -// why for <2-3, 1-2-10> it is that fast ? error i think -template -void SUBSET_intersection_same_interval_different_level(benchmark::State& state){ - samurai::CellList cl1, cl2 ; - for (int64_t i = 0 ; i < state.range(0); i++){ - int index = static_cast(i) ; - cl1[0][{}].add_interval({2*index, 2*index+1}); - cl2[delta_level][{}].add_interval({pow(2, delta_level+1)*index, pow(2, delta_level+1)*index + pow(2, delta_level)}); - } - samurai::CellArray ca1(cl1); - samurai::CellArray ca2(cl2); - for (auto _ : state){ - if constexpr(delta_level != 0){ - auto subset = samurai::intersection(ca1[0], samurai::projection(ca2[delta_level], 0)); - subset([](const auto&, const auto&) {}); // evaluation avec lambda vide - benchmark::DoNotOptimize(subset); - } - else if constexpr (delta_level == 0){ - auto subset = samurai::intersection(ca1[0], ca2[0]); - subset([](const auto&, const auto&) {}); // evaluation avec lambda vide - benchmark::DoNotOptimize(subset); - } - } +template +void SUBSET_set_diff_disjoint(benchmark::State& state) +{ + SUBSET_unified_benchmark_mixed_levels(state, gen_regular_intervals, gen_offset_intervals, op_difference); } -**/ -/** -template -void SUBSET_union_same_interval_different_level(benchmark::State& state){ - samurai::CellList cl1, cl2 ; - for (int64_t i = 0 ; i < state.range(0); i++){ - int index = static_cast(i) ; - cl1[0][{}].add_interval({2*index, 2*index+1}); - cl2[delta_level][{}].add_interval({pow(2, delta_level+1)*index, pow(2, delta_level+1)*index + pow(2, delta_level)}); - } - samurai::CellArray ca1(cl1); - samurai::CellArray ca2(cl2); - for (auto _ : state){ - if constexpr(delta_level != 0){ - auto subset = samurai::union_(ca1[0], samurai::projection(ca2[delta_level], 0)); - subset([](const auto&, const auto&) {}); // evaluation avec lambda vide - benchmark::DoNotOptimize(subset); - } - else if constexpr (delta_level == 0){ - auto subset = samurai::union_(ca1[0], ca2[0]); - subset([](const auto&, const auto&) {}); // evaluation avec lambda vide - benchmark::DoNotOptimize(subset); - } - } +template +void SUBSET_set_diff_single(benchmark::State& state) +{ + SUBSET_unified_benchmark_mixed_levels(state, gen_regular_intervals, gen_unique_interval, op_difference); } -**/ -template +template +void SUBSET_set_intersect_identical(benchmark::State& state) +{ + SUBSET_unified_benchmark_mixed_levels(state, gen_regular_intervals, gen_regular_intervals, op_intersection); +} + +template +void SUBSET_set_intersect_disjoint(benchmark::State& state) +{ + SUBSET_unified_benchmark_mixed_levels(state, gen_regular_intervals, gen_offset_intervals, op_intersection); +} + +template +void SUBSET_set_intersect_single(benchmark::State& state) +{ + SUBSET_unified_benchmark_mixed_levels(state, gen_regular_intervals, gen_unique_interval, op_intersection); +} + +template +void SUBSET_set_union_identical(benchmark::State& state) +{ + SUBSET_unified_benchmark_mixed_levels(state, gen_regular_intervals, gen_regular_intervals, op_union); +} + +template +void SUBSET_set_union_disjoint(benchmark::State& state) +{ + SUBSET_unified_benchmark_mixed_levels(state, gen_regular_intervals, gen_offset_intervals, op_union); +} + +template +void SUBSET_set_union_single(benchmark::State& state) +{ + SUBSET_unified_benchmark_mixed_levels(state, gen_regular_intervals, gen_unique_interval, op_union); +} + +/////////////////////////////////////////////////////////////////// +// Benchmarks pour les opérations géométriques +/////////////////////////////////////////////////////////////////// + +template void SUBSET_translate(benchmark::State& state) { samurai::CellList cl; for (int64_t i = 0; i < state.range(0); i++) { int index = static_cast(i); - cl[0][{}].add_interval({2 * index, 2 * index + 1}); + gen_regular_intervals(cl, index, level); } samurai::CellArray ca(cl); - xt::xtensor_fixed> stencil; - if constexpr (dim == 1) + + // Créer le stencil de translation + auto stencil = create_translation_stencil(); + + // Ajouter les statistiques + auto total_intervals = ca[level].nb_intervals(); + state.counters["Dimension"] = dim; + state.counters["Level"] = level; + state.counters["Total_intervals"] = total_intervals; + state.counters["ns/interval"] = benchmark::Counter(total_intervals, + benchmark::Counter::kIsIterationInvariantRate | benchmark::Counter::kInvert); + + for (auto _ : state) { - stencil = xt::xtensor_fixed>({1}); + auto total_cells = 0; + auto subset = samurai::translate(ca[level], stencil); + subset( + [&total_cells](const auto&, const auto&) + { + total_cells = 1; + }); + benchmark::DoNotOptimize(total_cells); + benchmark::DoNotOptimize(subset); } - else if constexpr (dim == 2) +} + +template +void SUBSET_translate_and_intersect(benchmark::State& state) +{ + samurai::CellList cl1, cl2; + for (int64_t i = 0; i < state.range(0); i++) { - stencil = xt::xtensor_fixed>({1, 1}); + int index = static_cast(i); + gen_regular_intervals(cl1, index, level1); + gen_regular_intervals(cl2, index, level2); } - else if constexpr (dim == 3) + samurai::CellArray ca1(cl1); + samurai::CellArray ca2(cl2); + + // Créer le stencil de translation + auto stencil = create_translation_stencil(); + + // Ajouter les statistiques + auto total_intervals = ca1[level1].nb_intervals() + ca2[level2].nb_intervals(); + state.counters["Dimension"] = dim; + state.counters["Level1"] = level1; + state.counters["Level2"] = level2; + state.counters["Input1_intervals"] = ca1[level1].nb_intervals(); + state.counters["Input2_intervals"] = ca2[level2].nb_intervals(); + state.counters["ns/interval"] = benchmark::Counter(total_intervals, + benchmark::Counter::kIsIterationInvariantRate | benchmark::Counter::kInvert); + + for (auto _ : state) { - stencil = xt::xtensor_fixed>({1, 1, 1}); + auto total_cells = 0; + // intersection(translate(ca1, stencil), ca2) + auto subset = samurai::intersection(samurai::translate(ca1[level1], stencil), ca2[level2]); + subset( + [&total_cells](const auto&, const auto&) + { + total_cells = 1; + }); + benchmark::DoNotOptimize(total_cells); + benchmark::DoNotOptimize(subset); + } +} + +template +void SUBSET_translate_and_intersect_and_project(benchmark::State& state) +{ + samurai::CellList cl1, cl2; + for (int64_t i = 0; i < state.range(0); i++) + { + int index = static_cast(i); + gen_regular_intervals(cl1, index, level1); + gen_regular_intervals(cl2, index, level2); } + samurai::CellArray ca1(cl1); + samurai::CellArray ca2(cl2); + + // Créer le stencil de translation + auto stencil = create_translation_stencil(); + + // Ajouter les statistiques + auto total_intervals = ca1[level1].nb_intervals() + ca2[level2].nb_intervals(); + state.counters["Dimension"] = dim; + state.counters["Level1"] = level1; + state.counters["Level2"] = level2; + state.counters["Input1_intervals"] = ca1[level1].nb_intervals(); + state.counters["Input2_intervals"] = ca2[level2].nb_intervals(); + state.counters["ns/interval"] = benchmark::Counter(total_intervals, + benchmark::Counter::kIsIterationInvariantRate | benchmark::Counter::kInvert); + for (auto _ : state) { - auto subset = samurai::translate(ca[0], stencil); - subset([](const auto&, const auto&) {}); // evaluation avec lambda vide + auto total_cells = 0; + // intersection(translate(ca1, stencil), ca2) puis projection sur niveau supérieur + auto project_level = std::max(level1, level2) + 1; + auto subset = samurai::intersection(samurai::translate(ca1[level1], stencil), ca2[level2]).on(project_level); + subset( + [&total_cells](const auto&, const auto&) + { + total_cells = 1; + }); + benchmark::DoNotOptimize(total_cells); benchmark::DoNotOptimize(subset); } } -/** -template -void SUBSET_expand(benchmark::State& state){ - samurai::CellList cl ; - for (int64_t i = 0 ; i < state.range(0); i++){ - int index = static_cast(i) ; - cl[0][{}].add_interval({2*index, 2*index+1}); - } - samurai::CellArray ca(cl); - xt::xtensor_fixed> stencil; - if constexpr (dim == 1) - stencil = xt::xtensor_fixed>({1}) ; - else if constexpr (dim == 2) - stencil = xt::xtensor_fixed>({1,1}) ; - else if constexpr (dim == 3) - stencil = xt::xtensor_fixed>({1,1,1}) ; - for (auto _ : state){ - auto subset = samurai::expand(ca[0]); - subset([](const auto&, const auto&) {}); // evaluation avec lambda vide - benchmark::DoNotOptimize(subset); - } +template +void SUBSET_translate_and_project(benchmark::State& state) +{ + samurai::CellList cl; + for (int64_t i = 0; i < state.range(0); i++) + { + int index = static_cast(i); + gen_regular_intervals(cl, index, level); + } + samurai::CellArray ca(cl); + + // Créer le stencil de translation + auto stencil = create_translation_stencil(); + + // Ajouter les statistiques + auto total_intervals = ca[level].nb_intervals(); + state.counters["Dimension"] = dim; + state.counters["Level"] = level; + state.counters["Total_intervals"] = total_intervals; + state.counters["ns/interval"] = benchmark::Counter(total_intervals, + benchmark::Counter::kIsIterationInvariantRate | benchmark::Counter::kInvert); + + for (auto _ : state) + { + auto total_cells = 0; + // Translate puis projection sur niveau supérieur + auto subset = samurai::translate(ca[level], stencil).on(level + 1); + subset( + [&total_cells](const auto&, const auto&) + { + total_cells = 1; + }); + benchmark::DoNotOptimize(total_cells); + benchmark::DoNotOptimize(subset); + } } -**/ -/** -template -void SUBSET_contraction(benchmark::State& state){ - samurai::CellList cl ; - for (int64_t i = 0 ; i < state.range(0); i++){ - int index = static_cast(i) ; - cl[0][{}].add_interval({2*index, 2*index+1}); - } - samurai::CellArray ca(cl); - xt::xtensor_fixed> stencil; - if constexpr (dim == 1) - stencil = xt::xtensor_fixed>({1}) ; - else if constexpr (dim == 2) - stencil = xt::xtensor_fixed>({1,1}) ; - else if constexpr (dim == 3) - stencil = xt::xtensor_fixed>({1,1,1}) ; - for (auto _ : state){ - auto subset = samurai::contraction(ca[0]); - subset([](const auto&, const auto&) {}); // evaluation avec lambda vide - benchmark::DoNotOptimize(subset); - } +template +void SUBSET_self(benchmark::State& state) +{ + samurai::CellList cl; + for (int64_t i = 0; i < state.range(0); i++) + { + int index = static_cast(i); + gen_regular_intervals(cl, index, level); + } + samurai::CellArray ca(cl); + + // Ajouter les statistiques + auto total_intervals = ca[level].nb_intervals(); + state.counters["Dimension"] = dim; + state.counters["Level"] = level; + state.counters["Total_intervals"] = total_intervals; + state.counters["ns/interval"] = benchmark::Counter(total_intervals, + benchmark::Counter::kIsIterationInvariantRate | benchmark::Counter::kInvert); + + for (auto _ : state) + { + auto total_cells = 0; + auto subset = samurai::self(ca[level]); + subset( + [&total_cells](const auto&, const auto&) + { + total_cells = 1; + }); + benchmark::DoNotOptimize(total_cells); + benchmark::DoNotOptimize(subset); + } +} + +template +void SUBSET_self_and_project(benchmark::State& state) +{ + samurai::CellList cl; + for (int64_t i = 0; i < state.range(0); i++) + { + int index = static_cast(i); + gen_regular_intervals(cl, index, level); + } + samurai::CellArray ca(cl); + + // Ajouter les statistiques + auto total_intervals = ca[level].nb_intervals(); + state.counters["Dimension"] = dim; + state.counters["Level"] = level; + state.counters["Total_intervals"] = total_intervals; + state.counters["ns/interval"] = benchmark::Counter(total_intervals, + benchmark::Counter::kIsIterationInvariantRate | benchmark::Counter::kInvert); + + for (auto _ : state) + { + auto total_cells = 0; + // Self puis projection sur niveau supérieur + auto subset = samurai::self(ca[level]).on(level + 1); + subset( + [&total_cells](const auto&, const auto&) + { + total_cells = 1; + }); + benchmark::DoNotOptimize(total_cells); + benchmark::DoNotOptimize(subset); + } } -**/ -/** -BENCHMARK_TEMPLATE(SUBSET_difference_same_interval_different_level,1, 0)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(SUBSET_difference_same_interval_different_level,2, 0)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(SUBSET_difference_same_interval_different_level,3, 0)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); - -BENCHMARK_TEMPLATE(SUBSET_difference_same_interval_different_level,1, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(SUBSET_difference_same_interval_different_level,2, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(SUBSET_difference_same_interval_different_level,3, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); - -BENCHMARK_TEMPLATE(SUBSET_difference_same_interval_different_level,1, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(SUBSET_difference_same_interval_different_level,2, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(SUBSET_difference_same_interval_different_level,3, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); - -BENCHMARK_TEMPLATE(SUBSET_difference_same_interval_different_level,1, 10)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(SUBSET_difference_same_interval_different_level,2, 10)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(SUBSET_difference_same_interval_different_level,3, 10)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -**/ -/** -BENCHMARK_TEMPLATE(SUBSET_difference_n1_interval_different_level,1, 0)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(SUBSET_difference_n1_interval_different_level,2, 0)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(SUBSET_difference_n1_interval_different_level,3, 0)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -**/ - -/** -BENCHMARK_TEMPLATE(SUBSET_double_difference_same_interval,1, 0)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(SUBSET_double_difference_same_interval,2, 0)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(SUBSET_double_difference_same_interval,3, 0)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -**/ - -/** -BENCHMARK_TEMPLATE(SUBSET_intersection_same_interval_different_level,1, 0)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(SUBSET_intersection_same_interval_different_level,2, 0)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(SUBSET_intersection_same_interval_different_level,3, 0)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); - -BENCHMARK_TEMPLATE(SUBSET_intersection_same_interval_different_level,1, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(SUBSET_intersection_same_interval_different_level,2, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(SUBSET_intersection_same_interval_different_level,3, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); - -BENCHMARK_TEMPLATE(SUBSET_intersection_same_interval_different_level,1, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(SUBSET_intersection_same_interval_different_level,2, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(SUBSET_intersection_same_interval_different_level,3, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); - -BENCHMARK_TEMPLATE(SUBSET_intersection_same_interval_different_level,1, 10)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(SUBSET_intersection_same_interval_different_level,2, 10)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(SUBSET_intersection_same_interval_different_level,3, 10)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -**/ - -/** -BENCHMARK_TEMPLATE(SUBSET_union_same_interval_different_level,1, 0)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(SUBSET_union_same_interval_different_level,2, 0)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(SUBSET_union_same_interval_different_level,3, 0)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); - -BENCHMARK_TEMPLATE(SUBSET_union_same_interval_different_level,1, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(SUBSET_union_same_interval_different_level,2, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(SUBSET_union_same_interval_different_level,3, 1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); - -BENCHMARK_TEMPLATE(SUBSET_union_same_interval_different_level,1, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(SUBSET_union_same_interval_different_level,2, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(SUBSET_union_same_interval_different_level,3, 2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); - -BENCHMARK_TEMPLATE(SUBSET_union_same_interval_different_level,1, 10)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(SUBSET_union_same_interval_different_level,2, 10)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(SUBSET_union_same_interval_different_level,3, 10)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -**/ - -// BENCHMARK_TEMPLATE(SUBSET_translate,1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -// BENCHMARK_TEMPLATE(SUBSET_translate,2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -// BENCHMARK_TEMPLATE(SUBSET_translate,3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); - -/** -BENCHMARK_TEMPLATE(SUBSET_expand,1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(SUBSET_expand,2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(SUBSET_expand,3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -**/ - -// BENCHMARK_TEMPLATE(SUBSET_contraction,1)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -// BENCHMARK_TEMPLATE(SUBSET_contraction,2)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); -// BENCHMARK_TEMPLATE(SUBSET_contraction,3)->RangeMultiplier(2)->Range(1 << 1, 1 << 10); + +/////////////////////////////////////////////////////////////////// +// Enregistrement des benchmarks +/////////////////////////////////////////////////////////////////// + +// Benchmarks pour les opérations ensemblistes en 1D (même niveau) - ~1000 intervalles +BENCHMARK_TEMPLATE(SUBSET_set_diff_identical, 1, 0, 0)->Arg(1000); +BENCHMARK_TEMPLATE(SUBSET_set_diff_disjoint, 1, 0, 0)->Arg(1000); +// BENCHMARK_TEMPLATE(SUBSET_set_diff_single, 1, 0, 0)->Arg(1000); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 1, 0, 0)->Arg(1000); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 1, 0, 0)->Arg(1000); +// BENCHMARK_TEMPLATE(SUBSET_set_intersect_single, 1, 0, 0)->Arg(1000); +BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 1, 0, 0)->Arg(1000); +BENCHMARK_TEMPLATE(SUBSET_set_union_disjoint, 1, 0, 0)->Arg(1000); +// BENCHMARK_TEMPLATE(SUBSET_set_union_single, 1, 0, 0)->Arg(1000); + +BENCHMARK_TEMPLATE(SUBSET_set_diff_identical, 1, 0, 1)->Arg(1000); +BENCHMARK_TEMPLATE(SUBSET_set_diff_disjoint, 1, 0, 1)->Arg(1000); +// BENCHMARK_TEMPLATE(SUBSET_set_diff_single, 1, 0, 1)->Arg(1000); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 1, 0, 1)->Arg(1000); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 1, 0, 1)->Arg(1000); +// BENCHMARK_TEMPLATE(SUBSET_set_intersect_single, 1, 0, 1)->Arg(1000); +BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 1, 0, 1)->Arg(1000); +BENCHMARK_TEMPLATE(SUBSET_set_union_disjoint, 1, 0, 1)->Arg(1000); +// BENCHMARK_TEMPLATE(SUBSET_set_union_single, 1, 0, 1)->Arg(1000); + +// Benchmarks pour les opérations ensemblistes en 2D (même niveau) - ~1000 intervalles +BENCHMARK_TEMPLATE(SUBSET_set_diff_identical, 2, 0, 0)->Arg(45); +BENCHMARK_TEMPLATE(SUBSET_set_diff_disjoint, 2, 0, 0)->Arg(45); +// BENCHMARK_TEMPLATE(SUBSET_set_diff_single, 2, 0, 0)->Arg(45); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 2, 0, 0)->Arg(45); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 2, 0, 0)->Arg(45); +// BENCHMARK_TEMPLATE(SUBSET_set_intersect_single, 2, 0, 0)->Arg(45); +BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 2, 0, 0)->Arg(45); +BENCHMARK_TEMPLATE(SUBSET_set_union_disjoint, 2, 0, 0)->Arg(45); +// BENCHMARK_TEMPLATE(SUBSET_set_union_single, 2, 0, 0)->Arg(45); + +BENCHMARK_TEMPLATE(SUBSET_set_diff_identical, 2, 0, 1)->Arg(45); +BENCHMARK_TEMPLATE(SUBSET_set_diff_disjoint, 2, 0, 1)->Arg(45); +// BENCHMARK_TEMPLATE(SUBSET_set_diff_single, 2, 0, 1)->Arg(45); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 2, 0, 1)->Arg(45); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 2, 0, 1)->Arg(45); +// BENCHMARK_TEMPLATE(SUBSET_set_intersect_single, 2, 0, 1)->Arg(45); +BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 2, 0, 1)->Arg(45); +BENCHMARK_TEMPLATE(SUBSET_set_union_disjoint, 2, 0, 1)->Arg(45); +// BENCHMARK_TEMPLATE(SUBSET_set_union_single, 2, 0, 1)->Arg(45); + +// Benchmarks pour les opérations ensemblistes en 3D (même niveau) - ~1000 intervalles +BENCHMARK_TEMPLATE(SUBSET_set_diff_identical, 3, 0, 0)->Arg(15); +BENCHMARK_TEMPLATE(SUBSET_set_diff_disjoint, 3, 0, 0)->Arg(15); +// BENCHMARK_TEMPLATE(SUBSET_set_diff_single, 3, 0, 0)->Arg(15); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 3, 0, 0)->Arg(15); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 3, 0, 0)->Arg(15); +// BENCHMARK_TEMPLATE(SUBSET_set_intersect_single, 3, 0, 0)->Arg(15); +BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 3, 0, 0)->Arg(15); +BENCHMARK_TEMPLATE(SUBSET_set_union_disjoint, 3, 0, 0)->Arg(15); +// BENCHMARK_TEMPLATE(SUBSET_set_union_single, 3, 0, 0)->Arg(15); + +BENCHMARK_TEMPLATE(SUBSET_set_diff_identical, 3, 0, 1)->Arg(15); +BENCHMARK_TEMPLATE(SUBSET_set_diff_disjoint, 3, 0, 1)->Arg(15); +// BENCHMARK_TEMPLATE(SUBSET_set_diff_single, 3, 0, 1)->Arg(15); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 3, 0, 1)->Arg(15); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 3, 0, 1)->Arg(15); +// BENCHMARK_TEMPLATE(SUBSET_set_intersect_single, 3, 0, 1)->Arg(15); +BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 3, 0, 1)->Arg(15); +BENCHMARK_TEMPLATE(SUBSET_set_union_disjoint, 3, 0, 1)->Arg(15); +// BENCHMARK_TEMPLATE(SUBSET_set_union_single, 3, 0, 1)->Arg(15); + +// Benchmarks pour les opérations géométriques (niveau unique) +BENCHMARK_TEMPLATE(SUBSET_translate, 1, 0)->Arg(1000); // ~1000 intervalles +BENCHMARK_TEMPLATE(SUBSET_translate, 2, 0)->Arg(45); // ~1000 intervalles +BENCHMARK_TEMPLATE(SUBSET_translate, 3, 0)->Arg(15); // ~1000 intervalles + +BENCHMARK_TEMPLATE(SUBSET_translate_and_project, 1, 0)->Arg(1000); +BENCHMARK_TEMPLATE(SUBSET_translate_and_project, 2, 0)->Arg(45); +BENCHMARK_TEMPLATE(SUBSET_translate_and_project, 3, 0)->Arg(15); + +BENCHMARK_TEMPLATE(SUBSET_self, 1, 0)->Arg(1000); // ~1000 intervalles +BENCHMARK_TEMPLATE(SUBSET_self, 2, 0)->Arg(45); // ~1000 intervalles +BENCHMARK_TEMPLATE(SUBSET_self, 3, 0)->Arg(15); // ~1000 intervalles + +BENCHMARK_TEMPLATE(SUBSET_self_and_project, 1, 0)->Arg(1000); +BENCHMARK_TEMPLATE(SUBSET_self_and_project, 2, 0)->Arg(45); +BENCHMARK_TEMPLATE(SUBSET_self_and_project, 3, 0)->Arg(15); + +// Benchmarks géométriques avec niveaux mixtes (niveau 0 vs autre niveau) +BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 1, 0, 0)->Arg(1000); +BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 2, 0, 0)->Arg(45); +BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 3, 0, 0)->Arg(15); + +BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 1, 0, 1)->Arg(1000); +BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 2, 0, 1)->Arg(45); +BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 2, 0, 2)->Arg(45); +BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 2, 0, 10)->Arg(45); // this bench is weird : the perf ??? maybe a bug. + +BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect_and_project, 1, 0, 0)->Arg(1000); +BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect_and_project, 2, 0, 0)->Arg(45); +BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect_and_project, 3, 0, 0)->Arg(15); + +/////////////////////////////////////////////////////////////////// +// Benchmarks avec niveaux mixtes (intéressants pour comparer les niveaux) +/////////////////////////////////////////////////////////////////// + +// Benchmarks 1D : niveau 0 vs niveau 1 +BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 1, 0, 1)->Arg(1000); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 1, 0, 1)->Arg(1000); +BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 1, 0, 1)->Arg(1000); + +// Benchmarks 1D : niveau 0 vs niveau 2 +BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 1, 0, 2)->Arg(1000); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 1, 0, 2)->Arg(1000); +BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 1, 0, 2)->Arg(1000); + +// Benchmarks 1D : niveau 1 vs niveau 2 +BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 1, 1, 2)->Arg(1000); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 1, 1, 2)->Arg(1000); +BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 1, 1, 2)->Arg(1000); + +// Benchmarks 2D : niveau 0 vs niveau 1 +BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 2, 0, 1)->Arg(45); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 2, 0, 1)->Arg(45); +BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 2, 0, 1)->Arg(45); + +// Benchmarks géométriques avec niveaux mixtes From 9038fa1ad890bce13527bc02719fc5f78cc2de79 Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Tue, 1 Jul 2025 11:18:06 +0200 Subject: [PATCH 07/12] update benhcmark --- benchmark/benchmark_subset.cpp | 320 +++++++++++++++++---------------- 1 file changed, 170 insertions(+), 150 deletions(-) diff --git a/benchmark/benchmark_subset.cpp b/benchmark/benchmark_subset.cpp index be84eb1cc..c94a34c62 100644 --- a/benchmark/benchmark_subset.cpp +++ b/benchmark/benchmark_subset.cpp @@ -22,98 +22,120 @@ // Fonctions utilitaires pour la génération d'intervalles /////////////////////////////////////////////////////////////////// +constexpr int DEFAULT_X_INTERVALS = 5; // nombre d'intervalles en X pour les cas 2D/3D + +// Générateur « régulier » template -auto gen_regular_intervals = [](auto& cl, int index, unsigned int level) +void gen_regular_intervals(auto& cl, int max_index, unsigned int level, int x_intervals = DEFAULT_X_INTERVALS) { - // Calcul des paramètres selon le niveau : - // Niveau L : taille = 2^L, espacement = 2^(L+1) int interval_size = 1 << level; // 2^level int spacing = 1 << (level + 1); // 2^(level+1) - int start = index * spacing; - int end = start + interval_size; if constexpr (dim == 1) { - cl[level][{}].add_interval({start, end}); + // En 1D on garde le comportement précédent : un intervalle par abscisse. + for (int x = 0; x < max_index; ++x) + { + int start = x * spacing; + cl[level][{}].add_interval({start, start + interval_size}); + } } else if constexpr (dim == 2) { - for (int y = 0; y < index; ++y) + int nx = x_intervals; + for (int x = 0; x < nx; ++x) { - xt::xtensor_fixed> coord{y}; - cl[level][coord].add_interval({start, end}); + int start = x * spacing; + int end = start + interval_size; + for (int y = 0; y < max_index; ++y) + { + xt::xtensor_fixed> coord{y}; + cl[level][coord].add_interval({start, end}); + } } } else if constexpr (dim == 3) { - for (int y = 0; y < index; ++y) + int nx = x_intervals; + for (int x = 0; x < nx; ++x) { - for (int z = 0; z < index; ++z) + int start = x * spacing; + int end = start + interval_size; + for (int y = 0; y < max_index; ++y) { - xt::xtensor_fixed> coord{y, z}; - cl[level][coord].add_interval({start, end}); + for (int z = 0; z < max_index; ++z) + { + xt::xtensor_fixed> coord{y, z}; + cl[level][coord].add_interval({start, end}); + } } } } -}; +} +// Générateur « décalé » template -auto gen_offset_intervals = [](auto& cl, int index, unsigned int level) +void gen_offset_intervals(auto& cl, int max_index, unsigned int level, int x_intervals = DEFAULT_X_INTERVALS) { - // Calcul des paramètres selon le niveau - int interval_size = 1 << level; // 2^level - int spacing = 1 << (level + 1); // 2^(level+1) - int start = index * spacing + interval_size; // Décalage d'une taille pour être disjoint des "same" - int end = start + interval_size; + int interval_size = 1 << level; // 2^level + int spacing = 1 << (level + 1); // 2^(level+1) if constexpr (dim == 1) { - cl[level][{}].add_interval({start, end}); + for (int x = 0; x < max_index; ++x) + { + int start = x * spacing + interval_size; // Décalage pour être disjoint + cl[level][{}].add_interval({start, start + interval_size}); + } } else if constexpr (dim == 2) { - for (int y = 0; y < index; ++y) + int nx = x_intervals; + for (int x = 0; x < nx; ++x) { - xt::xtensor_fixed> coord{y}; - cl[level][coord].add_interval({start, end}); + int start = x * spacing + interval_size; + int end = start + interval_size; + for (int y = 0; y < max_index; ++y) + { + xt::xtensor_fixed> coord{y}; + cl[level][coord].add_interval({start, end}); + } } } else if constexpr (dim == 3) { - for (int y = 0; y < index; ++y) + int nx = x_intervals; + for (int x = 0; x < nx; ++x) { - for (int z = 0; z < index; ++z) + int start = x * spacing + interval_size; + int end = start + interval_size; + for (int y = 0; y < max_index; ++y) { - xt::xtensor_fixed> coord{y, z}; - cl[level][coord].add_interval({start, end}); + for (int z = 0; z < max_index; ++z) + { + xt::xtensor_fixed> coord{y, z}; + cl[level][coord].add_interval({start, end}); + } } } } -}; +} +// Générateur « unique » : un intervalle englobant large +// (utilisé pour les cas « single » dans les benchmarks) template -auto gen_unique_interval = [](auto& cl, int index, unsigned int level) +void gen_unique_interval(auto& cl, int max_index, unsigned int level, int /*x_intervals inutilisé*/ = DEFAULT_X_INTERVALS) { - // Génère un seul grand intervalle qui grandit avec l'index - // Pour avoir une bounding box similaire aux autres générateurs, - // on crée un intervalle qui couvre plusieurs "espacements" - - int spacing = 1 << (level + 1); // 2^(level+1) - - // Créer un grand intervalle qui couvre (index+1) espacements complets - // Cela donne une taille proportionnelle à l'index, comme les autres générateurs - int interval_size = (index + 1) * spacing; + int spacing = 1 << (level + 1); // 2^(level+1) + int interval_size = (max_index)*spacing; // Grande taille proportionnelle à max_index if constexpr (dim == 1) { - if (index == 0) - { - cl[level][{}].add_interval({0, interval_size}); - } + cl[level][{}].add_interval({0, interval_size}); } else if constexpr (dim == 2) { - for (int y = 0; y < index; ++y) + for (int y = 0; y < max_index; ++y) { xt::xtensor_fixed> coord{y}; cl[level][coord].add_interval({0, interval_size}); @@ -121,16 +143,16 @@ auto gen_unique_interval = [](auto& cl, int index, unsigned int level) } else if constexpr (dim == 3) { - for (int y = 0; y < index; ++y) + for (int y = 0; y < max_index; ++y) { - for (int z = 0; z < index; ++z) + for (int z = 0; z < max_index; ++z) { xt::xtensor_fixed> coord{y, z}; cl[level][coord].add_interval({0, interval_size}); } } } -}; +} template auto create_translation_stencil() @@ -174,16 +196,32 @@ auto op_union = [](const auto& a, const auto& b) // Fonction de benchmark unifiée /////////////////////////////////////////////////////////////////// +// Wrappers lambda pour les générateurs afin de permettre la déduction de type +template +auto gen_regular_wrapper = [](auto& cl, int max_index, unsigned int level) +{ + gen_regular_intervals(cl, max_index, level); +}; + +template +auto gen_offset_wrapper = [](auto& cl, int max_index, unsigned int level) +{ + gen_offset_intervals(cl, max_index, level); +}; + +template +auto gen_unique_wrapper = [](auto& cl, int max_index, unsigned int level) +{ + gen_unique_interval(cl, max_index, level); +}; + template void SUBSET_unified_benchmark_mixed_levels(benchmark::State& state, Gen1&& gen1, Gen2&& gen2, Operation&& operation) { samurai::CellList cl1, cl2; - for (int64_t i = 0; i < state.range(0); i++) - { - int index = static_cast(i); - gen1(cl1, index, level1); - gen2(cl2, index, level2); - } + int max_index = static_cast(state.range(0)); + gen1(cl1, max_index, level1); + gen2(cl2, max_index, level2); samurai::CellArray ca1(cl1); samurai::CellArray ca2(cl2); @@ -222,55 +260,55 @@ void SUBSET_unified_benchmark_mixed_levels(benchmark::State& state, Gen1&& gen1, template void SUBSET_set_diff_identical(benchmark::State& state) { - SUBSET_unified_benchmark_mixed_levels(state, gen_regular_intervals, gen_regular_intervals, op_difference); + SUBSET_unified_benchmark_mixed_levels(state, gen_regular_wrapper, gen_regular_wrapper, op_difference); } template void SUBSET_set_diff_disjoint(benchmark::State& state) { - SUBSET_unified_benchmark_mixed_levels(state, gen_regular_intervals, gen_offset_intervals, op_difference); + SUBSET_unified_benchmark_mixed_levels(state, gen_regular_wrapper, gen_offset_wrapper, op_difference); } template void SUBSET_set_diff_single(benchmark::State& state) { - SUBSET_unified_benchmark_mixed_levels(state, gen_regular_intervals, gen_unique_interval, op_difference); + SUBSET_unified_benchmark_mixed_levels(state, gen_regular_wrapper, gen_unique_wrapper, op_difference); } template void SUBSET_set_intersect_identical(benchmark::State& state) { - SUBSET_unified_benchmark_mixed_levels(state, gen_regular_intervals, gen_regular_intervals, op_intersection); + SUBSET_unified_benchmark_mixed_levels(state, gen_regular_wrapper, gen_regular_wrapper, op_intersection); } template void SUBSET_set_intersect_disjoint(benchmark::State& state) { - SUBSET_unified_benchmark_mixed_levels(state, gen_regular_intervals, gen_offset_intervals, op_intersection); + SUBSET_unified_benchmark_mixed_levels(state, gen_regular_wrapper, gen_offset_wrapper, op_intersection); } template void SUBSET_set_intersect_single(benchmark::State& state) { - SUBSET_unified_benchmark_mixed_levels(state, gen_regular_intervals, gen_unique_interval, op_intersection); + SUBSET_unified_benchmark_mixed_levels(state, gen_regular_wrapper, gen_unique_wrapper, op_intersection); } template void SUBSET_set_union_identical(benchmark::State& state) { - SUBSET_unified_benchmark_mixed_levels(state, gen_regular_intervals, gen_regular_intervals, op_union); + SUBSET_unified_benchmark_mixed_levels(state, gen_regular_wrapper, gen_regular_wrapper, op_union); } template void SUBSET_set_union_disjoint(benchmark::State& state) { - SUBSET_unified_benchmark_mixed_levels(state, gen_regular_intervals, gen_offset_intervals, op_union); + SUBSET_unified_benchmark_mixed_levels(state, gen_regular_wrapper, gen_offset_wrapper, op_union); } template void SUBSET_set_union_single(benchmark::State& state) { - SUBSET_unified_benchmark_mixed_levels(state, gen_regular_intervals, gen_unique_interval, op_union); + SUBSET_unified_benchmark_mixed_levels(state, gen_regular_wrapper, gen_unique_wrapper, op_union); } /////////////////////////////////////////////////////////////////// @@ -281,11 +319,8 @@ template void SUBSET_translate(benchmark::State& state) { samurai::CellList cl; - for (int64_t i = 0; i < state.range(0); i++) - { - int index = static_cast(i); - gen_regular_intervals(cl, index, level); - } + int max_index = static_cast(state.range(0)); + gen_regular_intervals(cl, max_index, level); samurai::CellArray ca(cl); // Créer le stencil de translation @@ -317,12 +352,9 @@ template void SUBSET_translate_and_intersect(benchmark::State& state) { samurai::CellList cl1, cl2; - for (int64_t i = 0; i < state.range(0); i++) - { - int index = static_cast(i); - gen_regular_intervals(cl1, index, level1); - gen_regular_intervals(cl2, index, level2); - } + int max_index = static_cast(state.range(0)); + gen_regular_intervals(cl1, max_index, level1); + gen_regular_intervals(cl2, max_index, level2); samurai::CellArray ca1(cl1); samurai::CellArray ca2(cl2); @@ -358,12 +390,9 @@ template void SUBSET_translate_and_intersect_and_project(benchmark::State& state) { samurai::CellList cl1, cl2; - for (int64_t i = 0; i < state.range(0); i++) - { - int index = static_cast(i); - gen_regular_intervals(cl1, index, level1); - gen_regular_intervals(cl2, index, level2); - } + int max_index = static_cast(state.range(0)); + gen_regular_intervals(cl1, max_index, level1); + gen_regular_intervals(cl2, max_index, level2); samurai::CellArray ca1(cl1); samurai::CellArray ca2(cl2); @@ -400,11 +429,8 @@ template void SUBSET_translate_and_project(benchmark::State& state) { samurai::CellList cl; - for (int64_t i = 0; i < state.range(0); i++) - { - int index = static_cast(i); - gen_regular_intervals(cl, index, level); - } + int max_index = static_cast(state.range(0)); + gen_regular_intervals(cl, max_index, level); samurai::CellArray ca(cl); // Créer le stencil de translation @@ -437,11 +463,8 @@ template void SUBSET_self(benchmark::State& state) { samurai::CellList cl; - for (int64_t i = 0; i < state.range(0); i++) - { - int index = static_cast(i); - gen_regular_intervals(cl, index, level); - } + int max_index = static_cast(state.range(0)); + gen_regular_intervals(cl, max_index, level); samurai::CellArray ca(cl); // Ajouter les statistiques @@ -470,11 +493,8 @@ template void SUBSET_self_and_project(benchmark::State& state) { samurai::CellList cl; - for (int64_t i = 0; i < state.range(0); i++) - { - int index = static_cast(i); - gen_regular_intervals(cl, index, level); - } + int max_index = static_cast(state.range(0)); + gen_regular_intervals(cl, max_index, level); samurai::CellArray ca(cl); // Ajouter les statistiques @@ -526,77 +546,77 @@ BENCHMARK_TEMPLATE(SUBSET_set_union_disjoint, 1, 0, 1)->Arg(1000); // BENCHMARK_TEMPLATE(SUBSET_set_union_single, 1, 0, 1)->Arg(1000); // Benchmarks pour les opérations ensemblistes en 2D (même niveau) - ~1000 intervalles -BENCHMARK_TEMPLATE(SUBSET_set_diff_identical, 2, 0, 0)->Arg(45); -BENCHMARK_TEMPLATE(SUBSET_set_diff_disjoint, 2, 0, 0)->Arg(45); -// BENCHMARK_TEMPLATE(SUBSET_set_diff_single, 2, 0, 0)->Arg(45); -BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 2, 0, 0)->Arg(45); -BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 2, 0, 0)->Arg(45); -// BENCHMARK_TEMPLATE(SUBSET_set_intersect_single, 2, 0, 0)->Arg(45); -BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 2, 0, 0)->Arg(45); -BENCHMARK_TEMPLATE(SUBSET_set_union_disjoint, 2, 0, 0)->Arg(45); -// BENCHMARK_TEMPLATE(SUBSET_set_union_single, 2, 0, 0)->Arg(45); - -BENCHMARK_TEMPLATE(SUBSET_set_diff_identical, 2, 0, 1)->Arg(45); -BENCHMARK_TEMPLATE(SUBSET_set_diff_disjoint, 2, 0, 1)->Arg(45); -// BENCHMARK_TEMPLATE(SUBSET_set_diff_single, 2, 0, 1)->Arg(45); -BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 2, 0, 1)->Arg(45); -BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 2, 0, 1)->Arg(45); -// BENCHMARK_TEMPLATE(SUBSET_set_intersect_single, 2, 0, 1)->Arg(45); -BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 2, 0, 1)->Arg(45); -BENCHMARK_TEMPLATE(SUBSET_set_union_disjoint, 2, 0, 1)->Arg(45); -// BENCHMARK_TEMPLATE(SUBSET_set_union_single, 2, 0, 1)->Arg(45); +BENCHMARK_TEMPLATE(SUBSET_set_diff_identical, 2, 0, 0)->Arg(200); +BENCHMARK_TEMPLATE(SUBSET_set_diff_disjoint, 2, 0, 0)->Arg(200); +// BENCHMARK_TEMPLATE(SUBSET_set_diff_single, 2, 0, 0)->Arg(200); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 2, 0, 0)->Arg(200); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 2, 0, 0)->Arg(200); +// BENCHMARK_TEMPLATE(SUBSET_set_intersect_single, 2, 0, 0)->Arg(200); +BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 2, 0, 0)->Arg(200); +BENCHMARK_TEMPLATE(SUBSET_set_union_disjoint, 2, 0, 0)->Arg(200); +// BENCHMARK_TEMPLATE(SUBSET_set_union_single, 2, 0, 0)->Arg(200); + +BENCHMARK_TEMPLATE(SUBSET_set_diff_identical, 2, 0, 1)->Arg(200); +BENCHMARK_TEMPLATE(SUBSET_set_diff_disjoint, 2, 0, 1)->Arg(200); +// BENCHMARK_TEMPLATE(SUBSET_set_diff_single, 2, 0, 1)->Arg(200); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 2, 0, 1)->Arg(200); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 2, 0, 1)->Arg(200); +// BENCHMARK_TEMPLATE(SUBSET_set_intersect_single, 2, 0, 1)->Arg(200); +BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 2, 0, 1)->Arg(200); +BENCHMARK_TEMPLATE(SUBSET_set_union_disjoint, 2, 0, 1)->Arg(200); +// BENCHMARK_TEMPLATE(SUBSET_set_union_single, 2, 0, 1)->Arg(200); // Benchmarks pour les opérations ensemblistes en 3D (même niveau) - ~1000 intervalles -BENCHMARK_TEMPLATE(SUBSET_set_diff_identical, 3, 0, 0)->Arg(15); -BENCHMARK_TEMPLATE(SUBSET_set_diff_disjoint, 3, 0, 0)->Arg(15); -// BENCHMARK_TEMPLATE(SUBSET_set_diff_single, 3, 0, 0)->Arg(15); -BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 3, 0, 0)->Arg(15); -BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 3, 0, 0)->Arg(15); -// BENCHMARK_TEMPLATE(SUBSET_set_intersect_single, 3, 0, 0)->Arg(15); -BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 3, 0, 0)->Arg(15); -BENCHMARK_TEMPLATE(SUBSET_set_union_disjoint, 3, 0, 0)->Arg(15); -// BENCHMARK_TEMPLATE(SUBSET_set_union_single, 3, 0, 0)->Arg(15); - -BENCHMARK_TEMPLATE(SUBSET_set_diff_identical, 3, 0, 1)->Arg(15); -BENCHMARK_TEMPLATE(SUBSET_set_diff_disjoint, 3, 0, 1)->Arg(15); -// BENCHMARK_TEMPLATE(SUBSET_set_diff_single, 3, 0, 1)->Arg(15); -BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 3, 0, 1)->Arg(15); -BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 3, 0, 1)->Arg(15); -// BENCHMARK_TEMPLATE(SUBSET_set_intersect_single, 3, 0, 1)->Arg(15); -BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 3, 0, 1)->Arg(15); -BENCHMARK_TEMPLATE(SUBSET_set_union_disjoint, 3, 0, 1)->Arg(15); -// BENCHMARK_TEMPLATE(SUBSET_set_union_single, 3, 0, 1)->Arg(15); +BENCHMARK_TEMPLATE(SUBSET_set_diff_identical, 3, 0, 0)->Arg(14); +BENCHMARK_TEMPLATE(SUBSET_set_diff_disjoint, 3, 0, 0)->Arg(14); +// BENCHMARK_TEMPLATE(SUBSET_set_diff_single, 3, 0, 0)->Arg(14); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 3, 0, 0)->Arg(14); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 3, 0, 0)->Arg(14); +// BENCHMARK_TEMPLATE(SUBSET_set_intersect_single, 3, 0, 0)->Arg(14); +BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 3, 0, 0)->Arg(14); +BENCHMARK_TEMPLATE(SUBSET_set_union_disjoint, 3, 0, 0)->Arg(14); +// BENCHMARK_TEMPLATE(SUBSET_set_union_single, 3, 0, 0)->Arg(14); + +BENCHMARK_TEMPLATE(SUBSET_set_diff_identical, 3, 0, 1)->Arg(14); +BENCHMARK_TEMPLATE(SUBSET_set_diff_disjoint, 3, 0, 1)->Arg(14); +// BENCHMARK_TEMPLATE(SUBSET_set_diff_single, 3, 0, 1)->Arg(14); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 3, 0, 1)->Arg(14); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 3, 0, 1)->Arg(14); +// BENCHMARK_TEMPLATE(SUBSET_set_intersect_single, 3, 0, 1)->Arg(14); +BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 3, 0, 1)->Arg(14); +BENCHMARK_TEMPLATE(SUBSET_set_union_disjoint, 3, 0, 1)->Arg(14); +// BENCHMARK_TEMPLATE(SUBSET_set_union_single, 3, 0, 1)->Arg(14); // Benchmarks pour les opérations géométriques (niveau unique) BENCHMARK_TEMPLATE(SUBSET_translate, 1, 0)->Arg(1000); // ~1000 intervalles -BENCHMARK_TEMPLATE(SUBSET_translate, 2, 0)->Arg(45); // ~1000 intervalles -BENCHMARK_TEMPLATE(SUBSET_translate, 3, 0)->Arg(15); // ~1000 intervalles +BENCHMARK_TEMPLATE(SUBSET_translate, 2, 0)->Arg(200); // ~1000 intervalles +BENCHMARK_TEMPLATE(SUBSET_translate, 3, 0)->Arg(14); // ~1000 intervalles BENCHMARK_TEMPLATE(SUBSET_translate_and_project, 1, 0)->Arg(1000); -BENCHMARK_TEMPLATE(SUBSET_translate_and_project, 2, 0)->Arg(45); -BENCHMARK_TEMPLATE(SUBSET_translate_and_project, 3, 0)->Arg(15); +BENCHMARK_TEMPLATE(SUBSET_translate_and_project, 2, 0)->Arg(200); +BENCHMARK_TEMPLATE(SUBSET_translate_and_project, 3, 0)->Arg(14); BENCHMARK_TEMPLATE(SUBSET_self, 1, 0)->Arg(1000); // ~1000 intervalles -BENCHMARK_TEMPLATE(SUBSET_self, 2, 0)->Arg(45); // ~1000 intervalles -BENCHMARK_TEMPLATE(SUBSET_self, 3, 0)->Arg(15); // ~1000 intervalles +BENCHMARK_TEMPLATE(SUBSET_self, 2, 0)->Arg(200); // ~1000 intervalles +BENCHMARK_TEMPLATE(SUBSET_self, 3, 0)->Arg(14); // ~1000 intervalles BENCHMARK_TEMPLATE(SUBSET_self_and_project, 1, 0)->Arg(1000); -BENCHMARK_TEMPLATE(SUBSET_self_and_project, 2, 0)->Arg(45); -BENCHMARK_TEMPLATE(SUBSET_self_and_project, 3, 0)->Arg(15); +BENCHMARK_TEMPLATE(SUBSET_self_and_project, 2, 0)->Arg(200); +BENCHMARK_TEMPLATE(SUBSET_self_and_project, 3, 0)->Arg(14); // Benchmarks géométriques avec niveaux mixtes (niveau 0 vs autre niveau) BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 1, 0, 0)->Arg(1000); -BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 2, 0, 0)->Arg(45); -BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 3, 0, 0)->Arg(15); +BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 2, 0, 0)->Arg(200); +BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 3, 0, 0)->Arg(14); BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 1, 0, 1)->Arg(1000); -BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 2, 0, 1)->Arg(45); -BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 2, 0, 2)->Arg(45); -BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 2, 0, 10)->Arg(45); // this bench is weird : the perf ??? maybe a bug. +BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 2, 0, 1)->Arg(200); +BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 2, 0, 2)->Arg(200); +BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 2, 0, 10)->Arg(200); // this bench is weird : the perf ??? maybe a bug. BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect_and_project, 1, 0, 0)->Arg(1000); -BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect_and_project, 2, 0, 0)->Arg(45); -BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect_and_project, 3, 0, 0)->Arg(15); +BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect_and_project, 2, 0, 0)->Arg(200); +BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect_and_project, 3, 0, 0)->Arg(14); /////////////////////////////////////////////////////////////////// // Benchmarks avec niveaux mixtes (intéressants pour comparer les niveaux) @@ -618,8 +638,8 @@ BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 1, 1, 2)->Arg(1000); BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 1, 1, 2)->Arg(1000); // Benchmarks 2D : niveau 0 vs niveau 1 -BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 2, 0, 1)->Arg(45); -BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 2, 0, 1)->Arg(45); -BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 2, 0, 1)->Arg(45); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 2, 0, 1)->Arg(200); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 2, 0, 1)->Arg(200); +BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 2, 0, 1)->Arg(200); // Benchmarks géométriques avec niveaux mixtes From 8a20c82703ec04f86180a72a176277b530291b67 Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Tue, 1 Jul 2025 13:23:50 +0200 Subject: [PATCH 08/12] feat : improve benchmark --- benchmark/benchmark_cellarray.cpp | 76 ++++-- benchmark/benchmark_celllist_construction.cpp | 68 +++-- benchmark/benchmark_level_cell_array.cpp | 241 ++++++++---------- benchmark/benchmark_search.cpp | 69 ++--- benchmark/benchmark_subset.cpp | 226 ++++++++-------- 5 files changed, 352 insertions(+), 328 deletions(-) diff --git a/benchmark/benchmark_cellarray.cpp b/benchmark/benchmark_cellarray.cpp index de764ca47..17d35b12a 100644 --- a/benchmark/benchmark_cellarray.cpp +++ b/benchmark/benchmark_cellarray.cpp @@ -1,4 +1,3 @@ - #include #include #include @@ -23,39 +22,49 @@ /////////////////////////////////////////////////////////////////// // utils +constexpr int DEFAULT_X_INTERVALS = 5; // nombre d'intervalles en X pour les cas 2D/3D + template -auto gen_regular_intervals = [](int64_t size, unsigned int level = 0) +auto gen_regular_intervals = [](int max_index, unsigned int level = 0, int x_intervals = DEFAULT_X_INTERVALS) { samurai::CellList cl; - for (int64_t i = 0; i < size; i++) - { - int index = static_cast(i); - - // Calcul des paramètres selon le niveau : - // Niveau L : taille = 2^L, espacement = 2^(L+1) - int interval_size = 1 << level; // 2^level - int spacing = 1 << (level + 1); // 2^(level+1) - int start = index * spacing; - int end = start + interval_size; + int interval_size = 1 << level; // 2^level + int spacing = 1 << (level + 1); // 2^(level+1) - if constexpr (dim == 1) + if constexpr (dim == 1) + { + // En 1D on garde le comportement précédent : un intervalle par abscisse. + for (int x = 0; x < max_index; ++x) { - cl[level][{}].add_interval({start, end}); + int start = x * spacing; + cl[level][{}].add_interval({start, start + interval_size}); } - else if constexpr (dim == 2) + } + else if constexpr (dim == 2) + { + int nx = x_intervals; + for (int x = 0; x < nx; ++x) { - for (int y = 0; y < size; ++y) + int start = x * spacing; + int end = start + interval_size; + for (int y = 0; y < max_index; ++y) { xt::xtensor_fixed> coord{y}; cl[level][coord].add_interval({start, end}); } } - else if constexpr (dim == 3) + } + else if constexpr (dim == 3) + { + int nx = x_intervals; + for (int x = 0; x < nx; ++x) { - for (int y = 0; y < size; ++y) + int start = x * spacing; + int end = start + interval_size; + for (int y = 0; y < max_index; ++y) { - for (int z = 0; z < size; ++z) + for (int z = 0; z < max_index; ++z) { xt::xtensor_fixed> coord{y, z}; cl[level][coord].add_interval({start, end}); @@ -68,9 +77,9 @@ auto gen_regular_intervals = [](int64_t size, unsigned int level = 0) }; template -auto cell_array_with_n_intervals(int64_t size) +auto cell_array_with_n_intervals(int max_index) { - auto cl = gen_regular_intervals(size); + auto cl = gen_regular_intervals(max_index, 0, DEFAULT_X_INTERVALS); samurai::CellArray ca(cl); return ca; } @@ -91,10 +100,23 @@ void CELLARRAY_default(benchmark::State& state) template void CELLARRAY_cl_ca_multi(benchmark::State& state) { - auto cl = gen_regular_intervals(state.range(0)); + int max_index = static_cast(state.range(0)); + auto cl = gen_regular_intervals(max_index, 0, DEFAULT_X_INTERVALS); - // Le nombre d'intervalles est state.range(0)^dim - std::size_t nb_intervals = static_cast(std::pow(state.range(0), dim)); + // Calculer le nombre d'intervalles selon la nouvelle logique + std::size_t nb_intervals; + if constexpr (dim == 1) + { + nb_intervals = max_index; + } + else if constexpr (dim == 2) + { + nb_intervals = DEFAULT_X_INTERVALS * max_index; + } + else if constexpr (dim == 3) + { + nb_intervals = DEFAULT_X_INTERVALS * max_index * max_index; + } for (auto _ : state) { @@ -162,9 +184,9 @@ BENCHMARK_TEMPLATE(CELLARRAY_default, 1, 12); BENCHMARK_TEMPLATE(CELLARRAY_default, 2, 12); BENCHMARK_TEMPLATE(CELLARRAY_default, 3, 12); -BENCHMARK_TEMPLATE(CELLARRAY_cl_ca_multi, 1)->RangeMultiplier(8)->Range(1 << 1, 1 << 10); -BENCHMARK_TEMPLATE(CELLARRAY_cl_ca_multi, 2)->RangeMultiplier(4)->Range(1 << 1, 1 << 6); -BENCHMARK_TEMPLATE(CELLARRAY_cl_ca_multi, 3)->RangeMultiplier(2)->Range(1 << 1, 1 << 4); +BENCHMARK_TEMPLATE(CELLARRAY_cl_ca_multi, 1)->RangeMultiplier(8)->Range(1 << 1, 10000); +BENCHMARK_TEMPLATE(CELLARRAY_cl_ca_multi, 2)->RangeMultiplier(4)->Range(1 << 1, 2000); +BENCHMARK_TEMPLATE(CELLARRAY_cl_ca_multi, 3)->RangeMultiplier(2)->Range(1 << 1, 45); BENCHMARK_TEMPLATE(CELLARRAY_min_level, 1)->Arg(15); BENCHMARK_TEMPLATE(CELLARRAY_min_level, 2)->Arg(15); diff --git a/benchmark/benchmark_celllist_construction.cpp b/benchmark/benchmark_celllist_construction.cpp index f5f51e142..5351092d9 100644 --- a/benchmark/benchmark_celllist_construction.cpp +++ b/benchmark/benchmark_celllist_construction.cpp @@ -9,39 +9,49 @@ //////////////////////////////////////////////////////////// /// Générateur d'intervalles réguliers (adapté de benchmark_search.cpp) +constexpr int DEFAULT_X_INTERVALS = 5; // nombre d'intervalles en X pour les cas 2D/3D + template -auto gen_regular_intervals = [](int64_t size, unsigned int level = 0) +auto gen_regular_intervals = [](int max_index, unsigned int level = 0, int x_intervals = DEFAULT_X_INTERVALS) { samurai::CellList cl; - for (int64_t i = 0; i < size; i++) - { - int index = static_cast(i); - - // Calcul des paramètres selon le niveau : - // Niveau L : taille = 2^L, espacement = 2^(L+1) - int interval_size = 1 << level; // 2^level - int spacing = 1 << (level + 1); // 2^(level+1) - int start = index * spacing; - int end = start + interval_size; + int interval_size = 1 << level; // 2^level + int spacing = 1 << (level + 1); // 2^(level+1) - if constexpr (dim == 1) + if constexpr (dim == 1) + { + // En 1D on garde le comportement précédent : un intervalle par abscisse. + for (int x = 0; x < max_index; ++x) { - cl[level][{}].add_interval({start, end}); + int start = x * spacing; + cl[level][{}].add_interval({start, start + interval_size}); } - else if constexpr (dim == 2) + } + else if constexpr (dim == 2) + { + int nx = x_intervals; + for (int x = 0; x < nx; ++x) { - for (int y = 0; y < size; ++y) + int start = x * spacing; + int end = start + interval_size; + for (int y = 0; y < max_index; ++y) { xt::xtensor_fixed> coord{y}; cl[level][coord].add_interval({start, end}); } } - else if constexpr (dim == 3) + } + else if constexpr (dim == 3) + { + int nx = x_intervals; + for (int x = 0; x < nx; ++x) { - for (int y = 0; y < size; ++y) + int start = x * spacing; + int end = start + interval_size; + for (int y = 0; y < max_index; ++y) { - for (int z = 0; z < size; ++z) + for (int z = 0; z < max_index; ++z) { xt::xtensor_fixed> coord{y, z}; cl[level][coord].add_interval({start, end}); @@ -119,13 +129,14 @@ void CELLLIST_default(benchmark::State& state) template void CELLLIST_add_interval_begin(benchmark::State& state) { + int max_index = static_cast(state.range(0)); // Calculer une seule fois pour les métriques - auto cl_sample = gen_regular_intervals(state.range(0), 0); + auto cl_sample = gen_regular_intervals(max_index, 0, DEFAULT_X_INTERVALS); std::size_t total_intervals = count_intervals(cl_sample); for (auto _ : state) { - auto cl = gen_regular_intervals(state.range(0), 0); + auto cl = gen_regular_intervals(max_index, 0, DEFAULT_X_INTERVALS); benchmark::DoNotOptimize(cl); } @@ -139,7 +150,8 @@ void CELLLIST_add_interval_begin(benchmark::State& state) template void CELLLIST_copy_assignment(benchmark::State& state) { - auto source_cl = gen_regular_intervals(state.range(0), 0); + int max_index = static_cast(state.range(0)); + auto source_cl = gen_regular_intervals(max_index, 0, DEFAULT_X_INTERVALS); std::size_t total_intervals = count_intervals(source_cl); for (auto _ : state) @@ -163,11 +175,11 @@ BENCHMARK_TEMPLATE(CELLLIST_default, 1); BENCHMARK_TEMPLATE(CELLLIST_default, 2); BENCHMARK_TEMPLATE(CELLLIST_default, 3); -// Générateur avec intervalles réguliers (toutes dimensions) -BENCHMARK_TEMPLATE(CELLLIST_add_interval_begin, 1)->RangeMultiplier(64)->Range(1 << 1, 1 << 16); -BENCHMARK_TEMPLATE(CELLLIST_add_interval_begin, 2)->RangeMultiplier(8)->Range(1 << 1, 1 << 8); -BENCHMARK_TEMPLATE(CELLLIST_add_interval_begin, 3)->RangeMultiplier(4)->Range(1 << 1, 1 << 5); +// Générateur avec intervalles réguliers (toutes dimensions) - Ajusté pour ~10k intervalles max +BENCHMARK_TEMPLATE(CELLLIST_add_interval_begin, 1)->RangeMultiplier(64)->Range(1 << 1, 10000); +BENCHMARK_TEMPLATE(CELLLIST_add_interval_begin, 2)->RangeMultiplier(8)->Range(1 << 1, 2000); +BENCHMARK_TEMPLATE(CELLLIST_add_interval_begin, 3)->RangeMultiplier(4)->Range(1 << 1, 45); -BENCHMARK_TEMPLATE(CELLLIST_copy_assignment, 1)->RangeMultiplier(64)->Range(1 << 1, 1 << 16); -BENCHMARK_TEMPLATE(CELLLIST_copy_assignment, 2)->RangeMultiplier(8)->Range(1 << 1, 1 << 8); -BENCHMARK_TEMPLATE(CELLLIST_copy_assignment, 3)->RangeMultiplier(4)->Range(1 << 1, 1 << 5); +BENCHMARK_TEMPLATE(CELLLIST_copy_assignment, 1)->RangeMultiplier(64)->Range(1 << 1, 10000); +BENCHMARK_TEMPLATE(CELLLIST_copy_assignment, 2)->RangeMultiplier(8)->Range(1 << 1, 2000); +BENCHMARK_TEMPLATE(CELLLIST_copy_assignment, 3)->RangeMultiplier(4)->Range(1 << 1, 45); diff --git a/benchmark/benchmark_level_cell_array.cpp b/benchmark/benchmark_level_cell_array.cpp index bc1d5153f..0e38fc6e1 100644 --- a/benchmark/benchmark_level_cell_array.cpp +++ b/benchmark/benchmark_level_cell_array.cpp @@ -19,106 +19,124 @@ // Pourquoi -default est plus lent que _empty_lcl_to_lca en 2D/3D ?? // max_indices et min_indices très couteux : on peut pas faire mieux ?????? +constexpr int DEFAULT_X_INTERVALS = 5; // nombre d'intervalles en X pour les cas 2D/3D + /////////////////////////////////////////////////////////////////// // utils template -auto gen_regular_intervals = [](auto& lcl, int index, unsigned int level) +auto gen_regular_intervals = [](auto& lcl, int max_index, unsigned int level, int x_intervals = DEFAULT_X_INTERVALS) { - // Calcul des paramètres selon le niveau : - // Niveau L : taille = 2^L, espacement = 2^(L+1) int interval_size = 1 << level; // 2^level int spacing = 1 << (level + 1); // 2^(level+1) - int start = index * spacing; - int end = start + interval_size; if constexpr (dim == 1) { - lcl[{}].add_interval({start, end}); + // En 1D on garde le comportement précédent : un intervalle par abscisse. + for (int x = 0; x < max_index; ++x) + { + int start = x * spacing; + lcl[{}].add_interval({start, start + interval_size}); + } } else if constexpr (dim == 2) { - for (int y = 0; y < index; ++y) + int nx = x_intervals; + for (int x = 0; x < nx; ++x) { - lcl[{y}].add_interval({start, end}); + int start = x * spacing; + int end = start + interval_size; + for (int y = 0; y < max_index; ++y) + { + lcl[{y}].add_interval({start, end}); + } } } else if constexpr (dim == 3) { - for (int y = 0; y < index; ++y) + int nx = x_intervals; + for (int x = 0; x < nx; ++x) { - for (int z = 0; z < index; ++z) + int start = x * spacing; + int end = start + interval_size; + for (int y = 0; y < max_index; ++y) { - lcl[{y, z}].add_interval({start, end}); + for (int z = 0; z < max_index; ++z) + { + lcl[{y, z}].add_interval({start, end}); + } } } } }; template -auto gen_offset_intervals = [](auto& lcl, int index, unsigned int level) +auto gen_offset_intervals = [](auto& lcl, int max_index, unsigned int level, int x_intervals = DEFAULT_X_INTERVALS) { - // Calcul des paramètres selon le niveau - int interval_size = 1 << level; // 2^level - int spacing = 1 << (level + 1); // 2^(level+1) - int start = index * spacing + interval_size; // Décalage d'une taille pour être disjoint des "same" - int end = start + interval_size; + int interval_size = 1 << level; // 2^level + int spacing = 1 << (level + 1); // 2^(level+1) if constexpr (dim == 1) { - lcl[{}].add_interval({start, end}); + for (int x = 0; x < max_index; ++x) + { + int start = x * spacing + interval_size; // Décalage pour être disjoint + lcl[{}].add_interval({start, start + interval_size}); + } } else if constexpr (dim == 2) { - for (int y = 0; y < index; ++y) + int nx = x_intervals; + for (int x = 0; x < nx; ++x) { - lcl[{y}].add_interval({start, end}); + int start = x * spacing + interval_size; + int end = start + interval_size; + for (int y = 0; y < max_index; ++y) + { + lcl[{y}].add_interval({start, end}); + } } } else if constexpr (dim == 3) { - for (int y = 0; y < index; ++y) + int nx = x_intervals; + for (int x = 0; x < nx; ++x) { - for (int z = 0; z < index; ++z) + int start = x * spacing + interval_size; + int end = start + interval_size; + for (int y = 0; y < max_index; ++y) { - lcl[{y, z}].add_interval({start, end}); + for (int z = 0; z < max_index; ++z) + { + lcl[{y, z}].add_interval({start, end}); + } } } } }; template -auto gen_unique_interval = [](auto& lcl, int index, unsigned int level) +auto gen_unique_interval = [](auto& lcl, int max_index, unsigned int level, int x_intervals = DEFAULT_X_INTERVALS) { - // Génère un seul grand intervalle qui grandit avec l'index - // Pour avoir une bounding box similaire aux autres générateurs, - // on crée un intervalle qui couvre plusieurs "espacements" - - int spacing = 1 << (level + 1); // 2^(level+1) - - // Créer un grand intervalle qui couvre (index+1) espacements complets - // Cela donne une taille proportionnelle à l'index, comme les autres générateurs - int interval_size = (index + 1) * spacing; + int spacing = 1 << (level + 1); // 2^(level+1) + int interval_size = (max_index)*spacing; // Grande taille proportionnelle à max_index if constexpr (dim == 1) { - if (index == 0) - { - lcl[{}].add_interval({0, interval_size}); - } + lcl[{}].add_interval({0, interval_size}); } else if constexpr (dim == 2) { - for (int y = 0; y < index; ++y) + for (int y = 0; y < max_index; ++y) { lcl[{y}].add_interval({0, interval_size}); } } else if constexpr (dim == 3) { - for (int y = 0; y < index; ++y) + for (int y = 0; y < max_index; ++y) { - for (int z = 0; z < index; ++z) + for (int z = 0; z < max_index; ++z) { lcl[{y, z}].add_interval({0, interval_size}); } @@ -159,11 +177,8 @@ void LEVELCELLARRAY_lcl_to_lca(benchmark::State& state) { samurai::LevelCellList lcl; using TInterval = samurai::default_config::interval_t; - for (int64_t i = 0; i < state.range(0); i++) - { - int index = static_cast(i); - gen_regular_intervals(lcl, index, 0); - } + int max_index = static_cast(state.range(0)); + gen_regular_intervals(lcl, max_index, 0, DEFAULT_X_INTERVALS); // Créer un LevelCellArray temporaire pour compter les intervalles auto temp_lca = samurai::LevelCellArray(lcl); @@ -187,11 +202,8 @@ void LEVELCELLARRAY_begin(benchmark::State& state) { samurai::LevelCellList lcl; using TInterval = samurai::default_config::interval_t; - for (int64_t i = 0; i < state.range(0); i++) - { - int index = static_cast(i); - gen_regular_intervals(lcl, index, 0); - } + int max_index = static_cast(state.range(0)); + gen_regular_intervals(lcl, max_index, 0, DEFAULT_X_INTERVALS); auto lca = samurai::LevelCellArray(lcl); for (auto _ : state) @@ -207,11 +219,8 @@ void LEVELCELLARRAY_end(benchmark::State& state) { samurai::LevelCellList lcl; using TInterval = samurai::default_config::interval_t; - for (int64_t i = 0; i < state.range(0); i++) - { - int index = static_cast(i); - gen_regular_intervals(lcl, index, 0); - } + int max_index = static_cast(state.range(0)); + gen_regular_intervals(lcl, max_index, 0, DEFAULT_X_INTERVALS); auto lca = samurai::LevelCellArray(lcl); for (auto _ : state) @@ -227,11 +236,8 @@ void LEVELCELLARRAY_shape(benchmark::State& state) { samurai::LevelCellList lcl; using TInterval = samurai::default_config::interval_t; - for (int64_t i = 0; i < state.range(0); i++) - { - int index = static_cast(i); - gen_regular_intervals(lcl, index, 0); - } + int max_index = static_cast(state.range(0)); + gen_regular_intervals(lcl, max_index, 0, DEFAULT_X_INTERVALS); auto lca = samurai::LevelCellArray(lcl); for (auto _ : state) @@ -247,11 +253,8 @@ void LEVELCELLARRAY_nb_intervals(benchmark::State& state) { samurai::LevelCellList lcl; using TInterval = samurai::default_config::interval_t; - for (int64_t i = 0; i < state.range(0); i++) - { - int index = static_cast(i); - gen_regular_intervals(lcl, index, 0); - } + int max_index = static_cast(state.range(0)); + gen_regular_intervals(lcl, max_index, 0, DEFAULT_X_INTERVALS); auto lca = samurai::LevelCellArray(lcl); for (auto _ : state) @@ -267,11 +270,8 @@ void LEVELCELLARRAY_nb_cells(benchmark::State& state) { samurai::LevelCellList lcl; using TInterval = samurai::default_config::interval_t; - for (int64_t i = 0; i < state.range(0); i++) - { - int index = static_cast(i); - gen_regular_intervals(lcl, index, 0); - } + int max_index = static_cast(state.range(0)); + gen_regular_intervals(lcl, max_index, 0, DEFAULT_X_INTERVALS); auto lca = samurai::LevelCellArray(lcl); auto total_intervals = lca.nb_intervals(); @@ -293,11 +293,8 @@ void LEVELCELLARRAY_cell_length(benchmark::State& state) { samurai::LevelCellList lcl; using TInterval = samurai::default_config::interval_t; - for (int64_t i = 0; i < state.range(0); i++) - { - int index = static_cast(i); - gen_regular_intervals(lcl, index, 0); - } + int max_index = static_cast(state.range(0)); + gen_regular_intervals(lcl, max_index, 0, DEFAULT_X_INTERVALS); auto lca = samurai::LevelCellArray(lcl); for (auto _ : state) { @@ -312,11 +309,8 @@ void LEVELCELLARRAY_max_indices(benchmark::State& state) { samurai::LevelCellList lcl; using TInterval = samurai::default_config::interval_t; - for (int64_t i = 0; i < state.range(0); i++) - { - int index = static_cast(i); - gen_regular_intervals(lcl, index, 0); - } + int max_index = static_cast(state.range(0)); + gen_regular_intervals(lcl, max_index, 0, DEFAULT_X_INTERVALS); auto lca = samurai::LevelCellArray(lcl); auto total_intervals = lca.nb_intervals(); @@ -338,11 +332,8 @@ void LEVELCELLARRAY_min_indices(benchmark::State& state) { samurai::LevelCellList lcl; using TInterval = samurai::default_config::interval_t; - for (int64_t i = 0; i < state.range(0); i++) - { - int index = static_cast(i); - gen_regular_intervals(lcl, index, 0); - } + int max_index = static_cast(state.range(0)); + gen_regular_intervals(lcl, max_index, 0, DEFAULT_X_INTERVALS); auto lca = samurai::LevelCellArray(lcl); auto total_intervals = lca.nb_intervals(); @@ -364,11 +355,8 @@ void LEVELCELLARRAY_minmax_indices(benchmark::State& state) { samurai::LevelCellList lcl; using TInterval = samurai::default_config::interval_t; - for (int64_t i = 0; i < state.range(0); i++) - { - int index = static_cast(i); - gen_regular_intervals(lcl, index, 0); - } + int max_index = static_cast(state.range(0)); + gen_regular_intervals(lcl, max_index, 0, DEFAULT_X_INTERVALS); auto lca = samurai::LevelCellArray(lcl); auto total_intervals = lca.nb_intervals(); @@ -390,11 +378,8 @@ void LEVELCELLARRAY_equal(benchmark::State& state) { samurai::LevelCellList lcl; using TInterval = samurai::default_config::interval_t; - for (int64_t i = 0; i < state.range(0); i++) - { - int index = static_cast(i); - gen_regular_intervals(lcl, index, 0); - } + int max_index = static_cast(state.range(0)); + gen_regular_intervals(lcl, max_index, 0, DEFAULT_X_INTERVALS); auto lca = samurai::LevelCellArray(lcl); auto lca2 = samurai::LevelCellArray(lcl); @@ -417,11 +402,8 @@ void LEVELCELLARRAY_min_level(benchmark::State& state) { samurai::LevelCellList lcl; using TInterval = samurai::default_config::interval_t; - for (int64_t i = 0; i < state.range(0); i++) - { - int index = static_cast(i); - gen_regular_intervals(lcl, index, 0); - } + int max_index = static_cast(state.range(0)); + gen_regular_intervals(lcl, max_index, 0, DEFAULT_X_INTERVALS); auto lca = samurai::LevelCellArray(lcl); for (auto _ : state) @@ -437,11 +419,8 @@ void LEVELCELLARRAY_rbegin(benchmark::State& state) { samurai::LevelCellList lcl; using TInterval = samurai::default_config::interval_t; - for (int64_t i = 0; i < state.range(0); i++) - { - int index = static_cast(i); - gen_regular_intervals(lcl, index, 0); - } + int max_index = static_cast(state.range(0)); + gen_regular_intervals(lcl, max_index, 0, DEFAULT_X_INTERVALS); auto lca = samurai::LevelCellArray(lcl); for (auto _ : state) @@ -461,53 +440,53 @@ BENCHMARK_TEMPLATE(LEVELCELLARRAY_empty_lcl_to_lca, 2); BENCHMARK_TEMPLATE(LEVELCELLARRAY_empty_lcl_to_lca, 3); BENCHMARK_TEMPLATE(LEVELCELLARRAY_lcl_to_lca, 1)->Arg(10000); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_lcl_to_lca, 2)->Arg(141); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_lcl_to_lca, 3)->Arg(32); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_lcl_to_lca, 2)->Arg(2000); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_lcl_to_lca, 3)->Arg(45); BENCHMARK_TEMPLATE(LEVELCELLARRAY_begin, 1)->Arg(10000); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_begin, 2)->Arg(141); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_begin, 3)->Arg(32); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_begin, 2)->Arg(2000); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_begin, 3)->Arg(45); BENCHMARK_TEMPLATE(LEVELCELLARRAY_end, 1)->Arg(10000); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_end, 2)->Arg(141); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_end, 3)->Arg(32); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_end, 2)->Arg(2000); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_end, 3)->Arg(45); BENCHMARK_TEMPLATE(LEVELCELLARRAY_shape, 1)->Arg(10000); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_shape, 2)->Arg(141); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_shape, 3)->Arg(32); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_shape, 2)->Arg(2000); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_shape, 3)->Arg(45); BENCHMARK_TEMPLATE(LEVELCELLARRAY_nb_intervals, 1)->Arg(10000); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_nb_intervals, 2)->Arg(141); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_nb_intervals, 3)->Arg(32); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_nb_intervals, 2)->Arg(2000); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_nb_intervals, 3)->Arg(45); BENCHMARK_TEMPLATE(LEVELCELLARRAY_nb_cells, 1)->Arg(10000); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_nb_cells, 2)->Arg(141); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_nb_cells, 3)->Arg(32); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_nb_cells, 2)->Arg(2000); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_nb_cells, 3)->Arg(45); BENCHMARK_TEMPLATE(LEVELCELLARRAY_cell_length, 1)->Arg(10000); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_cell_length, 2)->Arg(141); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_cell_length, 3)->Arg(32); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_cell_length, 2)->Arg(2000); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_cell_length, 3)->Arg(45); BENCHMARK_TEMPLATE(LEVELCELLARRAY_max_indices, 1)->Arg(10000); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_max_indices, 2)->Arg(141); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_max_indices, 3)->Arg(32); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_max_indices, 2)->Arg(2000); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_max_indices, 3)->Arg(45); BENCHMARK_TEMPLATE(LEVELCELLARRAY_min_indices, 1)->Arg(10000); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_min_indices, 2)->Arg(141); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_min_indices, 3)->Arg(32); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_min_indices, 2)->Arg(2000); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_min_indices, 3)->Arg(45); BENCHMARK_TEMPLATE(LEVELCELLARRAY_minmax_indices, 1)->Arg(10000); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_minmax_indices, 2)->Arg(141); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_minmax_indices, 3)->Arg(32); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_minmax_indices, 2)->Arg(2000); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_minmax_indices, 3)->Arg(45); BENCHMARK_TEMPLATE(LEVELCELLARRAY_equal, 1)->Arg(10000); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_equal, 2)->Arg(141); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_equal, 3)->Arg(32); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_equal, 2)->Arg(2000); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_equal, 3)->Arg(45); BENCHMARK_TEMPLATE(LEVELCELLARRAY_min_level, 1)->Arg(10000); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_min_level, 2)->Arg(141); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_min_level, 3)->Arg(32); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_min_level, 2)->Arg(2000); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_min_level, 3)->Arg(45); BENCHMARK_TEMPLATE(LEVELCELLARRAY_rbegin, 1)->Arg(10000); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_rbegin, 2)->Arg(141); -BENCHMARK_TEMPLATE(LEVELCELLARRAY_rbegin, 3)->Arg(32); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_rbegin, 2)->Arg(2000); +BENCHMARK_TEMPLATE(LEVELCELLARRAY_rbegin, 3)->Arg(45); diff --git a/benchmark/benchmark_search.cpp b/benchmark/benchmark_search.cpp index 85ae68372..ae36d5332 100644 --- a/benchmark/benchmark_search.cpp +++ b/benchmark/benchmark_search.cpp @@ -14,39 +14,49 @@ //////////////////////////////////////////////////////////// /// utils +constexpr int DEFAULT_X_INTERVALS = 5; // nombre d'intervalles en X pour les cas 2D/3D + template -auto gen_regular_intervals = [](int64_t size, unsigned int level = 0) +auto gen_regular_intervals = [](int max_index, unsigned int level = 0, int x_intervals = DEFAULT_X_INTERVALS) { samurai::CellList cl; - for (int64_t i = 0; i < size; i++) - { - int index = static_cast(i); - - // Calcul des paramètres selon le niveau : - // Niveau L : taille = 2^L, espacement = 2^(L+1) - int interval_size = 1 << level; // 2^level - int spacing = 1 << (level + 1); // 2^(level+1) - int start = index * spacing; - int end = start + interval_size; + int interval_size = 1 << level; // 2^level + int spacing = 1 << (level + 1); // 2^(level+1) - if constexpr (dim == 1) + if constexpr (dim == 1) + { + // En 1D on garde le comportement précédent : un intervalle par abscisse. + for (int x = 0; x < max_index; ++x) { - cl[level][{}].add_interval({start, end}); + int start = x * spacing; + cl[level][{}].add_interval({start, start + interval_size}); } - else if constexpr (dim == 2) + } + else if constexpr (dim == 2) + { + int nx = x_intervals; + for (int x = 0; x < nx; ++x) { - for (int y = 0; y < size; ++y) + int start = x * spacing; + int end = start + interval_size; + for (int y = 0; y < max_index; ++y) { xt::xtensor_fixed> coord{y}; cl[level][coord].add_interval({start, end}); } } - else if constexpr (dim == 3) + } + else if constexpr (dim == 3) + { + int nx = x_intervals; + for (int x = 0; x < nx; ++x) { - for (int y = 0; y < size; ++y) + int start = x * spacing; + int end = start + interval_size; + for (int y = 0; y < max_index; ++y) { - for (int z = 0; z < size; ++z) + for (int z = 0; z < max_index; ++z) { xt::xtensor_fixed> coord{y, z}; cl[level][coord].add_interval({start, end}); @@ -59,9 +69,9 @@ auto gen_regular_intervals = [](int64_t size, unsigned int level = 0) }; template -auto cell_array_with_n_intervals(int64_t size) +auto cell_array_with_n_intervals(int max_index) { - auto cl = gen_regular_intervals(size); + auto cl = gen_regular_intervals(max_index, 0, DEFAULT_X_INTERVALS); samurai::CellArray ca(cl); return ca; } @@ -141,15 +151,16 @@ void FIND_find_middle(benchmark::State& state) FIND_find_unified(state, coord_generator); } -BENCHMARK_TEMPLATE(FIND_find_start, 1)->Args({2})->Args({4})->Args({32})->Args({64}); -BENCHMARK_TEMPLATE(FIND_find_start, 2)->Args({2})->Args({4})->Args({32})->Args({64}); -BENCHMARK_TEMPLATE(FIND_find_start, 3)->Args({2})->Args({4})->Args({32})->Args({64}); -BENCHMARK_TEMPLATE(FIND_find_end, 1)->Args({2})->Args({4})->Args({32})->Args({64}); -BENCHMARK_TEMPLATE(FIND_find_end, 2)->Args({2})->Args({4})->Args({32})->Args({64}); -BENCHMARK_TEMPLATE(FIND_find_end, 3)->Args({2})->Args({4})->Args({32})->Args({64}); -BENCHMARK_TEMPLATE(FIND_find_middle, 1)->Args({2})->Args({4})->Args({32})->Args({64}); -BENCHMARK_TEMPLATE(FIND_find_middle, 2)->Args({2})->Args({4})->Args({32})->Args({64}); -BENCHMARK_TEMPLATE(FIND_find_middle, 3)->Args({2})->Args({4})->Args({32})->Args({64}); +// Ajusté pour ~10k intervalles max : 1D=10000, 2D=2000, 3D=45 +BENCHMARK_TEMPLATE(FIND_find_start, 1)->Args({2})->Args({32})->Args({1000})->Args({10000}); +BENCHMARK_TEMPLATE(FIND_find_start, 2)->Args({2})->Args({32})->Args({200})->Args({2000}); +BENCHMARK_TEMPLATE(FIND_find_start, 3)->Args({2})->Args({8})->Args({20})->Args({45}); +BENCHMARK_TEMPLATE(FIND_find_end, 1)->Args({2})->Args({32})->Args({1000})->Args({10000}); +BENCHMARK_TEMPLATE(FIND_find_end, 2)->Args({2})->Args({32})->Args({200})->Args({2000}); +BENCHMARK_TEMPLATE(FIND_find_end, 3)->Args({2})->Args({8})->Args({20})->Args({45}); +BENCHMARK_TEMPLATE(FIND_find_middle, 1)->Args({2})->Args({32})->Args({1000})->Args({10000}); +BENCHMARK_TEMPLATE(FIND_find_middle, 2)->Args({2})->Args({32})->Args({200})->Args({2000}); +BENCHMARK_TEMPLATE(FIND_find_middle, 3)->Args({2})->Args({8})->Args({20})->Args({45}); /** template diff --git a/benchmark/benchmark_subset.cpp b/benchmark/benchmark_subset.cpp index c94a34c62..6a7267ea6 100644 --- a/benchmark/benchmark_subset.cpp +++ b/benchmark/benchmark_subset.cpp @@ -124,7 +124,7 @@ void gen_offset_intervals(auto& cl, int max_index, unsigned int level, int x_int // Générateur « unique » : un intervalle englobant large // (utilisé pour les cas « single » dans les benchmarks) template -void gen_unique_interval(auto& cl, int max_index, unsigned int level, int /*x_intervals inutilisé*/ = DEFAULT_X_INTERVALS) +void gen_unique_interval(auto& cl, int max_index, unsigned int level, int x_intervals = DEFAULT_X_INTERVALS) { int spacing = 1 << (level + 1); // 2^(level+1) int interval_size = (max_index)*spacing; // Grande taille proportionnelle à max_index @@ -198,21 +198,21 @@ auto op_union = [](const auto& a, const auto& b) // Wrappers lambda pour les générateurs afin de permettre la déduction de type template -auto gen_regular_wrapper = [](auto& cl, int max_index, unsigned int level) +auto gen_regular_wrapper = [](auto& cl, int max_index, unsigned int level, int x_intervals = DEFAULT_X_INTERVALS) { - gen_regular_intervals(cl, max_index, level); + gen_regular_intervals(cl, max_index, level, x_intervals); }; template -auto gen_offset_wrapper = [](auto& cl, int max_index, unsigned int level) +auto gen_offset_wrapper = [](auto& cl, int max_index, unsigned int level, int x_intervals = DEFAULT_X_INTERVALS) { - gen_offset_intervals(cl, max_index, level); + gen_offset_intervals(cl, max_index, level, x_intervals); }; template -auto gen_unique_wrapper = [](auto& cl, int max_index, unsigned int level) +auto gen_unique_wrapper = [](auto& cl, int max_index, unsigned int level, int x_intervals = DEFAULT_X_INTERVALS) { - gen_unique_interval(cl, max_index, level); + gen_unique_interval(cl, max_index, level, x_intervals); }; template @@ -220,8 +220,8 @@ void SUBSET_unified_benchmark_mixed_levels(benchmark::State& state, Gen1&& gen1, { samurai::CellList cl1, cl2; int max_index = static_cast(state.range(0)); - gen1(cl1, max_index, level1); - gen2(cl2, max_index, level2); + gen1(cl1, max_index, level1, DEFAULT_X_INTERVALS); + gen2(cl2, max_index, level2, DEFAULT_X_INTERVALS); samurai::CellArray ca1(cl1); samurai::CellArray ca2(cl2); @@ -320,7 +320,7 @@ void SUBSET_translate(benchmark::State& state) { samurai::CellList cl; int max_index = static_cast(state.range(0)); - gen_regular_intervals(cl, max_index, level); + gen_regular_intervals(cl, max_index, level, DEFAULT_X_INTERVALS); samurai::CellArray ca(cl); // Créer le stencil de translation @@ -353,8 +353,8 @@ void SUBSET_translate_and_intersect(benchmark::State& state) { samurai::CellList cl1, cl2; int max_index = static_cast(state.range(0)); - gen_regular_intervals(cl1, max_index, level1); - gen_regular_intervals(cl2, max_index, level2); + gen_regular_intervals(cl1, max_index, level1, DEFAULT_X_INTERVALS); + gen_regular_intervals(cl2, max_index, level2, DEFAULT_X_INTERVALS); samurai::CellArray ca1(cl1); samurai::CellArray ca2(cl2); @@ -391,8 +391,8 @@ void SUBSET_translate_and_intersect_and_project(benchmark::State& state) { samurai::CellList cl1, cl2; int max_index = static_cast(state.range(0)); - gen_regular_intervals(cl1, max_index, level1); - gen_regular_intervals(cl2, max_index, level2); + gen_regular_intervals(cl1, max_index, level1, DEFAULT_X_INTERVALS); + gen_regular_intervals(cl2, max_index, level2, DEFAULT_X_INTERVALS); samurai::CellArray ca1(cl1); samurai::CellArray ca2(cl2); @@ -430,7 +430,7 @@ void SUBSET_translate_and_project(benchmark::State& state) { samurai::CellList cl; int max_index = static_cast(state.range(0)); - gen_regular_intervals(cl, max_index, level); + gen_regular_intervals(cl, max_index, level, DEFAULT_X_INTERVALS); samurai::CellArray ca(cl); // Créer le stencil de translation @@ -464,7 +464,7 @@ void SUBSET_self(benchmark::State& state) { samurai::CellList cl; int max_index = static_cast(state.range(0)); - gen_regular_intervals(cl, max_index, level); + gen_regular_intervals(cl, max_index, level, DEFAULT_X_INTERVALS); samurai::CellArray ca(cl); // Ajouter les statistiques @@ -494,7 +494,7 @@ void SUBSET_self_and_project(benchmark::State& state) { samurai::CellList cl; int max_index = static_cast(state.range(0)); - gen_regular_intervals(cl, max_index, level); + gen_regular_intervals(cl, max_index, level, DEFAULT_X_INTERVALS); samurai::CellArray ca(cl); // Ajouter les statistiques @@ -524,122 +524,122 @@ void SUBSET_self_and_project(benchmark::State& state) // Enregistrement des benchmarks /////////////////////////////////////////////////////////////////// -// Benchmarks pour les opérations ensemblistes en 1D (même niveau) - ~1000 intervalles -BENCHMARK_TEMPLATE(SUBSET_set_diff_identical, 1, 0, 0)->Arg(1000); -BENCHMARK_TEMPLATE(SUBSET_set_diff_disjoint, 1, 0, 0)->Arg(1000); -// BENCHMARK_TEMPLATE(SUBSET_set_diff_single, 1, 0, 0)->Arg(1000); -BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 1, 0, 0)->Arg(1000); -BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 1, 0, 0)->Arg(1000); -// BENCHMARK_TEMPLATE(SUBSET_set_intersect_single, 1, 0, 0)->Arg(1000); -BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 1, 0, 0)->Arg(1000); -BENCHMARK_TEMPLATE(SUBSET_set_union_disjoint, 1, 0, 0)->Arg(1000); -// BENCHMARK_TEMPLATE(SUBSET_set_union_single, 1, 0, 0)->Arg(1000); - -BENCHMARK_TEMPLATE(SUBSET_set_diff_identical, 1, 0, 1)->Arg(1000); -BENCHMARK_TEMPLATE(SUBSET_set_diff_disjoint, 1, 0, 1)->Arg(1000); -// BENCHMARK_TEMPLATE(SUBSET_set_diff_single, 1, 0, 1)->Arg(1000); -BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 1, 0, 1)->Arg(1000); -BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 1, 0, 1)->Arg(1000); -// BENCHMARK_TEMPLATE(SUBSET_set_intersect_single, 1, 0, 1)->Arg(1000); -BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 1, 0, 1)->Arg(1000); -BENCHMARK_TEMPLATE(SUBSET_set_union_disjoint, 1, 0, 1)->Arg(1000); -// BENCHMARK_TEMPLATE(SUBSET_set_union_single, 1, 0, 1)->Arg(1000); - -// Benchmarks pour les opérations ensemblistes en 2D (même niveau) - ~1000 intervalles -BENCHMARK_TEMPLATE(SUBSET_set_diff_identical, 2, 0, 0)->Arg(200); -BENCHMARK_TEMPLATE(SUBSET_set_diff_disjoint, 2, 0, 0)->Arg(200); -// BENCHMARK_TEMPLATE(SUBSET_set_diff_single, 2, 0, 0)->Arg(200); -BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 2, 0, 0)->Arg(200); -BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 2, 0, 0)->Arg(200); -// BENCHMARK_TEMPLATE(SUBSET_set_intersect_single, 2, 0, 0)->Arg(200); -BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 2, 0, 0)->Arg(200); -BENCHMARK_TEMPLATE(SUBSET_set_union_disjoint, 2, 0, 0)->Arg(200); -// BENCHMARK_TEMPLATE(SUBSET_set_union_single, 2, 0, 0)->Arg(200); - -BENCHMARK_TEMPLATE(SUBSET_set_diff_identical, 2, 0, 1)->Arg(200); -BENCHMARK_TEMPLATE(SUBSET_set_diff_disjoint, 2, 0, 1)->Arg(200); -// BENCHMARK_TEMPLATE(SUBSET_set_diff_single, 2, 0, 1)->Arg(200); -BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 2, 0, 1)->Arg(200); -BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 2, 0, 1)->Arg(200); -// BENCHMARK_TEMPLATE(SUBSET_set_intersect_single, 2, 0, 1)->Arg(200); -BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 2, 0, 1)->Arg(200); -BENCHMARK_TEMPLATE(SUBSET_set_union_disjoint, 2, 0, 1)->Arg(200); -// BENCHMARK_TEMPLATE(SUBSET_set_union_single, 2, 0, 1)->Arg(200); - -// Benchmarks pour les opérations ensemblistes en 3D (même niveau) - ~1000 intervalles -BENCHMARK_TEMPLATE(SUBSET_set_diff_identical, 3, 0, 0)->Arg(14); -BENCHMARK_TEMPLATE(SUBSET_set_diff_disjoint, 3, 0, 0)->Arg(14); -// BENCHMARK_TEMPLATE(SUBSET_set_diff_single, 3, 0, 0)->Arg(14); -BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 3, 0, 0)->Arg(14); -BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 3, 0, 0)->Arg(14); -// BENCHMARK_TEMPLATE(SUBSET_set_intersect_single, 3, 0, 0)->Arg(14); -BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 3, 0, 0)->Arg(14); -BENCHMARK_TEMPLATE(SUBSET_set_union_disjoint, 3, 0, 0)->Arg(14); -// BENCHMARK_TEMPLATE(SUBSET_set_union_single, 3, 0, 0)->Arg(14); - -BENCHMARK_TEMPLATE(SUBSET_set_diff_identical, 3, 0, 1)->Arg(14); -BENCHMARK_TEMPLATE(SUBSET_set_diff_disjoint, 3, 0, 1)->Arg(14); -// BENCHMARK_TEMPLATE(SUBSET_set_diff_single, 3, 0, 1)->Arg(14); -BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 3, 0, 1)->Arg(14); -BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 3, 0, 1)->Arg(14); -// BENCHMARK_TEMPLATE(SUBSET_set_intersect_single, 3, 0, 1)->Arg(14); -BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 3, 0, 1)->Arg(14); -BENCHMARK_TEMPLATE(SUBSET_set_union_disjoint, 3, 0, 1)->Arg(14); -// BENCHMARK_TEMPLATE(SUBSET_set_union_single, 3, 0, 1)->Arg(14); +// Benchmarks pour les opérations ensemblistes en 1D (même niveau) - ~10k intervalles +BENCHMARK_TEMPLATE(SUBSET_set_diff_identical, 1, 0, 0)->Arg(10000); +BENCHMARK_TEMPLATE(SUBSET_set_diff_disjoint, 1, 0, 0)->Arg(10000); +// BENCHMARK_TEMPLATE(SUBSET_set_diff_single, 1, 0, 0)->Arg(10000); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 1, 0, 0)->Arg(10000); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 1, 0, 0)->Arg(10000); +// BENCHMARK_TEMPLATE(SUBSET_set_intersect_single, 1, 0, 0)->Arg(10000); +BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 1, 0, 0)->Arg(10000); +BENCHMARK_TEMPLATE(SUBSET_set_union_disjoint, 1, 0, 0)->Arg(10000); +// BENCHMARK_TEMPLATE(SUBSET_set_union_single, 1, 0, 0)->Arg(10000); + +BENCHMARK_TEMPLATE(SUBSET_set_diff_identical, 1, 0, 1)->Arg(10000); +BENCHMARK_TEMPLATE(SUBSET_set_diff_disjoint, 1, 0, 1)->Arg(10000); +// BENCHMARK_TEMPLATE(SUBSET_set_diff_single, 1, 0, 1)->Arg(10000); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 1, 0, 1)->Arg(10000); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 1, 0, 1)->Arg(10000); +// BENCHMARK_TEMPLATE(SUBSET_set_intersect_single, 1, 0, 1)->Arg(10000); +BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 1, 0, 1)->Arg(10000); +BENCHMARK_TEMPLATE(SUBSET_set_union_disjoint, 1, 0, 1)->Arg(10000); +// BENCHMARK_TEMPLATE(SUBSET_set_union_single, 1, 0, 1)->Arg(10000); + +// Benchmarks pour les opérations ensemblistes en 2D (même niveau) - ~10k intervalles +BENCHMARK_TEMPLATE(SUBSET_set_diff_identical, 2, 0, 0)->Arg(2000); +BENCHMARK_TEMPLATE(SUBSET_set_diff_disjoint, 2, 0, 0)->Arg(2000); +// BENCHMARK_TEMPLATE(SUBSET_set_diff_single, 2, 0, 0)->Arg(2000); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 2, 0, 0)->Arg(2000); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 2, 0, 0)->Arg(2000); +// BENCHMARK_TEMPLATE(SUBSET_set_intersect_single, 2, 0, 0)->Arg(2000); +BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 2, 0, 0)->Arg(2000); +BENCHMARK_TEMPLATE(SUBSET_set_union_disjoint, 2, 0, 0)->Arg(2000); +// BENCHMARK_TEMPLATE(SUBSET_set_union_single, 2, 0, 0)->Arg(2000); + +BENCHMARK_TEMPLATE(SUBSET_set_diff_identical, 2, 0, 1)->Arg(2000); +BENCHMARK_TEMPLATE(SUBSET_set_diff_disjoint, 2, 0, 1)->Arg(2000); +// BENCHMARK_TEMPLATE(SUBSET_set_diff_single, 2, 0, 1)->Arg(2000); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 2, 0, 1)->Arg(2000); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 2, 0, 1)->Arg(2000); +// BENCHMARK_TEMPLATE(SUBSET_set_intersect_single, 2, 0, 1)->Arg(2000); +BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 2, 0, 1)->Arg(2000); +BENCHMARK_TEMPLATE(SUBSET_set_union_disjoint, 2, 0, 1)->Arg(2000); +// BENCHMARK_TEMPLATE(SUBSET_set_union_single, 2, 0, 1)->Arg(2000); + +// Benchmarks pour les opérations ensemblistes en 3D (même niveau) - ~10k intervalles +BENCHMARK_TEMPLATE(SUBSET_set_diff_identical, 3, 0, 0)->Arg(45); +BENCHMARK_TEMPLATE(SUBSET_set_diff_disjoint, 3, 0, 0)->Arg(45); +// BENCHMARK_TEMPLATE(SUBSET_set_diff_single, 3, 0, 0)->Arg(45); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 3, 0, 0)->Arg(45); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 3, 0, 0)->Arg(45); +// BENCHMARK_TEMPLATE(SUBSET_set_intersect_single, 3, 0, 0)->Arg(45); +BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 3, 0, 0)->Arg(45); +BENCHMARK_TEMPLATE(SUBSET_set_union_disjoint, 3, 0, 0)->Arg(45); +// BENCHMARK_TEMPLATE(SUBSET_set_union_single, 3, 0, 0)->Arg(45); + +BENCHMARK_TEMPLATE(SUBSET_set_diff_identical, 3, 0, 1)->Arg(45); +BENCHMARK_TEMPLATE(SUBSET_set_diff_disjoint, 3, 0, 1)->Arg(45); +// BENCHMARK_TEMPLATE(SUBSET_set_diff_single, 3, 0, 1)->Arg(45); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 3, 0, 1)->Arg(45); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 3, 0, 1)->Arg(45); +// BENCHMARK_TEMPLATE(SUBSET_set_intersect_single, 3, 0, 1)->Arg(45); +BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 3, 0, 1)->Arg(45); +BENCHMARK_TEMPLATE(SUBSET_set_union_disjoint, 3, 0, 1)->Arg(45); +// BENCHMARK_TEMPLATE(SUBSET_set_union_single, 3, 0, 1)->Arg(45); // Benchmarks pour les opérations géométriques (niveau unique) -BENCHMARK_TEMPLATE(SUBSET_translate, 1, 0)->Arg(1000); // ~1000 intervalles -BENCHMARK_TEMPLATE(SUBSET_translate, 2, 0)->Arg(200); // ~1000 intervalles -BENCHMARK_TEMPLATE(SUBSET_translate, 3, 0)->Arg(14); // ~1000 intervalles +BENCHMARK_TEMPLATE(SUBSET_translate, 1, 0)->Arg(10000); // ~10k intervalles +BENCHMARK_TEMPLATE(SUBSET_translate, 2, 0)->Arg(2000); // ~10k intervalles +BENCHMARK_TEMPLATE(SUBSET_translate, 3, 0)->Arg(45); // ~10k intervalles -BENCHMARK_TEMPLATE(SUBSET_translate_and_project, 1, 0)->Arg(1000); -BENCHMARK_TEMPLATE(SUBSET_translate_and_project, 2, 0)->Arg(200); -BENCHMARK_TEMPLATE(SUBSET_translate_and_project, 3, 0)->Arg(14); +BENCHMARK_TEMPLATE(SUBSET_translate_and_project, 1, 0)->Arg(10000); +BENCHMARK_TEMPLATE(SUBSET_translate_and_project, 2, 0)->Arg(2000); +BENCHMARK_TEMPLATE(SUBSET_translate_and_project, 3, 0)->Arg(45); -BENCHMARK_TEMPLATE(SUBSET_self, 1, 0)->Arg(1000); // ~1000 intervalles -BENCHMARK_TEMPLATE(SUBSET_self, 2, 0)->Arg(200); // ~1000 intervalles -BENCHMARK_TEMPLATE(SUBSET_self, 3, 0)->Arg(14); // ~1000 intervalles +BENCHMARK_TEMPLATE(SUBSET_self, 1, 0)->Arg(10000); // ~10k intervalles +BENCHMARK_TEMPLATE(SUBSET_self, 2, 0)->Arg(2000); // ~10k intervalles +BENCHMARK_TEMPLATE(SUBSET_self, 3, 0)->Arg(45); // ~10k intervalles -BENCHMARK_TEMPLATE(SUBSET_self_and_project, 1, 0)->Arg(1000); -BENCHMARK_TEMPLATE(SUBSET_self_and_project, 2, 0)->Arg(200); -BENCHMARK_TEMPLATE(SUBSET_self_and_project, 3, 0)->Arg(14); +BENCHMARK_TEMPLATE(SUBSET_self_and_project, 1, 0)->Arg(10000); +BENCHMARK_TEMPLATE(SUBSET_self_and_project, 2, 0)->Arg(2000); +BENCHMARK_TEMPLATE(SUBSET_self_and_project, 3, 0)->Arg(45); // Benchmarks géométriques avec niveaux mixtes (niveau 0 vs autre niveau) -BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 1, 0, 0)->Arg(1000); -BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 2, 0, 0)->Arg(200); -BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 3, 0, 0)->Arg(14); +BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 1, 0, 0)->Arg(10000); +BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 2, 0, 0)->Arg(2000); +BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 3, 0, 0)->Arg(45); -BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 1, 0, 1)->Arg(1000); -BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 2, 0, 1)->Arg(200); -BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 2, 0, 2)->Arg(200); -BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 2, 0, 10)->Arg(200); // this bench is weird : the perf ??? maybe a bug. +BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 1, 0, 1)->Arg(10000); +BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 2, 0, 1)->Arg(2000); +BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 2, 0, 2)->Arg(2000); +BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect, 2, 0, 10)->Arg(2000); // this bench is weird : the perf ??? maybe a bug. -BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect_and_project, 1, 0, 0)->Arg(1000); -BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect_and_project, 2, 0, 0)->Arg(200); -BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect_and_project, 3, 0, 0)->Arg(14); +BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect_and_project, 1, 0, 0)->Arg(10000); +BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect_and_project, 2, 0, 0)->Arg(2000); +BENCHMARK_TEMPLATE(SUBSET_translate_and_intersect_and_project, 3, 0, 0)->Arg(45); /////////////////////////////////////////////////////////////////// // Benchmarks avec niveaux mixtes (intéressants pour comparer les niveaux) /////////////////////////////////////////////////////////////////// // Benchmarks 1D : niveau 0 vs niveau 1 -BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 1, 0, 1)->Arg(1000); -BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 1, 0, 1)->Arg(1000); -BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 1, 0, 1)->Arg(1000); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 1, 0, 1)->Arg(10000); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 1, 0, 1)->Arg(10000); +BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 1, 0, 1)->Arg(10000); // Benchmarks 1D : niveau 0 vs niveau 2 -BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 1, 0, 2)->Arg(1000); -BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 1, 0, 2)->Arg(1000); -BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 1, 0, 2)->Arg(1000); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 1, 0, 2)->Arg(10000); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 1, 0, 2)->Arg(10000); +BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 1, 0, 2)->Arg(10000); // Benchmarks 1D : niveau 1 vs niveau 2 -BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 1, 1, 2)->Arg(1000); -BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 1, 1, 2)->Arg(1000); -BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 1, 1, 2)->Arg(1000); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 1, 1, 2)->Arg(10000); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 1, 1, 2)->Arg(10000); +BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 1, 1, 2)->Arg(10000); // Benchmarks 2D : niveau 0 vs niveau 1 -BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 2, 0, 1)->Arg(200); -BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 2, 0, 1)->Arg(200); -BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 2, 0, 1)->Arg(200); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_identical, 2, 0, 1)->Arg(2000); +BENCHMARK_TEMPLATE(SUBSET_set_intersect_disjoint, 2, 0, 1)->Arg(2000); +BENCHMARK_TEMPLATE(SUBSET_set_union_identical, 2, 0, 1)->Arg(2000); // Benchmarks géométriques avec niveaux mixtes From 3cfac4609b18445b145ee5a84375c1b46365e984 Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Tue, 7 Oct 2025 12:52:59 +0200 Subject: [PATCH 09/12] ci: add separate runner to build and run bench_samurai; fix benchmark_bc types/includes --- .github/workflows/ci.yml | 50 ++++++++++++++++++++++++++++++++++++++ benchmark/benchmark_bc.cpp | 22 +++++++++++------ 2 files changed, 64 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c93366d20..c51074eca 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -497,3 +497,53 @@ jobs: mpiexec -n 2 ./demos/FiniteVolume/finite-volume-burgers --Tf 0.1 --nfiles 1 --max-level 8 # This test is failing with 3 processes due to a bug in the exchange of subdomain corners # mpiexec -n 3 ./demos/FiniteVolume/finite-volume-burgers --Tf 0.1 --nfiles 1 --max-level 8 + + # + # Benchmarks build and run (separate runner) + # + ######################################################### + linux-benchmarks: + needs: [pre-commit, cppcheck] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Cache + uses: actions/cache@v4 + with: + path: | + ~/.cache/ccache + ~/micromamba-root/envs/samurai-env + key: linux-benchmarks + restore-keys: | + linux-benchmarks + + - name: Mamba and samurai env installation + uses: mamba-org/setup-micromamba@v2 + with: + environment-file: conda/environment.yml + environment-name: samurai-env + cache-environment: true + + - name: Configure (benchmarks only) + shell: bash -l {0} + run: | + cmake \ + . \ + -Bbuild \ + -GNinja \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_BENCHMARKS=ON \ + -DBUILD_DEMOS=OFF \ + -DBUILD_TESTS=OFF + + - name: Build benchmarks + shell: bash -l {0} + run: | + cmake --build build --target bench_samurai --parallel 2 + + - name: Run bench_samurai (quick sanity) + shell: bash -l {0} + run: | + cd build + ./benchmark/bench_samurai --benchmark_min_time=0.003 --benchmark_color=no --benchmark_format=console diff --git a/benchmark/benchmark_bc.cpp b/benchmark/benchmark_bc.cpp index 191b4a566..3afc1e76c 100644 --- a/benchmark/benchmark_bc.cpp +++ b/benchmark/benchmark_bc.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -51,9 +52,9 @@ template box = unitary_box(); - using Config = samurai::UniformConfig; // Utilisation de l'ordre comme paramètre - auto mesh = samurai::UniformMesh(box, state.range(0)); - auto u = make_field("u", mesh); + using Config = samurai::UniformConfig(order)>; // ghost_width = order + auto mesh = samurai::UniformMesh(box, static_cast(state.range(0))); + auto u = samurai::make_vector_field("u", mesh); u.fill(1.0); @@ -61,10 +62,15 @@ void BC_homogeneous(benchmark::State& state) state.counters["Dimension"] = dim; state.counters["Composantes"] = n_comp; state.counters["Ordre"] = order; - state.counters["Type BC"] = std::is_same_v> ? 0 : 1; // 0 pour Dirichlet, 1 pour Neumann + state.counters["Type BC"] = std::is_same_v> ? 0 : 1; // 0 pour Dirichlet, 1 pour Neumann + + auto& bc_container = u.get_bc(); for (auto _ : state) { + state.PauseTiming(); + bc_container.clear(); + state.ResumeTiming(); samurai::make_bc(u); } } @@ -82,7 +88,7 @@ BENCHMARK_TEMPLATE(BC_homogeneous, 3, 1, samurai::Neumann<1>, 1)->DenseRange(1, BENCHMARK_TEMPLATE(BC_homogeneous, 1, 100, samurai::Neumann<1>, 1)->DenseRange(1, 1); // Tests Dirichlet ordre 3 -BENCHMARK_TEMPLATE(BC_homogeneous, 1, 1, samurai::Dirichlet<2>, 3)->DenseRange(1, 1); -BENCHMARK_TEMPLATE(BC_homogeneous, 2, 1, samurai::Dirichlet<2>, 3)->DenseRange(1, 1); -BENCHMARK_TEMPLATE(BC_homogeneous, 3, 1, samurai::Dirichlet<2>, 3)->DenseRange(1, 1); -BENCHMARK_TEMPLATE(BC_homogeneous, 1, 100, samurai::Dirichlet<2>, 3)->DenseRange(1, 1); +BENCHMARK_TEMPLATE(BC_homogeneous, 1, 1, samurai::Dirichlet<3>, 3)->DenseRange(1, 1); +BENCHMARK_TEMPLATE(BC_homogeneous, 2, 1, samurai::Dirichlet<3>, 3)->DenseRange(1, 1); +BENCHMARK_TEMPLATE(BC_homogeneous, 3, 1, samurai::Dirichlet<3>, 3)->DenseRange(1, 1); +BENCHMARK_TEMPLATE(BC_homogeneous, 1, 100, samurai::Dirichlet<3>, 3)->DenseRange(1, 1); From 4dbdae3a1ca3d05ace4a4954c0700da24ddcbf4d Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Tue, 7 Oct 2025 13:01:49 +0200 Subject: [PATCH 10/12] style: apply clang-format via pre-commit --- benchmark/benchmark_bc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmark/benchmark_bc.cpp b/benchmark/benchmark_bc.cpp index 3afc1e76c..2e376d652 100644 --- a/benchmark/benchmark_bc.cpp +++ b/benchmark/benchmark_bc.cpp @@ -6,8 +6,8 @@ #include #include -#include #include +#include #include #include #include From 0d0af93e62a9c77155ded0090d37f44d00501243 Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Tue, 7 Oct 2025 13:38:35 +0200 Subject: [PATCH 11/12] bench: add SetItemsProcessed/SetBytesProcessed for throughput where relevant --- benchmark/benchmark_cellarray.cpp | 2 ++ benchmark/benchmark_celllist_construction.cpp | 4 +++ benchmark/benchmark_field.cpp | 36 +++++++++++++++++++ benchmark/benchmark_level_cell_array.cpp | 12 +++++++ benchmark/benchmark_search.cpp | 2 ++ benchmark/benchmark_subset.cpp | 14 ++++++++ 6 files changed, 70 insertions(+) diff --git a/benchmark/benchmark_cellarray.cpp b/benchmark/benchmark_cellarray.cpp index 17d35b12a..de8dd38a0 100644 --- a/benchmark/benchmark_cellarray.cpp +++ b/benchmark/benchmark_cellarray.cpp @@ -129,6 +129,8 @@ void CELLARRAY_cl_ca_multi(benchmark::State& state) state.counters["ns/interval"] = benchmark::Counter(nb_intervals, benchmark::Counter::kIsIterationInvariantRate | benchmark::Counter::kInvert); state.counters["dim"] = dim; + + state.SetItemsProcessed(state.iterations() * static_cast(nb_intervals)); } // Mesure : Récupération du niveau bas d'un CellList diff --git a/benchmark/benchmark_celllist_construction.cpp b/benchmark/benchmark_celllist_construction.cpp index 5351092d9..b1b664155 100644 --- a/benchmark/benchmark_celllist_construction.cpp +++ b/benchmark/benchmark_celllist_construction.cpp @@ -144,6 +144,8 @@ void CELLLIST_add_interval_begin(benchmark::State& state) state.counters["intervals"] = static_cast(total_intervals); state.counters["ns/interval"] = benchmark::Counter(total_intervals, benchmark::Counter::kIsIterationInvariantRate | benchmark::Counter::kInvert); + + state.SetItemsProcessed(state.iterations() * static_cast(total_intervals)); } // Mesure : Copie de CellList par opérateur d'assignation @@ -165,6 +167,8 @@ void CELLLIST_copy_assignment(benchmark::State& state) state.counters["intervals"] = static_cast(total_intervals); state.counters["ns/interval"] = benchmark::Counter(total_intervals, benchmark::Counter::kIsIterationInvariantRate | benchmark::Counter::kInvert); + + state.SetItemsProcessed(state.iterations() * static_cast(total_intervals)); } //////////////////////////////////////////////////////////// diff --git a/benchmark/benchmark_field.cpp b/benchmark/benchmark_field.cpp index 709e880b5..d11ccfaf2 100644 --- a/benchmark/benchmark_field.cpp +++ b/benchmark/benchmark_field.cpp @@ -102,6 +102,10 @@ void FIELD_fill_uniform(benchmark::State& state) { u.fill(1.0); } + + state.SetItemsProcessed(state.iterations() * static_cast(total_cells)); + state.SetBytesProcessed(state.iterations() * static_cast(total_cells) * static_cast(n_comp) + * static_cast(sizeof(double)) * 1); } // Mesure ; Remplissage d'un champ 1D de taille de coté n ,en utilisant for_each_cell (mesure d'overhead) @@ -129,6 +133,10 @@ void FIELD_for_each_cell_fill_uniform(benchmark::State& state) u[cell] = 1.0; }); } + + state.SetItemsProcessed(state.iterations() * static_cast(total_cells)); + state.SetBytesProcessed(state.iterations() * static_cast(total_cells) * static_cast(n_comp) + * static_cast(sizeof(double)) * 1); } // Weird : MPI issue ??? wtf ??? @@ -153,6 +161,10 @@ void FIELD_equal_uniform(benchmark::State& state) { v = u; } + + state.SetItemsProcessed(state.iterations() * static_cast(total_cells)); + state.SetBytesProcessed(state.iterations() * static_cast(total_cells) * static_cast(1) + * static_cast(sizeof(double)) * 2); } // Mesure : Ajout d'un scalaire à un champ par broadcasting @@ -179,6 +191,10 @@ void FIELD_add_scalar_uniform(benchmark::State& state) v = u + 2.0; benchmark::DoNotOptimize(v[0]); } + + state.SetItemsProcessed(state.iterations() * static_cast(total_cells)); + state.SetBytesProcessed(state.iterations() * static_cast(total_cells) * static_cast(n_comp) + * static_cast(sizeof(double)) * 2); } // Mesure : Ajout d'un scalaire à un champ par "for_each_cell" @@ -208,6 +224,10 @@ void FIELD_for_each_cell_add_scalar_uniform(benchmark::State& state) v[cell] = u[cell] + 1.0; }); } + + state.SetItemsProcessed(state.iterations() * static_cast(total_cells)); + state.SetBytesProcessed(state.iterations() * static_cast(total_cells) * static_cast(n_comp) + * static_cast(sizeof(double)) * 2); } // Mesure : Somme de deux champs 1D par expression @@ -237,6 +257,10 @@ void FIELD_add_uniform(benchmark::State& state) w = u + v; benchmark::DoNotOptimize(w[0]); } + + state.SetItemsProcessed(state.iterations() * static_cast(total_cells)); + state.SetBytesProcessed(state.iterations() * static_cast(total_cells) * static_cast(n_comp) + * static_cast(sizeof(double)) * 3); } // Mesure : Somme de deux champs 1D par "for_each_cell" @@ -268,6 +292,10 @@ void FIELD_for_each_cell_add_uniform(benchmark::State& state) w[cell] = u[cell] + v[cell]; }); } + + state.SetItemsProcessed(state.iterations() * static_cast(total_cells)); + state.SetBytesProcessed(state.iterations() * static_cast(total_cells) * static_cast(n_comp) + * static_cast(sizeof(double)) * 3); } // Mesure : Expression complexe avec plusieurs opérations arithmétiques @@ -305,6 +333,10 @@ void FIELD_complex_expression_uniform(benchmark::State& state) u = 2.0 + v + (w * x) / z; benchmark::DoNotOptimize(u[0]); } + + state.SetItemsProcessed(state.iterations() * static_cast(total_cells)); + state.SetBytesProcessed(state.iterations() * static_cast(total_cells) * static_cast(n_comp) + * static_cast(sizeof(double)) * 5); } // Mesure : Expression complexe avec plusieurs opérations arithmétiques (version for_each_cell) @@ -345,6 +377,10 @@ void FIELD_for_each_cell_complex_expression_uniform(benchmark::State& state) u[cell] = 2.0 + v[cell] + (w[cell] * x[cell]) / z[cell]; }); } + + state.SetItemsProcessed(state.iterations() * static_cast(total_cells)); + state.SetBytesProcessed(state.iterations() * static_cast(total_cells) * static_cast(n_comp) + * static_cast(sizeof(double)) * 5); } BENCHMARK_TEMPLATE(FIELD_make_field_uniform, 1, 1)->Arg(16); diff --git a/benchmark/benchmark_level_cell_array.cpp b/benchmark/benchmark_level_cell_array.cpp index 0e38fc6e1..c0213db45 100644 --- a/benchmark/benchmark_level_cell_array.cpp +++ b/benchmark/benchmark_level_cell_array.cpp @@ -169,6 +169,8 @@ void LEVELCELLARRAY_empty_lcl_to_lca(benchmark::State& state) auto lca = samurai::LevelCellArray(lcl); benchmark::DoNotOptimize(lca); } + + state.SetItemsProcessed(state.iterations() * static_cast(total_intervals)); } // Mesure : Construction d'un LevelCellArray à partir d'un LevelCellList composé de n intervalles dans une direction @@ -285,6 +287,8 @@ void LEVELCELLARRAY_nb_cells(benchmark::State& state) auto nb = lca.nb_cells(); benchmark::DoNotOptimize(nb); } + + state.SetItemsProcessed(state.iterations() * static_cast(total_intervals)); } // Mesure : Récupération de la taille de cellule d'un LevelCellArray @@ -324,6 +328,8 @@ void LEVELCELLARRAY_max_indices(benchmark::State& state) auto max = lca.max_indices(); benchmark::DoNotOptimize(max); } + + state.SetItemsProcessed(state.iterations() * static_cast(total_intervals)); } // Mesure : Récupération du min d'indide d'un LevelCellArray @@ -347,6 +353,8 @@ void LEVELCELLARRAY_min_indices(benchmark::State& state) auto min = lca.min_indices(); benchmark::DoNotOptimize(min); } + + state.SetItemsProcessed(state.iterations() * static_cast(total_intervals)); } // Mesure : Récupération du minmax d'indice d'un LevelCellArray @@ -370,6 +378,8 @@ void LEVELCELLARRAY_minmax_indices(benchmark::State& state) auto minmax = lca.minmax_indices(); benchmark::DoNotOptimize(minmax); } + + state.SetItemsProcessed(state.iterations() * static_cast(total_intervals)); } // Mesure : Test d'égalité entre deux LevelCellArrays égaux de taille n @@ -394,6 +404,8 @@ void LEVELCELLARRAY_equal(benchmark::State& state) auto is_equal = (lca == lca2); benchmark::DoNotOptimize(is_equal); } + + state.SetItemsProcessed(state.iterations() * static_cast(total_intervals)); } // Mesure : Récupération du niveau bas d'un LevelCellArray diff --git a/benchmark/benchmark_search.cpp b/benchmark/benchmark_search.cpp index ae36d5332..d2b09e32c 100644 --- a/benchmark/benchmark_search.cpp +++ b/benchmark/benchmark_search.cpp @@ -104,6 +104,8 @@ void FIND_find_unified(benchmark::State& state, const std::function(total_intervals)); } /////////////////////////////////////////////////////////////////// @@ -346,6 +348,8 @@ void SUBSET_translate(benchmark::State& state) benchmark::DoNotOptimize(total_cells); benchmark::DoNotOptimize(subset); } + + state.SetItemsProcessed(state.iterations() * static_cast(total_intervals)); } template @@ -384,6 +388,8 @@ void SUBSET_translate_and_intersect(benchmark::State& state) benchmark::DoNotOptimize(total_cells); benchmark::DoNotOptimize(subset); } + + state.SetItemsProcessed(state.iterations() * static_cast(total_intervals)); } template @@ -423,6 +429,8 @@ void SUBSET_translate_and_intersect_and_project(benchmark::State& state) benchmark::DoNotOptimize(total_cells); benchmark::DoNotOptimize(subset); } + + state.SetItemsProcessed(state.iterations() * static_cast(total_intervals)); } template @@ -457,6 +465,8 @@ void SUBSET_translate_and_project(benchmark::State& state) benchmark::DoNotOptimize(total_cells); benchmark::DoNotOptimize(subset); } + + state.SetItemsProcessed(state.iterations() * static_cast(total_intervals)); } template @@ -487,6 +497,8 @@ void SUBSET_self(benchmark::State& state) benchmark::DoNotOptimize(total_cells); benchmark::DoNotOptimize(subset); } + + state.SetItemsProcessed(state.iterations() * static_cast(total_intervals)); } template @@ -518,6 +530,8 @@ void SUBSET_self_and_project(benchmark::State& state) benchmark::DoNotOptimize(total_cells); benchmark::DoNotOptimize(subset); } + + state.SetItemsProcessed(state.iterations() * static_cast(total_intervals)); } /////////////////////////////////////////////////////////////////// From d712bdaef5a583c39d6bcf2915c8c3e888aee573 Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Tue, 7 Oct 2025 13:42:34 +0200 Subject: [PATCH 12/12] bench: remove unused includes (, , xtensor/xrandom) after verification --- benchmark/benchmark_bc.cpp | 3 --- benchmark/benchmark_cell.cpp | 3 --- benchmark/benchmark_cellarray.cpp | 3 --- benchmark/benchmark_celllist_construction.cpp | 1 - benchmark/benchmark_field.cpp | 3 --- benchmark/benchmark_interval.cpp | 3 --- benchmark/benchmark_level_cell_array.cpp | 3 --- benchmark/benchmark_mesh.cpp | 3 --- benchmark/benchmark_search.cpp | 3 --- benchmark/benchmark_stencil.cpp | 3 --- benchmark/benchmark_subset.cpp | 3 --- 11 files changed, 31 deletions(-) diff --git a/benchmark/benchmark_bc.cpp b/benchmark/benchmark_bc.cpp index 2e376d652..22cbc172c 100644 --- a/benchmark/benchmark_bc.cpp +++ b/benchmark/benchmark_bc.cpp @@ -1,9 +1,6 @@ -#include #include -#include #include -#include #include #include diff --git a/benchmark/benchmark_cell.cpp b/benchmark/benchmark_cell.cpp index e7aa6217d..83663bf40 100644 --- a/benchmark/benchmark_cell.cpp +++ b/benchmark/benchmark_cell.cpp @@ -1,9 +1,6 @@ -#include #include -#include #include -#include #include #include diff --git a/benchmark/benchmark_cellarray.cpp b/benchmark/benchmark_cellarray.cpp index de8dd38a0..27470a812 100644 --- a/benchmark/benchmark_cellarray.cpp +++ b/benchmark/benchmark_cellarray.cpp @@ -1,10 +1,7 @@ -#include #include #include -#include #include -#include #include #include diff --git a/benchmark/benchmark_celllist_construction.cpp b/benchmark/benchmark_celllist_construction.cpp index b1b664155..136e813eb 100644 --- a/benchmark/benchmark_celllist_construction.cpp +++ b/benchmark/benchmark_celllist_construction.cpp @@ -1,5 +1,4 @@ #include -#include #include diff --git a/benchmark/benchmark_field.cpp b/benchmark/benchmark_field.cpp index d11ccfaf2..8f6a50d58 100644 --- a/benchmark/benchmark_field.cpp +++ b/benchmark/benchmark_field.cpp @@ -1,9 +1,6 @@ -#include #include -#include #include -#include #include #include diff --git a/benchmark/benchmark_interval.cpp b/benchmark/benchmark_interval.cpp index d4d3e2cfd..2fa429d16 100644 --- a/benchmark/benchmark_interval.cpp +++ b/benchmark/benchmark_interval.cpp @@ -1,10 +1,7 @@ -#include #include -#include #include -#include #include #include diff --git a/benchmark/benchmark_level_cell_array.cpp b/benchmark/benchmark_level_cell_array.cpp index c0213db45..1fad07943 100644 --- a/benchmark/benchmark_level_cell_array.cpp +++ b/benchmark/benchmark_level_cell_array.cpp @@ -1,9 +1,6 @@ -#include #include -#include #include -#include #include #include diff --git a/benchmark/benchmark_mesh.cpp b/benchmark/benchmark_mesh.cpp index 5054a0af0..8f52e79d4 100644 --- a/benchmark/benchmark_mesh.cpp +++ b/benchmark/benchmark_mesh.cpp @@ -1,10 +1,7 @@ -#include #include -#include #include -#include #include #include diff --git a/benchmark/benchmark_search.cpp b/benchmark/benchmark_search.cpp index d2b09e32c..21bedbf58 100644 --- a/benchmark/benchmark_search.cpp +++ b/benchmark/benchmark_search.cpp @@ -1,10 +1,7 @@ -#include #include -#include #include #include -#include #include #include diff --git a/benchmark/benchmark_stencil.cpp b/benchmark/benchmark_stencil.cpp index 608b51932..c05f70a0a 100644 --- a/benchmark/benchmark_stencil.cpp +++ b/benchmark/benchmark_stencil.cpp @@ -1,9 +1,6 @@ -#include #include -#include #include -#include #include #include diff --git a/benchmark/benchmark_subset.cpp b/benchmark/benchmark_subset.cpp index 98cf190c8..a587a6191 100644 --- a/benchmark/benchmark_subset.cpp +++ b/benchmark/benchmark_subset.cpp @@ -1,9 +1,6 @@ -#include #include -#include #include -#include #include #include