44 #ifndef TPETRA_DETAILS_COPYOFFSETS_HPP
45 #define TPETRA_DETAILS_COPYOFFSETS_HPP
52 #include "TpetraCore_config.h"
53 #include "Kokkos_Core.hpp"
55 #include <type_traits>
75 template<
class T1,
class T2,
76 const bool T1_is_signed = std::is_signed<T1>::value,
77 const bool T2_is_signed = std::is_signed<T2>::value>
78 struct OutputCanFitInput {
79 static const bool value =
sizeof (T1) >
sizeof (T2) ||
80 (
sizeof (T1) ==
sizeof (T2) &&
81 (std::is_unsigned<T1>::value || (std::is_signed<T1>::value && std::is_signed<T2>::value)));
93 template<
class OutputViewType,
95 const bool outputCanFitInput =
96 OutputCanFitInput<
typename OutputViewType::non_const_value_type,
97 typename InputViewType::non_const_value_type>::value>
98 class CopyOffsetsFunctor {};
101 template<
class OutputViewType,
class InputViewType>
102 class CopyOffsetsFunctor<OutputViewType, InputViewType, false> {
104 typedef typename OutputViewType::execution_space execution_space;
105 typedef typename OutputViewType::size_type size_type;
106 typedef int value_type;
108 typedef typename InputViewType::non_const_value_type input_value_type;
109 typedef typename OutputViewType::non_const_value_type output_value_type;
111 CopyOffsetsFunctor (
const OutputViewType& dst,
const InputViewType& src) :
120 minDstVal_ (static_cast<input_value_type> (std::numeric_limits<output_value_type>::min ())),
121 maxDstVal_ (static_cast<input_value_type> (std::numeric_limits<output_value_type>::max ()))
126 static_assert (Kokkos::Impl::VerifyExecutionCanAccessMemorySpace<
127 typename OutputViewType::memory_space,
128 typename InputViewType::memory_space>::value,
129 "CopyOffsetsFunctor (implements copyOffsets): Output "
130 "View's space must be able to access the input View's "
134 KOKKOS_INLINE_FUNCTION
void
135 operator () (
const size_type& i, value_type& noOverflow)
const {
136 const input_value_type src_i = src_(i);
137 if (src_i < minDstVal_ || src_i > maxDstVal_) {
140 dst_(i) =
static_cast<output_value_type
> (src_i);
143 KOKKOS_INLINE_FUNCTION
void init (value_type& noOverflow)
const {
147 KOKKOS_INLINE_FUNCTION
void
148 join (
volatile value_type& result,
149 const volatile value_type& current)
const {
150 result = (result>0 && current>0)?1:0;
156 input_value_type minDstVal_;
157 input_value_type maxDstVal_;
161 template<
class OutputViewType,
class InputViewType>
162 class CopyOffsetsFunctor<OutputViewType, InputViewType, true> {
164 typedef typename OutputViewType::execution_space execution_space;
165 typedef typename OutputViewType::size_type size_type;
166 typedef int value_type;
168 CopyOffsetsFunctor (
const OutputViewType& dst,
const InputViewType& src) :
175 static_assert (Kokkos::Impl::VerifyExecutionCanAccessMemorySpace<
176 typename OutputViewType::memory_space,
177 typename InputViewType::memory_space>::value,
178 "CopyOffsetsFunctor (implements copyOffsets): Output "
179 "View's space must be able to access the input View's "
183 KOKKOS_INLINE_FUNCTION
void
184 operator () (
const size_type& i, value_type& )
const {
189 KOKKOS_INLINE_FUNCTION
void init (value_type& noOverflow)
const {
193 KOKKOS_INLINE_FUNCTION
void
194 join (
volatile value_type& result,
195 const volatile value_type& current)
const {
196 result = (result>0 && current>0)?1:0;
223 template<
class OutputViewType,
225 const bool sameLayoutsSameOffsetTypes =
226 std::is_same<
typename OutputViewType::array_layout,
227 typename InputViewType::array_layout>::value &&
228 std::is_same<
typename OutputViewType::non_const_value_type,
229 typename InputViewType::non_const_value_type>::value,
230 const bool outputExecSpaceCanAccessInputMemSpace =
231 Kokkos::Impl::VerifyExecutionCanAccessMemorySpace<
232 typename OutputViewType::memory_space,
233 typename InputViewType::memory_space>::value>
234 struct CopyOffsetsImpl {
235 static void run (
const OutputViewType& dst,
const InputViewType& src);
246 template<
class OutputViewType,
248 const bool outputExecSpaceCanAccessInputMemSpace>
249 struct CopyOffsetsImpl<OutputViewType, InputViewType,
250 true, outputExecSpaceCanAccessInputMemSpace> {
251 static void run (
const OutputViewType& dst,
const InputViewType& src) {
252 static_assert (std::is_same<
typename OutputViewType::non_const_value_type,
253 typename InputViewType::non_const_value_type>::value,
254 "CopyOffsetsImpl (implementation of copyOffsets): In order"
255 " to call this specialization, the input and output must "
256 "use the same offset type.");
257 static_assert (static_cast<int> (OutputViewType::rank) ==
258 static_cast<int> (InputViewType::rank),
259 "CopyOffsetsImpl (implementation of copyOffsets): In order"
260 " to call this specialization, src and dst must have the "
262 static_assert (std::is_same<
typename OutputViewType::array_layout,
263 typename InputViewType::array_layout>::value,
264 "CopyOffsetsImpl (implementation of copyOffsets): In order"
265 " to call this specialization, src and dst must have the "
266 "the same array_layout.");
282 template<
class OutputViewType,
284 struct CopyOffsetsImpl<OutputViewType, InputViewType,
286 static void run (
const OutputViewType& dst,
const InputViewType& src) {
287 static_assert (static_cast<int> (OutputViewType::rank) ==
288 static_cast<int> (InputViewType::rank),
289 "CopyOffsetsImpl (implementation of copyOffsets): "
290 "src and dst must have the same rank.");
291 constexpr
bool sameLayoutsSameOffsetTypes =
292 std::is_same<
typename OutputViewType::array_layout,
293 typename InputViewType::array_layout>::value &&
294 std::is_same<
typename OutputViewType::non_const_value_type,
295 typename InputViewType::non_const_value_type>::value;
296 static_assert (! sameLayoutsSameOffsetTypes,
297 "CopyOffsetsImpl (implements copyOffsets): In order to "
298 "call this specialization, sameLayoutsSameOffsetTypes "
299 "must be false. That is, either the input and output "
300 "must have different array layouts, or their value types "
305 static_assert (Kokkos::Impl::VerifyExecutionCanAccessMemorySpace<
306 typename OutputViewType::memory_space,
307 typename InputViewType::memory_space>::value,
308 "CopyOffsetsImpl (implements copyOffsets): In order to "
309 "call this specialization, the output View's space must "
310 "be able to access the input View's memory space.");
311 typedef CopyOffsetsFunctor<OutputViewType, InputViewType> functor_type;
312 typedef typename OutputViewType::execution_space execution_space;
313 typedef typename OutputViewType::size_type size_type;
314 typedef Kokkos::RangePolicy<execution_space, size_type> range_type;
317 Kokkos::parallel_reduce (range_type (0, dst.extent (0)),
318 functor_type (dst, src),
320 TEUCHOS_TEST_FOR_EXCEPTION
321 (noOverflow==0, std::runtime_error,
"copyOffsets: One or more values in "
322 "src were too big (in the sense of integer overflow) to fit in dst.");
343 template<
class OutputViewType,
class InputViewType>
344 struct CopyOffsetsImpl<OutputViewType, InputViewType,
346 static void run (
const OutputViewType& dst,
const InputViewType& src) {
347 static_assert (static_cast<int> (OutputViewType::rank) ==
348 static_cast<int> (InputViewType::rank),
349 "CopyOffsetsImpl (implementation of copyOffsets): In order"
350 " to call this specialization, src and dst must have the "
352 constexpr
bool sameLayoutsSameOffsetTypes =
353 std::is_same<
typename OutputViewType::array_layout,
354 typename InputViewType::array_layout>::value &&
355 std::is_same<
typename OutputViewType::non_const_value_type,
356 typename InputViewType::non_const_value_type>::value;
357 static_assert (! sameLayoutsSameOffsetTypes,
358 "CopyOffsetsImpl (implements copyOffsets): In order to "
359 "call this specialization, sameLayoutsSameOffsetTypes "
360 "must be false. That is, either the input and output "
361 "must have different array layouts, or their value types "
364 typedef Kokkos::View<
typename InputViewType::non_const_value_type*,
366 typename OutputViewType::device_type>
367 output_space_copy_type;
368 using Kokkos::ViewAllocateWithoutInitializing;
369 output_space_copy_type
370 outputSpaceCopy (ViewAllocateWithoutInitializing (
"outputSpace"),
376 typedef CopyOffsetsFunctor<OutputViewType,
377 output_space_copy_type> functor_type;
378 typedef typename OutputViewType::execution_space execution_space;
379 typedef typename OutputViewType::size_type size_type;
380 typedef Kokkos::RangePolicy<execution_space, size_type> range_type;
383 Kokkos::parallel_reduce (range_type (0, dst.extent (0)),
384 functor_type (dst, outputSpaceCopy),
386 TEUCHOS_TEST_FOR_EXCEPTION
387 (noOverflow==0, std::runtime_error,
"copyOffsets: One or more values "
388 "in src were too big (in the sense of integer overflow) to fit in "
405 template<
class OutputViewType,
class InputViewType>
409 static_assert (Kokkos::Impl::is_view<OutputViewType>::value,
410 "OutputViewType (the type of dst) must be a Kokkos::View.");
411 static_assert (Kokkos::Impl::is_view<InputViewType>::value,
412 "InputViewType (the type of src) must be a Kokkos::View.");
413 static_assert (std::is_same<
typename OutputViewType::value_type,
414 typename OutputViewType::non_const_value_type>::value,
415 "OutputViewType (the type of dst) must be a nonconst Kokkos::View.");
416 static_assert (static_cast<int> (OutputViewType::rank) == 1,
417 "OutputViewType (the type of dst) must be a rank-1 Kokkos::View.");
418 static_assert (static_cast<int> (InputViewType::rank) == 1,
419 "InputViewType (the type of src) must be a rank-1 Kokkos::View.");
420 static_assert (std::is_integral<
typename std::decay<decltype (dst(0)) >::type>::value,
421 "The entries of dst must be built-in integers.");
422 static_assert (std::is_integral<
typename std::decay<decltype (src(0)) >::type>::value,
423 "The entries of src must be built-in integers.");
425 TEUCHOS_TEST_FOR_EXCEPTION
426 (dst.extent (0) != src.extent (0), std::invalid_argument,
427 "copyOffsets: dst.extent(0) = " << dst.extent (0)
428 <<
" != src.extent(0) = " << src.extent (0) <<
".");
430 CopyOffsetsImpl<OutputViewType, InputViewType>::run (dst, src);
436 #endif // TPETRA_DETAILS_COPYOFFSETS_HPP
void copyOffsets(const OutputViewType &dst, const InputViewType &src)
Copy row offsets (in a sparse graph or matrix) from src to dst. The offsets may have different types...
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.