blob: 74e46c28b78a37650b3714f5b9cf16e62e0f432b [file] [log] [blame]
Austin Schuh70cc9552019-01-21 19:46:48 -08001# Ceres Solver - A fast non-linear least squares minimizer
2# Copyright 2015 Google Inc. All rights reserved.
3# http://ceres-solver.org/
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# SchurEliminator class. It is a rather large class
33# and the number of explicit instantiations is also large. Explicitly
34# generating these instantiations in separate .cc files breaks the
35# compilation into separate compilation unit rather than one large cc
36# file which takes 2+GB of RAM to compile.
37#
38# This script creates three sets of files.
39#
40# 1. schur_eliminator_x_x_x.cc and partitioned_matrix_view_x_x_x.cc
41# where, the x indicates the template parameters and
42#
43# 2. schur_eliminator.cc & partitioned_matrix_view.cc
44#
45# that contains a factory function for instantiating these classes
46# based on runtime parameters.
47#
48# 3. schur_templates.cc
49#
50# that contains a function which can be queried to determine what
51# template specializations are available.
52#
53# The following list of tuples, specializations indicates the set of
54# specializations that is generated.
55SPECIALIZATIONS = [(2, 2, 2),
56 (2, 2, 3),
57 (2, 2, 4),
58 (2, 2, "Eigen::Dynamic"),
59 (2, 3, 3),
60 (2, 3, 4),
61 (2, 3, 6),
62 (2, 3, 9),
63 (2, 3, "Eigen::Dynamic"),
64 (2, 4, 3),
65 (2, 4, 4),
66 (2, 4, 6),
67 (2, 4, 8),
68 (2, 4, 9),
69 (2, 4, "Eigen::Dynamic"),
70 (2, "Eigen::Dynamic", "Eigen::Dynamic"),
Austin Schuh1d1e6ea2020-12-23 21:56:30 -080071 (3, 3, 3),
Austin Schuh70cc9552019-01-21 19:46:48 -080072 (4, 4, 2),
73 (4, 4, 3),
74 (4, 4, 4),
75 (4, 4, "Eigen::Dynamic")]
76
77import schur_eliminator_template
78import partitioned_matrix_view_template
79import os
80import glob
81
82def SuffixForSize(size):
83 if size == "Eigen::Dynamic":
84 return "d"
85 return str(size)
86
87def SpecializationFilename(prefix, row_block_size, e_block_size, f_block_size):
88 return "_".join([prefix] + map(SuffixForSize, (row_block_size,
89 e_block_size,
90 f_block_size)))
91
92def GenerateFactoryConditional(row_block_size, e_block_size, f_block_size):
93 conditionals = []
94 if (row_block_size != "Eigen::Dynamic"):
95 conditionals.append("(options.row_block_size == %s)" % row_block_size)
96 if (e_block_size != "Eigen::Dynamic"):
97 conditionals.append("(options.e_block_size == %s)" % e_block_size)
98 if (f_block_size != "Eigen::Dynamic"):
99 conditionals.append("(options.f_block_size == %s)" % f_block_size)
100 if (len(conditionals) == 0):
101 return "%s"
102
103 if (len(conditionals) == 1):
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800104 return " if " + conditionals[0] + " {\n %s\n }\n"
Austin Schuh70cc9552019-01-21 19:46:48 -0800105
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800106 return " if (" + " &&\n ".join(conditionals) + ") {\n %s\n }\n"
Austin Schuh70cc9552019-01-21 19:46:48 -0800107
108def Specialize(name, data):
109 """
110 Generate specialization code and the conditionals to instantiate it.
111 """
112
113 # Specialization files
114 for row_block_size, e_block_size, f_block_size in SPECIALIZATIONS:
115 output = SpecializationFilename("generated/" + name,
116 row_block_size,
117 e_block_size,
118 f_block_size) + ".cc"
119
120 with open(output, "w") as f:
121 f.write(data["HEADER"])
122 f.write(data["SPECIALIZATION_FILE"] %
123 (row_block_size, e_block_size, f_block_size))
124
125 # Generate the _d_d_d specialization.
126 output = SpecializationFilename("generated/" + name,
127 "Eigen::Dynamic",
128 "Eigen::Dynamic",
129 "Eigen::Dynamic") + ".cc"
130 with open(output, "w") as f:
131 f.write(data["HEADER"])
132 f.write(data["DYNAMIC_FILE"] %
133 ("Eigen::Dynamic", "Eigen::Dynamic", "Eigen::Dynamic"))
134
135 # Factory
136 with open(name + ".cc", "w") as f:
137 f.write(data["HEADER"])
138 f.write(data["FACTORY_FILE_HEADER"])
139 for row_block_size, e_block_size, f_block_size in SPECIALIZATIONS:
140 factory_conditional = GenerateFactoryConditional(
141 row_block_size, e_block_size, f_block_size)
142 factory = data["FACTORY"] % (row_block_size, e_block_size, f_block_size)
143 f.write(factory_conditional % factory);
144 f.write(data["FACTORY_FOOTER"])
145
146QUERY_HEADER = """// Ceres Solver - A fast non-linear least squares minimizer
147// Copyright 2017 Google Inc. All rights reserved.
148// http://ceres-solver.org/
149//
150// Redistribution and use in source and binary forms, with or without
151// modification, are permitted provided that the following conditions are met:
152//
153// * Redistributions of source code must retain the above copyright notice,
154// this list of conditions and the following disclaimer.
155// * Redistributions in binary form must reproduce the above copyright notice,
156// this list of conditions and the following disclaimer in the documentation
157// and/or other materials provided with the distribution.
158// * Neither the name of Google Inc. nor the names of its contributors may be
159// used to endorse or promote products derived from this software without
160// specific prior written permission.
161//
162// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
163// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
164// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
165// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
166// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
167// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
168// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
169// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
170// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
171// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
172// POSSIBILITY OF SUCH DAMAGE.
173//
174// Author: sameeragarwal@google.com (Sameer Agarwal)
175//
176// What template specializations are available.
177//
178// ========================================
179// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
180// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
181// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
182// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
183//=========================================
184//
185// This file is generated using generate_template_specializations.py.
186"""
187
188QUERY_FILE_HEADER = """
189#include "ceres/internal/eigen.h"
190#include "ceres/schur_templates.h"
191
192namespace ceres {
193namespace internal {
194
195void GetBestSchurTemplateSpecialization(int* row_block_size,
196 int* e_block_size,
197 int* f_block_size) {
198 LinearSolver::Options options;
199 options.row_block_size = *row_block_size;
200 options.e_block_size = *e_block_size;
201 options.f_block_size = *f_block_size;
202 *row_block_size = Eigen::Dynamic;
203 *e_block_size = Eigen::Dynamic;
204 *f_block_size = Eigen::Dynamic;
205#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
206"""
207
208QUERY_FOOTER = """
209#endif
210 return;
211}
212
213} // namespace internal
214} // namespace ceres
215"""
216
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800217QUERY_ACTION = """ *row_block_size = %s;
218 *e_block_size = %s;
219 *f_block_size = %s;
220 return;"""
Austin Schuh70cc9552019-01-21 19:46:48 -0800221
222def GenerateQueryFile():
223 """
224 Generate file that allows querying for available template specializations.
225 """
226
227 with open("schur_templates.cc", "w") as f:
228 f.write(QUERY_HEADER)
229 f.write(QUERY_FILE_HEADER)
230 for row_block_size, e_block_size, f_block_size in SPECIALIZATIONS:
231 factory_conditional = GenerateFactoryConditional(
232 row_block_size, e_block_size, f_block_size)
233 action = QUERY_ACTION % (row_block_size, e_block_size, f_block_size)
234 f.write(factory_conditional % action)
235 f.write(QUERY_FOOTER)
236
237
238if __name__ == "__main__":
239 for f in glob.glob("generated/*"):
240 os.remove(f)
241
242 Specialize("schur_eliminator",
243 schur_eliminator_template.__dict__)
244 Specialize("partitioned_matrix_view",
245 partitioned_matrix_view_template.__dict__)
246 GenerateQueryFile()