Fix outdated documentation across multiple .dox files

libeigen/eigen!2148

Co-authored-by: Rasmus Munk Larsen <rmlarsen@gmail.com>
This commit is contained in:
Rasmus Munk Larsen
2026-02-18 12:23:41 -08:00
parent bdec88009d
commit 073190be04
5 changed files with 60 additions and 52 deletions

View File

@@ -4,7 +4,11 @@ namespace Eigen {
Passing objects by value is almost always a very bad idea in C++, as this means useless copies, and one should pass them by reference instead.
With %Eigen, this is even more important: passing \ref TopicFixedSizeVectorizable "fixed-size vectorizable Eigen objects" by value is not only inefficient, it can be illegal or make your program crash! And the reason is that these %Eigen objects have alignment modifiers that aren't respected when they are passed by value.
\note If you are compiling in C++17 mode with a sufficiently recent compiler (GCC >= 7, Clang >= 5, MSVC >= 19.12),
the alignment issues described below are handled automatically by the compiler, and passing %Eigen objects by value
is safe (though still less efficient than passing by const reference).
With pre-C++17 compilers, passing \ref TopicFixedSizeVectorizable "fixed-size vectorizable Eigen objects" by value is not only inefficient, it can be illegal or make your program crash! And the reason is that these %Eigen objects have alignment modifiers that aren't respected when they are passed by value.
For example, a function like this, where \c v is passed by value:

View File

@@ -112,17 +112,19 @@ In this very particular case, a workaround would be to call A.reverse().eval() f
If you don't know why passing-by-value is wrong with %Eigen, read this \link TopicPassingByValue page \endlink first.
While you may be extremely careful and use care to make sure that all of your code that explicitly uses %Eigen types is pass-by-reference you have to watch out for templates which define the argument types at compile time.
\note If you are compiling in C++17 mode with a sufficiently recent compiler (GCC >= 7, Clang >= 5, MSVC >= 19.12),
the alignment issues described below are handled automatically by the compiler via over-aligned operator new,
and pass-by-value is safe.
If a template has a function that takes arguments pass-by-value, and the relevant template parameter ends up being an %Eigen type, then you will of course have the same alignment problems that you would in an explicitly defined function passing %Eigen types by reference.
For pre-C++17 code, you have to watch out for templates which define argument types at compile time.
If a template has a function that takes arguments pass-by-value, and the relevant template parameter ends up being an %Eigen type, then you will have the same alignment problems that you would in an explicitly defined function passing %Eigen types by value.
Using %Eigen types with other third party libraries or even the STL can present the same problem.
<code>boost::bind</code> for example uses pass-by-value to store arguments in the returned functor.
This will of course be a problem.
\c std::bind for example uses pass-by-value to store arguments in the returned functor.
There are at least two ways around this:
- If the value you are passing is guaranteed to be around for the life of the functor, you can use boost::ref() to wrap the value as you pass it to boost::bind. Generally this is not a solution for values on the stack as if the functor ever gets passed to a lower or independent scope, the object may be gone by the time it's attempted to be used.
- The other option is to make your functions take a reference counted pointer like boost::shared_ptr as the argument. This avoids needing to worry about managing the lifetime of the object being passed.
- If the value you are passing is guaranteed to be around for the life of the functor, you can use \c std::ref() to wrap the value as you pass it to \c std::bind. Generally this is not a solution for values on the stack as if the functor ever gets passed to a lower or independent scope, the object may be gone by the time it's attempted to be used.
- The other option is to make your functions take a reference counted pointer like \c std::shared_ptr as the argument. This avoids needing to worry about managing the lifetime of the object being passed.
\section TopicPitfalls_matrix_bool Matrices with boolean coefficients

View File

@@ -60,7 +60,8 @@ For instance, one might limit the C++ version to C++14 by defining EIGEN_MAX_CPP
functions by defining EIGEN_HAS_C99_MATH=1.
- \b EIGEN_HAS_C99_MATH - controls the usage of C99 math functions such as erf, erfc, lgamma, etc.
- \b EIGEN_HAS_STD_RESULT_OF - defines whether std::result_of is supported
- \b EIGEN_HAS_STD_INVOKE_RESULT - controls the usage of \c std::invoke_result (C++17). When disabled,
\c std::result_of is used as a fallback.
- \b EIGEN_NO_IO - Disables any usage and support for `<iostreams>`.
\section TopicPreprocessorDirectivesAssertions Assertions
@@ -103,8 +104,9 @@ run time. However, these assertions do cost time and can thus be turned off.
this threshold raises a compile time assertion. Use 0 to set no limit. Default is 128 KB.
- \b \c EIGEN_NO_CUDA - disables CUDA support when defined. Might be useful in .cu files for which Eigen is used on the host only,
and never called from device code.
- \b \c EIGEN_NO_HIP - disables HIP support when defined. Analogous to \c EIGEN_NO_CUDA for AMD's HIP compiler.
- \b \c EIGEN_STRONG_INLINE - This macro is used to qualify critical functions and methods that we expect the compiler to inline.
By default it is defined to \c __forceinline for MSVC and ICC, and to \c inline for other compilers. A tipical usage is to
By default it is defined to \c __forceinline for MSVC and ICC, and to \c inline for other compilers. A typical usage is to
define it to \c inline for MSVC users wanting faster compilation times, at the risk of performance degradations in some rare
cases for which MSVC inliner fails to do a good job.
- \b \c EIGEN_DEFAULT_L1_CACHE_SIZE - Sets the default L1 cache size that is used in Eigen's GEBP kernel when the correct cache size cannot be determined at runtime.
@@ -126,9 +128,7 @@ following macros are supported; none of them are defined by default.
- \b EIGEN_ARRAY_PLUGIN - filename of plugin for extending the Array class.
- \b EIGEN_ARRAYBASE_PLUGIN - filename of plugin for extending the ArrayBase class.
- \b EIGEN_CWISE_PLUGIN - filename of plugin for extending the Cwise class.
- \b EIGEN_DENSEBASE_PLUGIN - filename of plugin for extending the DenseBase class.
- \b EIGEN_DYNAMICSPARSEMATRIX_PLUGIN - filename of plugin for extending the DynamicSparseMatrix class.
- \b EIGEN_FUNCTORS_PLUGIN - filename of plugin for adding new functors and specializations of functor_traits.
- \b EIGEN_MAPBASE_PLUGIN - filename of plugin for extending the MapBase class.
- \b EIGEN_MATRIX_PLUGIN - filename of plugin for extending the Matrix class.

View File

@@ -4,11 +4,10 @@ namespace Eigen {
\section TopicMultiThreading_MakingEigenMT Make Eigen run in parallel
Some %Eigen's algorithms can exploit the multiple cores present in your hardware.
To this end, it is enough to enable OpenMP on your compiler, for instance:
- GCC: \c -fopenmp
- ICC: \c -openmp
- MSVC: check the respective option in the build properties.
Some of %Eigen's algorithms can exploit the multiple cores present in your hardware.
The primary mechanism is OpenMP. To enable it, pass the appropriate flag to your compiler:
- GCC/Clang: \c -fopenmp
- MSVC: \c /openmp (or check the respective option in the build properties)
You can control the number of threads that will be used using either the OpenMP API or %Eigen's API using the following priority:
\code
@@ -24,6 +23,14 @@ n = Eigen::nbThreads( );
\endcode
You can disable %Eigen's multi threading at compile time by defining the \link TopicPreprocessorDirectivesPerformance EIGEN_DONT_PARALLELIZE \endlink preprocessor token.
\subsection TopicMultiThreading_ThreadPool Alternative: ThreadPool backend
As an alternative to OpenMP, %Eigen supports a custom thread pool backend for GEMM operations.
Define \c EIGEN_GEMM_THREADPOOL and use \c Eigen::setGemmThreadPool(Eigen::ThreadPool*) to
provide a thread pool. OpenMP and \c EIGEN_GEMM_THREADPOOL are mutually exclusive.
\subsection TopicMultiThreading_ParallelOps Parallelized operations
Currently, the following algorithms can make use of multi-threading:
- general dense matrix - matrix products
- PartialPivLU
@@ -36,28 +43,14 @@ Currently, the following algorithms can make use of multi-threading:
Indeed, the principle of hyper-threading is to run multiple threads (in most cases 2) on a single core in an interleaved manner.
However, %Eigen's matrix-matrix product kernel is fully optimized and already exploits nearly 100% of the CPU capacity.
Consequently, there is no room for running multiple such threads on a single core, and the performance would drops significantly because of cache pollution and other sources of overheads.
Consequently, there is no room for running multiple such threads on a single core, and the performance would drop significantly because of cache pollution and other sources of overhead.
At this stage of reading you're probably wondering why %Eigen does not limit itself to the number of physical cores?
This is simply because OpenMP does not allow to know the number of physical cores, and thus %Eigen will launch as many threads as <i>cores</i> reported by OpenMP.
\section TopicMultiThreading_UsingEigenWithMT Using Eigen in a multi-threaded application
In the case your own application is multithreaded, and multiple threads make calls to %Eigen, then you have to initialize %Eigen by calling the following routine \b before creating the threads:
\code
#include <Eigen/Core>
int main(int argc, char** argv)
{
Eigen::initParallel();
...
}
\endcode
\note With %Eigen 3.3, and a fully C++11 compliant compiler (i.e., <a href="http://en.cppreference.com/w/cpp/language/storage_duration#Static_local_variables">thread-safe static local variable initialization</a>), then calling \c initParallel() is optional.
\warning Note that all functions generating random matrices are \b not re-entrant nor thread-safe. Those include DenseBase::Random(), and DenseBase::setRandom() despite a call to `Eigen::initParallel()`. This is because these functions are based on `std::rand` which is not re-entrant.
For thread-safe random generator, we recommend the use of c++11 random generators (\link DenseBase::NullaryExpr(Index, const CustomNullaryOp&) example \endlink) or `boost::random`.
\warning Note that all functions generating random matrices are \b not re-entrant nor thread-safe. Those include DenseBase::Random(), and DenseBase::setRandom(). This is because these functions are based on \c std::rand which is not re-entrant.
For thread-safe random generation, we recommend the use of C++11 random generators (\link DenseBase::NullaryExpr(Index, const CustomNullaryOp&) example \endlink).
In the case your application is parallelized with OpenMP, you might want to disable %Eigen's own parallelization as detailed in the previous section.

View File

@@ -3,27 +3,36 @@ namespace Eigen {
/** \page TopicCUDA Using Eigen in CUDA kernels
Staring from CUDA 5.5 and Eigen 3.3, it is possible to use Eigen's matrices, vectors, and arrays for fixed size within CUDA kernels. This is especially useful when working on numerous but small problems. By default, when Eigen's headers are included within a .cu file compiled by nvcc most Eigen's functions and methods are prefixed by the \c __device__ \c __host__ keywords making them callable from both host and device code.
This support can be disabled by defining \c EIGEN_NO_CUDA before including any Eigen's header.
This might be useful to disable some warnings when a .cu file makes use of Eigen on the host side only.
However, in both cases, host's SIMD vectorization has to be disabled in .cu files.
It is thus \b strongly \b recommended to properly move all costly host computation from your .cu files to regular .cpp files.
\section TopicCUDA_Overview Overview
Known issues:
%Eigen's fixed-size matrices, vectors, and arrays can be used inside CUDA and HIP kernels.
This is especially useful when working on numerous but small problems.
By default, when %Eigen's headers are included within a \c .cu file compiled by \c nvcc,
most of %Eigen's functions and methods are prefixed by the \c __device__ \c __host__ keywords
making them callable from both host and device code.
- \c nvcc with MS Visual Studio does not work (patch welcome)
- \c nvcc 5.5 with gcc-4.7 (or greater) has issues with the standard \c \<limits\> header file. To workaround this, you can add the following before including any other files:
\code
// workaround issue between gcc >= 4.7 and cuda 5.5
#if (defined __GNUC__) && (__GNUC__>4 || __GNUC_MINOR__>=7)
#undef _GLIBCXX_ATOMIC_BUILTINS
#undef _GLIBCXX_USE_INT128
#endif
\endcode
- On 64bits system Eigen uses \c long \c int as the default type for indexes and sizes. On CUDA device, it would make sense to default to 32 bits \c int.
However, to keep host and CUDA code compatible, this cannot be done automatically by %Eigen, and the user is thus required to define \c EIGEN_DEFAULT_DENSE_INDEX_TYPE to \c int throughout his code (or only for CUDA code if there is no interaction between host and CUDA code through %Eigen's object).
This support can be disabled by defining \c EIGEN_NO_CUDA (or \c EIGEN_NO_HIP for HIP)
before including any %Eigen header.
This might be useful to disable some warnings when a \c .cu file makes use of %Eigen on the host side only.
\warning Host SIMD vectorization must be disabled in \c .cu files. It is \b strongly
\b recommended to move all costly host-side computation from \c .cu files to regular \c .cpp files.
\section TopicCUDA_HIP HIP support
%Eigen also supports AMD's HIP compiler (\c hipcc). The same \c EIGEN_DEVICE_FUNC mechanism applies:
functions are annotated with \c __device__ \c __host__ when compiling with HIP.
Define \c EIGEN_NO_HIP to disable this. Internally, both CUDA and HIP are unified under the
\c EIGEN_GPUCC macro.
\section TopicCUDA_KnownIssues Known issues
- On 64-bit systems %Eigen uses \c long \c int as the default type for indexes and sizes.
On CUDA/HIP devices, it would make sense to default to 32-bit \c int.
However, to keep host and device code compatible, this cannot be done automatically by %Eigen,
and the user is thus required to define \c EIGEN_DEFAULT_DENSE_INDEX_TYPE to \c int throughout
their code (or only for device code if there is no interaction between host and device code
through %Eigen's objects).
*/