Skip to content

CrsMatrix

brian-kelley edited this page Aug 19, 2021 · 21 revisions

CrsMatrix class

The CrsMatrix class provides a compressed sparse row implementation of a sparse matrix, as described, for example, in Saad (2nd ed.).

KokkosSparse::CrsMatrix API

template<class ScalarType,
         class OrdinalType,
         class Device,
         class MemoryTraits = void,
         class SizeType = typename Kokkos::ViewTraits<OrdinalType*, Device, void, void>::size_type>
class CrsMatrix {
public:
  //! Type of the matrix's execution space.
  typedef typename Device::execution_space execution_space;
  //! Type of the matrix's memory space.
  typedef typename Device::memory_space memory_space;
  //! Type of the matrix's device type.
  typedef Kokkos::Device<execution_space, memory_space> device_type;

  //! Type of each value in the matrix.
  typedef ScalarType value_type;
  //! Type of each (column) index in the matrix.
  typedef OrdinalType ordinal_type;
  typedef MemoryTraits memory_traits;
  /// \brief Type of each entry of the "row map."
  ///
  /// The "row map" corresponds to the \c ptr array of row offsets in
  /// compressed sparse row (CSR) storage.
  typedef SizeType size_type;

  //! Type of a host-memory mirror of the sparse matrix.
  typedef CrsMatrix<ScalarType, OrdinalType, host_mirror_space, MemoryTraits> HostMirror;
  //! Type of the graph structure of the sparse matrix.
  typedef Kokkos::StaticCrsGraph<ordinal_type, Kokkos::LayoutLeft, execution_space, memory_traits, size_type> StaticCrsGraphType;
  //! Type of the graph structure of the sparse matrix - consistent with Kokkos.
  typedef Kokkos::StaticCrsGraph<ordinal_type, Kokkos::LayoutLeft, execution_space, memory_traits, size_type> staticcrsgraph_type;
  //! Type of column indices in the sparse matrix.
  typedef typename staticcrsgraph_type::entries_type index_type;
  //! Const version of the type of column indices in the sparse matrix.
  typedef typename index_type::const_value_type const_ordinal_type;
  //! Nonconst version of the type of column indices in the sparse matrix.
  typedef typename index_type::non_const_value_type non_const_ordinal_type;
  //! Type of the "row map" (which contains the offset for each row's data).
  typedef typename staticcrsgraph_type::row_map_type row_map_type;
  //! Const version of the type of row offsets in the sparse matrix.
  typedef typename row_map_type::const_value_type const_size_type;
  //! Nonconst version of the type of row offsets in the sparse matrix.
  typedef typename row_map_type::non_const_value_type non_const_size_type;
  //! Kokkos Array type of the entries (values) in the sparse matrix.
  typedef Kokkos::View<value_type*, Kokkos::LayoutRight, device_type, MemoryTraits> values_type;
  //! Const version of the type of the entries in the sparse matrix.
  typedef typename values_type::const_value_type const_value_type;
  //! Nonconst version of the type of the entries in the sparse matrix.
  typedef typename values_type::non_const_value_type non_const_value_type;


  /// \name Storage of the actual sparsity structure and values.
  ///
  /// CrsMatrix uses the compressed sparse row (CSR) storage format to
  /// store the sparse matrix.  CSR is also called "compressed row
  /// storage"; hence the name, which it inherits from Tpetra and from
  /// Epetra before it.
  //@{
  //! The graph (sparsity structure) of the sparse matrix.
  staticcrsgraph_type graph;
  //! The 1-D array of values of the sparse matrix.
  values_type values;
  //@}

  /// \brief Default constructor; constructs an empty sparse matrix.
  KOKKOS_INLINE_FUNCTION
  CrsMatrix () :
    numCols_ (0)
  {}

  //! Copy constructor (shallow copy - views of B must be assignable to views of *this).
  template<typename InScalar,
           typename InOrdinal,
           class InDevice,
           class InMemTraits,
           typename InSizeType>
  KOKKOS_INLINE_FUNCTION
  CrsMatrix (const CrsMatrix<InScalar,InOrdinal,InDevice,InMemTraits,InSizeType> & B);

  //! Deep copy constructor (can cross spaces)
  template<typename InScalar, typename InOrdinal, typename InDevice, typename InMemTraits, typename InSizeType>
  CrsMatrix (const std::string&,
      const CrsMatrix<InScalar, InOrdinal, InDevice, InMemTraits, InSizeType>& mat_);

  /// \brief Construct with a graph that will be shared. graph_'s views must be assignable to this->graph's views.
  ///
  /// Allocate the values array for subsequent fill.
  template<typename InOrdinal, typename InLayout, typename InDevice, typename InMemTraits, typename InSizeType>
  CrsMatrix (const std::string& label,
             const Kokkos::StaticCrsGraph<InOrdinal, InLayout, InDevice, InMemTraits, InSizeType>& graph_);

  /// \brief Constructor that copies raw arrays of host data in
  ///   3-array CRS (compresed row storage) format.
  ///
  /// On input, the entries must be sorted by row. \c rowmap determines where each row begins
  /// and ends. For each entry k (0 <= k < annz), \c cols[k] gives the adjacent column,
  /// and \c val[k] gives the corresponding matrix value.
  ///
  /// This constructor is mainly useful for benchmarking or for
  /// reading the sparse matrix's data from a file.
  ///
  /// \param label [in] The sparse matrix's label.
  /// \param nrows [in] The number of rows.
  /// \param ncols [in] The number of columns.
  /// \param annz [in] The number of entries.
  /// \param val [in] The values.
  /// \param rowmap [in] The row offsets. The values/columns in row k begin at index
  ///   \c rowmap[k] and end at \c rowmap[k+1]-1 (inclusive). This means the array
  ///   must have length \c nrows+1.
  /// \param cols [in] The column indices. \c cols[k] is the column
  ///   index of entry k, with a corresponding value of \c val[k] .
  CrsMatrix (const std::string &label,
             OrdinalType nrows,
             OrdinalType ncols,
             size_type annz,
             ScalarType* val,
             OrdinalType* rowmap,
             OrdinalType* cols);

  /// \brief Constructor that accepts a row map, column indices, and
  ///   values.
  ///
  /// The matrix will store and use the row map, indices, and values
  /// directly (by view, not by deep copy).
  ///
  /// \param label [in] The sparse matrix's label.
  /// \param nrows [in] The number of rows.
  /// \param ncols [in] The number of columns.
  /// \param annz [in] The number of entries.
  /// \param vals [in/out] The entries.
  /// \param rows [in/out] The row map (containing the offsets to the
  ///   data in each row).
  /// \param cols [in/out] The column indices.
  CrsMatrix (const std::string& /* label */,
             const OrdinalType nrows,
             const OrdinalType ncols,
             const size_type annz,
             const values_type& vals,
             const row_map_type& rows,
             const index_type& cols);

  /// \brief Constructor that accepts a a static graph, and values.
  ///
  /// The matrix will store and use the row map, indices, and values
  /// directly (by view, not by deep copy), so they must be directly assignable to the views of *this.
  ///
  /// \param label [in] The sparse matrix's label.
  /// \param nrows [in] The number of rows.
  /// \param ncols [in] The number of columns.
  /// \param annz [in] The number of entries.
  /// \param vals [in/out] The entries.
  /// \param rows [in/out] The row map (containing the offsets to the
  ///   data in each row).
  /// \param cols [in/out] The column indices.
  template<typename InOrdinal, typename InLayout, typename InDevice, typename InMemTraits, typename InSizeType>
  CrsMatrix (const std::string&,
             const OrdinalType& ncols,
             const values_type& vals,
             const Kokkos::StaticCrsGraph<InOrdinal, InLayout, InDevice, InMemTraits, InSizeType>& graph_);

  //! Attempt to assign the input matrix to \c *this.
  template<typename aScalarType, typename aOrdinalType, class aDevice, class aMemoryTraits,typename aSizeType>
  CrsMatrix&
  operator= (const CrsMatrix<aScalarType, aOrdinalType, aDevice, aMemoryTraits, aSizeType>& mtx);

  //! The number of rows in the sparse matrix.
  KOKKOS_INLINE_FUNCTION ordinal_type numRows () const;

  //! The number of columns in the sparse matrix.
  KOKKOS_INLINE_FUNCTION ordinal_type numCols () const;

  //! The number of stored entries in the sparse matrix.
  KOKKOS_INLINE_FUNCTION size_type nnz () const;

Example

Location: example/wiki/sparse/KokkosSparse_wiki_crsmatrix.cpp

#include <sstream>

#include "Kokkos_Core.hpp"

#include "KokkosKernels_default_types.hpp"
#include "KokkosSparse_CrsMatrix.hpp"
#include "KokkosSparse_spmv.hpp"

using Scalar  = default_scalar;
using Ordinal = default_lno_t;
using Offset  = default_size_type;
using Layout  = default_layout;

int main(int argc, char* argv[]) {
  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 graph_type   = typename matrix_type::staticcrsgraph_type;
  using row_map_type = typename graph_type::row_map_type;
  using entries_type = typename graph_type::entries_type;
  using values_type  = typename matrix_type::values_type;

  const Scalar SC_ONE = Kokkos::ArithTraits<Scalar>::one();

  Ordinal numRows = 10;

  {
    const Offset numNNZ = 2 + (numRows - 2)*3 + 2;
    typename row_map_type::non_const_type row_map("row pointers", numRows + 1);
    typename entries_type::non_const_type entries("column indices", numNNZ);
    typename values_type::non_const_type values("values", numNNZ);

    {
      // Build the row pointers and store numNNZ                                                                                                                                        
      typename row_map_type::HostMirror row_map_h = Kokkos::create_mirror_view(row_map);
      for(Ordinal rowIdx = 1; rowIdx < numRows + 1; ++rowIdx) {
        if( (rowIdx == 1) || (rowIdx == numRows) ){
          row_map_h(rowIdx) = row_map_h(rowIdx - 1) + 2;
        } else {
          row_map_h(rowIdx) = row_map_h(rowIdx - 1) + 3;
        }
      }
      Kokkos::deep_copy(row_map, row_map_h);
      if(row_map_h(numRows) != numNNZ) {
        std::ostringstream error_msg;
        error_msg << "error: row_map(numRows) != numNNZ, row_map_h(numRows)=" << row_map_h(numRows)
                  << ", numNNZ=" << numNNZ;
          throw std::runtime_error(error_msg.str());
      }

      typename entries_type::HostMirror entries_h = Kokkos::create_mirror_view(entries);
      typename values_type::HostMirror values_h = Kokkos::create_mirror_view(values);
      for(Ordinal rowIdx = 0; rowIdx < numRows; ++rowIdx) {
        if(rowIdx == 0) {
          entries_h(row_map_h(rowIdx))     = rowIdx;
          entries_h(row_map_h(rowIdx) + 1) = rowIdx + 1;

          values_h(row_map_h(rowIdx))      = SC_ONE;
          values_h(row_map_h(rowIdx) + 1)  = -SC_ONE;
        } else if(rowIdx == numRows - 1) {
          entries_h(row_map_h(rowIdx))     = rowIdx - 1;
          entries_h(row_map_h(rowIdx) + 1) = rowIdx;

          values_h(row_map_h(rowIdx))      = -SC_ONE;
          values_h(row_map_h(rowIdx) + 1)  = SC_ONE;
        } else {
          entries_h(row_map_h(rowIdx))     = rowIdx - 1;
          entries_h(row_map_h(rowIdx) + 1) = rowIdx;
          entries_h(row_map_h(rowIdx) + 2) = rowIdx + 1;

          values_h(row_map_h(rowIdx))      = -SC_ONE;
          values_h(row_map_h(rowIdx) + 1)  = SC_ONE + SC_ONE;
          values_h(row_map_h(rowIdx) + 2)  = -SC_ONE;
        }
      }
      Kokkos::deep_copy(entries, entries_h);
      Kokkos::deep_copy(values, values_h);
    }

    graph_type myGraph(entries, row_map);
    matrix_type myMatrix("test matrix", numRows, values, myGraph);
  }

  Kokkos::finalize();

  return 0;
}

Sparse linear algebra functions that support a CrsMatrix interface

  1. SpMV
  2. SpADD
  3. SpGEMM

SAND2020-6386 W

Clone this wiki locally