// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// 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-FileCopyrightText: The Eigen Authors
// SPDX-License-Identifier: MPL-2.0

// SME GEMM kernel tests.
// Requires a compiler targeting SME2, e.g. -march=armv9.2-a+sme2, which selects
// the backend on its own; -DEIGEN_ARM64_USE_SME then makes a toolchain that
// cannot provide it fail the build rather than fall back to NEON.
// double and complex<double> additionally need FEAT_SME_F64F64 (+sme-f64f64, or
// a -mcpu that implies it); without it EIGEN_VECTORIZE_SME_F64F64 is undefined
// and they keep the generic kernel, so their subtests pack their cases through
// that path instead.

#include "product.h"

#include <cfenv>

// Without the right -march flags, __ARM_FEATURE_SME is undefined and
// EIGEN_VECTORIZE_SME never fires - the test would silently compile
// against the NEON GEBP kernel and pass, making this a useless no-op.
// Fail the build instead.
#if !defined(EIGEN_VECTORIZE_SME)
#error \
    "product_sme requires the SME backend.  Build with -march=armv9.2-a+sme2 " \
    "(see -DEIGEN_TEST_SME=ON in test/CMakeLists.txt for the typical CMake " \
    "invocation)."
#endif

// The backend is chosen from the compiler's target features; EIGEN_ARM64_USE_SME,
// which this test's CMake option passes, only turns a toolchain that cannot
// provide it into a build error. Assert that here, so a regression making
// selection depend on the opt-in again is caught rather than masked by it.
#if !defined(EIGEN_ARM64_SME_SELECTED)
#error "the SME backend was forced by EIGEN_ARM64_USE_SME rather than selected from the compiler's target features."
#endif

template <typename Scalar>
using SmeColMajorMat = Matrix<Scalar, Dynamic, Dynamic, ColMajor>;
template <typename Scalar>
using SmeRowMajorMat = Matrix<Scalar, Dynamic, Dynamic, RowMajor>;
template <typename Scalar>
using SmeVector = Matrix<Scalar, Dynamic, 1>;
template <typename Scalar>
using SmeColMajorStridedMat = Map<SmeColMajorMat<Scalar>, 0, Stride<Dynamic, Dynamic>>;
template <typename Scalar>
using SmeRowMajorStridedMat = Map<SmeRowMajorMat<Scalar>, 0, Stride<Dynamic, Dynamic>>;

// The logical micro-kernel block for Scalar (kSmeMr/kSmeNr for float and so
// on).  Sizes below are expressed in terms of it so each scalar sweeps its own
// block boundaries; sme_tile() is the ZA tile side at the SVL=512 design point,
// which is where the intra-block splits fall.  Complex scalars pair two tiles
// per accumulator, so their block is not square.
template <typename Scalar>
static constexpr int sme_mr() {
  return internal::sme_block<Scalar>::mr;
}
template <typename Scalar>
static constexpr int sme_nr() {
  return internal::sme_block<Scalar>::nr;
}
template <typename Scalar>
static constexpr int sme_tile() {
  return internal::sme_block<Scalar>::mr / internal::sme_block<Scalar>::kGridRows;
}

// svwhilelt_b* is overloaded only on the four fixed-width types, so forwarding
// the caller's own type would leave Index ambiguous wherever it is `long` while
// int64_t is `long long`, and deducing one type from both arguments would reject
// the literal-plus-Index bounds the packers pass.  Name every spelling Index
// takes, mix the two argument types, and check the predicate so the traits'
// widening cannot change which lanes are active.
// EIGEN_DONT_INLINE here and below: GCC (14.1 through trunk) inlines a __arm_locally_streaming function into a
// non-streaming caller without its mode switch, running the body as non-streaming SVE at that vector length.
template <typename Scalar, typename Begin, typename End = Begin>
EIGEN_DONT_INLINE __arm_locally_streaming static bool sme_whilelt_covers_first_lane_only() {
  using Traits = internal::sme_packet_traits<Scalar>;
  const svbool_t pg = Traits::whilelt(Begin(0), End(1));
  return svptest_first(Traits::ptrue(), pg) && svcntp_b8(Traits::ptrue(), pg) == 1;
}

template <typename Scalar>
static void test_whilelt_operand_types() {
  VERIFY((sme_whilelt_covers_first_lane_only<Scalar, int>()));
  VERIFY((sme_whilelt_covers_first_lane_only<Scalar, long>()));
  VERIFY((sme_whilelt_covers_first_lane_only<Scalar, long long>()));
  VERIFY((sme_whilelt_covers_first_lane_only<Scalar, Index>()));
  VERIFY((sme_whilelt_covers_first_lane_only<Scalar, int, Index>()));
}

// Column j of out (n rows, one streaming vector) receives the j-th operation's result.
template <typename Scalar>
EIGEN_DONT_INLINE __arm_locally_streaming static Scalar sme_packet_ops(Scalar* out, const Scalar* a, const Scalar* b,
                                                                       const Scalar* c, Index active) {
  using Traits = internal::sme_packet_traits<Scalar>;
  using Vec = typename Traits::type;
  const svbool_t all = Traits::ptrue();
  const svbool_t pg = Traits::whilelt(0, active);
  const Index n = Traits::size();
  const Vec va = internal::ploadu(all, a), vb = internal::ploadu(all, b), vc = internal::ploadu(all, c);
  internal::pstoreu(all, out, internal::pmadd(all, va, vb, vc));
  internal::pstoreu(all, out + n, internal::pnmadd(all, va, vb, vc));
  internal::pstoreu(all, out + 2 * n, internal::pmadd_m(pg, va, vb, vc));
  internal::pstoreu(all, out + 3 * n, internal::padd(all, va, vb));
  internal::pstoreu(all, out + 4 * n, internal::pmul(all, va, vb));
  internal::pstoreu(all, out + 5 * n, internal::pnegate(all, va));
  internal::pstoreu(pg, out + 6 * n, internal::pset1<Vec>(Scalar(7)));
  return internal::predux(pg, va);
}

// Operand order and predication of the packet layer, on small integers so every result is exact.
// a_i = i + 2, b_i = -(i + 3), c_i = 2i + 5 are pairwise distinct and never +-1, so swapping two
// operands of pmadd or pnmadd changes every lane: ab + c - (ac + b) = (b - c)(a - 1), and so on.
template <typename Scalar>
static void test_packet_ops() {
  using Vec = Matrix<Scalar, Dynamic, 1>;
  using Mat = Matrix<Scalar, Dynamic, Dynamic>;
  const Index n = internal::sme_packet_traits<Scalar>::size();
  const Vec a = Vec::LinSpaced(n, Scalar(2), Scalar(n + 1));
  const Vec b = Vec::LinSpaced(n, Scalar(-3), Scalar(-(n + 2)));
  const Vec c = Vec::LinSpaced(n, Scalar(5), Scalar(2 * n + 3));
  for (Index active = 0; active <= n; ++active) {
    Mat out = Mat::Constant(n, 7, Scalar(-1));
    const Scalar sum = sme_packet_ops(out.data(), a.data(), b.data(), c.data(), active);
    Mat ref(n, 7);
    ref.col(0) = a.cwiseProduct(b) + c;
    ref.col(1) = c - a.cwiseProduct(b);
    ref.col(2) = c;
    ref.col(2).head(active) = ref.col(0).head(active);
    ref.col(3) = a + b;
    ref.col(4) = a.cwiseProduct(b);
    ref.col(5) = -a;
    ref.col(6).setConstant(Scalar(-1));
    ref.col(6).head(active).setConstant(Scalar(7));
    VERIFY_IS_EQUAL(out, ref);
    VERIFY_IS_EQUAL(sum, a.head(active).sum());
  }
}

// Write one element into a packed panel of width w, in the layout the SME
// kernel reads: a real scalar lands at dst[k*w + r], a complex one splits into
// the depth step's real and imaginary halves.
template <typename Scalar>
static void set_packed(Scalar* panel, Index w, Index k, Index r, const Scalar& v) {
  panel[k * w + r] = v;
}
template <typename RealScalar>
static void set_packed(std::complex<RealScalar>* panel, Index w, Index k, Index r, const std::complex<RealScalar>& v) {
  RealScalar* p = reinterpret_cast<RealScalar*>(panel + k * w);
  p[r] = numext::real(v);
  p[w + r] = numext::imag(v);
}

template <typename InputMat, typename ResultMat, typename ResultMap>
static void verify_strided_result(int n, ResultMat& storage, const Stride<Dynamic, Dynamic>& stride) {
  InputMat A = InputMat::Random(n, n);
  InputMat B = InputMat::Random(n, n);
  ResultMap C(storage.data(), n, n, stride);
  C = ResultMat::Random(n, n);
  ResultMat c_before = C.eval();

  C.noalias() += A * B;

  ResultMat ref = c_before + (A.lazyProduct(B)).eval();
  ResultMat got = C;
  VERIFY_IS_APPROX(got, ref);
}

template <typename Scalar, typename InputMat>
static void test_general_strided_result(int n) {
  // General-stride C path: InputMat selects the source packers, while both C
  // strides are non-unit so sme_store_za_tile uses scalar scatter.
  SmeColMajorMat<Scalar> storage = SmeColMajorMat<Scalar>::Zero(2 * n, n);
  verify_strided_result<InputMat, SmeColMajorMat<Scalar>, SmeColMajorStridedMat<Scalar>>(
      n, storage, Stride<Dynamic, Dynamic>(/*outer=*/2 * n, /*inner=*/2));

  // Padding rows skipped by the strided Map should not be touched.
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < n; ++j) {
      VERIFY(storage(2 * i + 1, j) == Scalar(0));
    }
  }
}

template <typename Scalar>
static void test_rowmajor_strided_result(int n) {
  // RowMajor C path: inner stride is one, with padded columns after the Map.
  SmeRowMajorMat<Scalar> storage = SmeRowMajorMat<Scalar>::Zero(n, 2 * n);
  verify_strided_result<SmeRowMajorMat<Scalar>, SmeRowMajorMat<Scalar>, SmeRowMajorStridedMat<Scalar>>(
      n, storage, Stride<Dynamic, Dynamic>(/*outer=*/2 * n, /*inner=*/1));

  // Padding columns skipped by the strided Map should not be touched.
  for (int i = 0; i < n; ++i) {
    for (int j = n; j < 2 * n; ++j) {
      VERIFY(storage(i, j) == Scalar(0));
    }
  }
}

// A non-trivial alpha: complex where the scalar is, so the store's rotation of
// the accumulator is exercised rather than a plain rescale.
template <typename Scalar>
struct nontrivial_alpha_impl {
  static Scalar run() { return Scalar(1.375); }
};
template <typename RealScalar>
struct nontrivial_alpha_impl<std::complex<RealScalar>> {
  static std::complex<RealScalar> run() { return std::complex<RealScalar>(RealScalar(1.375), RealScalar(-0.625)); }
};

// Conjugated operands and a non-real alpha.
//
// blas_traits folds .adjoint()/.conjugate() and a scalar factor into the
// gebp_kernel's ConjugateLhs/ConjugateRhs and alpha rather than materializing a
// temporary, so these expressions are the only thing that reaches the complex
// kernel's FMOPA/FMOPS sign choices and its alpha-scaled store. The references
// materialize the conjugation first and multiply coefficient-wise, so they do
// not share a code path with what they check.
template <typename Scalar, typename LhsMat, typename RhsMat, typename ResMat>
static void verify_conjugated_products(int n) {
  const LhsMat A = LhsMat::Random(n, n);
  const RhsMat B = RhsMat::Random(n, n);
  const SmeColMajorMat<Scalar> Ap = A, Bp = B;
  const SmeColMajorMat<Scalar> Aa = Ap.adjoint().eval(), Ac = Ap.conjugate().eval();
  const SmeColMajorMat<Scalar> Ba = Bp.adjoint().eval(), Bc = Bp.conjugate().eval();
  const Scalar alpha = nontrivial_alpha_impl<Scalar>::run();

  ResMat C(n, n);
  C.setZero();
  C.noalias() += A.adjoint() * B;
  VERIFY_IS_APPROX(SmeColMajorMat<Scalar>(C), SmeColMajorMat<Scalar>(Aa.lazyProduct(Bp)));
  C.setZero();
  C.noalias() += A * B.adjoint();
  VERIFY_IS_APPROX(SmeColMajorMat<Scalar>(C), SmeColMajorMat<Scalar>(Ap.lazyProduct(Ba)));
  C.setZero();
  C.noalias() += A.adjoint() * B.adjoint();
  VERIFY_IS_APPROX(SmeColMajorMat<Scalar>(C), SmeColMajorMat<Scalar>(Aa.lazyProduct(Ba)));
  C.setZero();
  C.noalias() += A.conjugate() * B;
  VERIFY_IS_APPROX(SmeColMajorMat<Scalar>(C), SmeColMajorMat<Scalar>(Ac.lazyProduct(Bp)));
  C.setZero();
  C.noalias() += A * B.conjugate();
  VERIFY_IS_APPROX(SmeColMajorMat<Scalar>(C), SmeColMajorMat<Scalar>(Ap.lazyProduct(Bc)));
  C.setZero();
  C.noalias() += A.conjugate() * B.conjugate();
  VERIFY_IS_APPROX(SmeColMajorMat<Scalar>(C), SmeColMajorMat<Scalar>(Ac.lazyProduct(Bc)));
  C.setZero();
  C.noalias() += alpha * (A.adjoint() * B);
  VERIFY_IS_APPROX(SmeColMajorMat<Scalar>(C), SmeColMajorMat<Scalar>(alpha * Aa.lazyProduct(Bp)));

  // A deep rectangular product reaches GEMM even for half-tile output widths.
  const LhsMat deepA = LhsMat::Random(n, 65);
  const RhsMat deepB = RhsMat::Random(65, n);
  const ResMat initial = ResMat::Random(n, n);
  const SmeColMajorMat<Scalar> reference = deepA.lazyProduct(deepB);
  C = initial;
  C.noalias() += deepA * deepB;
  VERIFY_IS_APPROX(SmeColMajorMat<Scalar>(C), SmeColMajorMat<Scalar>(initial + reference));
  C = initial;
  C.noalias() += alpha * (deepA * deepB);
  VERIFY_IS_APPROX(SmeColMajorMat<Scalar>(C), SmeColMajorMat<Scalar>(initial + alpha * reference));
  // A real alpha takes the complex store's fused path: -1 from -=, and a
  // non-unit real scale.
  const Scalar real_alpha(typename NumTraits<Scalar>::Real(1.375));
  C = initial;
  C.noalias() -= deepA * deepB;
  VERIFY_IS_APPROX(SmeColMajorMat<Scalar>(C), SmeColMajorMat<Scalar>(initial - reference));
  C = initial;
  C.noalias() += real_alpha * (deepA * deepB);
  VERIFY_IS_APPROX(SmeColMajorMat<Scalar>(C), SmeColMajorMat<Scalar>(initial + real_alpha * reference));

#ifdef EIGEN_VECTORIZE_SME_F64F64
  // RowMajor GEMM normally transposes the computation. Call the packed kernel
  // too, so RowMajor C actually reaches its horizontal ZA slice store.
  if (n <= sme_tile<Scalar>()) {
    std::vector<Scalar> packedA(n * 65), packedB(n * 65);
    for (Index k = 0; k < 65; ++k) {
      for (Index i = 0; i < n; ++i) {
        set_packed(packedA.data(), Index(n), k, i, deepA(i, k));
        set_packed(packedB.data(), Index(n), k, i, deepB(k, i));
      }
    }
    for (Scalar scale : {Scalar(1), alpha, Scalar(-1), real_alpha}) {
      C = initial;
      internal::sme_gebp_dispatch<Scalar, false, false>::run(
          C.data(), Index(ResMat::IsRowMajor ? n : 1), Index(ResMat::IsRowMajor ? 1 : n), packedA.data(),
          packedB.data(), Index(n), Index(65), Index(n), scale, Index(65), Index(65), Index(0), Index(0));
      VERIFY_IS_APPROX(SmeColMajorMat<Scalar>(C), SmeColMajorMat<Scalar>(initial + scale * reference));
    }
  }
#endif
}

// Exercise the kc split path just above the SME blocking heuristic's depth cap
// (sme_max_kc in GeneralBlockPanelKernel.h, scaled by the scalar width).
template <typename Scalar>
static void test_deep_k_split() {
  constexpr int rows = 64;
  const int depth = int(2 * (Index(EIGEN_SME_MAX_KC) * Index(sizeof(float)) / Index(sizeof(Scalar)))) + 2;
  constexpr int cols = 64;
  SmeColMajorMat<Scalar> A = SmeColMajorMat<Scalar>::Random(rows, depth);
  SmeColMajorMat<Scalar> B = SmeColMajorMat<Scalar>::Random(depth, cols);
  SmeColMajorMat<Scalar> C = SmeColMajorMat<Scalar>::Random(rows, cols);
  SmeColMajorMat<Scalar> c_before = C;

  C.noalias() += A * B;

  VERIFY_IS_APPROX(C, c_before + (A.lazyProduct(B)).eval());
}

// LHS read in place: strides on either side of the 4 KB-multiple rule (packed versus in place), an odd stride
// and base offset, a sub-block at a row offset, and a depth tail, each checked against lazyProduct.
template <typename Scalar>
static void test_direct_lhs() {
  const Index kPage = 4096 / Index(sizeof(Scalar));
  const Index rows = 97, depth = 101, cols = 70;
  const Index strides[] = {rows + 32 + 1, kPage, kPage + 16, 2 * kPage + 16};
  for (Index lda : strides) {
    for (Index offset = 0; offset <= 1; ++offset) {
      SmeVector<Scalar> storage = SmeVector<Scalar>::Zero(lda * depth + 1);
      Map<SmeColMajorMat<Scalar>, 0, OuterStride<>> A(storage.data() + offset, rows + 32, depth, OuterStride<>(lda));
      A.setRandom();
      const SmeColMajorMat<Scalar> B = SmeColMajorMat<Scalar>::Random(depth, cols);
      const SmeColMajorMat<Scalar> C0 = SmeColMajorMat<Scalar>::Random(rows + 32, cols);
      SmeColMajorMat<Scalar> C = C0;
      C.noalias() += A * B;
      VERIFY_IS_APPROX(C, C0 + A.lazyProduct(B));
      SmeColMajorMat<Scalar> D = C0.middleRows(3, rows);
      D.noalias() += A.middleRows(3, rows) * B;
      VERIFY_IS_APPROX(D, C0.middleRows(3, rows) + A.middleRows(3, rows).lazyProduct(B));
    }
  }
#ifdef EIGEN_VECTORIZE_SME
  const int units = nbSmeUnits();
  VERIFY(units >= 0);
  setNbSmeUnits(1);
  VERIFY_IS_EQUAL(nbSmeUnits(), 1);
  setNbSmeUnits(units);
  VERIFY_IS_EQUAL(nbSmeUnits(), units);
#endif
  // An LHS packed once for all column blocks, where the first block reads it in place and a narrower last one, whose
  // panel spans more than EIGEN_SME_DIRECT_LHS_MAX_SPAN_BYTES, packs.
  {
    const Index big = Index(EIGEN_SME_DIRECT_LHS_MAX_SPAN_BYTES) / (2048 * Index(sizeof(Scalar))) + 2;
    const SmeColMajorMat<Scalar> Abig = SmeColMajorMat<Scalar>::Random(big, 2048);
    const auto A = Abig.topRows(256);
    const SmeColMajorMat<Scalar> B = SmeColMajorMat<Scalar>::Random(2048, 532);
    SmeColMajorMat<Scalar> C(256, 532);
    C.noalias() = A * B;
    VERIFY_IS_APPROX(C, A.lazyProduct(B));
  }
}

// Small K against large M and N (NEON depths and just past them), and a RHS of one panel read in place: up to
// half a panel wide always, up to a full panel within the span limit, with 4 KB-multiple strides.
template <typename Scalar>
static void test_small_k_and_single_panel_rhs() {
  const Index MR = sme_mr<Scalar>(), NR = sme_nr<Scalar>();
  for (Index k : {1, 2, 3, 5, 8, 17, 24, 25, 40}) {
    for (Index mn : {Index(130), 4 * MR + 3}) {
      const SmeColMajorMat<Scalar> A = SmeColMajorMat<Scalar>::Random(mn, k), B = SmeColMajorMat<Scalar>::Random(k, mn);
      SmeColMajorMat<Scalar> C = SmeColMajorMat<Scalar>::Random(mn, mn);
      const SmeColMajorMat<Scalar> C0 = C;
      C.noalias() += A * B;
      VERIFY_IS_APPROX(C, C0 + A.lazyProduct(B));
    }
  }
  const Index page = 4096 / Index(sizeof(Scalar));
  for (Index n : {Index(1), NR / 2 - 1, NR / 2, NR / 2 + 1, NR}) {
    for (Index lda : {5 * MR + 3, page, 2 * page + 1}) {
      for (Index depth : {Index(40), Index(301)}) {
        const Index rows = numext::mini(lda, 5 * MR + 3);
        SmeVector<Scalar> storage = SmeVector<Scalar>::Zero(lda * depth);
        Map<SmeColMajorMat<Scalar>, 0, OuterStride<>> A(storage.data(), rows, depth, OuterStride<>(lda));
        A.setRandom();
        const SmeColMajorMat<Scalar> B = SmeColMajorMat<Scalar>::Random(depth, n);
        SmeColMajorMat<Scalar> C = SmeColMajorMat<Scalar>::Random(rows, n);
        const SmeColMajorMat<Scalar> C0 = C;
        C.noalias() += A * B;
        VERIFY_IS_APPROX(C, C0 + A.lazyProduct(B));
      }
    }
  }
  // A single-panel RHS whose depth block spans more than EIGEN_SME_DIRECT_LHS_MAX_SPAN_BYTES packs the LHS.
  const Index kc = Index(EIGEN_SME_MAX_KC) * Index(sizeof(float)) / Index(sizeof(Scalar));
  const Index wide = page * Index(std::size_t(EIGEN_SME_DIRECT_LHS_MAX_SPAN_BYTES) / (std::size_t(kc) * 4096) + 1);
  SmeVector<Scalar> storage = SmeVector<Scalar>::Zero(wide * kc);
  Map<SmeColMajorMat<Scalar>, 0, OuterStride<>> A(storage.data(), 2 * MR + 5, kc, OuterStride<>(wide));
  A.setRandom();
  const SmeColMajorMat<Scalar> B = SmeColMajorMat<Scalar>::Random(kc, NR);
  SmeColMajorMat<Scalar> C = SmeColMajorMat<Scalar>::Zero(2 * MR + 5, NR);
  C.noalias() += A * B;
  VERIFY_IS_APPROX(C, A.lazyProduct(B));
}

// Disjoint parts per SME unit (2 and 3 units) against a serial product. product_threaded covers the thread pool;
// this reaches the OpenMP branch in an EIGEN_TEST_OPENMP build and runs serially otherwise.
template <typename Scalar>
static void test_disjoint_parts() {
  using Col = SmeColMajorMat<Scalar>;
  using Row = SmeRowMajorMat<Scalar>;
  const int saved = nbSmeUnits();
  const int shapes[][3] = {{301, 259, 131}, {200, 40, 1024}, {20, 700, 300}};
  for (int units : {2, 3}) {
    setNbSmeUnits(units);
    for (const auto& sh : shapes) {
      const Col A = Col::Random(sh[0], sh[2]), B = Col::Random(sh[2], sh[1]);
      const Col ref = A.lazyProduct(B);
      Col C(sh[0], sh[1]);
      C.noalias() = A * B;
      VERIFY_IS_APPROX(C, ref);
      Row R(sh[0], sh[1]);
      R.noalias() = A * B;
      VERIFY_IS_APPROX(Col(R), ref);
      Col big = Col::Random(sh[0] + 5, sh[1] + 3);
      Col expected = big;
      expected.block(2, 1, sh[0], sh[1]) += Scalar(1.5) * ref;
      big.block(2, 1, sh[0], sh[1]).noalias() += Scalar(1.5) * A * B;
      VERIFY_IS_APPROX(big, expected);
    }
  }
  setNbSmeUnits(saved);
}

// Streaming-mode entry and exit set every FP exception flag: products on each SME path, with exact results, must leave
// the caller's flags as they were.
template <typename Scalar, typename Product>
static void verify_fp_flags_kept(Product product) {
#if defined(EIGEN_HAS_OPENMP) || defined(EIGEN_GEMM_THREADPOOL)
  // A threaded build's parallelize_gemm sizes the thread count in floating point, which can raise FE_INEXACT.
  const int checked = FE_ALL_EXCEPT & ~FE_INEXACT;
#else
  const int checked = FE_ALL_EXCEPT;
#endif
  std::feclearexcept(FE_ALL_EXCEPT);
  product();
  VERIFY_IS_EQUAL(std::fetestexcept(checked), 0);
  std::feraiseexcept(FE_INVALID);
  product();
  VERIFY_IS_EQUAL(std::fetestexcept(checked), FE_INVALID);
  std::feclearexcept(FE_ALL_EXCEPT);
}

template <typename Scalar>
static void test_fp_flags() {
  using Col = SmeColMajorMat<Scalar>;
  using Row = SmeRowMajorMat<Scalar>;
  const Index MR = sme_mr<Scalar>(), NR = sme_nr<Scalar>();
  const Index m = 4 * MR + 3, n = 3 * NR + 5, k = 131;
  // Small integers keep every product exact, so no flag is legitimately raised.
  const Col A = Col::Random(m, k).unaryExpr([](const Scalar& x) { return Scalar(numext::round(numext::real(x) * 4)); });
  const Col B = Col::Random(k, n).unaryExpr([](const Scalar& x) { return Scalar(numext::round(numext::real(x) * 4)); });
  const Col S = Col::Identity(m, m) * Scalar(2) + Col::Ones(m, m), O = Col::Ones(m, n);
  // I plus a subdiagonal of ones: the solution of L x = 1 is 1, 0, 1, 0, ..., exact.
  Col L = Col::Identity(m, m);
  L.diagonal(-1).setOnes();
  const Col Tall = Col::Ones(1024, k), Thin = Col::Ones(k, NR / 2);
  Col C(m, n), D(1024, NR / 2);
  Row R(m, n);
  verify_fp_flags_kept<Scalar>([&] { C.noalias() = A * B; });
  verify_fp_flags_kept<Scalar>([&] { C.noalias() += A.conjugate() * B; });
  verify_fp_flags_kept<Scalar>([&] { R.noalias() = A * B; });
  verify_fp_flags_kept<Scalar>([&] { R.noalias() = Row(A) * Row(B); });
  verify_fp_flags_kept<Scalar>([&] { D.noalias() = Tall * Thin; });
  verify_fp_flags_kept<Scalar>([&] { C.noalias() = S.template selfadjointView<Lower>() * O; });
  verify_fp_flags_kept<Scalar>([&] { C.noalias() = S.template triangularView<Upper>() * O; });
  verify_fp_flags_kept<Scalar>([&] {
    Col X = O;
    L.template triangularView<Lower>().solveInPlace(X);
  });
}

// Tiny results (the NEON kernel and both sides of its routing), every storage order of A, B and C.
template <typename Scalar, int AO, int BO, int CO>
static void test_tiny_results_order() {
  using MA = Matrix<Scalar, Dynamic, Dynamic, AO>;
  using MB = Matrix<Scalar, Dynamic, Dynamic, BO>;
  using MC = Matrix<Scalar, Dynamic, Dynamic, CO>;
  const Index ps = Index(16 / sizeof(Scalar));
  for (Index m : {Index(1), Index(2), Index(3), ps, ps + 1, 2 * ps, 2 * ps + 1})
    for (Index n : {1, 2, 3, 5, 8, 9})
      for (Index k : {1, 5, 6, 7, 15, 16, 17, 64, 2049}) {
        const MA A = MA::Random(m, k);
        const MB B = MB::Random(k, n);
        const MC ref = A.lazyProduct(B);
        MC C = MC::Random(m, n);
        const MC C0 = C;
        C.noalias() = A * B;
        VERIFY_IS_APPROX(C, ref);
        C = C0;
        C.noalias() += A * B;
        VERIFY_IS_APPROX(C, C0 + ref);
        C = C0;
        C.noalias() -= Scalar(2) * A * B;
        VERIFY_IS_APPROX(C, C0 - Scalar(2) * ref);
        const MA At = A.transpose();
        C.noalias() = At.transpose() * B;
        VERIFY_IS_APPROX(C, ref);
      }
}

template <typename Scalar>
static void test_tiny_results() {
  test_tiny_results_order<Scalar, ColMajor, ColMajor, ColMajor>();
  test_tiny_results_order<Scalar, RowMajor, ColMajor, ColMajor>();
  test_tiny_results_order<Scalar, ColMajor, RowMajor, ColMajor>();
  test_tiny_results_order<Scalar, RowMajor, RowMajor, ColMajor>();
  test_tiny_results_order<Scalar, ColMajor, ColMajor, RowMajor>();
  test_tiny_results_order<Scalar, RowMajor, ColMajor, RowMajor>();
  test_tiny_results_order<Scalar, ColMajor, RowMajor, RowMajor>();
  test_tiny_results_order<Scalar, RowMajor, RowMajor, RowMajor>();
  // Sub-blocks of larger operands, a result with an inner stride, and a Hankel view (outer stride 1 < rows): the
  // kernel reads only the rows and columns of the result.
  for (Index m : {Index(3), Index(16 / sizeof(Scalar)) + 1})
    for (Index n : {3, 7})
      for (Index k : {16, 19}) {
        const SmeColMajorMat<Scalar> Abig = SmeColMajorMat<Scalar>::Random(m + 5, k + 2);
        const SmeRowMajorMat<Scalar> Bbig = SmeRowMajorMat<Scalar>::Random(k + 3, n + 4);
        const auto A = Abig.block(2, 1, m, k);
        const auto B = Bbig.block(1, 2, k, n);
        SmeColMajorMat<Scalar> Cbig = SmeColMajorMat<Scalar>::Random(2 * m, n);
        const SmeColMajorMat<Scalar> Cbig0 = Cbig;
        Map<SmeColMajorMat<Scalar>, 0, Stride<Dynamic, 2>> C(Cbig.data(), m, n, Stride<Dynamic, 2>(2 * m, 2));
        C.noalias() += Scalar(3) * A * B;
        SmeColMajorMat<Scalar> ref = Cbig0;
        Map<SmeColMajorMat<Scalar>, 0, Stride<Dynamic, 2>>(ref.data(), m, n, Stride<Dynamic, 2>(2 * m, 2)) +=
            Scalar(3) * A.lazyProduct(B);
        VERIFY_IS_APPROX(Cbig, ref);
        std::vector<Scalar> h(std::size_t(k - 1 + m)), g(std::size_t(k - 1 + n));
        for (auto& x : h) x = internal::random<Scalar>();
        for (auto& x : g) x = internal::random<Scalar>();
        Map<const SmeColMajorMat<Scalar>, 0, OuterStride<>> H(h.data(), m, k, OuterStride<>(1));
        Map<const SmeRowMajorMat<Scalar>, 0, OuterStride<>> G(g.data(), k, n, OuterStride<>(1));
        SmeColMajorMat<Scalar> D(m, n);
        D.noalias() = H * G;
        VERIFY_IS_APPROX(D, H.lazyProduct(G));
      }
  // Operands packed tight at the end of their buffer, so a read past the last row or column leaves it.
  const Index ps = Index(16 / sizeof(Scalar));
  for (Index m : {Index(2), Index(3), ps + 1, 2 * ps})
    for (Index n : {2, 3, 5, 7})
      for (Index k : {16, 17, 18, 19}) {
        std::vector<Scalar> a(std::size_t(m * k)), b(std::size_t(k * n));
        Map<SmeColMajorMat<Scalar>> A(a.data(), m, k);
        Map<SmeRowMajorMat<Scalar>> B(b.data(), k, n);
        A.setRandom();
        B.setRandom();
        SmeColMajorMat<Scalar> C = SmeColMajorMat<Scalar>::Zero(m, n);
        C.noalias() += A * B;
        VERIFY_IS_APPROX(C, A.lazyProduct(B));
        Map<SmeRowMajorMat<Scalar>> Ar(a.data(), m, k);
        Map<SmeColMajorMat<Scalar>> Bc(b.data(), k, n);
        C.noalias() = Ar * Bc;
        VERIFY_IS_APPROX(C, Ar.lazyProduct(Bc));
      }
}

// Every tail width of a deep block, which the ZA transposer packs: a ColMajor RHS tail and, through a RowMajor
// product, a transposed LHS tail.
template <typename Scalar>
static void test_deep_tail_panels() {
  const Index MR = sme_mr<Scalar>(), NR = sme_nr<Scalar>();
  for (Index depth : {4 * NR, 6 * NR + 3}) {
    for (Index tail = 1; tail < NR; ++tail) {
      for (Index n : {tail, NR + tail}) {
        const SmeColMajorMat<Scalar> A = SmeColMajorMat<Scalar>::Random(MR + 3, depth);
        const SmeColMajorMat<Scalar> B = SmeColMajorMat<Scalar>::Random(depth, n);
        SmeColMajorMat<Scalar> C = SmeColMajorMat<Scalar>::Random(MR + 3, n);
        const SmeColMajorMat<Scalar> C0 = C;
        C.noalias() += A * B;
        VERIFY_IS_APPROX(C, C0 + A.lazyProduct(B));
        const SmeRowMajorMat<Scalar> Ar = SmeRowMajorMat<Scalar>::Random(n, depth);
        const SmeRowMajorMat<Scalar> Br = SmeRowMajorMat<Scalar>::Random(depth, MR + 3);
        SmeRowMajorMat<Scalar> Cr = SmeRowMajorMat<Scalar>::Random(n, MR + 3);
        const SmeRowMajorMat<Scalar> Cr0 = Cr;
        Cr.noalias() += Ar * Br;
        VERIFY_IS_APPROX(Cr, Cr0 + Ar.lazyProduct(Br));
      }
    }
  }
}

// ---------------------------------------------------------------------------
// Raw packed-buffer tests.
//
// The product tests above validate the packers only transitively through a full
// product, where the gebp_kernel can mask a mispack, or where a bug only shows
// at a specific SVL/region boundary.  The tests below call the SME packers
// directly and compare the packed buffer exactly against a scalar reference
// (equality is exact).  This pins every region -- in particular a dropped
// row-group in the two-pass trailing transpose, and a SYMM packer that copies
// the unused triangle instead of mirroring -- at whatever SVL the run uses.
// ---------------------------------------------------------------------------

// A distinctive marker for buffer cells the packer must leave untouched, and
// for the unused triangle of a lower-triangular operand. Random values live in
// [-1, 1], so it never collides with a real packed value. The complex marker's
// imaginary part differs from its real one, so a packer that fills only the
// real half of a split depth step is caught.
template <typename Scalar>
struct pack_sentinel_impl {
  static Scalar run() { return Scalar(98765); }
};
template <typename RealScalar>
struct pack_sentinel_impl<std::complex<RealScalar>> {
  static std::complex<RealScalar> run() { return std::complex<RealScalar>(RealScalar(98765), RealScalar(-54321)); }
};
template <typename Scalar>
static Scalar pack_sentinel() {
  return pack_sentinel_impl<Scalar>::run();
}

// ---------------------------------------------------------------------------
// NEON small-block path: sme_gebp_neon called directly on hand-packed panels,
// over every row, column and depth tail of the tile ladder, both conjugation
// flags, a non-trivial alpha, panel-mode stride/offset and a general-stride C.
// ---------------------------------------------------------------------------
template <typename Scalar, bool ConjLhs, bool ConjRhs>
static void verify_neon_small_block(Index rows, Index cols, Index depth, bool panel_mode, bool strided_c) {
  const Index MR = sme_mr<Scalar>();
  const Index NR = sme_nr<Scalar>();
  const Index strideA = panel_mode ? depth + 3 : depth;
  const Index strideB = panel_mode ? depth + 5 : depth;
  const Index offsetA = panel_mode ? 2 : 0;
  const Index offsetB = panel_mode ? 1 : 0;
  const SmeColMajorMat<Scalar> A = SmeColMajorMat<Scalar>::Random(rows, depth);
  const SmeColMajorMat<Scalar> B = SmeColMajorMat<Scalar>::Random(depth, cols);

  SmeVector<Scalar> packedA =
      SmeVector<Scalar>::Constant((rows + MR) * strideA + offsetA * MR, pack_sentinel<Scalar>());
  SmeVector<Scalar> packedB =
      SmeVector<Scalar>::Constant((cols + NR) * strideB + offsetB * NR, pack_sentinel<Scalar>());
  for (Index i = 0; i < rows; i += MR) {
    const Index w = numext::mini(MR, rows - i);
    for (Index k = 0; k < depth; ++k)
      for (Index r = 0; r < w; ++r) set_packed(packedA.data() + i * strideA + offsetA * w, w, k, r, A(i + r, k));
  }
  for (Index j = 0; j < cols; j += NR) {
    const Index w = numext::mini(NR, cols - j);
    for (Index k = 0; k < depth; ++k)
      for (Index c = 0; c < w; ++c) set_packed(packedB.data() + j * strideB + offsetB * w, w, k, c, B(k, j + c));
  }

  const Scalar alpha = nontrivial_alpha_impl<Scalar>::run();
  const Index rs = strided_c ? 2 : 1;
  const Index cs = strided_c ? 3 * rows : rows;
  SmeVector<Scalar> storage = SmeVector<Scalar>::Random(cs * cols);
  SmeColMajorStridedMat<Scalar> C(storage.data(), rows, cols, Stride<Dynamic, Dynamic>(cs, rs));
  const SmeColMajorMat<Scalar> c_before = C;
  const SmeVector<Scalar> storage_before = storage;

  internal::sme_gebp_neon<Scalar, ConjLhs, ConjRhs, Index>(storage.data(), rs, cs, packedA.data(), packedB.data(), rows,
                                                           depth, cols, alpha, strideA, strideB, offsetA, offsetB);

  const SmeColMajorMat<Scalar> Ac = ConjLhs ? A.conjugate().eval() : A;
  const SmeColMajorMat<Scalar> Bc = ConjRhs ? B.conjugate().eval() : B;
  const SmeColMajorMat<Scalar> ref = c_before + alpha * Ac.lazyProduct(Bc);
  VERIFY_IS_APPROX(SmeColMajorMat<Scalar>(C), ref);

  // Cells the strided map skips stay untouched.
  if (strided_c) {
    for (Index j = 0; j < cols; ++j)
      for (Index i = 0; i < rows; ++i)
        VERIFY_IS_EQUAL(storage(j * cs + i * rs + 1), storage_before(j * cs + i * rs + 1));
  }
}

template <typename Scalar>
static void test_neon_small_blocks() {
  const Index PS = Index(internal::packet_traits<typename NumTraits<Scalar>::Real>::size);
  const Index MR = sme_mr<Scalar>();
  const Index NR = sme_nr<Scalar>();
  const Index widths[] = {1, 2, 3, PS, PS + 1, 2 * PS + 1, 4 * PS, 4 * PS + 3, MR - 1, MR, MR + 1, 2 * MR + 5};
  const Index col_widths[] = {1, 2, 3, 4, 5, 9, NR - 1, NR, NR + 1, 2 * NR + 2};
  const Index depths[] = {1, 2, 3, 4, 5, 8, 9, 35};
  for (Index rows : widths) {
    for (Index cols : col_widths) {
      for (Index depth : depths) {
        const bool panel_mode = (rows + cols + depth) % 2 == 0;
        const bool strided_c = (rows + depth) % 3 == 0;
        verify_neon_small_block<Scalar, false, false>(rows, cols, depth, panel_mode, strided_c);
        if (NumTraits<Scalar>::IsComplex) {
          verify_neon_small_block<Scalar, true, false>(rows, cols, depth, panel_mode, strided_c);
          verify_neon_small_block<Scalar, false, true>(rows, cols, depth, panel_mode, strided_c);
          verify_neon_small_block<Scalar, true, true>(rows, cols, depth, panel_mode, strided_c);
        }
      }
    }
  }
}

// Lower-triangular n x n operand plus the dense selfadjoint reference the packer
// must emit. The unused triangle is filled with the sentinel so a packer that
// copies the dense matrix and never mirrors fails VERIFY_IS_EQUAL.
// product_selfadjoint_matrix stores the valid triangle where row >= col
// (after the Upper/RowMajor xor), so the packer must read stored(row,col)
// below the diagonal and conj(stored(col,row)) above it. Averaging with the
// adjoint cancels the diagonal's imaginary part exactly, which is what a
// selfadjoint view defines it to be.
template <typename Scalar, int StorageOrder>
static void make_lower_stored_selfadjoint(Index n, Matrix<Scalar, Dynamic, Dynamic, StorageOrder>& stored,
                                          Matrix<Scalar, Dynamic, Dynamic, StorageOrder>& full) {
  full = Matrix<Scalar, Dynamic, Dynamic, StorageOrder>::Random(n, n);
  full = ((full + full.adjoint()) * Scalar(0.5)).eval();
  stored = Matrix<Scalar, Dynamic, Dynamic, StorageOrder>::Constant(n, n, pack_sentinel<Scalar>());
  for (Index i = 0; i < n; ++i)
    for (Index j = 0; j <= i; ++j) stored(i, j) = full(i, j);
}

// LHS SYMM packer: a square selfadjoint diagonal block of size n, packed into
// uniform mr-wide depth-major panels.  Reference: full(i+r, k).
template <typename Scalar, int StorageOrder>
static void verify_symm_pack_lhs(Index n) {
  const Index MR = sme_mr<Scalar>();
  Matrix<Scalar, Dynamic, Dynamic, StorageOrder> stored, full;
  make_lower_stored_selfadjoint<Scalar, StorageOrder>(n, stored, full);

  SmeVector<Scalar> packed = SmeVector<Scalar>::Constant(n * n, pack_sentinel<Scalar>());
  SmeVector<Scalar> ref = SmeVector<Scalar>::Constant(n * n, pack_sentinel<Scalar>());
  for (Index i = 0; i < n; i += MR) {
    const Index w = numext::mini(MR, n - i);
    for (Index k = 0; k < n; ++k)
      for (Index r = 0; r < w; ++r) set_packed(ref.data() + i * n, w, k, r, Scalar(full(i + r, k)));
  }

  internal::symm_pack_lhs<Scalar, Index, sme_mr<Scalar>(), 1, StorageOrder> pack;
  pack(packed.data(), stored.data(), stored.outerStride(), /*cols(depth)=*/n, /*rows=*/n);
  VERIFY_IS_EQUAL(packed, ref);
}

// RHS SYMM packer: a depth block [k2, k2 + depth) x cols columns of an N x N
// selfadjoint matrix, packed into nr-wide depth-major panels.  Reference:
// full(k2 + k, j + c).  A k2 > 0 offset makes the transposed region non-empty,
// so partial-width panels reach the two-pass transpose.
template <typename Scalar, int StorageOrder>
static void verify_symm_pack_rhs(Index N, Index depth, Index cols, Index k2) {
  eigen_assert(k2 + depth <= N && cols <= N);
  const Index NR = sme_nr<Scalar>();
  Matrix<Scalar, Dynamic, Dynamic, StorageOrder> stored, full;
  make_lower_stored_selfadjoint<Scalar, StorageOrder>(N, stored, full);

  SmeVector<Scalar> packed = SmeVector<Scalar>::Constant(cols * depth, pack_sentinel<Scalar>());
  SmeVector<Scalar> ref = SmeVector<Scalar>::Constant(cols * depth, pack_sentinel<Scalar>());
  for (Index j = 0; j < cols; j += NR) {
    const Index w = numext::mini(NR, cols - j);
    for (Index k = 0; k < depth; ++k)
      for (Index c = 0; c < w; ++c) set_packed(ref.data() + j * depth, w, k, c, Scalar(full(k2 + k, j + c)));
  }

  internal::symm_pack_rhs<Scalar, Index, sme_nr<Scalar>(), StorageOrder> pack;
  pack(packed.data(), stored.data(), stored.outerStride(), /*rows(depth)=*/depth, /*cols=*/cols, k2);
  VERIFY_IS_EQUAL(packed, ref);
}

template <typename Scalar>
static void test_symm_pack() {
  // The last panel width sweeps a range of partial widths; at each SVL the
  // two-pass trailing transpose (the if->loop fix) fires when a partial width
  // leaves a trailing row-group remainder in (svl, 2*svl).  The spread below
  // hits that for svl in {2, 4, 8, 16, 32, 64} -- fp32 SVL 128..2048 and the
  // fp64 lane counts, which are half of those.
  const int sizes[] = {1, 5, 7, 17, 31, 32, 33, 37, 39, 45, 48, 49, 55, 57, 63, 64, 65, 79, 96, 97};
  for (int n : sizes) {
    verify_symm_pack_lhs<Scalar, ColMajor>(n);
    verify_symm_pack_lhs<Scalar, RowMajor>(n);
    // RHS, single depth block anchored at the diagonal (k2 == 0).
    verify_symm_pack_rhs<Scalar, ColMajor>(n, n, n, 0);
    verify_symm_pack_rhs<Scalar, RowMajor>(n, n, n, 0);
  }

  // RHS depth blocks offset from the diagonal (k2 > 0): the transposed region is
  // non-empty, so the RowMajor operand drives partial-width panels through the
  // two-pass transpose and the ColMajor operand through the partial copy.
  struct RhsCase {
    int N, depth, cols, k2;
  };
  const RhsCase rhs_cases[] = {
      {100, 32, 39, 16}, {100, 24, 39, 32}, {100, 40, 64, 8}, {100, 39, 39, 33}, {128, 57, 57, 40}, {128, 33, 45, 60},
  };
  for (const RhsCase& c : rhs_cases) {
    verify_symm_pack_rhs<Scalar, ColMajor>(c.N, c.depth, c.cols, c.k2);
    verify_symm_pack_rhs<Scalar, RowMajor>(c.N, c.depth, c.cols, c.k2);
  }

  // Full-panel direct regions [s_end, depth) of a ColMajor operand start at s_end = j + w - k2, off the depth chunk
  // grid, with real-view lengths 4*svl*a + 2*svl + t that pass through the four-chunk (64-bit), paired and single-tile
  // transposer loops in turn. The panel width w is nr and, where smaller, the 2*svl the full-panel path needs.
  const int svl = internal::sme_packet_traits<typename NumTraits<Scalar>::Real>::size();
  const int NR = sme_nr<Scalar>();
  const int scale = NumTraits<Scalar>::IsComplex ? 2 : 1;
  for (int real_range : {10 * svl + 3, 14 * svl + 1}) {
    const int range = (real_range + scale - 1) / scale;
    for (int k2 : {5, NR - 3}) {
      const int depth = NR - k2 + range, N = numext::maxi(k2 + depth, 2 * NR + 1);
      verify_symm_pack_rhs<Scalar, ColMajor>(N, depth, 2 * NR + 1, k2);
      verify_symm_pack_rhs<Scalar, RowMajor>(N, depth, 2 * NR + 1, k2);
    }
    if (svl >= 4 && 2 * svl < NR) {
      const int w = 2 * svl, k2 = w - 3, depth = 3 + range;
      verify_symm_pack_rhs<Scalar, ColMajor>(k2 + depth, depth, w, k2);
    }
  }
}

// ---------------------------------------------------------------------------
// Mapper-based packing fallback (sme_pack_{lhs,rhs}_fallback).
//
// Taken by by-value tensor sub-mappers and inner-strided blas mappers, which
// the raw pointer + stride packers cannot walk.  The product suite reaches these
// only through tensor contractions (nightly, SVL=512) and TriangularSolver
// (random sizes), so here we drive the fallback directly with both mapper
// families and compare the packed buffer against a scalar reference.
// ---------------------------------------------------------------------------

// Minimal stand-ins for by-value sub-mappers. ColMajor packets advance the
// first index, while RowMajor packets follow the normal storage-inner second
// index. operator() returns by value so both take the no-direct-access dispatch.
template <typename Scalar>
struct ByValueColMajorLhsMapper {
  const Scalar* data;
  Index stride;  // element(i, k) = data[i + k * stride], contiguous in i
  Scalar operator()(Index i, Index k) const { return data[i + k * stride]; }
  template <typename Packet>
  EIGEN_ALWAYS_INLINE Packet loadPacket(Index i, Index k) const {
    return internal::ploadu<Packet>(data + i + k * stride);
  }
};

template <typename Scalar>
struct ByValueRowMajorLhsMapper {
  const Scalar* data;
  Index stride;  // element(i, k) = data[i * stride + k], contiguous in k
  Scalar operator()(Index i, Index k) const { return data[i * stride + k]; }
  template <typename Packet>
  EIGEN_ALWAYS_INLINE Packet loadPacket(Index i, Index k) const {
    return internal::ploadu<Packet>(data + i * stride + k);
  }
};

template <typename Scalar>
struct ByValueColMajorRhsMapper {
  struct LinearMapper {
    const Scalar* p;  // &element(0, col); contiguous in depth
    Scalar operator()(Index k) const { return p[k]; }
    template <typename Packet>
    EIGEN_ALWAYS_INLINE Packet loadPacket(Index k) const {
      return internal::ploadu<Packet>(p + k);
    }
  };
  const Scalar* data;
  Index stride;  // element(k, col) = data[k + col * stride], contiguous in k
  Scalar operator()(Index k, Index col) const { return data[k + col * stride]; }
  LinearMapper getLinearMapper(Index k, Index col) const { return LinearMapper{data + k + col * stride}; }
};

template <typename Scalar>
struct ByValueRowMajorRhsMapper {
  struct LinearMapper {
    const Scalar* p;  // &element(row, col); packet offsets advance columns
    Scalar operator()(Index offset) const { return p[offset]; }
    template <typename Packet>
    EIGEN_ALWAYS_INLINE Packet loadPacket(Index offset) const {
      return internal::ploadu<Packet>(p + offset);
    }
  };
  const Scalar* data;
  Index stride;  // element(k, col) = data[k * stride + col], contiguous in col
  Scalar operator()(Index k, Index col) const { return data[k * stride + col]; }
  LinearMapper getLinearMapper(Index k, Index col) const { return LinearMapper{data + k * stride + col}; }
};

// Length of the packed LHS buffer for the given panel-mode layout, matching the
// dst_panel formula in sme_pack_lhs_fallback.
template <bool PanelMode>
static Index packed_len(Index outer, Index depth, Index unit, Index dst_stride, Index dst_offset) {
  // `outer` is rows (LHS) or cols (RHS); `unit` is the panel width mr or nr.
  if (!PanelMode) return outer * depth;
  Index end = 0;
  for (Index i = 0; i < outer; i += unit) {
    const Index w = numext::mini(unit, outer - i);
    end = numext::maxi(end, i * dst_stride + dst_offset * w + depth * w);
  }
  return end;
}

template <typename Scalar, bool PanelMode, bool Conjugate, typename MatrixType>
static void fill_lhs_ref(SmeVector<Scalar>& ref, const MatrixType& V, Index rows, Index depth, Index dst_stride,
                         Index dst_offset) {
  const Index MR = sme_mr<Scalar>();
  ref.setConstant(pack_sentinel<Scalar>());
  for (Index i = 0; i < rows; i += MR) {
    const Index w = numext::mini(MR, rows - i);
    const Index base = PanelMode ? i * dst_stride + dst_offset * w : i * depth;
    for (Index k = 0; k < depth; ++k)
      for (Index r = 0; r < w; ++r) {
        const Scalar v = V(i + r, k);
        set_packed(ref.data() + base, w, k, r, Conjugate ? numext::conj(v) : v);
      }
  }
}

template <typename Scalar, bool PanelMode, bool Conjugate, typename MatrixType>
static void fill_rhs_ref(SmeVector<Scalar>& ref, const MatrixType& V, Index cols, Index depth, Index dst_stride,
                         Index dst_offset) {
  const Index NR = sme_nr<Scalar>();
  ref.setConstant(pack_sentinel<Scalar>());
  for (Index j = 0; j < cols; j += NR) {
    const Index w = numext::mini(NR, cols - j);
    const Index base = PanelMode ? j * dst_stride + dst_offset * w : j * depth;
    for (Index k = 0; k < depth; ++k)
      for (Index c = 0; c < w; ++c) {
        const Scalar v = V(k, j + c);
        set_packed(ref.data() + base, w, k, c, Conjugate ? numext::conj(v) : v);
      }
  }
}

// Every packer check below is the same nine lines -- fill a sentinel buffer,
// build the scalar reference, run the packer, compare exactly -- over a
// different mapper. The mapper is what each check is really about, so it is
// built by the caller and the rest lives here once.
template <typename Scalar, int StorageOrder, bool PanelMode, bool Conjugate, typename Mapper, typename MatrixType>
static void check_packed_lhs(const Mapper& mapper, const MatrixType& V, Index rows, Index depth) {
  const Index dst_stride = PanelMode ? depth + 5 : 0;
  const Index dst_offset = PanelMode ? 3 : 0;
  const Index len = packed_len<PanelMode>(rows, depth, sme_mr<Scalar>(), dst_stride, dst_offset);
  SmeVector<Scalar> packed = SmeVector<Scalar>::Constant(len, pack_sentinel<Scalar>());
  SmeVector<Scalar> ref(len);
  fill_lhs_ref<Scalar, PanelMode, Conjugate>(ref, V, rows, depth, dst_stride, dst_offset);

  internal::gemm_pack_lhs<Scalar, Index, Mapper, sme_mr<Scalar>(), 1, typename internal::packet_traits<Scalar>::type,
                          StorageOrder, Conjugate, PanelMode>
      pack;
  pack(packed.data(), mapper, depth, rows, dst_stride, dst_offset);
  VERIFY_IS_EQUAL(packed, ref);
}

template <typename Scalar, int StorageOrder, bool PanelMode, bool Conjugate, typename Mapper, typename MatrixType>
static void check_packed_rhs(const Mapper& mapper, const MatrixType& V, Index depth, Index cols) {
  const Index dst_stride = PanelMode ? depth + 5 : 0;
  const Index dst_offset = PanelMode ? 3 : 0;
  const Index len = packed_len<PanelMode>(cols, depth, sme_nr<Scalar>(), dst_stride, dst_offset);
  SmeVector<Scalar> packed = SmeVector<Scalar>::Constant(len, pack_sentinel<Scalar>());
  SmeVector<Scalar> ref(len);
  fill_rhs_ref<Scalar, PanelMode, Conjugate>(ref, V, cols, depth, dst_stride, dst_offset);

  internal::gemm_pack_rhs<Scalar, Index, Mapper, sme_nr<Scalar>(), StorageOrder, Conjugate, PanelMode> pack;
  pack(packed.data(), mapper, depth, cols, dst_stride, dst_offset);
  VERIFY_IS_EQUAL(packed, ref);
}

// The raw pointer + stride packers, taken whenever the mapper grants direct
// unit-inner-stride access.
template <typename Scalar, int StorageOrder, bool PanelMode, bool Conjugate>
static void verify_pack_lhs_direct(Index rows, Index depth) {
  using MatrixType = Matrix<Scalar, Dynamic, Dynamic, StorageOrder>;
  using Mapper = internal::const_blas_data_mapper<Scalar, Index, StorageOrder>;
  MatrixType V = MatrixType::Random(rows, depth);
  check_packed_lhs<Scalar, StorageOrder, PanelMode, Conjugate>(Mapper(V.data(), V.outerStride()), V, rows, depth);
}

template <typename Scalar, int StorageOrder, bool PanelMode, bool Conjugate>
static void verify_pack_rhs_direct(Index depth, Index cols) {
  using MatrixType = Matrix<Scalar, Dynamic, Dynamic, StorageOrder>;
  using Mapper = internal::const_blas_data_mapper<Scalar, Index, StorageOrder>;
  MatrixType V = MatrixType::Random(depth, cols);
  check_packed_rhs<Scalar, StorageOrder, PanelMode, Conjugate>(Mapper(V.data(), V.outerStride()), V, depth, cols);
}

// Inner-strided blas mapper LHS: element(i, k) laid out with inner stride
// `incr`.  ColMajor takes the vectorised gather path; RowMajor takes the scalar
// path (its packets would run along depth, not rows).
template <typename Scalar, int StorageOrder, bool PanelMode, bool Conjugate>
static void verify_fallback_lhs_strided(Index rows, Index depth, Index incr) {
  using Mapper = internal::blas_data_mapper<Scalar, Index, StorageOrder, Unaligned, Dynamic>;
  Matrix<Scalar, Dynamic, Dynamic> V = Matrix<Scalar, Dynamic, Dynamic>::Random(rows, depth);
  const Index mstride = (StorageOrder == ColMajor ? rows : depth) * incr;
  SmeVector<Scalar> buf = SmeVector<Scalar>::Zero((StorageOrder == ColMajor ? depth : rows) * mstride + incr);
  for (Index k = 0; k < depth; ++k)
    for (Index i = 0; i < rows; ++i)
      buf[StorageOrder == ColMajor ? i * incr + k * mstride : k * incr + i * mstride] = V(i, k);
  check_packed_lhs<Scalar, StorageOrder, PanelMode, Conjugate>(Mapper(buf.data(), mstride, incr), V, rows, depth);
}

// By-value LHS mappers exercise both packet directions. RowMajor must stay
// scalar because its packets advance depth rather than rows.
template <typename Scalar, int StorageOrder, bool PanelMode, bool Conjugate>
static void verify_fallback_lhs_byvalue(Index rows, Index depth) {
  using MatrixType = Matrix<Scalar, Dynamic, Dynamic, StorageOrder>;
  using Mapper = typename std::conditional<StorageOrder == ColMajor, ByValueColMajorLhsMapper<Scalar>,
                                           ByValueRowMajorLhsMapper<Scalar>>::type;
  MatrixType V = MatrixType::Random(rows, depth);
  check_packed_lhs<Scalar, StorageOrder, PanelMode, Conjugate>(Mapper{V.data(), V.outerStride()}, V, rows, depth);
}

// Inner-strided blas mapper RHS: element(k, col) with inner stride `incr`.
// ColMajor takes the vectorised transpose path; RowMajor takes the scalar path.
template <typename Scalar, int StorageOrder, bool PanelMode, bool Conjugate>
static void verify_fallback_rhs_strided(Index depth, Index cols, Index incr) {
  using Mapper = internal::blas_data_mapper<Scalar, Index, StorageOrder, Unaligned, Dynamic>;
  Matrix<Scalar, Dynamic, Dynamic> V = Matrix<Scalar, Dynamic, Dynamic>::Random(depth, cols);
  const Index mstride = (StorageOrder == ColMajor ? depth : cols) * incr;
  SmeVector<Scalar> buf = SmeVector<Scalar>::Zero((StorageOrder == ColMajor ? cols : depth) * mstride + incr);
  for (Index col = 0; col < cols; ++col)
    for (Index k = 0; k < depth; ++k)
      buf[StorageOrder == ColMajor ? k * incr + col * mstride : col * incr + k * mstride] = V(k, col);
  check_packed_rhs<Scalar, StorageOrder, PanelMode, Conjugate>(Mapper(buf.data(), mstride, incr), V, depth, cols);
}

// By-value RHS mappers likewise cover both packet directions. RowMajor packets
// advance columns, so the depth-oriented transpose fallback must stay scalar.
template <typename Scalar, int StorageOrder, bool PanelMode, bool Conjugate>
static void verify_fallback_rhs_byvalue(Index depth, Index cols) {
  using MatrixType = Matrix<Scalar, Dynamic, Dynamic, StorageOrder>;
  using Mapper = typename std::conditional<StorageOrder == ColMajor, ByValueColMajorRhsMapper<Scalar>,
                                           ByValueRowMajorRhsMapper<Scalar>>::type;
  MatrixType V = MatrixType::Random(depth, cols);
  check_packed_rhs<Scalar, StorageOrder, PanelMode, Conjugate>(Mapper{V.data(), V.outerStride()}, V, depth, cols);
}

// Each packer is swept over all four (PanelMode, Conjugate) combinations.
// Conjugate=true is the identity on real scalars; for complex ones it negates
// the packed imaginary half, and reaches the direct packers from the SYMM
// above-diagonal transposed pack and the fallbacks from an inner-strided
// selfadjoint operand.
template <typename Scalar, int SO>
static void sweep_pack_direct(Index n, Index depth) {
  verify_pack_lhs_direct<Scalar, SO, false, false>(n, depth);
  verify_pack_lhs_direct<Scalar, SO, false, true>(n, depth);
  verify_pack_lhs_direct<Scalar, SO, true, false>(n, depth);
  verify_pack_lhs_direct<Scalar, SO, true, true>(n, depth);
  verify_pack_rhs_direct<Scalar, SO, false, false>(depth, n);
  verify_pack_rhs_direct<Scalar, SO, false, true>(depth, n);
  verify_pack_rhs_direct<Scalar, SO, true, false>(depth, n);
  verify_pack_rhs_direct<Scalar, SO, true, true>(depth, n);
}

template <typename Scalar, int SO>
static void sweep_fallback_strided(Index n, Index depth, Index incr) {
  verify_fallback_lhs_strided<Scalar, SO, false, false>(n, depth, incr);
  verify_fallback_lhs_strided<Scalar, SO, false, true>(n, depth, incr);
  verify_fallback_lhs_strided<Scalar, SO, true, false>(n, depth, incr);
  verify_fallback_lhs_strided<Scalar, SO, true, true>(n, depth, incr);
  verify_fallback_rhs_strided<Scalar, SO, false, false>(depth, n, incr);
  verify_fallback_rhs_strided<Scalar, SO, false, true>(depth, n, incr);
  verify_fallback_rhs_strided<Scalar, SO, true, false>(depth, n, incr);
  verify_fallback_rhs_strided<Scalar, SO, true, true>(depth, n, incr);
}

template <typename Scalar, int SO>
static void sweep_fallback_byvalue(Index n, Index depth) {
  verify_fallback_lhs_byvalue<Scalar, SO, false, false>(n, depth);
  verify_fallback_lhs_byvalue<Scalar, SO, false, true>(n, depth);
  verify_fallback_lhs_byvalue<Scalar, SO, true, false>(n, depth);
  verify_fallback_lhs_byvalue<Scalar, SO, true, true>(n, depth);
  verify_fallback_rhs_byvalue<Scalar, SO, false, false>(depth, n);
  verify_fallback_rhs_byvalue<Scalar, SO, false, true>(depth, n);
  verify_fallback_rhs_byvalue<Scalar, SO, true, false>(depth, n);
  verify_fallback_rhs_byvalue<Scalar, SO, true, true>(depth, n);
}

template <typename Scalar>
static void test_pack_direct() {
  const int TILE = sme_tile<Scalar>();
  const int MR = sme_mr<Scalar>();
  const int NR = sme_nr<Scalar>();
  // Widths around the tile side and both panel widths, which differ for
  // complex scalars.
  const int widths[] = {1, TILE - 1, TILE, TILE + 1, MR, MR + 1, NR, NR + 1, 2 * NR + 1};
  // Depths up to sme_neon_max_depth (24 / 16 / 16 / 8 by scalar) reach pack_neon,
  // the deeper ones the streaming pack_direct and its predicated tails.
  const int depths[] = {1, 3, 8, 9, 17, 25, 27, 35};
  for (int d : depths) {
    for (int n : widths) {
      sweep_pack_direct<Scalar, ColMajor>(n, d);
      sweep_pack_direct<Scalar, RowMajor>(n, d);
    }
  }
  // Four-panel LHS copies with leftover panels and tails, over several transposing depth chunks.
  for (int d : {35, 67, 97}) {
    for (int n : {4 * MR, 5 * MR + 1, 8 * MR + 3}) {
      sweep_pack_direct<Scalar, ColMajor>(n, d);
      sweep_pack_direct<Scalar, RowMajor>(n, d);
    }
  }
  // Depths at and one past whole multiples of four depth chunks, where the full-panel transposer's loops hand over to
  // the next and to the single-tile tail; a complex panel transposes a real view of twice the depth.
  const int svl = internal::sme_packet_traits<typename NumTraits<Scalar>::Real>::size();
  const int deep = (NumTraits<Scalar>::IsComplex ? 16 : 32) * svl;
  std::vector<int> deep_depths = {deep - 1, deep + 1};
  for (int j : {2, 3, 8, 9}) {
    deep_depths.push_back(4 * svl * j);
    deep_depths.push_back(4 * svl * j + 1);
  }
  // Deduplicate deep + 1 == 4*svl*8 + 1 for real scalars.
  std::sort(deep_depths.begin(), deep_depths.end());
  deep_depths.erase(std::unique(deep_depths.begin(), deep_depths.end()), deep_depths.end());
  // The paired transposer takes only unconjugated 2*svl-wide panels. At SVL 512 that is NR for every scalar and MR for
  // all but complex<float>. Below it, eligible real tails reach the paired transposer through tail_pack once deep
  // enough, and complex<float> has MR == 2*svl at SVL 256. Complex tails take the NEON tail_transpose_pack, so
  // complex<double> at SVL 256 reaches the four-chunk loop only through test_symm_pack's 2*svl-wide direct regions.
  // Real tails between svl and 2*svl wide store whole packed lines, through the copy or the ZA transposer.
  std::vector<int> deep_widths = {MR, MR + 1, NR, 2 * NR + 1, 2 * svl, svl + 1, 2 * svl - 1};
  std::sort(deep_widths.begin(), deep_widths.end());
  deep_widths.erase(std::unique(deep_widths.begin(), deep_widths.end()), deep_widths.end());
  for (int d : deep_depths) {
    for (int n : deep_widths) {
      sweep_pack_direct<Scalar, ColMajor>(n, d);
      sweep_pack_direct<Scalar, RowMajor>(n, d);
    }
  }
}

template <typename Scalar>
static void test_mapper_fallback() {
  const int MR = sme_mr<Scalar>();
  const int widths[] = {4, 5, MR, MR + 1, 2 * MR + 1};  // rows/cols around 4 and the panel width
  const int depths[] = {1, 3, 8, 35};                   // depth remainders 1..3 and larger
  for (int n : widths) {
    for (int d : depths) {
      // RowMajor mappers take the scalar path: their packets advance the index
      // the fallback does not transpose.
      for (int incr : {2, 3}) {
        sweep_fallback_strided<Scalar, ColMajor>(n, d, incr);
        sweep_fallback_strided<Scalar, RowMajor>(n, d, incr);
      }
      sweep_fallback_byvalue<Scalar, ColMajor>(n, d);
      sweep_fallback_byvalue<Scalar, RowMajor>(n, d);
    }
  }
}

// ---------------------------------------------------------------------------
// Product-level coverage, swept relative to the scalar's own block width.
// ---------------------------------------------------------------------------

// Sizes that land just on and off the block tails and the intra-block ZA-tile
// splits, for both panel widths (they differ for complex scalars) and the tile
// side at the SVL=512 design point.
template <typename Scalar>
static std::vector<int> sme_edge_sizes() {
  const int T = sme_tile<Scalar>();
  const int MR = sme_mr<Scalar>();
  const int NR = sme_nr<Scalar>();
  std::vector<int> sizes = {T / 2,  T + T / 2, 1,      T - 1,      T,      T + 1,      MR - 1,     MR,     MR + 1,
                            NR - 1, NR,        NR + 1, 2 * MR - 1, 2 * MR, 2 * MR + 1, 2 * NR - 1, 2 * NR, 2 * NR + 1};
  std::sort(sizes.begin(), sizes.end());
  sizes.erase(std::unique(sizes.begin(), sizes.end()), sizes.end());
  return sizes;
}

// The dimension-sum and output-area bounds in GeneralProduct.h route a small
// square product to the coeff-based evaluator, so the n x n sweeps above stop
// reaching the SME kernel once n gets small -- which is exactly where the
// intra-block ZA tile-split edges (T-1, T, T+1) live for double and
// complex<double>.  Repeat the same widths over a depth that clears both
// bounds, so every m and n edge still reaches the kernel, and check the
// conjugated forms too: at those sizes test_conjugated_products compares a
// lazyProduct against a lazyProduct and cannot fail.
template <typename Scalar>
static void test_edge_sizes_deep_k() {
  const int depth = 4 * sme_mr<Scalar>();
  for (int n : sme_edge_sizes<Scalar>()) {
    if (n < 2) continue;
    const SmeColMajorMat<Scalar> A = SmeColMajorMat<Scalar>::Random(n, depth);
    const SmeColMajorMat<Scalar> B = SmeColMajorMat<Scalar>::Random(depth, n);
    const SmeColMajorMat<Scalar> Aa = A.adjoint().eval();
    const SmeColMajorMat<Scalar> Ba = B.adjoint().eval();
    const SmeColMajorMat<Scalar> c_before = SmeColMajorMat<Scalar>::Random(n, n);
    const SmeColMajorMat<Scalar> expected = c_before + A.lazyProduct(B);

    SmeColMajorMat<Scalar> C = c_before;
    C.noalias() += A * B;
    VERIFY_IS_APPROX(C, expected);

    C = c_before;
    C.noalias() += Aa.adjoint() * B;
    VERIFY_IS_APPROX(C, expected);

    C = c_before;
    C.noalias() += A * Ba.adjoint();
    VERIFY_IS_APPROX(C, expected);
  }
}

template <typename Scalar>
static void test_conjugated_products() {
  for (int n : sme_edge_sizes<Scalar>()) {
    verify_conjugated_products<Scalar, SmeColMajorMat<Scalar>, SmeColMajorMat<Scalar>, SmeColMajorMat<Scalar>>(n);
    verify_conjugated_products<Scalar, SmeRowMajorMat<Scalar>, SmeColMajorMat<Scalar>, SmeColMajorMat<Scalar>>(n);
    verify_conjugated_products<Scalar, SmeColMajorMat<Scalar>, SmeRowMajorMat<Scalar>, SmeRowMajorMat<Scalar>>(n);
    verify_conjugated_products<Scalar, SmeRowMajorMat<Scalar>, SmeRowMajorMat<Scalar>, SmeColMajorMat<Scalar>>(n);
  }
}

template <typename Scalar>
static void test_products() {
  const int MR = sme_mr<Scalar>();

  // Square edge cases around the block and tile boundaries.
  for (int n : sme_edge_sizes<Scalar>()) product(SmeColMajorMat<Scalar>(n, n));

  // Thin / wide rectangular cases (M x 1, 1 x N) and non-square cases that
  // exercise tail paths for both M and N.
  product(SmeColMajorMat<Scalar>(MR, 1));
  product(SmeColMajorMat<Scalar>(1, MR));
  product(SmeColMajorMat<Scalar>(1, 2 * MR));
  product(SmeColMajorMat<Scalar>(2 * MR, 1));
  product(SmeColMajorMat<Scalar>(MR + 1, 2 * MR + 1));
  product(SmeColMajorMat<Scalar>(2 * MR + 1, MR + 1));
  product(SmeColMajorMat<Scalar>(MR - 1, 2 * MR - 1));
  product(SmeColMajorMat<Scalar>(MR + 1, 7));
  product(SmeColMajorMat<Scalar>(7, MR + 1));
  product(SmeColMajorMat<Scalar>(4 * MR, 3));
  product(SmeColMajorMat<Scalar>(3, 4 * MR));

  test_deep_k_split<Scalar>();
  test_edge_sizes_deep_k<Scalar>();

  // Random sizes
  for (int i = 0; i < g_repeat; i++) {
    product(SmeColMajorMat<Scalar>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE),
                                   internal::random<int>(1, EIGEN_TEST_MAX_SIZE)));
  }

  // Exercise the RowMajor packers and RowMajor result path.  When the input
  // MatrixType is RowMajor, product() instantiates m1/m2/m3/res in RowMajor,
  // so every matrix-matrix product in the suite flows through:
  //   - the RowMajor LHS packer (gemm_pack_lhs<..., RowMajor>)
  //   - the RowMajor RHS packer (gemm_pack_rhs<..., RowMajor>)
  //   - the RowMajor-C dispatch in GeneralMatrixMatrix.h (which transposes
  //     the computation: C^T = B^T * A^T).
  for (int n : sme_edge_sizes<Scalar>()) {
    if (n > 1) product(SmeRowMajorMat<Scalar>(n, n));
  }
  product(SmeRowMajorMat<Scalar>(MR + 1, 2 * MR + 1));
  product(SmeRowMajorMat<Scalar>(2 * MR + 1, MR + 1));
  for (int i = 0; i < g_repeat; i++) {
    product(SmeRowMajorMat<Scalar>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE),
                                   internal::random<int>(1, EIGEN_TEST_MAX_SIZE)));
  }

  // Exercise the general-stride branch of sme_store_za_tile: fires when both
  // C_stride_row != 1 and C_stride_col != 1, e.g. a Map<Matrix> with an
  // explicit non-unit inner stride.  product.h never builds such a result, so
  // without this subtest the scalar-scatter path is effectively untested.
  for (int n : sme_edge_sizes<Scalar>()) {
    if (n < 2) continue;
    test_general_strided_result<Scalar, SmeColMajorMat<Scalar>>(n);
    test_general_strided_result<Scalar, SmeRowMajorMat<Scalar>>(n);
    test_rowmajor_strided_result<Scalar>(n);
  }

  // Row-LHS x Row-RHS -> Col-C: the one LHS/RHS/C storage combination that
  // product.h's transpose-style expressions never build directly (it always
  // flips one side of the multiplication).  The code paths are the same as
  // other combinations via Eigen's dispatch, but exercise them explicitly.
  for (int n : sme_edge_sizes<Scalar>()) {
    if (n < 2) continue;
    SmeRowMajorMat<Scalar> A = SmeRowMajorMat<Scalar>::Random(n, n);
    SmeRowMajorMat<Scalar> B = SmeRowMajorMat<Scalar>::Random(n, n);
    SmeColMajorMat<Scalar> C = SmeColMajorMat<Scalar>::Zero(n, n);
    C.noalias() += A * B;
    VERIFY_IS_APPROX(C, (A.lazyProduct(B)).eval());
  }
}

// Folding C into the complex alpha chain, (c_re + re*ar) - im*ai, overflows
// for acc = (h,h), alpha = (1,1), C = (3h,0) although the exact result
// (3h,2h) is finite (#3139 review).  Widths straddle the one-vector slice
// width, which selects the store form; a real alpha takes the fused store.
// RowMajor GEMM transposes the computation, so the packed kernel is also
// called directly to reach the horizontal slice store.
template <typename Real, int Order>
static void test_complex_alpha_range() {
  using Scalar = std::complex<Real>;
  using Mat = Matrix<Scalar, Dynamic, Dynamic, Order>;
  const int svl = internal::sme_packet_traits<Real>::size();
  const Real h = std::ldexp(Real(1), std::numeric_limits<Real>::max_exponent - 2);
  const Index depth = 65;
  const Scalar initial(3 * h, 0);
  const Scalar alphas[] = {Scalar(1, 1), Scalar(-1, 0)};
  const Scalar expected[] = {Scalar(3 * h, 2 * h), Scalar(2 * h, -h)};
  for (int n : {svl / 2 - 1, svl / 2, svl / 2 + 1, svl, svl + 1}) {
    if (n < 2) continue;
    Mat a = Mat::Zero(n, depth), b = Mat::Zero(depth, n);
    a.col(0).setConstant(Scalar(h, h));
    b.row(0).setOnes();
    const Mat ac = a.conjugate(), bc = b.conjugate();
    for (int t = 0; t < 2; ++t) {
      const Scalar alpha = alphas[t];
      for (int conjugation = 0; conjugation < 4; ++conjugation) {
        Mat c = Mat::Constant(n, n, initial);
        if (conjugation == 0) c.noalias() += alpha * (a * b);
        if (conjugation == 1) c.noalias() += alpha * (ac.conjugate() * b);
        if (conjugation == 2) c.noalias() += alpha * (a * bc.conjugate());
        if (conjugation == 3) c.noalias() += alpha * (ac.conjugate() * bc.conjugate());
        for (Index j = 0; j < n; ++j) {
          for (Index i = 0; i < n; ++i) {
            VERIFY((std::isfinite)(c(i, j).real()) && (std::isfinite)(c(i, j).imag()));
            VERIFY(c(i, j) == expected[t]);
          }
        }
      }
      // One packed panel; a larger runtime SVL may exceed its static width.
      if (n <= numext::mini(sme_mr<Scalar>(), sme_nr<Scalar>())) {
        std::vector<Scalar> pa(n * depth), pb(n * depth);
        for (Index k = 0; k < depth; ++k) {
          for (Index i = 0; i < n; ++i) {
            set_packed(pa.data(), Index(n), k, i, a(i, k));
            set_packed(pb.data(), Index(n), k, i, b(k, i));
          }
        }
        Mat c = Mat::Constant(n, n, initial);
        internal::sme_gebp_dispatch<Scalar, false, false>::run(
            c.data(), Index(Order == RowMajor ? n : 1), Index(Order == RowMajor ? 1 : n), pa.data(), pb.data(),
            Index(n), depth, Index(n), alpha, depth, depth, Index(0), Index(0));
        for (Index j = 0; j < n; ++j) {
          for (Index i = 0; i < n; ++i) {
            VERIFY((std::isfinite)(c(i, j).real()) && (std::isfinite)(c(i, j).imag()));
            VERIFY(c(i, j) == expected[t]);
          }
        }
      }
    }
  }
}

EIGEN_DECLARE_TEST(product_sme) {
  CALL_SUBTEST_1(test_whilelt_operand_types<float>());
  CALL_SUBTEST_1(test_packet_ops<float>());
  CALL_SUBTEST_1(test_products<float>());
  CALL_SUBTEST_1(test_conjugated_products<float>());
  CALL_SUBTEST_1(test_symm_pack<float>());
  CALL_SUBTEST_1(test_pack_direct<float>());
  CALL_SUBTEST_1(test_mapper_fallback<float>());
  CALL_SUBTEST_1(test_neon_small_blocks<float>());
  CALL_SUBTEST_1(test_direct_lhs<float>());
  CALL_SUBTEST_1(test_small_k_and_single_panel_rhs<float>());
  CALL_SUBTEST_1(test_deep_tail_panels<float>());
  CALL_SUBTEST_1(test_tiny_results<float>());
  CALL_SUBTEST_1(test_fp_flags<float>());
  CALL_SUBTEST_1(test_disjoint_parts<float>());

  // double reaches the SME kernel and packers only with FEAT_SME_F64F64; the
  // product sweep is meaningful either way, but the packed-layout tests name
  // specializations that only exist when it is available.
  CALL_SUBTEST_2(test_products<double>());
  CALL_SUBTEST_2(test_conjugated_products<double>());
#ifdef EIGEN_VECTORIZE_SME_F64F64
  CALL_SUBTEST_2(test_whilelt_operand_types<double>());
  CALL_SUBTEST_2(test_packet_ops<double>());
  CALL_SUBTEST_2(test_symm_pack<double>());
  CALL_SUBTEST_2(test_pack_direct<double>());
  CALL_SUBTEST_2(test_mapper_fallback<double>());
  CALL_SUBTEST_2(test_neon_small_blocks<double>());
  CALL_SUBTEST_2(test_direct_lhs<double>());
  CALL_SUBTEST_2(test_small_k_and_single_panel_rhs<double>());
  CALL_SUBTEST_2(test_deep_tail_panels<double>());
  CALL_SUBTEST_2(test_tiny_results<double>());
  CALL_SUBTEST_2(test_fp_flags<double>());
  CALL_SUBTEST_2(test_disjoint_parts<double>());
#endif

  CALL_SUBTEST_3(test_products<std::complex<float>>());
  CALL_SUBTEST_3(test_conjugated_products<std::complex<float>>());
  CALL_SUBTEST_3(test_symm_pack<std::complex<float>>());
  CALL_SUBTEST_3(test_pack_direct<std::complex<float>>());
  CALL_SUBTEST_3(test_mapper_fallback<std::complex<float>>());
  CALL_SUBTEST_3(test_neon_small_blocks<std::complex<float>>());
  CALL_SUBTEST_3(test_fp_flags<std::complex<float>>());
  CALL_SUBTEST_3(test_disjoint_parts<std::complex<float>>());
  CALL_SUBTEST_3((test_complex_alpha_range<float, ColMajor>()));
  CALL_SUBTEST_3((test_complex_alpha_range<float, RowMajor>()));

  // complex<double> accumulates into ZA.D tiles, so it needs FEAT_SME_F64F64
  // exactly as double does.
  CALL_SUBTEST_4(test_products<std::complex<double>>());
  CALL_SUBTEST_4(test_conjugated_products<std::complex<double>>());
#ifdef EIGEN_VECTORIZE_SME_F64F64
  CALL_SUBTEST_4(test_symm_pack<std::complex<double>>());
  CALL_SUBTEST_4(test_pack_direct<std::complex<double>>());
  CALL_SUBTEST_4(test_mapper_fallback<std::complex<double>>());
  CALL_SUBTEST_4(test_neon_small_blocks<std::complex<double>>());
  CALL_SUBTEST_4(test_fp_flags<std::complex<double>>());
  CALL_SUBTEST_4(test_disjoint_parts<std::complex<double>>());
  CALL_SUBTEST_4((test_complex_alpha_range<double, ColMajor>()));
  CALL_SUBTEST_4((test_complex_alpha_range<double, RowMajor>()));
#endif

  // A scalar type SME does not specialize, proving it still routes through the
  // generic product path inside an SME build -- where packet traits, alignment
  // and cache blocking all differ from a plain NEON build.
  CALL_SUBTEST_5(product(Matrix<long double, Dynamic, Dynamic>(33, 17)));
}
