Files
eigen/benchmarks/bench_trsm.cpp
2026-02-20 00:56:57 -08:00

95 lines
3.0 KiB
C++

#include <benchmark/benchmark.h>
#include <Eigen/Dense>
using namespace Eigen;
// ---------- TRSV: triangular solve with single RHS vector ----------
template <typename Scalar, unsigned int Mode>
static void BM_TRSV(benchmark::State& state) {
using Mat = Matrix<Scalar, Dynamic, Dynamic>;
using Vec = Matrix<Scalar, Dynamic, 1>;
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<Mode>().solveInPlace(x);
benchmark::DoNotOptimize(x.data());
}
state.SetItemsProcessed(state.iterations() * n * n);
}
// ---------- TRSM: triangular solve with multiple RHS (OnTheLeft) ----------
template <typename Scalar, unsigned int Mode>
static void BM_TRSM_Left(benchmark::State& state) {
using Mat = Matrix<Scalar, Dynamic, Dynamic>;
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<Mode>().solveInPlace(X);
benchmark::DoNotOptimize(X.data());
}
state.SetItemsProcessed(state.iterations() * n * n * nrhs);
}
// ---------- TRSM: triangular solve with multiple RHS (OnTheRight) ----------
template <typename Scalar, unsigned int Mode>
static void BM_TRSM_Right(benchmark::State& state) {
using Mat = Matrix<Scalar, Dynamic, Dynamic>;
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<Mode>().template solveInPlace<OnTheRight>(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<float, Lower>)->Apply(TrsvSizes)->Name("TRSV_float_Lower");
BENCHMARK(BM_TRSV<double, Lower>)->Apply(TrsvSizes)->Name("TRSV_double_Lower");
// ---------- TRSM Left benchmarks ----------
BENCHMARK(BM_TRSM_Left<float, Lower>)->Apply(TrsmSizes)->Name("TRSM_Left_float_Lower");
BENCHMARK(BM_TRSM_Left<double, Lower>)->Apply(TrsmSizes)->Name("TRSM_Left_double_Lower");
// ---------- TRSM Right benchmarks ----------
BENCHMARK(BM_TRSM_Right<float, Lower>)->Apply(TrsmSizes)->Name("TRSM_Right_float_Lower");
BENCHMARK(BM_TRSM_Right<double, Lower>)->Apply(TrsmSizes)->Name("TRSM_Right_double_Lower");