XGCa
matrix.hpp
Go to the documentation of this file.
1 #ifndef MATRIX_HPP
2 #define MATRIX_HPP
3 
4 #include "space_settings.hpp"
5 #include "my_mirror_view.hpp"
6 
7 /* The Matrix class stores a sparse matrix. It is initialized in (?) format but can be converted to CSR (Compressed Sparse Row) with the convert_org_to_csr
8  * method.
9  * */
10 template<class Device>
11 class Matrix{
12 
13  using exspace = typename Device::execution_space;
14  public: // temporarily public, for testing
17  Add=1
18  };
19 
20  enum Type{
21  Identity=0
22  };
23 
24  int m;
25  int n;
26  int width; //< max of non-zero element of each row
27  View<double**,CLayout, Device> value;
28  View<int**,CLayout, Device> eindex;
29  View<int*,CLayout, Device> nelement;
30 
31  // use compressed sparse row matrix data structure
32  bool is_csr;
33  int nnz;
34  View<int*,CLayout, Device> csr_ridx;
35  View<double*,CLayout, Device> csr_v;
36  View<int*,CLayout, Device> csr_cidx;
37 
38  public:
39 
40  Matrix(){}
41 
42  Matrix(int m_in,int n_in,int w_in);
43 
44  Matrix(Type matrix_type, int m_in);
45 
46  Matrix(int m_in, int n_in, int w_in, int nnz_in, bool is_csr_in, int* csr_ridx_or_eindex, int* csr_cidx_or_nelement, double* values);
47 
48  // Create a mirror with a different device type
49  template<class Device2>
50  inline Matrix<Device2> mirror() const{
51  Matrix<Device2> mtx;
52 
53  mtx.m = m;
54  mtx.n = n;
55  mtx.width = width;
56  mtx.value = my_mirror_view(value, Device2());
57  mirror_copy(mtx.value, value);
58  mtx.eindex = my_mirror_view(eindex, Device2());
60  mtx.nelement = my_mirror_view(nelement, Device2());
62 
63  mtx.is_csr = is_csr;
64  mtx.nnz = nnz;
65  mtx.csr_ridx = my_mirror_view(csr_ridx, Device2());
67  mtx.csr_v = my_mirror_view(csr_v, Device2());
68  mirror_copy(mtx.csr_v, csr_v);
69  mtx.csr_cidx = my_mirror_view(csr_cidx, Device2());
71  return mtx;
72  }
73 
74  void convert_org_to_csr();
75 
76  // i row index
77  // j column index
78  // value_in is value
79  // flag is whether to replace or add
89  KOKKOS_INLINE_FUNCTION void set_value(int i, int j, double value_in, SetValueOpt flag) const{
90  if(is_csr){
91  DEVICE_PRINTF("\n Error: set_value is only allowed when matrix is not in csr format");
92  return;
93  }
94 
95  // Check matrix indices are valid
96  if(i>=m || j>=n || i<0 || j<0){
97  DEVICE_PRINTF("\n Error: Out of bounds access in set_value");
98  return;
99  }
100 
101  // Loop through indices that have already been assigned
102  for (int l=0; l<nelement(i); l++){
103  if(j==eindex(i,l)-1){ // If this index has already been assigned, replace or add the value (eindex is 1-indexed)
104  if(flag==Replace){
105  value(i,l) = value_in;
106  } else {
107  value(i,l) += value_in;
108  }
109  return; //DONE already -- exit the function
110  }
111  }
112 
113  // If the index has not already been assigned, then we need to add the index
114  // First, check that we have room in our mapping to add another index
115  if(nelement(i) < width){
116  int l=nelement(i);
117  eindex(i,l)=j+1; // 1-indexed
118  value(i,l)=value_in;
119  nelement(i) += 1;
120  }else{
121  DEVICE_PRINTF("\nError in set_value: Not enough memory space for matrix.");
122  DEVICE_PRINTF("\nIncrease width. width=%d but nelement(%d)=%d",width,i,nelement(i));
123  }
124  }
125 
133  KOKKOS_INLINE_FUNCTION void normalize_row(int irow, double norm) const{
134  double sum = 0.0;
135  for(int i=0; i<nelement(irow); i++) sum += value(irow,i);
136  double fac = norm/sum;
137  for(int i=0; i<nelement(irow); i++) value(irow,i) *= fac;
138  }
139 
140 
141  KOKKOS_INLINE_FUNCTION void sort_row(int i) const{
142  for(int j=0; j<nelement(i); j++){
143  // Find smallest index
144  int ein_min = eindex(i,j);
145  double val_min = value(i,j);
146  int k=j;
147  for(int k2=j;k2<nelement(i);k2++){
148  if(eindex(i,k2)<eindex(i,k)){
149  // Save smallest index and value
150  ein_min = eindex(i,k2);
151  val_min = value(i,k2);
152  k = k2;
153  }
154  }
155 
156  // Swap values
157  eindex(i,k) = eindex(i,j);
158  value(i,k) = value(i,j);
159  eindex(i,j) = ein_min;
160  value(i,j) = val_min;
161  }
162  }
163 
164 // private: // Can't be private because there is this cuda error:
165 // The enclosing parent function for an extended __host__ __device__ lambda cannot have private or protected access within its class
166 // There should be some workarounds available if this is a problem.
167 
168  void mult_org(const View<double*,CLayout,Device>& x, const View<double*,Kokkos::LayoutRight,Device>& y) const;
169 
170  void mult_csr(const View<double*,CLayout,Device>& x, const View<double*,Kokkos::LayoutRight,Device>& y) const;
171 
172  void mult_tensor_org(const View<double**,CLayout,Device>& x, const View<double**,Kokkos::LayoutRight,Device>& y) const;
173 
174  void mult_tensor_csr(const View<double**,CLayout,Device>& x, const View<double**,Kokkos::LayoutRight,Device>& y) const;
175 
176  void transpose_mult_org(const View<double*,CLayout,Device>& x, const View<double*,Kokkos::LayoutRight,Device>& y) const;
177 
178  void transpose_mult_csr(const View<double*,CLayout,Device>& x, const View<double*,Kokkos::LayoutRight,Device>& y) const;
179 
180  public:
181 
182  void mult(const View<double*,CLayout,Device>& x,const View<double*,Kokkos::LayoutRight,Device>& y) const;
183 
184  void mult_tensor(const View<double**,CLayout,Device>& x, const View<double**,Kokkos::LayoutRight,Device>& y) const;
185 
186  void transpose_mult(const View<double*,CLayout,Device>& x, const View<double*,Kokkos::LayoutRight,Device>& y) const;
187 
188  void write(const std::string stream_name, const std::string filename) const;
189 };
190 
191 #endif
Definition: matrix.hpp:11
View< int *, CLayout, Device > csr_ridx
row index for CSR - m+1
Definition: matrix.hpp:34
Matrix()
Definition: matrix.hpp:40
void mult_org(const View< double *, CLayout, Device > &x, const View< double *, Kokkos::LayoutRight, Device > &y) const
Definition: matrix.cpp:152
int m
Definition: matrix.hpp:24
void transpose_mult_org(const View< double *, CLayout, Device > &x, const View< double *, Kokkos::LayoutRight, Device > &y) const
Definition: matrix.cpp:189
KOKKOS_INLINE_FUNCTION void normalize_row(int irow, double norm) const
Definition: matrix.hpp:133
void transpose_mult_csr(const View< double *, CLayout, Device > &x, const View< double *, Kokkos::LayoutRight, Device > &y) const
Definition: matrix.cpp:208
void write(const std::string stream_name, const std::string filename) const
Definition: matrix.cpp:326
SetValueOpt
Definition: matrix.hpp:15
@ Replace
Definition: matrix.hpp:16
@ Add
Definition: matrix.hpp:17
void mult_tensor_csr(const View< double **, CLayout, Device > &x, const View< double **, Kokkos::LayoutRight, Device > &y) const
Definition: matrix.cpp:248
typename Device::execution_space exspace
Use execution space where matrix views are allocated.
Definition: matrix.hpp:13
bool is_csr
Whether the matrix is in CSR format.
Definition: matrix.hpp:32
View< double *, CLayout, Device > csr_v
value of CSR - nnz
Definition: matrix.hpp:35
void convert_org_to_csr()
Definition: matrix.cpp:94
KOKKOS_INLINE_FUNCTION void set_value(int i, int j, double value_in, SetValueOpt flag) const
Definition: matrix.hpp:89
void mult_tensor(const View< double **, CLayout, Device > &x, const View< double **, Kokkos::LayoutRight, Device > &y) const
Definition: matrix.cpp:301
View< int *, CLayout, Device > csr_cidx
columun index - nnz
Definition: matrix.hpp:36
void mult_csr(const View< double *, CLayout, Device > &x, const View< double *, Kokkos::LayoutRight, Device > &y) const
Definition: matrix.cpp:170
KOKKOS_INLINE_FUNCTION void sort_row(int i) const
Definition: matrix.hpp:141
View< int **, CLayout, Device > eindex
column index - 1-indexed!!
Definition: matrix.hpp:28
int nnz
if in CSR format, number of (nonzero) values
Definition: matrix.hpp:33
void transpose_mult(const View< double *, CLayout, Device > &x, const View< double *, Kokkos::LayoutRight, Device > &y) const
Definition: matrix.cpp:317
View< double **, CLayout, Device > value
matrix value
Definition: matrix.hpp:27
Matrix< Device2 > mirror() const
Definition: matrix.hpp:50
View< int *, CLayout, Device > nelement
Definition: matrix.hpp:29
void mult_tensor_org(const View< double **, CLayout, Device > &x, const View< double **, Kokkos::LayoutRight, Device > &y) const
Definition: matrix.cpp:227
int width
Definition: matrix.hpp:26
Type
Definition: matrix.hpp:20
@ Identity
Definition: matrix.hpp:21
int n
Definition: matrix.hpp:25
void mult(const View< double *, CLayout, Device > &x, const View< double *, Kokkos::LayoutRight, Device > &y) const
Definition: matrix.cpp:270
void mirror_copy(T1 &view_dest, const T2 &view_src)
Definition: my_mirror_view.hpp:122
View< T *, CLayout, Device > my_mirror_view(const View< T *, CLayout, Device > &view, Device nd)
Definition: my_mirror_view.hpp:14
#define DEVICE_PRINTF(...)
Definition: space_settings.hpp:86