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);