blob: 138e9aee256b132bc3ed7b2532e395e5f810ccaf [file] [edit]
// SPDX-FileCopyrightText: The Eigen Authors
// SPDX-License-Identifier: MPL-2.0
#include <benchmark/benchmark.h>
#include <Eigen/Cholesky>
#include <cstdlib>
#include <type_traits>
namespace {
using namespace Eigen;
template <typename Scalar, int Order, int UpLo, bool Indefinite>
void BM_CholeskyReconstruction(benchmark::State& state) {
using MatrixType = Matrix<Scalar, Dynamic, Dynamic, Order>;
using RealScalar = typename MatrixType::RealScalar;
using Factorization =
typename std::conditional<Indefinite, BunchKaufman<MatrixType, UpLo>, LDLT<MatrixType, UpLo>>::type;
const Index size = state.range(0);
std::srand(3395);
const MatrixType random = MatrixType::Random(size, size);
MatrixType input(size, size);
if (Indefinite) {
input = random + random.adjoint();
} else {
input.noalias() = random * random.adjoint();
input.diagonal().array() += Scalar(1);
}
const Factorization factorization(input);
const MatrixType reconstructed = factorization.reconstructedMatrix();
const RealScalar tolerance = RealScalar(64) * RealScalar(size) * NumTraits<RealScalar>::epsilon() * input.norm();
if (factorization.info() != Success || !reconstructed.allFinite() || !((reconstructed - input).norm() <= tolerance)) {
state.SkipWithError("Incorrect Cholesky reconstruction");
return;
}
for (auto _ : state) {
const MatrixType result = factorization.reconstructedMatrix();
benchmark::DoNotOptimize(result.data());
benchmark::ClobberMemory();
}
}
// Indefinite=false uses LDLT; true uses BunchKaufman. Factorization is outside timing.
#define EIGEN_BENCH_RECONSTRUCTION(Scalar, Order, UpLo) \
BENCHMARK_TEMPLATE(BM_CholeskyReconstruction, Scalar, Order, UpLo, false) \
->ArgsProduct({{4, 16, 64, 128, 256, 1024}}); \
BENCHMARK_TEMPLATE(BM_CholeskyReconstruction, Scalar, Order, UpLo, true)->ArgsProduct({{4, 16, 64, 128, 256, 1024}})
EIGEN_BENCH_RECONSTRUCTION(double, ColMajor, Lower);
EIGEN_BENCH_RECONSTRUCTION(double, RowMajor, Upper);
EIGEN_BENCH_RECONSTRUCTION(std::complex<double>, ColMajor, Upper);
EIGEN_BENCH_RECONSTRUCTION(std::complex<double>, RowMajor, Lower);
#undef EIGEN_BENCH_RECONSTRUCTION
} // namespace