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);
233 template<
class OutputViewType,
235 const bool canUseKokkosDeepCopy =
236 CanUseKokkosDeepCopy<OutputViewType, InputViewType>::value,
237 const bool outputExecSpaceCanAccessInputMemSpace =
238 Kokkos::SpaceAccessibility<
239 typename OutputViewType::memory_space,
240 typename InputViewType::memory_space>::accessible>
241 struct CopyConvertImpl {
243 run (
const OutputViewType& dst,
244 const InputViewType& src);
248 template<
class OutputViewType,
250 const bool outputExecSpaceCanAccessInputMemSpace>
251 struct CopyConvertImpl<OutputViewType, InputViewType,
252 true, outputExecSpaceCanAccessInputMemSpace>
255 run (
const OutputViewType& dst,
256 const InputViewType& src)
263 const ptrdiff_t dst_beg =
reinterpret_cast<ptrdiff_t
> (dst.data ());
264 const ptrdiff_t dst_end =
265 reinterpret_cast<ptrdiff_t
> (dst.data () + dst.span ());
266 const ptrdiff_t src_beg =
reinterpret_cast<ptrdiff_t
> (src.data ());
267 const ptrdiff_t src_end =
268 reinterpret_cast<ptrdiff_t
> (src.data () + src.span ());
270 if (dst_end > src_beg && src_end > dst_beg) {
278 auto src_copy = Kokkos::create_mirror (Kokkos::HostSpace (), src);
286 using execution_space =
typename OutputViewType::execution_space;
294 template<
class OutputViewType,
296 struct CopyConvertImpl<OutputViewType,
302 run (
const OutputViewType& dst,
303 const InputViewType& src)
305 using functor_type = CopyConvertFunctor<OutputViewType, InputViewType>;
306 using execution_space =
typename OutputViewType::execution_space;
307 using index_type =
typename OutputViewType::size_type;
308 using range_type = Kokkos::RangePolicy<execution_space, index_type>;
309 Kokkos::parallel_for (
"Tpetra::Details::copyConvert",
310 range_type (0, dst.extent (0)),
311 functor_type (dst, src));
321 template<
class OutputViewType,
323 struct CopyConvertImpl<OutputViewType, InputViewType, false, false>
326 run (
const OutputViewType& dst,
327 const InputViewType& src)
329 using output_memory_space =
typename OutputViewType::memory_space;
330 using output_execution_space =
typename OutputViewType::execution_space;
331 auto src_outputSpaceCopy =
332 Kokkos::create_mirror_view (output_memory_space (), src);
338 using output_space_copy_type = decltype (src_outputSpaceCopy);
340 CopyConvertFunctor<OutputViewType, output_space_copy_type>;
341 using execution_space =
typename OutputViewType::execution_space;
342 using index_type =
typename OutputViewType::size_type;
343 using range_type = Kokkos::RangePolicy<execution_space, index_type>;
344 Kokkos::parallel_for (
"Tpetra::Details::copyConvert",
345 range_type (0, dst.extent (0)),
346 functor_type (dst, src_outputSpaceCopy));
359 template<
class OutputViewType,
363 const InputViewType& src)
365 static_assert (Kokkos::is_view<OutputViewType>::value,
366 "OutputViewType must be a Kokkos::View.");
367 static_assert (Kokkos::is_view<InputViewType>::value,
368 "InputViewType must be a Kokkos::View.");
369 static_assert (std::is_same<
typename OutputViewType::value_type,
370 typename OutputViewType::non_const_value_type>::value,
371 "OutputViewType must be a nonconst Kokkos::View.");
372 static_assert (static_cast<int> (OutputViewType::rank) ==
373 static_cast<int> (InputViewType::rank),
374 "src and dst must have the same rank.");
376 if (dst.extent (0) != src.extent (0)) {
377 std::ostringstream os;
378 os <<
"Tpetra::Details::copyConvert: "
379 <<
"dst.extent(0) = " << dst.extent (0)
380 <<
" != src.extent(0) = " << src.extent (0)
382 throw std::invalid_argument (os.str ());
384 if (static_cast<int> (OutputViewType::rank) > 1 &&
385 dst.extent (1) != src.extent (1)) {
386 std::ostringstream os;
387 os <<
"Tpetra::Details::copyConvert: "
388 <<
"dst.extent(1) = " << dst.extent (1)
389 <<
" != src.extent(1) = " << src.extent (1)
391 throw std::invalid_argument (os.str ());
395 using output_view_type =
396 Kokkos::View<
typename OutputViewType::non_const_data_type,
397 typename OutputViewType::array_layout,
398 typename OutputViewType::device_type>;
399 using input_view_type =
400 Kokkos::View<
typename InputViewType::const_data_type,
401 typename InputViewType::array_layout,
402 typename InputViewType::device_type>;
403 CopyConvertImpl<output_view_type, input_view_type>::run (dst, src);
409 #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...