Actual source code: cupmsolverinterface.hpp
1: #pragma once
3: #include <petsc/private/cupmblasinterface.hpp>
4: #include <petsc/private/petscadvancedmacros.h>
6: namespace Petsc
7: {
9: namespace device
10: {
12: namespace cupm
13: {
15: namespace impl
16: {
18: #define PetscCallCUPMSOLVER_(__abort_fn__, __comm__, ...) \
19: do { \
20: PetscStackUpdateLine; \
21: const cupmSolverError_t cupmsolver_stat_p_ = __VA_ARGS__; \
22: if (PetscUnlikely(cupmsolver_stat_p_ != CUPMSOLVER_STATUS_SUCCESS)) { \
23: if (((cupmsolver_stat_p_ == CUPMSOLVER_STATUS_NOT_INITIALIZED) || (cupmsolver_stat_p_ == CUPMSOLVER_STATUS_ALLOC_FAILED) || (cupmsolver_stat_p_ == CUPMSOLVER_STATUS_INTERNAL_ERROR)) && PetscDeviceInitialized(PETSC_DEVICE_CUPM())) { \
24: __abort_fn__(__comm__, PETSC_ERR_GPU_RESOURCE, \
25: "%s error %d (%s). " \
26: "This indicates the GPU may have run out resources", \
27: cupmSolverName(), static_cast<PetscErrorCode>(cupmsolver_stat_p_), cupmSolverGetErrorName(cupmsolver_stat_p_)); \
28: } \
29: __abort_fn__(__comm__, PETSC_ERR_GPU, "%s error %d (%s)", cupmSolverName(), static_cast<PetscErrorCode>(cupmsolver_stat_p_), cupmSolverGetErrorName(cupmsolver_stat_p_)); \
30: } \
31: } while (0)
33: #define PetscCallCUPMSOLVER(...) PetscCallCUPMSOLVER_(SETERRQ, PETSC_COMM_SELF, __VA_ARGS__)
34: #define PetscCallCUPMSOLVERAbort(comm_, ...) PetscCallCUPMSOLVER_(SETERRABORT, comm_, __VA_ARGS__)
36: #ifndef PetscConcat3
37: #define PetscConcat3(a, b, c) PetscConcat(PetscConcat(a, b), c)
38: #endif
40: #if PetscDefined(USE_COMPLEX)
41: #define PETSC_CUPMSOLVER_FP_TYPE_SPECIAL un
42: #else
43: #define PETSC_CUPMSOLVER_FP_TYPE_SPECIAL or
44: #endif // USE_COMPLEX
46: #define PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupm_name, their_prefix, fp_type, suffix) PETSC_CUPM_ALIAS_FUNCTION(cupm_name, PetscConcat3(their_prefix, fp_type, suffix))
48: template <DeviceType>
49: struct SolverInterfaceImpl;
51: #if PetscDefined(HAVE_CUDA)
52: template <>
53: struct PETSC_SINGLE_LIBRARY_VISIBILITY_INTERNAL SolverInterfaceImpl<DeviceType::CUDA> : BlasInterface<DeviceType::CUDA> {
54: // typedefs
55: using cupmSolverHandle_t = cusolverDnHandle_t;
56: using cupmSolverError_t = cusolverStatus_t;
57: using cupmSolverFillMode_t = cublasFillMode_t;
58: using cupmSolverOperation_t = cublasOperation_t;
60: // error codes
61: static const auto CUPMSOLVER_STATUS_SUCCESS = CUSOLVER_STATUS_SUCCESS;
62: static const auto CUPMSOLVER_STATUS_NOT_INITIALIZED = CUSOLVER_STATUS_NOT_INITIALIZED;
63: static const auto CUPMSOLVER_STATUS_ALLOC_FAILED = CUSOLVER_STATUS_ALLOC_FAILED;
64: static const auto CUPMSOLVER_STATUS_INTERNAL_ERROR = CUSOLVER_STATUS_INTERNAL_ERROR;
66: // enums
67: // Why do these exist just to alias the CUBLAS versions? Because AMD -- in their boundless
68: // wisdom -- decided to do so for hipSOLVER...
69: // https://github.com/ROCmSoftwarePlatform/hipSOLVER/blob/develop/library/include/internal/hipsolver-types.h
70: static const auto CUPMSOLVER_OP_T = CUBLAS_OP_T;
71: static const auto CUPMSOLVER_OP_N = CUBLAS_OP_N;
72: static const auto CUPMSOLVER_OP_C = CUBLAS_OP_C;
73: static const auto CUPMSOLVER_FILL_MODE_LOWER = CUBLAS_FILL_MODE_LOWER;
74: static const auto CUPMSOLVER_FILL_MODE_UPPER = CUBLAS_FILL_MODE_UPPER;
75: static const auto CUPMSOLVER_SIDE_LEFT = CUBLAS_SIDE_LEFT;
76: static const auto CUPMSOLVER_SIDE_RIGHT = CUBLAS_SIDE_RIGHT;
78: // utility functions
79: PETSC_CUPM_ALIAS_FUNCTION(cupmSolverCreate, cusolverDnCreate)
80: PETSC_CUPM_ALIAS_FUNCTION(cupmSolverDestroy, cusolverDnDestroy)
81: PETSC_CUPM_ALIAS_FUNCTION(cupmSolverSetStream, cusolverDnSetStream)
82: PETSC_CUPM_ALIAS_FUNCTION(cupmSolverGetStream, cusolverDnGetStream)
84: PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupmSolverXpotrf_bufferSize, cusolverDn, PETSC_CUPMBLAS_FP_TYPE_U, potrf_bufferSize)
85: PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupmSolverXpotrf, cusolverDn, PETSC_CUPMBLAS_FP_TYPE_U, potrf)
87: using cupmBlasInt_t = typename BlasInterface<DeviceType::CUDA>::cupmBlasInt_t;
88: using cupmScalar_t = typename Interface<DeviceType::CUDA>::cupmScalar_t;
90: // to match hipSOLVER version (rocm 5.4.3, CUDA 12.0.1):
91: //
92: // hipsolverStatus_t hipsolverDpotrs_bufferSize(
93: // hipsolverHandle_t handle, hipsolverFillMode_t uplo, int n, int nrhs, double *A, int lda,
94: // double *B, int ldb, int *lwork
95: // )
96: //
97: // hipsolverStatus_t hipsolverDpotrs(
98: // hipsolverHandle_t handle, hipsolverFillMode_t uplo, int n, int nrhs, double *A, int lda,
99: // double *B, int ldb, double *work, int lwork, int *devInfo
100: // )
101: PETSC_NODISCARD static cupmSolverError_t cupmSolverXpotrs_bufferSize(cupmSolverHandle_t /* handle */, cupmSolverFillMode_t /* uplo */, cupmBlasInt_t /* n */, cupmBlasInt_t /* nrhs */, cupmScalar_t * /* A */, cupmBlasInt_t /* lda */, cupmScalar_t * /* B */, cupmBlasInt_t /* ldb */, cupmBlasInt_t *lwork) noexcept
102: {
103: *lwork = 0;
104: return CUPMSOLVER_STATUS_SUCCESS;
105: }
107: PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupmSolverXpotrs_p, cusolverDn, PETSC_CUPMBLAS_FP_TYPE_U, potrs)
109: PETSC_NODISCARD static cupmSolverError_t cupmSolverXpotrs(cupmSolverHandle_t handle, cupmSolverFillMode_t uplo, cupmBlasInt_t n, cupmBlasInt_t nrhs, const cupmScalar_t *A, cupmBlasInt_t lda, cupmScalar_t *B, cupmBlasInt_t ldb, cupmScalar_t * /* work */, cupmBlasInt_t /* lwork */, cupmBlasInt_t *dev_info) noexcept
110: {
111: return cupmSolverXpotrs_p(handle, uplo, n, nrhs, A, lda, B, ldb, dev_info);
112: }
114: PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupmSolverXpotri_bufferSize, cusolverDn, PETSC_CUPMBLAS_FP_TYPE_U, potri_bufferSize)
115: PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupmSolverXpotri, cusolverDn, PETSC_CUPMBLAS_FP_TYPE_U, potri)
117: PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupmSolverXsytrf_bufferSize, cusolverDn, PETSC_CUPMBLAS_FP_TYPE_U, sytrf_bufferSize)
118: PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupmSolverXsytrf, cusolverDn, PETSC_CUPMBLAS_FP_TYPE_U, sytrf)
120: PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupmSolverXgetrf_bufferSize, cusolverDn, PETSC_CUPMBLAS_FP_TYPE_U, getrf_bufferSize)
121: PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupmSolverXgetrf_p, cusolverDn, PETSC_CUPMBLAS_FP_TYPE_U, getrf)
122: // to match hipSOLVER version (rocm 5.4.3, CUDA 12.0.1):
123: //
124: // hipsolverStatus_t hipsolverDgetrf(
125: // hipsolverHandle_t handle, int m, int n, double *A, int lda, double *work, int lwork,
126: // int *devIpiv, int *devInfo
127: // )
128: PETSC_NODISCARD static cupmSolverError_t cupmSolverXgetrf(cupmSolverHandle_t handle, cupmBlasInt_t m, cupmBlasInt_t n, cupmScalar_t *A, cupmBlasInt_t lda, cupmScalar_t *work, cupmBlasInt_t /* lwork */, cupmBlasInt_t *dev_ipiv, cupmBlasInt_t *dev_info) noexcept
129: {
130: return cupmSolverXgetrf_p(handle, m, n, A, lda, work, dev_ipiv, dev_info);
131: }
133: // to match hipSOLVER version (rocm 5.4.3, CUDA 12.0.1):
134: //
135: // hipsolverStatus_t hipsolverDgetrs_bufferSize(
136: // hipsolverHandle_t handle, hipsolverOperation_t trans, int n, int nrhs, double *A,
137: // int lda, int *devIpiv, double *B, int ldb, int *lwork
138: // )
139: //
140: // hipsolverStatus_t hipsolverDgetrs(
141: // hipsolverHandle_t handle, hipsolverOperation_t trans, int n, int nrhs, double *A,
142: // int lda, int *devIpiv, double *B, int ldb, double *work, int lwork, int *devInfo
143: // )
144: PETSC_NODISCARD static cupmSolverError_t cupmSolverXgetrs_bufferSize(cupmSolverHandle_t /* handle */, cupmSolverOperation_t /* op */, cupmBlasInt_t /* n */, cupmBlasInt_t /* nrhs */, cupmScalar_t * /* A */, cupmBlasInt_t /* lda */, cupmBlasInt_t * /* devIpiv */, cupmScalar_t * /* B */, cupmBlasInt_t /* ldb */, cupmBlasInt_t *lwork) noexcept
145: {
146: *lwork = 0;
147: return CUPMSOLVER_STATUS_SUCCESS;
148: }
150: PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupmSolverXgetrs_p, cusolverDn, PETSC_CUPMBLAS_FP_TYPE_U, getrs)
152: PETSC_NODISCARD static cupmSolverError_t cupmSolverXgetrs(cupmSolverHandle_t handle, cupmSolverOperation_t op, cupmBlasInt_t n, cupmBlasInt_t nrhs, cupmScalar_t *A, cupmBlasInt_t lda, cupmBlasInt_t *dev_ipiv, cupmScalar_t *B, cupmBlasInt_t ldb, cupmScalar_t * /* work */, cupmBlasInt_t /* lwork */, cupmBlasInt_t *dev_info) noexcept
153: {
154: return cupmSolverXgetrs_p(handle, op, n, nrhs, A, lda, dev_ipiv, B, ldb, dev_info);
155: }
157: PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupmSolverXgeqrf_bufferSize, cusolverDn, PETSC_CUPMBLAS_FP_TYPE_U, geqrf_bufferSize)
158: PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupmSolverXgeqrf, cusolverDn, PETSC_CUPMBLAS_FP_TYPE_U, geqrf)
160: PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupmSolverXormqr_bufferSize, cusolverDn, PetscConcat(PETSC_CUPMBLAS_FP_TYPE_U, PETSC_CUPMSOLVER_FP_TYPE_SPECIAL), mqr_bufferSize)
161: PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupmSolverXormqr, cusolverDn, PetscConcat(PETSC_CUPMBLAS_FP_TYPE_U, PETSC_CUPMSOLVER_FP_TYPE_SPECIAL), mqr)
163: PETSC_NODISCARD static const char *cupmSolverGetErrorName(cupmSolverError_t status) noexcept { return PetscCUSolverGetErrorName(status); }
164: };
165: #endif
167: #if PetscDefined(HAVE_HIP)
168: template <>
169: struct PETSC_SINGLE_LIBRARY_VISIBILITY_INTERNAL SolverInterfaceImpl<DeviceType::HIP> : BlasInterface<DeviceType::HIP> {
170: // typedefs
171: using cupmSolverHandle_t = hipsolverHandle_t;
172: using cupmSolverError_t = hipsolverStatus_t;
173: using cupmSolverFillMode_t = hipsolverFillMode_t;
174: using cupmSolverOperation_t = hipsolverOperation_t;
176: // error codes
177: static const auto CUPMSOLVER_STATUS_SUCCESS = HIPSOLVER_STATUS_SUCCESS;
178: static const auto CUPMSOLVER_STATUS_NOT_INITIALIZED = HIPSOLVER_STATUS_NOT_INITIALIZED;
179: static const auto CUPMSOLVER_STATUS_ALLOC_FAILED = HIPSOLVER_STATUS_ALLOC_FAILED;
180: static const auto CUPMSOLVER_STATUS_INTERNAL_ERROR = HIPSOLVER_STATUS_INTERNAL_ERROR;
182: // enums
183: static const auto CUPMSOLVER_OP_T = HIPSOLVER_OP_T;
184: static const auto CUPMSOLVER_OP_N = HIPSOLVER_OP_N;
185: static const auto CUPMSOLVER_OP_C = HIPSOLVER_OP_C;
186: static const auto CUPMSOLVER_FILL_MODE_LOWER = HIPSOLVER_FILL_MODE_LOWER;
187: static const auto CUPMSOLVER_FILL_MODE_UPPER = HIPSOLVER_FILL_MODE_UPPER;
188: static const auto CUPMSOLVER_SIDE_LEFT = HIPSOLVER_SIDE_LEFT;
189: static const auto CUPMSOLVER_SIDE_RIGHT = HIPSOLVER_SIDE_RIGHT;
191: PETSC_CUPM_ALIAS_FUNCTION(cupmSolverCreate, hipsolverCreate)
192: PETSC_CUPM_ALIAS_FUNCTION(cupmSolverDestroy, hipsolverDestroy)
193: PETSC_CUPM_ALIAS_FUNCTION(cupmSolverSetStream, hipsolverSetStream)
194: PETSC_CUPM_ALIAS_FUNCTION(cupmSolverGetStream, hipsolverGetStream)
196: PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupmSolverXpotrf_bufferSize, hipsolver, PETSC_CUPMBLAS_FP_TYPE_U, potrf_bufferSize)
197: PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupmSolverXpotrf, hipsolver, PETSC_CUPMBLAS_FP_TYPE_U, potrf)
199: PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupmSolverXpotrs_bufferSize, hipsolver, PETSC_CUPMBLAS_FP_TYPE_U, potrs_bufferSize)
200: PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupmSolverXpotrs, hipsolver, PETSC_CUPMBLAS_FP_TYPE_U, potrs)
202: PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupmSolverXpotri_bufferSize, hipsolver, PETSC_CUPMBLAS_FP_TYPE_U, potri_bufferSize)
203: PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupmSolverXpotri, hipsolver, PETSC_CUPMBLAS_FP_TYPE_U, potri)
205: PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupmSolverXsytrf_bufferSize, hipsolver, PETSC_CUPMBLAS_FP_TYPE_U, sytrf_bufferSize)
206: PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupmSolverXsytrf, hipsolver, PETSC_CUPMBLAS_FP_TYPE_U, sytrf)
208: PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupmSolverXgetrf_bufferSize, hipsolver, PETSC_CUPMBLAS_FP_TYPE_U, getrf_bufferSize)
209: PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupmSolverXgetrf, hipsolver, PETSC_CUPMBLAS_FP_TYPE_U, getrf)
211: PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupmSolverXgetrs_bufferSize, hipsolver, PETSC_CUPMBLAS_FP_TYPE_U, getrs_bufferSize)
212: PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupmSolverXgetrs, hipsolver, PETSC_CUPMBLAS_FP_TYPE_U, getrs)
214: PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupmSolverXgeqrf_bufferSize, hipsolver, PETSC_CUPMBLAS_FP_TYPE_U, geqrf_bufferSize)
215: PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupmSolverXgeqrf, hipsolver, PETSC_CUPMBLAS_FP_TYPE_U, geqrf)
217: PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupmSolverXormqr_bufferSize, hipsolver, PetscConcat(PETSC_CUPMBLAS_FP_TYPE_U, PETSC_CUPMSOLVER_FP_TYPE_SPECIAL), mqr_bufferSize)
218: PETSC_CUPMSOLVER_ALIAS_BLAS_FUNCTION(cupmSolverXormqr, hipsolver, PetscConcat(PETSC_CUPMBLAS_FP_TYPE_U, PETSC_CUPMSOLVER_FP_TYPE_SPECIAL), mqr)
220: PETSC_NODISCARD static const char *cupmSolverGetErrorName(cupmSolverError_t status) noexcept { return PetscHIPSolverGetErrorName(status); }
221: };
222: #endif
224: #define PETSC_CUPMSOLVER_IMPL_CLASS_HEADER(T) \
225: PETSC_CUPMBLAS_INHERIT_INTERFACE_TYPEDEFS_USING(T); \
226: /* introspection */ \
227: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::cupmSolverGetErrorName; \
228: /* types */ \
229: using cupmSolverHandle_t = typename ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::cupmSolverHandle_t; \
230: using cupmSolverError_t = typename ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::cupmSolverError_t; \
231: using cupmSolverFillMode_t = typename ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::cupmSolverFillMode_t; \
232: using cupmSolverOperation_t = typename ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::cupmSolverOperation_t; \
233: /* error codes */ \
234: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::CUPMSOLVER_STATUS_SUCCESS; \
235: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::CUPMSOLVER_STATUS_NOT_INITIALIZED; \
236: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::CUPMSOLVER_STATUS_ALLOC_FAILED; \
237: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::CUPMSOLVER_STATUS_INTERNAL_ERROR; \
238: /* values */ \
239: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::CUPMSOLVER_OP_T; \
240: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::CUPMSOLVER_OP_N; \
241: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::CUPMSOLVER_OP_C; \
242: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::CUPMSOLVER_FILL_MODE_LOWER; \
243: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::CUPMSOLVER_FILL_MODE_UPPER; \
244: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::CUPMSOLVER_SIDE_LEFT; \
245: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::CUPMSOLVER_SIDE_RIGHT; \
246: /* utility functions */ \
247: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::cupmSolverCreate; \
248: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::cupmSolverDestroy; \
249: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::cupmSolverGetStream; \
250: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::cupmSolverSetStream; \
251: /* blas functions */ \
252: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::cupmSolverXpotrf_bufferSize; \
253: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::cupmSolverXpotrf; \
254: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::cupmSolverXpotrs_bufferSize; \
255: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::cupmSolverXpotrs; \
256: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::cupmSolverXpotri_bufferSize; \
257: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::cupmSolverXpotri; \
258: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::cupmSolverXsytrf_bufferSize; \
259: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::cupmSolverXsytrf; \
260: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::cupmSolverXgetrf_bufferSize; \
261: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::cupmSolverXgetrf; \
262: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::cupmSolverXgetrs_bufferSize; \
263: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::cupmSolverXgetrs; \
264: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::cupmSolverXgeqrf_bufferSize; \
265: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::cupmSolverXgeqrf; \
266: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::cupmSolverXormqr_bufferSize; \
267: using ::Petsc::device::cupm::impl::SolverInterfaceImpl<T>::cupmSolverXormqr
269: template <DeviceType T>
270: struct SolverInterface : SolverInterfaceImpl<T> {
271: PETSC_NODISCARD static constexpr const char *cupmSolverName() noexcept { return T == DeviceType::CUDA ? "cusolverDn" : "hipsolver"; }
272: };
274: #define PETSC_CUPMSOLVER_INHERIT_INTERFACE_TYPEDEFS_USING(T) \
275: PETSC_CUPMSOLVER_IMPL_CLASS_HEADER(T); \
276: using ::Petsc::device::cupm::impl::SolverInterface<T>::cupmSolverName
278: #if PetscDefined(HAVE_CUDA)
279: extern template struct PETSC_SINGLE_LIBRARY_VISIBILITY_INTERNAL SolverInterface<DeviceType::CUDA>;
280: #endif
282: #if PetscDefined(HAVE_HIP)
283: extern template struct PETSC_SINGLE_LIBRARY_VISIBILITY_INTERNAL SolverInterface<DeviceType::HIP>;
284: #endif
286: } // namespace impl
288: } // namespace cupm
290: } // namespace device
292: } // namespace Petsc