void spmv(const char mode[], const AlphaType& alpha, const AMatrix& A, const XVector& x, const BetaType& beta, const YVector& y, const RANK_ONE) { #ifdef KOKKOS_HAVE_CXX11 // Make sure that both x and y have the same rank. static_assert ((int) XVector::rank == (int) YVector::rank, "KokkosBlas::spmv: Vector ranks do not match."); // Make sure that x (and therefore y) is rank 1. static_assert ((int) XVector::rank == 1, "KokkosBlas::spmv: " "Both Vector inputs must have rank 1 or 2."); // Make sure that y is non-const. static_assert (Kokkos::Impl::is_same<typename YVector::value_type, typename YVector::non_const_value_type>::value, "KokkosBlas::spmv: Output Vector must be non-const."); #else // We prefer to use C++11 static_assert, because it doesn't give // "unused typedef" warnings, like the constructs below do. // // Make sure that both x and y have the same rank. typedef typename Kokkos::Impl::StaticAssert<(int) XVector::rank == (int) YVector::rank>::type Blas1_spmv_vector_ranks_do_not_match; // Make sure that x (and therefore y) is rank 1. typedef typename Kokkos::Impl::StaticAssert<(int) XVector::rank == 1 >::type Blas1_spmv_vector_rank_not_one; #endif // KOKKOS_HAVE_CXX11 // Check compatibility of dimensions at run time. if((mode[0]==NoTranspose[0])||(mode[0]==Conjugate[0])) { if ((x.dimension_1 () != y.dimension_1 ()) || (static_cast<size_t> (A.numCols ()) > static_cast<size_t> (x.dimension_0 ())) || (static_cast<size_t> (A.numRows ()) > static_cast<size_t> (y.dimension_0 ()))) { std::ostringstream os; os << "KokkosBlas::spmv: Dimensions do not match: " << ", A: " << A.numRows () << " x " << A.numCols() << ", x: " << x.dimension_0 () << " x " << x.dimension_1() << ", y: " << y.dimension_0 () << " x " << y.dimension_1() ; Kokkos::Impl::throw_runtime_exception (os.str ()); } } else { if ((x.dimension_1 () != y.dimension_1 ()) || (static_cast<size_t> (A.numCols ()) > static_cast<size_t> (y.dimension_0 ())) || (static_cast<size_t> (A.numRows ()) > static_cast<size_t> (x.dimension_0()))) { std::ostringstream os; os << "KokkosBlas::spmv: Dimensions do not match (transpose): " << ", A: " << A.numRows () << " x " << A.numCols() << ", x: " << x.dimension_0 () << " x " << x.dimension_1() << ", y: " << y.dimension_0 () << " x " << y.dimension_1() ; Kokkos::Impl::throw_runtime_exception (os.str ()); } } typedef KokkosSparse::CrsMatrix<typename AMatrix::const_value_type, typename AMatrix::non_const_ordinal_type, typename AMatrix::device_type, Kokkos::MemoryTraits<Kokkos::Unmanaged>, typename AMatrix::const_size_type> AMatrix_Internal; typedef Kokkos::View<typename XVector::const_value_type*, typename XVector::array_layout, typename XVector::device_type, Kokkos::MemoryTraits<Kokkos::Unmanaged|Kokkos::RandomAccess> > XVector_Internal; typedef Kokkos::View<typename YVector::non_const_value_type*, typename YVector::array_layout, typename YVector::device_type, Kokkos::MemoryTraits<Kokkos::Unmanaged> > YVector_Internal; AMatrix_Internal A_i = A; XVector_Internal x_i = x; YVector_Internal y_i = y; return Impl::SPMV<typename AMatrix_Internal::value_type, typename AMatrix_Internal::ordinal_type, typename AMatrix_Internal::device_type, typename AMatrix_Internal::memory_traits, typename AMatrix_Internal::size_type, typename XVector_Internal::value_type*, typename XVector_Internal::array_layout, typename XVector_Internal::device_type, typename XVector_Internal::memory_traits, typename YVector_Internal::value_type*, typename YVector_Internal::array_layout, typename YVector_Internal::device_type, typename YVector_Internal::memory_traits>::spmv(mode,alpha,A,x,beta,y); }
void spmv(const char mode[], const AlphaType& alpha_in, const AMatrix& A, const XVector& x, const BetaType& beta_in, const YVector& y, const RANK_TWO) { typedef typename Impl::GetCoeffView<AlphaType, typename XVector::device_type>::view_type alpha_view_type; typedef typename Impl::GetCoeffView<BetaType, typename XVector::device_type>::view_type beta_view_type; //alpha_view_type alpha = Impl::GetCoeffView<AlphaType, typename XVector::device_type>::get_view(alpha_in,x.dimension_1()); //beta_view_type beta = Impl::GetCoeffView<AlphaType, typename XVector::device_type>::get_view(beta_in, x.dimension_1()); #ifdef KOKKOS_HAVE_CXX11 // Make sure that both x and y have the same rank. static_assert (XVector::rank == YVector::rank, "KokkosBlas::spmv: Vector ranks do not match."); // Make sure that y is non-const. static_assert (Kokkos::Impl::is_same<typename YVector::value_type, typename YVector::non_const_value_type>::value, "KokkosBlas::spmv: Output Vector must be non-const."); #else // We prefer to use C++11 static_assert, because it doesn't give // "unused typedef" warnings, like the constructs below do. // // Make sure that both x and y have the same rank. typedef typename Kokkos::Impl::StaticAssert<XVector::rank == YVector::rank>::type Blas1_spmv_vector_ranks_do_not_match; #endif // KOKKOS_HAVE_CXX11 // Check compatibility of dimensions at run time. if((mode[0]==NoTranspose[0])||(mode[0]==Conjugate[0])) { if ((x.dimension_1 () != y.dimension_1 ()) || (static_cast<size_t> (A.numCols ()) > static_cast<size_t> (x.dimension_0 ())) || (static_cast<size_t> (A.numRows ()) > static_cast<size_t> (y.dimension_0 ()))) { std::ostringstream os; os << "KokkosBlas::spmv: Dimensions do not match: " << ", A: " << A.numRows () << " x " << A.numCols() << ", x: " << x.dimension_0 () << " x " << x.dimension_1 () << ", y: " << y.dimension_0 () << " x " << y.dimension_1 (); Kokkos::Impl::throw_runtime_exception (os.str ()); } } else { if ((x.dimension_1 () != y.dimension_1 ()) || (static_cast<size_t> (A.numCols ()) > static_cast<size_t> (y.dimension_0 ())) || (static_cast<size_t> (A.numRows ()) > static_cast<size_t> (x.dimension_0 ()))) { std::ostringstream os; os << "KokkosBlas::spmv: Dimensions do not match (transpose): " << ", A: " << A.numRows () << " x " << A.numCols() << ", x: " << x.dimension_0 () << " x " << x.dimension_1 () << ", y: " << y.dimension_0 () << " x " << y.dimension_1 (); Kokkos::Impl::throw_runtime_exception (os.str ()); } } typedef KokkosSparse::CrsMatrix<typename AMatrix::const_value_type, typename AMatrix::const_ordinal_type, typename AMatrix::device_type, typename AMatrix::memory_traits, typename AMatrix::const_size_type> AMatrix_Internal; AMatrix_Internal A_i = A; // Call single vector version if appropriate if( x.dimension_1() == 1) { typedef Kokkos::View<typename XVector::const_value_type*, typename Kokkos::Impl::if_c<Kokkos::Impl::is_same<typename YVector::array_layout,Kokkos::LayoutLeft>::value, Kokkos::LayoutLeft,Kokkos::LayoutStride>::type, typename XVector::device_type, Kokkos::MemoryTraits<Kokkos::Unmanaged|Kokkos::RandomAccess> > XVector_SubInternal; typedef Kokkos::View<typename YVector::non_const_value_type*, typename Kokkos::Impl::if_c<Kokkos::Impl::is_same<typename YVector::array_layout,Kokkos::LayoutLeft>::value, Kokkos::LayoutLeft,Kokkos::LayoutStride>::type, typename YVector::device_type, Kokkos::MemoryTraits<Kokkos::Unmanaged> > YVector_SubInternal; XVector_SubInternal x_i = Kokkos::subview(x,Kokkos::ALL(),0); YVector_SubInternal y_i = Kokkos::subview(y,Kokkos::ALL(),0); alpha_view_type alpha = Impl::GetCoeffView<AlphaType, typename XVector::device_type>::get_view(alpha_in,x.dimension_1()); beta_view_type beta = Impl::GetCoeffView<BetaType, typename XVector::device_type>::get_view(beta_in, x.dimension_1()); typename alpha_view_type::non_const_type::HostMirror h_alpha = Kokkos::create_mirror_view(alpha); Kokkos::deep_copy(h_alpha,alpha); typename beta_view_type::non_const_type::HostMirror h_beta = Kokkos::create_mirror_view(beta); Kokkos::deep_copy(h_beta,beta); spmv(mode,h_alpha(0),A,x_i,h_beta(0),y_i); return; } else { typedef Kokkos::View<typename XVector::const_value_type**, typename XVector::array_layout, typename XVector::device_type, Kokkos::MemoryTraits<Kokkos::Unmanaged|Kokkos::RandomAccess> > XVector_Internal; typedef Kokkos::View<typename YVector::non_const_value_type**, typename YVector::array_layout, typename YVector::device_type, Kokkos::MemoryTraits<Kokkos::Unmanaged> > YVector_Internal; XVector_Internal x_i = x; YVector_Internal y_i = y; typedef Kokkos::View<typename alpha_view_type::const_value_type*, typename alpha_view_type::array_layout, typename alpha_view_type::device_type, Kokkos::MemoryTraits<Kokkos::Unmanaged> > alpha_view_type_Internal; typedef Kokkos::View<typename beta_view_type::const_value_type*, typename beta_view_type::array_layout, typename beta_view_type::device_type, Kokkos::MemoryTraits<Kokkos::Unmanaged> > beta_view_type_Internal; //alpha_view_type_Internal alpha_c = alpha; //beta_view_type_Internal beta_c = beta; return Impl::SPMV_MV<typename alpha_view_type_Internal::value_type*, typename alpha_view_type_Internal::array_layout, typename alpha_view_type_Internal::device_type, typename alpha_view_type_Internal::memory_traits, typename AMatrix_Internal::value_type, typename AMatrix_Internal::ordinal_type, typename AMatrix_Internal::device_type, typename AMatrix_Internal::memory_traits, typename AMatrix_Internal::size_type, typename XVector_Internal::value_type**, typename XVector_Internal::array_layout, typename XVector_Internal::device_type, typename XVector_Internal::memory_traits, typename beta_view_type_Internal::value_type*, typename beta_view_type_Internal::array_layout, typename beta_view_type_Internal::device_type, typename beta_view_type_Internal::memory_traits, typename YVector_Internal::value_type**, typename YVector_Internal::array_layout, typename YVector_Internal::device_type, typename YVector_Internal::memory_traits>::spmv_mv(mode,alpha_in,A,x,beta_in,y); } }