Eigen is written and maintained by volunteers. Contributions — code, documentation, bug triage, tests on uncommon platforms, design feedback — are all welcome.
This document is the human-facing on-ramp. AGENTS.md is the AI-facing repository contract and routes readers to focused guides for testing, numerical work, performance, SIMD/GPU, Tensor/ThreadPool, and CI. Those guides are also useful to human contributors working in the corresponding areas.
AGENTS.md)You don't have to write C++ to help.
decision needed. Issues labelled contributions welcome are good entry points.libeigen/eigen as an upstream remote (use the https:// clone URL if you don't have an SSH key set up):git clone git@gitlab.com:<your-username>/eigen.git # or: https://gitlab.com/<your-username>/eigen.git cd eigen git remote add upstream https://gitlab.com/libeigen/eigen.git
master for your change:git fetch upstream git checkout -b my-topic upstream/master
clang-format-17 (see Coding standards).Area: short imperative subject message (see Commit messages). Stage files by path — don't use git add -A.libeigen/eigen master.If you're planning a large change (new module, API redesign, significant refactor), open an issue or start a discussion first. Aligning on direction before you write code avoids wasted work for everyone.
Eigen is header-only, so consumers don't need to build the library itself — but contributors do need to build the test suite. CMake configure happens out-of-source, and tests are intentionally not in the default all target — drive everything through the named targets.
cmake -S . -B build -G Ninja cmake --build build --target buildtests # build all unit tests cmake --build build --target check # build + run all tests cmake --build build --target buildsmoketests # the smoke set CI gates MRs on ctest --test-dir build --parallel --output-on-failure --no-tests=error
Other useful targets: BuildOfficial (just test/), BuildContrib (just contrib/test/), buildtests_gpu, check_gpu. Once configured, the build dir also exposes ./buildtests.sh <regex> and ./check.sh <regex> for narrowing by test-name regex.
For focused build recipes, test registration, split-test mechanics, and assertion guidance, see .agents/testing.md. Packet and accelerator validation is covered by .agents/simd-gpu.md. The checked-out CMake files remain authoritative for current options.
In-flight migration: MR 2159 is migrating the test framework from Eigen's own
EIGEN_DECLARE_TEST/CALL_SUBTEST_Nmacros to Google Test. Until it lands, write new tests with the existing framework (test/main.h,VERIFY_*,EIGEN_DECLARE_TEST,ei_add_testin the matchingCMakeLists.txt).
benchmarks/ or contrib/benchmarks/. Don't defer benchmarks to a follow-up MR.test/packetmath.cpp entry (or contrib/test/special_packetmath.cpp for special functions), and a specialization in every architecture backend that supports the type. Eigen/src/Core/arch/Default/ holds generic SIMD implementations shared across backends; scalar fallbacks live in Eigen/src/Core/GenericPacketMath.h and Eigen/src/Core/MathFunctions.h.uptime shows a low load average, finish or cancel background builds, and never run two benchmark binaries in the same shell invocation (parallel or chained with &&). Run each in its own shell, take medians within a binary, and optionally alternate (A, B, A, B) across separate invocations to detect drift.Eigen has a few hard rules that catch contributors most often. The repository-wide rules are in AGENTS.md, which also routes to task-specific guidance. The short version:
#include anything under Eigen/src/... or contrib/Eigen/src/... — InternalHeaderCheck.h makes that a hard compile error. User code reaches implementation only through the umbrella headers (Eigen/Core, Eigen/Dense, Eigen/SVD, …).EIGEN_DEVICE_FUNC on coefficient-level methods. Dropping it silently breaks CUDA / HIP / SYCL builds and rarely shows up in local testing.clang-format-17 exactly — Google base, 120 columns, configured in .clang-format. Newer or older clang-format will diff against CI. CI checks changed lines (git clang-format --diff --commit <base>), and the tree is not uniformly clang-format-17 clean. Inspect the selected files' diffs to exclude unrelated changes, then run git clang-format --binary clang-format-17 --force <base-sha> -- <files>; --force permits unstaged edits. Format new, untracked files with clang-format-17 -i <files> because Git's diff omits them. Follow the checks in .agents/ci.md. scripts/format.sh is for an intentional whole-tree pass.modernize-* / cppcoreguidelines-* clang-tidy fixes, no replacing EIGEN_STRONG_INLINE with inline, no reordering includes (.clang-format has SortIncludes: false). Eigen's conventions are encoded in .clang-format‘s StatementMacros and AttributeMacros lists — don’t “fix” their indentation.test/main.h, not gtest (today — see migration note above). VERIFY_* assertions, CALL_SUBTEST_N / EIGEN_TEST_PART_N for splitting, EIGEN_DECLARE_TEST(<name>) { ... } as the entry point.auto traps. auto x = A + B; captures a lazy expression holding references that can dangle. Use .eval() or an explicit type. Similarly, .noalias() is a promise from the caller — only use it when the destination doesn't appear on the right side (so mat.noalias() = mat * mat is wrong).git add -A / git add . — the repo root accumulates .vscode/, .idea/, build*/, and other untracked files that must not enter commits. Add by path or with targeted globs.Naming conventions:
Matrix, BDCSVD).coeffRef, applyOnTheLeft).EIGEN_UPPER_CASE (EIGEN_DEVICE_FUNC, EIGEN_STRONG_INLINE).Eigen::internal namespace; public API stays in Eigen:: or module namespaces.eigen_assert(cond) for runtime preconditions (not raw assert) and eigen_internal_assert for internal-only invariants gated on EIGEN_INTERNAL_DEBUGGING. Compile-time API preconditions use the appropriate EIGEN_STATIC_ASSERT_* helper or EIGEN_STATIC_ASSERT(cond, MSG_TOKEN) to honor EIGEN_NO_STATIC_ASSERT and user overrides. Use static_assert(cond, "message") for unconditional implementation invariants.The canonical class layout is visible in recent additions such as contrib/Eigen/src/GPU/DeviceMatrix.h. Template parameters that get re-exported as public aliases carry a trailing underscore (template <typename Scalar_, ...> paired with using Scalar = Scalar_; — prefer using over typedef in new code), member variables use an m_ prefix (m_matrix, m_isInitialized), implementation headers under Eigen/src/... begin with // IWYU pragma: private and #include "./InternalHeaderCheck.h", header guards follow EIGEN_<NAME>_H, and implementation detail lives inside nested namespace Eigen { namespace internal { ... } }. Public classes carry Doxygen blocks (\class, \brief, \tparam, \sa) and link to runnable snippets from doc/snippets/ via \include / \verbinclude. When in doubt, copy the style from a recent neighbouring file rather than inventing a new convention.
Every new source file must carry an inline copyright + license header. The reuse lint check in the checkformat:lint CI job blocks otherwise. Two header styles are in active use; pick whichever fits.
Attributed to an individual contributor:
// This file is part of Eigen, a lightweight C++ template library // for linear algebra. // // Copyright (C) <year> <Your Name> <your.email@example.com> // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // SPDX-License-Identifier: MPL-2.0
Attributed collectively (common for files written by multiple contributors, or where individual attribution isn't useful):
// This file is part of Eigen, a lightweight C++ template library // for linear algebra. // // Copyright (C) <year> The Eigen Authors. // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // SPDX-License-Identifier: MPL-2.0
Markdown docs, generated files (*.in), and binary assets that can‘t carry inline headers are covered by path annotations in REUSE.toml — add your path there if you’re creating one.
This is non-negotiable.
.agents/provenance.md.\note block is enough.Show where a change comes from. We encourage you to link, in the merge request description, the publicly available sources that support your code: the ISA or architecture manual, the vendor's optimization guide or intrinsics reference, the paper or standard an algorithm follows, the documented API a backend relies on. Original research is just as welcome — your own microbenchmarks of the hardware, measurements of other libraries from outside, numerical experiments, new algorithms and derivations — provided you have the right to contribute it; include its evidence (the reproducer, the method and results, the derivation) instead of a link. This helps most with hardware-specific optimizations and new features, where it lets a reviewer check the change against its sources and see that everything it relies on is public or published with it.
user.name and user.email in your git config are set to credit you correctly.The Eigen Authors attribution is fine when individual credit isn’t useful.Format: Area: short imperative subject.
Examples (from recent history):
BDCSVD: fix edge caseGPU: Drop direct LruCache.h include from CuBlasSupport.hci: drop CodeRabbit summaryTriangularView: alias-aware fallback for structured-diagonal product fast pathKeep the subject under ~72 characters; use the body for the why, not the what — the diff already shows what changed. Reference issues by #<n> when relevant.
Eigen aspires to state-of-the-art on two axes — performance and numerical accuracy / IEEE-754 conformance — and treats them as separate goals that are sometimes in tension.
EIGEN_GEMM_THREADPOOL) and covers a subset of operations. The Tensor module is multi-core by design via ThreadPoolDevice.log(0), pow(0, 0)) the bar is exact conformance to IEEE 754 / ISO C / C++ specifications, with cppreference as the authoritative spec. Special-value handling is not subject to the few-ULPs trade-off.For decompositions and solvers specifically, the bar is matching LAPACK on conditioning, pivoting strategy, and backward stability. Don't trade numerical robustness for speed in those code paths without explicit sign-off.
Some contrib/ modules carry stability guarantees beyond what the directory name suggests:
contrib/Eigen/Tensor and Eigen/ThreadPool together form TensorFlow's core compute backend. The contrib/ location means looser API-stability guarantees — it does not mean low-traffic or low-stakes. Breaking changes to header layout, signatures, semantics, or contraction / reduction kernel performance ripple into every TensorFlow build. Prefer additive changes, keep header paths stable, run contrib/test/tensor_* before submitting, and call out any behaviour change prominently in the MR description.AGENTS.md — repository-wide agent contract, standard workflow, essential Eigen hazards, and the map to task-specific guidance.README.md — high-level project description and pointers to the websites.CHANGELOG.md — release-by-release notes.Thank you for contributing to Eigen!