1 # Ceres Solver - A fast non-linear least squares minimizer
2 # Copyright 2015 Google Inc. All rights reserved.
3 # http://ceres-solver.org/
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are met:
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.
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.
29 # Author: sameeragarwal@google.com (Sameer Agarwal)
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.
38 # This script creates three sets of files.
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
43 # 2. schur_eliminator.cc & partitioned_matrix_view.cc
45 # that contains a factory function for instantiating these classes
46 # based on runtime parameters.
48 # 3. schur_templates.cc
50 # that contains a function which can be queried to determine what
51 # template specializations are available.
53 # The following list of tuples, specializations indicates the set of
54 # specializations that is generated.
55 SPECIALIZATIONS = [(2, 2, 2),
58 (2, 2, "Eigen::Dynamic"),
63 (2, 3, "Eigen::Dynamic"),
68 (2, 4, "Eigen::Dynamic"),
69 (2, "Eigen::Dynamic", "Eigen::Dynamic"),
73 (4, 4, "Eigen::Dynamic")]
75 import schur_eliminator_template
76 import partitioned_matrix_view_template
80 def SuffixForSize(size):
81 if size == "Eigen::Dynamic":
85 def SpecializationFilename(prefix, row_block_size, e_block_size, f_block_size):
86 return "_".join([prefix] + map(SuffixForSize, (row_block_size,
90 def GenerateFactoryConditional(row_block_size, e_block_size, f_block_size):
92 if (row_block_size != "Eigen::Dynamic"):
93 conditionals.append("(options.row_block_size == %s)" % row_block_size)
94 if (e_block_size != "Eigen::Dynamic"):
95 conditionals.append("(options.e_block_size == %s)" % e_block_size)
96 if (f_block_size != "Eigen::Dynamic"):
97 conditionals.append("(options.f_block_size == %s)" % f_block_size)
98 if (len(conditionals) == 0):
101 if (len(conditionals) == 1):
102 return " if " + conditionals[0] + "{\n %s\n }\n"
104 return " if (" + " &&\n ".join(conditionals) + ") {\n %s\n }\n"
106 def Specialize(name, data):
108 Generate specialization code and the conditionals to instantiate it.
111 # Specialization files
112 for row_block_size, e_block_size, f_block_size in SPECIALIZATIONS:
113 output = SpecializationFilename("generated/" + name,
116 f_block_size) + ".cc"
118 with open(output, "w") as f:
119 f.write(data["HEADER"])
120 f.write(data["SPECIALIZATION_FILE"] %
121 (row_block_size, e_block_size, f_block_size))
123 # Generate the _d_d_d specialization.
124 output = SpecializationFilename("generated/" + name,
127 "Eigen::Dynamic") + ".cc"
128 with open(output, "w") as f:
129 f.write(data["HEADER"])
130 f.write(data["DYNAMIC_FILE"] %
131 ("Eigen::Dynamic", "Eigen::Dynamic", "Eigen::Dynamic"))
134 with open(name + ".cc", "w") as f:
135 f.write(data["HEADER"])
136 f.write(data["FACTORY_FILE_HEADER"])
137 for row_block_size, e_block_size, f_block_size in SPECIALIZATIONS:
138 factory_conditional = GenerateFactoryConditional(
139 row_block_size, e_block_size, f_block_size)
140 factory = data["FACTORY"] % (row_block_size, e_block_size, f_block_size)
141 f.write(factory_conditional % factory);
142 f.write(data["FACTORY_FOOTER"])
144 QUERY_HEADER = """// Ceres Solver - A fast non-linear least squares minimizer
145 // Copyright 2017 Google Inc. All rights reserved.
146 // http://ceres-solver.org/
148 // Redistribution and use in source and binary forms, with or without
149 // modification, are permitted provided that the following conditions are met:
151 // * Redistributions of source code must retain the above copyright notice,
152 // this list of conditions and the following disclaimer.
153 // * Redistributions in binary form must reproduce the above copyright notice,
154 // this list of conditions and the following disclaimer in the documentation
155 // and/or other materials provided with the distribution.
156 // * Neither the name of Google Inc. nor the names of its contributors may be
157 // used to endorse or promote products derived from this software without
158 // specific prior written permission.
160 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
161 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
162 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
163 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
164 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
165 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
166 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
167 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
168 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
169 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
170 // POSSIBILITY OF SUCH DAMAGE.
172 // Author: sameeragarwal@google.com (Sameer Agarwal)
174 // What template specializations are available.
176 // ========================================
177 // THIS FILE IS AUTOGENERATED. DO NOT EDIT.
178 // THIS FILE IS AUTOGENERATED. DO NOT EDIT.
179 // THIS FILE IS AUTOGENERATED. DO NOT EDIT.
180 // THIS FILE IS AUTOGENERATED. DO NOT EDIT.
181 //=========================================
183 // This file is generated using generate_template_specializations.py.
186 QUERY_FILE_HEADER = """
187 #include "ceres/internal/eigen.h"
188 #include "ceres/schur_templates.h"
193 void GetBestSchurTemplateSpecialization(int* row_block_size,
196 LinearSolver::Options options;
197 options.row_block_size = *row_block_size;
198 options.e_block_size = *e_block_size;
199 options.f_block_size = *f_block_size;
200 *row_block_size = Eigen::Dynamic;
201 *e_block_size = Eigen::Dynamic;
202 *f_block_size = Eigen::Dynamic;
203 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
211 } // namespace internal
215 QUERY_ACTION = """ *row_block_size = %s;
220 def GenerateQueryFile():
222 Generate file that allows querying for available template specializations.
225 with open("schur_templates.cc", "w") as f:
226 f.write(QUERY_HEADER)
227 f.write(QUERY_FILE_HEADER)
228 for row_block_size, e_block_size, f_block_size in SPECIALIZATIONS:
229 factory_conditional = GenerateFactoryConditional(
230 row_block_size, e_block_size, f_block_size)
231 action = QUERY_ACTION % (row_block_size, e_block_size, f_block_size)
232 f.write(factory_conditional % action)
233 f.write(QUERY_FOOTER)
236 if __name__ == "__main__":
237 for f in glob.glob("generated/*"):
240 Specialize("schur_eliminator",
241 schur_eliminator_template.__dict__)
242 Specialize("partitioned_matrix_view",
243 partitioned_matrix_view_template.__dict__)