#include #include using namespace Eigen; // ---------- TRSV: triangular solve with single RHS vector ---------- template static void BM_TRSV(benchmark::State& state) { using Mat = Matrix; using Vec = Matrix; const Index n = state.range(0); Mat A = Mat::Random(n, n); // Make diagonally dominant to ensure well-conditioned triangular part. A.diagonal().array() += Scalar(n); Vec x = Vec::Random(n); Vec b = x; for (auto _ : state) { x = b; A.template triangularView().solveInPlace(x); benchmark::DoNotOptimize(x.data()); } state.SetItemsProcessed(state.iterations() * n * n); } // ---------- TRSM: triangular solve with multiple RHS (OnTheLeft) ---------- template static void BM_TRSM_Left(benchmark::State& state) { using Mat = Matrix; const Index n = state.range(0); const Index nrhs = state.range(1); Mat A = Mat::Random(n, n); A.diagonal().array() += Scalar(n); Mat X = Mat::Random(n, nrhs); Mat B = X; for (auto _ : state) { X = B; A.template triangularView().solveInPlace(X); benchmark::DoNotOptimize(X.data()); } state.SetItemsProcessed(state.iterations() * n * n * nrhs); } // ---------- TRSM: triangular solve with multiple RHS (OnTheRight) ---------- template static void BM_TRSM_Right(benchmark::State& state) { using Mat = Matrix; const Index n = state.range(0); const Index nrhs = state.range(1); Mat A = Mat::Random(n, n); A.diagonal().array() += Scalar(n); Mat X = Mat::Random(nrhs, n); Mat B = X; for (auto _ : state) { X = B; A.template triangularView().template solveInPlace(X); benchmark::DoNotOptimize(X.data()); } state.SetItemsProcessed(state.iterations() * n * n * nrhs); } // ---------- Size configurations ---------- static void TrsvSizes(::benchmark::Benchmark* b) { for (int n : {32, 128, 512}) { b->Args({n}); } } static void TrsmSizes(::benchmark::Benchmark* b) { for (int n : {64, 256, 512}) { for (int nrhs : {1, 16, 64}) { b->Args({n, nrhs}); } } } // ---------- TRSV benchmarks ---------- // Only Lower is benchmarked; Upper exercises the same kernel via transposed storage. BENCHMARK(BM_TRSV)->Apply(TrsvSizes)->Name("TRSV_float_Lower"); BENCHMARK(BM_TRSV)->Apply(TrsvSizes)->Name("TRSV_double_Lower"); // ---------- TRSM Left benchmarks ---------- BENCHMARK(BM_TRSM_Left)->Apply(TrsmSizes)->Name("TRSM_Left_float_Lower"); BENCHMARK(BM_TRSM_Left)->Apply(TrsmSizes)->Name("TRSM_Left_double_Lower"); // ---------- TRSM Right benchmarks ---------- BENCHMARK(BM_TRSM_Right)->Apply(TrsmSizes)->Name("TRSM_Right_float_Lower"); BENCHMARK(BM_TRSM_Right)->Apply(TrsmSizes)->Name("TRSM_Right_double_Lower");