xref: /petsc/src/mat/impls/aij/seq/fdaij.c (revision ca44d042d6f86ecc01fa7a52a5213a5161f95f53)
1*ca44d042SBarry Smith /*$Id: fdaij.c,v 1.29 2000/05/04 16:25:26 bsmith Exp bsmith $*/
270c3da92SBarry Smith 
370c3da92SBarry Smith #include "src/mat/impls/aij/seq/aij.h"
470c3da92SBarry Smith #include "src/vec/vecimpl.h"
5639f9d9dSBarry Smith 
6*ca44d042SBarry Smith EXTERN int MatGetColumnIJ_SeqAIJ(Mat,int,PetscTruth,int*,int**,int**,PetscTruth*);
7*ca44d042SBarry Smith EXTERN int MatRestoreColumnIJ_SeqAIJ(Mat,int,PetscTruth,int*,int**,int**,PetscTruth*);
843a90d84SBarry Smith 
95615d1e5SSatish Balay #undef __FUNC__
10b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatFDColoringCreate_SeqAIJ"
11639f9d9dSBarry Smith int MatFDColoringCreate_SeqAIJ(Mat mat,ISColoring iscoloring,MatFDColoring c)
12639f9d9dSBarry Smith {
13f1af5d2fSBarry Smith   int        i,*is,n,nrows,N = mat->N,j,k,m,*rows,ierr,*ci,*cj,ncols,col;
14639f9d9dSBarry Smith   int        nis = iscoloring->n,*rowhit,*columnsforrow;
15639f9d9dSBarry Smith   IS         *isa = iscoloring->is;
16f1af5d2fSBarry Smith   PetscTruth done,flg;
17639f9d9dSBarry Smith 
183a40ed3dSBarry Smith   PetscFunctionBegin;
19522c5e43SBarry Smith   if (!mat->assembled) {
20a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,1,"Matrix must be assembled by calls to MatAssemblyBegin/End();");
21522c5e43SBarry Smith   }
22522c5e43SBarry Smith 
23005c665bSBarry Smith   c->M             = mat->M;  /* set total rows, columns and local rows */
24005c665bSBarry Smith   c->N             = mat->N;
25005c665bSBarry Smith   c->m             = mat->M;
26005c665bSBarry Smith   c->rstart        = 0;
27005c665bSBarry Smith 
28639f9d9dSBarry Smith   c->ncolors       = nis;
29639f9d9dSBarry Smith   c->ncolumns      = (int*)PetscMalloc(nis*sizeof(int));CHKPTRQ(c->ncolumns);
30639f9d9dSBarry Smith   c->columns       = (int**)PetscMalloc(nis*sizeof(int *));CHKPTRQ(c->columns);
31639f9d9dSBarry Smith   c->nrows         = (int*)PetscMalloc(nis*sizeof(int));CHKPTRQ(c->nrows);
32639f9d9dSBarry Smith   c->rows          = (int**)PetscMalloc(nis*sizeof(int *));CHKPTRQ(c->rows);
33639f9d9dSBarry Smith   c->columnsforrow = (int**)PetscMalloc(nis*sizeof(int *));CHKPTRQ(c->columnsforrow);
3443a90d84SBarry Smith 
3543a90d84SBarry Smith   /*
3643a90d84SBarry Smith       Calls the _SeqAIJ() version of these routines to make sure it does not
3743a90d84SBarry Smith      get the reduced (by inodes) version of I and J
3843a90d84SBarry Smith   */
3943a90d84SBarry Smith   ierr = MatGetColumnIJ_SeqAIJ(mat,0,PETSC_FALSE,&ncols,&ci,&cj,&done);CHKERRQ(ierr);
4070c3da92SBarry Smith 
4170c3da92SBarry Smith   /*
42639f9d9dSBarry Smith      Temporary option to allow for debugging/testing
4370c3da92SBarry Smith   */
44454a90a3SBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-matfdcoloring_slow",&flg);CHKERRQ(ierr);
4570c3da92SBarry Smith 
46639f9d9dSBarry Smith   rowhit        = (int*)PetscMalloc((N+1)*sizeof(int));CHKPTRQ(rowhit);
47639f9d9dSBarry Smith   columnsforrow = (int*)PetscMalloc((N+1)*sizeof(int));CHKPTRQ(columnsforrow);
4870c3da92SBarry Smith 
49639f9d9dSBarry Smith   for (i=0; i<nis; i++) {
50639f9d9dSBarry Smith     ierr = ISGetSize(isa[i],&n);CHKERRQ(ierr);
51639f9d9dSBarry Smith     ierr = ISGetIndices(isa[i],&is);CHKERRQ(ierr);
52639f9d9dSBarry Smith     c->ncolumns[i] = n;
53639f9d9dSBarry Smith     if (n) {
54639f9d9dSBarry Smith       c->columns[i]  = (int*)PetscMalloc(n*sizeof(int));CHKPTRQ(c->columns[i]);
55549d3d68SSatish Balay       ierr = PetscMemcpy(c->columns[i],is,n*sizeof(int));CHKERRQ(ierr);
5670c3da92SBarry Smith     } else {
57639f9d9dSBarry Smith       c->columns[i]  = 0;
5870c3da92SBarry Smith     }
5970c3da92SBarry Smith 
60639f9d9dSBarry Smith     if (flg) { /* ------------------------------------------------------------------------------*/
61639f9d9dSBarry Smith       /* crude version requires O(N*N) work */
62549d3d68SSatish Balay       ierr = PetscMemzero(rowhit,N*sizeof(int));CHKERRQ(ierr);
63639f9d9dSBarry Smith       /* loop over columns*/
64639f9d9dSBarry Smith       for (j=0; j<n; j++) {
65639f9d9dSBarry Smith         col  = is[j];
66639f9d9dSBarry Smith         rows = cj + ci[col];
67639f9d9dSBarry Smith         m    = ci[col+1] - ci[col];
68639f9d9dSBarry Smith         /* loop over columns marking them in rowhit */
69639f9d9dSBarry Smith         for (k=0; k<m; k++) {
70639f9d9dSBarry Smith           rowhit[*rows++] = col + 1;
7170c3da92SBarry Smith         }
7270c3da92SBarry Smith       }
73639f9d9dSBarry Smith       /* count the number of hits */
74639f9d9dSBarry Smith       nrows = 0;
7570c3da92SBarry Smith       for (j=0; j<N; j++) {
76639f9d9dSBarry Smith         if (rowhit[j]) nrows++;
77639f9d9dSBarry Smith       }
78639f9d9dSBarry Smith       c->nrows[i]         = nrows;
79639f9d9dSBarry Smith       c->rows[i]          = (int*)PetscMalloc(nrows*sizeof(int));CHKPTRQ(c->rows[i]);
80639f9d9dSBarry Smith       c->columnsforrow[i] = (int*)PetscMalloc(nrows*sizeof(int));CHKPTRQ(c->columnsforrow[i]);
81639f9d9dSBarry Smith       nrows = 0;
82639f9d9dSBarry Smith       for (j=0; j<N; j++) {
83639f9d9dSBarry Smith         if (rowhit[j]) {
84639f9d9dSBarry Smith           c->rows[i][nrows]           = j;
85639f9d9dSBarry Smith           c->columnsforrow[i][nrows] = rowhit[j] - 1;
86639f9d9dSBarry Smith           nrows++;
8770c3da92SBarry Smith         }
8870c3da92SBarry Smith       }
89639f9d9dSBarry Smith     } else {  /*-------------------------------------------------------------------------------*/
90639f9d9dSBarry Smith       /* efficient version, using rowhit as a linked list */
91639f9d9dSBarry Smith       int currentcol,fm,mfm;
92639f9d9dSBarry Smith       rowhit[N] = N;
93639f9d9dSBarry Smith       nrows     = 0;
94639f9d9dSBarry Smith       /* loop over columns */
95639f9d9dSBarry Smith       for (j=0; j<n; j++) {
96639f9d9dSBarry Smith         col   = is[j];
97639f9d9dSBarry Smith         rows  = cj + ci[col];
98639f9d9dSBarry Smith         m     = ci[col+1] - ci[col];
99639f9d9dSBarry Smith         /* loop over columns marking them in rowhit */
100639f9d9dSBarry Smith         fm    = N; /* fm points to first entry in linked list */
101639f9d9dSBarry Smith         for (k=0; k<m; k++) {
102639f9d9dSBarry Smith           currentcol = *rows++;
103639f9d9dSBarry Smith 	  /* is it already in the list? */
104639f9d9dSBarry Smith           do {
105639f9d9dSBarry Smith             mfm  = fm;
106639f9d9dSBarry Smith             fm   = rowhit[fm];
107639f9d9dSBarry Smith           } while (fm < currentcol);
108639f9d9dSBarry Smith           /* not in list so add it */
109639f9d9dSBarry Smith           if (fm != currentcol) {
110639f9d9dSBarry Smith             nrows++;
111639f9d9dSBarry Smith             columnsforrow[currentcol] = col;
112639f9d9dSBarry Smith             /* next three lines insert new entry into linked list */
113639f9d9dSBarry Smith             rowhit[mfm]               = currentcol;
114639f9d9dSBarry Smith             rowhit[currentcol]        = fm;
115639f9d9dSBarry Smith             fm                        = currentcol;
116639f9d9dSBarry Smith             /* fm points to present position in list since we know the columns are sorted */
11770c3da92SBarry Smith           } else {
118a8c6a408SBarry Smith             SETERRQ(PETSC_ERR_PLIB,0,"Detected invalid coloring");
11970c3da92SBarry Smith           }
120639f9d9dSBarry Smith 
121639f9d9dSBarry Smith         }
122639f9d9dSBarry Smith       }
123639f9d9dSBarry Smith       c->nrows[i]         = nrows;
124639f9d9dSBarry Smith       c->rows[i]          = (int *)PetscMalloc((nrows+1)*sizeof(int));CHKPTRQ(c->rows[i]);
125639f9d9dSBarry Smith       c->columnsforrow[i] = (int *)PetscMalloc((nrows+1)*sizeof(int));CHKPTRQ(c->columnsforrow[i]);
126639f9d9dSBarry Smith       /* now store the linked list of rows into c->rows[i] */
127639f9d9dSBarry Smith       nrows = 0;
128639f9d9dSBarry Smith       fm    = rowhit[N];
129639f9d9dSBarry Smith       do {
130639f9d9dSBarry Smith         c->rows[i][nrows]            = fm;
131639f9d9dSBarry Smith         c->columnsforrow[i][nrows++] = columnsforrow[fm];
132639f9d9dSBarry Smith         fm                           = rowhit[fm];
133639f9d9dSBarry Smith       } while (fm < N);
134639f9d9dSBarry Smith     } /* ---------------------------------------------------------------------------------------*/
135639f9d9dSBarry Smith     ierr = ISRestoreIndices(isa[i],&is);CHKERRQ(ierr);
136639f9d9dSBarry Smith   }
13743a90d84SBarry Smith   ierr = MatRestoreColumnIJ_SeqAIJ(mat,0,PETSC_FALSE,&ncols,&ci,&cj,&done);CHKERRQ(ierr);
138639f9d9dSBarry Smith 
139606d414cSSatish Balay   ierr = PetscFree(rowhit);CHKERRQ(ierr);
140606d414cSSatish Balay   ierr = PetscFree(columnsforrow);CHKERRQ(ierr);
141639f9d9dSBarry Smith 
142639f9d9dSBarry Smith   c->scale  = (Scalar*)PetscMalloc(2*N*sizeof(Scalar));CHKPTRQ(c->scale);
143639f9d9dSBarry Smith   c->wscale = c->scale + N;
144639f9d9dSBarry Smith 
1453a40ed3dSBarry Smith   PetscFunctionReturn(0);
14670c3da92SBarry Smith }
14770c3da92SBarry Smith 
1485615d1e5SSatish Balay #undef __FUNC__
149b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatColoringPatch_SeqAIJ"
150639f9d9dSBarry Smith int MatColoringPatch_SeqAIJ(Mat mat,int ncolors,int *coloring,ISColoring *iscoloring)
15170c3da92SBarry Smith {
152639f9d9dSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)mat->data;
153639f9d9dSBarry Smith   int        n = a->n,*sizes,i,**ii,ierr,tag;
154639f9d9dSBarry Smith   IS         *is;
15570c3da92SBarry Smith 
1563a40ed3dSBarry Smith   PetscFunctionBegin;
157639f9d9dSBarry Smith   /* construct the index sets from the coloring array */
158639f9d9dSBarry Smith   sizes = (int*)PetscMalloc(ncolors*sizeof(int));CHKPTRQ(sizes);
159549d3d68SSatish Balay   ierr = PetscMemzero(sizes,ncolors*sizeof(int));CHKERRQ(ierr);
16070c3da92SBarry Smith   for (i=0; i<n; i++) {
161639f9d9dSBarry Smith     sizes[coloring[i]-1]++;
16270c3da92SBarry Smith   }
163639f9d9dSBarry Smith   ii    = (int**)PetscMalloc(ncolors*sizeof(int*));CHKPTRQ(ii);
164639f9d9dSBarry Smith   ii[0] = (int*)PetscMalloc(n*sizeof(int));CHKPTRQ(ii[0]);
165639f9d9dSBarry Smith   for (i=1; i<ncolors; i++) {
166639f9d9dSBarry Smith     ii[i] = ii[i-1] + sizes[i-1];
167639f9d9dSBarry Smith   }
168549d3d68SSatish Balay   ierr = PetscMemzero(sizes,ncolors*sizeof(int));CHKERRQ(ierr);
169639f9d9dSBarry Smith   for (i=0; i<n; i++) {
170639f9d9dSBarry Smith     ii[coloring[i]-1][sizes[coloring[i]-1]++] = i;
171639f9d9dSBarry Smith   }
172775f6a71SSatish Balay   is  = (IS*)PetscMalloc(ncolors*sizeof(IS));CHKPTRQ(is);
173639f9d9dSBarry Smith   for (i=0; i<ncolors; i++) {
174029af93fSBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,sizes[i],ii[i],is+i);CHKERRQ(ierr);
175639f9d9dSBarry Smith   }
176639f9d9dSBarry Smith 
177f09e8eb9SSatish Balay   *iscoloring         = (ISColoring)PetscMalloc(sizeof(struct _p_ISColoring));CHKPTRQ(*iscoloring);
178639f9d9dSBarry Smith   (*iscoloring)->n    = ncolors;
179639f9d9dSBarry Smith   (*iscoloring)->is   = is;
1804be1940cSBarry Smith   ierr = PetscCommDuplicate_Private(mat->comm,&(*iscoloring)->comm,&tag);CHKERRQ(ierr);
181606d414cSSatish Balay   ierr = PetscFree(sizes);CHKERRQ(ierr);
182606d414cSSatish Balay   ierr = PetscFree(ii[0]);CHKERRQ(ierr);
183606d414cSSatish Balay   ierr = PetscFree(ii);CHKERRQ(ierr);
1843a40ed3dSBarry Smith   PetscFunctionReturn(0);
18570c3da92SBarry Smith }
18670c3da92SBarry Smith 
187639f9d9dSBarry Smith /*
188639f9d9dSBarry Smith      Makes a longer coloring[] array and calls the usual code with that
189639f9d9dSBarry Smith */
1905615d1e5SSatish Balay #undef __FUNC__
191b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatColoringPatch_SeqAIJ_Inode"
192639f9d9dSBarry Smith int MatColoringPatch_SeqAIJ_Inode(Mat mat,int ncolors,int *coloring,ISColoring *iscoloring)
19370c3da92SBarry Smith {
194639f9d9dSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)mat->data;
195639f9d9dSBarry Smith   int        n = a->n,ierr,m = a->inode.node_count,j,*ns = a->inode.size,row;
196639f9d9dSBarry Smith   int        *colorused,i,*newcolor;
19770c3da92SBarry Smith 
1983a40ed3dSBarry Smith   PetscFunctionBegin;
199639f9d9dSBarry Smith   newcolor = (int*)PetscMalloc((n+1)*sizeof(int));CHKPTRQ(newcolor);
20070c3da92SBarry Smith 
201639f9d9dSBarry Smith   /* loop over inodes, marking a color for each column*/
202639f9d9dSBarry Smith   row = 0;
20370c3da92SBarry Smith   for (i=0; i<m; i++){
204639f9d9dSBarry Smith     for (j=0; j<ns[i]; j++) {
205639f9d9dSBarry Smith       newcolor[row++] = coloring[i] + j*ncolors;
20670c3da92SBarry Smith     }
20770c3da92SBarry Smith   }
20870c3da92SBarry Smith 
209639f9d9dSBarry Smith   /* eliminate unneeded colors */
210639f9d9dSBarry Smith   colorused = (int*)PetscMalloc(5*ncolors*sizeof(int));CHKPTRQ(colorused);
211549d3d68SSatish Balay   ierr      = PetscMemzero(colorused,5*ncolors*sizeof(int));CHKERRQ(ierr);
212639f9d9dSBarry Smith   for (i=0; i<n; i++) {
213639f9d9dSBarry Smith     colorused[newcolor[i]-1] = 1;
214639f9d9dSBarry Smith   }
21570c3da92SBarry Smith 
216639f9d9dSBarry Smith   for (i=1; i<5*ncolors; i++) {
217639f9d9dSBarry Smith     colorused[i] += colorused[i-1];
21870c3da92SBarry Smith   }
219639f9d9dSBarry Smith   ncolors = colorused[5*ncolors-1];
220639f9d9dSBarry Smith   for (i=0; i<n; i++) {
221639f9d9dSBarry Smith     newcolor[i] = colorused[newcolor[i]-1];
22270c3da92SBarry Smith   }
223606d414cSSatish Balay   ierr = PetscFree(colorused);CHKERRQ(ierr);
22470c3da92SBarry Smith 
225639f9d9dSBarry Smith   ierr = MatColoringPatch_SeqAIJ(mat,ncolors,newcolor,iscoloring);CHKERRQ(ierr);
226606d414cSSatish Balay   ierr = PetscFree(newcolor);CHKERRQ(ierr);
227639f9d9dSBarry Smith 
2283a40ed3dSBarry Smith   PetscFunctionReturn(0);
22970c3da92SBarry Smith }
23070c3da92SBarry Smith 
2313a40ed3dSBarry Smith 
2323a40ed3dSBarry Smith 
2333a40ed3dSBarry Smith 
2343a40ed3dSBarry Smith 
2353a40ed3dSBarry Smith 
236