KokkosBatched::Nrm

Defined in header: KokkosBatched_Nrm.hpp

template <typename NrmType>
struct SerialNrm {
  template <typename XViewType, typename NormViewType>
  KOKKOS_INLINE_FUNCTION static int invoke(const XViewType &X, const NormViewType &norm);
};

template <typename MemberType, typename NrmType>
struct TeamNrm {
  template <typename XViewType, typename NormViewType>
  KOKKOS_INLINE_FUNCTION static int invoke(const MemberType &member, const XViewType &X, const NormViewType &norm);
};

template <typename MemberType, typename NrmType>
struct TeamVectorNrm {
  template <typename XViewType, typename NormViewType>
  KOKKOS_INLINE_FUNCTION static int invoke(const MemberType &member, const XViewType &X, const NormViewType &norm);
};

Computes the \(L1\), \(L2\) or \(L_\infty\) norm of a vector \(X\).

\[\begin{split}\begin{align} norm &= ||x|| \: \text{(if NrmType == KokkosBatched::Norm::L1)} \\ norm &= ||x||_2 \: \text{(if NrmType == KokkosBatched::Norm::L2 or NrmType == KokkosBatched::Norm::ScaledL2)} \\ norm &= ||x||_\infty \: \text{(if NrmType == KokkosBatched::Norm::LInf)} \end{align}\end{split}\]
  1. If NrmType == KokkosBatched::Norm::L1, this operation is equivalent to the BLAS routine SASUM (SCASUM) or DASUM (DZASUM) for single or double precision for real (complex) vectors.

  2. If NrmType == KokkosBatched::Norm::L2 or NrmType == KokkosBatched::Norm::ScaledL2, this operation is equivalent to the BLAS routine SNRM2 (SCNRM2) or DNRM2 (DZNRM2) for single or double precision for real (complex) vectors.

  3. If NrmType == KokkosBatched::Norm::LInf, this operation is related to the BLAS routine ISAMAX (ICAMAX) or IDAMAX (IZAMAX) for single or double precision for real (complex) vectors, where the index of the maximum absolute value is returned in the output \(norm\). This routine returns the maximum absolute value instead.

Note

Though NrmType == KokkosBatched::Norm::L2 is more efficient, it may overflow for large vectors. For large vectors, NrmType == KokkosBatched::Norm::ScaledL2 is recommended as it uses a numerically stable algorithm to compute the \(L2\) norm that avoids overflow and underflow by scaling the input vector \(X\) by the maximum absolute value of its elements that has been encountered.

Parameters

X:

On input, \(X\) is a length \(n\) vector

norm:

On output, \(norm\) is the computed norm of the vector \(X\).

Type Requirements

  • MemberType must be a Kokkos team member handle (only for TeamNrm and TeamVectorNrm)

  • NrmType must be one of the following:
    • KokkosBatched::Norm::L1 for \(L1\) norm

    • KokkosBatched::Norm::L2 or KokkosBatched::Norm::ScaledL2 for \(L2\) norm

    • KokkosBatched::Norm::LInf for \(L_\infty\) norm

  • XViewType must be a Kokkos View of rank 1 containing a vector or matrix \(X\)

  • NormViewType must be a Kokkos View of rank 0 containing the output \(norm\). The norm is accumulated in the type of the elements of NormViewType

Example

 1#include <iostream>
 2#include <Kokkos_Core.hpp>
 3#include <KokkosBatched_Nrm.hpp>
 4
 5using ExecutionSpace = Kokkos::DefaultExecutionSpace;
 6
 7/// \brief Example of batched nrm
 8/// computing nrm = ||x||_2 for a batch of vectors x.
 9///
10/// Usage example:
11///        x: [1, 3, 5]
12///        nrm: sqrt(1^2 + 3^2 + 5^2) = sqrt(35)
13///
14int main(int /*argc*/, char** /*argv*/) {
15  Kokkos::initialize();
16  {
17    using View1DType = Kokkos::View<double*, ExecutionSpace>;
18    using View2DType = Kokkos::View<double**, ExecutionSpace>;
19    const int Nb = 10, n = 3;
20
21    // Vector x
22    View2DType x("x", Nb, n);
23    View1DType norm("norm", Nb);
24
25    // Initialize x
26    auto h_x = Kokkos::create_mirror_view(x);
27    for (int ib = 0; ib < Nb; ib++) {
28      h_x(ib, 0) = 1;
29      h_x(ib, 1) = 3;
30      h_x(ib, 2) = 5;
31    }
32    Kokkos::deep_copy(x, h_x);
33
34    // Compute L2 norm of x
35    ExecutionSpace exec;
36    using policy_type = Kokkos::RangePolicy<ExecutionSpace, Kokkos::IndexType<int>>;
37    policy_type policy{exec, 0, Nb};
38    Kokkos::parallel_for(
39        "nrm", policy, KOKKOS_LAMBDA(int ib) {
40          auto sub_x    = Kokkos::subview(x, ib, Kokkos::ALL());
41          auto sub_norm = Kokkos::subview(norm, ib);
42          KokkosBatched::SerialNrm<KokkosBatched::Norm::L2>::invoke(sub_x, sub_norm);
43        });
44
45    // Confirm that the results are correct
46    auto h_norm  = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{}, norm);
47    bool correct = true;
48    double eps   = 1.0e-12;
49    for (int ib = 0; ib < Nb; ib++) {
50      if (Kokkos::abs(h_norm(ib) - Kokkos::sqrt(35)) > eps) correct = false;
51    }
52
53    if (correct) {
54      std::cout << "nrm works correctly!" << std::endl;
55    }
56  }
57  Kokkos::finalize();
58}

output:

nrm works correctly!