Skip to content

Commit

Permalink
Lapack - svd: interface with flags for singular vector compute modes
Browse files Browse the repository at this point in the history
This should be the final interface now. Users can path two string
literals to specify the compute mode for the singular vector and
these modes are forwarded to the TPLs.
  • Loading branch information
lucbv committed Jan 23, 2024
1 parent ddd4cf3 commit 1b9efc8
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 52 deletions.
11 changes: 6 additions & 5 deletions lapack/impl/KokkosLapack_svd_spec.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ struct svd_eti_spec_avail {
Kokkos::View<SCALAR_TYPE **, LAYOUT_TYPE, \
Kokkos::Device<EXEC_SPACE_TYPE, MEM_SPACE_TYPE>, \
Kokkos::MemoryTraits<Kokkos::Unmanaged>>, \
Kokkos::View<SCALAR_TYPE *, LAYOUT_TYPE, \
Kokkos::View<Kokkos::ArithTraits<SCALAR_TYPE>::mag_type *, LAYOUT_TYPE, \
Kokkos::Device<EXEC_SPACE_TYPE, MEM_SPACE_TYPE>, \
Kokkos::MemoryTraits<Kokkos::Unmanaged>>, \
Kokkos::View<SCALAR_TYPE **, LAYOUT_TYPE, \
Expand Down Expand Up @@ -89,8 +89,9 @@ struct SVD {
template <class ExecutionSpace, class AMatrix, class SVector, class UMatrix, class VMatrix>
struct SVD<ExecutionSpace, AMatrix, SVector, UMatrix, VMatrix, false,
KOKKOSKERNELS_IMPL_COMPILE_LIBRARY> {
static void svd(const ExecutionSpace & /* space */, const AMatrix & /* A */,
const SVector & /* S */, const UMatrix & /* U */, const VMatrix & /* Vt */) {
static void svd(const ExecutionSpace & /* space */, const char* /* jobu */, const char* /* jobvt */,
const AMatrix & /* A */, const SVector & /* S */, const UMatrix & /* U */,
const VMatrix & /* Vt */) {
// NOTE: Might add the implementation of KokkosLapack::svd later
throw std::runtime_error(
"No fallback implementation of SVD (singular value decomposition) "
Expand All @@ -116,7 +117,7 @@ struct SVD<ExecutionSpace, AMatrix, SVector, UMatrix, VMatrix, false,
Kokkos::View<SCALAR_TYPE **, LAYOUT_TYPE, \
Kokkos::Device<EXEC_SPACE_TYPE, MEM_SPACE_TYPE>, \
Kokkos::MemoryTraits<Kokkos::Unmanaged>>, \
Kokkos::View<SCALAR_TYPE *, LAYOUT_TYPE, \
Kokkos::View<Kokkos::ArithTraits<SCALAR_TYPE>::mag_type *, LAYOUT_TYPE, \
Kokkos::Device<EXEC_SPACE_TYPE, MEM_SPACE_TYPE>, \
Kokkos::MemoryTraits<Kokkos::Unmanaged>>, \
Kokkos::View<SCALAR_TYPE **, LAYOUT_TYPE, \
Expand All @@ -134,7 +135,7 @@ struct SVD<ExecutionSpace, AMatrix, SVector, UMatrix, VMatrix, false,
Kokkos::View<SCALAR_TYPE **, LAYOUT_TYPE, \
Kokkos::Device<EXEC_SPACE_TYPE, MEM_SPACE_TYPE>, \
Kokkos::MemoryTraits<Kokkos::Unmanaged>>, \
Kokkos::View<SCALAR_TYPE *, LAYOUT_TYPE, \
Kokkos::View<Kokkos::ArithTraits<SCALAR_TYPE>::mag_type *, LAYOUT_TYPE, \
Kokkos::Device<EXEC_SPACE_TYPE, MEM_SPACE_TYPE>, \
Kokkos::MemoryTraits<Kokkos::Unmanaged>>, \
Kokkos::View<SCALAR_TYPE **, LAYOUT_TYPE, \
Expand Down
44 changes: 39 additions & 5 deletions lapack/src/KokkosLapack_svd.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ namespace KokkosLapack {
/// \param Vt [out] the first min(m, n) columns of Vt are the right singular vectors of A.
///
template <class ExecutionSpace, class AMatrix, class SVector, class UMatrix, class VMatrix>
void svd(const ExecutionSpace& space, const AMatrix& A, const SVector& S,
const UMatrix& U, const VMatrix& Vt) {
void svd(const ExecutionSpace& space, const char jobu[], const char jobvt[],
const AMatrix& A, const SVector& S, const UMatrix& U, const VMatrix& Vt) {

static_assert(
Kokkos::SpaceAccessibility<ExecutionSpace,
Expand Down Expand Up @@ -104,6 +104,40 @@ void svd(const ExecutionSpace& space, const AMatrix& A, const SVector& S,
KokkosKernels::Impl::throw_runtime_exception(os.str());
}

// Check the jobu and jobvt control flags
// The only valid options there are 'A', 'S', 'O' and 'N'
const bool is_jobu_invalid = !((jobu[0] == 'A') || (jobu[0] == 'a') ||
(jobu[0] == 'S') || (jobu[0] == 's') ||
(jobu[0] == 'O') || (jobu[0] == 'o') ||
(jobu[0] == 'N') || (jobu[0] == 'n'));

const bool is_jobvt_invalid = !((jobvt[0] == 'A') || (jobvt[0] == 'a') ||
(jobvt[0] == 'S') || (jobvt[0] == 's') ||
(jobvt[0] == 'O') || (jobvt[0] == 'o') ||
(jobvt[0] == 'N') || (jobvt[0] == 'n'));

if(is_jobu_invalid && is_jobvt_invalid) {
std::ostringstream oss;
oss << "KokkosLapack::svd: both jobu and jobvt are invalid!\n"
<< "Possible values are A, S, O or N, submitted values are "
<< jobu[0] << " and " << jobvt[0] << "\n";
KokkosKernels::Impl::throw_runtime_exception(os.str());
}
if(is_jobu_invalid) {
std::ostringstream oss;
oss << "KokkosLapack::svd: jobu is invalid!\n"
<< "Possible values are A, S, O or N, submitted value is "
<< jobu[0] << "\n";
KokkosKernels::Impl::throw_runtime_exception(os.str());
}
if(is_jobvt_invalid) {
std::ostringstream oss;
oss << "KokkosLapack::svd: jobvt is invalid!\n"
<< "Possible values are A, S, O or N, submitted value is "
<< jobvt[0] << "\n";
KokkosKernels::Impl::throw_runtime_exception(os.str());
}

using AMatrix_Internal = Kokkos::View<typename AMatrix::non_const_value_type**,
typename AMatrix::array_layout,
typename AMatrix::device_type,
Expand All @@ -130,7 +164,7 @@ void svd(const ExecutionSpace& space, const AMatrix& A, const SVector& S,
VMatrix_Internal Vt_i = Vt;

KokkosLapack::Impl::SVD<ExecutionSpace, AMatrix_Internal, SVector_Internal,
UMatrix_Internal, VMatrix_Internal>::svd(space, A_i, S_i, U_i, Vt_i);
UMatrix_Internal, VMatrix_Internal>::svd(space, jobu, jobvt, A_i, S_i, U_i, Vt_i);
}

/// \brief Compute the Singular Value Decomposition of A = U*S*Vt
Expand All @@ -146,10 +180,10 @@ void svd(const ExecutionSpace& space, const AMatrix& A, const SVector& S,
/// \param Vt [out] the first min(m, n) columns of Vt are the right singular vectors of A.
///
template <class AMatrix, class SVector, class UMatrix, class VMatrix>
void svd(const AMatrix& A, const SVector& S, const UMatrix& U,
void svd(const char jobu[], const char jobvt[], const AMatrix& A, const SVector& S, const UMatrix& U,
const VMatrix& Vt) {
typename AMatrix::execution_space space{};
svd(space, A, S, U, Vt);
svd(space, jobu, jobvt, A, S, U, Vt);
}

} // namespace KokkosLapack
Expand Down
6 changes: 3 additions & 3 deletions lapack/tpls/KokkosLapack_svd_tpl_spec_avail.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ struct svd_tpl_spec_avail {
EXECSPACE, \
Kokkos::View<SCALAR**, LAYOUT, Kokkos::Device<EXECSPACE, Kokkos::HostSpace>, \
Kokkos::MemoryTraits<Kokkos::Unmanaged> >, \
Kokkos::View<SCALAR*, LAYOUT, Kokkos::Device<EXECSPACE, Kokkos::HostSpace>, \
Kokkos::View<Kokkos::ArithTraits<SCALAR>::mag_type*, LAYOUT, Kokkos::Device<EXECSPACE, Kokkos::HostSpace>, \
Kokkos::MemoryTraits<Kokkos::Unmanaged> >, \
Kokkos::View<SCALAR**, LAYOUT, Kokkos::Device<EXECSPACE, Kokkos::HostSpace>, \
Kokkos::MemoryTraits<Kokkos::Unmanaged> >, \
Expand Down Expand Up @@ -74,7 +74,7 @@ KOKKOSLAPACK_SVD_TPL_SPEC_AVAIL_LAPACK(Kokkos::complex<double>, Kokkos::LayoutLe
Kokkos::Cuda, \
Kokkos::View<SCALAR**, LAYOUT, Kokkos::Device<Kokkos::Cuda, MEMSPACE>, \
Kokkos::MemoryTraits<Kokkos::Unmanaged> >, \
Kokkos::View<SCALAR*, LAYOUT, Kokkos::Device<Kokkos::Cuda, MEMSPACE>, \
Kokkos::View<Kokkos::ArithTraits<SCALAR>::mag_type*, LAYOUT, Kokkos::Device<Kokkos::Cuda, MEMSPACE>, \
Kokkos::MemoryTraits<Kokkos::Unmanaged> >, \
Kokkos::View<SCALAR**, LAYOUT, Kokkos::Device<Kokkos::Cuda, MEMSPACE>, \
Kokkos::MemoryTraits<Kokkos::Unmanaged> >, \
Expand Down Expand Up @@ -105,7 +105,7 @@ KOKKOSLAPACK_SVD_TPL_SPEC_AVAIL_CUSOLVER(Kokkos::complex<double>, Kokkos::Layout
Kokkos::HIP, \
Kokkos::View<SCALAR**, LAYOUT, Kokkos::Device<Kokkos::HIP, MEMSPACE>, \
Kokkos::MemoryTraits<Kokkos::Unmanaged> >, \
Kokkos::View<SCALAR*, LAYOUT, Kokkos::Device<Kokkos::HIP, MEMSPACE>, \
Kokkos::View<Kokkos::ArithTraits<SCALAR>::mag_type*, LAYOUT, Kokkos::Device<Kokkos::HIP, MEMSPACE>, \
Kokkos::MemoryTraits<Kokkos::Unmanaged> >, \
Kokkos::View<SCALAR**, LAYOUT, Kokkos::Device<Kokkos::HIP, MEMSPACE>, \
Kokkos::MemoryTraits<Kokkos::Unmanaged> >, \
Expand Down
Loading

0 comments on commit 1b9efc8

Please sign in to comment.