xref: /petsc/src/mat/impls/aij/seq/fdaij.c (revision 639f9d9dbbc54d6ac4e42e98283c540b41bb2cee)
170c3da92SBarry Smith 
270c3da92SBarry Smith #ifndef lint
3*639f9d9dSBarry Smith static char vcid[] = "$Id: fdaij.c,v 1.1 1996/10/09 18:09:59 bsmith Exp bsmith $";
470c3da92SBarry Smith #endif
570c3da92SBarry Smith 
670c3da92SBarry Smith #include "src/mat/impls/aij/seq/aij.h"
770c3da92SBarry Smith #include "src/vec/vecimpl.h"
870c3da92SBarry Smith #include "petsc.h"
9*639f9d9dSBarry Smith 
10*639f9d9dSBarry Smith int MatFDColoringCreate_SeqAIJ(Mat mat,ISColoring iscoloring,MatFDColoring c)
11*639f9d9dSBarry Smith {
12*639f9d9dSBarry Smith   int        i,*is,n,nrows,N = mat->N,j,k,m,*rows,ierr,*ci,*cj,ncols,col,flg;
13*639f9d9dSBarry Smith   int        nis = iscoloring->n,*rowhit,*columnsforrow;
14*639f9d9dSBarry Smith   IS         *isa = iscoloring->is;
15*639f9d9dSBarry Smith   PetscTruth done;
16*639f9d9dSBarry Smith 
17*639f9d9dSBarry Smith   c->ncolors       = nis;
18*639f9d9dSBarry Smith   c->ncolumns      = (int *) PetscMalloc( nis*sizeof(int) );   CHKPTRQ(c->ncolumns);
19*639f9d9dSBarry Smith   c->columns       = (int **) PetscMalloc( nis*sizeof(int *)); CHKPTRQ(c->columns);
20*639f9d9dSBarry Smith   c->nrows         = (int *) PetscMalloc( nis*sizeof(int) );   CHKPTRQ(c->nrows);
21*639f9d9dSBarry Smith   c->rows          = (int **) PetscMalloc( nis*sizeof(int *)); CHKPTRQ(c->rows);
22*639f9d9dSBarry Smith   c->columnsforrow = (int **) PetscMalloc( nis*sizeof(int *)); CHKPTRQ(c->columnsforrow);
23*639f9d9dSBarry Smith   ierr = MatGetColumnIJ(mat,0,PETSC_FALSE,&ncols,&ci,&cj,&done); CHKERRQ(ierr);
2470c3da92SBarry Smith 
2570c3da92SBarry Smith   /*
26*639f9d9dSBarry Smith      Temporary option to allow for debugging/testing
2770c3da92SBarry Smith   */
28*639f9d9dSBarry Smith   ierr = OptionsHasName(0,"-matfdcoloring_slow",&flg);
2970c3da92SBarry Smith 
30*639f9d9dSBarry Smith   rowhit        = (int *) PetscMalloc( (N+1)*sizeof(int) ); CHKPTRQ(rowhit);
31*639f9d9dSBarry Smith   columnsforrow = (int *) PetscMalloc( (N+1)*sizeof(int) ); CHKPTRQ(columnsforrow);
3270c3da92SBarry Smith 
33*639f9d9dSBarry Smith   for ( i=0; i<nis; i++ ) {
34*639f9d9dSBarry Smith     ierr = ISGetSize(isa[i],&n); CHKERRQ(ierr);
35*639f9d9dSBarry Smith     ierr = ISGetIndices(isa[i],&is); CHKERRQ(ierr);
36*639f9d9dSBarry Smith     c->ncolumns[i] = n;
37*639f9d9dSBarry Smith     if (n) {
38*639f9d9dSBarry Smith       c->columns[i]  = (int *) PetscMalloc( n*sizeof(int) ); CHKPTRQ(c->columns[i]);
39*639f9d9dSBarry Smith       PetscMemcpy(c->columns[i],is,n*sizeof(int));
4070c3da92SBarry Smith     } else {
41*639f9d9dSBarry Smith       c->columns[i]  = 0;
4270c3da92SBarry Smith     }
4370c3da92SBarry Smith 
44*639f9d9dSBarry Smith     if (flg) { /* ------------------------------------------------------------------------------*/
45*639f9d9dSBarry Smith       /* crude version requires O(N*N) work */
46*639f9d9dSBarry Smith       PetscMemzero(rowhit,N*sizeof(int));
47*639f9d9dSBarry Smith       /* loop over columns*/
48*639f9d9dSBarry Smith       for ( j=0; j<n; j++ ) {
49*639f9d9dSBarry Smith         col  = is[j];
50*639f9d9dSBarry Smith         rows = cj + ci[col];
51*639f9d9dSBarry Smith         m    = ci[col+1] - ci[col];
52*639f9d9dSBarry Smith         /* loop over columns marking them in rowhit */
53*639f9d9dSBarry Smith         for ( k=0; k<m; k++ ) {
54*639f9d9dSBarry Smith           rowhit[*rows++] = col + 1;
5570c3da92SBarry Smith         }
5670c3da92SBarry Smith       }
57*639f9d9dSBarry Smith       /* count the number of hits */
58*639f9d9dSBarry Smith       nrows = 0;
5970c3da92SBarry Smith       for ( j=0; j<N; j++ ) {
60*639f9d9dSBarry Smith         if (rowhit[j]) nrows++;
61*639f9d9dSBarry Smith       }
62*639f9d9dSBarry Smith       c->nrows[i]         = nrows;
63*639f9d9dSBarry Smith       c->rows[i]          = (int *) PetscMalloc(nrows*sizeof(int)); CHKPTRQ(c->rows[i]);
64*639f9d9dSBarry Smith       c->columnsforrow[i] = (int *) PetscMalloc(nrows*sizeof(int)); CHKPTRQ(c->columnsforrow[i]);
65*639f9d9dSBarry Smith       nrows = 0;
66*639f9d9dSBarry Smith       for ( j=0; j<N; j++ ) {
67*639f9d9dSBarry Smith         if (rowhit[j]) {
68*639f9d9dSBarry Smith           c->rows[i][nrows]           = j;
69*639f9d9dSBarry Smith           c->columnsforrow[i][nrows] = rowhit[j] - 1;
70*639f9d9dSBarry Smith           nrows++;
7170c3da92SBarry Smith         }
7270c3da92SBarry Smith       }
73*639f9d9dSBarry Smith     } else {  /*-------------------------------------------------------------------------------*/
74*639f9d9dSBarry Smith       /* efficient version, using rowhit as a linked list */
75*639f9d9dSBarry Smith       int currentcol,fm,mfm;
76*639f9d9dSBarry Smith       rowhit[N] = N;
77*639f9d9dSBarry Smith       nrows     = 0;
78*639f9d9dSBarry Smith       /* loop over columns */
79*639f9d9dSBarry Smith       for ( j=0; j<n; j++ ) {
80*639f9d9dSBarry Smith         col   = is[j];
81*639f9d9dSBarry Smith         rows  = cj + ci[col];
82*639f9d9dSBarry Smith         m     = ci[col+1] - ci[col];
83*639f9d9dSBarry Smith         /* loop over columns marking them in rowhit */
84*639f9d9dSBarry Smith         fm    = N; /* fm points to first entry in linked list */
85*639f9d9dSBarry Smith         for ( k=0; k<m; k++ ) {
86*639f9d9dSBarry Smith           currentcol = *rows++;
87*639f9d9dSBarry Smith 	  /* is it already in the list? */
88*639f9d9dSBarry Smith           do {
89*639f9d9dSBarry Smith             mfm  = fm;
90*639f9d9dSBarry Smith             fm   = rowhit[fm];
91*639f9d9dSBarry Smith           } while (fm < currentcol);
92*639f9d9dSBarry Smith           /* not in list so add it */
93*639f9d9dSBarry Smith           if (fm != currentcol) {
94*639f9d9dSBarry Smith             nrows++;
95*639f9d9dSBarry Smith             columnsforrow[currentcol] = col;
96*639f9d9dSBarry Smith             /* next three lines insert new entry into linked list */
97*639f9d9dSBarry Smith             rowhit[mfm]               = currentcol;
98*639f9d9dSBarry Smith             rowhit[currentcol]        = fm;
99*639f9d9dSBarry Smith             fm                        = currentcol;
100*639f9d9dSBarry Smith             /* fm points to present position in list since we know the columns are sorted */
10170c3da92SBarry Smith           } else {
102*639f9d9dSBarry Smith             SETERRQ(1,"MatFDColoringCreate_SeqAIJ:Invalid coloring");
10370c3da92SBarry Smith           }
104*639f9d9dSBarry Smith 
105*639f9d9dSBarry Smith         }
106*639f9d9dSBarry Smith       }
107*639f9d9dSBarry Smith       c->nrows[i]         = nrows;
108*639f9d9dSBarry Smith       c->rows[i]          = (int *)PetscMalloc((nrows+1)*sizeof(int));CHKPTRQ(c->rows[i]);
109*639f9d9dSBarry Smith       c->columnsforrow[i] = (int *)PetscMalloc((nrows+1)*sizeof(int));CHKPTRQ(c->columnsforrow[i]);
110*639f9d9dSBarry Smith       /* now store the linked list of rows into c->rows[i] */
111*639f9d9dSBarry Smith       nrows = 0;
112*639f9d9dSBarry Smith       fm    = rowhit[N];
113*639f9d9dSBarry Smith       do {
114*639f9d9dSBarry Smith         c->rows[i][nrows]            = fm;
115*639f9d9dSBarry Smith         c->columnsforrow[i][nrows++] = columnsforrow[fm];
116*639f9d9dSBarry Smith         fm                           = rowhit[fm];
117*639f9d9dSBarry Smith       } while (fm < N);
118*639f9d9dSBarry Smith     } /* ---------------------------------------------------------------------------------------*/
119*639f9d9dSBarry Smith     ierr = ISRestoreIndices(isa[i],&is); CHKERRQ(ierr);
120*639f9d9dSBarry Smith   }
121*639f9d9dSBarry Smith   ierr = MatRestoreColumnIJ(mat,0,PETSC_FALSE,&ncols,&ci,&cj,&done); CHKERRQ(ierr);
122*639f9d9dSBarry Smith 
123*639f9d9dSBarry Smith   PetscFree(rowhit);
124*639f9d9dSBarry Smith   PetscFree(columnsforrow);
125*639f9d9dSBarry Smith 
126*639f9d9dSBarry Smith   c->scale  = (Scalar *) PetscMalloc( 2*N*sizeof(Scalar) ); CHKPTRQ(c->scale);
127*639f9d9dSBarry Smith   c->wscale = c->scale + N;
128*639f9d9dSBarry Smith 
12970c3da92SBarry Smith   return 0;
13070c3da92SBarry Smith }
13170c3da92SBarry Smith 
132*639f9d9dSBarry Smith int MatColoringPatch_SeqAIJ(Mat mat,int ncolors,int *coloring,ISColoring *iscoloring)
13370c3da92SBarry Smith {
134*639f9d9dSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) mat->data;
135*639f9d9dSBarry Smith   int        n = a->n,*sizes,i,**ii,ierr,tag;
136*639f9d9dSBarry Smith   IS         *is;
13770c3da92SBarry Smith 
138*639f9d9dSBarry Smith   /* construct the index sets from the coloring array */
139*639f9d9dSBarry Smith   sizes = (int *) PetscMalloc( ncolors*sizeof(int) ); CHKPTRQ(sizes);
140*639f9d9dSBarry Smith   PetscMemzero(sizes,ncolors*sizeof(int));
14170c3da92SBarry Smith   for ( i=0; i<n; i++ ) {
142*639f9d9dSBarry Smith     sizes[coloring[i]-1]++;
14370c3da92SBarry Smith   }
144*639f9d9dSBarry Smith   ii    = (int **) PetscMalloc( ncolors*sizeof(int*) ); CHKPTRQ(ii);
145*639f9d9dSBarry Smith   ii[0] = (int *) PetscMalloc( n*sizeof(int) ); CHKPTRQ(ii[0]);
146*639f9d9dSBarry Smith   for ( i=1; i<ncolors; i++ ) {
147*639f9d9dSBarry Smith     ii[i] = ii[i-1] + sizes[i-1];
148*639f9d9dSBarry Smith   }
149*639f9d9dSBarry Smith   PetscMemzero(sizes,ncolors*sizeof(int));
150*639f9d9dSBarry Smith   for ( i=0; i<n; i++ ) {
151*639f9d9dSBarry Smith     ii[coloring[i]-1][sizes[coloring[i]-1]++] = i;
152*639f9d9dSBarry Smith   }
153*639f9d9dSBarry Smith   is  = (IS *) PetscMalloc( ncolors*sizeof(is) ); CHKPTRQ(is);
154*639f9d9dSBarry Smith   for ( i=0; i<ncolors; i++ ) {
155*639f9d9dSBarry Smith     ierr = ISCreateGeneral(MPI_COMM_SELF,sizes[i],ii[i],is+i); CHKERRQ(ierr);
156*639f9d9dSBarry Smith   }
157*639f9d9dSBarry Smith 
158*639f9d9dSBarry Smith   *iscoloring         = (ISColoring) PetscMalloc(sizeof(struct _ISColoring));CHKPTRQ(*iscoloring);
159*639f9d9dSBarry Smith   (*iscoloring)->n    = ncolors;
160*639f9d9dSBarry Smith   (*iscoloring)->is   = is;
161*639f9d9dSBarry Smith   PetscCommDup_Private(mat->comm,&(*iscoloring)->comm,&tag);
162*639f9d9dSBarry Smith   PetscFree(sizes);
163*639f9d9dSBarry Smith   PetscFree(ii[0]);
164*639f9d9dSBarry Smith   PetscFree(ii);
16570c3da92SBarry Smith   return 0;
16670c3da92SBarry Smith }
16770c3da92SBarry Smith 
168*639f9d9dSBarry Smith /*
169*639f9d9dSBarry Smith      Makes a longer coloring[] array and calls the usual code with that
170*639f9d9dSBarry Smith */
171*639f9d9dSBarry Smith int MatColoringPatch_SeqAIJ_Inode(Mat mat,int ncolors,int *coloring,ISColoring *iscoloring)
17270c3da92SBarry Smith {
173*639f9d9dSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) mat->data;
174*639f9d9dSBarry Smith   int        n = a->n,ierr, m = a->inode.node_count,j,*ns = a->inode.size,row;
175*639f9d9dSBarry Smith   int        *colorused,i,*newcolor;
17670c3da92SBarry Smith 
177*639f9d9dSBarry Smith   newcolor = (int *) PetscMalloc((n+1)*sizeof(int)); CHKPTRQ(newcolor);
17870c3da92SBarry Smith 
179*639f9d9dSBarry Smith   /* loop over inodes, marking a color for each column*/
180*639f9d9dSBarry Smith   row = 0;
18170c3da92SBarry Smith   for ( i=0; i<m; i++){
182*639f9d9dSBarry Smith     for ( j=0; j<ns[i]; j++) {
183*639f9d9dSBarry Smith       newcolor[row++] = coloring[i] + j*ncolors;
18470c3da92SBarry Smith     }
18570c3da92SBarry Smith   }
18670c3da92SBarry Smith 
187*639f9d9dSBarry Smith   /* eliminate unneeded colors */
188*639f9d9dSBarry Smith   colorused = (int *) PetscMalloc( 5*ncolors*sizeof(int) ); CHKPTRQ(colorused);
189*639f9d9dSBarry Smith   PetscMemzero(colorused,5*ncolors*sizeof(int));
190*639f9d9dSBarry Smith   for ( i=0; i<n; i++ ) {
191*639f9d9dSBarry Smith     colorused[newcolor[i]-1] = 1;
192*639f9d9dSBarry Smith   }
19370c3da92SBarry Smith 
194*639f9d9dSBarry Smith   for ( i=1; i<5*ncolors; i++ ) {
195*639f9d9dSBarry Smith     colorused[i] += colorused[i-1];
19670c3da92SBarry Smith   }
197*639f9d9dSBarry Smith   ncolors = colorused[5*ncolors-1];
198*639f9d9dSBarry Smith   for ( i=0; i<n; i++ ) {
199*639f9d9dSBarry Smith     newcolor[i] = colorused[newcolor[i]-1];
20070c3da92SBarry Smith   }
201*639f9d9dSBarry Smith   PetscFree(colorused);
20270c3da92SBarry Smith 
203*639f9d9dSBarry Smith   ierr = MatColoringPatch_SeqAIJ(mat,ncolors,newcolor,iscoloring); CHKERRQ(ierr);
204*639f9d9dSBarry Smith   PetscFree(newcolor);
205*639f9d9dSBarry Smith 
20670c3da92SBarry Smith   return 0;
20770c3da92SBarry Smith }
20870c3da92SBarry Smith 
209