// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2026 Rasmus Munk Larsen <rmlarsen@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// SPDX-License-Identifier: MPL-2.0

// Tests for GpuSVD: GPU SVD via cuSOLVER.

#define EIGEN_USE_GPU
#include "main.h"
#include <Eigen/SVD>
#include <contrib/Eigen/GPU>

#include "./gpu_test_helpers.h"

using namespace Eigen;

// ---- SVD reconstruction: U * diag(S) * VT ≈ A ------------------------------

template <typename Scalar, unsigned int Options>
void test_svd_reconstruction(Index m, Index n) {
  using Mat = Matrix<Scalar, Dynamic, Dynamic>;
  using RealScalar = typename NumTraits<Scalar>::Real;

  Mat A = Mat::Random(m, n);
  gpu::SVD<Scalar> svd(A, Options);
  VERIFY_IS_EQUAL(svd.info(), Success);

  auto S = svd.singularValues();
  Mat U = svd.matrixU();
  Mat VT = svd.matrixVT();

  const Index k = (std::min)(m, n);

  // Reconstruct: A_hat = U[:,:k] * diag(S) * VT[:k,:].
  Mat A_hat = U.leftCols(k) * S.asDiagonal() * VT.topRows(k);
  RealScalar tol = RealScalar(5) * std::sqrt(static_cast<RealScalar>(k)) * NumTraits<Scalar>::epsilon() * A.norm();
  VERIFY((A_hat - A).norm() < tol);

  // Orthogonality: U^H * U ≈ I.
  Mat UtU = U.adjoint() * U;
  Mat I_u = Mat::Identity(U.cols(), U.cols());
  VERIFY((UtU - I_u).norm() < tol);

  // Orthogonality: VT * VT^H ≈ I.
  Mat VtVh = VT * VT.adjoint();
  Mat I_v = Mat::Identity(VT.rows(), VT.rows());
  VERIFY((VtVh - I_v).norm() < tol);
}

// ---- Singular values match CPU BDCSVD ---------------------------------------

template <typename Scalar>
void test_svd_singular_values(Index m, Index n) {
  using Mat = Matrix<Scalar, Dynamic, Dynamic>;
  using RealScalar = typename NumTraits<Scalar>::Real;

  Mat A = Mat::Random(m, n);
  gpu::SVD<Scalar> svd(A, 0);  // values only
  VERIFY_IS_EQUAL(svd.info(), Success);

  auto S_gpu = svd.singularValues();
  auto S_cpu = BDCSVD<Mat>(A).singularValues();

  // Weyl's perturbation bound (Higham, Accuracy and Stability of Numerical
  // Algorithms, 2nd ed., §10.2.3): |σ_i(A) - σ_i(A+δA)| ≤ ||δA||. Both cuSOLVER
  // and BDCSVD have backward error ||δA|| / ||A|| ≤ p(m,n) · u; the difference
  // of the two computed singular value vectors is bounded by 2·p(m,n)·u·S_max,
  // and √(min) · ||·||_∞ ≥ ||·||_2. Across 5k trials per case in
  // {float, double, complex<float>, complex<double>} × {(64,64), (128,64)},
  // worst observed err / (√min · u · S_max) is ≈ 6.2; we use 12 for headroom
  // against future runs hitting the tail of the distribution.
  RealScalar tol =
      RealScalar(12) * std::sqrt(static_cast<RealScalar>((std::min)(m, n))) * NumTraits<Scalar>::epsilon() * S_cpu(0);
  VERIFY((S_gpu - S_cpu).norm() < tol);
}

// ---- Solve: pseudoinverse ---------------------------------------------------

template <typename Scalar>
void test_svd_solve(Index m, Index n, Index nrhs) {
  using Mat = Matrix<Scalar, Dynamic, Dynamic>;
  using RealScalar = typename NumTraits<Scalar>::Real;

  Mat A = Mat::Random(m, n);
  Mat B = Mat::Random(m, nrhs);

  gpu::SVD<Scalar> svd(A, ComputeThinU | ComputeThinV);
  VERIFY_IS_EQUAL(svd.info(), Success);

  Mat X = svd.solve(B);
  VERIFY_IS_EQUAL(X.rows(), n);
  VERIFY_IS_EQUAL(X.cols(), nrhs);

  // Compare with CPU BDCSVD solve. Wedin's perturbation theorem (Higham,
  // Accuracy and Stability of Numerical Algorithms, 2nd ed., §20.1) bounds
  // the forward error of a backward-stable SVD-based pseudoinverse solve by
  // c · κ(A) · u with c = O(1). Comparing two such solvers doubles the
  // constant. Across 6k trials over {float, double, complex<float>,
  // complex<double>} and {square, over-/underdetermined} shapes, the worst
  // observed err / (κ · u) is 5.3.
  auto cpu_svd = BDCSVD<Mat, ComputeThinU | ComputeThinV>(A);
  Mat X_cpu = cpu_svd.solve(B);
  auto S = cpu_svd.singularValues();
  const RealScalar cond = S(0) / S(S.size() - 1);
  const RealScalar tol = RealScalar(8) * cond * NumTraits<Scalar>::epsilon();
  VERIFY((X - X_cpu).norm() / X_cpu.norm() < tol);
}

// ---- Solve: Context-bound ---------------------------------------------------
// A Context-bound SVD shares the Context's stream and cuBLASLt plan cache /
// workspace; its pseudoinverse solve must agree with the standalone solver.

template <typename Scalar>
void test_svd_solve_context(Index m, Index n, Index nrhs) {
  using Mat = Matrix<Scalar, Dynamic, Dynamic>;
  using RealScalar = typename NumTraits<Scalar>::Real;

  Mat A = Mat::Random(m, n);
  Mat B = Mat::Random(m, nrhs);

  gpu::Context ctx;
  gpu::SVD<Scalar> svd(ctx, A, ComputeThinU | ComputeThinV);
  VERIFY_IS_EQUAL(svd.info(), Success);
  Mat X = svd.solve(B);

  gpu::SVD<Scalar> svd_standalone(A, ComputeThinU | ComputeThinV);
  Mat X_ref = svd_standalone.solve(B);

  // Same algorithm on both paths; only the cuBLASLt plan selection may
  // differ, so bound the difference by κ(A)·u as in test_svd_solve.
  auto S = svd_standalone.singularValues();
  const RealScalar cond = S(0) / S(S.size() - 1);
  const RealScalar tol = RealScalar(8) * cond * NumTraits<Scalar>::epsilon();
  VERIFY((X - X_ref).norm() / X_ref.norm() < tol);

  // Context-bound rvalue constructor adopts A when m >= n (a wide A is
  // transposed into a copy).
  auto d_A = gpu::DeviceMatrix<Scalar>::fromHost(A, ctx.stream());
  gpu::SVD<Scalar> svd_adopt(ctx, std::move(d_A), ComputeThinU | ComputeThinV);
  VERIFY(m < n || d_A.empty());
  VERIFY_IS_EQUAL(svd_adopt.info(), Success);
  VERIFY(svd_adopt.stream() == ctx.stream());
  Mat X_adopt = svd_adopt.solve(B);
  VERIFY((X_adopt - X_ref).norm() / X_ref.norm() < tol);
}

// ---- Solve: truncated -------------------------------------------------------

template <typename Scalar>
void test_svd_solve_truncated(Index m, Index n) {
  using Mat = Matrix<Scalar, Dynamic, Dynamic>;
  using RealScalar = typename NumTraits<Scalar>::Real;

  Mat A = Mat::Random(m, n);
  Mat B = Mat::Random(m, 1);
  const Index k = (std::min)(m, n);
  const Index trunc = k / 2;
  eigen_assert(trunc > 0);

  gpu::SVD<Scalar> svd(A, ComputeThinU | ComputeThinV);
  Mat X_trunc = svd.solve(B, trunc);

  // Build CPU reference: truncated pseudoinverse.
  auto cpu_svd = BDCSVD<Mat, ComputeThinU | ComputeThinV>(A);
  auto S = cpu_svd.singularValues();
  Mat U = cpu_svd.matrixU();
  Mat V = cpu_svd.matrixV();

  // D_ii = 1/S_i for i < trunc, 0 otherwise.
  Matrix<RealScalar, Dynamic, 1> D = Matrix<RealScalar, Dynamic, 1>::Zero(k);
  for (Index i = 0; i < trunc; ++i) D(i) = RealScalar(1) / S(i);
  Mat X_ref = V * D.asDiagonal() * U.adjoint() * B;

  RealScalar tol = RealScalar(100) * RealScalar(k) * NumTraits<Scalar>::epsilon();
  VERIFY((X_trunc - X_ref).norm() / X_ref.norm() < tol);
}

// ---- Solve: Tikhonov regularized --------------------------------------------

template <typename Scalar>
void test_svd_solve_regularized(Index m, Index n) {
  using Mat = Matrix<Scalar, Dynamic, Dynamic>;
  using RealScalar = typename NumTraits<Scalar>::Real;

  Mat A = Mat::Random(m, n);
  Mat B = Mat::Random(m, 1);
  RealScalar lambda = RealScalar(0.1);
  const Index k = (std::min)(m, n);

  gpu::SVD<Scalar> svd(A, ComputeThinU | ComputeThinV);
  Mat X_reg = svd.solve(B, lambda);

  // CPU reference: D_ii = S_i / (S_i^2 + lambda^2).
  auto cpu_svd = BDCSVD<Mat, ComputeThinU | ComputeThinV>(A);
  auto S = cpu_svd.singularValues();
  Mat U = cpu_svd.matrixU();
  Mat V = cpu_svd.matrixV();

  Matrix<RealScalar, Dynamic, 1> D(k);
  for (Index i = 0; i < k; ++i) D(i) = S(i) / (S(i) * S(i) + lambda * lambda);
  Mat X_ref = V * D.asDiagonal() * U.adjoint() * B;

  RealScalar tol = RealScalar(100) * RealScalar(k) * NumTraits<Scalar>::epsilon();
  VERIFY((X_reg - X_ref).norm() / X_ref.norm() < tol);
}

// ---- Solve: rank-deficient (exercise drop_threshold pseudoinverse) ----------

template <typename Scalar>
void test_svd_solve_rank_deficient(Index m, Index n, Index r) {
  using Mat = Matrix<Scalar, Dynamic, Dynamic>;
  using Vec = Matrix<typename NumTraits<Scalar>::Real, Dynamic, 1>;
  using RealScalar = typename NumTraits<Scalar>::Real;

  eigen_assert(r > 0 && r < (std::min)(m, n));

  // Build A of rank exactly r: A = U[:,:r] * diag(s) * V[:,:r]^H.
  Mat U_seed = Mat::Random(m, m);
  Mat U_full = HouseholderQR<Mat>(U_seed).householderQ();
  Mat V_seed = Mat::Random(n, n);
  Mat V_full = HouseholderQR<Mat>(V_seed).householderQ();
  Vec sigma(r);
  for (Index i = 0; i < r; ++i) sigma(i) = RealScalar(1) + RealScalar(i);  // distinct, well-spaced
  Mat A = U_full.leftCols(r) * sigma.asDiagonal() * V_full.leftCols(r).adjoint();

  Mat B = Mat::Random(m, 1);

  gpu::SVD<Scalar> svd(A, ComputeThinU | ComputeThinV);
  VERIFY_IS_EQUAL(svd.info(), Success);
  Mat X_gpu = svd.solve(B);

  // Reference: CPU BDCSVD with the same drop_threshold semantics (its default solve()
  // also drops near-zero singular values relative to S(0) * (m, n)_max * epsilon).
  Mat X_cpu = BDCSVD<Mat, ComputeThinU | ComputeThinV>(A).solve(B);

  // Both should produce the minimum-norm least-squares solution; compare via the
  // "useful" residual A^H r: zero up to the rank-r component plus rounding.
  RealScalar tol = RealScalar(50) * RealScalar((std::max)(m, n)) * NumTraits<Scalar>::epsilon();
  VERIFY((X_gpu - X_cpu).norm() / X_cpu.norm() < tol);

  // Norm of X should also be minimum (X has no component in null(A) up to rounding).
  VERIFY(numext::abs(X_gpu.norm() - X_cpu.norm()) / X_cpu.norm() < tol);
}

// ---- Reconstruction: full U / full V on a wide matrix (m < n) ---------------
//
// Exercises the transposed-internal-representation path through gesvd combined
// with the matrixU/matrixVT swap logic.

template <typename Scalar>
void test_svd_reconstruction_full_wide(Index m, Index n) {
  using Mat = Matrix<Scalar, Dynamic, Dynamic>;
  using RealScalar = typename NumTraits<Scalar>::Real;

  eigen_assert(m < n);
  Mat A = Mat::Random(m, n);
  gpu::SVD<Scalar> svd(A, ComputeFullU | ComputeFullV);
  VERIFY_IS_EQUAL(svd.info(), Success);

  auto S = svd.singularValues();
  Mat U = svd.matrixU();    // m × m
  Mat VT = svd.matrixVT();  // n × n
  Mat V = svd.matrixV();    // n × n (matrixV alias should match matrixVT().adjoint())

  VERIFY_IS_EQUAL(U.rows(), m);
  VERIFY_IS_EQUAL(U.cols(), m);
  VERIFY_IS_EQUAL(VT.rows(), n);
  VERIFY_IS_EQUAL(VT.cols(), n);
  VERIFY_IS_EQUAL(V.rows(), n);
  VERIFY_IS_EQUAL(V.cols(), n);
  VERIFY_IS_APPROX(V, VT.adjoint());

  const Index k = (std::min)(m, n);
  Mat A_hat = U.leftCols(k) * S.asDiagonal() * VT.topRows(k);
  RealScalar tol = RealScalar(5) * std::sqrt(static_cast<RealScalar>(k)) * NumTraits<Scalar>::epsilon() * A.norm();
  VERIFY((A_hat - A).norm() < tol);

  Mat UtU = U.adjoint() * U;
  VERIFY((UtU - Mat::Identity(m, m)).norm() < tol);
  Mat VtVh = VT * VT.adjoint();
  VERIFY((VtVh - Mat::Identity(n, n)).norm() < tol);
}

// ---- Device-side accessors --------------------------------------------------
//
// Verify that d_singularValues / d_matrixU / d_matrixVT return views over the
// SVD's internal storage that agree with the host accessors after toHost().

template <typename Scalar>
void test_svd_device_accessors(Index m, Index n) {
  using Mat = Matrix<Scalar, Dynamic, Dynamic>;
  using RealScalar = typename NumTraits<Scalar>::Real;

  Mat A = Mat::Random(m, n);
  gpu::SVD<Scalar> svd(A, ComputeThinU | ComputeThinV);
  VERIFY_IS_EQUAL(svd.info(), Success);

  auto d_S = svd.d_singularValues();
  auto d_U = svd.d_matrixU();
  auto d_VT = svd.d_matrixVT();

  Matrix<RealScalar, Dynamic, 1> S_host = d_S.toHost();
  Mat U_host = d_U.toHost();
  Mat VT_host = d_VT.toHost();

  VERIFY_IS_APPROX(S_host, svd.singularValues());
  VERIFY_IS_APPROX(U_host, svd.matrixU());
  VERIFY_IS_APPROX(VT_host, svd.matrixVT());

  // Multiple invocations must keep returning views without disturbing the SVD's state:
  // call again, then verify the SVD's host accessors still produce correct results.
  (void)svd.d_matrixU();
  (void)svd.d_matrixVT();
  VERIFY_IS_APPROX(svd.matrixU(), U_host);
  VERIFY_IS_APPROX(svd.matrixVT(), VT_host);
}

template <typename Scalar>
void test_svd_device_accessors_full_wide(Index m, Index n) {
  using Mat = Matrix<Scalar, Dynamic, Dynamic>;
  using RealScalar = typename NumTraits<Scalar>::Real;

  eigen_assert(m < n);
  Mat A = Mat::Random(m, n);
  gpu::SVD<Scalar> svd(A, ComputeFullU | ComputeFullV);
  VERIFY_IS_EQUAL(svd.info(), Success);

  auto d_S = svd.d_singularValues();
  auto d_U = svd.d_matrixU();
  auto d_VT = svd.d_matrixVT();

  VERIFY_IS_EQUAL(d_U.rows(), m);
  VERIFY_IS_EQUAL(d_U.cols(), m);
  VERIFY_IS_EQUAL(d_VT.rows(), n);
  VERIFY_IS_EQUAL(d_VT.cols(), n);

  Matrix<RealScalar, Dynamic, 1> S_host = d_S.toHost();
  Mat U_host = d_U.toHost();
  Mat VT_host = d_VT.toHost();

  VERIFY_IS_APPROX(S_host, svd.singularValues());
  VERIFY_IS_APPROX(U_host, svd.matrixU());
  VERIFY_IS_APPROX(VT_host, svd.matrixVT());
}

// ---- Chain device views into a downstream cuBLAS GEMM (no D2D copy) ---------
//
// d_matrixU() returns a non-owning view over the SVD's internal d_U_ buffer.
// Feeding the view straight into a Context-driven GEMM exercises cross-stream
// event sync and confirms the borrow-deleter does not double-free on temporary
// destruction.

template <typename Scalar>
void test_svd_chain_orthogonality(Index m, Index n) {
  using Mat = Matrix<Scalar, Dynamic, Dynamic>;
  using RealScalar = typename NumTraits<Scalar>::Real;

  Mat A = Mat::Random(m, n);
  gpu::SVD<Scalar> svd(A, ComputeThinU | ComputeThinV);
  VERIFY_IS_EQUAL(svd.info(), Success);

  const Index k = (std::min)(m, n);

  // U^H * U = I_k, all on device, no host roundtrip on U.
  gpu::Context ctx;
  gpu::DeviceMatrix<Scalar> d_UtU;
  {
    auto d_U = svd.d_matrixU();
    d_UtU.device(ctx) = d_U.adjoint() * d_U;
  }
  Mat UtU = d_UtU.toHost();
  RealScalar tol = RealScalar(20) * std::sqrt(static_cast<RealScalar>(k)) * NumTraits<Scalar>::epsilon();
  VERIFY((UtU - Mat::Identity(k, k)).norm() < tol);

  // VT * VT^H = I_k.
  gpu::DeviceMatrix<Scalar> d_VVt;
  {
    auto d_VT = svd.d_matrixVT();
    d_VVt.device(ctx) = d_VT * d_VT.adjoint();
  }
  Mat VVt = d_VVt.toHost();
  VERIFY((VVt - Mat::Identity(k, k)).norm() < tol);

  // After view destruction, SVD's state must remain valid (the deleter is a no-op
  // for views, so the underlying d_U_ / d_VT_ are not freed).
  Mat U_again = svd.matrixU();
  Mat VT_again = svd.matrixVT();
  VERIFY_IS_EQUAL(U_again.rows(), m);
  VERIFY_IS_EQUAL(VT_again.cols(), n);
}

// ---- Host getters wait only for the solver's stream -------------------------
// A download through the legacy default stream (cudaMemcpy) would also wait
// for the unrelated blocking stream parked below.

template <typename Scalar>
void test_svd_getters_ignore_other_streams(Index m, Index n) {
  using Mat = Matrix<Scalar, Dynamic, Dynamic>;

  Mat A = Mat::Random(m, n);
  gpu::SVD<Scalar> svd(A, ComputeThinU | ComputeThinV);
  VERIFY_IS_EQUAL(svd.info(), Success);

  gpu::Context other;
  gpu_test::ParkedStream parked(other.stream());
  (void)svd.singularValues();
  (void)svd.matrixU();
  (void)svd.matrixVT();
  VERIFY(parked.held());
}

// ---- Empty matrix -----------------------------------------------------------

void test_svd_empty() {
  ArrayXXd empty(0, 0);
  gpu::SVD<double> svd(empty, 0);
  VERIFY_IS_EQUAL(svd.info(), Success);
  VERIFY_IS_EQUAL(svd.rows(), 0);
  VERIFY_IS_EQUAL(svd.cols(), 0);

  svd.compute(MatrixXd::Random(4, 6), ComputeThinU | ComputeThinV);
  VERIFY_IS_EQUAL(svd.info(), Success);

  svd.compute(MatrixXd(0, 7), 0);
  VERIFY_IS_EQUAL(svd.info(), Success);
  VERIFY_IS_EQUAL(svd.rows(), 0);
  VERIFY_IS_EQUAL(svd.cols(), 7);
  VERIFY_IS_EQUAL(svd.singularValues().size(), 0);

  svd.compute(MatrixXd(5, 0), 0);
  VERIFY_IS_EQUAL(svd.info(), Success);
  VERIFY_IS_EQUAL(svd.rows(), 5);
  VERIFY_IS_EQUAL(svd.cols(), 0);
  VERIFY_IS_EQUAL(svd.singularValues().size(), 0);
}

// ---- Device-resident solve ----------------------------------------------------

template <typename Scalar>
void test_device_solve(Index m, Index n, Index nrhs) {
  using Mat = Eigen::Matrix<Scalar, Dynamic, Dynamic>;

  Mat A = Mat::Random(m, n);
  Mat B = Mat::Random(m, nrhs);

  gpu::SVD<Scalar> svd(A);
  VERIFY(svd.info() == Success);
  Mat X_host = svd.solve(B);

  auto d_B = gpu::DeviceMatrix<Scalar>::fromHost(B, svd.stream());
  gpu::DeviceMatrix<Scalar> d_X = svd.solve(d_B);
  VERIFY_IS_APPROX(d_X.toHost(), X_host);

  // Second device solve reuses the cached inverse diagonal (no host sync).
  gpu::DeviceMatrix<Scalar> d_X2 = svd.solve(d_B);
  VERIFY_IS_APPROX(d_X2.toHost(), X_host);

  // Truncated variant matches its host counterpart too.
  const Index trunc = (std::min)(m, n) / 2 + 1;
  Mat Xt_host = svd.solve(B, trunc);
  gpu::DeviceMatrix<Scalar> d_Xt = svd.solve(d_B, trunc);
  VERIFY_IS_APPROX(d_Xt.toHost(), Xt_host);
}

// ---- Per-scalar driver ------------------------------------------------------

template <typename Scalar>
void test_scalar() {
  CALL_SUBTEST(test_device_solve<Scalar>(64, 48, 4));
  CALL_SUBTEST(test_device_solve<Scalar>(48, 64, 3));
  // Reconstruction + orthogonality (thin and full, identical test logic).
  CALL_SUBTEST((test_svd_reconstruction<Scalar, ComputeThinU | ComputeThinV>(64, 64)));
  CALL_SUBTEST((test_svd_reconstruction<Scalar, ComputeThinU | ComputeThinV>(128, 64)));
  CALL_SUBTEST((test_svd_reconstruction<Scalar, ComputeThinU | ComputeThinV>(64, 128)));  // wide (m < n)
  CALL_SUBTEST((test_svd_reconstruction<Scalar, ComputeFullU | ComputeFullV>(64, 64)));
  CALL_SUBTEST((test_svd_reconstruction<Scalar, ComputeFullU | ComputeFullV>(128, 64)));

  // Singular values.
  CALL_SUBTEST(test_svd_singular_values<Scalar>(64, 64));
  CALL_SUBTEST(test_svd_singular_values<Scalar>(128, 64));

  // Solve.
  CALL_SUBTEST(test_svd_solve<Scalar>(64, 64, 4));
  CALL_SUBTEST(test_svd_solve<Scalar>(128, 64, 4));
  CALL_SUBTEST(test_svd_solve<Scalar>(64, 128, 4));  // wide (m < n)
  CALL_SUBTEST(test_svd_solve_context<Scalar>(64, 48, 3));

  // Truncated and regularized solve.
  CALL_SUBTEST(test_svd_solve_truncated<Scalar>(64, 64));
  CALL_SUBTEST(test_svd_solve_regularized<Scalar>(64, 64));

  // Rank-deficient solve (exercises drop_threshold pseudoinverse).
  CALL_SUBTEST(test_svd_solve_rank_deficient<Scalar>(64, 64, 32));
  CALL_SUBTEST(test_svd_solve_rank_deficient<Scalar>(96, 64, 16));
  CALL_SUBTEST(test_svd_solve_rank_deficient<Scalar>(64, 96, 16));

  // Wide matrix with full U/V (transposed-internal path).
  CALL_SUBTEST((test_svd_reconstruction_full_wide<Scalar>(64, 96)));

  // Device accessors.
  CALL_SUBTEST(test_svd_device_accessors<Scalar>(64, 64));
  CALL_SUBTEST(test_svd_device_accessors<Scalar>(96, 64));
  CALL_SUBTEST(test_svd_device_accessors<Scalar>(64, 96));
  CALL_SUBTEST(test_svd_device_accessors_full_wide<Scalar>(64, 96));

  // Chain device views into a downstream GEMM (orthogonality check).
  CALL_SUBTEST(test_svd_chain_orthogonality<Scalar>(64, 64));
  CALL_SUBTEST(test_svd_chain_orthogonality<Scalar>(96, 64));

  CALL_SUBTEST(test_svd_getters_ignore_other_streams<Scalar>(64, 48));
  CALL_SUBTEST(test_svd_getters_ignore_other_streams<Scalar>(48, 64));  // wide: U and V^T swap roles
}

EIGEN_DECLARE_TEST(gpu_cusolver_svd) {
  gpu_test::require_cuda_device();
  // Split by scalar so each part compiles in parallel.
  CALL_SUBTEST_1(test_scalar<float>());
  CALL_SUBTEST_2(test_scalar<double>());
  CALL_SUBTEST_3(test_scalar<std::complex<float>>());
  CALL_SUBTEST_4(test_scalar<std::complex<double>>());
  CALL_SUBTEST_5(test_svd_empty());
}
