opm-simulators
MiniMatrix.hpp
1 /*
2  Copyright 2025 Equinor ASA
3 
4  This file is part of the Open Porous Media project (OPM).
5  OPM is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9  OPM is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13  You should have received a copy of the GNU General Public License
14  along with OPM. If not, see <http://www.gnu.org/licenses/>.
15 */
16 
17 // Minimal fixed-size matrix class for CUDA kernels
18 #ifndef OPM_MINIMATRIX_HPP
19 #define OPM_MINIMATRIX_HPP
20 #include <array>
21 #include <cstddef>
22 #include <initializer_list>
23 
24 #include <opm/common/utility/gpuDecorators.hpp>
25 #include <opm/simulators/linalg/gpuistl/MiniVector.hpp>
26 #include <opm/simulators/linalg/matrixblock.hh>
27 
28 namespace Opm::gpuistl
29 {
30 
36 template<class T, int dimension>
37 class MiniMatrix {
38 public:
39  using value_type = T;
40  using size_type = std::size_t;
41  using array_type = std::array<T, dimension * dimension>;
42 
46  OPM_HOST_DEVICE MiniMatrix() = default;
47 
52  OPM_HOST_DEVICE MiniMatrix(std::initializer_list<T> init) {
53  size_type i = 0;
54  for (auto it = init.begin(); it != init.end() && i < data_.size(); ++it, ++i)
55  {
56  data_[i] = *it;
57  }
58  }
59 
60  // We need a conversion from CPU based matrix block to these GPU-friendly MiniMatrices
61  // Some copy-to-gpu routines will convert types using this ctor
62  template <class Type, int n, int m>
64  static_assert(n == m, "MiniMatrix can only be constructed from square MatrixBlock");
65  static_assert(n == dimension, "MiniMatrix dimension must match MatrixBlock dimension");
66  for (size_type i = 0; i < dimension; ++i)
67  {
68  for (size_type j = 0; j < dimension; ++j)
69  {
70  (*this)[i][j] = mb[i][j];
71  }
72  }
73  }
74 
75  OPM_HOST_DEVICE MiniMatrix(const T& value) {
76  fill(value);
77  }
78 
84  OPM_HOST_DEVICE T* operator[](size_type row) {
85  return &data_[row * dimension];
86  }
87 
93  OPM_HOST_DEVICE const T* operator[](size_type row) const {
94  return &data_[row * dimension];
95  }
96 
100  OPM_HOST_DEVICE auto begin() { return data_.begin(); }
101 
105  OPM_HOST_DEVICE auto end() { return data_.end(); }
106 
110  OPM_HOST_DEVICE auto begin() const { return data_.begin(); }
111 
115  OPM_HOST_DEVICE auto end() const { return data_.end(); }
116 
120  OPM_HOST_DEVICE T* data() { return data_.data(); }
121 
125  OPM_HOST_DEVICE const T* data() const { return data_.data(); }
126 
131  OPM_HOST_DEVICE void fill(const T& value) {
132  for (auto& x : data_) x = value;
133  }
134 
138  OPM_HOST_DEVICE static constexpr size_type size() { return dimension; }
139 
145  OPM_HOST_DEVICE MiniMatrix& operator+=(const MiniMatrix& other) {
146  for (size_type i = 0; i < data_.size(); ++i)
147  data_[i] += other.data_[i];
148  return *this;
149  }
150 
156  OPM_HOST_DEVICE MiniMatrix operator+(const MiniMatrix& other) const {
157  MiniMatrix result = *this;
158  result += other;
159  return result;
160  }
161 
167  OPM_HOST_DEVICE MiniMatrix& operator-=(const MiniMatrix& other) {
168  for (size_type i = 0; i < data_.size(); ++i)
169  data_[i] -= other.data_[i];
170  return *this;
171  }
172 
178  OPM_HOST_DEVICE MiniMatrix operator-(const MiniMatrix& other) const {
179  MiniMatrix result = *this;
180  result -= other;
181  return result;
182  }
183 
184  OPM_HOST_DEVICE MiniMatrix& operator=(const T& scalar) {
185  for (auto& x : data_)
186  x = scalar;
187  return *this;
188  }
189 
195  OPM_HOST_DEVICE std::array<T, dimension> operator*(const std::array<T, dimension>& x) const {
196  std::array<T, dimension> result{};
197  for (size_type row = 0; row < dimension; ++row) {
198  T sum = T{};
199  for (size_type col = 0; col < dimension; ++col)
200  sum += (*this)[row][col] * x[col];
201  result[row] = sum;
202  }
203  return result;
204  }
205 
211  OPM_HOST_DEVICE MiniMatrix& operator*=(const MiniMatrix& B) {
212  MiniMatrix temp = *this; // Save original values
213  for (size_type row = 0; row < dimension; ++row) {
214  for (size_type col = 0; col < dimension; ++col) {
215  T sum = T{};
216  for (size_type k = 0; k < dimension; ++k)
217  sum += temp[row][k] * B[k][col];
218  (*this)[row][col] = sum;
219  }
220  }
221  return *this;
222  }
223 
229  OPM_HOST_DEVICE MiniMatrix operator*(const MiniMatrix& B) const {
230  MiniMatrix result = *this;
231  result *= B;
232  return result;
233  }
234 
235 
243  for (size_type row = 0; row < dimension; ++row) {
244  T sum = T{};
245  for (size_type col = 0; col < dimension; ++col)
246  sum += (*this)[row][col] * x[col];
247  result[row] = sum;
248  }
249  return result;
250  }
251 
252  OPM_HOST_DEVICE MiniMatrix& operator*=(const T& scalar) {
253  for (auto& x : data_)
254  x *= scalar;
255  return *this;
256  }
257 
258  OPM_HOST_DEVICE MiniMatrix operator+=(const T& scalar) {
259  for (auto& x : data_)
260  x += scalar;
261  return *this;
262  }
263 
264 private:
265  array_type data_;
266 };
267 
268 } // namespace Opm::gpuistl
269 
270 #endif // OPM_MINIMATRIX_HPP
OPM_HOST_DEVICE MiniMatrix(std::initializer_list< T > init)
Constructor from initializer list.
Definition: MiniMatrix.hpp:52
OPM_HOST_DEVICE MiniMatrix & operator+=(const MiniMatrix &other)
Add another matrix to this one (element-wise).
Definition: MiniMatrix.hpp:145
OPM_HOST_DEVICE auto begin()
Get iterator to beginning of data.
Definition: MiniMatrix.hpp:100
OPM_HOST_DEVICE auto end() const
Get const iterator to end of data.
Definition: MiniMatrix.hpp:115
OPM_HOST_DEVICE MiniMatrix operator*(const MiniMatrix &B) const
Matrix-matrix multiplication: C = A * B.
Definition: MiniMatrix.hpp:229
OPM_HOST_DEVICE T * operator[](size_type row)
Access row for further column indexing.
Definition: MiniMatrix.hpp:84
Definition: matrixblock.hh:228
OPM_HOST_DEVICE T * data()
Get pointer to raw data.
Definition: MiniMatrix.hpp:120
OPM_HOST_DEVICE void fill(const T &value)
Fill all elements with a value.
Definition: MiniMatrix.hpp:131
OPM_HOST_DEVICE const T * data() const
Get const pointer to raw data.
Definition: MiniMatrix.hpp:125
A small fixed-size square matrix class for use in CUDA kernels.
Definition: MiniMatrix.hpp:37
OPM_HOST_DEVICE std::array< T, dimension > operator*(const std::array< T, dimension > &x) const
Matrix-vector multiplication: y = A * x.
Definition: MiniMatrix.hpp:195
OPM_HOST_DEVICE auto begin() const
Get const iterator to beginning of data.
Definition: MiniMatrix.hpp:110
OPM_HOST_DEVICE auto end()
Get iterator to end of data.
Definition: MiniMatrix.hpp:105
OPM_HOST_DEVICE MiniMatrix & operator-=(const MiniMatrix &other)
Subtract another matrix from this one (element-wise).
Definition: MiniMatrix.hpp:167
OPM_HOST_DEVICE const T * operator[](size_type row) const
Access row for further column indexing (const version).
Definition: MiniMatrix.hpp:93
A small, fixed‑dimension MiniVector class backed by std::array that can be used in both host and CUD...
Definition: AmgxInterface.hpp:37
OPM_HOST_DEVICE MiniMatrix & operator*=(const MiniMatrix &B)
Matrix-matrix multiplication: C = A * B.
Definition: MiniMatrix.hpp:211
OPM_HOST_DEVICE MiniMatrix()=default
Default constructor.
OPM_HOST_DEVICE Opm::gpuistl::MiniVector< T, dimension > operator*(const Opm::gpuistl::MiniVector< T, dimension > &x) const
Matrix-vector multiplication: y = A * x, with MiniVector.
Definition: MiniMatrix.hpp:241
OPM_HOST_DEVICE MiniMatrix operator-(const MiniMatrix &other) const
Subtract two matrices (element-wise).
Definition: MiniMatrix.hpp:178
OPM_HOST_DEVICE MiniMatrix operator+(const MiniMatrix &other) const
Add two matrices (element-wise).
Definition: MiniMatrix.hpp:156
static OPM_HOST_DEVICE constexpr size_type size()
Get matrix dimension.
Definition: MiniMatrix.hpp:138
Definition: MiniVector.hpp:49