6#include <thrust/sort.h>
7#include <thrust/gather.h>
8#include <thrust/sequence.h>
9#include <thrust/binary_search.h>
14#include "blas2_stencil.h"
17#if THRUST_DEVICE_SYSTEM==THRUST_DEVICE_SYSTEM_CUDA
19#elif THRUST_DEVICE_SYSTEM==THRUST_DEVICE_SYSTEM_OMP
28template<
class I0,
class I1>
35 dg::blas2::detail::doParallelFor_dispatch( policy(), csr.size()-1,
36 []
DG_DEVICE(
unsigned i,
const I0_t* csr_ptr, I1_t* coo_ptr)
38 for (
int jj = csr_ptr[i]; jj < csr_ptr[i+1]; jj++)
41 thrust::raw_pointer_cast(csr.data()),
42 thrust::raw_pointer_cast(coo.data()));
52template<
class I0,
class I1>
57 thrust::lower_bound( coo.begin(), coo.end(),
66I
coo2csr(
unsigned num_rows,
const I& coo)
100template<
class Index =
int,
class Value =
double,
template<
class>
class Vector = thrust::host_vector>
108 template<
class OtherMatrix>
109 using enable_if_serial = std::enable_if_t<std::is_same_v<typename OtherMatrix::policy, SerialTag>, OtherMatrix>;
139 template<
class I,
class V,
template<
class>
class Vec>
148 template<
class I,
class V,
template<
class>
class Vec>
150 : m_num_rows( src.m_num_rows), m_num_cols( src.m_num_cols), m_row_offsets(
151 src.m_row_offsets), m_cols( src.m_cols), m_vals( src.m_vals)
179 if( row_indices.size() !=
values.size())
181 <<row_indices.size()<<
" not equal to values size "<<
values.size()<<
"\n");
190 m_vals.resize(
values.size());
194 Vector<Index> trows( row_indices);
196 Vector<Index> p( row_indices.size());
197 thrust::sequence( p.begin(), p.end());
199 thrust::sort_by_key( tcols.begin(), tcols.end(), p.begin());
201 thrust::gather( p.begin(), p.end(), row_indices.begin(), trows.begin());
203 thrust::stable_sort_by_key( trows.begin(), trows.end(), p.begin());
207 thrust::gather( p.begin(), p.end(),
column_indices.begin(), m_cols.begin());
208 thrust::gather( p.begin(), p.end(),
values.begin(), m_vals.begin());
214 thrust::copy(
values.begin(),
values.end(), m_vals.begin());
260 if( m_num_rows != m_row_offsets.size()-1)
262 <<m_row_offsets.size()<<
" but num_rows is "<<m_num_rows<<
"\n");
263 if( m_cols.size() != m_vals.size())
265 <<m_cols.size()<<
" not equal to values size "<<m_vals.size()<<
"\n");
269 Vector<Index> cols = m_cols;
270 Vector<Value> vals = m_vals;
271 setFromCoo( m_num_rows, m_num_cols, rows, cols, vals,
true);
280 size_t&
num_rows() { m_cache.forget();
return m_num_rows;}
282 size_t&
num_cols() { m_cache.forget();
return m_num_cols;}
291 size_t num_nnz()
const {
return m_vals.size();}
298 const Vector<Index> &
row_offsets()
const {
return m_row_offsets;}
306 const Vector<Value> &
values()
const {
return m_vals;}
325 return m_row_offsets;
355 Vector<Value> &
values() {
return m_vals;}
358 template<
class value_type>
361 const auto* row_ptr = thrust::raw_pointer_cast( &m_row_offsets[0]);
362 const auto* col_ptr = thrust::raw_pointer_cast( &m_cols[0]);
363 const auto* val_ptr = thrust::raw_pointer_cast( &m_vals[0]);
365 m_vals.size(), row_ptr, col_ptr, val_ptr, alpha, beta, x,
y);
367#if THRUST_DEVICE_SYSTEM==THRUST_DEVICE_SYSTEM_CUDA
368 template<
class value_type>
371 const auto* row_ptr = thrust::raw_pointer_cast( &m_row_offsets[0]);
372 const auto* col_ptr = thrust::raw_pointer_cast( &m_cols[0]);
373 const auto* val_ptr = thrust::raw_pointer_cast( &m_vals[0]);
375 m_vals.size(), row_ptr, col_ptr, val_ptr, alpha, beta, x,
y);
377#elif THRUST_DEVICE_SYSTEM==THRUST_DEVICE_SYSTEM_OMP
378 template<
class value_type>
381 const auto* row_ptr = thrust::raw_pointer_cast( &m_row_offsets[0]);
382 const auto* col_ptr = thrust::raw_pointer_cast( &m_cols[0]);
383 const auto* val_ptr = thrust::raw_pointer_cast( &m_vals[0]);
384 if( !omp_in_parallel())
389 m_vals.size(), row_ptr, col_ptr, val_ptr, alpha, beta, x,
y);
394 m_vals.size(), row_ptr, col_ptr, val_ptr, alpha, beta, x,
y);
412 o.m_num_rows = m_num_cols;
413 o.m_num_cols = m_num_rows;
415 Vector<Index> rows( m_cols.begin(), m_cols.end());
416 Vector<Index> p( rows.size());
417 thrust::sequence( p.begin(), p.end());
419 thrust::stable_sort_by_key( rows.begin(), rows.end(), p.begin());
420 o.m_row_offsets.resize( o.m_num_rows+1);
423 o.m_cols.resize( cols.size());
424 o.m_vals.resize( m_vals.size());
426 thrust::gather( p.begin(), p.end(), cols.begin(), o.m_cols.begin());
427 thrust::gather( p.begin(), p.end(), m_vals.begin(), o.m_vals.begin());
441 template<
class OtherMatrix = SparseMatrix>
443 if(
rhs.m_num_rows != m_num_rows)
445 if(
rhs.m_num_cols != m_num_cols)
447 for(
size_t i = 0; i < m_row_offsets.size(); i++)
448 if( m_row_offsets[i] !=
rhs.m_row_offsets[i])
450 for(
size_t i = 0; i < m_cols.size(); i++)
451 if( m_cols[i] !=
rhs.m_cols[i])
453 for(
size_t i = 0; i < m_vals.size(); i++)
454 if( m_vals[i] !=
rhs.m_vals[i])
464 template<
class OtherMatrix = SparseMatrix>
474 return (*
this)*(Value(-1));
483 template<
class OtherMatrix = SparseMatrix>
496 template<
class OtherMatrix = SparseMatrix>
499 *
this = *
this + (-op);
511 dg::blas2::detail::doParallelFor_dispatch(
policy(), m_vals.size(),
512 [value]
DG_DEVICE(
unsigned i, Value* val_ptr)
516 thrust::raw_pointer_cast(m_vals.data()));
527 template<
class OtherMatrix = SparseMatrix>
530 if(
lhs.m_num_cols !=
rhs.m_num_cols)
532 <<
lhs.m_num_cols<<
" columns to matrix with "<<
rhs.m_num_cols<<
" columns\n");
533 if(
lhs.m_num_rows !=
rhs.m_num_rows)
535 <<
lhs.m_num_rows<<
" rows to matrix with "<<
rhs.m_num_rows<<
" rows\n");
540 lhs.m_row_offsets,
lhs.m_cols,
lhs.m_vals,
541 rhs.m_row_offsets,
rhs.m_cols,
rhs.m_vals,
555 template<
class OtherMatrix = SparseMatrix>
571 template<
class OtherMatrix = SparseMatrix>
588 template<
class OtherMatrix = SparseMatrix>
602 template<
class OtherMatrix = SparseMatrix>
605 if(
lhs.m_num_cols !=
rhs.m_num_rows)
607 <<
lhs.m_num_cols<<
" columns with matrix with "<<
rhs.m_num_rows<<
" rows\n");
613 lhs.m_row_offsets,
lhs.m_cols,
lhs.m_vals,
614 rhs.m_row_offsets,
rhs.m_cols,
rhs.m_vals,
631 template<
class ContainerType,
class = std::enable_if_t < dg::has_policy_v<ContainerType, policy> and dg::is_vector_v<ContainerType> >>
634 if( S.m_num_cols !=
x.size())
636 <<S.m_num_cols<<
" columns with vector with "<<
x.size()<<
" rows\n");
638 ContainerType out(S.m_num_rows);
639 const Value* RESTRICT x_ptr = thrust::raw_pointer_cast(
x.data());
640 Value* RESTRICT y_ptr = thrust::raw_pointer_cast( out.data());
652 template<
class Ostream,
class OtherMatrix = SparseMatrix>
653 friend std::enable_if_t<dg::has_policy_v<OtherMatrix, SerialTag>, Ostream>
656 os <<
"Sparse Matrix with "<<mat.m_num_rows<<
" rows and "<<mat.m_num_cols<<
" columns\n";
657 os <<
" # non-zeroes "<<mat.m_vals.size()<<
"\n";
658 for (
int i = 0; i < (int)mat.m_num_rows; i++)
660 for (
int pB = mat.m_row_offsets[i]; pB < mat.m_row_offsets[i+1]; pB++)
662 os <<
"("<<i<<
","<<mat.m_cols[pB]<<
","<<mat.m_vals[pB]<<
") ";
673#if THRUST_DEVICE_SYSTEM==THRUST_DEVICE_SYSTEM_CUDA
675#elif THRUST_DEVICE_SYSTEM==THRUST_DEVICE_SYSTEM_OMP
682 size_t m_num_rows, m_num_cols;
683 Vector<Index> m_row_offsets, m_cols;
684 Vector<Value> m_vals;
696template<
class Sparse>
697void print(
const Sparse& m, std::ostream& out = std::cout )
699 out <<
"Sparse matrix <" <<
m.num_rows() <<
", " <<
m.num_cols() <<
"> with "<<
m.num_nnz() <<
" entries\n";
701 for(
unsigned u=0; u<
m.num_nnz(); u++)
703 out <<
" "<< std::setw(14) << row_indices[u];
704 out <<
" "<< std::setw(14) <<
m.column_indices()[u];
705 out <<
" "<< std::setw(14) <<
"("<<
m.values()[u]<<
")\n";
711template <
class I,
class T,
template<
class>
class V>
class intended for the use in throw statements
Definition exceptions.h:83
small class holding a stringstream
Definition exceptions.h:29
Error classes or the dg library.
#define _ping_
Definition exceptions.h:12
void rhs(double t, double, double &yp)
void symv(MatrixType &&M, const ContainerType1 &x, ContainerType2 &y)
Definition blas2.h:331
typename TensorTraits< std::decay_t< Vector > >::execution_policy get_execution_policy
Definition tensor_traits.h:49
constexpr bool has_policy_v
Utility typedef.
Definition predicate.h:86
typename TensorTraits< std::decay_t< Vector > >::value_type get_value_type
Definition tensor_traits.h:45
#define DG_DEVICE
Expands to __host__ __device__ if compiled with nvcc else is empty.
Definition dg_doc.h:378
double lhs(double x, double y)
void spadd_cpu_kernel(size_t B_num_rows, size_t B_num_cols, const I &B_pos, const I &B_idx, const V &B_val, const I &C_pos, const I &C_idx, const V &C_val, I &A_pos, I &A_idx, V &A_val)
Definition sparsematrix_cpu.h:101
void spgemm_cpu_kernel(size_t B_num_rows, size_t, size_t C_num_cols, const I &B_pos, const I &B_idx, const V &B_val, const I &C_pos, const I &C_idx, const V &C_val, I &A_pos, I &A_idx, V &A_val)
Definition sparsematrix_cpu.h:20
void coo2csr_inline(const I0 &coo, I1 &csr)
Definition sparsematrix.h:53
void spmv_gpu_kernel(CSRCache_gpu &cache, size_t A_num_rows, size_t A_num_cols, size_t A_nnz, const I *A_pos, const I *A_idx, const V *A_val, value_type alpha, value_type beta, const C1 *x_ptr, C2 *y_ptr)
Definition sparsematrix_gpu.cuh:190
void csr2coo_inline(const I0 &csr, I1 &coo)
Definition sparsematrix.h:29
I csr2coo(const I &csr)
Definition sparsematrix.h:45
I coo2csr(unsigned num_rows, const I &coo)
Definition sparsematrix.h:66
void spmv_cpu_kernel(CSRCache_cpu &, size_t A_num_rows, size_t, size_t, const I *RESTRICT A_pos, const I *RESTRICT A_idx, const V *RESTRICT A_val, value_type alpha, value_type beta, const C1 *RESTRICT x_ptr, C2 *RESTRICT y_ptr)
Definition sparsematrix_cpu.h:184
void spmv_omp_kernel(CSRCache_omp &, size_t A_num_rows, size_t, size_t, const I *RESTRICT A_pos, const I *RESTRICT A_idx, const V *RESTRICT A_val, value_type alpha, value_type beta, const C1 *RESTRICT x_ptr, C2 *RESTRICT y_ptr)
Definition sparsematrix_omp.h:17
This is the namespace for all functions and classes defined and used by the discontinuous Galerkin li...
void print(const Sparse &m, std::ostream &out=std::cout)
Print textual representation of sparse matrix.
Definition sparsematrix.h:697
Indicate sequential execution.
Definition execution_policy.h:26
Indicate a contiguous chunk of shared memory.
Definition vector_categories.h:41
A CSR formatted sparse matrix.
Definition sparsematrix.h:102
size_t num_cols() const
Number of columns in matrix.
Definition sparsematrix.h:287
SparseMatrix operator-() const
Negate.
Definition sparsematrix.h:472
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.
Definition sparsematrix.h:237
friend enable_if_serial< OtherMatrix > operator+(const SparseMatrix &lhs, const SparseMatrix &rhs)
add
Definition sparsematrix.h:528
Vector< Value > & values()
Change values vector.
Definition sparsematrix.h:355
friend enable_if_serial< OtherMatrix > operator*(const SparseMatrix &lhs, const SparseMatrix &rhs)
matrix-matrix multiplication
Definition sparsematrix.h:603
Vector< Index > & column_indices()
Write column indices vector directly.
Definition sparsematrix.h:343
SparseMatrix(const SparseMatrix< I, V, Vec > &src)
Copy construct from differen type.
Definition sparsematrix.h:149
SparseMatrix transpose() const
Transposition.
Definition sparsematrix.h:405
Vector< Index > & row_offsets()
Write row_offsets vector directly.
Definition sparsematrix.h:323
Index index_type
The index type (on GPU must be either int or long)
Definition sparsematrix.h:104
size_t & num_cols()
Set number of columns in matrix (empties performance cache)
Definition sparsematrix.h:282
dg::get_execution_policy< Vector< Value > > policy
Execution policy of the matrix.
Definition sparsematrix.h:103
size_t total_num_rows() const
Alias for num_rows.
Definition sparsematrix.h:275
const Vector< Index > & row_offsets() const
Read row_offsets vector.
Definition sparsematrix.h:298
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.
Definition sparsematrix.h:177
size_t num_entries() const
Alias for num_nnz.
Definition sparsematrix.h:293
size_t total_num_cols() const
Alias for num_cols.
Definition sparsematrix.h:277
friend enable_if_serial< OtherMatrix > operator*(const SparseMatrix &lhs, const Value &value)
scalar multiplication
Definition sparsematrix.h:589
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.
Definition sparsematrix.h:131
size_t & num_rows()
Set number of rows in matrix (empties performance cache)
Definition sparsematrix.h:280
friend enable_if_serial< OtherMatrix > operator-(const SparseMatrix &lhs, const SparseMatrix &rhs)
subtract
Definition sparsematrix.h:556
size_t num_nnz() const
Number of nonzero elements in matrix.
Definition sparsematrix.h:291
enable_if_serial< OtherMatrix > & operator-=(const SparseMatrix &op)
subtract
Definition sparsematrix.h:497
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.
Definition sparsematrix.h:465
SparseMatrix & operator*=(const Value &value)
scalar multiply
Definition sparsematrix.h:509
SparseMatrix()=default
Empty matrix.
Value value_type
The value type (on GPU must be either float or double)
Definition sparsematrix.h:105
friend std::enable_if_t< dg::has_policy_v< OtherMatrix, SerialTag >, Ostream > & operator<<(Ostream &os, const SparseMatrix &mat)
puts a matrix linewise in output stream
Definition sparsematrix.h:654
void sort_indices()
Sort by row and column.
Definition sparsematrix.h:258
size_t num_vals() const
Alias for num_nnz.
Definition sparsematrix.h:289
const Vector< Index > & column_indices() const
Read column indices vector.
Definition sparsematrix.h:302
std::enable_if_t< std::is_same_v< typename OtherMatrix::policy, SerialTag >, OtherMatrix > enable_if_serial
A static guard to allow certain members only on host (for serial execution)
Definition sparsematrix.h:109
friend enable_if_serial< OtherMatrix > operator*(const Value &value, const SparseMatrix &rhs)
scalar multiplication
Definition sparsematrix.h:572
friend ContainerType operator*(const SparseMatrix &S, const ContainerType &x)
matrix-vector multiplication
Definition sparsematrix.h:632
const Vector< Value > & values() const
Read values vector.
Definition sparsematrix.h:306
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.
Definition sparsematrix.h:442
enable_if_serial< OtherMatrix > & operator+=(const SparseMatrix &op)
Add.
Definition sparsematrix.h:484
size_t num_rows() const
Number of rows in matrix.
Definition sparsematrix.h:285
indicate our sparse matrix format
Definition matrix_categories.h:35
typename SparseMatrix< I, T, V >::policy execution_policy
Definition sparsematrix.h:716
T value_type
Definition sparsematrix.h:714
The vector traits.
Definition tensor_traits.h:38
Definition sparsematrix_cpu.h:179
Definition sparsematrix_gpu.cuh:89
Definition sparsematrix_omp.h:12