Add ForceLegacy parameter to GpuSparseMatrixWrapper for GpuSeqILU0

This commit is contained in:
Jakob Torben committed 2025-12-05 14:57:08 +01:00
1 parent 20fbf5f637
commit 9515a620d4
5 files changed
+44 -11

No files matched your search

+10 -3
View File
@@ -124,7 +124,9 @@ private:
//! This is the storage for the LU composition.
//! Initially this will have the values of A, but will be
//! modified in the constructor to be the proper LU decomposition.
GpuSparseMatrixWrapper<field_type> m_LU;
//! We use ForceLegacy=true to ensure we always get GpuSparseMatrix (legacy API)
//! because GpuSeqILU0 requires the legacy cuSPARSE API (cusparseBsrilu02*) which needs cusparseMatDescr_t.
GpuSparseMatrixWrapper<field_type, true> m_LU;
GpuVector<field_type> m_temporaryStorage;
@@ -155,7 +157,7 @@ template <typename T, typename std::enable_if_t<!is_gpu_matrix_v<T>, int>>
GpuSeqILU0<M, X, Y, l>::GpuSeqILU0(const M& A, field_type w)
: m_underlyingMatrix(A)
, m_w(w)
, m_LU(GpuSparseMatrixWrapper<field_type>::fromMatrix(detail::makeMatrixWithNonzeroDiagonal(A)))
, m_LU(GpuSparseMatrixWrapper<field_type, true>::fromMatrix(detail::makeMatrixWithNonzeroDiagonal(A)))
, m_temporaryStorage(m_LU.N() * m_LU.blockSize())
, m_descriptionL(detail::createLowerDiagonalDescription())
, m_descriptionU(detail::createUpperDiagonalDescription())
@@ -185,7 +187,12 @@ template <typename T, typename std::enable_if_t<is_gpu_matrix_v<T>, int>>
GpuSeqILU0<M, X, Y, l>::GpuSeqILU0(const M& A, field_type w)
: m_underlyingMatrix(A)
, m_w(w)
, m_LU(A)
, m_LU(A.getNonZeroValues().data(),
A.getRowIndices().data(),
A.getColumnIndices().data(),
A.nonzeroes(),
A.blockSize(),
A.N())
, m_temporaryStorage(m_LU.N() * m_LU.blockSize())
, m_descriptionL(detail::createLowerDiagonalDescription())
, m_descriptionU(detail::createUpperDiagonalDescription())
@@ -185,6 +185,22 @@ GpuSparseMatrix<T>::updateNonzeroValues(const GpuSparseMatrix<T>& matrix)
m_nonZeroElements.copyFromDeviceToDevice(matrix.getNonZeroValues());
}
template <class T>
void
GpuSparseMatrix<T>::updateNonzeroValues(const GpuSparseMatrixGeneric<T>& matrix)
{
detail::validateMatrixCompatibility(nonzeroes(), blockSize(), N(),
matrix.nonzeroes(), matrix.blockSize(), matrix.N());
// For blockSize == 1, use GpuSparseMatrixGeneric
if (m_genericMatrixForBlockSize1) {
m_genericMatrixForBlockSize1->updateNonzeroValues(matrix);
return;
}
m_nonZeroElements.copyFromDeviceToDevice(matrix.getNonZeroValues());
}
template <typename T>
void
GpuSparseMatrix<T>::setUpperTriangular()
@@ -334,6 +334,12 @@ public:
*/
void updateNonzeroValues(const GpuSparseMatrix<T>& matrix);
/**
* @brief updateNonzeroValues updates the non-zero values by using the non-zero values of the supplied matrix
* @param matrix the GpuSparseMatrixGeneric to extract the non-zero values from
* @note This assumes the given matrix has the same sparsity pattern.
*/
void updateNonzeroValues(const GpuSparseMatrixGeneric<T>& matrix);
/**
* @brief Dispatches a function based on the block size of the matrix.
@@ -57,7 +57,7 @@ namespace Opm::gpuistl
* This is a temporary solution, and we should migrate to the new API for all block sizes in the future by
* replacing this class with GpuSparseMatrixGeneric.
*/
template <typename T>
template <typename T, bool ForceLegacy = false>
class GpuSparseMatrixWrapper
{
public:
@@ -68,11 +68,14 @@ public:
Since the generic API for CUDA/HIP is primaryly supported on CUDA 13 (and not yet HIP) for blocked
matrices, places wanting to use blocked matrices can invoke this class which handles which API to use.
Basically we just check if HIP is present, or if we are using cuda and a version prior to 13.
If ForceLegacy is true, always use the legacy API (GpuSparseMatrix) regardless of CUDA version.
*/
#if USE_HIP || (!USE_HIP && CUDA_VERSION < 13000)
using matrix_type = GpuSparseMatrix<T>;
#else
using matrix_type = GpuSparseMatrixGeneric<T>;
using matrix_type = std::conditional_t<ForceLegacy,
GpuSparseMatrix<T>,
GpuSparseMatrixGeneric<T>>;
#endif
// Arrow operator overloads for direct access to the underlying matrix
@@ -177,9 +180,9 @@ public:
* @tparam MatrixType is assumed to be a Dune::BCRSMatrix compatible matrix.
*/
template <class MatrixType>
static GpuSparseMatrixWrapper<T> fromMatrix(const MatrixType& matrix, bool copyNonZeroElementsDirectly = false)
static GpuSparseMatrixWrapper<T, ForceLegacy> fromMatrix(const MatrixType& matrix, bool copyNonZeroElementsDirectly = false)
{
GpuSparseMatrixWrapper<T> gpuSparseMatrixWrapper;
GpuSparseMatrixWrapper<T, ForceLegacy> gpuSparseMatrixWrapper;
gpuSparseMatrixWrapper.m_matrix = std::make_unique<matrix_type>(
matrix_type::fromMatrix(matrix, copyNonZeroElementsDirectly));
return gpuSparseMatrixWrapper;
@@ -382,7 +385,8 @@ public:
* @param matrix the matrix to extract the non-zero values from
* @note This assumes the given matrix has the same sparsity pattern.
*/
void updateNonzeroValues(const GpuSparseMatrixWrapper<T>& matrix)
template <bool OtherForceLegacy>
void updateNonzeroValues(const GpuSparseMatrixWrapper<T, OtherForceLegacy>& matrix)
{
m_matrix->updateNonzeroValues(matrix.get());
}
@@ -28,7 +28,7 @@ namespace Opm::gpuistl
// Forward declarations
template <typename T>
class GpuVector;
template <typename T>
template <typename T, bool ForceLegacy>
class GpuSparseMatrixWrapper;
template <typename T>
class GpuSparseMatrixGeneric;
@@ -45,8 +45,8 @@ template <typename T>
struct is_gpu_type<GpuVector<T>> : std::true_type {
};
template <typename T>
struct is_gpu_type<GpuSparseMatrixWrapper<T>> : std::true_type {
template <typename T, bool ForceLegacy>
struct is_gpu_type<GpuSparseMatrixWrapper<T, ForceLegacy>> : std::true_type {
};
template <typename T>