// 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)); } // clang-format off #define DIAG_SIZES ->Arg(32)->Arg(64)->Arg(128)->Arg(256)->Arg(512)->Arg(1024) BENCHMARK(BM_DiagonalExtract) DIAG_SIZES ->Name("DiagonalExtract_float"); BENCHMARK(BM_DiagonalExtract) DIAG_SIZES ->Name("DiagonalExtract_double"); BENCHMARK(BM_DiagonalTimesVector) DIAG_SIZES ->Name("DiagonalTimesVector_float"); BENCHMARK(BM_DiagonalTimesVector) DIAG_SIZES ->Name("DiagonalTimesVector_double"); BENCHMARK(BM_DiagonalTimesMatrix) DIAG_SIZES ->Name("DiagonalTimesMatrix_float"); BENCHMARK(BM_DiagonalTimesMatrix) DIAG_SIZES ->Name("DiagonalTimesMatrix_double"); BENCHMARK(BM_MatrixTimesDiagonal) DIAG_SIZES ->Name("MatrixTimesDiagonal_float"); BENCHMARK(BM_MatrixTimesDiagonal) DIAG_SIZES ->Name("MatrixTimesDiagonal_double"); #undef DIAG_SIZES // clang-format on