Updates to CUDA dense linear algebra tests

* Use relative error instead of absolute error.
* Update tolerance to account for embedded GPUs such as the Jetson TX2.

Change-Id: I05742ecbfd915e797fcbc4137acc5d1b513cd465
diff --git a/internal/ceres/cuda_dense_cholesky_test.cc b/internal/ceres/cuda_dense_cholesky_test.cc
index 6a45ecf..f134f7a 100644
--- a/internal/ceres/cuda_dense_cholesky_test.cc
+++ b/internal/ceres/cuda_dense_cholesky_test.cc
@@ -75,10 +75,12 @@
   Eigen::Vector4d x = Eigen::Vector4d::Zero();
   ASSERT_EQ(dense_cuda_solver->Solve(b.data(), x.data(), &error_string),
             LinearSolverTerminationType::SUCCESS);
-  EXPECT_NEAR(x(0), 113.75 / 3.0, std::numeric_limits<double>::epsilon() * 10);
-  EXPECT_NEAR(x(1), -31.0 / 3.0, std::numeric_limits<double>::epsilon() * 10);
-  EXPECT_NEAR(x(2), 5.0 / 3.0, std::numeric_limits<double>::epsilon() * 10);
-  EXPECT_NEAR(x(3), 1.0000, std::numeric_limits<double>::epsilon() * 10);
+  static const double kEpsilon = std::numeric_limits<double>::epsilon() * 10;
+  const Eigen::Vector4d x_expected(113.75 / 3.0, -31.0 / 3.0, 5.0 / 3.0, 1.0);
+  EXPECT_NEAR((x[0] - x_expected[0]) / x_expected[0], 0.0, kEpsilon);
+  EXPECT_NEAR((x[1] - x_expected[1]) / x_expected[1], 0.0, kEpsilon);
+  EXPECT_NEAR((x[2] - x_expected[2]) / x_expected[2], 0.0, kEpsilon);
+  EXPECT_NEAR((x[3] - x_expected[3]) / x_expected[3], 0.0, kEpsilon);
 }
 
 TEST(CUDADenseCholesky, SingularMatrix) {
@@ -174,7 +176,7 @@
     summary.termination_type = dense_cholesky->FactorAndSolve(
         kNumCols, lhs.data(), rhs.data(), x_computed.data(), &summary.message);
     ASSERT_EQ(summary.termination_type, LinearSolverTerminationType::SUCCESS);
-    static const double kEpsilon = std::numeric_limits<double>::epsilon() * 2e5;
+    static const double kEpsilon = std::numeric_limits<double>::epsilon() * 3e5;
     ASSERT_NEAR(
         (x_computed - x_expected).norm() / x_expected.norm(), 0.0, kEpsilon);
   }
@@ -236,11 +238,12 @@
   // A single step of the mixed precision solver will be equivalent to solving
   // in low precision (FP32). Hence the tolerance is defined w.r.t. FP32 epsilon
   // instead of FP64 epsilon.
-  static const double kEpsilon = std::numeric_limits<float>::epsilon() * 15.0f;
-  EXPECT_NEAR(x(0), 113.75 / 3.0, kEpsilon);
-  EXPECT_NEAR(x(1), -31.0 / 3.0, kEpsilon);
-  EXPECT_NEAR(x(2), 5.0 / 3.0, kEpsilon);
-  EXPECT_NEAR(x(3), 1.0000, kEpsilon);
+  static const double kEpsilon = std::numeric_limits<float>::epsilon() * 10;
+  const Eigen::Vector4d x_expected(113.75 / 3.0, -31.0 / 3.0, 5.0 / 3.0, 1.0);
+  EXPECT_NEAR((x[0] - x_expected[0]) / x_expected[0], 0.0, kEpsilon);
+  EXPECT_NEAR((x[1] - x_expected[1]) / x_expected[1], 0.0, kEpsilon);
+  EXPECT_NEAR((x[2] - x_expected[2]) / x_expected[2], 0.0, kEpsilon);
+  EXPECT_NEAR((x[3] - x_expected[3]) / x_expected[3], 0.0, kEpsilon);
 }
 
 // Tests the CUDA Cholesky solver with a simple 4x4 matrix.
@@ -272,11 +275,12 @@
             LinearSolverTerminationType::SUCCESS);
   // The error does not reduce beyond four iterations, and stagnates at this
   // level of precision.
-  static const double kEpsilon = std::numeric_limits<double>::epsilon() * 3e2;
-  EXPECT_NEAR(x(0), 113.75 / 3.0, kEpsilon);
-  EXPECT_NEAR(x(1), -31.0 / 3.0, kEpsilon);
-  EXPECT_NEAR(x(2), 5.0 / 3.0, kEpsilon);
-  EXPECT_NEAR(x(3), 1.0000, kEpsilon);
+  static const double kEpsilon = std::numeric_limits<double>::epsilon() * 100;
+  const Eigen::Vector4d x_expected(113.75 / 3.0, -31.0 / 3.0, 5.0 / 3.0, 1.0);
+  EXPECT_NEAR((x[0] - x_expected[0]) / x_expected[0], 0.0, kEpsilon);
+  EXPECT_NEAR((x[1] - x_expected[1]) / x_expected[1], 0.0, kEpsilon);
+  EXPECT_NEAR((x[2] - x_expected[2]) / x_expected[2], 0.0, kEpsilon);
+  EXPECT_NEAR((x[3] - x_expected[3]) / x_expected[3], 0.0, kEpsilon);
 }
 
 TEST(CUDADenseCholeskyMixedPrecision, Randomized1600x1600Tests) {
diff --git a/internal/ceres/cuda_dense_qr_test.cc b/internal/ceres/cuda_dense_qr_test.cc
index 798f12a..05aa416 100644
--- a/internal/ceres/cuda_dense_qr_test.cc
+++ b/internal/ceres/cuda_dense_qr_test.cc
@@ -75,11 +75,9 @@
   ASSERT_EQ(dense_cuda_solver->Solve(b.data(), x.data(), &error_string),
             LinearSolverTerminationType::SUCCESS);
   // Empirically observed accuracy of cuSolverDN's QR solver.
-  const double kEpsilon = 1e-11;
-  EXPECT_NEAR(x(0), 113.75 / 3.0, kEpsilon);
-  EXPECT_NEAR(x(1), -31.0 / 3.0, kEpsilon);
-  EXPECT_NEAR(x(2), 5.0 / 3.0, kEpsilon);
-  EXPECT_NEAR(x(3), 1.0000, kEpsilon);
+  const double kEpsilon = std::numeric_limits<double>::epsilon() * 10.0;
+  const Eigen::Vector4d x_expected(113.75 / 3.0, -31.0 / 3.0, 5.0 / 3.0, 1.0);
+  EXPECT_NEAR((x - x_expected).norm() / x_expected.norm(), 0.0, kEpsilon);
 }
 
 // Tests the CUDA QR solver with a simple 4x4 matrix.
@@ -109,10 +107,11 @@
   ASSERT_EQ(dense_cuda_solver->Solve(b.data(), x.data(), &error_string),
             LinearSolverTerminationType::SUCCESS);
   // Empirically observed accuracy of cuSolverDN's QR solver.
-  const double kEpsilon = 1e-11;
+  const double kEpsilon = std::numeric_limits<double>::epsilon() * 1.5e2;
   // Solution values computed with Octave.
-  EXPECT_NEAR(x[0], -1.143410852713177, kEpsilon);
-  EXPECT_NEAR(x[1], 0.4031007751937981, kEpsilon);
+  const Eigen::Vector2d x_expected(-1.143410852713177, 0.4031007751937981);
+  EXPECT_NEAR((x[0] - x_expected[0]) / x_expected[0], 0.0, kEpsilon);
+  EXPECT_NEAR((x[1] - x_expected[1]) / x_expected[1], 0.0, kEpsilon);
 }
 
 TEST(CUDADenseQR, MustFactorizeBeforeSolve) {