10#ifndef TPETRA_DETAILS_COPYCONVERT_HPP 
   11#define TPETRA_DETAILS_COPYCONVERT_HPP 
   18#include "TpetraCore_config.h" 
   19#include "Kokkos_Core.hpp" 
   20#if KOKKOS_VERSION >= 40799 
   21#include "KokkosKernels_ArithTraits.hpp" 
   23#include "Kokkos_ArithTraits.hpp" 
   41template <
class OutputValueType,
 
   43          const bool outputIsComplex =
 
   44#if KOKKOS_VERSION >= 40799 
   45              KokkosKernels::ArithTraits<OutputValueType>::is_complex,
 
   47              Kokkos::ArithTraits<OutputValueType>::is_complex,
 
   49          const bool inputIsComplex =
 
   50#if KOKKOS_VERSION >= 40799 
   51              KokkosKernels::ArithTraits<InputValueType>::is_complex>
 
   53              Kokkos::ArithTraits<InputValueType>::is_complex>
 
   56  static KOKKOS_INLINE_FUNCTION 
void 
   57  convert(OutputValueType& dst, 
const InputValueType& src) {
 
   62    dst = OutputValueType(src);
 
   66template <
class OutputRealType, 
class InputComplexType>
 
   67struct ConvertValue<OutputRealType, InputComplexType, false, true> {
 
   68  static KOKKOS_INLINE_FUNCTION 
void 
   69  convert(OutputRealType& dst,
 
   70          const InputComplexType& src) {
 
   73#if KOKKOS_VERSION >= 40799 
   74    using KAI = KokkosKernels::ArithTraits<InputComplexType>;
 
   76    using KAI = Kokkos::ArithTraits<InputComplexType>;
 
   78    dst = OutputRealType(KAI::real(src));
 
   82template <
class OutputComplexType, 
class InputRealType>
 
   83struct ConvertValue<OutputComplexType, InputRealType, true, false> {
 
   84  static KOKKOS_INLINE_FUNCTION 
void 
   85  convert(OutputComplexType& dst,
 
   86          const InputRealType& src) {
 
   89    using output_mag_type =
 
   90#if KOKKOS_VERSION >= 40799 
   91        typename KokkosKernels::ArithTraits<OutputComplexType>::mag_type;
 
   93        typename Kokkos::ArithTraits<OutputComplexType>::mag_type;
 
   95#if KOKKOS_VERSION >= 40799 
   96    using KAM = KokkosKernels::ArithTraits<output_mag_type>;
 
   98    using KAM = Kokkos::ArithTraits<output_mag_type>;
 
  100    dst = OutputComplexType(src, KAM::zero());
 
  104template <
class OutputValueType,
 
  105          class InputValueType>
 
  106KOKKOS_INLINE_FUNCTION 
void 
  107convertValue(OutputValueType& dst, 
const InputValueType& src) {
 
  108  ConvertValue<OutputValueType, InputValueType>::convert(dst, src);
 
  115template <
class OutputViewType,
 
  117          const int rank = 
static_cast<int>(OutputViewType::rank)>
 
  118class CopyConvertFunctor {};
 
  120template <
class OutputViewType,
 
  122class CopyConvertFunctor<OutputViewType, InputViewType, 1> {
 
  124  static_assert(
static_cast<int>(OutputViewType::rank) == 1 &&
 
  125                    static_cast<int>(InputViewType::rank) == 1,
 
  126                "CopyConvertFunctor (implements Tpetra::Details::copyConvert): " 
  127                "OutputViewType and InputViewType must both have rank 1.");
 
  132  using index_type = 
typename OutputViewType::size_type;
 
  134  CopyConvertFunctor(
const OutputViewType& dst,
 
  135                     const InputViewType& src)
 
  139  KOKKOS_INLINE_FUNCTION 
void 
  140  operator()(
const index_type i)
 const {
 
  141    convertValue(dst_(i), src_(i));
 
  145template <
class OutputViewType,
 
  147class CopyConvertFunctor<OutputViewType, InputViewType, 2> {
 
  149  using index_type = 
typename OutputViewType::size_type;
 
  152  static_assert(
static_cast<int>(OutputViewType::rank) == 2 &&
 
  153                    static_cast<int>(InputViewType::rank) == 2,
 
  154                "CopyConvertFunctor (implements Tpetra::Details::copyConvert): " 
  155                "OutputViewType and InputViewType must both have rank 2.");
 
  161  CopyConvertFunctor(
const OutputViewType& dst,
 
  162                     const InputViewType& src)
 
  165    , numCols_(dst.extent(1)) {}
 
  167  KOKKOS_INLINE_FUNCTION 
void 
  168  operator()(
const index_type i)
 const {
 
  169    const index_type numCols = numCols_;
 
  170    for (index_type j = 0; j < numCols; ++j) {
 
  171      convertValue(dst_(i, j), src_(i, j));
 
  177template <
class OutputViewType, 
class InputViewType>
 
  178class CanUseKokkosDeepCopy {
 
  180  static constexpr bool sameValueType =
 
  181      std::is_same<
typename OutputViewType::non_const_value_type,
 
  182                   typename InputViewType::non_const_value_type>::value;
 
  183  static constexpr bool sameMemorySpace =
 
  184      std::is_same<
typename OutputViewType::memory_space,
 
  185                   typename InputViewType::memory_space>::value;
 
  186  static constexpr bool sameLayout =
 
  187      std::is_same<
typename OutputViewType::array_layout,
 
  188                   typename InputViewType::array_layout>::value;
 
  191  static constexpr bool value =
 
  192      sameValueType && (sameMemorySpace || sameLayout);
 
  213template <
class OutputViewType,
 
  215          const bool canUseKokkosDeepCopy =
 
  216              CanUseKokkosDeepCopy<OutputViewType, InputViewType>::value,
 
  217          const bool outputExecSpaceCanAccessInputMemSpace =
 
  218              Kokkos::SpaceAccessibility<
 
  219                  typename OutputViewType::memory_space,
 
  220                  typename InputViewType::memory_space>::accessible>
 
  221struct CopyConvertImpl {
 
  223  run(
const OutputViewType& dst,
 
  224      const InputViewType& src);
 
  228template <
class OutputViewType,
 
  230          const bool outputExecSpaceCanAccessInputMemSpace>
 
  231struct CopyConvertImpl<OutputViewType, InputViewType,
 
  232                       true, outputExecSpaceCanAccessInputMemSpace> {
 
  234  run(
const OutputViewType& dst,
 
  235      const InputViewType& src) {
 
  241    const ptrdiff_t dst_beg = 
reinterpret_cast<ptrdiff_t
>(dst.data());
 
  242    const ptrdiff_t dst_end =
 
  243        reinterpret_cast<ptrdiff_t
>(dst.data() + dst.span());
 
  244    const ptrdiff_t src_beg = 
reinterpret_cast<ptrdiff_t
>(src.data());
 
  245    const ptrdiff_t src_end =
 
  246        reinterpret_cast<ptrdiff_t
>(src.data() + src.span());
 
  248    if (dst_end > src_beg && src_end > dst_beg) {
 
  256      auto src_copy = Kokkos::create_mirror(Kokkos::HostSpace(), src);
 
  258      Kokkos::deep_copy(src_copy, src);
 
  260      Kokkos::deep_copy(dst, src_copy);
 
  263      using execution_space = 
typename OutputViewType::execution_space;
 
  264      Kokkos::deep_copy(execution_space(), dst, src);
 
  271template <
class OutputViewType,
 
  273struct CopyConvertImpl<OutputViewType,
 
  278  run(
const OutputViewType& dst,
 
  279      const InputViewType& src) {
 
  280    using functor_type    = CopyConvertFunctor<OutputViewType, InputViewType>;
 
  281    using execution_space = 
typename OutputViewType::execution_space;
 
  282    using index_type      = 
typename OutputViewType::size_type;
 
  283    using range_type      = Kokkos::RangePolicy<execution_space, index_type>;
 
  284    Kokkos::parallel_for(
"Tpetra::Details::copyConvert",
 
  285                         range_type(0, dst.extent(0)),
 
  286                         functor_type(dst, src));
 
  296template <
class OutputViewType,
 
  298struct CopyConvertImpl<OutputViewType, InputViewType, false, false> {
 
  300  run(
const OutputViewType& dst,
 
  301      const InputViewType& src) {
 
  302    using output_memory_space    = 
typename OutputViewType::memory_space;
 
  303    using output_execution_space = 
typename OutputViewType::execution_space;
 
  304    auto src_outputSpaceCopy =
 
  305        Kokkos::create_mirror_view(output_memory_space(), src);
 
  307    Kokkos::deep_copy(output_execution_space(), src_outputSpaceCopy, src);
 
  311    using output_space_copy_type = 
decltype(src_outputSpaceCopy);
 
  313        CopyConvertFunctor<OutputViewType, output_space_copy_type>;
 
  314    using execution_space = 
typename OutputViewType::execution_space;
 
  315    using index_type      = 
typename OutputViewType::size_type;
 
  316    using range_type      = Kokkos::RangePolicy<execution_space, index_type>;
 
  317    Kokkos::parallel_for(
"Tpetra::Details::copyConvert",
 
  318                         range_type(0, dst.extent(0)),
 
  319                         functor_type(dst, src_outputSpaceCopy));
 
  332template <
class OutputViewType,
 
  336  static_assert(Kokkos::is_view<OutputViewType>::value,
 
  337                "OutputViewType must be a Kokkos::View.");
 
  338  static_assert(Kokkos::is_view<InputViewType>::value,
 
  339                "InputViewType must be a Kokkos::View.");
 
  340  static_assert(std::is_same<
typename OutputViewType::value_type,
 
  341                             typename OutputViewType::non_const_value_type>::value,
 
  342                "OutputViewType must be a nonconst Kokkos::View.");
 
  343  static_assert(
static_cast<int>(OutputViewType::rank) ==
 
  344                    static_cast<int>(InputViewType::rank),
 
  345                "src and dst must have the same rank.");
 
  347  if (dst.extent(0) != src.extent(0)) {
 
  348    std::ostringstream 
os;
 
  349    os << 
"Tpetra::Details::copyConvert: " 
  350       << 
"dst.extent(0) = " << dst.extent(0)
 
  351       << 
" != src.extent(0) = " << src.extent(0)
 
  353    throw std::invalid_argument(
os.str());
 
  355  if (
static_cast<int>(OutputViewType::rank) > 1 &&
 
  356      dst.extent(1) != src.extent(1)) {
 
  357    std::ostringstream 
os;
 
  358    os << 
"Tpetra::Details::copyConvert: " 
  359       << 
"dst.extent(1) = " << dst.extent(1)
 
  360       << 
" != src.extent(1) = " << src.extent(1)
 
  362    throw std::invalid_argument(
os.str());
 
  366  using output_view_type =
 
  367      Kokkos::View<
typename OutputViewType::non_const_data_type,
 
  368                   typename OutputViewType::array_layout,
 
  369                   typename OutputViewType::device_type>;
 
  370  using input_view_type =
 
  371      Kokkos::View<
typename InputViewType::const_data_type,
 
  372                   typename InputViewType::array_layout,
 
  373                   typename InputViewType::device_type>;
 
  374  CopyConvertImpl<output_view_type, input_view_type>::run(dst, src);
 
 
Struct that holds views of the contents of a CrsMatrix.
 
Implementation details of Tpetra.
 
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....
 
Namespace Tpetra contains the class and methods constituting the Tpetra library.