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;
313 Kokkos::parallel_reduce (dst.dimension_0 (),
314 functor_type (dst, src),
316 TEUCHOS_TEST_FOR_EXCEPTION
317 (noOverflow==0, std::runtime_error,
"copyOffsets: One or more values in " 318 "src were too big (in the sense of integer overflow) to fit in dst.");
339 template<
class OutputViewType,
class InputViewType>
340 struct CopyOffsetsImpl<OutputViewType, InputViewType,
342 static void run (
const OutputViewType& dst,
const InputViewType& src) {
343 static_assert (static_cast<int> (OutputViewType::rank) ==
344 static_cast<int> (InputViewType::rank),
345 "CopyOffsetsImpl (implementation of copyOffsets): In order" 346 " to call this specialization, src and dst must have the " 348 constexpr
bool sameLayoutsSameOffsetTypes =
349 std::is_same<
typename OutputViewType::array_layout,
350 typename InputViewType::array_layout>::value &&
351 std::is_same<
typename OutputViewType::non_const_value_type,
352 typename InputViewType::non_const_value_type>::value;
353 static_assert (! sameLayoutsSameOffsetTypes,
354 "CopyOffsetsImpl (implements copyOffsets): In order to " 355 "call this specialization, sameLayoutsSameOffsetTypes " 356 "must be false. That is, either the input and output " 357 "must have different array layouts, or their value types " 360 typedef Kokkos::View<
typename InputViewType::non_const_value_type*,
362 typename OutputViewType::device_type>
363 output_space_copy_type;
364 using Kokkos::ViewAllocateWithoutInitializing;
365 output_space_copy_type
366 outputSpaceCopy (ViewAllocateWithoutInitializing (
"outputSpace"),
372 typedef CopyOffsetsFunctor<OutputViewType,
373 output_space_copy_type> functor_type;
375 Kokkos::parallel_reduce (dst.dimension_0 (),
376 functor_type (dst, outputSpaceCopy),
378 TEUCHOS_TEST_FOR_EXCEPTION
379 (noOverflow==0, std::runtime_error,
"copyOffsets: One or more values " 380 "in src were too big (in the sense of integer overflow) to fit in " 397 template<
class OutputViewType,
class InputViewType>
401 static_assert (Kokkos::Impl::is_view<OutputViewType>::value,
402 "OutputViewType (the type of dst) must be a Kokkos::View.");
403 static_assert (Kokkos::Impl::is_view<InputViewType>::value,
404 "InputViewType (the type of src) must be a Kokkos::View.");
405 static_assert (std::is_same<
typename OutputViewType::value_type,
406 typename OutputViewType::non_const_value_type>::value,
407 "OutputViewType (the type of dst) must be a nonconst Kokkos::View.");
408 static_assert (static_cast<int> (OutputViewType::rank) == 1,
409 "OutputViewType (the type of dst) must be a rank-1 Kokkos::View.");
410 static_assert (static_cast<int> (InputViewType::rank) == 1,
411 "InputViewType (the type of src) must be a rank-1 Kokkos::View.");
412 static_assert (std::is_integral<
typename std::decay<decltype (dst(0)) >::type>::value,
413 "The entries of dst must be built-in integers.");
414 static_assert (std::is_integral<
typename std::decay<decltype (src(0)) >::type>::value,
415 "The entries of src must be built-in integers.");
417 TEUCHOS_TEST_FOR_EXCEPTION
418 (dst.dimension_0 () != src.dimension_0 (), std::invalid_argument,
419 "copyOffsets: dst.dimension_0() = " << dst.dimension_0 ()
420 <<
" != src.dimension_0() = " << src.dimension_0 () <<
".");
422 CopyOffsetsImpl<OutputViewType, InputViewType>::run (dst, src);
428 #endif // TPETRA_DETAILS_COPYOFFSETS_HPP Namespace Tpetra contains the class and methods constituting the Tpetra library.
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, dstClassic > &dst, const MultiVector< SS, SL, SG, SN, srcClassic > &src)
Copy the contents of the MultiVector src into dst.
Implementation details of Tpetra.