Skip to content

Commit

Permalink
Final test fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
brian-kelley committed Sep 15, 2021
1 parent 9594d75 commit 4e59574
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 27 deletions.
30 changes: 10 additions & 20 deletions src/batched/KokkosBatched_SVD_Serial_Internal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
//Use this macro to handle raw pointer/stride based 2D indexing in this file (just for readability)
//Requires that for pointer X, the corresponding row/col strides are named Xs0 and Xs1.
#define SVDIND(arr, i, j) arr[(i) * arr##s0 + (j) * arr##s1]
#define SVDSWAP(a, b) {auto tmp = a; a = b; b = tmp;}

namespace KokkosBatched {

Expand Down Expand Up @@ -290,16 +291,16 @@ namespace KokkosBatched {
//swap singular values and U/V columns i and maxloc (if maxloc is not already in the right place)
if(i != maxloc)
{
std::swap(sigma[i * ss], sigma[maxloc * ss]);
SVDSWAP(sigma[i * ss], sigma[maxloc * ss]);
if(U)
{
for(int j = 0; j < m; j++)
std::swap(SVDIND(U, j, i), SVDIND(U, j, maxloc));
SVDSWAP(SVDIND(U, j, i), SVDIND(U, j, maxloc))
}
if(Vt)
{
for(int j = 0; j < n; j++)
std::swap(SVDIND(Vt, i, j), SVDIND(Vt, maxloc, j));
SVDSWAP(SVDIND(Vt, i, j), SVDIND(Vt, maxloc, j))
}
}
}
Expand All @@ -318,26 +319,14 @@ namespace KokkosBatched {
//This just means swapping U & Vt, and m & n, and finally implicitly transposing A, U and Vt.
if(m < n)
{
{
value_type* tmp = U;
U = Vt;
Vt = tmp;
}
SVDSWAP(U, Vt);
{
//Transpose A
int tmp = m;
m = n;
n = tmp;
tmp = As0;
As0 = As1;
As1 = tmp;
SVDSWAP(m, n);
SVDSWAP(As0, As1);
//Transpose and finish swapping U, Vt
tmp = Us0;
Us0 = Vts1;
Vts1 = tmp;
tmp = Vts0;
Vts0 = Us1;
Us1 = tmp;
SVDSWAP(Us0, Vts1);
SVDSWAP(Us1, Vts0);
}
}
if(U)
Expand All @@ -363,5 +352,6 @@ namespace KokkosBatched {
} /// end namespace KokkosBatched

#undef SVDIND
#undef SVDSWAP

#endif
2 changes: 1 addition & 1 deletion unit_test/batched/Test_Batched.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
#include "Test_Batched_SerialTrtri.hpp"
#include "Test_Batched_SerialTrtri_Real.hpp"
#include "Test_Batched_SerialTrtri_Complex.hpp"
//#include "Test_Batched_SerialSVD.hpp"
#include "Test_Batched_SerialSVD.hpp"

// Team Kernels
#include "Test_Batched_TeamGemm.hpp"
Expand Down
50 changes: 44 additions & 6 deletions unit_test/batched/Test_Batched_SerialSVD.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
/// \author Brian Kelley (bmkelle@sandia.gov)

#include "Kokkos_Random.hpp"
#include "KokkosKernels_TestUtils.hpp"
#include "KokkosBatched_SVD_Decl.hpp" //For testing overall kernel
#include "KokkosBatched_SVD_Serial_Internal.hpp" //For unit testing individual components
#include "KokkosBatched_SetIdentity_Decl.hpp"
Expand All @@ -14,11 +12,11 @@ namespace Test

template<>
double svdEpsilon()
{return 1e-12;}
{return 1e-13;}

template<>
float svdEpsilon()
{return 2e-6;}
{return 2e-6f;}
}

template<typename Vector>
Expand Down Expand Up @@ -133,7 +131,7 @@ Matrix createRandomMatrix(int m, int n, int deficiency, double maxval = 1.0)
//make row i + 1 a multiple of row 0
for(int j = 0; j < n; j++)
{
mat(i + 1, j) = (double) (i + 2) * mat(0, j);
mhost(i + 1, j) = (double) (i + 2) * mhost(0, j);
}
}
}
Expand All @@ -144,7 +142,7 @@ Matrix createRandomMatrix(int m, int n, int deficiency, double maxval = 1.0)
//make col i + 1 a multiple of col 0
for(int j = 0; j < m; j++)
{
mat(j, i + 1) = (double) (i + 2) * mat(j, 0);
mhost(j, i + 1) = (double) (i + 2) * mhost(j, 0);
}
}
}
Expand Down Expand Up @@ -221,6 +219,44 @@ void testSerialSVD(int m, int n, int deficiency, double maxval = 1.0)
verifySVD(Acopy, Uhost, Vthost, sigmaHost);
}

template<typename Scalar, typename Layout, typename Device>
void testSerialSVDSingularValuesOnly(int m, int n)
{
using Matrix = Kokkos::View<Scalar**, Layout, Device>;
using Vector = Kokkos::View<Scalar*, Device>;
using ExecSpace = typename Device::execution_space;
Matrix A = createRandomMatrix<Matrix>(m, n, 0);
//Fill U, Vt, sigma with nonzeros as well to make sure they are properly overwritten
Matrix U("U", m, m);
Matrix Vt("Vt", n, n);
int maxrank = std::min(m, n);
Vector sigma1("sigma", maxrank);
Vector sigma2("sigma", maxrank);
Vector work("work", std::max(m, n));
Kokkos::deep_copy(U, -5.0);
Kokkos::deep_copy(Vt, -5.0);
Kokkos::deep_copy(sigma1, -5.0);
Kokkos::deep_copy(sigma2, -7.0);
Kokkos::deep_copy(work, -5.0);
//Make a copy of A (before SVD) for verification, since the original will be overwritten
typename Matrix::HostMirror Acopy("Acopy", m, n);
Kokkos::deep_copy(Acopy, A);
//Run the SVD (full mode)
Kokkos::parallel_for(Kokkos::RangePolicy<ExecSpace>(0, 1),
SerialSVDFunctor_Full<Matrix, Vector>(A, U, Vt, sigma1, work));
Kokkos::deep_copy(A, Acopy);
//Run the same SVD (singular values only mode)
Kokkos::parallel_for(Kokkos::RangePolicy<ExecSpace>(0, 1),
SerialSVDFunctor_SingularValuesOnly<Matrix, Vector>(A, sigma2, work));
auto sigma1Host = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), sigma1);
auto sigma2Host = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), sigma2);
//Make sure they match
for(int i = 0; i < maxrank; i++)
{
Test::EXPECT_NEAR_KK(sigma1Host(i), sigma2Host(i), Test::svdEpsilon<Scalar>());
}
}

//Test the bidiagonal n*n SVD step where the last diagonal entry is 0
template<typename Scalar, typename Layout>
void testSerialSVDZeroLastRow(int n)
Expand Down Expand Up @@ -351,6 +387,8 @@ void testSVD()
//Test some important internal routines which are not called often
testSerialSVDZeroLastRow<Scalar, Layout>(10);
testSerialSVDZeroDiagonal<Scalar, Layout>(10, 3);
//Test the mode that just computes singular values
testSerialSVDSingularValuesOnly<Scalar, Layout, Device>(10, 8);
}

#if defined(KOKKOSKERNELS_INST_DOUBLE)
Expand Down

0 comments on commit 4e59574

Please sign in to comment.