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*); 28*6ea7df73SStefano 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; 138*6ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_LT(2,19,0) 139*6ea7df73SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixInitialize,(ij)); 140*6ea7df73SStefano Zampini #else 141*6ea7df73SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixInitialize_v2,(ij,HYPRE_MEMORY_HOST)); 142*6ea7df73SStefano 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)); 178*6ea7df73SStefano 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 } 197*6ea7df73SStefano Zampini 198*6ea7df73SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&pa);CHKERRQ(ierr); 199*6ea7df73SStefano Zampini ierr = PetscArraycpy(hdiag->data,pa,pdiag->nz);CHKERRQ(ierr); 200*6ea7df73SStefano 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)); 218*6ea7df73SStefano 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 248*6ea7df73SStefano Zampini ierr = MatSeqAIJGetArrayRead(pA->A,&pa);CHKERRQ(ierr); 249*6ea7df73SStefano Zampini ierr = PetscArraycpy(hdiag->data,pa,pdiag->nz);CHKERRQ(ierr); 250*6ea7df73SStefano 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 268*6ea7df73SStefano Zampini ierr = MatSeqAIJGetArrayRead(pA->B,&pa);CHKERRQ(ierr); 269*6ea7df73SStefano Zampini ierr = PetscArraycpy(hoffd->data,pa,poffd->nz);CHKERRQ(ierr); 270*6ea7df73SStefano 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 } 445*6ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 446*6ea7df73SStefano Zampini if (HYPRE_MEMORY_DEVICE == hypre_IJMatrixMemoryLocation(hA->ij)) SETERRQ(comm,PETSC_ERR_SUP,"Not yet implemented"); 447*6ea7df73SStefano 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) { 4892cf14000SStefano Zampini 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 { 492580bdb30SBarry Smith 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 } 5312cf14000SStefano Zampini if (!sameint) { 5322cf14000SStefano Zampini for (i=0;i<m+1;i++) oii[i] = (PetscInt)(hypre_CSRMatrixI(hoffd)[i]); 5332cf14000SStefano Zampini } else { 534580bdb30SBarry Smith ierr = PetscArraycpy(oii,hypre_CSRMatrixI(hoffd),m+1);CHKERRQ(ierr); 5352cf14000SStefano Zampini } 53663c07aadSStefano Zampini offdj = hypre_CSRMatrixJ(hoffd); 53763c07aadSStefano Zampini coffd = hypre_ParCSRMatrixColMapOffd(parcsr); 53863c07aadSStefano Zampini for (i=0; i<onnz; i++) ojj[i] = coffd[offdj[i]]; 539580bdb30SBarry Smith ierr = PetscArraycpy(oa,hypre_CSRMatrixData(hoffd),onnz);CHKERRQ(ierr); 54063c07aadSStefano Zampini iptr = ojj; 54163c07aadSStefano Zampini aptr = oa; 54263c07aadSStefano Zampini for (i=0; i<m; i++) { 54363c07aadSStefano Zampini PetscInt nc = oii[i+1]-oii[i]; 54463c07aadSStefano Zampini ierr = PetscSortIntWithScalarArray(nc,iptr,aptr);CHKERRQ(ierr); 54563c07aadSStefano Zampini iptr += nc; 54663c07aadSStefano Zampini aptr += nc; 54763c07aadSStefano Zampini } 548225daaf8SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 54963c07aadSStefano Zampini Mat_MPIAIJ *b; 55063c07aadSStefano Zampini Mat_SeqAIJ *d,*o; 551225daaf8SStefano Zampini 55241073d71Sstefano_zampini ierr = MatCreateMPIAIJWithSplitArrays(comm,m,n,PETSC_DECIDE,PETSC_DECIDE,dii,djj,da,oii,ojj,oa,B);CHKERRQ(ierr); 55363c07aadSStefano Zampini /* hack MPIAIJ */ 55463c07aadSStefano Zampini b = (Mat_MPIAIJ*)((*B)->data); 55563c07aadSStefano Zampini d = (Mat_SeqAIJ*)b->A->data; 55663c07aadSStefano Zampini o = (Mat_SeqAIJ*)b->B->data; 55763c07aadSStefano Zampini d->free_a = PETSC_TRUE; 55863c07aadSStefano Zampini d->free_ij = PETSC_TRUE; 55963c07aadSStefano Zampini o->free_a = PETSC_TRUE; 56063c07aadSStefano Zampini o->free_ij = PETSC_TRUE; 561225daaf8SStefano Zampini } else if (reuse == MAT_INPLACE_MATRIX) { 562225daaf8SStefano Zampini Mat T; 5632cf14000SStefano Zampini 56441073d71Sstefano_zampini ierr = MatCreateMPIAIJWithSplitArrays(comm,m,n,PETSC_DECIDE,PETSC_DECIDE,dii,djj,da,oii,ojj,oa,&T);CHKERRQ(ierr); 5652cf14000SStefano Zampini if (sameint) { /* ownership of CSR pointers is transferred to PETSc */ 566225daaf8SStefano Zampini hypre_CSRMatrixI(hdiag) = NULL; 567225daaf8SStefano Zampini hypre_CSRMatrixJ(hdiag) = NULL; 568225daaf8SStefano Zampini hypre_CSRMatrixI(hoffd) = NULL; 569225daaf8SStefano Zampini hypre_CSRMatrixJ(hoffd) = NULL; 5702cf14000SStefano Zampini } else { /* Hack MPIAIJ -> free ij but not a */ 5712cf14000SStefano Zampini Mat_MPIAIJ *b = (Mat_MPIAIJ*)(T->data); 5722cf14000SStefano Zampini Mat_SeqAIJ *d = (Mat_SeqAIJ*)(b->A->data); 5732cf14000SStefano Zampini Mat_SeqAIJ *o = (Mat_SeqAIJ*)(b->B->data); 5742cf14000SStefano Zampini 5752cf14000SStefano Zampini d->free_ij = PETSC_TRUE; 5762cf14000SStefano Zampini o->free_ij = PETSC_TRUE; 5772cf14000SStefano Zampini } 5782cf14000SStefano Zampini hypre_CSRMatrixData(hdiag) = NULL; 579225daaf8SStefano Zampini hypre_CSRMatrixData(hoffd) = NULL; 580225daaf8SStefano Zampini ierr = MatHeaderReplace(A,&T);CHKERRQ(ierr); 58163c07aadSStefano Zampini } 582225daaf8SStefano Zampini } else { 583225daaf8SStefano Zampini oii = NULL; 584225daaf8SStefano Zampini ojj = NULL; 585225daaf8SStefano Zampini oa = NULL; 586225daaf8SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 58763c07aadSStefano Zampini Mat_SeqAIJ* b; 5882cf14000SStefano Zampini 58963c07aadSStefano Zampini ierr = MatCreateSeqAIJWithArrays(comm,m,n,dii,djj,da,B);CHKERRQ(ierr); 59063c07aadSStefano Zampini /* hack SeqAIJ */ 59163c07aadSStefano Zampini b = (Mat_SeqAIJ*)((*B)->data); 59263c07aadSStefano Zampini b->free_a = PETSC_TRUE; 59363c07aadSStefano Zampini b->free_ij = PETSC_TRUE; 594225daaf8SStefano Zampini } else if (reuse == MAT_INPLACE_MATRIX) { 595225daaf8SStefano Zampini Mat T; 5962cf14000SStefano Zampini 597225daaf8SStefano Zampini ierr = MatCreateSeqAIJWithArrays(comm,m,n,dii,djj,da,&T);CHKERRQ(ierr); 5982cf14000SStefano Zampini if (sameint) { /* ownership of CSR pointers is transferred to PETSc */ 599225daaf8SStefano Zampini hypre_CSRMatrixI(hdiag) = NULL; 600225daaf8SStefano Zampini hypre_CSRMatrixJ(hdiag) = NULL; 6012cf14000SStefano Zampini } else { /* free ij but not a */ 6022cf14000SStefano Zampini Mat_SeqAIJ* b = (Mat_SeqAIJ*)(T->data); 6032cf14000SStefano Zampini 6042cf14000SStefano Zampini b->free_ij = PETSC_TRUE; 6052cf14000SStefano Zampini } 606225daaf8SStefano Zampini hypre_CSRMatrixData(hdiag) = NULL; 607225daaf8SStefano Zampini ierr = MatHeaderReplace(A,&T);CHKERRQ(ierr); 60863c07aadSStefano Zampini } 609225daaf8SStefano Zampini } 610225daaf8SStefano Zampini 6112cf14000SStefano Zampini /* we have to use hypre_Tfree to free the HYPRE arrays 6122cf14000SStefano Zampini that PETSc now onws */ 61363c07aadSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 6142cf14000SStefano Zampini PetscInt nh; 6152cf14000SStefano Zampini void *ptrs[6] = {da,oa,dii,djj,oii,ojj}; 6162cf14000SStefano Zampini const char *names[6] = {"_hypre_csr_da", 6172cf14000SStefano Zampini "_hypre_csr_oa", 6182cf14000SStefano Zampini "_hypre_csr_dii", 619225daaf8SStefano Zampini "_hypre_csr_djj", 620225daaf8SStefano Zampini "_hypre_csr_oii", 6212cf14000SStefano Zampini "_hypre_csr_ojj"}; 6222cf14000SStefano Zampini nh = sameint ? 6 : 2; 6232cf14000SStefano Zampini for (i=0; i<nh; i++) { 624225daaf8SStefano Zampini PetscContainer c; 625225daaf8SStefano Zampini 626225daaf8SStefano Zampini ierr = PetscContainerCreate(comm,&c);CHKERRQ(ierr); 627225daaf8SStefano Zampini ierr = PetscContainerSetPointer(c,ptrs[i]);CHKERRQ(ierr); 628225daaf8SStefano Zampini ierr = PetscContainerSetUserDestroy(c,hypre_array_destroy);CHKERRQ(ierr); 629225daaf8SStefano Zampini ierr = PetscObjectCompose((PetscObject)(*B),names[i],(PetscObject)c);CHKERRQ(ierr); 630225daaf8SStefano Zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 631225daaf8SStefano Zampini } 63263c07aadSStefano Zampini } 63363c07aadSStefano Zampini PetscFunctionReturn(0); 63463c07aadSStefano Zampini } 63563c07aadSStefano Zampini 636613e5ff0Sstefano_zampini static PetscErrorCode MatAIJGetParCSR_Private(Mat A, hypre_ParCSRMatrix **hA) 637c1a070e6SStefano Zampini { 638613e5ff0Sstefano_zampini hypre_ParCSRMatrix *tA; 639c1a070e6SStefano Zampini hypre_CSRMatrix *hdiag,*hoffd; 640c1a070e6SStefano Zampini Mat_SeqAIJ *diag,*offd; 6412cf14000SStefano Zampini PetscInt *garray,i,noffd,dnnz,onnz,*row_starts,*col_starts; 642c1a070e6SStefano Zampini MPI_Comm comm = PetscObjectComm((PetscObject)A); 643613e5ff0Sstefano_zampini PetscBool ismpiaij,isseqaij; 6442cf14000SStefano Zampini PetscBool sameint = (PetscBool)(sizeof(PetscInt) == sizeof(HYPRE_Int)); 645c1a070e6SStefano Zampini PetscErrorCode ierr; 646*6ea7df73SStefano Zampini HYPRE_Int *hdi = NULL,*hdj = NULL,*hoi = NULL,*hoj = NULL; 647*6ea7df73SStefano Zampini PetscInt *pdi,*pdj,*poi,*poj; 648*6ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 649*6ea7df73SStefano Zampini PetscBool iscuda = PETSC_FALSE; 650*6ea7df73SStefano Zampini #endif 651c1a070e6SStefano Zampini 652c1a070e6SStefano Zampini PetscFunctionBegin; 6533937f725SBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)A,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr); 6544099cc6bSBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 655a32993e3SJed Brown if (!ismpiaij && !isseqaij) SETERRQ1(comm,PETSC_ERR_SUP,"Unsupported type %s",((PetscObject)A)->type_name); 656c1a070e6SStefano Zampini if (ismpiaij) { 657c1a070e6SStefano Zampini Mat_MPIAIJ *a = (Mat_MPIAIJ*)(A->data); 658c1a070e6SStefano Zampini 659c1a070e6SStefano Zampini diag = (Mat_SeqAIJ*)a->A->data; 660c1a070e6SStefano Zampini offd = (Mat_SeqAIJ*)a->B->data; 661*6ea7df73SStefano Zampini #if defined(PETSC_HAVE_CUDA) && defined(PETSC_HAVE_HYPRE_DEVICE) && defined(HYPRE_USING_CUDA) 662*6ea7df73SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJCUSPARSE,&iscuda);CHKERRQ(ierr); 663*6ea7df73SStefano Zampini if (iscuda && !A->boundtocpu) { 664*6ea7df73SStefano Zampini sameint = PETSC_TRUE; 665*6ea7df73SStefano Zampini ierr = MatSeqAIJCUSPARSEGetIJ(a->A,PETSC_FALSE,(const HYPRE_Int**)&hdi,(const HYPRE_Int**)&hdj);CHKERRQ(ierr); 666*6ea7df73SStefano Zampini ierr = MatSeqAIJCUSPARSEGetIJ(a->B,PETSC_FALSE,(const HYPRE_Int**)&hoi,(const HYPRE_Int**)&hoj);CHKERRQ(ierr); 667*6ea7df73SStefano Zampini } else { 668*6ea7df73SStefano Zampini #else 669*6ea7df73SStefano Zampini { 670*6ea7df73SStefano Zampini #endif 671*6ea7df73SStefano Zampini pdi = diag->i; 672*6ea7df73SStefano Zampini pdj = diag->j; 673*6ea7df73SStefano Zampini poi = offd->i; 674*6ea7df73SStefano Zampini poj = offd->j; 675*6ea7df73SStefano Zampini if (sameint) { 676*6ea7df73SStefano Zampini hdi = (HYPRE_Int*)pdi; 677*6ea7df73SStefano Zampini hdj = (HYPRE_Int*)pdj; 678*6ea7df73SStefano Zampini hoi = (HYPRE_Int*)poi; 679*6ea7df73SStefano Zampini hoj = (HYPRE_Int*)poj; 680*6ea7df73SStefano Zampini } 681*6ea7df73SStefano Zampini } 682c1a070e6SStefano Zampini garray = a->garray; 683c1a070e6SStefano Zampini noffd = a->B->cmap->N; 684c1a070e6SStefano Zampini dnnz = diag->nz; 685c1a070e6SStefano Zampini onnz = offd->nz; 686c1a070e6SStefano Zampini } else { 687c1a070e6SStefano Zampini diag = (Mat_SeqAIJ*)A->data; 688c1a070e6SStefano Zampini offd = NULL; 689*6ea7df73SStefano Zampini #if defined(PETSC_HAVE_CUDA) && defined(PETSC_HAVE_HYPRE_DEVICE) 690*6ea7df73SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJCUSPARSE,&iscuda);CHKERRQ(ierr); 691*6ea7df73SStefano Zampini if (iscuda && !A->boundtocpu) { 692*6ea7df73SStefano Zampini sameint = PETSC_TRUE; 693*6ea7df73SStefano Zampini ierr = MatSeqAIJCUSPARSEGetIJ(A,PETSC_FALSE,(const HYPRE_Int**)&hdi,(const HYPRE_Int**)&hdj);CHKERRQ(ierr); 694*6ea7df73SStefano Zampini } else { 695*6ea7df73SStefano Zampini #else 696*6ea7df73SStefano Zampini { 697*6ea7df73SStefano Zampini #endif 698*6ea7df73SStefano Zampini pdi = diag->i; 699*6ea7df73SStefano Zampini pdj = diag->j; 700*6ea7df73SStefano Zampini if (sameint) { 701*6ea7df73SStefano Zampini hdi = (HYPRE_Int*)pdi; 702*6ea7df73SStefano Zampini hdj = (HYPRE_Int*)pdj; 703*6ea7df73SStefano Zampini } 704*6ea7df73SStefano Zampini } 705c1a070e6SStefano Zampini garray = NULL; 706c1a070e6SStefano Zampini noffd = 0; 707c1a070e6SStefano Zampini dnnz = diag->nz; 708c1a070e6SStefano Zampini onnz = 0; 709c1a070e6SStefano Zampini } 710225daaf8SStefano Zampini 711c1a070e6SStefano Zampini /* create a temporary ParCSR */ 712c1a070e6SStefano Zampini if (HYPRE_AssumedPartitionCheck()) { 713c1a070e6SStefano Zampini PetscMPIInt myid; 714c1a070e6SStefano Zampini 71555b25c41SPierre Jolivet ierr = MPI_Comm_rank(comm,&myid);CHKERRMPI(ierr); 716c1a070e6SStefano Zampini row_starts = A->rmap->range + myid; 717c1a070e6SStefano Zampini col_starts = A->cmap->range + myid; 718c1a070e6SStefano Zampini } else { 719c1a070e6SStefano Zampini row_starts = A->rmap->range; 720c1a070e6SStefano Zampini col_starts = A->cmap->range; 721c1a070e6SStefano Zampini } 7222cf14000SStefano Zampini tA = hypre_ParCSRMatrixCreate(comm,A->rmap->N,A->cmap->N,(HYPRE_BigInt*)row_starts,(HYPRE_BigInt*)col_starts,noffd,dnnz,onnz); 723a1d2239cSSatish Balay #if defined(hypre_ParCSRMatrixOwnsRowStarts) 724c1a070e6SStefano Zampini hypre_ParCSRMatrixSetRowStartsOwner(tA,0); 725c1a070e6SStefano Zampini hypre_ParCSRMatrixSetColStartsOwner(tA,0); 726a1d2239cSSatish Balay #endif 727c1a070e6SStefano Zampini 728225daaf8SStefano Zampini /* set diagonal part */ 729c1a070e6SStefano Zampini hdiag = hypre_ParCSRMatrixDiag(tA); 730*6ea7df73SStefano Zampini if (!sameint) { /* malloc CSR pointers */ 731*6ea7df73SStefano Zampini ierr = PetscMalloc2(A->rmap->n+1,&hdi,dnnz,&hdj);CHKERRQ(ierr); 732*6ea7df73SStefano Zampini for (i = 0; i < A->rmap->n+1; i++) hdi[i] = (HYPRE_Int)(pdi[i]); 733*6ea7df73SStefano Zampini for (i = 0; i < dnnz; i++) hdj[i] = (HYPRE_Int)(pdj[i]); 7342cf14000SStefano Zampini } 735*6ea7df73SStefano Zampini hypre_CSRMatrixI(hdiag) = hdi; 736*6ea7df73SStefano Zampini hypre_CSRMatrixJ(hdiag) = hdj; 73739accc25SStefano Zampini hypre_CSRMatrixData(hdiag) = (HYPRE_Complex*)diag->a; 738c1a070e6SStefano Zampini hypre_CSRMatrixNumNonzeros(hdiag) = diag->nz; 739c1a070e6SStefano Zampini hypre_CSRMatrixSetRownnz(hdiag); 740c1a070e6SStefano Zampini hypre_CSRMatrixSetDataOwner(hdiag,0); 741c1a070e6SStefano Zampini 742225daaf8SStefano Zampini /* set offdiagonal part */ 743c1a070e6SStefano Zampini hoffd = hypre_ParCSRMatrixOffd(tA); 744c1a070e6SStefano Zampini if (offd) { 745*6ea7df73SStefano Zampini if (!sameint) { /* malloc CSR pointers */ 746*6ea7df73SStefano Zampini ierr = PetscMalloc2(A->rmap->n+1,&hoi,onnz,&hoj);CHKERRQ(ierr); 747*6ea7df73SStefano Zampini for (i = 0; i < A->rmap->n+1; i++) hoi[i] = (HYPRE_Int)(poi[i]); 748*6ea7df73SStefano Zampini for (i = 0; i < onnz; i++) hoj[i] = (HYPRE_Int)(poj[i]); 7492cf14000SStefano Zampini } 750*6ea7df73SStefano Zampini hypre_CSRMatrixI(hoffd) = hoi; 751*6ea7df73SStefano Zampini hypre_CSRMatrixJ(hoffd) = hoj; 75239accc25SStefano Zampini hypre_CSRMatrixData(hoffd) = (HYPRE_Complex*)offd->a; 753c1a070e6SStefano Zampini hypre_CSRMatrixNumNonzeros(hoffd) = offd->nz; 754c1a070e6SStefano Zampini hypre_CSRMatrixSetRownnz(hoffd); 755c1a070e6SStefano Zampini hypre_CSRMatrixSetDataOwner(hoffd,0); 756*6ea7df73SStefano Zampini } 757*6ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 758*6ea7df73SStefano Zampini PetscStackCallStandard(hypre_ParCSRMatrixInitialize_v2,(tA,iscuda ? HYPRE_MEMORY_DEVICE : HYPRE_MEMORY_HOST)); 759*6ea7df73SStefano Zampini #else 760*6ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_LT(2,18,0) 761*6ea7df73SStefano Zampini PetscStackCallStandard(hypre_ParCSRMatrixInitialize,(tA)); 762*6ea7df73SStefano Zampini #else 763*6ea7df73SStefano Zampini PetscStackCallStandard(hypre_ParCSRMatrixInitialize_v2,(tA,HYPRE_MEMORY_HOST)); 764*6ea7df73SStefano Zampini #endif 765*6ea7df73SStefano Zampini #endif 766*6ea7df73SStefano Zampini hypre_TFree(hypre_ParCSRMatrixColMapOffd(tA),HYPRE_MEMORY_HOST); 767c1a070e6SStefano Zampini hypre_ParCSRMatrixSetNumNonzeros(tA); 7682cf14000SStefano Zampini hypre_ParCSRMatrixColMapOffd(tA) = (HYPRE_BigInt*)garray; 769*6ea7df73SStefano Zampini if (!hypre_ParCSRMatrixCommPkg(tA)) PetscStackCallStandard(hypre_MatvecCommPkgCreate,(tA)); 770613e5ff0Sstefano_zampini *hA = tA; 771613e5ff0Sstefano_zampini PetscFunctionReturn(0); 772613e5ff0Sstefano_zampini } 773c1a070e6SStefano Zampini 774613e5ff0Sstefano_zampini static PetscErrorCode MatAIJRestoreParCSR_Private(Mat A, hypre_ParCSRMatrix **hA) 775613e5ff0Sstefano_zampini { 776613e5ff0Sstefano_zampini hypre_CSRMatrix *hdiag,*hoffd; 777*6ea7df73SStefano Zampini PetscBool ismpiaij,sameint = (PetscBool)(sizeof(PetscInt) == sizeof(HYPRE_Int)); 7782cf14000SStefano Zampini PetscErrorCode ierr; 779*6ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 780*6ea7df73SStefano Zampini PetscBool iscuda = PETSC_FALSE; 781*6ea7df73SStefano Zampini #endif 782c1a070e6SStefano Zampini 783613e5ff0Sstefano_zampini PetscFunctionBegin; 784*6ea7df73SStefano Zampini ierr = PetscObjectBaseTypeCompare((PetscObject)A,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr); 785*6ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 786*6ea7df73SStefano Zampini ierr = PetscObjectTypeCompareAny((PetscObject)A,&iscuda,MATSEQAIJCUSPARSE,MATMPIAIJCUSPARSE,"");CHKERRQ(ierr); 787*6ea7df73SStefano Zampini if (iscuda) sameint = PETSC_TRUE; 788*6ea7df73SStefano Zampini #endif 789613e5ff0Sstefano_zampini hdiag = hypre_ParCSRMatrixDiag(*hA); 790613e5ff0Sstefano_zampini hoffd = hypre_ParCSRMatrixOffd(*hA); 791*6ea7df73SStefano Zampini /* free temporary memory allocated by PETSc 792*6ea7df73SStefano Zampini set pointers to NULL before destroying tA */ 7932cf14000SStefano Zampini if (!sameint) { 7942cf14000SStefano Zampini HYPRE_Int *hi,*hj; 7952cf14000SStefano Zampini 7962cf14000SStefano Zampini hi = hypre_CSRMatrixI(hdiag); 7972cf14000SStefano Zampini hj = hypre_CSRMatrixJ(hdiag); 7982cf14000SStefano Zampini ierr = PetscFree2(hi,hj);CHKERRQ(ierr); 799*6ea7df73SStefano Zampini if (ismpiaij) { 8002cf14000SStefano Zampini hi = hypre_CSRMatrixI(hoffd); 8012cf14000SStefano Zampini hj = hypre_CSRMatrixJ(hoffd); 8022cf14000SStefano Zampini ierr = PetscFree2(hi,hj);CHKERRQ(ierr); 8032cf14000SStefano Zampini } 8042cf14000SStefano Zampini } 805c1a070e6SStefano Zampini hypre_CSRMatrixI(hdiag) = NULL; 806c1a070e6SStefano Zampini hypre_CSRMatrixJ(hdiag) = NULL; 807c1a070e6SStefano Zampini hypre_CSRMatrixData(hdiag) = NULL; 808*6ea7df73SStefano Zampini if (ismpiaij) { 809c1a070e6SStefano Zampini hypre_CSRMatrixI(hoffd) = NULL; 810c1a070e6SStefano Zampini hypre_CSRMatrixJ(hoffd) = NULL; 811c1a070e6SStefano Zampini hypre_CSRMatrixData(hoffd) = NULL; 812*6ea7df73SStefano Zampini } 813613e5ff0Sstefano_zampini hypre_ParCSRMatrixColMapOffd(*hA) = NULL; 814613e5ff0Sstefano_zampini hypre_ParCSRMatrixDestroy(*hA); 815613e5ff0Sstefano_zampini *hA = NULL; 816613e5ff0Sstefano_zampini PetscFunctionReturn(0); 817613e5ff0Sstefano_zampini } 818613e5ff0Sstefano_zampini 819613e5ff0Sstefano_zampini /* calls RAP from BoomerAMG: 8203dad0653Sstefano_zampini the resulting ParCSR will not own the column and row starts 821*6ea7df73SStefano Zampini It looks like we don't need to have the diagonal entries ordered first */ 822a055b5aaSBarry Smith static PetscErrorCode MatHYPRE_ParCSR_RAP(hypre_ParCSRMatrix *hR, hypre_ParCSRMatrix *hA,hypre_ParCSRMatrix *hP, hypre_ParCSRMatrix **hRAP) 823613e5ff0Sstefano_zampini { 824a1d2239cSSatish Balay #if defined(hypre_ParCSRMatrixOwnsRowStarts) 825613e5ff0Sstefano_zampini HYPRE_Int P_owns_col_starts,R_owns_row_starts; 826a1d2239cSSatish Balay #endif 827613e5ff0Sstefano_zampini 828613e5ff0Sstefano_zampini PetscFunctionBegin; 829a1d2239cSSatish Balay #if defined(hypre_ParCSRMatrixOwnsRowStarts) 830613e5ff0Sstefano_zampini P_owns_col_starts = hypre_ParCSRMatrixOwnsColStarts(hP); 831613e5ff0Sstefano_zampini R_owns_row_starts = hypre_ParCSRMatrixOwnsRowStarts(hR); 832a1d2239cSSatish Balay #endif 833*6ea7df73SStefano Zampini /* can be replaced by version test later */ 834*6ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 835*6ea7df73SStefano Zampini PetscStackPush("hypre_ParCSRMatrixRAP"); 836*6ea7df73SStefano Zampini *hRAP = hypre_ParCSRMatrixRAP(hR,hA,hP); 837*6ea7df73SStefano Zampini PetscStackPop; 838*6ea7df73SStefano Zampini #else 839613e5ff0Sstefano_zampini PetscStackCallStandard(hypre_BoomerAMGBuildCoarseOperator,(hR,hA,hP,hRAP)); 840613e5ff0Sstefano_zampini PetscStackCallStandard(hypre_ParCSRMatrixSetNumNonzeros,(*hRAP)); 841*6ea7df73SStefano Zampini #endif 842613e5ff0Sstefano_zampini /* hypre_BoomerAMGBuildCoarseOperator steals the col_starts from P and the row_starts from R */ 843a1d2239cSSatish Balay #if defined(hypre_ParCSRMatrixOwnsRowStarts) 844613e5ff0Sstefano_zampini hypre_ParCSRMatrixSetRowStartsOwner(*hRAP,0); 845613e5ff0Sstefano_zampini hypre_ParCSRMatrixSetColStartsOwner(*hRAP,0); 846613e5ff0Sstefano_zampini if (P_owns_col_starts) hypre_ParCSRMatrixSetColStartsOwner(hP,1); 847613e5ff0Sstefano_zampini if (R_owns_row_starts) hypre_ParCSRMatrixSetRowStartsOwner(hR,1); 848a1d2239cSSatish Balay #endif 849613e5ff0Sstefano_zampini PetscFunctionReturn(0); 850613e5ff0Sstefano_zampini } 851613e5ff0Sstefano_zampini 8526f231fbdSstefano_zampini static PetscErrorCode MatPtAPNumeric_AIJ_AIJ_wHYPRE(Mat A,Mat P,Mat C) 853613e5ff0Sstefano_zampini { 8546f231fbdSstefano_zampini Mat B; 855613e5ff0Sstefano_zampini hypre_ParCSRMatrix *hA,*hP,*hPtAP; 856613e5ff0Sstefano_zampini PetscErrorCode ierr; 8574222ddf1SHong Zhang Mat_Product *product=C->product; 858613e5ff0Sstefano_zampini 859613e5ff0Sstefano_zampini PetscFunctionBegin; 860613e5ff0Sstefano_zampini ierr = MatAIJGetParCSR_Private(A,&hA);CHKERRQ(ierr); 861613e5ff0Sstefano_zampini ierr = MatAIJGetParCSR_Private(P,&hP);CHKERRQ(ierr); 862613e5ff0Sstefano_zampini ierr = MatHYPRE_ParCSR_RAP(hP,hA,hP,&hPtAP);CHKERRQ(ierr); 8636f231fbdSstefano_zampini ierr = MatCreateFromParCSR(hPtAP,MATAIJ,PETSC_OWN_POINTER,&B);CHKERRQ(ierr); 8644222ddf1SHong Zhang 8656f231fbdSstefano_zampini ierr = MatHeaderMerge(C,&B);CHKERRQ(ierr); 8664222ddf1SHong Zhang C->product = product; 8674222ddf1SHong Zhang 868613e5ff0Sstefano_zampini ierr = MatAIJRestoreParCSR_Private(A,&hA);CHKERRQ(ierr); 869613e5ff0Sstefano_zampini ierr = MatAIJRestoreParCSR_Private(P,&hP);CHKERRQ(ierr); 8706f231fbdSstefano_zampini PetscFunctionReturn(0); 8716f231fbdSstefano_zampini } 8726f231fbdSstefano_zampini 8734222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatPtAPSymbolic_AIJ_AIJ_wHYPRE(Mat A,Mat P,PetscReal fill,Mat C) 8746f231fbdSstefano_zampini { 8756f231fbdSstefano_zampini PetscErrorCode ierr; 876ab4d48faSStefano Zampini 8776f231fbdSstefano_zampini PetscFunctionBegin; 8784222ddf1SHong Zhang ierr = MatSetType(C,MATAIJ);CHKERRQ(ierr); 8794222ddf1SHong Zhang C->ops->ptapnumeric = MatPtAPNumeric_AIJ_AIJ_wHYPRE; 8804222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_PtAP; 881613e5ff0Sstefano_zampini PetscFunctionReturn(0); 882613e5ff0Sstefano_zampini } 883613e5ff0Sstefano_zampini 8844cc28894Sstefano_zampini static PetscErrorCode MatPtAPNumeric_AIJ_HYPRE(Mat A,Mat P,Mat C) 885613e5ff0Sstefano_zampini { 8864cc28894Sstefano_zampini Mat B; 8874cc28894Sstefano_zampini Mat_HYPRE *hP; 888613e5ff0Sstefano_zampini hypre_ParCSRMatrix *hA = NULL,*Pparcsr,*ptapparcsr; 889613e5ff0Sstefano_zampini HYPRE_Int type; 890613e5ff0Sstefano_zampini MPI_Comm comm = PetscObjectComm((PetscObject)A); 8914cc28894Sstefano_zampini PetscBool ishypre; 892613e5ff0Sstefano_zampini PetscErrorCode ierr; 893613e5ff0Sstefano_zampini 894613e5ff0Sstefano_zampini PetscFunctionBegin; 8954cc28894Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)P,MATHYPRE,&ishypre);CHKERRQ(ierr); 8964cc28894Sstefano_zampini if (!ishypre) SETERRQ1(comm,PETSC_ERR_USER,"P should be of type %s",MATHYPRE); 8974cc28894Sstefano_zampini hP = (Mat_HYPRE*)P->data; 898613e5ff0Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(hP->ij,&type)); 899613e5ff0Sstefano_zampini if (type != HYPRE_PARCSR) SETERRQ(comm,PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 900613e5ff0Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hP->ij,(void**)&Pparcsr)); 901613e5ff0Sstefano_zampini 902613e5ff0Sstefano_zampini ierr = MatAIJGetParCSR_Private(A,&hA);CHKERRQ(ierr); 903613e5ff0Sstefano_zampini ierr = MatHYPRE_ParCSR_RAP(Pparcsr,hA,Pparcsr,&ptapparcsr);CHKERRQ(ierr); 904613e5ff0Sstefano_zampini ierr = MatAIJRestoreParCSR_Private(A,&hA);CHKERRQ(ierr); 905225daaf8SStefano Zampini 9064cc28894Sstefano_zampini /* create temporary matrix and merge to C */ 9074cc28894Sstefano_zampini ierr = MatCreateFromParCSR(ptapparcsr,((PetscObject)C)->type_name,PETSC_OWN_POINTER,&B);CHKERRQ(ierr); 9084cc28894Sstefano_zampini ierr = MatHeaderMerge(C,&B);CHKERRQ(ierr); 9094cc28894Sstefano_zampini PetscFunctionReturn(0); 9104cc28894Sstefano_zampini } 9114cc28894Sstefano_zampini 9124cc28894Sstefano_zampini static PetscErrorCode MatPtAPNumeric_HYPRE_HYPRE(Mat A,Mat P,Mat C) 9134cc28894Sstefano_zampini { 9144cc28894Sstefano_zampini Mat B; 9154cc28894Sstefano_zampini hypre_ParCSRMatrix *Aparcsr,*Pparcsr,*ptapparcsr; 9164cc28894Sstefano_zampini Mat_HYPRE *hA,*hP; 9174cc28894Sstefano_zampini PetscBool ishypre; 9184cc28894Sstefano_zampini HYPRE_Int type; 9194cc28894Sstefano_zampini PetscErrorCode ierr; 9204cc28894Sstefano_zampini 9214cc28894Sstefano_zampini PetscFunctionBegin; 9224cc28894Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)P,MATHYPRE,&ishypre);CHKERRQ(ierr); 9234cc28894Sstefano_zampini if (!ishypre) SETERRQ1(PetscObjectComm((PetscObject)P),PETSC_ERR_USER,"P should be of type %s",MATHYPRE); 9244cc28894Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATHYPRE,&ishypre);CHKERRQ(ierr); 9254cc28894Sstefano_zampini if (!ishypre) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_USER,"A should be of type %s",MATHYPRE); 9264cc28894Sstefano_zampini hA = (Mat_HYPRE*)A->data; 9274cc28894Sstefano_zampini hP = (Mat_HYPRE*)P->data; 9284cc28894Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(hA->ij,&type)); 9294cc28894Sstefano_zampini if (type != HYPRE_PARCSR) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 9304cc28894Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(hP->ij,&type)); 9314cc28894Sstefano_zampini if (type != HYPRE_PARCSR) SETERRQ(PetscObjectComm((PetscObject)P),PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 9324cc28894Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hA->ij,(void**)&Aparcsr)); 9334cc28894Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hP->ij,(void**)&Pparcsr)); 9344cc28894Sstefano_zampini ierr = MatHYPRE_ParCSR_RAP(Pparcsr,Aparcsr,Pparcsr,&ptapparcsr);CHKERRQ(ierr); 9354cc28894Sstefano_zampini ierr = MatCreateFromParCSR(ptapparcsr,MATHYPRE,PETSC_OWN_POINTER,&B);CHKERRQ(ierr); 9364cc28894Sstefano_zampini ierr = MatHeaderMerge(C,&B);CHKERRQ(ierr); 9374cc28894Sstefano_zampini PetscFunctionReturn(0); 9384cc28894Sstefano_zampini } 9394cc28894Sstefano_zampini 940d501dc42Sstefano_zampini /* calls hypre_ParMatmul 941d501dc42Sstefano_zampini hypre_ParMatMul uses hypre_ParMatrixCreate with the communicator of hA 9423dad0653Sstefano_zampini hypre_ParMatrixCreate does not duplicate the communicator 943*6ea7df73SStefano Zampini It looks like we don't need to have the diagonal entries ordered first */ 944d501dc42Sstefano_zampini static PetscErrorCode MatHYPRE_ParCSR_MatMatMult(hypre_ParCSRMatrix *hA, hypre_ParCSRMatrix *hB, hypre_ParCSRMatrix **hAB) 945d501dc42Sstefano_zampini { 946d501dc42Sstefano_zampini PetscFunctionBegin; 947*6ea7df73SStefano Zampini /* can be replaced by version test later */ 948*6ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 949*6ea7df73SStefano Zampini PetscStackPush("hypre_ParCSRMatMat"); 950*6ea7df73SStefano Zampini *hAB = hypre_ParCSRMatMat(hA,hB); 951*6ea7df73SStefano Zampini #else 952d501dc42Sstefano_zampini PetscStackPush("hypre_ParMatmul"); 953d501dc42Sstefano_zampini *hAB = hypre_ParMatmul(hA,hB); 954*6ea7df73SStefano Zampini #endif 955d501dc42Sstefano_zampini PetscStackPop; 956d501dc42Sstefano_zampini PetscFunctionReturn(0); 957d501dc42Sstefano_zampini } 958d501dc42Sstefano_zampini 9595e5acdf2Sstefano_zampini static PetscErrorCode MatMatMultNumeric_AIJ_AIJ_wHYPRE(Mat A,Mat B,Mat C) 9605e5acdf2Sstefano_zampini { 9615e5acdf2Sstefano_zampini Mat D; 962d501dc42Sstefano_zampini hypre_ParCSRMatrix *hA,*hB,*hAB = NULL; 9635e5acdf2Sstefano_zampini PetscErrorCode ierr; 9644222ddf1SHong Zhang Mat_Product *product=C->product; 9655e5acdf2Sstefano_zampini 9665e5acdf2Sstefano_zampini PetscFunctionBegin; 9675e5acdf2Sstefano_zampini ierr = MatAIJGetParCSR_Private(A,&hA);CHKERRQ(ierr); 9685e5acdf2Sstefano_zampini ierr = MatAIJGetParCSR_Private(B,&hB);CHKERRQ(ierr); 969d501dc42Sstefano_zampini ierr = MatHYPRE_ParCSR_MatMatMult(hA,hB,&hAB);CHKERRQ(ierr); 9705e5acdf2Sstefano_zampini ierr = MatCreateFromParCSR(hAB,MATAIJ,PETSC_OWN_POINTER,&D);CHKERRQ(ierr); 9714222ddf1SHong Zhang 9725e5acdf2Sstefano_zampini ierr = MatHeaderMerge(C,&D);CHKERRQ(ierr); 9734222ddf1SHong Zhang C->product = product; 9744222ddf1SHong Zhang 9755e5acdf2Sstefano_zampini ierr = MatAIJRestoreParCSR_Private(A,&hA);CHKERRQ(ierr); 9765e5acdf2Sstefano_zampini ierr = MatAIJRestoreParCSR_Private(B,&hB);CHKERRQ(ierr); 9775e5acdf2Sstefano_zampini PetscFunctionReturn(0); 9785e5acdf2Sstefano_zampini } 9795e5acdf2Sstefano_zampini 9804222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatMatMultSymbolic_AIJ_AIJ_wHYPRE(Mat A,Mat B,PetscReal fill,Mat C) 9815e5acdf2Sstefano_zampini { 9825e5acdf2Sstefano_zampini PetscErrorCode ierr; 98320e1dc0dSstefano_zampini 9845e5acdf2Sstefano_zampini PetscFunctionBegin; 9854222ddf1SHong Zhang ierr = MatSetType(C,MATAIJ);CHKERRQ(ierr); 9864222ddf1SHong Zhang C->ops->matmultnumeric = MatMatMultNumeric_AIJ_AIJ_wHYPRE; 9874222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_AB; 9885e5acdf2Sstefano_zampini PetscFunctionReturn(0); 9895e5acdf2Sstefano_zampini } 9905e5acdf2Sstefano_zampini 991d501dc42Sstefano_zampini static PetscErrorCode MatMatMultNumeric_HYPRE_HYPRE(Mat A,Mat B,Mat C) 992d501dc42Sstefano_zampini { 993d501dc42Sstefano_zampini Mat D; 994d501dc42Sstefano_zampini hypre_ParCSRMatrix *Aparcsr,*Bparcsr,*ABparcsr = NULL; 995d501dc42Sstefano_zampini Mat_HYPRE *hA,*hB; 996d501dc42Sstefano_zampini PetscBool ishypre; 997d501dc42Sstefano_zampini HYPRE_Int type; 998d501dc42Sstefano_zampini PetscErrorCode ierr; 9994222ddf1SHong Zhang Mat_Product *product; 1000d501dc42Sstefano_zampini 1001d501dc42Sstefano_zampini PetscFunctionBegin; 1002d501dc42Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)B,MATHYPRE,&ishypre);CHKERRQ(ierr); 1003d501dc42Sstefano_zampini if (!ishypre) SETERRQ1(PetscObjectComm((PetscObject)B),PETSC_ERR_USER,"B should be of type %s",MATHYPRE); 1004d501dc42Sstefano_zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATHYPRE,&ishypre);CHKERRQ(ierr); 1005d501dc42Sstefano_zampini if (!ishypre) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_USER,"A should be of type %s",MATHYPRE); 1006d501dc42Sstefano_zampini hA = (Mat_HYPRE*)A->data; 1007d501dc42Sstefano_zampini hB = (Mat_HYPRE*)B->data; 1008d501dc42Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(hA->ij,&type)); 1009d501dc42Sstefano_zampini if (type != HYPRE_PARCSR) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 1010d501dc42Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(hB->ij,&type)); 1011d501dc42Sstefano_zampini if (type != HYPRE_PARCSR) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"Only HYPRE_PARCSR is supported"); 1012d501dc42Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hA->ij,(void**)&Aparcsr)); 1013d501dc42Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hB->ij,(void**)&Bparcsr)); 1014d501dc42Sstefano_zampini ierr = MatHYPRE_ParCSR_MatMatMult(Aparcsr,Bparcsr,&ABparcsr);CHKERRQ(ierr); 1015d501dc42Sstefano_zampini ierr = MatCreateFromParCSR(ABparcsr,MATHYPRE,PETSC_OWN_POINTER,&D);CHKERRQ(ierr); 10164222ddf1SHong Zhang 1017d501dc42Sstefano_zampini /* need to use HeaderReplace because HeaderMerge messes up with the communicator */ 10184222ddf1SHong Zhang product = C->product; /* save it from MatHeaderReplace() */ 10194222ddf1SHong Zhang C->product = NULL; 1020d501dc42Sstefano_zampini ierr = MatHeaderReplace(C,&D);CHKERRQ(ierr); 10214222ddf1SHong Zhang C->product = product; 1022d501dc42Sstefano_zampini C->ops->matmultnumeric = MatMatMultNumeric_HYPRE_HYPRE; 10234222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_AB; 1024d501dc42Sstefano_zampini PetscFunctionReturn(0); 1025d501dc42Sstefano_zampini } 1026d501dc42Sstefano_zampini 10273dad0653Sstefano_zampini PETSC_INTERN PetscErrorCode MatTransposeMatMatMultNumeric_AIJ_AIJ_AIJ_wHYPRE(Mat A,Mat B,Mat C,Mat D) 102820e1dc0dSstefano_zampini { 102920e1dc0dSstefano_zampini Mat E; 103020e1dc0dSstefano_zampini hypre_ParCSRMatrix *hA,*hB,*hC,*hABC; 103120e1dc0dSstefano_zampini PetscErrorCode ierr; 103220e1dc0dSstefano_zampini 103320e1dc0dSstefano_zampini PetscFunctionBegin; 103420e1dc0dSstefano_zampini ierr = MatAIJGetParCSR_Private(A,&hA);CHKERRQ(ierr); 103520e1dc0dSstefano_zampini ierr = MatAIJGetParCSR_Private(B,&hB);CHKERRQ(ierr); 103620e1dc0dSstefano_zampini ierr = MatAIJGetParCSR_Private(C,&hC);CHKERRQ(ierr); 103720e1dc0dSstefano_zampini ierr = MatHYPRE_ParCSR_RAP(hA,hB,hC,&hABC);CHKERRQ(ierr); 103820e1dc0dSstefano_zampini ierr = MatCreateFromParCSR(hABC,MATAIJ,PETSC_OWN_POINTER,&E);CHKERRQ(ierr); 103920e1dc0dSstefano_zampini ierr = MatHeaderMerge(D,&E);CHKERRQ(ierr); 104020e1dc0dSstefano_zampini ierr = MatAIJRestoreParCSR_Private(A,&hA);CHKERRQ(ierr); 104120e1dc0dSstefano_zampini ierr = MatAIJRestoreParCSR_Private(B,&hB);CHKERRQ(ierr); 104220e1dc0dSstefano_zampini ierr = MatAIJRestoreParCSR_Private(C,&hC);CHKERRQ(ierr); 104320e1dc0dSstefano_zampini PetscFunctionReturn(0); 104420e1dc0dSstefano_zampini } 104520e1dc0dSstefano_zampini 10464222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatTransposeMatMatMultSymbolic_AIJ_AIJ_AIJ_wHYPRE(Mat A,Mat B,Mat C,PetscReal fill,Mat D) 104720e1dc0dSstefano_zampini { 104820e1dc0dSstefano_zampini PetscErrorCode ierr; 104920e1dc0dSstefano_zampini 105020e1dc0dSstefano_zampini PetscFunctionBegin; 10514222ddf1SHong Zhang ierr = MatSetType(D,MATAIJ);CHKERRQ(ierr); 105220e1dc0dSstefano_zampini PetscFunctionReturn(0); 105320e1dc0dSstefano_zampini } 105420e1dc0dSstefano_zampini 10554222ddf1SHong Zhang /* ---------------------------------------------------- */ 10564222ddf1SHong Zhang static PetscErrorCode MatProductSymbolic_AB_HYPRE(Mat C) 10574222ddf1SHong Zhang { 10584222ddf1SHong Zhang PetscFunctionBegin; 10594222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_AB; 10604222ddf1SHong Zhang PetscFunctionReturn(0); 10614222ddf1SHong Zhang } 10624222ddf1SHong Zhang 10634222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_HYPRE_AB(Mat C) 10644222ddf1SHong Zhang { 10654222ddf1SHong Zhang PetscErrorCode ierr; 10664222ddf1SHong Zhang Mat_Product *product = C->product; 10674222ddf1SHong Zhang PetscBool Ahypre; 10684222ddf1SHong Zhang 10694222ddf1SHong Zhang PetscFunctionBegin; 10704222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)product->A,MATHYPRE,&Ahypre);CHKERRQ(ierr); 10714222ddf1SHong Zhang if (Ahypre) { /* A is a Hypre matrix */ 10724222ddf1SHong Zhang ierr = MatSetType(C,MATHYPRE);CHKERRQ(ierr); 10734222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AB_HYPRE; 10744222ddf1SHong Zhang C->ops->matmultnumeric = MatMatMultNumeric_HYPRE_HYPRE; 10754222ddf1SHong Zhang PetscFunctionReturn(0); 10766718818eSStefano Zampini } 10774222ddf1SHong Zhang PetscFunctionReturn(0); 10784222ddf1SHong Zhang } 10794222ddf1SHong Zhang 10804222ddf1SHong Zhang static PetscErrorCode MatProductSymbolic_PtAP_HYPRE(Mat C) 10814222ddf1SHong Zhang { 10824222ddf1SHong Zhang PetscFunctionBegin; 10834222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_PtAP; 10844222ddf1SHong Zhang PetscFunctionReturn(0); 10854222ddf1SHong Zhang } 10864222ddf1SHong Zhang 10874222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_HYPRE_PtAP(Mat C) 10884222ddf1SHong Zhang { 10894222ddf1SHong Zhang PetscErrorCode ierr; 10904222ddf1SHong Zhang Mat_Product *product = C->product; 10914222ddf1SHong Zhang PetscBool flg; 10924222ddf1SHong Zhang PetscInt type = 0; 10934222ddf1SHong Zhang const char *outTypes[4] = {"aij","seqaij","mpiaij","hypre"}; 10944222ddf1SHong Zhang PetscInt ntype = 4; 10954222ddf1SHong Zhang Mat A = product->A; 10964222ddf1SHong Zhang PetscBool Ahypre; 10974222ddf1SHong Zhang 10984222ddf1SHong Zhang PetscFunctionBegin; 10994222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)A,MATHYPRE,&Ahypre);CHKERRQ(ierr); 11004222ddf1SHong Zhang if (Ahypre) { /* A is a Hypre matrix */ 11014222ddf1SHong Zhang ierr = MatSetType(C,MATHYPRE);CHKERRQ(ierr); 11024222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_PtAP_HYPRE; 11034222ddf1SHong Zhang C->ops->ptapnumeric = MatPtAPNumeric_HYPRE_HYPRE; 11044222ddf1SHong Zhang PetscFunctionReturn(0); 11054222ddf1SHong Zhang } 11064222ddf1SHong Zhang 11074222ddf1SHong Zhang /* A is AIJ, P is Hypre, C = PtAP can be either AIJ or Hypre format */ 11084222ddf1SHong Zhang /* Get runtime option */ 11094222ddf1SHong Zhang if (product->api_user) { 11104222ddf1SHong Zhang ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)C),((PetscObject)C)->prefix,"MatPtAP_HYPRE","Mat");CHKERRQ(ierr); 11114222ddf1SHong Zhang ierr = PetscOptionsEList("-matptap_hypre_outtype","MatPtAP outtype","MatPtAP outtype",outTypes,ntype,outTypes[type],&type,&flg);CHKERRQ(ierr); 11124222ddf1SHong Zhang ierr = PetscOptionsEnd();CHKERRQ(ierr); 11134222ddf1SHong Zhang } else { 11144222ddf1SHong Zhang ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)C),((PetscObject)C)->prefix,"MatProduct_PtAP_HYPRE","Mat");CHKERRQ(ierr); 11154222ddf1SHong Zhang ierr = PetscOptionsEList("-matproduct_ptap_hypre_outtype","MatProduct_PtAP outtype","MatProduct_PtAP",outTypes,ntype,outTypes[type],&type,&flg);CHKERRQ(ierr); 11164222ddf1SHong Zhang ierr = PetscOptionsEnd();CHKERRQ(ierr); 11174222ddf1SHong Zhang } 11184222ddf1SHong Zhang 11194222ddf1SHong Zhang if (type == 0 || type == 1 || type == 2) { 11204222ddf1SHong Zhang ierr = MatSetType(C,MATAIJ);CHKERRQ(ierr); 11214222ddf1SHong Zhang } else if (type == 3) { 11224222ddf1SHong Zhang ierr = MatSetType(C,MATHYPRE);CHKERRQ(ierr); 11234222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_SUP,"MatPtAP outtype is not supported"); 11244222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_PtAP_HYPRE; 11254222ddf1SHong Zhang C->ops->ptapnumeric = MatPtAPNumeric_AIJ_HYPRE; 11264222ddf1SHong Zhang PetscFunctionReturn(0); 11274222ddf1SHong Zhang } 11284222ddf1SHong Zhang 11294222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_HYPRE(Mat C) 11304222ddf1SHong Zhang { 11314222ddf1SHong Zhang PetscErrorCode ierr; 11324222ddf1SHong Zhang Mat_Product *product = C->product; 11334222ddf1SHong Zhang 11344222ddf1SHong Zhang PetscFunctionBegin; 11354222ddf1SHong Zhang switch (product->type) { 11364222ddf1SHong Zhang case MATPRODUCT_AB: 11374222ddf1SHong Zhang ierr = MatProductSetFromOptions_HYPRE_AB(C);CHKERRQ(ierr); 11384222ddf1SHong Zhang break; 11394222ddf1SHong Zhang case MATPRODUCT_PtAP: 11404222ddf1SHong Zhang ierr = MatProductSetFromOptions_HYPRE_PtAP(C);CHKERRQ(ierr); 11414222ddf1SHong Zhang break; 11426718818eSStefano Zampini default: 11436718818eSStefano Zampini break; 11444222ddf1SHong Zhang } 11454222ddf1SHong Zhang PetscFunctionReturn(0); 11464222ddf1SHong Zhang } 11474222ddf1SHong Zhang 11484222ddf1SHong Zhang /* -------------------------------------------------------- */ 11494222ddf1SHong Zhang 1150ea9daf28SStefano Zampini static PetscErrorCode MatMultTranspose_HYPRE(Mat A, Vec x, Vec y) 115163c07aadSStefano Zampini { 115263c07aadSStefano Zampini PetscErrorCode ierr; 115363c07aadSStefano Zampini 115463c07aadSStefano Zampini PetscFunctionBegin; 1155414bd5c3SStefano Zampini ierr = MatHYPRE_MultKernel_Private(A,1.0,x,0.0,y,PETSC_TRUE);CHKERRQ(ierr); 115663c07aadSStefano Zampini PetscFunctionReturn(0); 115763c07aadSStefano Zampini } 115863c07aadSStefano Zampini 1159ea9daf28SStefano Zampini static PetscErrorCode MatMult_HYPRE(Mat A, Vec x, Vec y) 116063c07aadSStefano Zampini { 116163c07aadSStefano Zampini PetscErrorCode ierr; 116263c07aadSStefano Zampini 116363c07aadSStefano Zampini PetscFunctionBegin; 1164414bd5c3SStefano Zampini ierr = MatHYPRE_MultKernel_Private(A,1.0,x,0.0,y,PETSC_FALSE);CHKERRQ(ierr); 116563c07aadSStefano Zampini PetscFunctionReturn(0); 116663c07aadSStefano Zampini } 116763c07aadSStefano Zampini 1168414bd5c3SStefano Zampini static PetscErrorCode MatMultAdd_HYPRE(Mat A, Vec x, Vec y, Vec z) 1169414bd5c3SStefano Zampini { 1170414bd5c3SStefano Zampini PetscErrorCode ierr; 1171414bd5c3SStefano Zampini 1172414bd5c3SStefano Zampini PetscFunctionBegin; 1173414bd5c3SStefano Zampini if (y != z) { 1174414bd5c3SStefano Zampini ierr = VecCopy(y,z);CHKERRQ(ierr); 1175414bd5c3SStefano Zampini } 1176414bd5c3SStefano Zampini ierr = MatHYPRE_MultKernel_Private(A,1.0,x,1.0,z,PETSC_FALSE);CHKERRQ(ierr); 1177414bd5c3SStefano Zampini PetscFunctionReturn(0); 1178414bd5c3SStefano Zampini } 1179414bd5c3SStefano Zampini 1180414bd5c3SStefano Zampini static PetscErrorCode MatMultTransposeAdd_HYPRE(Mat A, Vec x, Vec y, Vec z) 1181414bd5c3SStefano Zampini { 1182414bd5c3SStefano Zampini PetscErrorCode ierr; 1183414bd5c3SStefano Zampini 1184414bd5c3SStefano Zampini PetscFunctionBegin; 1185414bd5c3SStefano Zampini if (y != z) { 1186414bd5c3SStefano Zampini ierr = VecCopy(y,z);CHKERRQ(ierr); 1187414bd5c3SStefano Zampini } 1188414bd5c3SStefano Zampini ierr = MatHYPRE_MultKernel_Private(A,1.0,x,1.0,z,PETSC_TRUE);CHKERRQ(ierr); 1189414bd5c3SStefano Zampini PetscFunctionReturn(0); 1190414bd5c3SStefano Zampini } 1191414bd5c3SStefano Zampini 1192414bd5c3SStefano Zampini /* y = a * A * x + b * y or y = a * A^t * x + b * y depending on trans */ 119339accc25SStefano Zampini static PetscErrorCode MatHYPRE_MultKernel_Private(Mat A, HYPRE_Complex a, Vec x, HYPRE_Complex b, Vec y, PetscBool trans) 119463c07aadSStefano Zampini { 119563c07aadSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 119663c07aadSStefano Zampini hypre_ParCSRMatrix *parcsr; 119763c07aadSStefano Zampini hypre_ParVector *hx,*hy; 119863c07aadSStefano Zampini PetscErrorCode ierr; 119963c07aadSStefano Zampini 120063c07aadSStefano Zampini PetscFunctionBegin; 120163c07aadSStefano Zampini if (trans) { 1202*6ea7df73SStefano Zampini ierr = VecHYPRE_IJVectorPushVecRead(hA->b,x);CHKERRQ(ierr); 1203*6ea7df73SStefano Zampini if (b != 0.0) { ierr = VecHYPRE_IJVectorPushVec(hA->x,y);CHKERRQ(ierr); } 1204*6ea7df73SStefano Zampini else { ierr = VecHYPRE_IJVectorPushVecWrite(hA->x,y);CHKERRQ(ierr); } 1205*6ea7df73SStefano Zampini PetscStackCallStandard(HYPRE_IJVectorGetObject,(hA->b->ij,(void**)&hx)); 1206*6ea7df73SStefano Zampini PetscStackCallStandard(HYPRE_IJVectorGetObject,(hA->x->ij,(void**)&hy)); 120763c07aadSStefano Zampini } else { 1208*6ea7df73SStefano Zampini ierr = VecHYPRE_IJVectorPushVecRead(hA->x,x);CHKERRQ(ierr); 1209*6ea7df73SStefano Zampini if (b != 0.0) { ierr = VecHYPRE_IJVectorPushVec(hA->b,y);CHKERRQ(ierr); } 1210*6ea7df73SStefano Zampini else { ierr = VecHYPRE_IJVectorPushVecWrite(hA->b,y);CHKERRQ(ierr); } 1211*6ea7df73SStefano Zampini PetscStackCallStandard(HYPRE_IJVectorGetObject,(hA->x->ij,(void**)&hx)); 1212*6ea7df73SStefano Zampini PetscStackCallStandard(HYPRE_IJVectorGetObject,(hA->b->ij,(void**)&hy)); 121363c07aadSStefano Zampini } 1214*6ea7df73SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hA->ij,(void**)&parcsr)); 1215*6ea7df73SStefano Zampini if (trans) { 1216*6ea7df73SStefano Zampini PetscStackCallStandard(hypre_ParCSRMatrixMatvecT,(a,parcsr,hx,b,hy)); 1217*6ea7df73SStefano Zampini } else { 1218*6ea7df73SStefano Zampini PetscStackCallStandard(hypre_ParCSRMatrixMatvec,(a,parcsr,hx,b,hy)); 1219*6ea7df73SStefano Zampini } 1220*6ea7df73SStefano Zampini ierr = VecHYPRE_IJVectorPopVec(hA->x);CHKERRQ(ierr); 1221*6ea7df73SStefano Zampini ierr = VecHYPRE_IJVectorPopVec(hA->b);CHKERRQ(ierr); 122263c07aadSStefano Zampini PetscFunctionReturn(0); 122363c07aadSStefano Zampini } 122463c07aadSStefano Zampini 1225ea9daf28SStefano Zampini static PetscErrorCode MatDestroy_HYPRE(Mat A) 122663c07aadSStefano Zampini { 122763c07aadSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 122863c07aadSStefano Zampini PetscErrorCode ierr; 122963c07aadSStefano Zampini 123063c07aadSStefano Zampini PetscFunctionBegin; 1231*6ea7df73SStefano Zampini ierr = VecHYPRE_IJVectorDestroy(&hA->x);CHKERRQ(ierr); 1232*6ea7df73SStefano Zampini ierr = VecHYPRE_IJVectorDestroy(&hA->b);CHKERRQ(ierr); 1233978814f1SStefano Zampini if (hA->ij) { 1234978814f1SStefano Zampini if (!hA->inner_free) hypre_IJMatrixObject(hA->ij) = NULL; 1235978814f1SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixDestroy,(hA->ij)); 1236978814f1SStefano Zampini } 1237ffc4695bSBarry Smith if (hA->comm) {ierr = MPI_Comm_free(&hA->comm);CHKERRMPI(ierr);} 1238c69f721fSFande Kong 1239c69f721fSFande Kong ierr = MatStashDestroy_Private(&A->stash);CHKERRQ(ierr); 1240c69f721fSFande Kong 1241c69f721fSFande Kong ierr = PetscFree(hA->array);CHKERRQ(ierr); 1242c69f721fSFande Kong 124363c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_hypre_aij_C",NULL);CHKERRQ(ierr); 12442df22349SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_hypre_is_C",NULL);CHKERRQ(ierr); 12454222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqaij_hypre_C",NULL);CHKERRQ(ierr); 12464222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_mpiaij_hypre_C",NULL);CHKERRQ(ierr); 1247d975228cSstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatHYPRESetPreallocation_C",NULL);CHKERRQ(ierr); 1248dd9c0a25Sstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatHYPREGetParCSR_C",NULL);CHKERRQ(ierr); 124963c07aadSStefano Zampini ierr = PetscFree(A->data);CHKERRQ(ierr); 125063c07aadSStefano Zampini PetscFunctionReturn(0); 125163c07aadSStefano Zampini } 125263c07aadSStefano Zampini 1253ea9daf28SStefano Zampini static PetscErrorCode MatSetUp_HYPRE(Mat A) 125463c07aadSStefano Zampini { 12554ec6421dSstefano_zampini PetscErrorCode ierr; 12564ec6421dSstefano_zampini 12574ec6421dSstefano_zampini PetscFunctionBegin; 12584ec6421dSstefano_zampini ierr = MatHYPRESetPreallocation(A,PETSC_DEFAULT,NULL,PETSC_DEFAULT,NULL);CHKERRQ(ierr); 12594ec6421dSstefano_zampini PetscFunctionReturn(0); 12604ec6421dSstefano_zampini } 12614ec6421dSstefano_zampini 1262*6ea7df73SStefano Zampini //TODO FIX hypre_CSRMatrixMatvecOutOfPlace 1263*6ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 1264*6ea7df73SStefano Zampini static PetscErrorCode MatBindToCPU_HYPRE(Mat A, PetscBool bind) 1265*6ea7df73SStefano Zampini { 1266*6ea7df73SStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 1267*6ea7df73SStefano Zampini HYPRE_MemoryLocation hmem = bind ? HYPRE_MEMORY_HOST : HYPRE_MEMORY_DEVICE; 1268*6ea7df73SStefano Zampini PetscErrorCode ierr; 1269*6ea7df73SStefano Zampini 1270*6ea7df73SStefano Zampini PetscFunctionBegin; 1271*6ea7df73SStefano Zampini A->boundtocpu = bind; 1272*6ea7df73SStefano Zampini if (hypre_IJMatrixAssembleFlag(hA->ij) && hmem != hypre_IJMatrixMemoryLocation(hA->ij)) { 1273*6ea7df73SStefano Zampini hypre_ParCSRMatrix *parcsr; 1274*6ea7df73SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hA->ij,(void**)&parcsr)); 1275*6ea7df73SStefano Zampini PetscStackCallStandard(hypre_ParCSRMatrixMigrate,(parcsr, hmem)); 1276*6ea7df73SStefano Zampini } 1277*6ea7df73SStefano Zampini if (hA->x) { ierr = VecHYPRE_IJBindToCPU(hA->x,bind);CHKERRQ(ierr); } 1278*6ea7df73SStefano Zampini if (hA->b) { ierr = VecHYPRE_IJBindToCPU(hA->b,bind);CHKERRQ(ierr); } 1279*6ea7df73SStefano Zampini PetscFunctionReturn(0); 1280*6ea7df73SStefano Zampini } 1281*6ea7df73SStefano Zampini #endif 1282*6ea7df73SStefano Zampini 12834ec6421dSstefano_zampini static PetscErrorCode MatAssemblyEnd_HYPRE(Mat A, MatAssemblyType mode) 12844ec6421dSstefano_zampini { 128563c07aadSStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 1286c69f721fSFande Kong PetscMPIInt n; 1287c69f721fSFande Kong PetscInt i,j,rstart,ncols,flg; 1288c69f721fSFande Kong PetscInt *row,*col; 1289c69f721fSFande Kong PetscScalar *val; 129063c07aadSStefano Zampini PetscErrorCode ierr; 129163c07aadSStefano Zampini 129263c07aadSStefano Zampini PetscFunctionBegin; 12934ec6421dSstefano_zampini if (mode == MAT_FLUSH_ASSEMBLY) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MAT_FLUSH_ASSEMBLY currently not supported with MATHYPRE"); 1294c69f721fSFande Kong 1295c69f721fSFande Kong if (!A->nooffprocentries) { 1296c69f721fSFande Kong while (1) { 1297c69f721fSFande Kong ierr = MatStashScatterGetMesg_Private(&A->stash,&n,&row,&col,&val,&flg);CHKERRQ(ierr); 1298c69f721fSFande Kong if (!flg) break; 1299c69f721fSFande Kong 1300c69f721fSFande Kong for (i=0; i<n;) { 1301c69f721fSFande Kong /* Now identify the consecutive vals belonging to the same row */ 1302c69f721fSFande Kong for (j=i,rstart=row[j]; j<n; j++) { 1303c69f721fSFande Kong if (row[j] != rstart) break; 1304c69f721fSFande Kong } 1305c69f721fSFande Kong if (j < n) ncols = j-i; 1306c69f721fSFande Kong else ncols = n-i; 1307c69f721fSFande Kong /* Now assemble all these values with a single function call */ 1308c69f721fSFande Kong ierr = MatSetValues_HYPRE(A,1,row+i,ncols,col+i,val+i,A->insertmode);CHKERRQ(ierr); 1309c69f721fSFande Kong 1310c69f721fSFande Kong i = j; 1311c69f721fSFande Kong } 1312c69f721fSFande Kong } 1313c69f721fSFande Kong ierr = MatStashScatterEnd_Private(&A->stash);CHKERRQ(ierr); 1314c69f721fSFande Kong } 1315c69f721fSFande Kong 13164ec6421dSstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixAssemble,(hA->ij)); 1317336664bdSPierre Jolivet /* The assembly routine destroys the aux_matrix, we recreate it here by calling HYPRE_IJMatrixInitialize */ 1318336664bdSPierre 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 */ 1319336664bdSPierre Jolivet if (!hA->sorted_full) { 1320af1cf968SStefano Zampini hypre_AuxParCSRMatrix *aux_matrix; 1321af1cf968SStefano Zampini 1322af1cf968SStefano Zampini /* call destroy just to make sure we do not leak anything */ 1323af1cf968SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix*)hypre_IJMatrixTranslator(hA->ij); 1324af1cf968SStefano Zampini PetscStackCallStandard(hypre_AuxParCSRMatrixDestroy,(aux_matrix)); 1325af1cf968SStefano Zampini hypre_IJMatrixTranslator(hA->ij) = NULL; 1326af1cf968SStefano Zampini 1327af1cf968SStefano Zampini /* Initialize with assembled flag -> it only recreates the aux_par_matrix */ 1328af1cf968SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixInitialize,(hA->ij)); 1329af1cf968SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix*)hypre_IJMatrixTranslator(hA->ij); 1330*6ea7df73SStefano Zampini if (aux_matrix) { 1331af1cf968SStefano Zampini hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 1; /* see comment in MatHYPRESetPreallocation_HYPRE */ 133222235d61SPierre Jolivet #if PETSC_PKG_HYPRE_VERSION_LT(2,19,0) 1333af1cf968SStefano Zampini PetscStackCallStandard(hypre_AuxParCSRMatrixInitialize,(aux_matrix)); 133422235d61SPierre Jolivet #else 133522235d61SPierre Jolivet PetscStackCallStandard(hypre_AuxParCSRMatrixInitialize_v2,(aux_matrix,HYPRE_MEMORY_HOST)); 133622235d61SPierre Jolivet #endif 1337af1cf968SStefano Zampini } 1338*6ea7df73SStefano Zampini } 1339*6ea7df73SStefano Zampini { 1340*6ea7df73SStefano Zampini hypre_ParCSRMatrix *parcsr; 1341*6ea7df73SStefano Zampini 1342*6ea7df73SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hA->ij,(void**)&parcsr)); 1343*6ea7df73SStefano Zampini if (!hypre_ParCSRMatrixCommPkg(parcsr)) PetscStackCallStandard(hypre_MatvecCommPkgCreate,(parcsr)); 1344*6ea7df73SStefano Zampini } 1345*6ea7df73SStefano Zampini if (!hA->x) { ierr = VecHYPRE_IJVectorCreate(A->cmap,&hA->x);CHKERRQ(ierr); } 1346*6ea7df73SStefano Zampini if (!hA->b) { ierr = VecHYPRE_IJVectorCreate(A->rmap,&hA->b);CHKERRQ(ierr); } 1347*6ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 1348*6ea7df73SStefano Zampini ierr = MatBindToCPU_HYPRE(A,A->boundtocpu);CHKERRQ(ierr); 1349*6ea7df73SStefano Zampini #endif 135063c07aadSStefano Zampini PetscFunctionReturn(0); 135163c07aadSStefano Zampini } 135263c07aadSStefano Zampini 1353c69f721fSFande Kong static PetscErrorCode MatGetArray_HYPRE(Mat A, PetscInt size, void **array) 1354c69f721fSFande Kong { 1355c69f721fSFande Kong Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 1356c69f721fSFande Kong PetscErrorCode ierr; 1357c69f721fSFande Kong 1358c69f721fSFande Kong PetscFunctionBegin; 1359c69f721fSFande Kong if (!hA->available) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Temporary space is in use"); 1360c69f721fSFande Kong 136139accc25SStefano Zampini if (hA->size >= size) { 136239accc25SStefano Zampini *array = hA->array; 136339accc25SStefano Zampini } else { 1364c69f721fSFande Kong ierr = PetscFree(hA->array);CHKERRQ(ierr); 1365c69f721fSFande Kong hA->size = size; 1366c69f721fSFande Kong ierr = PetscMalloc(hA->size,&hA->array);CHKERRQ(ierr); 1367c69f721fSFande Kong *array = hA->array; 1368c69f721fSFande Kong } 1369c69f721fSFande Kong 1370c69f721fSFande Kong hA->available = PETSC_FALSE; 1371c69f721fSFande Kong PetscFunctionReturn(0); 1372c69f721fSFande Kong } 1373c69f721fSFande Kong 1374708542d2SFande Kong static PetscErrorCode MatRestoreArray_HYPRE(Mat A, void **array) 1375c69f721fSFande Kong { 1376c69f721fSFande Kong Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 1377c69f721fSFande Kong 1378c69f721fSFande Kong PetscFunctionBegin; 1379c69f721fSFande Kong *array = NULL; 1380c69f721fSFande Kong hA->available = PETSC_TRUE; 1381c69f721fSFande Kong PetscFunctionReturn(0); 1382c69f721fSFande Kong } 1383c69f721fSFande Kong 1384*6ea7df73SStefano Zampini static PetscErrorCode MatSetValues_HYPRE(Mat A, PetscInt nr, const PetscInt rows[], PetscInt nc, const PetscInt cols[], const PetscScalar v[], InsertMode ins) 1385d975228cSstefano_zampini { 1386d975228cSstefano_zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 1387d975228cSstefano_zampini PetscScalar *vals = (PetscScalar *)v; 138839accc25SStefano Zampini HYPRE_Complex *sscr; 1389c69f721fSFande Kong PetscInt *cscr[2]; 1390c69f721fSFande Kong PetscInt i,nzc; 139108defe43SFande Kong void *array = NULL; 1392d975228cSstefano_zampini PetscErrorCode ierr; 1393d975228cSstefano_zampini 1394d975228cSstefano_zampini PetscFunctionBegin; 139539accc25SStefano Zampini ierr = MatGetArray_HYPRE(A,sizeof(PetscInt)*(2*nc)+sizeof(HYPRE_Complex)*nc*nr,&array);CHKERRQ(ierr); 1396c69f721fSFande Kong cscr[0] = (PetscInt*)array; 1397c69f721fSFande Kong cscr[1] = ((PetscInt*)array)+nc; 139839accc25SStefano Zampini sscr = (HYPRE_Complex*)(((PetscInt*)array)+nc*2); 1399d975228cSstefano_zampini for (i=0,nzc=0;i<nc;i++) { 1400d975228cSstefano_zampini if (cols[i] >= 0) { 1401d975228cSstefano_zampini cscr[0][nzc ] = cols[i]; 1402d975228cSstefano_zampini cscr[1][nzc++] = i; 1403d975228cSstefano_zampini } 1404d975228cSstefano_zampini } 1405c69f721fSFande Kong if (!nzc) { 1406708542d2SFande Kong ierr = MatRestoreArray_HYPRE(A,&array);CHKERRQ(ierr); 1407c69f721fSFande Kong PetscFunctionReturn(0); 1408c69f721fSFande Kong } 1409d975228cSstefano_zampini 1410*6ea7df73SStefano Zampini #if 0 //defined(PETSC_HAVE_HYPRE_DEVICE) 1411*6ea7df73SStefano Zampini if (HYPRE_MEMORY_HOST != hypre_IJMatrixMemoryLocation(hA->ij)) { 1412*6ea7df73SStefano Zampini hypre_ParCSRMatrix *parcsr; 1413*6ea7df73SStefano Zampini 1414*6ea7df73SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hA->ij,(void**)&parcsr)); 1415*6ea7df73SStefano Zampini PetscStackCallStandard(hypre_ParCSRMatrixMigrate,(parcsr, HYPRE_MEMORY_HOST)); 1416*6ea7df73SStefano Zampini } 1417*6ea7df73SStefano Zampini #endif 1418*6ea7df73SStefano Zampini 1419d975228cSstefano_zampini if (ins == ADD_VALUES) { 1420d975228cSstefano_zampini for (i=0;i<nr;i++) { 1421*6ea7df73SStefano Zampini if (rows[i] >= 0) { 1422d975228cSstefano_zampini PetscInt j; 14232cf14000SStefano Zampini HYPRE_Int hnc = (HYPRE_Int)nzc; 14242cf14000SStefano Zampini 14252cf14000SStefano Zampini if ((PetscInt)hnc != nzc) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Hypre overflow! number of columns %D for row %D",nzc,rows[i]); 14261e1ea65dSPierre Jolivet for (j=0;j<nzc;j++) { ierr = PetscHYPREScalarCast(vals[cscr[1][j]],&sscr[j]);CHKERRQ(ierr); } 14272cf14000SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixAddToValues,(hA->ij,1,&hnc,(HYPRE_BigInt*)(rows+i),(HYPRE_BigInt*)cscr[0],sscr)); 1428d975228cSstefano_zampini } 1429d975228cSstefano_zampini vals += nc; 1430d975228cSstefano_zampini } 1431d975228cSstefano_zampini } else { /* INSERT_VALUES */ 1432d975228cSstefano_zampini PetscInt rst,ren; 1433c69f721fSFande Kong 1434c6698e78SStefano Zampini ierr = MatGetOwnershipRange(A,&rst,&ren);CHKERRQ(ierr); 1435d975228cSstefano_zampini for (i=0;i<nr;i++) { 1436*6ea7df73SStefano Zampini if (rows[i] >= 0) { 1437d975228cSstefano_zampini PetscInt j; 14382cf14000SStefano Zampini HYPRE_Int hnc = (HYPRE_Int)nzc; 14392cf14000SStefano Zampini 14402cf14000SStefano Zampini if ((PetscInt)hnc != nzc) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Hypre overflow! number of columns %D for row %D",nzc,rows[i]); 14411e1ea65dSPierre Jolivet for (j=0;j<nzc;j++) { ierr = PetscHYPREScalarCast(vals[cscr[1][j]],&sscr[j]);CHKERRQ(ierr); } 1442c69f721fSFande Kong /* nonlocal values */ 144339accc25SStefano Zampini if (rows[i] < rst || rows[i] >= ren) { ierr = MatStashValuesRow_Private(&A->stash,rows[i],nzc,cscr[0],(PetscScalar*)sscr,PETSC_FALSE);CHKERRQ(ierr); } 1444c69f721fSFande Kong /* local values */ 14452cf14000SStefano Zampini else PetscStackCallStandard(HYPRE_IJMatrixSetValues,(hA->ij,1,&hnc,(HYPRE_BigInt*)(rows+i),(HYPRE_BigInt*)cscr[0],sscr)); 1446d975228cSstefano_zampini } 1447d975228cSstefano_zampini vals += nc; 1448d975228cSstefano_zampini } 1449d975228cSstefano_zampini } 1450c69f721fSFande Kong 1451708542d2SFande Kong ierr = MatRestoreArray_HYPRE(A,&array);CHKERRQ(ierr); 1452d975228cSstefano_zampini PetscFunctionReturn(0); 1453d975228cSstefano_zampini } 1454d975228cSstefano_zampini 1455d975228cSstefano_zampini static PetscErrorCode MatHYPRESetPreallocation_HYPRE(Mat A, PetscInt dnz, const PetscInt dnnz[], PetscInt onz, const PetscInt onnz[]) 1456d975228cSstefano_zampini { 1457d975228cSstefano_zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 14587d968826Sstefano_zampini HYPRE_Int *hdnnz,*honnz; 145906a29025Sstefano_zampini PetscInt i,rs,re,cs,ce,bs; 1460d975228cSstefano_zampini PetscMPIInt size; 1461d975228cSstefano_zampini PetscErrorCode ierr; 1462d975228cSstefano_zampini 1463d975228cSstefano_zampini PetscFunctionBegin; 146406a29025Sstefano_zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 1465d975228cSstefano_zampini ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 1466d975228cSstefano_zampini ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 1467d975228cSstefano_zampini rs = A->rmap->rstart; 1468d975228cSstefano_zampini re = A->rmap->rend; 1469d975228cSstefano_zampini cs = A->cmap->rstart; 1470d975228cSstefano_zampini ce = A->cmap->rend; 1471d975228cSstefano_zampini if (!hA->ij) { 1472d975228cSstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixCreate,(hA->comm,rs,re-1,cs,ce-1,&hA->ij)); 1473d975228cSstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixSetObjectType,(hA->ij,HYPRE_PARCSR)); 1474d975228cSstefano_zampini } else { 14752cf14000SStefano Zampini HYPRE_BigInt hrs,hre,hcs,hce; 1476d975228cSstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetLocalRange,(hA->ij,&hrs,&hre,&hcs,&hce)); 14772cf14000SStefano 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); 14782cf14000SStefano 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); 1479d975228cSstefano_zampini } 148006a29025Sstefano_zampini if (dnz == PETSC_DEFAULT || dnz == PETSC_DECIDE) dnz = 10*bs; 148106a29025Sstefano_zampini if (onz == PETSC_DEFAULT || onz == PETSC_DECIDE) onz = 10*bs; 148206a29025Sstefano_zampini 1483d975228cSstefano_zampini if (!dnnz) { 1484d975228cSstefano_zampini ierr = PetscMalloc1(A->rmap->n,&hdnnz);CHKERRQ(ierr); 1485d975228cSstefano_zampini for (i=0;i<A->rmap->n;i++) hdnnz[i] = dnz; 1486d975228cSstefano_zampini } else { 14877d968826Sstefano_zampini hdnnz = (HYPRE_Int*)dnnz; 1488d975228cSstefano_zampini } 1489ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRMPI(ierr); 1490d975228cSstefano_zampini if (size > 1) { 1491ddbeb582SStefano Zampini hypre_AuxParCSRMatrix *aux_matrix; 1492d975228cSstefano_zampini if (!onnz) { 1493d975228cSstefano_zampini ierr = PetscMalloc1(A->rmap->n,&honnz);CHKERRQ(ierr); 1494d975228cSstefano_zampini for (i=0;i<A->rmap->n;i++) honnz[i] = onz; 149522235d61SPierre Jolivet } else honnz = (HYPRE_Int*)onnz; 1496ddbeb582SStefano Zampini /* SetDiagOffdSizes sets hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 0, since it seems 1497ddbeb582SStefano Zampini they assume the user will input the entire row values, properly sorted 1498336664bdSPierre Jolivet In PETSc, we don't make such an assumption and set this flag to 1, 1499336664bdSPierre Jolivet unless the option MAT_SORTED_FULL is set to true. 1500ddbeb582SStefano Zampini Also, to avoid possible memory leaks, we destroy and recreate the translator 1501ddbeb582SStefano Zampini This has to be done here, as HYPRE_IJMatrixInitialize will properly initialize 1502ddbeb582SStefano Zampini the IJ matrix for us */ 1503ddbeb582SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix*)hypre_IJMatrixTranslator(hA->ij); 1504ddbeb582SStefano Zampini hypre_AuxParCSRMatrixDestroy(aux_matrix); 1505ddbeb582SStefano Zampini hypre_IJMatrixTranslator(hA->ij) = NULL; 1506d975228cSstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixSetDiagOffdSizes,(hA->ij,hdnnz,honnz)); 1507ddbeb582SStefano Zampini aux_matrix = (hypre_AuxParCSRMatrix*)hypre_IJMatrixTranslator(hA->ij); 1508336664bdSPierre Jolivet hypre_AuxParCSRMatrixNeedAux(aux_matrix) = !hA->sorted_full; 1509d975228cSstefano_zampini } else { 1510d975228cSstefano_zampini honnz = NULL; 1511d975228cSstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixSetRowSizes,(hA->ij,hdnnz)); 1512d975228cSstefano_zampini } 1513ddbeb582SStefano Zampini 1514af1cf968SStefano Zampini /* reset assembled flag and call the initialize method */ 1515af1cf968SStefano Zampini hypre_IJMatrixAssembleFlag(hA->ij) = 0; 1516*6ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_LT(2,19,0) 1517ddbeb582SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixInitialize,(hA->ij)); 1518*6ea7df73SStefano Zampini #else 1519*6ea7df73SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixInitialize_v2,(hA->ij,HYPRE_MEMORY_HOST)); 1520*6ea7df73SStefano Zampini #endif 1521d975228cSstefano_zampini if (!dnnz) { 1522d975228cSstefano_zampini ierr = PetscFree(hdnnz);CHKERRQ(ierr); 1523d975228cSstefano_zampini } 1524d975228cSstefano_zampini if (!onnz && honnz) { 1525d975228cSstefano_zampini ierr = PetscFree(honnz);CHKERRQ(ierr); 1526d975228cSstefano_zampini } 1527af1cf968SStefano Zampini /* Match AIJ logic */ 152806a29025Sstefano_zampini A->preallocated = PETSC_TRUE; 1529af1cf968SStefano Zampini A->assembled = PETSC_FALSE; 1530d975228cSstefano_zampini PetscFunctionReturn(0); 1531d975228cSstefano_zampini } 1532d975228cSstefano_zampini 1533d975228cSstefano_zampini /*@C 1534d975228cSstefano_zampini MatHYPRESetPreallocation - Preallocates memory for a sparse parallel matrix in HYPRE IJ format 1535d975228cSstefano_zampini 1536d975228cSstefano_zampini Collective on Mat 1537d975228cSstefano_zampini 1538d975228cSstefano_zampini Input Parameters: 1539d975228cSstefano_zampini + A - the matrix 1540d975228cSstefano_zampini . dnz - number of nonzeros per row in DIAGONAL portion of local submatrix 1541d975228cSstefano_zampini (same value is used for all local rows) 1542d975228cSstefano_zampini . dnnz - array containing the number of nonzeros in the various rows of the 1543d975228cSstefano_zampini DIAGONAL portion of the local submatrix (possibly different for each row) 1544d975228cSstefano_zampini or NULL (PETSC_NULL_INTEGER in Fortran), if d_nz is used to specify the nonzero structure. 1545d975228cSstefano_zampini The size of this array is equal to the number of local rows, i.e 'm'. 1546d975228cSstefano_zampini For matrices that will be factored, you must leave room for (and set) 1547d975228cSstefano_zampini the diagonal entry even if it is zero. 1548d975228cSstefano_zampini . onz - number of nonzeros per row in the OFF-DIAGONAL portion of local 1549d975228cSstefano_zampini submatrix (same value is used for all local rows). 1550d975228cSstefano_zampini - onnz - array containing the number of nonzeros in the various rows of the 1551d975228cSstefano_zampini OFF-DIAGONAL portion of the local submatrix (possibly different for 1552d975228cSstefano_zampini each row) or NULL (PETSC_NULL_INTEGER in Fortran), if o_nz is used to specify the nonzero 1553d975228cSstefano_zampini structure. The size of this array is equal to the number 1554d975228cSstefano_zampini of local rows, i.e 'm'. 1555d975228cSstefano_zampini 155695452b02SPatrick Sanan Notes: 155795452b02SPatrick Sanan If the *nnz parameter is given then the *nz parameter is ignored; for sequential matrices, onz and onnz are ignored. 1558d975228cSstefano_zampini 1559d975228cSstefano_zampini Level: intermediate 1560d975228cSstefano_zampini 1561af1cf968SStefano Zampini .seealso: MatCreate(), MatMPIAIJSetPreallocation(), MATHYPRE 1562d975228cSstefano_zampini @*/ 1563d975228cSstefano_zampini PetscErrorCode MatHYPRESetPreallocation(Mat A, PetscInt dnz, const PetscInt dnnz[], PetscInt onz, const PetscInt onnz[]) 1564d975228cSstefano_zampini { 1565d975228cSstefano_zampini PetscErrorCode ierr; 1566d975228cSstefano_zampini 1567d975228cSstefano_zampini PetscFunctionBegin; 1568d975228cSstefano_zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 1569d975228cSstefano_zampini PetscValidType(A,1); 1570d975228cSstefano_zampini ierr = PetscTryMethod(A,"MatHYPRESetPreallocation_C",(Mat,PetscInt,const PetscInt[],PetscInt,const PetscInt[]),(A,dnz,dnnz,onz,onnz));CHKERRQ(ierr); 1571d975228cSstefano_zampini PetscFunctionReturn(0); 1572d975228cSstefano_zampini } 1573d975228cSstefano_zampini 1574225daaf8SStefano Zampini /* 1575225daaf8SStefano Zampini MatCreateFromParCSR - Creates a matrix from a hypre_ParCSRMatrix 1576225daaf8SStefano Zampini 1577225daaf8SStefano Zampini Collective 1578225daaf8SStefano Zampini 1579225daaf8SStefano Zampini Input Parameters: 158045b8d346SStefano Zampini + parcsr - the pointer to the hypre_ParCSRMatrix 1581bb4689ddSStefano Zampini . mtype - matrix type to be created. Currently MATAIJ, MATIS and MATHYPRE are supported. 1582225daaf8SStefano Zampini - copymode - PETSc copying options 1583225daaf8SStefano Zampini 1584225daaf8SStefano Zampini Output Parameter: 1585225daaf8SStefano Zampini . A - the matrix 1586225daaf8SStefano Zampini 1587225daaf8SStefano Zampini Level: intermediate 1588225daaf8SStefano Zampini 1589225daaf8SStefano Zampini .seealso: MatHYPRE, PetscCopyMode 1590225daaf8SStefano Zampini */ 159145b8d346SStefano Zampini PETSC_EXTERN PetscErrorCode MatCreateFromParCSR(hypre_ParCSRMatrix *parcsr, MatType mtype, PetscCopyMode copymode, Mat* A) 1592978814f1SStefano Zampini { 1593225daaf8SStefano Zampini Mat T; 1594978814f1SStefano Zampini Mat_HYPRE *hA; 1595978814f1SStefano Zampini MPI_Comm comm; 1596978814f1SStefano Zampini PetscInt rstart,rend,cstart,cend,M,N; 1597d248a85cSRichard Tran Mills PetscBool isseqaij,isseqaijmkl,ismpiaij,isaij,ishyp,isis; 1598978814f1SStefano Zampini PetscErrorCode ierr; 1599978814f1SStefano Zampini 1600978814f1SStefano Zampini PetscFunctionBegin; 1601978814f1SStefano Zampini comm = hypre_ParCSRMatrixComm(parcsr); 1602225daaf8SStefano Zampini ierr = PetscStrcmp(mtype,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 1603d248a85cSRichard Tran Mills ierr = PetscStrcmp(mtype,MATSEQAIJMKL,&isseqaijmkl);CHKERRQ(ierr); 1604225daaf8SStefano Zampini ierr = PetscStrcmp(mtype,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr); 1605225daaf8SStefano Zampini ierr = PetscStrcmp(mtype,MATAIJ,&isaij);CHKERRQ(ierr); 1606225daaf8SStefano Zampini ierr = PetscStrcmp(mtype,MATHYPRE,&ishyp);CHKERRQ(ierr); 16078cfe8d00SStefano Zampini ierr = PetscStrcmp(mtype,MATIS,&isis);CHKERRQ(ierr); 1608d248a85cSRichard Tran Mills isaij = (PetscBool)(isseqaij || isseqaijmkl || ismpiaij || isaij); 1609*6ea7df73SStefano Zampini /* TODO */ 1610d248a85cSRichard 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); 1611978814f1SStefano Zampini /* access ParCSRMatrix */ 1612978814f1SStefano Zampini rstart = hypre_ParCSRMatrixFirstRowIndex(parcsr); 1613978814f1SStefano Zampini rend = hypre_ParCSRMatrixLastRowIndex(parcsr); 1614978814f1SStefano Zampini cstart = hypre_ParCSRMatrixFirstColDiag(parcsr); 1615978814f1SStefano Zampini cend = hypre_ParCSRMatrixLastColDiag(parcsr); 1616978814f1SStefano Zampini M = hypre_ParCSRMatrixGlobalNumRows(parcsr); 1617978814f1SStefano Zampini N = hypre_ParCSRMatrixGlobalNumCols(parcsr); 1618978814f1SStefano Zampini 1619fa92c42cSstefano_zampini /* fix for empty local rows/columns */ 1620fa92c42cSstefano_zampini if (rend < rstart) rend = rstart; 1621fa92c42cSstefano_zampini if (cend < cstart) cend = cstart; 1622fa92c42cSstefano_zampini 1623e6471dc9SStefano Zampini /* PETSc convention */ 1624e6471dc9SStefano Zampini rend++; 1625e6471dc9SStefano Zampini cend++; 1626e6471dc9SStefano Zampini rend = PetscMin(rend,M); 1627e6471dc9SStefano Zampini cend = PetscMin(cend,N); 1628e6471dc9SStefano Zampini 1629978814f1SStefano Zampini /* create PETSc matrix with MatHYPRE */ 1630225daaf8SStefano Zampini ierr = MatCreate(comm,&T);CHKERRQ(ierr); 1631e6471dc9SStefano Zampini ierr = MatSetSizes(T,rend-rstart,cend-cstart,M,N);CHKERRQ(ierr); 1632225daaf8SStefano Zampini ierr = MatSetType(T,MATHYPRE);CHKERRQ(ierr); 1633225daaf8SStefano Zampini hA = (Mat_HYPRE*)(T->data); 1634978814f1SStefano Zampini 1635978814f1SStefano Zampini /* create HYPRE_IJMatrix */ 1636978814f1SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixCreate,(hA->comm,rstart,rend-1,cstart,cend-1,&hA->ij)); 163745b8d346SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixSetObjectType,(hA->ij,HYPRE_PARCSR)); 163845b8d346SStefano Zampini 1639*6ea7df73SStefano Zampini // TODO DEV 164045b8d346SStefano Zampini /* create new ParCSR object if needed */ 164145b8d346SStefano Zampini if (ishyp && copymode == PETSC_COPY_VALUES) { 164245b8d346SStefano Zampini hypre_ParCSRMatrix *new_parcsr; 1643*6ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_LT(2,18,0) 164445b8d346SStefano Zampini hypre_CSRMatrix *hdiag,*hoffd,*ndiag,*noffd; 164545b8d346SStefano Zampini 16460e6427aaSSatish Balay new_parcsr = hypre_ParCSRMatrixClone(parcsr,0); 164745b8d346SStefano Zampini hdiag = hypre_ParCSRMatrixDiag(parcsr); 164845b8d346SStefano Zampini hoffd = hypre_ParCSRMatrixOffd(parcsr); 164945b8d346SStefano Zampini ndiag = hypre_ParCSRMatrixDiag(new_parcsr); 165045b8d346SStefano Zampini noffd = hypre_ParCSRMatrixOffd(new_parcsr); 1651580bdb30SBarry Smith ierr = PetscArraycpy(hypre_CSRMatrixData(ndiag),hypre_CSRMatrixData(hdiag),hypre_CSRMatrixNumNonzeros(hdiag));CHKERRQ(ierr); 1652580bdb30SBarry Smith ierr = PetscArraycpy(hypre_CSRMatrixData(noffd),hypre_CSRMatrixData(hoffd),hypre_CSRMatrixNumNonzeros(hoffd));CHKERRQ(ierr); 1653*6ea7df73SStefano Zampini #else 1654*6ea7df73SStefano Zampini new_parcsr = hypre_ParCSRMatrixClone(parcsr,1); 1655*6ea7df73SStefano Zampini #endif 165645b8d346SStefano Zampini parcsr = new_parcsr; 165745b8d346SStefano Zampini copymode = PETSC_OWN_POINTER; 165845b8d346SStefano Zampini } 1659978814f1SStefano Zampini 1660978814f1SStefano Zampini /* set ParCSR object */ 1661978814f1SStefano Zampini hypre_IJMatrixObject(hA->ij) = parcsr; 16624ec6421dSstefano_zampini T->preallocated = PETSC_TRUE; 1663978814f1SStefano Zampini 1664978814f1SStefano Zampini /* set assembled flag */ 1665978814f1SStefano Zampini hypre_IJMatrixAssembleFlag(hA->ij) = 1; 1666*6ea7df73SStefano Zampini #if 0 1667978814f1SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixInitialize,(hA->ij)); 1668*6ea7df73SStefano Zampini #endif 1669225daaf8SStefano Zampini if (ishyp) { 16706d2a658fSstefano_zampini PetscMPIInt myid = 0; 16716d2a658fSstefano_zampini 16726d2a658fSstefano_zampini /* make sure we always have row_starts and col_starts available */ 16736d2a658fSstefano_zampini if (HYPRE_AssumedPartitionCheck()) { 1674ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm,&myid);CHKERRMPI(ierr); 16756d2a658fSstefano_zampini } 1676a1d2239cSSatish Balay #if defined(hypre_ParCSRMatrixOwnsRowStarts) 16776d2a658fSstefano_zampini if (!hypre_ParCSRMatrixOwnsColStarts(parcsr)) { 16786d2a658fSstefano_zampini PetscLayout map; 16796d2a658fSstefano_zampini 16806d2a658fSstefano_zampini ierr = MatGetLayouts(T,NULL,&map);CHKERRQ(ierr); 16816d2a658fSstefano_zampini ierr = PetscLayoutSetUp(map);CHKERRQ(ierr); 16822cf14000SStefano Zampini hypre_ParCSRMatrixColStarts(parcsr) = (HYPRE_BigInt*)(map->range + myid); 16836d2a658fSstefano_zampini } 16846d2a658fSstefano_zampini if (!hypre_ParCSRMatrixOwnsRowStarts(parcsr)) { 16856d2a658fSstefano_zampini PetscLayout map; 16866d2a658fSstefano_zampini 16876d2a658fSstefano_zampini ierr = MatGetLayouts(T,&map,NULL);CHKERRQ(ierr); 16886d2a658fSstefano_zampini ierr = PetscLayoutSetUp(map);CHKERRQ(ierr); 16892cf14000SStefano Zampini hypre_ParCSRMatrixRowStarts(parcsr) = (HYPRE_BigInt*)(map->range + myid); 16906d2a658fSstefano_zampini } 1691a1d2239cSSatish Balay #endif 1692978814f1SStefano Zampini /* prevent from freeing the pointer */ 1693978814f1SStefano Zampini if (copymode == PETSC_USE_POINTER) hA->inner_free = PETSC_FALSE; 1694225daaf8SStefano Zampini *A = T; 1695*6ea7df73SStefano Zampini ierr = MatSetOption(*A,MAT_SORTED_FULL,PETSC_TRUE);CHKERRQ(ierr); 1696978814f1SStefano Zampini ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1697978814f1SStefano Zampini ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1698bb4689ddSStefano Zampini } else if (isaij) { 1699bb4689ddSStefano Zampini if (copymode != PETSC_OWN_POINTER) { 1700225daaf8SStefano Zampini /* prevent from freeing the pointer */ 1701225daaf8SStefano Zampini hA->inner_free = PETSC_FALSE; 1702225daaf8SStefano Zampini ierr = MatConvert_HYPRE_AIJ(T,MATAIJ,MAT_INITIAL_MATRIX,A);CHKERRQ(ierr); 1703225daaf8SStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 1704225daaf8SStefano Zampini } else { /* AIJ return type with PETSC_OWN_POINTER */ 1705225daaf8SStefano Zampini ierr = MatConvert_HYPRE_AIJ(T,MATAIJ,MAT_INPLACE_MATRIX,&T);CHKERRQ(ierr); 1706225daaf8SStefano Zampini *A = T; 1707225daaf8SStefano Zampini } 1708bb4689ddSStefano Zampini } else if (isis) { 17098cfe8d00SStefano Zampini ierr = MatConvert_HYPRE_IS(T,MATIS,MAT_INITIAL_MATRIX,A);CHKERRQ(ierr); 17108cfe8d00SStefano Zampini if (copymode != PETSC_OWN_POINTER) hA->inner_free = PETSC_FALSE; 1711bb4689ddSStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 1712bb4689ddSStefano Zampini } 1713978814f1SStefano Zampini PetscFunctionReturn(0); 1714978814f1SStefano Zampini } 1715978814f1SStefano Zampini 171668ec7858SStefano Zampini static PetscErrorCode MatHYPREGetParCSR_HYPRE(Mat A, hypre_ParCSRMatrix **parcsr) 1717dd9c0a25Sstefano_zampini { 1718dd9c0a25Sstefano_zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 1719dd9c0a25Sstefano_zampini HYPRE_Int type; 1720dd9c0a25Sstefano_zampini 1721dd9c0a25Sstefano_zampini PetscFunctionBegin; 1722dd9c0a25Sstefano_zampini if (!hA->ij) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"HYPRE_IJMatrix not present"); 1723dd9c0a25Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObjectType,(hA->ij,&type)); 1724dd9c0a25Sstefano_zampini if (type != HYPRE_PARCSR) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"HYPRE_IJMatrix is not of type HYPRE_PARCSR"); 1725dd9c0a25Sstefano_zampini PetscStackCallStandard(HYPRE_IJMatrixGetObject,(hA->ij,(void**)parcsr)); 1726dd9c0a25Sstefano_zampini PetscFunctionReturn(0); 1727dd9c0a25Sstefano_zampini } 1728dd9c0a25Sstefano_zampini 1729dd9c0a25Sstefano_zampini /* 1730dd9c0a25Sstefano_zampini MatHYPREGetParCSR - Gets the pointer to the ParCSR matrix 1731dd9c0a25Sstefano_zampini 1732dd9c0a25Sstefano_zampini Not collective 1733dd9c0a25Sstefano_zampini 1734dd9c0a25Sstefano_zampini Input Parameters: 1735dd9c0a25Sstefano_zampini + A - the MATHYPRE object 1736dd9c0a25Sstefano_zampini 1737dd9c0a25Sstefano_zampini Output Parameter: 1738dd9c0a25Sstefano_zampini . parcsr - the pointer to the hypre_ParCSRMatrix 1739dd9c0a25Sstefano_zampini 1740dd9c0a25Sstefano_zampini Level: intermediate 1741dd9c0a25Sstefano_zampini 1742dd9c0a25Sstefano_zampini .seealso: MatHYPRE, PetscCopyMode 1743dd9c0a25Sstefano_zampini */ 1744dd9c0a25Sstefano_zampini PetscErrorCode MatHYPREGetParCSR(Mat A, hypre_ParCSRMatrix **parcsr) 1745dd9c0a25Sstefano_zampini { 1746dd9c0a25Sstefano_zampini PetscErrorCode ierr; 1747dd9c0a25Sstefano_zampini 1748dd9c0a25Sstefano_zampini PetscFunctionBegin; 1749dd9c0a25Sstefano_zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 1750dd9c0a25Sstefano_zampini PetscValidType(A,1); 1751dd9c0a25Sstefano_zampini ierr = PetscUseMethod(A,"MatHYPREGetParCSR_C",(Mat,hypre_ParCSRMatrix**),(A,parcsr));CHKERRQ(ierr); 1752dd9c0a25Sstefano_zampini PetscFunctionReturn(0); 1753dd9c0a25Sstefano_zampini } 1754dd9c0a25Sstefano_zampini 175568ec7858SStefano Zampini static PetscErrorCode MatMissingDiagonal_HYPRE(Mat A, PetscBool *missing, PetscInt *dd) 175668ec7858SStefano Zampini { 175768ec7858SStefano Zampini hypre_ParCSRMatrix *parcsr; 175868ec7858SStefano Zampini hypre_CSRMatrix *ha; 175968ec7858SStefano Zampini PetscInt rst; 176068ec7858SStefano Zampini PetscErrorCode ierr; 176168ec7858SStefano Zampini 176268ec7858SStefano Zampini PetscFunctionBegin; 176368ec7858SStefano Zampini if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented with non-square diagonal blocks"); 176468ec7858SStefano Zampini ierr = MatGetOwnershipRange(A,&rst,NULL);CHKERRQ(ierr); 176568ec7858SStefano Zampini ierr = MatHYPREGetParCSR_HYPRE(A,&parcsr);CHKERRQ(ierr); 176668ec7858SStefano Zampini if (missing) *missing = PETSC_FALSE; 176768ec7858SStefano Zampini if (dd) *dd = -1; 176868ec7858SStefano Zampini ha = hypre_ParCSRMatrixDiag(parcsr); 176968ec7858SStefano Zampini if (ha) { 177068299464SStefano Zampini PetscInt size,i; 177168299464SStefano Zampini HYPRE_Int *ii,*jj; 177268ec7858SStefano Zampini 177368ec7858SStefano Zampini size = hypre_CSRMatrixNumRows(ha); 177468ec7858SStefano Zampini ii = hypre_CSRMatrixI(ha); 177568ec7858SStefano Zampini jj = hypre_CSRMatrixJ(ha); 177668ec7858SStefano Zampini for (i = 0; i < size; i++) { 177768ec7858SStefano Zampini PetscInt j; 177868ec7858SStefano Zampini PetscBool found = PETSC_FALSE; 177968ec7858SStefano Zampini 178068ec7858SStefano Zampini for (j = ii[i]; j < ii[i+1] && !found; j++) 178168ec7858SStefano Zampini found = (jj[j] == i) ? PETSC_TRUE : PETSC_FALSE; 178268ec7858SStefano Zampini 178368ec7858SStefano Zampini if (!found) { 178468ec7858SStefano Zampini PetscInfo1(A,"Matrix is missing local diagonal entry %D\n",i); 178568ec7858SStefano Zampini if (missing) *missing = PETSC_TRUE; 178668ec7858SStefano Zampini if (dd) *dd = i+rst; 178768ec7858SStefano Zampini PetscFunctionReturn(0); 178868ec7858SStefano Zampini } 178968ec7858SStefano Zampini } 179068ec7858SStefano Zampini if (!size) { 179168ec7858SStefano Zampini PetscInfo(A,"Matrix has no diagonal entries therefore is missing diagonal\n"); 179268ec7858SStefano Zampini if (missing) *missing = PETSC_TRUE; 179368ec7858SStefano Zampini if (dd) *dd = rst; 179468ec7858SStefano Zampini } 179568ec7858SStefano Zampini } else { 179668ec7858SStefano Zampini PetscInfo(A,"Matrix has no diagonal entries therefore is missing diagonal\n"); 179768ec7858SStefano Zampini if (missing) *missing = PETSC_TRUE; 179868ec7858SStefano Zampini if (dd) *dd = rst; 179968ec7858SStefano Zampini } 180068ec7858SStefano Zampini PetscFunctionReturn(0); 180168ec7858SStefano Zampini } 180268ec7858SStefano Zampini 180368ec7858SStefano Zampini static PetscErrorCode MatScale_HYPRE(Mat A, PetscScalar s) 180468ec7858SStefano Zampini { 180568ec7858SStefano Zampini hypre_ParCSRMatrix *parcsr; 1806*6ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_LT(2,19,0) 180768ec7858SStefano Zampini hypre_CSRMatrix *ha; 1808*6ea7df73SStefano Zampini #endif 180968ec7858SStefano Zampini PetscErrorCode ierr; 181039accc25SStefano Zampini HYPRE_Complex hs; 181168ec7858SStefano Zampini 181268ec7858SStefano Zampini PetscFunctionBegin; 181339accc25SStefano Zampini ierr = PetscHYPREScalarCast(s,&hs);CHKERRQ(ierr); 181468ec7858SStefano Zampini ierr = MatHYPREGetParCSR_HYPRE(A,&parcsr);CHKERRQ(ierr); 1815*6ea7df73SStefano Zampini #if PETSC_PKG_HYPRE_VERSION_GE(2,19,0) 1816*6ea7df73SStefano Zampini PetscStackCallStandard(hypre_ParCSRMatrixScale,(parcsr,hs)); 1817*6ea7df73SStefano Zampini #else /* diagonal part */ 181868ec7858SStefano Zampini ha = hypre_ParCSRMatrixDiag(parcsr); 181968ec7858SStefano Zampini if (ha) { 182068299464SStefano Zampini PetscInt size,i; 182168299464SStefano Zampini HYPRE_Int *ii; 182239accc25SStefano Zampini HYPRE_Complex *a; 182368ec7858SStefano Zampini 182468ec7858SStefano Zampini size = hypre_CSRMatrixNumRows(ha); 182568ec7858SStefano Zampini a = hypre_CSRMatrixData(ha); 182668ec7858SStefano Zampini ii = hypre_CSRMatrixI(ha); 182739accc25SStefano Zampini for (i = 0; i < ii[size]; i++) a[i] *= hs; 182868ec7858SStefano Zampini } 182968ec7858SStefano Zampini /* offdiagonal part */ 183068ec7858SStefano Zampini ha = hypre_ParCSRMatrixOffd(parcsr); 183168ec7858SStefano Zampini if (ha) { 183268299464SStefano Zampini PetscInt size,i; 183368299464SStefano Zampini HYPRE_Int *ii; 183439accc25SStefano Zampini HYPRE_Complex *a; 183568ec7858SStefano Zampini 183668ec7858SStefano Zampini size = hypre_CSRMatrixNumRows(ha); 183768ec7858SStefano Zampini a = hypre_CSRMatrixData(ha); 183868ec7858SStefano Zampini ii = hypre_CSRMatrixI(ha); 183939accc25SStefano Zampini for (i = 0; i < ii[size]; i++) a[i] *= hs; 184068ec7858SStefano Zampini } 1841*6ea7df73SStefano Zampini #endif 184268ec7858SStefano Zampini PetscFunctionReturn(0); 184368ec7858SStefano Zampini } 184468ec7858SStefano Zampini 184568ec7858SStefano Zampini static PetscErrorCode MatZeroRowsColumns_HYPRE(Mat A, PetscInt numRows, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) 184668ec7858SStefano Zampini { 184768ec7858SStefano Zampini hypre_ParCSRMatrix *parcsr; 184868299464SStefano Zampini HYPRE_Int *lrows; 184968299464SStefano Zampini PetscInt rst,ren,i; 185068ec7858SStefano Zampini PetscErrorCode ierr; 185168ec7858SStefano Zampini 185268ec7858SStefano Zampini PetscFunctionBegin; 185368ec7858SStefano Zampini if (x || b) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"To be implemented"); 185468ec7858SStefano Zampini ierr = MatHYPREGetParCSR_HYPRE(A,&parcsr);CHKERRQ(ierr); 185568ec7858SStefano Zampini ierr = PetscMalloc1(numRows,&lrows);CHKERRQ(ierr); 185668ec7858SStefano Zampini ierr = MatGetOwnershipRange(A,&rst,&ren);CHKERRQ(ierr); 185768ec7858SStefano Zampini for (i=0;i<numRows;i++) { 185868ec7858SStefano Zampini if (rows[i] < rst || rows[i] >= ren) 185968ec7858SStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Non-local rows not yet supported"); 186068ec7858SStefano Zampini lrows[i] = rows[i] - rst; 186168ec7858SStefano Zampini } 186268ec7858SStefano Zampini PetscStackCallStandard(hypre_ParCSRMatrixEliminateRowsCols,(parcsr,numRows,lrows)); 186368ec7858SStefano Zampini ierr = PetscFree(lrows);CHKERRQ(ierr); 186468ec7858SStefano Zampini PetscFunctionReturn(0); 186568ec7858SStefano Zampini } 186668ec7858SStefano Zampini 1867c69f721fSFande Kong static PetscErrorCode MatZeroEntries_HYPRE_CSRMatrix(hypre_CSRMatrix *ha) 1868c69f721fSFande Kong { 1869c69f721fSFande Kong PetscErrorCode ierr; 1870c69f721fSFande Kong 1871c69f721fSFande Kong PetscFunctionBegin; 1872c69f721fSFande Kong if (ha) { 1873c69f721fSFande Kong HYPRE_Int *ii, size; 1874c69f721fSFande Kong HYPRE_Complex *a; 1875c69f721fSFande Kong 1876c69f721fSFande Kong size = hypre_CSRMatrixNumRows(ha); 1877c69f721fSFande Kong a = hypre_CSRMatrixData(ha); 1878c69f721fSFande Kong ii = hypre_CSRMatrixI(ha); 1879c69f721fSFande Kong 1880580bdb30SBarry Smith if (a) {ierr = PetscArrayzero(a,ii[size]);CHKERRQ(ierr);} 1881c69f721fSFande Kong } 1882c69f721fSFande Kong PetscFunctionReturn(0); 1883c69f721fSFande Kong } 1884c69f721fSFande Kong 1885c69f721fSFande Kong PetscErrorCode MatZeroEntries_HYPRE(Mat A) 1886c69f721fSFande Kong { 1887*6ea7df73SStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 1888*6ea7df73SStefano Zampini 1889*6ea7df73SStefano Zampini PetscFunctionBegin; 1890*6ea7df73SStefano Zampini if (HYPRE_MEMORY_DEVICE == hypre_IJMatrixMemoryLocation(hA->ij)) { 1891*6ea7df73SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixSetConstantValues,(hA->ij,0.0)); 1892*6ea7df73SStefano Zampini } else { 1893c69f721fSFande Kong hypre_ParCSRMatrix *parcsr; 1894c69f721fSFande Kong PetscErrorCode ierr; 1895c69f721fSFande Kong 1896c69f721fSFande Kong ierr = MatHYPREGetParCSR_HYPRE(A,&parcsr);CHKERRQ(ierr); 1897c69f721fSFande Kong ierr = MatZeroEntries_HYPRE_CSRMatrix(hypre_ParCSRMatrixDiag(parcsr));CHKERRQ(ierr); 1898c69f721fSFande Kong ierr = MatZeroEntries_HYPRE_CSRMatrix(hypre_ParCSRMatrixOffd(parcsr));CHKERRQ(ierr); 1899*6ea7df73SStefano Zampini } 1900c69f721fSFande Kong PetscFunctionReturn(0); 1901c69f721fSFande Kong } 1902c69f721fSFande Kong 190339accc25SStefano Zampini static PetscErrorCode MatZeroRows_HYPRE_CSRMatrix(hypre_CSRMatrix *hA,PetscInt N,const PetscInt rows[],HYPRE_Complex diag) 1904c69f721fSFande Kong { 190539accc25SStefano Zampini PetscInt ii; 190639accc25SStefano Zampini HYPRE_Int *i, *j; 190739accc25SStefano Zampini HYPRE_Complex *a; 1908c69f721fSFande Kong 1909c69f721fSFande Kong PetscFunctionBegin; 1910c69f721fSFande Kong if (!hA) PetscFunctionReturn(0); 1911c69f721fSFande Kong 191239accc25SStefano Zampini i = hypre_CSRMatrixI(hA); 191339accc25SStefano Zampini j = hypre_CSRMatrixJ(hA); 1914c69f721fSFande Kong a = hypre_CSRMatrixData(hA); 1915c69f721fSFande Kong 1916c69f721fSFande Kong for (ii = 0; ii < N; ii++) { 191739accc25SStefano Zampini HYPRE_Int jj, ibeg, iend, irow; 191839accc25SStefano Zampini 1919c69f721fSFande Kong irow = rows[ii]; 1920c69f721fSFande Kong ibeg = i[irow]; 1921c69f721fSFande Kong iend = i[irow+1]; 1922c69f721fSFande Kong for (jj = ibeg; jj < iend; jj++) 1923c69f721fSFande Kong if (j[jj] == irow) a[jj] = diag; 1924c69f721fSFande Kong else a[jj] = 0.0; 1925c69f721fSFande Kong } 1926c69f721fSFande Kong PetscFunctionReturn(0); 1927c69f721fSFande Kong } 1928c69f721fSFande Kong 1929ddbeb582SStefano Zampini static PetscErrorCode MatZeroRows_HYPRE(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 1930c69f721fSFande Kong { 1931c69f721fSFande Kong hypre_ParCSRMatrix *parcsr; 1932c69f721fSFande Kong PetscInt *lrows,len; 193339accc25SStefano Zampini HYPRE_Complex hdiag; 1934c69f721fSFande Kong PetscErrorCode ierr; 1935c69f721fSFande Kong 1936c69f721fSFande Kong PetscFunctionBegin; 1937c6698e78SStefano Zampini if (x || b) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Does not support to modify the solution and the right hand size"); 193839accc25SStefano Zampini ierr = PetscHYPREScalarCast(diag,&hdiag);CHKERRQ(ierr); 1939c69f721fSFande Kong /* retrieve the internal matrix */ 1940c69f721fSFande Kong ierr = MatHYPREGetParCSR_HYPRE(A,&parcsr);CHKERRQ(ierr); 1941c69f721fSFande Kong /* get locally owned rows */ 1942c69f721fSFande Kong ierr = MatZeroRowsMapLocal_Private(A,N,rows,&len,&lrows);CHKERRQ(ierr); 1943c69f721fSFande Kong /* zero diagonal part */ 194439accc25SStefano Zampini ierr = MatZeroRows_HYPRE_CSRMatrix(hypre_ParCSRMatrixDiag(parcsr),len,lrows,hdiag);CHKERRQ(ierr); 1945c69f721fSFande Kong /* zero off-diagonal part */ 1946c69f721fSFande Kong ierr = MatZeroRows_HYPRE_CSRMatrix(hypre_ParCSRMatrixOffd(parcsr),len,lrows,0.0);CHKERRQ(ierr); 1947c69f721fSFande Kong 1948c69f721fSFande Kong ierr = PetscFree(lrows);CHKERRQ(ierr); 1949c69f721fSFande Kong PetscFunctionReturn(0); 1950c69f721fSFande Kong } 1951c69f721fSFande Kong 1952ddbeb582SStefano Zampini static PetscErrorCode MatAssemblyBegin_HYPRE(Mat mat,MatAssemblyType mode) 1953c69f721fSFande Kong { 1954c69f721fSFande Kong PetscErrorCode ierr; 1955c69f721fSFande Kong 1956c69f721fSFande Kong PetscFunctionBegin; 1957c69f721fSFande Kong if (mat->nooffprocentries) PetscFunctionReturn(0); 1958c69f721fSFande Kong 1959c69f721fSFande Kong ierr = MatStashScatterBegin_Private(mat,&mat->stash,mat->rmap->range);CHKERRQ(ierr); 1960c69f721fSFande Kong PetscFunctionReturn(0); 1961c69f721fSFande Kong } 1962c69f721fSFande Kong 1963ddbeb582SStefano Zampini static PetscErrorCode MatGetRow_HYPRE(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 1964c69f721fSFande Kong { 1965c69f721fSFande Kong hypre_ParCSRMatrix *parcsr; 19662cf14000SStefano Zampini HYPRE_Int hnz; 1967c69f721fSFande Kong PetscErrorCode ierr; 1968c69f721fSFande Kong 1969c69f721fSFande Kong PetscFunctionBegin; 1970c69f721fSFande Kong /* retrieve the internal matrix */ 1971c69f721fSFande Kong ierr = MatHYPREGetParCSR_HYPRE(A,&parcsr);CHKERRQ(ierr); 1972c69f721fSFande Kong /* call HYPRE API */ 197339accc25SStefano Zampini PetscStackCallStandard(HYPRE_ParCSRMatrixGetRow,(parcsr,row,&hnz,(HYPRE_BigInt**)idx,(HYPRE_Complex**)v)); 19742cf14000SStefano Zampini if (nz) *nz = (PetscInt)hnz; 1975c69f721fSFande Kong PetscFunctionReturn(0); 1976c69f721fSFande Kong } 1977c69f721fSFande Kong 1978ddbeb582SStefano Zampini static PetscErrorCode MatRestoreRow_HYPRE(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 1979c69f721fSFande Kong { 1980c69f721fSFande Kong hypre_ParCSRMatrix *parcsr; 19812cf14000SStefano Zampini HYPRE_Int hnz; 1982c69f721fSFande Kong PetscErrorCode ierr; 1983c69f721fSFande Kong 1984c69f721fSFande Kong PetscFunctionBegin; 1985c69f721fSFande Kong /* retrieve the internal matrix */ 1986c69f721fSFande Kong ierr = MatHYPREGetParCSR_HYPRE(A,&parcsr);CHKERRQ(ierr); 1987c69f721fSFande Kong /* call HYPRE API */ 19882cf14000SStefano Zampini hnz = nz ? (HYPRE_Int)(*nz) : 0; 198939accc25SStefano Zampini PetscStackCallStandard(HYPRE_ParCSRMatrixRestoreRow,(parcsr,row,&hnz,(HYPRE_BigInt**)idx,(HYPRE_Complex**)v)); 1990c69f721fSFande Kong PetscFunctionReturn(0); 1991c69f721fSFande Kong } 1992c69f721fSFande Kong 1993ddbeb582SStefano Zampini static PetscErrorCode MatGetValues_HYPRE(Mat A,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[]) 1994c69f721fSFande Kong { 199545b8d346SStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 1996c69f721fSFande Kong PetscInt i; 19971d4906efSStefano Zampini 1998c69f721fSFande Kong PetscFunctionBegin; 1999c69f721fSFande Kong if (!m || !n) PetscFunctionReturn(0); 2000c69f721fSFande Kong /* Ignore negative row indices 2001c69f721fSFande Kong * And negative column indices should be automatically ignored in hypre 2002c69f721fSFande Kong * */ 20032cf14000SStefano Zampini for (i=0; i<m; i++) { 20042cf14000SStefano Zampini if (idxm[i] >= 0) { 20052cf14000SStefano Zampini HYPRE_Int hn = (HYPRE_Int)n; 200639accc25SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixGetValues,(hA->ij,1,&hn,(HYPRE_BigInt*)&idxm[i],(HYPRE_BigInt*)idxn,(HYPRE_Complex*)(v + i*n))); 20072cf14000SStefano Zampini } 20082cf14000SStefano Zampini } 2009c69f721fSFande Kong PetscFunctionReturn(0); 2010c69f721fSFande Kong } 2011c69f721fSFande Kong 2012ddbeb582SStefano Zampini static PetscErrorCode MatSetOption_HYPRE(Mat A,MatOption op,PetscBool flg) 2013ddbeb582SStefano Zampini { 2014ddbeb582SStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 2015ddbeb582SStefano Zampini 2016ddbeb582SStefano Zampini PetscFunctionBegin; 2017c6698e78SStefano Zampini switch (op) { 2018ddbeb582SStefano Zampini case MAT_NO_OFF_PROC_ENTRIES: 2019ddbeb582SStefano Zampini if (flg) { 2020ddbeb582SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixSetMaxOffProcElmts,(hA->ij,0)); 2021ddbeb582SStefano Zampini } 2022ddbeb582SStefano Zampini break; 2023336664bdSPierre Jolivet case MAT_SORTED_FULL: 2024336664bdSPierre Jolivet hA->sorted_full = flg; 2025336664bdSPierre Jolivet break; 2026ddbeb582SStefano Zampini default: 2027ddbeb582SStefano Zampini break; 2028ddbeb582SStefano Zampini } 2029ddbeb582SStefano Zampini PetscFunctionReturn(0); 2030ddbeb582SStefano Zampini } 2031c69f721fSFande Kong 203245b8d346SStefano Zampini static PetscErrorCode MatView_HYPRE(Mat A, PetscViewer view) 203345b8d346SStefano Zampini { 203445b8d346SStefano Zampini PetscErrorCode ierr; 203545b8d346SStefano Zampini PetscViewerFormat format; 203645b8d346SStefano Zampini 203745b8d346SStefano Zampini PetscFunctionBegin; 203845b8d346SStefano Zampini ierr = PetscViewerGetFormat(view,&format);CHKERRQ(ierr); 2039*6ea7df73SStefano Zampini if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) PetscFunctionReturn(0); 204045b8d346SStefano Zampini if (format != PETSC_VIEWER_NATIVE) { 2041*6ea7df73SStefano Zampini Mat B; 2042*6ea7df73SStefano Zampini hypre_ParCSRMatrix *parcsr; 2043*6ea7df73SStefano Zampini PetscErrorCode (*mview)(Mat,PetscViewer) = NULL; 2044*6ea7df73SStefano Zampini 204545b8d346SStefano Zampini ierr = MatHYPREGetParCSR_HYPRE(A,&parcsr);CHKERRQ(ierr); 204645b8d346SStefano Zampini ierr = MatCreateFromParCSR(parcsr,MATAIJ,PETSC_USE_POINTER,&B);CHKERRQ(ierr); 204745b8d346SStefano Zampini ierr = MatGetOperation(B,MATOP_VIEW,(void(**)(void))&mview);CHKERRQ(ierr); 20482758c9b9SBarry Smith if (!mview) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Missing view operation"); 204945b8d346SStefano Zampini ierr = (*mview)(B,view);CHKERRQ(ierr); 205045b8d346SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 205145b8d346SStefano Zampini } else { 205245b8d346SStefano Zampini Mat_HYPRE *hA = (Mat_HYPRE*)A->data; 205345b8d346SStefano Zampini PetscMPIInt size; 205445b8d346SStefano Zampini PetscBool isascii; 205545b8d346SStefano Zampini const char *filename; 205645b8d346SStefano Zampini 205745b8d346SStefano Zampini /* HYPRE uses only text files */ 205845b8d346SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)view,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 205945b8d346SStefano Zampini if (!isascii) SETERRQ1(PetscObjectComm((PetscObject)view),PETSC_ERR_SUP,"PetscViewerType %s: native HYPRE format needs PETSCVIEWERASCII",((PetscObject)view)->type_name); 206045b8d346SStefano Zampini ierr = PetscViewerFileGetName(view,&filename);CHKERRQ(ierr); 206145b8d346SStefano Zampini PetscStackCallStandard(HYPRE_IJMatrixPrint,(hA->ij,filename)); 2062ffc4695bSBarry Smith ierr = MPI_Comm_size(hA->comm,&size);CHKERRMPI(ierr); 206345b8d346SStefano Zampini if (size > 1) { 206445b8d346SStefano Zampini ierr = PetscViewerASCIIPrintf(view,"Matrix files: %s.%05d ... %s.%05d\n",filename,0,filename,size-1);CHKERRQ(ierr); 206545b8d346SStefano Zampini } else { 206645b8d346SStefano Zampini ierr = PetscViewerASCIIPrintf(view,"Matrix file: %s.%05d\n",filename,0);CHKERRQ(ierr); 206745b8d346SStefano Zampini } 206845b8d346SStefano Zampini } 206945b8d346SStefano Zampini PetscFunctionReturn(0); 207045b8d346SStefano Zampini } 207145b8d346SStefano Zampini 207245b8d346SStefano Zampini static PetscErrorCode MatDuplicate_HYPRE(Mat A,MatDuplicateOption op, Mat *B) 207345b8d346SStefano Zampini { 207445b8d346SStefano Zampini hypre_ParCSRMatrix *parcsr; 207545b8d346SStefano Zampini PetscErrorCode ierr; 207645b8d346SStefano Zampini PetscCopyMode cpmode; 207745b8d346SStefano Zampini 207845b8d346SStefano Zampini PetscFunctionBegin; 207945b8d346SStefano Zampini ierr = MatHYPREGetParCSR_HYPRE(A,&parcsr);CHKERRQ(ierr); 208045b8d346SStefano Zampini if (op == MAT_DO_NOT_COPY_VALUES || op == MAT_SHARE_NONZERO_PATTERN) { 20810e6427aaSSatish Balay parcsr = hypre_ParCSRMatrixClone(parcsr,0); 208245b8d346SStefano Zampini cpmode = PETSC_OWN_POINTER; 208345b8d346SStefano Zampini } else { 208445b8d346SStefano Zampini cpmode = PETSC_COPY_VALUES; 208545b8d346SStefano Zampini } 208645b8d346SStefano Zampini ierr = MatCreateFromParCSR(parcsr,MATHYPRE,cpmode,B);CHKERRQ(ierr); 208745b8d346SStefano Zampini PetscFunctionReturn(0); 208845b8d346SStefano Zampini } 208945b8d346SStefano Zampini 2090465edc17SStefano Zampini static PetscErrorCode MatCopy_HYPRE(Mat A, Mat B, MatStructure str) 2091465edc17SStefano Zampini { 2092465edc17SStefano Zampini hypre_ParCSRMatrix *acsr,*bcsr; 2093465edc17SStefano Zampini PetscErrorCode ierr; 2094465edc17SStefano Zampini 2095465edc17SStefano Zampini PetscFunctionBegin; 2096465edc17SStefano Zampini if (str == SAME_NONZERO_PATTERN && A->ops->copy == B->ops->copy) { 2097465edc17SStefano Zampini ierr = MatHYPREGetParCSR_HYPRE(A,&acsr);CHKERRQ(ierr); 2098465edc17SStefano Zampini ierr = MatHYPREGetParCSR_HYPRE(B,&bcsr);CHKERRQ(ierr); 2099465edc17SStefano Zampini PetscStackCallStandard(hypre_ParCSRMatrixCopy,(acsr,bcsr,1)); 21001e1ea65dSPierre Jolivet ierr = MatSetOption(B,MAT_SORTED_FULL,PETSC_TRUE);CHKERRQ(ierr); /* "perfect" preallocation, so no need for hypre_AuxParCSRMatrixNeedAux */ 2101465edc17SStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2102465edc17SStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2103465edc17SStefano Zampini } else { 2104465edc17SStefano Zampini ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 2105465edc17SStefano Zampini } 2106465edc17SStefano Zampini PetscFunctionReturn(0); 2107465edc17SStefano Zampini } 2108465edc17SStefano Zampini 21096305df00SStefano Zampini static PetscErrorCode MatGetDiagonal_HYPRE(Mat A, Vec d) 21106305df00SStefano Zampini { 21116305df00SStefano Zampini hypre_ParCSRMatrix *parcsr; 21126305df00SStefano Zampini hypre_CSRMatrix *dmat; 211339accc25SStefano Zampini HYPRE_Complex *a; 211439accc25SStefano Zampini HYPRE_Complex *data = NULL; 21152cf14000SStefano Zampini HYPRE_Int *diag = NULL; 21162cf14000SStefano Zampini PetscInt i; 21176305df00SStefano Zampini PetscBool cong; 21186305df00SStefano Zampini PetscErrorCode ierr; 21196305df00SStefano Zampini 21206305df00SStefano Zampini PetscFunctionBegin; 21216305df00SStefano Zampini ierr = MatHasCongruentLayouts(A,&cong);CHKERRQ(ierr); 21226305df00SStefano Zampini if (!cong) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Only for square matrices with same local distributions of rows and columns"); 212376bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 21246305df00SStefano Zampini PetscBool miss; 21256305df00SStefano Zampini ierr = MatMissingDiagonal(A,&miss,NULL);CHKERRQ(ierr); 21266305df00SStefano Zampini if (miss && A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented when diagonal entries are missing"); 21276305df00SStefano Zampini } 21286305df00SStefano Zampini ierr = MatHYPREGetParCSR_HYPRE(A,&parcsr);CHKERRQ(ierr); 21296305df00SStefano Zampini dmat = hypre_ParCSRMatrixDiag(parcsr); 21306305df00SStefano Zampini if (dmat) { 213139accc25SStefano Zampini /* this cast fixes the clang error: implicit conversion from 'HYPRE_Complex' (aka '_Complex double') to 'double' is not permitted in C++ */ 213239accc25SStefano Zampini ierr = VecGetArray(d,(PetscScalar**)&a);CHKERRQ(ierr); 21332cf14000SStefano Zampini diag = hypre_CSRMatrixI(dmat); 213439accc25SStefano Zampini data = hypre_CSRMatrixData(dmat); 21356305df00SStefano Zampini for (i=0;i<A->rmap->n;i++) a[i] = data[diag[i]]; 213639accc25SStefano Zampini ierr = VecRestoreArray(d,(PetscScalar**)&a);CHKERRQ(ierr); 21376305df00SStefano Zampini } 21386305df00SStefano Zampini PetscFunctionReturn(0); 21396305df00SStefano Zampini } 21406305df00SStefano Zampini 2141363d496dSStefano Zampini #include <petscblaslapack.h> 2142363d496dSStefano Zampini 2143363d496dSStefano Zampini static PetscErrorCode MatAXPY_HYPRE(Mat Y,PetscScalar a,Mat X,MatStructure str) 2144363d496dSStefano Zampini { 2145363d496dSStefano Zampini PetscErrorCode ierr; 2146363d496dSStefano Zampini 2147363d496dSStefano Zampini PetscFunctionBegin; 2148*6ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 2149*6ea7df73SStefano Zampini { 2150*6ea7df73SStefano Zampini Mat B; 2151*6ea7df73SStefano Zampini hypre_ParCSRMatrix *x,*y,*z; 2152*6ea7df73SStefano Zampini 2153*6ea7df73SStefano Zampini ierr = MatHYPREGetParCSR(Y,&y);CHKERRQ(ierr); 2154*6ea7df73SStefano Zampini ierr = MatHYPREGetParCSR(X,&x);CHKERRQ(ierr); 2155*6ea7df73SStefano Zampini PetscStackCallStandard(hypre_ParCSRMatrixAdd,(1.0,y,1.0,x,&z)); 2156*6ea7df73SStefano Zampini ierr = MatCreateFromParCSR(z,MATHYPRE,PETSC_OWN_POINTER,&B);CHKERRQ(ierr); 2157*6ea7df73SStefano Zampini ierr = MatHeaderMerge(Y,&B);CHKERRQ(ierr); 2158*6ea7df73SStefano Zampini } 2159*6ea7df73SStefano Zampini #else 2160363d496dSStefano Zampini if (str == SAME_NONZERO_PATTERN) { 2161363d496dSStefano Zampini hypre_ParCSRMatrix *x,*y; 2162363d496dSStefano Zampini hypre_CSRMatrix *xloc,*yloc; 2163363d496dSStefano Zampini PetscInt xnnz,ynnz; 216439accc25SStefano Zampini HYPRE_Complex *xarr,*yarr; 2165363d496dSStefano Zampini PetscBLASInt one=1,bnz; 2166363d496dSStefano Zampini 2167363d496dSStefano Zampini ierr = MatHYPREGetParCSR(Y,&y);CHKERRQ(ierr); 2168363d496dSStefano Zampini ierr = MatHYPREGetParCSR(X,&x);CHKERRQ(ierr); 2169363d496dSStefano Zampini 2170363d496dSStefano Zampini /* diagonal block */ 2171363d496dSStefano Zampini xloc = hypre_ParCSRMatrixDiag(x); 2172363d496dSStefano Zampini yloc = hypre_ParCSRMatrixDiag(y); 2173363d496dSStefano Zampini xnnz = 0; 2174363d496dSStefano Zampini ynnz = 0; 2175363d496dSStefano Zampini xarr = NULL; 2176363d496dSStefano Zampini yarr = NULL; 2177363d496dSStefano Zampini if (xloc) { 217839accc25SStefano Zampini xarr = hypre_CSRMatrixData(xloc); 2179363d496dSStefano Zampini xnnz = hypre_CSRMatrixNumNonzeros(xloc); 2180363d496dSStefano Zampini } 2181363d496dSStefano Zampini if (yloc) { 218239accc25SStefano Zampini yarr = hypre_CSRMatrixData(yloc); 2183363d496dSStefano Zampini ynnz = hypre_CSRMatrixNumNonzeros(yloc); 2184363d496dSStefano Zampini } 2185363d496dSStefano Zampini if (xnnz != ynnz) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Different number of nonzeros in diagonal block %D != %D",xnnz,ynnz); 2186363d496dSStefano Zampini ierr = PetscBLASIntCast(xnnz,&bnz);CHKERRQ(ierr); 218739accc25SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&a,(PetscScalar*)xarr,&one,(PetscScalar*)yarr,&one)); 2188363d496dSStefano Zampini 2189363d496dSStefano Zampini /* off-diagonal block */ 2190363d496dSStefano Zampini xloc = hypre_ParCSRMatrixOffd(x); 2191363d496dSStefano Zampini yloc = hypre_ParCSRMatrixOffd(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 off-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 } else if (str == SUBSET_NONZERO_PATTERN) { 2208363d496dSStefano Zampini ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr); 2209363d496dSStefano Zampini } else { 2210363d496dSStefano Zampini Mat B; 2211363d496dSStefano Zampini 2212363d496dSStefano Zampini ierr = MatAXPY_Basic_Preallocate(Y,X,&B);CHKERRQ(ierr); 2213363d496dSStefano Zampini ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr); 2214363d496dSStefano Zampini ierr = MatHeaderReplace(Y,&B);CHKERRQ(ierr); 2215363d496dSStefano Zampini } 2216*6ea7df73SStefano Zampini #endif 2217363d496dSStefano Zampini PetscFunctionReturn(0); 2218363d496dSStefano Zampini } 2219363d496dSStefano Zampini 2220a055b5aaSBarry Smith /*MC 2221a055b5aaSBarry Smith MATHYPRE - MATHYPRE = "hypre" - A matrix type to be used for sequential and parallel sparse matrices 2222a055b5aaSBarry Smith based on the hypre IJ interface. 2223a055b5aaSBarry Smith 2224a055b5aaSBarry Smith Level: intermediate 2225a055b5aaSBarry Smith 2226a055b5aaSBarry Smith .seealso: MatCreate() 2227a055b5aaSBarry Smith M*/ 2228a055b5aaSBarry Smith 222963c07aadSStefano Zampini PETSC_EXTERN PetscErrorCode MatCreate_HYPRE(Mat B) 223063c07aadSStefano Zampini { 223163c07aadSStefano Zampini Mat_HYPRE *hB; 223263c07aadSStefano Zampini PetscErrorCode ierr; 223363c07aadSStefano Zampini 223463c07aadSStefano Zampini PetscFunctionBegin; 223563c07aadSStefano Zampini ierr = PetscNewLog(B,&hB);CHKERRQ(ierr); 2236*6ea7df73SStefano Zampini 2237978814f1SStefano Zampini hB->inner_free = PETSC_TRUE; 2238c69f721fSFande Kong hB->available = PETSC_TRUE; 2239336664bdSPierre Jolivet hB->sorted_full = PETSC_FALSE; /* no assumption whether column indices are sorted or not */ 2240c69f721fSFande Kong hB->size = 0; 2241c69f721fSFande Kong hB->array = NULL; 2242978814f1SStefano Zampini 224363c07aadSStefano Zampini B->data = (void*)hB; 224463c07aadSStefano Zampini B->rmap->bs = 1; 224563c07aadSStefano Zampini B->assembled = PETSC_FALSE; 224663c07aadSStefano Zampini 2247de393100SStefano Zampini ierr = PetscMemzero(B->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 224863c07aadSStefano Zampini B->ops->mult = MatMult_HYPRE; 224963c07aadSStefano Zampini B->ops->multtranspose = MatMultTranspose_HYPRE; 2250414bd5c3SStefano Zampini B->ops->multadd = MatMultAdd_HYPRE; 2251414bd5c3SStefano Zampini B->ops->multtransposeadd = MatMultTransposeAdd_HYPRE; 225263c07aadSStefano Zampini B->ops->setup = MatSetUp_HYPRE; 225363c07aadSStefano Zampini B->ops->destroy = MatDestroy_HYPRE; 225463c07aadSStefano Zampini B->ops->assemblyend = MatAssemblyEnd_HYPRE; 2255c69f721fSFande Kong B->ops->assemblybegin = MatAssemblyBegin_HYPRE; 2256d975228cSstefano_zampini B->ops->setvalues = MatSetValues_HYPRE; 225768ec7858SStefano Zampini B->ops->missingdiagonal = MatMissingDiagonal_HYPRE; 225868ec7858SStefano Zampini B->ops->scale = MatScale_HYPRE; 225968ec7858SStefano Zampini B->ops->zerorowscolumns = MatZeroRowsColumns_HYPRE; 2260c69f721fSFande Kong B->ops->zeroentries = MatZeroEntries_HYPRE; 2261c69f721fSFande Kong B->ops->zerorows = MatZeroRows_HYPRE; 2262c69f721fSFande Kong B->ops->getrow = MatGetRow_HYPRE; 2263c69f721fSFande Kong B->ops->restorerow = MatRestoreRow_HYPRE; 2264c69f721fSFande Kong B->ops->getvalues = MatGetValues_HYPRE; 2265ddbeb582SStefano Zampini B->ops->setoption = MatSetOption_HYPRE; 226645b8d346SStefano Zampini B->ops->duplicate = MatDuplicate_HYPRE; 2267465edc17SStefano Zampini B->ops->copy = MatCopy_HYPRE; 226845b8d346SStefano Zampini B->ops->view = MatView_HYPRE; 22696305df00SStefano Zampini B->ops->getdiagonal = MatGetDiagonal_HYPRE; 2270363d496dSStefano Zampini B->ops->axpy = MatAXPY_HYPRE; 22714222ddf1SHong Zhang B->ops->productsetfromoptions = MatProductSetFromOptions_HYPRE; 2272*6ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 2273*6ea7df73SStefano Zampini B->ops->bindtocpu = MatBindToCPU_HYPRE; 2274*6ea7df73SStefano Zampini B->boundtocpu = PETSC_FALSE; 2275*6ea7df73SStefano Zampini #endif 227645b8d346SStefano Zampini 227745b8d346SStefano Zampini /* build cache for off array entries formed */ 227845b8d346SStefano Zampini ierr = MatStashCreate_Private(PetscObjectComm((PetscObject)B),1,&B->stash);CHKERRQ(ierr); 227963c07aadSStefano Zampini 2280ffc4695bSBarry Smith ierr = MPI_Comm_dup(PetscObjectComm((PetscObject)B),&hB->comm);CHKERRMPI(ierr); 228163c07aadSStefano Zampini ierr = PetscObjectChangeTypeName((PetscObject)B,MATHYPRE);CHKERRQ(ierr); 228263c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_hypre_aij_C",MatConvert_HYPRE_AIJ);CHKERRQ(ierr); 22832df22349SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_hypre_is_C",MatConvert_HYPRE_IS);CHKERRQ(ierr); 22844222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_hypre_C",MatProductSetFromOptions_HYPRE);CHKERRQ(ierr); 22854222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_mpiaij_hypre_C",MatProductSetFromOptions_HYPRE);CHKERRQ(ierr); 2286d975228cSstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatHYPRESetPreallocation_C",MatHYPRESetPreallocation_HYPRE);CHKERRQ(ierr); 2287dd9c0a25Sstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatHYPREGetParCSR_C",MatHYPREGetParCSR_HYPRE);CHKERRQ(ierr); 2288*6ea7df73SStefano Zampini #if defined(PETSC_HAVE_HYPRE_DEVICE) 2289*6ea7df73SStefano Zampini #if defined(HYPRE_USING_HIP) 2290*6ea7df73SStefano Zampini ierr = PetscHIPInitializeCheck();CHKERRQ(ierr); 2291*6ea7df73SStefano Zampini ierr = MatSetVecType(B,VECHIP);CHKERRQ(ierr); 2292*6ea7df73SStefano Zampini #endif 2293*6ea7df73SStefano Zampini #if defined(HYPRE_USING_CUDA) 2294*6ea7df73SStefano Zampini ierr = PetscCUDAInitializeCheck();CHKERRQ(ierr); 2295*6ea7df73SStefano Zampini ierr = MatSetVecType(B,VECCUDA);CHKERRQ(ierr); 2296*6ea7df73SStefano Zampini #endif 2297*6ea7df73SStefano Zampini #endif 229863c07aadSStefano Zampini PetscFunctionReturn(0); 229963c07aadSStefano Zampini } 230063c07aadSStefano Zampini 2301225daaf8SStefano Zampini static PetscErrorCode hypre_array_destroy(void *ptr) 2302225daaf8SStefano Zampini { 2303225daaf8SStefano Zampini PetscFunctionBegin; 2304e6de0934SSatish Balay hypre_TFree(ptr,HYPRE_MEMORY_HOST); 2305225daaf8SStefano Zampini PetscFunctionReturn(0); 2306225daaf8SStefano Zampini } 2307