xref: /petsc/src/mat/impls/aij/seq/fdaij.c (revision f09e8eb94a771781a812a8d81a9ca3d36ec35eba)
170c3da92SBarry Smith 
270c3da92SBarry Smith #ifndef lint
3*f09e8eb9SSatish Balay static char vcid[] = "$Id: fdaij.c,v 1.10 1997/04/10 00:02:38 bsmith Exp balay $";
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"
9639f9d9dSBarry Smith 
1043a90d84SBarry Smith extern int MatGetColumnIJ_SeqAIJ(Mat,int,PetscTruth,int*,int**,int**,PetscTruth*);
1143a90d84SBarry Smith extern int MatRestoreColumnIJ_SeqAIJ(Mat,int,PetscTruth,int*,int**,int**,PetscTruth*);
1243a90d84SBarry Smith 
135615d1e5SSatish Balay #undef __FUNC__
145eea60f9SBarry Smith #define __FUNC__ "MatFDColoringCreate_SeqAIJ" /* ADIC Ignore */
15639f9d9dSBarry Smith int MatFDColoringCreate_SeqAIJ(Mat mat,ISColoring iscoloring,MatFDColoring c)
16639f9d9dSBarry Smith {
17639f9d9dSBarry Smith   int        i,*is,n,nrows,N = mat->N,j,k,m,*rows,ierr,*ci,*cj,ncols,col,flg;
18639f9d9dSBarry Smith   int        nis = iscoloring->n,*rowhit,*columnsforrow;
19639f9d9dSBarry Smith   IS         *isa = iscoloring->is;
20639f9d9dSBarry Smith   PetscTruth done;
21639f9d9dSBarry Smith 
22639f9d9dSBarry Smith   c->ncolors       = nis;
23639f9d9dSBarry Smith   c->ncolumns      = (int *) PetscMalloc( nis*sizeof(int) );   CHKPTRQ(c->ncolumns);
24639f9d9dSBarry Smith   c->columns       = (int **) PetscMalloc( nis*sizeof(int *)); CHKPTRQ(c->columns);
25639f9d9dSBarry Smith   c->nrows         = (int *) PetscMalloc( nis*sizeof(int) );   CHKPTRQ(c->nrows);
26639f9d9dSBarry Smith   c->rows          = (int **) PetscMalloc( nis*sizeof(int *)); CHKPTRQ(c->rows);
27639f9d9dSBarry Smith   c->columnsforrow = (int **) PetscMalloc( nis*sizeof(int *)); CHKPTRQ(c->columnsforrow);
2843a90d84SBarry Smith 
2943a90d84SBarry Smith   /*
3043a90d84SBarry Smith       Calls the _SeqAIJ() version of these routines to make sure it does not
3143a90d84SBarry Smith      get the reduced (by inodes) version of I and J
3243a90d84SBarry Smith   */
3343a90d84SBarry Smith   ierr = MatGetColumnIJ_SeqAIJ(mat,0,PETSC_FALSE,&ncols,&ci,&cj,&done); CHKERRQ(ierr);
3470c3da92SBarry Smith 
3570c3da92SBarry Smith   /*
36639f9d9dSBarry Smith      Temporary option to allow for debugging/testing
3770c3da92SBarry Smith   */
38639f9d9dSBarry Smith   ierr = OptionsHasName(0,"-matfdcoloring_slow",&flg);
3970c3da92SBarry Smith 
40639f9d9dSBarry Smith   rowhit        = (int *) PetscMalloc( (N+1)*sizeof(int) ); CHKPTRQ(rowhit);
41639f9d9dSBarry Smith   columnsforrow = (int *) PetscMalloc( (N+1)*sizeof(int) ); CHKPTRQ(columnsforrow);
4270c3da92SBarry Smith 
43639f9d9dSBarry Smith   for ( i=0; i<nis; i++ ) {
44639f9d9dSBarry Smith     ierr = ISGetSize(isa[i],&n); CHKERRQ(ierr);
45639f9d9dSBarry Smith     ierr = ISGetIndices(isa[i],&is); CHKERRQ(ierr);
46639f9d9dSBarry Smith     c->ncolumns[i] = n;
47639f9d9dSBarry Smith     if (n) {
48639f9d9dSBarry Smith       c->columns[i]  = (int *) PetscMalloc( n*sizeof(int) ); CHKPTRQ(c->columns[i]);
49639f9d9dSBarry Smith       PetscMemcpy(c->columns[i],is,n*sizeof(int));
5070c3da92SBarry Smith     } else {
51639f9d9dSBarry Smith       c->columns[i]  = 0;
5270c3da92SBarry Smith     }
5370c3da92SBarry Smith 
54639f9d9dSBarry Smith     if (flg) { /* ------------------------------------------------------------------------------*/
55639f9d9dSBarry Smith       /* crude version requires O(N*N) work */
56639f9d9dSBarry Smith       PetscMemzero(rowhit,N*sizeof(int));
57639f9d9dSBarry Smith       /* loop over columns*/
58639f9d9dSBarry Smith       for ( j=0; j<n; j++ ) {
59639f9d9dSBarry Smith         col  = is[j];
60639f9d9dSBarry Smith         rows = cj + ci[col];
61639f9d9dSBarry Smith         m    = ci[col+1] - ci[col];
62639f9d9dSBarry Smith         /* loop over columns marking them in rowhit */
63639f9d9dSBarry Smith         for ( k=0; k<m; k++ ) {
64639f9d9dSBarry Smith           rowhit[*rows++] = col + 1;
6570c3da92SBarry Smith         }
6670c3da92SBarry Smith       }
67639f9d9dSBarry Smith       /* count the number of hits */
68639f9d9dSBarry Smith       nrows = 0;
6970c3da92SBarry Smith       for ( j=0; j<N; j++ ) {
70639f9d9dSBarry Smith         if (rowhit[j]) nrows++;
71639f9d9dSBarry Smith       }
72639f9d9dSBarry Smith       c->nrows[i]         = nrows;
73639f9d9dSBarry Smith       c->rows[i]          = (int *) PetscMalloc(nrows*sizeof(int)); CHKPTRQ(c->rows[i]);
74639f9d9dSBarry Smith       c->columnsforrow[i] = (int *) PetscMalloc(nrows*sizeof(int)); CHKPTRQ(c->columnsforrow[i]);
75639f9d9dSBarry Smith       nrows = 0;
76639f9d9dSBarry Smith       for ( j=0; j<N; j++ ) {
77639f9d9dSBarry Smith         if (rowhit[j]) {
78639f9d9dSBarry Smith           c->rows[i][nrows]           = j;
79639f9d9dSBarry Smith           c->columnsforrow[i][nrows] = rowhit[j] - 1;
80639f9d9dSBarry Smith           nrows++;
8170c3da92SBarry Smith         }
8270c3da92SBarry Smith       }
83639f9d9dSBarry Smith     } else {  /*-------------------------------------------------------------------------------*/
84639f9d9dSBarry Smith       /* efficient version, using rowhit as a linked list */
85639f9d9dSBarry Smith       int currentcol,fm,mfm;
86639f9d9dSBarry Smith       rowhit[N] = N;
87639f9d9dSBarry Smith       nrows     = 0;
88639f9d9dSBarry Smith       /* loop over columns */
89639f9d9dSBarry Smith       for ( j=0; j<n; j++ ) {
90639f9d9dSBarry Smith         col   = is[j];
91639f9d9dSBarry Smith         rows  = cj + ci[col];
92639f9d9dSBarry Smith         m     = ci[col+1] - ci[col];
93639f9d9dSBarry Smith         /* loop over columns marking them in rowhit */
94639f9d9dSBarry Smith         fm    = N; /* fm points to first entry in linked list */
95639f9d9dSBarry Smith         for ( k=0; k<m; k++ ) {
96639f9d9dSBarry Smith           currentcol = *rows++;
97639f9d9dSBarry Smith 	  /* is it already in the list? */
98639f9d9dSBarry Smith           do {
99639f9d9dSBarry Smith             mfm  = fm;
100639f9d9dSBarry Smith             fm   = rowhit[fm];
101639f9d9dSBarry Smith           } while (fm < currentcol);
102639f9d9dSBarry Smith           /* not in list so add it */
103639f9d9dSBarry Smith           if (fm != currentcol) {
104639f9d9dSBarry Smith             nrows++;
105639f9d9dSBarry Smith             columnsforrow[currentcol] = col;
106639f9d9dSBarry Smith             /* next three lines insert new entry into linked list */
107639f9d9dSBarry Smith             rowhit[mfm]               = currentcol;
108639f9d9dSBarry Smith             rowhit[currentcol]        = fm;
109639f9d9dSBarry Smith             fm                        = currentcol;
110639f9d9dSBarry Smith             /* fm points to present position in list since we know the columns are sorted */
11170c3da92SBarry Smith           } else {
112e3372554SBarry Smith             SETERRQ(1,0,"Invalid coloring");
11370c3da92SBarry Smith           }
114639f9d9dSBarry Smith 
115639f9d9dSBarry Smith         }
116639f9d9dSBarry Smith       }
117639f9d9dSBarry Smith       c->nrows[i]         = nrows;
118639f9d9dSBarry Smith       c->rows[i]          = (int *)PetscMalloc((nrows+1)*sizeof(int));CHKPTRQ(c->rows[i]);
119639f9d9dSBarry Smith       c->columnsforrow[i] = (int *)PetscMalloc((nrows+1)*sizeof(int));CHKPTRQ(c->columnsforrow[i]);
120639f9d9dSBarry Smith       /* now store the linked list of rows into c->rows[i] */
121639f9d9dSBarry Smith       nrows = 0;
122639f9d9dSBarry Smith       fm    = rowhit[N];
123639f9d9dSBarry Smith       do {
124639f9d9dSBarry Smith         c->rows[i][nrows]            = fm;
125639f9d9dSBarry Smith         c->columnsforrow[i][nrows++] = columnsforrow[fm];
126639f9d9dSBarry Smith         fm                           = rowhit[fm];
127639f9d9dSBarry Smith       } while (fm < N);
128639f9d9dSBarry Smith     } /* ---------------------------------------------------------------------------------------*/
129639f9d9dSBarry Smith     ierr = ISRestoreIndices(isa[i],&is); CHKERRQ(ierr);
130639f9d9dSBarry Smith   }
13143a90d84SBarry Smith   ierr = MatRestoreColumnIJ_SeqAIJ(mat,0,PETSC_FALSE,&ncols,&ci,&cj,&done); CHKERRQ(ierr);
132639f9d9dSBarry Smith 
133639f9d9dSBarry Smith   PetscFree(rowhit);
134639f9d9dSBarry Smith   PetscFree(columnsforrow);
135639f9d9dSBarry Smith 
136639f9d9dSBarry Smith   c->scale  = (Scalar *) PetscMalloc( 2*N*sizeof(Scalar) ); CHKPTRQ(c->scale);
137639f9d9dSBarry Smith   c->wscale = c->scale + N;
138639f9d9dSBarry Smith 
13970c3da92SBarry Smith   return 0;
14070c3da92SBarry Smith }
14170c3da92SBarry Smith 
1425615d1e5SSatish Balay #undef __FUNC__
1435eea60f9SBarry Smith #define __FUNC__ "MatColoringPatch_SeqAIJ" /* ADIC Ignore */
144639f9d9dSBarry Smith int MatColoringPatch_SeqAIJ(Mat mat,int ncolors,int *coloring,ISColoring *iscoloring)
14570c3da92SBarry Smith {
146639f9d9dSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) mat->data;
147639f9d9dSBarry Smith   int        n = a->n,*sizes,i,**ii,ierr,tag;
148639f9d9dSBarry Smith   IS         *is;
14970c3da92SBarry Smith 
150639f9d9dSBarry Smith   /* construct the index sets from the coloring array */
151639f9d9dSBarry Smith   sizes = (int *) PetscMalloc( ncolors*sizeof(int) ); CHKPTRQ(sizes);
152639f9d9dSBarry Smith   PetscMemzero(sizes,ncolors*sizeof(int));
15370c3da92SBarry Smith   for ( i=0; i<n; i++ ) {
154639f9d9dSBarry Smith     sizes[coloring[i]-1]++;
15570c3da92SBarry Smith   }
156639f9d9dSBarry Smith   ii    = (int **) PetscMalloc( ncolors*sizeof(int*) ); CHKPTRQ(ii);
157639f9d9dSBarry Smith   ii[0] = (int *) PetscMalloc( n*sizeof(int) ); CHKPTRQ(ii[0]);
158639f9d9dSBarry Smith   for ( i=1; i<ncolors; i++ ) {
159639f9d9dSBarry Smith     ii[i] = ii[i-1] + sizes[i-1];
160639f9d9dSBarry Smith   }
161639f9d9dSBarry Smith   PetscMemzero(sizes,ncolors*sizeof(int));
162639f9d9dSBarry Smith   for ( i=0; i<n; i++ ) {
163639f9d9dSBarry Smith     ii[coloring[i]-1][sizes[coloring[i]-1]++] = i;
164639f9d9dSBarry Smith   }
165775f6a71SSatish Balay   is  = (IS *) PetscMalloc( ncolors*sizeof(IS) ); CHKPTRQ(is);
166639f9d9dSBarry Smith   for ( i=0; i<ncolors; i++ ) {
167029af93fSBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,sizes[i],ii[i],is+i); CHKERRQ(ierr);
168639f9d9dSBarry Smith   }
169639f9d9dSBarry Smith 
170*f09e8eb9SSatish Balay   *iscoloring         = (ISColoring) PetscMalloc(sizeof(struct _p_ISColoring));CHKPTRQ(*iscoloring);
171639f9d9dSBarry Smith   (*iscoloring)->n    = ncolors;
172639f9d9dSBarry Smith   (*iscoloring)->is   = is;
173639f9d9dSBarry Smith   PetscCommDup_Private(mat->comm,&(*iscoloring)->comm,&tag);
174639f9d9dSBarry Smith   PetscFree(sizes);
175639f9d9dSBarry Smith   PetscFree(ii[0]);
176639f9d9dSBarry Smith   PetscFree(ii);
17770c3da92SBarry Smith   return 0;
17870c3da92SBarry Smith }
17970c3da92SBarry Smith 
180639f9d9dSBarry Smith /*
181639f9d9dSBarry Smith      Makes a longer coloring[] array and calls the usual code with that
182639f9d9dSBarry Smith */
1835615d1e5SSatish Balay #undef __FUNC__
1845eea60f9SBarry Smith #define __FUNC__ "MatColoringPatch_SeqAIJ_Inode" /* ADIC Ignore */
185639f9d9dSBarry Smith int MatColoringPatch_SeqAIJ_Inode(Mat mat,int ncolors,int *coloring,ISColoring *iscoloring)
18670c3da92SBarry Smith {
187639f9d9dSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) mat->data;
188639f9d9dSBarry Smith   int        n = a->n,ierr, m = a->inode.node_count,j,*ns = a->inode.size,row;
189639f9d9dSBarry Smith   int        *colorused,i,*newcolor;
19070c3da92SBarry Smith 
191639f9d9dSBarry Smith   newcolor = (int *) PetscMalloc((n+1)*sizeof(int)); CHKPTRQ(newcolor);
19270c3da92SBarry Smith 
193639f9d9dSBarry Smith   /* loop over inodes, marking a color for each column*/
194639f9d9dSBarry Smith   row = 0;
19570c3da92SBarry Smith   for ( i=0; i<m; i++){
196639f9d9dSBarry Smith     for ( j=0; j<ns[i]; j++) {
197639f9d9dSBarry Smith       newcolor[row++] = coloring[i] + j*ncolors;
19870c3da92SBarry Smith     }
19970c3da92SBarry Smith   }
20070c3da92SBarry Smith 
201639f9d9dSBarry Smith   /* eliminate unneeded colors */
202639f9d9dSBarry Smith   colorused = (int *) PetscMalloc( 5*ncolors*sizeof(int) ); CHKPTRQ(colorused);
203639f9d9dSBarry Smith   PetscMemzero(colorused,5*ncolors*sizeof(int));
204639f9d9dSBarry Smith   for ( i=0; i<n; i++ ) {
205639f9d9dSBarry Smith     colorused[newcolor[i]-1] = 1;
206639f9d9dSBarry Smith   }
20770c3da92SBarry Smith 
208639f9d9dSBarry Smith   for ( i=1; i<5*ncolors; i++ ) {
209639f9d9dSBarry Smith     colorused[i] += colorused[i-1];
21070c3da92SBarry Smith   }
211639f9d9dSBarry Smith   ncolors = colorused[5*ncolors-1];
212639f9d9dSBarry Smith   for ( i=0; i<n; i++ ) {
213639f9d9dSBarry Smith     newcolor[i] = colorused[newcolor[i]-1];
21470c3da92SBarry Smith   }
215639f9d9dSBarry Smith   PetscFree(colorused);
21670c3da92SBarry Smith 
217639f9d9dSBarry Smith   ierr = MatColoringPatch_SeqAIJ(mat,ncolors,newcolor,iscoloring); CHKERRQ(ierr);
218639f9d9dSBarry Smith   PetscFree(newcolor);
219639f9d9dSBarry Smith 
22070c3da92SBarry Smith   return 0;
22170c3da92SBarry Smith }
22270c3da92SBarry Smith 
223