blob: 85ee9c4e5b227f11ded4adf3744e8f723d376246 [file]
// SPDX-FileCopyrightText: The Eigen Authors
// SPDX-License-Identifier: MPL-2.0
#include <benchmark/benchmark.h>
#include <Eigen/Core>
namespace Eigen {
namespace {
enum Operation { All, Any, Count };
template <Operation Op, typename Derived>
Index reduce(const DenseBase<Derived>& input) {
if (Op == All) return input.all();
if (Op == Any) return input.any();
return input.count();
}
template <Operation Op, typename Derived>
void measure(benchmark::State& state, const DenseBase<Derived>& input) {
Index count = 0;
for (Index col = 0; col < input.cols(); ++col)
for (Index row = 0; row < input.rows(); ++row) count += input(row, col) != 0;
const Index expected = Op == All ? Index(count == input.size()) : Op == Any ? Index(count != 0) : count;
if (reduce<Op>(input) != expected) {
state.SkipWithError("visitor result does not match the scalar reference");
return;
}
for (auto _ : state) {
benchmark::ClobberMemory();
benchmark::DoNotOptimize(reduce<Op>(input));
}
}
template <typename Scalar, int Options, Operation Op, bool Strided>
void BM_Visitor(benchmark::State& state) {
const Index inner = state.range(0), outer = state.range(1);
const Index rows = Options == RowMajor ? outer : inner;
const Index cols = Options == RowMajor ? inner : outer;
using MatrixType = Matrix<Scalar, Dynamic, Dynamic, Options>;
MatrixType input(rows, cols);
for (Index i = 0; i < input.size(); ++i) input(i) = Scalar(Op == All || (Op == Count && i % 3 != 0));
if (state.range(2) != 0) input(state.range(2) == 1 ? 0 : input.size() - 1) = Scalar(Op != All);
if (Strided) {
MatrixType storage = MatrixType::Zero(rows + 2, cols + 2);
auto block = storage.block(1, 1, rows, cols);
block = input;
measure<Op>(state, block);
} else {
measure<Op>(state, input);
}
}
#define EIGEN_BENCH_VISITOR(SCALAR, ORDER, OP, STRIDED) \
BENCHMARK_TEMPLATE(BM_Visitor, SCALAR, ORDER, OP, STRIDED) \
->Args({1, 4099, 0}) \
->Args({3, 1367, 0}) \
->Args({17, 241, 0}) \
->Args({64, 64, 0}) \
->Args({256, 256, 0}) \
->Args({3, 1367, 1}) \
->Args({3, 1367, 2})
#define EIGEN_BENCH_VISITORS(SCALAR, ORDER) \
EIGEN_BENCH_VISITOR(SCALAR, ORDER, EIGEN_BENCH_VISITOR_OP, EIGEN_BENCH_VISITOR_STRIDED)
EIGEN_BENCH_VISITORS(float, ColMajor);
EIGEN_BENCH_VISITORS(float, RowMajor);
EIGEN_BENCH_VISITORS(bool, ColMajor);
EIGEN_BENCH_VISITORS(bool, RowMajor);
#undef EIGEN_BENCH_VISITORS
#undef EIGEN_BENCH_VISITOR
} // namespace
} // namespace Eigen