1# Ceres Solver - A fast non-linear least squares minimizer
2# Copyright 2013 Google Inc. All rights reserved.
3# http://code.google.com/p/ceres-solver/
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions are met:
7#
8# * Redistributions of source code must retain the above copyright notice,
9#   this list of conditions and the following disclaimer.
10# * Redistributions in binary form must reproduce the above copyright notice,
11#   this list of conditions and the following disclaimer in the documentation
12#   and/or other materials provided with the distribution.
13# * Neither the name of Google Inc. nor the names of its contributors may be
14#   used to endorse or promote products derived from this software without
15#   specific prior written permission.
16#
17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27# POSSIBILITY OF SUCH DAMAGE.
28#
29# Author: sameeragarwal@google.com (Sameer Agarwal)
30#
31# Script for explicitly generating template specialization of the
32# PartitionedMatrixView class. Explicitly generating these
33# instantiations in separate .cc files breaks the compilation into
34# separate compilation unit rather than one large cc file.
35#
36# This script creates two sets of files.
37#
38# 1. partitioned_matrix_view_x_x_x.cc
39# where the x indicates the template parameters and
40#
41# 2. partitioned_matrix_view.cc
42#
43# that contains a factory function for instantiating these classes
44# based on runtime parameters.
45#
46# The list of tuples, specializations indicates the set of
47# specializations that is generated.
48
49# Set of template specializations to generate
50SPECIALIZATIONS = [(2, 2, 2),
51                   (2, 2, 3),
52                   (2, 2, 4),
53                   (2, 2, "Eigen::Dynamic"),
54                   (2, 3, 3),
55                   (2, 3, 4),
56                   (2, 3, 9),
57                   (2, 3, "Eigen::Dynamic"),
58                   (2, 4, 3),
59                   (2, 4, 4),
60                   (2, 4, 8),
61                   (2, 4, 9),
62                   (2, 4, "Eigen::Dynamic"),
63                   (2, "Eigen::Dynamic", "Eigen::Dynamic"),
64                   (4, 4, 2),
65                   (4, 4, 3),
66                   (4, 4, 4),
67                   (4, 4, "Eigen::Dynamic"),
68                   ("Eigen::Dynamic", "Eigen::Dynamic", "Eigen::Dynamic")]
69HEADER = """// Ceres Solver - A fast non-linear least squares minimizer
70// Copyright 2013 Google Inc. All rights reserved.
71// http://code.google.com/p/ceres-solver/
72//
73// Redistribution and use in source and binary forms, with or without
74// modification, are permitted provided that the following conditions are met:
75//
76// * Redistributions of source code must retain the above copyright notice,
77//   this list of conditions and the following disclaimer.
78// * Redistributions in binary form must reproduce the above copyright notice,
79//   this list of conditions and the following disclaimer in the documentation
80//   and/or other materials provided with the distribution.
81// * Neither the name of Google Inc. nor the names of its contributors may be
82//   used to endorse or promote products derived from this software without
83//   specific prior written permission.
84//
85// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
86// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
87// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
88// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
89// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
90// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
91// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
92// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
93// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
94// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
95// POSSIBILITY OF SUCH DAMAGE.
96//
97// Author: sameeragarwal@google.com (Sameer Agarwal)
98//
99// Template specialization of PartitionedMatrixView.
100//
101// ========================================
102// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
103// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
104// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
105// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
106//=========================================
107//
108// This file is generated using generate_partitioned_matrix_view_specializations.py.
109// Editing it manually is not recommended.
110"""
111
112DYNAMIC_FILE = """
113
114#include "ceres/partitioned_matrix_view_impl.h"
115#include "ceres/internal/eigen.h"
116
117namespace ceres {
118namespace internal {
119
120template class PartitionedMatrixView<%s, %s, %s>;
121
122}  // namespace internal
123}  // namespace ceres
124"""
125
126SPECIALIZATION_FILE = """
127// This include must come before any #ifndef check on Ceres compile options.
128#include "ceres/internal/port.h"
129
130#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
131
132#include "ceres/partitioned_matrix_view_impl.h"
133#include "ceres/internal/eigen.h"
134
135namespace ceres {
136namespace internal {
137
138template class PartitionedMatrixView<%s, %s, %s>;
139
140}  // namespace internal
141}  // namespace ceres
142
143#endif  // CERES_RESTRICT_SCHUR_SPECIALIZATION
144"""
145
146FACTORY_FILE_HEADER = """
147#include "ceres/linear_solver.h"
148#include "ceres/partitioned_matrix_view.h"
149#include "ceres/internal/eigen.h"
150
151namespace ceres {
152namespace internal {
153
154PartitionedMatrixViewBase*
155PartitionedMatrixViewBase::Create(const LinearSolver::Options& options,
156                                  const BlockSparseMatrix& matrix) {
157#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
158"""
159
160FACTORY_CONDITIONAL = """  if ((options.row_block_size == %s) &&
161      (options.e_block_size == %s) &&
162      (options.f_block_size == %s)) {
163    return new PartitionedMatrixView<%s, %s, %s>(
164                 matrix, options.elimination_groups[0]);
165  }
166"""
167
168FACTORY_FOOTER = """
169#endif
170  VLOG(1) << "Template specializations not found for <"
171          << options.row_block_size << ","
172          << options.e_block_size << ","
173          << options.f_block_size << ">";
174  return new PartitionedMatrixView<Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic>(
175               matrix, options.elimination_groups[0]);
176};
177
178}  // namespace internal
179}  // namespace ceres
180"""
181
182
183def SuffixForSize(size):
184  if size == "Eigen::Dynamic":
185    return "d"
186  return str(size)
187
188
189def SpecializationFilename(prefix, row_block_size, e_block_size, f_block_size):
190  return "_".join([prefix] + map(SuffixForSize, (row_block_size,
191                                                 e_block_size,
192                                                 f_block_size)))
193
194
195def Specialize():
196  """
197  Generate specialization code and the conditionals to instantiate it.
198  """
199  f = open("partitioned_matrix_view.cc", "w")
200  f.write(HEADER)
201  f.write(FACTORY_FILE_HEADER)
202
203  for row_block_size, e_block_size, f_block_size in SPECIALIZATIONS:
204    output = SpecializationFilename("generated/partitioned_matrix_view",
205                                    row_block_size,
206                                    e_block_size,
207                                    f_block_size) + ".cc"
208    fptr = open(output, "w")
209    fptr.write(HEADER)
210
211    template = SPECIALIZATION_FILE
212    if (row_block_size == "Eigen::Dynamic" and
213        e_block_size == "Eigen::Dynamic" and
214        f_block_size == "Eigen::Dynamic"):
215      template = DYNAMIC_FILE
216
217    fptr.write(template % (row_block_size, e_block_size, f_block_size))
218    fptr.close()
219
220    f.write(FACTORY_CONDITIONAL % (row_block_size,
221                                   e_block_size,
222                                   f_block_size,
223                                   row_block_size,
224                                   e_block_size,
225                                   f_block_size))
226  f.write(FACTORY_FOOTER)
227  f.close()
228
229
230if __name__ == "__main__":
231  Specialize()
232