This eliminates an entire vector and computation of a square root
followed by a squaring.
Thanks to @rlabbe for pointing this out.
Change-Id: I0de117b31b9332c61e687f18466d7cb2e2ac611e
As pointed out by several users, introduction of parallel operations on
vectors severely impacts solver performance on small problems, with time
consumption increasing with the number of threads.
In order to minimize overhead of trying to execute small tasks using a
large number of threads, task scheduling mechanism was changed to avoid
scheduling all tasks at once.
However, there is still a large difference in exectuion time because the
main thread always launches the next thread before starting doing the
work. This leads to several orders of magnitude slowdown when going from
a single-threaded execution (which follows a fast-forward path to a
single loop over all indices, without any synchronization involved)
to a two-thread execution:
/bin/parallel_vector_operations_benchmark
-------------------------------------------
Benchmark Time
-------------------------------------------
SetZero/128 12.8 ns
SetZeroParallel/128/1 16.6 ns
SetZeroParallel/128/2 2211 ns
In order to eliminate this effect, we limit the block-size of parallel
execution of vector operations to 2^16 elements (thus, starting parallel
execution only for vectors of at least 2^17 elements).
Threshold of 2^16 elements was choosen by evaluating thresholds from
2^10 to 2^20 (only powers of 2), with 2^14..2^20 significantly reducing
worst-case runtime degradation.
Details can be found in discussion of the issue at
https://github.com/ceres-solver/ceres-solver/issues/1016
Change-Id: I555c882d63ee53323ceb426743b970f989b65503
As pointed out by several users, introduction of parallel operations on
vectors severely impacts solver performance on small problems, with time
consumption increasing with the number of threads.
The problem is two-fold:
- Single-threaded execution is faster than multi-threaded
- Overhead of multi-threaded execution increases dramaticaly when
number of threads is increased
Supposedly, the second problem is due to ParallelInvoke scheduling
a task for each thread via ThreadPool.
When the time required to perform computations is smaller than costs of
scheduling task, runtime becomes linear in num_threads.
Moreover, main thread competes with working threads for mutex in
ConcurrentQueue.
In order to limit scheduling overhead and minimize lock contention,
each new task is scheduled from the previous one, if:
- Number of scheduled tasks is less than num_threads
- At the moment of creating the task not all work has been done
Correctness is granted by atomicity of thread_id counter.
SchedulerBenchmark mini-benchmark was added to illustrate the issue.
Each iteration of parallel loop performs change of a single value.
With the previous scheduling strategy, increasing number of threads
leads to significant increase of runtime:
-----------------------------------------------------
Benchmark Time Iterations
-----------------------------------------------------
SchedulerBenchmark/128/1 14.1 ns 49496153
SchedulerBenchmark/128/2 3965 ns 240173
SchedulerBenchmark/128/4 13162 ns 71478
SchedulerBenchmark/128/8 30643 ns 29614
SchedulerBenchmark/128/16 63694 ns 10000
SchedulerBenchmark/256/1 24.1 ns 28943598
SchedulerBenchmark/256/2 3878 ns 227498
SchedulerBenchmark/256/4 13293 ns 69817
SchedulerBenchmark/256/8 31117 ns 32640
SchedulerBenchmark/256/16 59503 ns 14910
SchedulerBenchmark/1024/1 56.7 ns 12048398
SchedulerBenchmark/1024/2 4346 ns 203140
SchedulerBenchmark/1024/4 13487 ns 66736
SchedulerBenchmark/1024/8 30982 ns 33090
SchedulerBenchmark/1024/16 63199 ns 14762
SchedulerBenchmark/4096/1 189 ns 3633540
SchedulerBenchmark/4096/2 5932 ns 131884
SchedulerBenchmark/4096/4 14784 ns 61236
SchedulerBenchmark/4096/8 35857 ns 29276
SchedulerBenchmark/4096/16 63934 ns 10000
With new scheduling strategy, increasing requested number of threads
does not result in that high increase of runtime
-----------------------------------------------------
Benchmark Time Iterations
-----------------------------------------------------
SchedulerBenchmark/128/1 14.1 ns 49323498
SchedulerBenchmark/128/2 2411 ns 362916
SchedulerBenchmark/128/4 3556 ns 243026
SchedulerBenchmark/128/8 4346 ns 200626
SchedulerBenchmark/128/16 5066 ns 169698
SchedulerBenchmark/256/1 24.2 ns 28960018
SchedulerBenchmark/256/2 2330 ns 388470
SchedulerBenchmark/256/4 3864 ns 219233
SchedulerBenchmark/256/8 4399 ns 195225
SchedulerBenchmark/256/16 5111 ns 161858
SchedulerBenchmark/1024/1 55.9 ns 12204777
SchedulerBenchmark/1024/2 2541 ns 329807
SchedulerBenchmark/1024/4 3977 ns 222628
SchedulerBenchmark/1024/8 4607 ns 193548
SchedulerBenchmark/1024/16 5031 ns 160285
SchedulerBenchmark/4096/1 188 ns 3714433
SchedulerBenchmark/4096/2 4203 ns 188284
SchedulerBenchmark/4096/4 4832 ns 171811
SchedulerBenchmark/4096/8 5605 ns 159093
SchedulerBenchmark/4096/16 6425 ns 126861
(both runs were executed on 28-core 56-thread cpu)
Change-Id: I91eca783280598997bfe6abd28019847731692e4
Previously, MSVC warning C4996 was suppressed unconditionally in the
entire code base which made it difficult identifying and fixing specific
problems, particularly those in the public interface.
Prefer now to disable warnings at the specific location they occur. This
approach, however, reveals an inconsistency in how Ceres handles POSIX
functions which are declared deprecated by MSVC. Specifically, Bessel
functions use the underscore form whereas the read function does not. To
simplify the logic, we revert to POSIX compatible functions.
C++23 also deprecates std::numeric_limits<T>::has_denorm which MSVC
warns about. Here, we disable the deprecation warning locally to avoid
the warning leaking into the user code.
Fixes#1013
Change-Id: Ida8457cc8dd8770b4384a7c49d16f213b02cdec4
Parallelization of remaining block-diagonal matrix-vector product and
vector operations makes parallel execution slightly faster
Before (Intel 8176 CPU, 10 iterations):
-----------------------------------------------------------------------
Benchmark Time
-----------------------------------------------------------------------
PSEPreconditioner...<problem-13682-4456117-pre.txt>/1_median 26677 ms
PSEPreconditioner...<problem-13682-4456117-pre.txt>/1_stddev 26.6 ms
PSEPreconditioner...<problem-13682-4456117-pre.txt>/2_median 31037 ms
PSEPreconditioner...<problem-13682-4456117-pre.txt>/2_stddev 191 ms
PSEPreconditioner...<problem-13682-4456117-pre.txt>/4_median 16915 ms
PSEPreconditioner...<problem-13682-4456117-pre.txt>/4_stddev 98.0 ms
PSEPreconditioner...<problem-13682-4456117-pre.txt>/8_median 9175 ms
PSEPreconditioner...<problem-13682-4456117-pre.txt>/8_stddev 44.1 ms
PSEPreconditioner...<problem-13682-4456117-pre.txt>/16_median 4974 ms
PSEPreconditioner...<problem-13682-4456117-pre.txt>/16_stddev 11.5 ms
After:
-----------------------------------------------------------------------
Benchmark Time
-----------------------------------------------------------------------
PSEPreconditioner...<problem-13682-4456117-pre.txt>/1_median 26609 ms
PSEPreconditioner...<problem-13682-4456117-pre.txt>/1_stddev 69.4 ms
PSEPreconditioner...<problem-13682-4456117-pre.txt>/2_median 29178 ms
PSEPreconditioner...<problem-13682-4456117-pre.txt>/2_stddev 367 ms
PSEPreconditioner...<problem-13682-4456117-pre.txt>/4_median 16152 ms
PSEPreconditioner...<problem-13682-4456117-pre.txt>/4_stddev 106 ms
PSEPreconditioner...<problem-13682-4456117-pre.txt>/8_median 8773 ms
PSEPreconditioner...<problem-13682-4456117-pre.txt>/8_stddev 41.5 ms
PSEPreconditioner...<problem-13682-4456117-pre.txt>/16_median 4800 ms
PSEPreconditioner...<problem-13682-4456117-pre.txt>/16_stddev 14.7 ms
Change-Id: Ib1d1b0c4edf9c556a9e996c49486d2726efcc558
Also tighten the value of eta to make the iterative schur
solvers work better. This is the default value used in
bundle_adjuster.cc
Fixes https://github.com/ceres-solver/ceres-solver/issues/864
Change-Id: I48258fbbe256d6e932aaea0078b566fcd63de2fb
Change-Id: Ia5ad252cae31f415a47495fb8769421ade355bc9
iteration_callback_example.cc uses the curve_fitting.cc example
and uses a custom IterationCallback to log the values of the
parameter blocks are they change over the course of the optimization.
Change-Id: I6a478a8418e237aff576ca627d9b5c0b751b8088
Remove "using ceres:foo" directives from example code. The using
directives actually make the code harder to read unless you already
know the ceres API. By making the namespace explicit it is clear
to the reader that these are functions and objects from the Ceres
API.
Change-Id: I89b1281c754bf71c0f82e39e1607c5e40a148388
cuda-memcheck has been deprecated and these tests will be reinstated
once we move to compute sanitizer.
Change-Id: I7e01cffdd00ffb7404dfef2a171ebaeca017cda8
1. Add a version history
2. Update copyright years across the code base
3. Run format_all.sh
4. Update version strings from 2.1.0 to 2.2.0 in the docs and
elsewhere.
Change-Id: I46d8d479d54bd6002d532785e67342106e73c9ac
* Make sphinx_rtd_theme a find module component to avoid hard-wiring it
into the module and allowing to report the theme in case it is missing
using the standard CMake package mechanism.
* Adjust find module cache variables names case to match the find module
name.
* Also report sphinx-build version for completeness.
* Invoke the find module only once. Calling find_package on the same
module is not needed.
Change-Id: I9d1bf0fcc0d44b9b37e624128812f348c5442ada
Given we no longer support Ubuntu 18.04 due to packaged GCC lacking
C++17 support we can bump the minimum required CMake version to the one
provided by Ubuntu 20.04 which is CMake 3.16. Consequently, this allows
to drop some of the legacy CMake logic.
Change-Id: I1f05d4c5681d10aa7faa0800ef4a803be2f5b7dd
AppleClang 14.0.0.14000029 warns about a potential security problem
while invoking the sprintf C function:
internal/ceres/fixed_array_test.cc:469:3: warning: 'sprintf' is deprecated: This function is provided for compatibility reasons only. Due to security concerns inherent in the design of sprintf(3), it is highly recommended that you use snprintf(3) instead. [-Wdeprecated-declarations]
sprintf(buf.data(), "foo"); // NOLINT(runtime/printf)
^
/Applications/Xcode_14.2.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk/usr/include/stdio.h:188:1: note: 'sprintf' has been explicitly marked deprecated here
__deprecated_msg("This function is provided for compatibility reasons only. Due to security concerns inherent in the design of sprintf(3), it is highly recommended that you use snprintf(3) instead.")
^
/Applications/Xcode_14.2.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk/usr/include/sys/cdefs.h:215:48: note: expanded from macro '__deprecated_msg'
#define __deprecated_msg(_msg) __attribute__((__deprecated__(_msg)))
Replace sprintf by snprintf to avoid this deprecation warning.
Change-Id: I6870c0bd4e390388d1d7bcec082cee272b234eba
This avoids the following CMake error when exporting Ceres build
directory to local CMake package registry:
export called with target "ceres" which requires target
"ceres_cuda_kernels" that is not in any export set.
Fixes#966
Change-Id: I5a75191fc414a3f138b19cb9d5850f7330f2d24a
Without this we start getting errors related to FindSphinx.cmake
I am not sure yet, what version of cmake we can assume in the wild
but the current minimum version supports the old behaviour and this
policy seems relatively recent (CMake version 3.27) so we should
have this workaround till we update our minimum required version.
Fixes https://github.com/ceres-solver/ceres-solver/issues/1002
Change-Id: I1beaac9ee27bc9ff85b64f53f72606a0424f2391
Converting fixed size vectors to dynamic ones allows to avoid
segmentation faults in Eigen's packet math if the corresponding
expressions are invoked within GMock matchers.
Fixes#996
Change-Id: I7da5599883825ab0e580678d3d55de19095b41b1
- Perform temporary buffer size estimation only once
- Allow construction from existing buffers with col/row structure
Change-Id: I73c291328f1e8ed9184aba5d7058df71cbc6a15d
1. In cuda_sparse_matrix.cc fix the order of fields in the initializer list.
2. Move a line of code to the ifdef branch which will use it.
Change-Id: If32ea14a287f845c1740e6f726c1007e86a4eeca