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); 148*87ef5fa6SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 14963c07aadSStefano Zampini } 15063c07aadSStefano Zampini 151b73e3080SStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixCopyIJ_SeqAIJ(Mat A, HYPRE_IJMatrix ij) 152d71ae5a4SJacob Faibussowitsch { 15363c07aadSStefano Zampini Mat_SeqAIJ *pdiag = (Mat_SeqAIJ *)A->data; 15458968eb6SStefano Zampini HYPRE_Int type; 15563c07aadSStefano Zampini hypre_ParCSRMatrix *par_matrix; 15663c07aadSStefano Zampini hypre_AuxParCSRMatrix *aux_matrix; 15763c07aadSStefano Zampini hypre_CSRMatrix *hdiag; 1582cf14000SStefano Zampini PetscBool sameint = (PetscBool)(sizeof(PetscInt) == sizeof(HYPRE_Int)); 15963c07aadSStefano Zampini 16063c07aadSStefano Zampini PetscFunctionBegin; 161792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObjectType, ij, &type); 16208401ef6SPierre Jolivet PetscCheck(type == HYPRE_PARCSR, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Only HYPRE_PARCSR is supported"); 163792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, ij, (void **)&par_matrix); 16463c07aadSStefano Zampini hdiag = hypre_ParCSRMatrixDiag(par_matrix); 16563c07aadSStefano Zampini /* 16663c07aadSStefano Zampini this is the Hack part where we monkey directly with the hypre datastructures 16763c07aadSStefano Zampini */ 1682cf14000SStefano Zampini if (sameint) { 1699566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(hdiag->i, pdiag->i, A->rmap->n + 1)); 1709566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(hdiag->j, pdiag->j, pdiag->nz)); 1712cf14000SStefano Zampini } else { 1722cf14000SStefano Zampini PetscInt i; 1732cf14000SStefano Zampini 1742cf14000SStefano Zampini for (i = 0; i < A->rmap->n + 1; i++) hdiag->i[i] = (HYPRE_Int)pdiag->i[i]; 1752cf14000SStefano Zampini for (i = 0; i < pdiag->nz; i++) hdiag->j[i] = (HYPRE_Int)pdiag->j[i]; 1762cf14000SStefano Zampini } 1776ea7df73SStefano Zampini 178ea9daf28SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix *)hypre_IJMatrixTranslator(ij); 17963c07aadSStefano Zampini hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 0; 1803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18163c07aadSStefano Zampini } 18263c07aadSStefano Zampini 183b73e3080SStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixCopyIJ_MPIAIJ(Mat A, HYPRE_IJMatrix ij) 184d71ae5a4SJacob Faibussowitsch { 18563c07aadSStefano Zampini Mat_MPIAIJ *pA = (Mat_MPIAIJ *)A->data; 18663c07aadSStefano Zampini Mat_SeqAIJ *pdiag, *poffd; 18763c07aadSStefano Zampini PetscInt i, *garray = pA->garray, *jj, cstart, *pjj; 1882cf14000SStefano Zampini HYPRE_Int *hjj, type; 18963c07aadSStefano Zampini hypre_ParCSRMatrix *par_matrix; 19063c07aadSStefano Zampini hypre_AuxParCSRMatrix *aux_matrix; 19163c07aadSStefano Zampini hypre_CSRMatrix *hdiag, *hoffd; 1922cf14000SStefano Zampini PetscBool sameint = (PetscBool)(sizeof(PetscInt) == sizeof(HYPRE_Int)); 19363c07aadSStefano Zampini 19463c07aadSStefano Zampini PetscFunctionBegin; 19563c07aadSStefano Zampini pdiag = (Mat_SeqAIJ *)pA->A->data; 19663c07aadSStefano Zampini poffd = (Mat_SeqAIJ *)pA->B->data; 197da81f932SPierre Jolivet /* cstart is only valid for square MPIAIJ laid out in the usual way */ 1989566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(A, &cstart, NULL)); 19963c07aadSStefano Zampini 200792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObjectType, ij, &type); 20108401ef6SPierre Jolivet PetscCheck(type == HYPRE_PARCSR, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Only HYPRE_PARCSR is supported"); 202792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, ij, (void **)&par_matrix); 20363c07aadSStefano Zampini hdiag = hypre_ParCSRMatrixDiag(par_matrix); 20463c07aadSStefano Zampini hoffd = hypre_ParCSRMatrixOffd(par_matrix); 20563c07aadSStefano Zampini 2062cf14000SStefano Zampini if (sameint) { 2079566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(hdiag->i, pdiag->i, pA->A->rmap->n + 1)); 2082cf14000SStefano Zampini } else { 209f4f49eeaSPierre Jolivet for (i = 0; i < pA->A->rmap->n + 1; i++) hdiag->i[i] = (HYPRE_Int)pdiag->i[i]; 2102cf14000SStefano Zampini } 211b73e3080SStefano Zampini 2122cf14000SStefano Zampini hjj = hdiag->j; 2132cf14000SStefano Zampini pjj = pdiag->j; 214c6698e78SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2, 16, 0) 2152cf14000SStefano Zampini for (i = 0; i < pdiag->nz; i++) hjj[i] = pjj[i]; 216c6698e78SStefano Zampini #else 2172cf14000SStefano Zampini for (i = 0; i < pdiag->nz; i++) hjj[i] = cstart + pjj[i]; 218c6698e78SStefano Zampini #endif 2192cf14000SStefano Zampini if (sameint) { 2209566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(hoffd->i, poffd->i, pA->A->rmap->n + 1)); 2212cf14000SStefano Zampini } else { 222f4f49eeaSPierre Jolivet for (i = 0; i < pA->A->rmap->n + 1; i++) hoffd->i[i] = (HYPRE_Int)poffd->i[i]; 2232cf14000SStefano Zampini } 2242cf14000SStefano Zampini 22506977982Sstefanozampini jj = (PetscInt *)hoffd->j; 226c6698e78SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2, 16, 0) 227792fecdfSBarry Smith PetscCallExternal(hypre_CSRMatrixBigInitialize, hoffd); 228c6698e78SStefano Zampini jj = (PetscInt *)hoffd->big_j; 229c6698e78SStefano Zampini #endif 2302cf14000SStefano Zampini pjj = poffd->j; 23163c07aadSStefano Zampini for (i = 0; i < poffd->nz; i++) jj[i] = garray[pjj[i]]; 232c6698e78SStefano Zampini 233ea9daf28SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix *)hypre_IJMatrixTranslator(ij); 23463c07aadSStefano Zampini hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 0; 2353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23663c07aadSStefano Zampini } 23763c07aadSStefano Zampini 238d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatConvert_HYPRE_IS(Mat A, MatType mtype, MatReuse reuse, Mat *B) 239d71ae5a4SJacob Faibussowitsch { 240f4f49eeaSPierre Jolivet Mat_HYPRE *mhA = (Mat_HYPRE *)A->data; 2412df22349SStefano Zampini Mat lA; 2422df22349SStefano Zampini ISLocalToGlobalMapping rl2g, cl2g; 2432df22349SStefano Zampini IS is; 2442df22349SStefano Zampini hypre_ParCSRMatrix *hA; 2452df22349SStefano Zampini hypre_CSRMatrix *hdiag, *hoffd; 2462df22349SStefano Zampini MPI_Comm comm; 24739accc25SStefano Zampini HYPRE_Complex *hdd, *hod, *aa; 24839accc25SStefano Zampini PetscScalar *data; 2492cf14000SStefano Zampini HYPRE_BigInt *col_map_offd; 2502cf14000SStefano Zampini HYPRE_Int *hdi, *hdj, *hoi, *hoj; 2512df22349SStefano Zampini PetscInt *ii, *jj, *iptr, *jptr; 2522df22349SStefano Zampini PetscInt cum, dr, dc, oc, str, stc, nnz, i, jd, jo, M, N; 25358968eb6SStefano Zampini HYPRE_Int type; 25406977982Sstefanozampini MatType lmattype = NULL; 25506977982Sstefanozampini PetscBool freeparcsr = PETSC_FALSE; 2562df22349SStefano Zampini 2572df22349SStefano Zampini PetscFunctionBegin; 258a1787963SStefano Zampini comm = PetscObjectComm((PetscObject)A); 259792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObjectType, mhA->ij, &type); 26008401ef6SPierre Jolivet PetscCheck(type == HYPRE_PARCSR, comm, PETSC_ERR_SUP, "Only HYPRE_PARCSR is supported"); 261792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, mhA->ij, (void **)&hA); 26206977982Sstefanozampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 26306977982Sstefanozampini if (HYPRE_MEMORY_DEVICE == hypre_IJMatrixMemoryLocation(mhA->ij)) { 26406977982Sstefanozampini /* Support by copying back on the host and copy to GPU 26506977982Sstefanozampini Kind of inefficient, but this is the best we can do now */ 26606977982Sstefanozampini #if defined(HYPRE_USING_HIP) 26706977982Sstefanozampini lmattype = MATSEQAIJHIPSPARSE; 26806977982Sstefanozampini #elif defined(HYPRE_USING_CUDA) 26906977982Sstefanozampini lmattype = MATSEQAIJCUSPARSE; 27006977982Sstefanozampini #endif 27106977982Sstefanozampini hA = hypre_ParCSRMatrixClone_v2(hA, 1, HYPRE_MEMORY_HOST); 27206977982Sstefanozampini freeparcsr = PETSC_TRUE; 27306977982Sstefanozampini } 27406977982Sstefanozampini #endif 2752df22349SStefano Zampini M = hypre_ParCSRMatrixGlobalNumRows(hA); 2762df22349SStefano Zampini N = hypre_ParCSRMatrixGlobalNumCols(hA); 2772df22349SStefano Zampini str = hypre_ParCSRMatrixFirstRowIndex(hA); 2782df22349SStefano Zampini stc = hypre_ParCSRMatrixFirstColDiag(hA); 2792df22349SStefano Zampini hdiag = hypre_ParCSRMatrixDiag(hA); 2802df22349SStefano Zampini hoffd = hypre_ParCSRMatrixOffd(hA); 2812df22349SStefano Zampini dr = hypre_CSRMatrixNumRows(hdiag); 2822df22349SStefano Zampini dc = hypre_CSRMatrixNumCols(hdiag); 2832df22349SStefano Zampini nnz = hypre_CSRMatrixNumNonzeros(hdiag); 2842df22349SStefano Zampini hdi = hypre_CSRMatrixI(hdiag); 2852df22349SStefano Zampini hdj = hypre_CSRMatrixJ(hdiag); 2862df22349SStefano Zampini hdd = hypre_CSRMatrixData(hdiag); 2872df22349SStefano Zampini oc = hypre_CSRMatrixNumCols(hoffd); 2882df22349SStefano Zampini nnz += hypre_CSRMatrixNumNonzeros(hoffd); 2892df22349SStefano Zampini hoi = hypre_CSRMatrixI(hoffd); 2902df22349SStefano Zampini hoj = hypre_CSRMatrixJ(hoffd); 2912df22349SStefano Zampini hod = hypre_CSRMatrixData(hoffd); 2922df22349SStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 2932df22349SStefano Zampini PetscInt *aux; 2942df22349SStefano Zampini 2952df22349SStefano Zampini /* generate l2g maps for rows and cols */ 2969566063dSJacob Faibussowitsch PetscCall(ISCreateStride(comm, dr, str, 1, &is)); 2979566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingCreateIS(is, &rl2g)); 2989566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is)); 2992df22349SStefano Zampini col_map_offd = hypre_ParCSRMatrixColMapOffd(hA); 3009566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dc + oc, &aux)); 3012df22349SStefano Zampini for (i = 0; i < dc; i++) aux[i] = i + stc; 3022df22349SStefano Zampini for (i = 0; i < oc; i++) aux[i + dc] = col_map_offd[i]; 3039566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(comm, dc + oc, aux, PETSC_OWN_POINTER, &is)); 3049566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingCreateIS(is, &cl2g)); 3059566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is)); 3062df22349SStefano Zampini /* create MATIS object */ 3079566063dSJacob Faibussowitsch PetscCall(MatCreate(comm, B)); 3089566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*B, dr, dc, M, N)); 3099566063dSJacob Faibussowitsch PetscCall(MatSetType(*B, MATIS)); 3109566063dSJacob Faibussowitsch PetscCall(MatSetLocalToGlobalMapping(*B, rl2g, cl2g)); 3119566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingDestroy(&rl2g)); 3129566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingDestroy(&cl2g)); 3132df22349SStefano Zampini 3142df22349SStefano Zampini /* allocate CSR for local matrix */ 3159566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dr + 1, &iptr)); 3169566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &jptr)); 3179566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &data)); 3182df22349SStefano Zampini } else { 3192df22349SStefano Zampini PetscInt nr; 3202df22349SStefano Zampini PetscBool done; 3219566063dSJacob Faibussowitsch PetscCall(MatISGetLocalMat(*B, &lA)); 3229566063dSJacob Faibussowitsch PetscCall(MatGetRowIJ(lA, 0, PETSC_FALSE, PETSC_FALSE, &nr, (const PetscInt **)&iptr, (const PetscInt **)&jptr, &done)); 32308401ef6SPierre 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); 32408401ef6SPierre 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); 32506977982Sstefanozampini PetscCall(MatSeqAIJGetArrayWrite(lA, &data)); 3262df22349SStefano Zampini } 3272df22349SStefano Zampini /* merge local matrices */ 3282df22349SStefano Zampini ii = iptr; 3292df22349SStefano Zampini jj = jptr; 33039accc25SStefano 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++ */ 3312df22349SStefano Zampini *ii = *(hdi++) + *(hoi++); 3322df22349SStefano Zampini for (jd = 0, jo = 0, cum = 0; *ii < nnz; cum++) { 33339accc25SStefano Zampini PetscScalar *aold = (PetscScalar *)aa; 3342df22349SStefano Zampini PetscInt *jold = jj, nc = jd + jo; 3359371c9d4SSatish Balay for (; jd < *hdi; jd++) { 3369371c9d4SSatish Balay *jj++ = *hdj++; 3379371c9d4SSatish Balay *aa++ = *hdd++; 3389371c9d4SSatish Balay } 3399371c9d4SSatish Balay for (; jo < *hoi; jo++) { 3409371c9d4SSatish Balay *jj++ = *hoj++ + dc; 3419371c9d4SSatish Balay *aa++ = *hod++; 3429371c9d4SSatish Balay } 3432df22349SStefano Zampini *(++ii) = *(hdi++) + *(hoi++); 3449566063dSJacob Faibussowitsch PetscCall(PetscSortIntWithScalarArray(jd + jo - nc, jold, aold)); 3452df22349SStefano Zampini } 3462df22349SStefano Zampini for (; cum < dr; cum++) *(++ii) = nnz; 3472df22349SStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 348a033916dSStefano Zampini Mat_SeqAIJ *a; 349a033916dSStefano Zampini 3509566063dSJacob Faibussowitsch PetscCall(MatCreateSeqAIJWithArrays(PETSC_COMM_SELF, dr, dc + oc, iptr, jptr, data, &lA)); 351a033916dSStefano Zampini /* hack SeqAIJ */ 352f4f49eeaSPierre Jolivet a = (Mat_SeqAIJ *)lA->data; 353a033916dSStefano Zampini a->free_a = PETSC_TRUE; 354a033916dSStefano Zampini a->free_ij = PETSC_TRUE; 35506977982Sstefanozampini if (lmattype) PetscCall(MatConvert(lA, lmattype, MAT_INPLACE_MATRIX, &lA)); 35606977982Sstefanozampini PetscCall(MatISSetLocalMat(*B, lA)); 3579566063dSJacob Faibussowitsch PetscCall(MatDestroy(&lA)); 35806977982Sstefanozampini } else { 35906977982Sstefanozampini PetscCall(MatSeqAIJRestoreArrayWrite(lA, &data)); 3602df22349SStefano Zampini } 3619566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(*B, MAT_FINAL_ASSEMBLY)); 3629566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(*B, MAT_FINAL_ASSEMBLY)); 36348a46eb9SPierre Jolivet if (reuse == MAT_INPLACE_MATRIX) PetscCall(MatHeaderReplace(A, B)); 36406977982Sstefanozampini if (freeparcsr) PetscCallExternal(hypre_ParCSRMatrixDestroy, hA); 3653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3662df22349SStefano Zampini } 3672df22349SStefano Zampini 36806977982Sstefanozampini static PetscErrorCode MatHYPRE_DestroyCOOMat(Mat mat) 369d71ae5a4SJacob Faibussowitsch { 37006977982Sstefanozampini Mat_HYPRE *hA = (Mat_HYPRE *)mat->data; 37163c07aadSStefano Zampini 37263c07aadSStefano Zampini PetscFunctionBegin; 37306977982Sstefanozampini if (hA->cooMat) { /* If cooMat is present we need to destroy the column indices */ 37406977982Sstefanozampini PetscCall(MatDestroy(&hA->cooMat)); 37506977982Sstefanozampini if (hA->cooMatAttached) { 37606977982Sstefanozampini hypre_CSRMatrix *csr; 37706977982Sstefanozampini hypre_ParCSRMatrix *parcsr; 37806977982Sstefanozampini HYPRE_MemoryLocation mem; 37906977982Sstefanozampini 38006977982Sstefanozampini PetscCallExternal(HYPRE_IJMatrixGetObject, hA->ij, (void **)&parcsr); 38106977982Sstefanozampini csr = hypre_ParCSRMatrixDiag(parcsr); 38206977982Sstefanozampini if (csr) { 38306977982Sstefanozampini mem = hypre_CSRMatrixMemoryLocation(csr); 38406977982Sstefanozampini PetscStackCallExternalVoid("hypre_TFree", hypre_TFree(hypre_CSRMatrixJ(csr), mem)); 38506977982Sstefanozampini PetscStackCallExternalVoid("hypre_TFree", hypre_TFree(hypre_CSRMatrixBigJ(csr), mem)); 386b73e3080SStefano Zampini } 38706977982Sstefanozampini csr = hypre_ParCSRMatrixOffd(parcsr); 38806977982Sstefanozampini if (csr) { 38906977982Sstefanozampini mem = hypre_CSRMatrixMemoryLocation(csr); 39006977982Sstefanozampini PetscStackCallExternalVoid("hypre_TFree", hypre_TFree(hypre_CSRMatrixJ(csr), mem)); 39106977982Sstefanozampini PetscStackCallExternalVoid("hypre_TFree", hypre_TFree(hypre_CSRMatrixBigJ(csr), mem)); 392b73e3080SStefano Zampini } 393b73e3080SStefano Zampini } 39406977982Sstefanozampini } 39506977982Sstefanozampini hA->cooMatAttached = PETSC_FALSE; 396b73e3080SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 397b73e3080SStefano Zampini } 398b73e3080SStefano Zampini 39906977982Sstefanozampini static PetscErrorCode MatHYPRE_CreateCOOMat(Mat mat) 400b73e3080SStefano Zampini { 40106977982Sstefanozampini MPI_Comm comm; 40206977982Sstefanozampini PetscMPIInt size; 40306977982Sstefanozampini PetscLayout rmap, cmap; 40406977982Sstefanozampini Mat_HYPRE *hmat = (Mat_HYPRE *)mat->data; 40506977982Sstefanozampini MatType matType = MATAIJ; /* default type of cooMat */ 406b73e3080SStefano Zampini 407b73e3080SStefano Zampini PetscFunctionBegin; 40806977982Sstefanozampini /* Build an agent matrix cooMat with AIJ format 40906977982Sstefanozampini It has the same sparsity pattern as mat, and also shares the data array with mat. We use cooMat to do the COO work. 41006977982Sstefanozampini */ 41106977982Sstefanozampini PetscCall(PetscObjectGetComm((PetscObject)mat, &comm)); 41206977982Sstefanozampini PetscCallMPI(MPI_Comm_size(comm, &size)); 41306977982Sstefanozampini PetscCall(PetscLayoutSetUp(mat->rmap)); 41406977982Sstefanozampini PetscCall(PetscLayoutSetUp(mat->cmap)); 41506977982Sstefanozampini PetscCall(MatGetLayouts(mat, &rmap, &cmap)); 416b73e3080SStefano Zampini 41706977982Sstefanozampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 41806977982Sstefanozampini if (!mat->boundtocpu) { /* mat will be on device, so will cooMat */ 41906977982Sstefanozampini #if defined(HYPRE_USING_HIP) 42006977982Sstefanozampini matType = MATAIJHIPSPARSE; 42106977982Sstefanozampini #elif defined(HYPRE_USING_CUDA) 42206977982Sstefanozampini matType = MATAIJCUSPARSE; 42306977982Sstefanozampini #else 42406977982Sstefanozampini SETERRQ(comm, PETSC_ERR_SUP, "Do not know the HYPRE device"); 42506977982Sstefanozampini #endif 426b73e3080SStefano Zampini } 42706977982Sstefanozampini #endif 42806977982Sstefanozampini 42906977982Sstefanozampini /* Do COO preallocation through cooMat */ 43006977982Sstefanozampini PetscCall(MatHYPRE_DestroyCOOMat(mat)); 43106977982Sstefanozampini PetscCall(MatCreate(comm, &hmat->cooMat)); 43206977982Sstefanozampini PetscCall(MatSetType(hmat->cooMat, matType)); 43306977982Sstefanozampini PetscCall(MatSetLayouts(hmat->cooMat, rmap, cmap)); 43406977982Sstefanozampini 43506977982Sstefanozampini /* allocate local matrices if needed */ 43606977982Sstefanozampini PetscCall(MatMPIAIJSetPreallocation(hmat->cooMat, 0, NULL, 0, NULL)); 43706977982Sstefanozampini PetscFunctionReturn(PETSC_SUCCESS); 43806977982Sstefanozampini } 43906977982Sstefanozampini 44006977982Sstefanozampini /* Attach cooMat data array to hypre matrix. 44106977982Sstefanozampini When AIJCUPMSPARSE will support raw device pointers and not THRUSTARRAY 44206977982Sstefanozampini we should swap the arrays: i.e., attach hypre matrix array to cooMat 44306977982Sstefanozampini This is because hypre should be in charge of handling the memory, 44406977982Sstefanozampini cooMat is only a way to reuse PETSc COO code. 44506977982Sstefanozampini attaching the memory will then be done at MatSetValuesCOO time and it will dynamically 44606977982Sstefanozampini support hypre matrix migrating to host. 44706977982Sstefanozampini */ 44806977982Sstefanozampini static PetscErrorCode MatHYPRE_AttachCOOMat(Mat mat) 44906977982Sstefanozampini { 45006977982Sstefanozampini Mat_HYPRE *hmat = (Mat_HYPRE *)mat->data; 45106977982Sstefanozampini hypre_CSRMatrix *diag, *offd; 45206977982Sstefanozampini hypre_ParCSRMatrix *parCSR; 45306977982Sstefanozampini HYPRE_MemoryLocation hmem = HYPRE_MEMORY_HOST; 45406977982Sstefanozampini PetscMemType pmem; 45506977982Sstefanozampini Mat A, B; 45606977982Sstefanozampini PetscScalar *a; 45706977982Sstefanozampini PetscMPIInt size; 45806977982Sstefanozampini MPI_Comm comm; 45906977982Sstefanozampini 46006977982Sstefanozampini PetscFunctionBegin; 46106977982Sstefanozampini PetscCheck(hmat->cooMat, PetscObjectComm((PetscObject)mat), PETSC_ERR_PLIB, "HYPRE COO delegate matrix has not been created yet"); 46206977982Sstefanozampini if (hmat->cooMatAttached) PetscFunctionReturn(PETSC_SUCCESS); 46306977982Sstefanozampini PetscCheck(hmat->cooMat->preallocated, PetscObjectComm((PetscObject)mat), PETSC_ERR_PLIB, "HYPRE COO delegate matrix is not preallocated"); 46406977982Sstefanozampini PetscCall(PetscObjectSetName((PetscObject)hmat->cooMat, "_internal_COO_mat_for_hypre")); 46506977982Sstefanozampini PetscCall(PetscObjectGetComm((PetscObject)mat, &comm)); 46606977982Sstefanozampini PetscCallMPI(MPI_Comm_size(comm, &size)); 46706977982Sstefanozampini 46806977982Sstefanozampini /* Alias cooMat's data array to IJMatrix's */ 46906977982Sstefanozampini PetscCallExternal(HYPRE_IJMatrixGetObject, hmat->ij, (void **)&parCSR); 47006977982Sstefanozampini diag = hypre_ParCSRMatrixDiag(parCSR); 47106977982Sstefanozampini offd = hypre_ParCSRMatrixOffd(parCSR); 47206977982Sstefanozampini 47306977982Sstefanozampini A = (size == 1) ? hmat->cooMat : ((Mat_MPIAIJ *)hmat->cooMat->data)->A; 47406977982Sstefanozampini B = (size == 1) ? NULL : ((Mat_MPIAIJ *)hmat->cooMat->data)->B; 47506977982Sstefanozampini 47606977982Sstefanozampini PetscCall(PetscObjectSetName((PetscObject)A, "_internal_COO_mat_for_hypre")); 47706977982Sstefanozampini hmem = hypre_CSRMatrixMemoryLocation(diag); 47806977982Sstefanozampini PetscCall(MatSeqAIJGetCSRAndMemType(A, NULL, NULL, &a, &pmem)); 47906977982Sstefanozampini PetscAssert((PetscMemTypeHost(pmem) && hmem == HYPRE_MEMORY_HOST) || (PetscMemTypeDevice(pmem) && hmem == HYPRE_MEMORY_DEVICE), comm, PETSC_ERR_PLIB, "PETSc and hypre's memory types mismatch"); 48006977982Sstefanozampini PetscStackCallExternalVoid("hypre_TFree", hypre_TFree(hypre_CSRMatrixData(diag), hmem)); 48106977982Sstefanozampini hypre_CSRMatrixData(diag) = (HYPRE_Complex *)a; 48206977982Sstefanozampini hypre_CSRMatrixOwnsData(diag) = 0; /* Take ownership of (j,a) away from hypre. As a result, we need to free them on our own */ 48306977982Sstefanozampini 48406977982Sstefanozampini if (B) { 48506977982Sstefanozampini hmem = hypre_CSRMatrixMemoryLocation(offd); 48606977982Sstefanozampini PetscCall(MatSeqAIJGetCSRAndMemType(B, NULL, NULL, &a, &pmem)); 48706977982Sstefanozampini PetscAssert((PetscMemTypeHost(pmem) && hmem == HYPRE_MEMORY_HOST) || (PetscMemTypeDevice(pmem) && hmem == HYPRE_MEMORY_DEVICE), comm, PETSC_ERR_PLIB, "PETSc and hypre's memory types mismatch"); 48806977982Sstefanozampini PetscStackCallExternalVoid("hypre_TFree", hypre_TFree(hypre_CSRMatrixData(offd), hmem)); 48906977982Sstefanozampini hypre_CSRMatrixData(offd) = (HYPRE_Complex *)a; 49006977982Sstefanozampini hypre_CSRMatrixOwnsData(offd) = 0; 49106977982Sstefanozampini } 49206977982Sstefanozampini hmat->cooMatAttached = PETSC_TRUE; 49306977982Sstefanozampini PetscFunctionReturn(PETSC_SUCCESS); 49406977982Sstefanozampini } 49506977982Sstefanozampini 49606977982Sstefanozampini static PetscErrorCode CSRtoCOO_Private(PetscInt n, const PetscInt ii[], const PetscInt jj[], PetscCount *ncoo, PetscInt **coo_i, PetscInt **coo_j) 49706977982Sstefanozampini { 49806977982Sstefanozampini PetscInt *cooi, *cooj; 49906977982Sstefanozampini 50006977982Sstefanozampini PetscFunctionBegin; 50106977982Sstefanozampini *ncoo = ii[n]; 50206977982Sstefanozampini PetscCall(PetscMalloc2(*ncoo, &cooi, *ncoo, &cooj)); 50306977982Sstefanozampini for (PetscInt i = 0; i < n; i++) { 50406977982Sstefanozampini for (PetscInt j = ii[i]; j < ii[i + 1]; j++) cooi[j] = i; 50506977982Sstefanozampini } 50606977982Sstefanozampini PetscCall(PetscArraycpy(cooj, jj, *ncoo)); 50706977982Sstefanozampini *coo_i = cooi; 50806977982Sstefanozampini *coo_j = cooj; 50906977982Sstefanozampini PetscFunctionReturn(PETSC_SUCCESS); 51006977982Sstefanozampini } 51106977982Sstefanozampini 51206977982Sstefanozampini static PetscErrorCode CSRtoCOO_HYPRE_Int_Private(PetscInt n, const HYPRE_Int ii[], const HYPRE_Int jj[], PetscCount *ncoo, PetscInt **coo_i, PetscInt **coo_j) 51306977982Sstefanozampini { 51406977982Sstefanozampini PetscInt *cooi, *cooj; 51506977982Sstefanozampini 51606977982Sstefanozampini PetscFunctionBegin; 51706977982Sstefanozampini *ncoo = ii[n]; 51806977982Sstefanozampini PetscCall(PetscMalloc2(*ncoo, &cooi, *ncoo, &cooj)); 51906977982Sstefanozampini for (PetscInt i = 0; i < n; i++) { 52006977982Sstefanozampini for (HYPRE_Int j = ii[i]; j < ii[i + 1]; j++) cooi[j] = i; 52106977982Sstefanozampini } 52206977982Sstefanozampini for (PetscCount i = 0; i < *ncoo; i++) cooj[i] = jj[i]; 52306977982Sstefanozampini *coo_i = cooi; 52406977982Sstefanozampini *coo_j = cooj; 52506977982Sstefanozampini PetscFunctionReturn(PETSC_SUCCESS); 52606977982Sstefanozampini } 52706977982Sstefanozampini 52806977982Sstefanozampini static PetscErrorCode MatSeqAIJGetCOO_Private(Mat A, PetscCount *ncoo, PetscInt **coo_i, PetscInt **coo_j) 52906977982Sstefanozampini { 53006977982Sstefanozampini PetscInt n; 53106977982Sstefanozampini const PetscInt *ii, *jj; 53206977982Sstefanozampini PetscBool done; 53306977982Sstefanozampini 53406977982Sstefanozampini PetscFunctionBegin; 53506977982Sstefanozampini PetscCall(MatGetRowIJ(A, 0, PETSC_FALSE, PETSC_FALSE, &n, &ii, &jj, &done)); 53606977982Sstefanozampini PetscCheck(done, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Failure for MatGetRowIJ"); 53706977982Sstefanozampini PetscCall(CSRtoCOO_Private(n, ii, jj, ncoo, coo_i, coo_j)); 53806977982Sstefanozampini PetscCall(MatRestoreRowIJ(A, 0, PETSC_FALSE, PETSC_FALSE, &n, &ii, &jj, &done)); 53906977982Sstefanozampini PetscCheck(done, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Failure for MatRestoreRowIJ"); 54006977982Sstefanozampini PetscFunctionReturn(PETSC_SUCCESS); 54106977982Sstefanozampini } 54206977982Sstefanozampini 54306977982Sstefanozampini static PetscErrorCode hypreCSRMatrixGetCOO_Private(hypre_CSRMatrix *A, PetscCount *ncoo, PetscInt **coo_i, PetscInt **coo_j) 54406977982Sstefanozampini { 54506977982Sstefanozampini PetscInt n = hypre_CSRMatrixNumRows(A); 54606977982Sstefanozampini HYPRE_Int *ii, *jj; 54706977982Sstefanozampini HYPRE_MemoryLocation mem = HYPRE_MEMORY_HOST; 54806977982Sstefanozampini 54906977982Sstefanozampini PetscFunctionBegin; 55006977982Sstefanozampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 55106977982Sstefanozampini mem = hypre_CSRMatrixMemoryLocation(A); 55206977982Sstefanozampini if (mem != HYPRE_MEMORY_HOST) { 55306977982Sstefanozampini PetscCount nnz = hypre_CSRMatrixNumNonzeros(A); 55406977982Sstefanozampini PetscCall(PetscMalloc2(n + 1, &ii, nnz, &jj)); 55506977982Sstefanozampini hypre_TMemcpy(ii, hypre_CSRMatrixI(A), HYPRE_Int, n + 1, HYPRE_MEMORY_HOST, mem); 55606977982Sstefanozampini hypre_TMemcpy(jj, hypre_CSRMatrixJ(A), HYPRE_Int, nnz, HYPRE_MEMORY_HOST, mem); 55706977982Sstefanozampini } else { 55806977982Sstefanozampini #else 55906977982Sstefanozampini { 56006977982Sstefanozampini #endif 56106977982Sstefanozampini ii = hypre_CSRMatrixI(A); 56206977982Sstefanozampini jj = hypre_CSRMatrixJ(A); 56306977982Sstefanozampini } 56406977982Sstefanozampini PetscCall(CSRtoCOO_HYPRE_Int_Private(n, ii, jj, ncoo, coo_i, coo_j)); 56506977982Sstefanozampini if (mem != HYPRE_MEMORY_HOST) PetscCall(PetscFree2(ii, jj)); 56606977982Sstefanozampini PetscFunctionReturn(PETSC_SUCCESS); 56706977982Sstefanozampini } 56806977982Sstefanozampini 56906977982Sstefanozampini static PetscErrorCode MatSetValuesCOOFromCSRMatrix_Private(Mat A, hypre_CSRMatrix *H) 57006977982Sstefanozampini { 57106977982Sstefanozampini PetscBool iscpu = PETSC_TRUE; 57206977982Sstefanozampini PetscScalar *a; 57306977982Sstefanozampini HYPRE_MemoryLocation mem = HYPRE_MEMORY_HOST; 57406977982Sstefanozampini 57506977982Sstefanozampini PetscFunctionBegin; 57606977982Sstefanozampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 57706977982Sstefanozampini mem = hypre_CSRMatrixMemoryLocation(H); 57806977982Sstefanozampini PetscCall(PetscObjectTypeCompare((PetscObject)A, MATSEQAIJ, &iscpu)); 57906977982Sstefanozampini #endif 58006977982Sstefanozampini if (iscpu && mem != HYPRE_MEMORY_HOST) { 58106977982Sstefanozampini PetscCount nnz = hypre_CSRMatrixNumNonzeros(H); 58206977982Sstefanozampini PetscCall(PetscMalloc1(nnz, &a)); 58306977982Sstefanozampini hypre_TMemcpy(a, hypre_CSRMatrixData(H), PetscScalar, nnz, HYPRE_MEMORY_HOST, mem); 58406977982Sstefanozampini } else { 58506977982Sstefanozampini a = (PetscScalar *)hypre_CSRMatrixData(H); 58606977982Sstefanozampini } 58706977982Sstefanozampini PetscCall(MatSetValuesCOO(A, a, INSERT_VALUES)); 58806977982Sstefanozampini if (iscpu && mem != HYPRE_MEMORY_HOST) PetscCall(PetscFree(a)); 589b73e3080SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 590b73e3080SStefano Zampini } 591b73e3080SStefano Zampini 592b73e3080SStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A, MatType type, MatReuse reuse, Mat *B) 593b73e3080SStefano Zampini { 594b73e3080SStefano Zampini MPI_Comm comm = PetscObjectComm((PetscObject)A); 59506977982Sstefanozampini Mat M = NULL, dH = NULL, oH = NULL, dA = NULL, oA = NULL; 596b73e3080SStefano Zampini PetscBool ismpiaij, issbaij, isbaij; 597b73e3080SStefano Zampini Mat_HYPRE *hA; 598b73e3080SStefano Zampini 599b73e3080SStefano Zampini PetscFunctionBegin; 600b73e3080SStefano Zampini PetscCall(PetscObjectTypeCompareAny((PetscObject)A, &issbaij, MATSEQSBAIJ, MATMPIBAIJ, "")); 601b73e3080SStefano Zampini PetscCall(PetscObjectTypeCompareAny((PetscObject)A, &isbaij, MATSEQBAIJ, MATMPIBAIJ, "")); 602b73e3080SStefano Zampini if (isbaij || issbaij) { /* handle BAIJ and SBAIJ */ 603b73e3080SStefano Zampini PetscBool ismpi; 604b73e3080SStefano Zampini MatType newtype; 605b73e3080SStefano Zampini 606b73e3080SStefano Zampini PetscCall(PetscObjectTypeCompareAny((PetscObject)A, &ismpi, MATMPISBAIJ, MATMPIBAIJ, "")); 607b73e3080SStefano Zampini newtype = ismpi ? MATMPIAIJ : MATSEQAIJ; 60863c07aadSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 609b73e3080SStefano Zampini PetscCall(MatConvert(*B, newtype, MAT_INPLACE_MATRIX, B)); 610b73e3080SStefano Zampini PetscCall(MatConvert(A, newtype, MAT_REUSE_MATRIX, B)); 611b73e3080SStefano Zampini PetscCall(MatConvert(*B, MATHYPRE, MAT_INPLACE_MATRIX, B)); 612b73e3080SStefano Zampini } else if (reuse == MAT_INITIAL_MATRIX) { 613b73e3080SStefano Zampini PetscCall(MatConvert(A, newtype, MAT_INITIAL_MATRIX, B)); 614b73e3080SStefano Zampini PetscCall(MatConvert(*B, MATHYPRE, MAT_INPLACE_MATRIX, B)); 61563c07aadSStefano Zampini } else { 616b73e3080SStefano Zampini PetscCall(MatConvert(A, newtype, MAT_INPLACE_MATRIX, &A)); 617b73e3080SStefano Zampini PetscCall(MatConvert(A, MATHYPRE, MAT_INPLACE_MATRIX, &A)); 618b73e3080SStefano Zampini } 619b73e3080SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 620b73e3080SStefano Zampini } 62106977982Sstefanozampini 62206977982Sstefanozampini dA = A; 623b73e3080SStefano Zampini PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIAIJ, &ismpiaij)); 624b73e3080SStefano Zampini if (ismpiaij) PetscCall(MatMPIAIJGetSeqAIJ(A, &dA, &oA, NULL)); 62506977982Sstefanozampini 626b73e3080SStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 62706977982Sstefanozampini PetscCount coo_n; 62806977982Sstefanozampini PetscInt *coo_i, *coo_j; 62906977982Sstefanozampini 6309566063dSJacob Faibussowitsch PetscCall(MatCreate(comm, &M)); 6319566063dSJacob Faibussowitsch PetscCall(MatSetType(M, MATHYPRE)); 6329566063dSJacob Faibussowitsch PetscCall(MatSetSizes(M, A->rmap->n, A->cmap->n, A->rmap->N, A->cmap->N)); 633b73e3080SStefano Zampini PetscCall(MatSetOption(M, MAT_SORTED_FULL, PETSC_TRUE)); 634b73e3080SStefano Zampini PetscCall(MatSetOption(M, MAT_NO_OFF_PROC_ENTRIES, PETSC_TRUE)); 635b73e3080SStefano Zampini 636b73e3080SStefano Zampini hA = (Mat_HYPRE *)M->data; 63706977982Sstefanozampini PetscCall(MatHYPRE_CreateFromMat(A, hA)); 63806977982Sstefanozampini PetscCall(MatHYPRE_IJMatrixCopyIJ(A, hA->ij)); 63906977982Sstefanozampini 64006977982Sstefanozampini PetscCall(MatHYPRE_CreateCOOMat(M)); 64106977982Sstefanozampini 64206977982Sstefanozampini dH = hA->cooMat; 64306977982Sstefanozampini PetscCall(PetscObjectBaseTypeCompare((PetscObject)hA->cooMat, MATMPIAIJ, &ismpiaij)); 64406977982Sstefanozampini if (ismpiaij) PetscCall(MatMPIAIJGetSeqAIJ(hA->cooMat, &dH, &oH, NULL)); 64506977982Sstefanozampini 64606977982Sstefanozampini PetscCall(PetscObjectSetName((PetscObject)dH, "_internal_COO_mat_for_hypre")); 64706977982Sstefanozampini PetscCall(MatSeqAIJGetCOO_Private(dA, &coo_n, &coo_i, &coo_j)); 64806977982Sstefanozampini PetscCall(MatSetPreallocationCOO(dH, coo_n, coo_i, coo_j)); 64906977982Sstefanozampini PetscCall(PetscFree2(coo_i, coo_j)); 65006977982Sstefanozampini if (oH) { 65106977982Sstefanozampini PetscCall(PetscLayoutDestroy(&oH->cmap)); 65206977982Sstefanozampini PetscCall(PetscLayoutCreateFromSizes(PetscObjectComm((PetscObject)oH), oA->cmap->n, oA->cmap->n, 1, &oH->cmap)); 65306977982Sstefanozampini PetscCall(MatSeqAIJGetCOO_Private(oA, &coo_n, &coo_i, &coo_j)); 65406977982Sstefanozampini PetscCall(MatSetPreallocationCOO(oH, coo_n, coo_i, coo_j)); 65506977982Sstefanozampini PetscCall(PetscFree2(coo_i, coo_j)); 65606977982Sstefanozampini } 65706977982Sstefanozampini hA->cooMat->assembled = PETSC_TRUE; 65806977982Sstefanozampini 659b73e3080SStefano Zampini M->preallocated = PETSC_TRUE; 66006977982Sstefanozampini PetscCall(MatAssemblyBegin(M, MAT_FINAL_ASSEMBLY)); 66106977982Sstefanozampini PetscCall(MatAssemblyEnd(M, MAT_FINAL_ASSEMBLY)); 66206977982Sstefanozampini 66306977982Sstefanozampini PetscCall(MatHYPRE_AttachCOOMat(M)); 66484d4e069SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) *B = M; 665b73e3080SStefano Zampini } else M = *B; 666b73e3080SStefano Zampini 667b73e3080SStefano Zampini hA = (Mat_HYPRE *)M->data; 66806977982Sstefanozampini PetscCheck(hA->cooMat, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "HYPRE COO delegate matrix has not been created yet"); 66906977982Sstefanozampini 67006977982Sstefanozampini dH = hA->cooMat; 67106977982Sstefanozampini PetscCall(PetscObjectBaseTypeCompare((PetscObject)hA->cooMat, MATMPIAIJ, &ismpiaij)); 67206977982Sstefanozampini if (ismpiaij) PetscCall(MatMPIAIJGetSeqAIJ(hA->cooMat, &dH, &oH, NULL)); 67306977982Sstefanozampini 67406977982Sstefanozampini PetscScalar *a; 67506977982Sstefanozampini PetscCall(MatSeqAIJGetCSRAndMemType(dA, NULL, NULL, &a, NULL)); 67606977982Sstefanozampini PetscCall(MatSetValuesCOO(dH, a, INSERT_VALUES)); 67706977982Sstefanozampini if (oH) { 67806977982Sstefanozampini PetscCall(MatSeqAIJGetCSRAndMemType(oA, NULL, NULL, &a, NULL)); 67906977982Sstefanozampini PetscCall(MatSetValuesCOO(oH, a, INSERT_VALUES)); 68006977982Sstefanozampini } 681b73e3080SStefano Zampini 68248a46eb9SPierre Jolivet if (reuse == MAT_INPLACE_MATRIX) PetscCall(MatHeaderReplace(A, &M)); 6833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 68463c07aadSStefano Zampini } 68563c07aadSStefano Zampini 686d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatConvert_HYPRE_AIJ(Mat A, MatType mtype, MatReuse reuse, Mat *B) 687d71ae5a4SJacob Faibussowitsch { 68806977982Sstefanozampini Mat M, dA = NULL, oA = NULL; 68963c07aadSStefano Zampini hypre_ParCSRMatrix *parcsr; 69006977982Sstefanozampini hypre_CSRMatrix *dH, *oH; 69163c07aadSStefano Zampini MPI_Comm comm; 69206977982Sstefanozampini PetscBool ismpiaij, isseqaij; 69363c07aadSStefano Zampini 69463c07aadSStefano Zampini PetscFunctionBegin; 69563c07aadSStefano Zampini comm = PetscObjectComm((PetscObject)A); 69663c07aadSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 6979566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompare((PetscObject)*B, MATMPIAIJ, &ismpiaij)); 6989566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompare((PetscObject)*B, MATSEQAIJ, &isseqaij)); 69906977982Sstefanozampini PetscCheck(ismpiaij || isseqaij, comm, PETSC_ERR_SUP, "Only MATMPIAIJ or MATSEQAIJ base types are supported"); 70063c07aadSStefano Zampini } 70106977982Sstefanozampini PetscCall(MatHYPREGetParCSR(A, &parcsr)); 7026ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 70306977982Sstefanozampini if (HYPRE_MEMORY_DEVICE == hypre_ParCSRMatrixMemoryLocation(parcsr)) { 70406977982Sstefanozampini PetscBool isaij; 70506977982Sstefanozampini 70606977982Sstefanozampini PetscCall(PetscStrcmp(mtype, MATAIJ, &isaij)); 70706977982Sstefanozampini if (isaij) { 70806977982Sstefanozampini PetscMPIInt size; 70906977982Sstefanozampini 7109566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 71106977982Sstefanozampini #if defined(HYPRE_USING_HIP) 71206977982Sstefanozampini mtype = size > 1 ? MATMPIAIJHIPSPARSE : MATSEQAIJHIPSPARSE; 71306977982Sstefanozampini #elif defined(HYPRE_USING_CUDA) 71406977982Sstefanozampini mtype = size > 1 ? MATMPIAIJCUSPARSE : MATSEQAIJCUSPARSE; 71506977982Sstefanozampini #else 71606977982Sstefanozampini mtype = size > 1 ? MATMPIAIJ : MATSEQAIJ; 71706977982Sstefanozampini #endif 71863c07aadSStefano Zampini } 71963c07aadSStefano Zampini } 72006977982Sstefanozampini #endif 72106977982Sstefanozampini dH = hypre_ParCSRMatrixDiag(parcsr); 72206977982Sstefanozampini oH = hypre_ParCSRMatrixOffd(parcsr); 7239371c9d4SSatish Balay if (reuse != MAT_REUSE_MATRIX) { 72406977982Sstefanozampini PetscCount coo_n; 72506977982Sstefanozampini PetscInt *coo_i, *coo_j; 72663c07aadSStefano Zampini 72706977982Sstefanozampini PetscCall(MatCreate(comm, &M)); 72806977982Sstefanozampini PetscCall(MatSetType(M, mtype)); 72906977982Sstefanozampini PetscCall(MatSetSizes(M, A->rmap->n, A->cmap->n, A->rmap->N, A->cmap->N)); 73006977982Sstefanozampini PetscCall(MatMPIAIJSetPreallocation(M, 0, NULL, 0, NULL)); 73163c07aadSStefano Zampini 73206977982Sstefanozampini dA = M; 73306977982Sstefanozampini PetscCall(PetscObjectBaseTypeCompare((PetscObject)M, MATMPIAIJ, &ismpiaij)); 73406977982Sstefanozampini if (ismpiaij) PetscCall(MatMPIAIJGetSeqAIJ(M, &dA, &oA, NULL)); 735a16187a7SStefano Zampini 73606977982Sstefanozampini PetscCall(hypreCSRMatrixGetCOO_Private(dH, &coo_n, &coo_i, &coo_j)); 73706977982Sstefanozampini PetscCall(MatSetPreallocationCOO(dA, coo_n, coo_i, coo_j)); 73806977982Sstefanozampini PetscCall(PetscFree2(coo_i, coo_j)); 73906977982Sstefanozampini if (ismpiaij) { 74006977982Sstefanozampini HYPRE_Int nc = hypre_CSRMatrixNumCols(oH); 741a16187a7SStefano Zampini 74206977982Sstefanozampini PetscCall(PetscLayoutDestroy(&oA->cmap)); 74306977982Sstefanozampini PetscCall(PetscLayoutCreateFromSizes(PetscObjectComm((PetscObject)oA), nc, nc, 1, &oA->cmap)); 74406977982Sstefanozampini PetscCall(hypreCSRMatrixGetCOO_Private(oH, &coo_n, &coo_i, &coo_j)); 74506977982Sstefanozampini PetscCall(MatSetPreallocationCOO(oA, coo_n, coo_i, coo_j)); 74606977982Sstefanozampini PetscCall(PetscFree2(coo_i, coo_j)); 747a16187a7SStefano Zampini 74806977982Sstefanozampini /* garray */ 749f4f49eeaSPierre Jolivet Mat_MPIAIJ *aij = (Mat_MPIAIJ *)M->data; 75006977982Sstefanozampini HYPRE_BigInt *harray = hypre_ParCSRMatrixColMapOffd(parcsr); 75106977982Sstefanozampini PetscInt *garray; 75206977982Sstefanozampini 75306977982Sstefanozampini PetscCall(PetscFree(aij->garray)); 75406977982Sstefanozampini PetscCall(PetscMalloc1(nc, &garray)); 75506977982Sstefanozampini for (HYPRE_Int i = 0; i < nc; i++) garray[i] = (PetscInt)harray[i]; 75606977982Sstefanozampini aij->garray = garray; 75706977982Sstefanozampini PetscCall(MatSetUpMultiply_MPIAIJ(M)); 758a16187a7SStefano Zampini } 75906977982Sstefanozampini if (reuse == MAT_INITIAL_MATRIX) *B = M; 76006977982Sstefanozampini } else M = *B; 761225daaf8SStefano Zampini 76206977982Sstefanozampini dA = M; 76306977982Sstefanozampini PetscCall(PetscObjectBaseTypeCompare((PetscObject)M, MATMPIAIJ, &ismpiaij)); 76406977982Sstefanozampini if (ismpiaij) PetscCall(MatMPIAIJGetSeqAIJ(M, &dA, &oA, NULL)); 76506977982Sstefanozampini PetscCall(MatSetValuesCOOFromCSRMatrix_Private(dA, dH)); 76606977982Sstefanozampini if (oA) PetscCall(MatSetValuesCOOFromCSRMatrix_Private(oA, oH)); 76706977982Sstefanozampini M->assembled = PETSC_TRUE; 76806977982Sstefanozampini if (reuse == MAT_INPLACE_MATRIX) PetscCall(MatHeaderReplace(A, &M)); 7693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 77063c07aadSStefano Zampini } 77163c07aadSStefano Zampini 772d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAIJGetParCSR_Private(Mat A, hypre_ParCSRMatrix **hA) 773d71ae5a4SJacob Faibussowitsch { 774613e5ff0Sstefano_zampini hypre_ParCSRMatrix *tA; 775c1a070e6SStefano Zampini hypre_CSRMatrix *hdiag, *hoffd; 776c1a070e6SStefano Zampini Mat_SeqAIJ *diag, *offd; 7772cf14000SStefano Zampini PetscInt *garray, i, noffd, dnnz, onnz, *row_starts, *col_starts; 778c1a070e6SStefano Zampini MPI_Comm comm = PetscObjectComm((PetscObject)A); 779613e5ff0Sstefano_zampini PetscBool ismpiaij, isseqaij; 7802cf14000SStefano Zampini PetscBool sameint = (PetscBool)(sizeof(PetscInt) == sizeof(HYPRE_Int)); 7816ea7df73SStefano Zampini HYPRE_Int *hdi = NULL, *hdj = NULL, *hoi = NULL, *hoj = NULL; 7825c97c10fSStefano Zampini PetscInt *pdi = NULL, *pdj = NULL, *poi = NULL, *poj = NULL; 78306977982Sstefanozampini PetscBool iscuda, iship; 78406977982Sstefanozampini #if defined(PETSC_HAVE_DEVICE) && defined(PETSC_HAVE_HYPRE_DEVICE) 78506977982Sstefanozampini PetscBool boundtocpu = A->boundtocpu; 78606977982Sstefanozampini #else 78706977982Sstefanozampini PetscBool boundtocpu = PETSC_TRUE; 7886ea7df73SStefano Zampini #endif 789c1a070e6SStefano Zampini 790c1a070e6SStefano Zampini PetscFunctionBegin; 7919566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIAIJ, &ismpiaij)); 7929566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATSEQAIJ, &isseqaij)); 79308401ef6SPierre Jolivet PetscCheck(ismpiaij || isseqaij, comm, PETSC_ERR_SUP, "Unsupported type %s", ((PetscObject)A)->type_name); 79406977982Sstefanozampini PetscCall(PetscObjectTypeCompareAny((PetscObject)A, &iscuda, MATSEQAIJHIPSPARSE, MATMPIAIJCUSPARSE, "")); 79506977982Sstefanozampini PetscCall(PetscObjectTypeCompareAny((PetscObject)A, &iship, MATSEQAIJCUSPARSE, MATMPIAIJHIPSPARSE, "")); 796ea9ee2c1SPierre Jolivet PetscHYPREInitialize(); 797c1a070e6SStefano Zampini if (ismpiaij) { 798f4f49eeaSPierre Jolivet Mat_MPIAIJ *a = (Mat_MPIAIJ *)A->data; 799c1a070e6SStefano Zampini 800c1a070e6SStefano Zampini diag = (Mat_SeqAIJ *)a->A->data; 801c1a070e6SStefano Zampini offd = (Mat_SeqAIJ *)a->B->data; 80206977982Sstefanozampini if (!boundtocpu && (iscuda || iship)) { 80306977982Sstefanozampini #if defined(HYPRE_USING_CUDA) && defined(PETSC_HAVE_CUDA) 80406977982Sstefanozampini if (iscuda) { 8056ea7df73SStefano Zampini sameint = PETSC_TRUE; 8069566063dSJacob Faibussowitsch PetscCall(MatSeqAIJCUSPARSEGetIJ(a->A, PETSC_FALSE, (const HYPRE_Int **)&hdi, (const HYPRE_Int **)&hdj)); 8079566063dSJacob Faibussowitsch PetscCall(MatSeqAIJCUSPARSEGetIJ(a->B, PETSC_FALSE, (const HYPRE_Int **)&hoi, (const HYPRE_Int **)&hoj)); 80806977982Sstefanozampini } 8096ea7df73SStefano Zampini #endif 81006977982Sstefanozampini #if defined(HYPRE_USING_HIP) && defined(PETSC_HAVE_HIP) 81106977982Sstefanozampini if (iship) { 81206977982Sstefanozampini sameint = PETSC_TRUE; 81306977982Sstefanozampini PetscCall(MatSeqAIJHIPSPARSEGetIJ(a->A, PETSC_FALSE, (const HYPRE_Int **)&hdi, (const HYPRE_Int **)&hdj)); 81406977982Sstefanozampini PetscCall(MatSeqAIJHIPSPARSEGetIJ(a->B, PETSC_FALSE, (const HYPRE_Int **)&hoi, (const HYPRE_Int **)&hoj)); 81506977982Sstefanozampini } 81606977982Sstefanozampini #endif 81706977982Sstefanozampini } else { 81806977982Sstefanozampini boundtocpu = PETSC_TRUE; 8196ea7df73SStefano Zampini pdi = diag->i; 8206ea7df73SStefano Zampini pdj = diag->j; 8216ea7df73SStefano Zampini poi = offd->i; 8226ea7df73SStefano Zampini poj = offd->j; 8236ea7df73SStefano Zampini if (sameint) { 8246ea7df73SStefano Zampini hdi = (HYPRE_Int *)pdi; 8256ea7df73SStefano Zampini hdj = (HYPRE_Int *)pdj; 8266ea7df73SStefano Zampini hoi = (HYPRE_Int *)poi; 8276ea7df73SStefano Zampini hoj = (HYPRE_Int *)poj; 8286ea7df73SStefano Zampini } 8296ea7df73SStefano Zampini } 830c1a070e6SStefano Zampini garray = a->garray; 831c1a070e6SStefano Zampini noffd = a->B->cmap->N; 832c1a070e6SStefano Zampini dnnz = diag->nz; 833c1a070e6SStefano Zampini onnz = offd->nz; 834c1a070e6SStefano Zampini } else { 835c1a070e6SStefano Zampini diag = (Mat_SeqAIJ *)A->data; 836c1a070e6SStefano Zampini offd = NULL; 83706977982Sstefanozampini if (!boundtocpu && (iscuda || iship)) { 83806977982Sstefanozampini #if defined(HYPRE_USING_CUDA) && defined(PETSC_HAVE_CUDA) 83906977982Sstefanozampini if (iscuda) { 8406ea7df73SStefano Zampini sameint = PETSC_TRUE; 8419566063dSJacob Faibussowitsch PetscCall(MatSeqAIJCUSPARSEGetIJ(A, PETSC_FALSE, (const HYPRE_Int **)&hdi, (const HYPRE_Int **)&hdj)); 84206977982Sstefanozampini } 8436ea7df73SStefano Zampini #endif 84406977982Sstefanozampini #if defined(HYPRE_USING_HIP) && defined(PETSC_HAVE_HIP) 84506977982Sstefanozampini if (iship) { 84606977982Sstefanozampini sameint = PETSC_TRUE; 84706977982Sstefanozampini PetscCall(MatSeqAIJHIPSPARSEGetIJ(A, PETSC_FALSE, (const HYPRE_Int **)&hdi, (const HYPRE_Int **)&hdj)); 84806977982Sstefanozampini } 84906977982Sstefanozampini #endif 85006977982Sstefanozampini } else { 85106977982Sstefanozampini boundtocpu = PETSC_TRUE; 8526ea7df73SStefano Zampini pdi = diag->i; 8536ea7df73SStefano Zampini pdj = diag->j; 8546ea7df73SStefano Zampini if (sameint) { 8556ea7df73SStefano Zampini hdi = (HYPRE_Int *)pdi; 8566ea7df73SStefano Zampini hdj = (HYPRE_Int *)pdj; 8576ea7df73SStefano Zampini } 8586ea7df73SStefano Zampini } 859c1a070e6SStefano Zampini garray = NULL; 860c1a070e6SStefano Zampini noffd = 0; 861c1a070e6SStefano Zampini dnnz = diag->nz; 862c1a070e6SStefano Zampini onnz = 0; 863c1a070e6SStefano Zampini } 864225daaf8SStefano Zampini 865c1a070e6SStefano Zampini /* create a temporary ParCSR */ 866c1a070e6SStefano Zampini if (HYPRE_AssumedPartitionCheck()) { 867c1a070e6SStefano Zampini PetscMPIInt myid; 868c1a070e6SStefano Zampini 8699566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &myid)); 870c1a070e6SStefano Zampini row_starts = A->rmap->range + myid; 871c1a070e6SStefano Zampini col_starts = A->cmap->range + myid; 872c1a070e6SStefano Zampini } else { 873c1a070e6SStefano Zampini row_starts = A->rmap->range; 874c1a070e6SStefano Zampini col_starts = A->cmap->range; 875c1a070e6SStefano Zampini } 8762cf14000SStefano Zampini tA = hypre_ParCSRMatrixCreate(comm, A->rmap->N, A->cmap->N, (HYPRE_BigInt *)row_starts, (HYPRE_BigInt *)col_starts, noffd, dnnz, onnz); 877a1d2239cSSatish Balay #if defined(hypre_ParCSRMatrixOwnsRowStarts) 878c1a070e6SStefano Zampini hypre_ParCSRMatrixSetRowStartsOwner(tA, 0); 879c1a070e6SStefano Zampini hypre_ParCSRMatrixSetColStartsOwner(tA, 0); 880a1d2239cSSatish Balay #endif 881c1a070e6SStefano Zampini 882225daaf8SStefano Zampini /* set diagonal part */ 883c1a070e6SStefano Zampini hdiag = hypre_ParCSRMatrixDiag(tA); 8846ea7df73SStefano Zampini if (!sameint) { /* malloc CSR pointers */ 8859566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(A->rmap->n + 1, &hdi, dnnz, &hdj)); 886f4f49eeaSPierre Jolivet for (i = 0; i < A->rmap->n + 1; i++) hdi[i] = (HYPRE_Int)pdi[i]; 887f4f49eeaSPierre Jolivet for (i = 0; i < dnnz; i++) hdj[i] = (HYPRE_Int)pdj[i]; 8882cf14000SStefano Zampini } 8896ea7df73SStefano Zampini hypre_CSRMatrixI(hdiag) = hdi; 8906ea7df73SStefano Zampini hypre_CSRMatrixJ(hdiag) = hdj; 89139accc25SStefano Zampini hypre_CSRMatrixData(hdiag) = (HYPRE_Complex *)diag->a; 892c1a070e6SStefano Zampini hypre_CSRMatrixNumNonzeros(hdiag) = diag->nz; 893c1a070e6SStefano Zampini hypre_CSRMatrixSetRownnz(hdiag); 894c1a070e6SStefano Zampini hypre_CSRMatrixSetDataOwner(hdiag, 0); 895c1a070e6SStefano Zampini 8964cf0e950SBarry Smith /* set off-diagonal part */ 897c1a070e6SStefano Zampini hoffd = hypre_ParCSRMatrixOffd(tA); 898c1a070e6SStefano Zampini if (offd) { 8996ea7df73SStefano Zampini if (!sameint) { /* malloc CSR pointers */ 9009566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(A->rmap->n + 1, &hoi, onnz, &hoj)); 901f4f49eeaSPierre Jolivet for (i = 0; i < A->rmap->n + 1; i++) hoi[i] = (HYPRE_Int)poi[i]; 902f4f49eeaSPierre Jolivet for (i = 0; i < onnz; i++) hoj[i] = (HYPRE_Int)poj[i]; 9032cf14000SStefano Zampini } 9046ea7df73SStefano Zampini hypre_CSRMatrixI(hoffd) = hoi; 9056ea7df73SStefano Zampini hypre_CSRMatrixJ(hoffd) = hoj; 90639accc25SStefano Zampini hypre_CSRMatrixData(hoffd) = (HYPRE_Complex *)offd->a; 907c1a070e6SStefano Zampini hypre_CSRMatrixNumNonzeros(hoffd) = offd->nz; 908c1a070e6SStefano Zampini hypre_CSRMatrixSetRownnz(hoffd); 909c1a070e6SStefano Zampini hypre_CSRMatrixSetDataOwner(hoffd, 0); 9106ea7df73SStefano Zampini } 9116ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 91206977982Sstefanozampini PetscCallExternal(hypre_ParCSRMatrixInitialize_v2, tA, !boundtocpu ? HYPRE_MEMORY_DEVICE : HYPRE_MEMORY_HOST); 9136ea7df73SStefano Zampini #else 9146ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_LT(2, 18, 0) 915792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixInitialize, tA); 9166ea7df73SStefano Zampini #else 917792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixInitialize_v2, tA, HYPRE_MEMORY_HOST); 9186ea7df73SStefano Zampini #endif 9196ea7df73SStefano Zampini #endif 9206ea7df73SStefano Zampini hypre_TFree(hypre_ParCSRMatrixColMapOffd(tA), HYPRE_MEMORY_HOST); 921c1a070e6SStefano Zampini hypre_ParCSRMatrixSetNumNonzeros(tA); 9222cf14000SStefano Zampini hypre_ParCSRMatrixColMapOffd(tA) = (HYPRE_BigInt *)garray; 923792fecdfSBarry Smith if (!hypre_ParCSRMatrixCommPkg(tA)) PetscCallExternal(hypre_MatvecCommPkgCreate, tA); 924613e5ff0Sstefano_zampini *hA = tA; 9253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 926613e5ff0Sstefano_zampini } 927c1a070e6SStefano Zampini 928d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAIJRestoreParCSR_Private(Mat A, hypre_ParCSRMatrix **hA) 929d71ae5a4SJacob Faibussowitsch { 930613e5ff0Sstefano_zampini hypre_CSRMatrix *hdiag, *hoffd; 9316ea7df73SStefano Zampini PetscBool ismpiaij, sameint = (PetscBool)(sizeof(PetscInt) == sizeof(HYPRE_Int)); 9326ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 9336ea7df73SStefano Zampini PetscBool iscuda = PETSC_FALSE; 9346ea7df73SStefano Zampini #endif 935c1a070e6SStefano Zampini 936613e5ff0Sstefano_zampini PetscFunctionBegin; 9379566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIAIJ, &ismpiaij)); 9386ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 9399566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)A, &iscuda, MATSEQAIJCUSPARSE, MATMPIAIJCUSPARSE, "")); 9406ea7df73SStefano Zampini if (iscuda) sameint = PETSC_TRUE; 9416ea7df73SStefano Zampini #endif 942613e5ff0Sstefano_zampini hdiag = hypre_ParCSRMatrixDiag(*hA); 943613e5ff0Sstefano_zampini hoffd = hypre_ParCSRMatrixOffd(*hA); 9446ea7df73SStefano Zampini /* free temporary memory allocated by PETSc 9456ea7df73SStefano Zampini set pointers to NULL before destroying tA */ 9462cf14000SStefano Zampini if (!sameint) { 9472cf14000SStefano Zampini HYPRE_Int *hi, *hj; 9482cf14000SStefano Zampini 9492cf14000SStefano Zampini hi = hypre_CSRMatrixI(hdiag); 9502cf14000SStefano Zampini hj = hypre_CSRMatrixJ(hdiag); 9519566063dSJacob Faibussowitsch PetscCall(PetscFree2(hi, hj)); 9526ea7df73SStefano Zampini if (ismpiaij) { 9532cf14000SStefano Zampini hi = hypre_CSRMatrixI(hoffd); 9542cf14000SStefano Zampini hj = hypre_CSRMatrixJ(hoffd); 9559566063dSJacob Faibussowitsch PetscCall(PetscFree2(hi, hj)); 9562cf14000SStefano Zampini } 9572cf14000SStefano Zampini } 958c1a070e6SStefano Zampini hypre_CSRMatrixI(hdiag) = NULL; 959c1a070e6SStefano Zampini hypre_CSRMatrixJ(hdiag) = NULL; 960c1a070e6SStefano Zampini hypre_CSRMatrixData(hdiag) = NULL; 9616ea7df73SStefano Zampini if (ismpiaij) { 962c1a070e6SStefano Zampini hypre_CSRMatrixI(hoffd) = NULL; 963c1a070e6SStefano Zampini hypre_CSRMatrixJ(hoffd) = NULL; 964c1a070e6SStefano Zampini hypre_CSRMatrixData(hoffd) = NULL; 9656ea7df73SStefano Zampini } 966613e5ff0Sstefano_zampini hypre_ParCSRMatrixColMapOffd(*hA) = NULL; 967613e5ff0Sstefano_zampini hypre_ParCSRMatrixDestroy(*hA); 968613e5ff0Sstefano_zampini *hA = NULL; 9693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 970613e5ff0Sstefano_zampini } 971613e5ff0Sstefano_zampini 972613e5ff0Sstefano_zampini /* calls RAP from BoomerAMG: 9733dad0653Sstefano_zampini the resulting ParCSR will not own the column and row starts 9746ea7df73SStefano Zampini It looks like we don't need to have the diagonal entries ordered first */ 975d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatHYPRE_ParCSR_RAP(hypre_ParCSRMatrix *hR, hypre_ParCSRMatrix *hA, hypre_ParCSRMatrix *hP, hypre_ParCSRMatrix **hRAP) 976d71ae5a4SJacob Faibussowitsch { 977a1d2239cSSatish Balay #if defined(hypre_ParCSRMatrixOwnsRowStarts) 978613e5ff0Sstefano_zampini HYPRE_Int P_owns_col_starts, R_owns_row_starts; 979a1d2239cSSatish Balay #endif 980613e5ff0Sstefano_zampini 981613e5ff0Sstefano_zampini PetscFunctionBegin; 982a1d2239cSSatish Balay #if defined(hypre_ParCSRMatrixOwnsRowStarts) 983613e5ff0Sstefano_zampini P_owns_col_starts = hypre_ParCSRMatrixOwnsColStarts(hP); 984613e5ff0Sstefano_zampini R_owns_row_starts = hypre_ParCSRMatrixOwnsRowStarts(hR); 985a1d2239cSSatish Balay #endif 9866ea7df73SStefano Zampini /* can be replaced by version test later */ 9876ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 988792fecdfSBarry Smith PetscStackPushExternal("hypre_ParCSRMatrixRAP"); 9896ea7df73SStefano Zampini *hRAP = hypre_ParCSRMatrixRAP(hR, hA, hP); 9906ea7df73SStefano Zampini PetscStackPop; 9916ea7df73SStefano Zampini #else 992792fecdfSBarry Smith PetscCallExternal(hypre_BoomerAMGBuildCoarseOperator, hR, hA, hP, hRAP); 993792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixSetNumNonzeros, *hRAP); 9946ea7df73SStefano Zampini #endif 995613e5ff0Sstefano_zampini /* hypre_BoomerAMGBuildCoarseOperator steals the col_starts from P and the row_starts from R */ 996a1d2239cSSatish Balay #if defined(hypre_ParCSRMatrixOwnsRowStarts) 997613e5ff0Sstefano_zampini hypre_ParCSRMatrixSetRowStartsOwner(*hRAP, 0); 998613e5ff0Sstefano_zampini hypre_ParCSRMatrixSetColStartsOwner(*hRAP, 0); 999613e5ff0Sstefano_zampini if (P_owns_col_starts) hypre_ParCSRMatrixSetColStartsOwner(hP, 1); 1000613e5ff0Sstefano_zampini if (R_owns_row_starts) hypre_ParCSRMatrixSetRowStartsOwner(hR, 1); 1001a1d2239cSSatish Balay #endif 10023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1003613e5ff0Sstefano_zampini } 1004613e5ff0Sstefano_zampini 1005d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatPtAPNumeric_AIJ_AIJ_wHYPRE(Mat A, Mat P, Mat C) 1006d71ae5a4SJacob Faibussowitsch { 10076f231fbdSstefano_zampini Mat B; 10086abb4441SStefano Zampini hypre_ParCSRMatrix *hA, *hP, *hPtAP = NULL; 10094222ddf1SHong Zhang Mat_Product *product = C->product; 1010613e5ff0Sstefano_zampini 1011613e5ff0Sstefano_zampini PetscFunctionBegin; 10129566063dSJacob Faibussowitsch PetscCall(MatAIJGetParCSR_Private(A, &hA)); 10139566063dSJacob Faibussowitsch PetscCall(MatAIJGetParCSR_Private(P, &hP)); 10149566063dSJacob Faibussowitsch PetscCall(MatHYPRE_ParCSR_RAP(hP, hA, hP, &hPtAP)); 10159566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(hPtAP, MATAIJ, PETSC_OWN_POINTER, &B)); 10164222ddf1SHong Zhang 10179566063dSJacob Faibussowitsch PetscCall(MatHeaderMerge(C, &B)); 10184222ddf1SHong Zhang C->product = product; 10194222ddf1SHong Zhang 10209566063dSJacob Faibussowitsch PetscCall(MatAIJRestoreParCSR_Private(A, &hA)); 10219566063dSJacob Faibussowitsch PetscCall(MatAIJRestoreParCSR_Private(P, &hP)); 10223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 10236f231fbdSstefano_zampini } 10246f231fbdSstefano_zampini 1025d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatPtAPSymbolic_AIJ_AIJ_wHYPRE(Mat A, Mat P, PetscReal fill, Mat C) 1026d71ae5a4SJacob Faibussowitsch { 10276f231fbdSstefano_zampini PetscFunctionBegin; 10289566063dSJacob Faibussowitsch PetscCall(MatSetType(C, MATAIJ)); 10294222ddf1SHong Zhang C->ops->ptapnumeric = MatPtAPNumeric_AIJ_AIJ_wHYPRE; 10304222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_PtAP; 10313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1032613e5ff0Sstefano_zampini } 1033613e5ff0Sstefano_zampini 1034d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatPtAPNumeric_AIJ_HYPRE(Mat A, Mat P, Mat C) 1035d71ae5a4SJacob Faibussowitsch { 10364cc28894Sstefano_zampini Mat B; 10374cc28894Sstefano_zampini Mat_HYPRE *hP; 10386abb4441SStefano Zampini hypre_ParCSRMatrix *hA = NULL, *Pparcsr, *ptapparcsr = NULL; 1039613e5ff0Sstefano_zampini HYPRE_Int type; 1040613e5ff0Sstefano_zampini MPI_Comm comm = PetscObjectComm((PetscObject)A); 10414cc28894Sstefano_zampini PetscBool ishypre; 1042613e5ff0Sstefano_zampini 1043613e5ff0Sstefano_zampini PetscFunctionBegin; 10449566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)P, MATHYPRE, &ishypre)); 104528b400f6SJacob Faibussowitsch PetscCheck(ishypre, comm, PETSC_ERR_USER, "P should be of type %s", MATHYPRE); 10464cc28894Sstefano_zampini hP = (Mat_HYPRE *)P->data; 1047792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObjectType, hP->ij, &type); 104808401ef6SPierre Jolivet PetscCheck(type == HYPRE_PARCSR, comm, PETSC_ERR_SUP, "Only HYPRE_PARCSR is supported"); 1049792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hP->ij, (void **)&Pparcsr); 1050613e5ff0Sstefano_zampini 10519566063dSJacob Faibussowitsch PetscCall(MatAIJGetParCSR_Private(A, &hA)); 10529566063dSJacob Faibussowitsch PetscCall(MatHYPRE_ParCSR_RAP(Pparcsr, hA, Pparcsr, &ptapparcsr)); 10539566063dSJacob Faibussowitsch PetscCall(MatAIJRestoreParCSR_Private(A, &hA)); 1054225daaf8SStefano Zampini 10554cc28894Sstefano_zampini /* create temporary matrix and merge to C */ 10569566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(ptapparcsr, ((PetscObject)C)->type_name, PETSC_OWN_POINTER, &B)); 10579566063dSJacob Faibussowitsch PetscCall(MatHeaderMerge(C, &B)); 10583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 10594cc28894Sstefano_zampini } 10604cc28894Sstefano_zampini 1061d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatPtAPNumeric_HYPRE_HYPRE(Mat A, Mat P, Mat C) 1062d71ae5a4SJacob Faibussowitsch { 10634cc28894Sstefano_zampini Mat B; 10646abb4441SStefano Zampini hypre_ParCSRMatrix *Aparcsr, *Pparcsr, *ptapparcsr = NULL; 10654cc28894Sstefano_zampini Mat_HYPRE *hA, *hP; 10664cc28894Sstefano_zampini PetscBool ishypre; 10674cc28894Sstefano_zampini HYPRE_Int type; 10684cc28894Sstefano_zampini 10694cc28894Sstefano_zampini PetscFunctionBegin; 10709566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)P, MATHYPRE, &ishypre)); 107128b400f6SJacob Faibussowitsch PetscCheck(ishypre, PetscObjectComm((PetscObject)P), PETSC_ERR_USER, "P should be of type %s", MATHYPRE); 10729566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A, MATHYPRE, &ishypre)); 107328b400f6SJacob Faibussowitsch PetscCheck(ishypre, PetscObjectComm((PetscObject)A), PETSC_ERR_USER, "A should be of type %s", MATHYPRE); 10744cc28894Sstefano_zampini hA = (Mat_HYPRE *)A->data; 10754cc28894Sstefano_zampini hP = (Mat_HYPRE *)P->data; 1076792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObjectType, hA->ij, &type); 107708401ef6SPierre Jolivet PetscCheck(type == HYPRE_PARCSR, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Only HYPRE_PARCSR is supported"); 1078792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObjectType, hP->ij, &type); 107908401ef6SPierre Jolivet PetscCheck(type == HYPRE_PARCSR, PetscObjectComm((PetscObject)P), PETSC_ERR_SUP, "Only HYPRE_PARCSR is supported"); 1080792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hA->ij, (void **)&Aparcsr); 1081792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hP->ij, (void **)&Pparcsr); 10829566063dSJacob Faibussowitsch PetscCall(MatHYPRE_ParCSR_RAP(Pparcsr, Aparcsr, Pparcsr, &ptapparcsr)); 10839566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(ptapparcsr, MATHYPRE, PETSC_OWN_POINTER, &B)); 10849566063dSJacob Faibussowitsch PetscCall(MatHeaderMerge(C, &B)); 10853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 10864cc28894Sstefano_zampini } 10874cc28894Sstefano_zampini 1088d501dc42Sstefano_zampini /* calls hypre_ParMatmul 1089d501dc42Sstefano_zampini hypre_ParMatMul uses hypre_ParMatrixCreate with the communicator of hA 10903dad0653Sstefano_zampini hypre_ParMatrixCreate does not duplicate the communicator 10916ea7df73SStefano Zampini It looks like we don't need to have the diagonal entries ordered first */ 1092d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatHYPRE_ParCSR_MatMatMult(hypre_ParCSRMatrix *hA, hypre_ParCSRMatrix *hB, hypre_ParCSRMatrix **hAB) 1093d71ae5a4SJacob Faibussowitsch { 1094d501dc42Sstefano_zampini PetscFunctionBegin; 10956ea7df73SStefano Zampini /* can be replaced by version test later */ 10966ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 1097792fecdfSBarry Smith PetscStackPushExternal("hypre_ParCSRMatMat"); 10986ea7df73SStefano Zampini *hAB = hypre_ParCSRMatMat(hA, hB); 10996ea7df73SStefano Zampini #else 1100792fecdfSBarry Smith PetscStackPushExternal("hypre_ParMatmul"); 1101d501dc42Sstefano_zampini *hAB = hypre_ParMatmul(hA, hB); 11026ea7df73SStefano Zampini #endif 1103d501dc42Sstefano_zampini PetscStackPop; 11043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1105d501dc42Sstefano_zampini } 1106d501dc42Sstefano_zampini 1107d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatMultNumeric_AIJ_AIJ_wHYPRE(Mat A, Mat B, Mat C) 1108d71ae5a4SJacob Faibussowitsch { 11095e5acdf2Sstefano_zampini Mat D; 1110d501dc42Sstefano_zampini hypre_ParCSRMatrix *hA, *hB, *hAB = NULL; 11114222ddf1SHong Zhang Mat_Product *product = C->product; 11125e5acdf2Sstefano_zampini 11135e5acdf2Sstefano_zampini PetscFunctionBegin; 11149566063dSJacob Faibussowitsch PetscCall(MatAIJGetParCSR_Private(A, &hA)); 11159566063dSJacob Faibussowitsch PetscCall(MatAIJGetParCSR_Private(B, &hB)); 11169566063dSJacob Faibussowitsch PetscCall(MatHYPRE_ParCSR_MatMatMult(hA, hB, &hAB)); 11179566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(hAB, MATAIJ, PETSC_OWN_POINTER, &D)); 11184222ddf1SHong Zhang 11199566063dSJacob Faibussowitsch PetscCall(MatHeaderMerge(C, &D)); 11204222ddf1SHong Zhang C->product = product; 11214222ddf1SHong Zhang 11229566063dSJacob Faibussowitsch PetscCall(MatAIJRestoreParCSR_Private(A, &hA)); 11239566063dSJacob Faibussowitsch PetscCall(MatAIJRestoreParCSR_Private(B, &hB)); 11243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 11255e5acdf2Sstefano_zampini } 11265e5acdf2Sstefano_zampini 1127d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatMatMultSymbolic_AIJ_AIJ_wHYPRE(Mat A, Mat B, PetscReal fill, Mat C) 1128d71ae5a4SJacob Faibussowitsch { 11295e5acdf2Sstefano_zampini PetscFunctionBegin; 11309566063dSJacob Faibussowitsch PetscCall(MatSetType(C, MATAIJ)); 11314222ddf1SHong Zhang C->ops->matmultnumeric = MatMatMultNumeric_AIJ_AIJ_wHYPRE; 11324222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_AB; 11333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 11345e5acdf2Sstefano_zampini } 11355e5acdf2Sstefano_zampini 1136d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatMultNumeric_HYPRE_HYPRE(Mat A, Mat B, Mat C) 1137d71ae5a4SJacob Faibussowitsch { 1138d501dc42Sstefano_zampini Mat D; 1139d501dc42Sstefano_zampini hypre_ParCSRMatrix *Aparcsr, *Bparcsr, *ABparcsr = NULL; 1140d501dc42Sstefano_zampini Mat_HYPRE *hA, *hB; 1141d501dc42Sstefano_zampini PetscBool ishypre; 1142d501dc42Sstefano_zampini HYPRE_Int type; 11434222ddf1SHong Zhang Mat_Product *product; 1144d501dc42Sstefano_zampini 1145d501dc42Sstefano_zampini PetscFunctionBegin; 11469566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, MATHYPRE, &ishypre)); 114728b400f6SJacob Faibussowitsch PetscCheck(ishypre, PetscObjectComm((PetscObject)B), PETSC_ERR_USER, "B should be of type %s", MATHYPRE); 11489566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A, MATHYPRE, &ishypre)); 114928b400f6SJacob Faibussowitsch PetscCheck(ishypre, PetscObjectComm((PetscObject)A), PETSC_ERR_USER, "A should be of type %s", MATHYPRE); 1150d501dc42Sstefano_zampini hA = (Mat_HYPRE *)A->data; 1151d501dc42Sstefano_zampini hB = (Mat_HYPRE *)B->data; 1152792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObjectType, hA->ij, &type); 115308401ef6SPierre Jolivet PetscCheck(type == HYPRE_PARCSR, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Only HYPRE_PARCSR is supported"); 1154792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObjectType, hB->ij, &type); 115508401ef6SPierre Jolivet PetscCheck(type == HYPRE_PARCSR, PetscObjectComm((PetscObject)B), PETSC_ERR_SUP, "Only HYPRE_PARCSR is supported"); 1156792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hA->ij, (void **)&Aparcsr); 1157792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hB->ij, (void **)&Bparcsr); 11589566063dSJacob Faibussowitsch PetscCall(MatHYPRE_ParCSR_MatMatMult(Aparcsr, Bparcsr, &ABparcsr)); 11599566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(ABparcsr, MATHYPRE, PETSC_OWN_POINTER, &D)); 11604222ddf1SHong Zhang 1161d501dc42Sstefano_zampini /* need to use HeaderReplace because HeaderMerge messes up with the communicator */ 11624222ddf1SHong Zhang product = C->product; /* save it from MatHeaderReplace() */ 11634222ddf1SHong Zhang C->product = NULL; 11649566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(C, &D)); 11654222ddf1SHong Zhang C->product = product; 1166d501dc42Sstefano_zampini C->ops->matmultnumeric = MatMatMultNumeric_HYPRE_HYPRE; 11674222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_AB; 11683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1169d501dc42Sstefano_zampini } 1170d501dc42Sstefano_zampini 1171d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatTransposeMatMatMultNumeric_AIJ_AIJ_AIJ_wHYPRE(Mat A, Mat B, Mat C, Mat D) 1172d71ae5a4SJacob Faibussowitsch { 117320e1dc0dSstefano_zampini Mat E; 11746abb4441SStefano Zampini hypre_ParCSRMatrix *hA, *hB, *hC, *hABC = NULL; 117520e1dc0dSstefano_zampini 117620e1dc0dSstefano_zampini PetscFunctionBegin; 11779566063dSJacob Faibussowitsch PetscCall(MatAIJGetParCSR_Private(A, &hA)); 11789566063dSJacob Faibussowitsch PetscCall(MatAIJGetParCSR_Private(B, &hB)); 11799566063dSJacob Faibussowitsch PetscCall(MatAIJGetParCSR_Private(C, &hC)); 11809566063dSJacob Faibussowitsch PetscCall(MatHYPRE_ParCSR_RAP(hA, hB, hC, &hABC)); 11819566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(hABC, MATAIJ, PETSC_OWN_POINTER, &E)); 11829566063dSJacob Faibussowitsch PetscCall(MatHeaderMerge(D, &E)); 11839566063dSJacob Faibussowitsch PetscCall(MatAIJRestoreParCSR_Private(A, &hA)); 11849566063dSJacob Faibussowitsch PetscCall(MatAIJRestoreParCSR_Private(B, &hB)); 11859566063dSJacob Faibussowitsch PetscCall(MatAIJRestoreParCSR_Private(C, &hC)); 11863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 118720e1dc0dSstefano_zampini } 118820e1dc0dSstefano_zampini 1189d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatTransposeMatMatMultSymbolic_AIJ_AIJ_AIJ_wHYPRE(Mat A, Mat B, Mat C, PetscReal fill, Mat D) 1190d71ae5a4SJacob Faibussowitsch { 119120e1dc0dSstefano_zampini PetscFunctionBegin; 11929566063dSJacob Faibussowitsch PetscCall(MatSetType(D, MATAIJ)); 11933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 119420e1dc0dSstefano_zampini } 119520e1dc0dSstefano_zampini 1196d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSymbolic_AB_HYPRE(Mat C) 1197d71ae5a4SJacob Faibussowitsch { 11984222ddf1SHong Zhang PetscFunctionBegin; 11994222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_AB; 12003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12014222ddf1SHong Zhang } 12024222ddf1SHong Zhang 1203d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_HYPRE_AB(Mat C) 1204d71ae5a4SJacob Faibussowitsch { 12054222ddf1SHong Zhang Mat_Product *product = C->product; 12064222ddf1SHong Zhang PetscBool Ahypre; 12074222ddf1SHong Zhang 12084222ddf1SHong Zhang PetscFunctionBegin; 12099566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)product->A, MATHYPRE, &Ahypre)); 12104222ddf1SHong Zhang if (Ahypre) { /* A is a Hypre matrix */ 12119566063dSJacob Faibussowitsch PetscCall(MatSetType(C, MATHYPRE)); 12124222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AB_HYPRE; 12134222ddf1SHong Zhang C->ops->matmultnumeric = MatMatMultNumeric_HYPRE_HYPRE; 12143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12156718818eSStefano Zampini } 12163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12174222ddf1SHong Zhang } 12184222ddf1SHong Zhang 1219d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSymbolic_PtAP_HYPRE(Mat C) 1220d71ae5a4SJacob Faibussowitsch { 12214222ddf1SHong Zhang PetscFunctionBegin; 12224222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_PtAP; 12233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12244222ddf1SHong Zhang } 12254222ddf1SHong Zhang 1226d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_HYPRE_PtAP(Mat C) 1227d71ae5a4SJacob Faibussowitsch { 12284222ddf1SHong Zhang Mat_Product *product = C->product; 12294222ddf1SHong Zhang PetscBool flg; 12304222ddf1SHong Zhang PetscInt type = 0; 12314222ddf1SHong Zhang const char *outTypes[4] = {"aij", "seqaij", "mpiaij", "hypre"}; 12324222ddf1SHong Zhang PetscInt ntype = 4; 12334222ddf1SHong Zhang Mat A = product->A; 12344222ddf1SHong Zhang PetscBool Ahypre; 12354222ddf1SHong Zhang 12364222ddf1SHong Zhang PetscFunctionBegin; 12379566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A, MATHYPRE, &Ahypre)); 12384222ddf1SHong Zhang if (Ahypre) { /* A is a Hypre matrix */ 12399566063dSJacob Faibussowitsch PetscCall(MatSetType(C, MATHYPRE)); 12404222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_PtAP_HYPRE; 12414222ddf1SHong Zhang C->ops->ptapnumeric = MatPtAPNumeric_HYPRE_HYPRE; 12423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12434222ddf1SHong Zhang } 12444222ddf1SHong Zhang 12454222ddf1SHong Zhang /* A is AIJ, P is Hypre, C = PtAP can be either AIJ or Hypre format */ 12464222ddf1SHong Zhang /* Get runtime option */ 12474222ddf1SHong Zhang if (product->api_user) { 1248d0609cedSBarry Smith PetscOptionsBegin(PetscObjectComm((PetscObject)C), ((PetscObject)C)->prefix, "MatPtAP_HYPRE", "Mat"); 12499566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-matptap_hypre_outtype", "MatPtAP outtype", "MatPtAP outtype", outTypes, ntype, outTypes[type], &type, &flg)); 1250d0609cedSBarry Smith PetscOptionsEnd(); 12514222ddf1SHong Zhang } else { 1252d0609cedSBarry Smith PetscOptionsBegin(PetscObjectComm((PetscObject)C), ((PetscObject)C)->prefix, "MatProduct_PtAP_HYPRE", "Mat"); 12539566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-mat_product_algorithm_hypre_outtype", "MatProduct_PtAP outtype", "MatProduct_PtAP", outTypes, ntype, outTypes[type], &type, &flg)); 1254d0609cedSBarry Smith PetscOptionsEnd(); 12554222ddf1SHong Zhang } 12564222ddf1SHong Zhang 12574222ddf1SHong Zhang if (type == 0 || type == 1 || type == 2) { 12589566063dSJacob Faibussowitsch PetscCall(MatSetType(C, MATAIJ)); 12594222ddf1SHong Zhang } else if (type == 3) { 12609566063dSJacob Faibussowitsch PetscCall(MatSetType(C, MATHYPRE)); 12614222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)C), PETSC_ERR_SUP, "MatPtAP outtype is not supported"); 12624222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_PtAP_HYPRE; 12634222ddf1SHong Zhang C->ops->ptapnumeric = MatPtAPNumeric_AIJ_HYPRE; 12643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12654222ddf1SHong Zhang } 12664222ddf1SHong Zhang 1267d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_HYPRE(Mat C) 1268d71ae5a4SJacob Faibussowitsch { 12694222ddf1SHong Zhang Mat_Product *product = C->product; 12704222ddf1SHong Zhang 12714222ddf1SHong Zhang PetscFunctionBegin; 12724222ddf1SHong Zhang switch (product->type) { 1273d71ae5a4SJacob Faibussowitsch case MATPRODUCT_AB: 1274d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_HYPRE_AB(C)); 1275d71ae5a4SJacob Faibussowitsch break; 1276d71ae5a4SJacob Faibussowitsch case MATPRODUCT_PtAP: 1277d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_HYPRE_PtAP(C)); 1278d71ae5a4SJacob Faibussowitsch break; 1279d71ae5a4SJacob Faibussowitsch default: 1280d71ae5a4SJacob Faibussowitsch break; 12814222ddf1SHong Zhang } 12823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12834222ddf1SHong Zhang } 12844222ddf1SHong Zhang 1285d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMultTranspose_HYPRE(Mat A, Vec x, Vec y) 1286d71ae5a4SJacob Faibussowitsch { 128763c07aadSStefano Zampini PetscFunctionBegin; 12889566063dSJacob Faibussowitsch PetscCall(MatHYPRE_MultKernel_Private(A, 1.0, x, 0.0, y, PETSC_TRUE)); 12893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 129063c07aadSStefano Zampini } 129163c07aadSStefano Zampini 1292d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMult_HYPRE(Mat A, Vec x, Vec y) 1293d71ae5a4SJacob Faibussowitsch { 129463c07aadSStefano Zampini PetscFunctionBegin; 12959566063dSJacob Faibussowitsch PetscCall(MatHYPRE_MultKernel_Private(A, 1.0, x, 0.0, y, PETSC_FALSE)); 12963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 129763c07aadSStefano Zampini } 129863c07aadSStefano Zampini 1299d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMultAdd_HYPRE(Mat A, Vec x, Vec y, Vec z) 1300d71ae5a4SJacob Faibussowitsch { 1301414bd5c3SStefano Zampini PetscFunctionBegin; 130248a46eb9SPierre Jolivet if (y != z) PetscCall(VecCopy(y, z)); 13039566063dSJacob Faibussowitsch PetscCall(MatHYPRE_MultKernel_Private(A, 1.0, x, 1.0, z, PETSC_FALSE)); 13043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1305414bd5c3SStefano Zampini } 1306414bd5c3SStefano Zampini 1307d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMultTransposeAdd_HYPRE(Mat A, Vec x, Vec y, Vec z) 1308d71ae5a4SJacob Faibussowitsch { 1309414bd5c3SStefano Zampini PetscFunctionBegin; 131048a46eb9SPierre Jolivet if (y != z) PetscCall(VecCopy(y, z)); 13119566063dSJacob Faibussowitsch PetscCall(MatHYPRE_MultKernel_Private(A, 1.0, x, 1.0, z, PETSC_TRUE)); 13123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1313414bd5c3SStefano Zampini } 1314414bd5c3SStefano Zampini 1315414bd5c3SStefano Zampini /* y = a * A * x + b * y or y = a * A^t * x + b * y depending on trans */ 1316d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatHYPRE_MultKernel_Private(Mat A, HYPRE_Complex a, Vec x, HYPRE_Complex b, Vec y, PetscBool trans) 1317d71ae5a4SJacob Faibussowitsch { 131863c07aadSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 131963c07aadSStefano Zampini hypre_ParCSRMatrix *parcsr; 132063c07aadSStefano Zampini hypre_ParVector *hx, *hy; 132163c07aadSStefano Zampini 132263c07aadSStefano Zampini PetscFunctionBegin; 132363c07aadSStefano Zampini if (trans) { 13249566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPushVecRead(hA->b, x)); 13259566063dSJacob Faibussowitsch if (b != 0.0) PetscCall(VecHYPRE_IJVectorPushVec(hA->x, y)); 13269566063dSJacob Faibussowitsch else PetscCall(VecHYPRE_IJVectorPushVecWrite(hA->x, y)); 1327792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hA->b->ij, (void **)&hx); 1328792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hA->x->ij, (void **)&hy); 132963c07aadSStefano Zampini } else { 13309566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPushVecRead(hA->x, x)); 13319566063dSJacob Faibussowitsch if (b != 0.0) PetscCall(VecHYPRE_IJVectorPushVec(hA->b, y)); 13329566063dSJacob Faibussowitsch else PetscCall(VecHYPRE_IJVectorPushVecWrite(hA->b, y)); 1333792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hA->x->ij, (void **)&hx); 1334792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hA->b->ij, (void **)&hy); 133563c07aadSStefano Zampini } 1336792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hA->ij, (void **)&parcsr); 13376ea7df73SStefano Zampini if (trans) { 1338792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixMatvecT, a, parcsr, hx, b, hy); 13396ea7df73SStefano Zampini } else { 1340792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixMatvec, a, parcsr, hx, b, hy); 13416ea7df73SStefano Zampini } 13429566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hA->x)); 13439566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hA->b)); 13443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 134563c07aadSStefano Zampini } 134663c07aadSStefano Zampini 1347d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDestroy_HYPRE(Mat A) 1348d71ae5a4SJacob Faibussowitsch { 134963c07aadSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 135063c07aadSStefano Zampini 135163c07aadSStefano Zampini PetscFunctionBegin; 13529566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&hA->x)); 13539566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&hA->b)); 135406977982Sstefanozampini PetscCall(MatHYPRE_DestroyCOOMat(A)); /* must be called before destroying the individual CSR */ 1355978814f1SStefano Zampini if (hA->ij) { 1356978814f1SStefano Zampini if (!hA->inner_free) hypre_IJMatrixObject(hA->ij) = NULL; 1357792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixDestroy, hA->ij); 1358978814f1SStefano Zampini } 13599566063dSJacob Faibussowitsch if (hA->comm) PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)A), &hA->comm)); 1360c69f721fSFande Kong 13619566063dSJacob Faibussowitsch PetscCall(MatStashDestroy_Private(&A->stash)); 13629566063dSJacob Faibussowitsch PetscCall(PetscFree(hA->array)); 1363a32e9c99SJunchao Zhang if (hA->rows_d) PetscStackCallExternalVoid("hypre_Free", hypre_Free(hA->rows_d, HYPRE_MEMORY_DEVICE)); 1364c69f721fSFande Kong 13659566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatConvert_hypre_aij_C", NULL)); 13669566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatConvert_hypre_is_C", NULL)); 13679566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatProductSetFromOptions_seqaij_hypre_C", NULL)); 13689566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatProductSetFromOptions_mpiaij_hypre_C", NULL)); 136906977982Sstefanozampini PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatProductSetFromOptions_seqaijhipsparse_hypre_C", NULL)); 137006977982Sstefanozampini PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatProductSetFromOptions_mpiaijhipsparse_hypre_C", NULL)); 137106977982Sstefanozampini PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatProductSetFromOptions_seqaijcusparse_hypre_C", NULL)); 137206977982Sstefanozampini PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatProductSetFromOptions_mpiaijcusparse_hypre_C", NULL)); 13739566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatHYPRESetPreallocation_C", NULL)); 13749566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatHYPREGetParCSR_C", NULL)); 13755fbaff96SJunchao Zhang PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatSetPreallocationCOO_C", NULL)); 13765fbaff96SJunchao Zhang PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatSetValuesCOO_C", NULL)); 13779566063dSJacob Faibussowitsch PetscCall(PetscFree(A->data)); 13783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 137963c07aadSStefano Zampini } 138063c07aadSStefano Zampini 1381d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetUp_HYPRE(Mat A) 1382d71ae5a4SJacob Faibussowitsch { 13834ec6421dSstefano_zampini PetscFunctionBegin; 138406977982Sstefanozampini if (!A->preallocated) PetscCall(MatHYPRESetPreallocation(A, PETSC_DEFAULT, NULL, PETSC_DEFAULT, NULL)); 13853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13864ec6421dSstefano_zampini } 13874ec6421dSstefano_zampini 13886ea7df73SStefano Zampini //TODO FIX hypre_CSRMatrixMatvecOutOfPlace 13896ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 1390d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatBindToCPU_HYPRE(Mat A, PetscBool bind) 1391d71ae5a4SJacob Faibussowitsch { 13926ea7df73SStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 13936ea7df73SStefano Zampini HYPRE_MemoryLocation hmem = bind ? HYPRE_MEMORY_HOST : HYPRE_MEMORY_DEVICE; 13946ea7df73SStefano Zampini 13956ea7df73SStefano Zampini PetscFunctionBegin; 13966ea7df73SStefano Zampini A->boundtocpu = bind; 13975fbaff96SJunchao Zhang if (hA->ij && hypre_IJMatrixAssembleFlag(hA->ij) && hmem != hypre_IJMatrixMemoryLocation(hA->ij)) { 13986ea7df73SStefano Zampini hypre_ParCSRMatrix *parcsr; 1399792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hA->ij, (void **)&parcsr); 1400792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixMigrate, parcsr, hmem); 14016ea7df73SStefano Zampini } 14029566063dSJacob Faibussowitsch if (hA->x) PetscCall(VecHYPRE_IJBindToCPU(hA->x, bind)); 14039566063dSJacob Faibussowitsch if (hA->b) PetscCall(VecHYPRE_IJBindToCPU(hA->b, bind)); 14043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 14056ea7df73SStefano Zampini } 14066ea7df73SStefano Zampini #endif 14076ea7df73SStefano Zampini 1408d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyEnd_HYPRE(Mat A, MatAssemblyType mode) 1409d71ae5a4SJacob Faibussowitsch { 141063c07aadSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 1411c69f721fSFande Kong PetscMPIInt n; 1412c69f721fSFande Kong PetscInt i, j, rstart, ncols, flg; 1413c69f721fSFande Kong PetscInt *row, *col; 1414c69f721fSFande Kong PetscScalar *val; 141563c07aadSStefano Zampini 141663c07aadSStefano Zampini PetscFunctionBegin; 141708401ef6SPierre Jolivet PetscCheck(mode != MAT_FLUSH_ASSEMBLY, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "MAT_FLUSH_ASSEMBLY currently not supported with MATHYPRE"); 1418c69f721fSFande Kong 1419c69f721fSFande Kong if (!A->nooffprocentries) { 1420c69f721fSFande Kong while (1) { 14219566063dSJacob Faibussowitsch PetscCall(MatStashScatterGetMesg_Private(&A->stash, &n, &row, &col, &val, &flg)); 1422c69f721fSFande Kong if (!flg) break; 1423c69f721fSFande Kong 1424c69f721fSFande Kong for (i = 0; i < n;) { 1425c69f721fSFande Kong /* Now identify the consecutive vals belonging to the same row */ 1426c69f721fSFande Kong for (j = i, rstart = row[j]; j < n; j++) { 1427c69f721fSFande Kong if (row[j] != rstart) break; 1428c69f721fSFande Kong } 1429c69f721fSFande Kong if (j < n) ncols = j - i; 1430c69f721fSFande Kong else ncols = n - i; 1431c69f721fSFande Kong /* Now assemble all these values with a single function call */ 14329566063dSJacob Faibussowitsch PetscCall(MatSetValues_HYPRE(A, 1, row + i, ncols, col + i, val + i, A->insertmode)); 1433c69f721fSFande Kong 1434c69f721fSFande Kong i = j; 1435c69f721fSFande Kong } 1436c69f721fSFande Kong } 14379566063dSJacob Faibussowitsch PetscCall(MatStashScatterEnd_Private(&A->stash)); 1438c69f721fSFande Kong } 1439c69f721fSFande Kong 1440792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixAssemble, hA->ij); 1441336664bdSPierre Jolivet /* The assembly routine destroys the aux_matrix, we recreate it here by calling HYPRE_IJMatrixInitialize */ 1442336664bdSPierre 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 */ 1443651b1cf9SStefano Zampini if (!A->sortedfull) { 1444af1cf968SStefano Zampini hypre_AuxParCSRMatrix *aux_matrix; 1445af1cf968SStefano Zampini 1446af1cf968SStefano Zampini /* call destroy just to make sure we do not leak anything */ 1447af1cf968SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix *)hypre_IJMatrixTranslator(hA->ij); 1448792fecdfSBarry Smith PetscCallExternal(hypre_AuxParCSRMatrixDestroy, aux_matrix); 1449af1cf968SStefano Zampini hypre_IJMatrixTranslator(hA->ij) = NULL; 1450af1cf968SStefano Zampini 1451af1cf968SStefano Zampini /* Initialize with assembled flag -> it only recreates the aux_par_matrix */ 1452792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixInitialize, hA->ij); 1453af1cf968SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix *)hypre_IJMatrixTranslator(hA->ij); 14546ea7df73SStefano Zampini if (aux_matrix) { 1455af1cf968SStefano Zampini hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 1; /* see comment in MatHYPRESetPreallocation_HYPRE */ 145622235d61SPierre Jolivet #if PETSC_PKG_HYPRE_VERSION_LT(2, 19, 0) 1457792fecdfSBarry Smith PetscCallExternal(hypre_AuxParCSRMatrixInitialize, aux_matrix); 145822235d61SPierre Jolivet #else 1459792fecdfSBarry Smith PetscCallExternal(hypre_AuxParCSRMatrixInitialize_v2, aux_matrix, HYPRE_MEMORY_HOST); 146022235d61SPierre Jolivet #endif 1461af1cf968SStefano Zampini } 14626ea7df73SStefano Zampini } 14636ea7df73SStefano Zampini { 14646ea7df73SStefano Zampini hypre_ParCSRMatrix *parcsr; 14656ea7df73SStefano Zampini 1466792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hA->ij, (void **)&parcsr); 1467792fecdfSBarry Smith if (!hypre_ParCSRMatrixCommPkg(parcsr)) PetscCallExternal(hypre_MatvecCommPkgCreate, parcsr); 14686ea7df73SStefano Zampini } 14699566063dSJacob Faibussowitsch if (!hA->x) PetscCall(VecHYPRE_IJVectorCreate(A->cmap, &hA->x)); 14709566063dSJacob Faibussowitsch if (!hA->b) PetscCall(VecHYPRE_IJVectorCreate(A->rmap, &hA->b)); 14716ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 14729566063dSJacob Faibussowitsch PetscCall(MatBindToCPU_HYPRE(A, A->boundtocpu)); 14736ea7df73SStefano Zampini #endif 14743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 147563c07aadSStefano Zampini } 147663c07aadSStefano Zampini 1477d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetArray_HYPRE(Mat A, PetscInt size, void **array) 1478d71ae5a4SJacob Faibussowitsch { 1479c69f721fSFande Kong Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 1480c69f721fSFande Kong 1481c69f721fSFande Kong PetscFunctionBegin; 1482651b1cf9SStefano Zampini PetscCheck(hA->array_available, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Temporary space is in use"); 1483c69f721fSFande Kong 1484651b1cf9SStefano Zampini if (hA->array_size >= size) { 148539accc25SStefano Zampini *array = hA->array; 148639accc25SStefano Zampini } else { 14879566063dSJacob Faibussowitsch PetscCall(PetscFree(hA->array)); 1488651b1cf9SStefano Zampini hA->array_size = size; 1489651b1cf9SStefano Zampini PetscCall(PetscMalloc(hA->array_size, &hA->array)); 1490c69f721fSFande Kong *array = hA->array; 1491c69f721fSFande Kong } 1492c69f721fSFande Kong 1493651b1cf9SStefano Zampini hA->array_available = PETSC_FALSE; 14943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1495c69f721fSFande Kong } 1496c69f721fSFande Kong 1497d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRestoreArray_HYPRE(Mat A, void **array) 1498d71ae5a4SJacob Faibussowitsch { 1499c69f721fSFande Kong Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 1500c69f721fSFande Kong 1501c69f721fSFande Kong PetscFunctionBegin; 1502c69f721fSFande Kong *array = NULL; 1503651b1cf9SStefano Zampini hA->array_available = PETSC_TRUE; 15043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1505c69f721fSFande Kong } 1506c69f721fSFande Kong 1507d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetValues_HYPRE(Mat A, PetscInt nr, const PetscInt rows[], PetscInt nc, const PetscInt cols[], const PetscScalar v[], InsertMode ins) 1508d71ae5a4SJacob Faibussowitsch { 1509d975228cSstefano_zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 1510d975228cSstefano_zampini PetscScalar *vals = (PetscScalar *)v; 151139accc25SStefano Zampini HYPRE_Complex *sscr; 1512c69f721fSFande Kong PetscInt *cscr[2]; 1513c69f721fSFande Kong PetscInt i, nzc; 1514651b1cf9SStefano Zampini PetscInt rst = A->rmap->rstart, ren = A->rmap->rend; 151508defe43SFande Kong void *array = NULL; 1516d975228cSstefano_zampini 1517d975228cSstefano_zampini PetscFunctionBegin; 15189566063dSJacob Faibussowitsch PetscCall(MatGetArray_HYPRE(A, sizeof(PetscInt) * (2 * nc) + sizeof(HYPRE_Complex) * nc * nr, &array)); 1519c69f721fSFande Kong cscr[0] = (PetscInt *)array; 1520c69f721fSFande Kong cscr[1] = ((PetscInt *)array) + nc; 152139accc25SStefano Zampini sscr = (HYPRE_Complex *)(((PetscInt *)array) + nc * 2); 1522d975228cSstefano_zampini for (i = 0, nzc = 0; i < nc; i++) { 1523d975228cSstefano_zampini if (cols[i] >= 0) { 1524d975228cSstefano_zampini cscr[0][nzc] = cols[i]; 1525d975228cSstefano_zampini cscr[1][nzc++] = i; 1526d975228cSstefano_zampini } 1527d975228cSstefano_zampini } 1528c69f721fSFande Kong if (!nzc) { 15299566063dSJacob Faibussowitsch PetscCall(MatRestoreArray_HYPRE(A, &array)); 15303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1531c69f721fSFande Kong } 1532d975228cSstefano_zampini 15336ea7df73SStefano Zampini #if 0 //defined(PETSC_HAVE_HYPRE_DEVICE) 15346ea7df73SStefano Zampini if (HYPRE_MEMORY_HOST != hypre_IJMatrixMemoryLocation(hA->ij)) { 15356ea7df73SStefano Zampini hypre_ParCSRMatrix *parcsr; 15366ea7df73SStefano Zampini 1537792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hA->ij,(void**)&parcsr); 1538792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixMigrate,parcsr, HYPRE_MEMORY_HOST); 15396ea7df73SStefano Zampini } 15406ea7df73SStefano Zampini #endif 15416ea7df73SStefano Zampini 1542d975228cSstefano_zampini if (ins == ADD_VALUES) { 1543d975228cSstefano_zampini for (i = 0; i < nr; i++) { 15446ea7df73SStefano Zampini if (rows[i] >= 0) { 1545d975228cSstefano_zampini PetscInt j; 15462cf14000SStefano Zampini HYPRE_Int hnc = (HYPRE_Int)nzc; 15472cf14000SStefano Zampini 1548651b1cf9SStefano Zampini if (!nzc) continue; 1549651b1cf9SStefano Zampini /* nonlocal values */ 1550651b1cf9SStefano Zampini if (rows[i] < rst || rows[i] >= ren) { 1551651b1cf9SStefano 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]); 1552651b1cf9SStefano Zampini if (hA->donotstash) continue; 1553651b1cf9SStefano Zampini } 1554aed4548fSBarry 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]); 15559566063dSJacob Faibussowitsch for (j = 0; j < nzc; j++) PetscCall(PetscHYPREScalarCast(vals[cscr[1][j]], &sscr[j])); 1556792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixAddToValues, hA->ij, 1, &hnc, (HYPRE_BigInt *)(rows + i), (HYPRE_BigInt *)cscr[0], sscr); 1557d975228cSstefano_zampini } 1558d975228cSstefano_zampini vals += nc; 1559d975228cSstefano_zampini } 1560d975228cSstefano_zampini } else { /* INSERT_VALUES */ 1561d975228cSstefano_zampini for (i = 0; i < nr; i++) { 15626ea7df73SStefano Zampini if (rows[i] >= 0) { 1563d975228cSstefano_zampini PetscInt j; 15642cf14000SStefano Zampini HYPRE_Int hnc = (HYPRE_Int)nzc; 15652cf14000SStefano Zampini 1566651b1cf9SStefano Zampini if (!nzc) continue; 1567aed4548fSBarry 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]); 15689566063dSJacob Faibussowitsch for (j = 0; j < nzc; j++) PetscCall(PetscHYPREScalarCast(vals[cscr[1][j]], &sscr[j])); 1569c69f721fSFande Kong /* nonlocal values */ 1570651b1cf9SStefano Zampini if (rows[i] < rst || rows[i] >= ren) { 1571651b1cf9SStefano 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]); 1572651b1cf9SStefano Zampini if (!hA->donotstash) PetscCall(MatStashValuesRow_Private(&A->stash, rows[i], nzc, cscr[0], (PetscScalar *)sscr, PETSC_FALSE)); 1573651b1cf9SStefano Zampini } 1574c69f721fSFande Kong /* local values */ 1575651b1cf9SStefano Zampini else 1576651b1cf9SStefano Zampini PetscCallExternal(HYPRE_IJMatrixSetValues, hA->ij, 1, &hnc, (HYPRE_BigInt *)(rows + i), (HYPRE_BigInt *)cscr[0], sscr); 1577d975228cSstefano_zampini } 1578d975228cSstefano_zampini vals += nc; 1579d975228cSstefano_zampini } 1580d975228cSstefano_zampini } 1581c69f721fSFande Kong 15829566063dSJacob Faibussowitsch PetscCall(MatRestoreArray_HYPRE(A, &array)); 15833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1584d975228cSstefano_zampini } 1585d975228cSstefano_zampini 1586d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatHYPRESetPreallocation_HYPRE(Mat A, PetscInt dnz, const PetscInt dnnz[], PetscInt onz, const PetscInt onnz[]) 1587d71ae5a4SJacob Faibussowitsch { 1588d975228cSstefano_zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 15897d968826Sstefano_zampini HYPRE_Int *hdnnz, *honnz; 159006a29025Sstefano_zampini PetscInt i, rs, re, cs, ce, bs; 1591d975228cSstefano_zampini PetscMPIInt size; 1592d975228cSstefano_zampini 1593d975228cSstefano_zampini PetscFunctionBegin; 15949566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 15959566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 1596d975228cSstefano_zampini rs = A->rmap->rstart; 1597d975228cSstefano_zampini re = A->rmap->rend; 1598d975228cSstefano_zampini cs = A->cmap->rstart; 1599d975228cSstefano_zampini ce = A->cmap->rend; 1600d975228cSstefano_zampini if (!hA->ij) { 1601792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixCreate, hA->comm, rs, re - 1, cs, ce - 1, &hA->ij); 1602792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixSetObjectType, hA->ij, HYPRE_PARCSR); 1603d975228cSstefano_zampini } else { 16042cf14000SStefano Zampini HYPRE_BigInt hrs, hre, hcs, hce; 1605792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetLocalRange, hA->ij, &hrs, &hre, &hcs, &hce); 1606aed4548fSBarry 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); 1607aed4548fSBarry 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); 1608d975228cSstefano_zampini } 160906977982Sstefanozampini PetscCall(MatHYPRE_DestroyCOOMat(A)); 16109566063dSJacob Faibussowitsch PetscCall(MatGetBlockSize(A, &bs)); 161106a29025Sstefano_zampini if (dnz == PETSC_DEFAULT || dnz == PETSC_DECIDE) dnz = 10 * bs; 161206a29025Sstefano_zampini if (onz == PETSC_DEFAULT || onz == PETSC_DECIDE) onz = 10 * bs; 161306a29025Sstefano_zampini 1614d975228cSstefano_zampini if (!dnnz) { 16159566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->rmap->n, &hdnnz)); 1616d975228cSstefano_zampini for (i = 0; i < A->rmap->n; i++) hdnnz[i] = dnz; 1617d975228cSstefano_zampini } else { 16187d968826Sstefano_zampini hdnnz = (HYPRE_Int *)dnnz; 1619d975228cSstefano_zampini } 16209566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A), &size)); 1621d975228cSstefano_zampini if (size > 1) { 1622ddbeb582SStefano Zampini hypre_AuxParCSRMatrix *aux_matrix; 1623d975228cSstefano_zampini if (!onnz) { 16249566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->rmap->n, &honnz)); 1625d975228cSstefano_zampini for (i = 0; i < A->rmap->n; i++) honnz[i] = onz; 162622235d61SPierre Jolivet } else honnz = (HYPRE_Int *)onnz; 1627ddbeb582SStefano Zampini /* SetDiagOffdSizes sets hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 0, since it seems 1628ddbeb582SStefano Zampini they assume the user will input the entire row values, properly sorted 1629336664bdSPierre Jolivet In PETSc, we don't make such an assumption and set this flag to 1, 1630336664bdSPierre Jolivet unless the option MAT_SORTED_FULL is set to true. 1631ddbeb582SStefano Zampini Also, to avoid possible memory leaks, we destroy and recreate the translator 1632ddbeb582SStefano Zampini This has to be done here, as HYPRE_IJMatrixInitialize will properly initialize 1633ddbeb582SStefano Zampini the IJ matrix for us */ 1634ddbeb582SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix *)hypre_IJMatrixTranslator(hA->ij); 1635ddbeb582SStefano Zampini hypre_AuxParCSRMatrixDestroy(aux_matrix); 1636ddbeb582SStefano Zampini hypre_IJMatrixTranslator(hA->ij) = NULL; 1637792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixSetDiagOffdSizes, hA->ij, hdnnz, honnz); 1638ddbeb582SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix *)hypre_IJMatrixTranslator(hA->ij); 1639651b1cf9SStefano Zampini hypre_AuxParCSRMatrixNeedAux(aux_matrix) = !A->sortedfull; 1640d975228cSstefano_zampini } else { 1641d975228cSstefano_zampini honnz = NULL; 1642792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixSetRowSizes, hA->ij, hdnnz); 1643d975228cSstefano_zampini } 1644ddbeb582SStefano Zampini 1645af1cf968SStefano Zampini /* reset assembled flag and call the initialize method */ 1646af1cf968SStefano Zampini hypre_IJMatrixAssembleFlag(hA->ij) = 0; 16476ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_LT(2, 19, 0) 1648792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixInitialize, hA->ij); 16496ea7df73SStefano Zampini #else 1650792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixInitialize_v2, hA->ij, HYPRE_MEMORY_HOST); 16516ea7df73SStefano Zampini #endif 165248a46eb9SPierre Jolivet if (!dnnz) PetscCall(PetscFree(hdnnz)); 165348a46eb9SPierre Jolivet if (!onnz && honnz) PetscCall(PetscFree(honnz)); 1654af1cf968SStefano Zampini /* Match AIJ logic */ 165506a29025Sstefano_zampini A->preallocated = PETSC_TRUE; 1656af1cf968SStefano Zampini A->assembled = PETSC_FALSE; 16573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1658d975228cSstefano_zampini } 1659d975228cSstefano_zampini 1660d975228cSstefano_zampini /*@C 1661d975228cSstefano_zampini MatHYPRESetPreallocation - Preallocates memory for a sparse parallel matrix in HYPRE IJ format 1662d975228cSstefano_zampini 1663c3339decSBarry Smith Collective 1664d975228cSstefano_zampini 1665d975228cSstefano_zampini Input Parameters: 1666d975228cSstefano_zampini + A - the matrix 1667d975228cSstefano_zampini . dnz - number of nonzeros per row in DIAGONAL portion of local submatrix 1668d975228cSstefano_zampini (same value is used for all local rows) 1669d975228cSstefano_zampini . dnnz - array containing the number of nonzeros in the various rows of the 1670d975228cSstefano_zampini DIAGONAL portion of the local submatrix (possibly different for each row) 16712ef1f0ffSBarry Smith or `NULL` (`PETSC_NULL_INTEGER` in Fortran), if `d_nz` is used to specify the nonzero structure. 16722ef1f0ffSBarry Smith The size of this array is equal to the number of local rows, i.e `m`. 1673d975228cSstefano_zampini For matrices that will be factored, you must leave room for (and set) 1674d975228cSstefano_zampini the diagonal entry even if it is zero. 1675d975228cSstefano_zampini . onz - number of nonzeros per row in the OFF-DIAGONAL portion of local 1676d975228cSstefano_zampini submatrix (same value is used for all local rows). 1677d975228cSstefano_zampini - onnz - array containing the number of nonzeros in the various rows of the 1678d975228cSstefano_zampini OFF-DIAGONAL portion of the local submatrix (possibly different for 16792ef1f0ffSBarry Smith each row) or `NULL` (`PETSC_NULL_INTEGER` in Fortran), if `o_nz` is used to specify the nonzero 1680d975228cSstefano_zampini structure. The size of this array is equal to the number 16812ef1f0ffSBarry Smith of local rows, i.e `m`. 1682d975228cSstefano_zampini 16832fe279fdSBarry Smith Level: intermediate 16842fe279fdSBarry Smith 168511a5261eSBarry Smith Note: 16862ef1f0ffSBarry Smith If the *nnz parameter is given then the *nz parameter is ignored; for sequential matrices, `onz` and `onnz` are ignored. 1687d975228cSstefano_zampini 16881cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatCreate()`, `MatMPIAIJSetPreallocation()`, `MATHYPRE`, `MATAIJ` 1689d975228cSstefano_zampini @*/ 1690d71ae5a4SJacob Faibussowitsch PetscErrorCode MatHYPRESetPreallocation(Mat A, PetscInt dnz, const PetscInt dnnz[], PetscInt onz, const PetscInt onnz[]) 1691d71ae5a4SJacob Faibussowitsch { 1692d975228cSstefano_zampini PetscFunctionBegin; 1693d975228cSstefano_zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 1694d975228cSstefano_zampini PetscValidType(A, 1); 1695cac4c232SBarry Smith PetscTryMethod(A, "MatHYPRESetPreallocation_C", (Mat, PetscInt, const PetscInt[], PetscInt, const PetscInt[]), (A, dnz, dnnz, onz, onnz)); 16963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1697d975228cSstefano_zampini } 1698d975228cSstefano_zampini 169920f4b53cSBarry Smith /*@C 17002ef1f0ffSBarry Smith MatCreateFromParCSR - Creates a `Mat` from a `hypre_ParCSRMatrix` 1701225daaf8SStefano Zampini 1702225daaf8SStefano Zampini Collective 1703225daaf8SStefano Zampini 1704225daaf8SStefano Zampini Input Parameters: 17052ef1f0ffSBarry Smith + parcsr - the pointer to the `hypre_ParCSRMatrix` 17062ef1f0ffSBarry Smith . mtype - matrix type to be created. Currently `MATAIJ`, `MATIS` and `MATHYPRE` are supported. 170720f4b53cSBarry Smith - copymode - PETSc copying options, see `PetscCopyMode` 1708225daaf8SStefano Zampini 1709225daaf8SStefano Zampini Output Parameter: 1710225daaf8SStefano Zampini . A - the matrix 1711225daaf8SStefano Zampini 1712225daaf8SStefano Zampini Level: intermediate 1713225daaf8SStefano Zampini 17141cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatHYPRE`, `PetscCopyMode` 171520f4b53cSBarry Smith @*/ 1716d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatCreateFromParCSR(hypre_ParCSRMatrix *parcsr, MatType mtype, PetscCopyMode copymode, Mat *A) 1717d71ae5a4SJacob Faibussowitsch { 1718225daaf8SStefano Zampini Mat T; 1719978814f1SStefano Zampini Mat_HYPRE *hA; 1720978814f1SStefano Zampini MPI_Comm comm; 1721978814f1SStefano Zampini PetscInt rstart, rend, cstart, cend, M, N; 1722d248a85cSRichard Tran Mills PetscBool isseqaij, isseqaijmkl, ismpiaij, isaij, ishyp, isis; 1723978814f1SStefano Zampini 1724978814f1SStefano Zampini PetscFunctionBegin; 1725978814f1SStefano Zampini comm = hypre_ParCSRMatrixComm(parcsr); 17269566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(mtype, MATSEQAIJ, &isseqaij)); 17279566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(mtype, MATSEQAIJMKL, &isseqaijmkl)); 17289566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(mtype, MATMPIAIJ, &ismpiaij)); 17299566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(mtype, MATAIJ, &isaij)); 17309566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(mtype, MATHYPRE, &ishyp)); 17319566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(mtype, MATIS, &isis)); 1732d248a85cSRichard Tran Mills isaij = (PetscBool)(isseqaij || isseqaijmkl || ismpiaij || isaij); 17336ea7df73SStefano Zampini /* TODO */ 1734aed4548fSBarry 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); 1735978814f1SStefano Zampini /* access ParCSRMatrix */ 1736978814f1SStefano Zampini rstart = hypre_ParCSRMatrixFirstRowIndex(parcsr); 1737978814f1SStefano Zampini rend = hypre_ParCSRMatrixLastRowIndex(parcsr); 1738978814f1SStefano Zampini cstart = hypre_ParCSRMatrixFirstColDiag(parcsr); 1739978814f1SStefano Zampini cend = hypre_ParCSRMatrixLastColDiag(parcsr); 1740978814f1SStefano Zampini M = hypre_ParCSRMatrixGlobalNumRows(parcsr); 1741978814f1SStefano Zampini N = hypre_ParCSRMatrixGlobalNumCols(parcsr); 1742978814f1SStefano Zampini 1743fa92c42cSstefano_zampini /* fix for empty local rows/columns */ 1744fa92c42cSstefano_zampini if (rend < rstart) rend = rstart; 1745fa92c42cSstefano_zampini if (cend < cstart) cend = cstart; 1746fa92c42cSstefano_zampini 1747e6471dc9SStefano Zampini /* PETSc convention */ 1748e6471dc9SStefano Zampini rend++; 1749e6471dc9SStefano Zampini cend++; 1750e6471dc9SStefano Zampini rend = PetscMin(rend, M); 1751e6471dc9SStefano Zampini cend = PetscMin(cend, N); 1752e6471dc9SStefano Zampini 1753978814f1SStefano Zampini /* create PETSc matrix with MatHYPRE */ 17549566063dSJacob Faibussowitsch PetscCall(MatCreate(comm, &T)); 17559566063dSJacob Faibussowitsch PetscCall(MatSetSizes(T, rend - rstart, cend - cstart, M, N)); 17569566063dSJacob Faibussowitsch PetscCall(MatSetType(T, MATHYPRE)); 1757f4f49eeaSPierre Jolivet hA = (Mat_HYPRE *)T->data; 1758978814f1SStefano Zampini 1759978814f1SStefano Zampini /* create HYPRE_IJMatrix */ 1760792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixCreate, hA->comm, rstart, rend - 1, cstart, cend - 1, &hA->ij); 1761792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixSetObjectType, hA->ij, HYPRE_PARCSR); 176245b8d346SStefano Zampini 176345b8d346SStefano Zampini /* create new ParCSR object if needed */ 176445b8d346SStefano Zampini if (ishyp && copymode == PETSC_COPY_VALUES) { 176545b8d346SStefano Zampini hypre_ParCSRMatrix *new_parcsr; 17666ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_LT(2, 18, 0) 176745b8d346SStefano Zampini hypre_CSRMatrix *hdiag, *hoffd, *ndiag, *noffd; 176845b8d346SStefano Zampini 17690e6427aaSSatish Balay new_parcsr = hypre_ParCSRMatrixClone(parcsr, 0); 177045b8d346SStefano Zampini hdiag = hypre_ParCSRMatrixDiag(parcsr); 177145b8d346SStefano Zampini hoffd = hypre_ParCSRMatrixOffd(parcsr); 177245b8d346SStefano Zampini ndiag = hypre_ParCSRMatrixDiag(new_parcsr); 177345b8d346SStefano Zampini noffd = hypre_ParCSRMatrixOffd(new_parcsr); 17749566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(hypre_CSRMatrixData(ndiag), hypre_CSRMatrixData(hdiag), hypre_CSRMatrixNumNonzeros(hdiag))); 17759566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(hypre_CSRMatrixData(noffd), hypre_CSRMatrixData(hoffd), hypre_CSRMatrixNumNonzeros(hoffd))); 17766ea7df73SStefano Zampini #else 17776ea7df73SStefano Zampini new_parcsr = hypre_ParCSRMatrixClone(parcsr, 1); 17786ea7df73SStefano Zampini #endif 177945b8d346SStefano Zampini parcsr = new_parcsr; 178045b8d346SStefano Zampini copymode = PETSC_OWN_POINTER; 178145b8d346SStefano Zampini } 1782978814f1SStefano Zampini 1783978814f1SStefano Zampini /* set ParCSR object */ 1784978814f1SStefano Zampini hypre_IJMatrixObject(hA->ij) = parcsr; 17854ec6421dSstefano_zampini T->preallocated = PETSC_TRUE; 1786978814f1SStefano Zampini 1787978814f1SStefano Zampini /* set assembled flag */ 1788978814f1SStefano Zampini hypre_IJMatrixAssembleFlag(hA->ij) = 1; 17896ea7df73SStefano Zampini #if 0 1790792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixInitialize,hA->ij); 17916ea7df73SStefano Zampini #endif 1792225daaf8SStefano Zampini if (ishyp) { 17936d2a658fSstefano_zampini PetscMPIInt myid = 0; 17946d2a658fSstefano_zampini 17956d2a658fSstefano_zampini /* make sure we always have row_starts and col_starts available */ 179648a46eb9SPierre Jolivet if (HYPRE_AssumedPartitionCheck()) PetscCallMPI(MPI_Comm_rank(comm, &myid)); 1797a1d2239cSSatish Balay #if defined(hypre_ParCSRMatrixOwnsRowStarts) 17986d2a658fSstefano_zampini if (!hypre_ParCSRMatrixOwnsColStarts(parcsr)) { 17996d2a658fSstefano_zampini PetscLayout map; 18006d2a658fSstefano_zampini 18019566063dSJacob Faibussowitsch PetscCall(MatGetLayouts(T, NULL, &map)); 18029566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(map)); 18032cf14000SStefano Zampini hypre_ParCSRMatrixColStarts(parcsr) = (HYPRE_BigInt *)(map->range + myid); 18046d2a658fSstefano_zampini } 18056d2a658fSstefano_zampini if (!hypre_ParCSRMatrixOwnsRowStarts(parcsr)) { 18066d2a658fSstefano_zampini PetscLayout map; 18076d2a658fSstefano_zampini 18089566063dSJacob Faibussowitsch PetscCall(MatGetLayouts(T, &map, NULL)); 18099566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(map)); 18102cf14000SStefano Zampini hypre_ParCSRMatrixRowStarts(parcsr) = (HYPRE_BigInt *)(map->range + myid); 18116d2a658fSstefano_zampini } 1812a1d2239cSSatish Balay #endif 1813978814f1SStefano Zampini /* prevent from freeing the pointer */ 1814978814f1SStefano Zampini if (copymode == PETSC_USE_POINTER) hA->inner_free = PETSC_FALSE; 1815225daaf8SStefano Zampini *A = T; 18169566063dSJacob Faibussowitsch PetscCall(MatSetOption(*A, MAT_SORTED_FULL, PETSC_TRUE)); 18179566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(*A, MAT_FINAL_ASSEMBLY)); 18189566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(*A, MAT_FINAL_ASSEMBLY)); 1819bb4689ddSStefano Zampini } else if (isaij) { 1820bb4689ddSStefano Zampini if (copymode != PETSC_OWN_POINTER) { 1821225daaf8SStefano Zampini /* prevent from freeing the pointer */ 1822225daaf8SStefano Zampini hA->inner_free = PETSC_FALSE; 18239566063dSJacob Faibussowitsch PetscCall(MatConvert_HYPRE_AIJ(T, MATAIJ, MAT_INITIAL_MATRIX, A)); 18249566063dSJacob Faibussowitsch PetscCall(MatDestroy(&T)); 1825225daaf8SStefano Zampini } else { /* AIJ return type with PETSC_OWN_POINTER */ 18269566063dSJacob Faibussowitsch PetscCall(MatConvert_HYPRE_AIJ(T, MATAIJ, MAT_INPLACE_MATRIX, &T)); 1827225daaf8SStefano Zampini *A = T; 1828225daaf8SStefano Zampini } 1829bb4689ddSStefano Zampini } else if (isis) { 18309566063dSJacob Faibussowitsch PetscCall(MatConvert_HYPRE_IS(T, MATIS, MAT_INITIAL_MATRIX, A)); 18318cfe8d00SStefano Zampini if (copymode != PETSC_OWN_POINTER) hA->inner_free = PETSC_FALSE; 18329566063dSJacob Faibussowitsch PetscCall(MatDestroy(&T)); 1833bb4689ddSStefano Zampini } 18343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1835978814f1SStefano Zampini } 1836978814f1SStefano Zampini 1837d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatHYPREGetParCSR_HYPRE(Mat A, hypre_ParCSRMatrix **parcsr) 1838d71ae5a4SJacob Faibussowitsch { 1839dd9c0a25Sstefano_zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 1840dd9c0a25Sstefano_zampini HYPRE_Int type; 1841dd9c0a25Sstefano_zampini 1842dd9c0a25Sstefano_zampini PetscFunctionBegin; 184328b400f6SJacob Faibussowitsch PetscCheck(hA->ij, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "HYPRE_IJMatrix not present"); 1844792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObjectType, hA->ij, &type); 184508401ef6SPierre Jolivet PetscCheck(type == HYPRE_PARCSR, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "HYPRE_IJMatrix is not of type HYPRE_PARCSR"); 1846792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hA->ij, (void **)parcsr); 18473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1848dd9c0a25Sstefano_zampini } 1849dd9c0a25Sstefano_zampini 185020f4b53cSBarry Smith /*@C 1851dd9c0a25Sstefano_zampini MatHYPREGetParCSR - Gets the pointer to the ParCSR matrix 1852dd9c0a25Sstefano_zampini 18532ef1f0ffSBarry Smith Not Collective 1854dd9c0a25Sstefano_zampini 185520f4b53cSBarry Smith Input Parameter: 185620f4b53cSBarry Smith . A - the `MATHYPRE` object 1857dd9c0a25Sstefano_zampini 1858dd9c0a25Sstefano_zampini Output Parameter: 18592ef1f0ffSBarry Smith . parcsr - the pointer to the `hypre_ParCSRMatrix` 1860dd9c0a25Sstefano_zampini 1861dd9c0a25Sstefano_zampini Level: intermediate 1862dd9c0a25Sstefano_zampini 18631cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatHYPRE`, `PetscCopyMode` 186420f4b53cSBarry Smith @*/ 1865d71ae5a4SJacob Faibussowitsch PetscErrorCode MatHYPREGetParCSR(Mat A, hypre_ParCSRMatrix **parcsr) 1866d71ae5a4SJacob Faibussowitsch { 1867dd9c0a25Sstefano_zampini PetscFunctionBegin; 1868dd9c0a25Sstefano_zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 1869dd9c0a25Sstefano_zampini PetscValidType(A, 1); 1870cac4c232SBarry Smith PetscUseMethod(A, "MatHYPREGetParCSR_C", (Mat, hypre_ParCSRMatrix **), (A, parcsr)); 18713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1872dd9c0a25Sstefano_zampini } 1873dd9c0a25Sstefano_zampini 1874d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMissingDiagonal_HYPRE(Mat A, PetscBool *missing, PetscInt *dd) 1875d71ae5a4SJacob Faibussowitsch { 187668ec7858SStefano Zampini hypre_ParCSRMatrix *parcsr; 187768ec7858SStefano Zampini hypre_CSRMatrix *ha; 187868ec7858SStefano Zampini PetscInt rst; 187968ec7858SStefano Zampini 188068ec7858SStefano Zampini PetscFunctionBegin; 188108401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not implemented with non-square diagonal blocks"); 18829566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(A, &rst, NULL)); 18839566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(A, &parcsr)); 188468ec7858SStefano Zampini if (missing) *missing = PETSC_FALSE; 188568ec7858SStefano Zampini if (dd) *dd = -1; 188668ec7858SStefano Zampini ha = hypre_ParCSRMatrixDiag(parcsr); 188768ec7858SStefano Zampini if (ha) { 188868299464SStefano Zampini PetscInt size, i; 188968299464SStefano Zampini HYPRE_Int *ii, *jj; 189068ec7858SStefano Zampini 189168ec7858SStefano Zampini size = hypre_CSRMatrixNumRows(ha); 189268ec7858SStefano Zampini ii = hypre_CSRMatrixI(ha); 189368ec7858SStefano Zampini jj = hypre_CSRMatrixJ(ha); 189468ec7858SStefano Zampini for (i = 0; i < size; i++) { 189568ec7858SStefano Zampini PetscInt j; 189668ec7858SStefano Zampini PetscBool found = PETSC_FALSE; 189768ec7858SStefano Zampini 18989371c9d4SSatish Balay for (j = ii[i]; j < ii[i + 1] && !found; j++) found = (jj[j] == i) ? PETSC_TRUE : PETSC_FALSE; 189968ec7858SStefano Zampini 190068ec7858SStefano Zampini if (!found) { 19013ba16761SJacob Faibussowitsch PetscCall(PetscInfo(A, "Matrix is missing local diagonal entry %" PetscInt_FMT "\n", i)); 190268ec7858SStefano Zampini if (missing) *missing = PETSC_TRUE; 190368ec7858SStefano Zampini if (dd) *dd = i + rst; 19043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 190568ec7858SStefano Zampini } 190668ec7858SStefano Zampini } 190768ec7858SStefano Zampini if (!size) { 19083ba16761SJacob Faibussowitsch PetscCall(PetscInfo(A, "Matrix has no diagonal entries therefore is missing diagonal\n")); 190968ec7858SStefano Zampini if (missing) *missing = PETSC_TRUE; 191068ec7858SStefano Zampini if (dd) *dd = rst; 191168ec7858SStefano Zampini } 191268ec7858SStefano Zampini } else { 19133ba16761SJacob Faibussowitsch PetscCall(PetscInfo(A, "Matrix has no diagonal entries therefore is missing diagonal\n")); 191468ec7858SStefano Zampini if (missing) *missing = PETSC_TRUE; 191568ec7858SStefano Zampini if (dd) *dd = rst; 191668ec7858SStefano Zampini } 19173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 191868ec7858SStefano Zampini } 191968ec7858SStefano Zampini 1920d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatScale_HYPRE(Mat A, PetscScalar s) 1921d71ae5a4SJacob Faibussowitsch { 192268ec7858SStefano Zampini hypre_ParCSRMatrix *parcsr; 19236ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_LT(2, 19, 0) 192468ec7858SStefano Zampini hypre_CSRMatrix *ha; 19256ea7df73SStefano Zampini #endif 192639accc25SStefano Zampini HYPRE_Complex hs; 192768ec7858SStefano Zampini 192868ec7858SStefano Zampini PetscFunctionBegin; 19299566063dSJacob Faibussowitsch PetscCall(PetscHYPREScalarCast(s, &hs)); 19309566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(A, &parcsr)); 19316ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2, 19, 0) 1932792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixScale, parcsr, hs); 19336ea7df73SStefano Zampini #else /* diagonal part */ 193468ec7858SStefano Zampini ha = hypre_ParCSRMatrixDiag(parcsr); 193568ec7858SStefano Zampini if (ha) { 193668299464SStefano Zampini PetscInt size, i; 193768299464SStefano Zampini HYPRE_Int *ii; 193839accc25SStefano Zampini HYPRE_Complex *a; 193968ec7858SStefano Zampini 194068ec7858SStefano Zampini size = hypre_CSRMatrixNumRows(ha); 194168ec7858SStefano Zampini a = hypre_CSRMatrixData(ha); 194268ec7858SStefano Zampini ii = hypre_CSRMatrixI(ha); 194339accc25SStefano Zampini for (i = 0; i < ii[size]; i++) a[i] *= hs; 194468ec7858SStefano Zampini } 19454cf0e950SBarry Smith /* off-diagonal part */ 194668ec7858SStefano Zampini ha = hypre_ParCSRMatrixOffd(parcsr); 194768ec7858SStefano Zampini if (ha) { 194868299464SStefano Zampini PetscInt size, i; 194968299464SStefano Zampini HYPRE_Int *ii; 195039accc25SStefano Zampini HYPRE_Complex *a; 195168ec7858SStefano Zampini 195268ec7858SStefano Zampini size = hypre_CSRMatrixNumRows(ha); 195368ec7858SStefano Zampini a = hypre_CSRMatrixData(ha); 195468ec7858SStefano Zampini ii = hypre_CSRMatrixI(ha); 195539accc25SStefano Zampini for (i = 0; i < ii[size]; i++) a[i] *= hs; 195668ec7858SStefano Zampini } 19576ea7df73SStefano Zampini #endif 19583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 195968ec7858SStefano Zampini } 196068ec7858SStefano Zampini 1961d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatZeroRowsColumns_HYPRE(Mat A, PetscInt numRows, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) 1962d71ae5a4SJacob Faibussowitsch { 196368ec7858SStefano Zampini hypre_ParCSRMatrix *parcsr; 196468299464SStefano Zampini HYPRE_Int *lrows; 196568299464SStefano Zampini PetscInt rst, ren, i; 196668ec7858SStefano Zampini 196768ec7858SStefano Zampini PetscFunctionBegin; 196808401ef6SPierre Jolivet PetscCheck(!x && !b, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "To be implemented"); 19699566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(A, &parcsr)); 19709566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numRows, &lrows)); 19719566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(A, &rst, &ren)); 197268ec7858SStefano Zampini for (i = 0; i < numRows; i++) { 19737a46b595SBarry Smith PetscCheck(rows[i] >= rst && rows[i] < ren, PETSC_COMM_SELF, PETSC_ERR_SUP, "Non-local rows not yet supported"); 197468ec7858SStefano Zampini lrows[i] = rows[i] - rst; 197568ec7858SStefano Zampini } 1976792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixEliminateRowsCols, parcsr, numRows, lrows); 19779566063dSJacob Faibussowitsch PetscCall(PetscFree(lrows)); 19783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 197968ec7858SStefano Zampini } 198068ec7858SStefano Zampini 1981d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatZeroEntries_HYPRE_CSRMatrix(hypre_CSRMatrix *ha) 1982d71ae5a4SJacob Faibussowitsch { 1983c69f721fSFande Kong PetscFunctionBegin; 1984c69f721fSFande Kong if (ha) { 1985c69f721fSFande Kong HYPRE_Int *ii, size; 1986c69f721fSFande Kong HYPRE_Complex *a; 1987c69f721fSFande Kong 1988c69f721fSFande Kong size = hypre_CSRMatrixNumRows(ha); 1989c69f721fSFande Kong a = hypre_CSRMatrixData(ha); 1990c69f721fSFande Kong ii = hypre_CSRMatrixI(ha); 1991c69f721fSFande Kong 19929566063dSJacob Faibussowitsch if (a) PetscCall(PetscArrayzero(a, ii[size])); 1993c69f721fSFande Kong } 19943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1995c69f721fSFande Kong } 1996c69f721fSFande Kong 199766976f2fSJacob Faibussowitsch static PetscErrorCode MatZeroEntries_HYPRE(Mat A) 1998d71ae5a4SJacob Faibussowitsch { 19996ea7df73SStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 20006ea7df73SStefano Zampini 20016ea7df73SStefano Zampini PetscFunctionBegin; 20026ea7df73SStefano Zampini if (HYPRE_MEMORY_DEVICE == hypre_IJMatrixMemoryLocation(hA->ij)) { 2003792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixSetConstantValues, hA->ij, 0.0); 20046ea7df73SStefano Zampini } else { 2005c69f721fSFande Kong hypre_ParCSRMatrix *parcsr; 2006c69f721fSFande Kong 20079566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(A, &parcsr)); 20089566063dSJacob Faibussowitsch PetscCall(MatZeroEntries_HYPRE_CSRMatrix(hypre_ParCSRMatrixDiag(parcsr))); 20099566063dSJacob Faibussowitsch PetscCall(MatZeroEntries_HYPRE_CSRMatrix(hypre_ParCSRMatrixOffd(parcsr))); 20106ea7df73SStefano Zampini } 20113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2012c69f721fSFande Kong } 2013c69f721fSFande Kong 2014d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatZeroRows_HYPRE_CSRMatrix(hypre_CSRMatrix *hA, PetscInt N, const PetscInt rows[], HYPRE_Complex diag) 2015d71ae5a4SJacob Faibussowitsch { 201639accc25SStefano Zampini PetscInt ii; 201739accc25SStefano Zampini HYPRE_Int *i, *j; 201839accc25SStefano Zampini HYPRE_Complex *a; 2019c69f721fSFande Kong 2020c69f721fSFande Kong PetscFunctionBegin; 20213ba16761SJacob Faibussowitsch if (!hA) PetscFunctionReturn(PETSC_SUCCESS); 2022c69f721fSFande Kong 202339accc25SStefano Zampini i = hypre_CSRMatrixI(hA); 202439accc25SStefano Zampini j = hypre_CSRMatrixJ(hA); 2025c69f721fSFande Kong a = hypre_CSRMatrixData(hA); 2026a32e9c99SJunchao Zhang #if defined(PETSC_HAVE_HYPRE_DEVICE) 2027a32e9c99SJunchao Zhang if (HYPRE_MEMORY_DEVICE == hypre_CSRMatrixMemoryLocation(hA)) { 2028a32e9c99SJunchao Zhang #if defined(HYPRE_USING_CUDA) 2029a32e9c99SJunchao Zhang MatZeroRows_CUDA(N, rows, i, j, a, diag); 2030a32e9c99SJunchao Zhang #elif defined(HYPRE_USING_HIP) 2031a32e9c99SJunchao Zhang MatZeroRows_HIP(N, rows, i, j, a, diag); 2032a32e9c99SJunchao Zhang #elif defined(PETSC_HAVE_KOKKOS) 2033a32e9c99SJunchao Zhang MatZeroRows_Kokkos(N, rows, i, j, a, diag); 2034a32e9c99SJunchao Zhang #else 2035a32e9c99SJunchao Zhang SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No support for MatZeroRows on a hypre matrix in this memory location"); 2036a32e9c99SJunchao Zhang #endif 2037a32e9c99SJunchao Zhang } else 2038a32e9c99SJunchao Zhang #endif 2039a32e9c99SJunchao Zhang { 2040c69f721fSFande Kong for (ii = 0; ii < N; ii++) { 204139accc25SStefano Zampini HYPRE_Int jj, ibeg, iend, irow; 204239accc25SStefano Zampini 2043c69f721fSFande Kong irow = rows[ii]; 2044c69f721fSFande Kong ibeg = i[irow]; 2045c69f721fSFande Kong iend = i[irow + 1]; 2046c69f721fSFande Kong for (jj = ibeg; jj < iend; jj++) 2047c69f721fSFande Kong if (j[jj] == irow) a[jj] = diag; 2048c69f721fSFande Kong else a[jj] = 0.0; 2049c69f721fSFande Kong } 2050a32e9c99SJunchao Zhang } 20513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2052c69f721fSFande Kong } 2053c69f721fSFande Kong 2054d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatZeroRows_HYPRE(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) 2055d71ae5a4SJacob Faibussowitsch { 2056c69f721fSFande Kong hypre_ParCSRMatrix *parcsr; 2057a32e9c99SJunchao Zhang PetscInt *lrows, len, *lrows2; 205839accc25SStefano Zampini HYPRE_Complex hdiag; 2059c69f721fSFande Kong 2060c69f721fSFande Kong PetscFunctionBegin; 206108401ef6SPierre Jolivet PetscCheck(!x && !b, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Does not support to modify the solution and the right hand size"); 20629566063dSJacob Faibussowitsch PetscCall(PetscHYPREScalarCast(diag, &hdiag)); 2063c69f721fSFande Kong /* retrieve the internal matrix */ 20649566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(A, &parcsr)); 2065c69f721fSFande Kong /* get locally owned rows */ 20669566063dSJacob Faibussowitsch PetscCall(MatZeroRowsMapLocal_Private(A, N, rows, &len, &lrows)); 2067a32e9c99SJunchao Zhang 2068a32e9c99SJunchao Zhang #if defined(PETSC_HAVE_HYPRE_DEVICE) 2069a32e9c99SJunchao Zhang if (HYPRE_MEMORY_DEVICE == hypre_CSRMatrixMemoryLocation(hypre_ParCSRMatrixDiag(parcsr))) { 2070a32e9c99SJunchao Zhang Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 2071a32e9c99SJunchao Zhang PetscInt m; 2072a32e9c99SJunchao Zhang PetscCall(MatGetLocalSize(A, &m, NULL)); 2073a32e9c99SJunchao Zhang if (!hA->rows_d) { 2074a32e9c99SJunchao Zhang hA->rows_d = hypre_TAlloc(PetscInt, m, HYPRE_MEMORY_DEVICE); 2075a32e9c99SJunchao Zhang if (m) PetscCheck(hA->rows_d, PETSC_COMM_SELF, PETSC_ERR_MEM, "HYPRE_TAlloc failed"); 2076a32e9c99SJunchao Zhang } 2077a32e9c99SJunchao Zhang PetscCheck(len <= m, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Too many rows in rows[]"); 2078a32e9c99SJunchao Zhang PetscStackCallExternalVoid("hypre_Memcpy", hypre_Memcpy(hA->rows_d, lrows, sizeof(PetscInt) * len, HYPRE_MEMORY_DEVICE, HYPRE_MEMORY_HOST)); 2079a32e9c99SJunchao Zhang lrows2 = hA->rows_d; 2080a32e9c99SJunchao Zhang } else 2081a32e9c99SJunchao Zhang #endif 2082a32e9c99SJunchao Zhang { 2083a32e9c99SJunchao Zhang lrows2 = lrows; 2084a32e9c99SJunchao Zhang } 2085a32e9c99SJunchao Zhang 2086c69f721fSFande Kong /* zero diagonal part */ 2087a32e9c99SJunchao Zhang PetscCall(MatZeroRows_HYPRE_CSRMatrix(hypre_ParCSRMatrixDiag(parcsr), len, lrows2, hdiag)); 2088c69f721fSFande Kong /* zero off-diagonal part */ 2089a32e9c99SJunchao Zhang PetscCall(MatZeroRows_HYPRE_CSRMatrix(hypre_ParCSRMatrixOffd(parcsr), len, lrows2, 0.0)); 2090c69f721fSFande Kong 20919566063dSJacob Faibussowitsch PetscCall(PetscFree(lrows)); 20923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2093c69f721fSFande Kong } 2094c69f721fSFande Kong 2095d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyBegin_HYPRE(Mat mat, MatAssemblyType mode) 2096d71ae5a4SJacob Faibussowitsch { 2097c69f721fSFande Kong PetscFunctionBegin; 20983ba16761SJacob Faibussowitsch if (mat->nooffprocentries) PetscFunctionReturn(PETSC_SUCCESS); 2099c69f721fSFande Kong 21009566063dSJacob Faibussowitsch PetscCall(MatStashScatterBegin_Private(mat, &mat->stash, mat->rmap->range)); 21013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2102c69f721fSFande Kong } 2103c69f721fSFande Kong 2104d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRow_HYPRE(Mat A, PetscInt row, PetscInt *nz, PetscInt **idx, PetscScalar **v) 2105d71ae5a4SJacob Faibussowitsch { 2106c69f721fSFande Kong hypre_ParCSRMatrix *parcsr; 21072cf14000SStefano Zampini HYPRE_Int hnz; 2108c69f721fSFande Kong 2109c69f721fSFande Kong PetscFunctionBegin; 2110c69f721fSFande Kong /* retrieve the internal matrix */ 21119566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(A, &parcsr)); 2112c69f721fSFande Kong /* call HYPRE API */ 2113792fecdfSBarry Smith PetscCallExternal(HYPRE_ParCSRMatrixGetRow, parcsr, row, &hnz, (HYPRE_BigInt **)idx, (HYPRE_Complex **)v); 21142cf14000SStefano Zampini if (nz) *nz = (PetscInt)hnz; 21153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2116c69f721fSFande Kong } 2117c69f721fSFande Kong 2118d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRestoreRow_HYPRE(Mat A, PetscInt row, PetscInt *nz, PetscInt **idx, PetscScalar **v) 2119d71ae5a4SJacob Faibussowitsch { 2120c69f721fSFande Kong hypre_ParCSRMatrix *parcsr; 21212cf14000SStefano Zampini HYPRE_Int hnz; 2122c69f721fSFande Kong 2123c69f721fSFande Kong PetscFunctionBegin; 2124c69f721fSFande Kong /* retrieve the internal matrix */ 21259566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(A, &parcsr)); 2126c69f721fSFande Kong /* call HYPRE API */ 21272cf14000SStefano Zampini hnz = nz ? (HYPRE_Int)(*nz) : 0; 2128792fecdfSBarry Smith PetscCallExternal(HYPRE_ParCSRMatrixRestoreRow, parcsr, row, &hnz, (HYPRE_BigInt **)idx, (HYPRE_Complex **)v); 21293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2130c69f721fSFande Kong } 2131c69f721fSFande Kong 2132d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetValues_HYPRE(Mat A, PetscInt m, const PetscInt idxm[], PetscInt n, const PetscInt idxn[], PetscScalar v[]) 2133d71ae5a4SJacob Faibussowitsch { 213445b8d346SStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 2135c69f721fSFande Kong PetscInt i; 21361d4906efSStefano Zampini 2137c69f721fSFande Kong PetscFunctionBegin; 21383ba16761SJacob Faibussowitsch if (!m || !n) PetscFunctionReturn(PETSC_SUCCESS); 2139c69f721fSFande Kong /* Ignore negative row indices 2140c69f721fSFande Kong * And negative column indices should be automatically ignored in hypre 2141c69f721fSFande Kong * */ 21422cf14000SStefano Zampini for (i = 0; i < m; i++) { 21432cf14000SStefano Zampini if (idxm[i] >= 0) { 21442cf14000SStefano Zampini HYPRE_Int hn = (HYPRE_Int)n; 2145792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetValues, hA->ij, 1, &hn, (HYPRE_BigInt *)&idxm[i], (HYPRE_BigInt *)idxn, (HYPRE_Complex *)(v + i * n)); 21462cf14000SStefano Zampini } 21472cf14000SStefano Zampini } 21483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2149c69f721fSFande Kong } 2150c69f721fSFande Kong 2151d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetOption_HYPRE(Mat A, MatOption op, PetscBool flg) 2152d71ae5a4SJacob Faibussowitsch { 2153ddbeb582SStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 2154ddbeb582SStefano Zampini 2155ddbeb582SStefano Zampini PetscFunctionBegin; 2156c6698e78SStefano Zampini switch (op) { 2157ddbeb582SStefano Zampini case MAT_NO_OFF_PROC_ENTRIES: 215848a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_IJMatrixSetMaxOffProcElmts, hA->ij, 0); 2159ddbeb582SStefano Zampini break; 2160651b1cf9SStefano Zampini case MAT_IGNORE_OFF_PROC_ENTRIES: 2161651b1cf9SStefano Zampini hA->donotstash = flg; 2162d71ae5a4SJacob Faibussowitsch break; 2163d71ae5a4SJacob Faibussowitsch default: 2164d71ae5a4SJacob Faibussowitsch break; 2165ddbeb582SStefano Zampini } 21663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2167ddbeb582SStefano Zampini } 2168c69f721fSFande Kong 2169d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_HYPRE(Mat A, PetscViewer view) 2170d71ae5a4SJacob Faibussowitsch { 217145b8d346SStefano Zampini PetscViewerFormat format; 217245b8d346SStefano Zampini 217345b8d346SStefano Zampini PetscFunctionBegin; 21749566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(view, &format)); 21753ba16761SJacob Faibussowitsch if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) PetscFunctionReturn(PETSC_SUCCESS); 217645b8d346SStefano Zampini if (format != PETSC_VIEWER_NATIVE) { 21776ea7df73SStefano Zampini Mat B; 21786ea7df73SStefano Zampini hypre_ParCSRMatrix *parcsr; 21796ea7df73SStefano Zampini PetscErrorCode (*mview)(Mat, PetscViewer) = NULL; 21806ea7df73SStefano Zampini 21819566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(A, &parcsr)); 21829566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(parcsr, MATAIJ, PETSC_USE_POINTER, &B)); 21839566063dSJacob Faibussowitsch PetscCall(MatGetOperation(B, MATOP_VIEW, (void (**)(void)) & mview)); 218428b400f6SJacob Faibussowitsch PetscCheck(mview, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Missing view operation"); 21859566063dSJacob Faibussowitsch PetscCall((*mview)(B, view)); 21869566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 218745b8d346SStefano Zampini } else { 218845b8d346SStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 218945b8d346SStefano Zampini PetscMPIInt size; 219045b8d346SStefano Zampini PetscBool isascii; 219145b8d346SStefano Zampini const char *filename; 219245b8d346SStefano Zampini 219345b8d346SStefano Zampini /* HYPRE uses only text files */ 21949566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERASCII, &isascii)); 219528b400f6SJacob Faibussowitsch PetscCheck(isascii, PetscObjectComm((PetscObject)view), PETSC_ERR_SUP, "PetscViewerType %s: native HYPRE format needs PETSCVIEWERASCII", ((PetscObject)view)->type_name); 21969566063dSJacob Faibussowitsch PetscCall(PetscViewerFileGetName(view, &filename)); 2197792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixPrint, hA->ij, filename); 21989566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(hA->comm, &size)); 219945b8d346SStefano Zampini if (size > 1) { 22009566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(view, "Matrix files: %s.%05d ... %s.%05d\n", filename, 0, filename, size - 1)); 220145b8d346SStefano Zampini } else { 22029566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(view, "Matrix file: %s.%05d\n", filename, 0)); 220345b8d346SStefano Zampini } 220445b8d346SStefano Zampini } 22053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 220645b8d346SStefano Zampini } 220745b8d346SStefano Zampini 2208d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCopy_HYPRE(Mat A, Mat B, MatStructure str) 2209d71ae5a4SJacob Faibussowitsch { 2210465edc17SStefano Zampini hypre_ParCSRMatrix *acsr, *bcsr; 2211465edc17SStefano Zampini 2212465edc17SStefano Zampini PetscFunctionBegin; 2213465edc17SStefano Zampini if (str == SAME_NONZERO_PATTERN && A->ops->copy == B->ops->copy) { 22149566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(A, &acsr)); 22159566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(B, &bcsr)); 2216792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixCopy, acsr, bcsr, 1); 22179566063dSJacob Faibussowitsch PetscCall(MatSetOption(B, MAT_SORTED_FULL, PETSC_TRUE)); /* "perfect" preallocation, so no need for hypre_AuxParCSRMatrixNeedAux */ 22189566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 22199566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 2220465edc17SStefano Zampini } else { 22219566063dSJacob Faibussowitsch PetscCall(MatCopy_Basic(A, B, str)); 2222465edc17SStefano Zampini } 22233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2224465edc17SStefano Zampini } 2225465edc17SStefano Zampini 2226d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetDiagonal_HYPRE(Mat A, Vec d) 2227d71ae5a4SJacob Faibussowitsch { 22286305df00SStefano Zampini hypre_ParCSRMatrix *parcsr; 22296305df00SStefano Zampini hypre_CSRMatrix *dmat; 223039accc25SStefano Zampini HYPRE_Complex *a; 22316305df00SStefano Zampini PetscBool cong; 22326305df00SStefano Zampini 22336305df00SStefano Zampini PetscFunctionBegin; 22349566063dSJacob Faibussowitsch PetscCall(MatHasCongruentLayouts(A, &cong)); 223528b400f6SJacob Faibussowitsch PetscCheck(cong, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Only for square matrices with same local distributions of rows and columns"); 22369566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(A, &parcsr)); 22376305df00SStefano Zampini dmat = hypre_ParCSRMatrixDiag(parcsr); 22386305df00SStefano Zampini if (dmat) { 223906977982Sstefanozampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 224006977982Sstefanozampini HYPRE_MemoryLocation mem = hypre_CSRMatrixMemoryLocation(dmat); 224106977982Sstefanozampini #else 224206977982Sstefanozampini HYPRE_MemoryLocation mem = HYPRE_MEMORY_HOST; 224306977982Sstefanozampini #endif 224406977982Sstefanozampini 224506977982Sstefanozampini if (mem != HYPRE_MEMORY_HOST) PetscCall(VecGetArrayWriteAndMemType(d, (PetscScalar **)&a, NULL)); 224606977982Sstefanozampini else PetscCall(VecGetArrayWrite(d, (PetscScalar **)&a)); 224706977982Sstefanozampini hypre_CSRMatrixExtractDiagonal(dmat, a, 0); 224806977982Sstefanozampini if (mem != HYPRE_MEMORY_HOST) PetscCall(VecRestoreArrayWriteAndMemType(d, (PetscScalar **)&a)); 224906977982Sstefanozampini else PetscCall(VecRestoreArrayWrite(d, (PetscScalar **)&a)); 22506305df00SStefano Zampini } 22513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22526305df00SStefano Zampini } 22536305df00SStefano Zampini 2254363d496dSStefano Zampini #include <petscblaslapack.h> 2255363d496dSStefano Zampini 2256d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAXPY_HYPRE(Mat Y, PetscScalar a, Mat X, MatStructure str) 2257d71ae5a4SJacob Faibussowitsch { 2258363d496dSStefano Zampini PetscFunctionBegin; 22596ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 22606ea7df73SStefano Zampini { 22616ea7df73SStefano Zampini Mat B; 22626ea7df73SStefano Zampini hypre_ParCSRMatrix *x, *y, *z; 22636ea7df73SStefano Zampini 22649566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR(Y, &y)); 22659566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR(X, &x)); 2266792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixAdd, 1.0, y, 1.0, x, &z); 22679566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(z, MATHYPRE, PETSC_OWN_POINTER, &B)); 22689566063dSJacob Faibussowitsch PetscCall(MatHeaderMerge(Y, &B)); 22696ea7df73SStefano Zampini } 22706ea7df73SStefano Zampini #else 2271363d496dSStefano Zampini if (str == SAME_NONZERO_PATTERN) { 2272363d496dSStefano Zampini hypre_ParCSRMatrix *x, *y; 2273363d496dSStefano Zampini hypre_CSRMatrix *xloc, *yloc; 2274363d496dSStefano Zampini PetscInt xnnz, ynnz; 227539accc25SStefano Zampini HYPRE_Complex *xarr, *yarr; 2276363d496dSStefano Zampini PetscBLASInt one = 1, bnz; 2277363d496dSStefano Zampini 22789566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR(Y, &y)); 22799566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR(X, &x)); 2280363d496dSStefano Zampini 2281363d496dSStefano Zampini /* diagonal block */ 2282363d496dSStefano Zampini xloc = hypre_ParCSRMatrixDiag(x); 2283363d496dSStefano Zampini yloc = hypre_ParCSRMatrixDiag(y); 2284363d496dSStefano Zampini xnnz = 0; 2285363d496dSStefano Zampini ynnz = 0; 2286363d496dSStefano Zampini xarr = NULL; 2287363d496dSStefano Zampini yarr = NULL; 2288363d496dSStefano Zampini if (xloc) { 228939accc25SStefano Zampini xarr = hypre_CSRMatrixData(xloc); 2290363d496dSStefano Zampini xnnz = hypre_CSRMatrixNumNonzeros(xloc); 2291363d496dSStefano Zampini } 2292363d496dSStefano Zampini if (yloc) { 229339accc25SStefano Zampini yarr = hypre_CSRMatrixData(yloc); 2294363d496dSStefano Zampini ynnz = hypre_CSRMatrixNumNonzeros(yloc); 2295363d496dSStefano Zampini } 229608401ef6SPierre Jolivet PetscCheck(xnnz == ynnz, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Different number of nonzeros in diagonal block %" PetscInt_FMT " != %" PetscInt_FMT, xnnz, ynnz); 22979566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(xnnz, &bnz)); 2298792fecdfSBarry Smith PetscCallBLAS("BLASaxpy", BLASaxpy_(&bnz, &a, (PetscScalar *)xarr, &one, (PetscScalar *)yarr, &one)); 2299363d496dSStefano Zampini 2300363d496dSStefano Zampini /* off-diagonal block */ 2301363d496dSStefano Zampini xloc = hypre_ParCSRMatrixOffd(x); 2302363d496dSStefano Zampini yloc = hypre_ParCSRMatrixOffd(y); 2303363d496dSStefano Zampini xnnz = 0; 2304363d496dSStefano Zampini ynnz = 0; 2305363d496dSStefano Zampini xarr = NULL; 2306363d496dSStefano Zampini yarr = NULL; 2307363d496dSStefano Zampini if (xloc) { 230839accc25SStefano Zampini xarr = hypre_CSRMatrixData(xloc); 2309363d496dSStefano Zampini xnnz = hypre_CSRMatrixNumNonzeros(xloc); 2310363d496dSStefano Zampini } 2311363d496dSStefano Zampini if (yloc) { 231239accc25SStefano Zampini yarr = hypre_CSRMatrixData(yloc); 2313363d496dSStefano Zampini ynnz = hypre_CSRMatrixNumNonzeros(yloc); 2314363d496dSStefano Zampini } 231508401ef6SPierre 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); 23169566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(xnnz, &bnz)); 2317792fecdfSBarry Smith PetscCallBLAS("BLASaxpy", BLASaxpy_(&bnz, &a, (PetscScalar *)xarr, &one, (PetscScalar *)yarr, &one)); 2318363d496dSStefano Zampini } else if (str == SUBSET_NONZERO_PATTERN) { 23199566063dSJacob Faibussowitsch PetscCall(MatAXPY_Basic(Y, a, X, str)); 2320363d496dSStefano Zampini } else { 2321363d496dSStefano Zampini Mat B; 2322363d496dSStefano Zampini 23239566063dSJacob Faibussowitsch PetscCall(MatAXPY_Basic_Preallocate(Y, X, &B)); 23249566063dSJacob Faibussowitsch PetscCall(MatAXPY_BasicWithPreallocation(B, Y, a, X, str)); 23259566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(Y, &B)); 2326363d496dSStefano Zampini } 23276ea7df73SStefano Zampini #endif 23283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2329363d496dSStefano Zampini } 2330363d496dSStefano Zampini 23312c4ab24aSJunchao Zhang static PetscErrorCode MatDuplicate_HYPRE(Mat A, MatDuplicateOption op, Mat *B) 23322c4ab24aSJunchao Zhang { 23332c4ab24aSJunchao Zhang hypre_ParCSRMatrix *parcsr = NULL; 23342c4ab24aSJunchao Zhang PetscCopyMode cpmode; 23352c4ab24aSJunchao Zhang Mat_HYPRE *hA; 23362c4ab24aSJunchao Zhang 23372c4ab24aSJunchao Zhang PetscFunctionBegin; 23382c4ab24aSJunchao Zhang PetscCall(MatHYPREGetParCSR_HYPRE(A, &parcsr)); 23392c4ab24aSJunchao Zhang if (op == MAT_DO_NOT_COPY_VALUES || op == MAT_SHARE_NONZERO_PATTERN) { 23402c4ab24aSJunchao Zhang parcsr = hypre_ParCSRMatrixClone(parcsr, 0); 23412c4ab24aSJunchao Zhang cpmode = PETSC_OWN_POINTER; 23422c4ab24aSJunchao Zhang } else { 23432c4ab24aSJunchao Zhang cpmode = PETSC_COPY_VALUES; 23442c4ab24aSJunchao Zhang } 23452c4ab24aSJunchao Zhang PetscCall(MatCreateFromParCSR(parcsr, MATHYPRE, cpmode, B)); 23462c4ab24aSJunchao Zhang hA = (Mat_HYPRE *)A->data; 23472c4ab24aSJunchao Zhang if (hA->cooMat) { 234806977982Sstefanozampini Mat_HYPRE *hB = (Mat_HYPRE *)((*B)->data); 2349b73e3080SStefano Zampini op = (op == MAT_DO_NOT_COPY_VALUES) ? op : MAT_COPY_VALUES; 2350b73e3080SStefano Zampini /* Cannot simply increase the reference count of hA->cooMat, since B needs to share cooMat's data array */ 235106977982Sstefanozampini PetscCall(MatDuplicate(hA->cooMat, op, &hB->cooMat)); 235206977982Sstefanozampini PetscCall(MatHYPRE_AttachCOOMat(*B)); 23532c4ab24aSJunchao Zhang } 23542c4ab24aSJunchao Zhang PetscFunctionReturn(PETSC_SUCCESS); 23552c4ab24aSJunchao Zhang } 23562c4ab24aSJunchao Zhang 2357d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetPreallocationCOO_HYPRE(Mat mat, PetscCount coo_n, PetscInt coo_i[], PetscInt coo_j[]) 2358d71ae5a4SJacob Faibussowitsch { 235906977982Sstefanozampini Mat_HYPRE *hmat = (Mat_HYPRE *)mat->data; 23605fbaff96SJunchao Zhang 23615fbaff96SJunchao Zhang PetscFunctionBegin; 2362651b1cf9SStefano Zampini /* Build an agent matrix cooMat with AIJ format 23635fbaff96SJunchao 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. 23645fbaff96SJunchao Zhang */ 236506977982Sstefanozampini PetscCall(MatHYPRE_CreateCOOMat(mat)); 236606977982Sstefanozampini PetscCall(MatSetOption(hmat->cooMat, MAT_IGNORE_OFF_PROC_ENTRIES, hmat->donotstash)); 236706977982Sstefanozampini PetscCall(MatSetOption(hmat->cooMat, MAT_NO_OFF_PROC_ENTRIES, mat->nooffprocentries)); 2368651b1cf9SStefano Zampini 2369651b1cf9SStefano Zampini /* MatSetPreallocationCOO_SeqAIJ and MatSetPreallocationCOO_MPIAIJ uses this specific 2370651b1cf9SStefano Zampini name to automatically put the diagonal entries first */ 237106977982Sstefanozampini PetscCall(PetscObjectSetName((PetscObject)hmat->cooMat, "_internal_COO_mat_for_hypre")); 237206977982Sstefanozampini PetscCall(MatSetPreallocationCOO(hmat->cooMat, coo_n, coo_i, coo_j)); 237306977982Sstefanozampini hmat->cooMat->assembled = PETSC_TRUE; 23745fbaff96SJunchao Zhang 23755fbaff96SJunchao Zhang /* Copy the sparsity pattern from cooMat to hypre IJMatrix hmat->ij */ 23765fbaff96SJunchao Zhang PetscCall(MatSetOption(mat, MAT_SORTED_FULL, PETSC_TRUE)); 237706977982Sstefanozampini PetscCall(MatHYPRE_CreateFromMat(hmat->cooMat, hmat)); /* Create hmat->ij and preallocate it */ 237806977982Sstefanozampini PetscCall(MatHYPRE_IJMatrixCopyIJ(hmat->cooMat, hmat->ij)); /* Copy A's (i,j) to hmat->ij */ 23795fbaff96SJunchao Zhang 23805fbaff96SJunchao Zhang mat->preallocated = PETSC_TRUE; 23815fbaff96SJunchao Zhang PetscCall(MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY)); 23825fbaff96SJunchao Zhang PetscCall(MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY)); /* Migrate mat to device if it is bound to. Hypre builds its own SpMV context here */ 23835fbaff96SJunchao Zhang 23842c4ab24aSJunchao Zhang /* Attach cooMat to mat */ 238506977982Sstefanozampini PetscCall(MatHYPRE_AttachCOOMat(mat)); 23863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23875fbaff96SJunchao Zhang } 23885fbaff96SJunchao Zhang 2389d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetValuesCOO_HYPRE(Mat mat, const PetscScalar v[], InsertMode imode) 2390d71ae5a4SJacob Faibussowitsch { 23915fbaff96SJunchao Zhang Mat_HYPRE *hmat = (Mat_HYPRE *)mat->data; 23925fbaff96SJunchao Zhang 23935fbaff96SJunchao Zhang PetscFunctionBegin; 2394b73e3080SStefano Zampini PetscCheck(hmat->cooMat, PetscObjectComm((PetscObject)mat), PETSC_ERR_PLIB, "HYPRE COO delegate matrix has not been created yet"); 23955fbaff96SJunchao Zhang PetscCall(MatSetValuesCOO(hmat->cooMat, v, imode)); 2396651b1cf9SStefano Zampini PetscCall(MatViewFromOptions(hmat->cooMat, (PetscObject)mat, "-cooMat_view")); 23973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23985fbaff96SJunchao Zhang } 23995fbaff96SJunchao Zhang 2400a055b5aaSBarry Smith /*MC 24012ef1f0ffSBarry Smith MATHYPRE - "hypre" - A matrix type to be used for sequential and parallel sparse matrices 2402a055b5aaSBarry Smith based on the hypre IJ interface. 2403a055b5aaSBarry Smith 2404a055b5aaSBarry Smith Level: intermediate 2405a055b5aaSBarry Smith 24061cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatCreate()`, `MatHYPRESetPreallocation` 2407a055b5aaSBarry Smith M*/ 2408a055b5aaSBarry Smith 2409d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatCreate_HYPRE(Mat B) 2410d71ae5a4SJacob Faibussowitsch { 241163c07aadSStefano Zampini Mat_HYPRE *hB; 241263c07aadSStefano Zampini 241363c07aadSStefano Zampini PetscFunctionBegin; 24144dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&hB)); 24156ea7df73SStefano Zampini 2416978814f1SStefano Zampini hB->inner_free = PETSC_TRUE; 2417651b1cf9SStefano Zampini hB->array_available = PETSC_TRUE; 2418978814f1SStefano Zampini 241963c07aadSStefano Zampini B->data = (void *)hB; 242063c07aadSStefano Zampini 24219566063dSJacob Faibussowitsch PetscCall(PetscMemzero(B->ops, sizeof(struct _MatOps))); 242263c07aadSStefano Zampini B->ops->mult = MatMult_HYPRE; 242363c07aadSStefano Zampini B->ops->multtranspose = MatMultTranspose_HYPRE; 2424414bd5c3SStefano Zampini B->ops->multadd = MatMultAdd_HYPRE; 2425414bd5c3SStefano Zampini B->ops->multtransposeadd = MatMultTransposeAdd_HYPRE; 242663c07aadSStefano Zampini B->ops->setup = MatSetUp_HYPRE; 242763c07aadSStefano Zampini B->ops->destroy = MatDestroy_HYPRE; 242863c07aadSStefano Zampini B->ops->assemblyend = MatAssemblyEnd_HYPRE; 2429c69f721fSFande Kong B->ops->assemblybegin = MatAssemblyBegin_HYPRE; 2430d975228cSstefano_zampini B->ops->setvalues = MatSetValues_HYPRE; 243168ec7858SStefano Zampini B->ops->missingdiagonal = MatMissingDiagonal_HYPRE; 243268ec7858SStefano Zampini B->ops->scale = MatScale_HYPRE; 243368ec7858SStefano Zampini B->ops->zerorowscolumns = MatZeroRowsColumns_HYPRE; 2434c69f721fSFande Kong B->ops->zeroentries = MatZeroEntries_HYPRE; 2435c69f721fSFande Kong B->ops->zerorows = MatZeroRows_HYPRE; 2436c69f721fSFande Kong B->ops->getrow = MatGetRow_HYPRE; 2437c69f721fSFande Kong B->ops->restorerow = MatRestoreRow_HYPRE; 2438c69f721fSFande Kong B->ops->getvalues = MatGetValues_HYPRE; 2439ddbeb582SStefano Zampini B->ops->setoption = MatSetOption_HYPRE; 244045b8d346SStefano Zampini B->ops->duplicate = MatDuplicate_HYPRE; 2441465edc17SStefano Zampini B->ops->copy = MatCopy_HYPRE; 244245b8d346SStefano Zampini B->ops->view = MatView_HYPRE; 24436305df00SStefano Zampini B->ops->getdiagonal = MatGetDiagonal_HYPRE; 2444363d496dSStefano Zampini B->ops->axpy = MatAXPY_HYPRE; 24454222ddf1SHong Zhang B->ops->productsetfromoptions = MatProductSetFromOptions_HYPRE; 24466ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 24476ea7df73SStefano Zampini B->ops->bindtocpu = MatBindToCPU_HYPRE; 24486ea7df73SStefano Zampini B->boundtocpu = PETSC_FALSE; 24496ea7df73SStefano Zampini #endif 245045b8d346SStefano Zampini 245145b8d346SStefano Zampini /* build cache for off array entries formed */ 24529566063dSJacob Faibussowitsch PetscCall(MatStashCreate_Private(PetscObjectComm((PetscObject)B), 1, &B->stash)); 245363c07aadSStefano Zampini 24549566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)B), &hB->comm)); 24559566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATHYPRE)); 24569566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_hypre_aij_C", MatConvert_HYPRE_AIJ)); 24579566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_hypre_is_C", MatConvert_HYPRE_IS)); 24589566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaij_hypre_C", MatProductSetFromOptions_HYPRE)); 24599566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_mpiaij_hypre_C", MatProductSetFromOptions_HYPRE)); 24609566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatHYPRESetPreallocation_C", MatHYPRESetPreallocation_HYPRE)); 24619566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatHYPREGetParCSR_C", MatHYPREGetParCSR_HYPRE)); 24625fbaff96SJunchao Zhang PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSetPreallocationCOO_C", MatSetPreallocationCOO_HYPRE)); 24635fbaff96SJunchao Zhang PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSetValuesCOO_C", MatSetValuesCOO_HYPRE)); 24646ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 24656ea7df73SStefano Zampini #if defined(HYPRE_USING_HIP) 246606977982Sstefanozampini PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaijhipsparse_hypre_C", MatProductSetFromOptions_HYPRE)); 246706977982Sstefanozampini PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_mpiaijhipsparse_hypre_C", MatProductSetFromOptions_HYPRE)); 24689566063dSJacob Faibussowitsch PetscCall(PetscDeviceInitialize(PETSC_DEVICE_HIP)); 24699566063dSJacob Faibussowitsch PetscCall(MatSetVecType(B, VECHIP)); 24706ea7df73SStefano Zampini #endif 24716ea7df73SStefano Zampini #if defined(HYPRE_USING_CUDA) 247206977982Sstefanozampini PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaijcusparse_hypre_C", MatProductSetFromOptions_HYPRE)); 247306977982Sstefanozampini PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_mpiaijcusparse_hypre_C", MatProductSetFromOptions_HYPRE)); 24749566063dSJacob Faibussowitsch PetscCall(PetscDeviceInitialize(PETSC_DEVICE_CUDA)); 24759566063dSJacob Faibussowitsch PetscCall(MatSetVecType(B, VECCUDA)); 24766ea7df73SStefano Zampini #endif 24776ea7df73SStefano Zampini #endif 2478ea9ee2c1SPierre Jolivet PetscHYPREInitialize(); 24793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 248063c07aadSStefano Zampini } 2481