Simplify integration tests.

1. Remove SolverConfig, this was a wrapper
   around Solver::Options. As we experiment
   with more Solver::Options, it became a hurdle.

2. Updated generate_bundle_adjustment_tests.py to use
   Solver::Options directly.
3. Update system_test to use Solver::Options.

NOTE: generate_bundle_adjustment_tests.py changes are a bit
gunky, but I tried to minimize the changes in this CL
as I am going to introduce new test cases and that
is going to significantly change this file.

Change-Id: I34a2f51824b04ef368a5bbe54fbd7b281381909e
diff --git a/internal/ceres/generate_bundle_adjustment_tests.py b/internal/ceres/generate_bundle_adjustment_tests.py
index dcac22a..b36cf66 100644
--- a/internal/ceres/generate_bundle_adjustment_tests.py
+++ b/internal/ceres/generate_bundle_adjustment_tests.py
@@ -37,7 +37,9 @@
 # Product of ORDERINGS, THREAD_CONFIGS, and SOLVER_CONFIGS is the full set of
 # tests to generate.
 ORDERINGS = ["kAutomaticOrdering", "kUserOrdering"]
-THREAD_CONFIGS = ["SolverConfig", "ThreadedSolverConfig"]
+SINGLE_THREADED = "1"
+MULTI_THREADED = "4"
+THREAD_CONFIGS = [SINGLE_THREADED, MULTI_THREADED]
 
 SOLVER_CONFIGS = [
   # Linear solver            Sparse backend      Preconditioner
@@ -70,8 +72,6 @@
   CLUSTER_TRIDIAGONAL='clusttri',
   kAutomaticOrdering='auto',
   kUserOrdering='user',
-  SolverConfig='',  # Omit references to threads for single threaded tests.
-  ThreadedSolverConfig='threads',
 )
 
 COPYRIGHT_HEADER = (
@@ -121,12 +121,15 @@
 
 TEST_F(BundleAdjustmentTest,
        %(test_class_name)s) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      %(thread_config)s(
-          %(linear_solver)s,
-          %(sparse_backend)s,
-          %(ordering)s,
-          %(preconditioner)s));
+   Solver::Options options = *BundleAdjustmentProblem().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();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
@@ -134,7 +137,6 @@
 %(preprocessor_conditions_end)s
 """)
 
-
 def camelcasify(token):
   """Convert capitalized underscore tokens to camel case"""
   return ''.join([x.lower().capitalize() for x in token.split('_')])
@@ -163,7 +165,7 @@
       camelcasify(sparse_backend_tag),
       camelcasify(preconditioner_tag),
       ordering[1:],  # Strip 'k'
-      'Threads' if thread_config == 'ThreadedSolverConfig' else '']))
+      'Threads' if thread_config == MULTI_THREADED else '']))
 
   # Initial template parameters (augmented more below).
   template_parameters = dict(
@@ -171,7 +173,7 @@
           sparse_backend=sparse_backend,
           preconditioner=preconditioner,
           ordering=ordering,
-          thread_config=thread_config,
+          num_threads=thread_config,
           test_class_name=test_class_name)
 
   # Accumulate appropriate #ifdef/#ifndefs for the solver's sparse backend.
@@ -188,7 +190,7 @@
     preprocessor_conditions_end.insert(0, '#endif  // CERES_USE_EIGEN_SPARSE')
 
   # Accumulate appropriate #ifdef/#ifndefs for threading conditions.
-  if thread_config == 'ThreadedSolverConfig':
+  if thread_config == MULTI_THREADED:
     preprocessor_conditions_begin.append('#ifndef CERES_NO_THREADS')
     preprocessor_conditions_end.insert(0, '#endif  // CERES_NO_THREADS')
 
@@ -210,11 +212,13 @@
       linear_solver,
       sparse_backend_tag,
       preconditioner_tag,
-      ordering,
-      thread_config]
+      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())
+                filename_tag.lower())
   with open(filename, 'w') as fd:
     fd.write(BUNDLE_ADJUSTMENT_TEST_TEMPLATE % template_parameters)
 
@@ -245,4 +249,3 @@
     for generated_file in generated_files:
       fd.write('ceres_test(%s)\n' %
                generated_file.split('/')[1].replace('_test.cc', ''))
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_auto_test.cc
index 6c815da..2d3ea81 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_auto_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_auto_test.cc
@@ -42,12 +42,15 @@
 
 TEST_F(BundleAdjustmentTest,
        DenseSchur_AutomaticOrdering) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      SolverConfig(
-          DENSE_SCHUR,
-          NO_SPARSE,
-          kAutomaticOrdering,
-          IDENTITY));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 1;
+   options.linear_solver_type = DENSE_SCHUR;
+   options.sparse_linear_algebra_library_type = NO_SPARSE;
+   options.preconditioner_type = IDENTITY;
+   if (kAutomaticOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_auto_threads_test.cc
index 62032fe..311bceb 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_auto_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_auto_threads_test.cc
@@ -44,12 +44,15 @@
 
 TEST_F(BundleAdjustmentTest,
        DenseSchur_AutomaticOrdering_Threads) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      ThreadedSolverConfig(
-          DENSE_SCHUR,
-          NO_SPARSE,
-          kAutomaticOrdering,
-          IDENTITY));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 4;
+   options.linear_solver_type = DENSE_SCHUR;
+   options.sparse_linear_algebra_library_type = NO_SPARSE;
+   options.preconditioner_type = IDENTITY;
+   if (kAutomaticOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_user_test.cc
index 52e85f2..930f5f0 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_user_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_user_test.cc
@@ -42,12 +42,15 @@
 
 TEST_F(BundleAdjustmentTest,
        DenseSchur_UserOrdering) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      SolverConfig(
-          DENSE_SCHUR,
-          NO_SPARSE,
-          kUserOrdering,
-          IDENTITY));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 1;
+   options.linear_solver_type = DENSE_SCHUR;
+   options.sparse_linear_algebra_library_type = NO_SPARSE;
+   options.preconditioner_type = IDENTITY;
+   if (kUserOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_user_threads_test.cc
index 5b58564..cf8139a 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_user_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_user_threads_test.cc
@@ -44,12 +44,15 @@
 
 TEST_F(BundleAdjustmentTest,
        DenseSchur_UserOrdering_Threads) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      ThreadedSolverConfig(
-          DENSE_SCHUR,
-          NO_SPARSE,
-          kUserOrdering,
-          IDENTITY));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 4;
+   options.linear_solver_type = DENSE_SCHUR;
+   options.sparse_linear_algebra_library_type = NO_SPARSE;
+   options.preconditioner_type = IDENTITY;
+   if (kUserOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_auto_test.cc
index 2e85333..8c3b886 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_auto_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_auto_test.cc
@@ -42,12 +42,15 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_Jacobi_AutomaticOrdering) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      SolverConfig(
-          ITERATIVE_SCHUR,
-          NO_SPARSE,
-          kAutomaticOrdering,
-          JACOBI));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 1;
+   options.linear_solver_type = ITERATIVE_SCHUR;
+   options.sparse_linear_algebra_library_type = NO_SPARSE;
+   options.preconditioner_type = JACOBI;
+   if (kAutomaticOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_auto_threads_test.cc
index 3bfd7ba..4585201 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_auto_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_auto_threads_test.cc
@@ -44,12 +44,15 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_Jacobi_AutomaticOrdering_Threads) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      ThreadedSolverConfig(
-          ITERATIVE_SCHUR,
-          NO_SPARSE,
-          kAutomaticOrdering,
-          JACOBI));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 4;
+   options.linear_solver_type = ITERATIVE_SCHUR;
+   options.sparse_linear_algebra_library_type = NO_SPARSE;
+   options.preconditioner_type = JACOBI;
+   if (kAutomaticOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_user_test.cc
index 2a20911..9b864e4 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_user_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_user_test.cc
@@ -42,12 +42,15 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_Jacobi_UserOrdering) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      SolverConfig(
-          ITERATIVE_SCHUR,
-          NO_SPARSE,
-          kUserOrdering,
-          JACOBI));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 1;
+   options.linear_solver_type = ITERATIVE_SCHUR;
+   options.sparse_linear_algebra_library_type = NO_SPARSE;
+   options.preconditioner_type = JACOBI;
+   if (kUserOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_user_threads_test.cc
index 47bbaf5..6266bea 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_user_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_user_threads_test.cc
@@ -44,12 +44,15 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_Jacobi_UserOrdering_Threads) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      ThreadedSolverConfig(
-          ITERATIVE_SCHUR,
-          NO_SPARSE,
-          kUserOrdering,
-          JACOBI));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 4;
+   options.linear_solver_type = ITERATIVE_SCHUR;
+   options.sparse_linear_algebra_library_type = NO_SPARSE;
+   options.preconditioner_type = JACOBI;
+   if (kUserOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_auto_test.cc
index 6f0dcea..bc40f5d 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_auto_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_auto_test.cc
@@ -42,12 +42,15 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_SchurJacobi_AutomaticOrdering) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      SolverConfig(
-          ITERATIVE_SCHUR,
-          NO_SPARSE,
-          kAutomaticOrdering,
-          SCHUR_JACOBI));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 1;
+   options.linear_solver_type = ITERATIVE_SCHUR;
+   options.sparse_linear_algebra_library_type = NO_SPARSE;
+   options.preconditioner_type = SCHUR_JACOBI;
+   if (kAutomaticOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_auto_threads_test.cc
index 987d034..c55fa62 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_auto_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_auto_threads_test.cc
@@ -44,12 +44,15 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_SchurJacobi_AutomaticOrdering_Threads) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      ThreadedSolverConfig(
-          ITERATIVE_SCHUR,
-          NO_SPARSE,
-          kAutomaticOrdering,
-          SCHUR_JACOBI));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 4;
+   options.linear_solver_type = ITERATIVE_SCHUR;
+   options.sparse_linear_algebra_library_type = NO_SPARSE;
+   options.preconditioner_type = SCHUR_JACOBI;
+   if (kAutomaticOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_user_test.cc
index 5f41d6c..cc7f334 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_user_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_user_test.cc
@@ -42,12 +42,15 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_SchurJacobi_UserOrdering) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      SolverConfig(
-          ITERATIVE_SCHUR,
-          NO_SPARSE,
-          kUserOrdering,
-          SCHUR_JACOBI));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 1;
+   options.linear_solver_type = ITERATIVE_SCHUR;
+   options.sparse_linear_algebra_library_type = NO_SPARSE;
+   options.preconditioner_type = SCHUR_JACOBI;
+   if (kUserOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_user_threads_test.cc
index df14114..b8cd166 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_user_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_user_threads_test.cc
@@ -44,12 +44,15 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_SchurJacobi_UserOrdering_Threads) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      ThreadedSolverConfig(
-          ITERATIVE_SCHUR,
-          NO_SPARSE,
-          kUserOrdering,
-          SCHUR_JACOBI));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 4;
+   options.linear_solver_type = ITERATIVE_SCHUR;
+   options.sparse_linear_algebra_library_type = NO_SPARSE;
+   options.preconditioner_type = SCHUR_JACOBI;
+   if (kUserOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_auto_test.cc
index ff064c3..cdb4fd0 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_auto_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_auto_test.cc
@@ -44,12 +44,15 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_SuiteSparse_ClusterJacobi_AutomaticOrdering) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      SolverConfig(
-          ITERATIVE_SCHUR,
-          SUITE_SPARSE,
-          kAutomaticOrdering,
-          CLUSTER_JACOBI));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 1;
+   options.linear_solver_type = ITERATIVE_SCHUR;
+   options.sparse_linear_algebra_library_type = SUITE_SPARSE;
+   options.preconditioner_type = CLUSTER_JACOBI;
+   if (kAutomaticOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_auto_threads_test.cc
index ca6c275..15ed6b1 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_auto_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_auto_threads_test.cc
@@ -45,12 +45,15 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_SuiteSparse_ClusterJacobi_AutomaticOrdering_Threads) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      ThreadedSolverConfig(
-          ITERATIVE_SCHUR,
-          SUITE_SPARSE,
-          kAutomaticOrdering,
-          CLUSTER_JACOBI));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 4;
+   options.linear_solver_type = ITERATIVE_SCHUR;
+   options.sparse_linear_algebra_library_type = SUITE_SPARSE;
+   options.preconditioner_type = CLUSTER_JACOBI;
+   if (kAutomaticOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_user_test.cc
index f425b51..dda9d62 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_user_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_user_test.cc
@@ -44,12 +44,15 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_SuiteSparse_ClusterJacobi_UserOrdering) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      SolverConfig(
-          ITERATIVE_SCHUR,
-          SUITE_SPARSE,
-          kUserOrdering,
-          CLUSTER_JACOBI));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 1;
+   options.linear_solver_type = ITERATIVE_SCHUR;
+   options.sparse_linear_algebra_library_type = SUITE_SPARSE;
+   options.preconditioner_type = CLUSTER_JACOBI;
+   if (kUserOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_user_threads_test.cc
index 0d62b91..6ca9f7b 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_user_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_user_threads_test.cc
@@ -45,12 +45,15 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_SuiteSparse_ClusterJacobi_UserOrdering_Threads) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      ThreadedSolverConfig(
-          ITERATIVE_SCHUR,
-          SUITE_SPARSE,
-          kUserOrdering,
-          CLUSTER_JACOBI));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 4;
+   options.linear_solver_type = ITERATIVE_SCHUR;
+   options.sparse_linear_algebra_library_type = SUITE_SPARSE;
+   options.preconditioner_type = CLUSTER_JACOBI;
+   if (kUserOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_auto_test.cc
index a598cca..6a40ef8 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_auto_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_auto_test.cc
@@ -44,12 +44,15 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_SuiteSparse_ClusterTridiagonal_AutomaticOrdering) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      SolverConfig(
-          ITERATIVE_SCHUR,
-          SUITE_SPARSE,
-          kAutomaticOrdering,
-          CLUSTER_TRIDIAGONAL));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 1;
+   options.linear_solver_type = ITERATIVE_SCHUR;
+   options.sparse_linear_algebra_library_type = SUITE_SPARSE;
+   options.preconditioner_type = CLUSTER_TRIDIAGONAL;
+   if (kAutomaticOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_auto_threads_test.cc
index d296e3b..6bd66bc 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_auto_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_auto_threads_test.cc
@@ -45,12 +45,15 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_SuiteSparse_ClusterTridiagonal_AutomaticOrdering_Threads) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      ThreadedSolverConfig(
-          ITERATIVE_SCHUR,
-          SUITE_SPARSE,
-          kAutomaticOrdering,
-          CLUSTER_TRIDIAGONAL));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 4;
+   options.linear_solver_type = ITERATIVE_SCHUR;
+   options.sparse_linear_algebra_library_type = SUITE_SPARSE;
+   options.preconditioner_type = CLUSTER_TRIDIAGONAL;
+   if (kAutomaticOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_user_test.cc
index 07776c1..ae12ce9 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_user_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_user_test.cc
@@ -44,12 +44,15 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_SuiteSparse_ClusterTridiagonal_UserOrdering) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      SolverConfig(
-          ITERATIVE_SCHUR,
-          SUITE_SPARSE,
-          kUserOrdering,
-          CLUSTER_TRIDIAGONAL));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 1;
+   options.linear_solver_type = ITERATIVE_SCHUR;
+   options.sparse_linear_algebra_library_type = SUITE_SPARSE;
+   options.preconditioner_type = CLUSTER_TRIDIAGONAL;
+   if (kUserOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_user_threads_test.cc
index b428ad7..727d908 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_user_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_user_threads_test.cc
@@ -45,12 +45,15 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_SuiteSparse_ClusterTridiagonal_UserOrdering_Threads) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      ThreadedSolverConfig(
-          ITERATIVE_SCHUR,
-          SUITE_SPARSE,
-          kUserOrdering,
-          CLUSTER_TRIDIAGONAL));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 4;
+   options.linear_solver_type = ITERATIVE_SCHUR;
+   options.sparse_linear_algebra_library_type = SUITE_SPARSE;
+   options.preconditioner_type = CLUSTER_TRIDIAGONAL;
+   if (kUserOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_auto_test.cc
index 0684c65..3d3b642 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_auto_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_auto_test.cc
@@ -44,12 +44,15 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseNormalCholesky_CxSparse_AutomaticOrdering) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      SolverConfig(
-          SPARSE_NORMAL_CHOLESKY,
-          CX_SPARSE,
-          kAutomaticOrdering,
-          IDENTITY));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 1;
+   options.linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+   options.sparse_linear_algebra_library_type = CX_SPARSE;
+   options.preconditioner_type = IDENTITY;
+   if (kAutomaticOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_auto_threads_test.cc
index e810574..ae7f543 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_auto_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_auto_threads_test.cc
@@ -45,12 +45,15 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseNormalCholesky_CxSparse_AutomaticOrdering_Threads) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      ThreadedSolverConfig(
-          SPARSE_NORMAL_CHOLESKY,
-          CX_SPARSE,
-          kAutomaticOrdering,
-          IDENTITY));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 4;
+   options.linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+   options.sparse_linear_algebra_library_type = CX_SPARSE;
+   options.preconditioner_type = IDENTITY;
+   if (kAutomaticOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_user_test.cc
index 262c913..9f3d752 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_user_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_user_test.cc
@@ -44,12 +44,15 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseNormalCholesky_CxSparse_UserOrdering) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      SolverConfig(
-          SPARSE_NORMAL_CHOLESKY,
-          CX_SPARSE,
-          kUserOrdering,
-          IDENTITY));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 1;
+   options.linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+   options.sparse_linear_algebra_library_type = CX_SPARSE;
+   options.preconditioner_type = IDENTITY;
+   if (kUserOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_user_threads_test.cc
index 9ad0f20..366169c 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_user_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_user_threads_test.cc
@@ -45,12 +45,15 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseNormalCholesky_CxSparse_UserOrdering_Threads) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      ThreadedSolverConfig(
-          SPARSE_NORMAL_CHOLESKY,
-          CX_SPARSE,
-          kUserOrdering,
-          IDENTITY));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 4;
+   options.linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+   options.sparse_linear_algebra_library_type = CX_SPARSE;
+   options.preconditioner_type = IDENTITY;
+   if (kUserOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_auto_test.cc
index 63713fd..700bb50 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_auto_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_auto_test.cc
@@ -44,12 +44,15 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseNormalCholesky_EigenSparse_AutomaticOrdering) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      SolverConfig(
-          SPARSE_NORMAL_CHOLESKY,
-          EIGEN_SPARSE,
-          kAutomaticOrdering,
-          IDENTITY));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 1;
+   options.linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+   options.sparse_linear_algebra_library_type = EIGEN_SPARSE;
+   options.preconditioner_type = IDENTITY;
+   if (kAutomaticOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_auto_threads_test.cc
index 02e9c74..e363297 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_auto_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_auto_threads_test.cc
@@ -45,12 +45,15 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseNormalCholesky_EigenSparse_AutomaticOrdering_Threads) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      ThreadedSolverConfig(
-          SPARSE_NORMAL_CHOLESKY,
-          EIGEN_SPARSE,
-          kAutomaticOrdering,
-          IDENTITY));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 4;
+   options.linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+   options.sparse_linear_algebra_library_type = EIGEN_SPARSE;
+   options.preconditioner_type = IDENTITY;
+   if (kAutomaticOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_user_test.cc
index 3717c44..dd423f3 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_user_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_user_test.cc
@@ -44,12 +44,15 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseNormalCholesky_EigenSparse_UserOrdering) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      SolverConfig(
-          SPARSE_NORMAL_CHOLESKY,
-          EIGEN_SPARSE,
-          kUserOrdering,
-          IDENTITY));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 1;
+   options.linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+   options.sparse_linear_algebra_library_type = EIGEN_SPARSE;
+   options.preconditioner_type = IDENTITY;
+   if (kUserOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_user_threads_test.cc
index 5f99a33..27dc821 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_user_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_user_threads_test.cc
@@ -45,12 +45,15 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseNormalCholesky_EigenSparse_UserOrdering_Threads) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      ThreadedSolverConfig(
-          SPARSE_NORMAL_CHOLESKY,
-          EIGEN_SPARSE,
-          kUserOrdering,
-          IDENTITY));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 4;
+   options.linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+   options.sparse_linear_algebra_library_type = EIGEN_SPARSE;
+   options.preconditioner_type = IDENTITY;
+   if (kUserOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_auto_test.cc
index fa20b68..7155bd9 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_auto_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_auto_test.cc
@@ -44,12 +44,15 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseNormalCholesky_SuiteSparse_AutomaticOrdering) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      SolverConfig(
-          SPARSE_NORMAL_CHOLESKY,
-          SUITE_SPARSE,
-          kAutomaticOrdering,
-          IDENTITY));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 1;
+   options.linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+   options.sparse_linear_algebra_library_type = SUITE_SPARSE;
+   options.preconditioner_type = IDENTITY;
+   if (kAutomaticOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_auto_threads_test.cc
index 6963483..8991cca 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_auto_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_auto_threads_test.cc
@@ -45,12 +45,15 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseNormalCholesky_SuiteSparse_AutomaticOrdering_Threads) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      ThreadedSolverConfig(
-          SPARSE_NORMAL_CHOLESKY,
-          SUITE_SPARSE,
-          kAutomaticOrdering,
-          IDENTITY));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 4;
+   options.linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+   options.sparse_linear_algebra_library_type = SUITE_SPARSE;
+   options.preconditioner_type = IDENTITY;
+   if (kAutomaticOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_user_test.cc
index ab8615f..e4375c1 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_user_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_user_test.cc
@@ -44,12 +44,15 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseNormalCholesky_SuiteSparse_UserOrdering) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      SolverConfig(
-          SPARSE_NORMAL_CHOLESKY,
-          SUITE_SPARSE,
-          kUserOrdering,
-          IDENTITY));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 1;
+   options.linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+   options.sparse_linear_algebra_library_type = SUITE_SPARSE;
+   options.preconditioner_type = IDENTITY;
+   if (kUserOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_user_threads_test.cc
index 4833dbd..3c91c72 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_user_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_user_threads_test.cc
@@ -45,12 +45,15 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseNormalCholesky_SuiteSparse_UserOrdering_Threads) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      ThreadedSolverConfig(
-          SPARSE_NORMAL_CHOLESKY,
-          SUITE_SPARSE,
-          kUserOrdering,
-          IDENTITY));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 4;
+   options.linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+   options.sparse_linear_algebra_library_type = SUITE_SPARSE;
+   options.preconditioner_type = IDENTITY;
+   if (kUserOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_auto_test.cc
index 0318f95..d9b10e4 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_auto_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_auto_test.cc
@@ -44,12 +44,15 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseSchur_CxSparse_AutomaticOrdering) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      SolverConfig(
-          SPARSE_SCHUR,
-          CX_SPARSE,
-          kAutomaticOrdering,
-          IDENTITY));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 1;
+   options.linear_solver_type = SPARSE_SCHUR;
+   options.sparse_linear_algebra_library_type = CX_SPARSE;
+   options.preconditioner_type = IDENTITY;
+   if (kAutomaticOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_auto_threads_test.cc
index e8657bb..f7dbc45 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_auto_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_auto_threads_test.cc
@@ -45,12 +45,15 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseSchur_CxSparse_AutomaticOrdering_Threads) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      ThreadedSolverConfig(
-          SPARSE_SCHUR,
-          CX_SPARSE,
-          kAutomaticOrdering,
-          IDENTITY));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 4;
+   options.linear_solver_type = SPARSE_SCHUR;
+   options.sparse_linear_algebra_library_type = CX_SPARSE;
+   options.preconditioner_type = IDENTITY;
+   if (kAutomaticOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_user_test.cc
index 40943b3..27a673d 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_user_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_user_test.cc
@@ -44,12 +44,15 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseSchur_CxSparse_UserOrdering) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      SolverConfig(
-          SPARSE_SCHUR,
-          CX_SPARSE,
-          kUserOrdering,
-          IDENTITY));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 1;
+   options.linear_solver_type = SPARSE_SCHUR;
+   options.sparse_linear_algebra_library_type = CX_SPARSE;
+   options.preconditioner_type = IDENTITY;
+   if (kUserOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_user_threads_test.cc
index b95c13e..9e5db38 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_user_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_user_threads_test.cc
@@ -45,12 +45,15 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseSchur_CxSparse_UserOrdering_Threads) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      ThreadedSolverConfig(
-          SPARSE_SCHUR,
-          CX_SPARSE,
-          kUserOrdering,
-          IDENTITY));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 4;
+   options.linear_solver_type = SPARSE_SCHUR;
+   options.sparse_linear_algebra_library_type = CX_SPARSE;
+   options.preconditioner_type = IDENTITY;
+   if (kUserOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_auto_test.cc
index 74b9fe0..bc8d66b 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_auto_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_auto_test.cc
@@ -44,12 +44,15 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseSchur_EigenSparse_AutomaticOrdering) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      SolverConfig(
-          SPARSE_SCHUR,
-          EIGEN_SPARSE,
-          kAutomaticOrdering,
-          IDENTITY));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 1;
+   options.linear_solver_type = SPARSE_SCHUR;
+   options.sparse_linear_algebra_library_type = EIGEN_SPARSE;
+   options.preconditioner_type = IDENTITY;
+   if (kAutomaticOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_auto_threads_test.cc
index 8f6279c..6910d87 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_auto_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_auto_threads_test.cc
@@ -45,12 +45,15 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseSchur_EigenSparse_AutomaticOrdering_Threads) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      ThreadedSolverConfig(
-          SPARSE_SCHUR,
-          EIGEN_SPARSE,
-          kAutomaticOrdering,
-          IDENTITY));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 4;
+   options.linear_solver_type = SPARSE_SCHUR;
+   options.sparse_linear_algebra_library_type = EIGEN_SPARSE;
+   options.preconditioner_type = IDENTITY;
+   if (kAutomaticOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_user_test.cc
index 3643e3d..d626481 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_user_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_user_test.cc
@@ -44,12 +44,15 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseSchur_EigenSparse_UserOrdering) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      SolverConfig(
-          SPARSE_SCHUR,
-          EIGEN_SPARSE,
-          kUserOrdering,
-          IDENTITY));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 1;
+   options.linear_solver_type = SPARSE_SCHUR;
+   options.sparse_linear_algebra_library_type = EIGEN_SPARSE;
+   options.preconditioner_type = IDENTITY;
+   if (kUserOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_user_threads_test.cc
index 8ae2343..218c35f 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_user_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_user_threads_test.cc
@@ -45,12 +45,15 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseSchur_EigenSparse_UserOrdering_Threads) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      ThreadedSolverConfig(
-          SPARSE_SCHUR,
-          EIGEN_SPARSE,
-          kUserOrdering,
-          IDENTITY));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 4;
+   options.linear_solver_type = SPARSE_SCHUR;
+   options.sparse_linear_algebra_library_type = EIGEN_SPARSE;
+   options.preconditioner_type = IDENTITY;
+   if (kUserOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_auto_test.cc
index 739c927..67fff21 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_auto_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_auto_test.cc
@@ -44,12 +44,15 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseSchur_SuiteSparse_AutomaticOrdering) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      SolverConfig(
-          SPARSE_SCHUR,
-          SUITE_SPARSE,
-          kAutomaticOrdering,
-          IDENTITY));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 1;
+   options.linear_solver_type = SPARSE_SCHUR;
+   options.sparse_linear_algebra_library_type = SUITE_SPARSE;
+   options.preconditioner_type = IDENTITY;
+   if (kAutomaticOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_auto_threads_test.cc
index 3935811..f0dccb7 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_auto_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_auto_threads_test.cc
@@ -45,12 +45,15 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseSchur_SuiteSparse_AutomaticOrdering_Threads) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      ThreadedSolverConfig(
-          SPARSE_SCHUR,
-          SUITE_SPARSE,
-          kAutomaticOrdering,
-          IDENTITY));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 4;
+   options.linear_solver_type = SPARSE_SCHUR;
+   options.sparse_linear_algebra_library_type = SUITE_SPARSE;
+   options.preconditioner_type = IDENTITY;
+   if (kAutomaticOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_user_test.cc
index 28f9fa1..eb67b49 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_user_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_user_test.cc
@@ -44,12 +44,15 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseSchur_SuiteSparse_UserOrdering) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      SolverConfig(
-          SPARSE_SCHUR,
-          SUITE_SPARSE,
-          kUserOrdering,
-          IDENTITY));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 1;
+   options.linear_solver_type = SPARSE_SCHUR;
+   options.sparse_linear_algebra_library_type = SUITE_SPARSE;
+   options.preconditioner_type = IDENTITY;
+   if (kUserOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_user_threads_test.cc
index 1334ff7..c13cc4f 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_user_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_user_threads_test.cc
@@ -45,12 +45,15 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseSchur_SuiteSparse_UserOrdering_Threads) {  // NOLINT
-  RunSolverForConfigAndExpectResidualsMatch(
-      ThreadedSolverConfig(
-          SPARSE_SCHUR,
-          SUITE_SPARSE,
-          kUserOrdering,
-          IDENTITY));
+   Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
+   options.num_threads = 4;
+   options.linear_solver_type = SPARSE_SCHUR;
+   options.sparse_linear_algebra_library_type = SUITE_SPARSE;
+   options.preconditioner_type = IDENTITY;
+   if (kUserOrdering) {
+    options.linear_solver_ordering.reset();
+   }
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/system_test.cc b/internal/ceres/system_test.cc
index 7f26a98..5fb520f 100644
--- a/internal/ceres/system_test.cc
+++ b/internal/ceres/system_test.cc
@@ -144,46 +144,57 @@
 double PowellsFunction::kResidualTolerance = 1e-8;
 
 typedef SystemTest<PowellsFunction> PowellTest;
-const bool kAutomaticOrdering = true;
 
 TEST_F(PowellTest, DenseQR) {
-  RunSolverForConfigAndExpectResidualsMatch(
-      SolverConfig(DENSE_QR, NO_SPARSE));
+  Solver::Options options = *PowellsFunction().mutable_solver_options();
+  options.linear_solver_type = DENSE_QR;
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 TEST_F(PowellTest, DenseNormalCholesky) {
-  RunSolverForConfigAndExpectResidualsMatch(
-      SolverConfig(DENSE_NORMAL_CHOLESKY));
+  Solver::Options options = *PowellsFunction().mutable_solver_options();
+  options.linear_solver_type = DENSE_NORMAL_CHOLESKY;
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 TEST_F(PowellTest, DenseSchur) {
-  RunSolverForConfigAndExpectResidualsMatch(
-      SolverConfig(DENSE_SCHUR));
+  Solver::Options options = *PowellsFunction().mutable_solver_options();
+  options.linear_solver_type = DENSE_SCHUR;
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 TEST_F(PowellTest, IterativeSchurWithJacobi) {
-  RunSolverForConfigAndExpectResidualsMatch(
-      SolverConfig(ITERATIVE_SCHUR, NO_SPARSE, kAutomaticOrdering, JACOBI));
+  Solver::Options options = *PowellsFunction().mutable_solver_options();
+  options.linear_solver_type = ITERATIVE_SCHUR;
+  options.sparse_linear_algebra_library_type = NO_SPARSE;
+  options.preconditioner_type = JACOBI;
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 
 #ifndef CERES_NO_SUITESPARSE
 TEST_F(PowellTest, SparseNormalCholeskyUsingSuiteSparse) {
-  RunSolverForConfigAndExpectResidualsMatch(
-      SolverConfig(SPARSE_NORMAL_CHOLESKY, SUITE_SPARSE, kAutomaticOrdering));
+  Solver::Options options = *PowellsFunction().mutable_solver_options();
+  options.linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+  options.sparse_linear_algebra_library_type = SUITE_SPARSE;
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 #endif  // CERES_NO_SUITESPARSE
 
 #ifndef CERES_NO_CXSPARSE
 TEST_F(PowellTest, SparseNormalCholeskyUsingCXSparse) {
-  RunSolverForConfigAndExpectResidualsMatch(
-      SolverConfig(SPARSE_NORMAL_CHOLESKY, CX_SPARSE, kAutomaticOrdering));
+  Solver::Options options = *PowellsFunction().mutable_solver_options();
+  options.linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+  options.sparse_linear_algebra_library_type = CX_SPARSE;
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 #endif  // CERES_NO_CXSPARSE
 
 #ifdef CERES_USE_EIGEN_SPARSE
 TEST_F(PowellTest, SparseNormalCholeskyUsingEigenSparse) {
-  RunSolverForConfigAndExpectResidualsMatch(
-      SolverConfig(SPARSE_NORMAL_CHOLESKY, EIGEN_SPARSE, kAutomaticOrdering));
+  Solver::Options options = *PowellsFunction().mutable_solver_options();
+  options.linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+  options.sparse_linear_algebra_library_type = EIGEN_SPARSE;
+  RunSolverForConfigAndExpectResidualsMatch(options);
 }
 #endif  // CERES_USE_EIGEN_SPARSE
 
diff --git a/internal/ceres/test_util.cc b/internal/ceres/test_util.cc
index 3866eb5..5156856 100644
--- a/internal/ceres/test_util.cc
+++ b/internal/ceres/test_util.cc
@@ -129,17 +129,15 @@
                   filename);
 }
 
-SolverConfig ThreadedSolverConfig(
-    LinearSolverType linear_solver_type,
-    SparseLinearAlgebraLibraryType sparse_linear_algebra_library_type,
-    bool use_automatic_ordering,
-    PreconditionerType preconditioner_type) {
-  const int kNumThreads = 4;
-  return SolverConfig(linear_solver_type,
-                      sparse_linear_algebra_library_type,
-                      use_automatic_ordering,
-                      preconditioner_type,
-                      kNumThreads);
+std::string ToString(const Solver::Options& options) {
+  return StringPrintf(
+      "(%s, %s, %s, %s, %d)",
+      LinearSolverTypeToString(options.linear_solver_type),
+      SparseLinearAlgebraLibraryTypeToString(
+          options.sparse_linear_algebra_library_type),
+      options.linear_solver_ordering? "USER": "AUTOMATIC",
+      PreconditionerTypeToString(options.preconditioner_type),
+      options.num_threads);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/test_util.h b/internal/ceres/test_util.h
index f8bfa3a..c4c17d5 100644
--- a/internal/ceres/test_util.h
+++ b/internal/ceres/test_util.h
@@ -69,57 +69,7 @@
 // local build/testing environment.
 std::string TestFileAbsolutePath(const std::string& filename);
 
-// Struct used for configuring the solver. Used by end-to-end tests.
-struct SolverConfig {
-  SolverConfig(
-      LinearSolverType linear_solver_type,
-      SparseLinearAlgebraLibraryType
-      sparse_linear_algebra_library_type = NO_SPARSE,
-      bool use_automatic_ordering = true,
-      PreconditionerType preconditioner_type = IDENTITY,
-      int num_threads = 1)
-      : linear_solver_type(linear_solver_type),
-        sparse_linear_algebra_library_type(sparse_linear_algebra_library_type),
-        use_automatic_ordering(use_automatic_ordering),
-        preconditioner_type(preconditioner_type),
-        num_threads(num_threads) {
-  }
-
-  std::string ToString() const {
-    return StringPrintf(
-        "(%s, %s, %s, %s, %d)",
-        LinearSolverTypeToString(linear_solver_type),
-        SparseLinearAlgebraLibraryTypeToString(
-            sparse_linear_algebra_library_type),
-        use_automatic_ordering ? "AUTOMATIC" : "USER",
-        PreconditionerTypeToString(preconditioner_type),
-        num_threads);
-  }
-
-  void UpdateOptions(Solver::Options* options) const {
-    options->linear_solver_type = linear_solver_type;
-    options->sparse_linear_algebra_library_type =
-        sparse_linear_algebra_library_type;
-    options->preconditioner_type = preconditioner_type;
-    options->num_threads = num_threads;
-    if (use_automatic_ordering) {
-      options->linear_solver_ordering.reset();
-    }
-  }
-
-  LinearSolverType linear_solver_type;
-  SparseLinearAlgebraLibraryType sparse_linear_algebra_library_type;
-  bool use_automatic_ordering;
-  PreconditionerType preconditioner_type;
-  int num_threads;
-};
-
-SolverConfig ThreadedSolverConfig(
-    LinearSolverType linear_solver_type,
-    SparseLinearAlgebraLibraryType
-    sparse_linear_algebra_library_type = NO_SPARSE,
-    bool use_automatic_ordering = true,
-    PreconditionerType preconditioner_type = IDENTITY);
+std::string ToString(const Solver::Options& options);
 
 // A templated test fixture, that is used for testing Ceres end to end
 // by computing a solution to the problem for a given solver
@@ -127,7 +77,7 @@
 //
 // It is assumed that the SystemTestProblem has an Solver::Options
 // struct that contains the reference Solver configuration.
-template <class SystemTestProblem>
+template <typename SystemTestProblem>
 class SystemTest : public::testing::Test {
  protected:
   virtual void SetUp() {
@@ -138,15 +88,13 @@
         &expected_final_residuals_);
   }
 
-  void RunSolverForConfigAndExpectResidualsMatch(const SolverConfig& config) {
+  void RunSolverForConfigAndExpectResidualsMatch(const Solver::Options& options) {
     LOG(INFO) << "Running solver configuration: "
-              << config.ToString();
-
+              << ToString(options);
     SystemTestProblem system_test_problem;
-    config.UpdateOptions(system_test_problem.mutable_solver_options());
     std::vector<double> final_residuals;
     SolveAndEvaluateFinalResiduals(
-        *system_test_problem.mutable_solver_options(),
+        options,
         system_test_problem.mutable_problem(),
         &final_residuals);