opm-simulators
kernel_enums.hpp
1 /*
2  Copyright 2024 Equinor ASA
3 
4  This file is part of the Open Porous Media project (OPM).
5 
6  OPM is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  OPM is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with OPM. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #ifndef OPM_GPUISTL_KERNEL_ENUMS_HPP
21 #define OPM_GPUISTL_KERNEL_ENUMS_HPP
22 
23 #include <opm/common/ErrorMacros.hpp>
24 
25 #include <cuda_runtime.h>
26 
27 #if CUDA_VERSION >= 12100
28 #include <fmt/core.h>
29 #else
30 #include <sstream>
31 #endif
32 
33 /*
34  This file organizes a growing amount of different mixed precision options for the preconditioners.
35 */
36 
37 namespace Opm::gpuistl {
38  // Mixed precision schemes used for storing the matrix in GPU memory
39  enum class MatrixStorageMPScheme {
40  DOUBLE_DIAG_DOUBLE_OFFDIAG = 0, // full precision should be default
41  FLOAT_DIAG_FLOAT_OFFDIAG = 1,
42  DOUBLE_DIAG_FLOAT_OFFDIAG = 2
43  };
44 
45  namespace detail {
46  bool isValidMatrixStorageMPScheme(int scheme);
47  }
48 
49  inline MatrixStorageMPScheme makeMatrixStorageMPScheme(int scheme) {
50  if (!detail::isValidMatrixStorageMPScheme(scheme)) {
51 #if CUDA_VERSION >= 12100
52  OPM_THROW(std::invalid_argument,
53  fmt::format(fmt::runtime("Invalid matrix storage mixed precision scheme chosen: {}.\n"
54  "Valid Schemes:\n"
55  "\t0: DOUBLE_DIAG_DOUBLE_OFFDIAG\n"
56  "\t1: FLOAT_DIAG_FLOAT_OFFDIAG\n"
57  "\t2: DOUBLE_DIAG_FLOAT_OFFDIAG"),
58  scheme));
59 #else
60  std::stringstream str;
61  str << "Invalid matrix storage mixed precision scheme chosen: " << scheme << ".\n"
62  << "Valid Schemes:\n"
63  "\t0: DOUBLE_DIAG_DOUBLE_OFFDIAG\n"
64  "\t1: FLOAT_DIAG_FLOAT_OFFDIAG\n"
65  "\t2: DOUBLE_DIAG_FLOAT_OFFDIAG";
66  OPM_THROW(std::invalid_argument, str.str());
67 #endif
68  }
69  return static_cast<MatrixStorageMPScheme>(scheme);
70  }
71 
72  namespace detail {
73 
74  __host__ __device__ constexpr bool storeDiagonalAsFloat(MatrixStorageMPScheme scheme) {
75  switch (scheme) {
76  case MatrixStorageMPScheme::DOUBLE_DIAG_DOUBLE_OFFDIAG:
77  return false;
78  case MatrixStorageMPScheme::FLOAT_DIAG_FLOAT_OFFDIAG:
79  return true;
80  case MatrixStorageMPScheme::DOUBLE_DIAG_FLOAT_OFFDIAG:
81  return false;
82  default:
83  return false;
84  }
85  }
86 
87  __host__ __device__ constexpr bool storeOffDiagonalAsFloat(MatrixStorageMPScheme scheme) {
88  switch (scheme) {
89  case MatrixStorageMPScheme::DOUBLE_DIAG_DOUBLE_OFFDIAG:
90  return false;
91  case MatrixStorageMPScheme::FLOAT_DIAG_FLOAT_OFFDIAG:
92  return true;
93  case MatrixStorageMPScheme::DOUBLE_DIAG_FLOAT_OFFDIAG:
94  return true;
95  default:
96  return false;
97  }
98  }
99 
100  // returns true if we use anything else that the the default double precision for everything
101  __host__ __device__ constexpr bool usingMixedPrecision(MatrixStorageMPScheme scheme) {
102  switch (scheme) {
103  case MatrixStorageMPScheme::DOUBLE_DIAG_DOUBLE_OFFDIAG:
104  return false;
105  case MatrixStorageMPScheme::FLOAT_DIAG_FLOAT_OFFDIAG:
106  return true;
107  case MatrixStorageMPScheme::DOUBLE_DIAG_FLOAT_OFFDIAG:
108  return true;
109  default:
110  return false;
111  }
112  }
113 
114  inline bool isValidMatrixStorageMPScheme(int scheme) {
115  switch (static_cast<MatrixStorageMPScheme>(scheme)) {
116  case MatrixStorageMPScheme::DOUBLE_DIAG_DOUBLE_OFFDIAG:
117  case MatrixStorageMPScheme::FLOAT_DIAG_FLOAT_OFFDIAG:
118  case MatrixStorageMPScheme::DOUBLE_DIAG_FLOAT_OFFDIAG:
119  return true;
120  default:
121  return false;
122  }
123  }
124  }
125 }
126 
127 #endif // OPM_GPUISTL_KERNEL_ENUMS_HPP
A small, fixed‑dimension MiniVector class backed by std::array that can be used in both host and CUD...
Definition: AmgxInterface.hpp:37