monolish  0.17.1
MONOlithic LInear equation Solvers for Highly-parallel architecture
monolish_coo.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 #define MM_BANNER "%%MatrixMarket"
18 #define MM_MAT "matrix"
19 #define MM_VEC "vector"
20 #define MM_FMT "coordinate"
21 #define MM_TYPE_REAL "real"
22 #define MM_TYPE_GENERAL "general"
23 #define MM_TYPE_SYMM "symmetric"
24 
25 namespace monolish {
26 template <typename Float> class vector;
27 template <typename TYPE, typename Float> class view1D;
28 namespace tensor {
29 template <typename Float> class tensor_Dense;
30 }
31 namespace matrix {
32 template <typename Float> class Dense;
33 template <typename Float> class CRS;
34 template <typename Float> class LinearOperator;
35 
47 template <typename Float> class COO {
48 private:
52  size_t rowN;
53 
57  size_t colN;
58 
62  // size_t nnz;
63 
67  mutable bool gpu_status = false;
68 
69 public:
74  std::vector<int> row_index;
75 
80  std::vector<int> col_index;
81 
86  std::shared_ptr<Float> val;
87 
91  size_t val_nnz = 0;
92 
96  std::size_t alloc_nnz = 0;
97 
101  bool val_create_flag = false;
102 
103  COO()
104  : rowN(0), colN(0), gpu_status(false), row_index(), col_index(),
105  val_nnz(0) {
106  val_create_flag = true;
107  }
108 
118  COO(const size_t M, const size_t N)
119  : rowN(M), colN(N), gpu_status(false), row_index(), col_index(),
120  val_nnz(0) {
121  val_create_flag = true;
122  }
123 
139  COO(const size_t M, const size_t N, const size_t NNZ, const int *row,
140  const int *col, const Float *value);
141 
157  COO(const size_t M, const size_t N, const size_t NNZ,
158  const std::vector<int> &row, const std::vector<int> &col,
159  const std::vector<Float> &value) {
160  this = COO(M, N, NNZ, row.data(), col.data(), value.data());
161  }
162 
180  COO(const size_t M, const size_t N, const size_t NNZ,
181  const std::vector<int> &row, const std::vector<int> &col,
182  const vector<Float> &value) {
183  assert(value.get_device_mem_stat() == false);
184  this = COO(M, N, NNZ, row.data(), col.data(), value.data());
185  }
186 
204  COO(const size_t M, const size_t N, const size_t NNZ, const int *row,
205  const int *col, const Float *value, const size_t origin);
206 
224  COO(const size_t M, const size_t N, const size_t NNZ,
225  const std::vector<int> &row, const std::vector<int> &col,
226  const std::vector<Float> &value, const size_t origin) {
227  this = COO(M, N, NNZ, row.data(), col.data(), value.data(), origin);
228  }
229 
238  COO(const matrix::COO<Float> &coo);
239 
249  COO(const matrix::COO<Float> &coo, Float value);
250 
259  void convert(const matrix::CRS<Float> &crs);
260 
269  COO(const matrix::CRS<Float> &crs) {
270  val_create_flag = true;
271  convert(crs);
272  }
273 
282  void convert(const matrix::Dense<Float> &dense);
283 
292  COO(const matrix::Dense<Float> &dense) {
293  val_create_flag = true;
294  convert(dense);
295  }
296 
297  void convert(const matrix::LinearOperator<Float> &linearoperator);
298 
299  COO(const matrix::LinearOperator<Float> &linearoperator) {
300  val_create_flag = true;
301  convert(linearoperator);
302  }
303 
312  void set_row(const size_t M) { rowN = M; };
313 
322  void set_col(const size_t N) { colN = N; };
323 
332  // void set_nnz(const size_t NNZ) { val_nnz = NNZ; };
333 
334  // communication
335  // ///////////////////////////////////////////////////////////////////////////
341  void send() const {
342  throw std::runtime_error("error, GPU util of COO format is not impl. ");
343  };
344 
350  void recv() const {
351  throw std::runtime_error("error, GPU util of COO format is not impl. ");
352  };
353 
359  void device_free() const {};
360 
367  [[nodiscard]] bool get_device_mem_stat() const { return gpu_status; }
368 
374  ~COO() {
375  if (val_create_flag) {
376  if (get_device_mem_stat()) {
377  device_free();
378  }
379  }
380  }
381 
388  [[nodiscard]] const Float *data() const { return val.get(); }
389 
396  [[nodiscard]] Float *data() { return val.get(); }
397 
406  void resize(size_t N, Float Val = 0) {
407  if (get_device_mem_stat()) {
408  throw std::runtime_error("Error, GPU matrix cant use resize");
409  }
410  if (val_create_flag) {
411  std::shared_ptr<Float> tmp(new Float[N], std::default_delete<Float[]>());
412  size_t copy_size = std::min(val_nnz, N);
413  for (size_t i = 0; i < copy_size; ++i) {
414  tmp.get()[i] = data()[i];
415  }
416  for (size_t i = copy_size; i < N; ++i) {
417  tmp.get()[i] = Val;
418  }
419  val = tmp;
420  alloc_nnz = N;
421  val_nnz = N;
422 
423  row_index.resize(N);
424  col_index.resize(N);
425  } else {
426  throw std::runtime_error("Error, not create vector cant use resize");
427  }
428  }
429 
430  // I/O
431  // ///////////////////////////////////////////////////////////////////////////
432 
441  void input_mm(const std::string filename);
442 
451  COO(const std::string filename) { input_mm(filename); }
452 
461  void output_mm(const std::string filename) const;
462 
471  void print_all(bool force_cpu = false) const;
472 
481  void print_all(const std::string filename) const;
482 
490  [[nodiscard]] Float at(const size_t i, const size_t j) const;
491 
499  [[nodiscard]] Float at(const size_t i, const size_t j) {
500  return static_cast<const COO *>(this)->at(i, j);
501  };
502 
515  void set_ptr(const size_t rN, const size_t cN, const std::vector<int> &r,
516  const std::vector<int> &c, const std::vector<Float> &v);
517 
530  void set_ptr(const size_t rN, const size_t cN, const std::vector<int> &r,
531  const std::vector<int> &c, const size_t vsize, const Float *v);
532 
540  [[nodiscard]] size_t get_row() const { return rowN; }
541 
549  [[nodiscard]] size_t get_col() const { return colN; }
550 
558  [[nodiscard]] size_t get_nnz() const { return val_nnz; }
559 
568  void fill(Float value);
569 
578  [[nodiscard]] std::vector<int> &get_row_ptr() { return row_index; }
579 
588  [[nodiscard]] std::vector<int> &get_col_ind() { return col_index; }
589 
598  [[nodiscard]] std::vector<Float> get_val_ptr() {
599  std::vector<Float> val(val_nnz);
600  for (size_t i = 0; i < val_nnz; ++i) {
601  val[i] = data()[i];
602  }
603  return val;
604  }
605 
614  [[nodiscard]] const std::vector<int> &get_row_ptr() const {
615  return row_index;
616  }
617 
626  [[nodiscard]] const std::vector<int> &get_col_ind() const {
627  return col_index;
628  }
629 
638  [[nodiscard]] const std::vector<Float> get_val_ptr() const {
639  std::vector<Float> val(val_nnz);
640  for (size_t i = 0; i < val_nnz; ++i) {
641  val[i] = data()[i];
642  }
643  return val;
644  }
645 
646  // Utility
647  // ///////////////////////////////////////////////////////////////////////////
648 
657  void transpose();
658 
667  void transpose(const COO &B);
668 
676  double get_data_size() const {
677  return 3 * get_nnz() * sizeof(Float) / 1.0e+9;
678  }
679 
687  [[nodiscard]] std::string type() const { return "COO"; }
688 
697  void diag(vector<Float> &vec) const;
698  void diag(view1D<vector<Float>, Float> &vec) const;
699  void diag(view1D<matrix::Dense<Float>, Float> &vec) const;
700  void diag(view1D<tensor::tensor_Dense<Float>, Float> &vec) const;
701 
711  void row(const size_t r, vector<Float> &vec) const;
712  void row(const size_t r, view1D<vector<Float>, Float> &vec) const;
713  void row(const size_t r, view1D<matrix::Dense<Float>, Float> &vec) const;
714  void row(const size_t r,
715  view1D<tensor::tensor_Dense<Float>, Float> &vec) const;
716 
726  void col(const size_t c, vector<Float> &vec) const;
727  void col(const size_t c, view1D<vector<Float>, Float> &vec) const;
728  void col(const size_t c, view1D<matrix::Dense<Float>, Float> &vec) const;
729  void col(const size_t c,
730  view1D<tensor::tensor_Dense<Float>, Float> &vec) const;
731 
733 
744  void operator=(const COO<Float> &mat);
745 
755  [[nodiscard]] Float &operator[](size_t i) {
756  if (get_device_mem_stat()) {
757  throw std::runtime_error("Error, GPU vector cant use operator[]");
758  }
759  return data()[i];
760  }
761 
772  [[nodiscard]] bool equal(const COO<Float> &mat,
773  bool compare_cpu_and_device = false) const;
774 
784  [[nodiscard]] bool operator==(const COO<Float> &mat) const;
785 
795  [[nodiscard]] bool operator!=(const COO<Float> &mat) const;
796 
812  void insert(const size_t m, const size_t n, const Float val);
813 
814 private:
815  void _q_sort(int lo, int hi);
816 
817 public:
826  void sort(bool merge);
827 };
830 } // namespace matrix
831 } // namespace monolish
Coodinate (COO) format Matrix (need to sort)
void diag(view1D< vector< Float >, Float > &vec) const
bool operator!=(const COO< Float > &mat) const
Comparing matrices (A != mat)
void print_all(bool force_cpu=false) const
print all elements to standard I/O
void recv() const
recv data from GPU
Float at(const size_t i, const size_t j) const
Get matrix element (A(i,j))
void convert(const matrix::LinearOperator< Float > &linearoperator)
const Float * data() const
returns a direct pointer to the vector
COO(const size_t M, const size_t N, const size_t NNZ, const int *row, const int *col, const Float *value)
Create COO matrix from array.
bool equal(const COO< Float > &mat, bool compare_cpu_and_device=false) const
Comparing matrices (A == mat)
void col(const size_t c, view1D< tensor::tensor_Dense< Float >, Float > &vec) const
void operator=(const COO< Float > &mat)
matrix copy
void transpose(const COO &B)
create transposed matrix from COO matrix (B = A^T)
void fill(Float value)
fill matrix elements with a scalar value
COO(const std::string filename)
Create COO matrix from MatrixMarket format file (only real general) (MatrixMarket format: https://mat...
void col(const size_t c, view1D< vector< Float >, Float > &vec) const
void transpose()
get transposed matrix (A^T)
COO(const matrix::CRS< Float > &crs)
Create COO matrix from CRS matrix.
COO(const matrix::COO< Float > &coo)
Create COO matrix from COO matrix.
std::vector< int > row_index
Coodinate format row index, which stores row numbers of the non-zero elements (size nnz)
void diag(vector< Float > &vec) const
get diag. vector
void print_all(const std::string filename) const
print all elements to file
COO(const matrix::Dense< Float > &dense)
Create COO matrix from Dense matrix (drop zero)
bool operator==(const COO< Float > &mat) const
Comparing matrices (A == mat)
void set_col(const size_t N)
Set col number.
const std::vector< Float > get_val_ptr() const
get value
void col(const size_t c, vector< Float > &vec) const
get column vector
void set_ptr(const size_t rN, const size_t cN, const std::vector< int > &r, const std::vector< int > &c, const size_t vsize, const Float *v)
Set COO array from std::vector.
void sort(bool merge)
sort COO matrix elements (and merge elements)
COO(const matrix::COO< Float > &coo, Float value)
Initialize COO matrix of the same size as input matrix.
~COO()
; free gpu mem.
COO(const size_t M, const size_t N, const size_t NNZ, const std::vector< int > &row, const std::vector< int > &col, const vector< Float > &value)
Create COO matrix from monolish::vector.
std::vector< int > & get_col_ind()
get column index
void col(const size_t c, view1D< matrix::Dense< Float >, Float > &vec) const
COO(const size_t M, const size_t N)
Initialize M x N COO matrix.
void _q_sort(int lo, int hi)
void set_ptr(const size_t rN, const size_t cN, const std::vector< int > &r, const std::vector< int > &c, const std::vector< Float > &v)
Set COO array from std::vector.
void diag(view1D< tensor::tensor_Dense< Float >, Float > &vec) const
const std::vector< int > & get_col_ind() const
get column index
size_t colN
# of col
COO(const size_t M, const size_t N, const size_t NNZ, const std::vector< int > &row, const std::vector< int > &col, const std::vector< Float > &value)
Create COO matrix from std::vector.
std::string type() const
get format name "COO"
void insert(const size_t m, const size_t n, const Float val)
insert element to (m, n)
std::vector< int > & get_row_ptr()
get row index
Float at(const size_t i, const size_t j)
Get matrix element (A(i,j))
void device_free() const
free data on GPU
void input_mm(const std::string filename)
Create COO matrix from MatrixMarket format file (only real general) (MatrixMarket format: https://mat...
std::size_t alloc_nnz
alloced matrix size
COO(const matrix::LinearOperator< Float > &linearoperator)
Float & operator[](size_t i)
reference to the element at position (v[i])
const std::vector< int > & get_row_ptr() const
get row index
bool val_create_flag
matrix create flag;
bool gpu_status
# of non-zero element
size_t val_nnz
# of non-zero element
void resize(size_t N, Float Val=0)
resize matrix value
bool get_device_mem_stat() const
false; // true: sended, false: not send
void row(const size_t r, view1D< vector< Float >, Float > &vec) const
std::vector< Float > get_val_ptr()
get value
size_t get_nnz() const
get # of non-zeros
void row(const size_t r, view1D< tensor::tensor_Dense< Float >, Float > &vec) const
void send() const
Set # of non-zero elements.
size_t rowN
# of row
void convert(const matrix::Dense< Float > &dense)
Create COO matrix from Dense matrix (drop zero)
COO(const size_t M, const size_t N, const size_t NNZ, const std::vector< int > &row, const std::vector< int > &col, const std::vector< Float > &value, const size_t origin)
Create COO matrix from n-origin array.
size_t get_col() const
get # of col
std::shared_ptr< Float > val
Coodinate format value array (pointer), which stores values of the non-zero elements.
void diag(view1D< matrix::Dense< Float >, Float > &vec) const
std::vector< int > col_index
Coodinate format column index, which stores column numbers of the non-zero elements (size nnz)
size_t get_row() const
get # of row
void row(const size_t r, view1D< matrix::Dense< Float >, Float > &vec) const
void row(const size_t r, vector< Float > &vec) const
get row vector
void output_mm(const std::string filename) const
output matrix elements in MatrixMarket format (MatrixMarket format: https://math.nist....
COO(const size_t M, const size_t N, const size_t NNZ, const int *row, const int *col, const Float *value, const size_t origin)
Create COO matrix from n-origin array.
double get_data_size() const
Memory data space required by the matrix.
void convert(const matrix::CRS< Float > &crs)
Create COO matrix from CRS matrix.
Float * data()
returns a direct pointer to the vector
void set_row(const size_t M)
Set row number.
Compressed Row Storage (CRS) format Matrix.
Dense format Matrix.
Linear Operator imitating Matrix.
const Float * data() const
returns a direct pointer to the vector
bool get_device_mem_stat() const
true: sended, false: not send
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