10 #ifndef TPETRA_DETAILS_COPYCONVERT_HPP
11 #define TPETRA_DETAILS_COPYCONVERT_HPP
18 #include "TpetraCore_config.h"
19 #include "Kokkos_Core.hpp"
20 #include "Kokkos_ArithTraits.hpp"
23 #include <type_traits>
37 template<
class OutputValueType,
39 const bool outputIsComplex =
40 Kokkos::ArithTraits<OutputValueType>::is_complex,
41 const bool inputIsComplex =
42 Kokkos::ArithTraits<InputValueType>::is_complex>
45 static KOKKOS_INLINE_FUNCTION
void
46 convert (OutputValueType& dst,
const InputValueType& src)
52 dst = OutputValueType (src);
56 template<
class OutputRealType,
class InputComplexType>
57 struct ConvertValue<OutputRealType, InputComplexType, false, true>
59 static KOKKOS_INLINE_FUNCTION
void
60 convert (OutputRealType& dst,
61 const InputComplexType& src)
65 using KAI = Kokkos::ArithTraits<InputComplexType>;
66 dst = OutputRealType (KAI::real (src));
70 template<
class OutputComplexType,
class InputRealType>
71 struct ConvertValue<OutputComplexType, InputRealType, true, false>
73 static KOKKOS_INLINE_FUNCTION
void
74 convert (OutputComplexType& dst,
75 const InputRealType& src)
79 using output_mag_type =
80 typename Kokkos::ArithTraits<OutputComplexType>::mag_type;
81 using KAM = Kokkos::ArithTraits<output_mag_type>;
82 dst = OutputComplexType (src, KAM::zero ());
86 template<
class OutputValueType,
88 KOKKOS_INLINE_FUNCTION
void
89 convertValue (OutputValueType& dst,
const InputValueType& src) {
90 ConvertValue<OutputValueType, InputValueType>::convert (dst, src);
97 template<
class OutputViewType,
99 const int rank =
static_cast<int> (OutputViewType::rank)>
100 class CopyConvertFunctor {};
102 template<
class OutputViewType,
104 class CopyConvertFunctor<OutputViewType, InputViewType, 1> {
107 (static_cast<int> (OutputViewType::rank) == 1 &&
108 static_cast<int> (InputViewType::rank) == 1,
109 "CopyConvertFunctor (implements Tpetra::Details::copyConvert): "
110 "OutputViewType and InputViewType must both have rank 1.");
115 using index_type =
typename OutputViewType::size_type;
117 CopyConvertFunctor (
const OutputViewType& dst,
118 const InputViewType& src) :
123 KOKKOS_INLINE_FUNCTION
void
124 operator () (
const index_type i)
const {
125 convertValue (dst_(i), src_(i));
129 template<
class OutputViewType,
131 class CopyConvertFunctor<OutputViewType, InputViewType, 2> {
133 using index_type =
typename OutputViewType::size_type;
137 (static_cast<int> (OutputViewType::rank) == 2 &&
138 static_cast<int> (InputViewType::rank) == 2,
139 "CopyConvertFunctor (implements Tpetra::Details::copyConvert): "
140 "OutputViewType and InputViewType must both have rank 2.");
146 CopyConvertFunctor (
const OutputViewType& dst,
147 const InputViewType& src) :
150 numCols_ (dst.extent (1))
153 KOKKOS_INLINE_FUNCTION
void
154 operator () (
const index_type i)
const {
155 const index_type numCols = numCols_;
156 for (index_type j = 0; j < numCols; ++j) {
157 convertValue (dst_(i,j), src_(i,j));
163 template<
class OutputViewType,
class InputViewType>
164 class CanUseKokkosDeepCopy {
166 static constexpr
bool sameValueType =
167 std::is_same<
typename OutputViewType::non_const_value_type,
168 typename InputViewType::non_const_value_type>::value;
169 static constexpr
bool sameMemorySpace =
170 std::is_same<
typename OutputViewType::memory_space,
171 typename InputViewType::memory_space>::value;
172 static constexpr
bool sameLayout =
173 std::is_same<
typename OutputViewType::array_layout,
174 typename InputViewType::array_layout>::value;
177 static constexpr
bool value =
178 sameValueType && (sameMemorySpace || sameLayout);
199 template<
class OutputViewType,
201 const bool canUseKokkosDeepCopy =
202 CanUseKokkosDeepCopy<OutputViewType, InputViewType>::value,
203 const bool outputExecSpaceCanAccessInputMemSpace =
204 Kokkos::SpaceAccessibility<
205 typename OutputViewType::memory_space,
206 typename InputViewType::memory_space>::accessible>
207 struct CopyConvertImpl {
209 run (
const OutputViewType& dst,
210 const InputViewType& src);
214 template<
class OutputViewType,
216 const bool outputExecSpaceCanAccessInputMemSpace>
217 struct CopyConvertImpl<OutputViewType, InputViewType,
218 true, outputExecSpaceCanAccessInputMemSpace>
221 run (
const OutputViewType& dst,
222 const InputViewType& src)
229 const ptrdiff_t dst_beg =
reinterpret_cast<ptrdiff_t
> (dst.data ());
230 const ptrdiff_t dst_end =
231 reinterpret_cast<ptrdiff_t
> (dst.data () + dst.span ());
232 const ptrdiff_t src_beg =
reinterpret_cast<ptrdiff_t
> (src.data ());
233 const ptrdiff_t src_end =
234 reinterpret_cast<ptrdiff_t
> (src.data () + src.span ());
236 if (dst_end > src_beg && src_end > dst_beg) {
244 auto src_copy = Kokkos::create_mirror (Kokkos::HostSpace (), src);
252 using execution_space =
typename OutputViewType::execution_space;
260 template<
class OutputViewType,
262 struct CopyConvertImpl<OutputViewType,
268 run (
const OutputViewType& dst,
269 const InputViewType& src)
271 using functor_type = CopyConvertFunctor<OutputViewType, InputViewType>;
272 using execution_space =
typename OutputViewType::execution_space;
273 using index_type =
typename OutputViewType::size_type;
274 using range_type = Kokkos::RangePolicy<execution_space, index_type>;
275 Kokkos::parallel_for (
"Tpetra::Details::copyConvert",
276 range_type (0, dst.extent (0)),
277 functor_type (dst, src));
287 template<
class OutputViewType,
289 struct CopyConvertImpl<OutputViewType, InputViewType, false, false>
292 run (
const OutputViewType& dst,
293 const InputViewType& src)
295 using output_memory_space =
typename OutputViewType::memory_space;
296 using output_execution_space =
typename OutputViewType::execution_space;
297 auto src_outputSpaceCopy =
298 Kokkos::create_mirror_view (output_memory_space (), src);
304 using output_space_copy_type = decltype (src_outputSpaceCopy);
306 CopyConvertFunctor<OutputViewType, output_space_copy_type>;
307 using execution_space =
typename OutputViewType::execution_space;
308 using index_type =
typename OutputViewType::size_type;
309 using range_type = Kokkos::RangePolicy<execution_space, index_type>;
310 Kokkos::parallel_for (
"Tpetra::Details::copyConvert",
311 range_type (0, dst.extent (0)),
312 functor_type (dst, src_outputSpaceCopy));
325 template<
class OutputViewType,
329 const InputViewType& src)
331 static_assert (Kokkos::is_view<OutputViewType>::value,
332 "OutputViewType must be a Kokkos::View.");
333 static_assert (Kokkos::is_view<InputViewType>::value,
334 "InputViewType must be a Kokkos::View.");
335 static_assert (std::is_same<
typename OutputViewType::value_type,
336 typename OutputViewType::non_const_value_type>::value,
337 "OutputViewType must be a nonconst Kokkos::View.");
338 static_assert (static_cast<int> (OutputViewType::rank) ==
339 static_cast<int> (InputViewType::rank),
340 "src and dst must have the same rank.");
342 if (dst.extent (0) != src.extent (0)) {
343 std::ostringstream os;
344 os <<
"Tpetra::Details::copyConvert: "
345 <<
"dst.extent(0) = " << dst.extent (0)
346 <<
" != src.extent(0) = " << src.extent (0)
348 throw std::invalid_argument (os.str ());
350 if (static_cast<int> (OutputViewType::rank) > 1 &&
351 dst.extent (1) != src.extent (1)) {
352 std::ostringstream os;
353 os <<
"Tpetra::Details::copyConvert: "
354 <<
"dst.extent(1) = " << dst.extent (1)
355 <<
" != src.extent(1) = " << src.extent (1)
357 throw std::invalid_argument (os.str ());
361 using output_view_type =
362 Kokkos::View<
typename OutputViewType::non_const_data_type,
363 typename OutputViewType::array_layout,
364 typename OutputViewType::device_type>;
365 using input_view_type =
366 Kokkos::View<
typename InputViewType::const_data_type,
367 typename InputViewType::array_layout,
368 typename InputViewType::device_type>;
369 CopyConvertImpl<output_view_type, input_view_type>::run (dst, src);
375 #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...