monolish  0.17.2
MONOlithic LInear equation Solvers for Highly-parallel architecture
monolish_crs.hpp
Go to the documentation of this file.
1 #pragma once
2 #include <exception>
3 #include <memory>
4 #include <omp.h>
5 #include <stdexcept>
6 #include <string>
7 #include <vector>
8 
9 #if USE_SXAT
10 #undef _HAS_CPP17
11 #endif
12 #include <random>
13 #if USE_SXAT
14 #define _HAS_CPP17 1
15 #endif
16 
17 namespace monolish {
18 template <typename Float> class vector;
19 template <typename TYPE, typename Float> class view1D;
20 namespace tensor {
21 template <typename Float> class tensor_Dense;
22 template <typename Float> class tensor_COO;
23 } // namespace tensor
24 namespace matrix {
25 template <typename Float> class Dense;
26 template <typename Float> class COO;
27 
39 template <typename Float> class CRS {
40 private:
44  size_t rowN;
45 
49  size_t colN;
50 
54  // size_t nnz;
55 
59  mutable std::shared_ptr<bool> gpu_status = std::make_shared<bool>(false);
60 
65 
69  size_t first = 0;
70 
71 public:
76  std::shared_ptr<Float> val;
77 
81  size_t val_nnz = 0;
82 
86  size_t alloc_nnz = 0;
87 
91  bool val_create_flag = false;
92 
97  std::vector<int> col_ind;
98 
103  std::vector<int> row_ptr;
104 
105  CRS() { val_create_flag = true; }
106 
117  CRS(const size_t M, const size_t N, const size_t NNZ);
118 
134  CRS(const size_t M, const size_t N, const size_t NNZ, const int *rowptr,
135  const int *colind, const Float *value);
136 
154  CRS(const size_t M, const size_t N, const size_t NNZ, const int *rowptr,
155  const int *colind, const Float *value, const size_t origin);
156 
171  CRS(const size_t M, const size_t N, const std::vector<int> &rowptr,
172  const std::vector<int> &colind, const std::vector<Float> &value);
173 
188  CRS(const size_t M, const size_t N, const std::vector<int> &rowptr,
189  const std::vector<int> &colind, const vector<Float> &value);
190 
198  void convert(COO<Float> &coo);
199 
207  void convert(CRS<Float> &crs);
208 
217  CRS(COO<Float> &coo) {
218  val_create_flag = true;
219  convert(coo);
220  }
221 
234  CRS(const CRS<Float> &mat);
235 
249  CRS(const CRS<Float> &mat, Float value);
250 
265  void set_ptr(const size_t M, const size_t N, const std::vector<int> &rowptr,
266  const std::vector<int> &colind, const std::vector<Float> &value);
267 
282  void set_ptr(const size_t M, const size_t N, const std::vector<int> &rowptr,
283  const std::vector<int> &colind, const size_t vsize,
284  const Float *value);
285 
300  void set_ptr(const size_t M, const size_t N, const std::vector<int> &rowptr,
301  const std::vector<int> &colind, const size_t vsize,
302  const Float value);
303 
312  void print_all(bool force_cpu = false) const;
313 
321  [[nodiscard]] size_t get_row() const { return rowN; }
322 
330  [[nodiscard]] size_t get_col() const { return colN; }
331 
339  [[nodiscard]] size_t get_nnz() const { return val_nnz; }
340 
348  [[nodiscard]] size_t get_alloc_nnz() const { return alloc_nnz; }
349 
356  [[nodiscard]] size_t get_first() const { return first; }
357 
364  [[nodiscard]] size_t get_offset() const { return get_first(); }
365 
373  void set_row(const size_t N) { rowN = N; };
374 
382  void set_col(const size_t M) { colN = M; };
383 
391  [[nodiscard]] std::string type() const { return "CRS"; }
392 
400  void compute_hash();
401 
407  [[nodiscard]] size_t get_hash() const { return structure_hash; }
408 
409  // communication
410  // ///////////////////////////////////////////////////////////////////////////
418  void send() const;
419 
427  void recv();
428 
436  void nonfree_recv();
437 
445  void device_free() const;
446 
451  [[nodiscard]] bool get_device_mem_stat() const { return *gpu_status; }
452 
457  [[nodiscard]] std::shared_ptr<bool> get_gpu_status() const {
458  return gpu_status;
459  }
460 
468  ~CRS() {
469  if (val_create_flag) {
470  if (get_device_mem_stat()) {
471  device_free();
472  }
473  }
474  }
475 
482  [[nodiscard]] const Float *data() const { return val.get(); }
483 
490  [[nodiscard]] Float *data() { return val.get(); }
491 
500  void resize(size_t N, Float Val = 0) {
501  if (get_device_mem_stat()) {
502  throw std::runtime_error("Error, GPU matrix cant use resize");
503  }
504  if (val_create_flag) {
505  std::shared_ptr<Float> tmp(new Float[N], std::default_delete<Float[]>());
506  size_t copy_size = std::min(val_nnz, N);
507  for (size_t i = 0; i < copy_size; ++i) {
508  tmp.get()[i] = data()[i];
509  }
510  for (size_t i = copy_size; i < N; ++i) {
511  tmp.get()[i] = Val;
512  }
513  val = tmp;
514  alloc_nnz = N;
515  val_nnz = N;
516  } else {
517  throw std::runtime_error("Error, not create vector cant use resize");
518  }
519  }
520 
527  [[nodiscard]] const Float *begin() const { return data(); }
528 
535  [[nodiscard]] Float *begin() { return data(); }
536 
543  [[nodiscard]] const Float *end() const { return data() + get_nnz(); }
544 
551  [[nodiscard]] Float *end() { return data() + get_nnz(); }
552 
554 
562  void diag(vector<Float> &vec) const;
563  void diag(view1D<vector<Float>, Float> &vec) const;
564  void diag(view1D<matrix::Dense<Float>, Float> &vec) const;
565  void diag(view1D<tensor::tensor_Dense<Float>, Float> &vec) const;
566 
576  void row(const size_t r, vector<Float> &vec) const;
577  void row(const size_t r, view1D<vector<Float>, Float> &vec) const;
578  void row(const size_t r, view1D<matrix::Dense<Float>, Float> &vec) const;
579  void row(const size_t r,
580  view1D<tensor::tensor_Dense<Float>, Float> &vec) const;
581 
591  void col(const size_t c, vector<Float> &vec) const;
592  void col(const size_t c, view1D<vector<Float>, Float> &vec) const;
593  void col(const size_t c, view1D<matrix::Dense<Float>, Float> &vec) const;
594  void col(const size_t c,
595  view1D<tensor::tensor_Dense<Float>, Float> &vec) const;
596 
598 
610  void diag_add(const Float alpha);
611 
624  void diag_sub(const Float alpha);
625 
638  void diag_mul(const Float alpha);
639 
652  void diag_div(const Float alpha);
653 
666  void diag_add(const vector<Float> &vec);
667  void diag_add(const view1D<vector<Float>, Float> &vec);
668  void diag_add(const view1D<matrix::Dense<Float>, Float> &vec);
669  void diag_add(const view1D<tensor::tensor_Dense<Float>, Float> &vec);
670 
683  void diag_sub(const vector<Float> &vec);
684  void diag_sub(const view1D<vector<Float>, Float> &vec);
685  void diag_sub(const view1D<matrix::Dense<Float>, Float> &vec);
686  void diag_sub(const view1D<tensor::tensor_Dense<Float>, Float> &vec);
687 
700  void diag_mul(const vector<Float> &vec);
701  void diag_mul(const view1D<vector<Float>, Float> &vec);
702  void diag_mul(const view1D<matrix::Dense<Float>, Float> &vec);
703  void diag_mul(const view1D<tensor::tensor_Dense<Float>, Float> &vec);
704 
717  void diag_div(const vector<Float> &vec);
718  void diag_div(const view1D<vector<Float>, Float> &vec);
719  void diag_div(const view1D<matrix::Dense<Float>, Float> &vec);
720  void diag_div(const view1D<tensor::tensor_Dense<Float>, Float> &vec);
721 
723 
732  void transpose();
733 
742  void transpose(const CRS &B);
743 
744  /*
745  * @brief Memory data space required by the matrix
746  * @note
747  * - # of computation: 3
748  * - Multi-threading: false
749  * - GPU acceleration: false
750  **/
751  [[nodiscard]] double get_data_size() const {
752  return (get_nnz() * sizeof(Float) + (get_row() + 1) * sizeof(int) +
753  get_nnz() * sizeof(int)) /
754  1.0e+9;
755  }
756 
765  void fill(Float value);
766 
777  void operator=(const CRS<Float> &mat);
778 
788  [[nodiscard]] Float &operator[](size_t i) {
789  if (get_device_mem_stat()) {
790  throw std::runtime_error("Error, GPU vector cant use operator[]");
791  }
792  return data()[i];
793  }
794 
805  [[nodiscard]] bool equal(const CRS<Float> &mat,
806  bool compare_cpu_and_device = false) const;
807 
819  [[nodiscard]] bool operator==(const CRS<Float> &mat) const;
820 
832  [[nodiscard]] bool operator!=(const CRS<Float> &mat) const;
833 };
836 } // namespace matrix
837 } // namespace monolish
Coodinate (COO) format Matrix (need to sort)
Compressed Row Storage (CRS) format Matrix.
void diag_mul(const view1D< tensor::tensor_Dense< Float >, Float > &vec)
std::shared_ptr< bool > gpu_status
# of non-zero element
bool equal(const CRS< Float > &mat, bool compare_cpu_and_device=false) const
Comparing matrices (A == mat)
size_t rowN
# of row
std::shared_ptr< bool > get_gpu_status() const
gpu status shared pointer
void set_col(const size_t M)
Set column number.
CRS(const CRS< Float > &mat)
Create CRS matrix from CRS matrix.
const Float * data() const
returns a direct pointer to the matrix
Float * data()
returns a direct pointer to the matrix
void diag_mul(const Float alpha)
Scalar and diag. vector of CRS format matrix mul.
size_t get_col() const
get # of col
CRS(const size_t M, const size_t N, const size_t NNZ)
declare CRS matrix
void diag(vector< Float > &vec) const
get diag. vector
void diag_mul(const view1D< matrix::Dense< Float >, Float > &vec)
CRS(const size_t M, const size_t N, const size_t NNZ, const int *rowptr, const int *colind, const Float *value, const size_t origin)
Create CRS matrix from array, also compute the hash.
Float * end()
returns a end iterator
size_t first
first position of data array
size_t val_nnz
# of non-zero element (M * N)
CRS(COO< Float > &coo)
Create CRS matrix from COO matrix, also compute the hash.
void diag_mul(const vector< Float > &vec)
Vector and diag. vector of CRS format matrix mul.
void set_ptr(const size_t M, const size_t N, const std::vector< int > &rowptr, const std::vector< int > &colind, const size_t vsize, const Float *value)
Set CRS array from std::vector.
double get_data_size() const
void diag_sub(const Float alpha)
Scalar and diag. vector of CRS format matrix sub.
void compute_hash()
compute index array hash (to compare structure)
void diag_sub(const view1D< vector< Float >, Float > &vec)
CRS(const size_t M, const size_t N, const size_t NNZ, const int *rowptr, const int *colind, const Float *value)
Create CRS matrix from array, also compute the hash.
void row(const size_t r, view1D< matrix::Dense< Float >, Float > &vec) const
size_t alloc_nnz
alloced matrix size
bool operator!=(const CRS< Float > &mat) const
Comparing matrices (A != mat)
void diag_add(const view1D< vector< Float >, Float > &vec)
void fill(Float value)
fill matrix elements with a scalar value
size_t get_alloc_nnz() const
get # of alloced non-zeros
void row(const size_t r, view1D< tensor::tensor_Dense< Float >, Float > &vec) const
bool val_create_flag
matrix create flag;
size_t get_hash() const
get index array hash (to compare structure)
void diag_add(const view1D< matrix::Dense< Float >, Float > &vec)
bool operator==(const CRS< Float > &mat) const
Comparing matrices (A == mat)
void set_row(const size_t N)
Set row number.
void send() const
send data to GPU
size_t get_first() const
get first position
void convert(CRS< Float > &crs)
Convert CRS matrix from COO matrix.
void print_all(bool force_cpu=false) const
print all elements to standard I/O
void resize(size_t N, Float Val=0)
resize matrix value
void col(const size_t c, vector< Float > &vec) const
get column vector
void diag_sub(const vector< Float > &vec)
Vector and diag. vector of CRS format matrix sub.
void operator=(const CRS< Float > &mat)
matrix copy
void transpose(const CRS &B)
create transposed matrix from CRS format matrix (B = A^T)
CRS(const CRS< Float > &mat, Float value)
Create CRS matrix of the same size as input matrix.
std::shared_ptr< Float > val
CRS format value (pointer), which stores values of the non-zero elements.
size_t get_offset() const
get first position (same as get_first())
size_t get_nnz() const
get # of non-zeros
size_t structure_hash
hash, created from row_ptr and col_ind
void col(const size_t c, view1D< vector< Float >, Float > &vec) const
void diag_div(const view1D< tensor::tensor_Dense< Float >, Float > &vec)
const Float * end() const
returns a end iterator
void diag(view1D< vector< Float >, Float > &vec) const
void diag(view1D< tensor::tensor_Dense< Float >, Float > &vec) const
void diag(view1D< matrix::Dense< Float >, Float > &vec) const
size_t get_row() const
get # of row
std::vector< int > col_ind
CRS format column index, which stores column numbers of the non-zero elements (size nnz)
void diag_sub(const view1D< tensor::tensor_Dense< Float >, Float > &vec)
~CRS()
destructor of CRS matrix, free GPU memory
const Float * begin() const
returns a begin iterator
std::string type() const
get format name "CRS"
void diag_add(const view1D< tensor::tensor_Dense< Float >, Float > &vec)
void nonfree_recv()
recv. data to GPU (w/o free)
void convert(COO< Float > &coo)
Convert CRS matrix from COO matrix, also compute the hash.
void diag_add(const Float alpha)
Scalar and diag. vector of CRS format matrix add.
void col(const size_t c, view1D< tensor::tensor_Dense< Float >, Float > &vec) const
void transpose()
get transposed matrix (A^T)
void device_free() const
free data on GPU
void row(const size_t r, view1D< vector< Float >, Float > &vec) const
void diag_add(const vector< Float > &vec)
Vector and diag. vector of CRS format matrix add.
void diag_div(const view1D< matrix::Dense< Float >, Float > &vec)
void diag_div(const Float alpha)
Scalar and diag. vector of CRS format matrix div.
void diag_mul(const view1D< vector< Float >, Float > &vec)
Float * begin()
returns a begin iterator
void recv()
recv. data to GPU, and free data on GPU
Float & operator[](size_t i)
reference to the element at position (v[i])
void row(const size_t r, vector< Float > &vec) const
get row vector
void diag_div(const vector< Float > &vec)
Vector and diag. vector of CRS format matrix div.
size_t colN
# of col
void set_ptr(const size_t M, const size_t N, const std::vector< int > &rowptr, const std::vector< int > &colind, const std::vector< Float > &value)
Set CRS array from std::vector.
void col(const size_t c, view1D< matrix::Dense< Float >, Float > &vec) const
std::vector< int > row_ptr
CRS format row pointer, which stores the starting points of the rows of the arrays value and col_ind ...
CRS(const size_t M, const size_t N, const std::vector< int > &rowptr, const std::vector< int > &colind, const std::vector< Float > &value)
Create CRS matrix from std::vector, also compute the hash.
bool get_device_mem_stat() const
true: sended, false: not send
void diag_sub(const view1D< matrix::Dense< Float >, Float > &vec)
CRS(const size_t M, const size_t N, const std::vector< int > &rowptr, const std::vector< int > &colind, const vector< Float > &value)
Create CRS matrix from std::vector, also compute the hash.
void diag_div(const view1D< vector< Float >, Float > &vec)
void set_ptr(const size_t M, const size_t N, const std::vector< int > &rowptr, const std::vector< int > &colind, const size_t vsize, const Float value)
Set CRS array from std::vector.
Dense format Matrix.
void min(const matrix::CRS< double > &A, const matrix::CRS< double > &B, matrix::CRS< double > &C)
Create a new CRS matrix with smallest elements of two matrices (C[0:nnz] = min(A[0:nnz],...
monolish namespaces