163c07aadSStefano Zampini 263c07aadSStefano Zampini /* 363c07aadSStefano Zampini Creates hypre ijmatrix from PETSc matrix 463c07aadSStefano Zampini */ 5225daaf8SStefano Zampini 6c6698e78SStefano Zampini #include <petscpkg_version.h> 739accc25SStefano Zampini #include <petsc/private/petschypre.h> 8dd9c0a25Sstefano_zampini #include <petscmathypre.h> 963c07aadSStefano Zampini #include <petsc/private/matimpl.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); 2463c07aadSStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixFastCopy_MPIAIJ(Mat,HYPRE_IJMatrix); 2563c07aadSStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixFastCopy_SeqAIJ(Mat,HYPRE_IJMatrix); 2639accc25SStefano Zampini static PetscErrorCode MatHYPRE_MultKernel_Private(Mat,HYPRE_Complex,Vec,HYPRE_Complex,Vec,PetscBool); 27225daaf8SStefano Zampini static PetscErrorCode hypre_array_destroy(void*); 286ea7df73SStefano Zampini static PetscErrorCode MatSetValues_HYPRE(Mat,PetscInt,const PetscInt[],PetscInt,const PetscInt[],const PetscScalar[],InsertMode ins); 2963c07aadSStefano Zampini 3063c07aadSStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixPreallocate(Mat A_d, Mat A_o, HYPRE_IJMatrix ij) 3163c07aadSStefano Zampini { 3263c07aadSStefano Zampini PetscErrorCode ierr; 3363c07aadSStefano Zampini PetscInt i,n_d,n_o; 3463c07aadSStefano Zampini const PetscInt *ia_d,*ia_o; 3563c07aadSStefano Zampini PetscBool done_d=PETSC_FALSE,done_o=PETSC_FALSE; 362cf14000SStefano Zampini HYPRE_Int *nnz_d=NULL,*nnz_o=NULL; 3763c07aadSStefano Zampini 3863c07aadSStefano Zampini PetscFunctionBegin; 3963c07aadSStefano Zampini if (A_d) { /* determine number of nonzero entries in local diagonal part */ 4063c07aadSStefano Zampini ierr = MatGetRowIJ(A_d,0,PETSC_FALSE,PETSC_FALSE,&n_d,&ia_d,NULL,&done_d);CHKERRQ(ierr); 4163c07aadSStefano Zampini if (done_d) { 4263c07aadSStefano Zampini ierr = PetscMalloc1(n_d,&nnz_d);CHKERRQ(ierr); 4363c07aadSStefano Zampini for (i=0; i<n_d; i++) { 4463c07aadSStefano Zampini nnz_d[i] = ia_d[i+1] - ia_d[i]; 4563c07aadSStefano Zampini } 4663c07aadSStefano Zampini } 4763c07aadSStefano Zampini ierr = MatRestoreRowIJ(A_d,0,PETSC_FALSE,PETSC_FALSE,NULL,&ia_d,NULL,&done_d);CHKERRQ(ierr); 4863c07aadSStefano Zampini } 4963c07aadSStefano Zampini if (A_o) { /* determine number of nonzero entries in local off-diagonal part */ 5063c07aadSStefano Zampini ierr = MatGetRowIJ(A_o,0,PETSC_FALSE,PETSC_FALSE,&n_o,&ia_o,NULL,&done_o);CHKERRQ(ierr); 5163c07aadSStefano Zampini if (done_o) { 5263c07aadSStefano Zampini ierr = PetscMalloc1(n_o,&nnz_o);CHKERRQ(ierr); 5363c07aadSStefano Zampini for (i=0; i<n_o; i++) { 5463c07aadSStefano Zampini nnz_o[i] = ia_o[i+1] - ia_o[i]; 5563c07aadSStefano Zampini } 5663c07aadSStefano Zampini } 5763c07aadSStefano Zampini ierr = MatRestoreRowIJ(A_o,0,PETSC_FALSE,PETSC_FALSE,&n_o,&ia_o,NULL,&done_o);CHKERRQ(ierr); 5863c07aadSStefano Zampini } 5963c07aadSStefano Zampini if (done_d) { /* set number of nonzeros in HYPRE IJ matrix */ 6063c07aadSStefano Zampini if (!done_o) { /* only diagonal part */ 6122235d61SPierre Jolivet ierr = PetscCalloc1(n_d,&nnz_o);CHKERRQ(ierr); 6263c07aadSStefano Zampini } 63c6698e78SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2,16,0) 64c6698e78SStefano Zampini { /* If we don't do this, the columns of the matrix will be all zeros! */ 65c6698e78SStefano Zampini hypre_AuxParCSRMatrix *aux_matrix; 66c6698e78SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix*)hypre_IJMatrixTranslator(ij); 67c6698e78SStefano Zampini hypre_AuxParCSRMatrixDestroy(aux_matrix); 68c6698e78SStefano Zampini hypre_IJMatrixTranslator(ij) = NULL; 692cf14000SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixSetDiagOffdSizes,(ij,nnz_d,nnz_o)); 7022235d61SPierre Jolivet /* it seems they partially fixed it in 2.19.0 */ 7122235d61SPierre Jolivet #if PETSC_PKG_HYPRE_VERSION_LT(2,19,0) 72c6698e78SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix*)hypre_IJMatrixTranslator(ij); 73c6698e78SStefano Zampini hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 1; 7422235d61SPierre Jolivet #endif 75c6698e78SStefano Zampini } 76c6698e78SStefano Zampini #else 772cf14000SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixSetDiagOffdSizes,(ij,nnz_d,nnz_o)); 78c6698e78SStefano Zampini #endif 7963c07aadSStefano Zampini ierr = PetscFree(nnz_d);CHKERRQ(ierr); 8063c07aadSStefano Zampini ierr = PetscFree(nnz_o);CHKERRQ(ierr); 8163c07aadSStefano Zampini } 8263c07aadSStefano Zampini PetscFunctionReturn(0); 8363c07aadSStefano Zampini } 8463c07aadSStefano Zampini 8563c07aadSStefano Zampini static PetscErrorCode MatHYPRE_CreateFromMat(Mat A, Mat_HYPRE *hA) 8663c07aadSStefano Zampini { 8763c07aadSStefano Zampini PetscErrorCode ierr; 8863c07aadSStefano Zampini PetscInt rstart,rend,cstart,cend; 8963c07aadSStefano Zampini 9063c07aadSStefano Zampini PetscFunctionBegin; 91d975228cSstefano_zampini ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 92d975228cSstefano_zampini ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 9363c07aadSStefano Zampini rstart = A->rmap->rstart; 9463c07aadSStefano Zampini rend = A->rmap->rend; 9563c07aadSStefano Zampini cstart = A->cmap->rstart; 9663c07aadSStefano Zampini cend = A->cmap->rend; 9763c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixCreate,(hA->comm,rstart,rend-1,cstart,cend-1,&hA->ij)); 9863c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixSetObjectType,(hA->ij,HYPRE_PARCSR)); 9963c07aadSStefano Zampini { 10063c07aadSStefano Zampini PetscBool same; 10163c07aadSStefano Zampini Mat A_d,A_o; 10263c07aadSStefano Zampini const PetscInt *colmap; 103b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)A,MATMPIAIJ,&same);CHKERRQ(ierr); 10463c07aadSStefano Zampini if (same) { 10563c07aadSStefano Zampini ierr = MatMPIAIJGetSeqAIJ(A,&A_d,&A_o,&colmap);CHKERRQ(ierr); 10663c07aadSStefano Zampini ierr = MatHYPRE_IJMatrixPreallocate(A_d,A_o,hA->ij);CHKERRQ(ierr); 10763c07aadSStefano Zampini PetscFunctionReturn(0); 10863c07aadSStefano Zampini } 109b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)A,MATMPIBAIJ,&same);CHKERRQ(ierr); 11063c07aadSStefano Zampini if (same) { 11163c07aadSStefano Zampini ierr = MatMPIBAIJGetSeqBAIJ(A,&A_d,&A_o,&colmap);CHKERRQ(ierr); 11263c07aadSStefano Zampini ierr = MatHYPRE_IJMatrixPreallocate(A_d,A_o,hA->ij);CHKERRQ(ierr); 11363c07aadSStefano Zampini PetscFunctionReturn(0); 11463c07aadSStefano Zampini } 115b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)A,MATSEQAIJ,&same);CHKERRQ(ierr); 11663c07aadSStefano Zampini if (same) { 11763c07aadSStefano Zampini ierr = MatHYPRE_IJMatrixPreallocate(A,NULL,hA->ij);CHKERRQ(ierr); 11863c07aadSStefano Zampini PetscFunctionReturn(0); 11963c07aadSStefano Zampini } 120b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)A,MATSEQBAIJ,&same);CHKERRQ(ierr); 12163c07aadSStefano Zampini if (same) { 12263c07aadSStefano Zampini ierr = MatHYPRE_IJMatrixPreallocate(A,NULL,hA->ij);CHKERRQ(ierr); 12363c07aadSStefano Zampini PetscFunctionReturn(0); 12463c07aadSStefano Zampini } 12563c07aadSStefano Zampini } 12663c07aadSStefano Zampini PetscFunctionReturn(0); 12763c07aadSStefano Zampini } 12863c07aadSStefano Zampini 12963c07aadSStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixCopy(Mat A, HYPRE_IJMatrix ij) 13063c07aadSStefano Zampini { 13163c07aadSStefano Zampini PetscErrorCode ierr; 13263c07aadSStefano Zampini PetscInt i,rstart,rend,ncols,nr,nc; 13363c07aadSStefano Zampini const PetscScalar *values; 13463c07aadSStefano Zampini const PetscInt *cols; 13563c07aadSStefano Zampini PetscBool flg; 13663c07aadSStefano Zampini 13763c07aadSStefano Zampini PetscFunctionBegin; 1386ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_LT(2,19,0) 1396ea7df73SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixInitialize,(ij)); 1406ea7df73SStefano Zampini #else 1416ea7df73SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixInitialize_v2,(ij,HYPRE_MEMORY_HOST)); 1426ea7df73SStefano Zampini #endif 143b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)A,MATMPIAIJ,&flg);CHKERRQ(ierr); 14463c07aadSStefano Zampini ierr = MatGetSize(A,&nr,&nc);CHKERRQ(ierr); 14563c07aadSStefano Zampini if (flg && nr == nc) { 14663c07aadSStefano Zampini ierr = MatHYPRE_IJMatrixFastCopy_MPIAIJ(A,ij);CHKERRQ(ierr); 14763c07aadSStefano Zampini PetscFunctionReturn(0); 14863c07aadSStefano Zampini } 149b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)A,MATSEQAIJ,&flg);CHKERRQ(ierr); 15063c07aadSStefano Zampini if (flg) { 15163c07aadSStefano Zampini ierr = MatHYPRE_IJMatrixFastCopy_SeqAIJ(A,ij);CHKERRQ(ierr); 15263c07aadSStefano Zampini PetscFunctionReturn(0); 15363c07aadSStefano Zampini } 15463c07aadSStefano Zampini 15563c07aadSStefano Zampini ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 15663c07aadSStefano Zampini for (i=rstart; i<rend; i++) { 15763c07aadSStefano Zampini ierr = MatGetRow(A,i,&ncols,&cols,&values);CHKERRQ(ierr); 158e3977e59Sstefano_zampini if (ncols) { 1592cf14000SStefano Zampini HYPRE_Int nc = (HYPRE_Int)ncols; 1602cf14000SStefano Zampini 1612cf14000SStefano Zampini if ((PetscInt)nc != ncols) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Hypre overflow! number of columns %D for row %D",ncols,i); 16239accc25SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixSetValues,(ij,1,&nc,(HYPRE_BigInt *)&i,(HYPRE_BigInt *)cols,(HYPRE_Complex *)values)); 163e3977e59Sstefano_zampini } 16463c07aadSStefano Zampini ierr = MatRestoreRow(A,i,&ncols,&cols,&values);CHKERRQ(ierr); 16563c07aadSStefano Zampini } 16663c07aadSStefano Zampini PetscFunctionReturn(0); 16763c07aadSStefano Zampini } 16863c07aadSStefano Zampini 16963c07aadSStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixFastCopy_SeqAIJ(Mat A, HYPRE_IJMatrix ij) 17063c07aadSStefano Zampini { 17163c07aadSStefano Zampini PetscErrorCode ierr; 17263c07aadSStefano Zampini Mat_SeqAIJ *pdiag = (Mat_SeqAIJ*)A->data; 17358968eb6SStefano Zampini HYPRE_Int type; 17463c07aadSStefano Zampini hypre_ParCSRMatrix *par_matrix; 17563c07aadSStefano Zampini hypre_AuxParCSRMatrix *aux_matrix; 17663c07aadSStefano Zampini hypre_CSRMatrix *hdiag; 1772cf14000SStefano Zampini PetscBool sameint = (PetscBool)(sizeof(PetscInt) == sizeof(HYPRE_Int)); 1786ea7df73SStefano Zampini const PetscScalar *pa; 17963c07aadSStefano Zampini 18063c07aadSStefano Zampini PetscFunctionBegin; 181ea9daf28SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(ij,&type)); 182ea9daf28SStefano Zampini if (type != HYPRE_PARCSR) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 183ea9daf28SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(ij,(void**)&par_matrix)); 18463c07aadSStefano Zampini hdiag = hypre_ParCSRMatrixDiag(par_matrix); 18563c07aadSStefano Zampini /* 18663c07aadSStefano Zampini this is the Hack part where we monkey directly with the hypre datastructures 18763c07aadSStefano Zampini */ 1882cf14000SStefano Zampini if (sameint) { 189580bdb30SBarry Smith ierr = PetscArraycpy(hdiag->i,pdiag->i,A->rmap->n + 1);CHKERRQ(ierr); 190580bdb30SBarry Smith ierr = PetscArraycpy(hdiag->j,pdiag->j,pdiag->nz);CHKERRQ(ierr); 1912cf14000SStefano Zampini } else { 1922cf14000SStefano Zampini PetscInt i; 1932cf14000SStefano Zampini 1942cf14000SStefano Zampini for (i=0;i<A->rmap->n + 1;i++) hdiag->i[i] = (HYPRE_Int)pdiag->i[i]; 1952cf14000SStefano Zampini for (i=0;i<pdiag->nz;i++) hdiag->j[i] = (HYPRE_Int)pdiag->j[i]; 1962cf14000SStefano Zampini } 1976ea7df73SStefano Zampini 1986ea7df73SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&pa);CHKERRQ(ierr); 1996ea7df73SStefano Zampini ierr = PetscArraycpy(hdiag->data,pa,pdiag->nz);CHKERRQ(ierr); 2006ea7df73SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&pa);CHKERRQ(ierr); 201ea9daf28SStefano Zampini 202ea9daf28SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix*)hypre_IJMatrixTranslator(ij); 20363c07aadSStefano Zampini hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 0; 20463c07aadSStefano Zampini PetscFunctionReturn(0); 20563c07aadSStefano Zampini } 20663c07aadSStefano Zampini 20763c07aadSStefano Zampini static PetscErrorCode MatHYPRE_IJMatrixFastCopy_MPIAIJ(Mat A, HYPRE_IJMatrix ij) 20863c07aadSStefano Zampini { 20963c07aadSStefano Zampini PetscErrorCode ierr; 21063c07aadSStefano Zampini Mat_MPIAIJ *pA = (Mat_MPIAIJ*)A->data; 21163c07aadSStefano Zampini Mat_SeqAIJ *pdiag,*poffd; 21263c07aadSStefano Zampini PetscInt i,*garray = pA->garray,*jj,cstart,*pjj; 2132cf14000SStefano Zampini HYPRE_Int *hjj,type; 21463c07aadSStefano Zampini hypre_ParCSRMatrix *par_matrix; 21563c07aadSStefano Zampini hypre_AuxParCSRMatrix *aux_matrix; 21663c07aadSStefano Zampini hypre_CSRMatrix *hdiag,*hoffd; 2172cf14000SStefano Zampini PetscBool sameint = (PetscBool)(sizeof(PetscInt) == sizeof(HYPRE_Int)); 2186ea7df73SStefano Zampini const PetscScalar *pa; 21963c07aadSStefano Zampini 22063c07aadSStefano Zampini PetscFunctionBegin; 22163c07aadSStefano Zampini pdiag = (Mat_SeqAIJ*) pA->A->data; 22263c07aadSStefano Zampini poffd = (Mat_SeqAIJ*) pA->B->data; 22363c07aadSStefano Zampini /* cstart is only valid for square MPIAIJ layed out in the usual way */ 22463c07aadSStefano Zampini ierr = MatGetOwnershipRange(A,&cstart,NULL);CHKERRQ(ierr); 22563c07aadSStefano Zampini 226ea9daf28SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(ij,&type)); 227ea9daf28SStefano Zampini if (type != HYPRE_PARCSR) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 228ea9daf28SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(ij,(void**)&par_matrix)); 22963c07aadSStefano Zampini hdiag = hypre_ParCSRMatrixDiag(par_matrix); 23063c07aadSStefano Zampini hoffd = hypre_ParCSRMatrixOffd(par_matrix); 23163c07aadSStefano Zampini 23263c07aadSStefano Zampini /* 23363c07aadSStefano Zampini this is the Hack part where we monkey directly with the hypre datastructures 23463c07aadSStefano Zampini */ 2352cf14000SStefano Zampini if (sameint) { 236580bdb30SBarry Smith ierr = PetscArraycpy(hdiag->i,pdiag->i,pA->A->rmap->n + 1);CHKERRQ(ierr); 2372cf14000SStefano Zampini } else { 2382cf14000SStefano Zampini for (i=0; i<pA->A->rmap->n + 1; i++) hdiag->i[i] = (HYPRE_Int)(pdiag->i[i]); 2392cf14000SStefano Zampini } 24063c07aadSStefano Zampini /* need to shift the diag column indices (hdiag->j) back to global numbering since hypre is expecting this */ 2412cf14000SStefano Zampini hjj = hdiag->j; 2422cf14000SStefano Zampini pjj = pdiag->j; 243c6698e78SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2,16,0) 2442cf14000SStefano Zampini for (i=0; i<pdiag->nz; i++) hjj[i] = pjj[i]; 245c6698e78SStefano Zampini #else 2462cf14000SStefano Zampini for (i=0; i<pdiag->nz; i++) hjj[i] = cstart + pjj[i]; 247c6698e78SStefano Zampini #endif 2486ea7df73SStefano Zampini ierr = MatSeqAIJGetArrayRead(pA->A,&pa);CHKERRQ(ierr); 2496ea7df73SStefano Zampini ierr = PetscArraycpy(hdiag->data,pa,pdiag->nz);CHKERRQ(ierr); 2506ea7df73SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(pA->A,&pa);CHKERRQ(ierr); 2512cf14000SStefano Zampini if (sameint) { 252580bdb30SBarry Smith ierr = PetscArraycpy(hoffd->i,poffd->i,pA->A->rmap->n + 1);CHKERRQ(ierr); 2532cf14000SStefano Zampini } else { 2542cf14000SStefano Zampini for (i=0; i<pA->A->rmap->n + 1; i++) hoffd->i[i] = (HYPRE_Int)(poffd->i[i]); 2552cf14000SStefano Zampini } 2562cf14000SStefano Zampini 25763c07aadSStefano Zampini /* need to move the offd column indices (hoffd->j) back to global numbering since hypre is expecting this 25863c07aadSStefano Zampini If we hacked a hypre a bit more we might be able to avoid this step */ 259c6698e78SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2,16,0) 260c6698e78SStefano Zampini PetscStackCallStandard(hypre_CSRMatrixBigInitialize,(hoffd)); 261c6698e78SStefano Zampini jj = (PetscInt*) hoffd->big_j; 262c6698e78SStefano Zampini #else 26363c07aadSStefano Zampini jj = (PetscInt*) hoffd->j; 264c6698e78SStefano Zampini #endif 2652cf14000SStefano Zampini pjj = poffd->j; 26663c07aadSStefano Zampini for (i=0; i<poffd->nz; i++) jj[i] = garray[pjj[i]]; 267c6698e78SStefano Zampini 2686ea7df73SStefano Zampini ierr = MatSeqAIJGetArrayRead(pA->B,&pa);CHKERRQ(ierr); 2696ea7df73SStefano Zampini ierr = PetscArraycpy(hoffd->data,pa,poffd->nz);CHKERRQ(ierr); 2706ea7df73SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(pA->B,&pa);CHKERRQ(ierr); 27163c07aadSStefano Zampini 272ea9daf28SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix*)hypre_IJMatrixTranslator(ij); 27363c07aadSStefano Zampini hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 0; 27463c07aadSStefano Zampini PetscFunctionReturn(0); 27563c07aadSStefano Zampini } 27663c07aadSStefano Zampini 2772df22349SStefano Zampini static PetscErrorCode MatConvert_HYPRE_IS(Mat A, MatType mtype, MatReuse reuse, Mat* B) 2782df22349SStefano Zampini { 2792df22349SStefano Zampini Mat_HYPRE* mhA = (Mat_HYPRE*)(A->data); 2802df22349SStefano Zampini Mat lA; 2812df22349SStefano Zampini ISLocalToGlobalMapping rl2g,cl2g; 2822df22349SStefano Zampini IS is; 2832df22349SStefano Zampini hypre_ParCSRMatrix *hA; 2842df22349SStefano Zampini hypre_CSRMatrix *hdiag,*hoffd; 2852df22349SStefano Zampini MPI_Comm comm; 28639accc25SStefano Zampini HYPRE_Complex *hdd,*hod,*aa; 28739accc25SStefano Zampini PetscScalar *data; 2882cf14000SStefano Zampini HYPRE_BigInt *col_map_offd; 2892cf14000SStefano Zampini HYPRE_Int *hdi,*hdj,*hoi,*hoj; 2902df22349SStefano Zampini PetscInt *ii,*jj,*iptr,*jptr; 2912df22349SStefano Zampini PetscInt cum,dr,dc,oc,str,stc,nnz,i,jd,jo,M,N; 29258968eb6SStefano Zampini HYPRE_Int type; 2932df22349SStefano Zampini PetscErrorCode ierr; 2942df22349SStefano Zampini 2952df22349SStefano Zampini PetscFunctionBegin; 296a1787963SStefano Zampini comm = PetscObjectComm((PetscObject)A); 2972df22349SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(mhA->ij,&type)); 2982df22349SStefano Zampini if (type != HYPRE_PARCSR) SETERRQ(comm,PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 2992df22349SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(mhA->ij,(void**)&hA)); 3002df22349SStefano Zampini M = hypre_ParCSRMatrixGlobalNumRows(hA); 3012df22349SStefano Zampini N = hypre_ParCSRMatrixGlobalNumCols(hA); 3022df22349SStefano Zampini str = hypre_ParCSRMatrixFirstRowIndex(hA); 3032df22349SStefano Zampini stc = hypre_ParCSRMatrixFirstColDiag(hA); 3042df22349SStefano Zampini hdiag = hypre_ParCSRMatrixDiag(hA); 3052df22349SStefano Zampini hoffd = hypre_ParCSRMatrixOffd(hA); 3062df22349SStefano Zampini dr = hypre_CSRMatrixNumRows(hdiag); 3072df22349SStefano Zampini dc = hypre_CSRMatrixNumCols(hdiag); 3082df22349SStefano Zampini nnz = hypre_CSRMatrixNumNonzeros(hdiag); 3092df22349SStefano Zampini hdi = hypre_CSRMatrixI(hdiag); 3102df22349SStefano Zampini hdj = hypre_CSRMatrixJ(hdiag); 3112df22349SStefano Zampini hdd = hypre_CSRMatrixData(hdiag); 3122df22349SStefano Zampini oc = hypre_CSRMatrixNumCols(hoffd); 3132df22349SStefano Zampini nnz += hypre_CSRMatrixNumNonzeros(hoffd); 3142df22349SStefano Zampini hoi = hypre_CSRMatrixI(hoffd); 3152df22349SStefano Zampini hoj = hypre_CSRMatrixJ(hoffd); 3162df22349SStefano Zampini hod = hypre_CSRMatrixData(hoffd); 3172df22349SStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 3182df22349SStefano Zampini PetscInt *aux; 3192df22349SStefano Zampini 3202df22349SStefano Zampini /* generate l2g maps for rows and cols */ 3212df22349SStefano Zampini ierr = ISCreateStride(comm,dr,str,1,&is);CHKERRQ(ierr); 3222df22349SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g);CHKERRQ(ierr); 3232df22349SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 3242df22349SStefano Zampini col_map_offd = hypre_ParCSRMatrixColMapOffd(hA); 3252df22349SStefano Zampini ierr = PetscMalloc1(dc+oc,&aux);CHKERRQ(ierr); 3262df22349SStefano Zampini for (i=0; i<dc; i++) aux[i] = i+stc; 3272df22349SStefano Zampini for (i=0; i<oc; i++) aux[i+dc] = col_map_offd[i]; 3282df22349SStefano Zampini ierr = ISCreateGeneral(comm,dc+oc,aux,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); 3292df22349SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g);CHKERRQ(ierr); 3302df22349SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 3312df22349SStefano Zampini /* create MATIS object */ 3322df22349SStefano Zampini ierr = MatCreate(comm,B);CHKERRQ(ierr); 3332df22349SStefano Zampini ierr = MatSetSizes(*B,dr,dc,M,N);CHKERRQ(ierr); 3342df22349SStefano Zampini ierr = MatSetType(*B,MATIS);CHKERRQ(ierr); 3352df22349SStefano Zampini ierr = MatSetLocalToGlobalMapping(*B,rl2g,cl2g);CHKERRQ(ierr); 3362df22349SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 3372df22349SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 3382df22349SStefano Zampini 3392df22349SStefano Zampini /* allocate CSR for local matrix */ 3402df22349SStefano Zampini ierr = PetscMalloc1(dr+1,&iptr);CHKERRQ(ierr); 3412df22349SStefano Zampini ierr = PetscMalloc1(nnz,&jptr);CHKERRQ(ierr); 3422df22349SStefano Zampini ierr = PetscMalloc1(nnz,&data);CHKERRQ(ierr); 3432df22349SStefano Zampini } else { 3442df22349SStefano Zampini PetscInt nr; 3452df22349SStefano Zampini PetscBool done; 3462df22349SStefano Zampini ierr = MatISGetLocalMat(*B,&lA);CHKERRQ(ierr); 3472df22349SStefano Zampini ierr = MatGetRowIJ(lA,0,PETSC_FALSE,PETSC_FALSE,&nr,(const PetscInt**)&iptr,(const PetscInt**)&jptr,&done);CHKERRQ(ierr); 3482df22349SStefano Zampini if (nr != dr) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot reuse mat: invalid number of rows in local mat! %D != %D",nr,dr); 3492df22349SStefano Zampini if (iptr[nr] < nnz) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot reuse mat: invalid number of nonzeros in local mat! reuse %D requested %D",iptr[nr],nnz); 3502df22349SStefano Zampini ierr = MatSeqAIJGetArray(lA,&data);CHKERRQ(ierr); 3512df22349SStefano Zampini } 3522df22349SStefano Zampini /* merge local matrices */ 3532df22349SStefano Zampini ii = iptr; 3542df22349SStefano Zampini jj = jptr; 35539accc25SStefano 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++ */ 3562df22349SStefano Zampini *ii = *(hdi++) + *(hoi++); 3572df22349SStefano Zampini for (jd=0,jo=0,cum=0; *ii<nnz; cum++) { 35839accc25SStefano Zampini PetscScalar *aold = (PetscScalar*)aa; 3592df22349SStefano Zampini PetscInt *jold = jj,nc = jd+jo; 3602df22349SStefano Zampini for (; jd<*hdi; jd++) { *jj++ = *hdj++; *aa++ = *hdd++; } 3612df22349SStefano Zampini for (; jo<*hoi; jo++) { *jj++ = *hoj++ + dc; *aa++ = *hod++; } 3622df22349SStefano Zampini *(++ii) = *(hdi++) + *(hoi++); 3632df22349SStefano Zampini ierr = PetscSortIntWithScalarArray(jd+jo-nc,jold,aold);CHKERRQ(ierr); 3642df22349SStefano Zampini } 3652df22349SStefano Zampini for (; cum<dr; cum++) *(++ii) = nnz; 3662df22349SStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 367a033916dSStefano Zampini Mat_SeqAIJ* a; 368a033916dSStefano Zampini 3692df22349SStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,dr,dc+oc,iptr,jptr,data,&lA);CHKERRQ(ierr); 3702df22349SStefano Zampini ierr = MatISSetLocalMat(*B,lA);CHKERRQ(ierr); 371a033916dSStefano Zampini /* hack SeqAIJ */ 372a033916dSStefano Zampini a = (Mat_SeqAIJ*)(lA->data); 373a033916dSStefano Zampini a->free_a = PETSC_TRUE; 374a033916dSStefano Zampini a->free_ij = PETSC_TRUE; 3752df22349SStefano Zampini ierr = MatDestroy(&lA);CHKERRQ(ierr); 3762df22349SStefano Zampini } 3772df22349SStefano Zampini ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3782df22349SStefano Zampini ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3792df22349SStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 3802df22349SStefano Zampini ierr = MatHeaderReplace(A,B);CHKERRQ(ierr); 3812df22349SStefano Zampini } 3822df22349SStefano Zampini PetscFunctionReturn(0); 3832df22349SStefano Zampini } 3842df22349SStefano Zampini 38563c07aadSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A, MatType type, MatReuse reuse, Mat *B) 38663c07aadSStefano Zampini { 38784d4e069SStefano Zampini Mat M = NULL; 38863c07aadSStefano Zampini Mat_HYPRE *hB; 38963c07aadSStefano Zampini MPI_Comm comm = PetscObjectComm((PetscObject)A); 39063c07aadSStefano Zampini PetscErrorCode ierr; 39163c07aadSStefano Zampini 39263c07aadSStefano Zampini PetscFunctionBegin; 39363c07aadSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 39463c07aadSStefano Zampini /* always destroy the old matrix and create a new memory; 39563c07aadSStefano Zampini hope this does not churn the memory too much. The problem 39663c07aadSStefano Zampini is I do not know if it is possible to put the matrix back to 39763c07aadSStefano Zampini its initial state so that we can directly copy the values 39863c07aadSStefano Zampini the second time through. */ 39963c07aadSStefano Zampini hB = (Mat_HYPRE*)((*B)->data); 40063c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixDestroy,(hB->ij)); 40163c07aadSStefano Zampini } else { 40284d4e069SStefano Zampini ierr = MatCreate(comm,&M);CHKERRQ(ierr); 40384d4e069SStefano Zampini ierr = MatSetType(M,MATHYPRE);CHKERRQ(ierr); 40484d4e069SStefano Zampini ierr = MatSetSizes(M,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 40584d4e069SStefano Zampini hB = (Mat_HYPRE*)(M->data); 40684d4e069SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) *B = M; 40763c07aadSStefano Zampini } 408d04e6649SStefano Zampini ierr = MatSetOption(*B,MAT_SORTED_FULL,PETSC_TRUE);CHKERRQ(ierr); /* "perfect" preallocation, so no need for hypre_AuxParCSRMatrixNeedAux */ 409d04e6649SStefano Zampini ierr = MatSetOption(*B,MAT_NO_OFF_PROC_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 41063c07aadSStefano Zampini ierr = MatHYPRE_CreateFromMat(A,hB);CHKERRQ(ierr); 41163c07aadSStefano Zampini ierr = MatHYPRE_IJMatrixCopy(A,hB->ij);CHKERRQ(ierr); 41284d4e069SStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 41384d4e069SStefano Zampini ierr = MatHeaderReplace(A,&M);CHKERRQ(ierr); 41484d4e069SStefano Zampini } 4154ec6421dSstefano_zampini (*B)->preallocated = PETSC_TRUE; 41663c07aadSStefano Zampini ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 41763c07aadSStefano Zampini ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 41863c07aadSStefano Zampini PetscFunctionReturn(0); 41963c07aadSStefano Zampini } 42063c07aadSStefano Zampini 421ea9daf28SStefano Zampini static PetscErrorCode MatConvert_HYPRE_AIJ(Mat A, MatType mtype, MatReuse reuse, Mat *B) 42263c07aadSStefano Zampini { 42363c07aadSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 42463c07aadSStefano Zampini hypre_ParCSRMatrix *parcsr; 42563c07aadSStefano Zampini hypre_CSRMatrix *hdiag,*hoffd; 42663c07aadSStefano Zampini MPI_Comm comm; 42763c07aadSStefano Zampini PetscScalar *da,*oa,*aptr; 42863c07aadSStefano Zampini PetscInt *dii,*djj,*oii,*ojj,*iptr; 42963c07aadSStefano Zampini PetscInt i,dnnz,onnz,m,n; 43058968eb6SStefano Zampini HYPRE_Int type; 43163c07aadSStefano Zampini PetscMPIInt size; 4322cf14000SStefano Zampini PetscBool sameint = (PetscBool)(sizeof(PetscInt) == sizeof(HYPRE_Int)); 43363c07aadSStefano Zampini PetscErrorCode ierr; 43463c07aadSStefano Zampini 43563c07aadSStefano Zampini PetscFunctionBegin; 43663c07aadSStefano Zampini comm = PetscObjectComm((PetscObject)A); 43763c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(hA->ij,&type)); 43863c07aadSStefano Zampini if (type != HYPRE_PARCSR) SETERRQ(comm,PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 43963c07aadSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 44063c07aadSStefano Zampini PetscBool ismpiaij,isseqaij; 441b9e7e5c1SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)*B,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr); 4424099cc6bSBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)*B,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 44363c07aadSStefano Zampini if (!ismpiaij && !isseqaij) SETERRQ(comm,PETSC_ERR_SUP,"Only MATMPIAIJ or MATSEQAIJ are supported"); 44463c07aadSStefano Zampini } 4456ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 4466ea7df73SStefano Zampini if (HYPRE_MEMORY_DEVICE == hypre_IJMatrixMemoryLocation(hA->ij)) SETERRQ(comm,PETSC_ERR_SUP,"Not yet implemented"); 4476ea7df73SStefano Zampini #endif 448ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 44963c07aadSStefano Zampini 45063c07aadSStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hA->ij,(void**)&parcsr)); 45163c07aadSStefano Zampini hdiag = hypre_ParCSRMatrixDiag(parcsr); 45263c07aadSStefano Zampini hoffd = hypre_ParCSRMatrixOffd(parcsr); 45363c07aadSStefano Zampini m = hypre_CSRMatrixNumRows(hdiag); 45463c07aadSStefano Zampini n = hypre_CSRMatrixNumCols(hdiag); 45563c07aadSStefano Zampini dnnz = hypre_CSRMatrixNumNonzeros(hdiag); 45663c07aadSStefano Zampini onnz = hypre_CSRMatrixNumNonzeros(hoffd); 457225daaf8SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 45863c07aadSStefano Zampini ierr = PetscMalloc1(m+1,&dii);CHKERRQ(ierr); 45963c07aadSStefano Zampini ierr = PetscMalloc1(dnnz,&djj);CHKERRQ(ierr); 46063c07aadSStefano Zampini ierr = PetscMalloc1(dnnz,&da);CHKERRQ(ierr); 461225daaf8SStefano Zampini } else if (reuse == MAT_REUSE_MATRIX) { 46263c07aadSStefano Zampini PetscInt nr; 46363c07aadSStefano Zampini PetscBool done; 46463c07aadSStefano Zampini if (size > 1) { 46563c07aadSStefano Zampini Mat_MPIAIJ *b = (Mat_MPIAIJ*)((*B)->data); 46663c07aadSStefano Zampini 46763c07aadSStefano Zampini ierr = MatGetRowIJ(b->A,0,PETSC_FALSE,PETSC_FALSE,&nr,(const PetscInt**)&dii,(const PetscInt**)&djj,&done);CHKERRQ(ierr); 46863c07aadSStefano Zampini if (nr != m) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot reuse mat: invalid number of local rows in diag part! %D != %D",nr,m); 46963c07aadSStefano Zampini if (dii[nr] < dnnz) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot reuse mat: invalid number of nonzeros in diag part! reuse %D hypre %D",dii[nr],dnnz); 47063c07aadSStefano Zampini ierr = MatSeqAIJGetArray(b->A,&da);CHKERRQ(ierr); 47163c07aadSStefano Zampini } else { 47263c07aadSStefano Zampini ierr = MatGetRowIJ(*B,0,PETSC_FALSE,PETSC_FALSE,&nr,(const PetscInt**)&dii,(const PetscInt**)&djj,&done);CHKERRQ(ierr); 47363c07aadSStefano Zampini if (nr != m) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot reuse mat: invalid number of local rows! %D != %D",nr,m); 47463c07aadSStefano Zampini if (dii[nr] < dnnz) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot reuse mat: invalid number of nonzeros! reuse %D hypre %D",dii[nr],dnnz); 47563c07aadSStefano Zampini ierr = MatSeqAIJGetArray(*B,&da);CHKERRQ(ierr); 47663c07aadSStefano Zampini } 477225daaf8SStefano Zampini } else { /* MAT_INPLACE_MATRIX */ 4782cf14000SStefano Zampini if (!sameint) { 4792cf14000SStefano Zampini ierr = PetscMalloc1(m+1,&dii);CHKERRQ(ierr); 4802cf14000SStefano Zampini ierr = PetscMalloc1(dnnz,&djj);CHKERRQ(ierr); 4812cf14000SStefano Zampini } else { 4827d968826Sstefano_zampini dii = (PetscInt*)hypre_CSRMatrixI(hdiag); 4837d968826Sstefano_zampini djj = (PetscInt*)hypre_CSRMatrixJ(hdiag); 48463c07aadSStefano Zampini } 48539accc25SStefano Zampini da = (PetscScalar*)hypre_CSRMatrixData(hdiag); 48663c07aadSStefano Zampini } 4872cf14000SStefano Zampini 4882cf14000SStefano Zampini if (!sameint) { 489*a16187a7SStefano Zampini if (reuse != MAT_REUSE_MATRIX) { for (i=0;i<m+1;i++) dii[i] = (PetscInt)(hypre_CSRMatrixI(hdiag)[i]); } 4902cf14000SStefano Zampini for (i=0;i<dnnz;i++) djj[i] = (PetscInt)(hypre_CSRMatrixJ(hdiag)[i]); 4912cf14000SStefano Zampini } else { 492*a16187a7SStefano Zampini if (reuse != MAT_REUSE_MATRIX) { ierr = PetscArraycpy(dii,hypre_CSRMatrixI(hdiag),m+1);CHKERRQ(ierr); } 493580bdb30SBarry Smith ierr = PetscArraycpy(djj,hypre_CSRMatrixJ(hdiag),dnnz);CHKERRQ(ierr); 4942cf14000SStefano Zampini } 495580bdb30SBarry Smith ierr = PetscArraycpy(da,hypre_CSRMatrixData(hdiag),dnnz);CHKERRQ(ierr); 49663c07aadSStefano Zampini iptr = djj; 49763c07aadSStefano Zampini aptr = da; 49863c07aadSStefano Zampini for (i=0; i<m; i++) { 49963c07aadSStefano Zampini PetscInt nc = dii[i+1]-dii[i]; 50063c07aadSStefano Zampini ierr = PetscSortIntWithScalarArray(nc,iptr,aptr);CHKERRQ(ierr); 50163c07aadSStefano Zampini iptr += nc; 50263c07aadSStefano Zampini aptr += nc; 50363c07aadSStefano Zampini } 50463c07aadSStefano Zampini if (size > 1) { 5052cf14000SStefano Zampini HYPRE_BigInt *coffd; 5062cf14000SStefano Zampini HYPRE_Int *offdj; 50763c07aadSStefano Zampini 508225daaf8SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 50963c07aadSStefano Zampini ierr = PetscMalloc1(m+1,&oii);CHKERRQ(ierr); 51063c07aadSStefano Zampini ierr = PetscMalloc1(onnz,&ojj);CHKERRQ(ierr); 51163c07aadSStefano Zampini ierr = PetscMalloc1(onnz,&oa);CHKERRQ(ierr); 512225daaf8SStefano Zampini } else if (reuse == MAT_REUSE_MATRIX) { 51363c07aadSStefano Zampini Mat_MPIAIJ *b = (Mat_MPIAIJ*)((*B)->data); 51463c07aadSStefano Zampini PetscInt nr,hr = hypre_CSRMatrixNumRows(hoffd); 51563c07aadSStefano Zampini PetscBool done; 51663c07aadSStefano Zampini 51763c07aadSStefano Zampini ierr = MatGetRowIJ(b->B,0,PETSC_FALSE,PETSC_FALSE,&nr,(const PetscInt**)&oii,(const PetscInt**)&ojj,&done);CHKERRQ(ierr); 51863c07aadSStefano Zampini if (nr != hr) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot reuse mat: invalid number of local rows in offdiag part! %D != %D",nr,hr); 51963c07aadSStefano Zampini if (oii[nr] < onnz) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Cannot reuse mat: invalid number of nonzeros in offdiag part! reuse %D hypre %D",oii[nr],onnz); 52063c07aadSStefano Zampini ierr = MatSeqAIJGetArray(b->B,&oa);CHKERRQ(ierr); 521225daaf8SStefano Zampini } else { /* MAT_INPLACE_MATRIX */ 5222cf14000SStefano Zampini if (!sameint) { 5232cf14000SStefano Zampini ierr = PetscMalloc1(m+1,&oii);CHKERRQ(ierr); 5242cf14000SStefano Zampini ierr = PetscMalloc1(onnz,&ojj);CHKERRQ(ierr); 5252cf14000SStefano Zampini } else { 5267d968826Sstefano_zampini oii = (PetscInt*)hypre_CSRMatrixI(hoffd); 5277d968826Sstefano_zampini ojj = (PetscInt*)hypre_CSRMatrixJ(hoffd); 52863c07aadSStefano Zampini } 52939accc25SStefano Zampini oa = (PetscScalar*)hypre_CSRMatrixData(hoffd); 53063c07aadSStefano Zampini } 531*a16187a7SStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 5322cf14000SStefano Zampini if (!sameint) { 5332cf14000SStefano Zampini for (i=0;i<m+1;i++) oii[i] = (PetscInt)(hypre_CSRMatrixI(hoffd)[i]); 5342cf14000SStefano Zampini } else { 535580bdb30SBarry Smith ierr = PetscArraycpy(oii,hypre_CSRMatrixI(hoffd),m+1);CHKERRQ(ierr); 5362cf14000SStefano Zampini } 537*a16187a7SStefano Zampini } 538*a16187a7SStefano Zampini ierr = PetscArraycpy(oa,hypre_CSRMatrixData(hoffd),onnz);CHKERRQ(ierr); 539*a16187a7SStefano Zampini 54063c07aadSStefano Zampini offdj = hypre_CSRMatrixJ(hoffd); 54163c07aadSStefano Zampini coffd = hypre_ParCSRMatrixColMapOffd(parcsr); 542*a16187a7SStefano Zampini /* we only need the permutation to be computed properly, I don't know if HYPRE 543*a16187a7SStefano Zampini messes up with the ordering. Just in case, allocate some memory and free it 544*a16187a7SStefano Zampini later */ 545*a16187a7SStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 546*a16187a7SStefano Zampini Mat_MPIAIJ *b = (Mat_MPIAIJ*)((*B)->data); 547*a16187a7SStefano Zampini PetscInt mnz; 548*a16187a7SStefano Zampini 549*a16187a7SStefano Zampini ierr = MatSeqAIJGetMaxRowNonzeros(b->B,&mnz);CHKERRQ(ierr); 550*a16187a7SStefano Zampini ierr = PetscMalloc1(mnz,&ojj);CHKERRQ(ierr); 551*a16187a7SStefano Zampini } else for (i=0; i<onnz; i++) ojj[i] = coffd[offdj[i]]; 55263c07aadSStefano Zampini iptr = ojj; 55363c07aadSStefano Zampini aptr = oa; 55463c07aadSStefano Zampini for (i=0; i<m; i++) { 55563c07aadSStefano Zampini PetscInt nc = oii[i+1]-oii[i]; 556*a16187a7SStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 557*a16187a7SStefano Zampini PetscInt j; 558*a16187a7SStefano Zampini 559*a16187a7SStefano Zampini iptr = ojj; 560*a16187a7SStefano Zampini for (j=0; j<nc; j++) iptr[j] = coffd[offdj[oii[i] + j]]; 561*a16187a7SStefano Zampini } 56263c07aadSStefano Zampini ierr = PetscSortIntWithScalarArray(nc,iptr,aptr);CHKERRQ(ierr); 56363c07aadSStefano Zampini iptr += nc; 56463c07aadSStefano Zampini aptr += nc; 56563c07aadSStefano Zampini } 566*a16187a7SStefano Zampini if (reuse == MAT_REUSE_MATRIX) { ierr = PetscFree(ojj);CHKERRQ(ierr); } 567225daaf8SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 56863c07aadSStefano Zampini Mat_MPIAIJ *b; 56963c07aadSStefano Zampini Mat_SeqAIJ *d,*o; 570225daaf8SStefano Zampini 57141073d71Sstefano_zampini ierr = MatCreateMPIAIJWithSplitArrays(comm,m,n,PETSC_DECIDE,PETSC_DECIDE,dii,djj,da,oii,ojj,oa,B);CHKERRQ(ierr); 57263c07aadSStefano Zampini /* hack MPIAIJ */ 57363c07aadSStefano Zampini b = (Mat_MPIAIJ*)((*B)->data); 57463c07aadSStefano Zampini d = (Mat_SeqAIJ*)b->A->data; 57563c07aadSStefano Zampini o = (Mat_SeqAIJ*)b->B->data; 57663c07aadSStefano Zampini d->free_a = PETSC_TRUE; 57763c07aadSStefano Zampini d->free_ij = PETSC_TRUE; 57863c07aadSStefano Zampini o->free_a = PETSC_TRUE; 57963c07aadSStefano Zampini o->free_ij = PETSC_TRUE; 580225daaf8SStefano Zampini } else if (reuse == MAT_INPLACE_MATRIX) { 581225daaf8SStefano Zampini Mat T; 5822cf14000SStefano Zampini 58341073d71Sstefano_zampini ierr = MatCreateMPIAIJWithSplitArrays(comm,m,n,PETSC_DECIDE,PETSC_DECIDE,dii,djj,da,oii,ojj,oa,&T);CHKERRQ(ierr); 5842cf14000SStefano Zampini if (sameint) { /* ownership of CSR pointers is transferred to PETSc */ 585225daaf8SStefano Zampini hypre_CSRMatrixI(hdiag) = NULL; 586225daaf8SStefano Zampini hypre_CSRMatrixJ(hdiag) = NULL; 587225daaf8SStefano Zampini hypre_CSRMatrixI(hoffd) = NULL; 588225daaf8SStefano Zampini hypre_CSRMatrixJ(hoffd) = NULL; 5892cf14000SStefano Zampini } else { /* Hack MPIAIJ -> free ij but not a */ 5902cf14000SStefano Zampini Mat_MPIAIJ *b = (Mat_MPIAIJ*)(T->data); 5912cf14000SStefano Zampini Mat_SeqAIJ *d = (Mat_SeqAIJ*)(b->A->data); 5922cf14000SStefano Zampini Mat_SeqAIJ *o = (Mat_SeqAIJ*)(b->B->data); 5932cf14000SStefano Zampini 5942cf14000SStefano Zampini d->free_ij = PETSC_TRUE; 5952cf14000SStefano Zampini o->free_ij = PETSC_TRUE; 5962cf14000SStefano Zampini } 5972cf14000SStefano Zampini hypre_CSRMatrixData(hdiag) = NULL; 598225daaf8SStefano Zampini hypre_CSRMatrixData(hoffd) = NULL; 599225daaf8SStefano Zampini ierr = MatHeaderReplace(A,&T);CHKERRQ(ierr); 60063c07aadSStefano Zampini } 601225daaf8SStefano Zampini } else { 602225daaf8SStefano Zampini oii = NULL; 603225daaf8SStefano Zampini ojj = NULL; 604225daaf8SStefano Zampini oa = NULL; 605225daaf8SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 60663c07aadSStefano Zampini Mat_SeqAIJ* b; 6072cf14000SStefano Zampini 60863c07aadSStefano Zampini ierr = MatCreateSeqAIJWithArrays(comm,m,n,dii,djj,da,B);CHKERRQ(ierr); 60963c07aadSStefano Zampini /* hack SeqAIJ */ 61063c07aadSStefano Zampini b = (Mat_SeqAIJ*)((*B)->data); 61163c07aadSStefano Zampini b->free_a = PETSC_TRUE; 61263c07aadSStefano Zampini b->free_ij = PETSC_TRUE; 613225daaf8SStefano Zampini } else if (reuse == MAT_INPLACE_MATRIX) { 614225daaf8SStefano Zampini Mat T; 6152cf14000SStefano Zampini 616225daaf8SStefano Zampini ierr = MatCreateSeqAIJWithArrays(comm,m,n,dii,djj,da,&T);CHKERRQ(ierr); 6172cf14000SStefano Zampini if (sameint) { /* ownership of CSR pointers is transferred to PETSc */ 618225daaf8SStefano Zampini hypre_CSRMatrixI(hdiag) = NULL; 619225daaf8SStefano Zampini hypre_CSRMatrixJ(hdiag) = NULL; 6202cf14000SStefano Zampini } else { /* free ij but not a */ 6212cf14000SStefano Zampini Mat_SeqAIJ* b = (Mat_SeqAIJ*)(T->data); 6222cf14000SStefano Zampini 6232cf14000SStefano Zampini b->free_ij = PETSC_TRUE; 6242cf14000SStefano Zampini } 625225daaf8SStefano Zampini hypre_CSRMatrixData(hdiag) = NULL; 626225daaf8SStefano Zampini ierr = MatHeaderReplace(A,&T);CHKERRQ(ierr); 62763c07aadSStefano Zampini } 628225daaf8SStefano Zampini } 629225daaf8SStefano Zampini 6302cf14000SStefano Zampini /* we have to use hypre_Tfree to free the HYPRE arrays 6312cf14000SStefano Zampini that PETSc now onws */ 63263c07aadSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 6332cf14000SStefano Zampini PetscInt nh; 6342cf14000SStefano Zampini void *ptrs[6] = {da,oa,dii,djj,oii,ojj}; 6352cf14000SStefano Zampini const char *names[6] = {"_hypre_csr_da", 6362cf14000SStefano Zampini "_hypre_csr_oa", 6372cf14000SStefano Zampini "_hypre_csr_dii", 638225daaf8SStefano Zampini "_hypre_csr_djj", 639225daaf8SStefano Zampini "_hypre_csr_oii", 6402cf14000SStefano Zampini "_hypre_csr_ojj"}; 6412cf14000SStefano Zampini nh = sameint ? 6 : 2; 6422cf14000SStefano Zampini for (i=0; i<nh; i++) { 643225daaf8SStefano Zampini PetscContainer c; 644225daaf8SStefano Zampini 645225daaf8SStefano Zampini ierr = PetscContainerCreate(comm,&c);CHKERRQ(ierr); 646225daaf8SStefano Zampini ierr = PetscContainerSetPointer(c,ptrs[i]);CHKERRQ(ierr); 647225daaf8SStefano Zampini ierr = PetscContainerSetUserDestroy(c,hypre_array_destroy);CHKERRQ(ierr); 648225daaf8SStefano Zampini ierr = PetscObjectCompose((PetscObject)(*B),names[i],(PetscObject)c);CHKERRQ(ierr); 649225daaf8SStefano Zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 650225daaf8SStefano Zampini } 65163c07aadSStefano Zampini } 65263c07aadSStefano Zampini PetscFunctionReturn(0); 65363c07aadSStefano Zampini } 65463c07aadSStefano Zampini 655613e5ff0Sstefano_zampini static PetscErrorCode MatAIJGetParCSR_Private(Mat A, hypre_ParCSRMatrix **hA) 656c1a070e6SStefano Zampini { 657613e5ff0Sstefano_zampini hypre_ParCSRMatrix *tA; 658c1a070e6SStefano Zampini hypre_CSRMatrix *hdiag,*hoffd; 659c1a070e6SStefano Zampini Mat_SeqAIJ *diag,*offd; 6602cf14000SStefano Zampini PetscInt *garray,i,noffd,dnnz,onnz,*row_starts,*col_starts; 661c1a070e6SStefano Zampini MPI_Comm comm = PetscObjectComm((PetscObject)A); 662613e5ff0Sstefano_zampini PetscBool ismpiaij,isseqaij; 6632cf14000SStefano Zampini PetscBool sameint = (PetscBool)(sizeof(PetscInt) == sizeof(HYPRE_Int)); 664c1a070e6SStefano Zampini PetscErrorCode ierr; 6656ea7df73SStefano Zampini HYPRE_Int *hdi = NULL,*hdj = NULL,*hoi = NULL,*hoj = NULL; 6666ea7df73SStefano Zampini PetscInt *pdi,*pdj,*poi,*poj; 6676ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 6686ea7df73SStefano Zampini PetscBool iscuda = PETSC_FALSE; 6696ea7df73SStefano Zampini #endif 670c1a070e6SStefano Zampini 671c1a070e6SStefano Zampini PetscFunctionBegin; 6723937f725SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)A,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr); 6734099cc6bSBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 674a32993e3SJed Brown if (!ismpiaij && !isseqaij) SETERRQ1(comm,PETSC_ERR_SUP,"Unsupported type %s",((PetscObject)A)->type_name); 675c1a070e6SStefano Zampini if (ismpiaij) { 676c1a070e6SStefano Zampini Mat_MPIAIJ *a = (Mat_MPIAIJ*)(A->data); 677c1a070e6SStefano Zampini 678c1a070e6SStefano Zampini diag = (Mat_SeqAIJ*)a->A->data; 679c1a070e6SStefano Zampini offd = (Mat_SeqAIJ*)a->B->data; 6806ea7df73SStefano Zampini #if defined(PETSC_HAVE_CUDA) && defined(PETSC_HAVE_HYPRE_DEVICE) && defined(HYPRE_USING_CUDA) 6816ea7df73SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJCUSPARSE,&iscuda);CHKERRQ(ierr); 6826ea7df73SStefano Zampini if (iscuda && !A->boundtocpu) { 6836ea7df73SStefano Zampini sameint = PETSC_TRUE; 6846ea7df73SStefano Zampini ierr = MatSeqAIJCUSPARSEGetIJ(a->A,PETSC_FALSE,(const HYPRE_Int**)&hdi,(const HYPRE_Int**)&hdj);CHKERRQ(ierr); 6856ea7df73SStefano Zampini ierr = MatSeqAIJCUSPARSEGetIJ(a->B,PETSC_FALSE,(const HYPRE_Int**)&hoi,(const HYPRE_Int**)&hoj);CHKERRQ(ierr); 6866ea7df73SStefano Zampini } else { 6876ea7df73SStefano Zampini #else 6886ea7df73SStefano Zampini { 6896ea7df73SStefano Zampini #endif 6906ea7df73SStefano Zampini pdi = diag->i; 6916ea7df73SStefano Zampini pdj = diag->j; 6926ea7df73SStefano Zampini poi = offd->i; 6936ea7df73SStefano Zampini poj = offd->j; 6946ea7df73SStefano Zampini if (sameint) { 6956ea7df73SStefano Zampini hdi = (HYPRE_Int*)pdi; 6966ea7df73SStefano Zampini hdj = (HYPRE_Int*)pdj; 6976ea7df73SStefano Zampini hoi = (HYPRE_Int*)poi; 6986ea7df73SStefano Zampini hoj = (HYPRE_Int*)poj; 6996ea7df73SStefano Zampini } 7006ea7df73SStefano Zampini } 701c1a070e6SStefano Zampini garray = a->garray; 702c1a070e6SStefano Zampini noffd = a->B->cmap->N; 703c1a070e6SStefano Zampini dnnz = diag->nz; 704c1a070e6SStefano Zampini onnz = offd->nz; 705c1a070e6SStefano Zampini } else { 706c1a070e6SStefano Zampini diag = (Mat_SeqAIJ*)A->data; 707c1a070e6SStefano Zampini offd = NULL; 7086ea7df73SStefano Zampini #if defined(PETSC_HAVE_CUDA) && defined(PETSC_HAVE_HYPRE_DEVICE) 7096ea7df73SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJCUSPARSE,&iscuda);CHKERRQ(ierr); 7106ea7df73SStefano Zampini if (iscuda && !A->boundtocpu) { 7116ea7df73SStefano Zampini sameint = PETSC_TRUE; 7126ea7df73SStefano Zampini ierr = MatSeqAIJCUSPARSEGetIJ(A,PETSC_FALSE,(const HYPRE_Int**)&hdi,(const HYPRE_Int**)&hdj);CHKERRQ(ierr); 7136ea7df73SStefano Zampini } else { 7146ea7df73SStefano Zampini #else 7156ea7df73SStefano Zampini { 7166ea7df73SStefano Zampini #endif 7176ea7df73SStefano Zampini pdi = diag->i; 7186ea7df73SStefano Zampini pdj = diag->j; 7196ea7df73SStefano Zampini if (sameint) { 7206ea7df73SStefano Zampini hdi = (HYPRE_Int*)pdi; 7216ea7df73SStefano Zampini hdj = (HYPRE_Int*)pdj; 7226ea7df73SStefano Zampini } 7236ea7df73SStefano Zampini } 724c1a070e6SStefano Zampini garray = NULL; 725c1a070e6SStefano Zampini noffd = 0; 726c1a070e6SStefano Zampini dnnz = diag->nz; 727c1a070e6SStefano Zampini onnz = 0; 728c1a070e6SStefano Zampini } 729225daaf8SStefano Zampini 730c1a070e6SStefano Zampini /* create a temporary ParCSR */ 731c1a070e6SStefano Zampini if (HYPRE_AssumedPartitionCheck()) { 732c1a070e6SStefano Zampini PetscMPIInt myid; 733c1a070e6SStefano Zampini 73455b25c41SPierre Jolivet ierr = MPI_Comm_rank(comm,&myid);CHKERRMPI(ierr); 735c1a070e6SStefano Zampini row_starts = A->rmap->range + myid; 736c1a070e6SStefano Zampini col_starts = A->cmap->range + myid; 737c1a070e6SStefano Zampini } else { 738c1a070e6SStefano Zampini row_starts = A->rmap->range; 739c1a070e6SStefano Zampini col_starts = A->cmap->range; 740c1a070e6SStefano Zampini } 7412cf14000SStefano Zampini tA = hypre_ParCSRMatrixCreate(comm,A->rmap->N,A->cmap->N,(HYPRE_BigInt*)row_starts,(HYPRE_BigInt*)col_starts,noffd,dnnz,onnz); 742a1d2239cSSatish Balay #if defined(hypre_ParCSRMatrixOwnsRowStarts) 743c1a070e6SStefano Zampini hypre_ParCSRMatrixSetRowStartsOwner(tA,0); 744c1a070e6SStefano Zampini hypre_ParCSRMatrixSetColStartsOwner(tA,0); 745a1d2239cSSatish Balay #endif 746c1a070e6SStefano Zampini 747225daaf8SStefano Zampini /* set diagonal part */ 748c1a070e6SStefano Zampini hdiag = hypre_ParCSRMatrixDiag(tA); 7496ea7df73SStefano Zampini if (!sameint) { /* malloc CSR pointers */ 7506ea7df73SStefano Zampini ierr = PetscMalloc2(A->rmap->n+1,&hdi,dnnz,&hdj);CHKERRQ(ierr); 7516ea7df73SStefano Zampini for (i = 0; i < A->rmap->n+1; i++) hdi[i] = (HYPRE_Int)(pdi[i]); 7526ea7df73SStefano Zampini for (i = 0; i < dnnz; i++) hdj[i] = (HYPRE_Int)(pdj[i]); 7532cf14000SStefano Zampini } 7546ea7df73SStefano Zampini hypre_CSRMatrixI(hdiag) = hdi; 7556ea7df73SStefano Zampini hypre_CSRMatrixJ(hdiag) = hdj; 75639accc25SStefano Zampini hypre_CSRMatrixData(hdiag) = (HYPRE_Complex*)diag->a; 757c1a070e6SStefano Zampini hypre_CSRMatrixNumNonzeros(hdiag) = diag->nz; 758c1a070e6SStefano Zampini hypre_CSRMatrixSetRownnz(hdiag); 759c1a070e6SStefano Zampini hypre_CSRMatrixSetDataOwner(hdiag,0); 760c1a070e6SStefano Zampini 761225daaf8SStefano Zampini /* set offdiagonal part */ 762c1a070e6SStefano Zampini hoffd = hypre_ParCSRMatrixOffd(tA); 763c1a070e6SStefano Zampini if (offd) { 7646ea7df73SStefano Zampini if (!sameint) { /* malloc CSR pointers */ 7656ea7df73SStefano Zampini ierr = PetscMalloc2(A->rmap->n+1,&hoi,onnz,&hoj);CHKERRQ(ierr); 7666ea7df73SStefano Zampini for (i = 0; i < A->rmap->n+1; i++) hoi[i] = (HYPRE_Int)(poi[i]); 7676ea7df73SStefano Zampini for (i = 0; i < onnz; i++) hoj[i] = (HYPRE_Int)(poj[i]); 7682cf14000SStefano Zampini } 7696ea7df73SStefano Zampini hypre_CSRMatrixI(hoffd) = hoi; 7706ea7df73SStefano Zampini hypre_CSRMatrixJ(hoffd) = hoj; 77139accc25SStefano Zampini hypre_CSRMatrixData(hoffd) = (HYPRE_Complex*)offd->a; 772c1a070e6SStefano Zampini hypre_CSRMatrixNumNonzeros(hoffd) = offd->nz; 773c1a070e6SStefano Zampini hypre_CSRMatrixSetRownnz(hoffd); 774c1a070e6SStefano Zampini hypre_CSRMatrixSetDataOwner(hoffd,0); 7756ea7df73SStefano Zampini } 7766ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 7776ea7df73SStefano Zampini PetscStackCallStandard(hypre_ParCSRMatrixInitialize_v2,(tA,iscuda ? HYPRE_MEMORY_DEVICE : HYPRE_MEMORY_HOST)); 7786ea7df73SStefano Zampini #else 7796ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_LT(2,18,0) 7806ea7df73SStefano Zampini PetscStackCallStandard(hypre_ParCSRMatrixInitialize,(tA)); 7816ea7df73SStefano Zampini #else 7826ea7df73SStefano Zampini PetscStackCallStandard(hypre_ParCSRMatrixInitialize_v2,(tA,HYPRE_MEMORY_HOST)); 7836ea7df73SStefano Zampini #endif 7846ea7df73SStefano Zampini #endif 7856ea7df73SStefano Zampini hypre_TFree(hypre_ParCSRMatrixColMapOffd(tA),HYPRE_MEMORY_HOST); 786c1a070e6SStefano Zampini hypre_ParCSRMatrixSetNumNonzeros(tA); 7872cf14000SStefano Zampini hypre_ParCSRMatrixColMapOffd(tA) = (HYPRE_BigInt*)garray; 7886ea7df73SStefano Zampini if (!hypre_ParCSRMatrixCommPkg(tA)) PetscStackCallStandard(hypre_MatvecCommPkgCreate,(tA)); 789613e5ff0Sstefano_zampini *hA = tA; 790613e5ff0Sstefano_zampini PetscFunctionReturn(0); 791613e5ff0Sstefano_zampini } 792c1a070e6SStefano Zampini 793613e5ff0Sstefano_zampini static PetscErrorCode MatAIJRestoreParCSR_Private(Mat A, hypre_ParCSRMatrix **hA) 794613e5ff0Sstefano_zampini { 795613e5ff0Sstefano_zampini hypre_CSRMatrix *hdiag,*hoffd; 7966ea7df73SStefano Zampini PetscBool ismpiaij,sameint = (PetscBool)(sizeof(PetscInt) == sizeof(HYPRE_Int)); 7972cf14000SStefano Zampini PetscErrorCode ierr; 7986ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 7996ea7df73SStefano Zampini PetscBool iscuda = PETSC_FALSE; 8006ea7df73SStefano Zampini #endif 801c1a070e6SStefano Zampini 802613e5ff0Sstefano_zampini PetscFunctionBegin; 8036ea7df73SStefano Zampini ierr = PetscObjectBaseTypeCompare((PetscObject)A,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr); 8046ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 8056ea7df73SStefano Zampini ierr = PetscObjectTypeCompareAny((PetscObject)A,&iscuda,MATSEQAIJCUSPARSE,MATMPIAIJCUSPARSE,"");CHKERRQ(ierr); 8066ea7df73SStefano Zampini if (iscuda) sameint = PETSC_TRUE; 8076ea7df73SStefano Zampini #endif 808613e5ff0Sstefano_zampini hdiag = hypre_ParCSRMatrixDiag(*hA); 809613e5ff0Sstefano_zampini hoffd = hypre_ParCSRMatrixOffd(*hA); 8106ea7df73SStefano Zampini /* free temporary memory allocated by PETSc 8116ea7df73SStefano Zampini set pointers to NULL before destroying tA */ 8122cf14000SStefano Zampini if (!sameint) { 8132cf14000SStefano Zampini HYPRE_Int *hi,*hj; 8142cf14000SStefano Zampini 8152cf14000SStefano Zampini hi = hypre_CSRMatrixI(hdiag); 8162cf14000SStefano Zampini hj = hypre_CSRMatrixJ(hdiag); 8172cf14000SStefano Zampini ierr = PetscFree2(hi,hj);CHKERRQ(ierr); 8186ea7df73SStefano Zampini if (ismpiaij) { 8192cf14000SStefano Zampini hi = hypre_CSRMatrixI(hoffd); 8202cf14000SStefano Zampini hj = hypre_CSRMatrixJ(hoffd); 8212cf14000SStefano Zampini ierr = PetscFree2(hi,hj);CHKERRQ(ierr); 8222cf14000SStefano Zampini } 8232cf14000SStefano Zampini } 824c1a070e6SStefano Zampini hypre_CSRMatrixI(hdiag) = NULL; 825c1a070e6SStefano Zampini hypre_CSRMatrixJ(hdiag) = NULL; 826c1a070e6SStefano Zampini hypre_CSRMatrixData(hdiag) = NULL; 8276ea7df73SStefano Zampini if (ismpiaij) { 828c1a070e6SStefano Zampini hypre_CSRMatrixI(hoffd) = NULL; 829c1a070e6SStefano Zampini hypre_CSRMatrixJ(hoffd) = NULL; 830c1a070e6SStefano Zampini hypre_CSRMatrixData(hoffd) = NULL; 8316ea7df73SStefano Zampini } 832613e5ff0Sstefano_zampini hypre_ParCSRMatrixColMapOffd(*hA) = NULL; 833613e5ff0Sstefano_zampini hypre_ParCSRMatrixDestroy(*hA); 834613e5ff0Sstefano_zampini *hA = NULL; 835613e5ff0Sstefano_zampini PetscFunctionReturn(0); 836613e5ff0Sstefano_zampini } 837613e5ff0Sstefano_zampini 838613e5ff0Sstefano_zampini /* calls RAP from BoomerAMG: 8393dad0653Sstefano_zampini the resulting ParCSR will not own the column and row starts 8406ea7df73SStefano Zampini It looks like we don't need to have the diagonal entries ordered first */ 841a055b5aaSBarry Smith static PetscErrorCode MatHYPRE_ParCSR_RAP(hypre_ParCSRMatrix *hR, hypre_ParCSRMatrix *hA,hypre_ParCSRMatrix *hP, hypre_ParCSRMatrix **hRAP) 842613e5ff0Sstefano_zampini { 843a1d2239cSSatish Balay #if defined(hypre_ParCSRMatrixOwnsRowStarts) 844613e5ff0Sstefano_zampini HYPRE_Int P_owns_col_starts,R_owns_row_starts; 845a1d2239cSSatish Balay #endif 846613e5ff0Sstefano_zampini 847613e5ff0Sstefano_zampini PetscFunctionBegin; 848a1d2239cSSatish Balay #if defined(hypre_ParCSRMatrixOwnsRowStarts) 849613e5ff0Sstefano_zampini P_owns_col_starts = hypre_ParCSRMatrixOwnsColStarts(hP); 850613e5ff0Sstefano_zampini R_owns_row_starts = hypre_ParCSRMatrixOwnsRowStarts(hR); 851a1d2239cSSatish Balay #endif 8526ea7df73SStefano Zampini /* can be replaced by version test later */ 8536ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 8546ea7df73SStefano Zampini PetscStackPush("hypre_ParCSRMatrixRAP"); 8556ea7df73SStefano Zampini *hRAP = hypre_ParCSRMatrixRAP(hR,hA,hP); 8566ea7df73SStefano Zampini PetscStackPop; 8576ea7df73SStefano Zampini #else 858613e5ff0Sstefano_zampini PetscStackCallStandard(hypre_BoomerAMGBuildCoarseOperator,(hR,hA,hP,hRAP)); 859613e5ff0Sstefano_zampini PetscStackCallStandard(hypre_ParCSRMatrixSetNumNonzeros,(*hRAP)); 8606ea7df73SStefano Zampini #endif 861613e5ff0Sstefano_zampini /* hypre_BoomerAMGBuildCoarseOperator steals the col_starts from P and the row_starts from R */ 862a1d2239cSSatish Balay #if defined(hypre_ParCSRMatrixOwnsRowStarts) 863613e5ff0Sstefano_zampini hypre_ParCSRMatrixSetRowStartsOwner(*hRAP,0); 864613e5ff0Sstefano_zampini hypre_ParCSRMatrixSetColStartsOwner(*hRAP,0); 865613e5ff0Sstefano_zampini if (P_owns_col_starts) hypre_ParCSRMatrixSetColStartsOwner(hP,1); 866613e5ff0Sstefano_zampini if (R_owns_row_starts) hypre_ParCSRMatrixSetRowStartsOwner(hR,1); 867a1d2239cSSatish Balay #endif 868613e5ff0Sstefano_zampini PetscFunctionReturn(0); 869613e5ff0Sstefano_zampini } 870613e5ff0Sstefano_zampini 8716f231fbdSstefano_zampini static PetscErrorCode MatPtAPNumeric_AIJ_AIJ_wHYPRE(Mat A,Mat P,Mat C) 872613e5ff0Sstefano_zampini { 8736f231fbdSstefano_zampini Mat B; 8746abb4441SStefano Zampini hypre_ParCSRMatrix *hA,*hP,*hPtAP = NULL; 875613e5ff0Sstefano_zampini PetscErrorCode ierr; 8764222ddf1SHong Zhang Mat_Product *product=C->product; 877613e5ff0Sstefano_zampini 878613e5ff0Sstefano_zampini PetscFunctionBegin; 879613e5ff0Sstefano_zampini ierr = MatAIJGetParCSR_Private(A,&hA);CHKERRQ(ierr); 880613e5ff0Sstefano_zampini ierr = MatAIJGetParCSR_Private(P,&hP);CHKERRQ(ierr); 881613e5ff0Sstefano_zampini ierr = MatHYPRE_ParCSR_RAP(hP,hA,hP,&hPtAP);CHKERRQ(ierr); 8826f231fbdSstefano_zampini ierr = MatCreateFromParCSR(hPtAP,MATAIJ,PETSC_OWN_POINTER,&B);CHKERRQ(ierr); 8834222ddf1SHong Zhang 8846f231fbdSstefano_zampini ierr = MatHeaderMerge(C,&B);CHKERRQ(ierr); 8854222ddf1SHong Zhang C->product = product; 8864222ddf1SHong Zhang 887613e5ff0Sstefano_zampini ierr = MatAIJRestoreParCSR_Private(A,&hA);CHKERRQ(ierr); 888613e5ff0Sstefano_zampini ierr = MatAIJRestoreParCSR_Private(P,&hP);CHKERRQ(ierr); 8896f231fbdSstefano_zampini PetscFunctionReturn(0); 8906f231fbdSstefano_zampini } 8916f231fbdSstefano_zampini 8924222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatPtAPSymbolic_AIJ_AIJ_wHYPRE(Mat A,Mat P,PetscReal fill,Mat C) 8936f231fbdSstefano_zampini { 8946f231fbdSstefano_zampini PetscErrorCode ierr; 895ab4d48faSStefano Zampini 8966f231fbdSstefano_zampini PetscFunctionBegin; 8974222ddf1SHong Zhang ierr = MatSetType(C,MATAIJ);CHKERRQ(ierr); 8984222ddf1SHong Zhang C->ops->ptapnumeric = MatPtAPNumeric_AIJ_AIJ_wHYPRE; 8994222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_PtAP; 900613e5ff0Sstefano_zampini PetscFunctionReturn(0); 901613e5ff0Sstefano_zampini } 902613e5ff0Sstefano_zampini 9034cc28894Sstefano_zampini static PetscErrorCode MatPtAPNumeric_AIJ_HYPRE(Mat A,Mat P,Mat C) 904613e5ff0Sstefano_zampini { 9054cc28894Sstefano_zampini Mat B; 9064cc28894Sstefano_zampini Mat_HYPRE *hP; 9076abb4441SStefano Zampini hypre_ParCSRMatrix *hA = NULL,*Pparcsr,*ptapparcsr = NULL; 908613e5ff0Sstefano_zampini HYPRE_Int type; 909613e5ff0Sstefano_zampini MPI_Comm comm = PetscObjectComm((PetscObject)A); 9104cc28894Sstefano_zampini PetscBool ishypre; 911613e5ff0Sstefano_zampini PetscErrorCode ierr; 912613e5ff0Sstefano_zampini 913613e5ff0Sstefano_zampini PetscFunctionBegin; 9144cc28894Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)P,MATHYPRE,&ishypre);CHKERRQ(ierr); 9154cc28894Sstefano_zampini if (!ishypre) SETERRQ1(comm,PETSC_ERR_USER,"P should be of type %s",MATHYPRE); 9164cc28894Sstefano_zampini hP = (Mat_HYPRE*)P->data; 917613e5ff0Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(hP->ij,&type)); 918613e5ff0Sstefano_zampini if (type != HYPRE_PARCSR) SETERRQ(comm,PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 919613e5ff0Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hP->ij,(void**)&Pparcsr)); 920613e5ff0Sstefano_zampini 921613e5ff0Sstefano_zampini ierr = MatAIJGetParCSR_Private(A,&hA);CHKERRQ(ierr); 922613e5ff0Sstefano_zampini ierr = MatHYPRE_ParCSR_RAP(Pparcsr,hA,Pparcsr,&ptapparcsr);CHKERRQ(ierr); 923613e5ff0Sstefano_zampini ierr = MatAIJRestoreParCSR_Private(A,&hA);CHKERRQ(ierr); 924225daaf8SStefano Zampini 9254cc28894Sstefano_zampini /* create temporary matrix and merge to C */ 9264cc28894Sstefano_zampini ierr = MatCreateFromParCSR(ptapparcsr,((PetscObject)C)->type_name,PETSC_OWN_POINTER,&B);CHKERRQ(ierr); 9274cc28894Sstefano_zampini ierr = MatHeaderMerge(C,&B);CHKERRQ(ierr); 9284cc28894Sstefano_zampini PetscFunctionReturn(0); 9294cc28894Sstefano_zampini } 9304cc28894Sstefano_zampini 9314cc28894Sstefano_zampini static PetscErrorCode MatPtAPNumeric_HYPRE_HYPRE(Mat A,Mat P,Mat C) 9324cc28894Sstefano_zampini { 9334cc28894Sstefano_zampini Mat B; 9346abb4441SStefano Zampini hypre_ParCSRMatrix *Aparcsr,*Pparcsr,*ptapparcsr = NULL; 9354cc28894Sstefano_zampini Mat_HYPRE *hA,*hP; 9364cc28894Sstefano_zampini PetscBool ishypre; 9374cc28894Sstefano_zampini HYPRE_Int type; 9384cc28894Sstefano_zampini PetscErrorCode ierr; 9394cc28894Sstefano_zampini 9404cc28894Sstefano_zampini PetscFunctionBegin; 9414cc28894Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)P,MATHYPRE,&ishypre);CHKERRQ(ierr); 9424cc28894Sstefano_zampini if (!ishypre) SETERRQ1(PetscObjectComm((PetscObject)P),PETSC_ERR_USER,"P should be of type %s",MATHYPRE); 9434cc28894Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATHYPRE,&ishypre);CHKERRQ(ierr); 9444cc28894Sstefano_zampini if (!ishypre) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_USER,"A should be of type %s",MATHYPRE); 9454cc28894Sstefano_zampini hA = (Mat_HYPRE*)A->data; 9464cc28894Sstefano_zampini hP = (Mat_HYPRE*)P->data; 9474cc28894Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(hA->ij,&type)); 9484cc28894Sstefano_zampini if (type != HYPRE_PARCSR) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 9494cc28894Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(hP->ij,&type)); 9504cc28894Sstefano_zampini if (type != HYPRE_PARCSR) SETERRQ(PetscObjectComm((PetscObject)P),PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 9514cc28894Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hA->ij,(void**)&Aparcsr)); 9524cc28894Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hP->ij,(void**)&Pparcsr)); 9534cc28894Sstefano_zampini ierr = MatHYPRE_ParCSR_RAP(Pparcsr,Aparcsr,Pparcsr,&ptapparcsr);CHKERRQ(ierr); 9544cc28894Sstefano_zampini ierr = MatCreateFromParCSR(ptapparcsr,MATHYPRE,PETSC_OWN_POINTER,&B);CHKERRQ(ierr); 9554cc28894Sstefano_zampini ierr = MatHeaderMerge(C,&B);CHKERRQ(ierr); 9564cc28894Sstefano_zampini PetscFunctionReturn(0); 9574cc28894Sstefano_zampini } 9584cc28894Sstefano_zampini 959d501dc42Sstefano_zampini /* calls hypre_ParMatmul 960d501dc42Sstefano_zampini hypre_ParMatMul uses hypre_ParMatrixCreate with the communicator of hA 9613dad0653Sstefano_zampini hypre_ParMatrixCreate does not duplicate the communicator 9626ea7df73SStefano Zampini It looks like we don't need to have the diagonal entries ordered first */ 963d501dc42Sstefano_zampini static PetscErrorCode MatHYPRE_ParCSR_MatMatMult(hypre_ParCSRMatrix *hA, hypre_ParCSRMatrix *hB, hypre_ParCSRMatrix **hAB) 964d501dc42Sstefano_zampini { 965d501dc42Sstefano_zampini PetscFunctionBegin; 9666ea7df73SStefano Zampini /* can be replaced by version test later */ 9676ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 9686ea7df73SStefano Zampini PetscStackPush("hypre_ParCSRMatMat"); 9696ea7df73SStefano Zampini *hAB = hypre_ParCSRMatMat(hA,hB); 9706ea7df73SStefano Zampini #else 971d501dc42Sstefano_zampini PetscStackPush("hypre_ParMatmul"); 972d501dc42Sstefano_zampini *hAB = hypre_ParMatmul(hA,hB); 9736ea7df73SStefano Zampini #endif 974d501dc42Sstefano_zampini PetscStackPop; 975d501dc42Sstefano_zampini PetscFunctionReturn(0); 976d501dc42Sstefano_zampini } 977d501dc42Sstefano_zampini 9785e5acdf2Sstefano_zampini static PetscErrorCode MatMatMultNumeric_AIJ_AIJ_wHYPRE(Mat A,Mat B,Mat C) 9795e5acdf2Sstefano_zampini { 9805e5acdf2Sstefano_zampini Mat D; 981d501dc42Sstefano_zampini hypre_ParCSRMatrix *hA,*hB,*hAB = NULL; 9825e5acdf2Sstefano_zampini PetscErrorCode ierr; 9834222ddf1SHong Zhang Mat_Product *product=C->product; 9845e5acdf2Sstefano_zampini 9855e5acdf2Sstefano_zampini PetscFunctionBegin; 9865e5acdf2Sstefano_zampini ierr = MatAIJGetParCSR_Private(A,&hA);CHKERRQ(ierr); 9875e5acdf2Sstefano_zampini ierr = MatAIJGetParCSR_Private(B,&hB);CHKERRQ(ierr); 988d501dc42Sstefano_zampini ierr = MatHYPRE_ParCSR_MatMatMult(hA,hB,&hAB);CHKERRQ(ierr); 9895e5acdf2Sstefano_zampini ierr = MatCreateFromParCSR(hAB,MATAIJ,PETSC_OWN_POINTER,&D);CHKERRQ(ierr); 9904222ddf1SHong Zhang 9915e5acdf2Sstefano_zampini ierr = MatHeaderMerge(C,&D);CHKERRQ(ierr); 9924222ddf1SHong Zhang C->product = product; 9934222ddf1SHong Zhang 9945e5acdf2Sstefano_zampini ierr = MatAIJRestoreParCSR_Private(A,&hA);CHKERRQ(ierr); 9955e5acdf2Sstefano_zampini ierr = MatAIJRestoreParCSR_Private(B,&hB);CHKERRQ(ierr); 9965e5acdf2Sstefano_zampini PetscFunctionReturn(0); 9975e5acdf2Sstefano_zampini } 9985e5acdf2Sstefano_zampini 9994222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatMatMultSymbolic_AIJ_AIJ_wHYPRE(Mat A,Mat B,PetscReal fill,Mat C) 10005e5acdf2Sstefano_zampini { 10015e5acdf2Sstefano_zampini PetscErrorCode ierr; 100220e1dc0dSstefano_zampini 10035e5acdf2Sstefano_zampini PetscFunctionBegin; 10044222ddf1SHong Zhang ierr = MatSetType(C,MATAIJ);CHKERRQ(ierr); 10054222ddf1SHong Zhang C->ops->matmultnumeric = MatMatMultNumeric_AIJ_AIJ_wHYPRE; 10064222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_AB; 10075e5acdf2Sstefano_zampini PetscFunctionReturn(0); 10085e5acdf2Sstefano_zampini } 10095e5acdf2Sstefano_zampini 1010d501dc42Sstefano_zampini static PetscErrorCode MatMatMultNumeric_HYPRE_HYPRE(Mat A,Mat B,Mat C) 1011d501dc42Sstefano_zampini { 1012d501dc42Sstefano_zampini Mat D; 1013d501dc42Sstefano_zampini hypre_ParCSRMatrix *Aparcsr,*Bparcsr,*ABparcsr = NULL; 1014d501dc42Sstefano_zampini Mat_HYPRE *hA,*hB; 1015d501dc42Sstefano_zampini PetscBool ishypre; 1016d501dc42Sstefano_zampini HYPRE_Int type; 1017d501dc42Sstefano_zampini PetscErrorCode ierr; 10184222ddf1SHong Zhang Mat_Product *product; 1019d501dc42Sstefano_zampini 1020d501dc42Sstefano_zampini PetscFunctionBegin; 1021d501dc42Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)B,MATHYPRE,&ishypre);CHKERRQ(ierr); 1022d501dc42Sstefano_zampini if (!ishypre) SETERRQ1(PetscObjectComm((PetscObject)B),PETSC_ERR_USER,"B should be of type %s",MATHYPRE); 1023d501dc42Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATHYPRE,&ishypre);CHKERRQ(ierr); 1024d501dc42Sstefano_zampini if (!ishypre) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_USER,"A should be of type %s",MATHYPRE); 1025d501dc42Sstefano_zampini hA = (Mat_HYPRE*)A->data; 1026d501dc42Sstefano_zampini hB = (Mat_HYPRE*)B->data; 1027d501dc42Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(hA->ij,&type)); 1028d501dc42Sstefano_zampini if (type != HYPRE_PARCSR) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 1029d501dc42Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(hB->ij,&type)); 1030d501dc42Sstefano_zampini if (type != HYPRE_PARCSR) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 1031d501dc42Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hA->ij,(void**)&Aparcsr)); 1032d501dc42Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hB->ij,(void**)&Bparcsr)); 1033d501dc42Sstefano_zampini ierr = MatHYPRE_ParCSR_MatMatMult(Aparcsr,Bparcsr,&ABparcsr);CHKERRQ(ierr); 1034d501dc42Sstefano_zampini ierr = MatCreateFromParCSR(ABparcsr,MATHYPRE,PETSC_OWN_POINTER,&D);CHKERRQ(ierr); 10354222ddf1SHong Zhang 1036d501dc42Sstefano_zampini /* need to use HeaderReplace because HeaderMerge messes up with the communicator */ 10374222ddf1SHong Zhang product = C->product; /* save it from MatHeaderReplace() */ 10384222ddf1SHong Zhang C->product = NULL; 1039d501dc42Sstefano_zampini ierr = MatHeaderReplace(C,&D);CHKERRQ(ierr); 10404222ddf1SHong Zhang C->product = product; 1041d501dc42Sstefano_zampini C->ops->matmultnumeric = MatMatMultNumeric_HYPRE_HYPRE; 10424222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_AB; 1043d501dc42Sstefano_zampini PetscFunctionReturn(0); 1044d501dc42Sstefano_zampini } 1045d501dc42Sstefano_zampini 10463dad0653Sstefano_zampini PETSC_INTERN PetscErrorCode MatTransposeMatMatMultNumeric_AIJ_AIJ_AIJ_wHYPRE(Mat A,Mat B,Mat C,Mat D) 104720e1dc0dSstefano_zampini { 104820e1dc0dSstefano_zampini Mat E; 10496abb4441SStefano Zampini hypre_ParCSRMatrix *hA,*hB,*hC,*hABC = NULL; 105020e1dc0dSstefano_zampini PetscErrorCode ierr; 105120e1dc0dSstefano_zampini 105220e1dc0dSstefano_zampini PetscFunctionBegin; 105320e1dc0dSstefano_zampini ierr = MatAIJGetParCSR_Private(A,&hA);CHKERRQ(ierr); 105420e1dc0dSstefano_zampini ierr = MatAIJGetParCSR_Private(B,&hB);CHKERRQ(ierr); 105520e1dc0dSstefano_zampini ierr = MatAIJGetParCSR_Private(C,&hC);CHKERRQ(ierr); 105620e1dc0dSstefano_zampini ierr = MatHYPRE_ParCSR_RAP(hA,hB,hC,&hABC);CHKERRQ(ierr); 105720e1dc0dSstefano_zampini ierr = MatCreateFromParCSR(hABC,MATAIJ,PETSC_OWN_POINTER,&E);CHKERRQ(ierr); 105820e1dc0dSstefano_zampini ierr = MatHeaderMerge(D,&E);CHKERRQ(ierr); 105920e1dc0dSstefano_zampini ierr = MatAIJRestoreParCSR_Private(A,&hA);CHKERRQ(ierr); 106020e1dc0dSstefano_zampini ierr = MatAIJRestoreParCSR_Private(B,&hB);CHKERRQ(ierr); 106120e1dc0dSstefano_zampini ierr = MatAIJRestoreParCSR_Private(C,&hC);CHKERRQ(ierr); 106220e1dc0dSstefano_zampini PetscFunctionReturn(0); 106320e1dc0dSstefano_zampini } 106420e1dc0dSstefano_zampini 10654222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatTransposeMatMatMultSymbolic_AIJ_AIJ_AIJ_wHYPRE(Mat A,Mat B,Mat C,PetscReal fill,Mat D) 106620e1dc0dSstefano_zampini { 106720e1dc0dSstefano_zampini PetscErrorCode ierr; 106820e1dc0dSstefano_zampini 106920e1dc0dSstefano_zampini PetscFunctionBegin; 10704222ddf1SHong Zhang ierr = MatSetType(D,MATAIJ);CHKERRQ(ierr); 107120e1dc0dSstefano_zampini PetscFunctionReturn(0); 107220e1dc0dSstefano_zampini } 107320e1dc0dSstefano_zampini 10744222ddf1SHong Zhang /* ---------------------------------------------------- */ 10754222ddf1SHong Zhang static PetscErrorCode MatProductSymbolic_AB_HYPRE(Mat C) 10764222ddf1SHong Zhang { 10774222ddf1SHong Zhang PetscFunctionBegin; 10784222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_AB; 10794222ddf1SHong Zhang PetscFunctionReturn(0); 10804222ddf1SHong Zhang } 10814222ddf1SHong Zhang 10824222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_HYPRE_AB(Mat C) 10834222ddf1SHong Zhang { 10844222ddf1SHong Zhang PetscErrorCode ierr; 10854222ddf1SHong Zhang Mat_Product *product = C->product; 10864222ddf1SHong Zhang PetscBool Ahypre; 10874222ddf1SHong Zhang 10884222ddf1SHong Zhang PetscFunctionBegin; 10894222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)product->A,MATHYPRE,&Ahypre);CHKERRQ(ierr); 10904222ddf1SHong Zhang if (Ahypre) { /* A is a Hypre matrix */ 10914222ddf1SHong Zhang ierr = MatSetType(C,MATHYPRE);CHKERRQ(ierr); 10924222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AB_HYPRE; 10934222ddf1SHong Zhang C->ops->matmultnumeric = MatMatMultNumeric_HYPRE_HYPRE; 10944222ddf1SHong Zhang PetscFunctionReturn(0); 10956718818eSStefano Zampini } 10964222ddf1SHong Zhang PetscFunctionReturn(0); 10974222ddf1SHong Zhang } 10984222ddf1SHong Zhang 10994222ddf1SHong Zhang static PetscErrorCode MatProductSymbolic_PtAP_HYPRE(Mat C) 11004222ddf1SHong Zhang { 11014222ddf1SHong Zhang PetscFunctionBegin; 11024222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_PtAP; 11034222ddf1SHong Zhang PetscFunctionReturn(0); 11044222ddf1SHong Zhang } 11054222ddf1SHong Zhang 11064222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_HYPRE_PtAP(Mat C) 11074222ddf1SHong Zhang { 11084222ddf1SHong Zhang PetscErrorCode ierr; 11094222ddf1SHong Zhang Mat_Product *product = C->product; 11104222ddf1SHong Zhang PetscBool flg; 11114222ddf1SHong Zhang PetscInt type = 0; 11124222ddf1SHong Zhang const char *outTypes[4] = {"aij","seqaij","mpiaij","hypre"}; 11134222ddf1SHong Zhang PetscInt ntype = 4; 11144222ddf1SHong Zhang Mat A = product->A; 11154222ddf1SHong Zhang PetscBool Ahypre; 11164222ddf1SHong Zhang 11174222ddf1SHong Zhang PetscFunctionBegin; 11184222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)A,MATHYPRE,&Ahypre);CHKERRQ(ierr); 11194222ddf1SHong Zhang if (Ahypre) { /* A is a Hypre matrix */ 11204222ddf1SHong Zhang ierr = MatSetType(C,MATHYPRE);CHKERRQ(ierr); 11214222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_PtAP_HYPRE; 11224222ddf1SHong Zhang C->ops->ptapnumeric = MatPtAPNumeric_HYPRE_HYPRE; 11234222ddf1SHong Zhang PetscFunctionReturn(0); 11244222ddf1SHong Zhang } 11254222ddf1SHong Zhang 11264222ddf1SHong Zhang /* A is AIJ, P is Hypre, C = PtAP can be either AIJ or Hypre format */ 11274222ddf1SHong Zhang /* Get runtime option */ 11284222ddf1SHong Zhang if (product->api_user) { 11294222ddf1SHong Zhang ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)C),((PetscObject)C)->prefix,"MatPtAP_HYPRE","Mat");CHKERRQ(ierr); 11304222ddf1SHong Zhang ierr = PetscOptionsEList("-matptap_hypre_outtype","MatPtAP outtype","MatPtAP outtype",outTypes,ntype,outTypes[type],&type,&flg);CHKERRQ(ierr); 11314222ddf1SHong Zhang ierr = PetscOptionsEnd();CHKERRQ(ierr); 11324222ddf1SHong Zhang } else { 11334222ddf1SHong Zhang ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)C),((PetscObject)C)->prefix,"MatProduct_PtAP_HYPRE","Mat");CHKERRQ(ierr); 11344222ddf1SHong Zhang ierr = PetscOptionsEList("-matproduct_ptap_hypre_outtype","MatProduct_PtAP outtype","MatProduct_PtAP",outTypes,ntype,outTypes[type],&type,&flg);CHKERRQ(ierr); 11354222ddf1SHong Zhang ierr = PetscOptionsEnd();CHKERRQ(ierr); 11364222ddf1SHong Zhang } 11374222ddf1SHong Zhang 11384222ddf1SHong Zhang if (type == 0 || type == 1 || type == 2) { 11394222ddf1SHong Zhang ierr = MatSetType(C,MATAIJ);CHKERRQ(ierr); 11404222ddf1SHong Zhang } else if (type == 3) { 11414222ddf1SHong Zhang ierr = MatSetType(C,MATHYPRE);CHKERRQ(ierr); 11424222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_SUP,"MatPtAP outtype is not supported"); 11434222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_PtAP_HYPRE; 11444222ddf1SHong Zhang C->ops->ptapnumeric = MatPtAPNumeric_AIJ_HYPRE; 11454222ddf1SHong Zhang PetscFunctionReturn(0); 11464222ddf1SHong Zhang } 11474222ddf1SHong Zhang 11484222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_HYPRE(Mat C) 11494222ddf1SHong Zhang { 11504222ddf1SHong Zhang PetscErrorCode ierr; 11514222ddf1SHong Zhang Mat_Product *product = C->product; 11524222ddf1SHong Zhang 11534222ddf1SHong Zhang PetscFunctionBegin; 11544222ddf1SHong Zhang switch (product->type) { 11554222ddf1SHong Zhang case MATPRODUCT_AB: 11564222ddf1SHong Zhang ierr = MatProductSetFromOptions_HYPRE_AB(C);CHKERRQ(ierr); 11574222ddf1SHong Zhang break; 11584222ddf1SHong Zhang case MATPRODUCT_PtAP: 11594222ddf1SHong Zhang ierr = MatProductSetFromOptions_HYPRE_PtAP(C);CHKERRQ(ierr); 11604222ddf1SHong Zhang break; 11616718818eSStefano Zampini default: 11626718818eSStefano Zampini break; 11634222ddf1SHong Zhang } 11644222ddf1SHong Zhang PetscFunctionReturn(0); 11654222ddf1SHong Zhang } 11664222ddf1SHong Zhang 11674222ddf1SHong Zhang /* -------------------------------------------------------- */ 11684222ddf1SHong Zhang 1169ea9daf28SStefano Zampini static PetscErrorCode MatMultTranspose_HYPRE(Mat A, Vec x, Vec y) 117063c07aadSStefano Zampini { 117163c07aadSStefano Zampini PetscErrorCode ierr; 117263c07aadSStefano Zampini 117363c07aadSStefano Zampini PetscFunctionBegin; 1174414bd5c3SStefano Zampini ierr = MatHYPRE_MultKernel_Private(A,1.0,x,0.0,y,PETSC_TRUE);CHKERRQ(ierr); 117563c07aadSStefano Zampini PetscFunctionReturn(0); 117663c07aadSStefano Zampini } 117763c07aadSStefano Zampini 1178ea9daf28SStefano Zampini static PetscErrorCode MatMult_HYPRE(Mat A, Vec x, Vec y) 117963c07aadSStefano Zampini { 118063c07aadSStefano Zampini PetscErrorCode ierr; 118163c07aadSStefano Zampini 118263c07aadSStefano Zampini PetscFunctionBegin; 1183414bd5c3SStefano Zampini ierr = MatHYPRE_MultKernel_Private(A,1.0,x,0.0,y,PETSC_FALSE);CHKERRQ(ierr); 118463c07aadSStefano Zampini PetscFunctionReturn(0); 118563c07aadSStefano Zampini } 118663c07aadSStefano Zampini 1187414bd5c3SStefano Zampini static PetscErrorCode MatMultAdd_HYPRE(Mat A, Vec x, Vec y, Vec z) 1188414bd5c3SStefano Zampini { 1189414bd5c3SStefano Zampini PetscErrorCode ierr; 1190414bd5c3SStefano Zampini 1191414bd5c3SStefano Zampini PetscFunctionBegin; 1192414bd5c3SStefano Zampini if (y != z) { 1193414bd5c3SStefano Zampini ierr = VecCopy(y,z);CHKERRQ(ierr); 1194414bd5c3SStefano Zampini } 1195414bd5c3SStefano Zampini ierr = MatHYPRE_MultKernel_Private(A,1.0,x,1.0,z,PETSC_FALSE);CHKERRQ(ierr); 1196414bd5c3SStefano Zampini PetscFunctionReturn(0); 1197414bd5c3SStefano Zampini } 1198414bd5c3SStefano Zampini 1199414bd5c3SStefano Zampini static PetscErrorCode MatMultTransposeAdd_HYPRE(Mat A, Vec x, Vec y, Vec z) 1200414bd5c3SStefano Zampini { 1201414bd5c3SStefano Zampini PetscErrorCode ierr; 1202414bd5c3SStefano Zampini 1203414bd5c3SStefano Zampini PetscFunctionBegin; 1204414bd5c3SStefano Zampini if (y != z) { 1205414bd5c3SStefano Zampini ierr = VecCopy(y,z);CHKERRQ(ierr); 1206414bd5c3SStefano Zampini } 1207414bd5c3SStefano Zampini ierr = MatHYPRE_MultKernel_Private(A,1.0,x,1.0,z,PETSC_TRUE);CHKERRQ(ierr); 1208414bd5c3SStefano Zampini PetscFunctionReturn(0); 1209414bd5c3SStefano Zampini } 1210414bd5c3SStefano Zampini 1211414bd5c3SStefano Zampini /* y = a * A * x + b * y or y = a * A^t * x + b * y depending on trans */ 121239accc25SStefano Zampini static PetscErrorCode MatHYPRE_MultKernel_Private(Mat A, HYPRE_Complex a, Vec x, HYPRE_Complex b, Vec y, PetscBool trans) 121363c07aadSStefano Zampini { 121463c07aadSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 121563c07aadSStefano Zampini hypre_ParCSRMatrix *parcsr; 121663c07aadSStefano Zampini hypre_ParVector *hx,*hy; 121763c07aadSStefano Zampini PetscErrorCode ierr; 121863c07aadSStefano Zampini 121963c07aadSStefano Zampini PetscFunctionBegin; 122063c07aadSStefano Zampini if (trans) { 12216ea7df73SStefano Zampini ierr = VecHYPRE_IJVectorPushVecRead(hA->b,x);CHKERRQ(ierr); 12226ea7df73SStefano Zampini if (b != 0.0) { ierr = VecHYPRE_IJVectorPushVec(hA->x,y);CHKERRQ(ierr); } 12236ea7df73SStefano Zampini else { ierr = VecHYPRE_IJVectorPushVecWrite(hA->x,y);CHKERRQ(ierr); } 12246ea7df73SStefano Zampini PetscStackCallStandard(HYPRE_IJVectorGetObject,(hA->b->ij,(void**)&hx)); 12256ea7df73SStefano Zampini PetscStackCallStandard(HYPRE_IJVectorGetObject,(hA->x->ij,(void**)&hy)); 122663c07aadSStefano Zampini } else { 12276ea7df73SStefano Zampini ierr = VecHYPRE_IJVectorPushVecRead(hA->x,x);CHKERRQ(ierr); 12286ea7df73SStefano Zampini if (b != 0.0) { ierr = VecHYPRE_IJVectorPushVec(hA->b,y);CHKERRQ(ierr); } 12296ea7df73SStefano Zampini else { ierr = VecHYPRE_IJVectorPushVecWrite(hA->b,y);CHKERRQ(ierr); } 12306ea7df73SStefano Zampini PetscStackCallStandard(HYPRE_IJVectorGetObject,(hA->x->ij,(void**)&hx)); 12316ea7df73SStefano Zampini PetscStackCallStandard(HYPRE_IJVectorGetObject,(hA->b->ij,(void**)&hy)); 123263c07aadSStefano Zampini } 12336ea7df73SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hA->ij,(void**)&parcsr)); 12346ea7df73SStefano Zampini if (trans) { 12356ea7df73SStefano Zampini PetscStackCallStandard(hypre_ParCSRMatrixMatvecT,(a,parcsr,hx,b,hy)); 12366ea7df73SStefano Zampini } else { 12376ea7df73SStefano Zampini PetscStackCallStandard(hypre_ParCSRMatrixMatvec,(a,parcsr,hx,b,hy)); 12386ea7df73SStefano Zampini } 12396ea7df73SStefano Zampini ierr = VecHYPRE_IJVectorPopVec(hA->x);CHKERRQ(ierr); 12406ea7df73SStefano Zampini ierr = VecHYPRE_IJVectorPopVec(hA->b);CHKERRQ(ierr); 124163c07aadSStefano Zampini PetscFunctionReturn(0); 124263c07aadSStefano Zampini } 124363c07aadSStefano Zampini 1244ea9daf28SStefano Zampini static PetscErrorCode MatDestroy_HYPRE(Mat A) 124563c07aadSStefano Zampini { 124663c07aadSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 124763c07aadSStefano Zampini PetscErrorCode ierr; 124863c07aadSStefano Zampini 124963c07aadSStefano Zampini PetscFunctionBegin; 12506ea7df73SStefano Zampini ierr = VecHYPRE_IJVectorDestroy(&hA->x);CHKERRQ(ierr); 12516ea7df73SStefano Zampini ierr = VecHYPRE_IJVectorDestroy(&hA->b);CHKERRQ(ierr); 1252978814f1SStefano Zampini if (hA->ij) { 1253978814f1SStefano Zampini if (!hA->inner_free) hypre_IJMatrixObject(hA->ij) = NULL; 1254978814f1SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixDestroy,(hA->ij)); 1255978814f1SStefano Zampini } 1256ffc4695bSBarry Smith if (hA->comm) {ierr = MPI_Comm_free(&hA->comm);CHKERRMPI(ierr);} 1257c69f721fSFande Kong 1258c69f721fSFande Kong ierr = MatStashDestroy_Private(&A->stash);CHKERRQ(ierr); 1259c69f721fSFande Kong 1260c69f721fSFande Kong ierr = PetscFree(hA->array);CHKERRQ(ierr); 1261c69f721fSFande Kong 126263c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_hypre_aij_C",NULL);CHKERRQ(ierr); 12632df22349SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_hypre_is_C",NULL);CHKERRQ(ierr); 12644222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqaij_hypre_C",NULL);CHKERRQ(ierr); 12654222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_mpiaij_hypre_C",NULL);CHKERRQ(ierr); 1266d975228cSstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatHYPRESetPreallocation_C",NULL);CHKERRQ(ierr); 1267dd9c0a25Sstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatHYPREGetParCSR_C",NULL);CHKERRQ(ierr); 126863c07aadSStefano Zampini ierr = PetscFree(A->data);CHKERRQ(ierr); 126963c07aadSStefano Zampini PetscFunctionReturn(0); 127063c07aadSStefano Zampini } 127163c07aadSStefano Zampini 1272ea9daf28SStefano Zampini static PetscErrorCode MatSetUp_HYPRE(Mat A) 127363c07aadSStefano Zampini { 12744ec6421dSstefano_zampini PetscErrorCode ierr; 12754ec6421dSstefano_zampini 12764ec6421dSstefano_zampini PetscFunctionBegin; 12774ec6421dSstefano_zampini ierr = MatHYPRESetPreallocation(A,PETSC_DEFAULT,NULL,PETSC_DEFAULT,NULL);CHKERRQ(ierr); 12784ec6421dSstefano_zampini PetscFunctionReturn(0); 12794ec6421dSstefano_zampini } 12804ec6421dSstefano_zampini 12816ea7df73SStefano Zampini //TODO FIX hypre_CSRMatrixMatvecOutOfPlace 12826ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 12836ea7df73SStefano Zampini static PetscErrorCode MatBindToCPU_HYPRE(Mat A, PetscBool bind) 12846ea7df73SStefano Zampini { 12856ea7df73SStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 12866ea7df73SStefano Zampini HYPRE_MemoryLocation hmem = bind ? HYPRE_MEMORY_HOST : HYPRE_MEMORY_DEVICE; 12876ea7df73SStefano Zampini PetscErrorCode ierr; 12886ea7df73SStefano Zampini 12896ea7df73SStefano Zampini PetscFunctionBegin; 12906ea7df73SStefano Zampini A->boundtocpu = bind; 12916ea7df73SStefano Zampini if (hypre_IJMatrixAssembleFlag(hA->ij) && hmem != hypre_IJMatrixMemoryLocation(hA->ij)) { 12926ea7df73SStefano Zampini hypre_ParCSRMatrix *parcsr; 12936ea7df73SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hA->ij,(void**)&parcsr)); 12946ea7df73SStefano Zampini PetscStackCallStandard(hypre_ParCSRMatrixMigrate,(parcsr, hmem)); 12956ea7df73SStefano Zampini } 12966ea7df73SStefano Zampini if (hA->x) { ierr = VecHYPRE_IJBindToCPU(hA->x,bind);CHKERRQ(ierr); } 12976ea7df73SStefano Zampini if (hA->b) { ierr = VecHYPRE_IJBindToCPU(hA->b,bind);CHKERRQ(ierr); } 12986ea7df73SStefano Zampini PetscFunctionReturn(0); 12996ea7df73SStefano Zampini } 13006ea7df73SStefano Zampini #endif 13016ea7df73SStefano Zampini 13024ec6421dSstefano_zampini static PetscErrorCode MatAssemblyEnd_HYPRE(Mat A, MatAssemblyType mode) 13034ec6421dSstefano_zampini { 130463c07aadSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 1305c69f721fSFande Kong PetscMPIInt n; 1306c69f721fSFande Kong PetscInt i,j,rstart,ncols,flg; 1307c69f721fSFande Kong PetscInt *row,*col; 1308c69f721fSFande Kong PetscScalar *val; 130963c07aadSStefano Zampini PetscErrorCode ierr; 131063c07aadSStefano Zampini 131163c07aadSStefano Zampini PetscFunctionBegin; 13124ec6421dSstefano_zampini if (mode == MAT_FLUSH_ASSEMBLY) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MAT_FLUSH_ASSEMBLY currently not supported with MATHYPRE"); 1313c69f721fSFande Kong 1314c69f721fSFande Kong if (!A->nooffprocentries) { 1315c69f721fSFande Kong while (1) { 1316c69f721fSFande Kong ierr = MatStashScatterGetMesg_Private(&A->stash,&n,&row,&col,&val,&flg);CHKERRQ(ierr); 1317c69f721fSFande Kong if (!flg) break; 1318c69f721fSFande Kong 1319c69f721fSFande Kong for (i=0; i<n;) { 1320c69f721fSFande Kong /* Now identify the consecutive vals belonging to the same row */ 1321c69f721fSFande Kong for (j=i,rstart=row[j]; j<n; j++) { 1322c69f721fSFande Kong if (row[j] != rstart) break; 1323c69f721fSFande Kong } 1324c69f721fSFande Kong if (j < n) ncols = j-i; 1325c69f721fSFande Kong else ncols = n-i; 1326c69f721fSFande Kong /* Now assemble all these values with a single function call */ 1327c69f721fSFande Kong ierr = MatSetValues_HYPRE(A,1,row+i,ncols,col+i,val+i,A->insertmode);CHKERRQ(ierr); 1328c69f721fSFande Kong 1329c69f721fSFande Kong i = j; 1330c69f721fSFande Kong } 1331c69f721fSFande Kong } 1332c69f721fSFande Kong ierr = MatStashScatterEnd_Private(&A->stash);CHKERRQ(ierr); 1333c69f721fSFande Kong } 1334c69f721fSFande Kong 13354ec6421dSstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixAssemble,(hA->ij)); 1336336664bdSPierre Jolivet /* The assembly routine destroys the aux_matrix, we recreate it here by calling HYPRE_IJMatrixInitialize */ 1337336664bdSPierre 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 */ 1338336664bdSPierre Jolivet if (!hA->sorted_full) { 1339af1cf968SStefano Zampini hypre_AuxParCSRMatrix *aux_matrix; 1340af1cf968SStefano Zampini 1341af1cf968SStefano Zampini /* call destroy just to make sure we do not leak anything */ 1342af1cf968SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix*)hypre_IJMatrixTranslator(hA->ij); 1343af1cf968SStefano Zampini PetscStackCallStandard(hypre_AuxParCSRMatrixDestroy,(aux_matrix)); 1344af1cf968SStefano Zampini hypre_IJMatrixTranslator(hA->ij) = NULL; 1345af1cf968SStefano Zampini 1346af1cf968SStefano Zampini /* Initialize with assembled flag -> it only recreates the aux_par_matrix */ 1347af1cf968SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixInitialize,(hA->ij)); 1348af1cf968SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix*)hypre_IJMatrixTranslator(hA->ij); 13496ea7df73SStefano Zampini if (aux_matrix) { 1350af1cf968SStefano Zampini hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 1; /* see comment in MatHYPRESetPreallocation_HYPRE */ 135122235d61SPierre Jolivet #if PETSC_PKG_HYPRE_VERSION_LT(2,19,0) 1352af1cf968SStefano Zampini PetscStackCallStandard(hypre_AuxParCSRMatrixInitialize,(aux_matrix)); 135322235d61SPierre Jolivet #else 135422235d61SPierre Jolivet PetscStackCallStandard(hypre_AuxParCSRMatrixInitialize_v2,(aux_matrix,HYPRE_MEMORY_HOST)); 135522235d61SPierre Jolivet #endif 1356af1cf968SStefano Zampini } 13576ea7df73SStefano Zampini } 13586ea7df73SStefano Zampini { 13596ea7df73SStefano Zampini hypre_ParCSRMatrix *parcsr; 13606ea7df73SStefano Zampini 13616ea7df73SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hA->ij,(void**)&parcsr)); 13626ea7df73SStefano Zampini if (!hypre_ParCSRMatrixCommPkg(parcsr)) PetscStackCallStandard(hypre_MatvecCommPkgCreate,(parcsr)); 13636ea7df73SStefano Zampini } 13646ea7df73SStefano Zampini if (!hA->x) { ierr = VecHYPRE_IJVectorCreate(A->cmap,&hA->x);CHKERRQ(ierr); } 13656ea7df73SStefano Zampini if (!hA->b) { ierr = VecHYPRE_IJVectorCreate(A->rmap,&hA->b);CHKERRQ(ierr); } 13666ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 13676ea7df73SStefano Zampini ierr = MatBindToCPU_HYPRE(A,A->boundtocpu);CHKERRQ(ierr); 13686ea7df73SStefano Zampini #endif 136963c07aadSStefano Zampini PetscFunctionReturn(0); 137063c07aadSStefano Zampini } 137163c07aadSStefano Zampini 1372c69f721fSFande Kong static PetscErrorCode MatGetArray_HYPRE(Mat A, PetscInt size, void **array) 1373c69f721fSFande Kong { 1374c69f721fSFande Kong Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 1375c69f721fSFande Kong PetscErrorCode ierr; 1376c69f721fSFande Kong 1377c69f721fSFande Kong PetscFunctionBegin; 1378c69f721fSFande Kong if (!hA->available) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Temporary space is in use"); 1379c69f721fSFande Kong 138039accc25SStefano Zampini if (hA->size >= size) { 138139accc25SStefano Zampini *array = hA->array; 138239accc25SStefano Zampini } else { 1383c69f721fSFande Kong ierr = PetscFree(hA->array);CHKERRQ(ierr); 1384c69f721fSFande Kong hA->size = size; 1385c69f721fSFande Kong ierr = PetscMalloc(hA->size,&hA->array);CHKERRQ(ierr); 1386c69f721fSFande Kong *array = hA->array; 1387c69f721fSFande Kong } 1388c69f721fSFande Kong 1389c69f721fSFande Kong hA->available = PETSC_FALSE; 1390c69f721fSFande Kong PetscFunctionReturn(0); 1391c69f721fSFande Kong } 1392c69f721fSFande Kong 1393708542d2SFande Kong static PetscErrorCode MatRestoreArray_HYPRE(Mat A, void **array) 1394c69f721fSFande Kong { 1395c69f721fSFande Kong Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 1396c69f721fSFande Kong 1397c69f721fSFande Kong PetscFunctionBegin; 1398c69f721fSFande Kong *array = NULL; 1399c69f721fSFande Kong hA->available = PETSC_TRUE; 1400c69f721fSFande Kong PetscFunctionReturn(0); 1401c69f721fSFande Kong } 1402c69f721fSFande Kong 14036ea7df73SStefano Zampini static PetscErrorCode MatSetValues_HYPRE(Mat A, PetscInt nr, const PetscInt rows[], PetscInt nc, const PetscInt cols[], const PetscScalar v[], InsertMode ins) 1404d975228cSstefano_zampini { 1405d975228cSstefano_zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 1406d975228cSstefano_zampini PetscScalar *vals = (PetscScalar *)v; 140739accc25SStefano Zampini HYPRE_Complex *sscr; 1408c69f721fSFande Kong PetscInt *cscr[2]; 1409c69f721fSFande Kong PetscInt i,nzc; 141008defe43SFande Kong void *array = NULL; 1411d975228cSstefano_zampini PetscErrorCode ierr; 1412d975228cSstefano_zampini 1413d975228cSstefano_zampini PetscFunctionBegin; 141439accc25SStefano Zampini ierr = MatGetArray_HYPRE(A,sizeof(PetscInt)*(2*nc)+sizeof(HYPRE_Complex)*nc*nr,&array);CHKERRQ(ierr); 1415c69f721fSFande Kong cscr[0] = (PetscInt*)array; 1416c69f721fSFande Kong cscr[1] = ((PetscInt*)array)+nc; 141739accc25SStefano Zampini sscr = (HYPRE_Complex*)(((PetscInt*)array)+nc*2); 1418d975228cSstefano_zampini for (i=0,nzc=0;i<nc;i++) { 1419d975228cSstefano_zampini if (cols[i] >= 0) { 1420d975228cSstefano_zampini cscr[0][nzc ] = cols[i]; 1421d975228cSstefano_zampini cscr[1][nzc++] = i; 1422d975228cSstefano_zampini } 1423d975228cSstefano_zampini } 1424c69f721fSFande Kong if (!nzc) { 1425708542d2SFande Kong ierr = MatRestoreArray_HYPRE(A,&array);CHKERRQ(ierr); 1426c69f721fSFande Kong PetscFunctionReturn(0); 1427c69f721fSFande Kong } 1428d975228cSstefano_zampini 14296ea7df73SStefano Zampini #if 0 //defined(PETSC_HAVE_HYPRE_DEVICE) 14306ea7df73SStefano Zampini if (HYPRE_MEMORY_HOST != hypre_IJMatrixMemoryLocation(hA->ij)) { 14316ea7df73SStefano Zampini hypre_ParCSRMatrix *parcsr; 14326ea7df73SStefano Zampini 14336ea7df73SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hA->ij,(void**)&parcsr)); 14346ea7df73SStefano Zampini PetscStackCallStandard(hypre_ParCSRMatrixMigrate,(parcsr, HYPRE_MEMORY_HOST)); 14356ea7df73SStefano Zampini } 14366ea7df73SStefano Zampini #endif 14376ea7df73SStefano Zampini 1438d975228cSstefano_zampini if (ins == ADD_VALUES) { 1439d975228cSstefano_zampini for (i=0;i<nr;i++) { 14406ea7df73SStefano Zampini if (rows[i] >= 0) { 1441d975228cSstefano_zampini PetscInt j; 14422cf14000SStefano Zampini HYPRE_Int hnc = (HYPRE_Int)nzc; 14432cf14000SStefano Zampini 14442cf14000SStefano Zampini if ((PetscInt)hnc != nzc) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Hypre overflow! number of columns %D for row %D",nzc,rows[i]); 14451e1ea65dSPierre Jolivet for (j=0;j<nzc;j++) { ierr = PetscHYPREScalarCast(vals[cscr[1][j]],&sscr[j]);CHKERRQ(ierr); } 14462cf14000SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixAddToValues,(hA->ij,1,&hnc,(HYPRE_BigInt*)(rows+i),(HYPRE_BigInt*)cscr[0],sscr)); 1447d975228cSstefano_zampini } 1448d975228cSstefano_zampini vals += nc; 1449d975228cSstefano_zampini } 1450d975228cSstefano_zampini } else { /* INSERT_VALUES */ 1451d975228cSstefano_zampini PetscInt rst,ren; 1452c69f721fSFande Kong 1453c6698e78SStefano Zampini ierr = MatGetOwnershipRange(A,&rst,&ren);CHKERRQ(ierr); 1454d975228cSstefano_zampini for (i=0;i<nr;i++) { 14556ea7df73SStefano Zampini if (rows[i] >= 0) { 1456d975228cSstefano_zampini PetscInt j; 14572cf14000SStefano Zampini HYPRE_Int hnc = (HYPRE_Int)nzc; 14582cf14000SStefano Zampini 14592cf14000SStefano Zampini if ((PetscInt)hnc != nzc) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Hypre overflow! number of columns %D for row %D",nzc,rows[i]); 14601e1ea65dSPierre Jolivet for (j=0;j<nzc;j++) { ierr = PetscHYPREScalarCast(vals[cscr[1][j]],&sscr[j]);CHKERRQ(ierr); } 1461c69f721fSFande Kong /* nonlocal values */ 146239accc25SStefano Zampini if (rows[i] < rst || rows[i] >= ren) { ierr = MatStashValuesRow_Private(&A->stash,rows[i],nzc,cscr[0],(PetscScalar*)sscr,PETSC_FALSE);CHKERRQ(ierr); } 1463c69f721fSFande Kong /* local values */ 14642cf14000SStefano Zampini else PetscStackCallStandard(HYPRE_IJMatrixSetValues,(hA->ij,1,&hnc,(HYPRE_BigInt*)(rows+i),(HYPRE_BigInt*)cscr[0],sscr)); 1465d975228cSstefano_zampini } 1466d975228cSstefano_zampini vals += nc; 1467d975228cSstefano_zampini } 1468d975228cSstefano_zampini } 1469c69f721fSFande Kong 1470708542d2SFande Kong ierr = MatRestoreArray_HYPRE(A,&array);CHKERRQ(ierr); 1471d975228cSstefano_zampini PetscFunctionReturn(0); 1472d975228cSstefano_zampini } 1473d975228cSstefano_zampini 1474d975228cSstefano_zampini static PetscErrorCode MatHYPRESetPreallocation_HYPRE(Mat A, PetscInt dnz, const PetscInt dnnz[], PetscInt onz, const PetscInt onnz[]) 1475d975228cSstefano_zampini { 1476d975228cSstefano_zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 14777d968826Sstefano_zampini HYPRE_Int *hdnnz,*honnz; 147806a29025Sstefano_zampini PetscInt i,rs,re,cs,ce,bs; 1479d975228cSstefano_zampini PetscMPIInt size; 1480d975228cSstefano_zampini PetscErrorCode ierr; 1481d975228cSstefano_zampini 1482d975228cSstefano_zampini PetscFunctionBegin; 148306a29025Sstefano_zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 1484d975228cSstefano_zampini ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 1485d975228cSstefano_zampini ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 1486d975228cSstefano_zampini rs = A->rmap->rstart; 1487d975228cSstefano_zampini re = A->rmap->rend; 1488d975228cSstefano_zampini cs = A->cmap->rstart; 1489d975228cSstefano_zampini ce = A->cmap->rend; 1490d975228cSstefano_zampini if (!hA->ij) { 1491d975228cSstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixCreate,(hA->comm,rs,re-1,cs,ce-1,&hA->ij)); 1492d975228cSstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixSetObjectType,(hA->ij,HYPRE_PARCSR)); 1493d975228cSstefano_zampini } else { 14942cf14000SStefano Zampini HYPRE_BigInt hrs,hre,hcs,hce; 1495d975228cSstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetLocalRange,(hA->ij,&hrs,&hre,&hcs,&hce)); 14962cf14000SStefano Zampini if (hre-hrs+1 != re -rs) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Inconsistent local rows: IJMatrix [%D,%D), PETSc [%D,%D)",hrs,hre+1,rs,re); 14972cf14000SStefano Zampini if (hce-hcs+1 != ce -cs) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Inconsistent local cols: IJMatrix [%D,%D), PETSc [%D,%D)",hcs,hce+1,cs,ce); 1498d975228cSstefano_zampini } 149906a29025Sstefano_zampini if (dnz == PETSC_DEFAULT || dnz == PETSC_DECIDE) dnz = 10*bs; 150006a29025Sstefano_zampini if (onz == PETSC_DEFAULT || onz == PETSC_DECIDE) onz = 10*bs; 150106a29025Sstefano_zampini 1502d975228cSstefano_zampini if (!dnnz) { 1503d975228cSstefano_zampini ierr = PetscMalloc1(A->rmap->n,&hdnnz);CHKERRQ(ierr); 1504d975228cSstefano_zampini for (i=0;i<A->rmap->n;i++) hdnnz[i] = dnz; 1505d975228cSstefano_zampini } else { 15067d968826Sstefano_zampini hdnnz = (HYPRE_Int*)dnnz; 1507d975228cSstefano_zampini } 1508ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRMPI(ierr); 1509d975228cSstefano_zampini if (size > 1) { 1510ddbeb582SStefano Zampini hypre_AuxParCSRMatrix *aux_matrix; 1511d975228cSstefano_zampini if (!onnz) { 1512d975228cSstefano_zampini ierr = PetscMalloc1(A->rmap->n,&honnz);CHKERRQ(ierr); 1513d975228cSstefano_zampini for (i=0;i<A->rmap->n;i++) honnz[i] = onz; 151422235d61SPierre Jolivet } else honnz = (HYPRE_Int*)onnz; 1515ddbeb582SStefano Zampini /* SetDiagOffdSizes sets hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 0, since it seems 1516ddbeb582SStefano Zampini they assume the user will input the entire row values, properly sorted 1517336664bdSPierre Jolivet In PETSc, we don't make such an assumption and set this flag to 1, 1518336664bdSPierre Jolivet unless the option MAT_SORTED_FULL is set to true. 1519ddbeb582SStefano Zampini Also, to avoid possible memory leaks, we destroy and recreate the translator 1520ddbeb582SStefano Zampini This has to be done here, as HYPRE_IJMatrixInitialize will properly initialize 1521ddbeb582SStefano Zampini the IJ matrix for us */ 1522ddbeb582SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix*)hypre_IJMatrixTranslator(hA->ij); 1523ddbeb582SStefano Zampini hypre_AuxParCSRMatrixDestroy(aux_matrix); 1524ddbeb582SStefano Zampini hypre_IJMatrixTranslator(hA->ij) = NULL; 1525d975228cSstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixSetDiagOffdSizes,(hA->ij,hdnnz,honnz)); 1526ddbeb582SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix*)hypre_IJMatrixTranslator(hA->ij); 1527336664bdSPierre Jolivet hypre_AuxParCSRMatrixNeedAux(aux_matrix) = !hA->sorted_full; 1528d975228cSstefano_zampini } else { 1529d975228cSstefano_zampini honnz = NULL; 1530d975228cSstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixSetRowSizes,(hA->ij,hdnnz)); 1531d975228cSstefano_zampini } 1532ddbeb582SStefano Zampini 1533af1cf968SStefano Zampini /* reset assembled flag and call the initialize method */ 1534af1cf968SStefano Zampini hypre_IJMatrixAssembleFlag(hA->ij) = 0; 15356ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_LT(2,19,0) 1536ddbeb582SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixInitialize,(hA->ij)); 15376ea7df73SStefano Zampini #else 15386ea7df73SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixInitialize_v2,(hA->ij,HYPRE_MEMORY_HOST)); 15396ea7df73SStefano Zampini #endif 1540d975228cSstefano_zampini if (!dnnz) { 1541d975228cSstefano_zampini ierr = PetscFree(hdnnz);CHKERRQ(ierr); 1542d975228cSstefano_zampini } 1543d975228cSstefano_zampini if (!onnz && honnz) { 1544d975228cSstefano_zampini ierr = PetscFree(honnz);CHKERRQ(ierr); 1545d975228cSstefano_zampini } 1546af1cf968SStefano Zampini /* Match AIJ logic */ 154706a29025Sstefano_zampini A->preallocated = PETSC_TRUE; 1548af1cf968SStefano Zampini A->assembled = PETSC_FALSE; 1549d975228cSstefano_zampini PetscFunctionReturn(0); 1550d975228cSstefano_zampini } 1551d975228cSstefano_zampini 1552d975228cSstefano_zampini /*@C 1553d975228cSstefano_zampini MatHYPRESetPreallocation - Preallocates memory for a sparse parallel matrix in HYPRE IJ format 1554d975228cSstefano_zampini 1555d975228cSstefano_zampini Collective on Mat 1556d975228cSstefano_zampini 1557d975228cSstefano_zampini Input Parameters: 1558d975228cSstefano_zampini + A - the matrix 1559d975228cSstefano_zampini . dnz - number of nonzeros per row in DIAGONAL portion of local submatrix 1560d975228cSstefano_zampini (same value is used for all local rows) 1561d975228cSstefano_zampini . dnnz - array containing the number of nonzeros in the various rows of the 1562d975228cSstefano_zampini DIAGONAL portion of the local submatrix (possibly different for each row) 1563d975228cSstefano_zampini or NULL (PETSC_NULL_INTEGER in Fortran), if d_nz is used to specify the nonzero structure. 1564d975228cSstefano_zampini The size of this array is equal to the number of local rows, i.e 'm'. 1565d975228cSstefano_zampini For matrices that will be factored, you must leave room for (and set) 1566d975228cSstefano_zampini the diagonal entry even if it is zero. 1567d975228cSstefano_zampini . onz - number of nonzeros per row in the OFF-DIAGONAL portion of local 1568d975228cSstefano_zampini submatrix (same value is used for all local rows). 1569d975228cSstefano_zampini - onnz - array containing the number of nonzeros in the various rows of the 1570d975228cSstefano_zampini OFF-DIAGONAL portion of the local submatrix (possibly different for 1571d975228cSstefano_zampini each row) or NULL (PETSC_NULL_INTEGER in Fortran), if o_nz is used to specify the nonzero 1572d975228cSstefano_zampini structure. The size of this array is equal to the number 1573d975228cSstefano_zampini of local rows, i.e 'm'. 1574d975228cSstefano_zampini 157595452b02SPatrick Sanan Notes: 157695452b02SPatrick Sanan If the *nnz parameter is given then the *nz parameter is ignored; for sequential matrices, onz and onnz are ignored. 1577d975228cSstefano_zampini 1578d975228cSstefano_zampini Level: intermediate 1579d975228cSstefano_zampini 1580af1cf968SStefano Zampini .seealso: MatCreate(), MatMPIAIJSetPreallocation(), MATHYPRE 1581d975228cSstefano_zampini @*/ 1582d975228cSstefano_zampini PetscErrorCode MatHYPRESetPreallocation(Mat A, PetscInt dnz, const PetscInt dnnz[], PetscInt onz, const PetscInt onnz[]) 1583d975228cSstefano_zampini { 1584d975228cSstefano_zampini PetscErrorCode ierr; 1585d975228cSstefano_zampini 1586d975228cSstefano_zampini PetscFunctionBegin; 1587d975228cSstefano_zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 1588d975228cSstefano_zampini PetscValidType(A,1); 1589d975228cSstefano_zampini ierr = PetscTryMethod(A,"MatHYPRESetPreallocation_C",(Mat,PetscInt,const PetscInt[],PetscInt,const PetscInt[]),(A,dnz,dnnz,onz,onnz));CHKERRQ(ierr); 1590d975228cSstefano_zampini PetscFunctionReturn(0); 1591d975228cSstefano_zampini } 1592d975228cSstefano_zampini 1593225daaf8SStefano Zampini /* 1594225daaf8SStefano Zampini MatCreateFromParCSR - Creates a matrix from a hypre_ParCSRMatrix 1595225daaf8SStefano Zampini 1596225daaf8SStefano Zampini Collective 1597225daaf8SStefano Zampini 1598225daaf8SStefano Zampini Input Parameters: 159945b8d346SStefano Zampini + parcsr - the pointer to the hypre_ParCSRMatrix 1600bb4689ddSStefano Zampini . mtype - matrix type to be created. Currently MATAIJ, MATIS and MATHYPRE are supported. 1601225daaf8SStefano Zampini - copymode - PETSc copying options 1602225daaf8SStefano Zampini 1603225daaf8SStefano Zampini Output Parameter: 1604225daaf8SStefano Zampini . A - the matrix 1605225daaf8SStefano Zampini 1606225daaf8SStefano Zampini Level: intermediate 1607225daaf8SStefano Zampini 1608225daaf8SStefano Zampini .seealso: MatHYPRE, PetscCopyMode 1609225daaf8SStefano Zampini */ 161045b8d346SStefano Zampini PETSC_EXTERN PetscErrorCode MatCreateFromParCSR(hypre_ParCSRMatrix *parcsr, MatType mtype, PetscCopyMode copymode, Mat* A) 1611978814f1SStefano Zampini { 1612225daaf8SStefano Zampini Mat T; 1613978814f1SStefano Zampini Mat_HYPRE *hA; 1614978814f1SStefano Zampini MPI_Comm comm; 1615978814f1SStefano Zampini PetscInt rstart,rend,cstart,cend,M,N; 1616d248a85cSRichard Tran Mills PetscBool isseqaij,isseqaijmkl,ismpiaij,isaij,ishyp,isis; 1617978814f1SStefano Zampini PetscErrorCode ierr; 1618978814f1SStefano Zampini 1619978814f1SStefano Zampini PetscFunctionBegin; 1620978814f1SStefano Zampini comm = hypre_ParCSRMatrixComm(parcsr); 1621225daaf8SStefano Zampini ierr = PetscStrcmp(mtype,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 1622d248a85cSRichard Tran Mills ierr = PetscStrcmp(mtype,MATSEQAIJMKL,&isseqaijmkl);CHKERRQ(ierr); 1623225daaf8SStefano Zampini ierr = PetscStrcmp(mtype,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr); 1624225daaf8SStefano Zampini ierr = PetscStrcmp(mtype,MATAIJ,&isaij);CHKERRQ(ierr); 1625225daaf8SStefano Zampini ierr = PetscStrcmp(mtype,MATHYPRE,&ishyp);CHKERRQ(ierr); 16268cfe8d00SStefano Zampini ierr = PetscStrcmp(mtype,MATIS,&isis);CHKERRQ(ierr); 1627d248a85cSRichard Tran Mills isaij = (PetscBool)(isseqaij || isseqaijmkl || ismpiaij || isaij); 16286ea7df73SStefano Zampini /* TODO */ 1629d248a85cSRichard Tran Mills if (!isaij && !ishyp && !isis) SETERRQ7(comm,PETSC_ERR_SUP,"Unsupported MatType %s! Supported types are %s, %s, %s, %s, %s, and %s",mtype,MATAIJ,MATSEQAIJ,MATSEQAIJMKL,MATMPIAIJ,MATIS,MATHYPRE); 1630978814f1SStefano Zampini /* access ParCSRMatrix */ 1631978814f1SStefano Zampini rstart = hypre_ParCSRMatrixFirstRowIndex(parcsr); 1632978814f1SStefano Zampini rend = hypre_ParCSRMatrixLastRowIndex(parcsr); 1633978814f1SStefano Zampini cstart = hypre_ParCSRMatrixFirstColDiag(parcsr); 1634978814f1SStefano Zampini cend = hypre_ParCSRMatrixLastColDiag(parcsr); 1635978814f1SStefano Zampini M = hypre_ParCSRMatrixGlobalNumRows(parcsr); 1636978814f1SStefano Zampini N = hypre_ParCSRMatrixGlobalNumCols(parcsr); 1637978814f1SStefano Zampini 1638fa92c42cSstefano_zampini /* fix for empty local rows/columns */ 1639fa92c42cSstefano_zampini if (rend < rstart) rend = rstart; 1640fa92c42cSstefano_zampini if (cend < cstart) cend = cstart; 1641fa92c42cSstefano_zampini 1642e6471dc9SStefano Zampini /* PETSc convention */ 1643e6471dc9SStefano Zampini rend++; 1644e6471dc9SStefano Zampini cend++; 1645e6471dc9SStefano Zampini rend = PetscMin(rend,M); 1646e6471dc9SStefano Zampini cend = PetscMin(cend,N); 1647e6471dc9SStefano Zampini 1648978814f1SStefano Zampini /* create PETSc matrix with MatHYPRE */ 1649225daaf8SStefano Zampini ierr = MatCreate(comm,&T);CHKERRQ(ierr); 1650e6471dc9SStefano Zampini ierr = MatSetSizes(T,rend-rstart,cend-cstart,M,N);CHKERRQ(ierr); 1651225daaf8SStefano Zampini ierr = MatSetType(T,MATHYPRE);CHKERRQ(ierr); 1652225daaf8SStefano Zampini hA = (Mat_HYPRE*)(T->data); 1653978814f1SStefano Zampini 1654978814f1SStefano Zampini /* create HYPRE_IJMatrix */ 1655978814f1SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixCreate,(hA->comm,rstart,rend-1,cstart,cend-1,&hA->ij)); 165645b8d346SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixSetObjectType,(hA->ij,HYPRE_PARCSR)); 165745b8d346SStefano Zampini 16586ea7df73SStefano Zampini // TODO DEV 165945b8d346SStefano Zampini /* create new ParCSR object if needed */ 166045b8d346SStefano Zampini if (ishyp && copymode == PETSC_COPY_VALUES) { 166145b8d346SStefano Zampini hypre_ParCSRMatrix *new_parcsr; 16626ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_LT(2,18,0) 166345b8d346SStefano Zampini hypre_CSRMatrix *hdiag,*hoffd,*ndiag,*noffd; 166445b8d346SStefano Zampini 16650e6427aaSSatish Balay new_parcsr = hypre_ParCSRMatrixClone(parcsr,0); 166645b8d346SStefano Zampini hdiag = hypre_ParCSRMatrixDiag(parcsr); 166745b8d346SStefano Zampini hoffd = hypre_ParCSRMatrixOffd(parcsr); 166845b8d346SStefano Zampini ndiag = hypre_ParCSRMatrixDiag(new_parcsr); 166945b8d346SStefano Zampini noffd = hypre_ParCSRMatrixOffd(new_parcsr); 1670580bdb30SBarry Smith ierr = PetscArraycpy(hypre_CSRMatrixData(ndiag),hypre_CSRMatrixData(hdiag),hypre_CSRMatrixNumNonzeros(hdiag));CHKERRQ(ierr); 1671580bdb30SBarry Smith ierr = PetscArraycpy(hypre_CSRMatrixData(noffd),hypre_CSRMatrixData(hoffd),hypre_CSRMatrixNumNonzeros(hoffd));CHKERRQ(ierr); 16726ea7df73SStefano Zampini #else 16736ea7df73SStefano Zampini new_parcsr = hypre_ParCSRMatrixClone(parcsr,1); 16746ea7df73SStefano Zampini #endif 167545b8d346SStefano Zampini parcsr = new_parcsr; 167645b8d346SStefano Zampini copymode = PETSC_OWN_POINTER; 167745b8d346SStefano Zampini } 1678978814f1SStefano Zampini 1679978814f1SStefano Zampini /* set ParCSR object */ 1680978814f1SStefano Zampini hypre_IJMatrixObject(hA->ij) = parcsr; 16814ec6421dSstefano_zampini T->preallocated = PETSC_TRUE; 1682978814f1SStefano Zampini 1683978814f1SStefano Zampini /* set assembled flag */ 1684978814f1SStefano Zampini hypre_IJMatrixAssembleFlag(hA->ij) = 1; 16856ea7df73SStefano Zampini #if 0 1686978814f1SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixInitialize,(hA->ij)); 16876ea7df73SStefano Zampini #endif 1688225daaf8SStefano Zampini if (ishyp) { 16896d2a658fSstefano_zampini PetscMPIInt myid = 0; 16906d2a658fSstefano_zampini 16916d2a658fSstefano_zampini /* make sure we always have row_starts and col_starts available */ 16926d2a658fSstefano_zampini if (HYPRE_AssumedPartitionCheck()) { 1693ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm,&myid);CHKERRMPI(ierr); 16946d2a658fSstefano_zampini } 1695a1d2239cSSatish Balay #if defined(hypre_ParCSRMatrixOwnsRowStarts) 16966d2a658fSstefano_zampini if (!hypre_ParCSRMatrixOwnsColStarts(parcsr)) { 16976d2a658fSstefano_zampini PetscLayout map; 16986d2a658fSstefano_zampini 16996d2a658fSstefano_zampini ierr = MatGetLayouts(T,NULL,&map);CHKERRQ(ierr); 17006d2a658fSstefano_zampini ierr = PetscLayoutSetUp(map);CHKERRQ(ierr); 17012cf14000SStefano Zampini hypre_ParCSRMatrixColStarts(parcsr) = (HYPRE_BigInt*)(map->range + myid); 17026d2a658fSstefano_zampini } 17036d2a658fSstefano_zampini if (!hypre_ParCSRMatrixOwnsRowStarts(parcsr)) { 17046d2a658fSstefano_zampini PetscLayout map; 17056d2a658fSstefano_zampini 17066d2a658fSstefano_zampini ierr = MatGetLayouts(T,&map,NULL);CHKERRQ(ierr); 17076d2a658fSstefano_zampini ierr = PetscLayoutSetUp(map);CHKERRQ(ierr); 17082cf14000SStefano Zampini hypre_ParCSRMatrixRowStarts(parcsr) = (HYPRE_BigInt*)(map->range + myid); 17096d2a658fSstefano_zampini } 1710a1d2239cSSatish Balay #endif 1711978814f1SStefano Zampini /* prevent from freeing the pointer */ 1712978814f1SStefano Zampini if (copymode == PETSC_USE_POINTER) hA->inner_free = PETSC_FALSE; 1713225daaf8SStefano Zampini *A = T; 17146ea7df73SStefano Zampini ierr = MatSetOption(*A,MAT_SORTED_FULL,PETSC_TRUE);CHKERRQ(ierr); 1715978814f1SStefano Zampini ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1716978814f1SStefano Zampini ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1717bb4689ddSStefano Zampini } else if (isaij) { 1718bb4689ddSStefano Zampini if (copymode != PETSC_OWN_POINTER) { 1719225daaf8SStefano Zampini /* prevent from freeing the pointer */ 1720225daaf8SStefano Zampini hA->inner_free = PETSC_FALSE; 1721225daaf8SStefano Zampini ierr = MatConvert_HYPRE_AIJ(T,MATAIJ,MAT_INITIAL_MATRIX,A);CHKERRQ(ierr); 1722225daaf8SStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 1723225daaf8SStefano Zampini } else { /* AIJ return type with PETSC_OWN_POINTER */ 1724225daaf8SStefano Zampini ierr = MatConvert_HYPRE_AIJ(T,MATAIJ,MAT_INPLACE_MATRIX,&T);CHKERRQ(ierr); 1725225daaf8SStefano Zampini *A = T; 1726225daaf8SStefano Zampini } 1727bb4689ddSStefano Zampini } else if (isis) { 17288cfe8d00SStefano Zampini ierr = MatConvert_HYPRE_IS(T,MATIS,MAT_INITIAL_MATRIX,A);CHKERRQ(ierr); 17298cfe8d00SStefano Zampini if (copymode != PETSC_OWN_POINTER) hA->inner_free = PETSC_FALSE; 1730bb4689ddSStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 1731bb4689ddSStefano Zampini } 1732978814f1SStefano Zampini PetscFunctionReturn(0); 1733978814f1SStefano Zampini } 1734978814f1SStefano Zampini 173568ec7858SStefano Zampini static PetscErrorCode MatHYPREGetParCSR_HYPRE(Mat A, hypre_ParCSRMatrix **parcsr) 1736dd9c0a25Sstefano_zampini { 1737dd9c0a25Sstefano_zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 1738dd9c0a25Sstefano_zampini HYPRE_Int type; 1739dd9c0a25Sstefano_zampini 1740dd9c0a25Sstefano_zampini PetscFunctionBegin; 1741dd9c0a25Sstefano_zampini if (!hA->ij) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"HYPRE_IJMatrix not present"); 1742dd9c0a25Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(hA->ij,&type)); 1743dd9c0a25Sstefano_zampini if (type != HYPRE_PARCSR) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"HYPRE_IJMatrix is not of type HYPRE_PARCSR"); 1744dd9c0a25Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hA->ij,(void**)parcsr)); 1745dd9c0a25Sstefano_zampini PetscFunctionReturn(0); 1746dd9c0a25Sstefano_zampini } 1747dd9c0a25Sstefano_zampini 1748dd9c0a25Sstefano_zampini /* 1749dd9c0a25Sstefano_zampini MatHYPREGetParCSR - Gets the pointer to the ParCSR matrix 1750dd9c0a25Sstefano_zampini 1751dd9c0a25Sstefano_zampini Not collective 1752dd9c0a25Sstefano_zampini 1753dd9c0a25Sstefano_zampini Input Parameters: 1754dd9c0a25Sstefano_zampini + A - the MATHYPRE object 1755dd9c0a25Sstefano_zampini 1756dd9c0a25Sstefano_zampini Output Parameter: 1757dd9c0a25Sstefano_zampini . parcsr - the pointer to the hypre_ParCSRMatrix 1758dd9c0a25Sstefano_zampini 1759dd9c0a25Sstefano_zampini Level: intermediate 1760dd9c0a25Sstefano_zampini 1761dd9c0a25Sstefano_zampini .seealso: MatHYPRE, PetscCopyMode 1762dd9c0a25Sstefano_zampini */ 1763dd9c0a25Sstefano_zampini PetscErrorCode MatHYPREGetParCSR(Mat A, hypre_ParCSRMatrix **parcsr) 1764dd9c0a25Sstefano_zampini { 1765dd9c0a25Sstefano_zampini PetscErrorCode ierr; 1766dd9c0a25Sstefano_zampini 1767dd9c0a25Sstefano_zampini PetscFunctionBegin; 1768dd9c0a25Sstefano_zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 1769dd9c0a25Sstefano_zampini PetscValidType(A,1); 1770dd9c0a25Sstefano_zampini ierr = PetscUseMethod(A,"MatHYPREGetParCSR_C",(Mat,hypre_ParCSRMatrix**),(A,parcsr));CHKERRQ(ierr); 1771dd9c0a25Sstefano_zampini PetscFunctionReturn(0); 1772dd9c0a25Sstefano_zampini } 1773dd9c0a25Sstefano_zampini 177468ec7858SStefano Zampini static PetscErrorCode MatMissingDiagonal_HYPRE(Mat A, PetscBool *missing, PetscInt *dd) 177568ec7858SStefano Zampini { 177668ec7858SStefano Zampini hypre_ParCSRMatrix *parcsr; 177768ec7858SStefano Zampini hypre_CSRMatrix *ha; 177868ec7858SStefano Zampini PetscInt rst; 177968ec7858SStefano Zampini PetscErrorCode ierr; 178068ec7858SStefano Zampini 178168ec7858SStefano Zampini PetscFunctionBegin; 178268ec7858SStefano Zampini if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented with non-square diagonal blocks"); 178368ec7858SStefano Zampini ierr = MatGetOwnershipRange(A,&rst,NULL);CHKERRQ(ierr); 178468ec7858SStefano Zampini ierr = MatHYPREGetParCSR_HYPRE(A,&parcsr);CHKERRQ(ierr); 178568ec7858SStefano Zampini if (missing) *missing = PETSC_FALSE; 178668ec7858SStefano Zampini if (dd) *dd = -1; 178768ec7858SStefano Zampini ha = hypre_ParCSRMatrixDiag(parcsr); 178868ec7858SStefano Zampini if (ha) { 178968299464SStefano Zampini PetscInt size,i; 179068299464SStefano Zampini HYPRE_Int *ii,*jj; 179168ec7858SStefano Zampini 179268ec7858SStefano Zampini size = hypre_CSRMatrixNumRows(ha); 179368ec7858SStefano Zampini ii = hypre_CSRMatrixI(ha); 179468ec7858SStefano Zampini jj = hypre_CSRMatrixJ(ha); 179568ec7858SStefano Zampini for (i = 0; i < size; i++) { 179668ec7858SStefano Zampini PetscInt j; 179768ec7858SStefano Zampini PetscBool found = PETSC_FALSE; 179868ec7858SStefano Zampini 179968ec7858SStefano Zampini for (j = ii[i]; j < ii[i+1] && !found; j++) 180068ec7858SStefano Zampini found = (jj[j] == i) ? PETSC_TRUE : PETSC_FALSE; 180168ec7858SStefano Zampini 180268ec7858SStefano Zampini if (!found) { 180368ec7858SStefano Zampini PetscInfo1(A,"Matrix is missing local diagonal entry %D\n",i); 180468ec7858SStefano Zampini if (missing) *missing = PETSC_TRUE; 180568ec7858SStefano Zampini if (dd) *dd = i+rst; 180668ec7858SStefano Zampini PetscFunctionReturn(0); 180768ec7858SStefano Zampini } 180868ec7858SStefano Zampini } 180968ec7858SStefano Zampini if (!size) { 181068ec7858SStefano Zampini PetscInfo(A,"Matrix has no diagonal entries therefore is missing diagonal\n"); 181168ec7858SStefano Zampini if (missing) *missing = PETSC_TRUE; 181268ec7858SStefano Zampini if (dd) *dd = rst; 181368ec7858SStefano Zampini } 181468ec7858SStefano Zampini } else { 181568ec7858SStefano Zampini PetscInfo(A,"Matrix has no diagonal entries therefore is missing diagonal\n"); 181668ec7858SStefano Zampini if (missing) *missing = PETSC_TRUE; 181768ec7858SStefano Zampini if (dd) *dd = rst; 181868ec7858SStefano Zampini } 181968ec7858SStefano Zampini PetscFunctionReturn(0); 182068ec7858SStefano Zampini } 182168ec7858SStefano Zampini 182268ec7858SStefano Zampini static PetscErrorCode MatScale_HYPRE(Mat A, PetscScalar s) 182368ec7858SStefano Zampini { 182468ec7858SStefano Zampini hypre_ParCSRMatrix *parcsr; 18256ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_LT(2,19,0) 182668ec7858SStefano Zampini hypre_CSRMatrix *ha; 18276ea7df73SStefano Zampini #endif 182868ec7858SStefano Zampini PetscErrorCode ierr; 182939accc25SStefano Zampini HYPRE_Complex hs; 183068ec7858SStefano Zampini 183168ec7858SStefano Zampini PetscFunctionBegin; 183239accc25SStefano Zampini ierr = PetscHYPREScalarCast(s,&hs);CHKERRQ(ierr); 183368ec7858SStefano Zampini ierr = MatHYPREGetParCSR_HYPRE(A,&parcsr);CHKERRQ(ierr); 18346ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2,19,0) 18356ea7df73SStefano Zampini PetscStackCallStandard(hypre_ParCSRMatrixScale,(parcsr,hs)); 18366ea7df73SStefano Zampini #else /* diagonal part */ 183768ec7858SStefano Zampini ha = hypre_ParCSRMatrixDiag(parcsr); 183868ec7858SStefano Zampini if (ha) { 183968299464SStefano Zampini PetscInt size,i; 184068299464SStefano Zampini HYPRE_Int *ii; 184139accc25SStefano Zampini HYPRE_Complex *a; 184268ec7858SStefano Zampini 184368ec7858SStefano Zampini size = hypre_CSRMatrixNumRows(ha); 184468ec7858SStefano Zampini a = hypre_CSRMatrixData(ha); 184568ec7858SStefano Zampini ii = hypre_CSRMatrixI(ha); 184639accc25SStefano Zampini for (i = 0; i < ii[size]; i++) a[i] *= hs; 184768ec7858SStefano Zampini } 184868ec7858SStefano Zampini /* offdiagonal part */ 184968ec7858SStefano Zampini ha = hypre_ParCSRMatrixOffd(parcsr); 185068ec7858SStefano Zampini if (ha) { 185168299464SStefano Zampini PetscInt size,i; 185268299464SStefano Zampini HYPRE_Int *ii; 185339accc25SStefano Zampini HYPRE_Complex *a; 185468ec7858SStefano Zampini 185568ec7858SStefano Zampini size = hypre_CSRMatrixNumRows(ha); 185668ec7858SStefano Zampini a = hypre_CSRMatrixData(ha); 185768ec7858SStefano Zampini ii = hypre_CSRMatrixI(ha); 185839accc25SStefano Zampini for (i = 0; i < ii[size]; i++) a[i] *= hs; 185968ec7858SStefano Zampini } 18606ea7df73SStefano Zampini #endif 186168ec7858SStefano Zampini PetscFunctionReturn(0); 186268ec7858SStefano Zampini } 186368ec7858SStefano Zampini 186468ec7858SStefano Zampini static PetscErrorCode MatZeroRowsColumns_HYPRE(Mat A, PetscInt numRows, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) 186568ec7858SStefano Zampini { 186668ec7858SStefano Zampini hypre_ParCSRMatrix *parcsr; 186768299464SStefano Zampini HYPRE_Int *lrows; 186868299464SStefano Zampini PetscInt rst,ren,i; 186968ec7858SStefano Zampini PetscErrorCode ierr; 187068ec7858SStefano Zampini 187168ec7858SStefano Zampini PetscFunctionBegin; 187268ec7858SStefano Zampini if (x || b) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"To be implemented"); 187368ec7858SStefano Zampini ierr = MatHYPREGetParCSR_HYPRE(A,&parcsr);CHKERRQ(ierr); 187468ec7858SStefano Zampini ierr = PetscMalloc1(numRows,&lrows);CHKERRQ(ierr); 187568ec7858SStefano Zampini ierr = MatGetOwnershipRange(A,&rst,&ren);CHKERRQ(ierr); 187668ec7858SStefano Zampini for (i=0;i<numRows;i++) { 187768ec7858SStefano Zampini if (rows[i] < rst || rows[i] >= ren) 187868ec7858SStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Non-local rows not yet supported"); 187968ec7858SStefano Zampini lrows[i] = rows[i] - rst; 188068ec7858SStefano Zampini } 188168ec7858SStefano Zampini PetscStackCallStandard(hypre_ParCSRMatrixEliminateRowsCols,(parcsr,numRows,lrows)); 188268ec7858SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 188368ec7858SStefano Zampini PetscFunctionReturn(0); 188468ec7858SStefano Zampini } 188568ec7858SStefano Zampini 1886c69f721fSFande Kong static PetscErrorCode MatZeroEntries_HYPRE_CSRMatrix(hypre_CSRMatrix *ha) 1887c69f721fSFande Kong { 1888c69f721fSFande Kong PetscErrorCode ierr; 1889c69f721fSFande Kong 1890c69f721fSFande Kong PetscFunctionBegin; 1891c69f721fSFande Kong if (ha) { 1892c69f721fSFande Kong HYPRE_Int *ii, size; 1893c69f721fSFande Kong HYPRE_Complex *a; 1894c69f721fSFande Kong 1895c69f721fSFande Kong size = hypre_CSRMatrixNumRows(ha); 1896c69f721fSFande Kong a = hypre_CSRMatrixData(ha); 1897c69f721fSFande Kong ii = hypre_CSRMatrixI(ha); 1898c69f721fSFande Kong 1899580bdb30SBarry Smith if (a) {ierr = PetscArrayzero(a,ii[size]);CHKERRQ(ierr);} 1900c69f721fSFande Kong } 1901c69f721fSFande Kong PetscFunctionReturn(0); 1902c69f721fSFande Kong } 1903c69f721fSFande Kong 1904c69f721fSFande Kong PetscErrorCode MatZeroEntries_HYPRE(Mat A) 1905c69f721fSFande Kong { 19066ea7df73SStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 19076ea7df73SStefano Zampini 19086ea7df73SStefano Zampini PetscFunctionBegin; 19096ea7df73SStefano Zampini if (HYPRE_MEMORY_DEVICE == hypre_IJMatrixMemoryLocation(hA->ij)) { 19106ea7df73SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixSetConstantValues,(hA->ij,0.0)); 19116ea7df73SStefano Zampini } else { 1912c69f721fSFande Kong hypre_ParCSRMatrix *parcsr; 1913c69f721fSFande Kong PetscErrorCode ierr; 1914c69f721fSFande Kong 1915c69f721fSFande Kong ierr = MatHYPREGetParCSR_HYPRE(A,&parcsr);CHKERRQ(ierr); 1916c69f721fSFande Kong ierr = MatZeroEntries_HYPRE_CSRMatrix(hypre_ParCSRMatrixDiag(parcsr));CHKERRQ(ierr); 1917c69f721fSFande Kong ierr = MatZeroEntries_HYPRE_CSRMatrix(hypre_ParCSRMatrixOffd(parcsr));CHKERRQ(ierr); 19186ea7df73SStefano Zampini } 1919c69f721fSFande Kong PetscFunctionReturn(0); 1920c69f721fSFande Kong } 1921c69f721fSFande Kong 192239accc25SStefano Zampini static PetscErrorCode MatZeroRows_HYPRE_CSRMatrix(hypre_CSRMatrix *hA,PetscInt N,const PetscInt rows[],HYPRE_Complex diag) 1923c69f721fSFande Kong { 192439accc25SStefano Zampini PetscInt ii; 192539accc25SStefano Zampini HYPRE_Int *i, *j; 192639accc25SStefano Zampini HYPRE_Complex *a; 1927c69f721fSFande Kong 1928c69f721fSFande Kong PetscFunctionBegin; 1929c69f721fSFande Kong if (!hA) PetscFunctionReturn(0); 1930c69f721fSFande Kong 193139accc25SStefano Zampini i = hypre_CSRMatrixI(hA); 193239accc25SStefano Zampini j = hypre_CSRMatrixJ(hA); 1933c69f721fSFande Kong a = hypre_CSRMatrixData(hA); 1934c69f721fSFande Kong 1935c69f721fSFande Kong for (ii = 0; ii < N; ii++) { 193639accc25SStefano Zampini HYPRE_Int jj, ibeg, iend, irow; 193739accc25SStefano Zampini 1938c69f721fSFande Kong irow = rows[ii]; 1939c69f721fSFande Kong ibeg = i[irow]; 1940c69f721fSFande Kong iend = i[irow+1]; 1941c69f721fSFande Kong for (jj = ibeg; jj < iend; jj++) 1942c69f721fSFande Kong if (j[jj] == irow) a[jj] = diag; 1943c69f721fSFande Kong else a[jj] = 0.0; 1944c69f721fSFande Kong } 1945c69f721fSFande Kong PetscFunctionReturn(0); 1946c69f721fSFande Kong } 1947c69f721fSFande Kong 1948ddbeb582SStefano Zampini static PetscErrorCode MatZeroRows_HYPRE(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 1949c69f721fSFande Kong { 1950c69f721fSFande Kong hypre_ParCSRMatrix *parcsr; 1951c69f721fSFande Kong PetscInt *lrows,len; 195239accc25SStefano Zampini HYPRE_Complex hdiag; 1953c69f721fSFande Kong PetscErrorCode ierr; 1954c69f721fSFande Kong 1955c69f721fSFande Kong PetscFunctionBegin; 1956c6698e78SStefano Zampini if (x || b) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Does not support to modify the solution and the right hand size"); 195739accc25SStefano Zampini ierr = PetscHYPREScalarCast(diag,&hdiag);CHKERRQ(ierr); 1958c69f721fSFande Kong /* retrieve the internal matrix */ 1959c69f721fSFande Kong ierr = MatHYPREGetParCSR_HYPRE(A,&parcsr);CHKERRQ(ierr); 1960c69f721fSFande Kong /* get locally owned rows */ 1961c69f721fSFande Kong ierr = MatZeroRowsMapLocal_Private(A,N,rows,&len,&lrows);CHKERRQ(ierr); 1962c69f721fSFande Kong /* zero diagonal part */ 196339accc25SStefano Zampini ierr = MatZeroRows_HYPRE_CSRMatrix(hypre_ParCSRMatrixDiag(parcsr),len,lrows,hdiag);CHKERRQ(ierr); 1964c69f721fSFande Kong /* zero off-diagonal part */ 1965c69f721fSFande Kong ierr = MatZeroRows_HYPRE_CSRMatrix(hypre_ParCSRMatrixOffd(parcsr),len,lrows,0.0);CHKERRQ(ierr); 1966c69f721fSFande Kong 1967c69f721fSFande Kong ierr = PetscFree(lrows);CHKERRQ(ierr); 1968c69f721fSFande Kong PetscFunctionReturn(0); 1969c69f721fSFande Kong } 1970c69f721fSFande Kong 1971ddbeb582SStefano Zampini static PetscErrorCode MatAssemblyBegin_HYPRE(Mat mat,MatAssemblyType mode) 1972c69f721fSFande Kong { 1973c69f721fSFande Kong PetscErrorCode ierr; 1974c69f721fSFande Kong 1975c69f721fSFande Kong PetscFunctionBegin; 1976c69f721fSFande Kong if (mat->nooffprocentries) PetscFunctionReturn(0); 1977c69f721fSFande Kong 1978c69f721fSFande Kong ierr = MatStashScatterBegin_Private(mat,&mat->stash,mat->rmap->range);CHKERRQ(ierr); 1979c69f721fSFande Kong PetscFunctionReturn(0); 1980c69f721fSFande Kong } 1981c69f721fSFande Kong 1982ddbeb582SStefano Zampini static PetscErrorCode MatGetRow_HYPRE(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 1983c69f721fSFande Kong { 1984c69f721fSFande Kong hypre_ParCSRMatrix *parcsr; 19852cf14000SStefano Zampini HYPRE_Int hnz; 1986c69f721fSFande Kong PetscErrorCode ierr; 1987c69f721fSFande Kong 1988c69f721fSFande Kong PetscFunctionBegin; 1989c69f721fSFande Kong /* retrieve the internal matrix */ 1990c69f721fSFande Kong ierr = MatHYPREGetParCSR_HYPRE(A,&parcsr);CHKERRQ(ierr); 1991c69f721fSFande Kong /* call HYPRE API */ 199239accc25SStefano Zampini PetscStackCallStandard(HYPRE_ParCSRMatrixGetRow,(parcsr,row,&hnz,(HYPRE_BigInt**)idx,(HYPRE_Complex**)v)); 19932cf14000SStefano Zampini if (nz) *nz = (PetscInt)hnz; 1994c69f721fSFande Kong PetscFunctionReturn(0); 1995c69f721fSFande Kong } 1996c69f721fSFande Kong 1997ddbeb582SStefano Zampini static PetscErrorCode MatRestoreRow_HYPRE(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 1998c69f721fSFande Kong { 1999c69f721fSFande Kong hypre_ParCSRMatrix *parcsr; 20002cf14000SStefano Zampini HYPRE_Int hnz; 2001c69f721fSFande Kong PetscErrorCode ierr; 2002c69f721fSFande Kong 2003c69f721fSFande Kong PetscFunctionBegin; 2004c69f721fSFande Kong /* retrieve the internal matrix */ 2005c69f721fSFande Kong ierr = MatHYPREGetParCSR_HYPRE(A,&parcsr);CHKERRQ(ierr); 2006c69f721fSFande Kong /* call HYPRE API */ 20072cf14000SStefano Zampini hnz = nz ? (HYPRE_Int)(*nz) : 0; 200839accc25SStefano Zampini PetscStackCallStandard(HYPRE_ParCSRMatrixRestoreRow,(parcsr,row,&hnz,(HYPRE_BigInt**)idx,(HYPRE_Complex**)v)); 2009c69f721fSFande Kong PetscFunctionReturn(0); 2010c69f721fSFande Kong } 2011c69f721fSFande Kong 2012ddbeb582SStefano Zampini static PetscErrorCode MatGetValues_HYPRE(Mat A,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[]) 2013c69f721fSFande Kong { 201445b8d346SStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 2015c69f721fSFande Kong PetscInt i; 20161d4906efSStefano Zampini 2017c69f721fSFande Kong PetscFunctionBegin; 2018c69f721fSFande Kong if (!m || !n) PetscFunctionReturn(0); 2019c69f721fSFande Kong /* Ignore negative row indices 2020c69f721fSFande Kong * And negative column indices should be automatically ignored in hypre 2021c69f721fSFande Kong * */ 20222cf14000SStefano Zampini for (i=0; i<m; i++) { 20232cf14000SStefano Zampini if (idxm[i] >= 0) { 20242cf14000SStefano Zampini HYPRE_Int hn = (HYPRE_Int)n; 202539accc25SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetValues,(hA->ij,1,&hn,(HYPRE_BigInt*)&idxm[i],(HYPRE_BigInt*)idxn,(HYPRE_Complex*)(v + i*n))); 20262cf14000SStefano Zampini } 20272cf14000SStefano Zampini } 2028c69f721fSFande Kong PetscFunctionReturn(0); 2029c69f721fSFande Kong } 2030c69f721fSFande Kong 2031ddbeb582SStefano Zampini static PetscErrorCode MatSetOption_HYPRE(Mat A,MatOption op,PetscBool flg) 2032ddbeb582SStefano Zampini { 2033ddbeb582SStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 2034ddbeb582SStefano Zampini 2035ddbeb582SStefano Zampini PetscFunctionBegin; 2036c6698e78SStefano Zampini switch (op) { 2037ddbeb582SStefano Zampini case MAT_NO_OFF_PROC_ENTRIES: 2038ddbeb582SStefano Zampini if (flg) { 2039ddbeb582SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixSetMaxOffProcElmts,(hA->ij,0)); 2040ddbeb582SStefano Zampini } 2041ddbeb582SStefano Zampini break; 2042336664bdSPierre Jolivet case MAT_SORTED_FULL: 2043336664bdSPierre Jolivet hA->sorted_full = flg; 2044336664bdSPierre Jolivet break; 2045ddbeb582SStefano Zampini default: 2046ddbeb582SStefano Zampini break; 2047ddbeb582SStefano Zampini } 2048ddbeb582SStefano Zampini PetscFunctionReturn(0); 2049ddbeb582SStefano Zampini } 2050c69f721fSFande Kong 205145b8d346SStefano Zampini static PetscErrorCode MatView_HYPRE(Mat A, PetscViewer view) 205245b8d346SStefano Zampini { 205345b8d346SStefano Zampini PetscErrorCode ierr; 205445b8d346SStefano Zampini PetscViewerFormat format; 205545b8d346SStefano Zampini 205645b8d346SStefano Zampini PetscFunctionBegin; 205745b8d346SStefano Zampini ierr = PetscViewerGetFormat(view,&format);CHKERRQ(ierr); 20586ea7df73SStefano Zampini if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) PetscFunctionReturn(0); 205945b8d346SStefano Zampini if (format != PETSC_VIEWER_NATIVE) { 20606ea7df73SStefano Zampini Mat B; 20616ea7df73SStefano Zampini hypre_ParCSRMatrix *parcsr; 20626ea7df73SStefano Zampini PetscErrorCode (*mview)(Mat,PetscViewer) = NULL; 20636ea7df73SStefano Zampini 206445b8d346SStefano Zampini ierr = MatHYPREGetParCSR_HYPRE(A,&parcsr);CHKERRQ(ierr); 206545b8d346SStefano Zampini ierr = MatCreateFromParCSR(parcsr,MATAIJ,PETSC_USE_POINTER,&B);CHKERRQ(ierr); 206645b8d346SStefano Zampini ierr = MatGetOperation(B,MATOP_VIEW,(void(**)(void))&mview);CHKERRQ(ierr); 20672758c9b9SBarry Smith if (!mview) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Missing view operation"); 206845b8d346SStefano Zampini ierr = (*mview)(B,view);CHKERRQ(ierr); 206945b8d346SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 207045b8d346SStefano Zampini } else { 207145b8d346SStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 207245b8d346SStefano Zampini PetscMPIInt size; 207345b8d346SStefano Zampini PetscBool isascii; 207445b8d346SStefano Zampini const char *filename; 207545b8d346SStefano Zampini 207645b8d346SStefano Zampini /* HYPRE uses only text files */ 207745b8d346SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)view,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 207845b8d346SStefano Zampini if (!isascii) SETERRQ1(PetscObjectComm((PetscObject)view),PETSC_ERR_SUP,"PetscViewerType %s: native HYPRE format needs PETSCVIEWERASCII",((PetscObject)view)->type_name); 207945b8d346SStefano Zampini ierr = PetscViewerFileGetName(view,&filename);CHKERRQ(ierr); 208045b8d346SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixPrint,(hA->ij,filename)); 2081ffc4695bSBarry Smith ierr = MPI_Comm_size(hA->comm,&size);CHKERRMPI(ierr); 208245b8d346SStefano Zampini if (size > 1) { 208345b8d346SStefano Zampini ierr = PetscViewerASCIIPrintf(view,"Matrix files: %s.%05d ... %s.%05d\n",filename,0,filename,size-1);CHKERRQ(ierr); 208445b8d346SStefano Zampini } else { 208545b8d346SStefano Zampini ierr = PetscViewerASCIIPrintf(view,"Matrix file: %s.%05d\n",filename,0);CHKERRQ(ierr); 208645b8d346SStefano Zampini } 208745b8d346SStefano Zampini } 208845b8d346SStefano Zampini PetscFunctionReturn(0); 208945b8d346SStefano Zampini } 209045b8d346SStefano Zampini 209145b8d346SStefano Zampini static PetscErrorCode MatDuplicate_HYPRE(Mat A,MatDuplicateOption op, Mat *B) 209245b8d346SStefano Zampini { 20936abb4441SStefano Zampini hypre_ParCSRMatrix *parcsr = NULL; 209445b8d346SStefano Zampini PetscErrorCode ierr; 209545b8d346SStefano Zampini PetscCopyMode cpmode; 209645b8d346SStefano Zampini 209745b8d346SStefano Zampini PetscFunctionBegin; 209845b8d346SStefano Zampini ierr = MatHYPREGetParCSR_HYPRE(A,&parcsr);CHKERRQ(ierr); 209945b8d346SStefano Zampini if (op == MAT_DO_NOT_COPY_VALUES || op == MAT_SHARE_NONZERO_PATTERN) { 21000e6427aaSSatish Balay parcsr = hypre_ParCSRMatrixClone(parcsr,0); 210145b8d346SStefano Zampini cpmode = PETSC_OWN_POINTER; 210245b8d346SStefano Zampini } else { 210345b8d346SStefano Zampini cpmode = PETSC_COPY_VALUES; 210445b8d346SStefano Zampini } 210545b8d346SStefano Zampini ierr = MatCreateFromParCSR(parcsr,MATHYPRE,cpmode,B);CHKERRQ(ierr); 210645b8d346SStefano Zampini PetscFunctionReturn(0); 210745b8d346SStefano Zampini } 210845b8d346SStefano Zampini 2109465edc17SStefano Zampini static PetscErrorCode MatCopy_HYPRE(Mat A, Mat B, MatStructure str) 2110465edc17SStefano Zampini { 2111465edc17SStefano Zampini hypre_ParCSRMatrix *acsr,*bcsr; 2112465edc17SStefano Zampini PetscErrorCode ierr; 2113465edc17SStefano Zampini 2114465edc17SStefano Zampini PetscFunctionBegin; 2115465edc17SStefano Zampini if (str == SAME_NONZERO_PATTERN && A->ops->copy == B->ops->copy) { 2116465edc17SStefano Zampini ierr = MatHYPREGetParCSR_HYPRE(A,&acsr);CHKERRQ(ierr); 2117465edc17SStefano Zampini ierr = MatHYPREGetParCSR_HYPRE(B,&bcsr);CHKERRQ(ierr); 2118465edc17SStefano Zampini PetscStackCallStandard(hypre_ParCSRMatrixCopy,(acsr,bcsr,1)); 21191e1ea65dSPierre Jolivet ierr = MatSetOption(B,MAT_SORTED_FULL,PETSC_TRUE);CHKERRQ(ierr); /* "perfect" preallocation, so no need for hypre_AuxParCSRMatrixNeedAux */ 2120465edc17SStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2121465edc17SStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2122465edc17SStefano Zampini } else { 2123465edc17SStefano Zampini ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 2124465edc17SStefano Zampini } 2125465edc17SStefano Zampini PetscFunctionReturn(0); 2126465edc17SStefano Zampini } 2127465edc17SStefano Zampini 21286305df00SStefano Zampini static PetscErrorCode MatGetDiagonal_HYPRE(Mat A, Vec d) 21296305df00SStefano Zampini { 21306305df00SStefano Zampini hypre_ParCSRMatrix *parcsr; 21316305df00SStefano Zampini hypre_CSRMatrix *dmat; 213239accc25SStefano Zampini HYPRE_Complex *a; 213339accc25SStefano Zampini HYPRE_Complex *data = NULL; 21342cf14000SStefano Zampini HYPRE_Int *diag = NULL; 21352cf14000SStefano Zampini PetscInt i; 21366305df00SStefano Zampini PetscBool cong; 21376305df00SStefano Zampini PetscErrorCode ierr; 21386305df00SStefano Zampini 21396305df00SStefano Zampini PetscFunctionBegin; 21406305df00SStefano Zampini ierr = MatHasCongruentLayouts(A,&cong);CHKERRQ(ierr); 21416305df00SStefano Zampini if (!cong) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Only for square matrices with same local distributions of rows and columns"); 214276bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 21436305df00SStefano Zampini PetscBool miss; 21446305df00SStefano Zampini ierr = MatMissingDiagonal(A,&miss,NULL);CHKERRQ(ierr); 21456305df00SStefano Zampini if (miss && A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented when diagonal entries are missing"); 21466305df00SStefano Zampini } 21476305df00SStefano Zampini ierr = MatHYPREGetParCSR_HYPRE(A,&parcsr);CHKERRQ(ierr); 21486305df00SStefano Zampini dmat = hypre_ParCSRMatrixDiag(parcsr); 21496305df00SStefano Zampini if (dmat) { 215039accc25SStefano Zampini /* this cast fixes the clang error: implicit conversion from 'HYPRE_Complex' (aka '_Complex double') to 'double' is not permitted in C++ */ 215139accc25SStefano Zampini ierr = VecGetArray(d,(PetscScalar**)&a);CHKERRQ(ierr); 21522cf14000SStefano Zampini diag = hypre_CSRMatrixI(dmat); 215339accc25SStefano Zampini data = hypre_CSRMatrixData(dmat); 21546305df00SStefano Zampini for (i=0;i<A->rmap->n;i++) a[i] = data[diag[i]]; 215539accc25SStefano Zampini ierr = VecRestoreArray(d,(PetscScalar**)&a);CHKERRQ(ierr); 21566305df00SStefano Zampini } 21576305df00SStefano Zampini PetscFunctionReturn(0); 21586305df00SStefano Zampini } 21596305df00SStefano Zampini 2160363d496dSStefano Zampini #include <petscblaslapack.h> 2161363d496dSStefano Zampini 2162363d496dSStefano Zampini static PetscErrorCode MatAXPY_HYPRE(Mat Y,PetscScalar a,Mat X,MatStructure str) 2163363d496dSStefano Zampini { 2164363d496dSStefano Zampini PetscErrorCode ierr; 2165363d496dSStefano Zampini 2166363d496dSStefano Zampini PetscFunctionBegin; 21676ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 21686ea7df73SStefano Zampini { 21696ea7df73SStefano Zampini Mat B; 21706ea7df73SStefano Zampini hypre_ParCSRMatrix *x,*y,*z; 21716ea7df73SStefano Zampini 21726ea7df73SStefano Zampini ierr = MatHYPREGetParCSR(Y,&y);CHKERRQ(ierr); 21736ea7df73SStefano Zampini ierr = MatHYPREGetParCSR(X,&x);CHKERRQ(ierr); 21746ea7df73SStefano Zampini PetscStackCallStandard(hypre_ParCSRMatrixAdd,(1.0,y,1.0,x,&z)); 21756ea7df73SStefano Zampini ierr = MatCreateFromParCSR(z,MATHYPRE,PETSC_OWN_POINTER,&B);CHKERRQ(ierr); 21766ea7df73SStefano Zampini ierr = MatHeaderMerge(Y,&B);CHKERRQ(ierr); 21776ea7df73SStefano Zampini } 21786ea7df73SStefano Zampini #else 2179363d496dSStefano Zampini if (str == SAME_NONZERO_PATTERN) { 2180363d496dSStefano Zampini hypre_ParCSRMatrix *x,*y; 2181363d496dSStefano Zampini hypre_CSRMatrix *xloc,*yloc; 2182363d496dSStefano Zampini PetscInt xnnz,ynnz; 218339accc25SStefano Zampini HYPRE_Complex *xarr,*yarr; 2184363d496dSStefano Zampini PetscBLASInt one=1,bnz; 2185363d496dSStefano Zampini 2186363d496dSStefano Zampini ierr = MatHYPREGetParCSR(Y,&y);CHKERRQ(ierr); 2187363d496dSStefano Zampini ierr = MatHYPREGetParCSR(X,&x);CHKERRQ(ierr); 2188363d496dSStefano Zampini 2189363d496dSStefano Zampini /* diagonal block */ 2190363d496dSStefano Zampini xloc = hypre_ParCSRMatrixDiag(x); 2191363d496dSStefano Zampini yloc = hypre_ParCSRMatrixDiag(y); 2192363d496dSStefano Zampini xnnz = 0; 2193363d496dSStefano Zampini ynnz = 0; 2194363d496dSStefano Zampini xarr = NULL; 2195363d496dSStefano Zampini yarr = NULL; 2196363d496dSStefano Zampini if (xloc) { 219739accc25SStefano Zampini xarr = hypre_CSRMatrixData(xloc); 2198363d496dSStefano Zampini xnnz = hypre_CSRMatrixNumNonzeros(xloc); 2199363d496dSStefano Zampini } 2200363d496dSStefano Zampini if (yloc) { 220139accc25SStefano Zampini yarr = hypre_CSRMatrixData(yloc); 2202363d496dSStefano Zampini ynnz = hypre_CSRMatrixNumNonzeros(yloc); 2203363d496dSStefano Zampini } 2204363d496dSStefano Zampini if (xnnz != ynnz) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Different number of nonzeros in diagonal block %D != %D",xnnz,ynnz); 2205363d496dSStefano Zampini ierr = PetscBLASIntCast(xnnz,&bnz);CHKERRQ(ierr); 220639accc25SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&a,(PetscScalar*)xarr,&one,(PetscScalar*)yarr,&one)); 2207363d496dSStefano Zampini 2208363d496dSStefano Zampini /* off-diagonal block */ 2209363d496dSStefano Zampini xloc = hypre_ParCSRMatrixOffd(x); 2210363d496dSStefano Zampini yloc = hypre_ParCSRMatrixOffd(y); 2211363d496dSStefano Zampini xnnz = 0; 2212363d496dSStefano Zampini ynnz = 0; 2213363d496dSStefano Zampini xarr = NULL; 2214363d496dSStefano Zampini yarr = NULL; 2215363d496dSStefano Zampini if (xloc) { 221639accc25SStefano Zampini xarr = hypre_CSRMatrixData(xloc); 2217363d496dSStefano Zampini xnnz = hypre_CSRMatrixNumNonzeros(xloc); 2218363d496dSStefano Zampini } 2219363d496dSStefano Zampini if (yloc) { 222039accc25SStefano Zampini yarr = hypre_CSRMatrixData(yloc); 2221363d496dSStefano Zampini ynnz = hypre_CSRMatrixNumNonzeros(yloc); 2222363d496dSStefano Zampini } 2223363d496dSStefano Zampini if (xnnz != ynnz) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Different number of nonzeros in off-diagonal block %D != %D",xnnz,ynnz); 2224363d496dSStefano Zampini ierr = PetscBLASIntCast(xnnz,&bnz);CHKERRQ(ierr); 222539accc25SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&a,(PetscScalar*)xarr,&one,(PetscScalar*)yarr,&one)); 2226363d496dSStefano Zampini } else if (str == SUBSET_NONZERO_PATTERN) { 2227363d496dSStefano Zampini ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr); 2228363d496dSStefano Zampini } else { 2229363d496dSStefano Zampini Mat B; 2230363d496dSStefano Zampini 2231363d496dSStefano Zampini ierr = MatAXPY_Basic_Preallocate(Y,X,&B);CHKERRQ(ierr); 2232363d496dSStefano Zampini ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr); 2233363d496dSStefano Zampini ierr = MatHeaderReplace(Y,&B);CHKERRQ(ierr); 2234363d496dSStefano Zampini } 22356ea7df73SStefano Zampini #endif 2236363d496dSStefano Zampini PetscFunctionReturn(0); 2237363d496dSStefano Zampini } 2238363d496dSStefano Zampini 2239a055b5aaSBarry Smith /*MC 2240a055b5aaSBarry Smith MATHYPRE - MATHYPRE = "hypre" - A matrix type to be used for sequential and parallel sparse matrices 2241a055b5aaSBarry Smith based on the hypre IJ interface. 2242a055b5aaSBarry Smith 2243a055b5aaSBarry Smith Level: intermediate 2244a055b5aaSBarry Smith 2245a055b5aaSBarry Smith .seealso: MatCreate() 2246a055b5aaSBarry Smith M*/ 2247a055b5aaSBarry Smith 224863c07aadSStefano Zampini PETSC_EXTERN PetscErrorCode MatCreate_HYPRE(Mat B) 224963c07aadSStefano Zampini { 225063c07aadSStefano Zampini Mat_HYPRE *hB; 225163c07aadSStefano Zampini PetscErrorCode ierr; 225263c07aadSStefano Zampini 225363c07aadSStefano Zampini PetscFunctionBegin; 225463c07aadSStefano Zampini ierr = PetscNewLog(B,&hB);CHKERRQ(ierr); 22556ea7df73SStefano Zampini 2256978814f1SStefano Zampini hB->inner_free = PETSC_TRUE; 2257c69f721fSFande Kong hB->available = PETSC_TRUE; 2258336664bdSPierre Jolivet hB->sorted_full = PETSC_FALSE; /* no assumption whether column indices are sorted or not */ 2259c69f721fSFande Kong hB->size = 0; 2260c69f721fSFande Kong hB->array = NULL; 2261978814f1SStefano Zampini 226263c07aadSStefano Zampini B->data = (void*)hB; 226363c07aadSStefano Zampini B->rmap->bs = 1; 226463c07aadSStefano Zampini B->assembled = PETSC_FALSE; 226563c07aadSStefano Zampini 2266de393100SStefano Zampini ierr = PetscMemzero(B->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 226763c07aadSStefano Zampini B->ops->mult = MatMult_HYPRE; 226863c07aadSStefano Zampini B->ops->multtranspose = MatMultTranspose_HYPRE; 2269414bd5c3SStefano Zampini B->ops->multadd = MatMultAdd_HYPRE; 2270414bd5c3SStefano Zampini B->ops->multtransposeadd = MatMultTransposeAdd_HYPRE; 227163c07aadSStefano Zampini B->ops->setup = MatSetUp_HYPRE; 227263c07aadSStefano Zampini B->ops->destroy = MatDestroy_HYPRE; 227363c07aadSStefano Zampini B->ops->assemblyend = MatAssemblyEnd_HYPRE; 2274c69f721fSFande Kong B->ops->assemblybegin = MatAssemblyBegin_HYPRE; 2275d975228cSstefano_zampini B->ops->setvalues = MatSetValues_HYPRE; 227668ec7858SStefano Zampini B->ops->missingdiagonal = MatMissingDiagonal_HYPRE; 227768ec7858SStefano Zampini B->ops->scale = MatScale_HYPRE; 227868ec7858SStefano Zampini B->ops->zerorowscolumns = MatZeroRowsColumns_HYPRE; 2279c69f721fSFande Kong B->ops->zeroentries = MatZeroEntries_HYPRE; 2280c69f721fSFande Kong B->ops->zerorows = MatZeroRows_HYPRE; 2281c69f721fSFande Kong B->ops->getrow = MatGetRow_HYPRE; 2282c69f721fSFande Kong B->ops->restorerow = MatRestoreRow_HYPRE; 2283c69f721fSFande Kong B->ops->getvalues = MatGetValues_HYPRE; 2284ddbeb582SStefano Zampini B->ops->setoption = MatSetOption_HYPRE; 228545b8d346SStefano Zampini B->ops->duplicate = MatDuplicate_HYPRE; 2286465edc17SStefano Zampini B->ops->copy = MatCopy_HYPRE; 228745b8d346SStefano Zampini B->ops->view = MatView_HYPRE; 22886305df00SStefano Zampini B->ops->getdiagonal = MatGetDiagonal_HYPRE; 2289363d496dSStefano Zampini B->ops->axpy = MatAXPY_HYPRE; 22904222ddf1SHong Zhang B->ops->productsetfromoptions = MatProductSetFromOptions_HYPRE; 22916ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 22926ea7df73SStefano Zampini B->ops->bindtocpu = MatBindToCPU_HYPRE; 22936ea7df73SStefano Zampini B->boundtocpu = PETSC_FALSE; 22946ea7df73SStefano Zampini #endif 229545b8d346SStefano Zampini 229645b8d346SStefano Zampini /* build cache for off array entries formed */ 229745b8d346SStefano Zampini ierr = MatStashCreate_Private(PetscObjectComm((PetscObject)B),1,&B->stash);CHKERRQ(ierr); 229863c07aadSStefano Zampini 2299ffc4695bSBarry Smith ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)B),&hB->comm);CHKERRMPI(ierr); 230063c07aadSStefano Zampini ierr = PetscObjectChangeTypeName((PetscObject)B,MATHYPRE);CHKERRQ(ierr); 230163c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_hypre_aij_C",MatConvert_HYPRE_AIJ);CHKERRQ(ierr); 23022df22349SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_hypre_is_C",MatConvert_HYPRE_IS);CHKERRQ(ierr); 23034222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_hypre_C",MatProductSetFromOptions_HYPRE);CHKERRQ(ierr); 23044222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_mpiaij_hypre_C",MatProductSetFromOptions_HYPRE);CHKERRQ(ierr); 2305d975228cSstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatHYPRESetPreallocation_C",MatHYPRESetPreallocation_HYPRE);CHKERRQ(ierr); 2306dd9c0a25Sstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatHYPREGetParCSR_C",MatHYPREGetParCSR_HYPRE);CHKERRQ(ierr); 23076ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 23086ea7df73SStefano Zampini #if defined(HYPRE_USING_HIP) 23096ea7df73SStefano Zampini ierr = PetscHIPInitializeCheck();CHKERRQ(ierr); 23106ea7df73SStefano Zampini ierr = MatSetVecType(B,VECHIP);CHKERRQ(ierr); 23116ea7df73SStefano Zampini #endif 23126ea7df73SStefano Zampini #if defined(HYPRE_USING_CUDA) 23136ea7df73SStefano Zampini ierr = PetscCUDAInitializeCheck();CHKERRQ(ierr); 23146ea7df73SStefano Zampini ierr = MatSetVecType(B,VECCUDA);CHKERRQ(ierr); 23156ea7df73SStefano Zampini #endif 23166ea7df73SStefano Zampini #endif 231763c07aadSStefano Zampini PetscFunctionReturn(0); 231863c07aadSStefano Zampini } 231963c07aadSStefano Zampini 2320225daaf8SStefano Zampini static PetscErrorCode hypre_array_destroy(void *ptr) 2321225daaf8SStefano Zampini { 2322225daaf8SStefano Zampini PetscFunctionBegin; 2323e6de0934SSatish Balay hypre_TFree(ptr,HYPRE_MEMORY_HOST); 2324225daaf8SStefano Zampini PetscFunctionReturn(0); 2325225daaf8SStefano Zampini } 2326