xref: /petsc/src/mat/impls/aij/mpi/fdmpiaij.c (revision 6eaac0f392fb8c7860fbfbe134bd9044ce5c0c4b)
1a64fbb32SBarry Smith 
2a64fbb32SBarry Smith 
3a64fbb32SBarry Smith #ifndef lint
4*6eaac0f3SBarry Smith static char vcid[] = "$Id: fdmpiaij.c,v 1.1 1996/10/15 18:50:07 bsmith Exp bsmith $";
5a64fbb32SBarry Smith #endif
6a64fbb32SBarry Smith 
7*6eaac0f3SBarry Smith #include "src/mat/impls/aij/mpi/mpiaij.h"
8a64fbb32SBarry Smith #include "src/vec/vecimpl.h"
9a64fbb32SBarry Smith #include "petsc.h"
10a64fbb32SBarry Smith 
11*6eaac0f3SBarry Smith extern int CreateColmap_MPIAIJ_Private(Mat);
12a64fbb32SBarry Smith 
13*6eaac0f3SBarry Smith int MatFDColoringCreate_MPIAIJ(Mat mat,ISColoring iscoloring,MatFDColoring c)
14a64fbb32SBarry Smith {
15*6eaac0f3SBarry Smith   Mat_MPIAIJ *aij = (Mat_MPIAIJ *) mat->data;
16*6eaac0f3SBarry Smith   int        i,*is,n,nrows,j,k,m,*rows = 0,ierr,*A_ci,*A_cj,ncols,col,flg;
17*6eaac0f3SBarry Smith   int        nis = iscoloring->n,*ncolsonproc,size,nctot,*cols,*disp,*B_ci,*B_cj;
18*6eaac0f3SBarry Smith   int        *rowhit, M = mat->m,cstart = aij->cstart, cend = aij->cend,colb;
19*6eaac0f3SBarry Smith   int        *columnsforrow;
20a64fbb32SBarry Smith   IS         *isa = iscoloring->is;
21a64fbb32SBarry Smith   PetscTruth done;
22a64fbb32SBarry Smith 
23a64fbb32SBarry Smith   c->ncolors       = nis;
24a64fbb32SBarry Smith   c->ncolumns      = (int *) PetscMalloc( nis*sizeof(int) );   CHKPTRQ(c->ncolumns);
25a64fbb32SBarry Smith   c->columns       = (int **) PetscMalloc( nis*sizeof(int *)); CHKPTRQ(c->columns);
26a64fbb32SBarry Smith   c->nrows         = (int *) PetscMalloc( nis*sizeof(int) );   CHKPTRQ(c->nrows);
27a64fbb32SBarry Smith   c->rows          = (int **) PetscMalloc( nis*sizeof(int *)); CHKPTRQ(c->rows);
28a64fbb32SBarry Smith   c->columnsforrow = (int **) PetscMalloc( nis*sizeof(int *)); CHKPTRQ(c->columnsforrow);
29*6eaac0f3SBarry Smith 
30*6eaac0f3SBarry Smith   /* Allow access to data structures of local part of matrix */
31*6eaac0f3SBarry Smith   if (!aij->colmap) {
32*6eaac0f3SBarry Smith     ierr = CreateColmap_MPIAIJ_Private(mat);CHKERRQ(ierr);
33*6eaac0f3SBarry Smith   }
34*6eaac0f3SBarry Smith   ierr = MatGetColumnIJ(aij->A,0,PETSC_FALSE,&ncols,&A_ci,&A_cj,&done); CHKERRQ(ierr);
35*6eaac0f3SBarry Smith   ierr = MatGetColumnIJ(aij->B,0,PETSC_FALSE,&ncols,&B_ci,&B_cj,&done); CHKERRQ(ierr);
36*6eaac0f3SBarry Smith 
37*6eaac0f3SBarry Smith   MPI_Comm_size(mat->comm,&size);
38*6eaac0f3SBarry Smith   ncolsonproc = (int *) PetscMalloc( 2*size*sizeof(int *) ); CHKPTRQ(ncolsonproc);
39*6eaac0f3SBarry Smith   disp        = ncolsonproc + size;
40*6eaac0f3SBarry Smith 
41*6eaac0f3SBarry Smith   rowhit        = (int *) PetscMalloc( (M+1)*sizeof(int) ); CHKPTRQ(rowhit);
42*6eaac0f3SBarry Smith   columnsforrow = (int *) PetscMalloc( (M+1)*sizeof(int) );CHKPTRQ(columnsforrow);
43*6eaac0f3SBarry Smith 
44a64fbb32SBarry Smith   /*
45a64fbb32SBarry Smith      Temporary option to allow for debugging/testing
46a64fbb32SBarry Smith   */
47a64fbb32SBarry Smith   ierr = OptionsHasName(0,"-matfdcoloring_slow",&flg);
48*6eaac0f3SBarry Smith 
49a64fbb32SBarry Smith   for ( i=0; i<nis; i++ ) {
50a64fbb32SBarry Smith     ierr = ISGetSize(isa[i],&n); CHKERRQ(ierr);
51a64fbb32SBarry Smith     ierr = ISGetIndices(isa[i],&is); CHKERRQ(ierr);
52a64fbb32SBarry Smith     c->ncolumns[i] = n;
53*6eaac0f3SBarry Smith     c->ncolumns[i] = n;
54a64fbb32SBarry Smith     if (n) {
55a64fbb32SBarry Smith       c->columns[i]  = (int *) PetscMalloc( n*sizeof(int) ); CHKPTRQ(c->columns[i]);
56a64fbb32SBarry Smith       PetscMemcpy(c->columns[i],is,n*sizeof(int));
57a64fbb32SBarry Smith     } else {
58a64fbb32SBarry Smith       c->columns[i]  = 0;
59a64fbb32SBarry Smith     }
60a64fbb32SBarry Smith 
61*6eaac0f3SBarry Smith     /* Determine the total (parallel) number of columns of this color */
62*6eaac0f3SBarry Smith     MPI_Allgather(&n,1,MPI_INT,ncolsonproc,1,MPI_INT,mat->comm);
63*6eaac0f3SBarry Smith     nctot = 0; for ( j=0; j<size; j++ ) {nctot += ncolsonproc[j];}
64*6eaac0f3SBarry Smith     if (!nctot) SETERRQ(1,"MatFDColoringCreate_MPIAIJ:Invalid coloring");
65*6eaac0f3SBarry Smith 
66*6eaac0f3SBarry Smith     disp[0] = 0;
67*6eaac0f3SBarry Smith     for ( j=1; j<size; j++ ) {
68*6eaac0f3SBarry Smith       disp[j] = disp[j-1] + ncolsonproc[j-1];
69*6eaac0f3SBarry Smith     }
70*6eaac0f3SBarry Smith 
71*6eaac0f3SBarry Smith     /* Get complete list of columns for color on each processor */
72*6eaac0f3SBarry Smith     cols = (int *) PetscMalloc( nctot*sizeof(int) ); CHKPTRQ(cols);
73*6eaac0f3SBarry Smith     MPI_Allgatherv(is,n,MPI_INT,cols,ncolsonproc,disp,MPI_INT,mat->comm);
74*6eaac0f3SBarry Smith 
75*6eaac0f3SBarry Smith /*
76*6eaac0f3SBarry Smith for ( j=0; j<nctot; j++ ) {
77*6eaac0f3SBarry Smith   printf("color %d %d col %d\n",i,j,cols[j]);
78*6eaac0f3SBarry Smith }
79*6eaac0f3SBarry Smith */
80*6eaac0f3SBarry Smith 
81*6eaac0f3SBarry Smith     /*
82*6eaac0f3SBarry Smith        Mark all rows affect by these columns
83*6eaac0f3SBarry Smith     */
84*6eaac0f3SBarry Smith     if (flg) {/*-----------------------------------------------------------------------------*/
85*6eaac0f3SBarry Smith       /* crude, slow version */
86*6eaac0f3SBarry Smith       PetscMemzero(rowhit,M*sizeof(int));
87a64fbb32SBarry Smith       /* loop over columns*/
88*6eaac0f3SBarry Smith       for ( j=0; j<nctot; j++ ) {
89*6eaac0f3SBarry Smith         col  = cols[j];
90*6eaac0f3SBarry Smith         if (col >= cstart && col < cend) {
91*6eaac0f3SBarry Smith           /* column is in diagonal block of matrix */
92*6eaac0f3SBarry Smith           rows = A_cj + A_ci[col-cstart];
93*6eaac0f3SBarry Smith           m    = A_ci[col-cstart+1] - A_ci[col-cstart];
94*6eaac0f3SBarry Smith         } else {
95*6eaac0f3SBarry Smith           colb = aij->colmap[col] - 1;
96*6eaac0f3SBarry Smith           if (colb == -1) {
97*6eaac0f3SBarry Smith             m = 0;
98*6eaac0f3SBarry Smith           } else {
99*6eaac0f3SBarry Smith             rows = B_cj + B_ci[colb];
100*6eaac0f3SBarry Smith             m    = B_ci[colb+1] - B_ci[colb];
101*6eaac0f3SBarry Smith           }
102*6eaac0f3SBarry Smith         }
103a64fbb32SBarry Smith         /* loop over columns marking them in rowhit */
104a64fbb32SBarry Smith         for ( k=0; k<m; k++ ) {
105a64fbb32SBarry Smith           rowhit[*rows++] = col + 1;
106a64fbb32SBarry Smith         }
107a64fbb32SBarry Smith       }
108*6eaac0f3SBarry Smith 
109*6eaac0f3SBarry Smith /*
110*6eaac0f3SBarry Smith printf("for col %d found rows \n",i);
111*6eaac0f3SBarry Smith for ( j=0; j<M; j++ ) printf("rhow hit %d %d\n",j,rowhit[j]);
112*6eaac0f3SBarry Smith */
113*6eaac0f3SBarry Smith 
114a64fbb32SBarry Smith       /* count the number of hits */
115a64fbb32SBarry Smith       nrows = 0;
116*6eaac0f3SBarry Smith       for ( j=0; j<M; j++ ) {
117a64fbb32SBarry Smith         if (rowhit[j]) nrows++;
118a64fbb32SBarry Smith       }
119a64fbb32SBarry Smith       c->nrows[i]         = nrows;
120*6eaac0f3SBarry Smith       c->rows[i]          = (int *) PetscMalloc((nrows+1)*sizeof(int)); CHKPTRQ(c->rows[i]);
121*6eaac0f3SBarry Smith       c->columnsforrow[i] = (int *) PetscMalloc((nrows+1)*sizeof(int)); CHKPTRQ(c->columnsforrow[i]);
122a64fbb32SBarry Smith       nrows = 0;
123*6eaac0f3SBarry Smith       for ( j=0; j<M; j++ ) {
124a64fbb32SBarry Smith         if (rowhit[j]) {
125a64fbb32SBarry Smith           c->rows[i][nrows]           = j;
126a64fbb32SBarry Smith           c->columnsforrow[i][nrows] = rowhit[j] - 1;
127a64fbb32SBarry Smith           nrows++;
128a64fbb32SBarry Smith         }
129a64fbb32SBarry Smith       }
130a64fbb32SBarry Smith     } else {/*-------------------------------------------------------------------------------*/
131a64fbb32SBarry Smith       /* efficient version, using rowhit as a linked list */
132*6eaac0f3SBarry Smith       int currentcol,fm,mfm;
133*6eaac0f3SBarry Smith       rowhit[M] = M;
134a64fbb32SBarry Smith       nrows     = 0;
135a64fbb32SBarry Smith       /* loop over columns*/
136*6eaac0f3SBarry Smith       for ( j=0; j<nctot; j++ ) {
137*6eaac0f3SBarry Smith         col  = cols[j];
138*6eaac0f3SBarry Smith         if (col >= cstart && col < cend) {
139*6eaac0f3SBarry Smith           /* column is in diagonal block of matrix */
140*6eaac0f3SBarry Smith           rows = A_cj + A_ci[col-cstart];
141*6eaac0f3SBarry Smith           m    = A_ci[col-cstart+1] - A_ci[col-cstart];
142*6eaac0f3SBarry Smith         } else {
143*6eaac0f3SBarry Smith           colb = aij->colmap[col] - 1;
144*6eaac0f3SBarry Smith           if (colb == -1) {
145*6eaac0f3SBarry Smith             m = 0;
146*6eaac0f3SBarry Smith           } else {
147*6eaac0f3SBarry Smith             rows = B_cj + B_ci[colb];
148*6eaac0f3SBarry Smith             m    = B_ci[colb+1] - B_ci[colb];
149*6eaac0f3SBarry Smith           }
150*6eaac0f3SBarry Smith         }
151a64fbb32SBarry Smith         /* loop over columns marking them in rowhit */
152*6eaac0f3SBarry Smith         fm    = M; /* fm points to first entry in linked list */
153a64fbb32SBarry Smith         for ( k=0; k<m; k++ ) {
154a64fbb32SBarry Smith           currentcol = *rows++;
155a64fbb32SBarry Smith 	  /* is it already in the list? */
156a64fbb32SBarry Smith           do {
157a64fbb32SBarry Smith             mfm  = fm;
158a64fbb32SBarry Smith             fm   = rowhit[fm];
159a64fbb32SBarry Smith           } while (fm < currentcol);
160a64fbb32SBarry Smith           /* not in list so add it */
161a64fbb32SBarry Smith           if (fm != currentcol) {
162a64fbb32SBarry Smith             nrows++;
163a64fbb32SBarry Smith             columnsforrow[currentcol] = col;
164a64fbb32SBarry Smith             /* next three lines insert new entry into linked list */
165a64fbb32SBarry Smith             rowhit[mfm]               = currentcol;
166a64fbb32SBarry Smith             rowhit[currentcol]        = fm;
167a64fbb32SBarry Smith             fm                        = currentcol;
168a64fbb32SBarry Smith             /* fm points to present position in list since we know the columns are sorted */
169a64fbb32SBarry Smith           } else {
170*6eaac0f3SBarry Smith             SETERRQ(1,"MatFDColoringCreate_MPIAIJ:Invalid coloring");
171a64fbb32SBarry Smith           }
172a64fbb32SBarry Smith         }
173a64fbb32SBarry Smith       }
174a64fbb32SBarry Smith       c->nrows[i]         = nrows;
175*6eaac0f3SBarry Smith       c->rows[i]          = (int *)PetscMalloc((nrows+1)*sizeof(int));CHKPTRQ(c->rows[i]);
176*6eaac0f3SBarry Smith       c->columnsforrow[i] = (int *)PetscMalloc((nrows+1)*sizeof(int));CHKPTRQ(c->columnsforrow[i]);
177a64fbb32SBarry Smith       /* now store the linked list of rows into c->rows[i] */
178a64fbb32SBarry Smith       nrows = 0;
179*6eaac0f3SBarry Smith       fm    = rowhit[M];
180a64fbb32SBarry Smith       do {
181a64fbb32SBarry Smith         c->rows[i][nrows]            = fm;
182a64fbb32SBarry Smith         c->columnsforrow[i][nrows++] = columnsforrow[fm];
183a64fbb32SBarry Smith         fm                           = rowhit[fm];
184*6eaac0f3SBarry Smith       } while (fm < M);
185*6eaac0f3SBarry Smith     } /* ---------------------------------------------------------------------------------------*/
186*6eaac0f3SBarry Smith     PetscFree(cols);
187*6eaac0f3SBarry Smith   }
188a64fbb32SBarry Smith   PetscFree(rowhit);
189a64fbb32SBarry Smith   PetscFree(columnsforrow);
190*6eaac0f3SBarry Smith   PetscFree(ncolsonproc);
191*6eaac0f3SBarry Smith   ierr = MatRestoreColumnIJ(aij->A,0,PETSC_FALSE,&ncols,&A_ci,&A_cj,&done); CHKERRQ(ierr);
192*6eaac0f3SBarry Smith   ierr = MatRestoreColumnIJ(aij->B,0,PETSC_FALSE,&ncols,&B_ci,&B_cj,&done); CHKERRQ(ierr);
193a64fbb32SBarry Smith 
194*6eaac0f3SBarry Smith   c->scale  = (Scalar *) PetscMalloc( 2*mat->N*sizeof(Scalar) ); CHKPTRQ(c->scale);
195*6eaac0f3SBarry Smith   c->wscale = c->scale + mat->N;
196a64fbb32SBarry Smith   return 0;
197a64fbb32SBarry Smith }
198a64fbb32SBarry Smith 
199