KokkosBatched::Rotg

Defined in header: KokkosBatched_Rotg.hpp

struct Rotg {
  template <class SViewType, class MViewType>
  KOKKOS_INLINE_FUNCTION static int invoke(const SViewType &a, const SViewType &b, const MViewType &c,
                                           const SViewType &s);
};

Constructs a plane rotation such that:

\[\begin{split}\begin{aligned} \begin{bmatrix} c & s\\ -s & c\end{bmatrix}\begin{bmatrix}a\\ b\end{bmatrix} &= \begin{bmatrix}r\\ 0\end{bmatrix} & \text{(for real arithmetic)} \\ \begin{bmatrix} c & s\\ -\mathrm{conj}(s) & c\end{bmatrix}\begin{bmatrix}a\\ b\end{bmatrix} &= \begin{bmatrix}r\\ 0\end{bmatrix} & \text{(for complex arithmetic)} \end{aligned}\end{split}\]
  1. For real arithmetic, the rotation is defined such that \(c^2+s^2=1\) and \(r=\pm\sqrt{a^2 + b^2}\). This operation is equivalent to the BLAS routine SROTG or DROTG for single or double precision.

  2. For complex arithmetic, the rotation is defined such that \(c^2+|s|^2=1\) and \(r=a/|a| \times \sqrt{a^2 + |b|^2}\). This operation is equivalent to the BLAS routine CROTG or ZROTG for single or double precision.

The rotation can be applied to vectors \(x\) and \(y\) by calling the Rot routine described in KokkosBatched::Rot.

Parameters

a, b:

0-D views. On input, the components of the 2D vector to rotate. On output, a contains the first component of the rotated vector. For real arithmetic, b contains the z parameter that provides an alternate way to define the rotation. For complex arithmetic, b is unchanged on output.

c, s:

0-D views. cosine and sine of the rotation that rotates [a, b] onto \(e_1\)

Type Requirements

  • SViewType must be a Kokkos View of rank 0 that satisfies:
    • std::is_same_v<typename SViewType::value_type, typename SViewType::non_const_value_type>

  • MViewType must be a Kokkos View of rank 0 that satisfies:
    • std::is_same_v<typename MViewType::value_type, typename MViewType::non_const_value_type>

    • !KokkosKernels::ArithTraits<typename MViewType::value_type>::is_complex

Example

 1#include <Kokkos_Core.hpp>
 2#include <KokkosBatched_Rot.hpp>
 3#include <KokkosBatched_Rotg.hpp>
 4
 5using ExecutionSpace = Kokkos::DefaultExecutionSpace;
 6
 7/// \brief Example of batched rot and rotg
 8/// Compute c ans s such that
 9/// [[c,  s],  * [[a],  = [[r],
10///  [-s, c]]     [b]]     [0]]
11/// Then apply the rotation to vectors X and Y:
12/// [[X'],  = [[c,  s],  * [[X],
13///  [Y']]     [-s, c]]     [Y]]
14///
15/// Usage example:
16/// a = 3, b = 4
17/// X = [3, 3, 3], Y = [4, 4, 4]
18/// X' = [5, 5, 5], Y' = [0, 0, 0]
19///
20int main(int /*argc*/, char** /*argv*/) {
21  Kokkos::initialize();
22  {
23    using View1DType = Kokkos::View<double*, ExecutionSpace>;
24    using View2DType = Kokkos::View<double**, ExecutionSpace>;
25    const int Nb = 10, n = 3;
26
27    // Values A and B we want to rotate
28    View1DType A("A", Nb), B("B", Nb), C("C", Nb), S("S", Nb);
29
30    // Vector X and Y of the rot/rotg operation
31    View2DType X("X", Nb, n), Y("Y", Nb, n);
32
33    // Initialize A, B, X and Y
34    const double a = 3.0, b = 4.0;
35    Kokkos::deep_copy(A, a);
36    Kokkos::deep_copy(B, b);
37    Kokkos::deep_copy(X, a);
38    Kokkos::deep_copy(Y, b);
39
40    // Compute givens rotation coefficients and apply the rotation to X and Y
41    ExecutionSpace exec;
42    using policy_type = Kokkos::RangePolicy<ExecutionSpace, Kokkos::IndexType<int>>;
43    policy_type policy{exec, 0, Nb};
44    Kokkos::parallel_for(
45        "rot/rotg", policy, KOKKOS_LAMBDA(int ib) {
46          auto sub_A = Kokkos::subview(A, ib);
47          auto sub_B = Kokkos::subview(B, ib);
48          auto sub_C = Kokkos::subview(C, ib);
49          auto sub_S = Kokkos::subview(S, ib);
50          KokkosBatched::Rotg::invoke(sub_A, sub_B, sub_C, sub_S);
51
52          auto sub_X = Kokkos::subview(X, ib, Kokkos::ALL());
53          auto sub_Y = Kokkos::subview(Y, ib, Kokkos::ALL());
54          KokkosBatched::SerialRot<>::invoke(sub_X, sub_Y, sub_C(), sub_S());
55        });
56
57    // Confirm that the results are correct
58    auto h_X     = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{}, X);
59    auto h_Y     = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{}, Y);
60    bool correct = true;
61    double eps   = 1.0e-12;
62    for (int ib = 0; ib < Nb; ib++) {
63      for (int j = 0; j < n; j++) {
64        if (Kokkos::abs(h_X(ib, j) - 5) > eps) correct = false;
65        if (Kokkos::abs(h_Y(ib, j)) > eps) correct = false;
66      }
67    }
68
69    if (correct) {
70      std::cout << "rot/rotg works correctly!" << std::endl;
71    }
72  }
73  Kokkos::finalize();
74}

output:

rot/rotg works correctly!