Remove a level of indirection when using CellInfo
The CellInfo struct contains a mutex, which interacts poorly
with some standard library containers which may move things around.
As a result we were using std::unique_ptr<CellInfo> in these
containers, but this change gets rid of that level of indirection
as std::unordered_map can construct CellInfo in place and we can
replace the use of std::vector with an array we know will not be
resized.
This improves the performance of the schur eliminator a bit but
also the performance of the block diagonal preconditioners.
Change-Id: If3ccd1273a754d9c5112e6e611ce31066b6b27b5
diff --git a/internal/ceres/block_random_access_diagonal_matrix.cc b/internal/ceres/block_random_access_diagonal_matrix.cc
index 357fc31..643dbf1 100644
--- a/internal/ceres/block_random_access_diagonal_matrix.cc
+++ b/internal/ceres/block_random_access_diagonal_matrix.cc
@@ -52,10 +52,10 @@
: context_(context), num_threads_(num_threads) {
m_ = CompressedRowSparseMatrix::CreateBlockDiagonalMatrix(nullptr, blocks);
double* values = m_->mutable_values();
- layout_.reserve(blocks.size());
- for (auto& block : blocks) {
- layout_.emplace_back(std::make_unique<CellInfo>(values));
- values += block.size * block.size;
+ layout_ = std::make_unique<CellInfo[]>(blocks.size());
+ for (int i = 0; i < blocks.size(); ++i) {
+ layout_[i].values = values;
+ values += blocks[i].size * blocks[i].size;
}
}
@@ -77,7 +77,7 @@
*col = 0;
*row_stride = stride;
*col_stride = stride;
- return layout_[row_block_id].get();
+ return &layout_[row_block_id];
}
// Assume that the user does not hold any locks on any cell blocks
@@ -91,9 +91,9 @@
auto& 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].get();
+ auto& cell_info = layout_[i];
auto& block = blocks[i];
- MatrixRef b(cell_info->values, block.size, block.size);
+ MatrixRef b(cell_info.values, block.size, block.size);
b = b.selfadjointView<Eigen::Upper>().llt().solve(
Matrix::Identity(block.size, block.size));
});
@@ -107,9 +107,9 @@
const int num_blocks = blocks.size();
ParallelFor(
context_, 0, num_blocks, num_threads_, [this, blocks, x, y](int i) {
- auto* cell_info = layout_[i].get();
+ auto& cell_info = layout_[i];
auto& block = blocks[i];
- ConstMatrixRef b(cell_info->values, block.size, block.size);
+ 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/block_random_access_diagonal_matrix.h b/internal/ceres/block_random_access_diagonal_matrix.h
index e5f50b0..9671f3e 100644
--- a/internal/ceres/block_random_access_diagonal_matrix.h
+++ b/internal/ceres/block_random_access_diagonal_matrix.h
@@ -33,7 +33,6 @@
#include <memory>
#include <utility>
-#include <vector>
#include "ceres/block_random_access_matrix.h"
#include "ceres/block_structure.h"
@@ -85,7 +84,7 @@
ContextImpl* context_ = nullptr;
const int num_threads_ = 1;
std::unique_ptr<CompressedRowSparseMatrix> m_;
- std::vector<std::unique_ptr<CellInfo>> layout_;
+ std::unique_ptr<CellInfo[]> layout_;
};
} // namespace ceres::internal
diff --git a/internal/ceres/block_random_access_sparse_matrix.cc b/internal/ceres/block_random_access_sparse_matrix.cc
index 271544e..b9f8b36 100644
--- a/internal/ceres/block_random_access_sparse_matrix.cc
+++ b/internal/ceres/block_random_access_sparse_matrix.cc
@@ -91,8 +91,7 @@
for (auto& c : cells) {
const int col_block_id = c.block_id;
double* const data = values + c.position;
- layout_[IntPairToInt64(row_block_id, col_block_id)] =
- std::make_unique<CellInfo>(data);
+ layout_.emplace(IntPairToInt64(row_block_id, col_block_id), data);
}
}
}
@@ -113,7 +112,7 @@
*col = 0;
*row_stride = blocks_[row_block_id].size;
*col_stride = blocks_[col_block_id].size;
- return it->second.get();
+ return &it->second;
}
// Assume that the user does not hold any locks on any cell blocks
diff --git a/internal/ceres/block_random_access_sparse_matrix.h b/internal/ceres/block_random_access_sparse_matrix.h
index c509a01..5121832 100644
--- a/internal/ceres/block_random_access_sparse_matrix.h
+++ b/internal/ceres/block_random_access_sparse_matrix.h
@@ -113,8 +113,8 @@
const int num_threads_ = 1;
// A mapping from <row_block_id, col_block_id> to the position in
- // the values array of tsm_ where the block is stored.
- using LayoutType = std::unordered_map<int64_t, std::unique_ptr<CellInfo>>;
+ // the values array of bsm_ where the block is stored.
+ using LayoutType = std::unordered_map<std::int64_t, CellInfo>;
LayoutType layout_;
// The underlying matrix object which actually stores the cells.