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); 14887ef5fa6SStefano 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 496*1c265611SJunchao Zhang // Build COO's coordinate list i[], j[] based on CSR's i[], j[] arrays and the number of local rows 'n' 49706977982Sstefanozampini static PetscErrorCode CSRtoCOO_Private(PetscInt n, const PetscInt ii[], const PetscInt jj[], PetscCount *ncoo, PetscInt **coo_i, PetscInt **coo_j) 49806977982Sstefanozampini { 49906977982Sstefanozampini PetscInt *cooi, *cooj; 50006977982Sstefanozampini 50106977982Sstefanozampini PetscFunctionBegin; 50206977982Sstefanozampini *ncoo = ii[n]; 50306977982Sstefanozampini PetscCall(PetscMalloc2(*ncoo, &cooi, *ncoo, &cooj)); 50406977982Sstefanozampini for (PetscInt i = 0; i < n; i++) { 50506977982Sstefanozampini for (PetscInt j = ii[i]; j < ii[i + 1]; j++) cooi[j] = i; 50606977982Sstefanozampini } 50706977982Sstefanozampini PetscCall(PetscArraycpy(cooj, jj, *ncoo)); 50806977982Sstefanozampini *coo_i = cooi; 50906977982Sstefanozampini *coo_j = cooj; 51006977982Sstefanozampini PetscFunctionReturn(PETSC_SUCCESS); 51106977982Sstefanozampini } 51206977982Sstefanozampini 513*1c265611SJunchao Zhang // Similar to CSRtoCOO_Private, but the CSR's i[], j[] are of type HYPRE_Int 51406977982Sstefanozampini static PetscErrorCode CSRtoCOO_HYPRE_Int_Private(PetscInt n, const HYPRE_Int ii[], const HYPRE_Int jj[], PetscCount *ncoo, PetscInt **coo_i, PetscInt **coo_j) 51506977982Sstefanozampini { 51606977982Sstefanozampini PetscInt *cooi, *cooj; 51706977982Sstefanozampini 51806977982Sstefanozampini PetscFunctionBegin; 51906977982Sstefanozampini *ncoo = ii[n]; 52006977982Sstefanozampini PetscCall(PetscMalloc2(*ncoo, &cooi, *ncoo, &cooj)); 52106977982Sstefanozampini for (PetscInt i = 0; i < n; i++) { 52206977982Sstefanozampini for (HYPRE_Int j = ii[i]; j < ii[i + 1]; j++) cooi[j] = i; 52306977982Sstefanozampini } 52406977982Sstefanozampini for (PetscCount i = 0; i < *ncoo; i++) cooj[i] = jj[i]; 52506977982Sstefanozampini *coo_i = cooi; 52606977982Sstefanozampini *coo_j = cooj; 52706977982Sstefanozampini PetscFunctionReturn(PETSC_SUCCESS); 52806977982Sstefanozampini } 52906977982Sstefanozampini 530*1c265611SJunchao Zhang // Build a COO data structure for the seqaij matrix, as if the nonzeros are laid out in the same order as in the CSR 53106977982Sstefanozampini static PetscErrorCode MatSeqAIJGetCOO_Private(Mat A, PetscCount *ncoo, PetscInt **coo_i, PetscInt **coo_j) 53206977982Sstefanozampini { 53306977982Sstefanozampini PetscInt n; 53406977982Sstefanozampini const PetscInt *ii, *jj; 53506977982Sstefanozampini PetscBool done; 53606977982Sstefanozampini 53706977982Sstefanozampini PetscFunctionBegin; 53806977982Sstefanozampini PetscCall(MatGetRowIJ(A, 0, PETSC_FALSE, PETSC_FALSE, &n, &ii, &jj, &done)); 53906977982Sstefanozampini PetscCheck(done, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Failure for MatGetRowIJ"); 54006977982Sstefanozampini PetscCall(CSRtoCOO_Private(n, ii, jj, ncoo, coo_i, coo_j)); 54106977982Sstefanozampini PetscCall(MatRestoreRowIJ(A, 0, PETSC_FALSE, PETSC_FALSE, &n, &ii, &jj, &done)); 54206977982Sstefanozampini PetscCheck(done, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Failure for MatRestoreRowIJ"); 54306977982Sstefanozampini PetscFunctionReturn(PETSC_SUCCESS); 54406977982Sstefanozampini } 54506977982Sstefanozampini 546*1c265611SJunchao Zhang // Build a COO data structure for the hypreCSRMatrix, as if the nonzeros are laid out in the same order as in the hypreCSRMatrix 54706977982Sstefanozampini static PetscErrorCode hypreCSRMatrixGetCOO_Private(hypre_CSRMatrix *A, PetscCount *ncoo, PetscInt **coo_i, PetscInt **coo_j) 54806977982Sstefanozampini { 54906977982Sstefanozampini PetscInt n = hypre_CSRMatrixNumRows(A); 55006977982Sstefanozampini HYPRE_Int *ii, *jj; 55106977982Sstefanozampini HYPRE_MemoryLocation mem = HYPRE_MEMORY_HOST; 55206977982Sstefanozampini 55306977982Sstefanozampini PetscFunctionBegin; 55406977982Sstefanozampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 55506977982Sstefanozampini mem = hypre_CSRMatrixMemoryLocation(A); 55606977982Sstefanozampini if (mem != HYPRE_MEMORY_HOST) { 55706977982Sstefanozampini PetscCount nnz = hypre_CSRMatrixNumNonzeros(A); 55806977982Sstefanozampini PetscCall(PetscMalloc2(n + 1, &ii, nnz, &jj)); 55906977982Sstefanozampini hypre_TMemcpy(ii, hypre_CSRMatrixI(A), HYPRE_Int, n + 1, HYPRE_MEMORY_HOST, mem); 56006977982Sstefanozampini hypre_TMemcpy(jj, hypre_CSRMatrixJ(A), HYPRE_Int, nnz, HYPRE_MEMORY_HOST, mem); 56106977982Sstefanozampini } else { 56206977982Sstefanozampini #else 56306977982Sstefanozampini { 56406977982Sstefanozampini #endif 56506977982Sstefanozampini ii = hypre_CSRMatrixI(A); 56606977982Sstefanozampini jj = hypre_CSRMatrixJ(A); 56706977982Sstefanozampini } 56806977982Sstefanozampini PetscCall(CSRtoCOO_HYPRE_Int_Private(n, ii, jj, ncoo, coo_i, coo_j)); 56906977982Sstefanozampini if (mem != HYPRE_MEMORY_HOST) PetscCall(PetscFree2(ii, jj)); 57006977982Sstefanozampini PetscFunctionReturn(PETSC_SUCCESS); 57106977982Sstefanozampini } 57206977982Sstefanozampini 57306977982Sstefanozampini static PetscErrorCode MatSetValuesCOOFromCSRMatrix_Private(Mat A, hypre_CSRMatrix *H) 57406977982Sstefanozampini { 57506977982Sstefanozampini PetscBool iscpu = PETSC_TRUE; 57606977982Sstefanozampini PetscScalar *a; 57706977982Sstefanozampini HYPRE_MemoryLocation mem = HYPRE_MEMORY_HOST; 57806977982Sstefanozampini 57906977982Sstefanozampini PetscFunctionBegin; 58006977982Sstefanozampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 58106977982Sstefanozampini mem = hypre_CSRMatrixMemoryLocation(H); 58206977982Sstefanozampini PetscCall(PetscObjectTypeCompare((PetscObject)A, MATSEQAIJ, &iscpu)); 58306977982Sstefanozampini #endif 58406977982Sstefanozampini if (iscpu && mem != HYPRE_MEMORY_HOST) { 58506977982Sstefanozampini PetscCount nnz = hypre_CSRMatrixNumNonzeros(H); 58606977982Sstefanozampini PetscCall(PetscMalloc1(nnz, &a)); 58706977982Sstefanozampini hypre_TMemcpy(a, hypre_CSRMatrixData(H), PetscScalar, nnz, HYPRE_MEMORY_HOST, mem); 58806977982Sstefanozampini } else { 58906977982Sstefanozampini a = (PetscScalar *)hypre_CSRMatrixData(H); 59006977982Sstefanozampini } 59106977982Sstefanozampini PetscCall(MatSetValuesCOO(A, a, INSERT_VALUES)); 59206977982Sstefanozampini if (iscpu && mem != HYPRE_MEMORY_HOST) PetscCall(PetscFree(a)); 593b73e3080SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 594b73e3080SStefano Zampini } 595b73e3080SStefano Zampini 596b73e3080SStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A, MatType type, MatReuse reuse, Mat *B) 597b73e3080SStefano Zampini { 598b73e3080SStefano Zampini MPI_Comm comm = PetscObjectComm((PetscObject)A); 59906977982Sstefanozampini Mat M = NULL, dH = NULL, oH = NULL, dA = NULL, oA = NULL; 600b73e3080SStefano Zampini PetscBool ismpiaij, issbaij, isbaij; 601b73e3080SStefano Zampini Mat_HYPRE *hA; 602b73e3080SStefano Zampini 603b73e3080SStefano Zampini PetscFunctionBegin; 604b73e3080SStefano Zampini PetscCall(PetscObjectTypeCompareAny((PetscObject)A, &issbaij, MATSEQSBAIJ, MATMPIBAIJ, "")); 605b73e3080SStefano Zampini PetscCall(PetscObjectTypeCompareAny((PetscObject)A, &isbaij, MATSEQBAIJ, MATMPIBAIJ, "")); 606b73e3080SStefano Zampini if (isbaij || issbaij) { /* handle BAIJ and SBAIJ */ 607b73e3080SStefano Zampini PetscBool ismpi; 608b73e3080SStefano Zampini MatType newtype; 609b73e3080SStefano Zampini 610b73e3080SStefano Zampini PetscCall(PetscObjectTypeCompareAny((PetscObject)A, &ismpi, MATMPISBAIJ, MATMPIBAIJ, "")); 611b73e3080SStefano Zampini newtype = ismpi ? MATMPIAIJ : MATSEQAIJ; 61263c07aadSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 613b73e3080SStefano Zampini PetscCall(MatConvert(*B, newtype, MAT_INPLACE_MATRIX, B)); 614b73e3080SStefano Zampini PetscCall(MatConvert(A, newtype, MAT_REUSE_MATRIX, B)); 615b73e3080SStefano Zampini PetscCall(MatConvert(*B, MATHYPRE, MAT_INPLACE_MATRIX, B)); 616b73e3080SStefano Zampini } else if (reuse == MAT_INITIAL_MATRIX) { 617b73e3080SStefano Zampini PetscCall(MatConvert(A, newtype, MAT_INITIAL_MATRIX, B)); 618b73e3080SStefano Zampini PetscCall(MatConvert(*B, MATHYPRE, MAT_INPLACE_MATRIX, B)); 61963c07aadSStefano Zampini } else { 620b73e3080SStefano Zampini PetscCall(MatConvert(A, newtype, MAT_INPLACE_MATRIX, &A)); 621b73e3080SStefano Zampini PetscCall(MatConvert(A, MATHYPRE, MAT_INPLACE_MATRIX, &A)); 622b73e3080SStefano Zampini } 623b73e3080SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 624b73e3080SStefano Zampini } 62506977982Sstefanozampini 62606977982Sstefanozampini dA = A; 627b73e3080SStefano Zampini PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIAIJ, &ismpiaij)); 628b73e3080SStefano Zampini if (ismpiaij) PetscCall(MatMPIAIJGetSeqAIJ(A, &dA, &oA, NULL)); 62906977982Sstefanozampini 630b73e3080SStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 63106977982Sstefanozampini PetscCount coo_n; 63206977982Sstefanozampini PetscInt *coo_i, *coo_j; 63306977982Sstefanozampini 6349566063dSJacob Faibussowitsch PetscCall(MatCreate(comm, &M)); 6359566063dSJacob Faibussowitsch PetscCall(MatSetType(M, MATHYPRE)); 6369566063dSJacob Faibussowitsch PetscCall(MatSetSizes(M, A->rmap->n, A->cmap->n, A->rmap->N, A->cmap->N)); 637b73e3080SStefano Zampini PetscCall(MatSetOption(M, MAT_SORTED_FULL, PETSC_TRUE)); 638b73e3080SStefano Zampini PetscCall(MatSetOption(M, MAT_NO_OFF_PROC_ENTRIES, PETSC_TRUE)); 639b73e3080SStefano Zampini 640b73e3080SStefano Zampini hA = (Mat_HYPRE *)M->data; 64106977982Sstefanozampini PetscCall(MatHYPRE_CreateFromMat(A, hA)); 64206977982Sstefanozampini PetscCall(MatHYPRE_IJMatrixCopyIJ(A, hA->ij)); 64306977982Sstefanozampini 64406977982Sstefanozampini PetscCall(MatHYPRE_CreateCOOMat(M)); 64506977982Sstefanozampini 64606977982Sstefanozampini dH = hA->cooMat; 64706977982Sstefanozampini PetscCall(PetscObjectBaseTypeCompare((PetscObject)hA->cooMat, MATMPIAIJ, &ismpiaij)); 64806977982Sstefanozampini if (ismpiaij) PetscCall(MatMPIAIJGetSeqAIJ(hA->cooMat, &dH, &oH, NULL)); 64906977982Sstefanozampini 65006977982Sstefanozampini PetscCall(PetscObjectSetName((PetscObject)dH, "_internal_COO_mat_for_hypre")); 65106977982Sstefanozampini PetscCall(MatSeqAIJGetCOO_Private(dA, &coo_n, &coo_i, &coo_j)); 65206977982Sstefanozampini PetscCall(MatSetPreallocationCOO(dH, coo_n, coo_i, coo_j)); 65306977982Sstefanozampini PetscCall(PetscFree2(coo_i, coo_j)); 65406977982Sstefanozampini if (oH) { 65506977982Sstefanozampini PetscCall(PetscLayoutDestroy(&oH->cmap)); 65606977982Sstefanozampini PetscCall(PetscLayoutCreateFromSizes(PetscObjectComm((PetscObject)oH), oA->cmap->n, oA->cmap->n, 1, &oH->cmap)); 65706977982Sstefanozampini PetscCall(MatSeqAIJGetCOO_Private(oA, &coo_n, &coo_i, &coo_j)); 65806977982Sstefanozampini PetscCall(MatSetPreallocationCOO(oH, coo_n, coo_i, coo_j)); 65906977982Sstefanozampini PetscCall(PetscFree2(coo_i, coo_j)); 66006977982Sstefanozampini } 66106977982Sstefanozampini hA->cooMat->assembled = PETSC_TRUE; 66206977982Sstefanozampini 663b73e3080SStefano Zampini M->preallocated = PETSC_TRUE; 66406977982Sstefanozampini PetscCall(MatAssemblyBegin(M, MAT_FINAL_ASSEMBLY)); 66506977982Sstefanozampini PetscCall(MatAssemblyEnd(M, MAT_FINAL_ASSEMBLY)); 66606977982Sstefanozampini 66706977982Sstefanozampini PetscCall(MatHYPRE_AttachCOOMat(M)); 66884d4e069SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) *B = M; 669b73e3080SStefano Zampini } else M = *B; 670b73e3080SStefano Zampini 671b73e3080SStefano Zampini hA = (Mat_HYPRE *)M->data; 67206977982Sstefanozampini PetscCheck(hA->cooMat, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "HYPRE COO delegate matrix has not been created yet"); 67306977982Sstefanozampini 67406977982Sstefanozampini dH = hA->cooMat; 67506977982Sstefanozampini PetscCall(PetscObjectBaseTypeCompare((PetscObject)hA->cooMat, MATMPIAIJ, &ismpiaij)); 67606977982Sstefanozampini if (ismpiaij) PetscCall(MatMPIAIJGetSeqAIJ(hA->cooMat, &dH, &oH, NULL)); 67706977982Sstefanozampini 67806977982Sstefanozampini PetscScalar *a; 67906977982Sstefanozampini PetscCall(MatSeqAIJGetCSRAndMemType(dA, NULL, NULL, &a, NULL)); 68006977982Sstefanozampini PetscCall(MatSetValuesCOO(dH, a, INSERT_VALUES)); 68106977982Sstefanozampini if (oH) { 68206977982Sstefanozampini PetscCall(MatSeqAIJGetCSRAndMemType(oA, NULL, NULL, &a, NULL)); 68306977982Sstefanozampini PetscCall(MatSetValuesCOO(oH, a, INSERT_VALUES)); 68406977982Sstefanozampini } 685b73e3080SStefano Zampini 68648a46eb9SPierre Jolivet if (reuse == MAT_INPLACE_MATRIX) PetscCall(MatHeaderReplace(A, &M)); 6873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 68863c07aadSStefano Zampini } 68963c07aadSStefano Zampini 690d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatConvert_HYPRE_AIJ(Mat A, MatType mtype, MatReuse reuse, Mat *B) 691d71ae5a4SJacob Faibussowitsch { 69206977982Sstefanozampini Mat M, dA = NULL, oA = NULL; 69363c07aadSStefano Zampini hypre_ParCSRMatrix *parcsr; 69406977982Sstefanozampini hypre_CSRMatrix *dH, *oH; 69563c07aadSStefano Zampini MPI_Comm comm; 69606977982Sstefanozampini PetscBool ismpiaij, isseqaij; 69763c07aadSStefano Zampini 69863c07aadSStefano Zampini PetscFunctionBegin; 69963c07aadSStefano Zampini comm = PetscObjectComm((PetscObject)A); 70063c07aadSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 7019566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompare((PetscObject)*B, MATMPIAIJ, &ismpiaij)); 7029566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompare((PetscObject)*B, MATSEQAIJ, &isseqaij)); 70306977982Sstefanozampini PetscCheck(ismpiaij || isseqaij, comm, PETSC_ERR_SUP, "Only MATMPIAIJ or MATSEQAIJ base types are supported"); 70463c07aadSStefano Zampini } 70506977982Sstefanozampini PetscCall(MatHYPREGetParCSR(A, &parcsr)); 7066ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 70706977982Sstefanozampini if (HYPRE_MEMORY_DEVICE == hypre_ParCSRMatrixMemoryLocation(parcsr)) { 70806977982Sstefanozampini PetscBool isaij; 70906977982Sstefanozampini 71006977982Sstefanozampini PetscCall(PetscStrcmp(mtype, MATAIJ, &isaij)); 71106977982Sstefanozampini if (isaij) { 71206977982Sstefanozampini PetscMPIInt size; 71306977982Sstefanozampini 7149566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 71506977982Sstefanozampini #if defined(HYPRE_USING_HIP) 71606977982Sstefanozampini mtype = size > 1 ? MATMPIAIJHIPSPARSE : MATSEQAIJHIPSPARSE; 71706977982Sstefanozampini #elif defined(HYPRE_USING_CUDA) 71806977982Sstefanozampini mtype = size > 1 ? MATMPIAIJCUSPARSE : MATSEQAIJCUSPARSE; 71906977982Sstefanozampini #else 72006977982Sstefanozampini mtype = size > 1 ? MATMPIAIJ : MATSEQAIJ; 72106977982Sstefanozampini #endif 72263c07aadSStefano Zampini } 72363c07aadSStefano Zampini } 72406977982Sstefanozampini #endif 72506977982Sstefanozampini dH = hypre_ParCSRMatrixDiag(parcsr); 72606977982Sstefanozampini oH = hypre_ParCSRMatrixOffd(parcsr); 7279371c9d4SSatish Balay if (reuse != MAT_REUSE_MATRIX) { 72806977982Sstefanozampini PetscCount coo_n; 72906977982Sstefanozampini PetscInt *coo_i, *coo_j; 73063c07aadSStefano Zampini 73106977982Sstefanozampini PetscCall(MatCreate(comm, &M)); 73206977982Sstefanozampini PetscCall(MatSetType(M, mtype)); 73306977982Sstefanozampini PetscCall(MatSetSizes(M, A->rmap->n, A->cmap->n, A->rmap->N, A->cmap->N)); 73406977982Sstefanozampini PetscCall(MatMPIAIJSetPreallocation(M, 0, NULL, 0, NULL)); 73563c07aadSStefano Zampini 73606977982Sstefanozampini dA = M; 73706977982Sstefanozampini PetscCall(PetscObjectBaseTypeCompare((PetscObject)M, MATMPIAIJ, &ismpiaij)); 73806977982Sstefanozampini if (ismpiaij) PetscCall(MatMPIAIJGetSeqAIJ(M, &dA, &oA, NULL)); 739a16187a7SStefano Zampini 74006977982Sstefanozampini PetscCall(hypreCSRMatrixGetCOO_Private(dH, &coo_n, &coo_i, &coo_j)); 74106977982Sstefanozampini PetscCall(MatSetPreallocationCOO(dA, coo_n, coo_i, coo_j)); 74206977982Sstefanozampini PetscCall(PetscFree2(coo_i, coo_j)); 74306977982Sstefanozampini if (ismpiaij) { 74406977982Sstefanozampini HYPRE_Int nc = hypre_CSRMatrixNumCols(oH); 745a16187a7SStefano Zampini 74606977982Sstefanozampini PetscCall(PetscLayoutDestroy(&oA->cmap)); 74706977982Sstefanozampini PetscCall(PetscLayoutCreateFromSizes(PetscObjectComm((PetscObject)oA), nc, nc, 1, &oA->cmap)); 74806977982Sstefanozampini PetscCall(hypreCSRMatrixGetCOO_Private(oH, &coo_n, &coo_i, &coo_j)); 74906977982Sstefanozampini PetscCall(MatSetPreallocationCOO(oA, coo_n, coo_i, coo_j)); 75006977982Sstefanozampini PetscCall(PetscFree2(coo_i, coo_j)); 751a16187a7SStefano Zampini 75206977982Sstefanozampini /* garray */ 753f4f49eeaSPierre Jolivet Mat_MPIAIJ *aij = (Mat_MPIAIJ *)M->data; 75406977982Sstefanozampini HYPRE_BigInt *harray = hypre_ParCSRMatrixColMapOffd(parcsr); 75506977982Sstefanozampini PetscInt *garray; 75606977982Sstefanozampini 75706977982Sstefanozampini PetscCall(PetscFree(aij->garray)); 75806977982Sstefanozampini PetscCall(PetscMalloc1(nc, &garray)); 75906977982Sstefanozampini for (HYPRE_Int i = 0; i < nc; i++) garray[i] = (PetscInt)harray[i]; 76006977982Sstefanozampini aij->garray = garray; 76106977982Sstefanozampini PetscCall(MatSetUpMultiply_MPIAIJ(M)); 762a16187a7SStefano Zampini } 76306977982Sstefanozampini if (reuse == MAT_INITIAL_MATRIX) *B = M; 76406977982Sstefanozampini } else M = *B; 765225daaf8SStefano Zampini 76606977982Sstefanozampini dA = M; 76706977982Sstefanozampini PetscCall(PetscObjectBaseTypeCompare((PetscObject)M, MATMPIAIJ, &ismpiaij)); 76806977982Sstefanozampini if (ismpiaij) PetscCall(MatMPIAIJGetSeqAIJ(M, &dA, &oA, NULL)); 76906977982Sstefanozampini PetscCall(MatSetValuesCOOFromCSRMatrix_Private(dA, dH)); 77006977982Sstefanozampini if (oA) PetscCall(MatSetValuesCOOFromCSRMatrix_Private(oA, oH)); 77106977982Sstefanozampini M->assembled = PETSC_TRUE; 77206977982Sstefanozampini if (reuse == MAT_INPLACE_MATRIX) PetscCall(MatHeaderReplace(A, &M)); 7733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 77463c07aadSStefano Zampini } 77563c07aadSStefano Zampini 776d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAIJGetParCSR_Private(Mat A, hypre_ParCSRMatrix **hA) 777d71ae5a4SJacob Faibussowitsch { 778613e5ff0Sstefano_zampini hypre_ParCSRMatrix *tA; 779c1a070e6SStefano Zampini hypre_CSRMatrix *hdiag, *hoffd; 780c1a070e6SStefano Zampini Mat_SeqAIJ *diag, *offd; 7812cf14000SStefano Zampini PetscInt *garray, i, noffd, dnnz, onnz, *row_starts, *col_starts; 782c1a070e6SStefano Zampini MPI_Comm comm = PetscObjectComm((PetscObject)A); 783613e5ff0Sstefano_zampini PetscBool ismpiaij, isseqaij; 7842cf14000SStefano Zampini PetscBool sameint = (PetscBool)(sizeof(PetscInt) == sizeof(HYPRE_Int)); 7856ea7df73SStefano Zampini HYPRE_Int *hdi = NULL, *hdj = NULL, *hoi = NULL, *hoj = NULL; 7865c97c10fSStefano Zampini PetscInt *pdi = NULL, *pdj = NULL, *poi = NULL, *poj = NULL; 78706977982Sstefanozampini PetscBool iscuda, iship; 78806977982Sstefanozampini #if defined(PETSC_HAVE_DEVICE) && defined(PETSC_HAVE_HYPRE_DEVICE) 78906977982Sstefanozampini PetscBool boundtocpu = A->boundtocpu; 79006977982Sstefanozampini #else 79106977982Sstefanozampini PetscBool boundtocpu = PETSC_TRUE; 7926ea7df73SStefano Zampini #endif 793c1a070e6SStefano Zampini 794c1a070e6SStefano Zampini PetscFunctionBegin; 7959566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIAIJ, &ismpiaij)); 7969566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATSEQAIJ, &isseqaij)); 79708401ef6SPierre Jolivet PetscCheck(ismpiaij || isseqaij, comm, PETSC_ERR_SUP, "Unsupported type %s", ((PetscObject)A)->type_name); 79806977982Sstefanozampini PetscCall(PetscObjectTypeCompareAny((PetscObject)A, &iscuda, MATSEQAIJHIPSPARSE, MATMPIAIJCUSPARSE, "")); 79906977982Sstefanozampini PetscCall(PetscObjectTypeCompareAny((PetscObject)A, &iship, MATSEQAIJCUSPARSE, MATMPIAIJHIPSPARSE, "")); 800ea9ee2c1SPierre Jolivet PetscHYPREInitialize(); 801c1a070e6SStefano Zampini if (ismpiaij) { 802f4f49eeaSPierre Jolivet Mat_MPIAIJ *a = (Mat_MPIAIJ *)A->data; 803c1a070e6SStefano Zampini 804c1a070e6SStefano Zampini diag = (Mat_SeqAIJ *)a->A->data; 805c1a070e6SStefano Zampini offd = (Mat_SeqAIJ *)a->B->data; 80606977982Sstefanozampini if (!boundtocpu && (iscuda || iship)) { 80706977982Sstefanozampini #if defined(HYPRE_USING_CUDA) && defined(PETSC_HAVE_CUDA) 80806977982Sstefanozampini if (iscuda) { 8096ea7df73SStefano Zampini sameint = PETSC_TRUE; 8109566063dSJacob Faibussowitsch PetscCall(MatSeqAIJCUSPARSEGetIJ(a->A, PETSC_FALSE, (const HYPRE_Int **)&hdi, (const HYPRE_Int **)&hdj)); 8119566063dSJacob Faibussowitsch PetscCall(MatSeqAIJCUSPARSEGetIJ(a->B, PETSC_FALSE, (const HYPRE_Int **)&hoi, (const HYPRE_Int **)&hoj)); 81206977982Sstefanozampini } 8136ea7df73SStefano Zampini #endif 81406977982Sstefanozampini #if defined(HYPRE_USING_HIP) && defined(PETSC_HAVE_HIP) 81506977982Sstefanozampini if (iship) { 81606977982Sstefanozampini sameint = PETSC_TRUE; 81706977982Sstefanozampini PetscCall(MatSeqAIJHIPSPARSEGetIJ(a->A, PETSC_FALSE, (const HYPRE_Int **)&hdi, (const HYPRE_Int **)&hdj)); 81806977982Sstefanozampini PetscCall(MatSeqAIJHIPSPARSEGetIJ(a->B, PETSC_FALSE, (const HYPRE_Int **)&hoi, (const HYPRE_Int **)&hoj)); 81906977982Sstefanozampini } 82006977982Sstefanozampini #endif 82106977982Sstefanozampini } else { 82206977982Sstefanozampini boundtocpu = PETSC_TRUE; 8236ea7df73SStefano Zampini pdi = diag->i; 8246ea7df73SStefano Zampini pdj = diag->j; 8256ea7df73SStefano Zampini poi = offd->i; 8266ea7df73SStefano Zampini poj = offd->j; 8276ea7df73SStefano Zampini if (sameint) { 8286ea7df73SStefano Zampini hdi = (HYPRE_Int *)pdi; 8296ea7df73SStefano Zampini hdj = (HYPRE_Int *)pdj; 8306ea7df73SStefano Zampini hoi = (HYPRE_Int *)poi; 8316ea7df73SStefano Zampini hoj = (HYPRE_Int *)poj; 8326ea7df73SStefano Zampini } 8336ea7df73SStefano Zampini } 834c1a070e6SStefano Zampini garray = a->garray; 835c1a070e6SStefano Zampini noffd = a->B->cmap->N; 836c1a070e6SStefano Zampini dnnz = diag->nz; 837c1a070e6SStefano Zampini onnz = offd->nz; 838c1a070e6SStefano Zampini } else { 839c1a070e6SStefano Zampini diag = (Mat_SeqAIJ *)A->data; 840c1a070e6SStefano Zampini offd = NULL; 84106977982Sstefanozampini if (!boundtocpu && (iscuda || iship)) { 84206977982Sstefanozampini #if defined(HYPRE_USING_CUDA) && defined(PETSC_HAVE_CUDA) 84306977982Sstefanozampini if (iscuda) { 8446ea7df73SStefano Zampini sameint = PETSC_TRUE; 8459566063dSJacob Faibussowitsch PetscCall(MatSeqAIJCUSPARSEGetIJ(A, PETSC_FALSE, (const HYPRE_Int **)&hdi, (const HYPRE_Int **)&hdj)); 84606977982Sstefanozampini } 8476ea7df73SStefano Zampini #endif 84806977982Sstefanozampini #if defined(HYPRE_USING_HIP) && defined(PETSC_HAVE_HIP) 84906977982Sstefanozampini if (iship) { 85006977982Sstefanozampini sameint = PETSC_TRUE; 85106977982Sstefanozampini PetscCall(MatSeqAIJHIPSPARSEGetIJ(A, PETSC_FALSE, (const HYPRE_Int **)&hdi, (const HYPRE_Int **)&hdj)); 85206977982Sstefanozampini } 85306977982Sstefanozampini #endif 85406977982Sstefanozampini } else { 85506977982Sstefanozampini boundtocpu = PETSC_TRUE; 8566ea7df73SStefano Zampini pdi = diag->i; 8576ea7df73SStefano Zampini pdj = diag->j; 8586ea7df73SStefano Zampini if (sameint) { 8596ea7df73SStefano Zampini hdi = (HYPRE_Int *)pdi; 8606ea7df73SStefano Zampini hdj = (HYPRE_Int *)pdj; 8616ea7df73SStefano Zampini } 8626ea7df73SStefano Zampini } 863c1a070e6SStefano Zampini garray = NULL; 864c1a070e6SStefano Zampini noffd = 0; 865c1a070e6SStefano Zampini dnnz = diag->nz; 866c1a070e6SStefano Zampini onnz = 0; 867c1a070e6SStefano Zampini } 868225daaf8SStefano Zampini 869c1a070e6SStefano Zampini /* create a temporary ParCSR */ 870c1a070e6SStefano Zampini if (HYPRE_AssumedPartitionCheck()) { 871c1a070e6SStefano Zampini PetscMPIInt myid; 872c1a070e6SStefano Zampini 8739566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &myid)); 874c1a070e6SStefano Zampini row_starts = A->rmap->range + myid; 875c1a070e6SStefano Zampini col_starts = A->cmap->range + myid; 876c1a070e6SStefano Zampini } else { 877c1a070e6SStefano Zampini row_starts = A->rmap->range; 878c1a070e6SStefano Zampini col_starts = A->cmap->range; 879c1a070e6SStefano Zampini } 8802cf14000SStefano Zampini tA = hypre_ParCSRMatrixCreate(comm, A->rmap->N, A->cmap->N, (HYPRE_BigInt *)row_starts, (HYPRE_BigInt *)col_starts, noffd, dnnz, onnz); 881a1d2239cSSatish Balay #if defined(hypre_ParCSRMatrixOwnsRowStarts) 882c1a070e6SStefano Zampini hypre_ParCSRMatrixSetRowStartsOwner(tA, 0); 883c1a070e6SStefano Zampini hypre_ParCSRMatrixSetColStartsOwner(tA, 0); 884a1d2239cSSatish Balay #endif 885c1a070e6SStefano Zampini 886225daaf8SStefano Zampini /* set diagonal part */ 887c1a070e6SStefano Zampini hdiag = hypre_ParCSRMatrixDiag(tA); 8886ea7df73SStefano Zampini if (!sameint) { /* malloc CSR pointers */ 8899566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(A->rmap->n + 1, &hdi, dnnz, &hdj)); 890f4f49eeaSPierre Jolivet for (i = 0; i < A->rmap->n + 1; i++) hdi[i] = (HYPRE_Int)pdi[i]; 891f4f49eeaSPierre Jolivet for (i = 0; i < dnnz; i++) hdj[i] = (HYPRE_Int)pdj[i]; 8922cf14000SStefano Zampini } 8936ea7df73SStefano Zampini hypre_CSRMatrixI(hdiag) = hdi; 8946ea7df73SStefano Zampini hypre_CSRMatrixJ(hdiag) = hdj; 89539accc25SStefano Zampini hypre_CSRMatrixData(hdiag) = (HYPRE_Complex *)diag->a; 896c1a070e6SStefano Zampini hypre_CSRMatrixNumNonzeros(hdiag) = diag->nz; 897c1a070e6SStefano Zampini hypre_CSRMatrixSetRownnz(hdiag); 898c1a070e6SStefano Zampini hypre_CSRMatrixSetDataOwner(hdiag, 0); 899c1a070e6SStefano Zampini 9004cf0e950SBarry Smith /* set off-diagonal part */ 901c1a070e6SStefano Zampini hoffd = hypre_ParCSRMatrixOffd(tA); 902c1a070e6SStefano Zampini if (offd) { 9036ea7df73SStefano Zampini if (!sameint) { /* malloc CSR pointers */ 9049566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(A->rmap->n + 1, &hoi, onnz, &hoj)); 905f4f49eeaSPierre Jolivet for (i = 0; i < A->rmap->n + 1; i++) hoi[i] = (HYPRE_Int)poi[i]; 906f4f49eeaSPierre Jolivet for (i = 0; i < onnz; i++) hoj[i] = (HYPRE_Int)poj[i]; 9072cf14000SStefano Zampini } 9086ea7df73SStefano Zampini hypre_CSRMatrixI(hoffd) = hoi; 9096ea7df73SStefano Zampini hypre_CSRMatrixJ(hoffd) = hoj; 91039accc25SStefano Zampini hypre_CSRMatrixData(hoffd) = (HYPRE_Complex *)offd->a; 911c1a070e6SStefano Zampini hypre_CSRMatrixNumNonzeros(hoffd) = offd->nz; 912c1a070e6SStefano Zampini hypre_CSRMatrixSetRownnz(hoffd); 913c1a070e6SStefano Zampini hypre_CSRMatrixSetDataOwner(hoffd, 0); 9146ea7df73SStefano Zampini } 9156ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 91606977982Sstefanozampini PetscCallExternal(hypre_ParCSRMatrixInitialize_v2, tA, !boundtocpu ? HYPRE_MEMORY_DEVICE : HYPRE_MEMORY_HOST); 9176ea7df73SStefano Zampini #else 9186ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_LT(2, 18, 0) 919792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixInitialize, tA); 9206ea7df73SStefano Zampini #else 921792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixInitialize_v2, tA, HYPRE_MEMORY_HOST); 9226ea7df73SStefano Zampini #endif 9236ea7df73SStefano Zampini #endif 9246ea7df73SStefano Zampini hypre_TFree(hypre_ParCSRMatrixColMapOffd(tA), HYPRE_MEMORY_HOST); 925c1a070e6SStefano Zampini hypre_ParCSRMatrixSetNumNonzeros(tA); 9262cf14000SStefano Zampini hypre_ParCSRMatrixColMapOffd(tA) = (HYPRE_BigInt *)garray; 927792fecdfSBarry Smith if (!hypre_ParCSRMatrixCommPkg(tA)) PetscCallExternal(hypre_MatvecCommPkgCreate, tA); 928613e5ff0Sstefano_zampini *hA = tA; 9293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 930613e5ff0Sstefano_zampini } 931c1a070e6SStefano Zampini 932d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAIJRestoreParCSR_Private(Mat A, hypre_ParCSRMatrix **hA) 933d71ae5a4SJacob Faibussowitsch { 934613e5ff0Sstefano_zampini hypre_CSRMatrix *hdiag, *hoffd; 9356ea7df73SStefano Zampini PetscBool ismpiaij, sameint = (PetscBool)(sizeof(PetscInt) == sizeof(HYPRE_Int)); 9366ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 9376ea7df73SStefano Zampini PetscBool iscuda = PETSC_FALSE; 9386ea7df73SStefano Zampini #endif 939c1a070e6SStefano Zampini 940613e5ff0Sstefano_zampini PetscFunctionBegin; 9419566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIAIJ, &ismpiaij)); 9426ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 9439566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)A, &iscuda, MATSEQAIJCUSPARSE, MATMPIAIJCUSPARSE, "")); 9446ea7df73SStefano Zampini if (iscuda) sameint = PETSC_TRUE; 9456ea7df73SStefano Zampini #endif 946613e5ff0Sstefano_zampini hdiag = hypre_ParCSRMatrixDiag(*hA); 947613e5ff0Sstefano_zampini hoffd = hypre_ParCSRMatrixOffd(*hA); 9486ea7df73SStefano Zampini /* free temporary memory allocated by PETSc 9496ea7df73SStefano Zampini set pointers to NULL before destroying tA */ 9502cf14000SStefano Zampini if (!sameint) { 9512cf14000SStefano Zampini HYPRE_Int *hi, *hj; 9522cf14000SStefano Zampini 9532cf14000SStefano Zampini hi = hypre_CSRMatrixI(hdiag); 9542cf14000SStefano Zampini hj = hypre_CSRMatrixJ(hdiag); 9559566063dSJacob Faibussowitsch PetscCall(PetscFree2(hi, hj)); 9566ea7df73SStefano Zampini if (ismpiaij) { 9572cf14000SStefano Zampini hi = hypre_CSRMatrixI(hoffd); 9582cf14000SStefano Zampini hj = hypre_CSRMatrixJ(hoffd); 9599566063dSJacob Faibussowitsch PetscCall(PetscFree2(hi, hj)); 9602cf14000SStefano Zampini } 9612cf14000SStefano Zampini } 962c1a070e6SStefano Zampini hypre_CSRMatrixI(hdiag) = NULL; 963c1a070e6SStefano Zampini hypre_CSRMatrixJ(hdiag) = NULL; 964c1a070e6SStefano Zampini hypre_CSRMatrixData(hdiag) = NULL; 9656ea7df73SStefano Zampini if (ismpiaij) { 966c1a070e6SStefano Zampini hypre_CSRMatrixI(hoffd) = NULL; 967c1a070e6SStefano Zampini hypre_CSRMatrixJ(hoffd) = NULL; 968c1a070e6SStefano Zampini hypre_CSRMatrixData(hoffd) = NULL; 9696ea7df73SStefano Zampini } 970613e5ff0Sstefano_zampini hypre_ParCSRMatrixColMapOffd(*hA) = NULL; 971613e5ff0Sstefano_zampini hypre_ParCSRMatrixDestroy(*hA); 972613e5ff0Sstefano_zampini *hA = NULL; 9733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 974613e5ff0Sstefano_zampini } 975613e5ff0Sstefano_zampini 976613e5ff0Sstefano_zampini /* calls RAP from BoomerAMG: 9773dad0653Sstefano_zampini the resulting ParCSR will not own the column and row starts 9786ea7df73SStefano Zampini It looks like we don't need to have the diagonal entries ordered first */ 979d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatHYPRE_ParCSR_RAP(hypre_ParCSRMatrix *hR, hypre_ParCSRMatrix *hA, hypre_ParCSRMatrix *hP, hypre_ParCSRMatrix **hRAP) 980d71ae5a4SJacob Faibussowitsch { 981a1d2239cSSatish Balay #if defined(hypre_ParCSRMatrixOwnsRowStarts) 982613e5ff0Sstefano_zampini HYPRE_Int P_owns_col_starts, R_owns_row_starts; 983a1d2239cSSatish Balay #endif 984613e5ff0Sstefano_zampini 985613e5ff0Sstefano_zampini PetscFunctionBegin; 986a1d2239cSSatish Balay #if defined(hypre_ParCSRMatrixOwnsRowStarts) 987613e5ff0Sstefano_zampini P_owns_col_starts = hypre_ParCSRMatrixOwnsColStarts(hP); 988613e5ff0Sstefano_zampini R_owns_row_starts = hypre_ParCSRMatrixOwnsRowStarts(hR); 989a1d2239cSSatish Balay #endif 9906ea7df73SStefano Zampini /* can be replaced by version test later */ 9916ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 992792fecdfSBarry Smith PetscStackPushExternal("hypre_ParCSRMatrixRAP"); 9936ea7df73SStefano Zampini *hRAP = hypre_ParCSRMatrixRAP(hR, hA, hP); 9946ea7df73SStefano Zampini PetscStackPop; 9956ea7df73SStefano Zampini #else 996792fecdfSBarry Smith PetscCallExternal(hypre_BoomerAMGBuildCoarseOperator, hR, hA, hP, hRAP); 997792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixSetNumNonzeros, *hRAP); 9986ea7df73SStefano Zampini #endif 999613e5ff0Sstefano_zampini /* hypre_BoomerAMGBuildCoarseOperator steals the col_starts from P and the row_starts from R */ 1000a1d2239cSSatish Balay #if defined(hypre_ParCSRMatrixOwnsRowStarts) 1001613e5ff0Sstefano_zampini hypre_ParCSRMatrixSetRowStartsOwner(*hRAP, 0); 1002613e5ff0Sstefano_zampini hypre_ParCSRMatrixSetColStartsOwner(*hRAP, 0); 1003613e5ff0Sstefano_zampini if (P_owns_col_starts) hypre_ParCSRMatrixSetColStartsOwner(hP, 1); 1004613e5ff0Sstefano_zampini if (R_owns_row_starts) hypre_ParCSRMatrixSetRowStartsOwner(hR, 1); 1005a1d2239cSSatish Balay #endif 10063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1007613e5ff0Sstefano_zampini } 1008613e5ff0Sstefano_zampini 1009d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatPtAPNumeric_AIJ_AIJ_wHYPRE(Mat A, Mat P, Mat C) 1010d71ae5a4SJacob Faibussowitsch { 10116f231fbdSstefano_zampini Mat B; 10126abb4441SStefano Zampini hypre_ParCSRMatrix *hA, *hP, *hPtAP = NULL; 10134222ddf1SHong Zhang Mat_Product *product = C->product; 1014613e5ff0Sstefano_zampini 1015613e5ff0Sstefano_zampini PetscFunctionBegin; 10169566063dSJacob Faibussowitsch PetscCall(MatAIJGetParCSR_Private(A, &hA)); 10179566063dSJacob Faibussowitsch PetscCall(MatAIJGetParCSR_Private(P, &hP)); 10189566063dSJacob Faibussowitsch PetscCall(MatHYPRE_ParCSR_RAP(hP, hA, hP, &hPtAP)); 10199566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(hPtAP, MATAIJ, PETSC_OWN_POINTER, &B)); 10204222ddf1SHong Zhang 10219566063dSJacob Faibussowitsch PetscCall(MatHeaderMerge(C, &B)); 10224222ddf1SHong Zhang C->product = product; 10234222ddf1SHong Zhang 10249566063dSJacob Faibussowitsch PetscCall(MatAIJRestoreParCSR_Private(A, &hA)); 10259566063dSJacob Faibussowitsch PetscCall(MatAIJRestoreParCSR_Private(P, &hP)); 10263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 10276f231fbdSstefano_zampini } 10286f231fbdSstefano_zampini 1029d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatPtAPSymbolic_AIJ_AIJ_wHYPRE(Mat A, Mat P, PetscReal fill, Mat C) 1030d71ae5a4SJacob Faibussowitsch { 10316f231fbdSstefano_zampini PetscFunctionBegin; 10329566063dSJacob Faibussowitsch PetscCall(MatSetType(C, MATAIJ)); 10334222ddf1SHong Zhang C->ops->ptapnumeric = MatPtAPNumeric_AIJ_AIJ_wHYPRE; 10344222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_PtAP; 10353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1036613e5ff0Sstefano_zampini } 1037613e5ff0Sstefano_zampini 1038d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatPtAPNumeric_AIJ_HYPRE(Mat A, Mat P, Mat C) 1039d71ae5a4SJacob Faibussowitsch { 10404cc28894Sstefano_zampini Mat B; 10414cc28894Sstefano_zampini Mat_HYPRE *hP; 10426abb4441SStefano Zampini hypre_ParCSRMatrix *hA = NULL, *Pparcsr, *ptapparcsr = NULL; 1043613e5ff0Sstefano_zampini HYPRE_Int type; 1044613e5ff0Sstefano_zampini MPI_Comm comm = PetscObjectComm((PetscObject)A); 10454cc28894Sstefano_zampini PetscBool ishypre; 1046613e5ff0Sstefano_zampini 1047613e5ff0Sstefano_zampini PetscFunctionBegin; 10489566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)P, MATHYPRE, &ishypre)); 104928b400f6SJacob Faibussowitsch PetscCheck(ishypre, comm, PETSC_ERR_USER, "P should be of type %s", MATHYPRE); 10504cc28894Sstefano_zampini hP = (Mat_HYPRE *)P->data; 1051792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObjectType, hP->ij, &type); 105208401ef6SPierre Jolivet PetscCheck(type == HYPRE_PARCSR, comm, PETSC_ERR_SUP, "Only HYPRE_PARCSR is supported"); 1053792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hP->ij, (void **)&Pparcsr); 1054613e5ff0Sstefano_zampini 10559566063dSJacob Faibussowitsch PetscCall(MatAIJGetParCSR_Private(A, &hA)); 10569566063dSJacob Faibussowitsch PetscCall(MatHYPRE_ParCSR_RAP(Pparcsr, hA, Pparcsr, &ptapparcsr)); 10579566063dSJacob Faibussowitsch PetscCall(MatAIJRestoreParCSR_Private(A, &hA)); 1058225daaf8SStefano Zampini 10594cc28894Sstefano_zampini /* create temporary matrix and merge to C */ 10609566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(ptapparcsr, ((PetscObject)C)->type_name, PETSC_OWN_POINTER, &B)); 10619566063dSJacob Faibussowitsch PetscCall(MatHeaderMerge(C, &B)); 10623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 10634cc28894Sstefano_zampini } 10644cc28894Sstefano_zampini 1065d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatPtAPNumeric_HYPRE_HYPRE(Mat A, Mat P, Mat C) 1066d71ae5a4SJacob Faibussowitsch { 10674cc28894Sstefano_zampini Mat B; 10686abb4441SStefano Zampini hypre_ParCSRMatrix *Aparcsr, *Pparcsr, *ptapparcsr = NULL; 10694cc28894Sstefano_zampini Mat_HYPRE *hA, *hP; 10704cc28894Sstefano_zampini PetscBool ishypre; 10714cc28894Sstefano_zampini HYPRE_Int type; 10724cc28894Sstefano_zampini 10734cc28894Sstefano_zampini PetscFunctionBegin; 10749566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)P, MATHYPRE, &ishypre)); 107528b400f6SJacob Faibussowitsch PetscCheck(ishypre, PetscObjectComm((PetscObject)P), PETSC_ERR_USER, "P should be of type %s", MATHYPRE); 10769566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A, MATHYPRE, &ishypre)); 107728b400f6SJacob Faibussowitsch PetscCheck(ishypre, PetscObjectComm((PetscObject)A), PETSC_ERR_USER, "A should be of type %s", MATHYPRE); 10784cc28894Sstefano_zampini hA = (Mat_HYPRE *)A->data; 10794cc28894Sstefano_zampini hP = (Mat_HYPRE *)P->data; 1080792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObjectType, hA->ij, &type); 108108401ef6SPierre Jolivet PetscCheck(type == HYPRE_PARCSR, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Only HYPRE_PARCSR is supported"); 1082792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObjectType, hP->ij, &type); 108308401ef6SPierre Jolivet PetscCheck(type == HYPRE_PARCSR, PetscObjectComm((PetscObject)P), PETSC_ERR_SUP, "Only HYPRE_PARCSR is supported"); 1084792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hA->ij, (void **)&Aparcsr); 1085792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hP->ij, (void **)&Pparcsr); 10869566063dSJacob Faibussowitsch PetscCall(MatHYPRE_ParCSR_RAP(Pparcsr, Aparcsr, Pparcsr, &ptapparcsr)); 10879566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(ptapparcsr, MATHYPRE, PETSC_OWN_POINTER, &B)); 10889566063dSJacob Faibussowitsch PetscCall(MatHeaderMerge(C, &B)); 10893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 10904cc28894Sstefano_zampini } 10914cc28894Sstefano_zampini 1092d501dc42Sstefano_zampini /* calls hypre_ParMatmul 1093d501dc42Sstefano_zampini hypre_ParMatMul uses hypre_ParMatrixCreate with the communicator of hA 10943dad0653Sstefano_zampini hypre_ParMatrixCreate does not duplicate the communicator 10956ea7df73SStefano Zampini It looks like we don't need to have the diagonal entries ordered first */ 1096d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatHYPRE_ParCSR_MatMatMult(hypre_ParCSRMatrix *hA, hypre_ParCSRMatrix *hB, hypre_ParCSRMatrix **hAB) 1097d71ae5a4SJacob Faibussowitsch { 1098d501dc42Sstefano_zampini PetscFunctionBegin; 10996ea7df73SStefano Zampini /* can be replaced by version test later */ 11006ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 1101792fecdfSBarry Smith PetscStackPushExternal("hypre_ParCSRMatMat"); 11026ea7df73SStefano Zampini *hAB = hypre_ParCSRMatMat(hA, hB); 11036ea7df73SStefano Zampini #else 1104792fecdfSBarry Smith PetscStackPushExternal("hypre_ParMatmul"); 1105d501dc42Sstefano_zampini *hAB = hypre_ParMatmul(hA, hB); 11066ea7df73SStefano Zampini #endif 1107d501dc42Sstefano_zampini PetscStackPop; 11083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1109d501dc42Sstefano_zampini } 1110d501dc42Sstefano_zampini 1111d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatMultNumeric_AIJ_AIJ_wHYPRE(Mat A, Mat B, Mat C) 1112d71ae5a4SJacob Faibussowitsch { 11135e5acdf2Sstefano_zampini Mat D; 1114d501dc42Sstefano_zampini hypre_ParCSRMatrix *hA, *hB, *hAB = NULL; 11154222ddf1SHong Zhang Mat_Product *product = C->product; 11165e5acdf2Sstefano_zampini 11175e5acdf2Sstefano_zampini PetscFunctionBegin; 11189566063dSJacob Faibussowitsch PetscCall(MatAIJGetParCSR_Private(A, &hA)); 11199566063dSJacob Faibussowitsch PetscCall(MatAIJGetParCSR_Private(B, &hB)); 11209566063dSJacob Faibussowitsch PetscCall(MatHYPRE_ParCSR_MatMatMult(hA, hB, &hAB)); 11219566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(hAB, MATAIJ, PETSC_OWN_POINTER, &D)); 11224222ddf1SHong Zhang 11239566063dSJacob Faibussowitsch PetscCall(MatHeaderMerge(C, &D)); 11244222ddf1SHong Zhang C->product = product; 11254222ddf1SHong Zhang 11269566063dSJacob Faibussowitsch PetscCall(MatAIJRestoreParCSR_Private(A, &hA)); 11279566063dSJacob Faibussowitsch PetscCall(MatAIJRestoreParCSR_Private(B, &hB)); 11283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 11295e5acdf2Sstefano_zampini } 11305e5acdf2Sstefano_zampini 1131d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatMatMultSymbolic_AIJ_AIJ_wHYPRE(Mat A, Mat B, PetscReal fill, Mat C) 1132d71ae5a4SJacob Faibussowitsch { 11335e5acdf2Sstefano_zampini PetscFunctionBegin; 11349566063dSJacob Faibussowitsch PetscCall(MatSetType(C, MATAIJ)); 11354222ddf1SHong Zhang C->ops->matmultnumeric = MatMatMultNumeric_AIJ_AIJ_wHYPRE; 11364222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_AB; 11373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 11385e5acdf2Sstefano_zampini } 11395e5acdf2Sstefano_zampini 1140d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatMultNumeric_HYPRE_HYPRE(Mat A, Mat B, Mat C) 1141d71ae5a4SJacob Faibussowitsch { 1142d501dc42Sstefano_zampini Mat D; 1143d501dc42Sstefano_zampini hypre_ParCSRMatrix *Aparcsr, *Bparcsr, *ABparcsr = NULL; 1144d501dc42Sstefano_zampini Mat_HYPRE *hA, *hB; 1145d501dc42Sstefano_zampini PetscBool ishypre; 1146d501dc42Sstefano_zampini HYPRE_Int type; 11474222ddf1SHong Zhang Mat_Product *product; 1148d501dc42Sstefano_zampini 1149d501dc42Sstefano_zampini PetscFunctionBegin; 11509566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, MATHYPRE, &ishypre)); 115128b400f6SJacob Faibussowitsch PetscCheck(ishypre, PetscObjectComm((PetscObject)B), PETSC_ERR_USER, "B should be of type %s", MATHYPRE); 11529566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A, MATHYPRE, &ishypre)); 115328b400f6SJacob Faibussowitsch PetscCheck(ishypre, PetscObjectComm((PetscObject)A), PETSC_ERR_USER, "A should be of type %s", MATHYPRE); 1154d501dc42Sstefano_zampini hA = (Mat_HYPRE *)A->data; 1155d501dc42Sstefano_zampini hB = (Mat_HYPRE *)B->data; 1156792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObjectType, hA->ij, &type); 115708401ef6SPierre Jolivet PetscCheck(type == HYPRE_PARCSR, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Only HYPRE_PARCSR is supported"); 1158792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObjectType, hB->ij, &type); 115908401ef6SPierre Jolivet PetscCheck(type == HYPRE_PARCSR, PetscObjectComm((PetscObject)B), PETSC_ERR_SUP, "Only HYPRE_PARCSR is supported"); 1160792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hA->ij, (void **)&Aparcsr); 1161792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hB->ij, (void **)&Bparcsr); 11629566063dSJacob Faibussowitsch PetscCall(MatHYPRE_ParCSR_MatMatMult(Aparcsr, Bparcsr, &ABparcsr)); 11639566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(ABparcsr, MATHYPRE, PETSC_OWN_POINTER, &D)); 11644222ddf1SHong Zhang 1165d501dc42Sstefano_zampini /* need to use HeaderReplace because HeaderMerge messes up with the communicator */ 11664222ddf1SHong Zhang product = C->product; /* save it from MatHeaderReplace() */ 11674222ddf1SHong Zhang C->product = NULL; 11689566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(C, &D)); 11694222ddf1SHong Zhang C->product = product; 1170d501dc42Sstefano_zampini C->ops->matmultnumeric = MatMatMultNumeric_HYPRE_HYPRE; 11714222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_AB; 11723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1173d501dc42Sstefano_zampini } 1174d501dc42Sstefano_zampini 1175d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatTransposeMatMatMultNumeric_AIJ_AIJ_AIJ_wHYPRE(Mat A, Mat B, Mat C, Mat D) 1176d71ae5a4SJacob Faibussowitsch { 117720e1dc0dSstefano_zampini Mat E; 11786abb4441SStefano Zampini hypre_ParCSRMatrix *hA, *hB, *hC, *hABC = NULL; 117920e1dc0dSstefano_zampini 118020e1dc0dSstefano_zampini PetscFunctionBegin; 11819566063dSJacob Faibussowitsch PetscCall(MatAIJGetParCSR_Private(A, &hA)); 11829566063dSJacob Faibussowitsch PetscCall(MatAIJGetParCSR_Private(B, &hB)); 11839566063dSJacob Faibussowitsch PetscCall(MatAIJGetParCSR_Private(C, &hC)); 11849566063dSJacob Faibussowitsch PetscCall(MatHYPRE_ParCSR_RAP(hA, hB, hC, &hABC)); 11859566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(hABC, MATAIJ, PETSC_OWN_POINTER, &E)); 11869566063dSJacob Faibussowitsch PetscCall(MatHeaderMerge(D, &E)); 11879566063dSJacob Faibussowitsch PetscCall(MatAIJRestoreParCSR_Private(A, &hA)); 11889566063dSJacob Faibussowitsch PetscCall(MatAIJRestoreParCSR_Private(B, &hB)); 11899566063dSJacob Faibussowitsch PetscCall(MatAIJRestoreParCSR_Private(C, &hC)); 11903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 119120e1dc0dSstefano_zampini } 119220e1dc0dSstefano_zampini 1193d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatTransposeMatMatMultSymbolic_AIJ_AIJ_AIJ_wHYPRE(Mat A, Mat B, Mat C, PetscReal fill, Mat D) 1194d71ae5a4SJacob Faibussowitsch { 119520e1dc0dSstefano_zampini PetscFunctionBegin; 11969566063dSJacob Faibussowitsch PetscCall(MatSetType(D, MATAIJ)); 11973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 119820e1dc0dSstefano_zampini } 119920e1dc0dSstefano_zampini 1200d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSymbolic_AB_HYPRE(Mat C) 1201d71ae5a4SJacob Faibussowitsch { 12024222ddf1SHong Zhang PetscFunctionBegin; 12034222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_AB; 12043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12054222ddf1SHong Zhang } 12064222ddf1SHong Zhang 1207d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_HYPRE_AB(Mat C) 1208d71ae5a4SJacob Faibussowitsch { 12094222ddf1SHong Zhang Mat_Product *product = C->product; 12104222ddf1SHong Zhang PetscBool Ahypre; 12114222ddf1SHong Zhang 12124222ddf1SHong Zhang PetscFunctionBegin; 12139566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)product->A, MATHYPRE, &Ahypre)); 12144222ddf1SHong Zhang if (Ahypre) { /* A is a Hypre matrix */ 12159566063dSJacob Faibussowitsch PetscCall(MatSetType(C, MATHYPRE)); 12164222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AB_HYPRE; 12174222ddf1SHong Zhang C->ops->matmultnumeric = MatMatMultNumeric_HYPRE_HYPRE; 12183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12196718818eSStefano Zampini } 12203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12214222ddf1SHong Zhang } 12224222ddf1SHong Zhang 1223d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSymbolic_PtAP_HYPRE(Mat C) 1224d71ae5a4SJacob Faibussowitsch { 12254222ddf1SHong Zhang PetscFunctionBegin; 12264222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_PtAP; 12273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12284222ddf1SHong Zhang } 12294222ddf1SHong Zhang 1230d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_HYPRE_PtAP(Mat C) 1231d71ae5a4SJacob Faibussowitsch { 12324222ddf1SHong Zhang Mat_Product *product = C->product; 12334222ddf1SHong Zhang PetscBool flg; 12344222ddf1SHong Zhang PetscInt type = 0; 12354222ddf1SHong Zhang const char *outTypes[4] = {"aij", "seqaij", "mpiaij", "hypre"}; 12364222ddf1SHong Zhang PetscInt ntype = 4; 12374222ddf1SHong Zhang Mat A = product->A; 12384222ddf1SHong Zhang PetscBool Ahypre; 12394222ddf1SHong Zhang 12404222ddf1SHong Zhang PetscFunctionBegin; 12419566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A, MATHYPRE, &Ahypre)); 12424222ddf1SHong Zhang if (Ahypre) { /* A is a Hypre matrix */ 12439566063dSJacob Faibussowitsch PetscCall(MatSetType(C, MATHYPRE)); 12444222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_PtAP_HYPRE; 12454222ddf1SHong Zhang C->ops->ptapnumeric = MatPtAPNumeric_HYPRE_HYPRE; 12463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12474222ddf1SHong Zhang } 12484222ddf1SHong Zhang 12494222ddf1SHong Zhang /* A is AIJ, P is Hypre, C = PtAP can be either AIJ or Hypre format */ 12504222ddf1SHong Zhang /* Get runtime option */ 12514222ddf1SHong Zhang if (product->api_user) { 1252d0609cedSBarry Smith PetscOptionsBegin(PetscObjectComm((PetscObject)C), ((PetscObject)C)->prefix, "MatPtAP_HYPRE", "Mat"); 12539566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-matptap_hypre_outtype", "MatPtAP outtype", "MatPtAP outtype", outTypes, ntype, outTypes[type], &type, &flg)); 1254d0609cedSBarry Smith PetscOptionsEnd(); 12554222ddf1SHong Zhang } else { 1256d0609cedSBarry Smith PetscOptionsBegin(PetscObjectComm((PetscObject)C), ((PetscObject)C)->prefix, "MatProduct_PtAP_HYPRE", "Mat"); 12579566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-mat_product_algorithm_hypre_outtype", "MatProduct_PtAP outtype", "MatProduct_PtAP", outTypes, ntype, outTypes[type], &type, &flg)); 1258d0609cedSBarry Smith PetscOptionsEnd(); 12594222ddf1SHong Zhang } 12604222ddf1SHong Zhang 12614222ddf1SHong Zhang if (type == 0 || type == 1 || type == 2) { 12629566063dSJacob Faibussowitsch PetscCall(MatSetType(C, MATAIJ)); 12634222ddf1SHong Zhang } else if (type == 3) { 12649566063dSJacob Faibussowitsch PetscCall(MatSetType(C, MATHYPRE)); 12654222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)C), PETSC_ERR_SUP, "MatPtAP outtype is not supported"); 12664222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_PtAP_HYPRE; 12674222ddf1SHong Zhang C->ops->ptapnumeric = MatPtAPNumeric_AIJ_HYPRE; 12683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12694222ddf1SHong Zhang } 12704222ddf1SHong Zhang 1271d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_HYPRE(Mat C) 1272d71ae5a4SJacob Faibussowitsch { 12734222ddf1SHong Zhang Mat_Product *product = C->product; 12744222ddf1SHong Zhang 12754222ddf1SHong Zhang PetscFunctionBegin; 12764222ddf1SHong Zhang switch (product->type) { 1277d71ae5a4SJacob Faibussowitsch case MATPRODUCT_AB: 1278d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_HYPRE_AB(C)); 1279d71ae5a4SJacob Faibussowitsch break; 1280d71ae5a4SJacob Faibussowitsch case MATPRODUCT_PtAP: 1281d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_HYPRE_PtAP(C)); 1282d71ae5a4SJacob Faibussowitsch break; 1283d71ae5a4SJacob Faibussowitsch default: 1284d71ae5a4SJacob Faibussowitsch break; 12854222ddf1SHong Zhang } 12863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12874222ddf1SHong Zhang } 12884222ddf1SHong Zhang 1289d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMultTranspose_HYPRE(Mat A, Vec x, Vec y) 1290d71ae5a4SJacob Faibussowitsch { 129163c07aadSStefano Zampini PetscFunctionBegin; 12929566063dSJacob Faibussowitsch PetscCall(MatHYPRE_MultKernel_Private(A, 1.0, x, 0.0, y, PETSC_TRUE)); 12933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 129463c07aadSStefano Zampini } 129563c07aadSStefano Zampini 1296d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMult_HYPRE(Mat A, Vec x, Vec y) 1297d71ae5a4SJacob Faibussowitsch { 129863c07aadSStefano Zampini PetscFunctionBegin; 12999566063dSJacob Faibussowitsch PetscCall(MatHYPRE_MultKernel_Private(A, 1.0, x, 0.0, y, PETSC_FALSE)); 13003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 130163c07aadSStefano Zampini } 130263c07aadSStefano Zampini 1303d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMultAdd_HYPRE(Mat A, Vec x, Vec y, Vec z) 1304d71ae5a4SJacob Faibussowitsch { 1305414bd5c3SStefano Zampini PetscFunctionBegin; 130648a46eb9SPierre Jolivet if (y != z) PetscCall(VecCopy(y, z)); 13079566063dSJacob Faibussowitsch PetscCall(MatHYPRE_MultKernel_Private(A, 1.0, x, 1.0, z, PETSC_FALSE)); 13083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1309414bd5c3SStefano Zampini } 1310414bd5c3SStefano Zampini 1311d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMultTransposeAdd_HYPRE(Mat A, Vec x, Vec y, Vec z) 1312d71ae5a4SJacob Faibussowitsch { 1313414bd5c3SStefano Zampini PetscFunctionBegin; 131448a46eb9SPierre Jolivet if (y != z) PetscCall(VecCopy(y, z)); 13159566063dSJacob Faibussowitsch PetscCall(MatHYPRE_MultKernel_Private(A, 1.0, x, 1.0, z, PETSC_TRUE)); 13163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1317414bd5c3SStefano Zampini } 1318414bd5c3SStefano Zampini 1319414bd5c3SStefano Zampini /* y = a * A * x + b * y or y = a * A^t * x + b * y depending on trans */ 1320d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatHYPRE_MultKernel_Private(Mat A, HYPRE_Complex a, Vec x, HYPRE_Complex b, Vec y, PetscBool trans) 1321d71ae5a4SJacob Faibussowitsch { 132263c07aadSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 132363c07aadSStefano Zampini hypre_ParCSRMatrix *parcsr; 132463c07aadSStefano Zampini hypre_ParVector *hx, *hy; 132563c07aadSStefano Zampini 132663c07aadSStefano Zampini PetscFunctionBegin; 132763c07aadSStefano Zampini if (trans) { 13289566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPushVecRead(hA->b, x)); 13299566063dSJacob Faibussowitsch if (b != 0.0) PetscCall(VecHYPRE_IJVectorPushVec(hA->x, y)); 13309566063dSJacob Faibussowitsch else PetscCall(VecHYPRE_IJVectorPushVecWrite(hA->x, y)); 1331792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hA->b->ij, (void **)&hx); 1332792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hA->x->ij, (void **)&hy); 133363c07aadSStefano Zampini } else { 13349566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPushVecRead(hA->x, x)); 13359566063dSJacob Faibussowitsch if (b != 0.0) PetscCall(VecHYPRE_IJVectorPushVec(hA->b, y)); 13369566063dSJacob Faibussowitsch else PetscCall(VecHYPRE_IJVectorPushVecWrite(hA->b, y)); 1337792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hA->x->ij, (void **)&hx); 1338792fecdfSBarry Smith PetscCallExternal(HYPRE_IJVectorGetObject, hA->b->ij, (void **)&hy); 133963c07aadSStefano Zampini } 1340792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hA->ij, (void **)&parcsr); 13416ea7df73SStefano Zampini if (trans) { 1342792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixMatvecT, a, parcsr, hx, b, hy); 13436ea7df73SStefano Zampini } else { 1344792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixMatvec, a, parcsr, hx, b, hy); 13456ea7df73SStefano Zampini } 13469566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hA->x)); 13479566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorPopVec(hA->b)); 13483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 134963c07aadSStefano Zampini } 135063c07aadSStefano Zampini 1351d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDestroy_HYPRE(Mat A) 1352d71ae5a4SJacob Faibussowitsch { 135363c07aadSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 135463c07aadSStefano Zampini 135563c07aadSStefano Zampini PetscFunctionBegin; 13569566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&hA->x)); 13579566063dSJacob Faibussowitsch PetscCall(VecHYPRE_IJVectorDestroy(&hA->b)); 135806977982Sstefanozampini PetscCall(MatHYPRE_DestroyCOOMat(A)); /* must be called before destroying the individual CSR */ 1359978814f1SStefano Zampini if (hA->ij) { 1360978814f1SStefano Zampini if (!hA->inner_free) hypre_IJMatrixObject(hA->ij) = NULL; 1361792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixDestroy, hA->ij); 1362978814f1SStefano Zampini } 13639566063dSJacob Faibussowitsch if (hA->comm) PetscCall(PetscCommRestoreComm(PetscObjectComm((PetscObject)A), &hA->comm)); 1364c69f721fSFande Kong 13659566063dSJacob Faibussowitsch PetscCall(MatStashDestroy_Private(&A->stash)); 13669566063dSJacob Faibussowitsch PetscCall(PetscFree(hA->array)); 1367a32e9c99SJunchao Zhang if (hA->rows_d) PetscStackCallExternalVoid("hypre_Free", hypre_Free(hA->rows_d, HYPRE_MEMORY_DEVICE)); 1368c69f721fSFande Kong 13699566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatConvert_hypre_aij_C", NULL)); 13709566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatConvert_hypre_is_C", NULL)); 13719566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatProductSetFromOptions_seqaij_hypre_C", NULL)); 13729566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatProductSetFromOptions_mpiaij_hypre_C", NULL)); 137306977982Sstefanozampini PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatProductSetFromOptions_seqaijhipsparse_hypre_C", NULL)); 137406977982Sstefanozampini PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatProductSetFromOptions_mpiaijhipsparse_hypre_C", NULL)); 137506977982Sstefanozampini PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatProductSetFromOptions_seqaijcusparse_hypre_C", NULL)); 137606977982Sstefanozampini PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatProductSetFromOptions_mpiaijcusparse_hypre_C", NULL)); 13779566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatHYPRESetPreallocation_C", NULL)); 13789566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatHYPREGetParCSR_C", NULL)); 13795fbaff96SJunchao Zhang PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatSetPreallocationCOO_C", NULL)); 13805fbaff96SJunchao Zhang PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatSetValuesCOO_C", NULL)); 13819566063dSJacob Faibussowitsch PetscCall(PetscFree(A->data)); 13823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 138363c07aadSStefano Zampini } 138463c07aadSStefano Zampini 1385d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetUp_HYPRE(Mat A) 1386d71ae5a4SJacob Faibussowitsch { 13874ec6421dSstefano_zampini PetscFunctionBegin; 138806977982Sstefanozampini if (!A->preallocated) PetscCall(MatHYPRESetPreallocation(A, PETSC_DEFAULT, NULL, PETSC_DEFAULT, NULL)); 13893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13904ec6421dSstefano_zampini } 13914ec6421dSstefano_zampini 13926ea7df73SStefano Zampini //TODO FIX hypre_CSRMatrixMatvecOutOfPlace 13936ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 1394d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatBindToCPU_HYPRE(Mat A, PetscBool bind) 1395d71ae5a4SJacob Faibussowitsch { 13966ea7df73SStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 13976ea7df73SStefano Zampini HYPRE_MemoryLocation hmem = bind ? HYPRE_MEMORY_HOST : HYPRE_MEMORY_DEVICE; 13986ea7df73SStefano Zampini 13996ea7df73SStefano Zampini PetscFunctionBegin; 14006ea7df73SStefano Zampini A->boundtocpu = bind; 14015fbaff96SJunchao Zhang if (hA->ij && hypre_IJMatrixAssembleFlag(hA->ij) && hmem != hypre_IJMatrixMemoryLocation(hA->ij)) { 14026ea7df73SStefano Zampini hypre_ParCSRMatrix *parcsr; 1403792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hA->ij, (void **)&parcsr); 1404792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixMigrate, parcsr, hmem); 14056ea7df73SStefano Zampini } 14069566063dSJacob Faibussowitsch if (hA->x) PetscCall(VecHYPRE_IJBindToCPU(hA->x, bind)); 14079566063dSJacob Faibussowitsch if (hA->b) PetscCall(VecHYPRE_IJBindToCPU(hA->b, bind)); 14083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 14096ea7df73SStefano Zampini } 14106ea7df73SStefano Zampini #endif 14116ea7df73SStefano Zampini 1412d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyEnd_HYPRE(Mat A, MatAssemblyType mode) 1413d71ae5a4SJacob Faibussowitsch { 141463c07aadSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 1415c69f721fSFande Kong PetscMPIInt n; 1416c69f721fSFande Kong PetscInt i, j, rstart, ncols, flg; 1417c69f721fSFande Kong PetscInt *row, *col; 1418c69f721fSFande Kong PetscScalar *val; 141963c07aadSStefano Zampini 142063c07aadSStefano Zampini PetscFunctionBegin; 142108401ef6SPierre Jolivet PetscCheck(mode != MAT_FLUSH_ASSEMBLY, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "MAT_FLUSH_ASSEMBLY currently not supported with MATHYPRE"); 1422c69f721fSFande Kong 1423c69f721fSFande Kong if (!A->nooffprocentries) { 1424c69f721fSFande Kong while (1) { 14259566063dSJacob Faibussowitsch PetscCall(MatStashScatterGetMesg_Private(&A->stash, &n, &row, &col, &val, &flg)); 1426c69f721fSFande Kong if (!flg) break; 1427c69f721fSFande Kong 1428c69f721fSFande Kong for (i = 0; i < n;) { 1429c69f721fSFande Kong /* Now identify the consecutive vals belonging to the same row */ 1430c69f721fSFande Kong for (j = i, rstart = row[j]; j < n; j++) { 1431c69f721fSFande Kong if (row[j] != rstart) break; 1432c69f721fSFande Kong } 1433c69f721fSFande Kong if (j < n) ncols = j - i; 1434c69f721fSFande Kong else ncols = n - i; 1435c69f721fSFande Kong /* Now assemble all these values with a single function call */ 14369566063dSJacob Faibussowitsch PetscCall(MatSetValues_HYPRE(A, 1, row + i, ncols, col + i, val + i, A->insertmode)); 1437c69f721fSFande Kong 1438c69f721fSFande Kong i = j; 1439c69f721fSFande Kong } 1440c69f721fSFande Kong } 14419566063dSJacob Faibussowitsch PetscCall(MatStashScatterEnd_Private(&A->stash)); 1442c69f721fSFande Kong } 1443c69f721fSFande Kong 1444792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixAssemble, hA->ij); 1445336664bdSPierre Jolivet /* The assembly routine destroys the aux_matrix, we recreate it here by calling HYPRE_IJMatrixInitialize */ 1446336664bdSPierre 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 */ 1447651b1cf9SStefano Zampini if (!A->sortedfull) { 1448af1cf968SStefano Zampini hypre_AuxParCSRMatrix *aux_matrix; 1449af1cf968SStefano Zampini 1450af1cf968SStefano Zampini /* call destroy just to make sure we do not leak anything */ 1451af1cf968SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix *)hypre_IJMatrixTranslator(hA->ij); 1452792fecdfSBarry Smith PetscCallExternal(hypre_AuxParCSRMatrixDestroy, aux_matrix); 1453af1cf968SStefano Zampini hypre_IJMatrixTranslator(hA->ij) = NULL; 1454af1cf968SStefano Zampini 1455af1cf968SStefano Zampini /* Initialize with assembled flag -> it only recreates the aux_par_matrix */ 1456792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixInitialize, hA->ij); 1457af1cf968SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix *)hypre_IJMatrixTranslator(hA->ij); 14586ea7df73SStefano Zampini if (aux_matrix) { 1459af1cf968SStefano Zampini hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 1; /* see comment in MatHYPRESetPreallocation_HYPRE */ 146022235d61SPierre Jolivet #if PETSC_PKG_HYPRE_VERSION_LT(2, 19, 0) 1461792fecdfSBarry Smith PetscCallExternal(hypre_AuxParCSRMatrixInitialize, aux_matrix); 146222235d61SPierre Jolivet #else 1463792fecdfSBarry Smith PetscCallExternal(hypre_AuxParCSRMatrixInitialize_v2, aux_matrix, HYPRE_MEMORY_HOST); 146422235d61SPierre Jolivet #endif 1465af1cf968SStefano Zampini } 14666ea7df73SStefano Zampini } 14676ea7df73SStefano Zampini { 14686ea7df73SStefano Zampini hypre_ParCSRMatrix *parcsr; 14696ea7df73SStefano Zampini 1470792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hA->ij, (void **)&parcsr); 1471792fecdfSBarry Smith if (!hypre_ParCSRMatrixCommPkg(parcsr)) PetscCallExternal(hypre_MatvecCommPkgCreate, parcsr); 14726ea7df73SStefano Zampini } 14739566063dSJacob Faibussowitsch if (!hA->x) PetscCall(VecHYPRE_IJVectorCreate(A->cmap, &hA->x)); 14749566063dSJacob Faibussowitsch if (!hA->b) PetscCall(VecHYPRE_IJVectorCreate(A->rmap, &hA->b)); 14756ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 14769566063dSJacob Faibussowitsch PetscCall(MatBindToCPU_HYPRE(A, A->boundtocpu)); 14776ea7df73SStefano Zampini #endif 14783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 147963c07aadSStefano Zampini } 148063c07aadSStefano Zampini 1481d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetArray_HYPRE(Mat A, PetscInt size, void **array) 1482d71ae5a4SJacob Faibussowitsch { 1483c69f721fSFande Kong Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 1484c69f721fSFande Kong 1485c69f721fSFande Kong PetscFunctionBegin; 1486651b1cf9SStefano Zampini PetscCheck(hA->array_available, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Temporary space is in use"); 1487c69f721fSFande Kong 1488651b1cf9SStefano Zampini if (hA->array_size >= size) { 148939accc25SStefano Zampini *array = hA->array; 149039accc25SStefano Zampini } else { 14919566063dSJacob Faibussowitsch PetscCall(PetscFree(hA->array)); 1492651b1cf9SStefano Zampini hA->array_size = size; 1493651b1cf9SStefano Zampini PetscCall(PetscMalloc(hA->array_size, &hA->array)); 1494c69f721fSFande Kong *array = hA->array; 1495c69f721fSFande Kong } 1496c69f721fSFande Kong 1497651b1cf9SStefano Zampini hA->array_available = PETSC_FALSE; 14983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1499c69f721fSFande Kong } 1500c69f721fSFande Kong 1501d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRestoreArray_HYPRE(Mat A, void **array) 1502d71ae5a4SJacob Faibussowitsch { 1503c69f721fSFande Kong Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 1504c69f721fSFande Kong 1505c69f721fSFande Kong PetscFunctionBegin; 1506c69f721fSFande Kong *array = NULL; 1507651b1cf9SStefano Zampini hA->array_available = PETSC_TRUE; 15083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1509c69f721fSFande Kong } 1510c69f721fSFande Kong 1511d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetValues_HYPRE(Mat A, PetscInt nr, const PetscInt rows[], PetscInt nc, const PetscInt cols[], const PetscScalar v[], InsertMode ins) 1512d71ae5a4SJacob Faibussowitsch { 1513d975228cSstefano_zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 1514d975228cSstefano_zampini PetscScalar *vals = (PetscScalar *)v; 151539accc25SStefano Zampini HYPRE_Complex *sscr; 1516c69f721fSFande Kong PetscInt *cscr[2]; 1517c69f721fSFande Kong PetscInt i, nzc; 1518651b1cf9SStefano Zampini PetscInt rst = A->rmap->rstart, ren = A->rmap->rend; 151908defe43SFande Kong void *array = NULL; 1520d975228cSstefano_zampini 1521d975228cSstefano_zampini PetscFunctionBegin; 15229566063dSJacob Faibussowitsch PetscCall(MatGetArray_HYPRE(A, sizeof(PetscInt) * (2 * nc) + sizeof(HYPRE_Complex) * nc * nr, &array)); 1523c69f721fSFande Kong cscr[0] = (PetscInt *)array; 1524c69f721fSFande Kong cscr[1] = ((PetscInt *)array) + nc; 152539accc25SStefano Zampini sscr = (HYPRE_Complex *)(((PetscInt *)array) + nc * 2); 1526d975228cSstefano_zampini for (i = 0, nzc = 0; i < nc; i++) { 1527d975228cSstefano_zampini if (cols[i] >= 0) { 1528d975228cSstefano_zampini cscr[0][nzc] = cols[i]; 1529d975228cSstefano_zampini cscr[1][nzc++] = i; 1530d975228cSstefano_zampini } 1531d975228cSstefano_zampini } 1532c69f721fSFande Kong if (!nzc) { 15339566063dSJacob Faibussowitsch PetscCall(MatRestoreArray_HYPRE(A, &array)); 15343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1535c69f721fSFande Kong } 1536d975228cSstefano_zampini 15376ea7df73SStefano Zampini #if 0 //defined(PETSC_HAVE_HYPRE_DEVICE) 15386ea7df73SStefano Zampini if (HYPRE_MEMORY_HOST != hypre_IJMatrixMemoryLocation(hA->ij)) { 15396ea7df73SStefano Zampini hypre_ParCSRMatrix *parcsr; 15406ea7df73SStefano Zampini 1541792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject,hA->ij,(void**)&parcsr); 1542792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixMigrate,parcsr, HYPRE_MEMORY_HOST); 15436ea7df73SStefano Zampini } 15446ea7df73SStefano Zampini #endif 15456ea7df73SStefano Zampini 1546d975228cSstefano_zampini if (ins == ADD_VALUES) { 1547d975228cSstefano_zampini for (i = 0; i < nr; i++) { 15486ea7df73SStefano Zampini if (rows[i] >= 0) { 1549d975228cSstefano_zampini PetscInt j; 15502cf14000SStefano Zampini HYPRE_Int hnc = (HYPRE_Int)nzc; 15512cf14000SStefano Zampini 1552651b1cf9SStefano Zampini if (!nzc) continue; 1553651b1cf9SStefano Zampini /* nonlocal values */ 1554651b1cf9SStefano Zampini if (rows[i] < rst || rows[i] >= ren) { 1555651b1cf9SStefano 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]); 1556651b1cf9SStefano Zampini if (hA->donotstash) continue; 1557651b1cf9SStefano Zampini } 1558aed4548fSBarry 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]); 15599566063dSJacob Faibussowitsch for (j = 0; j < nzc; j++) PetscCall(PetscHYPREScalarCast(vals[cscr[1][j]], &sscr[j])); 1560792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixAddToValues, hA->ij, 1, &hnc, (HYPRE_BigInt *)(rows + i), (HYPRE_BigInt *)cscr[0], sscr); 1561d975228cSstefano_zampini } 1562d975228cSstefano_zampini vals += nc; 1563d975228cSstefano_zampini } 1564d975228cSstefano_zampini } else { /* INSERT_VALUES */ 1565d975228cSstefano_zampini for (i = 0; i < nr; i++) { 15666ea7df73SStefano Zampini if (rows[i] >= 0) { 1567d975228cSstefano_zampini PetscInt j; 15682cf14000SStefano Zampini HYPRE_Int hnc = (HYPRE_Int)nzc; 15692cf14000SStefano Zampini 1570651b1cf9SStefano Zampini if (!nzc) continue; 1571aed4548fSBarry 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]); 15729566063dSJacob Faibussowitsch for (j = 0; j < nzc; j++) PetscCall(PetscHYPREScalarCast(vals[cscr[1][j]], &sscr[j])); 1573c69f721fSFande Kong /* nonlocal values */ 1574651b1cf9SStefano Zampini if (rows[i] < rst || rows[i] >= ren) { 1575651b1cf9SStefano 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]); 1576651b1cf9SStefano Zampini if (!hA->donotstash) PetscCall(MatStashValuesRow_Private(&A->stash, rows[i], nzc, cscr[0], (PetscScalar *)sscr, PETSC_FALSE)); 1577651b1cf9SStefano Zampini } 1578c69f721fSFande Kong /* local values */ 1579651b1cf9SStefano Zampini else 1580651b1cf9SStefano Zampini PetscCallExternal(HYPRE_IJMatrixSetValues, hA->ij, 1, &hnc, (HYPRE_BigInt *)(rows + i), (HYPRE_BigInt *)cscr[0], sscr); 1581d975228cSstefano_zampini } 1582d975228cSstefano_zampini vals += nc; 1583d975228cSstefano_zampini } 1584d975228cSstefano_zampini } 1585c69f721fSFande Kong 15869566063dSJacob Faibussowitsch PetscCall(MatRestoreArray_HYPRE(A, &array)); 15873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1588d975228cSstefano_zampini } 1589d975228cSstefano_zampini 1590d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatHYPRESetPreallocation_HYPRE(Mat A, PetscInt dnz, const PetscInt dnnz[], PetscInt onz, const PetscInt onnz[]) 1591d71ae5a4SJacob Faibussowitsch { 1592d975228cSstefano_zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 15937d968826Sstefano_zampini HYPRE_Int *hdnnz, *honnz; 159406a29025Sstefano_zampini PetscInt i, rs, re, cs, ce, bs; 1595d975228cSstefano_zampini PetscMPIInt size; 1596d975228cSstefano_zampini 1597d975228cSstefano_zampini PetscFunctionBegin; 15989566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 15999566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 1600d975228cSstefano_zampini rs = A->rmap->rstart; 1601d975228cSstefano_zampini re = A->rmap->rend; 1602d975228cSstefano_zampini cs = A->cmap->rstart; 1603d975228cSstefano_zampini ce = A->cmap->rend; 1604d975228cSstefano_zampini if (!hA->ij) { 1605792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixCreate, hA->comm, rs, re - 1, cs, ce - 1, &hA->ij); 1606792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixSetObjectType, hA->ij, HYPRE_PARCSR); 1607d975228cSstefano_zampini } else { 16082cf14000SStefano Zampini HYPRE_BigInt hrs, hre, hcs, hce; 1609792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetLocalRange, hA->ij, &hrs, &hre, &hcs, &hce); 1610aed4548fSBarry 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); 1611aed4548fSBarry 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); 1612d975228cSstefano_zampini } 161306977982Sstefanozampini PetscCall(MatHYPRE_DestroyCOOMat(A)); 16149566063dSJacob Faibussowitsch PetscCall(MatGetBlockSize(A, &bs)); 161506a29025Sstefano_zampini if (dnz == PETSC_DEFAULT || dnz == PETSC_DECIDE) dnz = 10 * bs; 161606a29025Sstefano_zampini if (onz == PETSC_DEFAULT || onz == PETSC_DECIDE) onz = 10 * bs; 161706a29025Sstefano_zampini 1618d975228cSstefano_zampini if (!dnnz) { 16199566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->rmap->n, &hdnnz)); 1620d975228cSstefano_zampini for (i = 0; i < A->rmap->n; i++) hdnnz[i] = dnz; 1621d975228cSstefano_zampini } else { 16227d968826Sstefano_zampini hdnnz = (HYPRE_Int *)dnnz; 1623d975228cSstefano_zampini } 16249566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A), &size)); 1625d975228cSstefano_zampini if (size > 1) { 1626ddbeb582SStefano Zampini hypre_AuxParCSRMatrix *aux_matrix; 1627d975228cSstefano_zampini if (!onnz) { 16289566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->rmap->n, &honnz)); 1629d975228cSstefano_zampini for (i = 0; i < A->rmap->n; i++) honnz[i] = onz; 163022235d61SPierre Jolivet } else honnz = (HYPRE_Int *)onnz; 1631ddbeb582SStefano Zampini /* SetDiagOffdSizes sets hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 0, since it seems 1632ddbeb582SStefano Zampini they assume the user will input the entire row values, properly sorted 1633336664bdSPierre Jolivet In PETSc, we don't make such an assumption and set this flag to 1, 1634336664bdSPierre Jolivet unless the option MAT_SORTED_FULL is set to true. 1635ddbeb582SStefano Zampini Also, to avoid possible memory leaks, we destroy and recreate the translator 1636ddbeb582SStefano Zampini This has to be done here, as HYPRE_IJMatrixInitialize will properly initialize 1637ddbeb582SStefano Zampini the IJ matrix for us */ 1638ddbeb582SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix *)hypre_IJMatrixTranslator(hA->ij); 1639ddbeb582SStefano Zampini hypre_AuxParCSRMatrixDestroy(aux_matrix); 1640ddbeb582SStefano Zampini hypre_IJMatrixTranslator(hA->ij) = NULL; 1641792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixSetDiagOffdSizes, hA->ij, hdnnz, honnz); 1642ddbeb582SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix *)hypre_IJMatrixTranslator(hA->ij); 1643651b1cf9SStefano Zampini hypre_AuxParCSRMatrixNeedAux(aux_matrix) = !A->sortedfull; 1644d975228cSstefano_zampini } else { 1645d975228cSstefano_zampini honnz = NULL; 1646792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixSetRowSizes, hA->ij, hdnnz); 1647d975228cSstefano_zampini } 1648ddbeb582SStefano Zampini 1649af1cf968SStefano Zampini /* reset assembled flag and call the initialize method */ 1650af1cf968SStefano Zampini hypre_IJMatrixAssembleFlag(hA->ij) = 0; 16516ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_LT(2, 19, 0) 1652792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixInitialize, hA->ij); 16536ea7df73SStefano Zampini #else 1654792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixInitialize_v2, hA->ij, HYPRE_MEMORY_HOST); 16556ea7df73SStefano Zampini #endif 165648a46eb9SPierre Jolivet if (!dnnz) PetscCall(PetscFree(hdnnz)); 165748a46eb9SPierre Jolivet if (!onnz && honnz) PetscCall(PetscFree(honnz)); 1658af1cf968SStefano Zampini /* Match AIJ logic */ 165906a29025Sstefano_zampini A->preallocated = PETSC_TRUE; 1660af1cf968SStefano Zampini A->assembled = PETSC_FALSE; 16613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1662d975228cSstefano_zampini } 1663d975228cSstefano_zampini 1664d975228cSstefano_zampini /*@C 1665d975228cSstefano_zampini MatHYPRESetPreallocation - Preallocates memory for a sparse parallel matrix in HYPRE IJ format 1666d975228cSstefano_zampini 1667c3339decSBarry Smith Collective 1668d975228cSstefano_zampini 1669d975228cSstefano_zampini Input Parameters: 1670d975228cSstefano_zampini + A - the matrix 1671d975228cSstefano_zampini . dnz - number of nonzeros per row in DIAGONAL portion of local submatrix 1672d975228cSstefano_zampini (same value is used for all local rows) 1673d975228cSstefano_zampini . dnnz - array containing the number of nonzeros in the various rows of the 1674d975228cSstefano_zampini DIAGONAL portion of the local submatrix (possibly different for each row) 16752ef1f0ffSBarry Smith or `NULL` (`PETSC_NULL_INTEGER` in Fortran), if `d_nz` is used to specify the nonzero structure. 16762ef1f0ffSBarry Smith The size of this array is equal to the number of local rows, i.e `m`. 1677d975228cSstefano_zampini For matrices that will be factored, you must leave room for (and set) 1678d975228cSstefano_zampini the diagonal entry even if it is zero. 1679d975228cSstefano_zampini . onz - number of nonzeros per row in the OFF-DIAGONAL portion of local 1680d975228cSstefano_zampini submatrix (same value is used for all local rows). 1681d975228cSstefano_zampini - onnz - array containing the number of nonzeros in the various rows of the 1682d975228cSstefano_zampini OFF-DIAGONAL portion of the local submatrix (possibly different for 16832ef1f0ffSBarry Smith each row) or `NULL` (`PETSC_NULL_INTEGER` in Fortran), if `o_nz` is used to specify the nonzero 1684d975228cSstefano_zampini structure. The size of this array is equal to the number 16852ef1f0ffSBarry Smith of local rows, i.e `m`. 1686d975228cSstefano_zampini 16872fe279fdSBarry Smith Level: intermediate 16882fe279fdSBarry Smith 168911a5261eSBarry Smith Note: 16902ef1f0ffSBarry Smith If the *nnz parameter is given then the *nz parameter is ignored; for sequential matrices, `onz` and `onnz` are ignored. 1691d975228cSstefano_zampini 16921cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatCreate()`, `MatMPIAIJSetPreallocation()`, `MATHYPRE`, `MATAIJ` 1693d975228cSstefano_zampini @*/ 1694d71ae5a4SJacob Faibussowitsch PetscErrorCode MatHYPRESetPreallocation(Mat A, PetscInt dnz, const PetscInt dnnz[], PetscInt onz, const PetscInt onnz[]) 1695d71ae5a4SJacob Faibussowitsch { 1696d975228cSstefano_zampini PetscFunctionBegin; 1697d975228cSstefano_zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 1698d975228cSstefano_zampini PetscValidType(A, 1); 1699cac4c232SBarry Smith PetscTryMethod(A, "MatHYPRESetPreallocation_C", (Mat, PetscInt, const PetscInt[], PetscInt, const PetscInt[]), (A, dnz, dnnz, onz, onnz)); 17003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1701d975228cSstefano_zampini } 1702d975228cSstefano_zampini 170320f4b53cSBarry Smith /*@C 17042ef1f0ffSBarry Smith MatCreateFromParCSR - Creates a `Mat` from a `hypre_ParCSRMatrix` 1705225daaf8SStefano Zampini 1706225daaf8SStefano Zampini Collective 1707225daaf8SStefano Zampini 1708225daaf8SStefano Zampini Input Parameters: 17092ef1f0ffSBarry Smith + parcsr - the pointer to the `hypre_ParCSRMatrix` 17102ef1f0ffSBarry Smith . mtype - matrix type to be created. Currently `MATAIJ`, `MATIS` and `MATHYPRE` are supported. 171120f4b53cSBarry Smith - copymode - PETSc copying options, see `PetscCopyMode` 1712225daaf8SStefano Zampini 1713225daaf8SStefano Zampini Output Parameter: 1714225daaf8SStefano Zampini . A - the matrix 1715225daaf8SStefano Zampini 1716225daaf8SStefano Zampini Level: intermediate 1717225daaf8SStefano Zampini 17181cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatHYPRE`, `PetscCopyMode` 171920f4b53cSBarry Smith @*/ 1720d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatCreateFromParCSR(hypre_ParCSRMatrix *parcsr, MatType mtype, PetscCopyMode copymode, Mat *A) 1721d71ae5a4SJacob Faibussowitsch { 1722225daaf8SStefano Zampini Mat T; 1723978814f1SStefano Zampini Mat_HYPRE *hA; 1724978814f1SStefano Zampini MPI_Comm comm; 1725978814f1SStefano Zampini PetscInt rstart, rend, cstart, cend, M, N; 1726d248a85cSRichard Tran Mills PetscBool isseqaij, isseqaijmkl, ismpiaij, isaij, ishyp, isis; 1727978814f1SStefano Zampini 1728978814f1SStefano Zampini PetscFunctionBegin; 1729978814f1SStefano Zampini comm = hypre_ParCSRMatrixComm(parcsr); 17309566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(mtype, MATSEQAIJ, &isseqaij)); 17319566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(mtype, MATSEQAIJMKL, &isseqaijmkl)); 17329566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(mtype, MATMPIAIJ, &ismpiaij)); 17339566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(mtype, MATAIJ, &isaij)); 17349566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(mtype, MATHYPRE, &ishyp)); 17359566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(mtype, MATIS, &isis)); 1736d248a85cSRichard Tran Mills isaij = (PetscBool)(isseqaij || isseqaijmkl || ismpiaij || isaij); 17376ea7df73SStefano Zampini /* TODO */ 1738aed4548fSBarry 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); 1739978814f1SStefano Zampini /* access ParCSRMatrix */ 1740978814f1SStefano Zampini rstart = hypre_ParCSRMatrixFirstRowIndex(parcsr); 1741978814f1SStefano Zampini rend = hypre_ParCSRMatrixLastRowIndex(parcsr); 1742978814f1SStefano Zampini cstart = hypre_ParCSRMatrixFirstColDiag(parcsr); 1743978814f1SStefano Zampini cend = hypre_ParCSRMatrixLastColDiag(parcsr); 1744978814f1SStefano Zampini M = hypre_ParCSRMatrixGlobalNumRows(parcsr); 1745978814f1SStefano Zampini N = hypre_ParCSRMatrixGlobalNumCols(parcsr); 1746978814f1SStefano Zampini 1747fa92c42cSstefano_zampini /* fix for empty local rows/columns */ 1748fa92c42cSstefano_zampini if (rend < rstart) rend = rstart; 1749fa92c42cSstefano_zampini if (cend < cstart) cend = cstart; 1750fa92c42cSstefano_zampini 1751e6471dc9SStefano Zampini /* PETSc convention */ 1752e6471dc9SStefano Zampini rend++; 1753e6471dc9SStefano Zampini cend++; 1754e6471dc9SStefano Zampini rend = PetscMin(rend, M); 1755e6471dc9SStefano Zampini cend = PetscMin(cend, N); 1756e6471dc9SStefano Zampini 1757978814f1SStefano Zampini /* create PETSc matrix with MatHYPRE */ 17589566063dSJacob Faibussowitsch PetscCall(MatCreate(comm, &T)); 17599566063dSJacob Faibussowitsch PetscCall(MatSetSizes(T, rend - rstart, cend - cstart, M, N)); 17609566063dSJacob Faibussowitsch PetscCall(MatSetType(T, MATHYPRE)); 1761f4f49eeaSPierre Jolivet hA = (Mat_HYPRE *)T->data; 1762978814f1SStefano Zampini 1763978814f1SStefano Zampini /* create HYPRE_IJMatrix */ 1764792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixCreate, hA->comm, rstart, rend - 1, cstart, cend - 1, &hA->ij); 1765792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixSetObjectType, hA->ij, HYPRE_PARCSR); 176645b8d346SStefano Zampini 176745b8d346SStefano Zampini /* create new ParCSR object if needed */ 176845b8d346SStefano Zampini if (ishyp && copymode == PETSC_COPY_VALUES) { 176945b8d346SStefano Zampini hypre_ParCSRMatrix *new_parcsr; 17706ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_LT(2, 18, 0) 177145b8d346SStefano Zampini hypre_CSRMatrix *hdiag, *hoffd, *ndiag, *noffd; 177245b8d346SStefano Zampini 17730e6427aaSSatish Balay new_parcsr = hypre_ParCSRMatrixClone(parcsr, 0); 177445b8d346SStefano Zampini hdiag = hypre_ParCSRMatrixDiag(parcsr); 177545b8d346SStefano Zampini hoffd = hypre_ParCSRMatrixOffd(parcsr); 177645b8d346SStefano Zampini ndiag = hypre_ParCSRMatrixDiag(new_parcsr); 177745b8d346SStefano Zampini noffd = hypre_ParCSRMatrixOffd(new_parcsr); 17789566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(hypre_CSRMatrixData(ndiag), hypre_CSRMatrixData(hdiag), hypre_CSRMatrixNumNonzeros(hdiag))); 17799566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(hypre_CSRMatrixData(noffd), hypre_CSRMatrixData(hoffd), hypre_CSRMatrixNumNonzeros(hoffd))); 17806ea7df73SStefano Zampini #else 17816ea7df73SStefano Zampini new_parcsr = hypre_ParCSRMatrixClone(parcsr, 1); 17826ea7df73SStefano Zampini #endif 178345b8d346SStefano Zampini parcsr = new_parcsr; 178445b8d346SStefano Zampini copymode = PETSC_OWN_POINTER; 178545b8d346SStefano Zampini } 1786978814f1SStefano Zampini 1787978814f1SStefano Zampini /* set ParCSR object */ 1788978814f1SStefano Zampini hypre_IJMatrixObject(hA->ij) = parcsr; 17894ec6421dSstefano_zampini T->preallocated = PETSC_TRUE; 1790978814f1SStefano Zampini 1791978814f1SStefano Zampini /* set assembled flag */ 1792978814f1SStefano Zampini hypre_IJMatrixAssembleFlag(hA->ij) = 1; 17936ea7df73SStefano Zampini #if 0 1794792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixInitialize,hA->ij); 17956ea7df73SStefano Zampini #endif 1796225daaf8SStefano Zampini if (ishyp) { 17976d2a658fSstefano_zampini PetscMPIInt myid = 0; 17986d2a658fSstefano_zampini 17996d2a658fSstefano_zampini /* make sure we always have row_starts and col_starts available */ 180048a46eb9SPierre Jolivet if (HYPRE_AssumedPartitionCheck()) PetscCallMPI(MPI_Comm_rank(comm, &myid)); 1801a1d2239cSSatish Balay #if defined(hypre_ParCSRMatrixOwnsRowStarts) 18026d2a658fSstefano_zampini if (!hypre_ParCSRMatrixOwnsColStarts(parcsr)) { 18036d2a658fSstefano_zampini PetscLayout map; 18046d2a658fSstefano_zampini 18059566063dSJacob Faibussowitsch PetscCall(MatGetLayouts(T, NULL, &map)); 18069566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(map)); 18072cf14000SStefano Zampini hypre_ParCSRMatrixColStarts(parcsr) = (HYPRE_BigInt *)(map->range + myid); 18086d2a658fSstefano_zampini } 18096d2a658fSstefano_zampini if (!hypre_ParCSRMatrixOwnsRowStarts(parcsr)) { 18106d2a658fSstefano_zampini PetscLayout map; 18116d2a658fSstefano_zampini 18129566063dSJacob Faibussowitsch PetscCall(MatGetLayouts(T, &map, NULL)); 18139566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(map)); 18142cf14000SStefano Zampini hypre_ParCSRMatrixRowStarts(parcsr) = (HYPRE_BigInt *)(map->range + myid); 18156d2a658fSstefano_zampini } 1816a1d2239cSSatish Balay #endif 1817978814f1SStefano Zampini /* prevent from freeing the pointer */ 1818978814f1SStefano Zampini if (copymode == PETSC_USE_POINTER) hA->inner_free = PETSC_FALSE; 1819225daaf8SStefano Zampini *A = T; 18209566063dSJacob Faibussowitsch PetscCall(MatSetOption(*A, MAT_SORTED_FULL, PETSC_TRUE)); 18219566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(*A, MAT_FINAL_ASSEMBLY)); 18229566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(*A, MAT_FINAL_ASSEMBLY)); 1823bb4689ddSStefano Zampini } else if (isaij) { 1824bb4689ddSStefano Zampini if (copymode != PETSC_OWN_POINTER) { 1825225daaf8SStefano Zampini /* prevent from freeing the pointer */ 1826225daaf8SStefano Zampini hA->inner_free = PETSC_FALSE; 18279566063dSJacob Faibussowitsch PetscCall(MatConvert_HYPRE_AIJ(T, MATAIJ, MAT_INITIAL_MATRIX, A)); 18289566063dSJacob Faibussowitsch PetscCall(MatDestroy(&T)); 1829225daaf8SStefano Zampini } else { /* AIJ return type with PETSC_OWN_POINTER */ 18309566063dSJacob Faibussowitsch PetscCall(MatConvert_HYPRE_AIJ(T, MATAIJ, MAT_INPLACE_MATRIX, &T)); 1831225daaf8SStefano Zampini *A = T; 1832225daaf8SStefano Zampini } 1833bb4689ddSStefano Zampini } else if (isis) { 18349566063dSJacob Faibussowitsch PetscCall(MatConvert_HYPRE_IS(T, MATIS, MAT_INITIAL_MATRIX, A)); 18358cfe8d00SStefano Zampini if (copymode != PETSC_OWN_POINTER) hA->inner_free = PETSC_FALSE; 18369566063dSJacob Faibussowitsch PetscCall(MatDestroy(&T)); 1837bb4689ddSStefano Zampini } 18383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1839978814f1SStefano Zampini } 1840978814f1SStefano Zampini 1841d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatHYPREGetParCSR_HYPRE(Mat A, hypre_ParCSRMatrix **parcsr) 1842d71ae5a4SJacob Faibussowitsch { 1843dd9c0a25Sstefano_zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 1844dd9c0a25Sstefano_zampini HYPRE_Int type; 1845dd9c0a25Sstefano_zampini 1846dd9c0a25Sstefano_zampini PetscFunctionBegin; 184728b400f6SJacob Faibussowitsch PetscCheck(hA->ij, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "HYPRE_IJMatrix not present"); 1848792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObjectType, hA->ij, &type); 184908401ef6SPierre Jolivet PetscCheck(type == HYPRE_PARCSR, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "HYPRE_IJMatrix is not of type HYPRE_PARCSR"); 1850792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetObject, hA->ij, (void **)parcsr); 18513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1852dd9c0a25Sstefano_zampini } 1853dd9c0a25Sstefano_zampini 185420f4b53cSBarry Smith /*@C 1855dd9c0a25Sstefano_zampini MatHYPREGetParCSR - Gets the pointer to the ParCSR matrix 1856dd9c0a25Sstefano_zampini 1857cc4c1da9SBarry Smith Not Collective, No Fortran Support 1858dd9c0a25Sstefano_zampini 185920f4b53cSBarry Smith Input Parameter: 186020f4b53cSBarry Smith . A - the `MATHYPRE` object 1861dd9c0a25Sstefano_zampini 1862dd9c0a25Sstefano_zampini Output Parameter: 18632ef1f0ffSBarry Smith . parcsr - the pointer to the `hypre_ParCSRMatrix` 1864dd9c0a25Sstefano_zampini 1865dd9c0a25Sstefano_zampini Level: intermediate 1866dd9c0a25Sstefano_zampini 18671cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatHYPRE`, `PetscCopyMode` 186820f4b53cSBarry Smith @*/ 1869d71ae5a4SJacob Faibussowitsch PetscErrorCode MatHYPREGetParCSR(Mat A, hypre_ParCSRMatrix **parcsr) 1870d71ae5a4SJacob Faibussowitsch { 1871dd9c0a25Sstefano_zampini PetscFunctionBegin; 1872dd9c0a25Sstefano_zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 1873dd9c0a25Sstefano_zampini PetscValidType(A, 1); 1874cac4c232SBarry Smith PetscUseMethod(A, "MatHYPREGetParCSR_C", (Mat, hypre_ParCSRMatrix **), (A, parcsr)); 18753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1876dd9c0a25Sstefano_zampini } 1877dd9c0a25Sstefano_zampini 1878d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMissingDiagonal_HYPRE(Mat A, PetscBool *missing, PetscInt *dd) 1879d71ae5a4SJacob Faibussowitsch { 188068ec7858SStefano Zampini hypre_ParCSRMatrix *parcsr; 188168ec7858SStefano Zampini hypre_CSRMatrix *ha; 188268ec7858SStefano Zampini PetscInt rst; 188368ec7858SStefano Zampini 188468ec7858SStefano Zampini PetscFunctionBegin; 188508401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not implemented with non-square diagonal blocks"); 18869566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(A, &rst, NULL)); 18879566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(A, &parcsr)); 188868ec7858SStefano Zampini if (missing) *missing = PETSC_FALSE; 188968ec7858SStefano Zampini if (dd) *dd = -1; 189068ec7858SStefano Zampini ha = hypre_ParCSRMatrixDiag(parcsr); 189168ec7858SStefano Zampini if (ha) { 189268299464SStefano Zampini PetscInt size, i; 189368299464SStefano Zampini HYPRE_Int *ii, *jj; 189468ec7858SStefano Zampini 189568ec7858SStefano Zampini size = hypre_CSRMatrixNumRows(ha); 189668ec7858SStefano Zampini ii = hypre_CSRMatrixI(ha); 189768ec7858SStefano Zampini jj = hypre_CSRMatrixJ(ha); 189868ec7858SStefano Zampini for (i = 0; i < size; i++) { 189968ec7858SStefano Zampini PetscInt j; 190068ec7858SStefano Zampini PetscBool found = PETSC_FALSE; 190168ec7858SStefano Zampini 19029371c9d4SSatish Balay for (j = ii[i]; j < ii[i + 1] && !found; j++) found = (jj[j] == i) ? PETSC_TRUE : PETSC_FALSE; 190368ec7858SStefano Zampini 190468ec7858SStefano Zampini if (!found) { 19053ba16761SJacob Faibussowitsch PetscCall(PetscInfo(A, "Matrix is missing local diagonal entry %" PetscInt_FMT "\n", i)); 190668ec7858SStefano Zampini if (missing) *missing = PETSC_TRUE; 190768ec7858SStefano Zampini if (dd) *dd = i + rst; 19083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 190968ec7858SStefano Zampini } 191068ec7858SStefano Zampini } 191168ec7858SStefano Zampini if (!size) { 19123ba16761SJacob Faibussowitsch PetscCall(PetscInfo(A, "Matrix has no diagonal entries therefore is missing diagonal\n")); 191368ec7858SStefano Zampini if (missing) *missing = PETSC_TRUE; 191468ec7858SStefano Zampini if (dd) *dd = rst; 191568ec7858SStefano Zampini } 191668ec7858SStefano Zampini } else { 19173ba16761SJacob Faibussowitsch PetscCall(PetscInfo(A, "Matrix has no diagonal entries therefore is missing diagonal\n")); 191868ec7858SStefano Zampini if (missing) *missing = PETSC_TRUE; 191968ec7858SStefano Zampini if (dd) *dd = rst; 192068ec7858SStefano Zampini } 19213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 192268ec7858SStefano Zampini } 192368ec7858SStefano Zampini 1924d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatScale_HYPRE(Mat A, PetscScalar s) 1925d71ae5a4SJacob Faibussowitsch { 192668ec7858SStefano Zampini hypre_ParCSRMatrix *parcsr; 19276ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_LT(2, 19, 0) 192868ec7858SStefano Zampini hypre_CSRMatrix *ha; 19296ea7df73SStefano Zampini #endif 193039accc25SStefano Zampini HYPRE_Complex hs; 193168ec7858SStefano Zampini 193268ec7858SStefano Zampini PetscFunctionBegin; 19339566063dSJacob Faibussowitsch PetscCall(PetscHYPREScalarCast(s, &hs)); 19349566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(A, &parcsr)); 19356ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2, 19, 0) 1936792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixScale, parcsr, hs); 19376ea7df73SStefano Zampini #else /* diagonal part */ 193868ec7858SStefano Zampini ha = hypre_ParCSRMatrixDiag(parcsr); 193968ec7858SStefano Zampini if (ha) { 194068299464SStefano Zampini PetscInt size, i; 194168299464SStefano Zampini HYPRE_Int *ii; 194239accc25SStefano Zampini HYPRE_Complex *a; 194368ec7858SStefano Zampini 194468ec7858SStefano Zampini size = hypre_CSRMatrixNumRows(ha); 194568ec7858SStefano Zampini a = hypre_CSRMatrixData(ha); 194668ec7858SStefano Zampini ii = hypre_CSRMatrixI(ha); 194739accc25SStefano Zampini for (i = 0; i < ii[size]; i++) a[i] *= hs; 194868ec7858SStefano Zampini } 19494cf0e950SBarry Smith /* off-diagonal part */ 195068ec7858SStefano Zampini ha = hypre_ParCSRMatrixOffd(parcsr); 195168ec7858SStefano Zampini if (ha) { 195268299464SStefano Zampini PetscInt size, i; 195368299464SStefano Zampini HYPRE_Int *ii; 195439accc25SStefano Zampini HYPRE_Complex *a; 195568ec7858SStefano Zampini 195668ec7858SStefano Zampini size = hypre_CSRMatrixNumRows(ha); 195768ec7858SStefano Zampini a = hypre_CSRMatrixData(ha); 195868ec7858SStefano Zampini ii = hypre_CSRMatrixI(ha); 195939accc25SStefano Zampini for (i = 0; i < ii[size]; i++) a[i] *= hs; 196068ec7858SStefano Zampini } 19616ea7df73SStefano Zampini #endif 19623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 196368ec7858SStefano Zampini } 196468ec7858SStefano Zampini 1965d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatZeroRowsColumns_HYPRE(Mat A, PetscInt numRows, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) 1966d71ae5a4SJacob Faibussowitsch { 196768ec7858SStefano Zampini hypre_ParCSRMatrix *parcsr; 196868299464SStefano Zampini HYPRE_Int *lrows; 196968299464SStefano Zampini PetscInt rst, ren, i; 197068ec7858SStefano Zampini 197168ec7858SStefano Zampini PetscFunctionBegin; 197208401ef6SPierre Jolivet PetscCheck(!x && !b, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "To be implemented"); 19739566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(A, &parcsr)); 19749566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numRows, &lrows)); 19759566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(A, &rst, &ren)); 197668ec7858SStefano Zampini for (i = 0; i < numRows; i++) { 19777a46b595SBarry Smith PetscCheck(rows[i] >= rst && rows[i] < ren, PETSC_COMM_SELF, PETSC_ERR_SUP, "Non-local rows not yet supported"); 197868ec7858SStefano Zampini lrows[i] = rows[i] - rst; 197968ec7858SStefano Zampini } 1980792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixEliminateRowsCols, parcsr, numRows, lrows); 19819566063dSJacob Faibussowitsch PetscCall(PetscFree(lrows)); 19823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 198368ec7858SStefano Zampini } 198468ec7858SStefano Zampini 1985d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatZeroEntries_HYPRE_CSRMatrix(hypre_CSRMatrix *ha) 1986d71ae5a4SJacob Faibussowitsch { 1987c69f721fSFande Kong PetscFunctionBegin; 1988c69f721fSFande Kong if (ha) { 1989c69f721fSFande Kong HYPRE_Int *ii, size; 1990c69f721fSFande Kong HYPRE_Complex *a; 1991c69f721fSFande Kong 1992c69f721fSFande Kong size = hypre_CSRMatrixNumRows(ha); 1993c69f721fSFande Kong a = hypre_CSRMatrixData(ha); 1994c69f721fSFande Kong ii = hypre_CSRMatrixI(ha); 1995c69f721fSFande Kong 19969566063dSJacob Faibussowitsch if (a) PetscCall(PetscArrayzero(a, ii[size])); 1997c69f721fSFande Kong } 19983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1999c69f721fSFande Kong } 2000c69f721fSFande Kong 200166976f2fSJacob Faibussowitsch static PetscErrorCode MatZeroEntries_HYPRE(Mat A) 2002d71ae5a4SJacob Faibussowitsch { 20036ea7df73SStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 20046ea7df73SStefano Zampini 20056ea7df73SStefano Zampini PetscFunctionBegin; 20066ea7df73SStefano Zampini if (HYPRE_MEMORY_DEVICE == hypre_IJMatrixMemoryLocation(hA->ij)) { 2007792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixSetConstantValues, hA->ij, 0.0); 20086ea7df73SStefano Zampini } else { 2009c69f721fSFande Kong hypre_ParCSRMatrix *parcsr; 2010c69f721fSFande Kong 20119566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(A, &parcsr)); 20129566063dSJacob Faibussowitsch PetscCall(MatZeroEntries_HYPRE_CSRMatrix(hypre_ParCSRMatrixDiag(parcsr))); 20139566063dSJacob Faibussowitsch PetscCall(MatZeroEntries_HYPRE_CSRMatrix(hypre_ParCSRMatrixOffd(parcsr))); 20146ea7df73SStefano Zampini } 20153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2016c69f721fSFande Kong } 2017c69f721fSFande Kong 2018d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatZeroRows_HYPRE_CSRMatrix(hypre_CSRMatrix *hA, PetscInt N, const PetscInt rows[], HYPRE_Complex diag) 2019d71ae5a4SJacob Faibussowitsch { 202039accc25SStefano Zampini PetscInt ii; 202139accc25SStefano Zampini HYPRE_Int *i, *j; 202239accc25SStefano Zampini HYPRE_Complex *a; 2023c69f721fSFande Kong 2024c69f721fSFande Kong PetscFunctionBegin; 20253ba16761SJacob Faibussowitsch if (!hA) PetscFunctionReturn(PETSC_SUCCESS); 2026c69f721fSFande Kong 202739accc25SStefano Zampini i = hypre_CSRMatrixI(hA); 202839accc25SStefano Zampini j = hypre_CSRMatrixJ(hA); 2029c69f721fSFande Kong a = hypre_CSRMatrixData(hA); 2030a32e9c99SJunchao Zhang #if defined(PETSC_HAVE_HYPRE_DEVICE) 2031a32e9c99SJunchao Zhang if (HYPRE_MEMORY_DEVICE == hypre_CSRMatrixMemoryLocation(hA)) { 2032a32e9c99SJunchao Zhang #if defined(HYPRE_USING_CUDA) 2033a32e9c99SJunchao Zhang MatZeroRows_CUDA(N, rows, i, j, a, diag); 2034a32e9c99SJunchao Zhang #elif defined(HYPRE_USING_HIP) 2035a32e9c99SJunchao Zhang MatZeroRows_HIP(N, rows, i, j, a, diag); 2036a32e9c99SJunchao Zhang #elif defined(PETSC_HAVE_KOKKOS) 2037a32e9c99SJunchao Zhang MatZeroRows_Kokkos(N, rows, i, j, a, diag); 2038a32e9c99SJunchao Zhang #else 2039a32e9c99SJunchao Zhang SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No support for MatZeroRows on a hypre matrix in this memory location"); 2040a32e9c99SJunchao Zhang #endif 2041a32e9c99SJunchao Zhang } else 2042a32e9c99SJunchao Zhang #endif 2043a32e9c99SJunchao Zhang { 2044c69f721fSFande Kong for (ii = 0; ii < N; ii++) { 204539accc25SStefano Zampini HYPRE_Int jj, ibeg, iend, irow; 204639accc25SStefano Zampini 2047c69f721fSFande Kong irow = rows[ii]; 2048c69f721fSFande Kong ibeg = i[irow]; 2049c69f721fSFande Kong iend = i[irow + 1]; 2050c69f721fSFande Kong for (jj = ibeg; jj < iend; jj++) 2051c69f721fSFande Kong if (j[jj] == irow) a[jj] = diag; 2052c69f721fSFande Kong else a[jj] = 0.0; 2053c69f721fSFande Kong } 2054a32e9c99SJunchao Zhang } 20553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2056c69f721fSFande Kong } 2057c69f721fSFande Kong 2058d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatZeroRows_HYPRE(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) 2059d71ae5a4SJacob Faibussowitsch { 2060c69f721fSFande Kong hypre_ParCSRMatrix *parcsr; 2061a32e9c99SJunchao Zhang PetscInt *lrows, len, *lrows2; 206239accc25SStefano Zampini HYPRE_Complex hdiag; 2063c69f721fSFande Kong 2064c69f721fSFande Kong PetscFunctionBegin; 206508401ef6SPierre Jolivet PetscCheck(!x && !b, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Does not support to modify the solution and the right hand size"); 20669566063dSJacob Faibussowitsch PetscCall(PetscHYPREScalarCast(diag, &hdiag)); 2067c69f721fSFande Kong /* retrieve the internal matrix */ 20689566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(A, &parcsr)); 2069c69f721fSFande Kong /* get locally owned rows */ 20709566063dSJacob Faibussowitsch PetscCall(MatZeroRowsMapLocal_Private(A, N, rows, &len, &lrows)); 2071a32e9c99SJunchao Zhang 2072a32e9c99SJunchao Zhang #if defined(PETSC_HAVE_HYPRE_DEVICE) 2073a32e9c99SJunchao Zhang if (HYPRE_MEMORY_DEVICE == hypre_CSRMatrixMemoryLocation(hypre_ParCSRMatrixDiag(parcsr))) { 2074a32e9c99SJunchao Zhang Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 2075a32e9c99SJunchao Zhang PetscInt m; 2076a32e9c99SJunchao Zhang PetscCall(MatGetLocalSize(A, &m, NULL)); 2077a32e9c99SJunchao Zhang if (!hA->rows_d) { 2078a32e9c99SJunchao Zhang hA->rows_d = hypre_TAlloc(PetscInt, m, HYPRE_MEMORY_DEVICE); 2079a32e9c99SJunchao Zhang if (m) PetscCheck(hA->rows_d, PETSC_COMM_SELF, PETSC_ERR_MEM, "HYPRE_TAlloc failed"); 2080a32e9c99SJunchao Zhang } 2081a32e9c99SJunchao Zhang PetscCheck(len <= m, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Too many rows in rows[]"); 2082a32e9c99SJunchao Zhang PetscStackCallExternalVoid("hypre_Memcpy", hypre_Memcpy(hA->rows_d, lrows, sizeof(PetscInt) * len, HYPRE_MEMORY_DEVICE, HYPRE_MEMORY_HOST)); 2083a32e9c99SJunchao Zhang lrows2 = hA->rows_d; 2084a32e9c99SJunchao Zhang } else 2085a32e9c99SJunchao Zhang #endif 2086a32e9c99SJunchao Zhang { 2087a32e9c99SJunchao Zhang lrows2 = lrows; 2088a32e9c99SJunchao Zhang } 2089a32e9c99SJunchao Zhang 2090c69f721fSFande Kong /* zero diagonal part */ 2091a32e9c99SJunchao Zhang PetscCall(MatZeroRows_HYPRE_CSRMatrix(hypre_ParCSRMatrixDiag(parcsr), len, lrows2, hdiag)); 2092c69f721fSFande Kong /* zero off-diagonal part */ 2093a32e9c99SJunchao Zhang PetscCall(MatZeroRows_HYPRE_CSRMatrix(hypre_ParCSRMatrixOffd(parcsr), len, lrows2, 0.0)); 2094c69f721fSFande Kong 20959566063dSJacob Faibussowitsch PetscCall(PetscFree(lrows)); 20963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2097c69f721fSFande Kong } 2098c69f721fSFande Kong 2099d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyBegin_HYPRE(Mat mat, MatAssemblyType mode) 2100d71ae5a4SJacob Faibussowitsch { 2101c69f721fSFande Kong PetscFunctionBegin; 21023ba16761SJacob Faibussowitsch if (mat->nooffprocentries) PetscFunctionReturn(PETSC_SUCCESS); 2103c69f721fSFande Kong 21049566063dSJacob Faibussowitsch PetscCall(MatStashScatterBegin_Private(mat, &mat->stash, mat->rmap->range)); 21053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2106c69f721fSFande Kong } 2107c69f721fSFande Kong 2108d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRow_HYPRE(Mat A, PetscInt row, PetscInt *nz, PetscInt **idx, PetscScalar **v) 2109d71ae5a4SJacob Faibussowitsch { 2110c69f721fSFande Kong hypre_ParCSRMatrix *parcsr; 21112cf14000SStefano Zampini HYPRE_Int hnz; 2112c69f721fSFande Kong 2113c69f721fSFande Kong PetscFunctionBegin; 2114c69f721fSFande Kong /* retrieve the internal matrix */ 21159566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(A, &parcsr)); 2116c69f721fSFande Kong /* call HYPRE API */ 2117792fecdfSBarry Smith PetscCallExternal(HYPRE_ParCSRMatrixGetRow, parcsr, row, &hnz, (HYPRE_BigInt **)idx, (HYPRE_Complex **)v); 21182cf14000SStefano Zampini if (nz) *nz = (PetscInt)hnz; 21193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2120c69f721fSFande Kong } 2121c69f721fSFande Kong 2122d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRestoreRow_HYPRE(Mat A, PetscInt row, PetscInt *nz, PetscInt **idx, PetscScalar **v) 2123d71ae5a4SJacob Faibussowitsch { 2124c69f721fSFande Kong hypre_ParCSRMatrix *parcsr; 21252cf14000SStefano Zampini HYPRE_Int hnz; 2126c69f721fSFande Kong 2127c69f721fSFande Kong PetscFunctionBegin; 2128c69f721fSFande Kong /* retrieve the internal matrix */ 21299566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(A, &parcsr)); 2130c69f721fSFande Kong /* call HYPRE API */ 21312cf14000SStefano Zampini hnz = nz ? (HYPRE_Int)(*nz) : 0; 2132792fecdfSBarry Smith PetscCallExternal(HYPRE_ParCSRMatrixRestoreRow, parcsr, row, &hnz, (HYPRE_BigInt **)idx, (HYPRE_Complex **)v); 21333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2134c69f721fSFande Kong } 2135c69f721fSFande Kong 2136d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetValues_HYPRE(Mat A, PetscInt m, const PetscInt idxm[], PetscInt n, const PetscInt idxn[], PetscScalar v[]) 2137d71ae5a4SJacob Faibussowitsch { 213845b8d346SStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 2139c69f721fSFande Kong PetscInt i; 21401d4906efSStefano Zampini 2141c69f721fSFande Kong PetscFunctionBegin; 21423ba16761SJacob Faibussowitsch if (!m || !n) PetscFunctionReturn(PETSC_SUCCESS); 2143c69f721fSFande Kong /* Ignore negative row indices 2144c69f721fSFande Kong * And negative column indices should be automatically ignored in hypre 2145c69f721fSFande Kong * */ 21462cf14000SStefano Zampini for (i = 0; i < m; i++) { 21472cf14000SStefano Zampini if (idxm[i] >= 0) { 21482cf14000SStefano Zampini HYPRE_Int hn = (HYPRE_Int)n; 2149792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixGetValues, hA->ij, 1, &hn, (HYPRE_BigInt *)&idxm[i], (HYPRE_BigInt *)idxn, (HYPRE_Complex *)(v + i * n)); 21502cf14000SStefano Zampini } 21512cf14000SStefano Zampini } 21523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2153c69f721fSFande Kong } 2154c69f721fSFande Kong 2155d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetOption_HYPRE(Mat A, MatOption op, PetscBool flg) 2156d71ae5a4SJacob Faibussowitsch { 2157ddbeb582SStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 2158ddbeb582SStefano Zampini 2159ddbeb582SStefano Zampini PetscFunctionBegin; 2160c6698e78SStefano Zampini switch (op) { 2161ddbeb582SStefano Zampini case MAT_NO_OFF_PROC_ENTRIES: 216248a46eb9SPierre Jolivet if (flg) PetscCallExternal(HYPRE_IJMatrixSetMaxOffProcElmts, hA->ij, 0); 2163ddbeb582SStefano Zampini break; 2164651b1cf9SStefano Zampini case MAT_IGNORE_OFF_PROC_ENTRIES: 2165651b1cf9SStefano Zampini hA->donotstash = flg; 2166d71ae5a4SJacob Faibussowitsch break; 2167d71ae5a4SJacob Faibussowitsch default: 2168d71ae5a4SJacob Faibussowitsch break; 2169ddbeb582SStefano Zampini } 21703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2171ddbeb582SStefano Zampini } 2172c69f721fSFande Kong 2173d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_HYPRE(Mat A, PetscViewer view) 2174d71ae5a4SJacob Faibussowitsch { 217545b8d346SStefano Zampini PetscViewerFormat format; 217645b8d346SStefano Zampini 217745b8d346SStefano Zampini PetscFunctionBegin; 21789566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(view, &format)); 21793ba16761SJacob Faibussowitsch if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) PetscFunctionReturn(PETSC_SUCCESS); 218045b8d346SStefano Zampini if (format != PETSC_VIEWER_NATIVE) { 21816ea7df73SStefano Zampini Mat B; 21826ea7df73SStefano Zampini hypre_ParCSRMatrix *parcsr; 21836ea7df73SStefano Zampini PetscErrorCode (*mview)(Mat, PetscViewer) = NULL; 21846ea7df73SStefano Zampini 21859566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(A, &parcsr)); 21869566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(parcsr, MATAIJ, PETSC_USE_POINTER, &B)); 21879566063dSJacob Faibussowitsch PetscCall(MatGetOperation(B, MATOP_VIEW, (void (**)(void))&mview)); 218828b400f6SJacob Faibussowitsch PetscCheck(mview, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Missing view operation"); 21899566063dSJacob Faibussowitsch PetscCall((*mview)(B, view)); 21909566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 219145b8d346SStefano Zampini } else { 219245b8d346SStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE *)A->data; 219345b8d346SStefano Zampini PetscMPIInt size; 219445b8d346SStefano Zampini PetscBool isascii; 219545b8d346SStefano Zampini const char *filename; 219645b8d346SStefano Zampini 219745b8d346SStefano Zampini /* HYPRE uses only text files */ 21989566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERASCII, &isascii)); 219928b400f6SJacob Faibussowitsch PetscCheck(isascii, PetscObjectComm((PetscObject)view), PETSC_ERR_SUP, "PetscViewerType %s: native HYPRE format needs PETSCVIEWERASCII", ((PetscObject)view)->type_name); 22009566063dSJacob Faibussowitsch PetscCall(PetscViewerFileGetName(view, &filename)); 2201792fecdfSBarry Smith PetscCallExternal(HYPRE_IJMatrixPrint, hA->ij, filename); 22029566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(hA->comm, &size)); 220345b8d346SStefano Zampini if (size > 1) { 22049566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(view, "Matrix files: %s.%05d ... %s.%05d\n", filename, 0, filename, size - 1)); 220545b8d346SStefano Zampini } else { 22069566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(view, "Matrix file: %s.%05d\n", filename, 0)); 220745b8d346SStefano Zampini } 220845b8d346SStefano Zampini } 22093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 221045b8d346SStefano Zampini } 221145b8d346SStefano Zampini 2212d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCopy_HYPRE(Mat A, Mat B, MatStructure str) 2213d71ae5a4SJacob Faibussowitsch { 2214465edc17SStefano Zampini hypre_ParCSRMatrix *acsr, *bcsr; 2215465edc17SStefano Zampini 2216465edc17SStefano Zampini PetscFunctionBegin; 2217465edc17SStefano Zampini if (str == SAME_NONZERO_PATTERN && A->ops->copy == B->ops->copy) { 22189566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(A, &acsr)); 22199566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(B, &bcsr)); 2220792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixCopy, acsr, bcsr, 1); 22219566063dSJacob Faibussowitsch PetscCall(MatSetOption(B, MAT_SORTED_FULL, PETSC_TRUE)); /* "perfect" preallocation, so no need for hypre_AuxParCSRMatrixNeedAux */ 22229566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 22239566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 2224465edc17SStefano Zampini } else { 22259566063dSJacob Faibussowitsch PetscCall(MatCopy_Basic(A, B, str)); 2226465edc17SStefano Zampini } 22273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2228465edc17SStefano Zampini } 2229465edc17SStefano Zampini 2230d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetDiagonal_HYPRE(Mat A, Vec d) 2231d71ae5a4SJacob Faibussowitsch { 22326305df00SStefano Zampini hypre_ParCSRMatrix *parcsr; 22336305df00SStefano Zampini hypre_CSRMatrix *dmat; 223439accc25SStefano Zampini HYPRE_Complex *a; 22356305df00SStefano Zampini PetscBool cong; 22366305df00SStefano Zampini 22376305df00SStefano Zampini PetscFunctionBegin; 22389566063dSJacob Faibussowitsch PetscCall(MatHasCongruentLayouts(A, &cong)); 223928b400f6SJacob Faibussowitsch PetscCheck(cong, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Only for square matrices with same local distributions of rows and columns"); 22409566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR_HYPRE(A, &parcsr)); 22416305df00SStefano Zampini dmat = hypre_ParCSRMatrixDiag(parcsr); 22426305df00SStefano Zampini if (dmat) { 224306977982Sstefanozampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 224406977982Sstefanozampini HYPRE_MemoryLocation mem = hypre_CSRMatrixMemoryLocation(dmat); 224506977982Sstefanozampini #else 224606977982Sstefanozampini HYPRE_MemoryLocation mem = HYPRE_MEMORY_HOST; 224706977982Sstefanozampini #endif 224806977982Sstefanozampini 224906977982Sstefanozampini if (mem != HYPRE_MEMORY_HOST) PetscCall(VecGetArrayWriteAndMemType(d, (PetscScalar **)&a, NULL)); 225006977982Sstefanozampini else PetscCall(VecGetArrayWrite(d, (PetscScalar **)&a)); 225106977982Sstefanozampini hypre_CSRMatrixExtractDiagonal(dmat, a, 0); 225206977982Sstefanozampini if (mem != HYPRE_MEMORY_HOST) PetscCall(VecRestoreArrayWriteAndMemType(d, (PetscScalar **)&a)); 225306977982Sstefanozampini else PetscCall(VecRestoreArrayWrite(d, (PetscScalar **)&a)); 22546305df00SStefano Zampini } 22553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22566305df00SStefano Zampini } 22576305df00SStefano Zampini 2258363d496dSStefano Zampini #include <petscblaslapack.h> 2259363d496dSStefano Zampini 2260d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAXPY_HYPRE(Mat Y, PetscScalar a, Mat X, MatStructure str) 2261d71ae5a4SJacob Faibussowitsch { 2262363d496dSStefano Zampini PetscFunctionBegin; 22636ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 22646ea7df73SStefano Zampini { 22656ea7df73SStefano Zampini Mat B; 22666ea7df73SStefano Zampini hypre_ParCSRMatrix *x, *y, *z; 22676ea7df73SStefano Zampini 22689566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR(Y, &y)); 22699566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR(X, &x)); 2270792fecdfSBarry Smith PetscCallExternal(hypre_ParCSRMatrixAdd, 1.0, y, 1.0, x, &z); 22719566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(z, MATHYPRE, PETSC_OWN_POINTER, &B)); 22729566063dSJacob Faibussowitsch PetscCall(MatHeaderMerge(Y, &B)); 22736ea7df73SStefano Zampini } 22746ea7df73SStefano Zampini #else 2275363d496dSStefano Zampini if (str == SAME_NONZERO_PATTERN) { 2276363d496dSStefano Zampini hypre_ParCSRMatrix *x, *y; 2277363d496dSStefano Zampini hypre_CSRMatrix *xloc, *yloc; 2278363d496dSStefano Zampini PetscInt xnnz, ynnz; 227939accc25SStefano Zampini HYPRE_Complex *xarr, *yarr; 2280363d496dSStefano Zampini PetscBLASInt one = 1, bnz; 2281363d496dSStefano Zampini 22829566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR(Y, &y)); 22839566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR(X, &x)); 2284363d496dSStefano Zampini 2285363d496dSStefano Zampini /* diagonal block */ 2286363d496dSStefano Zampini xloc = hypre_ParCSRMatrixDiag(x); 2287363d496dSStefano Zampini yloc = hypre_ParCSRMatrixDiag(y); 2288363d496dSStefano Zampini xnnz = 0; 2289363d496dSStefano Zampini ynnz = 0; 2290363d496dSStefano Zampini xarr = NULL; 2291363d496dSStefano Zampini yarr = NULL; 2292363d496dSStefano Zampini if (xloc) { 229339accc25SStefano Zampini xarr = hypre_CSRMatrixData(xloc); 2294363d496dSStefano Zampini xnnz = hypre_CSRMatrixNumNonzeros(xloc); 2295363d496dSStefano Zampini } 2296363d496dSStefano Zampini if (yloc) { 229739accc25SStefano Zampini yarr = hypre_CSRMatrixData(yloc); 2298363d496dSStefano Zampini ynnz = hypre_CSRMatrixNumNonzeros(yloc); 2299363d496dSStefano Zampini } 230008401ef6SPierre Jolivet PetscCheck(xnnz == ynnz, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Different number of nonzeros in diagonal block %" PetscInt_FMT " != %" PetscInt_FMT, xnnz, ynnz); 23019566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(xnnz, &bnz)); 2302792fecdfSBarry Smith PetscCallBLAS("BLASaxpy", BLASaxpy_(&bnz, &a, (PetscScalar *)xarr, &one, (PetscScalar *)yarr, &one)); 2303363d496dSStefano Zampini 2304363d496dSStefano Zampini /* off-diagonal block */ 2305363d496dSStefano Zampini xloc = hypre_ParCSRMatrixOffd(x); 2306363d496dSStefano Zampini yloc = hypre_ParCSRMatrixOffd(y); 2307363d496dSStefano Zampini xnnz = 0; 2308363d496dSStefano Zampini ynnz = 0; 2309363d496dSStefano Zampini xarr = NULL; 2310363d496dSStefano Zampini yarr = NULL; 2311363d496dSStefano Zampini if (xloc) { 231239accc25SStefano Zampini xarr = hypre_CSRMatrixData(xloc); 2313363d496dSStefano Zampini xnnz = hypre_CSRMatrixNumNonzeros(xloc); 2314363d496dSStefano Zampini } 2315363d496dSStefano Zampini if (yloc) { 231639accc25SStefano Zampini yarr = hypre_CSRMatrixData(yloc); 2317363d496dSStefano Zampini ynnz = hypre_CSRMatrixNumNonzeros(yloc); 2318363d496dSStefano Zampini } 231908401ef6SPierre 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); 23209566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(xnnz, &bnz)); 2321792fecdfSBarry Smith PetscCallBLAS("BLASaxpy", BLASaxpy_(&bnz, &a, (PetscScalar *)xarr, &one, (PetscScalar *)yarr, &one)); 2322363d496dSStefano Zampini } else if (str == SUBSET_NONZERO_PATTERN) { 23239566063dSJacob Faibussowitsch PetscCall(MatAXPY_Basic(Y, a, X, str)); 2324363d496dSStefano Zampini } else { 2325363d496dSStefano Zampini Mat B; 2326363d496dSStefano Zampini 23279566063dSJacob Faibussowitsch PetscCall(MatAXPY_Basic_Preallocate(Y, X, &B)); 23289566063dSJacob Faibussowitsch PetscCall(MatAXPY_BasicWithPreallocation(B, Y, a, X, str)); 23299566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(Y, &B)); 2330363d496dSStefano Zampini } 23316ea7df73SStefano Zampini #endif 23323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2333363d496dSStefano Zampini } 2334363d496dSStefano Zampini 23352c4ab24aSJunchao Zhang static PetscErrorCode MatDuplicate_HYPRE(Mat A, MatDuplicateOption op, Mat *B) 23362c4ab24aSJunchao Zhang { 23372c4ab24aSJunchao Zhang hypre_ParCSRMatrix *parcsr = NULL; 23382c4ab24aSJunchao Zhang PetscCopyMode cpmode; 23392c4ab24aSJunchao Zhang Mat_HYPRE *hA; 23402c4ab24aSJunchao Zhang 23412c4ab24aSJunchao Zhang PetscFunctionBegin; 23422c4ab24aSJunchao Zhang PetscCall(MatHYPREGetParCSR_HYPRE(A, &parcsr)); 23432c4ab24aSJunchao Zhang if (op == MAT_DO_NOT_COPY_VALUES || op == MAT_SHARE_NONZERO_PATTERN) { 23442c4ab24aSJunchao Zhang parcsr = hypre_ParCSRMatrixClone(parcsr, 0); 23452c4ab24aSJunchao Zhang cpmode = PETSC_OWN_POINTER; 23462c4ab24aSJunchao Zhang } else { 23472c4ab24aSJunchao Zhang cpmode = PETSC_COPY_VALUES; 23482c4ab24aSJunchao Zhang } 23492c4ab24aSJunchao Zhang PetscCall(MatCreateFromParCSR(parcsr, MATHYPRE, cpmode, B)); 23502c4ab24aSJunchao Zhang hA = (Mat_HYPRE *)A->data; 23512c4ab24aSJunchao Zhang if (hA->cooMat) { 235206977982Sstefanozampini Mat_HYPRE *hB = (Mat_HYPRE *)((*B)->data); 2353b73e3080SStefano Zampini op = (op == MAT_DO_NOT_COPY_VALUES) ? op : MAT_COPY_VALUES; 2354b73e3080SStefano Zampini /* Cannot simply increase the reference count of hA->cooMat, since B needs to share cooMat's data array */ 235506977982Sstefanozampini PetscCall(MatDuplicate(hA->cooMat, op, &hB->cooMat)); 235606977982Sstefanozampini PetscCall(MatHYPRE_AttachCOOMat(*B)); 23572c4ab24aSJunchao Zhang } 23582c4ab24aSJunchao Zhang PetscFunctionReturn(PETSC_SUCCESS); 23592c4ab24aSJunchao Zhang } 23602c4ab24aSJunchao Zhang 2361d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetPreallocationCOO_HYPRE(Mat mat, PetscCount coo_n, PetscInt coo_i[], PetscInt coo_j[]) 2362d71ae5a4SJacob Faibussowitsch { 236306977982Sstefanozampini Mat_HYPRE *hmat = (Mat_HYPRE *)mat->data; 23645fbaff96SJunchao Zhang 23655fbaff96SJunchao Zhang PetscFunctionBegin; 2366651b1cf9SStefano Zampini /* Build an agent matrix cooMat with AIJ format 23675fbaff96SJunchao 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. 23685fbaff96SJunchao Zhang */ 236906977982Sstefanozampini PetscCall(MatHYPRE_CreateCOOMat(mat)); 237006977982Sstefanozampini PetscCall(MatSetOption(hmat->cooMat, MAT_IGNORE_OFF_PROC_ENTRIES, hmat->donotstash)); 237106977982Sstefanozampini PetscCall(MatSetOption(hmat->cooMat, MAT_NO_OFF_PROC_ENTRIES, mat->nooffprocentries)); 2372651b1cf9SStefano Zampini 2373651b1cf9SStefano Zampini /* MatSetPreallocationCOO_SeqAIJ and MatSetPreallocationCOO_MPIAIJ uses this specific 2374651b1cf9SStefano Zampini name to automatically put the diagonal entries first */ 237506977982Sstefanozampini PetscCall(PetscObjectSetName((PetscObject)hmat->cooMat, "_internal_COO_mat_for_hypre")); 237606977982Sstefanozampini PetscCall(MatSetPreallocationCOO(hmat->cooMat, coo_n, coo_i, coo_j)); 237706977982Sstefanozampini hmat->cooMat->assembled = PETSC_TRUE; 23785fbaff96SJunchao Zhang 23795fbaff96SJunchao Zhang /* Copy the sparsity pattern from cooMat to hypre IJMatrix hmat->ij */ 23805fbaff96SJunchao Zhang PetscCall(MatSetOption(mat, MAT_SORTED_FULL, PETSC_TRUE)); 238106977982Sstefanozampini PetscCall(MatHYPRE_CreateFromMat(hmat->cooMat, hmat)); /* Create hmat->ij and preallocate it */ 238206977982Sstefanozampini PetscCall(MatHYPRE_IJMatrixCopyIJ(hmat->cooMat, hmat->ij)); /* Copy A's (i,j) to hmat->ij */ 23835fbaff96SJunchao Zhang 23845fbaff96SJunchao Zhang mat->preallocated = PETSC_TRUE; 23855fbaff96SJunchao Zhang PetscCall(MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY)); 23865fbaff96SJunchao Zhang PetscCall(MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY)); /* Migrate mat to device if it is bound to. Hypre builds its own SpMV context here */ 23875fbaff96SJunchao Zhang 23882c4ab24aSJunchao Zhang /* Attach cooMat to mat */ 238906977982Sstefanozampini PetscCall(MatHYPRE_AttachCOOMat(mat)); 23903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23915fbaff96SJunchao Zhang } 23925fbaff96SJunchao Zhang 2393d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetValuesCOO_HYPRE(Mat mat, const PetscScalar v[], InsertMode imode) 2394d71ae5a4SJacob Faibussowitsch { 23955fbaff96SJunchao Zhang Mat_HYPRE *hmat = (Mat_HYPRE *)mat->data; 23965fbaff96SJunchao Zhang 23975fbaff96SJunchao Zhang PetscFunctionBegin; 2398b73e3080SStefano Zampini PetscCheck(hmat->cooMat, PetscObjectComm((PetscObject)mat), PETSC_ERR_PLIB, "HYPRE COO delegate matrix has not been created yet"); 23995fbaff96SJunchao Zhang PetscCall(MatSetValuesCOO(hmat->cooMat, v, imode)); 2400651b1cf9SStefano Zampini PetscCall(MatViewFromOptions(hmat->cooMat, (PetscObject)mat, "-cooMat_view")); 24013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 24025fbaff96SJunchao Zhang } 24035fbaff96SJunchao Zhang 2404a055b5aaSBarry Smith /*MC 24052ef1f0ffSBarry Smith MATHYPRE - "hypre" - A matrix type to be used for sequential and parallel sparse matrices 2406a055b5aaSBarry Smith based on the hypre IJ interface. 2407a055b5aaSBarry Smith 2408a055b5aaSBarry Smith Level: intermediate 2409a055b5aaSBarry Smith 24101cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatCreate()`, `MatHYPRESetPreallocation` 2411a055b5aaSBarry Smith M*/ 2412a055b5aaSBarry Smith 2413d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatCreate_HYPRE(Mat B) 2414d71ae5a4SJacob Faibussowitsch { 241563c07aadSStefano Zampini Mat_HYPRE *hB; 2416a9e6c71bSAlex Lindsay #if defined(PETSC_HAVE_HYPRE_DEVICE) 2417a9e6c71bSAlex Lindsay HYPRE_MemoryLocation memory_location; 2418a9e6c71bSAlex Lindsay #endif 241963c07aadSStefano Zampini 242063c07aadSStefano Zampini PetscFunctionBegin; 2421a9e6c71bSAlex Lindsay PetscHYPREInitialize(); 24224dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&hB)); 24236ea7df73SStefano Zampini 2424978814f1SStefano Zampini hB->inner_free = PETSC_TRUE; 2425651b1cf9SStefano Zampini hB->array_available = PETSC_TRUE; 2426978814f1SStefano Zampini 242763c07aadSStefano Zampini B->data = (void *)hB; 242863c07aadSStefano Zampini 24299566063dSJacob Faibussowitsch PetscCall(PetscMemzero(B->ops, sizeof(struct _MatOps))); 243063c07aadSStefano Zampini B->ops->mult = MatMult_HYPRE; 243163c07aadSStefano Zampini B->ops->multtranspose = MatMultTranspose_HYPRE; 2432414bd5c3SStefano Zampini B->ops->multadd = MatMultAdd_HYPRE; 2433414bd5c3SStefano Zampini B->ops->multtransposeadd = MatMultTransposeAdd_HYPRE; 243463c07aadSStefano Zampini B->ops->setup = MatSetUp_HYPRE; 243563c07aadSStefano Zampini B->ops->destroy = MatDestroy_HYPRE; 243663c07aadSStefano Zampini B->ops->assemblyend = MatAssemblyEnd_HYPRE; 2437c69f721fSFande Kong B->ops->assemblybegin = MatAssemblyBegin_HYPRE; 2438d975228cSstefano_zampini B->ops->setvalues = MatSetValues_HYPRE; 243968ec7858SStefano Zampini B->ops->missingdiagonal = MatMissingDiagonal_HYPRE; 244068ec7858SStefano Zampini B->ops->scale = MatScale_HYPRE; 244168ec7858SStefano Zampini B->ops->zerorowscolumns = MatZeroRowsColumns_HYPRE; 2442c69f721fSFande Kong B->ops->zeroentries = MatZeroEntries_HYPRE; 2443c69f721fSFande Kong B->ops->zerorows = MatZeroRows_HYPRE; 2444c69f721fSFande Kong B->ops->getrow = MatGetRow_HYPRE; 2445c69f721fSFande Kong B->ops->restorerow = MatRestoreRow_HYPRE; 2446c69f721fSFande Kong B->ops->getvalues = MatGetValues_HYPRE; 2447ddbeb582SStefano Zampini B->ops->setoption = MatSetOption_HYPRE; 244845b8d346SStefano Zampini B->ops->duplicate = MatDuplicate_HYPRE; 2449465edc17SStefano Zampini B->ops->copy = MatCopy_HYPRE; 245045b8d346SStefano Zampini B->ops->view = MatView_HYPRE; 24516305df00SStefano Zampini B->ops->getdiagonal = MatGetDiagonal_HYPRE; 2452363d496dSStefano Zampini B->ops->axpy = MatAXPY_HYPRE; 24534222ddf1SHong Zhang B->ops->productsetfromoptions = MatProductSetFromOptions_HYPRE; 24546ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 24556ea7df73SStefano Zampini B->ops->bindtocpu = MatBindToCPU_HYPRE; 2456a9e6c71bSAlex Lindsay /* Get hypre's default memory location. Users can control this using the corresponding HYPRE_SetMemoryLocation API */ 2457a9e6c71bSAlex Lindsay PetscCallExternal(HYPRE_GetMemoryLocation, &memory_location); 2458a9e6c71bSAlex Lindsay B->boundtocpu = (memory_location == HYPRE_MEMORY_HOST) ? PETSC_TRUE : PETSC_FALSE; 24596ea7df73SStefano Zampini #endif 246045b8d346SStefano Zampini 246145b8d346SStefano Zampini /* build cache for off array entries formed */ 24629566063dSJacob Faibussowitsch PetscCall(MatStashCreate_Private(PetscObjectComm((PetscObject)B), 1, &B->stash)); 246363c07aadSStefano Zampini 24649566063dSJacob Faibussowitsch PetscCall(PetscCommGetComm(PetscObjectComm((PetscObject)B), &hB->comm)); 24659566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATHYPRE)); 24669566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_hypre_aij_C", MatConvert_HYPRE_AIJ)); 24679566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_hypre_is_C", MatConvert_HYPRE_IS)); 24689566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaij_hypre_C", MatProductSetFromOptions_HYPRE)); 24699566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_mpiaij_hypre_C", MatProductSetFromOptions_HYPRE)); 24709566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatHYPRESetPreallocation_C", MatHYPRESetPreallocation_HYPRE)); 24719566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatHYPREGetParCSR_C", MatHYPREGetParCSR_HYPRE)); 24725fbaff96SJunchao Zhang PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSetPreallocationCOO_C", MatSetPreallocationCOO_HYPRE)); 24735fbaff96SJunchao Zhang PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSetValuesCOO_C", MatSetValuesCOO_HYPRE)); 24746ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 24756ea7df73SStefano Zampini #if defined(HYPRE_USING_HIP) 247606977982Sstefanozampini PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaijhipsparse_hypre_C", MatProductSetFromOptions_HYPRE)); 247706977982Sstefanozampini PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_mpiaijhipsparse_hypre_C", MatProductSetFromOptions_HYPRE)); 24789566063dSJacob Faibussowitsch PetscCall(PetscDeviceInitialize(PETSC_DEVICE_HIP)); 24799566063dSJacob Faibussowitsch PetscCall(MatSetVecType(B, VECHIP)); 24806ea7df73SStefano Zampini #endif 24816ea7df73SStefano Zampini #if defined(HYPRE_USING_CUDA) 248206977982Sstefanozampini PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaijcusparse_hypre_C", MatProductSetFromOptions_HYPRE)); 248306977982Sstefanozampini PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_mpiaijcusparse_hypre_C", MatProductSetFromOptions_HYPRE)); 24849566063dSJacob Faibussowitsch PetscCall(PetscDeviceInitialize(PETSC_DEVICE_CUDA)); 24859566063dSJacob Faibussowitsch PetscCall(MatSetVecType(B, VECCUDA)); 24866ea7df73SStefano Zampini #endif 24876ea7df73SStefano Zampini #endif 24883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 248963c07aadSStefano Zampini } 2490