xref: /petsc/src/mat/impls/adj/mpi/mpiadj.c (revision 3a40ed3dce77c081171d005ae1a6ff4bb9d13b6f)
1b97cf49bSBarry Smith #ifdef PETSC_RCS_HEADER
2*3a40ed3dSBarry Smith static char vcid[] = "$Id: mpiadj.c,v 1.2 1997/09/26 02:19:39 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) {
28*3a40ed3dSBarry 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);
39*3a40ed3dSBarry Smith   PetscFunctionReturn(0);
40b97cf49bSBarry Smith }
41b97cf49bSBarry Smith 
42b97cf49bSBarry Smith #undef __FUNC__
430752156aSBarry Smith #define __FUNC__ "MatView_MPIAdj"
440752156aSBarry 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);
510752156aSBarry Smith   if (vtype == ASCII_FILE_VIEWER || vtype == ASCII_FILES_VIEWER){
52*3a40ed3dSBarry Smith     ierr = MatView_MPIAdj_ASCII(A,viewer);CHKERRQ(ierr);
53b97cf49bSBarry Smith   }
54*3a40ed3dSBarry Smith   PetscFunctionReturn(0);
55b97cf49bSBarry Smith }
56b97cf49bSBarry Smith 
57b97cf49bSBarry Smith #undef __FUNC__
580752156aSBarry Smith #define __FUNC__ "MatDestroy_MPIAdj"
590752156aSBarry Smith int MatDestroy_MPIAdj(PetscObject obj)
60b97cf49bSBarry Smith {
61b97cf49bSBarry Smith   Mat        A  = (Mat) obj;
620752156aSBarry Smith   Mat_MPIAdj *a = (Mat_MPIAdj *) A->data;
63b97cf49bSBarry Smith 
64*3a40ed3dSBarry Smith #if defined(USE_PETSC_LOG)
650752156aSBarry 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);
700752156aSBarry Smith   PetscFree(a->rowners);
71b97cf49bSBarry Smith   PetscFree(a);
72b97cf49bSBarry Smith 
73b97cf49bSBarry Smith   PLogObjectDestroy(A);
74b97cf49bSBarry Smith   PetscHeaderDestroy(A);
75*3a40ed3dSBarry Smith   PetscFunctionReturn(0);
76b97cf49bSBarry Smith }
77b97cf49bSBarry Smith 
78b97cf49bSBarry Smith 
79b97cf49bSBarry Smith #undef __FUNC__
800752156aSBarry Smith #define __FUNC__ "MatSetOption_MPIAdj"
810752156aSBarry Smith int MatSetOption_MPIAdj(Mat A,MatOption op)
82b97cf49bSBarry Smith {
830752156aSBarry 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 {
880752156aSBarry Smith     PLogInfo(A,"Info:MatSetOption_MPIAdj:Option ignored\n");
89b97cf49bSBarry Smith   }
90*3a40ed3dSBarry Smith   PetscFunctionReturn(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__
990752156aSBarry Smith #define __FUNC__ "MatMarkDiag_MPIAdj"
1000752156aSBarry Smith int MatMarkDiag_MPIAdj(Mat A)
101b97cf49bSBarry Smith {
1020752156aSBarry 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;
116*3a40ed3dSBarry Smith   PetscFunctionReturn(0);
117b97cf49bSBarry Smith }
118b97cf49bSBarry Smith 
119b97cf49bSBarry Smith #undef __FUNC__
1200752156aSBarry Smith #define __FUNC__ "MatGetSize_MPIAdj"
1210752156aSBarry Smith int MatGetSize_MPIAdj(Mat A,int *m,int *n)
122b97cf49bSBarry Smith {
1230752156aSBarry Smith   if (m) *m = A->M;
1240752156aSBarry Smith   if (n) *n = A->N;
125*3a40ed3dSBarry Smith   PetscFunctionReturn(0);
126b97cf49bSBarry Smith }
127b97cf49bSBarry Smith 
128b97cf49bSBarry Smith #undef __FUNC__
1290752156aSBarry Smith #define __FUNC__ "MatGetSize_MPIAdj"
1300752156aSBarry Smith int MatGetLocalSize_MPIAdj(Mat A,int *m,int *n)
131b97cf49bSBarry Smith {
1320752156aSBarry Smith   Mat_MPIAdj *a = (Mat_MPIAdj *) A->data;
1330752156aSBarry Smith   if (m) *m = a->m;
1340752156aSBarry Smith   if (n) *n = A->N;
135*3a40ed3dSBarry Smith   PetscFunctionReturn(0);
136b97cf49bSBarry Smith }
137b97cf49bSBarry Smith 
138b97cf49bSBarry Smith #undef __FUNC__
1390752156aSBarry Smith #define __FUNC__ "MatGetOwnershipRange_MPIAdj"
1400752156aSBarry Smith int MatGetOwnershipRange_MPIAdj(Mat A,int *m,int *n)
141b97cf49bSBarry Smith {
1420752156aSBarry Smith   Mat_MPIAdj *a = (Mat_MPIAdj *) A->data;
1430752156aSBarry Smith   *m = a->rstart; *n = a->rend;
144*3a40ed3dSBarry Smith   PetscFunctionReturn(0);
145b97cf49bSBarry Smith }
146b97cf49bSBarry Smith 
147b97cf49bSBarry Smith #undef __FUNC__
1480752156aSBarry Smith #define __FUNC__ "MatGetRow_MPIAdj"
1490752156aSBarry Smith int MatGetRow_MPIAdj(Mat A,int row,int *nz,int **idx,Scalar **v)
150b97cf49bSBarry Smith {
1510752156aSBarry Smith   Mat_MPIAdj *a = (Mat_MPIAdj *) A->data;
152b97cf49bSBarry Smith   int        *itmp;
153b97cf49bSBarry Smith 
1540752156aSBarry Smith   row -= a->rstart;
1550752156aSBarry 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   }
167*3a40ed3dSBarry Smith   PetscFunctionReturn(0);
168b97cf49bSBarry Smith }
169b97cf49bSBarry Smith 
170b97cf49bSBarry Smith #undef __FUNC__
1710752156aSBarry Smith #define __FUNC__ "MatRestoreRow_MPIAdj"
1720752156aSBarry Smith int MatRestoreRow_MPIAdj(Mat A,int row,int *nz,int **idx,Scalar **v)
173b97cf49bSBarry Smith {
174*3a40ed3dSBarry Smith   PetscFunctionReturn(0);
175b97cf49bSBarry Smith }
176b97cf49bSBarry Smith 
177b97cf49bSBarry Smith #undef __FUNC__
1780752156aSBarry Smith #define __FUNC__ "MatGetBlockSize_MPIAdj"
1790752156aSBarry Smith int MatGetBlockSize_MPIAdj(Mat A, int *bs)
180b97cf49bSBarry Smith {
181b97cf49bSBarry Smith   *bs = 1;
182*3a40ed3dSBarry Smith   PetscFunctionReturn(0);
183b97cf49bSBarry Smith }
184b97cf49bSBarry Smith 
185b97cf49bSBarry Smith 
186b97cf49bSBarry Smith #undef __FUNC__
1870752156aSBarry Smith #define __FUNC__ "MatEqual_MPIAdj"
1880752156aSBarry Smith int MatEqual_MPIAdj(Mat A,Mat B, PetscTruth* flg)
189b97cf49bSBarry Smith {
1900752156aSBarry Smith   Mat_MPIAdj *a = (Mat_MPIAdj *)A->data, *b = (Mat_MPIAdj *)B->data;
1910752156aSBarry Smith  int         flag = 1;
192b97cf49bSBarry Smith 
1930752156aSBarry 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 */
1960752156aSBarry Smith   if ((a->m != b->m ) ||( a->nz != b->nz)) {
1970752156aSBarry 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))) {
2020752156aSBarry 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))) {
2070752156aSBarry Smith     flag = 0;
208b97cf49bSBarry Smith   }
209b97cf49bSBarry Smith 
2100752156aSBarry Smith   MPI_Allreduce(&flag,flg,1,MPI_INT,MPI_LAND,A->comm);
2110752156aSBarry Smith 
2120752156aSBarry Smith 
213*3a40ed3dSBarry Smith   PetscFunctionReturn(0);
214b97cf49bSBarry Smith }
215b97cf49bSBarry Smith 
216b97cf49bSBarry Smith 
217b97cf49bSBarry Smith /* -------------------------------------------------------------------*/
218b97cf49bSBarry Smith static struct _MatOps MatOps = {0,
2190752156aSBarry 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,
2270752156aSBarry Smith        0,MatEqual_MPIAdj,
228b97cf49bSBarry Smith        0,0,0,
229b97cf49bSBarry Smith        0,0,
230b97cf49bSBarry Smith        0,
2310752156aSBarry Smith        MatSetOption_MPIAdj,0,0,
232b97cf49bSBarry Smith        0,0,0,0,
2330752156aSBarry 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,
2380752156aSBarry Smith        0,0,
239b97cf49bSBarry Smith        0,0,
240b97cf49bSBarry Smith        0,
241b97cf49bSBarry Smith        0,0,0,
242b97cf49bSBarry Smith        0,
2430752156aSBarry Smith        MatGetBlockSize_MPIAdj,
244b97cf49bSBarry Smith        0,
245b97cf49bSBarry Smith        0,
246b97cf49bSBarry Smith        0,
247b97cf49bSBarry Smith        0,
248b97cf49bSBarry Smith        0,
2490752156aSBarry Smith        0,
2500752156aSBarry Smith        0,
2510752156aSBarry Smith        0};
252b97cf49bSBarry Smith 
253b97cf49bSBarry Smith 
254b97cf49bSBarry Smith #undef __FUNC__
2550752156aSBarry Smith #define __FUNC__ "MatCreateMPIAdj"
256b97cf49bSBarry Smith /*@C
2570752156aSBarry 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
2630752156aSBarry 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 
2720752156aSBarry 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 
2770752156aSBarry Smith .seealso: MatCreate(), MatCreateSeqAdj(), MatGetReordering()
278b97cf49bSBarry Smith @*/
2790752156aSBarry Smith int MatCreateMPIAdj(MPI_Comm comm,int m,int n,int *i,int *j, Mat *A)
280b97cf49bSBarry Smith {
281b97cf49bSBarry Smith   Mat        B;
2820752156aSBarry Smith   Mat_MPIAdj *b;
2830752156aSBarry Smith   int        ii,ierr, flg,size,rank;
284b97cf49bSBarry Smith 
285b97cf49bSBarry Smith   MPI_Comm_size(comm,&size);
2860752156aSBarry Smith   MPI_Comm_rank(comm,&rank);
287b97cf49bSBarry Smith 
288b97cf49bSBarry Smith   *A                  = 0;
2890752156aSBarry Smith   PetscHeaderCreate(B,_p_Mat,MAT_COOKIE,MATMPIADJ,comm,MatDestroy,MatView);
290b97cf49bSBarry Smith   PLogObjectCreate(B);
2910752156aSBarry Smith   B->data             = (void *) (b = PetscNew(Mat_MPIAdj)); CHKPTRQ(b);
2920752156aSBarry Smith   PetscMemzero(b,sizeof(Mat_MPIAdj));
293b97cf49bSBarry Smith   PetscMemcpy(&B->ops,&MatOps,sizeof(struct _MatOps));
2940752156aSBarry Smith   B->destroy          = MatDestroy_MPIAdj;
2950752156aSBarry 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 
3010752156aSBarry Smith   b->m = m; B->m = m;
3020752156aSBarry Smith   MPI_Allreduce(&m,&B->M,1,MPI_INT,MPI_SUM,comm);
3030752156aSBarry Smith   B->n = n; B->N = n;
3040752156aSBarry Smith 
3050752156aSBarry Smith   b->rowners = (int *) PetscMalloc((size+1)*sizeof(int)); CHKPTRQ(b->rowners);
3060752156aSBarry Smith   PLogObjectMemory(B,(size+2)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_MPIAdj));
3070752156aSBarry Smith   MPI_Allgather(&m,1,MPI_INT,b->rowners+1,1,MPI_INT,comm);
3080752156aSBarry Smith   b->rowners[0] = 0;
3090752156aSBarry Smith   for ( ii=2; ii<=size; ii++ ) {
3100752156aSBarry Smith     b->rowners[ii] += b->rowners[ii-1];
3110752156aSBarry Smith   }
3120752156aSBarry Smith   b->rstart = b->rowners[rank];
3130752156aSBarry 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);
328*3a40ed3dSBarry Smith   PetscFunctionReturn(0);
329b97cf49bSBarry Smith }
330b97cf49bSBarry Smith 
331b97cf49bSBarry Smith 
332b97cf49bSBarry Smith 
333