Deprecate Solver::Options::num_linear_solver_threads

1. Solver::Options::num_threads now controls parallelism in Ceres
   Solver. The user specified value of
   Solver::Options::num_linear_solver_threads is ignored.
2. If the user specifies Solver::Options::num_linear_solver_threads
   and it is different from Solver::Options::num_threads,
   a warning is printed.
3. Solver::Summary:num_linear_solver_threads_given and
   Solver::Summary::num_linear_solver_threads_used are also
   deprecated and are always set to Solver::Summary::num_threads_given
   and Solver::Summary::num_threads_used.

Change-Id: I20b9336d9336e400e6f0a15b63857c0c43eb271c
diff --git a/docs/source/nnls_solving.rst b/docs/source/nnls_solving.rst
index d39ce95..96291f5 100644
--- a/docs/source/nnls_solving.rst
+++ b/docs/source/nnls_solving.rst
@@ -1282,7 +1282,12 @@
 
 .. member:: int Solver::Options::num_linear_solver_threads
 
-   Default: ``1``
+   Default: ``-1``
+
+   **This field is deprecated, and is ignored by
+   Ceres. Solver::Options::num_threads controls threading for all
+   of Ceres Solver. This setting is scheduled to be removed in
+   1.15.0.**
 
    Number of threads used by the linear solver.
 
@@ -2125,20 +2130,33 @@
 
    Number of threads actually used by the solver for Jacobian and
    residual evaluation. This number is not equal to
-   :member:`Solver::Summary::num_threads_given` if neither `OpenMP` nor `TBB`
-   is available.
+   :member:`Solver::Summary::num_threads_given` if none of `OpenMP`,
+   `TBB` or `CXX11_THREADS` is available.
 
 .. member:: int Solver::Summary::num_linear_solver_threads_given
 
+   **This field is deprecated, and is ignored by
+   Ceres. Solver::Summary::num_threads_given should be used
+   instead.
+
+   This field is scheduled to be removed in 1.15.0. In the interim the
+   value of this field will be num_threads_given.**
+
    Number of threads specified by the user for solving the trust
    region problem.
 
 .. member:: int Solver::Summary::num_linear_solver_threads_used
 
+   **This field is deprecated. Solver::Summary::num_threads_used
+   should be used instead.
+
+   This field is scheduled to be removed in 1.15.0. In the interim the
+   value of this field will be num_threads_used.**
+
    Number of threads actually used by the solver for solving the trust
    region problem. This number is not equal to
-   :member:`Solver::Summary::num_linear_solver_threads_given` if neither
-   `OpenMP` nor `TBB` is available.
+   :member:`Solver::Summary::num_linear_solver_threads_given` if none
+   of `OpenMP`, `TBB` or `CXX11_THREADS` is available.
 
 .. member:: LinearSolverType Solver::Summary::linear_solver_type_given
 
diff --git a/examples/bundle_adjuster.cc b/examples/bundle_adjuster.cc
index e21c4ee..319e385 100644
--- a/examples/bundle_adjuster.cc
+++ b/examples/bundle_adjuster.cc
@@ -140,7 +140,6 @@
   CHECK(StringToDenseLinearAlgebraLibraryType(
             FLAGS_dense_linear_algebra_library,
             &options->dense_linear_algebra_library_type));
-  options->num_linear_solver_threads = FLAGS_num_threads;
   options->use_explicit_schur_complement = FLAGS_explicit_schur_complement;
 }
 
diff --git a/include/ceres/solver.h b/include/ceres/solver.h
index 13f520b..ec0758f 100644
--- a/include/ceres/solver.h
+++ b/include/ceres/solver.h
@@ -118,7 +118,7 @@
   #endif
 #endif
 
-      num_linear_solver_threads = 1;
+      num_linear_solver_threads = -1;
       use_explicit_schur_complement = false;
       use_postordering = false;
       dynamic_sparsity = false;
@@ -425,9 +425,11 @@
     // whether they are linked into Ceres at build time.
     SparseLinearAlgebraLibraryType sparse_linear_algebra_library_type;
 
-    // Number of threads used by Ceres to solve the Newton
-    // step. Currently only the SPARSE_SCHUR solver is capable of
-    // using this setting.
+    // NOTE: This field is deprecated, and is ignored by
+    // Ceres. Solver::Options::num_threads controls threading for all
+    // of Ceres Solver.
+    //
+    // This setting is scheduled to be removed in 1.15.0.
     int num_linear_solver_threads;
 
     // The order in which variables are eliminated in a linear solver
@@ -932,10 +934,24 @@
     // num_threads_given if OpenMP is not available.
     int num_threads_used;
 
-    //  Number of threads specified by the user for solving the trust
+    // NOTE: This field is deprecated,
+    // Solver::Summary::num_threads_given should be used instead.
+    //
+    // This field is scheduled to be removed in 1.15.0. In the interim
+    // the value of this field will always be equal to
+    // num_threads_given.
+    //
+    // Number of threads specified by the user for solving the trust
     // region problem.
     int num_linear_solver_threads_given;
 
+    // NOTE: This field is deprecated,
+    // Solver::Summary::num_threads_used should be used instead.
+    //
+    // This field is scheduled to be removed in 1.15.0. In the interim
+    // the value of this field will always be equal to
+    // num_threads_used.
+    //
     // Number of threads actually used by the solver for solving the
     // trust region problem. This number is not equal to
     // num_threads_given if OpenMP is not available.
diff --git a/internal/ceres/preprocessor.cc b/internal/ceres/preprocessor.cc
index e9dc293..88d5398 100644
--- a/internal/ceres/preprocessor.cc
+++ b/internal/ceres/preprocessor.cc
@@ -56,6 +56,19 @@
 }
 
 void ChangeNumThreadsIfNeeded(Solver::Options* options) {
+  if (options->num_linear_solver_threads != -1 &&
+      options->num_threads != options->num_linear_solver_threads) {
+    LOG(WARNING) << "Solver::Options::num_threads = "
+                 << options->num_threads
+                 << " and Solver::Options::num_linear_solver_threads = "
+                 << options->num_linear_solver_threads
+                 << ". Solver::Options::num_linear_solver_threads is "
+                 << "deprecated and is ignored."
+                 << "Solver::Options::num_threads now controls threading "
+                 << "behaviour in all of Ceres Solver. "
+                 << "This field will go away in Ceres Solver 1.15.0.";
+  }
+
 #ifdef CERES_NO_THREADS
   if (options->num_threads > 1) {
     LOG(WARNING)
@@ -64,16 +77,6 @@
         << "to single threaded mode.";
     options->num_threads = 1;
   }
-
-  // Only the Trust Region solver currently uses a linear solver.
-  if (options->minimizer_type == TRUST_REGION &&
-      options->num_linear_solver_threads > 1) {
-    LOG(WARNING)
-        << "Neither OpenMP nor TBB support is compiled into this binary; "
-        << "only options.num_linear_solver_threads=1 is supported. Switching "
-        << "to single threaded mode.";
-    options->num_linear_solver_threads = 1;
-  }
 #endif  // CERES_NO_THREADS
 }
 
diff --git a/internal/ceres/solver.cc b/internal/ceres/solver.cc
index 5f047cb..016d841 100644
--- a/internal/ceres/solver.cc
+++ b/internal/ceres/solver.cc
@@ -96,7 +96,6 @@
   OPTION_GE(gradient_tolerance, 0.0);
   OPTION_GE(parameter_tolerance, 0.0);
   OPTION_GT(num_threads, 0);
-  OPTION_GT(num_linear_solver_threads, 0);
   if (options.check_gradients) {
     OPTION_GT(gradient_check_relative_precision, 0.0);
     OPTION_GT(gradient_check_numeric_derivative_relative_step_size, 0.0);
@@ -369,7 +368,7 @@
   summary->max_lbfgs_rank                     = options.max_lbfgs_rank;
   summary->minimizer_type                     = options.minimizer_type;
   summary->nonlinear_conjugate_gradient_type  = options.nonlinear_conjugate_gradient_type;  //  NOLINT
-  summary->num_linear_solver_threads_given    = options.num_linear_solver_threads;          //  NOLINT
+  summary->num_linear_solver_threads_given    = options.num_threads;
   summary->num_threads_given                  = options.num_threads;
   summary->preconditioner_type_given          = options.preconditioner_type;
   summary->sparse_linear_algebra_library_type = options.sparse_linear_algebra_library_type; //  NOLINT
@@ -386,9 +385,9 @@
 
   summary->inner_iterations_used          = pp.inner_iteration_minimizer.get() != NULL;     // NOLINT
   summary->linear_solver_type_used        = pp.linear_solver_options.type;
-  summary->num_linear_solver_threads_used = pp.options.num_linear_solver_threads;           // NOLINT
+  summary->num_linear_solver_threads_used = pp.options.num_threads;
   summary->num_threads_used               = pp.options.num_threads;
-  summary->preconditioner_type_used       = pp.options.preconditioner_type;                 // NOLINT
+  summary->preconditioner_type_used       = pp.options.preconditioner_type;
 
   internal::SetSummaryFinalCost(summary);
 
@@ -528,8 +527,7 @@
   PreSolveSummarize(options, problem_impl, summary);
 
   // The main thread also does work so we only need to launch num_threads - 1.
-  problem_impl->context()->EnsureMinimumThreads(
-      std::max(options.num_threads, options.num_linear_solver_threads) - 1);
+  problem_impl->context()->EnsureMinimumThreads(options.num_threads - 1);
 
   // Make sure that all the parameter blocks states are set to the
   // values provided by the user.
@@ -779,9 +777,6 @@
     }
     StringAppendF(&report, "Threads             % 25d% 25d\n",
                   num_threads_given, num_threads_used);
-    StringAppendF(&report, "Linear solver threads % 23d% 25d\n",
-                  num_linear_solver_threads_given,
-                  num_linear_solver_threads_used);
 
     string given;
     StringifyOrdering(linear_solver_ordering_given, &given);
diff --git a/internal/ceres/test_util.h b/internal/ceres/test_util.h
index 95ca389..f8bfa3a 100644
--- a/internal/ceres/test_util.h
+++ b/internal/ceres/test_util.h
@@ -102,8 +102,6 @@
         sparse_linear_algebra_library_type;
     options->preconditioner_type = preconditioner_type;
     options->num_threads = num_threads;
-    options->num_linear_solver_threads = num_threads;
-
     if (use_automatic_ordering) {
       options->linear_solver_ordering.reset();
     }
diff --git a/internal/ceres/trust_region_preprocessor.cc b/internal/ceres/trust_region_preprocessor.cc
index 803baef..4c20aac 100644
--- a/internal/ceres/trust_region_preprocessor.cc
+++ b/internal/ceres/trust_region_preprocessor.cc
@@ -193,7 +193,7 @@
   pp->linear_solver_options.use_explicit_schur_complement =
       options.use_explicit_schur_complement;
   pp->linear_solver_options.dynamic_sparsity = options.dynamic_sparsity;
-  pp->linear_solver_options.num_threads = options.num_linear_solver_threads;
+  pp->linear_solver_options.num_threads = options.num_threads;
   pp->linear_solver_options.use_postordering = options.use_postordering;
   pp->linear_solver_options.context = pp->problem->context();