From f46eac9961f471f6f0bf677ebb45b1f6da77b4e9 Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Thu, 29 Feb 2024 16:46:04 +0100 Subject: [PATCH 1/3] Benchmark of the new sparse matrix product --- .../SparseMatrixProduct.cpp | 176 ++++++++++++------ 1 file changed, 123 insertions(+), 53 deletions(-) diff --git a/src/benchmarks/Sofa.LinearAlgebra/SparseMatrixProduct.cpp b/src/benchmarks/Sofa.LinearAlgebra/SparseMatrixProduct.cpp index 6940e4e..fbaad53 100644 --- a/src/benchmarks/Sofa.LinearAlgebra/SparseMatrixProduct.cpp +++ b/src/benchmarks/Sofa.LinearAlgebra/SparseMatrixProduct.cpp @@ -1,15 +1,49 @@ #include #include -#include +#include +#include +#include +#include +#include #include +template +struct SparseMatrixProductInit +{ + static void init(T& product) + { + SOFA_UNUSED(product); + }; + + static void cleanup() + { + } +}; +template +struct SparseMatrixProductInit< + sofa::simulation::ParallelSparseMatrixProduct> +{ + static void init(sofa::simulation::ParallelSparseMatrixProduct& product) + { + product.taskScheduler = sofa::simulation::MainTaskSchedulerFactory::createInRegistry(); + product.taskScheduler->init(); + }; -template + static void cleanup() + { + sofa::simulation::MainTaskSchedulerRegistry::clear(); + } +}; + + +template class BM_SparseMatrixProduct : public benchmark::Fixture { public: + using MatrixLHS = typename TProduct::LhsCleaned; + using MatrixRHS = typename TProduct::RhsCleaned; void SetUp(const ::benchmark::State& state) override { @@ -20,7 +54,7 @@ class BM_SparseMatrixProduct : public benchmark::Fixture auto itA = matrixMapA.find({matrixSize, sparsityPerMil}); if (itA == matrixMapA.end()) { - TMatrix matrixA; + MatrixLHS matrixA; generateRandomSparseMatrix(matrixA, matrixSize, matrixSize, sparsity); if (const auto insertIt = matrixMapA.insert({{matrixSize, sparsityPerMil}, matrixA}); insertIt.second) { @@ -35,7 +69,7 @@ class BM_SparseMatrixProduct : public benchmark::Fixture auto itB = matrixMapB.find({matrixSize, sparsityPerMil}); if (itB == matrixMapB.end()) { - TMatrix matrixB; + MatrixRHS matrixB; generateRandomSparseMatrix(matrixB, matrixSize, matrixSize, sparsity); if (const auto insertIt = matrixMapB.insert({ {matrixSize, sparsityPerMil}, matrixB}); insertIt.second) { @@ -50,14 +84,15 @@ class BM_SparseMatrixProduct : public benchmark::Fixture auto it = productMap.find({matrixSize, sparsityPerMil}); if (it == productMap.end()) { - sofa::linearalgebra::SparseMatrixProduct p; + TProduct p; const auto insertIt = productMap.insert({ {matrixSize, sparsityPerMil}, p}); if (insertIt.second) { product = &insertIt.first->second; + SparseMatrixProductInit::init(*product); - product->matrixA = a; - product->matrixB = b; + product->m_lhs = a; + product->m_rhs = b; product->computeProduct(); } } @@ -68,70 +103,105 @@ class BM_SparseMatrixProduct : public benchmark::Fixture } + void TearDown(const ::benchmark::State& state) override + { + SparseMatrixProductInit::cleanup(); + } + void regularProduct(benchmark::State& state) { + SparseMatrixProductInit::init(*product); product->computeRegularProduct(); } void fastProduct(benchmark::State& state) { + SparseMatrixProductInit::init(*product); product->computeProduct(); } void forceComputingIntersection(benchmark::State& state) { + SparseMatrixProductInit::init(*product); product->computeProduct(true); } - sofa::linearalgebra::SparseMatrixProduct* product { nullptr }; + TProduct* product { nullptr }; private: - TMatrix* a { nullptr }; - TMatrix* b { nullptr }; + MatrixLHS* a { nullptr }; + MatrixRHS* b { nullptr }; - static std::map< std::pair< int, int>, TMatrix> matrixMapA, matrixMapB; - static std::map< std::pair< int, int>, sofa::linearalgebra::SparseMatrixProduct > productMap; + static std::map< std::pair< int, int>, MatrixLHS> matrixMapA; + static std::map< std::pair< int, int>, MatrixRHS> matrixMapB; + static std::map< std::pair< int, int>, TProduct > productMap; }; -template -std::map< std::pair< int, int>, TMatrix> BM_SparseMatrixProduct::matrixMapA; -template -std::map< std::pair< int, int>, TMatrix> BM_SparseMatrixProduct::matrixMapB; -template -std::map< std::pair< int, int>, sofa::linearalgebra::SparseMatrixProduct > BM_SparseMatrixProduct::productMap; - -BENCHMARK_TEMPLATE_DEFINE_F(BM_SparseMatrixProduct, RegularProduct, Eigen::SparseMatrix)(benchmark::State& st) -{ - for (auto _ : st) - { - this->regularProduct(st); - } -} -BENCHMARK_REGISTER_F(BM_SparseMatrixProduct, RegularProduct)->Unit(benchmark::kMicrosecond) - ->ArgsProduct({{100, 1000}, {10, 20, 100, 150}}) - ->Args({10000, 1}) - ->Args({10000, 5}); - -BENCHMARK_TEMPLATE_DEFINE_F(BM_SparseMatrixProduct, FastProduct, Eigen::SparseMatrix)(benchmark::State& st) -{ - for (auto _ : st) - { - this->fastProduct(st); - } -} -BENCHMARK_REGISTER_F(BM_SparseMatrixProduct, FastProduct)->Unit(benchmark::kMicrosecond) - ->ArgsProduct({{100, 1000}, {10, 20, 100, 150}}) - ->Args({10000, 1}) - ->Args({10000, 5}); - - -BENCHMARK_TEMPLATE_DEFINE_F(BM_SparseMatrixProduct, ForceComputingIntersection, Eigen::SparseMatrix)(benchmark::State& st) -{ - for (auto _ : st) - { - this->forceComputingIntersection(st); - } -} -// BENCHMARK_REGISTER_F(BM_SparseMatrixProduct, ForceComputingIntersection)->Unit(benchmark::kMicrosecond) -// ->ArgsProduct({{100, 1000},{10}}); +template +std::map< std::pair< int, int>, typename BM_SparseMatrixProduct::MatrixLHS> BM_SparseMatrixProduct::matrixMapA; +template +std::map< std::pair< int, int>, typename BM_SparseMatrixProduct::MatrixRHS> BM_SparseMatrixProduct::matrixMapB; +template +std::map< std::pair< int, int>, TProduct > BM_SparseMatrixProduct::productMap; + +#define BENCHARGS \ + ->ArgsProduct({{100, 1000}, {10, 20, 100, 150}}) \ + ->Args({10000, 1}) \ + ->Args({10000, 5}) \ + +#define SPARSEMATRIXPRODUCTBENCHMARK(Name, ScalarType, ProductType, StorageLHS, StorageRHS, StorageResult) \ + using Product ## Name = ProductType< \ + Eigen::SparseMatrix, \ + Eigen::SparseMatrix, \ + Eigen::SparseMatrix \ + >;\ + BENCHMARK_TEMPLATE_DEFINE_F(BM_SparseMatrixProduct, RegularProduct ## Name, Product ## Name)(benchmark::State& st) \ + { \ + for (auto _ : st) \ + {\ + this->regularProduct(st); \ + }\ + } \ + BENCHMARK_TEMPLATE_DEFINE_F(BM_SparseMatrixProduct, FastProduct ## Name, Product ## Name)(benchmark::State& st) \ + { \ + for (auto _ : st) \ + {\ + this->fastProduct(st); \ + }\ + } \ + BENCHMARK_TEMPLATE_DEFINE_F(BM_SparseMatrixProduct, ForceComputingIntersection ## Name, Product ## Name)(benchmark::State& st) \ + { \ + for (auto _ : st) \ + {\ + this->forceComputingIntersection(st); \ + }\ + }\ + BENCHMARK_REGISTER_F(BM_SparseMatrixProduct, RegularProduct ## Name)->Unit(benchmark::kMicrosecond) BENCHARGS;\ + BENCHMARK_REGISTER_F(BM_SparseMatrixProduct, FastProduct ## Name)->Unit(benchmark::kMicrosecond) BENCHARGS;\ + BENCHMARK_REGISTER_F(BM_SparseMatrixProduct, ForceComputingIntersection ## Name)->Unit(benchmark::kMicrosecond) BENCHARGS; + + +using Eigen::ColMajor; +using Eigen::RowMajor; + +SPARSEMATRIXPRODUCTBENCHMARK(ColColCol, SReal, sofa::linearalgebra::SparseMatrixProduct, ColMajor, ColMajor, ColMajor) +SPARSEMATRIXPRODUCTBENCHMARK(RowColCol, SReal, sofa::linearalgebra::SparseMatrixProduct, RowMajor, ColMajor, ColMajor) +SPARSEMATRIXPRODUCTBENCHMARK(ColRowCol, SReal, sofa::linearalgebra::SparseMatrixProduct, ColMajor, RowMajor, ColMajor) +SPARSEMATRIXPRODUCTBENCHMARK(RowRowCol, SReal, sofa::linearalgebra::SparseMatrixProduct, RowMajor, RowMajor, ColMajor) +SPARSEMATRIXPRODUCTBENCHMARK(ColColRow, SReal, sofa::linearalgebra::SparseMatrixProduct, ColMajor, ColMajor, RowMajor) +SPARSEMATRIXPRODUCTBENCHMARK(RowColRow, SReal, sofa::linearalgebra::SparseMatrixProduct, RowMajor, ColMajor, RowMajor) +SPARSEMATRIXPRODUCTBENCHMARK(ColRowRow, SReal, sofa::linearalgebra::SparseMatrixProduct, ColMajor, RowMajor, RowMajor) +SPARSEMATRIXPRODUCTBENCHMARK(RowRowRow, SReal, sofa::linearalgebra::SparseMatrixProduct, RowMajor, RowMajor, RowMajor) + +SPARSEMATRIXPRODUCTBENCHMARK(ParColColCol, SReal, sofa::simulation::ParallelSparseMatrixProduct, ColMajor, ColMajor, ColMajor) +SPARSEMATRIXPRODUCTBENCHMARK(ParRowColCol, SReal, sofa::simulation::ParallelSparseMatrixProduct, RowMajor, ColMajor, ColMajor) +SPARSEMATRIXPRODUCTBENCHMARK(ParColRowCol, SReal, sofa::simulation::ParallelSparseMatrixProduct, ColMajor, RowMajor, ColMajor) +SPARSEMATRIXPRODUCTBENCHMARK(ParRowRowCol, SReal, sofa::simulation::ParallelSparseMatrixProduct, RowMajor, RowMajor, ColMajor) +SPARSEMATRIXPRODUCTBENCHMARK(ParColColRow, SReal, sofa::simulation::ParallelSparseMatrixProduct, ColMajor, ColMajor, RowMajor) +SPARSEMATRIXPRODUCTBENCHMARK(ParRowColRow, SReal, sofa::simulation::ParallelSparseMatrixProduct, RowMajor, ColMajor, RowMajor) +SPARSEMATRIXPRODUCTBENCHMARK(ParColRowRow, SReal, sofa::simulation::ParallelSparseMatrixProduct, ColMajor, RowMajor, RowMajor) +SPARSEMATRIXPRODUCTBENCHMARK(ParRowRowRow, SReal, sofa::simulation::ParallelSparseMatrixProduct, RowMajor, RowMajor, RowMajor) + +#undef BENCHARGS +#undef SPARSEMATRIXPRODUCTBENCHMARK From 6aae60ae0ea67c63183fc8816f8a805a0f27e997 Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Wed, 19 Feb 2025 14:59:31 +0900 Subject: [PATCH 2/3] refresh --- .github/workflows/ci.yml | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bfc78db..f7ae90d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,28 +12,13 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-20.04, macos-11, windows-2019] + os: [ubuntu-22.04, macos-14, windows-2022] sofa_branch: [master] - steps: - - name: (Mac) Workaround for homebrew - shell: bash - if: runner.os == 'macOS' - run: | - rm -f /usr/local/bin/2to3 - rm -f /usr/local/bin/idle3 - rm -f /usr/local/bin/pydoc3 - rm -f /usr/local/bin/python3 - rm -f /usr/local/bin/python3-config - rm -f /usr/local/bin/2to3-3.11 - rm -f /usr/local/bin/idle3.11 - rm -f /usr/local/bin/pydoc3.11 - rm -f /usr/local/bin/python3.11 - rm -f /usr/local/bin/python3.11-config - + steps: - name: Setup SOFA and environment id: sofa - uses: sofa-framework/sofa-setup-action@v4 + uses: sofa-framework/sofa-setup-action@v5 with: sofa_root: ${{ github.workspace }}/sofa sofa_version: ${{ matrix.sofa_branch }} From 065844bd5ea7f983ffaaf9be8a29a8a214e83506 Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Wed, 19 Feb 2025 15:14:19 +0900 Subject: [PATCH 3/3] fix compilation wrt sofa master --- .../src/SofaBenchmarkScenes/BenchScene.h | 10 ++++------ src/benchmarks/SofaCore/ReadAccessor.cpp | 8 ++++---- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/SofaBenchmarkScenes/src/SofaBenchmarkScenes/BenchScene.h b/SofaBenchmarkScenes/src/SofaBenchmarkScenes/BenchScene.h index c1f77c8..1d1d5af 100644 --- a/SofaBenchmarkScenes/src/SofaBenchmarkScenes/BenchScene.h +++ b/SofaBenchmarkScenes/src/SofaBenchmarkScenes/BenchScene.h @@ -71,7 +71,6 @@ void BM_Scene_bench_AdvancedTimer(benchmark::State& state, const std::vector timerIds; timerIds.reserve(advancedTimerLabels.size()); @@ -92,7 +91,7 @@ void BM_Scene_bench_AdvancedTimer(benchmark::State& state, const std::vectoranimate(root.get(), TScene::dt); + sofa::simulation::node::animate(root.get(), TScene::dt); sofa::helper::AdvancedTimer::end("Animate"); const auto records = sofa::helper::AdvancedTimer::getStepData("Animate", true); @@ -112,7 +111,7 @@ void BM_Scene_bench_AdvancedTimer(benchmark::State& state, const std::vectorunload(root); + sofa::simulation::node::unload(root); } std::transform(avgTimers.begin(), avgTimers.end(), avgTimers.begin(), [&state](SReal t) { return t / state.range(0);}); @@ -136,7 +135,6 @@ void BM_Scene_bench_StepFactor(benchmark::State& state) sofa::component::init(); sofa::simulation::Simulation* simu = new sofa::simulation::graph::DAGSimulation(); - setSimulation(simu); for (auto _ : state) { @@ -149,10 +147,10 @@ void BM_Scene_bench_StepFactor(benchmark::State& state) state.ResumeTiming(); for (auto i = 0; i < state.range(0); ++i) { - simu->animate(root.get(), TScene::dt); + sofa::simulation::node::animate(root.get(), TScene::dt); } - simu->unload(root); + sofa::simulation::node::unload(root); } state.counters["FPS"] = benchmark::Counter(state.range(0), benchmark::Counter::kIsIterationInvariantRate); diff --git a/src/benchmarks/SofaCore/ReadAccessor.cpp b/src/benchmarks/SofaCore/ReadAccessor.cpp index 8c1ea5f..c861f4a 100644 --- a/src/benchmarks/SofaCore/ReadAccessor.cpp +++ b/src/benchmarks/SofaCore/ReadAccessor.cpp @@ -35,7 +35,7 @@ void BM_Data_GetValue(benchmark::State& state) { sofa::core::objectmodel::Data data; - if constexpr (sofa::type::trait::is_vector::value) + if constexpr (sofa::type::trait::is_vector) { auto d = sofa::helper::getWriteOnlyAccessor(data); d.resize(state.range(0)); @@ -53,7 +53,7 @@ void BM_Data_ReadAccessor_ImplicitConversion(benchmark::State& state) { sofa::core::objectmodel::Data data; - if constexpr (sofa::type::trait::is_vector::value) + if constexpr (sofa::type::trait::is_vector) { auto wa = sofa::helper::getWriteOnlyAccessor(data); wa.resize(state.range(0)); @@ -72,7 +72,7 @@ void BM_Data_ReadAccessor_ExplicitConversion(benchmark::State& state) { sofa::core::objectmodel::Data data; - if constexpr (sofa::type::trait::is_vector::value) + if constexpr (sofa::type::trait::is_vector) { auto wa = sofa::helper::getWriteOnlyAccessor(data); wa.resize(state.range(0)); @@ -91,7 +91,7 @@ void BM_Data_ReadAccessor_StarOperatorConversion(benchmark::State& state) { sofa::core::objectmodel::Data data; - if constexpr (sofa::type::trait::is_vector::value) + if constexpr (sofa::type::trait::is_vector) { auto wa = sofa::helper::getWriteOnlyAccessor(data); wa.resize(state.range(0));