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: }