9 #include <dpsim/GpuSparseAdapter.h>
11 using namespace DPsim;
13 #pragma GCC diagnostic push
14 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
21 cusparseDestroyMatDescr(descr_L);
22 cusparseDestroyMatDescr(descr_U);
23 cusparseDestroyCsrsv2Info(info_L);
24 cusparseDestroyCsrsv2Info(info_U);
27 if (mCusolverhandle !=
nullptr) {
28 cusolverSpDestroy(mCusolverhandle);
32 inline void GpuSparseAdapter::checkCusparseStatus(cusparseStatus_t status,
33 std::string additionalInfo) {
34 if (status != CUSPARSE_STATUS_SUCCESS) {
36 std::cout <<
"Status not success: " << status << std::endl;
41 void GpuSparseAdapter::performFactorization(SparseMatrix &systemMatrix) {
42 cusparseStatus_t csp_status;
43 cusolverStatus_t cso_status;
45 checkCusparseStatus(csp_status,
"cuSparse initialization failed:");
47 if ((cso_status = cusolverSpCreate(&mCusolverhandle)) !=
48 CUSOLVER_STATUS_SUCCESS) {
50 std::cout <<
"cso_status not success" << std::endl;
54 size_t N = systemMatrix.rows();
55 auto hMat = systemMatrix;
61 cusparseMatDescr_t descr_M = 0;
62 csrilu02Info_t info_M = 0;
66 size_t nnz = hMat.nonZeros();
76 checkCusparseStatus(cusparseCreateMatDescr(&descr_M));
78 cusparseSetMatIndexBase(descr_M, CUSPARSE_INDEX_BASE_ZERO));
80 cusparseSetMatType(descr_M, CUSPARSE_MATRIX_TYPE_GENERAL));
82 checkCusparseStatus(cusparseCreateMatDescr(&descr_L));
84 cusparseSetMatIndexBase(descr_L, CUSPARSE_INDEX_BASE_ZERO));
86 cusparseSetMatType(descr_L, CUSPARSE_MATRIX_TYPE_GENERAL));
88 cusparseSetMatFillMode(descr_L, CUSPARSE_FILL_MODE_LOWER));
89 checkCusparseStatus(cusparseSetMatDiagType(descr_L, CUSPARSE_DIAG_TYPE_UNIT));
91 checkCusparseStatus(cusparseCreateMatDescr(&descr_U));
93 cusparseSetMatIndexBase(descr_U, CUSPARSE_INDEX_BASE_ZERO));
95 cusparseSetMatType(descr_U, CUSPARSE_MATRIX_TYPE_GENERAL));
97 cusparseSetMatFillMode(descr_U, CUSPARSE_FILL_MODE_UPPER));
99 cusparseSetMatDiagType(descr_U, CUSPARSE_DIAG_TYPE_NON_UNIT));
103 checkCusparseStatus(cusparseCreateCsrilu02Info(&info_M));
104 checkCusparseStatus(cusparseCreateCsrsv2Info(&info_L));
105 checkCusparseStatus(cusparseCreateCsrsv2Info(&info_U));
111 cso_status = cusolverSpDcsrzfdHost(mCusolverhandle, N, nnz, descr_M,
112 hMat.valuePtr(), hMat.outerIndexPtr(),
113 hMat.innerIndexPtr(), p, &p_nnz);
115 if (cso_status != CUSOLVER_STATUS_SUCCESS) {
119 mTransp = std::unique_ptr<Eigen::PermutationMatrix<Eigen::Dynamic>>(
120 new Eigen::PermutationMatrix<Eigen::Dynamic>(
121 Eigen::Map<Eigen::Matrix<int, Eigen::Dynamic, 1>>(p, N, 1)));
124 hMat = *mTransp * hMat;
127 mSysMat = std::unique_ptr<cuda::CudaMatrix<double, int>>(
130 double *d_csrVal =
mSysMat->val.data();
131 int *d_csrRowPtr =
mSysMat->row.data();
132 int *d_csrColInd =
mSysMat->col.data();
135 int pBufferSize_M, pBufferSize_L, pBufferSize_U;
137 csp_status = cusparseDcsrilu02_bufferSize(
mCusparsehandle, N, nnz, descr_M,
138 d_csrVal, d_csrRowPtr, d_csrColInd,
139 info_M, &pBufferSize_M);
140 checkCusparseStatus(csp_status,
"failed to get cusparse bufferSize:");
142 csp_status = cusparseDcsrsv2_bufferSize(
144 d_csrVal, d_csrRowPtr, d_csrColInd, info_L, &pBufferSize_L);
145 checkCusparseStatus(csp_status,
"failed to get cusparse bufferSize:");
147 csp_status = cusparseDcsrsv2_bufferSize(
149 d_csrVal, d_csrRowPtr, d_csrColInd, info_U, &pBufferSize_U);
150 checkCusparseStatus(csp_status,
"failed to get cusparse bufferSize:");
153 pBufferSize = std::max({pBufferSize_M, pBufferSize_L, pBufferSize_U});
160 csp_status = cusparseDcsrilu02_analysis(
162 info_M, CUSPARSE_SOLVE_POLICY_NO_LEVEL, pBuffer.data());
163 checkCusparseStatus(csp_status,
"failed to analyse cusparse problem:");
166 cusparseXcsrilu02_zeroPivot(
mCusparsehandle, info_M, &structural_zero);
167 if (csp_status == CUSPARSE_STATUS_ZERO_PIVOT) {
169 checkCusparseStatus(csp_status);
170 std::cout <<
"csp_status zero pivot" << std::endl;
174 csp_status = cusparseDcsrsv2_analysis(
176 d_csrVal, d_csrRowPtr, d_csrColInd, info_L,
177 CUSPARSE_SOLVE_POLICY_NO_LEVEL, pBuffer.data());
178 checkCusparseStatus(csp_status,
"failed to analyse cusparse problem:");
180 csp_status = cusparseDcsrsv2_analysis(
182 d_csrVal, d_csrRowPtr, d_csrColInd, info_U,
183 CUSPARSE_SOLVE_POLICY_USE_LEVEL, pBuffer.data());
184 checkCusparseStatus(csp_status,
"failed to analyse cusparse problem:");
188 csp_status = cusparseDcsrilu02(
190 info_M, CUSPARSE_SOLVE_POLICY_NO_LEVEL, pBuffer.data());
191 checkCusparseStatus(csp_status,
"failed to perform cusparse ILU:");
195 if (csp_status == CUSPARSE_STATUS_ZERO_PIVOT) {
197 checkCusparseStatus(csp_status);
198 std::cout <<
"csp_status zero pivot" << std::endl;
204 csp_status = cusparseDestroyCsrilu02Info(info_M);
205 checkCusparseStatus(csp_status,
"failed to destroy info:");
206 csp_status = cusparseDestroyMatDescr(descr_M);
207 checkCusparseStatus(csp_status,
"failed to destroy MatDescr:");
211 SparseMatrix &systemMatrix,
212 std::vector<std::pair<UInt, UInt>> &listVariableSystemMatrixEntries) {
217 performFactorization(systemMatrix);
221 performFactorization(systemMatrix);
225 SparseMatrix &systemMatrix,
226 std::vector<std::pair<UInt, UInt>> &listVariableSystemMatrixEntries) {
227 performFactorization(systemMatrix);
231 Matrix leftSideVector = mRightHandSideVector;
233 cusparseStatus_t csp_status;
234 int size = mRightHandSideVector.rows();
238 mRightHandSideVector = *mTransp * mRightHandSideVector;
239 status = cudaMemcpy(
mGpuRhsVec.data(), &mRightHandSideVector(0),
240 size *
sizeof(Real), cudaMemcpyHostToDevice);
241 if (status != cudaSuccess) {
243 std::cout <<
"status not cudasuccess" << std::endl;
247 const double alpha = 1.;
250 csp_status = cusparseDcsrsv2_solve(
256 checkCusparseStatus(csp_status,
"failed to solve L*z=x:");
259 csp_status = cusparseDcsrsv2_solve(
264 CUSPARSE_SOLVE_POLICY_USE_LEVEL, pBuffer.data());
265 checkCusparseStatus(csp_status,
"failed to solve U*y=z:");
268 status = cudaMemcpy(&(leftSideVector)(0),
mGpuLhsVec.data(),
269 size *
sizeof(Real), cudaMemcpyDeviceToHost);
270 if (status != cudaSuccess) {
272 std::cout <<
"status not cudasuccess" << std::endl;
275 return leftSideVector;
virtual ~GpuSparseAdapter()
Destructor.
virtual void preprocessing(SparseMatrix &systemMatrix, std::vector< std::pair< UInt, UInt >> &listVariableSystemMatrixEntries) override
preprocessing function pre-ordering and scaling the matrix
virtual void refactorize(SparseMatrix &systemMatrix) override
refactorization without partial pivoting
cuda::Vector< double > mGpuLhsVec
LHS-Vector.
cuda::Vector< double > mGpuRhsVec
RHS-Vector.
virtual Matrix solve(Matrix &rightSideVector) override
solution function for a right hand side
virtual void partialRefactorize(SparseMatrix &systemMatrix, std::vector< std::pair< UInt, UInt >> &listVariableSystemMatrixEntries) override
partial refactorization withouth partial pivoting
GpuSparseAdapter()
Constructor.
std::unique_ptr< cuda::CudaMatrix< double, int > > mSysMat
Systemmatrix on Device.
virtual void factorize(SparseMatrix &systemMatrix) override
factorization function with partial pivoting
cuda::Vector< double > mGpuIntermediateVec
Intermediate Vector.
cusparseHandle_t mCusparsehandle
Solver-Handle.