Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 3 additions & 18 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
Expand Down
10 changes: 4 additions & 6 deletions SofaBenchmarkScenes/src/SofaBenchmarkScenes/BenchScene.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ void BM_Scene_bench_AdvancedTimer(benchmark::State& state, const std::vector<con
sofa::component::init();

sofa::simulation::Simulation* simu = new sofa::simulation::graph::DAGSimulation();
setSimulation(simu);

std::vector<sofa::helper::AdvancedTimer::IdStep> timerIds;
timerIds.reserve(advancedTimerLabels.size());
Expand All @@ -92,7 +91,7 @@ void BM_Scene_bench_AdvancedTimer(benchmark::State& state, const std::vector<con
for (auto j = 0; j < state.range(0); j++)
{
sofa::helper::AdvancedTimer::begin("Animate");
simu->animate(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);
Expand All @@ -112,7 +111,7 @@ void BM_Scene_bench_AdvancedTimer(benchmark::State& state, const std::vector<con

sofa::helper::AdvancedTimer::clearData("Animate");

simu->unload(root);
sofa::simulation::node::unload(root);
}

std::transform(avgTimers.begin(), avgTimers.end(), avgTimers.begin(), [&state](SReal t) { return t / state.range(0);});
Expand All @@ -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)
{
Expand All @@ -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);
Expand Down
176 changes: 123 additions & 53 deletions src/benchmarks/Sofa.LinearAlgebra/SparseMatrixProduct.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,49 @@
#include <iostream>
#include <benchmark/benchmark.h>

#include <sofa/linearalgebra/SparseMatrixProduct[EigenSparseMatrix].h>
#include <sofa/linearalgebra/SparseMatrixProduct.inl>
#include <sofa/simulation/BaseSimulationExporter.h>
#include <sofa/simulation/MainTaskSchedulerFactory.h>
#include <sofa/simulation/MainTaskSchedulerRegistry.h>
#include <sofa/simulation/ParallelSparseMatrixProduct.h>
#include <utils/SparseMatrix.h>

template<class T>
struct SparseMatrixProductInit
{
static void init(T& product)
{
SOFA_UNUSED(product);
};

static void cleanup()
{
}
};

template<class Lhs, class Rhs, class ResultType>
struct SparseMatrixProductInit<
sofa::simulation::ParallelSparseMatrixProduct<Lhs, Rhs, ResultType>>
{
static void init(sofa::simulation::ParallelSparseMatrixProduct<Lhs, Rhs, ResultType>& product)
{
product.taskScheduler = sofa::simulation::MainTaskSchedulerFactory::createInRegistry();
product.taskScheduler->init();
};

template<class TMatrix>
static void cleanup()
{
sofa::simulation::MainTaskSchedulerRegistry::clear();
}
};


template<class TProduct>
class BM_SparseMatrixProduct : public benchmark::Fixture
{
public:
using MatrixLHS = typename TProduct::LhsCleaned;
using MatrixRHS = typename TProduct::RhsCleaned;

void SetUp(const ::benchmark::State& state) override
{
Expand All @@ -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)
{
Expand All @@ -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)
{
Expand All @@ -50,14 +84,15 @@ class BM_SparseMatrixProduct : public benchmark::Fixture
auto it = productMap.find({matrixSize, sparsityPerMil});
if (it == productMap.end())
{
sofa::linearalgebra::SparseMatrixProduct<TMatrix> p;
TProduct p;
const auto insertIt = productMap.insert({ {matrixSize, sparsityPerMil}, p});
if (insertIt.second)
{
product = &insertIt.first->second;
SparseMatrixProductInit<TProduct>::init(*product);

product->matrixA = a;
product->matrixB = b;
product->m_lhs = a;
product->m_rhs = b;
product->computeProduct();
}
}
Expand All @@ -68,70 +103,105 @@ class BM_SparseMatrixProduct : public benchmark::Fixture

}

void TearDown(const ::benchmark::State& state) override
{
SparseMatrixProductInit<TProduct>::cleanup();
}

void regularProduct(benchmark::State& state)
{
SparseMatrixProductInit<TProduct>::init(*product);
product->computeRegularProduct();
}

void fastProduct(benchmark::State& state)
{
SparseMatrixProductInit<TProduct>::init(*product);
product->computeProduct();
}

void forceComputingIntersection(benchmark::State& state)
{
SparseMatrixProductInit<TProduct>::init(*product);
product->computeProduct(true);
}

sofa::linearalgebra::SparseMatrixProduct<TMatrix>* 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<TMatrix> > 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<class TMatrix>
std::map< std::pair< int, int>, TMatrix> BM_SparseMatrixProduct<TMatrix>::matrixMapA;
template<class TMatrix>
std::map< std::pair< int, int>, TMatrix> BM_SparseMatrixProduct<TMatrix>::matrixMapB;
template<class TMatrix>
std::map< std::pair< int, int>, sofa::linearalgebra::SparseMatrixProduct<TMatrix> > BM_SparseMatrixProduct<TMatrix>::productMap;

BENCHMARK_TEMPLATE_DEFINE_F(BM_SparseMatrixProduct, RegularProduct, Eigen::SparseMatrix<SReal>)(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<SReal>)(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<SReal>)(benchmark::State& st)
{
for (auto _ : st)
{
this->forceComputingIntersection(st);
}
}
// BENCHMARK_REGISTER_F(BM_SparseMatrixProduct, ForceComputingIntersection)->Unit(benchmark::kMicrosecond)
// ->ArgsProduct({{100, 1000},{10}});
template<class TProduct>
std::map< std::pair< int, int>, typename BM_SparseMatrixProduct<TProduct>::MatrixLHS> BM_SparseMatrixProduct<TProduct>::matrixMapA;
template<class TProduct>
std::map< std::pair< int, int>, typename BM_SparseMatrixProduct<TProduct>::MatrixRHS> BM_SparseMatrixProduct<TProduct>::matrixMapB;
template<class TProduct>
std::map< std::pair< int, int>, TProduct > BM_SparseMatrixProduct<TProduct>::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<ScalarType, StorageLHS>, \
Eigen::SparseMatrix<ScalarType, StorageRHS>, \
Eigen::SparseMatrix<ScalarType, StorageResult> \
>;\
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
8 changes: 4 additions & 4 deletions src/benchmarks/SofaCore/ReadAccessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ void BM_Data_GetValue(benchmark::State& state)
{
sofa::core::objectmodel::Data<T> data;

if constexpr (sofa::type::trait::is_vector<T>::value)
if constexpr (sofa::type::trait::is_vector<T>)
{
auto d = sofa::helper::getWriteOnlyAccessor(data);
d.resize(state.range(0));
Expand All @@ -53,7 +53,7 @@ void BM_Data_ReadAccessor_ImplicitConversion(benchmark::State& state)
{
sofa::core::objectmodel::Data<T> data;

if constexpr (sofa::type::trait::is_vector<T>::value)
if constexpr (sofa::type::trait::is_vector<T>)
{
auto wa = sofa::helper::getWriteOnlyAccessor(data);
wa.resize(state.range(0));
Expand All @@ -72,7 +72,7 @@ void BM_Data_ReadAccessor_ExplicitConversion(benchmark::State& state)
{
sofa::core::objectmodel::Data<T> data;

if constexpr (sofa::type::trait::is_vector<T>::value)
if constexpr (sofa::type::trait::is_vector<T>)
{
auto wa = sofa::helper::getWriteOnlyAccessor(data);
wa.resize(state.range(0));
Expand All @@ -91,7 +91,7 @@ void BM_Data_ReadAccessor_StarOperatorConversion(benchmark::State& state)
{
sofa::core::objectmodel::Data<T> data;

if constexpr (sofa::type::trait::is_vector<T>::value)
if constexpr (sofa::type::trait::is_vector<T>)
{
auto wa = sofa::helper::getWriteOnlyAccessor(data);
wa.resize(state.range(0));
Expand Down
Loading