42 #ifndef TPETRA_DETAILS_NORMIMPL_DEF_HPP
43 #define TPETRA_DETAILS_NORMIMPL_DEF_HPP
48 #include "Tpetra_Details_normImpl_decl.hpp"
52 #include "Teuchos_ArrayView.hpp"
53 #include "Teuchos_CommHelpers.hpp"
54 #include "KokkosBlas.hpp"
55 #include "Kokkos_ArithTraits.hpp"
61 template<
class RV,
class XMV>
63 lclNormImpl (
const RV& normsOut,
66 const Teuchos::ArrayView<const size_t>& whichVecs,
67 const bool constantStride,
71 using Kokkos::subview;
72 using mag_type =
typename RV::non_const_value_type;
74 static_assert (static_cast<int> (RV::Rank) == 1,
75 "Tpetra::MultiVector::lclNormImpl: "
76 "The first argument normsOut must have rank 1.");
77 static_assert (Kokkos::Impl::is_view<XMV>::value,
78 "Tpetra::MultiVector::lclNormImpl: "
79 "The second argument X is not a Kokkos::View.");
80 static_assert (static_cast<int> (XMV::Rank) == 2,
81 "Tpetra::MultiVector::lclNormImpl: "
82 "The second argument X must have rank 2.");
84 const size_t lclNumRows =
static_cast<size_t> (X.extent (0));
85 TEUCHOS_TEST_FOR_EXCEPTION
86 (lclNumRows != 0 && constantStride &&
87 static_cast<size_t> (X.extent (1)) != numVecs,
88 std::logic_error,
"Constant Stride X's dimensions are " << X.extent (0)
89 <<
" x " << X.extent (1) <<
", which differ from the local dimensions "
90 << lclNumRows <<
" x " << numVecs <<
". Please report this bug to "
91 "the Tpetra developers.");
92 TEUCHOS_TEST_FOR_EXCEPTION
93 (lclNumRows != 0 && ! constantStride &&
94 static_cast<size_t> (X.extent (1)) < numVecs,
95 std::logic_error,
"Strided X's dimensions are " << X.extent (0) <<
" x "
96 << X.extent (1) <<
", which are incompatible with the local dimensions "
97 << lclNumRows <<
" x " << numVecs <<
". Please report this bug to "
98 "the Tpetra developers.");
100 if (lclNumRows == 0) {
101 const mag_type zeroMag = Kokkos::ArithTraits<mag_type>::zero ();
105 if (constantStride) {
106 if (whichNorm == NORM_INF) {
107 KokkosBlas::nrminf (normsOut, X);
109 else if (whichNorm == NORM_ONE) {
110 KokkosBlas::nrm1 (normsOut, X);
112 else if (whichNorm == NORM_TWO) {
113 KokkosBlas::nrm2_squared (normsOut, X);
116 TEUCHOS_TEST_FOR_EXCEPTION
117 (
true, std::logic_error,
"Should never get here!");
126 for (
size_t k = 0; k < numVecs; ++k) {
127 const size_t X_col = constantStride ? k : whichVecs[k];
128 if (whichNorm == NORM_INF) {
129 KokkosBlas::nrminf (subview (normsOut, k),
130 subview (X, ALL (), X_col));
132 else if (whichNorm == NORM_ONE) {
133 KokkosBlas::nrm1 (subview (normsOut, k),
134 subview (X, ALL (), X_col));
136 else if (whichNorm == NORM_TWO) {
137 KokkosBlas::nrm2_squared (subview (normsOut, k),
138 subview (X, ALL (), X_col));
141 TEUCHOS_TEST_FOR_EXCEPTION
142 (
true, std::logic_error,
"Should never get here!");
151 template<
class ViewType>
152 class SquareRootFunctor {
154 typedef typename ViewType::execution_space execution_space;
155 typedef typename ViewType::size_type size_type;
157 SquareRootFunctor (
const ViewType& theView) :
161 KOKKOS_INLINE_FUNCTION
void
162 operator() (
const size_type& i)
const
164 typedef typename ViewType::non_const_value_type value_type;
165 typedef Kokkos::Details::ArithTraits<value_type> KAT;
166 theView_(i) = KAT::sqrt (theView_(i));
175 gblNormImpl (
const RV& normsOut,
176 const Teuchos::Comm<int>*
const comm,
177 const bool distributed,
180 using Teuchos::REDUCE_MAX;
181 using Teuchos::REDUCE_SUM;
182 using Teuchos::reduceAll;
183 typedef typename RV::non_const_value_type mag_type;
185 const size_t numVecs = normsOut.extent (0);
200 if (distributed && comm !=
nullptr) {
206 RV lclNorms (
"MV::normImpl lcl", numVecs);
208 const mag_type*
const lclSum = lclNorms.data ();
209 mag_type*
const gblSum = normsOut.data ();
210 const int nv =
static_cast<int> (numVecs);
211 if (whichNorm == NORM_INF) {
212 reduceAll<int, mag_type> (*comm, REDUCE_MAX, nv, lclSum, gblSum);
214 reduceAll<int, mag_type> (*comm, REDUCE_SUM, nv, lclSum, gblSum);
218 if (whichNorm == NORM_TWO) {
224 const bool inHostMemory =
225 Kokkos::Impl::is_same<
typename RV::memory_space,
226 typename RV::host_mirror_space::memory_space>::value;
228 for (
size_t j = 0; j < numVecs; ++j) {
229 normsOut(j) = Kokkos::Details::ArithTraits<mag_type>::sqrt (normsOut(j));
237 SquareRootFunctor<RV> f (normsOut);
238 typedef typename RV::execution_space execution_space;
239 typedef Kokkos::RangePolicy<execution_space, size_t> range_type;
240 Kokkos::parallel_for (range_type (0, numVecs), f);
247 template <
class ValueType,
253 const Kokkos::View<const ValueType**, ArrayLayout, DeviceType>& X,
255 const Teuchos::ArrayView<const size_t>& whichVecs,
256 const bool isConstantStride,
257 const bool isDistributed,
258 const Teuchos::Comm<int>* comm)
260 using RV = Kokkos::View<MagnitudeType*, Kokkos::HostSpace>;
264 const size_t numVecs = isConstantStride ?
265 static_cast<size_t> (X.extent (1)) :
266 static_cast<size_t> (whichVecs.size ());
270 RV normsOut (norms, numVecs);
272 Impl::lclNormImpl (normsOut, X, numVecs, whichVecs,
273 isConstantStride, whichNorm);
274 Impl::gblNormImpl (normsOut, comm, isDistributed, whichNorm);
280 #define TPETRA_DETAILS_NORMIMPL_INSTANT( SC, NT ) \
281 namespace Details { \
284 Kokkos::ArithTraits<SC>::val_type, \
285 Kokkos::LayoutLeft, \
287 Kokkos::ArithTraits<SC>::mag_type \
288 > (Kokkos::ArithTraits<SC>::mag_type[], \
289 const Kokkos::View< \
290 const Kokkos::ArithTraits<SC>::val_type**, \
291 Kokkos::LayoutLeft, \
294 const Teuchos::ArrayView<const size_t>&, \
297 const Teuchos::Comm<int>* ); \
300 #endif // TPETRA_DETAILS_NORMIMPL_DEF_HPP
void deep_copy(MultiVector< DS, DL, DG, DN > &dst, const MultiVector< SS, SL, SG, SN > &src)
Copy the contents of the MultiVector src into dst.
void normImpl(MagnitudeType norms[], const Kokkos::View< const ValueType **, ArrayLayout, DeviceType > &X, const EWhichNorm whichNorm, const Teuchos::ArrayView< const size_t > &whichVecs, const bool isConstantStride, const bool isDistributed, const Teuchos::Comm< int > *comm)
Implementation of MultiVector norms.
EWhichNorm
Input argument for normImpl() (which see).