blob: d1926832435a3a2fe74fc9354e571f8bb4c9caad [file]
// SPDX-FileCopyrightText: The Eigen Authors
// SPDX-License-Identifier: MPL-2.0
#include <benchmark/benchmark.h>
#include <Eigen/Core>
#include "benchmark_boolean_helpers.h"
namespace Eigen {
namespace {
using namespace benchmark_detail;
struct Sum {
static bool run(const BoolArray& input) { return input.sum(); }
static bool reference(bool accum, bool value) { return accum || value; }
static bool identity() { return false; }
};
struct Product {
static bool run(const BoolArray& input) { return input.prod(); }
static bool reference(bool accum, bool value) { return accum && value; }
static bool identity() { return true; }
};
template <typename Operation, InputPattern Pattern>
void BM_BooleanReduction(benchmark::State& state) {
const Index size = state.range(0);
BoolArray input(size);
fill_input<Pattern>(input, 0x12345678u);
bool result = Operation::identity();
for (auto _ : state) {
result = Operation::run(input);
benchmark::DoNotOptimize(result);
}
bool reference = Operation::identity();
for (Index i = 0; i < size; ++i) reference = Operation::reference(reference, input[i]);
if (result != reference) state.SkipWithError("reduction result does not match the boolean reference");
state.SetItemsProcessed(state.iterations() * size);
}
struct LogicalAnd {
static void run(BoolArray& result, const BoolArray& lhs, const BoolArray& rhs) { result = lhs && rhs; }
static bool reference(bool lhs, bool rhs) { return lhs && rhs; }
};
struct LogicalOr {
static void run(BoolArray& result, const BoolArray& lhs, const BoolArray& rhs) { result = lhs || rhs; }
static bool reference(bool lhs, bool rhs) { return lhs || rhs; }
};
template <typename Operation, InputPattern Pattern>
void BM_BooleanBinary(benchmark::State& state) {
const Index size = state.range(0);
BoolArray lhs(size);
BoolArray rhs(size);
BoolArray result(size);
fill_input<Pattern>(lhs, 0x12345678u);
fill_input<Pattern>(rhs, 0x87654321u);
for (auto _ : state) {
Operation::run(result, lhs, rhs);
benchmark::DoNotOptimize(result.data());
benchmark::ClobberMemory();
}
for (Index i = 0; i < size; ++i) {
if (result[i] != Operation::reference(lhs[i], rhs[i])) {
state.SkipWithError("binary result does not match the boolean reference");
break;
}
}
state.SetItemsProcessed(state.iterations() * size);
}
#define EIGEN_BENCH_BOOLEAN_PATTERNS(BENCHMARK_FUNCTION, OPERATION) \
BENCHMARK_TEMPLATE(BENCHMARK_FUNCTION, OPERATION, Random)->Arg(262151); \
BENCHMARK_TEMPLATE(BENCHMARK_FUNCTION, OPERATION, AllFalse)->Arg(262151); \
BENCHMARK_TEMPLATE(BENCHMARK_FUNCTION, OPERATION, AllTrue)->Arg(262151); \
BENCHMARK_TEMPLATE(BENCHMARK_FUNCTION, OPERATION, benchmark_detail::Sparse)->Arg(262151)
EIGEN_BENCH_BOOLEAN_PATTERNS(BM_BooleanReduction, Sum);
EIGEN_BENCH_BOOLEAN_PATTERNS(BM_BooleanReduction, Product);
EIGEN_BENCH_BOOLEAN_PATTERNS(BM_BooleanBinary, LogicalAnd);
EIGEN_BENCH_BOOLEAN_PATTERNS(BM_BooleanBinary, LogicalOr);
#undef EIGEN_BENCH_BOOLEAN_PATTERNS
} // namespace
} // namespace Eigen