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_Complex.hpp"
57 #include <type_traits>
68 template<
class OutputValueType,
71 static KOKKOS_INLINE_FUNCTION
void
72 convert (OutputValueType& dst,
const InputValueType& src) {
77 dst = OutputValueType (src);
81 template<
class RealType>
82 struct ConvertValue<RealType, Kokkos::complex<RealType> > {
83 static KOKKOS_INLINE_FUNCTION
void
84 convert (RealType& dst,
const Kokkos::complex<RealType>& src) {
88 dst = RealType (src.real ());
96 template<
class OutputViewType,
98 class CopyConvertFunctor {
104 typedef typename std::decay<decltype (dst_[0])>::type output_type;
105 typedef typename OutputViewType::size_type index_type;
107 CopyConvertFunctor (
const OutputViewType& dst,
const InputViewType& src) :
114 static_assert (Kokkos::Impl::VerifyExecutionCanAccessMemorySpace<
115 typename OutputViewType::memory_space,
116 typename InputViewType::memory_space>::value,
117 "CopyConvertFunctor (implements copyConvert): Output "
118 "View's space must be able to access the input View's "
120 static_assert (OutputViewType::Rank == 1 && InputViewType::Rank == 1,
121 "CopyConvertFunctor (implements copyConvert): "
122 "OutputViewType and InputViewType must be rank-1 "
123 "Kokkos::View specializations.");
126 KOKKOS_INLINE_FUNCTION
void
127 operator () (
const index_type& i)
const {
128 using input_type =
typename std::decay<decltype (src_[i])>::type;
129 ConvertValue<output_type, input_type>::convert (dst_(i), src_(i));
154 template<
class OutputViewType,
156 const bool canUseKokkosDeepCopy =
157 std::is_same<
typename OutputViewType::array_layout,
158 typename InputViewType::array_layout>::value &&
159 std::is_same<
typename OutputViewType::non_const_value_type,
160 typename InputViewType::non_const_value_type>::value,
161 const bool outputExecSpaceCanAccessInputMemSpace =
162 Kokkos::Impl::VerifyExecutionCanAccessMemorySpace<
163 typename OutputViewType::memory_space,
164 typename InputViewType::memory_space>::value>
165 struct CopyConvertImpl {
166 static void run (
const OutputViewType& dst,
const InputViewType& src);
176 template<
class OutputViewType,
178 const bool outputExecSpaceCanAccessInputMemSpace>
179 struct CopyConvertImpl<OutputViewType, InputViewType,
180 true, outputExecSpaceCanAccessInputMemSpace> {
181 static void run (
const OutputViewType& dst,
const InputViewType& src) {
182 static_assert (std::is_same<
typename OutputViewType::non_const_value_type,
183 typename InputViewType::non_const_value_type>::value,
184 "CopyConvertImpl (implementation of copyConvert): In order"
185 " to call this specialization, the input and output must "
186 "use the same offset type.");
187 static_assert (OutputViewType::Rank == 1 && InputViewType::Rank == 1,
188 "CopyConvertImpl (implementation of copyConvert): "
189 "OutputViewType and InputViewType must be rank-1 "
190 "Kokkos::View specializations.");
191 static_assert (std::is_same<
typename OutputViewType::array_layout,
192 typename InputViewType::array_layout>::value,
193 "CopyConvertImpl (implementation of copyConvert): In order"
194 " to call this specialization, src and dst must have the "
195 "the same array_layout.");
205 template<
class OutputViewType,
207 struct CopyConvertImpl<OutputViewType,
211 static void run (
const OutputViewType& dst,
const InputViewType& src) {
212 static_assert (! std::is_same<
typename OutputViewType::array_layout,
213 typename InputViewType::array_layout>::value ||
214 ! std::is_same<
typename OutputViewType::non_const_value_type,
215 typename InputViewType::non_const_value_type>::value,
216 "CopyConvertImpl (implementation of copyConvert): We "
217 "should not be calling this specialization if "
218 "OutputViewType and InputViewType have the same entry "
219 "and layout types.");
220 static_assert (OutputViewType::Rank == 1 && InputViewType::Rank == 1,
221 "CopyConvertImpl (implementation of copyConvert): "
222 "OutputViewType and InputViewType must both be rank-1 "
223 "Kokkos::View types.");
227 static_assert (Kokkos::Impl::VerifyExecutionCanAccessMemorySpace<
228 typename OutputViewType::memory_space,
229 typename InputViewType::memory_space>::value,
230 "CopyConvertImpl (implements copyConvert): In order to "
231 "call this specialization, the output View's space must "
232 "be able to access the input View's memory space.");
234 typedef CopyConvertFunctor<OutputViewType, InputViewType> functor_type;
235 typedef typename OutputViewType::execution_space execution_space;
236 typedef typename OutputViewType::size_type index_type;
237 typedef Kokkos::RangePolicy<execution_space, index_type> range_type;
238 Kokkos::parallel_for (range_type (0, dst.extent (0)),
239 functor_type (dst, src));
260 template<
class OutputViewType,
262 struct CopyConvertImpl<OutputViewType,
266 static void run (
const OutputViewType& dst,
const InputViewType& src) {
267 const bool canUseKokkosDeepCopy =
268 std::is_same<
typename OutputViewType::array_layout,
269 typename InputViewType::array_layout>::value &&
270 std::is_same<
typename OutputViewType::non_const_value_type,
271 typename InputViewType::non_const_value_type>::value;
272 static_assert (! canUseKokkosDeepCopy,
273 "CopyConvertImpl (implementation of copyConvert): We "
274 "should not be calling this specialization if we could "
275 "have used Kokkos::deep_copy instead.");
276 static_assert (OutputViewType::Rank == 1 && InputViewType::Rank == 1,
277 "CopyConvertImpl (implementation of copyConvert): "
278 "OutputViewType and InputViewType must both be rank-1 "
279 "Kokkos::View types.");
281 using Kokkos::ViewAllocateWithoutInitializing;
282 typedef Kokkos::View<
typename InputViewType::non_const_value_type*,
283 typename InputViewType::array_layout,
284 typename OutputViewType::device_type> output_space_copy_type;
285 output_space_copy_type
286 outputSpaceCopy (ViewAllocateWithoutInitializing (
"outputSpace"),
292 typedef CopyConvertFunctor<OutputViewType,
293 output_space_copy_type> functor_type;
294 typedef typename OutputViewType::execution_space execution_space;
295 typedef typename OutputViewType::size_type index_type;
296 typedef Kokkos::RangePolicy<execution_space, index_type> range_type;
297 Kokkos::parallel_for (range_type (0, dst.extent (0)),
298 functor_type (dst, outputSpaceCopy));
311 template<
class OutputViewType,
315 const InputViewType& src)
317 static_assert (Kokkos::Impl::is_view<OutputViewType>::value,
318 "OutputViewType (the type of dst) must be a Kokkos::View.");
319 static_assert (Kokkos::Impl::is_view<InputViewType>::value,
320 "InputViewType (the type of src) must be a Kokkos::View.");
321 static_assert (std::is_same<
typename OutputViewType::value_type,
322 typename OutputViewType::non_const_value_type>::value,
323 "OutputViewType (the type of dst) must be a nonconst Kokkos::View.");
324 static_assert (static_cast<int> (OutputViewType::rank) == 1,
325 "OutputViewType (the type of dst) must be a rank-1 Kokkos::View.");
326 static_assert (static_cast<int> (InputViewType::rank) == 1,
327 "InputViewType (the type of src) must be a rank-1 Kokkos::View.");
328 if (dst.extent (0) != src.extent (0)) {
329 std::ostringstream os;
330 os <<
"Tpetra::Details::copyConvert: "
331 <<
"dst.extent(0) = " << dst.extent (0)
332 <<
" != src.extent(0) = " << src.extent (0)
334 throw std::invalid_argument (os.str ());
337 typedef typename OutputViewType::non_const_type output_view_type;
338 typedef typename InputViewType::const_type input_view_type;
339 CopyConvertImpl<output_view_type, input_view_type>::run (dst, src);
345 #endif // TPETRA_DETAILS_COPYCONVERT_HPP