xref: /petsc/src/mat/impls/adj/mpi/mpiadj.c (revision 0752156a28ac8f8e9dfaef7ce98457a01bf27fb6)
1b97cf49bSBarry Smith #ifdef PETSC_RCS_HEADER
2*0752156aSBarry Smith static char vcid[] = "$Id: mpiadj.c,v 1.1 1997/09/23 20:11:18 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"
11*0752156aSBarry Smith #include "src/mat/impls/adj/mpi/mpiadj.h"
12b97cf49bSBarry Smith 
13b97cf49bSBarry Smith 
14b97cf49bSBarry Smith #undef __FUNC__
15*0752156aSBarry Smith #define __FUNC__ "MatView_MPIAdj_ASCII"
16*0752156aSBarry Smith extern int MatView_MPIAdj_ASCII(Mat A,Viewer viewer)
17b97cf49bSBarry Smith {
18*0752156aSBarry 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;
22*0752156aSBarry 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) {
28b97cf49bSBarry Smith     return 0;
29*0752156aSBarry Smith   } else {
30b97cf49bSBarry Smith     for ( i=0; i<m; i++ ) {
31*0752156aSBarry Smith       PetscSynchronizedFPrintf(comm,fd,"row %d:",i+a->rstart);
32b97cf49bSBarry Smith       for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
33*0752156aSBarry Smith         PetscSynchronizedFPrintf(comm,fd," %d ",a->j[j]);
34*0752156aSBarry Smith       }
35*0752156aSBarry Smith       PetscSynchronizedFPrintf(comm,fd,"\n");
36b97cf49bSBarry Smith     }
37b97cf49bSBarry Smith   }
38*0752156aSBarry Smith   PetscSynchronizedFlush(comm);
39b97cf49bSBarry Smith   return 0;
40b97cf49bSBarry Smith }
41b97cf49bSBarry Smith 
42b97cf49bSBarry Smith #undef __FUNC__
43*0752156aSBarry Smith #define __FUNC__ "MatView_MPIAdj"
44*0752156aSBarry Smith int MatView_MPIAdj(PetscObject obj,Viewer viewer)
45b97cf49bSBarry Smith {
46b97cf49bSBarry Smith   Mat         A = (Mat) obj;
47b97cf49bSBarry Smith   ViewerType  vtype;
48b97cf49bSBarry Smith   int         ierr;
49b97cf49bSBarry Smith 
50b97cf49bSBarry Smith   ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr);
51*0752156aSBarry Smith   if (vtype == ASCII_FILE_VIEWER || vtype == ASCII_FILES_VIEWER){
52*0752156aSBarry Smith     return MatView_MPIAdj_ASCII(A,viewer);
53b97cf49bSBarry Smith   }
54b97cf49bSBarry Smith   return 0;
55b97cf49bSBarry Smith }
56b97cf49bSBarry Smith 
57b97cf49bSBarry Smith #undef __FUNC__
58*0752156aSBarry Smith #define __FUNC__ "MatDestroy_MPIAdj"
59*0752156aSBarry Smith int MatDestroy_MPIAdj(PetscObject obj)
60b97cf49bSBarry Smith {
61b97cf49bSBarry Smith   Mat        A  = (Mat) obj;
62*0752156aSBarry Smith   Mat_MPIAdj *a = (Mat_MPIAdj *) A->data;
63b97cf49bSBarry Smith 
64b97cf49bSBarry Smith #if defined(PETSC_LOG)
65*0752156aSBarry Smith   PLogObjectState(obj,"Rows=%d, Cols=%d, NZ=%d",A->m,A->n,a->nz);
66b97cf49bSBarry Smith #endif
67b97cf49bSBarry Smith   if (a->diag) PetscFree(a->diag);
68b97cf49bSBarry Smith   PetscFree(a->i);
69b97cf49bSBarry Smith   PetscFree(a->j);
70*0752156aSBarry Smith   PetscFree(a->rowners);
71b97cf49bSBarry Smith   PetscFree(a);
72b97cf49bSBarry Smith 
73b97cf49bSBarry Smith   PLogObjectDestroy(A);
74b97cf49bSBarry Smith   PetscHeaderDestroy(A);
75b97cf49bSBarry Smith   return 0;
76b97cf49bSBarry Smith }
77b97cf49bSBarry Smith 
78b97cf49bSBarry Smith 
79b97cf49bSBarry Smith #undef __FUNC__
80*0752156aSBarry Smith #define __FUNC__ "MatSetOption_MPIAdj"
81*0752156aSBarry Smith int MatSetOption_MPIAdj(Mat A,MatOption op)
82b97cf49bSBarry Smith {
83*0752156aSBarry Smith   Mat_MPIAdj *a = (Mat_MPIAdj *) A->data;
84b97cf49bSBarry Smith 
85b97cf49bSBarry Smith   if (op == MAT_STRUCTURALLY_SYMMETRIC) {
86b97cf49bSBarry Smith     a->symmetric = PETSC_TRUE;
87b97cf49bSBarry Smith   } else {
88*0752156aSBarry Smith     PLogInfo(A,"Info:MatSetOption_MPIAdj:Option ignored\n");
89b97cf49bSBarry Smith   }
90b97cf49bSBarry Smith   return 0;
91b97cf49bSBarry Smith }
92b97cf49bSBarry Smith 
93b97cf49bSBarry Smith 
94b97cf49bSBarry Smith /*
95b97cf49bSBarry Smith      Adds diagonal pointers to sparse matrix structure.
96b97cf49bSBarry Smith */
97b97cf49bSBarry Smith 
98b97cf49bSBarry Smith #undef __FUNC__
99*0752156aSBarry Smith #define __FUNC__ "MatMarkDiag_MPIAdj"
100*0752156aSBarry Smith int MatMarkDiag_MPIAdj(Mat A)
101b97cf49bSBarry Smith {
102*0752156aSBarry Smith   Mat_MPIAdj *a = (Mat_MPIAdj *) A->data;
103b97cf49bSBarry Smith   int        i,j, *diag, m = a->m;
104b97cf49bSBarry Smith 
105b97cf49bSBarry Smith   diag = (int *) PetscMalloc( (m+1)*sizeof(int)); CHKPTRQ(diag);
106b97cf49bSBarry Smith   PLogObjectMemory(A,(m+1)*sizeof(int));
107b97cf49bSBarry Smith   for ( i=0; i<a->m; i++ ) {
108b97cf49bSBarry Smith     for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
109b97cf49bSBarry Smith       if (a->j[j] == i) {
110b97cf49bSBarry Smith         diag[i] = j;
111b97cf49bSBarry Smith         break;
112b97cf49bSBarry Smith       }
113b97cf49bSBarry Smith     }
114b97cf49bSBarry Smith   }
115b97cf49bSBarry Smith   a->diag = diag;
116b97cf49bSBarry Smith   return 0;
117b97cf49bSBarry Smith }
118b97cf49bSBarry Smith 
119b97cf49bSBarry Smith #undef __FUNC__
120*0752156aSBarry Smith #define __FUNC__ "MatGetSize_MPIAdj"
121*0752156aSBarry Smith int MatGetSize_MPIAdj(Mat A,int *m,int *n)
122b97cf49bSBarry Smith {
123*0752156aSBarry Smith   if (m) *m = A->M;
124*0752156aSBarry Smith   if (n) *n = A->N;
125b97cf49bSBarry Smith   return 0;
126b97cf49bSBarry Smith }
127b97cf49bSBarry Smith 
128b97cf49bSBarry Smith #undef __FUNC__
129*0752156aSBarry Smith #define __FUNC__ "MatGetSize_MPIAdj"
130*0752156aSBarry Smith int MatGetLocalSize_MPIAdj(Mat A,int *m,int *n)
131b97cf49bSBarry Smith {
132*0752156aSBarry Smith   Mat_MPIAdj *a = (Mat_MPIAdj *) A->data;
133*0752156aSBarry Smith   if (m) *m = a->m;
134*0752156aSBarry Smith   if (n) *n = A->N;
135b97cf49bSBarry Smith   return 0;
136b97cf49bSBarry Smith }
137b97cf49bSBarry Smith 
138b97cf49bSBarry Smith #undef __FUNC__
139*0752156aSBarry Smith #define __FUNC__ "MatGetOwnershipRange_MPIAdj"
140*0752156aSBarry Smith int MatGetOwnershipRange_MPIAdj(Mat A,int *m,int *n)
141b97cf49bSBarry Smith {
142*0752156aSBarry Smith   Mat_MPIAdj *a = (Mat_MPIAdj *) A->data;
143*0752156aSBarry Smith   *m = a->rstart; *n = a->rend;
144b97cf49bSBarry Smith   return 0;
145b97cf49bSBarry Smith }
146b97cf49bSBarry Smith 
147b97cf49bSBarry Smith #undef __FUNC__
148*0752156aSBarry Smith #define __FUNC__ "MatGetRow_MPIAdj"
149*0752156aSBarry Smith int MatGetRow_MPIAdj(Mat A,int row,int *nz,int **idx,Scalar **v)
150b97cf49bSBarry Smith {
151*0752156aSBarry Smith   Mat_MPIAdj *a = (Mat_MPIAdj *) A->data;
152b97cf49bSBarry Smith   int        *itmp;
153b97cf49bSBarry Smith 
154*0752156aSBarry Smith   row -= a->rstart;
155*0752156aSBarry Smith 
156b97cf49bSBarry Smith   if (row < 0 || row >= a->m) SETERRQ(1,0,"Row out of range");
157b97cf49bSBarry Smith 
158b97cf49bSBarry Smith   *nz = a->i[row+1] - a->i[row];
159b97cf49bSBarry Smith   if (v) *v = PETSC_NULL;
160b97cf49bSBarry Smith   if (idx) {
161b97cf49bSBarry Smith     itmp = a->j + a->i[row];
162b97cf49bSBarry Smith     if (*nz) {
163b97cf49bSBarry Smith       *idx = itmp;
164b97cf49bSBarry Smith     }
165b97cf49bSBarry Smith     else *idx = 0;
166b97cf49bSBarry Smith   }
167b97cf49bSBarry Smith   return 0;
168b97cf49bSBarry Smith }
169b97cf49bSBarry Smith 
170b97cf49bSBarry Smith #undef __FUNC__
171*0752156aSBarry Smith #define __FUNC__ "MatRestoreRow_MPIAdj"
172*0752156aSBarry Smith int MatRestoreRow_MPIAdj(Mat A,int row,int *nz,int **idx,Scalar **v)
173b97cf49bSBarry Smith {
174b97cf49bSBarry Smith   return 0;
175b97cf49bSBarry Smith }
176b97cf49bSBarry Smith 
177b97cf49bSBarry Smith #undef __FUNC__
178*0752156aSBarry Smith #define __FUNC__ "MatGetBlockSize_MPIAdj"
179*0752156aSBarry Smith int MatGetBlockSize_MPIAdj(Mat A, int *bs)
180b97cf49bSBarry Smith {
181b97cf49bSBarry Smith   *bs = 1;
182b97cf49bSBarry Smith   return 0;
183b97cf49bSBarry Smith }
184b97cf49bSBarry Smith 
185b97cf49bSBarry Smith 
186b97cf49bSBarry Smith #undef __FUNC__
187*0752156aSBarry Smith #define __FUNC__ "MatEqual_MPIAdj"
188*0752156aSBarry Smith int MatEqual_MPIAdj(Mat A,Mat B, PetscTruth* flg)
189b97cf49bSBarry Smith {
190*0752156aSBarry Smith   Mat_MPIAdj *a = (Mat_MPIAdj *)A->data, *b = (Mat_MPIAdj *)B->data;
191*0752156aSBarry Smith  int         flag = 1;
192b97cf49bSBarry Smith 
193*0752156aSBarry Smith   if (B->type != MATMPIADJ) SETERRQ(1,0,"Matrices must be same type");
194b97cf49bSBarry Smith 
195b97cf49bSBarry Smith   /* If the  matrix dimensions are not equal, or no of nonzeros */
196*0752156aSBarry Smith   if ((a->m != b->m ) ||( a->nz != b->nz)) {
197*0752156aSBarry Smith     flag = 0;
198b97cf49bSBarry Smith   }
199b97cf49bSBarry Smith 
200b97cf49bSBarry Smith   /* if the a->i are the same */
201b97cf49bSBarry Smith   if (PetscMemcmp(a->i,b->i,(a->m+1)*sizeof(int))) {
202*0752156aSBarry Smith     flag = 0;
203b97cf49bSBarry Smith   }
204b97cf49bSBarry Smith 
205b97cf49bSBarry Smith   /* if a->j are the same */
206b97cf49bSBarry Smith   if (PetscMemcmp(a->j, b->j, (a->nz)*sizeof(int))) {
207*0752156aSBarry Smith     flag = 0;
208b97cf49bSBarry Smith   }
209b97cf49bSBarry Smith 
210*0752156aSBarry Smith   MPI_Allreduce(&flag,flg,1,MPI_INT,MPI_LAND,A->comm);
211*0752156aSBarry Smith 
212*0752156aSBarry Smith 
213b97cf49bSBarry Smith   return 0;
214b97cf49bSBarry Smith }
215b97cf49bSBarry Smith 
216b97cf49bSBarry Smith 
217b97cf49bSBarry Smith /* -------------------------------------------------------------------*/
218b97cf49bSBarry Smith static struct _MatOps MatOps = {0,
219*0752156aSBarry Smith        MatGetRow_MPIAdj,MatRestoreRow_MPIAdj,
220b97cf49bSBarry Smith        0,0,
221b97cf49bSBarry Smith        0,0,
222b97cf49bSBarry Smith        0,0,
223b97cf49bSBarry Smith        0,0,
224b97cf49bSBarry Smith        0,0,
225b97cf49bSBarry Smith        0,
226b97cf49bSBarry Smith        0,
227*0752156aSBarry Smith        0,MatEqual_MPIAdj,
228b97cf49bSBarry Smith        0,0,0,
229b97cf49bSBarry Smith        0,0,
230b97cf49bSBarry Smith        0,
231*0752156aSBarry Smith        MatSetOption_MPIAdj,0,0,
232b97cf49bSBarry Smith        0,0,0,0,
233*0752156aSBarry Smith        MatGetSize_MPIAdj,MatGetLocalSize_MPIAdj,MatGetOwnershipRange_MPIAdj,
234b97cf49bSBarry Smith        0,0,
235b97cf49bSBarry Smith        0,0,
236b97cf49bSBarry Smith        0,0,0,
237b97cf49bSBarry Smith        0,0,0,
238*0752156aSBarry Smith        0,0,
239b97cf49bSBarry Smith        0,0,
240b97cf49bSBarry Smith        0,
241b97cf49bSBarry Smith        0,0,0,
242b97cf49bSBarry Smith        0,
243*0752156aSBarry Smith        MatGetBlockSize_MPIAdj,
244b97cf49bSBarry Smith        0,
245b97cf49bSBarry Smith        0,
246b97cf49bSBarry Smith        0,
247b97cf49bSBarry Smith        0,
248b97cf49bSBarry Smith        0,
249*0752156aSBarry Smith        0,
250*0752156aSBarry Smith        0,
251*0752156aSBarry Smith        0};
252b97cf49bSBarry Smith 
253b97cf49bSBarry Smith 
254b97cf49bSBarry Smith #undef __FUNC__
255*0752156aSBarry Smith #define __FUNC__ "MatCreateMPIAdj"
256b97cf49bSBarry Smith /*@C
257*0752156aSBarry Smith    MatCreateMPIAdj - Creates a sparse matrix representing an adjacency list.
258b97cf49bSBarry Smith      The matrix does not have numerical values associated with it, but is
259b97cf49bSBarry Smith      intended for ordering (to reduce bandwidth etc) and partitioning.
260b97cf49bSBarry Smith 
261b97cf49bSBarry Smith    Input Parameters:
262b97cf49bSBarry Smith .  comm - MPI communicator, set to PETSC_COMM_SELF
263*0752156aSBarry Smith .  m - number of local rows
264b97cf49bSBarry Smith .  n - number of columns
265b97cf49bSBarry Smith .  i - the indices into j for the start of each row
266b97cf49bSBarry Smith .  j - the column indices for each row (sorted for each row)
267b97cf49bSBarry Smith        The indices in i and j start with zero NOT one.
268b97cf49bSBarry Smith 
269b97cf49bSBarry Smith    Output Parameter:
270b97cf49bSBarry Smith .  A - the matrix
271b97cf49bSBarry Smith 
272*0752156aSBarry Smith    Notes: You must NOT free the ii and jj arrays yourself. PETSc will free them
273b97cf49bSBarry Smith    when the matrix is destroyed.
274b97cf49bSBarry Smith 
275b97cf49bSBarry Smith .  MatSetOptions() possible values - MAT_STRUCTURALLY_SYMMETRIC
276b97cf49bSBarry Smith 
277*0752156aSBarry Smith .seealso: MatCreate(), MatCreateSeqAdj(), MatGetReordering()
278b97cf49bSBarry Smith @*/
279*0752156aSBarry Smith int MatCreateMPIAdj(MPI_Comm comm,int m,int n,int *i,int *j, Mat *A)
280b97cf49bSBarry Smith {
281b97cf49bSBarry Smith   Mat        B;
282*0752156aSBarry Smith   Mat_MPIAdj *b;
283*0752156aSBarry Smith   int        ii,ierr, flg,size,rank;
284b97cf49bSBarry Smith 
285b97cf49bSBarry Smith   MPI_Comm_size(comm,&size);
286*0752156aSBarry Smith   MPI_Comm_rank(comm,&rank);
287b97cf49bSBarry Smith 
288b97cf49bSBarry Smith   *A                  = 0;
289*0752156aSBarry Smith   PetscHeaderCreate(B,_p_Mat,MAT_COOKIE,MATMPIADJ,comm,MatDestroy,MatView);
290b97cf49bSBarry Smith   PLogObjectCreate(B);
291*0752156aSBarry Smith   B->data             = (void *) (b = PetscNew(Mat_MPIAdj)); CHKPTRQ(b);
292*0752156aSBarry Smith   PetscMemzero(b,sizeof(Mat_MPIAdj));
293b97cf49bSBarry Smith   PetscMemcpy(&B->ops,&MatOps,sizeof(struct _MatOps));
294*0752156aSBarry Smith   B->destroy          = MatDestroy_MPIAdj;
295*0752156aSBarry Smith   B->view             = MatView_MPIAdj;
296b97cf49bSBarry Smith   B->factor           = 0;
297b97cf49bSBarry Smith   B->lupivotthreshold = 1.0;
298b97cf49bSBarry Smith   B->mapping          = 0;
299b97cf49bSBarry Smith   B->assembled        = PETSC_FALSE;
300b97cf49bSBarry Smith 
301*0752156aSBarry Smith   b->m = m; B->m = m;
302*0752156aSBarry Smith   MPI_Allreduce(&m,&B->M,1,MPI_INT,MPI_SUM,comm);
303*0752156aSBarry Smith   B->n = n; B->N = n;
304*0752156aSBarry Smith 
305*0752156aSBarry Smith   b->rowners = (int *) PetscMalloc((size+1)*sizeof(int)); CHKPTRQ(b->rowners);
306*0752156aSBarry Smith   PLogObjectMemory(B,(size+2)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_MPIAdj));
307*0752156aSBarry Smith   MPI_Allgather(&m,1,MPI_INT,b->rowners+1,1,MPI_INT,comm);
308*0752156aSBarry Smith   b->rowners[0] = 0;
309*0752156aSBarry Smith   for ( ii=2; ii<=size; ii++ ) {
310*0752156aSBarry Smith     b->rowners[ii] += b->rowners[ii-1];
311*0752156aSBarry Smith   }
312*0752156aSBarry Smith   b->rstart = b->rowners[rank];
313*0752156aSBarry Smith   b->rend   = b->rowners[rank+1];
314b97cf49bSBarry Smith 
315b97cf49bSBarry Smith   b->j  = j;
316b97cf49bSBarry Smith   b->i  = i;
317b97cf49bSBarry Smith 
318b97cf49bSBarry Smith   b->nz               = i[m];
319b97cf49bSBarry Smith   b->diag             = 0;
320b97cf49bSBarry Smith   b->symmetric        = PETSC_FALSE;
321b97cf49bSBarry Smith 
322b97cf49bSBarry Smith   *A = B;
323b97cf49bSBarry Smith 
324b97cf49bSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr);
325b97cf49bSBarry Smith   if (flg) {ierr = MatPrintHelp(B); CHKERRQ(ierr); }
326b97cf49bSBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
327b97cf49bSBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
328b97cf49bSBarry Smith   return 0;
329b97cf49bSBarry Smith }
330b97cf49bSBarry Smith 
331b97cf49bSBarry Smith 
332b97cf49bSBarry Smith 
333