Discontinuous Galerkin Library
#include "dg/algorithm.h"
Loading...
Searching...
No Matches
dg::SparseMatrix< Index, Value, Vector > Struct Template Reference

A CSR formatted sparse matrix. More...

Public Types

using policy = dg::get_execution_policy<Vector<Value>>
 Execution policy of the matrix.
 
using index_type = Index
 The index type (on GPU must be either int or long)
 
using value_type = Value
 The value type (on GPU must be either float or double)
 
template<class OtherMatrix >
using enable_if_serial = std::enable_if_t<std::is_same_v<typename OtherMatrix::policy, SerialTag>, OtherMatrix>
 A static guard to allow certain members only on host (for serial execution)
 

Public Member Functions

 SparseMatrix ()=default
 Empty matrix.
 
 SparseMatrix (size_t num_rows, size_t num_cols, const Vector< Index > &row_offsets, const Vector< Index > &column_indices, const Vector< Value > &values)
 Directly construct from given vectors.
 
template<class I , class V , template< class > class Vec>
 SparseMatrix (const SparseMatrix< I, V, Vec > &src)
 Copy construct from differen type.
 
void setFromCoo (size_t num_rows, size_t num_cols, const Vector< Index > &row_indices, const Vector< Index > &column_indices, const Vector< Value > &values, bool sort=false)
 Set csr values from coo formatted sparse matrix.
 
void set (size_t num_rows, size_t num_cols, const Vector< Index > &row_offsets, const Vector< Index > column_indices, const Vector< Value > &values, bool sort=false)
 Set csr values directly.
 
void sort_indices ()
 Sort by row and column.
 
size_t total_num_rows () const
 Alias for num_rows.
 
size_t total_num_cols () const
 Alias for num_cols.
 
size_t num_rows () const
 Number of rows in matrix.
 
size_t num_cols () const
 Number of columns in matrix.
 
size_t num_vals () const
 Alias for num_nnz.
 
size_t num_nnz () const
 Number of nonzero elements in matrix.
 
size_t num_entries () const
 Alias for num_nnz.
 
const Vector< Index > & row_offsets () const
 Read row_offsets vector.
 
const Vector< Index > & column_indices () const
 Read column indices vector.
 
const Vector< Value > & values () const
 Read values vector.
 
Vector< Value > & values ()
 Change values vector.
 
SparseMatrix transpose () const
 Transposition.
 
template<class OtherMatrix = SparseMatrix>
std::enable_if_t< dg::has_policy_v< OtherMatrix, SerialTag >, bool > operator!= (const SparseMatrix &rhs) const
 Two Matrices are considered equal if elements and sparsity pattern are equal.
 
template<class OtherMatrix = SparseMatrix>
std::enable_if_t< dg::has_policy_v< OtherMatrix, SerialTag >, bool > operator== (const SparseMatrix &rhs) const
 Two Matrices are considered equal if elements and sparsity pattern are equal.
 
SparseMatrix operator- () const
 Negate.
 
template<class OtherMatrix = SparseMatrix>
enable_if_serial< OtherMatrix > & operator+= (const SparseMatrix &op)
 Add.
 
template<class OtherMatrix = SparseMatrix>
enable_if_serial< OtherMatrix > & operator-= (const SparseMatrix &op)
 subtract
 
SparseMatrixoperator*= (const Value &value)
 scalar multiply
 

Friends

template<class I , class V , template< class > class Vec>
class SparseMatrix
 Enable copy constructor from foreign types.
 
template<class OtherMatrix = SparseMatrix>
enable_if_serial< OtherMatrix > operator+ (const SparseMatrix &lhs, const SparseMatrix &rhs)
 add
 
template<class OtherMatrix = SparseMatrix>
enable_if_serial< OtherMatrix > operator- (const SparseMatrix &lhs, const SparseMatrix &rhs)
 subtract
 
template<class OtherMatrix = SparseMatrix>
enable_if_serial< OtherMatrix > operator* (const Value &value, const SparseMatrix &rhs)
 scalar multiplication
 
template<class OtherMatrix = SparseMatrix>
enable_if_serial< OtherMatrix > operator* (const SparseMatrix &lhs, const Value &value)
 scalar multiplication
 
template<class OtherMatrix = SparseMatrix>
enable_if_serial< OtherMatrix > operator* (const SparseMatrix &lhs, const SparseMatrix &rhs)
 matrix-matrix multiplication \( C = A*B\)
 
template<class ContainerType , class = std::enable_if_t < dg::has_policy_v<ContainerType, policy> and dg::is_vector_v<ContainerType> >>
ContainerType operator* (const SparseMatrix &S, const ContainerType &x)
 matrix-vector multiplication \( y = S x\)
 
template<class Ostream , class OtherMatrix = SparseMatrix>
std::enable_if_t< dg::has_policy_v< OtherMatrix, SerialTag >, Ostream > & operator<< (Ostream &os, const SparseMatrix &mat)
 puts a matrix linewise in output stream
 

Detailed Description

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
struct dg::SparseMatrix< Index, Value, Vector >

A CSR formatted sparse matrix.

This class was designed to replace our dependency on cusp::csr_matrix. On the host arithmetic operators like + and * are overloaded allowing for expressive code to concisely assemble the matrix:

// 1 0 0 2
// 2 0 5 0
// 0 4 0 0
// 0 1 1 0
unsigned num_rows = 4, num_cols = 4;
std::vector<int> rows = {0,2,4,5,7}, cols = {0,3,0,2,1,1,2};
std::vector<double> vals = {1,2,2,5,4,1,1};
dg::SparseMatrix<int,double,std::vector> A ( num_rows, num_cols, rows, cols, vals);
//
// 2 0 0 0
// 0 3 3 5
// 0 0 4 0
// 0 0 0 5
// 1 0 0 2
num_rows = 5, num_cols = 4;
rows = {0,1,4,5,6,8};
cols = {0,1,2,3,2,3,0,3};
vals = {2,3,3,5,4,5,1,2};
dg::SparseMatrix<int,double,std::vector> B ( num_rows, num_cols, rows, cols, vals);
//
// 3 4 0 0
// 10 16.5 13.5 8.5
// 0 20 2 4
// 10 0 0 2.5
// 5.5 2 0 1
auto C = B*A.transpose()+0.5*B;
//
CHECK( C.num_rows() == 5);
CHECK( C.num_cols() == 4);
CHECK( C.row_offsets() == std::vector<int>{ 0,2,6,9,11,14});
CHECK( C.column_indices() == std::vector<int>{ 0,1,0,1,2,3,1,2,3,0,3,0,1,3});
CHECK( C.values() == std::vector<double>{ 3, 4, 10, 16.5, 13.5, 8.5, 20, 2, 4, 10, 2.5, 5.5, 2, 1});
//
// Matrix-vector multiplication can be done on device
std::vector<double> v = { 2,4,6,8}, w = {1,2,3,4,5};
thrust::device_vector<double> dv( v.begin(), v.end()), dw( w.begin(), w.end());
// dw = dC * dv + 0.5 dw
dg::blas2::gemv( 1., dC, dv, 0.5, dw);
//
thrust::copy( dw.begin(), dw.end(), w.begin());
CHECK( w == std::vector{22.5,236.,125.5,42.,29.5});

On the device like OpenMP or GPU the only currently allowed operations are transpose and the matrix-vector multiplications through dg::blas2::symv (and its aliases dg::blas2::gemv and dg::apply). We use the cusparse library to dispatch matrix-vector multiplication on the GPU.

See also
The CSR format is nicely explained at the cusparse documentation We use the zero-base index
Template Parameters
IndexThe index type (on GPU must be either int or long)
ValueThe value type (on GPU must be either float or double)
VectorThe vector class to store indices and values (typically thrust::host_vector or thrust::device_vector)
See also
IHMatrix, IDMatrix

Member Typedef Documentation

◆ enable_if_serial

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
template<class OtherMatrix >
using dg::SparseMatrix< Index, Value, Vector >::enable_if_serial = std::enable_if_t<std::is_same_v<typename OtherMatrix::policy, SerialTag>, OtherMatrix>

A static guard to allow certain members only on host (for serial execution)

◆ index_type

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
using dg::SparseMatrix< Index, Value, Vector >::index_type = Index

The index type (on GPU must be either int or long)

◆ policy

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
using dg::SparseMatrix< Index, Value, Vector >::policy = dg::get_execution_policy<Vector<Value>>

Execution policy of the matrix.

◆ value_type

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
using dg::SparseMatrix< Index, Value, Vector >::value_type = Value

The value type (on GPU must be either float or double)

Constructor & Destructor Documentation

◆ SparseMatrix() [1/3]

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
dg::SparseMatrix< Index, Value, Vector >::SparseMatrix ( )
default

Empty matrix.

Set values using either setFromCoo or set members

◆ SparseMatrix() [2/3]

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
dg::SparseMatrix< Index, Value, Vector >::SparseMatrix ( size_t num_rows,
size_t num_cols,
const Vector< Index > & row_offsets,
const Vector< Index > & column_indices,
const Vector< Value > & values )
inline

Directly construct from given vectors.

// 1 0 0 2 3
// 2 0 5 0 0
// 0 4 0 0 1
unsigned num_rows = 3, num_cols = 5;
std::vector<int> rows = {0,3,5,7}, cols = {0,3,4,0,2,1,4};
std::vector<double> vals = {1,2,3,2,5,4,1};
dg::SparseMatrix<int,double,std::vector> A ( num_rows, num_cols, rows, cols, vals);
//
CHECK( A.num_rows() == num_rows);
CHECK( A.num_cols() == num_cols);
CHECK( A.num_vals() == vals.size());
CHECK( A.row_offsets() == rows);
CHECK( A.column_indices() == cols);
CHECK( A.values() == vals);
Parameters
num_rowsNumber of rows in the matrix
num_colsNumber of columns in the matrix
row_offsetsVector of size num_rows+1 representing the starting position of each row in the column_indices and values arrays. row_offsets.back() equals the number of non-zero elements in the matrix
column_indicesVector of size row_offsets.back() containing column indices. The column indices may be unsorted within each row and should be unique. If duplicates exist symv may not be correct (from cusparse).
valuesVector of size row_offsets.back() containing nonzero values

◆ SparseMatrix() [3/3]

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
template<class I , class V , template< class > class Vec>
dg::SparseMatrix< Index, Value, Vector >::SparseMatrix ( const SparseMatrix< I, V, Vec > & src)
inline

Copy construct from differen type.

Typically used to transfer a matrix from host to device

// 1 0 0 2 3
// 2 0 5 0 0
// 0 4 0 0 1
unsigned num_rows = 3, num_cols = 5;
// unsorted!!
std::vector<int> rows = {0,3,5,7}, cols = {0,4,3,0,2,1,4};
std::vector<double> vals = {1,3,2,2,5,4,1};
dg::SparseMatrix<int,double,thrust::host_vector> A ( num_rows, num_cols, rows, cols, vals);
Parameters
srcCopy the matrix

Member Function Documentation

◆ column_indices()

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
const Vector< Index > & dg::SparseMatrix< Index, Value, Vector >::column_indices ( ) const
inline

Read column indices vector.

Returns
column indices

◆ num_cols()

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
size_t dg::SparseMatrix< Index, Value, Vector >::num_cols ( ) const
inline

Number of columns in matrix.

◆ num_entries()

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
size_t dg::SparseMatrix< Index, Value, Vector >::num_entries ( ) const
inline

Alias for num_nnz.

◆ num_nnz()

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
size_t dg::SparseMatrix< Index, Value, Vector >::num_nnz ( ) const
inline

Number of nonzero elements in matrix.

◆ num_rows()

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
size_t dg::SparseMatrix< Index, Value, Vector >::num_rows ( ) const
inline

Number of rows in matrix.

◆ num_vals()

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
size_t dg::SparseMatrix< Index, Value, Vector >::num_vals ( ) const
inline

Alias for num_nnz.

◆ operator!=()

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
template<class OtherMatrix = SparseMatrix>
std::enable_if_t< dg::has_policy_v< OtherMatrix, SerialTag >, bool > dg::SparseMatrix< Index, Value, Vector >::operator!= ( const SparseMatrix< Index, Value, Vector > & rhs) const
inline

Two Matrices are considered equal if elements and sparsity pattern are equal.

Parameters
rhsMatrix to be compared to this
Returns
true if rhs does not equal this

◆ operator*=()

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
SparseMatrix & dg::SparseMatrix< Index, Value, Vector >::operator*= ( const Value & value)
inline

scalar multiply

Parameters
value
Returns

◆ operator+=()

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
template<class OtherMatrix = SparseMatrix>
enable_if_serial< OtherMatrix > & dg::SparseMatrix< Index, Value, Vector >::operator+= ( const SparseMatrix< Index, Value, Vector > & op)
inline

Add.

Parameters
op
Returns

◆ operator-()

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
SparseMatrix dg::SparseMatrix< Index, Value, Vector >::operator- ( ) const
inline

Negate.

Returns

◆ operator-=()

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
template<class OtherMatrix = SparseMatrix>
enable_if_serial< OtherMatrix > & dg::SparseMatrix< Index, Value, Vector >::operator-= ( const SparseMatrix< Index, Value, Vector > & op)
inline

subtract

Parameters
op
Returns

◆ operator==()

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
template<class OtherMatrix = SparseMatrix>
std::enable_if_t< dg::has_policy_v< OtherMatrix, SerialTag >, bool > dg::SparseMatrix< Index, Value, Vector >::operator== ( const SparseMatrix< Index, Value, Vector > & rhs) const
inline

Two Matrices are considered equal if elements and sparsity pattern are equal.

Parameters
rhsMatrix to be compared to this
Returns
true if rhs equals this

◆ row_offsets()

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
const Vector< Index > & dg::SparseMatrix< Index, Value, Vector >::row_offsets ( ) const
inline

Read row_offsets vector.

Returns
row_offsets

◆ set()

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
void dg::SparseMatrix< Index, Value, Vector >::set ( size_t num_rows,
size_t num_cols,
const Vector< Index > & row_offsets,
const Vector< Index > column_indices,
const Vector< Value > & values,
bool sort = false )
inline

Set csr values directly.

// 0 2 0 0 4
// 0 1 2 0 0
// 0 0 0 0 0
num_rows = 3, num_cols = 5;
rows = {0,2,4,4}, cols = {1,4,1,2};
vals = {2,4,1,2};
D.set( num_rows, num_cols, rows, cols, vals);
Parameters
num_rowsNumber of rows in the matrix
num_colsNumber of columns in the matrix
row_offsetsVector of size num_rows+1 representing the starting position of each row in the column_indices and values arrays. row_offsets.back() equals the number of non-zero elements in the matrix
column_indicesVector of size row_offsets.back() containing column indices. The column indices may be unsorted within each row and should be unique. If duplicates exist symv may not be correct (from cusparse).
valuesVector of size row_offsets.back() containing nonzero values
sortIf true the given vectors are sorted by column_indices in each row. It is allowed to have unsorted column indices in each row so sorting is not strictly necessary. It may (or may not) have an effect on performance.

◆ setFromCoo()

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
void dg::SparseMatrix< Index, Value, Vector >::setFromCoo ( size_t num_rows,
size_t num_cols,
const Vector< Index > & row_indices,
const Vector< Index > & column_indices,
const Vector< Value > & values,
bool sort = false )
inline

Set csr values from coo formatted sparse matrix.

// 1 0 0 2 3
// 2 0 5 0 0
// 0 4 0 0 1
unsigned num_rows = 3, num_cols = 5;
std::vector<int> rows = {2,2,0,0,0,1,1}, cols = {4,1,4,3,0,2,0};
std::vector<double> vals = {1,4, 3,2,1,5,2};
A.setFromCoo( num_rows, num_cols, rows, cols, vals, true);
CHECK( A.row_offsets() == std::vector{0,3,5,7});
CHECK( A.column_indices() == std::vector{0,3,4,0,2,1,4});
CHECK( A.values() == std::vector<double>{1,2,3,2,5,4,1});
Note
May be unsorted, in which case the sort parameter should be set to true; if duplicates exist symv may not be correct (from cusparse)
Parameters
num_rowsNumber of rows in the matrix
num_colsNumber of columns in the matrix
row_indicesContains row indices of the corresponding elements in the values vector
column_indicesVector of size row_indices.size()() containing column indices.
valuesVector of size row_indices.size() containing nonzero values
sortIf true the given vectors are sorted by row and column before converted to the csr format. Per default we assume that the values are sorted by row (not necessarily by column). In this case there is no need to sort the indices, which may be somewhat expensive. If the row indices are unsorted however, sort must be set to true otherwise the coo2csr conversion will fail.

◆ sort_indices()

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
void dg::SparseMatrix< Index, Value, Vector >::sort_indices ( )
inline

Sort by row and column.

Sort is somewhat expensive and it is allowed to have unsorted column indices (at least in cusparse). Sorting may or may not have an influence on performance. Never sort a stencil for dg::blas2::stencil.

◆ total_num_cols()

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
size_t dg::SparseMatrix< Index, Value, Vector >::total_num_cols ( ) const
inline

Alias for num_cols.

◆ total_num_rows()

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
size_t dg::SparseMatrix< Index, Value, Vector >::total_num_rows ( ) const
inline

Alias for num_rows.

◆ transpose()

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
SparseMatrix dg::SparseMatrix< Index, Value, Vector >::transpose ( ) const
inline

Transposition.

The transpose is sorted even if the original is not

Returns
A newly generated SparseMatrix containing the transpose.

◆ values() [1/2]

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
Vector< Value > & dg::SparseMatrix< Index, Value, Vector >::values ( )
inline

Change values vector.

Note
The reason why values can be changed directly while row_offsets and column_indices cannot, is that changing the values does not influence the performance cache, while changing the sparsity pattern through row_offsets and column_indices does
Returns
Values array reference

◆ values() [2/2]

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
const Vector< Value > & dg::SparseMatrix< Index, Value, Vector >::values ( ) const
inline

Read values vector.

Returns
values

Friends And Related Symbol Documentation

◆ operator* [1/4]

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
template<class OtherMatrix = SparseMatrix>
enable_if_serial< OtherMatrix > operator* ( const SparseMatrix< Index, Value, Vector > & lhs,
const SparseMatrix< Index, Value, Vector > & rhs )
friend

matrix-matrix multiplication \( C = A*B\)

Parameters
lhs
rhs
Returns
multiplication (sorted even if lhs and rhs are not)

◆ operator* [2/4]

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
template<class OtherMatrix = SparseMatrix>
enable_if_serial< OtherMatrix > operator* ( const SparseMatrix< Index, Value, Vector > & lhs,
const Value & value )
friend

scalar multiplication

Simply multiply values array by given value

Parameters
lhs
value
Returns

◆ operator* [3/4]

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
template<class ContainerType , class = std::enable_if_t < dg::has_policy_v<ContainerType, policy> and dg::is_vector_v<ContainerType> >>
ContainerType operator* ( const SparseMatrix< Index, Value, Vector > & S,
const ContainerType & x )
friend

matrix-vector multiplication \( y = S x\)

Works if ContainerType has the same execution policy as the SparseMatrix

auto mat = dg::SquareMatrix<double>({0,1,2, 3,4,5, 6,7,8});
std::vector<double> vec = {1,2,3};
std::vector<double> res = mat*vec;
CHECK( res == std::vector<double>{8, 26, 44});
Parameters
SMatrix
xVector
Returns
Vector

◆ operator* [4/4]

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
template<class OtherMatrix = SparseMatrix>
enable_if_serial< OtherMatrix > operator* ( const Value & value,
const SparseMatrix< Index, Value, Vector > & rhs )
friend

scalar multiplication

Simply multiply values array by given value

Parameters
value
rhs
Returns

◆ operator+

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
template<class OtherMatrix = SparseMatrix>
enable_if_serial< OtherMatrix > operator+ ( const SparseMatrix< Index, Value, Vector > & lhs,
const SparseMatrix< Index, Value, Vector > & rhs )
friend

add

Parameters
lhs
rhs
Returns
addition (sorted even if lhs and rhs are not)

◆ operator-

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
template<class OtherMatrix = SparseMatrix>
enable_if_serial< OtherMatrix > operator- ( const SparseMatrix< Index, Value, Vector > & lhs,
const SparseMatrix< Index, Value, Vector > & rhs )
friend

subtract

Parameters
lhs
rhs
Returns
subtraction (sorted even if lhs and rhs are not)

◆ operator<<

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
template<class Ostream , class OtherMatrix = SparseMatrix>
std::enable_if_t< dg::has_policy_v< OtherMatrix, SerialTag >, Ostream > & operator<< ( Ostream & os,
const SparseMatrix< Index, Value, Vector > & mat )
friend

puts a matrix linewise in output stream

Template Parameters
OstreamThe stream e.g. std::cout
Parameters
osthe outstream
matthe matrix to output
Returns
the outstream

◆ SparseMatrix

template<class Index = int, class Value = double, template< class > class Vector = thrust::host_vector>
template<class I , class V , template< class > class Vec>
friend class SparseMatrix
friend

Enable copy constructor from foreign types.


The documentation for this struct was generated from the following file: