mirror of
https://github.com/ceres-solver/ceres-solver.git
synced 2026-08-30 00:50:37 +08:00
Adds a Ceres Context structure.
A Ceres Context holds common global state that can be re-used within Ceres. The Context current contains a thread pool if compiling with C++11 threading support. Threads are expensive to create and destroy so it is good to maintain across multiple Ceres solves. Tested by compiling with and without TBB support and ran unit tests. Ran bazel as well. Change-Id: I82f598dfae642aa0e81a6039dc174608a5e8dbfb
This commit is contained in:
@@ -41,6 +41,7 @@
|
||||
#include "ceres/casts.h"
|
||||
#include "ceres/compressed_row_jacobian_writer.h"
|
||||
#include "ceres/compressed_row_sparse_matrix.h"
|
||||
#include "ceres/context_impl.h"
|
||||
#include "ceres/cost_function.h"
|
||||
#include "ceres/crs_matrix.h"
|
||||
#include "ceres/evaluator.h"
|
||||
@@ -107,6 +108,18 @@ void STLDeleteContainerPairFirstPointers(ForwardIterator begin,
|
||||
}
|
||||
}
|
||||
|
||||
void InitializeContext(Context* context,
|
||||
ContextImpl** context_impl,
|
||||
bool* context_impl_owned) {
|
||||
if (context == NULL) {
|
||||
*context_impl_owned = true;
|
||||
*context_impl = new ContextImpl;
|
||||
} else {
|
||||
*context_impl_owned = false;
|
||||
*context_impl = down_cast<ContextImpl*>(context);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ParameterBlock* ProblemImpl::InternalAddParameterBlock(double* values,
|
||||
@@ -230,13 +243,17 @@ void ProblemImpl::DeleteBlock(ParameterBlock* parameter_block) {
|
||||
}
|
||||
|
||||
ProblemImpl::ProblemImpl()
|
||||
: program_(new internal::Program) {
|
||||
: options_(Problem::Options()),
|
||||
program_(new internal::Program) {
|
||||
residual_parameters_.reserve(10);
|
||||
InitializeContext(options_.context, &context_impl_, &context_impl_owned_);
|
||||
}
|
||||
|
||||
ProblemImpl::ProblemImpl(const Problem::Options& options)
|
||||
: options_(options), program_(new internal::Program) {
|
||||
: options_(options),
|
||||
program_(new internal::Program) {
|
||||
residual_parameters_.reserve(10);
|
||||
InitializeContext(options_.context, &context_impl_, &context_impl_owned_);
|
||||
}
|
||||
|
||||
ProblemImpl::~ProblemImpl() {
|
||||
@@ -261,6 +278,10 @@ ProblemImpl::~ProblemImpl() {
|
||||
// Delete the owned parameterizations.
|
||||
STLDeleteUniqueContainerPointers(local_parameterizations_to_delete_.begin(),
|
||||
local_parameterizations_to_delete_.end());
|
||||
|
||||
if (context_impl_owned_) {
|
||||
delete context_impl_;
|
||||
}
|
||||
}
|
||||
|
||||
ResidualBlock* ProblemImpl::AddResidualBlock(
|
||||
@@ -798,6 +819,10 @@ bool ProblemImpl::Evaluate(const Problem::EvaluateOptions& evaluate_options,
|
||||
evaluator_options.num_threads = evaluate_options.num_threads;
|
||||
#endif // CERES_NO_THREADS
|
||||
|
||||
// The main thread also does work so we only need to launch num_threads - 1.
|
||||
context_impl_->EnsureMinimumThreads(evaluator_options.num_threads - 1);
|
||||
evaluator_options.context = context_impl_;
|
||||
|
||||
scoped_ptr<Evaluator> evaluator(
|
||||
new ProgramEvaluator<ScratchEvaluatePreparer,
|
||||
CompressedRowJacobianWriter>(evaluator_options,
|
||||
|
||||
Reference in New Issue
Block a user