163c07aadSStefano Zampini /* 263c07aadSStefano Zampini Creates hypre ijmatrix from PETSc matrix 363c07aadSStefano Zampini */ 4225daaf8SStefano Zampini 5c6698e78SStefano Zampini #include <petscpkg_version.h> 639accc25SStefano Zampini #include <petsc/private/petschypre.h> 7dd9c0a25Sstefano_zampini #include <petscmathypre.h> 863c07aadSStefano Zampini #include <petsc/private/matimpl.h> 9a4af0ceeSJacob Faibussowitsch #include <petsc/private/deviceimpl.h> 1063c07aadSStefano Zampini #include <../src/mat/impls/hypre/mhypre.h> 1163c07aadSStefano Zampini #include <../src/mat/impls/aij/mpi/mpiaij.h> 1258968eb6SStefano Zampini #include <../src/vec/vec/impls/hypre/vhyp.h> 1358968eb6SStefano Zampini #include <HYPRE.h> 14c1a070e6SStefano Zampini #include <HYPRE_utilities.h> 15cd8bc7baSStefano Zampini #include <_hypre_parcsr_ls.h> 1668ec7858SStefano Zampini #include <_hypre_sstruct_ls.h> 1763c07aadSStefano Zampini 180e6427aaSSatish Balay #if PETSC_PKG_HYPRE_VERSION_LT(2, 18, 0) 190e6427aaSSatish Balay #define hypre_ParCSRMatrixClone(A, B) hypre_ParCSRMatrixCompleteClone(A) 200e6427aaSSatish Balay #endif 210e6427aaSSatish Balay 2263c07aadSStefano Zampini static PetscErrorCode MatHYPRE_CreateFromMat(Mat, Mat_HYPRE *); 2363c07aadSStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixPreallocate(Mat, Mat, HYPRE_IJMatrix); 24b73e3080SStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixCopyIJ_MPIAIJ(Mat, HYPRE_IJMatrix); 25b73e3080SStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixCopyIJ_SeqAIJ(Mat, HYPRE_IJMatrix); 2639accc25SStefano Zampini static PetscErrorCode MatHYPRE_MultKernel_Private(Mat, HYPRE_Complex, Vec, HYPRE_Complex, Vec, PetscBool); 276ea7df73SStefano Zampini static PetscErrorCode MatSetValues_HYPRE(Mat, PetscInt, const PetscInt[], PetscInt, const PetscInt[], const PetscScalar[], InsertMode ins); 2863c07aadSStefano Zampini 29d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatHYPRE_IJMatrixPreallocate(Mat A_d, Mat A_o, HYPRE_IJMatrix ij) 30d71ae5a4SJacob Faibussowitsch { 3163c07aadSStefano Zampini PetscInt i, n_d, n_o; 3263c07aadSStefano Zampini const PetscInt *ia_d, *ia_o; 3363c07aadSStefano Zampini PetscBool done_d = PETSC_FALSE, done_o = PETSC_FALSE; 342cf14000SStefano Zampini HYPRE_Int *nnz_d = NULL, *nnz_o = NULL; 3563c07aadSStefano Zampini 3663c07aadSStefano Zampini PetscFunctionBegin; 3763c07aadSStefano Zampini if (A_d) { /* determine number of nonzero entries in local diagonal part */ 389566063dSJacob Faibussowitsch PetscCall(MatGetRowIJ(A_d, 0, PETSC_FALSE, PETSC_FALSE, &n_d, &ia_d, NULL, &done_d)); 3963c07aadSStefano Zampini if (done_d) { 409566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n_d, &nnz_d)); 41ad540459SPierre Jolivet for (i = 0; i < n_d; i++) nnz_d[i] = ia_d[i + 1] - ia_d[i]; 4263c07aadSStefano Zampini } 439566063dSJacob Faibussowitsch PetscCall(MatRestoreRowIJ(A_d, 0, PETSC_FALSE, PETSC_FALSE, NULL, &ia_d, NULL, &done_d)); 4463c07aadSStefano Zampini } 4563c07aadSStefano Zampini if (A_o) { /* determine number of nonzero entries in local off-diagonal part */ 469566063dSJacob Faibussowitsch PetscCall(MatGetRowIJ(A_o, 0, PETSC_FALSE, PETSC_FALSE, &n_o, &ia_o, NULL, &done_o)); 4763c07aadSStefano Zampini if (done_o) { 489566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n_o, &nnz_o)); 49ad540459SPierre Jolivet for (i = 0; i < n_o; i++) nnz_o[i] = ia_o[i + 1] - ia_o[i]; 5063c07aadSStefano Zampini } 519566063dSJacob Faibussowitsch PetscCall(MatRestoreRowIJ(A_o, 0, PETSC_FALSE, PETSC_FALSE, &n_o, &ia_o, NULL, &done_o)); 5263c07aadSStefano Zampini } 5363c07aadSStefano Zampini if (done_d) { /* set number of nonzeros in HYPRE IJ matrix */ 5463c07aadSStefano Zampini if (!done_o) { /* only diagonal part */ 559566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(n_d, &nnz_o)); 5663c07aadSStefano Zampini } 57c6698e78SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2, 16, 0) 58c6698e78SStefano Zampini { /* If we don't do this, the columns of the matrix will be all zeros! */ 59c6698e78SStefano Zampini hypre_AuxParCSRMatrix *aux_matrix; 60c6698e78SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix *)hypre_IJMatrixTranslator(ij); 61c6698e78SStefano Zampini hypre_AuxParCSRMatrixDestroy(aux_matrix); 62c6698e78SStefano Zampini hypre_IJMatrixTranslator(ij) = NULL; 63792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixSetDiagOffdSizes, ij, nnz_d, nnz_o); 6422235d61SPierre Jolivet /* it seems they partially fixed it in 2.19.0 */ 6522235d61SPierre Jolivet #if PETSC_PKG_HYPRE_VERSION_LT(2, 19, 0) 66c6698e78SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix *)hypre_IJMatrixTranslator(ij); 67c6698e78SStefano Zampini hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 1; 6822235d61SPierre Jolivet #endif 69c6698e78SStefano Zampini } 70c6698e78SStefano Zampini #else 71792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixSetDiagOffdSizes, ij, nnz_d, nnz_o); 72c6698e78SStefano Zampini #endif 739566063dSJacob Faibussowitsch PetscCall(PetscFree(nnz_d)); 749566063dSJacob Faibussowitsch PetscCall(PetscFree(nnz_o)); 7563c07aadSStefano Zampini } 763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7763c07aadSStefano Zampini } 7863c07aadSStefano Zampini 79d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatHYPRE_CreateFromMat(Mat A, Mat_HYPRE *hA) 80d71ae5a4SJacob Faibussowitsch { 8163c07aadSStefano Zampini PetscInt rstart, rend, cstart, cend; 8263c07aadSStefano Zampini 8363c07aadSStefano Zampini PetscFunctionBegin; 849566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 859566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 8663c07aadSStefano Zampini rstart = A->rmap->rstart; 8763c07aadSStefano Zampini rend = A->rmap->rend; 8863c07aadSStefano Zampini cstart = A->cmap->rstart; 8963c07aadSStefano Zampini cend = A->cmap->rend; 90ea9ee2c1SPierre Jolivet PetscHYPREInitialize(); 91651b1cf9SStefano Zampini if (hA->ij) { 92651b1cf9SStefano Zampini if (!hA->inner_free) hypre_IJMatrixObject(hA->ij) = NULL; 93651b1cf9SStefano Zampini PetscCallExternal(HYPRE_IJMatrixDestroy, hA->ij); 94651b1cf9SStefano Zampini } 95792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixCreate, hA->comm, rstart, rend - 1, cstart, cend - 1, &hA->ij); 96792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixSetObjectType, hA->ij, HYPRE_PARCSR); 9763c07aadSStefano Zampini { 9863c07aadSStefano Zampini PetscBool same; 9963c07aadSStefano Zampini Mat A_d, A_o; 10063c07aadSStefano Zampini const PetscInt *colmap; 1019566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIAIJ, &same)); 10263c07aadSStefano Zampini if (same) { 1039566063dSJacob Faibussowitsch PetscCall(MatMPIAIJGetSeqAIJ(A, &A_d, &A_o, &colmap)); 1049566063dSJacob Faibussowitsch PetscCall(MatHYPRE_IJMatrixPreallocate(A_d, A_o, hA->ij)); 1053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 10663c07aadSStefano Zampini } 1079566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIBAIJ, &same)); 10863c07aadSStefano Zampini if (same) { 1099566063dSJacob Faibussowitsch PetscCall(MatMPIBAIJGetSeqBAIJ(A, &A_d, &A_o, &colmap)); 1109566063dSJacob Faibussowitsch PetscCall(MatHYPRE_IJMatrixPreallocate(A_d, A_o, hA->ij)); 1113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 11263c07aadSStefano Zampini } 1139566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATSEQAIJ, &same)); 11463c07aadSStefano Zampini if (same) { 1159566063dSJacob Faibussowitsch PetscCall(MatHYPRE_IJMatrixPreallocate(A, NULL, hA->ij)); 1163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 11763c07aadSStefano Zampini } 1189566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATSEQBAIJ, &same)); 11963c07aadSStefano Zampini if (same) { 1209566063dSJacob Faibussowitsch PetscCall(MatHYPRE_IJMatrixPreallocate(A, NULL, hA->ij)); 1213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12263c07aadSStefano Zampini } 12363c07aadSStefano Zampini } 1243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12563c07aadSStefano Zampini } 12663c07aadSStefano Zampini 127b73e3080SStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixCopyIJ(Mat A, HYPRE_IJMatrix ij) 128d71ae5a4SJacob Faibussowitsch { 12963c07aadSStefano Zampini PetscBool flg; 13063c07aadSStefano Zampini 13163c07aadSStefano Zampini PetscFunctionBegin; 1326ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_LT(2, 19, 0) 133792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixInitialize, ij); 1346ea7df73SStefano Zampini #else 135792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixInitialize_v2, ij, HYPRE_MEMORY_HOST); 1366ea7df73SStefano Zampini #endif 1379566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIAIJ, &flg)); 138b73e3080SStefano Zampini if (flg) { 139b73e3080SStefano Zampini PetscCall(MatHYPRE_IJMatrixCopyIJ_MPIAIJ(A, ij)); 1403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 14163c07aadSStefano Zampini } 1429566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATSEQAIJ, &flg)); 14363c07aadSStefano Zampini if (flg) { 144b73e3080SStefano Zampini PetscCall(MatHYPRE_IJMatrixCopyIJ_SeqAIJ(A, ij)); 1453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 14663c07aadSStefano Zampini } 147b73e3080SStefano Zampini PetscCheck(PETSC_FALSE, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "No support for matrix type %s", ((PetscObject)A)->type_name); 14863c07aadSStefano Zampini } 14963c07aadSStefano Zampini 150b73e3080SStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixCopyIJ_SeqAIJ(Mat A, HYPRE_IJMatrix ij) 151d71ae5a4SJacob Faibussowitsch { 15263c07aadSStefano Zampini Mat_SeqAIJ *pdiag = (Mat_SeqAIJ *)A->data; 15358968eb6SStefano Zampini HYPRE_Int type; 15463c07aadSStefano Zampini hypre_ParCSRMatrix *par_matrix; 15563c07aadSStefano Zampini hypre_AuxParCSRMatrix *aux_matrix; 15663c07aadSStefano Zampini hypre_CSRMatrix *hdiag; 1572cf14000SStefano Zampini PetscBool sameint = (PetscBool)(sizeof(PetscInt) == sizeof(HYPRE_Int)); 15863c07aadSStefano Zampini 15963c07aadSStefano Zampini PetscFunctionBegin; 160792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObjectType, ij, &type); 16108401ef6SPierre Jolivet PetscCheck(type == HYPRE_PARCSR, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Only HYPRE_PARCSR is supported"); 162792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, ij, (void **)&par_matrix); 16363c07aadSStefano Zampini hdiag = hypre_ParCSRMatrixDiag(par_matrix); 16463c07aadSStefano Zampini /* 16563c07aadSStefano Zampini this is the Hack part where we monkey directly with the hypre datastructures 16663c07aadSStefano Zampini */ 1672cf14000SStefano Zampini if (sameint) { 1689566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(hdiag->i, pdiag->i, A->rmap->n + 1)); 1699566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(hdiag->j, pdiag->j, pdiag->nz)); 1702cf14000SStefano Zampini } else { 1712cf14000SStefano Zampini PetscInt i; 1722cf14000SStefano Zampini 1732cf14000SStefano Zampini for (i = 0; i < A->rmap->n + 1; i++) hdiag->i[i] = (HYPRE_Int)pdiag->i[i]; 1742cf14000SStefano Zampini for (i = 0; i < pdiag->nz; i++) hdiag->j[i] = (HYPRE_Int)pdiag->j[i]; 1752cf14000SStefano Zampini } 1766ea7df73SStefano Zampini 177ea9daf28SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix *)hypre_IJMatrixTranslator(ij); 17863c07aadSStefano Zampini hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 0; 1793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18063c07aadSStefano Zampini } 18163c07aadSStefano Zampini 182b73e3080SStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixCopyIJ_MPIAIJ(Mat A, HYPRE_IJMatrix ij) 183d71ae5a4SJacob Faibussowitsch { 18463c07aadSStefano Zampini Mat_MPIAIJ *pA = (Mat_MPIAIJ *)A->data; 18563c07aadSStefano Zampini Mat_SeqAIJ *pdiag, *poffd; 18663c07aadSStefano Zampini PetscInt i, *garray = pA->garray, *jj, cstart, *pjj; 1872cf14000SStefano Zampini HYPRE_Int *hjj, type; 18863c07aadSStefano Zampini hypre_ParCSRMatrix *par_matrix; 18963c07aadSStefano Zampini hypre_AuxParCSRMatrix *aux_matrix; 19063c07aadSStefano Zampini hypre_CSRMatrix *hdiag, *hoffd; 1912cf14000SStefano Zampini PetscBool sameint = (PetscBool)(sizeof(PetscInt) == sizeof(HYPRE_Int)); 19263c07aadSStefano Zampini 19363c07aadSStefano Zampini PetscFunctionBegin; 19463c07aadSStefano Zampini pdiag = (Mat_SeqAIJ *)pA->A->data; 19563c07aadSStefano Zampini poffd = (Mat_SeqAIJ *)pA->B->data; 196da81f932SPierre Jolivet /* cstart is only valid for square MPIAIJ laid out in the usual way */ 1979566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(A, &cstart, NULL)); 19863c07aadSStefano Zampini 199792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObjectType, ij, &type); 20008401ef6SPierre Jolivet PetscCheck(type == HYPRE_PARCSR, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Only HYPRE_PARCSR is supported"); 201792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, ij, (void **)&par_matrix); 20263c07aadSStefano Zampini hdiag = hypre_ParCSRMatrixDiag(par_matrix); 20363c07aadSStefano Zampini hoffd = hypre_ParCSRMatrixOffd(par_matrix); 20463c07aadSStefano Zampini 2052cf14000SStefano Zampini if (sameint) { 2069566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(hdiag->i, pdiag->i, pA->A->rmap->n + 1)); 2072cf14000SStefano Zampini } else { 208*f4f49eeaSPierre Jolivet for (i = 0; i < pA->A->rmap->n + 1; i++) hdiag->i[i] = (HYPRE_Int)pdiag->i[i]; 2092cf14000SStefano Zampini } 210b73e3080SStefano Zampini 2112cf14000SStefano Zampini hjj = hdiag->j; 2122cf14000SStefano Zampini pjj = pdiag->j; 213c6698e78SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2, 16, 0) 2142cf14000SStefano Zampini for (i = 0; i < pdiag->nz; i++) hjj[i] = pjj[i]; 215c6698e78SStefano Zampini #else 2162cf14000SStefano Zampini for (i = 0; i < pdiag->nz; i++) hjj[i] = cstart + pjj[i]; 217c6698e78SStefano Zampini #endif 2182cf14000SStefano Zampini if (sameint) { 2199566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(hoffd->i, poffd->i, pA->A->rmap->n + 1)); 2202cf14000SStefano Zampini } else { 221*f4f49eeaSPierre Jolivet for (i = 0; i < pA->A->rmap->n + 1; i++) hoffd->i[i] = (HYPRE_Int)poffd->i[i]; 2222cf14000SStefano Zampini } 2232cf14000SStefano Zampini 22406977982Sstefanozampini jj = (PetscInt *)hoffd->j; 225c6698e78SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2, 16, 0) 226792fecdfSBarry Smith PetscCallExternal(hypre_CSRMatrixBigInitialize, hoffd); 227c6698e78SStefano Zampini jj = (PetscInt *)hoffd->big_j; 228c6698e78SStefano Zampini #endif 2292cf14000SStefano Zampini pjj = poffd->j; 23063c07aadSStefano Zampini for (i = 0; i < poffd->nz; i++) jj[i] = garray[pjj[i]]; 231c6698e78SStefano Zampini 232ea9daf28SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix *)hypre_IJMatrixTranslator(ij); 23363c07aadSStefano Zampini hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 0; 2343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23563c07aadSStefano Zampini } 23663c07aadSStefano Zampini 237d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatConvert_HYPRE_IS(Mat A, MatType mtype, MatReuse reuse, Mat *B) 238d71ae5a4SJacob Faibussowitsch { 239*f4f49eeaSPierre Jolivet Mat_HYPRE *mhA = (Mat_HYPRE *)A->data; 2402df22349SStefano Zampini Mat lA; 2412df22349SStefano Zampini ISLocalToGlobalMapping rl2g, cl2g; 2422df22349SStefano Zampini IS is; 2432df22349SStefano Zampini hypre_ParCSRMatrix *hA; 2442df22349SStefano Zampini hypre_CSRMatrix *hdiag, *hoffd; 2452df22349SStefano Zampini MPI_Comm comm; 24639accc25SStefano Zampini HYPRE_Complex *hdd, *hod, *aa; 24739accc25SStefano Zampini PetscScalar *data; 2482cf14000SStefano Zampini HYPRE_BigInt *col_map_offd; 2492cf14000SStefano Zampini HYPRE_Int *hdi, *hdj, *hoi, *hoj; 2502df22349SStefano Zampini PetscInt *ii, *jj, *iptr, *jptr; 2512df22349SStefano Zampini PetscInt cum, dr, dc, oc, str, stc, nnz, i, jd, jo, M, N; 25258968eb6SStefano Zampini HYPRE_Int type; 25306977982Sstefanozampini MatType lmattype = NULL; 25406977982Sstefanozampini PetscBool freeparcsr = PETSC_FALSE; 2552df22349SStefano Zampini 2562df22349SStefano Zampini PetscFunctionBegin; 257a1787963SStefano Zampini comm = PetscObjectComm((PetscObject)A); 258792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObjectType, mhA->ij, &type); 25908401ef6SPierre Jolivet PetscCheck(type == HYPRE_PARCSR, comm, PETSC_ERR_SUP, "Only HYPRE_PARCSR is supported"); 260792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, mhA->ij, (void **)&hA); 26106977982Sstefanozampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 26206977982Sstefanozampini if (HYPRE_MEMORY_DEVICE == hypre_IJMatrixMemoryLocation(mhA->ij)) { 26306977982Sstefanozampini /* Support by copying back on the host and copy to GPU 26406977982Sstefanozampini Kind of inefficient, but this is the best we can do now */ 26506977982Sstefanozampini #if defined(HYPRE_USING_HIP) 26606977982Sstefanozampini lmattype = MATSEQAIJHIPSPARSE; 26706977982Sstefanozampini #elif defined(HYPRE_USING_CUDA) 26806977982Sstefanozampini lmattype = MATSEQAIJCUSPARSE; 26906977982Sstefanozampini #endif 27006977982Sstefanozampini hA = hypre_ParCSRMatrixClone_v2(hA, 1, HYPRE_MEMORY_HOST); 27106977982Sstefanozampini freeparcsr = PETSC_TRUE; 27206977982Sstefanozampini } 27306977982Sstefanozampini #endif 2742df22349SStefano Zampini M = hypre_ParCSRMatrixGlobalNumRows(hA); 2752df22349SStefano Zampini N = hypre_ParCSRMatrixGlobalNumCols(hA); 2762df22349SStefano Zampini str = hypre_ParCSRMatrixFirstRowIndex(hA); 2772df22349SStefano Zampini stc = hypre_ParCSRMatrixFirstColDiag(hA); 2782df22349SStefano Zampini hdiag = hypre_ParCSRMatrixDiag(hA); 2792df22349SStefano Zampini hoffd = hypre_ParCSRMatrixOffd(hA); 2802df22349SStefano Zampini dr = hypre_CSRMatrixNumRows(hdiag); 2812df22349SStefano Zampini dc = hypre_CSRMatrixNumCols(hdiag); 2822df22349SStefano Zampini nnz = hypre_CSRMatrixNumNonzeros(hdiag); 2832df22349SStefano Zampini hdi = hypre_CSRMatrixI(hdiag); 2842df22349SStefano Zampini hdj = hypre_CSRMatrixJ(hdiag); 2852df22349SStefano Zampini hdd = hypre_CSRMatrixData(hdiag); 2862df22349SStefano Zampini oc = hypre_CSRMatrixNumCols(hoffd); 2872df22349SStefano Zampini nnz += hypre_CSRMatrixNumNonzeros(hoffd); 2882df22349SStefano Zampini hoi = hypre_CSRMatrixI(hoffd); 2892df22349SStefano Zampini hoj = hypre_CSRMatrixJ(hoffd); 2902df22349SStefano Zampini hod = hypre_CSRMatrixData(hoffd); 2912df22349SStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 2922df22349SStefano Zampini PetscInt *aux; 2932df22349SStefano Zampini 2942df22349SStefano Zampini /* generate l2g maps for rows and cols */ 2959566063dSJacob Faibussowitsch PetscCall(ISCreateStride(comm, dr, str, 1, &is)); 2969566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingCreateIS(is, &rl2g)); 2979566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is)); 2982df22349SStefano Zampini col_map_offd = hypre_ParCSRMatrixColMapOffd(hA); 2999566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dc + oc, &aux)); 3002df22349SStefano Zampini for (i = 0; i < dc; i++) aux[i] = i + stc; 3012df22349SStefano Zampini for (i = 0; i < oc; i++) aux[i + dc] = col_map_offd[i]; 3029566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(comm, dc + oc, aux, PETSC_OWN_POINTER, &is)); 3039566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingCreateIS(is, &cl2g)); 3049566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is)); 3052df22349SStefano Zampini /* create MATIS object */ 3069566063dSJacob Faibussowitsch PetscCall(MatCreate(comm, B)); 3079566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*B, dr, dc, M, N)); 3089566063dSJacob Faibussowitsch PetscCall(MatSetType(*B, MATIS)); 3099566063dSJacob Faibussowitsch PetscCall(MatSetLocalToGlobalMapping(*B, rl2g, cl2g)); 3109566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingDestroy(&rl2g)); 3119566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingDestroy(&cl2g)); 3122df22349SStefano Zampini 3132df22349SStefano Zampini /* allocate CSR for local matrix */ 3149566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dr + 1, &iptr)); 3159566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &jptr)); 3169566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &data)); 3172df22349SStefano Zampini } else { 3182df22349SStefano Zampini PetscInt nr; 3192df22349SStefano Zampini PetscBool done; 3209566063dSJacob Faibussowitsch PetscCall(MatISGetLocalMat(*B, &lA)); 3219566063dSJacob Faibussowitsch PetscCall(MatGetRowIJ(lA, 0, PETSC_FALSE, PETSC_FALSE, &nr, (const PetscInt **)&iptr, (const PetscInt **)&jptr, &done)); 32208401ef6SPierre Jolivet PetscCheck(nr == dr, PETSC_COMM_SELF, PETSC_ERR_USER, "Cannot reuse mat: invalid number of rows in local mat! %" PetscInt_FMT " != %" PetscInt_FMT, nr, dr); 32308401ef6SPierre Jolivet PetscCheck(iptr[nr] >= nnz, PETSC_COMM_SELF, PETSC_ERR_USER, "Cannot reuse mat: invalid number of nonzeros in local mat! reuse %" PetscInt_FMT " requested %" PetscInt_FMT, iptr[nr], nnz); 32406977982Sstefanozampini PetscCall(MatSeqAIJGetArrayWrite(lA, &data)); 3252df22349SStefano Zampini } 3262df22349SStefano Zampini /* merge local matrices */ 3272df22349SStefano Zampini ii = iptr; 3282df22349SStefano Zampini jj = jptr; 32939accc25SStefano Zampini aa = (HYPRE_Complex *)data; /* this cast fixes the clang error when doing the assignments below: implicit conversion from 'HYPRE_Complex' (aka '_Complex double') to 'double' is not permitted in C++ */ 3302df22349SStefano Zampini *ii = *(hdi++) + *(hoi++); 3312df22349SStefano Zampini for (jd = 0, jo = 0, cum = 0; *ii < nnz; cum++) { 33239accc25SStefano Zampini PetscScalar *aold = (PetscScalar *)aa; 3332df22349SStefano Zampini PetscInt *jold = jj, nc = jd + jo; 3349371c9d4SSatish Balay for (; jd < *hdi; jd++) { 3359371c9d4SSatish Balay *jj++ = *hdj++; 3369371c9d4SSatish Balay *aa++ = *hdd++; 3379371c9d4SSatish Balay } 3389371c9d4SSatish Balay for (; jo < *hoi; jo++) { 3399371c9d4SSatish Balay *jj++ = *hoj++ + dc; 3409371c9d4SSatish Balay *aa++ = *hod++; 3419371c9d4SSatish Balay } 3422df22349SStefano Zampini *(++ii) = *(hdi++) + *(hoi++); 3439566063dSJacob Faibussowitsch PetscCall(PetscSortIntWithScalarArray(jd + jo - nc, jold, aold)); 3442df22349SStefano Zampini } 3452df22349SStefano Zampini for (; cum < dr; cum++) *(++ii) = nnz; 3462df22349SStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 347a033916dSStefano Zampini Mat_SeqAIJ *a; 348a033916dSStefano Zampini 3499566063dSJacob Faibussowitsch PetscCall(MatCreateSeqAIJWithArrays(PETSC_COMM_SELF, dr, dc + oc, iptr, jptr, data, &lA)); 350a033916dSStefano Zampini /* hack SeqAIJ */ 351*f4f49eeaSPierre Jolivet a = (Mat_SeqAIJ *)lA->data; 352a033916dSStefano Zampini a->free_a = PETSC_TRUE; 353a033916dSStefano Zampini a->free_ij = PETSC_TRUE; 35406977982Sstefanozampini if (lmattype) PetscCall(MatConvert(lA, lmattype, MAT_INPLACE_MATRIX, &lA)); 35506977982Sstefanozampini PetscCall(MatISSetLocalMat(*B, lA)); 3569566063dSJacob Faibussowitsch PetscCall(MatDestroy(&lA)); 35706977982Sstefanozampini } else { 35806977982Sstefanozampini PetscCall(MatSeqAIJRestoreArrayWrite(lA, &data)); 3592df22349SStefano Zampini } 3609566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(*B, MAT_FINAL_ASSEMBLY)); 3619566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(*B, MAT_FINAL_ASSEMBLY)); 36248a46eb9SPierre Jolivet if (reuse == MAT_INPLACE_MATRIX) PetscCall(MatHeaderReplace(A, B)); 36306977982Sstefanozampini if (freeparcsr) PetscCallExternal(hypre_ParCSRMatrixDestroy, hA); 3643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3652df22349SStefano Zampini } 3662df22349SStefano Zampini 36706977982Sstefanozampini static PetscErrorCode MatHYPRE_DestroyCOOMat(Mat mat) 368d71ae5a4SJacob Faibussowitsch { 36906977982Sstefanozampini Mat_HYPRE *hA = (Mat_HYPRE *)mat->data; 37063c07aadSStefano Zampini 37163c07aadSStefano Zampini PetscFunctionBegin; 37206977982Sstefanozampini if (hA->cooMat) { /* If cooMat is present we need to destroy the column indices */ 37306977982Sstefanozampini PetscCall(MatDestroy(&hA->cooMat)); 37406977982Sstefanozampini if (hA->cooMatAttached) { 37506977982Sstefanozampini hypre_CSRMatrix *csr; 37606977982Sstefanozampini hypre_ParCSRMatrix *parcsr; 37706977982Sstefanozampini HYPRE_MemoryLocation mem; 37806977982Sstefanozampini 37906977982Sstefanozampini PetscCallExternal(HYPRE_IJMatrixGetObject, hA->ij, (void **)&parcsr); 38006977982Sstefanozampini csr = hypre_ParCSRMatrixDiag(parcsr); 38106977982Sstefanozampini if (csr) { 38206977982Sstefanozampini mem = hypre_CSRMatrixMemoryLocation(csr); 38306977982Sstefanozampini PetscStackCallExternalVoid("hypre_TFree", hypre_TFree(hypre_CSRMatrixJ(csr), mem)); 38406977982Sstefanozampini PetscStackCallExternalVoid("hypre_TFree", hypre_TFree(hypre_CSRMatrixBigJ(csr), mem)); 385b73e3080SStefano Zampini } 38606977982Sstefanozampini csr = hypre_ParCSRMatrixOffd(parcsr); 38706977982Sstefanozampini if (csr) { 38806977982Sstefanozampini mem = hypre_CSRMatrixMemoryLocation(csr); 38906977982Sstefanozampini PetscStackCallExternalVoid("hypre_TFree", hypre_TFree(hypre_CSRMatrixJ(csr), mem)); 39006977982Sstefanozampini PetscStackCallExternalVoid("hypre_TFree", hypre_TFree(hypre_CSRMatrixBigJ(csr), mem)); 391b73e3080SStefano Zampini } 392b73e3080SStefano Zampini } 39306977982Sstefanozampini } 39406977982Sstefanozampini hA->cooMatAttached = PETSC_FALSE; 395b73e3080SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 396b73e3080SStefano Zampini } 397b73e3080SStefano Zampini 39806977982Sstefanozampini static PetscErrorCode MatHYPRE_CreateCOOMat(Mat mat) 399b73e3080SStefano Zampini { 40006977982Sstefanozampini MPI_Comm comm; 40106977982Sstefanozampini PetscMPIInt size; 40206977982Sstefanozampini PetscLayout rmap, cmap; 40306977982Sstefanozampini Mat_HYPRE *hmat = (Mat_HYPRE *)mat->data; 40406977982Sstefanozampini MatType matType = MATAIJ; /* default type of cooMat */ 405b73e3080SStefano Zampini 406b73e3080SStefano Zampini PetscFunctionBegin; 40706977982Sstefanozampini /* Build an agent matrix cooMat with AIJ format 40806977982Sstefanozampini It has the same sparsity pattern as mat, and also shares the data array with mat. We use cooMat to do the COO work. 40906977982Sstefanozampini */ 41006977982Sstefanozampini PetscCall(PetscObjectGetComm((PetscObject)mat, &comm)); 41106977982Sstefanozampini PetscCallMPI(MPI_Comm_size(comm, &size)); 41206977982Sstefanozampini PetscCall(PetscLayoutSetUp(mat->rmap)); 41306977982Sstefanozampini PetscCall(PetscLayoutSetUp(mat->cmap)); 41406977982Sstefanozampini PetscCall(MatGetLayouts(mat, &rmap, &cmap)); 415b73e3080SStefano Zampini 41606977982Sstefanozampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 41706977982Sstefanozampini if (!mat->boundtocpu) { /* mat will be on device, so will cooMat */ 41806977982Sstefanozampini #if defined(HYPRE_USING_HIP) 41906977982Sstefanozampini matType = MATAIJHIPSPARSE; 42006977982Sstefanozampini #elif defined(HYPRE_USING_CUDA) 42106977982Sstefanozampini matType = MATAIJCUSPARSE; 42206977982Sstefanozampini #else 42306977982Sstefanozampini SETERRQ(comm, PETSC_ERR_SUP, "Do not know the HYPRE device"); 42406977982Sstefanozampini #endif 425b73e3080SStefano Zampini } 42606977982Sstefanozampini #endif 42706977982Sstefanozampini 42806977982Sstefanozampini /* Do COO preallocation through cooMat */ 42906977982Sstefanozampini PetscCall(MatHYPRE_DestroyCOOMat(mat)); 43006977982Sstefanozampini PetscCall(MatCreate(comm, &hmat->cooMat)); 43106977982Sstefanozampini PetscCall(MatSetType(hmat->cooMat, matType)); 43206977982Sstefanozampini PetscCall(MatSetLayouts(hmat->cooMat, rmap, cmap)); 43306977982Sstefanozampini 43406977982Sstefanozampini /* allocate local matrices if needed */ 43506977982Sstefanozampini PetscCall(MatMPIAIJSetPreallocation(hmat->cooMat, 0, NULL, 0, NULL)); 43606977982Sstefanozampini PetscFunctionReturn(PETSC_SUCCESS); 43706977982Sstefanozampini } 43806977982Sstefanozampini 43906977982Sstefanozampini /* Attach cooMat data array to hypre matrix. 44006977982Sstefanozampini When AIJCUPMSPARSE will support raw device pointers and not THRUSTARRAY 44106977982Sstefanozampini we should swap the arrays: i.e., attach hypre matrix array to cooMat 44206977982Sstefanozampini This is because hypre should be in charge of handling the memory, 44306977982Sstefanozampini cooMat is only a way to reuse PETSc COO code. 44406977982Sstefanozampini attaching the memory will then be done at MatSetValuesCOO time and it will dynamically 44506977982Sstefanozampini support hypre matrix migrating to host. 44606977982Sstefanozampini */ 44706977982Sstefanozampini static PetscErrorCode MatHYPRE_AttachCOOMat(Mat mat) 44806977982Sstefanozampini { 44906977982Sstefanozampini Mat_HYPRE *hmat = (Mat_HYPRE *)mat->data; 45006977982Sstefanozampini hypre_CSRMatrix *diag, *offd; 45106977982Sstefanozampini hypre_ParCSRMatrix *parCSR; 45206977982Sstefanozampini HYPRE_MemoryLocation hmem = HYPRE_MEMORY_HOST; 45306977982Sstefanozampini PetscMemType pmem; 45406977982Sstefanozampini Mat A, B; 45506977982Sstefanozampini PetscScalar *a; 45606977982Sstefanozampini PetscMPIInt size; 45706977982Sstefanozampini MPI_Comm comm; 45806977982Sstefanozampini 45906977982Sstefanozampini PetscFunctionBegin; 46006977982Sstefanozampini PetscCheck(hmat->cooMat, PetscObjectComm((PetscObject)mat), PETSC_ERR_PLIB, "HYPRE COO delegate matrix has not been created yet"); 46106977982Sstefanozampini if (hmat->cooMatAttached) PetscFunctionReturn(PETSC_SUCCESS); 46206977982Sstefanozampini PetscCheck(hmat->cooMat->preallocated, PetscObjectComm((PetscObject)mat), PETSC_ERR_PLIB, "HYPRE COO delegate matrix is not preallocated"); 46306977982Sstefanozampini PetscCall(PetscObjectSetName((PetscObject)hmat->cooMat, "_internal_COO_mat_for_hypre")); 46406977982Sstefanozampini PetscCall(PetscObjectGetComm((PetscObject)mat, &comm)); 46506977982Sstefanozampini PetscCallMPI(MPI_Comm_size(comm, &size)); 46606977982Sstefanozampini 46706977982Sstefanozampini /* Alias cooMat's data array to IJMatrix's */ 46806977982Sstefanozampini PetscCallExternal(HYPRE_IJMatrixGetObject, hmat->ij, (void **)&parCSR); 46906977982Sstefanozampini diag = hypre_ParCSRMatrixDiag(parCSR); 47006977982Sstefanozampini offd = hypre_ParCSRMatrixOffd(parCSR); 47106977982Sstefanozampini 47206977982Sstefanozampini A = (size == 1) ? hmat->cooMat : ((Mat_MPIAIJ *)hmat->cooMat->data)->A; 47306977982Sstefanozampini B = (size == 1) ? NULL : ((Mat_MPIAIJ *)hmat->cooMat->data)->B; 47406977982Sstefanozampini 47506977982Sstefanozampini PetscCall(PetscObjectSetName((PetscObject)A, "_internal_COO_mat_for_hypre")); 47606977982Sstefanozampini hmem = hypre_CSRMatrixMemoryLocation(diag); 47706977982Sstefanozampini PetscCall(MatSeqAIJGetCSRAndMemType(A, NULL, NULL, &a, &pmem)); 47806977982Sstefanozampini PetscAssert((PetscMemTypeHost(pmem) && hmem == HYPRE_MEMORY_HOST) || (PetscMemTypeDevice(pmem) && hmem == HYPRE_MEMORY_DEVICE), comm, PETSC_ERR_PLIB, "PETSc and hypre's memory types mismatch"); 47906977982Sstefanozampini PetscStackCallExternalVoid("hypre_TFree", hypre_TFree(hypre_CSRMatrixData(diag), hmem)); 48006977982Sstefanozampini hypre_CSRMatrixData(diag) = (HYPRE_Complex *)a; 48106977982Sstefanozampini hypre_CSRMatrixOwnsData(diag) = 0; /* Take ownership of (j,a) away from hypre. As a result, we need to free them on our own */ 48206977982Sstefanozampini 48306977982Sstefanozampini if (B) { 48406977982Sstefanozampini hmem = hypre_CSRMatrixMemoryLocation(offd); 48506977982Sstefanozampini PetscCall(MatSeqAIJGetCSRAndMemType(B, NULL, NULL, &a, &pmem)); 48606977982Sstefanozampini PetscAssert((PetscMemTypeHost(pmem) && hmem == HYPRE_MEMORY_HOST) || (PetscMemTypeDevice(pmem) && hmem == HYPRE_MEMORY_DEVICE), comm, PETSC_ERR_PLIB, "PETSc and hypre's memory types mismatch"); 48706977982Sstefanozampini PetscStackCallExternalVoid("hypre_TFree", hypre_TFree(hypre_CSRMatrixData(offd), hmem)); 48806977982Sstefanozampini hypre_CSRMatrixData(offd) = (HYPRE_Complex *)a; 48906977982Sstefanozampini hypre_CSRMatrixOwnsData(offd) = 0; 49006977982Sstefanozampini } 49106977982Sstefanozampini hmat->cooMatAttached = PETSC_TRUE; 49206977982Sstefanozampini PetscFunctionReturn(PETSC_SUCCESS); 49306977982Sstefanozampini } 49406977982Sstefanozampini 49506977982Sstefanozampini static PetscErrorCode CSRtoCOO_Private(PetscInt n, const PetscInt ii[], const PetscInt jj[], PetscCount *ncoo, PetscInt **coo_i, PetscInt **coo_j) 49606977982Sstefanozampini { 49706977982Sstefanozampini PetscInt *cooi, *cooj; 49806977982Sstefanozampini 49906977982Sstefanozampini PetscFunctionBegin; 50006977982Sstefanozampini *ncoo = ii[n]; 50106977982Sstefanozampini PetscCall(PetscMalloc2(*ncoo, &cooi, *ncoo, &cooj)); 50206977982Sstefanozampini for (PetscInt i = 0; i < n; i++) { 50306977982Sstefanozampini for (PetscInt j = ii[i]; j < ii[i + 1]; j++) cooi[j] = i; 50406977982Sstefanozampini } 50506977982Sstefanozampini PetscCall(PetscArraycpy(cooj, jj, *ncoo)); 50606977982Sstefanozampini *coo_i = cooi; 50706977982Sstefanozampini *coo_j = cooj; 50806977982Sstefanozampini PetscFunctionReturn(PETSC_SUCCESS); 50906977982Sstefanozampini } 51006977982Sstefanozampini 51106977982Sstefanozampini static PetscErrorCode CSRtoCOO_HYPRE_Int_Private(PetscInt n, const HYPRE_Int ii[], const HYPRE_Int jj[], PetscCount *ncoo, PetscInt **coo_i, PetscInt **coo_j) 51206977982Sstefanozampini { 51306977982Sstefanozampini PetscInt *cooi, *cooj; 51406977982Sstefanozampini 51506977982Sstefanozampini PetscFunctionBegin; 51606977982Sstefanozampini *ncoo = ii[n]; 51706977982Sstefanozampini PetscCall(PetscMalloc2(*ncoo, &cooi, *ncoo, &cooj)); 51806977982Sstefanozampini for (PetscInt i = 0; i < n; i++) { 51906977982Sstefanozampini for (HYPRE_Int j = ii[i]; j < ii[i + 1]; j++) cooi[j] = i; 52006977982Sstefanozampini } 52106977982Sstefanozampini for (PetscCount i = 0; i < *ncoo; i++) cooj[i] = jj[i]; 52206977982Sstefanozampini *coo_i = cooi; 52306977982Sstefanozampini *coo_j = cooj; 52406977982Sstefanozampini PetscFunctionReturn(PETSC_SUCCESS); 52506977982Sstefanozampini } 52606977982Sstefanozampini 52706977982Sstefanozampini static PetscErrorCode MatSeqAIJGetCOO_Private(Mat A, PetscCount *ncoo, PetscInt **coo_i, PetscInt **coo_j) 52806977982Sstefanozampini { 52906977982Sstefanozampini PetscInt n; 53006977982Sstefanozampini const PetscInt *ii, *jj; 53106977982Sstefanozampini PetscBool done; 53206977982Sstefanozampini 53306977982Sstefanozampini PetscFunctionBegin; 53406977982Sstefanozampini PetscCall(MatGetRowIJ(A, 0, PETSC_FALSE, PETSC_FALSE, &n, &ii, &jj, &done)); 53506977982Sstefanozampini PetscCheck(done, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Failure for MatGetRowIJ"); 53606977982Sstefanozampini PetscCall(CSRtoCOO_Private(n, ii, jj, ncoo, coo_i, coo_j)); 53706977982Sstefanozampini PetscCall(MatRestoreRowIJ(A, 0, PETSC_FALSE, PETSC_FALSE, &n, &ii, &jj, &done)); 53806977982Sstefanozampini PetscCheck(done, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Failure for MatRestoreRowIJ"); 53906977982Sstefanozampini PetscFunctionReturn(PETSC_SUCCESS); 54006977982Sstefanozampini } 54106977982Sstefanozampini 54206977982Sstefanozampini static PetscErrorCode hypreCSRMatrixGetCOO_Private(hypre_CSRMatrix *A, PetscCount *ncoo, PetscInt **coo_i, PetscInt **coo_j) 54306977982Sstefanozampini { 54406977982Sstefanozampini PetscInt n = hypre_CSRMatrixNumRows(A); 54506977982Sstefanozampini HYPRE_Int *ii, *jj; 54606977982Sstefanozampini HYPRE_MemoryLocation mem = HYPRE_MEMORY_HOST; 54706977982Sstefanozampini 54806977982Sstefanozampini PetscFunctionBegin; 54906977982Sstefanozampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 55006977982Sstefanozampini mem = hypre_CSRMatrixMemoryLocation(A); 55106977982Sstefanozampini if (mem != HYPRE_MEMORY_HOST) { 55206977982Sstefanozampini PetscCount nnz = hypre_CSRMatrixNumNonzeros(A); 55306977982Sstefanozampini PetscCall(PetscMalloc2(n + 1, &ii, nnz, &jj)); 55406977982Sstefanozampini hypre_TMemcpy(ii, hypre_CSRMatrixI(A), HYPRE_Int, n + 1, HYPRE_MEMORY_HOST, mem); 55506977982Sstefanozampini hypre_TMemcpy(jj, hypre_CSRMatrixJ(A), HYPRE_Int, nnz, HYPRE_MEMORY_HOST, mem); 55606977982Sstefanozampini } else { 55706977982Sstefanozampini #else 55806977982Sstefanozampini { 55906977982Sstefanozampini #endif 56006977982Sstefanozampini ii = hypre_CSRMatrixI(A); 56106977982Sstefanozampini jj = hypre_CSRMatrixJ(A); 56206977982Sstefanozampini } 56306977982Sstefanozampini PetscCall(CSRtoCOO_HYPRE_Int_Private(n, ii, jj, ncoo, coo_i, coo_j)); 56406977982Sstefanozampini if (mem != HYPRE_MEMORY_HOST) PetscCall(PetscFree2(ii, jj)); 56506977982Sstefanozampini PetscFunctionReturn(PETSC_SUCCESS); 56606977982Sstefanozampini } 56706977982Sstefanozampini 56806977982Sstefanozampini static PetscErrorCode MatSetValuesCOOFromCSRMatrix_Private(Mat A, hypre_CSRMatrix *H) 56906977982Sstefanozampini { 57006977982Sstefanozampini PetscBool iscpu = PETSC_TRUE; 57106977982Sstefanozampini PetscScalar *a; 57206977982Sstefanozampini HYPRE_MemoryLocation mem = HYPRE_MEMORY_HOST; 57306977982Sstefanozampini 57406977982Sstefanozampini PetscFunctionBegin; 57506977982Sstefanozampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 57606977982Sstefanozampini mem = hypre_CSRMatrixMemoryLocation(H); 57706977982Sstefanozampini PetscCall(PetscObjectTypeCompare((PetscObject)A, MATSEQAIJ, &iscpu)); 57806977982Sstefanozampini #endif 57906977982Sstefanozampini if (iscpu && mem != HYPRE_MEMORY_HOST) { 58006977982Sstefanozampini PetscCount nnz = hypre_CSRMatrixNumNonzeros(H); 58106977982Sstefanozampini PetscCall(PetscMalloc1(nnz, &a)); 58206977982Sstefanozampini hypre_TMemcpy(a, hypre_CSRMatrixData(H), PetscScalar, nnz, HYPRE_MEMORY_HOST, mem); 58306977982Sstefanozampini } else { 58406977982Sstefanozampini a = (PetscScalar *)hypre_CSRMatrixData(H); 58506977982Sstefanozampini } 58606977982Sstefanozampini PetscCall(MatSetValuesCOO(A, a, INSERT_VALUES)); 58706977982Sstefanozampini if (iscpu && mem != HYPRE_MEMORY_HOST) PetscCall(PetscFree(a)); 588b73e3080SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 589b73e3080SStefano Zampini } 590b73e3080SStefano Zampini 591b73e3080SStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A, MatType type, MatReuse reuse, Mat *B) 592b73e3080SStefano Zampini { 593b73e3080SStefano Zampini MPI_Comm comm = PetscObjectComm((PetscObject)A); 59406977982Sstefanozampini Mat M = NULL, dH = NULL, oH = NULL, dA = NULL, oA = NULL; 595b73e3080SStefano Zampini PetscBool ismpiaij, issbaij, isbaij; 596b73e3080SStefano Zampini Mat_HYPRE *hA; 597b73e3080SStefano Zampini 598b73e3080SStefano Zampini PetscFunctionBegin; 599b73e3080SStefano Zampini PetscCall(PetscObjectTypeCompareAny((PetscObject)A, &issbaij, MATSEQSBAIJ, MATMPIBAIJ, "")); 600b73e3080SStefano Zampini PetscCall(PetscObjectTypeCompareAny((PetscObject)A, &isbaij, MATSEQBAIJ, MATMPIBAIJ, "")); 601b73e3080SStefano Zampini if (isbaij || issbaij) { /* handle BAIJ and SBAIJ */ 602b73e3080SStefano Zampini PetscBool ismpi; 603b73e3080SStefano Zampini MatType newtype; 604b73e3080SStefano Zampini 605b73e3080SStefano Zampini PetscCall(PetscObjectTypeCompareAny((PetscObject)A, &ismpi, MATMPISBAIJ, MATMPIBAIJ, "")); 606b73e3080SStefano Zampini newtype = ismpi ? MATMPIAIJ : MATSEQAIJ; 60763c07aadSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 608b73e3080SStefano Zampini PetscCall(MatConvert(*B, newtype, MAT_INPLACE_MATRIX, B)); 609b73e3080SStefano Zampini PetscCall(MatConvert(A, newtype, MAT_REUSE_MATRIX, B)); 610b73e3080SStefano Zampini PetscCall(MatConvert(*B, MATHYPRE, MAT_INPLACE_MATRIX, B)); 611b73e3080SStefano Zampini } else if (reuse == MAT_INITIAL_MATRIX) { 612b73e3080SStefano Zampini PetscCall(MatConvert(A, newtype, MAT_INITIAL_MATRIX, B)); 613b73e3080SStefano Zampini PetscCall(MatConvert(*B, MATHYPRE, MAT_INPLACE_MATRIX, B)); 61463c07aadSStefano Zampini } else { 615b73e3080SStefano Zampini PetscCall(MatConvert(A, newtype, MAT_INPLACE_MATRIX, &A)); 616b73e3080SStefano Zampini PetscCall(MatConvert(A, MATHYPRE, MAT_INPLACE_MATRIX, &A)); 617b73e3080SStefano Zampini } 618b73e3080SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 619b73e3080SStefano Zampini } 62006977982Sstefanozampini 62106977982Sstefanozampini dA = A; 622b73e3080SStefano Zampini PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIAIJ, &ismpiaij)); 623b73e3080SStefano Zampini if (ismpiaij) PetscCall(MatMPIAIJGetSeqAIJ(A, &dA, &oA, NULL)); 62406977982Sstefanozampini 625b73e3080SStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 62606977982Sstefanozampini PetscCount coo_n; 62706977982Sstefanozampini PetscInt *coo_i, *coo_j; 62806977982Sstefanozampini 6299566063dSJacob Faibussowitsch PetscCall(MatCreate(comm, &M)); 6309566063dSJacob Faibussowitsch PetscCall(MatSetType(M, MATHYPRE)); 6319566063dSJacob Faibussowitsch PetscCall(MatSetSizes(M, A->rmap->n, A->cmap->n, A->rmap->N, A->cmap->N)); 632b73e3080SStefano Zampini PetscCall(MatSetOption(M, MAT_SORTED_FULL, PETSC_TRUE)); 633b73e3080SStefano Zampini PetscCall(MatSetOption(M, MAT_NO_OFF_PROC_ENTRIES, PETSC_TRUE)); 634b73e3080SStefano Zampini 635b73e3080SStefano Zampini hA = (Mat_HYPRE *)M->data; 63606977982Sstefanozampini PetscCall(MatHYPRE_CreateFromMat(A, hA)); 63706977982Sstefanozampini PetscCall(MatHYPRE_IJMatrixCopyIJ(A, hA->ij)); 63806977982Sstefanozampini 63906977982Sstefanozampini PetscCall(MatHYPRE_CreateCOOMat(M)); 64006977982Sstefanozampini 64106977982Sstefanozampini dH = hA->cooMat; 64206977982Sstefanozampini PetscCall(PetscObjectBaseTypeCompare((PetscObject)hA->cooMat, MATMPIAIJ, &ismpiaij)); 64306977982Sstefanozampini if (ismpiaij) PetscCall(MatMPIAIJGetSeqAIJ(hA->cooMat, &dH, &oH, NULL)); 64406977982Sstefanozampini 64506977982Sstefanozampini PetscCall(PetscObjectSetName((PetscObject)dH, "_internal_COO_mat_for_hypre")); 64606977982Sstefanozampini PetscCall(MatSeqAIJGetCOO_Private(dA, &coo_n, &coo_i, &coo_j)); 64706977982Sstefanozampini PetscCall(MatSetPreallocationCOO(dH, coo_n, coo_i, coo_j)); 64806977982Sstefanozampini PetscCall(PetscFree2(coo_i, coo_j)); 64906977982Sstefanozampini if (oH) { 65006977982Sstefanozampini PetscCall(PetscLayoutDestroy(&oH->cmap)); 65106977982Sstefanozampini PetscCall(PetscLayoutCreateFromSizes(PetscObjectComm((PetscObject)oH), oA->cmap->n, oA->cmap->n, 1, &oH->cmap)); 65206977982Sstefanozampini PetscCall(MatSeqAIJGetCOO_Private(oA, &coo_n, &coo_i, &coo_j)); 65306977982Sstefanozampini PetscCall(MatSetPreallocationCOO(oH, coo_n, coo_i, coo_j)); 65406977982Sstefanozampini PetscCall(PetscFree2(coo_i, coo_j)); 65506977982Sstefanozampini } 65606977982Sstefanozampini hA->cooMat->assembled = PETSC_TRUE; 65706977982Sstefanozampini 658b73e3080SStefano Zampini M->preallocated = PETSC_TRUE; 65906977982Sstefanozampini PetscCall(MatAssemblyBegin(M, MAT_FINAL_ASSEMBLY)); 66006977982Sstefanozampini PetscCall(MatAssemblyEnd(M, MAT_FINAL_ASSEMBLY)); 66106977982Sstefanozampini 66206977982Sstefanozampini PetscCall(MatHYPRE_AttachCOOMat(M)); 66384d4e069SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) *B = M; 664b73e3080SStefano Zampini } else M = *B; 665b73e3080SStefano Zampini 666b73e3080SStefano Zampini hA = (Mat_HYPRE *)M->data; 66706977982Sstefanozampini PetscCheck(hA->cooMat, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "HYPRE COO delegate matrix has not been created yet"); 66806977982Sstefanozampini 66906977982Sstefanozampini dH = hA->cooMat; 67006977982Sstefanozampini PetscCall(PetscObjectBaseTypeCompare((PetscObject)hA->cooMat, MATMPIAIJ, &ismpiaij)); 67106977982Sstefanozampini if (ismpiaij) PetscCall(MatMPIAIJGetSeqAIJ(hA->cooMat, &dH, &oH, NULL)); 67206977982Sstefanozampini 67306977982Sstefanozampini PetscScalar *a; 67406977982Sstefanozampini PetscCall(MatSeqAIJGetCSRAndMemType(dA, NULL, NULL, &a, NULL)); 67506977982Sstefanozampini PetscCall(MatSetValuesCOO(dH, a, INSERT_VALUES)); 67606977982Sstefanozampini if (oH) { 67706977982Sstefanozampini PetscCall(MatSeqAIJGetCSRAndMemType(oA, NULL, NULL, &a, NULL)); 67806977982Sstefanozampini PetscCall(MatSetValuesCOO(oH, a, INSERT_VALUES)); 67906977982Sstefanozampini } 680b73e3080SStefano Zampini 68148a46eb9SPierre Jolivet if (reuse == MAT_INPLACE_MATRIX) PetscCall(MatHeaderReplace(A, &M)); 6823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 68363c07aadSStefano Zampini } 68463c07aadSStefano Zampini 685d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatConvert_HYPRE_AIJ(Mat A, MatType mtype, MatReuse reuse, Mat *B) 686d71ae5a4SJacob Faibussowitsch { 68706977982Sstefanozampini Mat M, dA = NULL, oA = NULL; 68863c07aadSStefano Zampini hypre_ParCSRMatrix *parcsr; 68906977982Sstefanozampini hypre_CSRMatrix *dH, *oH; 69063c07aadSStefano Zampini MPI_Comm comm; 69106977982Sstefanozampini PetscBool ismpiaij, isseqaij; 69263c07aadSStefano Zampini 69363c07aadSStefano Zampini PetscFunctionBegin; 69463c07aadSStefano Zampini comm = PetscObjectComm((PetscObject)A); 69563c07aadSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 6969566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompare((PetscObject)*B, MATMPIAIJ, &ismpiaij)); 6979566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompare((PetscObject)*B, MATSEQAIJ, &isseqaij)); 69806977982Sstefanozampini PetscCheck(ismpiaij || isseqaij, comm, PETSC_ERR_SUP, "Only MATMPIAIJ or MATSEQAIJ base types are supported"); 69963c07aadSStefano Zampini } 70006977982Sstefanozampini PetscCall(MatHYPREGetParCSR(A, &parcsr)); 7016ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 70206977982Sstefanozampini if (HYPRE_MEMORY_DEVICE == hypre_ParCSRMatrixMemoryLocation(parcsr)) { 70306977982Sstefanozampini PetscBool isaij; 70406977982Sstefanozampini 70506977982Sstefanozampini PetscCall(PetscStrcmp(mtype, MATAIJ, &isaij)); 70606977982Sstefanozampini if (isaij) { 70706977982Sstefanozampini PetscMPIInt size; 70806977982Sstefanozampini 7099566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 71006977982Sstefanozampini #if defined(HYPRE_USING_HIP) 71106977982Sstefanozampini mtype = size > 1 ? MATMPIAIJHIPSPARSE : MATSEQAIJHIPSPARSE; 71206977982Sstefanozampini #elif defined(HYPRE_USING_CUDA) 71306977982Sstefanozampini mtype = size > 1 ? MATMPIAIJCUSPARSE : MATSEQAIJCUSPARSE; 71406977982Sstefanozampini #else 71506977982Sstefanozampini mtype = size > 1 ? MATMPIAIJ : MATSEQAIJ; 71606977982Sstefanozampini #endif 71763c07aadSStefano Zampini } 71863c07aadSStefano Zampini } 71906977982Sstefanozampini #endif 72006977982Sstefanozampini dH = hypre_ParCSRMatrixDiag(parcsr); 72106977982Sstefanozampini oH = hypre_ParCSRMatrixOffd(parcsr); 7229371c9d4SSatish Balay if (reuse != MAT_REUSE_MATRIX) { 72306977982Sstefanozampini PetscCount coo_n; 72406977982Sstefanozampini PetscInt *coo_i, *coo_j; 72563c07aadSStefano Zampini 72606977982Sstefanozampini PetscCall(MatCreate(comm, &M)); 72706977982Sstefanozampini PetscCall(MatSetType(M, mtype)); 72806977982Sstefanozampini PetscCall(MatSetSizes(M, A->rmap->n, A->cmap->n, A->rmap->N, A->cmap->N)); 72906977982Sstefanozampini PetscCall(MatMPIAIJSetPreallocation(M, 0, NULL, 0, NULL)); 73063c07aadSStefano Zampini 73106977982Sstefanozampini dA = M; 73206977982Sstefanozampini PetscCall(PetscObjectBaseTypeCompare((PetscObject)M, MATMPIAIJ, &ismpiaij)); 73306977982Sstefanozampini if (ismpiaij) PetscCall(MatMPIAIJGetSeqAIJ(M, &dA, &oA, NULL)); 734a16187a7SStefano Zampini 73506977982Sstefanozampini PetscCall(hypreCSRMatrixGetCOO_Private(dH, &coo_n, &coo_i, &coo_j)); 73606977982Sstefanozampini PetscCall(MatSetPreallocationCOO(dA, coo_n, coo_i, coo_j)); 73706977982Sstefanozampini PetscCall(PetscFree2(coo_i, coo_j)); 73806977982Sstefanozampini if (ismpiaij) { 73906977982Sstefanozampini HYPRE_Int nc = hypre_CSRMatrixNumCols(oH); 740a16187a7SStefano Zampini 74106977982Sstefanozampini PetscCall(PetscLayoutDestroy(&oA->cmap)); 74206977982Sstefanozampini PetscCall(PetscLayoutCreateFromSizes(PetscObjectComm((PetscObject)oA), nc, nc, 1, &oA->cmap)); 74306977982Sstefanozampini PetscCall(hypreCSRMatrixGetCOO_Private(oH, &coo_n, &coo_i, &coo_j)); 74406977982Sstefanozampini PetscCall(MatSetPreallocationCOO(oA, coo_n, coo_i, coo_j)); 74506977982Sstefanozampini PetscCall(PetscFree2(coo_i, coo_j)); 746a16187a7SStefano Zampini 74706977982Sstefanozampini /* garray */ 748*f4f49eeaSPierre Jolivet Mat_MPIAIJ *aij = (Mat_MPIAIJ *)M->data; 74906977982Sstefanozampini HYPRE_BigInt *harray = hypre_ParCSRMatrixColMapOffd(parcsr); 75006977982Sstefanozampini PetscInt *garray; 75106977982Sstefanozampini 75206977982Sstefanozampini PetscCall(PetscFree(aij->garray)); 75306977982Sstefanozampini PetscCall(PetscMalloc1(nc, &garray)); 75406977982Sstefanozampini for (HYPRE_Int i = 0; i < nc; i++) garray[i] = (PetscInt)harray[i]; 75506977982Sstefanozampini aij->garray = garray; 75606977982Sstefanozampini PetscCall(MatSetUpMultiply_MPIAIJ(M)); 757a16187a7SStefano Zampini } 75806977982Sstefanozampini if (reuse == MAT_INITIAL_MATRIX) *B = M; 75906977982Sstefanozampini } else M = *B; 760225daaf8SStefano Zampini 76106977982Sstefanozampini dA = M; 76206977982Sstefanozampini PetscCall(PetscObjectBaseTypeCompare((PetscObject)M, MATMPIAIJ, &ismpiaij)); 76306977982Sstefanozampini if (ismpiaij) PetscCall(MatMPIAIJGetSeqAIJ(M, &dA, &oA, NULL)); 76406977982Sstefanozampini PetscCall(MatSetValuesCOOFromCSRMatrix_Private(dA, dH)); 76506977982Sstefanozampini if (oA) PetscCall(MatSetValuesCOOFromCSRMatrix_Private(oA, oH)); 76606977982Sstefanozampini M->assembled = PETSC_TRUE; 76706977982Sstefanozampini if (reuse == MAT_INPLACE_MATRIX) PetscCall(MatHeaderReplace(A, &M)); 7683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 76963c07aadSStefano Zampini } 77063c07aadSStefano Zampini 771d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAIJGetParCSR_Private(Mat A, hypre_ParCSRMatrix **hA) 772d71ae5a4SJacob Faibussowitsch { 773613e5ff0Sstefano_zampini hypre_ParCSRMatrix *tA; 774c1a070e6SStefano Zampini hypre_CSRMatrix *hdiag, *hoffd; 775c1a070e6SStefano Zampini Mat_SeqAIJ *diag, *offd; 7762cf14000SStefano Zampini PetscInt *garray, i, noffd, dnnz, onnz, *row_starts, *col_starts; 777c1a070e6SStefano Zampini MPI_Comm comm = PetscObjectComm((PetscObject)A); 778613e5ff0Sstefano_zampini PetscBool ismpiaij, isseqaij; 7792cf14000SStefano Zampini PetscBool sameint = (PetscBool)(sizeof(PetscInt) == sizeof(HYPRE_Int)); 7806ea7df73SStefano Zampini HYPRE_Int *hdi = NULL, *hdj = NULL, *hoi = NULL, *hoj = NULL; 7815c97c10fSStefano Zampini PetscInt *pdi = NULL, *pdj = NULL, *poi = NULL, *poj = NULL; 78206977982Sstefanozampini PetscBool iscuda, iship; 78306977982Sstefanozampini #if defined(PETSC_HAVE_DEVICE) && defined(PETSC_HAVE_HYPRE_DEVICE) 78406977982Sstefanozampini PetscBool boundtocpu = A->boundtocpu; 78506977982Sstefanozampini #else 78606977982Sstefanozampini PetscBool boundtocpu = PETSC_TRUE; 7876ea7df73SStefano Zampini #endif 788c1a070e6SStefano Zampini 789c1a070e6SStefano Zampini PetscFunctionBegin; 7909566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIAIJ, &ismpiaij)); 7919566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATSEQAIJ, &isseqaij)); 79208401ef6SPierre Jolivet PetscCheck(ismpiaij || isseqaij, comm, PETSC_ERR_SUP, "Unsupported type %s", ((PetscObject)A)->type_name); 79306977982Sstefanozampini PetscCall(PetscObjectTypeCompareAny((PetscObject)A, &iscuda, MATSEQAIJHIPSPARSE, MATMPIAIJCUSPARSE, "")); 79406977982Sstefanozampini PetscCall(PetscObjectTypeCompareAny((PetscObject)A, &iship, MATSEQAIJCUSPARSE, MATMPIAIJHIPSPARSE, "")); 795ea9ee2c1SPierre Jolivet PetscHYPREInitialize(); 796c1a070e6SStefano Zampini if (ismpiaij) { 797*f4f49eeaSPierre Jolivet Mat_MPIAIJ *a = (Mat_MPIAIJ *)A->data; 798c1a070e6SStefano Zampini 799c1a070e6SStefano Zampini diag = (Mat_SeqAIJ *)a->A->data; 800c1a070e6SStefano Zampini offd = (Mat_SeqAIJ *)a->B->data; 80106977982Sstefanozampini if (!boundtocpu && (iscuda || iship)) { 80206977982Sstefanozampini #if defined(HYPRE_USING_CUDA) && defined(PETSC_HAVE_CUDA) 80306977982Sstefanozampini if (iscuda) { 8046ea7df73SStefano Zampini sameint = PETSC_TRUE; 8059566063dSJacob Faibussowitsch PetscCall(MatSeqAIJCUSPARSEGetIJ(a->A, PETSC_FALSE, (const HYPRE_Int **)&hdi, (const HYPRE_Int **)&hdj)); 8069566063dSJacob Faibussowitsch PetscCall(MatSeqAIJCUSPARSEGetIJ(a->B, PETSC_FALSE, (const HYPRE_Int **)&hoi, (const HYPRE_Int **)&hoj)); 80706977982Sstefanozampini } 8086ea7df73SStefano Zampini #endif 80906977982Sstefanozampini #if defined(HYPRE_USING_HIP) && defined(PETSC_HAVE_HIP) 81006977982Sstefanozampini if (iship) { 81106977982Sstefanozampini sameint = PETSC_TRUE; 81206977982Sstefanozampini PetscCall(MatSeqAIJHIPSPARSEGetIJ(a->A, PETSC_FALSE, (const HYPRE_Int **)&hdi, (const HYPRE_Int **)&hdj)); 81306977982Sstefanozampini PetscCall(MatSeqAIJHIPSPARSEGetIJ(a->B, PETSC_FALSE, (const HYPRE_Int **)&hoi, (const HYPRE_Int **)&hoj)); 81406977982Sstefanozampini } 81506977982Sstefanozampini #endif 81606977982Sstefanozampini } else { 81706977982Sstefanozampini boundtocpu = PETSC_TRUE; 8186ea7df73SStefano Zampini pdi = diag->i; 8196ea7df73SStefano Zampini pdj = diag->j; 8206ea7df73SStefano Zampini poi = offd->i; 8216ea7df73SStefano Zampini poj = offd->j; 8226ea7df73SStefano Zampini if (sameint) { 8236ea7df73SStefano Zampini hdi = (HYPRE_Int *)pdi; 8246ea7df73SStefano Zampini hdj = (HYPRE_Int *)pdj; 8256ea7df73SStefano Zampini hoi = (HYPRE_Int *)poi; 8266ea7df73SStefano Zampini hoj = (HYPRE_Int *)poj; 8276ea7df73SStefano Zampini } 8286ea7df73SStefano Zampini } 829c1a070e6SStefano Zampini garray = a->garray; 830c1a070e6SStefano Zampini noffd = a->B->cmap->N; 831c1a070e6SStefano Zampini dnnz = diag->nz; 832c1a070e6SStefano Zampini onnz = offd->nz; 833c1a070e6SStefano Zampini } else { 834c1a070e6SStefano Zampini diag = (Mat_SeqAIJ *)A->data; 835c1a070e6SStefano Zampini offd = NULL; 83606977982Sstefanozampini if (!boundtocpu && (iscuda || iship)) { 83706977982Sstefanozampini #if defined(HYPRE_USING_CUDA) && defined(PETSC_HAVE_CUDA) 83806977982Sstefanozampini if (iscuda) { 8396ea7df73SStefano Zampini sameint = PETSC_TRUE; 8409566063dSJacob Faibussowitsch PetscCall(MatSeqAIJCUSPARSEGetIJ(A, PETSC_FALSE, (const HYPRE_Int **)&hdi, (const HYPRE_Int **)&hdj)); 84106977982Sstefanozampini } 8426ea7df73SStefano Zampini #endif 84306977982Sstefanozampini #if defined(HYPRE_USING_HIP) && defined(PETSC_HAVE_HIP) 84406977982Sstefanozampini if (iship) { 84506977982Sstefanozampini sameint = PETSC_TRUE; 84606977982Sstefanozampini PetscCall(MatSeqAIJHIPSPARSEGetIJ(A, PETSC_FALSE, (const HYPRE_Int **)&hdi, (const HYPRE_Int **)&hdj)); 84706977982Sstefanozampini } 84806977982Sstefanozampini #endif 84906977982Sstefanozampini } else { 85006977982Sstefanozampini boundtocpu = PETSC_TRUE; 8516ea7df73SStefano Zampini pdi = diag->i; 8526ea7df73SStefano Zampini pdj = diag->j; 8536ea7df73SStefano Zampini if (sameint) { 8546ea7df73SStefano Zampini hdi = (HYPRE_Int *)pdi; 8556ea7df73SStefano Zampini hdj = (HYPRE_Int *)pdj; 8566ea7df73SStefano Zampini } 8576ea7df73SStefano Zampini } 858c1a070e6SStefano Zampini garray = NULL; 859c1a070e6SStefano Zampini noffd = 0; 860c1a070e6SStefano Zampini dnnz = diag->nz; 861c1a070e6SStefano Zampini onnz = 0; 862c1a070e6SStefano Zampini } 863225daaf8SStefano Zampini 864c1a070e6SStefano Zampini /* create a temporary ParCSR */ 865c1a070e6SStefano Zampini if (HYPRE_AssumedPartitionCheck()) { 866c1a070e6SStefano Zampini PetscMPIInt myid; 867c1a070e6SStefano Zampini 8689566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &myid)); 869c1a070e6SStefano Zampini row_starts = A->rmap->range + myid; 870c1a070e6SStefano Zampini col_starts = A->cmap->range + myid; 871c1a070e6SStefano Zampini } else { 872c1a070e6SStefano Zampini row_starts = A->rmap->range; 873c1a070e6SStefano Zampini col_starts = A->cmap->range; 874c1a070e6SStefano Zampini } 8752cf14000SStefano Zampini tA = hypre_ParCSRMatrixCreate(comm, A->rmap->N, A->cmap->N, (HYPRE_BigInt *)row_starts, (HYPRE_BigInt *)col_starts, noffd, dnnz, onnz); 876a1d2239cSSatish Balay #if defined(hypre_ParCSRMatrixOwnsRowStarts) 877c1a070e6SStefano Zampini hypre_ParCSRMatrixSetRowStartsOwner(tA, 0); 878c1a070e6SStefano Zampini hypre_ParCSRMatrixSetColStartsOwner(tA, 0); 879a1d2239cSSatish Balay #endif 880c1a070e6SStefano Zampini 881225daaf8SStefano Zampini /* set diagonal part */ 882c1a070e6SStefano Zampini hdiag = hypre_ParCSRMatrixDiag(tA); 8836ea7df73SStefano Zampini if (!sameint) { /* malloc CSR pointers */ 8849566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(A->rmap->n + 1, &hdi, dnnz, &hdj)); 885*f4f49eeaSPierre Jolivet for (i = 0; i < A->rmap->n + 1; i++) hdi[i] = (HYPRE_Int)pdi[i]; 886*f4f49eeaSPierre Jolivet for (i = 0; i < dnnz; i++) hdj[i] = (HYPRE_Int)pdj[i]; 8872cf14000SStefano Zampini } 8886ea7df73SStefano Zampini hypre_CSRMatrixI(hdiag) = hdi; 8896ea7df73SStefano Zampini hypre_CSRMatrixJ(hdiag) = hdj; 89039accc25SStefano Zampini hypre_CSRMatrixData(hdiag) = (HYPRE_Complex *)diag->a; 891c1a070e6SStefano Zampini hypre_CSRMatrixNumNonzeros(hdiag) = diag->nz; 892c1a070e6SStefano Zampini hypre_CSRMatrixSetRownnz(hdiag); 893c1a070e6SStefano Zampini hypre_CSRMatrixSetDataOwner(hdiag, 0); 894c1a070e6SStefano Zampini 8954cf0e950SBarry Smith /* set off-diagonal part */ 896c1a070e6SStefano Zampini hoffd = hypre_ParCSRMatrixOffd(tA); 897c1a070e6SStefano Zampini if (offd) { 8986ea7df73SStefano Zampini if (!sameint) { /* malloc CSR pointers */ 8999566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(A->rmap->n + 1, &hoi, onnz, &hoj)); 900*f4f49eeaSPierre Jolivet for (i = 0; i < A->rmap->n + 1; i++) hoi[i] = (HYPRE_Int)poi[i]; 901*f4f49eeaSPierre Jolivet for (i = 0; i < onnz; i++) hoj[i] = (HYPRE_Int)poj[i]; 9022cf14000SStefano Zampini } 9036ea7df73SStefano Zampini hypre_CSRMatrixI(hoffd) = hoi; 9046ea7df73SStefano Zampini hypre_CSRMatrixJ(hoffd) = hoj; 90539accc25SStefano Zampini hypre_CSRMatrixData(hoffd) = (HYPRE_Complex *)offd->a; 906c1a070e6SStefano Zampini hypre_CSRMatrixNumNonzeros(hoffd) = offd->nz; 907c1a070e6SStefano Zampini hypre_CSRMatrixSetRownnz(hoffd); 908c1a070e6SStefano Zampini hypre_CSRMatrixSetDataOwner(hoffd, 0); 9096ea7df73SStefano Zampini } 9106ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 91106977982Sstefanozampini PetscCallExternal(hypre_ParCSRMatrixInitialize_v2, tA, !boundtocpu ? HYPRE_MEMORY_DEVICE : HYPRE_MEMORY_HOST); 9126ea7df73SStefano Zampini #else 9136ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_LT(2, 18, 0) 914792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixInitialize, tA); 9156ea7df73SStefano Zampini #else 916792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixInitialize_v2, tA, HYPRE_MEMORY_HOST); 9176ea7df73SStefano Zampini #endif 9186ea7df73SStefano Zampini #endif 9196ea7df73SStefano Zampini hypre_TFree(hypre_ParCSRMatrixColMapOffd(tA), HYPRE_MEMORY_HOST); 920c1a070e6SStefano Zampini hypre_ParCSRMatrixSetNumNonzeros(tA); 9212cf14000SStefano Zampini hypre_ParCSRMatrixColMapOffd(tA) = (HYPRE_BigInt *)garray; 922792fecdfSBarry Smith if (!hypre_ParCSRMatrixCommPkg(tA)) PetscCallExternal(hypre_MatvecCommPkgCreate, tA); 923613e5ff0Sstefano_zampini *hA = tA; 9243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 925613e5ff0Sstefano_zampini } 926c1a070e6SStefano Zampini 927d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAIJRestoreParCSR_Private(Mat A, hypre_ParCSRMatrix **hA) 928d71ae5a4SJacob Faibussowitsch { 929613e5ff0Sstefano_zampini hypre_CSRMatrix *hdiag, *hoffd; 9306ea7df73SStefano Zampini PetscBool ismpiaij, sameint = (PetscBool)(sizeof(PetscInt) == sizeof(HYPRE_Int)); 9316ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 9326ea7df73SStefano Zampini PetscBool iscuda = PETSC_FALSE; 9336ea7df73SStefano Zampini #endif 934c1a070e6SStefano Zampini 935613e5ff0Sstefano_zampini PetscFunctionBegin; 9369566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIAIJ, &ismpiaij)); 9376ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 9389566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)A, &iscuda, MATSEQAIJCUSPARSE, MATMPIAIJCUSPARSE, "")); 9396ea7df73SStefano Zampini if (iscuda) sameint = PETSC_TRUE; 9406ea7df73SStefano Zampini #endif 941613e5ff0Sstefano_zampini hdiag = hypre_ParCSRMatrixDiag(*hA); 942613e5ff0Sstefano_zampini hoffd = hypre_ParCSRMatrixOffd(*hA); 9436ea7df73SStefano Zampini /* free temporary memory allocated by PETSc 9446ea7df73SStefano Zampini set pointers to NULL before destroying tA */ 9452cf14000SStefano Zampini if (!sameint) { 9462cf14000SStefano Zampini HYPRE_Int *hi, *hj; 9472cf14000SStefano Zampini 9482cf14000SStefano Zampini hi = hypre_CSRMatrixI(hdiag); 9492cf14000SStefano Zampini hj = hypre_CSRMatrixJ(hdiag); 9509566063dSJacob Faibussowitsch PetscCall(PetscFree2(hi, hj)); 9516ea7df73SStefano Zampini if (ismpiaij) { 9522cf14000SStefano Zampini hi = hypre_CSRMatrixI(hoffd); 9532cf14000SStefano Zampini hj = hypre_CSRMatrixJ(hoffd); 9549566063dSJacob Faibussowitsch PetscCall(PetscFree2(hi, hj)); 9552cf14000SStefano Zampini } 9562cf14000SStefano Zampini } 957c1a070e6SStefano Zampini hypre_CSRMatrixI(hdiag) = NULL; 958c1a070e6SStefano Zampini hypre_CSRMatrixJ(hdiag) = NULL; 959c1a070e6SStefano Zampini hypre_CSRMatrixData(hdiag) = NULL; 9606ea7df73SStefano Zampini if (ismpiaij) { 961c1a070e6SStefano Zampini hypre_CSRMatrixI(hoffd) = NULL; 962c1a070e6SStefano Zampini hypre_CSRMatrixJ(hoffd) = NULL; 963c1a070e6SStefano Zampini hypre_CSRMatrixData(hoffd) = NULL; 9646ea7df73SStefano Zampini } 965613e5ff0Sstefano_zampini hypre_ParCSRMatrixColMapOffd(*hA) = NULL; 966613e5ff0Sstefano_zampini hypre_ParCSRMatrixDestroy(*hA); 967613e5ff0Sstefano_zampini *hA = NULL; 9683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 969613e5ff0Sstefano_zampini } 970613e5ff0Sstefano_zampini 971613e5ff0Sstefano_zampini /* calls RAP from BoomerAMG: 9723dad0653Sstefano_zampini the resulting ParCSR will not own the column and row starts 9736ea7df73SStefano Zampini It looks like we don't need to have the diagonal entries ordered first */ 974d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatHYPRE_ParCSR_RAP(hypre_ParCSRMatrix *hR, hypre_ParCSRMatrix *hA, hypre_ParCSRMatrix *hP, hypre_ParCSRMatrix **hRAP) 975d71ae5a4SJacob Faibussowitsch { 976a1d2239cSSatish Balay #if defined(hypre_ParCSRMatrixOwnsRowStarts) 977613e5ff0Sstefano_zampini HYPRE_Int P_owns_col_starts, R_owns_row_starts; 978a1d2239cSSatish Balay #endif 979613e5ff0Sstefano_zampini 980613e5ff0Sstefano_zampini PetscFunctionBegin; 981a1d2239cSSatish Balay #if defined(hypre_ParCSRMatrixOwnsRowStarts) 982613e5ff0Sstefano_zampini P_owns_col_starts = hypre_ParCSRMatrixOwnsColStarts(hP); 983613e5ff0Sstefano_zampini R_owns_row_starts = hypre_ParCSRMatrixOwnsRowStarts(hR); 984a1d2239cSSatish Balay #endif 9856ea7df73SStefano Zampini /* can be replaced by version test later */ 9866ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 987792fecdfSBarry Smith PetscStackPushExternal("hypre_ParCSRMatrixRAP"); 9886ea7df73SStefano Zampini *hRAP = hypre_ParCSRMatrixRAP(hR, hA, hP); 9896ea7df73SStefano Zampini PetscStackPop; 9906ea7df73SStefano Zampini #else 991792fecdfSBarry Smith PetscCallExternal(hypre_BoomerAMGBuildCoarseOperator, hR, hA, hP, hRAP); 992792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixSetNumNonzeros, *hRAP); 9936ea7df73SStefano Zampini #endif 994613e5ff0Sstefano_zampini /* hypre_BoomerAMGBuildCoarseOperator steals the col_starts from P and the row_starts from R */ 995a1d2239cSSatish Balay #if defined(hypre_ParCSRMatrixOwnsRowStarts) 996613e5ff0Sstefano_zampini hypre_ParCSRMatrixSetRowStartsOwner(*hRAP, 0); 997613e5ff0Sstefano_zampini hypre_ParCSRMatrixSetColStartsOwner(*hRAP, 0); 998613e5ff0Sstefano_zampini if (P_owns_col_starts) hypre_ParCSRMatrixSetColStartsOwner(hP, 1); 999613e5ff0Sstefano_zampini if (R_owns_row_starts) hypre_ParCSRMatrixSetRowStartsOwner(hR, 1); 1000a1d2239cSSatish Balay #endif 10013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1002613e5ff0Sstefano_zampini } 1003613e5ff0Sstefano_zampini 1004d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatPtAPNumeric_AIJ_AIJ_wHYPRE(Mat A, Mat P, Mat C) 1005d71ae5a4SJacob Faibussowitsch { 10066f231fbdSstefano_zampini Mat B; 10076abb4441SStefano Zampini hypre_ParCSRMatrix *hA, *hP, *hPtAP = NULL; 10084222ddf1SHong Zhang Mat_Product *product = C->product; 1009613e5ff0Sstefano_zampini 1010613e5ff0Sstefano_zampini PetscFunctionBegin; 10119566063dSJacob Faibussowitsch PetscCall(MatAIJGetParCSR_Private(A, &hA)); 10129566063dSJacob Faibussowitsch PetscCall(MatAIJGetParCSR_Private(P, &hP)); 10139566063dSJacob Faibussowitsch PetscCall(MatHYPRE_ParCSR_RAP(hP, hA, hP, &hPtAP)); 10149566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(hPtAP, MATAIJ, PETSC_OWN_POINTER, &B)); 10154222ddf1SHong Zhang 10169566063dSJacob Faibussowitsch PetscCall(MatHeaderMerge(C, &B)); 10174222ddf1SHong Zhang C->product = product; 10184222ddf1SHong Zhang 10199566063dSJacob Faibussowitsch PetscCall(MatAIJRestoreParCSR_Private(A, &hA)); 10209566063dSJacob Faibussowitsch PetscCall(MatAIJRestoreParCSR_Private(P, &hP)); 10213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 10226f231fbdSstefano_zampini } 10236f231fbdSstefano_zampini 1024d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatPtAPSymbolic_AIJ_AIJ_wHYPRE(Mat A, Mat P, PetscReal fill, Mat C) 1025d71ae5a4SJacob Faibussowitsch { 10266f231fbdSstefano_zampini PetscFunctionBegin; 10279566063dSJacob Faibussowitsch PetscCall(MatSetType(C, MATAIJ)); 10284222ddf1SHong Zhang C->ops->ptapnumeric = MatPtAPNumeric_AIJ_AIJ_wHYPRE; 10294222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_PtAP; 10303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1031613e5ff0Sstefano_zampini } 1032613e5ff0Sstefano_zampini 1033d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatPtAPNumeric_AIJ_HYPRE(Mat A, Mat P, Mat C) 1034d71ae5a4SJacob Faibussowitsch { 10354cc28894Sstefano_zampini Mat B; 10364cc28894Sstefano_zampini Mat_HYPRE *hP; 10376abb4441SStefano Zampini hypre_ParCSRMatrix *hA = NULL, *Pparcsr, *ptapparcsr = NULL; 1038613e5ff0Sstefano_zampini HYPRE_Int type; 1039613e5ff0Sstefano_zampini MPI_Comm comm = PetscObjectComm((PetscObject)A); 10404cc28894Sstefano_zampini PetscBool ishypre; 1041613e5ff0Sstefano_zampini 1042613e5ff0Sstefano_zampini PetscFunctionBegin; 10439566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)P, MATHYPRE, &ishypre)); 104428b400f6SJacob Faibussowitsch PetscCheck(ishypre, comm, PETSC_ERR_USER, "P should be of type %s", MATHYPRE); 10454cc28894Sstefano_zampini hP = (Mat_HYPRE *)P->data; 1046792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObjectType, hP->ij, &type); 104708401ef6SPierre Jolivet PetscCheck(type == HYPRE_PARCSR, comm, PETSC_ERR_SUP, "Only HYPRE_PARCSR is supported"); 1048792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hP->ij, (void **)&Pparcsr); 1049613e5ff0Sstefano_zampini 10509566063dSJacob Faibussowitsch PetscCall(MatAIJGetParCSR_Private(A, &hA)); 10519566063dSJacob Faibussowitsch PetscCall(MatHYPRE_ParCSR_RAP(Pparcsr, hA, Pparcsr, &ptapparcsr)); 10529566063dSJacob Faibussowitsch PetscCall(MatAIJRestoreParCSR_Private(A, &hA)); 1053225daaf8SStefano Zampini 10544cc28894Sstefano_zampini /* create temporary matrix and merge to C */ 10559566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(ptapparcsr, ((PetscObject)C)->type_name, PETSC_OWN_POINTER, &B)); 10569566063dSJacob Faibussowitsch PetscCall(MatHeaderMerge(C, &B)); 10573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 10584cc28894Sstefano_zampini } 10594cc28894Sstefano_zampini 1060d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatPtAPNumeric_HYPRE_HYPRE(Mat A, Mat P, Mat C) 1061d71ae5a4SJacob Faibussowitsch { 10624cc28894Sstefano_zampini Mat B; 10636abb4441SStefano Zampini hypre_ParCSRMatrix *Aparcsr, *Pparcsr, *ptapparcsr = NULL; 10644cc28894Sstefano_zampini Mat_HYPRE *hA, *hP; 10654cc28894Sstefano_zampini PetscBool ishypre; 10664cc28894Sstefano_zampini HYPRE_Int type; 10674cc28894Sstefano_zampini 10684cc28894Sstefano_zampini PetscFunctionBegin; 10699566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)P, MATHYPRE, &ishypre)); 107028b400f6SJacob Faibussowitsch PetscCheck(ishypre, PetscObjectComm((PetscObject)P), PETSC_ERR_USER, "P should be of type %s", MATHYPRE); 10719566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A, MATHYPRE, &ishypre)); 107228b400f6SJacob Faibussowitsch PetscCheck(ishypre, PetscObjectComm((PetscObject)A), PETSC_ERR_USER, "A should be of type %s", MATHYPRE); 10734cc28894Sstefano_zampini hA = (Mat_HYPRE *)A->data; 10744cc28894Sstefano_zampini hP = (Mat_HYPRE *)P->data; 1075792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObjectType, hA->ij, &type); 107608401ef6SPierre Jolivet PetscCheck(type == HYPRE_PARCSR, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Only HYPRE_PARCSR is supported"); 1077792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObjectType, hP->ij, &type); 107808401ef6SPierre Jolivet PetscCheck(type == HYPRE_PARCSR, PetscObjectComm((PetscObject)P), PETSC_ERR_SUP, "Only HYPRE_PARCSR is supported"); 1079792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hA->ij, (void **)&Aparcsr); 1080792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hP->ij, (void **)&Pparcsr); 10819566063dSJacob Faibussowitsch PetscCall(MatHYPRE_ParCSR_RAP(Pparcsr, Aparcsr, Pparcsr, &ptapparcsr)); 10829566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(ptapparcsr, MATHYPRE, PETSC_OWN_POINTER, &B)); 10839566063dSJacob Faibussowitsch PetscCall(MatHeaderMerge(C, &B)); 10843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 10854cc28894Sstefano_zampini } 10864cc28894Sstefano_zampini 1087d501dc42Sstefano_zampini /* calls hypre_ParMatmul 1088d501dc42Sstefano_zampini hypre_ParMatMul uses hypre_ParMatrixCreate with the communicator of hA 10893dad0653Sstefano_zampini hypre_ParMatrixCreate does not duplicate the communicator 10906ea7df73SStefano Zampini It looks like we don't need to have the diagonal entries ordered first */ 1091d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatHYPRE_ParCSR_MatMatMult(hypre_ParCSRMatrix *hA, hypre_ParCSRMatrix *hB, hypre_ParCSRMatrix **hAB) 1092d71ae5a4SJacob Faibussowitsch { 1093d501dc42Sstefano_zampini PetscFunctionBegin; 10946ea7df73SStefano Zampini /* can be replaced by version test later */ 10956ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 1096792fecdfSBarry Smith PetscStackPushExternal("hypre_ParCSRMatMat"); 10976ea7df73SStefano Zampini *hAB = hypre_ParCSRMatMat(hA, hB); 10986ea7df73SStefano Zampini #else 1099792fecdfSBarry Smith PetscStackPushExternal("hypre_ParMatmul"); 1100d501dc42Sstefano_zampini *hAB = hypre_ParMatmul(hA, hB); 11016ea7df73SStefano Zampini #endif 1102d501dc42Sstefano_zampini PetscStackPop; 11033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1104d501dc42Sstefano_zampini } 1105d501dc42Sstefano_zampini 1106d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatMultNumeric_AIJ_AIJ_wHYPRE(Mat A, Mat B, Mat C) 1107d71ae5a4SJacob Faibussowitsch { 11085e5acdf2Sstefano_zampini Mat D; 1109d501dc42Sstefano_zampini hypre_ParCSRMatrix *hA, *hB, *hAB = NULL; 11104222ddf1SHong Zhang Mat_Product *product = C->product; 11115e5acdf2Sstefano_zampini 11125e5acdf2Sstefano_zampini PetscFunctionBegin; 11139566063dSJacob Faibussowitsch PetscCall(MatAIJGetParCSR_Private(A, &hA)); 11149566063dSJacob Faibussowitsch PetscCall(MatAIJGetParCSR_Private(B, &hB)); 11159566063dSJacob Faibussowitsch PetscCall(MatHYPRE_ParCSR_MatMatMult(hA, hB, &hAB)); 11169566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(hAB, MATAIJ, PETSC_OWN_POINTER, &D)); 11174222ddf1SHong Zhang 11189566063dSJacob Faibussowitsch PetscCall(MatHeaderMerge(C, &D)); 11194222ddf1SHong Zhang C->product = product; 11204222ddf1SHong Zhang 11219566063dSJacob Faibussowitsch PetscCall(MatAIJRestoreParCSR_Private(A, &hA)); 11229566063dSJacob Faibussowitsch PetscCall(MatAIJRestoreParCSR_Private(B, &hB)); 11233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 11245e5acdf2Sstefano_zampini } 11255e5acdf2Sstefano_zampini 1126d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatMatMultSymbolic_AIJ_AIJ_wHYPRE(Mat A, Mat B, PetscReal fill, Mat C) 1127d71ae5a4SJacob Faibussowitsch { 11285e5acdf2Sstefano_zampini PetscFunctionBegin; 11299566063dSJacob Faibussowitsch PetscCall(MatSetType(C, MATAIJ)); 11304222ddf1SHong Zhang C->ops->matmultnumeric = MatMatMultNumeric_AIJ_AIJ_wHYPRE; 11314222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_AB; 11323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 11335e5acdf2Sstefano_zampini } 11345e5acdf2Sstefano_zampini 1135d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatMultNumeric_HYPRE_HYPRE(Mat A, Mat B, Mat C) 1136d71ae5a4SJacob Faibussowitsch { 1137d501dc42Sstefano_zampini Mat D; 1138d501dc42Sstefano_zampini hypre_ParCSRMatrix *Aparcsr, *Bparcsr, *ABparcsr = NULL; 1139d501dc42Sstefano_zampini Mat_HYPRE *hA, *hB; 1140d501dc42Sstefano_zampini PetscBool ishypre; 1141d501dc42Sstefano_zampini HYPRE_Int type; 11424222ddf1SHong Zhang Mat_Product *product; 1143d501dc42Sstefano_zampini 1144d501dc42Sstefano_zampini PetscFunctionBegin; 11459566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, MATHYPRE, &ishypre)); 114628b400f6SJacob Faibussowitsch PetscCheck(ishypre, PetscObjectComm((PetscObject)B), PETSC_ERR_USER, "B should be of type %s", MATHYPRE); 11479566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A, MATHYPRE, &ishypre)); 114828b400f6SJacob Faibussowitsch PetscCheck(ishypre, PetscObjectComm((PetscObject)A), PETSC_ERR_USER, "A should be of type %s", MATHYPRE); 1149d501dc42Sstefano_zampini hA = (Mat_HYPRE *)A->data; 1150d501dc42Sstefano_zampini hB = (Mat_HYPRE *)B->data; 1151792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObjectType, hA->ij, &type); 115208401ef6SPierre Jolivet PetscCheck(type == HYPRE_PARCSR, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Only HYPRE_PARCSR is supported"); 1153792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObjectType, hB->ij, &type); 115408401ef6SPierre Jolivet PetscCheck(type == HYPRE_PARCSR, PetscObjectComm((PetscObject)B), PETSC_ERR_SUP, "Only HYPRE_PARCSR is supported"); 1155792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hA->ij, (void **)&Aparcsr); 1156792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hB->ij, (void **)&Bparcsr); 11579566063dSJacob Faibussowitsch PetscCall(MatHYPRE_ParCSR_MatMatMult(Aparcsr, Bparcsr, &ABparcsr)); 11589566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(ABparcsr, MATHYPRE, PETSC_OWN_POINTER, &D)); 11594222ddf1SHong Zhang 1160d501dc42Sstefano_zampini /* need to use HeaderReplace because HeaderMerge messes up with the communicator */ 11614222ddf1SHong Zhang product = C->product; /* save it from MatHeaderReplace() */ 11624222ddf1SHong Zhang C->product = NULL; 11639566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(C, &D)); 11644222ddf1SHong Zhang C->product = product; 1165d501dc42Sstefano_zampini C->ops->matmultnumeric = MatMatMultNumeric_HYPRE_HYPRE; 11664222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_AB; 11673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1168d501dc42Sstefano_zampini } 1169d501dc42Sstefano_zampini 1170d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatTransposeMatMatMultNumeric_AIJ_AIJ_AIJ_wHYPRE(Mat A, Mat B, Mat C, Mat D) 1171d71ae5a4SJacob Faibussowitsch { 117220e1dc0dSstefano_zampini Mat E; 11736abb4441SStefano Zampini hypre_ParCSRMatrix *hA, *hB, *hC, *hABC = NULL; 117420e1dc0dSstefano_zampini 117520e1dc0dSstefano_zampini PetscFunctionBegin; 11769566063dSJacob Faibussowitsch PetscCall(MatAIJGetParCSR_Private(A, &hA)); 11779566063dSJacob Faibussowitsch PetscCall(MatAIJGetParCSR_Private(B, &hB)); 11789566063dSJacob Faibussowitsch PetscCall(MatAIJGetParCSR_Private(C, &hC)); 11799566063dSJacob Faibussowitsch PetscCall(MatHYPRE_ParCSR_RAP(hA, hB, hC, &hABC)); 11809566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(hABC, MATAIJ, PETSC_OWN_POINTER, &E)); 11819566063dSJacob Faibussowitsch PetscCall(MatHeaderMerge(D, &E)); 11829566063dSJacob Faibussowitsch PetscCall(MatAIJRestoreParCSR_Private(A, &hA)); 11839566063dSJacob Faibussowitsch PetscCall(MatAIJRestoreParCSR_Private(B, &hB)); 11849566063dSJacob Faibussowitsch PetscCall(MatAIJRestoreParCSR_Private(C, &hC)); 11853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 118620e1dc0dSstefano_zampini } 118720e1dc0dSstefano_zampini 1188d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatTransposeMatMatMultSymbolic_AIJ_AIJ_AIJ_wHYPRE(Mat A, Mat B, Mat C, PetscReal fill, Mat D) 1189d71ae5a4SJacob Faibussowitsch { 119020e1dc0dSstefano_zampini PetscFunctionBegin; 11919566063dSJacob Faibussowitsch PetscCall(MatSetType(D, MATAIJ)); 11923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 119320e1dc0dSstefano_zampini } 119420e1dc0dSstefano_zampini 1195d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSymbolic_AB_HYPRE(Mat C) 1196d71ae5a4SJacob Faibussowitsch { 11974222ddf1SHong Zhang PetscFunctionBegin; 11984222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_AB; 11993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12004222ddf1SHong Zhang } 12014222ddf1SHong Zhang 1202d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_HYPRE_AB(Mat C) 1203d71ae5a4SJacob Faibussowitsch { 12044222ddf1SHong Zhang Mat_Product *product = C->product; 12054222ddf1SHong Zhang PetscBool Ahypre; 12064222ddf1SHong Zhang 12074222ddf1SHong Zhang PetscFunctionBegin; 12089566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)product->A, MATHYPRE, &Ahypre)); 12094222ddf1SHong Zhang if (Ahypre) { /* A is a Hypre matrix */ 12109566063dSJacob Faibussowitsch PetscCall(MatSetType(C, MATHYPRE)); 12114222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AB_HYPRE; 12124222ddf1SHong Zhang C->ops->matmultnumeric = MatMatMultNumeric_HYPRE_HYPRE; 12133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12146718818eSStefano Zampini } 12153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12164222ddf1SHong Zhang } 12174222ddf1SHong Zhang 1218d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSymbolic_PtAP_HYPRE(Mat C) 1219d71ae5a4SJacob Faibussowitsch { 12204222ddf1SHong Zhang PetscFunctionBegin; 12214222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_PtAP; 12223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12234222ddf1SHong Zhang } 12244222ddf1SHong Zhang 1225d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_HYPRE_PtAP(Mat C) 1226d71ae5a4SJacob Faibussowitsch { 12274222ddf1SHong Zhang Mat_Product *product = C->product; 12284222ddf1SHong Zhang PetscBool flg; 12294222ddf1SHong Zhang PetscInt type = 0; 12304222ddf1SHong Zhang const char *outTypes[4] = {"aij", "seqaij", "mpiaij", "hypre"}; 12314222ddf1SHong Zhang PetscInt ntype = 4; 12324222ddf1SHong Zhang Mat A = product->A; 12334222ddf1SHong Zhang PetscBool Ahypre; 12344222ddf1SHong Zhang 12354222ddf1SHong Zhang PetscFunctionBegin; 12369566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A, MATHYPRE, &Ahypre)); 12374222ddf1SHong Zhang if (Ahypre) { /* A is a Hypre matrix */ 12389566063dSJacob Faibussowitsch PetscCall(MatSetType(C, MATHYPRE)); 12394222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_PtAP_HYPRE; 12404222ddf1SHong Zhang C->ops->ptapnumeric = MatPtAPNumeric_HYPRE_HYPRE; 12413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12424222ddf1SHong Zhang } 12434222ddf1SHong Zhang 12444222ddf1SHong Zhang /* A is AIJ, P is Hypre, C = PtAP can be either AIJ or Hypre format */ 12454222ddf1SHong Zhang /* Get runtime option */ 12464222ddf1SHong Zhang if (product->api_user) { 1247d0609cedSBarry Smith PetscOptionsBegin(PetscObjectComm((PetscObject)C), ((PetscObject)C)->prefix, "MatPtAP_HYPRE", "Mat"); 12489566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-matptap_hypre_outtype", "MatPtAP outtype", "MatPtAP outtype", outTypes, ntype, outTypes[type], &type, &flg)); 1249d0609cedSBarry Smith PetscOptionsEnd(); 12504222ddf1SHong Zhang } else { 1251d0609cedSBarry Smith PetscOptionsBegin(PetscObjectComm((PetscObject)C), ((PetscObject)C)->prefix, "MatProduct_PtAP_HYPRE", "Mat"); 12529566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-mat_product_algorithm_hypre_outtype", "MatProduct_PtAP outtype", "MatProduct_PtAP", outTypes, ntype, outTypes[type], &type, &flg)); 1253d0609cedSBarry Smith PetscOptionsEnd(); 12544222ddf1SHong Zhang } 12554222ddf1SHong Zhang 12564222ddf1SHong Zhang if (type == 0 || type == 1 || type == 2) { 12579566063dSJacob Faibussowitsch PetscCall(MatSetType(C, MATAIJ)); 12584222ddf1SHong Zhang } else if (type == 3) { 12599566063dSJacob Faibussowitsch PetscCall(MatSetType(C, MATHYPRE)); 12604222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)C), PETSC_ERR_SUP, "MatPtAP outtype is not supported"); 12614222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_PtAP_HYPRE; 12624222ddf1SHong Zhang C->ops->ptapnumeric = MatPtAPNumeric_AIJ_HYPRE; 12633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12644222ddf1SHong Zhang } 12654222ddf1SHong Zhang 1266d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_HYPRE(Mat C) 1267d71ae5a4SJacob Faibussowitsch { 12684222ddf1SHong Zhang Mat_Product *product = C->product; 12694222ddf1SHong Zhang 12704222ddf1SHong Zhang PetscFunctionBegin; 12714222ddf1SHong Zhang switch (product->type) { 1272d71ae5a4SJacob Faibussowitsch case MATPRODUCT_AB: 1273d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_HYPRE_AB(C)); 1274d71ae5a4SJacob Faibussowitsch break; 1275d71ae5a4SJacob Faibussowitsch case MATPRODUCT_PtAP: 1276d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_HYPRE_PtAP(C)); 1277d71ae5a4SJacob Faibussowitsch break; 1278d71ae5a4SJacob Faibussowitsch default: 1279d71ae5a4SJacob Faibussowitsch break; 12804222ddf1SHong Zhang } 12813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12824222ddf1SHong Zhang } 12834222ddf1SHong Zhang 1284d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMultTranspose_HYPRE(Mat A, Vec x, Vec y) 1285d71ae5a4SJacob Faibussowitsch { 128663c07aadSStefano Zampini PetscFunctionBegin; 12879566063dSJacob Faibussowitsch PetscCall(MatHYPRE_MultKernel_Private(A, 1.0, x, 0.0, y, PETSC_TRUE)); 12883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 128963c07aadSStefano Zampini } 129063c07aadSStefano Zampini 1291d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMult_HYPRE(Mat A, Vec x, Vec y) 1292d71ae5a4SJacob Faibussowitsch { 129363c07aadSStefano Zampini PetscFunctionBegin; 12949566063dSJacob Faibussowitsch PetscCall(MatHYPRE_MultKernel_Private(A, 1.0, x, 0.0, y, PETSC_FALSE)); 12953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 129663c07aadSStefano Zampini } 129763c07aadSStefano Zampini 1298d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMultAdd_HYPRE(Mat A, Vec x, Vec y, Vec z) 1299d71ae5a4SJacob Faibussowitsch { 1300414bd5c3SStefano Zampini PetscFunctionBegin; 130148a46eb9SPierre Jolivet if (y != z) PetscCall(VecCopy(y, z)); 13029566063dSJacob Faibussowitsch PetscCall(MatHYPRE_MultKernel_Private(A, 1.0, x, 1.0, z, PETSC_FALSE)); 13033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1304414bd5c3SStefano Zampini } 1305414bd5c3SStefano Zampini 1306d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMultTransposeAdd_HYPRE(Mat A, Vec x, Vec y, Vec z) 1307d71ae5a4SJacob Faibussowitsch { 1308414bd5c3SStefano Zampini PetscFunctionBegin; 130948a46eb9SPierre Jolivet if (y != z) PetscCall(VecCopy(y, z)); 13109566063dSJacob Faibussowitsch PetscCall(MatHYPRE_MultKernel_Private(A, 1.0, x, 1.0, z, PETSC_TRUE)); 13113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1312414bd5c3SStefano Zampini } 1313414bd5c3SStefano Zampini 1314414bd5c3SStefano Zampini /* y = a * A * x + b * y or y = a * A^t * x + b * y depending on trans */ 1315d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatHYPRE_MultKernel_Private(Mat A, HYPRE_Complex a, Vec x, HYPRE_Complex b, Vec y, PetscBool trans) 1316d71ae5a4SJacob Faibussowitsch { 131763c07aadSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 131863c07aadSStefano Zampini hypre_ParCSRMatrix *parcsr; 131963c07aadSStefano Zampini hypre_ParVector *hx, *hy; 132063c07aadSStefano Zampini 132163c07aadSStefano Zampini PetscFunctionBegin; 132263c07aadSStefano Zampini if (trans) { 13239566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPushVecRead(hA->b, x)); 13249566063dSJacob Faibussowitsch if (b != 0.0) PetscCall(VecHYPRE_IJVectorPushVec(hA->x, y)); 13259566063dSJacob Faibussowitsch else PetscCall(VecHYPRE_IJVectorPushVecWrite(hA->x, y)); 1326792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hA->b->ij, (void **)&hx); 1327792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hA->x->ij, (void **)&hy); 132863c07aadSStefano Zampini } else { 13299566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPushVecRead(hA->x, x)); 13309566063dSJacob Faibussowitsch if (b != 0.0) PetscCall(VecHYPRE_IJVectorPushVec(hA->b, y)); 13319566063dSJacob Faibussowitsch else PetscCall(VecHYPRE_IJVectorPushVecWrite(hA->b, y)); 1332792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hA->x->ij, (void **)&hx); 1333792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hA->b->ij, (void **)&hy); 133463c07aadSStefano Zampini } 1335792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hA->ij, (void **)&parcsr); 13366ea7df73SStefano Zampini if (trans) { 1337792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixMatvecT, a, parcsr, hx, b, hy); 13386ea7df73SStefano Zampini } else { 1339792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixMatvec, a, parcsr, hx, b, hy); 13406ea7df73SStefano Zampini } 13419566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hA->x)); 13429566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hA->b)); 13433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 134463c07aadSStefano Zampini } 134563c07aadSStefano Zampini 1346d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDestroy_HYPRE(Mat A) 1347d71ae5a4SJacob Faibussowitsch { 134863c07aadSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 134963c07aadSStefano Zampini 135063c07aadSStefano Zampini PetscFunctionBegin; 13519566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&hA->x)); 13529566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&hA->b)); 135306977982Sstefanozampini PetscCall(MatHYPRE_DestroyCOOMat(A)); /* must be called before destroying the individual CSR */ 1354978814f1SStefano Zampini if (hA->ij) { 1355978814f1SStefano Zampini if (!hA->inner_free) hypre_IJMatrixObject(hA->ij) = NULL; 1356792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixDestroy, hA->ij); 1357978814f1SStefano Zampini } 13589566063dSJacob Faibussowitsch if (hA->comm) PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)A), &hA->comm)); 1359c69f721fSFande Kong 13609566063dSJacob Faibussowitsch PetscCall(MatStashDestroy_Private(&A->stash)); 13619566063dSJacob Faibussowitsch PetscCall(PetscFree(hA->array)); 1362a32e9c99SJunchao Zhang if (hA->rows_d) PetscStackCallExternalVoid("hypre_Free", hypre_Free(hA->rows_d, HYPRE_MEMORY_DEVICE)); 1363c69f721fSFande Kong 13649566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatConvert_hypre_aij_C", NULL)); 13659566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatConvert_hypre_is_C", NULL)); 13669566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatProductSetFromOptions_seqaij_hypre_C", NULL)); 13679566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatProductSetFromOptions_mpiaij_hypre_C", NULL)); 136806977982Sstefanozampini PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatProductSetFromOptions_seqaijhipsparse_hypre_C", NULL)); 136906977982Sstefanozampini PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatProductSetFromOptions_mpiaijhipsparse_hypre_C", NULL)); 137006977982Sstefanozampini PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatProductSetFromOptions_seqaijcusparse_hypre_C", NULL)); 137106977982Sstefanozampini PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatProductSetFromOptions_mpiaijcusparse_hypre_C", NULL)); 13729566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatHYPRESetPreallocation_C", NULL)); 13739566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatHYPREGetParCSR_C", NULL)); 13745fbaff96SJunchao Zhang PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatSetPreallocationCOO_C", NULL)); 13755fbaff96SJunchao Zhang PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatSetValuesCOO_C", NULL)); 13769566063dSJacob Faibussowitsch PetscCall(PetscFree(A->data)); 13773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 137863c07aadSStefano Zampini } 137963c07aadSStefano Zampini 1380d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetUp_HYPRE(Mat A) 1381d71ae5a4SJacob Faibussowitsch { 13824ec6421dSstefano_zampini PetscFunctionBegin; 138306977982Sstefanozampini if (!A->preallocated) PetscCall(MatHYPRESetPreallocation(A, PETSC_DEFAULT, NULL, PETSC_DEFAULT, NULL)); 13843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13854ec6421dSstefano_zampini } 13864ec6421dSstefano_zampini 13876ea7df73SStefano Zampini //TODO FIX hypre_CSRMatrixMatvecOutOfPlace 13886ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 1389d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatBindToCPU_HYPRE(Mat A, PetscBool bind) 1390d71ae5a4SJacob Faibussowitsch { 13916ea7df73SStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 13926ea7df73SStefano Zampini HYPRE_MemoryLocation hmem = bind ? HYPRE_MEMORY_HOST : HYPRE_MEMORY_DEVICE; 13936ea7df73SStefano Zampini 13946ea7df73SStefano Zampini PetscFunctionBegin; 13956ea7df73SStefano Zampini A->boundtocpu = bind; 13965fbaff96SJunchao Zhang if (hA->ij && hypre_IJMatrixAssembleFlag(hA->ij) && hmem != hypre_IJMatrixMemoryLocation(hA->ij)) { 13976ea7df73SStefano Zampini hypre_ParCSRMatrix *parcsr; 1398792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hA->ij, (void **)&parcsr); 1399792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixMigrate, parcsr, hmem); 14006ea7df73SStefano Zampini } 14019566063dSJacob Faibussowitsch if (hA->x) PetscCall(VecHYPRE_IJBindToCPU(hA->x, bind)); 14029566063dSJacob Faibussowitsch if (hA->b) PetscCall(VecHYPRE_IJBindToCPU(hA->b, bind)); 14033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 14046ea7df73SStefano Zampini } 14056ea7df73SStefano Zampini #endif 14066ea7df73SStefano Zampini 1407d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyEnd_HYPRE(Mat A, MatAssemblyType mode) 1408d71ae5a4SJacob Faibussowitsch { 140963c07aadSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 1410c69f721fSFande Kong PetscMPIInt n; 1411c69f721fSFande Kong PetscInt i, j, rstart, ncols, flg; 1412c69f721fSFande Kong PetscInt *row, *col; 1413c69f721fSFande Kong PetscScalar *val; 141463c07aadSStefano Zampini 141563c07aadSStefano Zampini PetscFunctionBegin; 141608401ef6SPierre Jolivet PetscCheck(mode != MAT_FLUSH_ASSEMBLY, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "MAT_FLUSH_ASSEMBLY currently not supported with MATHYPRE"); 1417c69f721fSFande Kong 1418c69f721fSFande Kong if (!A->nooffprocentries) { 1419c69f721fSFande Kong while (1) { 14209566063dSJacob Faibussowitsch PetscCall(MatStashScatterGetMesg_Private(&A->stash, &n, &row, &col, &val, &flg)); 1421c69f721fSFande Kong if (!flg) break; 1422c69f721fSFande Kong 1423c69f721fSFande Kong for (i = 0; i < n;) { 1424c69f721fSFande Kong /* Now identify the consecutive vals belonging to the same row */ 1425c69f721fSFande Kong for (j = i, rstart = row[j]; j < n; j++) { 1426c69f721fSFande Kong if (row[j] != rstart) break; 1427c69f721fSFande Kong } 1428c69f721fSFande Kong if (j < n) ncols = j - i; 1429c69f721fSFande Kong else ncols = n - i; 1430c69f721fSFande Kong /* Now assemble all these values with a single function call */ 14319566063dSJacob Faibussowitsch PetscCall(MatSetValues_HYPRE(A, 1, row + i, ncols, col + i, val + i, A->insertmode)); 1432c69f721fSFande Kong 1433c69f721fSFande Kong i = j; 1434c69f721fSFande Kong } 1435c69f721fSFande Kong } 14369566063dSJacob Faibussowitsch PetscCall(MatStashScatterEnd_Private(&A->stash)); 1437c69f721fSFande Kong } 1438c69f721fSFande Kong 1439792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixAssemble, hA->ij); 1440336664bdSPierre Jolivet /* The assembly routine destroys the aux_matrix, we recreate it here by calling HYPRE_IJMatrixInitialize */ 1441336664bdSPierre Jolivet /* If the option MAT_SORTED_FULL is set to true, the indices and values can be passed to hypre directly, so we don't need the aux_matrix */ 1442651b1cf9SStefano Zampini if (!A->sortedfull) { 1443af1cf968SStefano Zampini hypre_AuxParCSRMatrix *aux_matrix; 1444af1cf968SStefano Zampini 1445af1cf968SStefano Zampini /* call destroy just to make sure we do not leak anything */ 1446af1cf968SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix *)hypre_IJMatrixTranslator(hA->ij); 1447792fecdfSBarry Smith PetscCallExternal(hypre_AuxParCSRMatrixDestroy, aux_matrix); 1448af1cf968SStefano Zampini hypre_IJMatrixTranslator(hA->ij) = NULL; 1449af1cf968SStefano Zampini 1450af1cf968SStefano Zampini /* Initialize with assembled flag -> it only recreates the aux_par_matrix */ 1451792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixInitialize, hA->ij); 1452af1cf968SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix *)hypre_IJMatrixTranslator(hA->ij); 14536ea7df73SStefano Zampini if (aux_matrix) { 1454af1cf968SStefano Zampini hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 1; /* see comment in MatHYPRESetPreallocation_HYPRE */ 145522235d61SPierre Jolivet #if PETSC_PKG_HYPRE_VERSION_LT(2, 19, 0) 1456792fecdfSBarry Smith PetscCallExternal(hypre_AuxParCSRMatrixInitialize, aux_matrix); 145722235d61SPierre Jolivet #else 1458792fecdfSBarry Smith PetscCallExternal(hypre_AuxParCSRMatrixInitialize_v2, aux_matrix, HYPRE_MEMORY_HOST); 145922235d61SPierre Jolivet #endif 1460af1cf968SStefano Zampini } 14616ea7df73SStefano Zampini } 14626ea7df73SStefano Zampini { 14636ea7df73SStefano Zampini hypre_ParCSRMatrix *parcsr; 14646ea7df73SStefano Zampini 1465792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hA->ij, (void **)&parcsr); 1466792fecdfSBarry Smith if (!hypre_ParCSRMatrixCommPkg(parcsr)) PetscCallExternal(hypre_MatvecCommPkgCreate, parcsr); 14676ea7df73SStefano Zampini } 14689566063dSJacob Faibussowitsch if (!hA->x) PetscCall(VecHYPRE_IJVectorCreate(A->cmap, &hA->x)); 14699566063dSJacob Faibussowitsch if (!hA->b) PetscCall(VecHYPRE_IJVectorCreate(A->rmap, &hA->b)); 14706ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 14719566063dSJacob Faibussowitsch PetscCall(MatBindToCPU_HYPRE(A, A->boundtocpu)); 14726ea7df73SStefano Zampini #endif 14733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 147463c07aadSStefano Zampini } 147563c07aadSStefano Zampini 1476d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetArray_HYPRE(Mat A, PetscInt size, void **array) 1477d71ae5a4SJacob Faibussowitsch { 1478c69f721fSFande Kong Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 1479c69f721fSFande Kong 1480c69f721fSFande Kong PetscFunctionBegin; 1481651b1cf9SStefano Zampini PetscCheck(hA->array_available, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Temporary space is in use"); 1482c69f721fSFande Kong 1483651b1cf9SStefano Zampini if (hA->array_size >= size) { 148439accc25SStefano Zampini *array = hA->array; 148539accc25SStefano Zampini } else { 14869566063dSJacob Faibussowitsch PetscCall(PetscFree(hA->array)); 1487651b1cf9SStefano Zampini hA->array_size = size; 1488651b1cf9SStefano Zampini PetscCall(PetscMalloc(hA->array_size, &hA->array)); 1489c69f721fSFande Kong *array = hA->array; 1490c69f721fSFande Kong } 1491c69f721fSFande Kong 1492651b1cf9SStefano Zampini hA->array_available = PETSC_FALSE; 14933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1494c69f721fSFande Kong } 1495c69f721fSFande Kong 1496d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRestoreArray_HYPRE(Mat A, void **array) 1497d71ae5a4SJacob Faibussowitsch { 1498c69f721fSFande Kong Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 1499c69f721fSFande Kong 1500c69f721fSFande Kong PetscFunctionBegin; 1501c69f721fSFande Kong *array = NULL; 1502651b1cf9SStefano Zampini hA->array_available = PETSC_TRUE; 15033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1504c69f721fSFande Kong } 1505c69f721fSFande Kong 1506d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetValues_HYPRE(Mat A, PetscInt nr, const PetscInt rows[], PetscInt nc, const PetscInt cols[], const PetscScalar v[], InsertMode ins) 1507d71ae5a4SJacob Faibussowitsch { 1508d975228cSstefano_zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 1509d975228cSstefano_zampini PetscScalar *vals = (PetscScalar *)v; 151039accc25SStefano Zampini HYPRE_Complex *sscr; 1511c69f721fSFande Kong PetscInt *cscr[2]; 1512c69f721fSFande Kong PetscInt i, nzc; 1513651b1cf9SStefano Zampini PetscInt rst = A->rmap->rstart, ren = A->rmap->rend; 151408defe43SFande Kong void *array = NULL; 1515d975228cSstefano_zampini 1516d975228cSstefano_zampini PetscFunctionBegin; 15179566063dSJacob Faibussowitsch PetscCall(MatGetArray_HYPRE(A, sizeof(PetscInt) * (2 * nc) + sizeof(HYPRE_Complex) * nc * nr, &array)); 1518c69f721fSFande Kong cscr[0] = (PetscInt *)array; 1519c69f721fSFande Kong cscr[1] = ((PetscInt *)array) + nc; 152039accc25SStefano Zampini sscr = (HYPRE_Complex *)(((PetscInt *)array) + nc * 2); 1521d975228cSstefano_zampini for (i = 0, nzc = 0; i < nc; i++) { 1522d975228cSstefano_zampini if (cols[i] >= 0) { 1523d975228cSstefano_zampini cscr[0][nzc] = cols[i]; 1524d975228cSstefano_zampini cscr[1][nzc++] = i; 1525d975228cSstefano_zampini } 1526d975228cSstefano_zampini } 1527c69f721fSFande Kong if (!nzc) { 15289566063dSJacob Faibussowitsch PetscCall(MatRestoreArray_HYPRE(A, &array)); 15293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1530c69f721fSFande Kong } 1531d975228cSstefano_zampini 15326ea7df73SStefano Zampini #if 0 //defined(PETSC_HAVE_HYPRE_DEVICE) 15336ea7df73SStefano Zampini if (HYPRE_MEMORY_HOST != hypre_IJMatrixMemoryLocation(hA->ij)) { 15346ea7df73SStefano Zampini hypre_ParCSRMatrix *parcsr; 15356ea7df73SStefano Zampini 1536792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hA->ij,(void**)&parcsr); 1537792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixMigrate,parcsr, HYPRE_MEMORY_HOST); 15386ea7df73SStefano Zampini } 15396ea7df73SStefano Zampini #endif 15406ea7df73SStefano Zampini 1541d975228cSstefano_zampini if (ins == ADD_VALUES) { 1542d975228cSstefano_zampini for (i = 0; i < nr; i++) { 15436ea7df73SStefano Zampini if (rows[i] >= 0) { 1544d975228cSstefano_zampini PetscInt j; 15452cf14000SStefano Zampini HYPRE_Int hnc = (HYPRE_Int)nzc; 15462cf14000SStefano Zampini 1547651b1cf9SStefano Zampini if (!nzc) continue; 1548651b1cf9SStefano Zampini /* nonlocal values */ 1549651b1cf9SStefano Zampini if (rows[i] < rst || rows[i] >= ren) { 1550651b1cf9SStefano Zampini PetscCheck(!A->nooffprocentries, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Setting off process row %" PetscInt_FMT " even though MatSetOption(,MAT_NO_OFF_PROC_ENTRIES,PETSC_TRUE) was set", rows[i]); 1551651b1cf9SStefano Zampini if (hA->donotstash) continue; 1552651b1cf9SStefano Zampini } 1553aed4548fSBarry Smith PetscCheck((PetscInt)hnc == nzc, PETSC_COMM_SELF, PETSC_ERR_SUP, "Hypre overflow! number of columns %" PetscInt_FMT " for row %" PetscInt_FMT, nzc, rows[i]); 15549566063dSJacob Faibussowitsch for (j = 0; j < nzc; j++) PetscCall(PetscHYPREScalarCast(vals[cscr[1][j]], &sscr[j])); 1555792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixAddToValues, hA->ij, 1, &hnc, (HYPRE_BigInt *)(rows + i), (HYPRE_BigInt *)cscr[0], sscr); 1556d975228cSstefano_zampini } 1557d975228cSstefano_zampini vals += nc; 1558d975228cSstefano_zampini } 1559d975228cSstefano_zampini } else { /* INSERT_VALUES */ 1560d975228cSstefano_zampini for (i = 0; i < nr; i++) { 15616ea7df73SStefano Zampini if (rows[i] >= 0) { 1562d975228cSstefano_zampini PetscInt j; 15632cf14000SStefano Zampini HYPRE_Int hnc = (HYPRE_Int)nzc; 15642cf14000SStefano Zampini 1565651b1cf9SStefano Zampini if (!nzc) continue; 1566aed4548fSBarry Smith PetscCheck((PetscInt)hnc == nzc, PETSC_COMM_SELF, PETSC_ERR_SUP, "Hypre overflow! number of columns %" PetscInt_FMT " for row %" PetscInt_FMT, nzc, rows[i]); 15679566063dSJacob Faibussowitsch for (j = 0; j < nzc; j++) PetscCall(PetscHYPREScalarCast(vals[cscr[1][j]], &sscr[j])); 1568c69f721fSFande Kong /* nonlocal values */ 1569651b1cf9SStefano Zampini if (rows[i] < rst || rows[i] >= ren) { 1570651b1cf9SStefano Zampini PetscCheck(!A->nooffprocentries, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Setting off process row %" PetscInt_FMT " even though MatSetOption(,MAT_NO_OFF_PROC_ENTRIES,PETSC_TRUE) was set", rows[i]); 1571651b1cf9SStefano Zampini if (!hA->donotstash) PetscCall(MatStashValuesRow_Private(&A->stash, rows[i], nzc, cscr[0], (PetscScalar *)sscr, PETSC_FALSE)); 1572651b1cf9SStefano Zampini } 1573c69f721fSFande Kong /* local values */ 1574651b1cf9SStefano Zampini else 1575651b1cf9SStefano Zampini PetscCallExternal(HYPRE_IJMatrixSetValues, hA->ij, 1, &hnc, (HYPRE_BigInt *)(rows + i), (HYPRE_BigInt *)cscr[0], sscr); 1576d975228cSstefano_zampini } 1577d975228cSstefano_zampini vals += nc; 1578d975228cSstefano_zampini } 1579d975228cSstefano_zampini } 1580c69f721fSFande Kong 15819566063dSJacob Faibussowitsch PetscCall(MatRestoreArray_HYPRE(A, &array)); 15823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1583d975228cSstefano_zampini } 1584d975228cSstefano_zampini 1585d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatHYPRESetPreallocation_HYPRE(Mat A, PetscInt dnz, const PetscInt dnnz[], PetscInt onz, const PetscInt onnz[]) 1586d71ae5a4SJacob Faibussowitsch { 1587d975228cSstefano_zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 15887d968826Sstefano_zampini HYPRE_Int *hdnnz, *honnz; 158906a29025Sstefano_zampini PetscInt i, rs, re, cs, ce, bs; 1590d975228cSstefano_zampini PetscMPIInt size; 1591d975228cSstefano_zampini 1592d975228cSstefano_zampini PetscFunctionBegin; 15939566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 15949566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 1595d975228cSstefano_zampini rs = A->rmap->rstart; 1596d975228cSstefano_zampini re = A->rmap->rend; 1597d975228cSstefano_zampini cs = A->cmap->rstart; 1598d975228cSstefano_zampini ce = A->cmap->rend; 1599d975228cSstefano_zampini if (!hA->ij) { 1600792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixCreate, hA->comm, rs, re - 1, cs, ce - 1, &hA->ij); 1601792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixSetObjectType, hA->ij, HYPRE_PARCSR); 1602d975228cSstefano_zampini } else { 16032cf14000SStefano Zampini HYPRE_BigInt hrs, hre, hcs, hce; 1604792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetLocalRange, hA->ij, &hrs, &hre, &hcs, &hce); 1605aed4548fSBarry Smith PetscCheck(hre - hrs + 1 == re - rs, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistent local rows: IJMatrix [%" PetscHYPRE_BigInt_FMT ",%" PetscHYPRE_BigInt_FMT "), PETSc [%" PetscInt_FMT ",%" PetscInt_FMT ")", hrs, hre + 1, rs, re); 1606aed4548fSBarry Smith PetscCheck(hce - hcs + 1 == ce - cs, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistent local cols: IJMatrix [%" PetscHYPRE_BigInt_FMT ",%" PetscHYPRE_BigInt_FMT "), PETSc [%" PetscInt_FMT ",%" PetscInt_FMT ")", hcs, hce + 1, cs, ce); 1607d975228cSstefano_zampini } 160806977982Sstefanozampini PetscCall(MatHYPRE_DestroyCOOMat(A)); 16099566063dSJacob Faibussowitsch PetscCall(MatGetBlockSize(A, &bs)); 161006a29025Sstefano_zampini if (dnz == PETSC_DEFAULT || dnz == PETSC_DECIDE) dnz = 10 * bs; 161106a29025Sstefano_zampini if (onz == PETSC_DEFAULT || onz == PETSC_DECIDE) onz = 10 * bs; 161206a29025Sstefano_zampini 1613d975228cSstefano_zampini if (!dnnz) { 16149566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->rmap->n, &hdnnz)); 1615d975228cSstefano_zampini for (i = 0; i < A->rmap->n; i++) hdnnz[i] = dnz; 1616d975228cSstefano_zampini } else { 16177d968826Sstefano_zampini hdnnz = (HYPRE_Int *)dnnz; 1618d975228cSstefano_zampini } 16199566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A), &size)); 1620d975228cSstefano_zampini if (size > 1) { 1621ddbeb582SStefano Zampini hypre_AuxParCSRMatrix *aux_matrix; 1622d975228cSstefano_zampini if (!onnz) { 16239566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->rmap->n, &honnz)); 1624d975228cSstefano_zampini for (i = 0; i < A->rmap->n; i++) honnz[i] = onz; 162522235d61SPierre Jolivet } else honnz = (HYPRE_Int *)onnz; 1626ddbeb582SStefano Zampini /* SetDiagOffdSizes sets hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 0, since it seems 1627ddbeb582SStefano Zampini they assume the user will input the entire row values, properly sorted 1628336664bdSPierre Jolivet In PETSc, we don't make such an assumption and set this flag to 1, 1629336664bdSPierre Jolivet unless the option MAT_SORTED_FULL is set to true. 1630ddbeb582SStefano Zampini Also, to avoid possible memory leaks, we destroy and recreate the translator 1631ddbeb582SStefano Zampini This has to be done here, as HYPRE_IJMatrixInitialize will properly initialize 1632ddbeb582SStefano Zampini the IJ matrix for us */ 1633ddbeb582SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix *)hypre_IJMatrixTranslator(hA->ij); 1634ddbeb582SStefano Zampini hypre_AuxParCSRMatrixDestroy(aux_matrix); 1635ddbeb582SStefano Zampini hypre_IJMatrixTranslator(hA->ij) = NULL; 1636792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixSetDiagOffdSizes, hA->ij, hdnnz, honnz); 1637ddbeb582SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix *)hypre_IJMatrixTranslator(hA->ij); 1638651b1cf9SStefano Zampini hypre_AuxParCSRMatrixNeedAux(aux_matrix) = !A->sortedfull; 1639d975228cSstefano_zampini } else { 1640d975228cSstefano_zampini honnz = NULL; 1641792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixSetRowSizes, hA->ij, hdnnz); 1642d975228cSstefano_zampini } 1643ddbeb582SStefano Zampini 1644af1cf968SStefano Zampini /* reset assembled flag and call the initialize method */ 1645af1cf968SStefano Zampini hypre_IJMatrixAssembleFlag(hA->ij) = 0; 16466ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_LT(2, 19, 0) 1647792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixInitialize, hA->ij); 16486ea7df73SStefano Zampini #else 1649792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixInitialize_v2, hA->ij, HYPRE_MEMORY_HOST); 16506ea7df73SStefano Zampini #endif 165148a46eb9SPierre Jolivet if (!dnnz) PetscCall(PetscFree(hdnnz)); 165248a46eb9SPierre Jolivet if (!onnz && honnz) PetscCall(PetscFree(honnz)); 1653af1cf968SStefano Zampini /* Match AIJ logic */ 165406a29025Sstefano_zampini A->preallocated = PETSC_TRUE; 1655af1cf968SStefano Zampini A->assembled = PETSC_FALSE; 16563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1657d975228cSstefano_zampini } 1658d975228cSstefano_zampini 1659d975228cSstefano_zampini /*@C 1660d975228cSstefano_zampini MatHYPRESetPreallocation - Preallocates memory for a sparse parallel matrix in HYPRE IJ format 1661d975228cSstefano_zampini 1662c3339decSBarry Smith Collective 1663d975228cSstefano_zampini 1664d975228cSstefano_zampini Input Parameters: 1665d975228cSstefano_zampini + A - the matrix 1666d975228cSstefano_zampini . dnz - number of nonzeros per row in DIAGONAL portion of local submatrix 1667d975228cSstefano_zampini (same value is used for all local rows) 1668d975228cSstefano_zampini . dnnz - array containing the number of nonzeros in the various rows of the 1669d975228cSstefano_zampini DIAGONAL portion of the local submatrix (possibly different for each row) 16702ef1f0ffSBarry Smith or `NULL` (`PETSC_NULL_INTEGER` in Fortran), if `d_nz` is used to specify the nonzero structure. 16712ef1f0ffSBarry Smith The size of this array is equal to the number of local rows, i.e `m`. 1672d975228cSstefano_zampini For matrices that will be factored, you must leave room for (and set) 1673d975228cSstefano_zampini the diagonal entry even if it is zero. 1674d975228cSstefano_zampini . onz - number of nonzeros per row in the OFF-DIAGONAL portion of local 1675d975228cSstefano_zampini submatrix (same value is used for all local rows). 1676d975228cSstefano_zampini - onnz - array containing the number of nonzeros in the various rows of the 1677d975228cSstefano_zampini OFF-DIAGONAL portion of the local submatrix (possibly different for 16782ef1f0ffSBarry Smith each row) or `NULL` (`PETSC_NULL_INTEGER` in Fortran), if `o_nz` is used to specify the nonzero 1679d975228cSstefano_zampini structure. The size of this array is equal to the number 16802ef1f0ffSBarry Smith of local rows, i.e `m`. 1681d975228cSstefano_zampini 16822fe279fdSBarry Smith Level: intermediate 16832fe279fdSBarry Smith 168411a5261eSBarry Smith Note: 16852ef1f0ffSBarry Smith If the *nnz parameter is given then the *nz parameter is ignored; for sequential matrices, `onz` and `onnz` are ignored. 1686d975228cSstefano_zampini 16871cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatCreate()`, `MatMPIAIJSetPreallocation()`, `MATHYPRE`, `MATAIJ` 1688d975228cSstefano_zampini @*/ 1689d71ae5a4SJacob Faibussowitsch PetscErrorCode MatHYPRESetPreallocation(Mat A, PetscInt dnz, const PetscInt dnnz[], PetscInt onz, const PetscInt onnz[]) 1690d71ae5a4SJacob Faibussowitsch { 1691d975228cSstefano_zampini PetscFunctionBegin; 1692d975228cSstefano_zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 1693d975228cSstefano_zampini PetscValidType(A, 1); 1694cac4c232SBarry Smith PetscTryMethod(A, "MatHYPRESetPreallocation_C", (Mat, PetscInt, const PetscInt[], PetscInt, const PetscInt[]), (A, dnz, dnnz, onz, onnz)); 16953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1696d975228cSstefano_zampini } 1697d975228cSstefano_zampini 169820f4b53cSBarry Smith /*@C 16992ef1f0ffSBarry Smith MatCreateFromParCSR - Creates a `Mat` from a `hypre_ParCSRMatrix` 1700225daaf8SStefano Zampini 1701225daaf8SStefano Zampini Collective 1702225daaf8SStefano Zampini 1703225daaf8SStefano Zampini Input Parameters: 17042ef1f0ffSBarry Smith + parcsr - the pointer to the `hypre_ParCSRMatrix` 17052ef1f0ffSBarry Smith . mtype - matrix type to be created. Currently `MATAIJ`, `MATIS` and `MATHYPRE` are supported. 170620f4b53cSBarry Smith - copymode - PETSc copying options, see `PetscCopyMode` 1707225daaf8SStefano Zampini 1708225daaf8SStefano Zampini Output Parameter: 1709225daaf8SStefano Zampini . A - the matrix 1710225daaf8SStefano Zampini 1711225daaf8SStefano Zampini Level: intermediate 1712225daaf8SStefano Zampini 17131cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatHYPRE`, `PetscCopyMode` 171420f4b53cSBarry Smith @*/ 1715d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatCreateFromParCSR(hypre_ParCSRMatrix *parcsr, MatType mtype, PetscCopyMode copymode, Mat *A) 1716d71ae5a4SJacob Faibussowitsch { 1717225daaf8SStefano Zampini Mat T; 1718978814f1SStefano Zampini Mat_HYPRE *hA; 1719978814f1SStefano Zampini MPI_Comm comm; 1720978814f1SStefano Zampini PetscInt rstart, rend, cstart, cend, M, N; 1721d248a85cSRichard Tran Mills PetscBool isseqaij, isseqaijmkl, ismpiaij, isaij, ishyp, isis; 1722978814f1SStefano Zampini 1723978814f1SStefano Zampini PetscFunctionBegin; 1724978814f1SStefano Zampini comm = hypre_ParCSRMatrixComm(parcsr); 17259566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(mtype, MATSEQAIJ, &isseqaij)); 17269566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(mtype, MATSEQAIJMKL, &isseqaijmkl)); 17279566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(mtype, MATMPIAIJ, &ismpiaij)); 17289566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(mtype, MATAIJ, &isaij)); 17299566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(mtype, MATHYPRE, &ishyp)); 17309566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(mtype, MATIS, &isis)); 1731d248a85cSRichard Tran Mills isaij = (PetscBool)(isseqaij || isseqaijmkl || ismpiaij || isaij); 17326ea7df73SStefano Zampini /* TODO */ 1733aed4548fSBarry Smith PetscCheck(isaij || ishyp || isis, comm, PETSC_ERR_SUP, "Unsupported MatType %s! Supported types are %s, %s, %s, %s, %s, and %s", mtype, MATAIJ, MATSEQAIJ, MATSEQAIJMKL, MATMPIAIJ, MATIS, MATHYPRE); 1734978814f1SStefano Zampini /* access ParCSRMatrix */ 1735978814f1SStefano Zampini rstart = hypre_ParCSRMatrixFirstRowIndex(parcsr); 1736978814f1SStefano Zampini rend = hypre_ParCSRMatrixLastRowIndex(parcsr); 1737978814f1SStefano Zampini cstart = hypre_ParCSRMatrixFirstColDiag(parcsr); 1738978814f1SStefano Zampini cend = hypre_ParCSRMatrixLastColDiag(parcsr); 1739978814f1SStefano Zampini M = hypre_ParCSRMatrixGlobalNumRows(parcsr); 1740978814f1SStefano Zampini N = hypre_ParCSRMatrixGlobalNumCols(parcsr); 1741978814f1SStefano Zampini 1742fa92c42cSstefano_zampini /* fix for empty local rows/columns */ 1743fa92c42cSstefano_zampini if (rend < rstart) rend = rstart; 1744fa92c42cSstefano_zampini if (cend < cstart) cend = cstart; 1745fa92c42cSstefano_zampini 1746e6471dc9SStefano Zampini /* PETSc convention */ 1747e6471dc9SStefano Zampini rend++; 1748e6471dc9SStefano Zampini cend++; 1749e6471dc9SStefano Zampini rend = PetscMin(rend, M); 1750e6471dc9SStefano Zampini cend = PetscMin(cend, N); 1751e6471dc9SStefano Zampini 1752978814f1SStefano Zampini /* create PETSc matrix with MatHYPRE */ 17539566063dSJacob Faibussowitsch PetscCall(MatCreate(comm, &T)); 17549566063dSJacob Faibussowitsch PetscCall(MatSetSizes(T, rend - rstart, cend - cstart, M, N)); 17559566063dSJacob Faibussowitsch PetscCall(MatSetType(T, MATHYPRE)); 1756*f4f49eeaSPierre Jolivet hA = (Mat_HYPRE *)T->data; 1757978814f1SStefano Zampini 1758978814f1SStefano Zampini /* create HYPRE_IJMatrix */ 1759792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixCreate, hA->comm, rstart, rend - 1, cstart, cend - 1, &hA->ij); 1760792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixSetObjectType, hA->ij, HYPRE_PARCSR); 176145b8d346SStefano Zampini 176245b8d346SStefano Zampini /* create new ParCSR object if needed */ 176345b8d346SStefano Zampini if (ishyp && copymode == PETSC_COPY_VALUES) { 176445b8d346SStefano Zampini hypre_ParCSRMatrix *new_parcsr; 17656ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_LT(2, 18, 0) 176645b8d346SStefano Zampini hypre_CSRMatrix *hdiag, *hoffd, *ndiag, *noffd; 176745b8d346SStefano Zampini 17680e6427aaSSatish Balay new_parcsr = hypre_ParCSRMatrixClone(parcsr, 0); 176945b8d346SStefano Zampini hdiag = hypre_ParCSRMatrixDiag(parcsr); 177045b8d346SStefano Zampini hoffd = hypre_ParCSRMatrixOffd(parcsr); 177145b8d346SStefano Zampini ndiag = hypre_ParCSRMatrixDiag(new_parcsr); 177245b8d346SStefano Zampini noffd = hypre_ParCSRMatrixOffd(new_parcsr); 17739566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(hypre_CSRMatrixData(ndiag), hypre_CSRMatrixData(hdiag), hypre_CSRMatrixNumNonzeros(hdiag))); 17749566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(hypre_CSRMatrixData(noffd), hypre_CSRMatrixData(hoffd), hypre_CSRMatrixNumNonzeros(hoffd))); 17756ea7df73SStefano Zampini #else 17766ea7df73SStefano Zampini new_parcsr = hypre_ParCSRMatrixClone(parcsr, 1); 17776ea7df73SStefano Zampini #endif 177845b8d346SStefano Zampini parcsr = new_parcsr; 177945b8d346SStefano Zampini copymode = PETSC_OWN_POINTER; 178045b8d346SStefano Zampini } 1781978814f1SStefano Zampini 1782978814f1SStefano Zampini /* set ParCSR object */ 1783978814f1SStefano Zampini hypre_IJMatrixObject(hA->ij) = parcsr; 17844ec6421dSstefano_zampini T->preallocated = PETSC_TRUE; 1785978814f1SStefano Zampini 1786978814f1SStefano Zampini /* set assembled flag */ 1787978814f1SStefano Zampini hypre_IJMatrixAssembleFlag(hA->ij) = 1; 17886ea7df73SStefano Zampini #if 0 1789792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixInitialize,hA->ij); 17906ea7df73SStefano Zampini #endif 1791225daaf8SStefano Zampini if (ishyp) { 17926d2a658fSstefano_zampini PetscMPIInt myid = 0; 17936d2a658fSstefano_zampini 17946d2a658fSstefano_zampini /* make sure we always have row_starts and col_starts available */ 179548a46eb9SPierre Jolivet if (HYPRE_AssumedPartitionCheck()) PetscCallMPI(MPI_Comm_rank(comm, &myid)); 1796a1d2239cSSatish Balay #if defined(hypre_ParCSRMatrixOwnsRowStarts) 17976d2a658fSstefano_zampini if (!hypre_ParCSRMatrixOwnsColStarts(parcsr)) { 17986d2a658fSstefano_zampini PetscLayout map; 17996d2a658fSstefano_zampini 18009566063dSJacob Faibussowitsch PetscCall(MatGetLayouts(T, NULL, &map)); 18019566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(map)); 18022cf14000SStefano Zampini hypre_ParCSRMatrixColStarts(parcsr) = (HYPRE_BigInt *)(map->range + myid); 18036d2a658fSstefano_zampini } 18046d2a658fSstefano_zampini if (!hypre_ParCSRMatrixOwnsRowStarts(parcsr)) { 18056d2a658fSstefano_zampini PetscLayout map; 18066d2a658fSstefano_zampini 18079566063dSJacob Faibussowitsch PetscCall(MatGetLayouts(T, &map, NULL)); 18089566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(map)); 18092cf14000SStefano Zampini hypre_ParCSRMatrixRowStarts(parcsr) = (HYPRE_BigInt *)(map->range + myid); 18106d2a658fSstefano_zampini } 1811a1d2239cSSatish Balay #endif 1812978814f1SStefano Zampini /* prevent from freeing the pointer */ 1813978814f1SStefano Zampini if (copymode == PETSC_USE_POINTER) hA->inner_free = PETSC_FALSE; 1814225daaf8SStefano Zampini *A = T; 18159566063dSJacob Faibussowitsch PetscCall(MatSetOption(*A, MAT_SORTED_FULL, PETSC_TRUE)); 18169566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(*A, MAT_FINAL_ASSEMBLY)); 18179566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(*A, MAT_FINAL_ASSEMBLY)); 1818bb4689ddSStefano Zampini } else if (isaij) { 1819bb4689ddSStefano Zampini if (copymode != PETSC_OWN_POINTER) { 1820225daaf8SStefano Zampini /* prevent from freeing the pointer */ 1821225daaf8SStefano Zampini hA->inner_free = PETSC_FALSE; 18229566063dSJacob Faibussowitsch PetscCall(MatConvert_HYPRE_AIJ(T, MATAIJ, MAT_INITIAL_MATRIX, A)); 18239566063dSJacob Faibussowitsch PetscCall(MatDestroy(&T)); 1824225daaf8SStefano Zampini } else { /* AIJ return type with PETSC_OWN_POINTER */ 18259566063dSJacob Faibussowitsch PetscCall(MatConvert_HYPRE_AIJ(T, MATAIJ, MAT_INPLACE_MATRIX, &T)); 1826225daaf8SStefano Zampini *A = T; 1827225daaf8SStefano Zampini } 1828bb4689ddSStefano Zampini } else if (isis) { 18299566063dSJacob Faibussowitsch PetscCall(MatConvert_HYPRE_IS(T, MATIS, MAT_INITIAL_MATRIX, A)); 18308cfe8d00SStefano Zampini if (copymode != PETSC_OWN_POINTER) hA->inner_free = PETSC_FALSE; 18319566063dSJacob Faibussowitsch PetscCall(MatDestroy(&T)); 1832bb4689ddSStefano Zampini } 18333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1834978814f1SStefano Zampini } 1835978814f1SStefano Zampini 1836d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatHYPREGetParCSR_HYPRE(Mat A, hypre_ParCSRMatrix **parcsr) 1837d71ae5a4SJacob Faibussowitsch { 1838dd9c0a25Sstefano_zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 1839dd9c0a25Sstefano_zampini HYPRE_Int type; 1840dd9c0a25Sstefano_zampini 1841dd9c0a25Sstefano_zampini PetscFunctionBegin; 184228b400f6SJacob Faibussowitsch PetscCheck(hA->ij, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "HYPRE_IJMatrix not present"); 1843792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObjectType, hA->ij, &type); 184408401ef6SPierre Jolivet PetscCheck(type == HYPRE_PARCSR, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "HYPRE_IJMatrix is not of type HYPRE_PARCSR"); 1845792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hA->ij, (void **)parcsr); 18463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1847dd9c0a25Sstefano_zampini } 1848dd9c0a25Sstefano_zampini 184920f4b53cSBarry Smith /*@C 1850dd9c0a25Sstefano_zampini MatHYPREGetParCSR - Gets the pointer to the ParCSR matrix 1851dd9c0a25Sstefano_zampini 18522ef1f0ffSBarry Smith Not Collective 1853dd9c0a25Sstefano_zampini 185420f4b53cSBarry Smith Input Parameter: 185520f4b53cSBarry Smith . A - the `MATHYPRE` object 1856dd9c0a25Sstefano_zampini 1857dd9c0a25Sstefano_zampini Output Parameter: 18582ef1f0ffSBarry Smith . parcsr - the pointer to the `hypre_ParCSRMatrix` 1859dd9c0a25Sstefano_zampini 1860dd9c0a25Sstefano_zampini Level: intermediate 1861dd9c0a25Sstefano_zampini 18621cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatHYPRE`, `PetscCopyMode` 186320f4b53cSBarry Smith @*/ 1864d71ae5a4SJacob Faibussowitsch PetscErrorCode MatHYPREGetParCSR(Mat A, hypre_ParCSRMatrix **parcsr) 1865d71ae5a4SJacob Faibussowitsch { 1866dd9c0a25Sstefano_zampini PetscFunctionBegin; 1867dd9c0a25Sstefano_zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 1868dd9c0a25Sstefano_zampini PetscValidType(A, 1); 1869cac4c232SBarry Smith PetscUseMethod(A, "MatHYPREGetParCSR_C", (Mat, hypre_ParCSRMatrix **), (A, parcsr)); 18703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1871dd9c0a25Sstefano_zampini } 1872dd9c0a25Sstefano_zampini 1873d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMissingDiagonal_HYPRE(Mat A, PetscBool *missing, PetscInt *dd) 1874d71ae5a4SJacob Faibussowitsch { 187568ec7858SStefano Zampini hypre_ParCSRMatrix *parcsr; 187668ec7858SStefano Zampini hypre_CSRMatrix *ha; 187768ec7858SStefano Zampini PetscInt rst; 187868ec7858SStefano Zampini 187968ec7858SStefano Zampini PetscFunctionBegin; 188008401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not implemented with non-square diagonal blocks"); 18819566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(A, &rst, NULL)); 18829566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(A, &parcsr)); 188368ec7858SStefano Zampini if (missing) *missing = PETSC_FALSE; 188468ec7858SStefano Zampini if (dd) *dd = -1; 188568ec7858SStefano Zampini ha = hypre_ParCSRMatrixDiag(parcsr); 188668ec7858SStefano Zampini if (ha) { 188768299464SStefano Zampini PetscInt size, i; 188868299464SStefano Zampini HYPRE_Int *ii, *jj; 188968ec7858SStefano Zampini 189068ec7858SStefano Zampini size = hypre_CSRMatrixNumRows(ha); 189168ec7858SStefano Zampini ii = hypre_CSRMatrixI(ha); 189268ec7858SStefano Zampini jj = hypre_CSRMatrixJ(ha); 189368ec7858SStefano Zampini for (i = 0; i < size; i++) { 189468ec7858SStefano Zampini PetscInt j; 189568ec7858SStefano Zampini PetscBool found = PETSC_FALSE; 189668ec7858SStefano Zampini 18979371c9d4SSatish Balay for (j = ii[i]; j < ii[i + 1] && !found; j++) found = (jj[j] == i) ? PETSC_TRUE : PETSC_FALSE; 189868ec7858SStefano Zampini 189968ec7858SStefano Zampini if (!found) { 19003ba16761SJacob Faibussowitsch PetscCall(PetscInfo(A, "Matrix is missing local diagonal entry %" PetscInt_FMT "\n", i)); 190168ec7858SStefano Zampini if (missing) *missing = PETSC_TRUE; 190268ec7858SStefano Zampini if (dd) *dd = i + rst; 19033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 190468ec7858SStefano Zampini } 190568ec7858SStefano Zampini } 190668ec7858SStefano Zampini if (!size) { 19073ba16761SJacob Faibussowitsch PetscCall(PetscInfo(A, "Matrix has no diagonal entries therefore is missing diagonal\n")); 190868ec7858SStefano Zampini if (missing) *missing = PETSC_TRUE; 190968ec7858SStefano Zampini if (dd) *dd = rst; 191068ec7858SStefano Zampini } 191168ec7858SStefano Zampini } else { 19123ba16761SJacob Faibussowitsch PetscCall(PetscInfo(A, "Matrix has no diagonal entries therefore is missing diagonal\n")); 191368ec7858SStefano Zampini if (missing) *missing = PETSC_TRUE; 191468ec7858SStefano Zampini if (dd) *dd = rst; 191568ec7858SStefano Zampini } 19163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 191768ec7858SStefano Zampini } 191868ec7858SStefano Zampini 1919d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatScale_HYPRE(Mat A, PetscScalar s) 1920d71ae5a4SJacob Faibussowitsch { 192168ec7858SStefano Zampini hypre_ParCSRMatrix *parcsr; 19226ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_LT(2, 19, 0) 192368ec7858SStefano Zampini hypre_CSRMatrix *ha; 19246ea7df73SStefano Zampini #endif 192539accc25SStefano Zampini HYPRE_Complex hs; 192668ec7858SStefano Zampini 192768ec7858SStefano Zampini PetscFunctionBegin; 19289566063dSJacob Faibussowitsch PetscCall(PetscHYPREScalarCast(s, &hs)); 19299566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(A, &parcsr)); 19306ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2, 19, 0) 1931792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixScale, parcsr, hs); 19326ea7df73SStefano Zampini #else /* diagonal part */ 193368ec7858SStefano Zampini ha = hypre_ParCSRMatrixDiag(parcsr); 193468ec7858SStefano Zampini if (ha) { 193568299464SStefano Zampini PetscInt size, i; 193668299464SStefano Zampini HYPRE_Int *ii; 193739accc25SStefano Zampini HYPRE_Complex *a; 193868ec7858SStefano Zampini 193968ec7858SStefano Zampini size = hypre_CSRMatrixNumRows(ha); 194068ec7858SStefano Zampini a = hypre_CSRMatrixData(ha); 194168ec7858SStefano Zampini ii = hypre_CSRMatrixI(ha); 194239accc25SStefano Zampini for (i = 0; i < ii[size]; i++) a[i] *= hs; 194368ec7858SStefano Zampini } 19444cf0e950SBarry Smith /* off-diagonal part */ 194568ec7858SStefano Zampini ha = hypre_ParCSRMatrixOffd(parcsr); 194668ec7858SStefano Zampini if (ha) { 194768299464SStefano Zampini PetscInt size, i; 194868299464SStefano Zampini HYPRE_Int *ii; 194939accc25SStefano Zampini HYPRE_Complex *a; 195068ec7858SStefano Zampini 195168ec7858SStefano Zampini size = hypre_CSRMatrixNumRows(ha); 195268ec7858SStefano Zampini a = hypre_CSRMatrixData(ha); 195368ec7858SStefano Zampini ii = hypre_CSRMatrixI(ha); 195439accc25SStefano Zampini for (i = 0; i < ii[size]; i++) a[i] *= hs; 195568ec7858SStefano Zampini } 19566ea7df73SStefano Zampini #endif 19573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 195868ec7858SStefano Zampini } 195968ec7858SStefano Zampini 1960d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatZeroRowsColumns_HYPRE(Mat A, PetscInt numRows, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) 1961d71ae5a4SJacob Faibussowitsch { 196268ec7858SStefano Zampini hypre_ParCSRMatrix *parcsr; 196368299464SStefano Zampini HYPRE_Int *lrows; 196468299464SStefano Zampini PetscInt rst, ren, i; 196568ec7858SStefano Zampini 196668ec7858SStefano Zampini PetscFunctionBegin; 196708401ef6SPierre Jolivet PetscCheck(!x && !b, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "To be implemented"); 19689566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(A, &parcsr)); 19699566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numRows, &lrows)); 19709566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(A, &rst, &ren)); 197168ec7858SStefano Zampini for (i = 0; i < numRows; i++) { 19727a46b595SBarry Smith PetscCheck(rows[i] >= rst && rows[i] < ren, PETSC_COMM_SELF, PETSC_ERR_SUP, "Non-local rows not yet supported"); 197368ec7858SStefano Zampini lrows[i] = rows[i] - rst; 197468ec7858SStefano Zampini } 1975792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixEliminateRowsCols, parcsr, numRows, lrows); 19769566063dSJacob Faibussowitsch PetscCall(PetscFree(lrows)); 19773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 197868ec7858SStefano Zampini } 197968ec7858SStefano Zampini 1980d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatZeroEntries_HYPRE_CSRMatrix(hypre_CSRMatrix *ha) 1981d71ae5a4SJacob Faibussowitsch { 1982c69f721fSFande Kong PetscFunctionBegin; 1983c69f721fSFande Kong if (ha) { 1984c69f721fSFande Kong HYPRE_Int *ii, size; 1985c69f721fSFande Kong HYPRE_Complex *a; 1986c69f721fSFande Kong 1987c69f721fSFande Kong size = hypre_CSRMatrixNumRows(ha); 1988c69f721fSFande Kong a = hypre_CSRMatrixData(ha); 1989c69f721fSFande Kong ii = hypre_CSRMatrixI(ha); 1990c69f721fSFande Kong 19919566063dSJacob Faibussowitsch if (a) PetscCall(PetscArrayzero(a, ii[size])); 1992c69f721fSFande Kong } 19933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1994c69f721fSFande Kong } 1995c69f721fSFande Kong 199666976f2fSJacob Faibussowitsch static PetscErrorCode MatZeroEntries_HYPRE(Mat A) 1997d71ae5a4SJacob Faibussowitsch { 19986ea7df73SStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 19996ea7df73SStefano Zampini 20006ea7df73SStefano Zampini PetscFunctionBegin; 20016ea7df73SStefano Zampini if (HYPRE_MEMORY_DEVICE == hypre_IJMatrixMemoryLocation(hA->ij)) { 2002792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixSetConstantValues, hA->ij, 0.0); 20036ea7df73SStefano Zampini } else { 2004c69f721fSFande Kong hypre_ParCSRMatrix *parcsr; 2005c69f721fSFande Kong 20069566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(A, &parcsr)); 20079566063dSJacob Faibussowitsch PetscCall(MatZeroEntries_HYPRE_CSRMatrix(hypre_ParCSRMatrixDiag(parcsr))); 20089566063dSJacob Faibussowitsch PetscCall(MatZeroEntries_HYPRE_CSRMatrix(hypre_ParCSRMatrixOffd(parcsr))); 20096ea7df73SStefano Zampini } 20103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2011c69f721fSFande Kong } 2012c69f721fSFande Kong 2013d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatZeroRows_HYPRE_CSRMatrix(hypre_CSRMatrix *hA, PetscInt N, const PetscInt rows[], HYPRE_Complex diag) 2014d71ae5a4SJacob Faibussowitsch { 201539accc25SStefano Zampini PetscInt ii; 201639accc25SStefano Zampini HYPRE_Int *i, *j; 201739accc25SStefano Zampini HYPRE_Complex *a; 2018c69f721fSFande Kong 2019c69f721fSFande Kong PetscFunctionBegin; 20203ba16761SJacob Faibussowitsch if (!hA) PetscFunctionReturn(PETSC_SUCCESS); 2021c69f721fSFande Kong 202239accc25SStefano Zampini i = hypre_CSRMatrixI(hA); 202339accc25SStefano Zampini j = hypre_CSRMatrixJ(hA); 2024c69f721fSFande Kong a = hypre_CSRMatrixData(hA); 2025a32e9c99SJunchao Zhang #if defined(PETSC_HAVE_HYPRE_DEVICE) 2026a32e9c99SJunchao Zhang if (HYPRE_MEMORY_DEVICE == hypre_CSRMatrixMemoryLocation(hA)) { 2027a32e9c99SJunchao Zhang #if defined(HYPRE_USING_CUDA) 2028a32e9c99SJunchao Zhang MatZeroRows_CUDA(N, rows, i, j, a, diag); 2029a32e9c99SJunchao Zhang #elif defined(HYPRE_USING_HIP) 2030a32e9c99SJunchao Zhang MatZeroRows_HIP(N, rows, i, j, a, diag); 2031a32e9c99SJunchao Zhang #elif defined(PETSC_HAVE_KOKKOS) 2032a32e9c99SJunchao Zhang MatZeroRows_Kokkos(N, rows, i, j, a, diag); 2033a32e9c99SJunchao Zhang #else 2034a32e9c99SJunchao Zhang SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No support for MatZeroRows on a hypre matrix in this memory location"); 2035a32e9c99SJunchao Zhang #endif 2036a32e9c99SJunchao Zhang } else 2037a32e9c99SJunchao Zhang #endif 2038a32e9c99SJunchao Zhang { 2039c69f721fSFande Kong for (ii = 0; ii < N; ii++) { 204039accc25SStefano Zampini HYPRE_Int jj, ibeg, iend, irow; 204139accc25SStefano Zampini 2042c69f721fSFande Kong irow = rows[ii]; 2043c69f721fSFande Kong ibeg = i[irow]; 2044c69f721fSFande Kong iend = i[irow + 1]; 2045c69f721fSFande Kong for (jj = ibeg; jj < iend; jj++) 2046c69f721fSFande Kong if (j[jj] == irow) a[jj] = diag; 2047c69f721fSFande Kong else a[jj] = 0.0; 2048c69f721fSFande Kong } 2049a32e9c99SJunchao Zhang } 20503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2051c69f721fSFande Kong } 2052c69f721fSFande Kong 2053d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatZeroRows_HYPRE(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) 2054d71ae5a4SJacob Faibussowitsch { 2055c69f721fSFande Kong hypre_ParCSRMatrix *parcsr; 2056a32e9c99SJunchao Zhang PetscInt *lrows, len, *lrows2; 205739accc25SStefano Zampini HYPRE_Complex hdiag; 2058c69f721fSFande Kong 2059c69f721fSFande Kong PetscFunctionBegin; 206008401ef6SPierre Jolivet PetscCheck(!x && !b, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Does not support to modify the solution and the right hand size"); 20619566063dSJacob Faibussowitsch PetscCall(PetscHYPREScalarCast(diag, &hdiag)); 2062c69f721fSFande Kong /* retrieve the internal matrix */ 20639566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(A, &parcsr)); 2064c69f721fSFande Kong /* get locally owned rows */ 20659566063dSJacob Faibussowitsch PetscCall(MatZeroRowsMapLocal_Private(A, N, rows, &len, &lrows)); 2066a32e9c99SJunchao Zhang 2067a32e9c99SJunchao Zhang #if defined(PETSC_HAVE_HYPRE_DEVICE) 2068a32e9c99SJunchao Zhang if (HYPRE_MEMORY_DEVICE == hypre_CSRMatrixMemoryLocation(hypre_ParCSRMatrixDiag(parcsr))) { 2069a32e9c99SJunchao Zhang Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 2070a32e9c99SJunchao Zhang PetscInt m; 2071a32e9c99SJunchao Zhang PetscCall(MatGetLocalSize(A, &m, NULL)); 2072a32e9c99SJunchao Zhang if (!hA->rows_d) { 2073a32e9c99SJunchao Zhang hA->rows_d = hypre_TAlloc(PetscInt, m, HYPRE_MEMORY_DEVICE); 2074a32e9c99SJunchao Zhang if (m) PetscCheck(hA->rows_d, PETSC_COMM_SELF, PETSC_ERR_MEM, "HYPRE_TAlloc failed"); 2075a32e9c99SJunchao Zhang } 2076a32e9c99SJunchao Zhang PetscCheck(len <= m, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Too many rows in rows[]"); 2077a32e9c99SJunchao Zhang PetscStackCallExternalVoid("hypre_Memcpy", hypre_Memcpy(hA->rows_d, lrows, sizeof(PetscInt) * len, HYPRE_MEMORY_DEVICE, HYPRE_MEMORY_HOST)); 2078a32e9c99SJunchao Zhang lrows2 = hA->rows_d; 2079a32e9c99SJunchao Zhang } else 2080a32e9c99SJunchao Zhang #endif 2081a32e9c99SJunchao Zhang { 2082a32e9c99SJunchao Zhang lrows2 = lrows; 2083a32e9c99SJunchao Zhang } 2084a32e9c99SJunchao Zhang 2085c69f721fSFande Kong /* zero diagonal part */ 2086a32e9c99SJunchao Zhang PetscCall(MatZeroRows_HYPRE_CSRMatrix(hypre_ParCSRMatrixDiag(parcsr), len, lrows2, hdiag)); 2087c69f721fSFande Kong /* zero off-diagonal part */ 2088a32e9c99SJunchao Zhang PetscCall(MatZeroRows_HYPRE_CSRMatrix(hypre_ParCSRMatrixOffd(parcsr), len, lrows2, 0.0)); 2089c69f721fSFande Kong 20909566063dSJacob Faibussowitsch PetscCall(PetscFree(lrows)); 20913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2092c69f721fSFande Kong } 2093c69f721fSFande Kong 2094d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyBegin_HYPRE(Mat mat, MatAssemblyType mode) 2095d71ae5a4SJacob Faibussowitsch { 2096c69f721fSFande Kong PetscFunctionBegin; 20973ba16761SJacob Faibussowitsch if (mat->nooffprocentries) PetscFunctionReturn(PETSC_SUCCESS); 2098c69f721fSFande Kong 20999566063dSJacob Faibussowitsch PetscCall(MatStashScatterBegin_Private(mat, &mat->stash, mat->rmap->range)); 21003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2101c69f721fSFande Kong } 2102c69f721fSFande Kong 2103d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRow_HYPRE(Mat A, PetscInt row, PetscInt *nz, PetscInt **idx, PetscScalar **v) 2104d71ae5a4SJacob Faibussowitsch { 2105c69f721fSFande Kong hypre_ParCSRMatrix *parcsr; 21062cf14000SStefano Zampini HYPRE_Int hnz; 2107c69f721fSFande Kong 2108c69f721fSFande Kong PetscFunctionBegin; 2109c69f721fSFande Kong /* retrieve the internal matrix */ 21109566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(A, &parcsr)); 2111c69f721fSFande Kong /* call HYPRE API */ 2112792fecdfSBarry Smith PetscCallExternal(HYPRE_ParCSRMatrixGetRow, parcsr, row, &hnz, (HYPRE_BigInt **)idx, (HYPRE_Complex **)v); 21132cf14000SStefano Zampini if (nz) *nz = (PetscInt)hnz; 21143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2115c69f721fSFande Kong } 2116c69f721fSFande Kong 2117d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRestoreRow_HYPRE(Mat A, PetscInt row, PetscInt *nz, PetscInt **idx, PetscScalar **v) 2118d71ae5a4SJacob Faibussowitsch { 2119c69f721fSFande Kong hypre_ParCSRMatrix *parcsr; 21202cf14000SStefano Zampini HYPRE_Int hnz; 2121c69f721fSFande Kong 2122c69f721fSFande Kong PetscFunctionBegin; 2123c69f721fSFande Kong /* retrieve the internal matrix */ 21249566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(A, &parcsr)); 2125c69f721fSFande Kong /* call HYPRE API */ 21262cf14000SStefano Zampini hnz = nz ? (HYPRE_Int)(*nz) : 0; 2127792fecdfSBarry Smith PetscCallExternal(HYPRE_ParCSRMatrixRestoreRow, parcsr, row, &hnz, (HYPRE_BigInt **)idx, (HYPRE_Complex **)v); 21283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2129c69f721fSFande Kong } 2130c69f721fSFande Kong 2131d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetValues_HYPRE(Mat A, PetscInt m, const PetscInt idxm[], PetscInt n, const PetscInt idxn[], PetscScalar v[]) 2132d71ae5a4SJacob Faibussowitsch { 213345b8d346SStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 2134c69f721fSFande Kong PetscInt i; 21351d4906efSStefano Zampini 2136c69f721fSFande Kong PetscFunctionBegin; 21373ba16761SJacob Faibussowitsch if (!m || !n) PetscFunctionReturn(PETSC_SUCCESS); 2138c69f721fSFande Kong /* Ignore negative row indices 2139c69f721fSFande Kong * And negative column indices should be automatically ignored in hypre 2140c69f721fSFande Kong * */ 21412cf14000SStefano Zampini for (i = 0; i < m; i++) { 21422cf14000SStefano Zampini if (idxm[i] >= 0) { 21432cf14000SStefano Zampini HYPRE_Int hn = (HYPRE_Int)n; 2144792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetValues, hA->ij, 1, &hn, (HYPRE_BigInt *)&idxm[i], (HYPRE_BigInt *)idxn, (HYPRE_Complex *)(v + i * n)); 21452cf14000SStefano Zampini } 21462cf14000SStefano Zampini } 21473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2148c69f721fSFande Kong } 2149c69f721fSFande Kong 2150d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetOption_HYPRE(Mat A, MatOption op, PetscBool flg) 2151d71ae5a4SJacob Faibussowitsch { 2152ddbeb582SStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 2153ddbeb582SStefano Zampini 2154ddbeb582SStefano Zampini PetscFunctionBegin; 2155c6698e78SStefano Zampini switch (op) { 2156ddbeb582SStefano Zampini case MAT_NO_OFF_PROC_ENTRIES: 215748a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_IJMatrixSetMaxOffProcElmts, hA->ij, 0); 2158ddbeb582SStefano Zampini break; 2159651b1cf9SStefano Zampini case MAT_IGNORE_OFF_PROC_ENTRIES: 2160651b1cf9SStefano Zampini hA->donotstash = flg; 2161d71ae5a4SJacob Faibussowitsch break; 2162d71ae5a4SJacob Faibussowitsch default: 2163d71ae5a4SJacob Faibussowitsch break; 2164ddbeb582SStefano Zampini } 21653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2166ddbeb582SStefano Zampini } 2167c69f721fSFande Kong 2168d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_HYPRE(Mat A, PetscViewer view) 2169d71ae5a4SJacob Faibussowitsch { 217045b8d346SStefano Zampini PetscViewerFormat format; 217145b8d346SStefano Zampini 217245b8d346SStefano Zampini PetscFunctionBegin; 21739566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(view, &format)); 21743ba16761SJacob Faibussowitsch if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) PetscFunctionReturn(PETSC_SUCCESS); 217545b8d346SStefano Zampini if (format != PETSC_VIEWER_NATIVE) { 21766ea7df73SStefano Zampini Mat B; 21776ea7df73SStefano Zampini hypre_ParCSRMatrix *parcsr; 21786ea7df73SStefano Zampini PetscErrorCode (*mview)(Mat, PetscViewer) = NULL; 21796ea7df73SStefano Zampini 21809566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(A, &parcsr)); 21819566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(parcsr, MATAIJ, PETSC_USE_POINTER, &B)); 21829566063dSJacob Faibussowitsch PetscCall(MatGetOperation(B, MATOP_VIEW, (void (**)(void)) & mview)); 218328b400f6SJacob Faibussowitsch PetscCheck(mview, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Missing view operation"); 21849566063dSJacob Faibussowitsch PetscCall((*mview)(B, view)); 21859566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 218645b8d346SStefano Zampini } else { 218745b8d346SStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 218845b8d346SStefano Zampini PetscMPIInt size; 218945b8d346SStefano Zampini PetscBool isascii; 219045b8d346SStefano Zampini const char *filename; 219145b8d346SStefano Zampini 219245b8d346SStefano Zampini /* HYPRE uses only text files */ 21939566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERASCII, &isascii)); 219428b400f6SJacob Faibussowitsch PetscCheck(isascii, PetscObjectComm((PetscObject)view), PETSC_ERR_SUP, "PetscViewerType %s: native HYPRE format needs PETSCVIEWERASCII", ((PetscObject)view)->type_name); 21959566063dSJacob Faibussowitsch PetscCall(PetscViewerFileGetName(view, &filename)); 2196792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixPrint, hA->ij, filename); 21979566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(hA->comm, &size)); 219845b8d346SStefano Zampini if (size > 1) { 21999566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(view, "Matrix files: %s.%05d ... %s.%05d\n", filename, 0, filename, size - 1)); 220045b8d346SStefano Zampini } else { 22019566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(view, "Matrix file: %s.%05d\n", filename, 0)); 220245b8d346SStefano Zampini } 220345b8d346SStefano Zampini } 22043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 220545b8d346SStefano Zampini } 220645b8d346SStefano Zampini 2207d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCopy_HYPRE(Mat A, Mat B, MatStructure str) 2208d71ae5a4SJacob Faibussowitsch { 2209465edc17SStefano Zampini hypre_ParCSRMatrix *acsr, *bcsr; 2210465edc17SStefano Zampini 2211465edc17SStefano Zampini PetscFunctionBegin; 2212465edc17SStefano Zampini if (str == SAME_NONZERO_PATTERN && A->ops->copy == B->ops->copy) { 22139566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(A, &acsr)); 22149566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(B, &bcsr)); 2215792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixCopy, acsr, bcsr, 1); 22169566063dSJacob Faibussowitsch PetscCall(MatSetOption(B, MAT_SORTED_FULL, PETSC_TRUE)); /* "perfect" preallocation, so no need for hypre_AuxParCSRMatrixNeedAux */ 22179566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 22189566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 2219465edc17SStefano Zampini } else { 22209566063dSJacob Faibussowitsch PetscCall(MatCopy_Basic(A, B, str)); 2221465edc17SStefano Zampini } 22223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2223465edc17SStefano Zampini } 2224465edc17SStefano Zampini 2225d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetDiagonal_HYPRE(Mat A, Vec d) 2226d71ae5a4SJacob Faibussowitsch { 22276305df00SStefano Zampini hypre_ParCSRMatrix *parcsr; 22286305df00SStefano Zampini hypre_CSRMatrix *dmat; 222939accc25SStefano Zampini HYPRE_Complex *a; 22306305df00SStefano Zampini PetscBool cong; 22316305df00SStefano Zampini 22326305df00SStefano Zampini PetscFunctionBegin; 22339566063dSJacob Faibussowitsch PetscCall(MatHasCongruentLayouts(A, &cong)); 223428b400f6SJacob Faibussowitsch PetscCheck(cong, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Only for square matrices with same local distributions of rows and columns"); 22359566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(A, &parcsr)); 22366305df00SStefano Zampini dmat = hypre_ParCSRMatrixDiag(parcsr); 22376305df00SStefano Zampini if (dmat) { 223806977982Sstefanozampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 223906977982Sstefanozampini HYPRE_MemoryLocation mem = hypre_CSRMatrixMemoryLocation(dmat); 224006977982Sstefanozampini #else 224106977982Sstefanozampini HYPRE_MemoryLocation mem = HYPRE_MEMORY_HOST; 224206977982Sstefanozampini #endif 224306977982Sstefanozampini 224406977982Sstefanozampini if (mem != HYPRE_MEMORY_HOST) PetscCall(VecGetArrayWriteAndMemType(d, (PetscScalar **)&a, NULL)); 224506977982Sstefanozampini else PetscCall(VecGetArrayWrite(d, (PetscScalar **)&a)); 224606977982Sstefanozampini hypre_CSRMatrixExtractDiagonal(dmat, a, 0); 224706977982Sstefanozampini if (mem != HYPRE_MEMORY_HOST) PetscCall(VecRestoreArrayWriteAndMemType(d, (PetscScalar **)&a)); 224806977982Sstefanozampini else PetscCall(VecRestoreArrayWrite(d, (PetscScalar **)&a)); 22496305df00SStefano Zampini } 22503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22516305df00SStefano Zampini } 22526305df00SStefano Zampini 2253363d496dSStefano Zampini #include <petscblaslapack.h> 2254363d496dSStefano Zampini 2255d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAXPY_HYPRE(Mat Y, PetscScalar a, Mat X, MatStructure str) 2256d71ae5a4SJacob Faibussowitsch { 2257363d496dSStefano Zampini PetscFunctionBegin; 22586ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 22596ea7df73SStefano Zampini { 22606ea7df73SStefano Zampini Mat B; 22616ea7df73SStefano Zampini hypre_ParCSRMatrix *x, *y, *z; 22626ea7df73SStefano Zampini 22639566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR(Y, &y)); 22649566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR(X, &x)); 2265792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixAdd, 1.0, y, 1.0, x, &z); 22669566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(z, MATHYPRE, PETSC_OWN_POINTER, &B)); 22679566063dSJacob Faibussowitsch PetscCall(MatHeaderMerge(Y, &B)); 22686ea7df73SStefano Zampini } 22696ea7df73SStefano Zampini #else 2270363d496dSStefano Zampini if (str == SAME_NONZERO_PATTERN) { 2271363d496dSStefano Zampini hypre_ParCSRMatrix *x, *y; 2272363d496dSStefano Zampini hypre_CSRMatrix *xloc, *yloc; 2273363d496dSStefano Zampini PetscInt xnnz, ynnz; 227439accc25SStefano Zampini HYPRE_Complex *xarr, *yarr; 2275363d496dSStefano Zampini PetscBLASInt one = 1, bnz; 2276363d496dSStefano Zampini 22779566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR(Y, &y)); 22789566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR(X, &x)); 2279363d496dSStefano Zampini 2280363d496dSStefano Zampini /* diagonal block */ 2281363d496dSStefano Zampini xloc = hypre_ParCSRMatrixDiag(x); 2282363d496dSStefano Zampini yloc = hypre_ParCSRMatrixDiag(y); 2283363d496dSStefano Zampini xnnz = 0; 2284363d496dSStefano Zampini ynnz = 0; 2285363d496dSStefano Zampini xarr = NULL; 2286363d496dSStefano Zampini yarr = NULL; 2287363d496dSStefano Zampini if (xloc) { 228839accc25SStefano Zampini xarr = hypre_CSRMatrixData(xloc); 2289363d496dSStefano Zampini xnnz = hypre_CSRMatrixNumNonzeros(xloc); 2290363d496dSStefano Zampini } 2291363d496dSStefano Zampini if (yloc) { 229239accc25SStefano Zampini yarr = hypre_CSRMatrixData(yloc); 2293363d496dSStefano Zampini ynnz = hypre_CSRMatrixNumNonzeros(yloc); 2294363d496dSStefano Zampini } 229508401ef6SPierre Jolivet PetscCheck(xnnz == ynnz, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Different number of nonzeros in diagonal block %" PetscInt_FMT " != %" PetscInt_FMT, xnnz, ynnz); 22969566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(xnnz, &bnz)); 2297792fecdfSBarry Smith PetscCallBLAS("BLASaxpy", BLASaxpy_(&bnz, &a, (PetscScalar *)xarr, &one, (PetscScalar *)yarr, &one)); 2298363d496dSStefano Zampini 2299363d496dSStefano Zampini /* off-diagonal block */ 2300363d496dSStefano Zampini xloc = hypre_ParCSRMatrixOffd(x); 2301363d496dSStefano Zampini yloc = hypre_ParCSRMatrixOffd(y); 2302363d496dSStefano Zampini xnnz = 0; 2303363d496dSStefano Zampini ynnz = 0; 2304363d496dSStefano Zampini xarr = NULL; 2305363d496dSStefano Zampini yarr = NULL; 2306363d496dSStefano Zampini if (xloc) { 230739accc25SStefano Zampini xarr = hypre_CSRMatrixData(xloc); 2308363d496dSStefano Zampini xnnz = hypre_CSRMatrixNumNonzeros(xloc); 2309363d496dSStefano Zampini } 2310363d496dSStefano Zampini if (yloc) { 231139accc25SStefano Zampini yarr = hypre_CSRMatrixData(yloc); 2312363d496dSStefano Zampini ynnz = hypre_CSRMatrixNumNonzeros(yloc); 2313363d496dSStefano Zampini } 231408401ef6SPierre Jolivet PetscCheck(xnnz == ynnz, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Different number of nonzeros in off-diagonal block %" PetscInt_FMT " != %" PetscInt_FMT, xnnz, ynnz); 23159566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(xnnz, &bnz)); 2316792fecdfSBarry Smith PetscCallBLAS("BLASaxpy", BLASaxpy_(&bnz, &a, (PetscScalar *)xarr, &one, (PetscScalar *)yarr, &one)); 2317363d496dSStefano Zampini } else if (str == SUBSET_NONZERO_PATTERN) { 23189566063dSJacob Faibussowitsch PetscCall(MatAXPY_Basic(Y, a, X, str)); 2319363d496dSStefano Zampini } else { 2320363d496dSStefano Zampini Mat B; 2321363d496dSStefano Zampini 23229566063dSJacob Faibussowitsch PetscCall(MatAXPY_Basic_Preallocate(Y, X, &B)); 23239566063dSJacob Faibussowitsch PetscCall(MatAXPY_BasicWithPreallocation(B, Y, a, X, str)); 23249566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(Y, &B)); 2325363d496dSStefano Zampini } 23266ea7df73SStefano Zampini #endif 23273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2328363d496dSStefano Zampini } 2329363d496dSStefano Zampini 23302c4ab24aSJunchao Zhang static PetscErrorCode MatDuplicate_HYPRE(Mat A, MatDuplicateOption op, Mat *B) 23312c4ab24aSJunchao Zhang { 23322c4ab24aSJunchao Zhang hypre_ParCSRMatrix *parcsr = NULL; 23332c4ab24aSJunchao Zhang PetscCopyMode cpmode; 23342c4ab24aSJunchao Zhang Mat_HYPRE *hA; 23352c4ab24aSJunchao Zhang 23362c4ab24aSJunchao Zhang PetscFunctionBegin; 23372c4ab24aSJunchao Zhang PetscCall(MatHYPREGetParCSR_HYPRE(A, &parcsr)); 23382c4ab24aSJunchao Zhang if (op == MAT_DO_NOT_COPY_VALUES || op == MAT_SHARE_NONZERO_PATTERN) { 23392c4ab24aSJunchao Zhang parcsr = hypre_ParCSRMatrixClone(parcsr, 0); 23402c4ab24aSJunchao Zhang cpmode = PETSC_OWN_POINTER; 23412c4ab24aSJunchao Zhang } else { 23422c4ab24aSJunchao Zhang cpmode = PETSC_COPY_VALUES; 23432c4ab24aSJunchao Zhang } 23442c4ab24aSJunchao Zhang PetscCall(MatCreateFromParCSR(parcsr, MATHYPRE, cpmode, B)); 23452c4ab24aSJunchao Zhang hA = (Mat_HYPRE *)A->data; 23462c4ab24aSJunchao Zhang if (hA->cooMat) { 234706977982Sstefanozampini Mat_HYPRE *hB = (Mat_HYPRE *)((*B)->data); 2348b73e3080SStefano Zampini op = (op == MAT_DO_NOT_COPY_VALUES) ? op : MAT_COPY_VALUES; 2349b73e3080SStefano Zampini /* Cannot simply increase the reference count of hA->cooMat, since B needs to share cooMat's data array */ 235006977982Sstefanozampini PetscCall(MatDuplicate(hA->cooMat, op, &hB->cooMat)); 235106977982Sstefanozampini PetscCall(MatHYPRE_AttachCOOMat(*B)); 23522c4ab24aSJunchao Zhang } 23532c4ab24aSJunchao Zhang PetscFunctionReturn(PETSC_SUCCESS); 23542c4ab24aSJunchao Zhang } 23552c4ab24aSJunchao Zhang 2356d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetPreallocationCOO_HYPRE(Mat mat, PetscCount coo_n, PetscInt coo_i[], PetscInt coo_j[]) 2357d71ae5a4SJacob Faibussowitsch { 235806977982Sstefanozampini Mat_HYPRE *hmat = (Mat_HYPRE *)mat->data; 23595fbaff96SJunchao Zhang 23605fbaff96SJunchao Zhang PetscFunctionBegin; 2361651b1cf9SStefano Zampini /* Build an agent matrix cooMat with AIJ format 23625fbaff96SJunchao Zhang It has the same sparsity pattern as mat, and also shares the data array with mat. We use cooMat to do the COO work. 23635fbaff96SJunchao Zhang */ 236406977982Sstefanozampini PetscCall(MatHYPRE_CreateCOOMat(mat)); 236506977982Sstefanozampini PetscCall(MatSetOption(hmat->cooMat, MAT_IGNORE_OFF_PROC_ENTRIES, hmat->donotstash)); 236606977982Sstefanozampini PetscCall(MatSetOption(hmat->cooMat, MAT_NO_OFF_PROC_ENTRIES, mat->nooffprocentries)); 2367651b1cf9SStefano Zampini 2368651b1cf9SStefano Zampini /* MatSetPreallocationCOO_SeqAIJ and MatSetPreallocationCOO_MPIAIJ uses this specific 2369651b1cf9SStefano Zampini name to automatically put the diagonal entries first */ 237006977982Sstefanozampini PetscCall(PetscObjectSetName((PetscObject)hmat->cooMat, "_internal_COO_mat_for_hypre")); 237106977982Sstefanozampini PetscCall(MatSetPreallocationCOO(hmat->cooMat, coo_n, coo_i, coo_j)); 237206977982Sstefanozampini hmat->cooMat->assembled = PETSC_TRUE; 23735fbaff96SJunchao Zhang 23745fbaff96SJunchao Zhang /* Copy the sparsity pattern from cooMat to hypre IJMatrix hmat->ij */ 23755fbaff96SJunchao Zhang PetscCall(MatSetOption(mat, MAT_SORTED_FULL, PETSC_TRUE)); 237606977982Sstefanozampini PetscCall(MatHYPRE_CreateFromMat(hmat->cooMat, hmat)); /* Create hmat->ij and preallocate it */ 237706977982Sstefanozampini PetscCall(MatHYPRE_IJMatrixCopyIJ(hmat->cooMat, hmat->ij)); /* Copy A's (i,j) to hmat->ij */ 23785fbaff96SJunchao Zhang 23795fbaff96SJunchao Zhang mat->preallocated = PETSC_TRUE; 23805fbaff96SJunchao Zhang PetscCall(MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY)); 23815fbaff96SJunchao Zhang PetscCall(MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY)); /* Migrate mat to device if it is bound to. Hypre builds its own SpMV context here */ 23825fbaff96SJunchao Zhang 23832c4ab24aSJunchao Zhang /* Attach cooMat to mat */ 238406977982Sstefanozampini PetscCall(MatHYPRE_AttachCOOMat(mat)); 23853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23865fbaff96SJunchao Zhang } 23875fbaff96SJunchao Zhang 2388d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetValuesCOO_HYPRE(Mat mat, const PetscScalar v[], InsertMode imode) 2389d71ae5a4SJacob Faibussowitsch { 23905fbaff96SJunchao Zhang Mat_HYPRE *hmat = (Mat_HYPRE *)mat->data; 23915fbaff96SJunchao Zhang 23925fbaff96SJunchao Zhang PetscFunctionBegin; 2393b73e3080SStefano Zampini PetscCheck(hmat->cooMat, PetscObjectComm((PetscObject)mat), PETSC_ERR_PLIB, "HYPRE COO delegate matrix has not been created yet"); 23945fbaff96SJunchao Zhang PetscCall(MatSetValuesCOO(hmat->cooMat, v, imode)); 2395651b1cf9SStefano Zampini PetscCall(MatViewFromOptions(hmat->cooMat, (PetscObject)mat, "-cooMat_view")); 23963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23975fbaff96SJunchao Zhang } 23985fbaff96SJunchao Zhang 2399a055b5aaSBarry Smith /*MC 24002ef1f0ffSBarry Smith MATHYPRE - "hypre" - A matrix type to be used for sequential and parallel sparse matrices 2401a055b5aaSBarry Smith based on the hypre IJ interface. 2402a055b5aaSBarry Smith 2403a055b5aaSBarry Smith Level: intermediate 2404a055b5aaSBarry Smith 24051cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatCreate()`, `MatHYPRESetPreallocation` 2406a055b5aaSBarry Smith M*/ 2407a055b5aaSBarry Smith 2408d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatCreate_HYPRE(Mat B) 2409d71ae5a4SJacob Faibussowitsch { 241063c07aadSStefano Zampini Mat_HYPRE *hB; 241163c07aadSStefano Zampini 241263c07aadSStefano Zampini PetscFunctionBegin; 24134dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&hB)); 24146ea7df73SStefano Zampini 2415978814f1SStefano Zampini hB->inner_free = PETSC_TRUE; 2416651b1cf9SStefano Zampini hB->array_available = PETSC_TRUE; 2417978814f1SStefano Zampini 241863c07aadSStefano Zampini B->data = (void *)hB; 241963c07aadSStefano Zampini 24209566063dSJacob Faibussowitsch PetscCall(PetscMemzero(B->ops, sizeof(struct _MatOps))); 242163c07aadSStefano Zampini B->ops->mult = MatMult_HYPRE; 242263c07aadSStefano Zampini B->ops->multtranspose = MatMultTranspose_HYPRE; 2423414bd5c3SStefano Zampini B->ops->multadd = MatMultAdd_HYPRE; 2424414bd5c3SStefano Zampini B->ops->multtransposeadd = MatMultTransposeAdd_HYPRE; 242563c07aadSStefano Zampini B->ops->setup = MatSetUp_HYPRE; 242663c07aadSStefano Zampini B->ops->destroy = MatDestroy_HYPRE; 242763c07aadSStefano Zampini B->ops->assemblyend = MatAssemblyEnd_HYPRE; 2428c69f721fSFande Kong B->ops->assemblybegin = MatAssemblyBegin_HYPRE; 2429d975228cSstefano_zampini B->ops->setvalues = MatSetValues_HYPRE; 243068ec7858SStefano Zampini B->ops->missingdiagonal = MatMissingDiagonal_HYPRE; 243168ec7858SStefano Zampini B->ops->scale = MatScale_HYPRE; 243268ec7858SStefano Zampini B->ops->zerorowscolumns = MatZeroRowsColumns_HYPRE; 2433c69f721fSFande Kong B->ops->zeroentries = MatZeroEntries_HYPRE; 2434c69f721fSFande Kong B->ops->zerorows = MatZeroRows_HYPRE; 2435c69f721fSFande Kong B->ops->getrow = MatGetRow_HYPRE; 2436c69f721fSFande Kong B->ops->restorerow = MatRestoreRow_HYPRE; 2437c69f721fSFande Kong B->ops->getvalues = MatGetValues_HYPRE; 2438ddbeb582SStefano Zampini B->ops->setoption = MatSetOption_HYPRE; 243945b8d346SStefano Zampini B->ops->duplicate = MatDuplicate_HYPRE; 2440465edc17SStefano Zampini B->ops->copy = MatCopy_HYPRE; 244145b8d346SStefano Zampini B->ops->view = MatView_HYPRE; 24426305df00SStefano Zampini B->ops->getdiagonal = MatGetDiagonal_HYPRE; 2443363d496dSStefano Zampini B->ops->axpy = MatAXPY_HYPRE; 24444222ddf1SHong Zhang B->ops->productsetfromoptions = MatProductSetFromOptions_HYPRE; 24456ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 24466ea7df73SStefano Zampini B->ops->bindtocpu = MatBindToCPU_HYPRE; 24476ea7df73SStefano Zampini B->boundtocpu = PETSC_FALSE; 24486ea7df73SStefano Zampini #endif 244945b8d346SStefano Zampini 245045b8d346SStefano Zampini /* build cache for off array entries formed */ 24519566063dSJacob Faibussowitsch PetscCall(MatStashCreate_Private(PetscObjectComm((PetscObject)B), 1, &B->stash)); 245263c07aadSStefano Zampini 24539566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)B), &hB->comm)); 24549566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATHYPRE)); 24559566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_hypre_aij_C", MatConvert_HYPRE_AIJ)); 24569566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_hypre_is_C", MatConvert_HYPRE_IS)); 24579566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaij_hypre_C", MatProductSetFromOptions_HYPRE)); 24589566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_mpiaij_hypre_C", MatProductSetFromOptions_HYPRE)); 24599566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatHYPRESetPreallocation_C", MatHYPRESetPreallocation_HYPRE)); 24609566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatHYPREGetParCSR_C", MatHYPREGetParCSR_HYPRE)); 24615fbaff96SJunchao Zhang PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSetPreallocationCOO_C", MatSetPreallocationCOO_HYPRE)); 24625fbaff96SJunchao Zhang PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSetValuesCOO_C", MatSetValuesCOO_HYPRE)); 24636ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 24646ea7df73SStefano Zampini #if defined(HYPRE_USING_HIP) 246506977982Sstefanozampini PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaijhipsparse_hypre_C", MatProductSetFromOptions_HYPRE)); 246606977982Sstefanozampini PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_mpiaijhipsparse_hypre_C", MatProductSetFromOptions_HYPRE)); 24679566063dSJacob Faibussowitsch PetscCall(PetscDeviceInitialize(PETSC_DEVICE_HIP)); 24689566063dSJacob Faibussowitsch PetscCall(MatSetVecType(B, VECHIP)); 24696ea7df73SStefano Zampini #endif 24706ea7df73SStefano Zampini #if defined(HYPRE_USING_CUDA) 247106977982Sstefanozampini PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaijcusparse_hypre_C", MatProductSetFromOptions_HYPRE)); 247206977982Sstefanozampini PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_mpiaijcusparse_hypre_C", MatProductSetFromOptions_HYPRE)); 24739566063dSJacob Faibussowitsch PetscCall(PetscDeviceInitialize(PETSC_DEVICE_CUDA)); 24749566063dSJacob Faibussowitsch PetscCall(MatSetVecType(B, VECCUDA)); 24756ea7df73SStefano Zampini #endif 24766ea7df73SStefano Zampini #endif 2477ea9ee2c1SPierre Jolivet PetscHYPREInitialize(); 24783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 247963c07aadSStefano Zampini } 2480