xref: /petsc/src/mat/impls/adj/mpi/mpiadj.c (revision e1311b9049e89cb3452dcd306fde571f4b440ff2)
1b97cf49bSBarry Smith #ifdef PETSC_RCS_HEADER
2*e1311b90SBarry Smith static char vcid[] = "$Id: mpiadj.c,v 1.8 1998/03/12 23:19:41 bsmith Exp bsmith $";
3b97cf49bSBarry Smith #endif
4b97cf49bSBarry Smith 
5b97cf49bSBarry Smith /*
6b97cf49bSBarry Smith     Defines the basic matrix operations for the ADJ adjacency list matrix data-structure.
7b97cf49bSBarry Smith */
8b97cf49bSBarry Smith 
9b97cf49bSBarry Smith #include "pinclude/pviewer.h"
10b97cf49bSBarry Smith #include "sys.h"
110752156aSBarry Smith #include "src/mat/impls/adj/mpi/mpiadj.h"
12b97cf49bSBarry Smith 
13b97cf49bSBarry Smith 
14b97cf49bSBarry Smith #undef __FUNC__
150752156aSBarry Smith #define __FUNC__ "MatView_MPIAdj_ASCII"
160752156aSBarry Smith extern int MatView_MPIAdj_ASCII(Mat A,Viewer viewer)
17b97cf49bSBarry Smith {
180752156aSBarry Smith   Mat_MPIAdj  *a = (Mat_MPIAdj *) A->data;
19b97cf49bSBarry Smith   int         ierr, i,j, m = a->m,  format;
20b97cf49bSBarry Smith   FILE        *fd;
21b97cf49bSBarry Smith   char        *outputname;
220752156aSBarry Smith   MPI_Comm    comm = A->comm;
23b97cf49bSBarry Smith 
24b97cf49bSBarry Smith   ierr = ViewerASCIIGetPointer(viewer,&fd); CHKERRQ(ierr);
25b97cf49bSBarry Smith   ierr = ViewerFileGetOutputname_Private(viewer,&outputname); CHKERRQ(ierr);
26b97cf49bSBarry Smith   ierr = ViewerGetFormat(viewer,&format);
27b97cf49bSBarry Smith   if (format == VIEWER_FORMAT_ASCII_INFO) {
283a40ed3dSBarry Smith     PetscFunctionReturn(0);
290752156aSBarry Smith   } else {
30b97cf49bSBarry Smith     for ( i=0; i<m; i++ ) {
310752156aSBarry Smith       PetscSynchronizedFPrintf(comm,fd,"row %d:",i+a->rstart);
32b97cf49bSBarry Smith       for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
330752156aSBarry Smith         PetscSynchronizedFPrintf(comm,fd," %d ",a->j[j]);
340752156aSBarry Smith       }
350752156aSBarry Smith       PetscSynchronizedFPrintf(comm,fd,"\n");
36b97cf49bSBarry Smith     }
37b97cf49bSBarry Smith   }
380752156aSBarry Smith   PetscSynchronizedFlush(comm);
393a40ed3dSBarry Smith   PetscFunctionReturn(0);
40b97cf49bSBarry Smith }
41b97cf49bSBarry Smith 
42b97cf49bSBarry Smith #undef __FUNC__
430752156aSBarry Smith #define __FUNC__ "MatView_MPIAdj"
44*e1311b90SBarry Smith int MatView_MPIAdj(Mat A,Viewer viewer)
45b97cf49bSBarry Smith {
46b97cf49bSBarry Smith   ViewerType  vtype;
47b97cf49bSBarry Smith   int         ierr;
48b97cf49bSBarry Smith 
49b97cf49bSBarry Smith   ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr);
500752156aSBarry Smith   if (vtype == ASCII_FILE_VIEWER || vtype == ASCII_FILES_VIEWER){
513a40ed3dSBarry Smith     ierr = MatView_MPIAdj_ASCII(A,viewer);CHKERRQ(ierr);
52b97cf49bSBarry Smith   }
533a40ed3dSBarry Smith   PetscFunctionReturn(0);
54b97cf49bSBarry Smith }
55b97cf49bSBarry Smith 
56b97cf49bSBarry Smith #undef __FUNC__
570752156aSBarry Smith #define __FUNC__ "MatDestroy_MPIAdj"
58*e1311b90SBarry Smith int MatDestroy_MPIAdj(Mat A)
59b97cf49bSBarry Smith {
600752156aSBarry Smith   Mat_MPIAdj *a = (Mat_MPIAdj *) A->data;
61b97cf49bSBarry Smith 
623a40ed3dSBarry Smith #if defined(USE_PETSC_LOG)
63*e1311b90SBarry Smith   PLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",A->m,A->n,a->nz);
64b97cf49bSBarry Smith #endif
65b97cf49bSBarry Smith   if (a->diag) PetscFree(a->diag);
66b97cf49bSBarry Smith   PetscFree(a->i);
67b97cf49bSBarry Smith   PetscFree(a->j);
680752156aSBarry Smith   PetscFree(a->rowners);
69b97cf49bSBarry Smith   PetscFree(a);
70b97cf49bSBarry Smith 
71b97cf49bSBarry Smith   PLogObjectDestroy(A);
72b97cf49bSBarry Smith   PetscHeaderDestroy(A);
733a40ed3dSBarry Smith   PetscFunctionReturn(0);
74b97cf49bSBarry Smith }
75b97cf49bSBarry Smith 
76b97cf49bSBarry Smith 
77b97cf49bSBarry Smith #undef __FUNC__
780752156aSBarry Smith #define __FUNC__ "MatSetOption_MPIAdj"
790752156aSBarry Smith int MatSetOption_MPIAdj(Mat A,MatOption op)
80b97cf49bSBarry Smith {
810752156aSBarry Smith   Mat_MPIAdj *a = (Mat_MPIAdj *) A->data;
82b97cf49bSBarry Smith 
83b97cf49bSBarry Smith   if (op == MAT_STRUCTURALLY_SYMMETRIC) {
84b97cf49bSBarry Smith     a->symmetric = PETSC_TRUE;
85b97cf49bSBarry Smith   } else {
86981c4779SBarry Smith     PLogInfo(A,"MatSetOption_MPIAdj:Option ignored\n");
87b97cf49bSBarry Smith   }
883a40ed3dSBarry Smith   PetscFunctionReturn(0);
89b97cf49bSBarry Smith }
90b97cf49bSBarry Smith 
91b97cf49bSBarry Smith 
92b97cf49bSBarry Smith /*
93b97cf49bSBarry Smith      Adds diagonal pointers to sparse matrix structure.
94b97cf49bSBarry Smith */
95b97cf49bSBarry Smith 
96b97cf49bSBarry Smith #undef __FUNC__
970752156aSBarry Smith #define __FUNC__ "MatMarkDiag_MPIAdj"
980752156aSBarry Smith int MatMarkDiag_MPIAdj(Mat A)
99b97cf49bSBarry Smith {
1000752156aSBarry Smith   Mat_MPIAdj *a = (Mat_MPIAdj *) A->data;
101b97cf49bSBarry Smith   int        i,j, *diag, m = a->m;
102b97cf49bSBarry Smith 
103b97cf49bSBarry Smith   diag = (int *) PetscMalloc( (m+1)*sizeof(int)); CHKPTRQ(diag);
104b97cf49bSBarry Smith   PLogObjectMemory(A,(m+1)*sizeof(int));
105b97cf49bSBarry Smith   for ( i=0; i<a->m; i++ ) {
106b97cf49bSBarry Smith     for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
107b97cf49bSBarry Smith       if (a->j[j] == i) {
108b97cf49bSBarry Smith         diag[i] = j;
109b97cf49bSBarry Smith         break;
110b97cf49bSBarry Smith       }
111b97cf49bSBarry Smith     }
112b97cf49bSBarry Smith   }
113b97cf49bSBarry Smith   a->diag = diag;
1143a40ed3dSBarry Smith   PetscFunctionReturn(0);
115b97cf49bSBarry Smith }
116b97cf49bSBarry Smith 
117b97cf49bSBarry Smith #undef __FUNC__
1180752156aSBarry Smith #define __FUNC__ "MatGetSize_MPIAdj"
1190752156aSBarry Smith int MatGetSize_MPIAdj(Mat A,int *m,int *n)
120b97cf49bSBarry Smith {
1210752156aSBarry Smith   if (m) *m = A->M;
1220752156aSBarry Smith   if (n) *n = A->N;
1233a40ed3dSBarry Smith   PetscFunctionReturn(0);
124b97cf49bSBarry Smith }
125b97cf49bSBarry Smith 
126b97cf49bSBarry Smith #undef __FUNC__
1270752156aSBarry Smith #define __FUNC__ "MatGetSize_MPIAdj"
1280752156aSBarry Smith int MatGetLocalSize_MPIAdj(Mat A,int *m,int *n)
129b97cf49bSBarry Smith {
1300752156aSBarry Smith   Mat_MPIAdj *a = (Mat_MPIAdj *) A->data;
1310752156aSBarry Smith   if (m) *m = a->m;
1320752156aSBarry Smith   if (n) *n = A->N;
1333a40ed3dSBarry Smith   PetscFunctionReturn(0);
134b97cf49bSBarry Smith }
135b97cf49bSBarry Smith 
136b97cf49bSBarry Smith #undef __FUNC__
1370752156aSBarry Smith #define __FUNC__ "MatGetOwnershipRange_MPIAdj"
1380752156aSBarry Smith int MatGetOwnershipRange_MPIAdj(Mat A,int *m,int *n)
139b97cf49bSBarry Smith {
1400752156aSBarry Smith   Mat_MPIAdj *a = (Mat_MPIAdj *) A->data;
1410752156aSBarry Smith   *m = a->rstart; *n = a->rend;
1423a40ed3dSBarry Smith   PetscFunctionReturn(0);
143b97cf49bSBarry Smith }
144b97cf49bSBarry Smith 
145b97cf49bSBarry Smith #undef __FUNC__
1460752156aSBarry Smith #define __FUNC__ "MatGetRow_MPIAdj"
1470752156aSBarry Smith int MatGetRow_MPIAdj(Mat A,int row,int *nz,int **idx,Scalar **v)
148b97cf49bSBarry Smith {
1490752156aSBarry Smith   Mat_MPIAdj *a = (Mat_MPIAdj *) A->data;
150b97cf49bSBarry Smith   int        *itmp;
151b97cf49bSBarry Smith 
1520752156aSBarry Smith   row -= a->rstart;
1530752156aSBarry Smith 
154a8c6a408SBarry Smith   if (row < 0 || row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row out of range");
155b97cf49bSBarry Smith 
156b97cf49bSBarry Smith   *nz = a->i[row+1] - a->i[row];
157b97cf49bSBarry Smith   if (v) *v = PETSC_NULL;
158b97cf49bSBarry Smith   if (idx) {
159b97cf49bSBarry Smith     itmp = a->j + a->i[row];
160b97cf49bSBarry Smith     if (*nz) {
161b97cf49bSBarry Smith       *idx = itmp;
162b97cf49bSBarry Smith     }
163b97cf49bSBarry Smith     else *idx = 0;
164b97cf49bSBarry Smith   }
1653a40ed3dSBarry Smith   PetscFunctionReturn(0);
166b97cf49bSBarry Smith }
167b97cf49bSBarry Smith 
168b97cf49bSBarry Smith #undef __FUNC__
1690752156aSBarry Smith #define __FUNC__ "MatRestoreRow_MPIAdj"
1700752156aSBarry Smith int MatRestoreRow_MPIAdj(Mat A,int row,int *nz,int **idx,Scalar **v)
171b97cf49bSBarry Smith {
1723a40ed3dSBarry Smith   PetscFunctionReturn(0);
173b97cf49bSBarry Smith }
174b97cf49bSBarry Smith 
175b97cf49bSBarry Smith #undef __FUNC__
1760752156aSBarry Smith #define __FUNC__ "MatGetBlockSize_MPIAdj"
1770752156aSBarry Smith int MatGetBlockSize_MPIAdj(Mat A, int *bs)
178b97cf49bSBarry Smith {
179b97cf49bSBarry Smith   *bs = 1;
1803a40ed3dSBarry Smith   PetscFunctionReturn(0);
181b97cf49bSBarry Smith }
182b97cf49bSBarry Smith 
183b97cf49bSBarry Smith 
184b97cf49bSBarry Smith #undef __FUNC__
1850752156aSBarry Smith #define __FUNC__ "MatEqual_MPIAdj"
1860752156aSBarry Smith int MatEqual_MPIAdj(Mat A,Mat B, PetscTruth* flg)
187b97cf49bSBarry Smith {
1880752156aSBarry Smith   Mat_MPIAdj *a = (Mat_MPIAdj *)A->data, *b = (Mat_MPIAdj *)B->data;
189ca161407SBarry Smith  int         flag = 1,ierr;
190b97cf49bSBarry Smith 
191a8c6a408SBarry Smith   if (B->type != MATMPIADJ) SETERRQ(PETSC_ERR_ARG_INCOMP,0,"Matrices must be same type");
192b97cf49bSBarry Smith 
193b97cf49bSBarry Smith   /* If the  matrix dimensions are not equal, or no of nonzeros */
1940752156aSBarry Smith   if ((a->m != b->m ) ||( a->nz != b->nz)) {
1950752156aSBarry Smith     flag = 0;
196b97cf49bSBarry Smith   }
197b97cf49bSBarry Smith 
198b97cf49bSBarry Smith   /* if the a->i are the same */
199b97cf49bSBarry Smith   if (PetscMemcmp(a->i,b->i,(a->m+1)*sizeof(int))) {
2000752156aSBarry Smith     flag = 0;
201b97cf49bSBarry Smith   }
202b97cf49bSBarry Smith 
203b97cf49bSBarry Smith   /* if a->j are the same */
204b97cf49bSBarry Smith   if (PetscMemcmp(a->j, b->j, (a->nz)*sizeof(int))) {
2050752156aSBarry Smith     flag = 0;
206b97cf49bSBarry Smith   }
207b97cf49bSBarry Smith 
208ca161407SBarry Smith   ierr = MPI_Allreduce(&flag,flg,1,MPI_INT,MPI_LAND,A->comm);CHKERRQ(ierr);
2090752156aSBarry Smith 
2100752156aSBarry Smith 
2113a40ed3dSBarry Smith   PetscFunctionReturn(0);
212b97cf49bSBarry Smith }
213b97cf49bSBarry Smith 
214b97cf49bSBarry Smith 
215b97cf49bSBarry Smith /* -------------------------------------------------------------------*/
216b97cf49bSBarry Smith static struct _MatOps MatOps = {0,
2170752156aSBarry Smith        MatGetRow_MPIAdj,MatRestoreRow_MPIAdj,
218b97cf49bSBarry Smith        0,0,
219b97cf49bSBarry Smith        0,0,
220b97cf49bSBarry Smith        0,0,
221b97cf49bSBarry Smith        0,0,
222b97cf49bSBarry Smith        0,0,
223b97cf49bSBarry Smith        0,
224b97cf49bSBarry Smith        0,
2250752156aSBarry Smith        0,MatEqual_MPIAdj,
226b97cf49bSBarry Smith        0,0,0,
227b97cf49bSBarry Smith        0,0,
228b97cf49bSBarry Smith        0,
2290752156aSBarry Smith        MatSetOption_MPIAdj,0,0,
230b97cf49bSBarry Smith        0,0,0,0,
2310752156aSBarry Smith        MatGetSize_MPIAdj,MatGetLocalSize_MPIAdj,MatGetOwnershipRange_MPIAdj,
232b97cf49bSBarry Smith        0,0,
233b97cf49bSBarry Smith        0,0,
234b97cf49bSBarry Smith        0,0,0,
235b97cf49bSBarry Smith        0,0,0,
2360752156aSBarry Smith        0,0,
237b97cf49bSBarry Smith        0,0,
238b97cf49bSBarry Smith        0,
239b97cf49bSBarry Smith        0,0,0,
240b97cf49bSBarry Smith        0,
2410752156aSBarry Smith        MatGetBlockSize_MPIAdj,
242b97cf49bSBarry Smith        0,
243b97cf49bSBarry Smith        0,
244b97cf49bSBarry Smith        0,
245b97cf49bSBarry Smith        0,
246b97cf49bSBarry Smith        0,
2470752156aSBarry Smith        0,
2480752156aSBarry Smith        0,
2490752156aSBarry Smith        0};
250b97cf49bSBarry Smith 
251b97cf49bSBarry Smith 
252b97cf49bSBarry Smith #undef __FUNC__
2530752156aSBarry Smith #define __FUNC__ "MatCreateMPIAdj"
254b97cf49bSBarry Smith /*@C
2550752156aSBarry Smith    MatCreateMPIAdj - Creates a sparse matrix representing an adjacency list.
256b97cf49bSBarry Smith      The matrix does not have numerical values associated with it, but is
257b97cf49bSBarry Smith      intended for ordering (to reduce bandwidth etc) and partitioning.
258b97cf49bSBarry Smith 
259b97cf49bSBarry Smith    Input Parameters:
260b97cf49bSBarry Smith .  comm - MPI communicator, set to PETSC_COMM_SELF
2610752156aSBarry Smith .  m - number of local rows
262b97cf49bSBarry Smith .  n - number of columns
263b97cf49bSBarry Smith .  i - the indices into j for the start of each row
264b97cf49bSBarry Smith .  j - the column indices for each row (sorted for each row)
265b97cf49bSBarry Smith        The indices in i and j start with zero NOT one.
266b97cf49bSBarry Smith 
267b97cf49bSBarry Smith    Output Parameter:
268b97cf49bSBarry Smith .  A - the matrix
269b97cf49bSBarry Smith 
2700752156aSBarry Smith    Notes: You must NOT free the ii and jj arrays yourself. PETSc will free them
271b97cf49bSBarry Smith    when the matrix is destroyed.
272b97cf49bSBarry Smith 
273b58e66f3SSatish Balay .  MatSetOption() possible values - MAT_STRUCTURALLY_SYMMETRIC
274b97cf49bSBarry Smith 
2750752156aSBarry Smith .seealso: MatCreate(), MatCreateSeqAdj(), MatGetReordering()
276b97cf49bSBarry Smith @*/
2770752156aSBarry Smith int MatCreateMPIAdj(MPI_Comm comm,int m,int n,int *i,int *j, Mat *A)
278b97cf49bSBarry Smith {
279b97cf49bSBarry Smith   Mat        B;
2800752156aSBarry Smith   Mat_MPIAdj *b;
2810752156aSBarry Smith   int        ii,ierr, flg,size,rank;
282b97cf49bSBarry Smith 
283b97cf49bSBarry Smith   MPI_Comm_size(comm,&size);
2840752156aSBarry Smith   MPI_Comm_rank(comm,&rank);
285b97cf49bSBarry Smith 
286b97cf49bSBarry Smith   *A                  = 0;
287f830108cSBarry Smith   PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATMPIADJ,comm,MatDestroy,MatView);
288b97cf49bSBarry Smith   PLogObjectCreate(B);
2890752156aSBarry Smith   B->data             = (void *) (b = PetscNew(Mat_MPIAdj)); CHKPTRQ(b);
2900752156aSBarry Smith   PetscMemzero(b,sizeof(Mat_MPIAdj));
291f830108cSBarry Smith   PetscMemcpy(B->ops,&MatOps,sizeof(struct _MatOps));
292*e1311b90SBarry Smith   B->ops->destroy          = MatDestroy_MPIAdj;
293*e1311b90SBarry Smith   B->ops->view             = MatView_MPIAdj;
294b97cf49bSBarry Smith   B->factor           = 0;
295b97cf49bSBarry Smith   B->lupivotthreshold = 1.0;
296b97cf49bSBarry Smith   B->mapping          = 0;
297b97cf49bSBarry Smith   B->assembled        = PETSC_FALSE;
298b97cf49bSBarry Smith 
2990752156aSBarry Smith   b->m = m; B->m = m;
300ca161407SBarry Smith   ierr = MPI_Allreduce(&m,&B->M,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr);
3010752156aSBarry Smith   B->n = n; B->N = n;
3020752156aSBarry Smith 
3030752156aSBarry Smith   b->rowners = (int *) PetscMalloc((size+1)*sizeof(int)); CHKPTRQ(b->rowners);
3040752156aSBarry Smith   PLogObjectMemory(B,(size+2)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_MPIAdj));
305ca161407SBarry Smith   ierr = MPI_Allgather(&m,1,MPI_INT,b->rowners+1,1,MPI_INT,comm);CHKERRQ(ierr);
3060752156aSBarry Smith   b->rowners[0] = 0;
3070752156aSBarry Smith   for ( ii=2; ii<=size; ii++ ) {
3080752156aSBarry Smith     b->rowners[ii] += b->rowners[ii-1];
3090752156aSBarry Smith   }
3100752156aSBarry Smith   b->rstart = b->rowners[rank];
3110752156aSBarry Smith   b->rend   = b->rowners[rank+1];
312b97cf49bSBarry Smith 
313b97cf49bSBarry Smith   b->j  = j;
314b97cf49bSBarry Smith   b->i  = i;
315b97cf49bSBarry Smith 
316b97cf49bSBarry Smith   b->nz               = i[m];
317b97cf49bSBarry Smith   b->diag             = 0;
318b97cf49bSBarry Smith   b->symmetric        = PETSC_FALSE;
319b97cf49bSBarry Smith 
320b97cf49bSBarry Smith   *A = B;
321b97cf49bSBarry Smith 
322b97cf49bSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr);
323b97cf49bSBarry Smith   if (flg) {ierr = MatPrintHelp(B); CHKERRQ(ierr); }
324b97cf49bSBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
325b97cf49bSBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3263a40ed3dSBarry Smith   PetscFunctionReturn(0);
327b97cf49bSBarry Smith }
328b97cf49bSBarry Smith 
329b97cf49bSBarry Smith 
330b97cf49bSBarry Smith 
331