# Ceres Solver - A fast non-linear least squares minimizer
# Copyright 2018 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: keir@google.com (Keir Mierle)
#
# Generate bundle adjustment tests as separate binaries. Since the bundle
# adjustment tests are fairly processing intensive, serializing them makes the
# tests take forever to run. Splitting them into separate binaries makes it
# easier to parallelize in continuous integration systems, and makes local
# processing on multi-core workstations much faster.

# Product of ORDERINGS, THREAD_CONFIGS, and SOLVER_CONFIGS is the full set of
# tests to generate.
ORDERINGS = ["kAutomaticOrdering", "kUserOrdering"]
SINGLE_THREADED = "1"
MULTI_THREADED = "4"
THREAD_CONFIGS = [SINGLE_THREADED, MULTI_THREADED]

SOLVER_CONFIGS = [
  # Linear solver            Sparse backend      Preconditioner
  ('DENSE_SCHUR',            'NO_SPARSE',        'IDENTITY'),
  ('ITERATIVE_SCHUR',        'NO_SPARSE',        'JACOBI'),
  ('ITERATIVE_SCHUR',        'NO_SPARSE',        'SCHUR_JACOBI'),
  ('ITERATIVE_SCHUR',        'SUITE_SPARSE',     'CLUSTER_JACOBI'),
  ('ITERATIVE_SCHUR',        'EIGEN_SPARSE',     'CLUSTER_JACOBI'),
  ('ITERATIVE_SCHUR',        'CX_SPARSE',        'CLUSTER_JACOBI'),
  ('ITERATIVE_SCHUR',        'ACCELERATE_SPARSE','CLUSTER_JACOBI'),
  ('ITERATIVE_SCHUR',        'SUITE_SPARSE',     'CLUSTER_TRIDIAGONAL'),
  ('ITERATIVE_SCHUR',        'EIGEN_SPARSE',     'CLUSTER_TRIDIAGONAL'),
  ('ITERATIVE_SCHUR',        'CX_SPARSE',        'CLUSTER_TRIDIAGONAL'),
  ('ITERATIVE_SCHUR',        'ACCELERATE_SPARSE','CLUSTER_TRIDIAGONAL'),
  ('SPARSE_NORMAL_CHOLESKY', 'SUITE_SPARSE',     'IDENTITY'),
  ('SPARSE_NORMAL_CHOLESKY', 'EIGEN_SPARSE',     'IDENTITY'),
  ('SPARSE_NORMAL_CHOLESKY', 'CX_SPARSE',        'IDENTITY'),
  ('SPARSE_NORMAL_CHOLESKY', 'ACCELERATE_SPARSE','IDENTITY'),
  ('SPARSE_SCHUR',           'SUITE_SPARSE',     'IDENTITY'),
  ('SPARSE_SCHUR',           'EIGEN_SPARSE',     'IDENTITY'),
  ('SPARSE_SCHUR',           'CX_SPARSE',        'IDENTITY'),
  ('SPARSE_SCHUR',           'ACCELERATE_SPARSE','IDENTITY'),
]

FILENAME_SHORTENING_MAP = dict(
  DENSE_SCHUR='denseschur',
  ITERATIVE_SCHUR='iterschur',
  SPARSE_NORMAL_CHOLESKY='sparsecholesky',
  SPARSE_SCHUR='sparseschur',
  NO_SPARSE='',  # Omit sparse reference entirely for dense tests.
  SUITE_SPARSE='suitesparse',
  EIGEN_SPARSE='eigensparse',
  CX_SPARSE='cxsparse',
  ACCELERATE_SPARSE='acceleratesparse',
  IDENTITY='identity',
  JACOBI='jacobi',
  SCHUR_JACOBI='schurjacobi',
  CLUSTER_JACOBI='clustjacobi',
  CLUSTER_TRIDIAGONAL='clusttri',
  kAutomaticOrdering='auto',
  kUserOrdering='user',
)

COPYRIGHT_HEADER = (
"""// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2018 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.
//
// ========================================
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
// ========================================
//
// This file is generated using generate_bundle_adjustment_tests.py.""")

BUNDLE_ADJUSTMENT_TEST_TEMPLATE = (COPYRIGHT_HEADER + """

#include "bundle_adjustment_test_util.h"
%(preprocessor_conditions_begin)s
namespace ceres {
namespace internal {

TEST_F(BundleAdjustmentTest,
       %(test_class_name)s) {  // NOLINT
  BundleAdjustmentProblem bundle_adjustment_problem;
  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
  options->num_threads = %(num_threads)s;
  options->linear_solver_type = %(linear_solver)s;
  options->sparse_linear_algebra_library_type = %(sparse_backend)s;
  options->preconditioner_type = %(preconditioner)s;
  if (%(ordering)s) {
    options->linear_solver_ordering.reset();
  }
  Problem* problem = bundle_adjustment_problem.mutable_problem();
  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
}

}  // namespace internal
}  // namespace ceres
%(preprocessor_conditions_end)s""")

def camelcasify(token):
  """Convert capitalized underscore tokens to camel case"""
  return ''.join([x.lower().capitalize() for x in token.split('_')])


def generate_bundle_test(linear_solver,
                         sparse_backend,
                         preconditioner,
                         ordering,
                         thread_config):
  """Generate a bundle adjustment test executable configured appropriately"""

  # Preconditioner only makes sense for iterative schur; drop it otherwise.
  preconditioner_tag = preconditioner
  if linear_solver != 'ITERATIVE_SCHUR':
    preconditioner_tag = ''

  # Omit references to the sparse backend when one is not in use.
  sparse_backend_tag = sparse_backend
  if sparse_backend == 'NO_SPARSE':
    sparse_backend_tag = ''

  # Use a double underscore; otherwise the names are harder to understand.
  test_class_name = '_'.join(filter(lambda x: x, [
      camelcasify(linear_solver),
      camelcasify(sparse_backend_tag),
      camelcasify(preconditioner_tag),
      ordering[1:],  # Strip 'k'
      'Threads' if thread_config == MULTI_THREADED else '']))

  # Initial template parameters (augmented more below).
  template_parameters = dict(
          linear_solver=linear_solver,
          sparse_backend=sparse_backend,
          preconditioner=preconditioner,
          ordering=ordering,
          num_threads=thread_config,
          test_class_name=test_class_name)

  # Accumulate appropriate #ifdef/#ifndefs for the solver's sparse backend.
  preprocessor_conditions_begin = []
  preprocessor_conditions_end = []
  if sparse_backend == 'SUITE_SPARSE':
    preprocessor_conditions_begin.append('#ifndef CERES_NO_SUITESPARSE')
    preprocessor_conditions_end.insert(0, '#endif  // CERES_NO_SUITESPARSE')
  elif sparse_backend == 'CX_SPARSE':
    preprocessor_conditions_begin.append('#ifndef CERES_NO_CXSPARSE')
    preprocessor_conditions_end.insert(0, '#endif  // CERES_NO_CXSPARSE')
  elif sparse_backend == 'ACCELERATE_SPARSE':
    preprocessor_conditions_begin.append('#ifndef CERES_NO_ACCELERATE_SPARSE')
    preprocessor_conditions_end.insert(0, '#endif  // CERES_NO_ACCELERATE_SPARSE')
  elif sparse_backend == 'EIGEN_SPARSE':
    preprocessor_conditions_begin.append('#ifdef CERES_USE_EIGEN_SPARSE')
    preprocessor_conditions_end.insert(0, '#endif  // CERES_USE_EIGEN_SPARSE')

  # Accumulate appropriate #ifdef/#ifndefs for threading conditions.
  if thread_config == MULTI_THREADED:
    preprocessor_conditions_begin.append('#ifndef CERES_NO_THREADS')
    preprocessor_conditions_end.insert(0, '#endif  // CERES_NO_THREADS')

  # If there are #ifdefs, put newlines around them.
  if preprocessor_conditions_begin:
    preprocessor_conditions_begin.insert(0, '')
    preprocessor_conditions_begin.append('')
    preprocessor_conditions_end.insert(0, '')
    preprocessor_conditions_end.append('')

  # Put #ifdef/#ifndef stacks into the template parameters.
  template_parameters['preprocessor_conditions_begin'] = '\n'.join(
      preprocessor_conditions_begin)
  template_parameters['preprocessor_conditions_end'] = '\n'.join(
      preprocessor_conditions_end)

  # Substitute variables into the test template, and write the result to a file.
  filename_tag = '_'.join(FILENAME_SHORTENING_MAP.get(x) for x in [
      linear_solver,
      sparse_backend_tag,
      preconditioner_tag,
      ordering]
      if FILENAME_SHORTENING_MAP.get(x))
  if (thread_config == MULTI_THREADED):
    filename_tag += '_threads'

  filename = ('generated_bundle_adjustment_tests/ba_%s_test.cc' %
                filename_tag.lower())
  with open(filename, 'w') as fd:
    fd.write(BUNDLE_ADJUSTMENT_TEST_TEMPLATE % template_parameters)

  # All done.
  print 'Generated', filename

  return filename


if __name__ == '__main__':
  # Iterate over all the possible configurations and generate the tests.
  generated_files = []
  for linear_solver, sparse_backend, preconditioner in SOLVER_CONFIGS:
    for ordering in ORDERINGS:
      for thread_config in THREAD_CONFIGS:
        generated_files.append(
            generate_bundle_test(linear_solver,
                                 sparse_backend,
                                 preconditioner,
                                 ordering,
                                 thread_config))

  # Generate the CMakeLists.txt as well.
  with open('generated_bundle_adjustment_tests/CMakeLists.txt', 'w') as fd:
    fd.write(COPYRIGHT_HEADER.replace('//', '#').replace('http:#', 'http://'))
    fd.write('\n')
    fd.write('\n')
    for generated_file in generated_files:
      fd.write('ceres_test(%s)\n' %
               generated_file.split('/')[1].replace('_test.cc', ''))
