// Benchmarks for diagonal operations. // // Tests diagonal extraction, diagonal-matrix product, and matrix-diagonal product. #include #include using namespace Eigen; // Extract diagonal from a square matrix and sum it. template static void BM_DiagonalExtract(benchmark::State& state) { const Index n = state.range(0); using Mat = Matrix; Mat A = Mat::Random(n, n); for (auto _ : state) { Scalar s = A.diagonal().sum(); benchmark::DoNotOptimize(s); } state.SetBytesProcessed(state.iterations() * n * sizeof(Scalar)); } // y = diag(d) * x (diagonal matrix times vector). template static void BM_DiagonalTimesVector(benchmark::State& state) { const Index n = state.range(0); using Vec = Matrix; Vec d = Vec::Random(n); Vec x = Vec::Random(n); Vec y(n); for (auto _ : state) { y = d.asDiagonal() * x; benchmark::DoNotOptimize(y.data()); } state.SetBytesProcessed(state.iterations() * 3 * n * sizeof(Scalar)); } // C = diag(d) * A (diagonal matrix times dense matrix). template static void BM_DiagonalTimesMatrix(benchmark::State& state) { const Index n = state.range(0); using Mat = Matrix; using Vec = Matrix; Vec d = Vec::Random(n); Mat A = Mat::Random(n, n); Mat C(n, n); for (auto _ : state) { C.noalias() = d.asDiagonal() * A; benchmark::DoNotOptimize(C.data()); } state.SetBytesProcessed(state.iterations() * 2 * n * n * sizeof(Scalar)); } // C = A * diag(d) (dense matrix times diagonal matrix). template static void BM_MatrixTimesDiagonal(benchmark::State& state) { const Index n = state.range(0); using Mat = Matrix; using Vec = Matrix; Vec d = Vec::Random(n); Mat A = Mat::Random(n, n); Mat C(n, n); for (auto _ : state) { C.noalias() = A * d.asDiagonal(); benchmark::DoNotOptimize(C.data()); } state.SetBytesProcessed(state.iterations() * 2 * n * n * sizeof(Scalar)); } static void Sizes(::benchmark::Benchmark* b) { for (int n : {32, 64, 128, 256, 512, 1024}) b->Arg(n); } BENCHMARK(BM_DiagonalExtract)->Apply(Sizes)->Name("DiagonalExtract_float"); BENCHMARK(BM_DiagonalExtract)->Apply(Sizes)->Name("DiagonalExtract_double"); BENCHMARK(BM_DiagonalTimesVector)->Apply(Sizes)->Name("DiagonalTimesVector_float"); BENCHMARK(BM_DiagonalTimesVector)->Apply(Sizes)->Name("DiagonalTimesVector_double"); BENCHMARK(BM_DiagonalTimesMatrix)->Apply(Sizes)->Name("DiagonalTimesMatrix_float"); BENCHMARK(BM_DiagonalTimesMatrix)->Apply(Sizes)->Name("DiagonalTimesMatrix_double"); BENCHMARK(BM_MatrixTimesDiagonal)->Apply(Sizes)->Name("MatrixTimesDiagonal_float"); BENCHMARK(BM_MatrixTimesDiagonal)->Apply(Sizes)->Name("MatrixTimesDiagonal_double");