KokkosSparse::spmv¶
Defined in header KokkosSparse_spmv.hpp
template <class ExecutionSpace, class Handle, class AlphaType, class AMatrix,
class XVector, class BetaType, class YVector>
void spmv(const ExecutionSpace& space, Handle* handle, const char mode[],
const AlphaType& alpha, const AMatrix& A, const XVector& x,
const BetaType& beta, const YVector& y);
template <class ExecutionSpace, class AlphaType, class AMatrix, class XVector,
class BetaType, class YVector,
typename = std::enable_if_t<Kokkos::is_execution_space_v<ExecutionSpace>>>
void spmv(const ExecutionSpace& space, const char mode[], const AlphaType& alpha,
const AMatrix& A, const XVector& x,
const BetaType& beta, const YVector& y);
template <class Handle, class AlphaType, class AMatrix, class XVector,
class BetaType, class YVector,
typename = std::enable_if_t<!Kokkos::is_execution_space<Handle>::value>>
void spmv(Handle* handle, const char mode[], const AlphaType& alpha,
const AMatrix& A, const XVector& x,
const BetaType& beta, const YVector& y);
template <class AlphaType, class AMatrix, class XVector, class BetaType, class YVector>
void spmv(const char mode[], const AlphaType& alpha, const AMatrix& A,
const XVector& x, const BetaType& beta, const YVector& y);
Kokkos sparse matrix-vector multiply. Computes y := alpha*Op(A)*x + beta*y, where Op(A) is controlled by mode (see below).
Scale the
y
vector bybeta
, and accumulate the result of the sparse matrix-vector product (A*x
), scaled byalpha
, intoy
.Calls 1. using an spmv handle with
SPMV_FAST_SETUP
algorithm for the handle parameter.Calls 1. using an instance of
Handle::ExecutionSpaceType
for the execution space parameter.Calls 1. using an spmv handle with
SPMV_FAST_SETUP
algorithm and an instance ofHandle::ExecutionSpaceType
for the handle and execution space parameters respectively.
Parameters¶
- space:
execution space instance.
- handle:
an spmv handle that stores multiple parameters for algorithm and third party libraries choices at run time.
- mode:
mode to be applied to
A
, possible values are “N” (normal), “T” (transpose), “C” (conjugate) and “H” (hermitian or conjugate-transpose).- alpha, beta:
scaling coefficents for the matrix
A
and left hand sidey
vector respectively.- A:
The matrix used to perform the matrix-vector product.
- x, y:
The right and left hand side vectors used as input and output respectively.
Type Requirements¶
AMatrix
must be either a KokkosSparse::CrsMatrix or a KokkosSparse::BsrMatrix and have a memory space compatible with theExecutionSpace
type:Kokkos::SpaceAccessibility<ExecutionSpace, typename AMatrix::memory_space>::accessible == true
ExecutionSpace must be a Kokkos execution space
XVector
andYVector
are two Kokkos Views of same rank, either rank 1 or rank 2 with memory spaces accessible fromExecutionSpace
andYVector
must store non-const data:Kokkos::is_view_v<XVector> == true && Kokkos::is_view_v<YVector> == true
XVector::rank() == YVector::rank() && (XVector::rank() == 1 || XVector::rank() == 2)
Kokkos::SpaceAccessibility<ExecutionSpace, typename XVector::memory_space>::accessible
Kokkos::SpaceAccessibility<ExecutionSpace, typename YVector::memory_space>::accessible
!std::is_const_v<typename YVector::value_type> == true
Example¶
#include "Kokkos_Core.hpp"
#include "KokkosKernels_default_types.hpp"
#include "KokkosSparse_CrsMatrix.hpp"
#include "KokkosSparse_spmv.hpp"
#include "KokkosKernels_Test_Structured_Matrix.hpp"
using Scalar = KokkosKernels::default_scalar;
using Ordinal = KokkosKernels::default_lno_t;
using Offset = KokkosKernels::default_size_type;
using Layout = KokkosKernels::default_layout;
template <class Yvector>
struct check_spmv_functor {
Yvector y;
const Scalar SC_ONE = Kokkos::ArithTraits<Scalar>::one();
check_spmv_functor(Yvector y_) : y(y_){};
KOKKOS_INLINE_FUNCTION
void operator()(const int i, Ordinal& update) const {
if (y(i) != (SC_ONE + SC_ONE)) {
++update;
}
}
};
int main() {
Kokkos::initialize();
using device_type =
typename Kokkos::Device<Kokkos::DefaultExecutionSpace, typename Kokkos::DefaultExecutionSpace::memory_space>;
using matrix_type = typename KokkosSparse::CrsMatrix<Scalar, Ordinal, device_type, void, Offset>;
using values_type = typename matrix_type::values_type;
int return_value = 0;
{
const Scalar SC_ONE = Kokkos::ArithTraits<Scalar>::one();
// The mat_structure view is used to generate a matrix using
// finite difference (FD) or finite element (FE) discretization
// on a cartesian grid.
// Each row corresponds to an axis (x, y and z)
// In each row the first entry is the number of grid point in
// that direction, the second and third entries are used to apply
// BCs in that direction, BC=0 means Neumann BC is applied,
// BC=1 means Dirichlet BC is applied by zeroing out the row and putting
// one on the diagonal.
Kokkos::View<Ordinal* [3], Kokkos::HostSpace> mat_structure("Matrix Structure", 2);
mat_structure(0, 0) = 10; // Request 10 grid point in 'x' direction
mat_structure(0, 1) = 0; // Add BC to the left
mat_structure(0, 2) = 0; // Add BC to the right
mat_structure(1, 0) = 10; // Request 10 grid point in 'y' direction
mat_structure(1, 1) = 0; // Add BC to the bottom
mat_structure(1, 2) = 0; // Add BC to the top
matrix_type myMatrix = Test::generate_structured_matrix2D<matrix_type>("FD", mat_structure);
const Ordinal numRows = myMatrix.numRows();
const Scalar alpha = SC_ONE;
const Scalar beta = SC_ONE;
typename values_type::non_const_type x("lhs", numRows);
typename values_type::non_const_type y("rhs", numRows);
Kokkos::deep_copy(x, SC_ONE);
Kokkos::deep_copy(y, SC_ONE + SC_ONE);
KokkosSparse::spmv("N", alpha, myMatrix, x, beta, y);
Ordinal count_errors = 0;
check_spmv_functor<values_type> check_spmv(y);
Kokkos::parallel_reduce(Kokkos::RangePolicy<Ordinal>(0, numRows), check_spmv, count_errors);
if (count_errors > 0) {
return_value = 1;
std::cout << "Found " << count_errors << " errors in y vector!" << std::endl;
} else {
std::cout << "spmv was performed correctly: y = beta*y + alpha*A*x" << std::endl;
}
}
Kokkos::finalize();
return return_value;
}