xref: /petsc/src/mat/impls/aij/mpi/fdmpiaij.c (revision a64fbb3267d78e2c4a37b0de5be922a57d77298b)
1*a64fbb32SBarry Smith 
2*a64fbb32SBarry Smith 
3*a64fbb32SBarry Smith #ifndef lint
4*a64fbb32SBarry Smith static char vcid[] = "$Id: fdaij.c,v 1.1 1996/10/09 18:09:59 bsmith Exp bsmith $";
5*a64fbb32SBarry Smith #endif
6*a64fbb32SBarry Smith 
7*a64fbb32SBarry Smith #include "src/mat/impls/aij/seq/aij.h"
8*a64fbb32SBarry Smith #include "src/vec/vecimpl.h"
9*a64fbb32SBarry Smith #include "petsc.h"
10*a64fbb32SBarry Smith 
11*a64fbb32SBarry Smith 
12*a64fbb32SBarry Smith int MatFDColoringCreate_SeqAIJ(Mat mat,ISColoring iscoloring,MatFDColoring c)
13*a64fbb32SBarry Smith {
14*a64fbb32SBarry Smith   int        i,*is,n,nrows,N = mat->N,j,k,m,*rows,ierr,*ci,*cj,ncols,col,flg;
15*a64fbb32SBarry Smith   int        nis = iscoloring->n;
16*a64fbb32SBarry Smith   IS         *isa = iscoloring->is;
17*a64fbb32SBarry Smith   PetscTruth done;
18*a64fbb32SBarry Smith 
19*a64fbb32SBarry Smith   c->ncolors       = nis;
20*a64fbb32SBarry Smith   c->ncolumns      = (int *) PetscMalloc( nis*sizeof(int) );   CHKPTRQ(c->ncolumns);
21*a64fbb32SBarry Smith   c->columns       = (int **) PetscMalloc( nis*sizeof(int *)); CHKPTRQ(c->columns);
22*a64fbb32SBarry Smith   c->nrows         = (int *) PetscMalloc( nis*sizeof(int) );   CHKPTRQ(c->nrows);
23*a64fbb32SBarry Smith   c->rows          = (int **) PetscMalloc( nis*sizeof(int *)); CHKPTRQ(c->rows);
24*a64fbb32SBarry Smith   c->columnsforrow = (int **) PetscMalloc( nis*sizeof(int *)); CHKPTRQ(c->columnsforrow);
25*a64fbb32SBarry Smith   ierr = MatGetColumnIJ(mat,0,PETSC_FALSE,&ncols,&ci,&cj,&done); CHKERRQ(ierr);
26*a64fbb32SBarry Smith   /*
27*a64fbb32SBarry Smith      Temporary option to allow for debugging/testing
28*a64fbb32SBarry Smith   */
29*a64fbb32SBarry Smith   ierr = OptionsHasName(0,"-matfdcoloring_slow",&flg);
30*a64fbb32SBarry Smith   for ( i=0; i<nis; i++ ) {
31*a64fbb32SBarry Smith     ierr = ISGetSize(isa[i],&n); CHKERRQ(ierr);
32*a64fbb32SBarry Smith     ierr = ISGetIndices(isa[i],&is); CHKERRQ(ierr);
33*a64fbb32SBarry Smith     c->ncolumns[i] = n;
34*a64fbb32SBarry Smith     if (n) {
35*a64fbb32SBarry Smith       c->columns[i]  = (int *) PetscMalloc( n*sizeof(int) ); CHKPTRQ(c->columns[i]);
36*a64fbb32SBarry Smith       PetscMemcpy(c->columns[i],is,n*sizeof(int));
37*a64fbb32SBarry Smith     } else {
38*a64fbb32SBarry Smith       c->columns[i]  = 0;
39*a64fbb32SBarry Smith     }
40*a64fbb32SBarry Smith 
41*a64fbb32SBarry Smith     if (flg) { /* --------------------------------------------------------------------------------*/
42*a64fbb32SBarry Smith       /* crude version requires O(N*N) work */
43*a64fbb32SBarry Smith       int *rowhit = (int *) PetscMalloc( N*sizeof(int) ); CHKPTRQ(rowhit);
44*a64fbb32SBarry Smith       PetscMemzero(rowhit,N*sizeof(int));
45*a64fbb32SBarry Smith       /* loop over columns*/
46*a64fbb32SBarry Smith       for ( j=0; j<n; j++ ) {
47*a64fbb32SBarry Smith         col  = is[j];
48*a64fbb32SBarry Smith         rows = cj + ci[col];
49*a64fbb32SBarry Smith         m    = ci[col+1] - ci[col];
50*a64fbb32SBarry Smith         /* loop over columns marking them in rowhit */
51*a64fbb32SBarry Smith         for ( k=0; k<m; k++ ) {
52*a64fbb32SBarry Smith           rowhit[*rows++] = col + 1;
53*a64fbb32SBarry Smith         }
54*a64fbb32SBarry Smith       }
55*a64fbb32SBarry Smith       /* count the number of hits */
56*a64fbb32SBarry Smith       nrows = 0;
57*a64fbb32SBarry Smith       for ( j=0; j<N; j++ ) {
58*a64fbb32SBarry Smith         if (rowhit[j]) nrows++;
59*a64fbb32SBarry Smith       }
60*a64fbb32SBarry Smith       c->nrows[i]         = nrows;
61*a64fbb32SBarry Smith       c->rows[i]          = (int *) PetscMalloc(nrows*sizeof(int)); CHKPTRQ(c->rows[i]);
62*a64fbb32SBarry Smith       c->columnsforrow[i] = (int *) PetscMalloc(nrows*sizeof(int)); CHKPTRQ(c->columnsforrow[i]);
63*a64fbb32SBarry Smith       nrows = 0;
64*a64fbb32SBarry Smith       for ( j=0; j<N; j++ ) {
65*a64fbb32SBarry Smith         if (rowhit[j]) {
66*a64fbb32SBarry Smith           c->rows[i][nrows]           = j;
67*a64fbb32SBarry Smith           c->columnsforrow[i][nrows] = rowhit[j] - 1;
68*a64fbb32SBarry Smith           nrows++;
69*a64fbb32SBarry Smith         }
70*a64fbb32SBarry Smith       }
71*a64fbb32SBarry Smith       PetscFree(rowhit);
72*a64fbb32SBarry Smith     } else {  /*-------------------------------------------------------------------------------*/
73*a64fbb32SBarry Smith       /* efficient version, using rowhit as a linked list */
74*a64fbb32SBarry Smith       int currentcol,fm,mfm,*rowhit,*columnsforrow;
75*a64fbb32SBarry Smith       rowhit = (int *) PetscMalloc( (N+1)*sizeof(int) ); CHKPTRQ(rowhit);
76*a64fbb32SBarry Smith       columnsforrow = (int *) PetscMalloc( (N+1)*sizeof(int) ); CHKPTRQ(columnsforrow);
77*a64fbb32SBarry Smith       rowhit[N] = N;
78*a64fbb32SBarry Smith       nrows = 0;
79*a64fbb32SBarry Smith       /* loop over columns */
80*a64fbb32SBarry Smith       for ( j=0; j<n; j++ ) {
81*a64fbb32SBarry Smith         col   = is[j];
82*a64fbb32SBarry Smith         rows  = cj + ci[col];
83*a64fbb32SBarry Smith         m     = ci[col+1] - ci[col];
84*a64fbb32SBarry Smith         /* loop over columns marking them in rowhit */
85*a64fbb32SBarry Smith         fm    = N; /* fm points to first entry in linked list */
86*a64fbb32SBarry Smith         for ( k=0; k<m; k++ ) {
87*a64fbb32SBarry Smith           currentcol = *rows++;
88*a64fbb32SBarry Smith 	  /* is it already in the list? */
89*a64fbb32SBarry Smith           do {
90*a64fbb32SBarry Smith             mfm  = fm;
91*a64fbb32SBarry Smith             fm   = rowhit[fm];
92*a64fbb32SBarry Smith           } while (fm < currentcol);
93*a64fbb32SBarry Smith           /* not in list so add it */
94*a64fbb32SBarry Smith           if (fm != currentcol) {
95*a64fbb32SBarry Smith             nrows++;
96*a64fbb32SBarry Smith             columnsforrow[currentcol] = col;
97*a64fbb32SBarry Smith             /* next three lines insert new entry into linked list */
98*a64fbb32SBarry Smith             rowhit[mfm]               = currentcol;
99*a64fbb32SBarry Smith             rowhit[currentcol]        = fm;
100*a64fbb32SBarry Smith             fm                        = currentcol;
101*a64fbb32SBarry Smith             /* fm points to present position in list since we know the columns are sorted */
102*a64fbb32SBarry Smith           } else {
103*a64fbb32SBarry Smith             SETERRQ(1,"MatFDColoringCreate_SeqAIJ:Invalid coloring");
104*a64fbb32SBarry Smith           }
105*a64fbb32SBarry Smith 
106*a64fbb32SBarry Smith         }
107*a64fbb32SBarry Smith       }
108*a64fbb32SBarry Smith       c->nrows[i]         = nrows;
109*a64fbb32SBarry Smith       c->rows[i]          = (int *) PetscMalloc(nrows*sizeof(int));CHKPTRQ(c->rows[i]);
110*a64fbb32SBarry Smith       c->columnsforrow[i] = (int *) PetscMalloc(nrows*sizeof(int));CHKPTRQ(c->columnsforrow[i]);
111*a64fbb32SBarry Smith       /* now store the linked list of rows into c->rows[i] */
112*a64fbb32SBarry Smith       nrows = 0;
113*a64fbb32SBarry Smith       fm    = rowhit[N];
114*a64fbb32SBarry Smith       do {
115*a64fbb32SBarry Smith         c->rows[i][nrows]            = fm;
116*a64fbb32SBarry Smith         c->columnsforrow[i][nrows++] = columnsforrow[fm];
117*a64fbb32SBarry Smith         fm                           = rowhit[fm];
118*a64fbb32SBarry Smith       } while (fm < N);
119*a64fbb32SBarry Smith       PetscFree(rowhit);
120*a64fbb32SBarry Smith       PetscFree(columnsforrow);
121*a64fbb32SBarry Smith     } /* ---------------------------------------------------------------------------------------*/
122*a64fbb32SBarry Smith     ierr = ISRestoreIndices(isa[i],&is); CHKERRQ(ierr);
123*a64fbb32SBarry Smith   }
124*a64fbb32SBarry Smith   ierr = MatRestoreColumnIJ(mat,0,PETSC_FALSE,&ncols,&ci,&cj,&done); CHKERRQ(ierr);
125*a64fbb32SBarry Smith 
126*a64fbb32SBarry Smith   c->scale  = (Scalar *) PetscMalloc( 2*N*sizeof(Scalar) ); CHKPTRQ(c->scale);
127*a64fbb32SBarry Smith   c->wscale = c->scale + N;
128*a64fbb32SBarry Smith 
129*a64fbb32SBarry Smith   return 0;
130*a64fbb32SBarry Smith }
131*a64fbb32SBarry Smith 
132*a64fbb32SBarry Smith int MatColoringPatch_SeqAIJ(Mat mat,int ncolors,int *coloring,ISColoring *iscoloring)
133*a64fbb32SBarry Smith {
134*a64fbb32SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) mat->data;
135*a64fbb32SBarry Smith   int        n = a->n,*sizes,i,**ii,ierr;
136*a64fbb32SBarry Smith   IS         *is;
137*a64fbb32SBarry Smith 
138*a64fbb32SBarry Smith   /* construct the index sets from the coloring array */
139*a64fbb32SBarry Smith   sizes = (int *) PetscMalloc( ncolors*sizeof(int) ); CHKPTRQ(sizes);
140*a64fbb32SBarry Smith   PetscMemzero(sizes,ncolors*sizeof(int));
141*a64fbb32SBarry Smith   for ( i=0; i<n; i++ ) {
142*a64fbb32SBarry Smith     sizes[coloring[i]-1]++;
143*a64fbb32SBarry Smith   }
144*a64fbb32SBarry Smith   ii    = (int **) PetscMalloc( ncolors*sizeof(int*) ); CHKPTRQ(ii);
145*a64fbb32SBarry Smith   ii[0] = (int *) PetscMalloc( n*sizeof(int) ); CHKPTRQ(ii[0]);
146*a64fbb32SBarry Smith   for ( i=1; i<ncolors; i++ ) {
147*a64fbb32SBarry Smith     ii[i] = ii[i-1] + sizes[i-1];
148*a64fbb32SBarry Smith   }
149*a64fbb32SBarry Smith   PetscMemzero(sizes,ncolors*sizeof(int));
150*a64fbb32SBarry Smith   for ( i=0; i<n; i++ ) {
151*a64fbb32SBarry Smith     ii[coloring[i]-1][sizes[coloring[i]-1]++] = i;
152*a64fbb32SBarry Smith   }
153*a64fbb32SBarry Smith   is  = (IS *) PetscMalloc( ncolors*sizeof(is) ); CHKPTRQ(is);
154*a64fbb32SBarry Smith   for ( i=0; i<ncolors; i++ ) {
155*a64fbb32SBarry Smith     ierr = ISCreateGeneral(MPI_COMM_SELF,sizes[i],ii[i],is+i); CHKERRQ(ierr);
156*a64fbb32SBarry Smith   }
157*a64fbb32SBarry Smith 
158*a64fbb32SBarry Smith   *iscoloring         = (ISColoring) PetscMalloc(sizeof(struct _ISColoring));CHKPTRQ(*iscoloring);
159*a64fbb32SBarry Smith   (*iscoloring)->n    = ncolors;
160*a64fbb32SBarry Smith   (*iscoloring)->is   = is;
161*a64fbb32SBarry Smith   (*iscoloring)->comm = MPI_COMM_SELF;
162*a64fbb32SBarry Smith   PetscFree(sizes);
163*a64fbb32SBarry Smith   PetscFree(ii[0]);
164*a64fbb32SBarry Smith   PetscFree(ii);
165*a64fbb32SBarry Smith   return 0;
166*a64fbb32SBarry Smith }
167*a64fbb32SBarry Smith 
168*a64fbb32SBarry Smith /*
169*a64fbb32SBarry Smith      Makes a longer coloring[] array and calls the usual code with that
170*a64fbb32SBarry Smith */
171*a64fbb32SBarry Smith int MatColoringPatch_SeqAIJ_Inode(Mat mat,int ncolors,int *coloring,ISColoring *iscoloring)
172*a64fbb32SBarry Smith {
173*a64fbb32SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) mat->data;
174*a64fbb32SBarry Smith   int        n = a->n,ierr, m = a->inode.node_count,j,*ns = a->inode.size,row;
175*a64fbb32SBarry Smith   int        *colorused,i,*newcolor;
176*a64fbb32SBarry Smith 
177*a64fbb32SBarry Smith   newcolor = (int *) PetscMalloc((n+1)*sizeof(int)); CHKPTRQ(newcolor);
178*a64fbb32SBarry Smith 
179*a64fbb32SBarry Smith   /* loop over inodes, marking a color for each column*/
180*a64fbb32SBarry Smith   row = 0;
181*a64fbb32SBarry Smith   for ( i=0; i<m; i++){
182*a64fbb32SBarry Smith     for ( j=0; j<ns[i]; j++) {
183*a64fbb32SBarry Smith       newcolor[row++] = coloring[i] + j*ncolors;
184*a64fbb32SBarry Smith     }
185*a64fbb32SBarry Smith   }
186*a64fbb32SBarry Smith 
187*a64fbb32SBarry Smith   /* eliminate unneeded colors */
188*a64fbb32SBarry Smith   colorused = (int *) PetscMalloc( 5*ncolors*sizeof(int) ); CHKPTRQ(colorused);
189*a64fbb32SBarry Smith   PetscMemzero(colorused,5*ncolors*sizeof(int));
190*a64fbb32SBarry Smith   for ( i=0; i<n; i++ ) {
191*a64fbb32SBarry Smith     colorused[newcolor[i]-1] = 1;
192*a64fbb32SBarry Smith   }
193*a64fbb32SBarry Smith 
194*a64fbb32SBarry Smith   for ( i=1; i<5*ncolors; i++ ) {
195*a64fbb32SBarry Smith     colorused[i] += colorused[i-1];
196*a64fbb32SBarry Smith   }
197*a64fbb32SBarry Smith   ncolors = colorused[5*ncolors-1];
198*a64fbb32SBarry Smith   for ( i=0; i<n; i++ ) {
199*a64fbb32SBarry Smith     newcolor[i] = colorused[newcolor[i]-1];
200*a64fbb32SBarry Smith   }
201*a64fbb32SBarry Smith   PetscFree(colorused);
202*a64fbb32SBarry Smith 
203*a64fbb32SBarry Smith   ierr = MatColoringPatch_SeqAIJ(mat,ncolors,newcolor,iscoloring); CHKERRQ(ierr);
204*a64fbb32SBarry Smith   PetscFree(newcolor);
205*a64fbb32SBarry Smith 
206*a64fbb32SBarry Smith   return 0;
207*a64fbb32SBarry Smith }
208*a64fbb32SBarry Smith 
209