Avoid unintentional std::vector copies

Capture block structure vectors by reference instead of by value in
ParallelFor lambdas inside BlockRandomAccessDiagonalMatrix and
BlockCRSJacobiPreconditioner, and use explicit types instead of auto.
Also bind parameter_blocks by const reference in
ComputeRecursiveIndependentSetOrdering.

Change-Id: I8f2d422423e5c3f58b937c4a6d52a3837068c14f
diff --git a/internal/ceres/block_jacobi_preconditioner.cc b/internal/ceres/block_jacobi_preconditioner.cc
index c608ba2..4749422 100644
--- a/internal/ceres/block_jacobi_preconditioner.cc
+++ b/internal/ceres/block_jacobi_preconditioner.cc
@@ -117,7 +117,7 @@
 BlockCRSJacobiPreconditioner::BlockCRSJacobiPreconditioner(
     Preconditioner::Options options, const CompressedRowSparseMatrix& A)
     : options_(std::move(options)), locks_(A.col_blocks().size()) {
-  auto& col_blocks = A.col_blocks();
+  const std::vector<Block>& col_blocks = A.col_blocks();
 
   // Compute the number of non-zeros in the preconditioner. This is needed so
   // that we can construct the CompressedRowSparseMatrix.
@@ -136,7 +136,7 @@
     // Not that the because of the way the CompressedRowSparseMatrix format
     // works, the entire diagonal block is laid out contiguously in memory as a
     // row-major matrix. We will use this when updating the block.
-    auto& block = col_blocks[i];
+    const Block& block = col_blocks[i];
     for (int j = 0; j < block.size; ++j) {
       for (int k = 0; k < block.size; ++k, ++idx) {
         m_cols[idx] = block.position + k;
@@ -158,8 +158,8 @@
 
 bool BlockCRSJacobiPreconditioner::UpdateImpl(
     const CompressedRowSparseMatrix& A, const double* D) {
-  const auto& col_blocks = A.col_blocks();
-  const auto& row_blocks = A.row_blocks();
+  const std::vector<Block>& col_blocks = A.col_blocks();
+  const std::vector<Block>& row_blocks = A.row_blocks();
   const int num_col_blocks = col_blocks.size();
   const int num_row_blocks = row_blocks.size();
 
@@ -176,7 +176,7 @@
       0,
       num_row_blocks,
       options_.num_threads,
-      [this, row_blocks, a_rows, a_cols, a_values, m_values, m_rows](int i) {
+      [this, &row_blocks, a_rows, a_cols, a_values, m_values, m_rows](int i) {
         const int row = row_blocks[i].position;
         const int row_block_size = row_blocks[i].size;
         const int row_nnz = a_rows[row + 1] - a_rows[row];
@@ -206,7 +206,7 @@
       0,
       num_col_blocks,
       options_.num_threads,
-      [col_blocks, m_rows, m_values, D](int i) {
+      [&col_blocks, m_rows, m_values, D](int i) {
         const int col = col_blocks[i].position;
         const int col_block_size = col_blocks[i].size;
         MatrixRef m(m_values + m_rows[col], col_block_size, col_block_size);
diff --git a/internal/ceres/block_random_access_diagonal_matrix.cc b/internal/ceres/block_random_access_diagonal_matrix.cc
index b657266..aef1024 100644
--- a/internal/ceres/block_random_access_diagonal_matrix.cc
+++ b/internal/ceres/block_random_access_diagonal_matrix.cc
@@ -69,7 +69,7 @@
     return nullptr;
   }
 
-  auto& blocks = m_->row_blocks();
+  const std::vector<Block>& blocks = m_->row_blocks();
   const int stride = blocks[row_block_id].size;
 
   // Each cell is stored contiguously as its own little dense matrix.
@@ -88,11 +88,11 @@
 }
 
 void BlockRandomAccessDiagonalMatrix::Invert() {
-  auto& blocks = m_->row_blocks();
+  const std::vector<Block>& blocks = m_->row_blocks();
   const int num_blocks = blocks.size();
-  ParallelFor(context_, 0, num_blocks, num_threads_, [this, blocks](int i) {
-    auto& cell_info = layout_[i];
-    auto& block = blocks[i];
+  ParallelFor(context_, 0, num_blocks, num_threads_, [this, &blocks](int i) {
+    const CellInfo& cell_info = layout_[i];
+    const Block& block = blocks[i];
     MatrixRef b(cell_info.values, block.size, block.size);
     b = b.selfadjointView<Eigen::Upper>().llt().solve(
         Matrix::Identity(block.size, block.size));
@@ -103,12 +103,12 @@
     const double* x, double* y) const {
   CHECK(x != nullptr);
   CHECK(y != nullptr);
-  auto& blocks = m_->row_blocks();
+  const std::vector<Block>& blocks = m_->row_blocks();
   const int num_blocks = blocks.size();
   ParallelFor(
-      context_, 0, num_blocks, num_threads_, [this, blocks, x, y](int i) {
-        auto& cell_info = layout_[i];
-        auto& block = blocks[i];
+      context_, 0, num_blocks, num_threads_, [this, &blocks, x, y](int i) {
+        const CellInfo& cell_info = layout_[i];
+        const Block& block = blocks[i];
         ConstMatrixRef b(cell_info.values, block.size, block.size);
         VectorRef(y + block.position, block.size).noalias() +=
             b * ConstVectorRef(x + block.position, block.size);
diff --git a/internal/ceres/parameter_block_ordering.cc b/internal/ceres/parameter_block_ordering.cc
index 6db8a60..59137b2 100644
--- a/internal/ceres/parameter_block_ordering.cc
+++ b/internal/ceres/parameter_block_ordering.cc
@@ -102,7 +102,7 @@
                                             ParameterBlockOrdering* ordering) {
   CHECK(ordering != nullptr);
   ordering->Clear();
-  const std::vector<ParameterBlock*> parameter_blocks =
+  const std::vector<ParameterBlock*>& parameter_blocks =
       program.parameter_blocks();
   auto graph = CreateHessianGraph(program);