Discontinuous Galerkin Library
#include "dg/algorithm.h"
Loading...
Searching...
No Matches
sparsematrix.h
Go to the documentation of this file.
1
2#pragma once
3
4#include <iomanip>
5#include <numeric>
6#include <thrust/sort.h>
7#include <thrust/gather.h>
8#include <thrust/sequence.h>
9#include <thrust/binary_search.h>
10#include "tensor_traits.h"
11#include "predicate.h"
12#include "exceptions.h"
13#include "config.h"
14#include "blas2_stencil.h"
15
16#include "sparsematrix_cpu.h"
17#if THRUST_DEVICE_SYSTEM==THRUST_DEVICE_SYSTEM_CUDA
18#include "sparsematrix_gpu.cuh"
19#elif THRUST_DEVICE_SYSTEM==THRUST_DEVICE_SYSTEM_OMP
20#include "sparsematrix_omp.h"
21#endif
22
23namespace dg
24{
25
26namespace detail
27{
28template<class I0, class I1>
29void csr2coo_inline( const I0& csr, I1& coo)
30{
31 using policy = dg::get_execution_policy<I0>;
32 static_assert( dg::has_policy_v<I1, policy>, "Vector types must have same execution policy");
33 using I0_t = dg::get_value_type<I0>;
34 using I1_t = dg::get_value_type<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)
37 {
38 for (int jj = csr_ptr[i]; jj < csr_ptr[i+1]; jj++)
39 coo_ptr[jj] = i;
40 },
41 thrust::raw_pointer_cast(csr.data()),
42 thrust::raw_pointer_cast(coo.data()));
43}
44template<class I>
45I csr2coo( const I& csr)
46{
47 I coo( csr.back());
48 csr2coo_inline( csr, coo);
49 return coo;
50}
51//coo must be sorted
52template<class I0, class I1>
53void coo2csr_inline( const I0& coo, I1& csr)
54{
55 using policy = dg::get_execution_policy<I0>;
56 static_assert( dg::has_policy_v<I1, policy>, "Vector types must have same execution policy");
57 thrust::lower_bound( coo.begin(), coo.end(),
58 thrust::counting_iterator<dg::get_value_type<I1>>(0),
59 thrust::counting_iterator<dg::get_value_type<I1>>( csr.size()),
60 csr.begin());
61 //if( (size_t)csr[num_rows] != (size_t)coo.size())
62 // throw dg::Error( dg::Message( _ping_) << "Error: Row indices contain values beyond num_rows "
63 // <<num_rows<<"\n");
64}
65template<class I>
66I coo2csr( unsigned num_rows, const I& coo)
67{
68 I csr(num_rows+1,0);
69 coo2csr_inline( coo, csr);
70 return csr;
71}
72}
73
100template<class Index = int, class Value = double, template<class> class Vector = thrust::host_vector>
102{
104 using index_type = Index;
105 using value_type = Value;
106
108 template<class OtherMatrix>
109 using enable_if_serial = std::enable_if_t<std::is_same_v<typename OtherMatrix::policy, SerialTag>, OtherMatrix>;
110
115 SparseMatrix() = default;
116 // MW: Allowing unsored indices in row is important for our stencils
131 SparseMatrix( size_t num_rows, size_t num_cols, const Vector<Index>&
132 row_offsets, const Vector<Index>& column_indices, const Vector<Value>& values)
133 : m_num_rows( num_rows), m_num_cols( num_cols), m_row_offsets(
134 row_offsets), m_cols(column_indices), m_vals(values)
135 {
136 }
137
139 template< class I, class V, template<class> class Vec>
140 friend struct SparseMatrix; // enable copy
141
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)
152 {
153 }
154
155
177 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)
178 {
179 if( row_indices.size() != values.size())
180 throw dg::Error( dg::Message( _ping_) << "Error: Row indices size "
181 <<row_indices.size()<<" not equal to values size "<<values.size()<<"\n");
182 if( column_indices.size() != values.size())
183 throw dg::Error( dg::Message( _ping_) << "Error: Column indices size "
184 <<column_indices.size()<<" not equal to values size "<<values.size()<<"\n");
185 m_num_rows = num_rows;
186 m_num_cols = num_cols;
187
188 m_row_offsets.resize( num_rows+1);
189 m_cols.resize( column_indices.size());
190 m_vals.resize( values.size());
191
192 if( sort)
193 {
194 Vector<Index> trows( row_indices);
195 Vector<Index> tcols( column_indices);
196 Vector<Index> p( row_indices.size()); // permutation
197 thrust::sequence( p.begin(), p.end());
198 // First sort columns
199 thrust::sort_by_key( tcols.begin(), tcols.end(), p.begin());
200 // Repeat sort on rows
201 thrust::gather( p.begin(), p.end(), row_indices.begin(), trows.begin());
202 // Now sort rows preserving relative ordering
203 thrust::stable_sort_by_key( trows.begin(), trows.end(), p.begin());
204 m_row_offsets.resize( num_rows+1);
205 detail::coo2csr_inline( trows, m_row_offsets);
206 // Repeat sort on cols and vals
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());
209 }
210 else
211 {
212 detail::coo2csr_inline( row_indices, m_row_offsets);
213 thrust::copy( column_indices.begin(), column_indices.end(), m_cols.begin());
214 thrust::copy( values.begin(), values.end(), m_vals.begin());
215 }
216 m_cache.forget();
217 }
218
237 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)
238 {
239 if ( sort)
240 {
241 Vector<Index> rows = detail::csr2coo( row_offsets);
243 }
244 else
245 {
246 m_num_rows = num_rows, m_num_cols = num_cols;
247 m_row_offsets = row_offsets, m_cols = column_indices, m_vals = values;
248 }
249 m_cache.forget();
250 }
251
259 {
260 if( m_num_rows != m_row_offsets.size()-1)
261 throw dg::Error( dg::Message( _ping_) << "Error: Row offsets have size "
262 <<m_row_offsets.size()<<" but num_rows is "<<m_num_rows<<"\n");
263 if( m_cols.size() != m_vals.size())
264 throw dg::Error( dg::Message( _ping_) << "Error: Column indices size "
265 <<m_cols.size()<<" not equal to values size "<<m_vals.size()<<"\n");
266
267 // Sort each row
268 Vector<Index> rows = detail::csr2coo( m_row_offsets);
269 Vector<Index> cols = m_cols;
270 Vector<Value> vals = m_vals;
271 setFromCoo( m_num_rows, m_num_cols, rows, cols, vals, true);
272 }
273
275 size_t total_num_rows() const { return m_num_rows;} // for blas2_sparseblockmat dispatch
277 size_t total_num_cols() const { return m_num_cols;} // for blas2_sparseblockmat dispatch
278
280 size_t& num_rows() { m_cache.forget(); return m_num_rows;}
282 size_t& num_cols() { m_cache.forget(); return m_num_cols;}
283
285 size_t num_rows() const { return m_num_rows;}
287 size_t num_cols() const { return m_num_cols;}
289 size_t num_vals() const { return m_vals.size();}
291 size_t num_nnz() const { return m_vals.size();}
293 size_t num_entries() const { return m_vals.size();}
294
298 const Vector<Index> & row_offsets() const { return m_row_offsets;}
302 const Vector<Index> & column_indices() const { return m_cols;}
306 const Vector<Value> & values() const { return m_vals;}
323 Vector<Index> & row_offsets() {
324 m_cache.forget();
325 return m_row_offsets;
326 }
343 Vector<Index> & column_indices() {
344 m_cache.forget();
345 return m_cols;
346 }
355 Vector<Value> & values() { return m_vals;}
356
358 template<class value_type>
359 void symv(SharedVectorTag, SerialTag, value_type alpha, const value_type* RESTRICT x, value_type beta, value_type* RESTRICT y) const
360 {
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]);
364 detail::spmv_cpu_kernel( m_cache, m_num_rows, m_num_cols,
365 m_vals.size(), row_ptr, col_ptr, val_ptr, alpha, beta, x, y);
366 }
367#if THRUST_DEVICE_SYSTEM==THRUST_DEVICE_SYSTEM_CUDA
368 template<class value_type>
369 void symv(SharedVectorTag, CudaTag, value_type alpha, const value_type* x, value_type beta, value_type* y) const
370 {
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]);
374 detail::spmv_gpu_kernel( m_cache, m_num_rows, m_num_cols,
375 m_vals.size(), row_ptr, col_ptr, val_ptr, alpha, beta, x, y);
376 }
377#elif THRUST_DEVICE_SYSTEM==THRUST_DEVICE_SYSTEM_OMP
378 template<class value_type>
379 void symv(SharedVectorTag, OmpTag, value_type alpha, const value_type* x, value_type beta, value_type* y) const
380 {
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())
385 {
386 #pragma omp parallel
387 {
388 detail::spmv_omp_kernel( m_cache, m_num_rows, m_num_cols,
389 m_vals.size(), row_ptr, col_ptr, val_ptr, alpha, beta, x, y);
390 }
391 return;
392 }
393 detail::spmv_omp_kernel( m_cache, m_num_rows, m_num_cols,
394 m_vals.size(), row_ptr, col_ptr, val_ptr, alpha, beta, x, y);
395 }
396#endif
398
406 {
407 auto cols = detail::csr2coo(m_row_offsets);
408 // cols are sorted
409
410 // We need to sort now
412 o.m_num_rows = m_num_cols;
413 o.m_num_cols = m_num_rows;
414
415 Vector<Index> rows( m_cols.begin(), m_cols.end());
416 Vector<Index> p( rows.size()); // permutation
417 thrust::sequence( p.begin(), p.end());
418
419 thrust::stable_sort_by_key( rows.begin(), rows.end(), p.begin());
420 o.m_row_offsets.resize( o.m_num_rows+1);
421 detail::coo2csr_inline( rows, o.m_row_offsets);
422 // Repeat sort on cols and vals
423 o.m_cols.resize( cols.size());
424 o.m_vals.resize( m_vals.size());
425 // Since cols are sorted o.m_cols will be as well
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());
428 o.m_cache.forget();
429 return o;
430
431 }
432
433 //
434 // We enable the following only for serial sparse matrices
435
441 template<class OtherMatrix = SparseMatrix>
442 std::enable_if_t<dg::has_policy_v<OtherMatrix, SerialTag>, bool> operator!=( const SparseMatrix& rhs) const{
443 if( rhs.m_num_rows != m_num_rows)
444 return true;
445 if( rhs.m_num_cols != m_num_cols)
446 return true;
447 for( size_t i = 0; i < m_row_offsets.size(); i++)
448 if( m_row_offsets[i] != rhs.m_row_offsets[i])
449 return true;
450 for( size_t i = 0; i < m_cols.size(); i++)
451 if( m_cols[i] != rhs.m_cols[i])
452 return true;
453 for( size_t i = 0; i < m_vals.size(); i++)
454 if( m_vals[i] != rhs.m_vals[i])
455 return true;
456 return false;
457 }
458
464 template<class OtherMatrix = SparseMatrix>
465 std::enable_if_t<dg::has_policy_v<OtherMatrix, SerialTag>, bool> operator==( const SparseMatrix& rhs) const {return !((*this != rhs));}
466
473 {
474 return (*this)*(Value(-1));
475 }
483 template<class OtherMatrix = SparseMatrix>
485 {
486 *this = *this + op;
487 return *this;
488 }
496 template<class OtherMatrix = SparseMatrix>
498 {
499 *this = *this + (-op);
500 return *this;
501 }
509 SparseMatrix& operator*=( const Value& value )
510 {
511 dg::blas2::detail::doParallelFor_dispatch( policy(), m_vals.size(),
512 [value]DG_DEVICE( unsigned i, Value* val_ptr)
513 {
514 val_ptr[i] *= value;
515 },
516 thrust::raw_pointer_cast(m_vals.data()));
517 return *this;
518 }
527 template<class OtherMatrix = SparseMatrix>
529 {
530 if( lhs.m_num_cols != rhs.m_num_cols)
531 throw dg::Error( dg::Message( _ping_) << "Error: cannot add matrix with "
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)
534 throw dg::Error( dg::Message( _ping_) << "Error: cannot add matrix with "
535 <<lhs.m_num_rows<<" rows to matrix with "<<rhs.m_num_rows<<" rows\n");
536 Vector<Index> row_offsets, cols;
537 Vector<Value> vals;
538
539 detail::spadd_cpu_kernel( lhs.m_num_rows, lhs.m_num_cols,
540 lhs.m_row_offsets, lhs.m_cols, lhs.m_vals,
541 rhs.m_row_offsets, rhs.m_cols, rhs.m_vals,
542 row_offsets, cols, vals);
543
544 SparseMatrix temp(lhs.m_num_rows, rhs.m_num_cols, row_offsets, cols, vals);
545 return temp;
546 }
555 template<class OtherMatrix = SparseMatrix>
557 {
558 SparseMatrix temp(lhs);
559 temp-=rhs;
560 return temp;
561 }
571 template<class OtherMatrix = SparseMatrix>
572 friend enable_if_serial<OtherMatrix> operator*( const Value& value, const SparseMatrix& rhs )
573 {
574 SparseMatrix temp(rhs);
575 temp*=value;
576 return temp;
577 }
578
588 template<class OtherMatrix = SparseMatrix>
589 friend enable_if_serial<OtherMatrix> operator*( const SparseMatrix& lhs, const Value& value)
590 {
591 return value*lhs;
592 }
593
602 template<class OtherMatrix = SparseMatrix>
604 {
605 if( lhs.m_num_cols != rhs.m_num_rows)
606 throw dg::Error( dg::Message( _ping_) << "Error: cannot multiply matrix with "
607 <<lhs.m_num_cols<<" columns with matrix with "<<rhs.m_num_rows<<" rows\n");
608
609 Vector<Index> row_offsets, cols;
610 Vector<Value> vals;
611
612 detail::spgemm_cpu_kernel( lhs.m_num_rows, lhs.m_num_cols, rhs.m_num_cols,
613 lhs.m_row_offsets, lhs.m_cols, lhs.m_vals,
614 rhs.m_row_offsets, rhs.m_cols, rhs.m_vals,
615 row_offsets, cols, vals);
616
617 SparseMatrix temp(lhs.m_num_rows, rhs.m_num_cols, row_offsets, cols, vals);
618 return temp;
619 }
620
631 template<class ContainerType, class = std::enable_if_t < dg::has_policy_v<ContainerType, policy> and dg::is_vector_v<ContainerType> >>
632 friend ContainerType operator*( const SparseMatrix& S, const ContainerType& x)
633 {
634 if( S.m_num_cols != x.size())
635 throw dg::Error( dg::Message( _ping_) << "Error: cannot multiply matrix with "
636 <<S.m_num_cols<<" columns with vector with "<<x.size()<<" rows\n");
637
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());
641 S.symv( SharedVectorTag(), policy(), Value(1), x_ptr, Value(0), y_ptr);
642 return out;
643 }
644
652 template< class Ostream, class OtherMatrix = SparseMatrix>
653 friend std::enable_if_t<dg::has_policy_v<OtherMatrix, SerialTag>, Ostream>
654 & operator<<(Ostream& os, const SparseMatrix& mat)
655 {
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++)
659 {
660 for (int pB = mat.m_row_offsets[i]; pB < mat.m_row_offsets[i+1]; pB++)
661 {
662 os << "("<<i<<","<<mat.m_cols[pB]<<","<<mat.m_vals[pB]<<") ";
663 }
664 os << "\n";
665 }
666 return os;
667 }
668
669 private:
670 // The task of the cache is to keep performance information across multiple calls to
671 // symv. The cache needs to forget said information any time the matrix changes
672 mutable std::conditional_t< std::is_same_v<policy, SerialTag>, detail::CSRCache_cpu,
673#if THRUST_DEVICE_SYSTEM==THRUST_DEVICE_SYSTEM_CUDA
675#elif THRUST_DEVICE_SYSTEM==THRUST_DEVICE_SYSTEM_OMP
677#else
679#endif
680 m_cache;
681
682 size_t m_num_rows, m_num_cols;
683 Vector<Index> m_row_offsets, m_cols;
684 Vector<Value> m_vals;
685};
686
696template<class Sparse>
697void print( const Sparse& m, std::ostream& out = std::cout )
698{
699 out << "Sparse matrix <" << m.num_rows() << ", " << m.num_cols() << "> with "<< m.num_nnz() << " entries\n";
700 auto row_indices = detail::csr2coo( m.row_offsets());
701 for( unsigned u=0; u<m.num_nnz(); u++)
702 {
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";
706 }
707}
708
711template <class I, class T, template<class> class V>
719}//namespace dg
720
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
@ y
y direction
@ x
x direction
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)
const double m
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
double value_type