44 #ifndef TPETRA_DETAILS_COPYCONVERT_HPP
45 #define TPETRA_DETAILS_COPYCONVERT_HPP
52 #include "TpetraCore_config.h"
53 #include "Kokkos_Core.hpp"
54 #include "Kokkos_ArithTraits.hpp"
57 #include <type_traits>
71 template<
class OutputValueType,
73 const bool outputIsComplex =
74 Kokkos::ArithTraits<OutputValueType>::is_complex,
75 const bool inputIsComplex =
76 Kokkos::ArithTraits<InputValueType>::is_complex>
79 static KOKKOS_INLINE_FUNCTION
void
80 convert (OutputValueType& dst,
const InputValueType& src)
86 dst = OutputValueType (src);
90 template<
class OutputRealType,
class InputComplexType>
91 struct ConvertValue<OutputRealType, InputComplexType, false, true>
93 static KOKKOS_INLINE_FUNCTION
void
94 convert (OutputRealType& dst,
95 const InputComplexType& src)
99 using KAI = Kokkos::ArithTraits<InputComplexType>;
100 dst = OutputRealType (KAI::real (src));
104 template<
class OutputComplexType,
class InputRealType>
105 struct ConvertValue<OutputComplexType, InputRealType, true, false>
107 static KOKKOS_INLINE_FUNCTION
void
108 convert (OutputComplexType& dst,
109 const InputRealType& src)
113 using output_mag_type =
114 typename Kokkos::ArithTraits<OutputComplexType>::mag_type;
115 using KAM = Kokkos::ArithTraits<output_mag_type>;
116 dst = OutputComplexType (src, KAM::zero ());
120 template<
class OutputValueType,
121 class InputValueType>
122 KOKKOS_INLINE_FUNCTION
void
123 convertValue (OutputValueType& dst,
const InputValueType& src) {
124 ConvertValue<OutputValueType, InputValueType>::convert (dst, src);
131 template<
class OutputViewType,
133 const int rank =
static_cast<int> (OutputViewType::Rank)>
134 class CopyConvertFunctor {};
136 template<
class OutputViewType,
138 class CopyConvertFunctor<OutputViewType, InputViewType, 1> {
141 (static_cast<int> (OutputViewType::Rank) == 1 &&
142 static_cast<int> (InputViewType::Rank) == 1,
143 "CopyConvertFunctor (implements Tpetra::Details::copyConvert): "
144 "OutputViewType and InputViewType must both have rank 1.");
149 using index_type =
typename OutputViewType::size_type;
151 CopyConvertFunctor (
const OutputViewType& dst,
152 const InputViewType& src) :
157 KOKKOS_INLINE_FUNCTION
void
158 operator () (
const index_type i)
const {
159 convertValue (dst_(i), src_(i));
163 template<
class OutputViewType,
165 class CopyConvertFunctor<OutputViewType, InputViewType, 2> {
167 using index_type =
typename OutputViewType::size_type;
171 (static_cast<int> (OutputViewType::Rank) == 2 &&
172 static_cast<int> (InputViewType::Rank) == 2,
173 "CopyConvertFunctor (implements Tpetra::Details::copyConvert): "
174 "OutputViewType and InputViewType must both have rank 2.");
180 CopyConvertFunctor (
const OutputViewType& dst,
181 const InputViewType& src) :
184 numCols_ (dst.extent (1))
187 KOKKOS_INLINE_FUNCTION
void
188 operator () (
const index_type i)
const {
189 const index_type numCols = numCols_;
190 for (index_type j = 0; j < numCols; ++j) {
191 convertValue (dst_(i,j), src_(i,j));
197 template<
class OutputViewType,
class InputViewType>
198 class CanUseKokkosDeepCopy {
200 static constexpr
bool sameValueType =
201 std::is_same<
typename OutputViewType::non_const_value_type,
202 typename InputViewType::non_const_value_type>::value;
203 static constexpr
bool sameMemorySpace =
204 std::is_same<
typename OutputViewType::memory_space,
205 typename InputViewType::memory_space>::value;
206 static constexpr
bool sameLayout =
207 std::is_same<
typename OutputViewType::array_layout,
208 typename InputViewType::array_layout>::value;
211 static constexpr
bool value =
212 sameValueType && (sameMemorySpace || sameLayout);
236 template<
class OutputViewType,
238 const bool canUseKokkosDeepCopy =
239 CanUseKokkosDeepCopy<OutputViewType, InputViewType>::value,
240 const bool outputExecSpaceCanAccessInputMemSpace =
241 Kokkos::Impl::VerifyExecutionCanAccessMemorySpace<
242 typename OutputViewType::memory_space,
243 typename InputViewType::memory_space>::value>
244 struct CopyConvertImpl {
246 run (
const OutputViewType& dst,
247 const InputViewType& src);
251 template<
class OutputViewType,
253 const bool outputExecSpaceCanAccessInputMemSpace>
254 struct CopyConvertImpl<OutputViewType, InputViewType,
255 true, outputExecSpaceCanAccessInputMemSpace>
258 run (
const OutputViewType& dst,
259 const InputViewType& src)
266 const ptrdiff_t dst_beg =
reinterpret_cast<ptrdiff_t
> (dst.data ());
267 const ptrdiff_t dst_end =
268 reinterpret_cast<ptrdiff_t
> (dst.data () + dst.span ());
269 const ptrdiff_t src_beg =
reinterpret_cast<ptrdiff_t
> (src.data ());
270 const ptrdiff_t src_end =
271 reinterpret_cast<ptrdiff_t
> (src.data () + src.span ());
273 if (dst_end > src_beg && src_end > dst_beg) {
281 auto src_copy = Kokkos::create_mirror (Kokkos::HostSpace (), src);
293 template<
class OutputViewType,
295 struct CopyConvertImpl<OutputViewType,
301 run (
const OutputViewType& dst,
302 const InputViewType& src)
304 using functor_type = CopyConvertFunctor<OutputViewType, InputViewType>;
305 using execution_space =
typename OutputViewType::execution_space;
306 using index_type =
typename OutputViewType::size_type;
307 using range_type = Kokkos::RangePolicy<execution_space, index_type>;
308 Kokkos::parallel_for (
"Tpetra::Details::copyConvert",
309 range_type (0, dst.extent (0)),
310 functor_type (dst, src));
320 template<
class OutputViewType,
322 struct CopyConvertImpl<OutputViewType, InputViewType, false, false>
325 run (
const OutputViewType& dst,
326 const InputViewType& src)
328 using output_memory_space =
typename OutputViewType::memory_space;
329 auto src_outputSpaceCopy =
330 Kokkos::create_mirror_view (output_memory_space (), src);
335 using output_space_copy_type = decltype (src_outputSpaceCopy);
337 CopyConvertFunctor<OutputViewType, output_space_copy_type>;
338 using execution_space =
typename OutputViewType::execution_space;
339 using index_type =
typename OutputViewType::size_type;
340 using range_type = Kokkos::RangePolicy<execution_space, index_type>;
341 Kokkos::parallel_for (
"Tpetra::Details::copyConvert",
342 range_type (0, dst.extent (0)),
343 functor_type (dst, src_outputSpaceCopy));
356 template<
class OutputViewType,
360 const InputViewType& src)
362 static_assert (Kokkos::Impl::is_view<OutputViewType>::value,
363 "OutputViewType must be a Kokkos::View.");
364 static_assert (Kokkos::Impl::is_view<InputViewType>::value,
365 "InputViewType must be a Kokkos::View.");
366 static_assert (std::is_same<
typename OutputViewType::value_type,
367 typename OutputViewType::non_const_value_type>::value,
368 "OutputViewType must be a nonconst Kokkos::View.");
369 static_assert (static_cast<int> (OutputViewType::Rank) ==
370 static_cast<int> (InputViewType::Rank),
371 "src and dst must have the same rank.");
373 if (dst.extent (0) != src.extent (0)) {
374 std::ostringstream os;
375 os <<
"Tpetra::Details::copyConvert: "
376 <<
"dst.extent(0) = " << dst.extent (0)
377 <<
" != src.extent(0) = " << src.extent (0)
379 throw std::invalid_argument (os.str ());
381 if (static_cast<int> (OutputViewType::Rank) > 1 &&
382 dst.extent (1) != src.extent (1)) {
383 std::ostringstream os;
384 os <<
"Tpetra::Details::copyConvert: "
385 <<
"dst.extent(1) = " << dst.extent (1)
386 <<
" != src.extent(1) = " << src.extent (1)
388 throw std::invalid_argument (os.str ());
392 using output_view_type =
393 Kokkos::View<
typename OutputViewType::non_const_data_type,
394 typename OutputViewType::array_layout,
395 typename OutputViewType::device_type>;
396 using input_view_type =
397 Kokkos::View<
typename InputViewType::const_data_type,
398 typename InputViewType::array_layout,
399 typename InputViewType::device_type>;
400 CopyConvertImpl<output_view_type, input_view_type>::run (dst, src);
406 #endif // TPETRA_DETAILS_COPYCONVERT_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 copyConvert(const OutputViewType &dst, const InputViewType &src)
Copy values from the 1-D Kokkos::View src, to the 1-D Kokkos::View dst, of the same length...