// Benchmarks for the masked partial-packet ("segment") tail of vectorized
// assignments -- the path gated by internal::has_packet_segment<Packet>.
// See libeigen/eigen#3083 (the regression) and #3086 (segment-tail placement).
//
// Part A measures end-to-end assignments whose length is not a multiple of
// the packet size, so the tail loop is on the hot path:
//   * fixed-size  -> LinearVectorizedTraversal / CompleteUnrolling
//                    (compile-time tail count; the #3083 regression shape)
//   * dynamic     -> LinearVectorizedTraversal / NoUnrolling
//                    (runtime tail count)
// Part A's destinations are not read back, so apart from DynChain it does NOT
// exercise the store-to-load forwarding hazard -- see Part C.
//
// Part B is a direct A/B of the segment primitives (ploaduSegment /
// pstoreuSegment) against an equivalent scalar loop, swept over the tail
// length. This isolates the masked load/store hardware cost (e.g. AVX2
// vmaskmov) and the store-to-load forwarding stall, and is the data that
// drives the per-ISA has_packet_segment decision.
//
// Part C runs the #3083 regression kernels: chained small fixed-size matrix
// ops where each result is consumed by the next. A partial-packet tail store
// then collides with the consumer's packet load -- the store-to-load
// forwarding hazard that makes a masked tail far more costly than a scalar
// one. This is the cost Parts A and B cannot see in isolation. Chained/Rotation
// additionally covers the lazy-product shape, whose tail is reached through
// SliceVectorizedTraversal with InnerUnrolling and through the product
// evaluator's own partial loads, not through LinearVectorizedTraversal.
//
// Part D takes the same traversal as Chained/Rotation but streams over a runtime
// outer size with nothing reloading the destination, so the segment amortizes a
// source evaluation instead of stalling a consumer. It is the shape that decides
// how narrowly the scalar tail may be applied.
//
// The active packet size and the value of has_packet_segment per scalar type
// are emitted as Google Benchmark custom context, so a captured run is
// self-describing. To sweep ISAs, build once per target, e.g.:
//   g++ -O3 -DNDEBUG -std=c++17 -msse4.2      bench_segment_tail.cpp ...
//   g++ -O3 -DNDEBUG -std=c++17 -mavx         bench_segment_tail.cpp ...
//   g++ -O3 -DNDEBUG -std=c++17 -mavx2 -mfma  bench_segment_tail.cpp ...
//   g++ -O3 -DNDEBUG -std=c++17 -march=native bench_segment_tail.cpp ...
// or, via CMake, configure benchmarks/ with -DCMAKE_CXX_FLAGS=<isa flags>.
//
// SPDX-FileCopyrightText: The Eigen Authors
// SPDX-License-Identifier: MPL-2.0

#include <benchmark/benchmark.h>

#include <complex>
#include <cstdint>
#include <string>
#include <tuple>

#include <Eigen/Core>
#include <Eigen/LU>

using namespace Eigen;

namespace {

// Capacity of the Part B scratch buffers (Buffers<T>). Must be >= the largest
// packet size of any benchmarked scalar type, since the primitives load and
// store a full packet; the static_assert in Buffers enforces it.
constexpr int kMaxCount = 16;

// ---------------------------------------------------------------------------
// Records, per scalar type, the packet size in use and the value of
// has_packet_segment for the active ISA. Emitted as Google Benchmark custom
// context so it appears once in the report header and in any --benchmark_out
// JSON, making the captured baseline self-describing.
// ---------------------------------------------------------------------------
template <typename T>
void add_trait_context(const char* name) {
  using Packet = typename internal::packet_traits<T>::type;
  constexpr int PacketSize = internal::unpacket_traits<Packet>::size;
  constexpr bool HasSegment = internal::has_packet_segment<Packet>::value;
  benchmark::AddCustomContext(
      std::string("segment.") + name,
      "PacketSize=" + std::to_string(PacketSize) + " has_packet_segment=" + (HasSegment ? "true" : "false"));
}

// ===========================================================================
// Part A : assignment-level tail benchmarks
// ===========================================================================

// Fixed-size column vector: dst = a + b, with N a compile-time constant.
// When N % PacketSize != 0 the completely-unrolled assignment ends in a
// compile-time-length segment tail.
template <typename T, int N>
void BM_FixedAssign(benchmark::State& state) {
  using Vec = Matrix<T, N, 1>;
  Vec a = Vec::Random();
  Vec b = Vec::Random();
  Vec dst = Vec::Random();
  for (auto _ : state) {
    benchmark::DoNotOptimize(a.data());
    benchmark::DoNotOptimize(b.data());
    dst = a + b;
    benchmark::DoNotOptimize(dst.data());
    benchmark::ClobberMemory();
  }
  state.SetBytesProcessed(state.iterations() * static_cast<int64_t>(N) * sizeof(T) * 3);
}

// Dynamic-size column vector: dst = a + b, with a runtime length that is not a
// multiple of the packet size, so the NoUnrolling tail loop runs every call.
template <typename T>
void BM_DynamicAssign(benchmark::State& state) {
  const Index size = state.range(0);
  Matrix<T, Dynamic, 1> a = Matrix<T, Dynamic, 1>::Random(size);
  Matrix<T, Dynamic, 1> b = Matrix<T, Dynamic, 1>::Random(size);
  Matrix<T, Dynamic, 1> dst = Matrix<T, Dynamic, 1>::Random(size);
  for (auto _ : state) {
    benchmark::DoNotOptimize(a.data());
    benchmark::DoNotOptimize(b.data());
    dst = a + b;
    benchmark::DoNotOptimize(dst.data());
    benchmark::ClobberMemory();
  }
  state.SetBytesProcessed(state.iterations() * static_cast<int64_t>(size) * sizeof(T) * 3);
}

// Dynamic-size chain: the second assignment reloads tmp right after the first stores it, so the
// tail store sits on the critical path. A masked store does not forward to that reload.
template <typename T>
void BM_DynamicChain(benchmark::State& state) {
  const Index size = state.range(0);
  using Vec = Matrix<T, Dynamic, 1>;
  Vec a = Vec::Random(size), b = Vec::Random(size), c = Vec::Random(size), tmp(size), dst(size);
  for (auto _ : state) {
    benchmark::DoNotOptimize(a.data());
    benchmark::DoNotOptimize(b.data());
    benchmark::DoNotOptimize(tmp.data());
    tmp = a + b;
    benchmark::ClobberMemory();
    dst = tmp.cwiseProduct(c);
    benchmark::DoNotOptimize(dst.data());
    benchmark::ClobberMemory();
  }
}

// ===========================================================================
// Part B : segment-primitive A/B micro-benchmarks
//
// Each pair (segment vs scalar) is registered over the same count range so the
// reports line up. count is taken from state.range(0): runtime for the
// non-CT variants (matches the dynamic tail), compile-time for the *_CT
// variants (matches the completely-unrolled tail).
// ===========================================================================

template <typename T>
struct Buffers {
  static_assert(kMaxCount >= internal::unpacket_traits<typename internal::packet_traits<T>::type>::size,
                "kMaxCount is smaller than this type's packet size: the scratch buffers cannot hold a full packet");
  EIGEN_ALIGN_MAX T src[kMaxCount];
  EIGEN_ALIGN_MAX T dst[kMaxCount];
  Buffers() {
    for (int i = 0; i < kMaxCount; ++i) {
      src[i] = T(i + 1);
      dst[i] = T(0);
    }
  }
};

// --- runtime-count store: masked segment store vs scalar store loop ---------
template <typename T>
void BM_PrimSegmentStore(benchmark::State& state) {
  using Packet = typename internal::packet_traits<T>::type;
  constexpr int PacketSize = internal::unpacket_traits<Packet>::size;
  const Index count = state.range(0);
  if (PacketSize <= 1 || count > PacketSize) {
    state.SkipWithError("count exceeds packet size");
    return;
  }
  Buffers<T> buf;
  Packet p = internal::ploadu<Packet>(buf.src);
  for (auto _ : state) {
    benchmark::DoNotOptimize(p);
    internal::pstoreuSegment<T, Packet>(buf.dst, p, 0, count);
    benchmark::DoNotOptimize(buf.dst);
    benchmark::ClobberMemory();
  }
  state.SetItemsProcessed(state.iterations() * count);
}

template <typename T>
void BM_PrimScalarStore(benchmark::State& state) {
  using Packet = typename internal::packet_traits<T>::type;
  constexpr int PacketSize = internal::unpacket_traits<Packet>::size;
  const Index count = state.range(0);
  if (PacketSize <= 1 || count > PacketSize) {
    state.SkipWithError("count exceeds packet size");
    return;
  }
  Buffers<T> buf;
  for (auto _ : state) {
    benchmark::DoNotOptimize(buf.src);
    for (Index k = 0; k < count; ++k) buf.dst[k] = buf.src[k];
    benchmark::DoNotOptimize(buf.dst);
    benchmark::ClobberMemory();
  }
  state.SetItemsProcessed(state.iterations() * count);
}

// --- runtime-count store+reload: captures store-to-load forwarding stalls ---
template <typename T>
void BM_PrimSegmentStoreReload(benchmark::State& state) {
  using Packet = typename internal::packet_traits<T>::type;
  constexpr int PacketSize = internal::unpacket_traits<Packet>::size;
  const Index count = state.range(0);
  if (PacketSize <= 1 || count > PacketSize) {
    state.SkipWithError("count exceeds packet size");
    return;
  }
  Buffers<T> buf;
  Packet p = internal::ploadu<Packet>(buf.src);
  Packet acc = internal::pset1<Packet>(T(0));
  for (auto _ : state) {
    benchmark::DoNotOptimize(p);
    internal::pstoreuSegment<T, Packet>(buf.dst, p, 0, count);
    benchmark::DoNotOptimize(buf.dst);
    Packet q = internal::ploaduSegment<Packet>(buf.dst, 0, count);
    acc = internal::padd(acc, q);
    benchmark::DoNotOptimize(acc);
  }
  state.SetItemsProcessed(state.iterations() * count);
}

template <typename T>
void BM_PrimScalarStoreReload(benchmark::State& state) {
  using Packet = typename internal::packet_traits<T>::type;
  constexpr int PacketSize = internal::unpacket_traits<Packet>::size;
  const Index count = state.range(0);
  if (PacketSize <= 1 || count > PacketSize) {
    state.SkipWithError("count exceeds packet size");
    return;
  }
  Buffers<T> buf;
  for (auto _ : state) {
    benchmark::DoNotOptimize(buf.src);
    for (Index k = 0; k < count; ++k) buf.dst[k] = buf.src[k];
    benchmark::DoNotOptimize(buf.dst);
    // acc is reset every iteration: a persistent accumulator would grow without
    // bound over the benchmark's iterations -- signed-integer overflow (UB) for
    // integer T. Reset keeps the reload + add live without that.
    T acc = T(0);
    for (Index k = 0; k < count; ++k) acc += buf.dst[k];
    benchmark::DoNotOptimize(acc);
  }
  state.SetItemsProcessed(state.iterations() * count);
}

// --- overlapping full-width store+reload: one unmasked packet, count-free ---
// Models the "store a full packet ending at size" tail strategy: valid for a
// plain assignment when size >= PacketSize. Mask-free, so it is available on
// every ISA (including SSE/NEON), and a full-width store forwards cleanly to a
// same-width reload -- unlike a masked store. Cost is independent of the tail
// length, so this is registered once per type rather than swept over count.
template <typename T>
void BM_PrimOverlapStoreReload(benchmark::State& state) {
  using Packet = typename internal::packet_traits<T>::type;
  constexpr int PacketSize = internal::unpacket_traits<Packet>::size;
  if (PacketSize <= 1) {
    state.SkipWithError("type not vectorized");
    return;
  }
  Buffers<T> buf;
  Packet p = internal::ploadu<Packet>(buf.src);
  Packet acc = internal::pset1<Packet>(T(0));
  for (auto _ : state) {
    benchmark::DoNotOptimize(p);
    internal::pstoreu<T, Packet>(buf.dst, p);
    benchmark::DoNotOptimize(buf.dst);
    Packet q = internal::ploadu<Packet>(buf.dst);
    acc = internal::padd(acc, q);
    benchmark::DoNotOptimize(acc);
  }
  state.SetItemsProcessed(state.iterations() * PacketSize);
}

// --- runtime-count load: masked segment load vs scalar load loop -----------
template <typename T>
void BM_PrimSegmentLoad(benchmark::State& state) {
  using Packet = typename internal::packet_traits<T>::type;
  constexpr int PacketSize = internal::unpacket_traits<Packet>::size;
  const Index count = state.range(0);
  if (PacketSize <= 1 || count > PacketSize) {
    state.SkipWithError("count exceeds packet size");
    return;
  }
  Buffers<T> buf;
  Packet acc = internal::pset1<Packet>(T(0));
  for (auto _ : state) {
    benchmark::DoNotOptimize(buf.src);
    Packet q = internal::ploaduSegment<Packet>(buf.src, 0, count);
    acc = internal::padd(acc, q);
    benchmark::DoNotOptimize(acc);
  }
  state.SetItemsProcessed(state.iterations() * count);
}

template <typename T>
void BM_PrimScalarLoad(benchmark::State& state) {
  using Packet = typename internal::packet_traits<T>::type;
  constexpr int PacketSize = internal::unpacket_traits<Packet>::size;
  const Index count = state.range(0);
  if (PacketSize <= 1 || count > PacketSize) {
    state.SkipWithError("count exceeds packet size");
    return;
  }
  Buffers<T> buf;
  for (auto _ : state) {
    benchmark::DoNotOptimize(buf.src);
    // acc is reset every iteration -- see BM_PrimScalarStoreReload.
    T acc = T(0);
    for (Index k = 0; k < count; ++k) acc += buf.src[k];
    benchmark::DoNotOptimize(acc);
  }
  state.SetItemsProcessed(state.iterations() * count);
}

#ifdef EIGEN_VECTORIZE_AVX
void BM_ComplexHalfSegmentLoad(benchmark::State& state) {
  using Packet = typename internal::find_packet_by_size<std::complex<float>, 2>::type;
  const Index begin = state.range(0), count = state.range(1);
  Buffers<std::complex<float>> buf;
  const std::complex<float>* input = buf.src + 1;
  std::complex<float> output[2];
  internal::pstoreu(output, internal::ploaduSegment<Packet>(input, begin, count));
  for (Index i = 0; i < 2; ++i) {
    const std::complex<float> expected = i >= begin && i < begin + count ? input[i] : std::complex<float>(0);
    if (output[i] != expected) {
      state.SkipWithError("complex half-packet segment differs from scalar reference");
      return;
    }
  }
  for (auto _ : state) {
    benchmark::DoNotOptimize(buf.src);
    Packet packet = internal::ploaduSegment<Packet>(input, begin, count);
    benchmark::DoNotOptimize(packet);
  }
  state.SetItemsProcessed(state.iterations());
}
#endif

// --- compile-time-count store: matches the completely-unrolled tail --------
// Here the scalar alternative is itself fully unrolled (no loop), which is why
// it can beat a masked store for tiny tails.
template <typename T, int Count>
void BM_PrimSegmentStoreCT(benchmark::State& state) {
  using Packet = typename internal::packet_traits<T>::type;
  constexpr int PacketSize = internal::unpacket_traits<Packet>::size;
  if (PacketSize <= 1 || Count > PacketSize) {
    state.SkipWithError("count exceeds packet size");
    return;
  }
  Buffers<T> buf;
  Packet p = internal::ploadu<Packet>(buf.src);
  for (auto _ : state) {
    benchmark::DoNotOptimize(p);
    internal::pstoreuSegment<T, Packet>(buf.dst, p, 0, Count);
    benchmark::DoNotOptimize(buf.dst);
    benchmark::ClobberMemory();
  }
  state.SetItemsProcessed(state.iterations() * Count);
}

template <typename T, int Count>
void BM_PrimScalarStoreCT(benchmark::State& state) {
  using Packet = typename internal::packet_traits<T>::type;
  constexpr int PacketSize = internal::unpacket_traits<Packet>::size;
  if (PacketSize <= 1 || Count > PacketSize) {
    state.SkipWithError("count exceeds packet size");
    return;
  }
  Buffers<T> buf;
  for (auto _ : state) {
    benchmark::DoNotOptimize(buf.src);
    EIGEN_UNROLL_LOOP
    for (int k = 0; k < Count; ++k) buf.dst[k] = buf.src[k];
    benchmark::DoNotOptimize(buf.dst);
    benchmark::ClobberMemory();
  }
  state.SetItemsProcessed(state.iterations() * Count);
}

// ===========================================================================
// Part C : chained fixed-size kernels (results consumed immediately)
//
// The #3083 regression kernels. Unlike Part A, each assignment's result feeds
// the next op, so a partial-packet tail store is followed by a packet load of
// the same destination. That store-to-load forwarding hazard is what makes a
// masked (or overlapping) tail far more costly than a scalar one -- it is only
// visible when the result is consumed, which these benchmarks do and Part A
// deliberately does not. These are the kernels that reflect the real cost.
// ===========================================================================

// #3083 Example 2: double 3x3 inverse() * t -- the headline regression.
EIGEN_DONT_INLINE void kernel_inverse(const Vector3d& a, const Vector3d& b, const Vector3d& c, const Matrix3d& R,
                                      const Vector3d& t, Vector3d& result) {
  Matrix3d A;
  A << a, -R * b, c;
  result = A.inverse() * t;
}

void BM_Chained_Inverse3x3(benchmark::State& state) {
  Vector3d a = Vector3d::Random(), b = Vector3d::Random(), c = Vector3d::Random(), t = Vector3d::Random(), result;
  Matrix3d R = Matrix3d::Random();
  for (auto _ : state) {
    benchmark::DoNotOptimize(a);
    benchmark::DoNotOptimize(b);
    benchmark::DoNotOptimize(R);
    kernel_inverse(a, b, c, R, t, result);
    benchmark::DoNotOptimize(result);
    benchmark::ClobberMemory();
  }
}

// #3083 Example 1: camera kernel chaining Matrix<double,2,3> blocks.
using Blk23 = Matrix<double, 2, 3, RowMajor>;
using Blocks5 = std::tuple<Blk23, Blk23, Blk23, Blk23, Blk23>;

EIGEN_DONT_INLINE void kernel_camera(const Matrix3d& A, const Matrix3d& B, const Vector3d& u, const Vector3d& v,
                                     const Vector3d& w, const Vector3d& x, const Vector4d& params, Vector2d& output,
                                     Blocks5& blocks) {
  const Vector3d a = A * u + v;
  const Vector3d b = B.transpose() * (a - w);
  const Vector3d c = b - x;
  const double iz = 1.0 / c.z();
  const double iz2 = iz * iz;
  const double k0 = params(0), k1 = params(1);
  Blk23 J;
  J << k0 * iz, 0.0, -k0 * c.x() * iz2, 0.0, k1 * iz, -k1 * c.y() * iz2;
  std::get<0>(blocks) = J * B.transpose();
  std::get<1>(blocks) = std::get<0>(blocks) * A;
  std::get<2>(blocks) = -std::get<1>(blocks);
  std::get<3>(blocks) = std::get<0>(blocks) + std::get<1>(blocks);
  std::get<4>(blocks) = std::get<3>(blocks) - std::get<2>(blocks);
  output << k0 * c.x() * iz + params(2), k1 * c.y() * iz + params(3);
}

void BM_Chained_Camera(benchmark::State& state) {
  Matrix3d A = Matrix3d::Random(), B = Matrix3d::Random();
  Vector3d u = Vector3d::Random(), v = Vector3d::Random(), w = Vector3d::Random(), x = Vector3d::Random();
  Vector4d params = Vector4d::Random();
  Vector2d output;
  Blocks5 blocks;
  for (auto _ : state) {
    benchmark::DoNotOptimize(A);
    benchmark::DoNotOptimize(B);
    benchmark::DoNotOptimize(u);
    kernel_camera(A, B, u, v, w, x, params, output, blocks);
    benchmark::DoNotOptimize(&blocks);
    benchmark::DoNotOptimize(output);
    benchmark::ClobberMemory();
  }
}

// Direct chained Matrix<double,2,3> sums: isolates the 6-element tail with a
// read-after-write dependency between consecutive assignments.
void BM_Chained_Block23(benchmark::State& state) {
  Blk23 m0 = Blk23::Random(), m1 = Blk23::Random(), m2 = Blk23::Random(), m3 = Blk23::Random();
  for (auto _ : state) {
    benchmark::DoNotOptimize(m0);
    m1 = m0 + m1;
    m2 = m1 + m2;
    m3 = m2 + m3;
    benchmark::DoNotOptimize(m3);
    benchmark::ClobberMemory();
  }
}

// #3083 Example A: the matrix algebra of one IMU integration step. Its 3x3
// products are lazy, so unlike the kernels above the destination assignment
// takes SliceVectorizedTraversal with InnerUnrolling, and the product evaluator
// itself loads a partial packet. Neither path was covered by the kernels above,
// which is why this one kept a masked tail after !2581.
void BM_Chained_Rotation(benchmark::State& state) {
  Matrix3d S = Matrix3d::Random(), R = Matrix3d::Random(), Xi = Matrix3d::Random();
  Vector3d a = Vector3d::Random(), v = Vector3d::Zero();
  const double dt = 0.005;
  for (auto _ : state) {
    benchmark::DoNotOptimize(S);
    benchmark::DoNotOptimize(R);
    benchmark::DoNotOptimize(a);
    const Matrix3d S2 = S * S;
    Xi = dt * Matrix3d::Identity() + 0.5 * dt * dt * S + (dt * dt * dt / 6.0) * S2;
    v += R * Xi * a;
    benchmark::DoNotOptimize(Xi);
    benchmark::DoNotOptimize(v);
    benchmark::ClobberMemory();
  }
}

// ===========================================================================
// Part D : streaming slices (compile-time inner size, runtime outer size)
//
// SliceVectorizedTraversal with InnerUnrolling, as in Chained/Rotation, but the
// tail is paid once per column of a long runtime outer loop and no consumer
// reloads the destination. Sqrt makes one packet evaluation of the source far
// cheaper than PacketSize scalar ones, so unlike Part C this shape wants the
// masked segment; the copy variant is the cheap-source control.
// ===========================================================================

template <typename T, int Rows>
void BM_SliceCopy(benchmark::State& state) {
  const Index cols = state.range(0);
  using Mat = Matrix<T, Dynamic, Dynamic>;
  Mat src = Mat::Random(Rows + 9, cols), dst = Mat::Zero(Rows + 9, cols);
  for (auto _ : state) {
    benchmark::DoNotOptimize(src.data());
    dst.template topRows<Rows>() = src.template topRows<Rows>();
    benchmark::DoNotOptimize(dst.data());
    benchmark::ClobberMemory();
  }
  state.SetBytesProcessed(state.iterations() * Rows * cols * static_cast<int64_t>(sizeof(T)) * 2);
}

template <typename T, int Rows>
void BM_SliceSqrt(benchmark::State& state) {
  const Index cols = state.range(0);
  using Mat = Matrix<T, Dynamic, Dynamic>;
  Mat src = Mat::Random(Rows + 9, cols).cwiseAbs(), dst = Mat::Zero(Rows + 9, cols);
  for (auto _ : state) {
    benchmark::DoNotOptimize(src.data());
    dst.template topRows<Rows>() = src.template topRows<Rows>().array().sqrt().matrix();
    benchmark::DoNotOptimize(dst.data());
    benchmark::ClobberMemory();
  }
  state.SetBytesProcessed(state.iterations() * Rows * cols * static_cast<int64_t>(sizeof(T)) * 2);
}

// ===========================================================================
// Registration
//
// Done programmatically (rather than via the BENCHMARK macro) so that Part B's
// tail count is clamped to the packet size actually in use: the report then
// contains no inapplicable count > PacketSize entries, whatever ISA the source
// was compiled for.
// ===========================================================================

template <typename T>
const char* type_tag();
template <>
const char* type_tag<float>() {
  return "f32";
}
template <>
const char* type_tag<double>() {
  return "f64";
}
template <>
const char* type_tag<int32_t>() {
  return "i32";
}
template <>
const char* type_tag<int64_t>() {
  return "i64";
}
template <>
const char* type_tag<std::complex<float>>() {
  return "cf32";
}
template <>
const char* type_tag<std::complex<double>>() {
  return "cf64";
}

template <typename T>
int packet_size() {
  return internal::unpacket_traits<typename internal::packet_traits<T>::type>::size;
}

// Part A : fixed-size tails. Exact multiples (8/16/32/64) act as no-tail
// controls; the rest cover a spread of remainders across SSE/AVX/AVX-512.
template <typename T, int N>
void add_fixed() {
  benchmark::RegisterBenchmark(std::string("FixedAssign/") + type_tag<T>() + "/" + std::to_string(N),
                               &BM_FixedAssign<T, N>);
}

template <typename T>
void add_all_fixed() {
  add_fixed<T, 8>();
  add_fixed<T, 9>();
  add_fixed<T, 11>();
  add_fixed<T, 15>();
  add_fixed<T, 16>();
  add_fixed<T, 17>();
  add_fixed<T, 23>();
  add_fixed<T, 32>();
  add_fixed<T, 33>();
  add_fixed<T, 47>();
  add_fixed<T, 64>();
  add_fixed<T, 65>();
}

// Part A : dynamic-size tails. Small sizes keep the tail a meaningful fraction;
// 1025 confirms there is no regression once the tail is amortized. The multiples
// of 16 have an empty tail for every packet up to 512 bits, so the masked op never
// runs: they are the control, isolating code size and layout from the tail itself.
template <typename T>
void add_dynamic() {
  auto* b = benchmark::RegisterBenchmark(std::string("DynAssign/") + type_tag<T>(), &BM_DynamicAssign<T>);
  for (int s : {15, 16, 17, 31, 32, 33, 63, 64, 65, 127, 128, 129, 255, 256, 1024, 1025}) b->Arg(s);
  auto* c = benchmark::RegisterBenchmark(std::string("DynChain/") + type_tag<T>(), &BM_DynamicChain<T>);
  for (int s : {3, 7, 15, 17, 33, 129, 1025}) c->Arg(s);
}

// Part B : segment vs scalar primitives, runtime count 1..PacketSize.
void add_prim_range(const std::string& name, void (*fn)(benchmark::State&), int ps) {
  auto* b = benchmark::RegisterBenchmark(name, fn);
  for (int c = 1; c <= ps; ++c) b->Arg(c);
}

template <typename T>
void add_prim() {
  const int ps = packet_size<T>();
  if (ps <= 1) return;  // type not vectorized on this ISA
  const std::string tag = type_tag<T>();
  add_prim_range("Prim/Store/seg/" + tag, &BM_PrimSegmentStore<T>, ps);
  add_prim_range("Prim/Store/scl/" + tag, &BM_PrimScalarStore<T>, ps);
  add_prim_range("Prim/StoreReload/seg/" + tag, &BM_PrimSegmentStoreReload<T>, ps);
  add_prim_range("Prim/StoreReload/scl/" + tag, &BM_PrimScalarStoreReload<T>, ps);
  benchmark::RegisterBenchmark("Prim/StoreReload/ovl/" + tag, &BM_PrimOverlapStoreReload<T>);
  add_prim_range("Prim/Load/seg/" + tag, &BM_PrimSegmentLoad<T>, ps);
  add_prim_range("Prim/Load/scl/" + tag, &BM_PrimScalarLoad<T>, ps);
}

// Part B : compile-time count store (matches the completely-unrolled tail).
template <typename T, int Count>
void add_prim_ct() {
  if (Count > packet_size<T>()) return;
  const std::string tag = std::string(type_tag<T>()) + "/" + std::to_string(Count);
  benchmark::RegisterBenchmark("PrimCT/Store/seg/" + tag, &BM_PrimSegmentStoreCT<T, Count>);
  benchmark::RegisterBenchmark("PrimCT/Store/scl/" + tag, &BM_PrimScalarStoreCT<T, Count>);
}

template <typename T>
void add_all_prim_ct() {
  add_prim_ct<T, 1>();
  add_prim_ct<T, 3>();
  add_prim_ct<T, 5>();
  add_prim_ct<T, 7>();
}

// Part D : one fixed inner size that is not a packet multiple for any supported
// packet width, swept over outer sizes that span the cache hierarchy.
template <typename T>
void add_slice() {
  const std::string tag = std::string("/") + type_tag<T>() + "/7";
  for (auto entry : {std::make_pair("Slice/copy" + tag, &BM_SliceCopy<T, 7>),
                     std::make_pair("Slice/sqrt" + tag, &BM_SliceSqrt<T, 7>)}) {
    auto* b = benchmark::RegisterBenchmark(entry.first, entry.second);
    for (int c : {64, 1024, 4096}) b->Arg(c);
  }
}

int RegisterAll() {
  add_trait_context<float>("f32");
  add_trait_context<double>("f64");
  add_trait_context<int32_t>("i32");
  add_trait_context<int64_t>("i64");
  add_trait_context<std::complex<float>>("cf32");
  add_trait_context<std::complex<double>>("cf64");

  add_all_fixed<float>();
  add_all_fixed<double>();
  add_dynamic<float>();
  add_dynamic<double>();

  add_prim<float>();
  add_prim<double>();
  add_prim<int32_t>();
  add_prim<int64_t>();
  add_prim<std::complex<float>>();
  add_prim<std::complex<double>>();
#ifdef EIGEN_VECTORIZE_AVX
  benchmark::RegisterBenchmark("Prim/Load/seg/half_cf32", &BM_ComplexHalfSegmentLoad)
      ->Args({0, 0})
      ->Args({0, 1})
      ->Args({0, 2})
      ->Args({1, 0})
      ->Args({1, 1})
      ->Args({2, 0});
#endif

  add_all_prim_ct<float>();
  add_all_prim_ct<double>();

  benchmark::RegisterBenchmark("Chained/Inverse3x3", &BM_Chained_Inverse3x3);
  benchmark::RegisterBenchmark("Chained/Camera", &BM_Chained_Camera);
  benchmark::RegisterBenchmark("Chained/Block23", &BM_Chained_Block23);
  benchmark::RegisterBenchmark("Chained/Rotation", &BM_Chained_Rotation);

  add_slice<float>();
  add_slice<double>();
  return 0;
}

const int registered = RegisterAll();

}  // namespace

// main() is provided by benchmark::benchmark_main (linked via eigen_add_benchmark).
