Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rotg/rot/rotmg/rotm docs and examples #2472

Merged
merged 5 commits into from
Jan 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions blas/src/KokkosBlas1_rot.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,28 @@
#ifndef KOKKOSBLAS1_ROT_HPP_
#define KOKKOSBLAS1_ROT_HPP_

#include <Kokkos_Core.hpp>
#include <KokkosBlas1_rot_spec.hpp>
#include <KokkosKernels_helpers.hpp>
#include <KokkosKernels_Error.hpp>

namespace KokkosBlas {

// clang-format off
/// \brief Apply a plane rotation.
///
/// \tparam execution_space Space on which to execute. Must be able to access VectorView, MagnitudeView and ScalarView.
/// \tparam VectorView A 1-D view of nonconst scalars
/// \tparam MagnitudeView A 0-D view of nonconst, real-valued scalar
/// \tparam ScalarView A 0-D view of scalar
///
/// \param space [in] the execution space
/// \param X [in/out] First vector to be rotated
/// \param Y [in/out] Second vector to be rotated
/// \param c [out] cosine value associated with the
/// rotation
/// \param s [out] sine value associated with the rotation
// clang-format on
template <class execution_space, class VectorView, class MagnitudeView, class ScalarView>
void rot(execution_space const& space, VectorView const& X, VectorView const& Y, MagnitudeView const& c,
ScalarView const& s) {
Expand Down
9 changes: 6 additions & 3 deletions blas/src/KokkosBlas1_rotg.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,21 @@

#include <Kokkos_Core.hpp>
#include <KokkosBlas1_rotg_spec.hpp>
#include <KokkosKernels_helpers.hpp>

namespace KokkosBlas {

/// \brief Compute the coefficients to apply a Givens rotation.
///
/// \tparam Scalar data type of inputs and outputs
/// \tparam execution_space Space on which to execute. Must be able to access SViewType and MViewType.
/// \tparam SViewType 0-D View type containing a nonconst real or complex scalar
/// \tparam MViewType 0-D View type containing a nonconst real/magnitude-typed scalar
///
/// \param space [in] the execution space
/// \param a [in/out] on input one of the values to rotate, on output the
/// rotated value
/// rotated value r
/// \param b [in/out] on input one of the values to rotate, on
/// output the rotated value
/// output the rotation parameter z
/// \param c [out] cosine value associated with the
/// rotation
/// \param s [out] sine value associated with the rotation
Expand Down
9 changes: 5 additions & 4 deletions blas/src/KokkosBlas1_rotm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include <Kokkos_Core.hpp>
#include <KokkosBlas1_rotm_spec.hpp>
#include <KokkosKernels_helpers.hpp>

namespace KokkosBlas {

Expand All @@ -30,10 +31,10 @@ namespace KokkosBlas {
/// \tparam ParamView a rank1 view of static extent [5] type that
/// holds const data
///
/// \param space [in] execution space used for parallel loops in this kernel
/// \param X [in/out] vector to be rotated with param coefficients
/// \param Y [in/out] vector to be rotated with param coefficients
/// \param param [in] output of rotmg contains rotation coefficients
/// \param space [in] execution space used for parallel loops in this kernel
/// \param X [in/out] First vector to be rotated with param coefficients
/// \param Y [in/out] Second vector to be rotated with param coefficients
/// \param param [in] rotation parameters produced by rotmg
///
template <class execution_space, class VectorView, class ParamView>
void rotm(execution_space const& space, VectorView const& X, VectorView const& Y, ParamView const& param) {
Expand Down
15 changes: 9 additions & 6 deletions blas/src/KokkosBlas1_rotmg.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@

#include <Kokkos_Core.hpp>
#include <KokkosBlas1_rotmg_spec.hpp>
#include <KokkosKernels_helpers.hpp>

namespace KokkosBlas {

// clang-format off
/// \brief Compute the coefficients to apply a modified Givens rotation.
///
/// \tparam execution_space the execution space where the kernel will be
Expand All @@ -32,12 +34,13 @@ namespace KokkosBlas {
/// static extent 5 that holds non const data
///
/// \param space [in] execution space used for parallel loops
/// \param d1 [in/out]
/// \param d2 [in/out]
/// \param x1 [in/out]
/// \param y1 [in]
/// \param param [out]
///
/// \param d1 [in/out] On input, square of initial x scaling factor. On output, square of x scaling factor to be applied after rotm.
/// \param d2 [in/out] On input, square of initial y scaling factor. On output, square of y scaling factor
/// to be applied after rotm.
/// \param x1 [in/out] On input, element from first vector to rotate. On output, the rotated element before scaling.
/// \param y1 [in] Element from second vector to rotate. It is not modified by this routine.
/// \param param [out] 5-element parameter array defining the rotation, to be used by rotm.
// clang-format on
template <class execution_space, class DXView, class YView, class PView>
void rotmg(execution_space const& space, DXView const& d1, DXView const& d2, DXView const& x1, YView const& y1,
PView const& param) {
Expand Down
10 changes: 10 additions & 0 deletions example/wiki/blas/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ KOKKOSKERNELS_ADD_EXECUTABLE_AND_TEST(
SOURCES KokkosBlas1_wiki_nrm2.cpp
)

KOKKOSKERNELS_ADD_EXECUTABLE_AND_TEST(
wiki_blas1_rotg_rot
SOURCES KokkosBlas1_wiki_rotg_rot.cpp
)

KOKKOSKERNELS_ADD_EXECUTABLE_AND_TEST(
wiki_blas1_rotmg_rotm
SOURCES KokkosBlas1_wiki_rotmg_rotm.cpp
)

KOKKOSKERNELS_ADD_EXECUTABLE_AND_TEST(
wiki_blas2_ger
SOURCES KokkosBlas2_wiki_ger.cpp
Expand Down
59 changes: 59 additions & 0 deletions example/wiki/blas/KokkosBlas1_wiki_rotg_rot.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#include <iostream>
#include <Kokkos_Core.hpp>
#include <Kokkos_Random.hpp>
#include "KokkosBlas1_rotg.hpp"
#include "KokkosBlas1_rot.hpp"
#include "KokkosKernels_PrintUtils.hpp"

using execution_space = Kokkos::DefaultExecutionSpace;
using Scalar = double;
using Vector = Kokkos::View<Scalar*, execution_space>;
using ScalarView = Kokkos::View<Scalar, execution_space>;

int main(int argc, char* argv[]) {
Kokkos::initialize();
{
const int N = 10;
Vector x("x", N);
Vector y("y", N);

// Populate x,y with uniform random values between 0 and 10
Kokkos::Random_XorShift64_Pool<execution_space> rand_pool(13718);
Kokkos::fill_random(x, rand_pool, Scalar(10));
Kokkos::fill_random(y, rand_pool, Scalar(10));

std::cout << "x,y before applying Givens rotation:\n";
KokkosKernels::Impl::kk_print_1Dview(std::cout, x);
KokkosKernels::Impl::kk_print_1Dview(std::cout, y);

ScalarView c("c");
ScalarView s("s");

// Calculate Givens rotation coefficients to eliminate y(0)
KokkosBlas::rotg<execution_space, ScalarView, ScalarView>(execution_space(), Kokkos::subview(x, 0),
Kokkos::subview(y, 0), c, s);

std::cout << "\nrotg output (rotation parameters) to eliminate y(0):\n";
std::cout << "c = ";
KokkosKernels::Impl::kk_print_1Dview(std::cout, c);
std::cout << "s = ";
KokkosKernels::Impl::kk_print_1Dview(std::cout, s);
std::cout << "r = x(0) = ";
KokkosKernels::Impl::kk_print_1Dview(std::cout, Kokkos::subview(x, 0));
std::cout << "z = ";
KokkosKernels::Impl::kk_print_1Dview(std::cout, Kokkos::subview(y, 0));

// Zero out y(0), which now contains the output parameter z.
// This completes the replacement of [x(0), y(0)] with [r, 0].
Kokkos::deep_copy(Kokkos::subview(y, 0), Scalar(0));

// Apply the rotation to the remaining entries of x and y
KokkosBlas::rot(execution_space(), Kokkos::subview(x, Kokkos::make_pair(1, N)),
Kokkos::subview(y, Kokkos::make_pair(1, N)), c, s);

std::cout << "\nx,y after applying Givens rotation:\n";
KokkosKernels::Impl::kk_print_1Dview(std::cout, x);
KokkosKernels::Impl::kk_print_1Dview(std::cout, y);
}
Kokkos::finalize();
}
72 changes: 72 additions & 0 deletions example/wiki/blas/KokkosBlas1_wiki_rotmg_rotm.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#include <iostream>
#include <Kokkos_Core.hpp>
#include <Kokkos_Random.hpp>
#include "KokkosBlas1_rotmg.hpp"
#include "KokkosBlas1_rotm.hpp"
#include "KokkosKernels_PrintUtils.hpp"

using execution_space = Kokkos::DefaultExecutionSpace;
using Scalar = double;
using Vector = Kokkos::View<Scalar*, execution_space>;
using ParamView = Kokkos::View<Scalar[5], execution_space>;
using ScalarView = Kokkos::View<Scalar, execution_space>;

int main(int argc, char* argv[]) {
Kokkos::initialize();
{
const int N = 10;
Vector x("x", N);
Vector y("y", N);
ScalarView d1("d1");
ScalarView d2("d2");
ParamView param("param");

// Populate x,y with uniform random values between 0 and 10
Kokkos::Random_XorShift64_Pool<execution_space> rand_pool(13718);
Kokkos::fill_random(x, rand_pool, Scalar(10));
Kokkos::fill_random(y, rand_pool, Scalar(10));

// Populate input vector scaling factors with 1
Kokkos::deep_copy(d1, Scalar(1));
Kokkos::deep_copy(d2, Scalar(1));

std::cout << "x,y before applying modified Givens rotation:\n";
KokkosKernels::Impl::kk_print_1Dview(std::cout, x);
KokkosKernels::Impl::kk_print_1Dview(std::cout, y);

// Calculate Givens rotation coefficients to eliminate y(0)
KokkosBlas::rotmg<execution_space, ScalarView, ScalarView, ParamView>(
execution_space(), d1, d2, Kokkos::subview(x, 0), Kokkos::subview(y, 0), param);

auto paramHost = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), param);

std::cout << "\nrotmg output (rotation parameters) to eliminate y(0):\n";
std::cout << "d1 = ";
KokkosKernels::Impl::kk_print_1Dview(std::cout, d1);
std::cout << "d2 = ";
KokkosKernels::Impl::kk_print_1Dview(std::cout, d2);
std::cout << "flag = " << paramHost(0) << '\n';
std::cout << "h components = ";
for (int i = 0; i < 4; i++) std::cout << paramHost(1 + i) << " ";
std::cout << '\n';

// Zero out y(0), which was left unmodified by rotmg.
Kokkos::deep_copy(Kokkos::subview(y, 0), Scalar(0));

// Apply the rotation to the remaining entries of x and y
KokkosBlas::rotm(execution_space(), Kokkos::subview(x, Kokkos::make_pair(1, N)),
Kokkos::subview(y, Kokkos::make_pair(1, N)), param);

// Apply scaling factors: sqrt(d1) and sqrt(d2) to x and y respectively
Kokkos::parallel_for(
Kokkos::RangePolicy<execution_space>(0, N), KOKKOS_LAMBDA(int i) {
x(i) *= Kokkos::sqrt(d1());
y(i) *= Kokkos::sqrt(d2());
});

std::cout << "\nx,y after applying modified Givens rotation and scaling by [sqrt(d1), sqrt(d2)]):\n";
KokkosKernels::Impl::kk_print_1Dview(std::cout, x);
KokkosKernels::Impl::kk_print_1Dview(std::cout, y);
}
Kokkos::finalize();
}
Loading