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:
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
SROTGorDROTGfor single or double precision.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
CROTGorZROTGfor 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,
acontains the first component of the rotated vector. For real arithmetic,bcontains thezparameter that provides an alternate way to define the rotation. For complex arithmetic,bis 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!