Add a constant cost function to the autodiff benchmarks
The constant cost function is run with a variable number of
parameters to test at which point, different compilers fail
to optimize the autodiff code.
Clang achieves expected performance which fails at >50 parameters.
G++ fails already at 20 parameters
Change-Id: I75d8c683ef0011d813ec6d966d7ad58f86530f44
diff --git a/internal/ceres/autodiff_benchmarks/autodiff_benchmarks.cc b/internal/ceres/autodiff_benchmarks/autodiff_benchmarks.cc
index 252cb52..c274aa5 100644
--- a/internal/ceres/autodiff_benchmarks/autodiff_benchmarks.cc
+++ b/internal/ceres/autodiff_benchmarks/autodiff_benchmarks.cc
@@ -32,6 +32,7 @@
#include "benchmark/benchmark.h"
#include "ceres/autodiff_benchmarks/brdf_cost_function.h"
+#include "ceres/autodiff_benchmarks/constant_cost_function.h"
#include "ceres/autodiff_benchmarks/linear_cost_functions.h"
#include "ceres/autodiff_benchmarks/snavely_reprojection_error.h"
#include "ceres/ceres.h"
@@ -39,6 +40,64 @@
namespace ceres {
+template <int kParameterBlockSize>
+static void BM_ConstantAnalytic(benchmark::State& state) {
+ constexpr int num_residuals = 1;
+ std::array<double, kParameterBlockSize> parameters_values;
+ std::iota(parameters_values.begin(), parameters_values.end(), 0);
+ double* parameters[] = {parameters_values.data()};
+
+ std::array<double, num_residuals> residuals;
+
+ std::array<double, num_residuals * kParameterBlockSize> jacobian_values;
+ double* jacobians[] = {jacobian_values.data()};
+
+ std::unique_ptr<ceres::CostFunction> cost_function(
+ new ConstantCostFunction<kParameterBlockSize>());
+
+ for (auto _ : state) {
+ cost_function->Evaluate(parameters, residuals.data(), jacobians);
+ }
+}
+
+template <int kParameterBlockSize>
+static void BM_ConstantAutodiff(benchmark::State& state) {
+ constexpr int num_residuals = 1;
+ std::array<double, kParameterBlockSize> parameters_values;
+ std::iota(parameters_values.begin(), parameters_values.end(), 0);
+ double* parameters[] = {parameters_values.data()};
+
+ std::array<double, num_residuals> residuals;
+
+ std::array<double, num_residuals * kParameterBlockSize> jacobian_values;
+ double* jacobians[] = {jacobian_values.data()};
+
+ using AutoDiffFunctor = ceres::internal::CostFunctionToFunctor<
+ ConstantCostFunction<kParameterBlockSize>>;
+ std::unique_ptr<ceres::CostFunction> cost_function(
+ new ceres::AutoDiffCostFunction<AutoDiffFunctor, 1, kParameterBlockSize>(
+ new AutoDiffFunctor()));
+
+ for (auto _ : state) {
+ cost_function->Evaluate(parameters, residuals.data(), jacobians);
+ }
+}
+
+BENCHMARK_TEMPLATE(BM_ConstantAnalytic, 1);
+BENCHMARK_TEMPLATE(BM_ConstantAutodiff, 1);
+BENCHMARK_TEMPLATE(BM_ConstantAnalytic, 10);
+BENCHMARK_TEMPLATE(BM_ConstantAutodiff, 10);
+BENCHMARK_TEMPLATE(BM_ConstantAnalytic, 20);
+BENCHMARK_TEMPLATE(BM_ConstantAutodiff, 20);
+BENCHMARK_TEMPLATE(BM_ConstantAnalytic, 30);
+BENCHMARK_TEMPLATE(BM_ConstantAutodiff, 30);
+BENCHMARK_TEMPLATE(BM_ConstantAnalytic, 40);
+BENCHMARK_TEMPLATE(BM_ConstantAutodiff, 40);
+BENCHMARK_TEMPLATE(BM_ConstantAnalytic, 50);
+BENCHMARK_TEMPLATE(BM_ConstantAutodiff, 50);
+BENCHMARK_TEMPLATE(BM_ConstantAnalytic, 60);
+BENCHMARK_TEMPLATE(BM_ConstantAutodiff, 60);
+
#ifdef WITH_CODE_GENERATION
static void BM_Linear1CodeGen(benchmark::State& state) {
double parameter_block1[] = {1.};
diff --git a/internal/ceres/autodiff_benchmarks/constant_cost_function.h b/internal/ceres/autodiff_benchmarks/constant_cost_function.h
new file mode 100644
index 0000000..00f39d6
--- /dev/null
+++ b/internal/ceres/autodiff_benchmarks/constant_cost_function.h
@@ -0,0 +1,63 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2020 Google Inc. All rights reserved.
+// http://ceres-solver.org/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+// used to endorse or promote products derived from this software without
+// specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: darius.rueckert@fau.de (Darius Rueckert)
+//
+//
+#ifndef CERES_INTERNAL_AUTODIFF_BENCHMARKS_CONSTANT_COST_FUNCTIONS_H_
+#define CERES_INTERNAL_AUTODIFF_BENCHMARKS_CONSTANT_COST_FUNCTIONS_H_
+
+#include "ceres/sized_cost_function.h"
+
+namespace ceres {
+
+template <int kParameterBlockSize>
+struct ConstantCostFunction
+ : public ceres::SizedCostFunction<1, kParameterBlockSize> {
+ template <typename T>
+ bool operator()(const T* const x, T* residuals) const {
+ residuals[0] = T(5);
+ return true;
+ }
+
+ virtual bool Evaluate(double const* const* parameters,
+ double* residuals,
+ double** jacobians) const {
+ residuals[0] = 5.0;
+ if (jacobians) {
+ if (jacobians[0]) {
+ memset(jacobians[0], 0, sizeof(double) * kParameterBlockSize);
+ }
+ }
+ return true;
+ }
+};
+
+} // namespace ceres
+
+#endif // CERES_INTERNAL_AUTODIFF_BENCHMARKS_CONSTANT_COST_FUNCTIONS_H_