# 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]

DENSE_SOLVER_CONFIGS = [
    # Linear solver  Dense backend
    ('DENSE_SCHUR',  'EIGEN'),
    ('DENSE_SCHUR',  'LAPACK'),
    ('DENSE_SCHUR',  'CUDA'),
]

SPARSE_SOLVER_CONFIGS = [
    # Linear solver            Sparse backend
    ('SPARSE_NORMAL_CHOLESKY', 'SUITE_SPARSE'),
    ('SPARSE_NORMAL_CHOLESKY', 'EIGEN_SPARSE'),
    ('SPARSE_NORMAL_CHOLESKY', 'CX_SPARSE'),
    ('SPARSE_NORMAL_CHOLESKY', 'ACCELERATE_SPARSE'),
    ('SPARSE_SCHUR',           'SUITE_SPARSE'),
    ('SPARSE_SCHUR',           'EIGEN_SPARSE'),
    ('SPARSE_SCHUR',           'CX_SPARSE'),
    ('SPARSE_SCHUR',           'ACCELERATE_SPARSE'),
]

ITERATIVE_SOLVER_CONFIGS = [
    # Linear solver            Sparse backend      Preconditioner
    ('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'),
]

FILENAME_SHORTENING_MAP = dict(
  DENSE_SCHUR='denseschur',
  ITERATIVE_SCHUR='iterschur',
  SPARSE_NORMAL_CHOLESKY='sparsecholesky',
  SPARSE_SCHUR='sparseschur',
  EIGEN='eigen',
  LAPACK='lapack',
  CUDA='cuda',
  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 2022 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 "ceres/internal/config.h"
#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->dense_linear_algebra_library_type = %(dense_backend)s;
  options->sparse_linear_algebra_library_type = %(sparse_backend)s;
  options->preconditioner_type = %(preconditioner)s;
  if (%(ordering)s) {
    options->linear_solver_ordering = nullptr;
  }
  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,
                         dense_backend,
                         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 = ''

  dense_backend_tag = dense_backend
  if linear_solver != 'DENSE_SCHUR':
    dense_backend_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(dense_backend_tag),
      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,
          dense_backend=dense_backend,
          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')

  if dense_backend == "LAPACK":
    preprocessor_conditions_begin.append('#ifndef CERES_NO_LAPACK')
    preprocessor_conditions_end.insert(0, '#endif  // CERES_NO_LAPACK')
  elif dense_backend == "CUDA":
    preprocessor_conditions_begin.append('#ifndef CERES_NO_CUDA')
    preprocessor_conditions_end.insert(0, '#endif  // CERES_NO_CUDA')

  # 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,
      dense_backend_tag,
      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 ordering in ORDERINGS:
    for thread_config in THREAD_CONFIGS:
      for linear_solver, dense_backend in DENSE_SOLVER_CONFIGS:
        generated_files.append(
            generate_bundle_test(linear_solver,
                                 dense_backend,
                                 'NO_SPARSE',
                                 'IDENTITY',
                                 ordering,
                                 thread_config))

      for linear_solver, sparse_backend, in SPARSE_SOLVER_CONFIGS:
        generated_files.append(
            generate_bundle_test(linear_solver,
                                 'EIGEN',
                                 sparse_backend,
                                 'IDENTITY',
                                 ordering,
                                 thread_config))

      for linear_solver, sparse_backend, preconditioner, in ITERATIVE_SOLVER_CONFIGS:
        generated_files.append(
            generate_bundle_test(linear_solver,
                                 'EIGEN',
                                 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', ''))
