Actual source code: mhyp.c

  1: #define PETSCMAT_DLL

  3: /*
  4:     Creates hypre ijmatrix from PETSc matrix
  5: */

 7:  #include private/matimpl.h
  9: #include "HYPRE.h"
 10: #include "HYPRE_parcsr_ls.h"

 15: PetscErrorCode MatHYPRE_IJMatrixPreallocate(Mat A_d, Mat A_o,HYPRE_IJMatrix ij)
 16: {
 18:   PetscInt       i;
 19:   PetscInt       n_d,*ia_d,n_o,*ia_o;
 20:   PetscTruth     done_d=PETSC_FALSE,done_o=PETSC_FALSE;
 21:   PetscInt       *nnz_d=PETSC_NULL,*nnz_o=PETSC_NULL;
 22: 
 24:   if (A_d) { /* determine number of nonzero entries in local diagonal part */
 25:     MatGetRowIJ(A_d,0,PETSC_FALSE,PETSC_FALSE,&n_d,&ia_d,PETSC_NULL,&done_d);
 26:     if (done_d) {
 27:       PetscMalloc(n_d*sizeof(PetscInt),&nnz_d);
 28:       for (i=0; i<n_d; i++) {
 29:         nnz_d[i] = ia_d[i+1] - ia_d[i];
 30:       }
 31:     }
 32:     MatRestoreRowIJ(A_d,0,PETSC_FALSE,PETSC_FALSE,&n_d,&ia_d,PETSC_NULL,&done_d);
 33:   }
 34:   if (A_o) { /* determine number of nonzero entries in local off-diagonal part */
 35:     MatGetRowIJ(A_o,0,PETSC_FALSE,PETSC_FALSE,&n_o,&ia_o,PETSC_NULL,&done_o);
 36:     if (done_o) {
 37:       PetscMalloc(n_o*sizeof(PetscInt),&nnz_o);
 38:       for (i=0; i<n_o; i++) {
 39:         nnz_o[i] = ia_o[i+1] - ia_o[i];
 40:       }
 41:     }
 42:     MatRestoreRowIJ(A_o,0,PETSC_FALSE,PETSC_FALSE,&n_o,&ia_o,PETSC_NULL,&done_o);
 43:   }
 44:   if (done_d) {    /* set number of nonzeros in HYPRE IJ matrix */
 45:     if (!done_o) { /* only diagonal part */
 46:       PetscMalloc(n_d*sizeof(PetscInt),&nnz_o);
 47:       for (i=0; i<n_d; i++) {
 48:         nnz_o[i] = 0;
 49:       }
 50:     }
 51:     HYPRE_IJMatrixSetDiagOffdSizes(ij,nnz_d,nnz_o);
 52:     PetscFree(nnz_d);
 53:     PetscFree(nnz_o);
 54:   }
 55:   return(0);
 56: }


 61: PetscErrorCode MatHYPRE_IJMatrixCreate(Mat A,HYPRE_IJMatrix *ij)
 62: {
 64:   int            rstart,rend,cstart,cend;
 65: 
 70:   MatPreallocated(A);
 71:   rstart = A->rmap->rstart;
 72:   rend   = A->rmap->rend;
 73:   cstart = A->cmap->rstart;
 74:   cend   = A->cmap->rend;
 75:   HYPRE_IJMatrixCreate(((PetscObject)A)->comm,rstart,rend-1,cstart,cend-1,ij);
 76:   HYPRE_IJMatrixSetObjectType(*ij,HYPRE_PARCSR);
 77:   {
 78:     PetscTruth  same;
 79:     Mat         A_d,A_o;
 80:     PetscInt    *colmap;
 81:     PetscTypeCompare((PetscObject)A,MATMPIAIJ,&same);
 82:     if (same) {
 83:       MatMPIAIJGetSeqAIJ(A,&A_d,&A_o,&colmap);
 84:       MatHYPRE_IJMatrixPreallocate(A_d,A_o,*ij);
 85:       return(0);
 86:     }
 87:     PetscTypeCompare((PetscObject)A,MATMPIBAIJ,&same);
 88:     if (same) {
 89:       MatMPIBAIJGetSeqBAIJ(A,&A_d,&A_o,&colmap);
 90:       MatHYPRE_IJMatrixPreallocate(A_d,A_o,*ij);
 91:       return(0);
 92:     }
 93:     PetscTypeCompare((PetscObject)A,MATSEQAIJ,&same);
 94:     if (same) {
 95:       MatHYPRE_IJMatrixPreallocate(A,PETSC_NULL,*ij);
 96:       return(0);
 97:     }
 98:     PetscTypeCompare((PetscObject)A,MATSEQBAIJ,&same);
 99:     if (same) {
100:       MatHYPRE_IJMatrixPreallocate(A,PETSC_NULL,*ij);
101:       return(0);
102:     }
103:   }
104:   return(0);
105: }

109: /*
110:     Copies the data over (column indices, numerical values) to hypre matrix  
111: */

115: PetscErrorCode MatHYPRE_IJMatrixCopy(Mat A,HYPRE_IJMatrix ij)
116: {
117:   PetscErrorCode    ierr;
118:   PetscInt          i,rstart,rend,ncols;
119:   const PetscScalar *values;
120:   const PetscInt    *cols;
121:   PetscTruth        flg;

124:   PetscTypeCompare((PetscObject)A,MATMPIAIJ,&flg);
125:   if (flg) {
126:     MatHYPRE_IJMatrixFastCopy_MPIAIJ(A,ij);
127:     return(0);
128:   }
129:   PetscTypeCompare((PetscObject)A,MATSEQAIJ,&flg);
130:   if (flg) {
131:     MatHYPRE_IJMatrixFastCopy_SeqAIJ(A,ij);
132:     return(0);
133:   }

135:   PetscLogEventBegin(MAT_Convert,A,0,0,0);
136:   HYPRE_IJMatrixInitialize(ij);
137:   MatGetOwnershipRange(A,&rstart,&rend);
138:   for (i=rstart; i<rend; i++) {
139:     MatGetRow(A,i,&ncols,&cols,&values);
140:     HYPRE_IJMatrixSetValues(ij,1,&ncols,&i,cols,values);
141:     MatRestoreRow(A,i,&ncols,&cols,&values);
142:   }
143:   HYPRE_IJMatrixAssemble(ij);
144:   PetscLogEventEnd(MAT_Convert,A,0,0,0);
145:   return(0);
146: }

148: /*
149:     This copies the CSR format directly from the PETSc data structure to the hypre 
150:     data structure without calls to MatGetRow() or hypre's set values.

152: */
153: #include "_hypre_IJ_mv.h"
154: #include "HYPRE_IJ_mv.h"
155:  #include ../src/mat/impls/aij/mpi/mpiaij.h

159: PetscErrorCode MatHYPRE_IJMatrixFastCopy_SeqAIJ(Mat A,HYPRE_IJMatrix ij)
160: {
161:   PetscErrorCode        ierr;
162:   Mat_SeqAIJ            *pdiag = (Mat_SeqAIJ*)A->data;;

164:   hypre_ParCSRMatrix    *par_matrix;
165:   hypre_AuxParCSRMatrix *aux_matrix;
166:   hypre_CSRMatrix       *hdiag,*hoffd;


173:   PetscLogEventBegin(MAT_Convert,A,0,0,0);
174:   HYPRE_IJMatrixInitialize(ij);
175:   par_matrix = (hypre_ParCSRMatrix*)hypre_IJMatrixObject(ij);
176:   aux_matrix = (hypre_AuxParCSRMatrix*)hypre_IJMatrixTranslator(ij);
177:   hdiag = hypre_ParCSRMatrixDiag(par_matrix);
178:   hoffd = hypre_ParCSRMatrixOffd(par_matrix);

180:   /* 
181:        this is the Hack part where we monkey directly with the hypre datastructures
182:   */

184:   PetscMemcpy(hdiag->i,pdiag->i,(A->rmap->n + 1)*sizeof(PetscInt));
185:   PetscMemcpy(hdiag->j,pdiag->j,pdiag->nz*sizeof(PetscInt));
186:   PetscMemcpy(hdiag->data,pdiag->a,pdiag->nz*sizeof(PetscScalar));

188:   hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 0;
189:   HYPRE_IJMatrixAssemble(ij);
190:   PetscLogEventEnd(MAT_Convert,A,0,0,0);
191:   return(0);
192: }

196: PetscErrorCode MatHYPRE_IJMatrixFastCopy_MPIAIJ(Mat A,HYPRE_IJMatrix ij)
197: {
198:   PetscErrorCode        ierr;
199:   Mat_MPIAIJ            *pA = (Mat_MPIAIJ*)A->data;
200:   Mat_SeqAIJ            *pdiag,*poffd;
201:   PetscInt              i,*garray = pA->garray,*jj,cstart,*pjj;

203:   hypre_ParCSRMatrix    *par_matrix;
204:   hypre_AuxParCSRMatrix *aux_matrix;
205:   hypre_CSRMatrix       *hdiag,*hoffd;

211:   pdiag = (Mat_SeqAIJ*) pA->A->data;
212:   poffd = (Mat_SeqAIJ*) pA->B->data;
213:   /* cstart is only valid for square MPIAIJ layed out in the usual way */
214:   MatGetOwnershipRange(A,&cstart,PETSC_NULL);

216:   PetscLogEventBegin(MAT_Convert,A,0,0,0);

218:   HYPRE_IJMatrixInitialize(ij);
219:   par_matrix = (hypre_ParCSRMatrix*)hypre_IJMatrixObject(ij);
220:   aux_matrix = (hypre_AuxParCSRMatrix*)hypre_IJMatrixTranslator(ij);
221:   hdiag = hypre_ParCSRMatrixDiag(par_matrix);
222:   hoffd = hypre_ParCSRMatrixOffd(par_matrix);

224:   /* 
225:        this is the Hack part where we monkey directly with the hypre datastructures
226:   */

228:   PetscMemcpy(hdiag->i,pdiag->i,(pA->A->rmap->n + 1)*sizeof(PetscInt));
229:   /* need to shift the diag column indices (hdiag->j) back to global numbering since hypre is expecting this */
230:   jj  = hdiag->j;
231:   pjj = pdiag->j;
232:   for (i=0; i<pdiag->nz; i++) {
233:     jj[i] = cstart + pjj[i];
234:   }
235:   PetscMemcpy(hdiag->data,pdiag->a,pdiag->nz*sizeof(PetscScalar));

237:   PetscMemcpy(hoffd->i,poffd->i,(pA->A->rmap->n + 1)*sizeof(PetscInt));
238:   /* need to move the offd column indices (hoffd->j) back to global numbering since hypre is expecting this
239:      If we hacked a hypre a bit more we might be able to avoid this step */
240:   jj  = hoffd->j;
241:   pjj = poffd->j;
242:   for (i=0; i<poffd->nz; i++) {
243:     jj[i] = garray[pjj[i]];
244:   }
245:   PetscMemcpy(hoffd->data,poffd->a,poffd->nz*sizeof(PetscScalar));

247:   hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 0;
248:   HYPRE_IJMatrixAssemble(ij);
249:   PetscLogEventEnd(MAT_Convert,A,0,0,0);
250:   return(0);
251: }

253: /*
254:     Does NOT copy the data over, instead uses DIRECTLY the pointers from the PETSc MPIAIJ format

256:     This is UNFINISHED and does NOT work! The problem is that hypre puts the diagonal entry first
257:     which will corrupt the PETSc data structure if we did this. Need a work around to this problem.
258: */
259: #include "_hypre_IJ_mv.h"
260: #include "HYPRE_IJ_mv.h"

264: PetscErrorCode MatHYPRE_IJMatrixLink(Mat A,HYPRE_IJMatrix *ij)
265: {
266:   PetscErrorCode        ierr;
267:   int                   rstart,rend,cstart,cend;
268:   PetscTruth            flg;
269:   hypre_ParCSRMatrix    *par_matrix;
270:   hypre_AuxParCSRMatrix *aux_matrix;

276:   PetscTypeCompare((PetscObject)A,MATMPIAIJ,&flg);
277:   if (!flg) SETERRQ(PETSC_ERR_SUP,"Can only use with PETSc MPIAIJ matrices");
278:   MatPreallocated(A);

280:   PetscLogEventBegin(MAT_Convert,A,0,0,0);
281:   rstart = A->rmap->rstart;
282:   rend   = A->rmap->rend;
283:   cstart = A->cmap->rstart;
284:   cend   = A->cmap->rend;
285:   HYPRE_IJMatrixCreate(((PetscObject)A)->comm,rstart,rend-1,cstart,cend-1,ij);
286:   HYPRE_IJMatrixSetObjectType(*ij,HYPRE_PARCSR);
287: 
288:   HYPRE_IJMatrixInitialize(*ij);
289:   par_matrix = (hypre_ParCSRMatrix*)hypre_IJMatrixObject(*ij);
290:   aux_matrix = (hypre_AuxParCSRMatrix*)hypre_IJMatrixTranslator(*ij);

292:   hypre_AuxParCSRMatrixNeedAux(aux_matrix) = 0;

294:   /* this is the Hack part where we monkey directly with the hypre datastructures */

296:   HYPRE_IJMatrixAssemble(*ij);
297:   PetscLogEventEnd(MAT_Convert,A,0,0,0);
298:   return(0);
299: }