xref: /petsc/src/mat/impls/aij/seq/fdaij.c (revision 82eb862226417fd0e5f83d8cbfe40869d2871bbc)
173f4d377SMatthew Knepley /*$Id: fdaij.c,v 1.40 2001/06/21 21:16:21 bsmith Exp $*/
270c3da92SBarry Smith 
370c3da92SBarry Smith #include "src/mat/impls/aij/seq/aij.h"
470c3da92SBarry Smith #include "src/vec/vecimpl.h"
5639f9d9dSBarry Smith 
6ca44d042SBarry Smith EXTERN int MatGetColumnIJ_SeqAIJ(Mat,int,PetscTruth,int*,int**,int**,PetscTruth*);
7ca44d042SBarry Smith EXTERN int MatRestoreColumnIJ_SeqAIJ(Mat,int,PetscTruth,int*,int**,int**,PetscTruth*);
843a90d84SBarry Smith 
94a2ae208SSatish Balay #undef __FUNCT__
104a2ae208SSatish Balay #define __FUNCT__ "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;
1430b34957SBarry Smith   int        nis = iscoloring->n,*rowhit,*columnsforrow,l;
15b9617806SBarry Smith   IS         *isa;
16f1af5d2fSBarry Smith   PetscTruth done,flg;
17639f9d9dSBarry Smith 
183a40ed3dSBarry Smith   PetscFunctionBegin;
19522c5e43SBarry Smith   if (!mat->assembled) {
2029bbc08cSBarry Smith     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be assembled by calls to MatAssemblyBegin/End();");
21522c5e43SBarry Smith   }
22522c5e43SBarry Smith 
23b9617806SBarry Smith   ierr = ISColoringGetIS(iscoloring,PETSC_IGNORE,&isa);CHKERRQ(ierr);
24005c665bSBarry Smith   c->M       = mat->M;  /* set total rows, columns and local rows */
25005c665bSBarry Smith   c->N       = mat->N;
26005c665bSBarry Smith   c->m       = mat->M;
27005c665bSBarry Smith   c->rstart  = 0;
28005c665bSBarry Smith 
29639f9d9dSBarry Smith   c->ncolors = nis;
30b0a32e0cSBarry Smith   ierr       = PetscMalloc(nis*sizeof(int),&c->ncolumns);CHKERRQ(ierr);
31b0a32e0cSBarry Smith   ierr       = PetscMalloc(nis*sizeof(int*),&c->columns);CHKERRQ(ierr);
32b0a32e0cSBarry Smith   ierr       = PetscMalloc(nis*sizeof(int),&c->nrows);CHKERRQ(ierr);
33b0a32e0cSBarry Smith   ierr       = PetscMalloc(nis*sizeof(int*),&c->rows);CHKERRQ(ierr);
34b0a32e0cSBarry Smith   ierr       = PetscMalloc(nis*sizeof(int*),&c->columnsforrow);CHKERRQ(ierr);
3543a90d84SBarry Smith 
3643a90d84SBarry Smith   /*
3743a90d84SBarry Smith       Calls the _SeqAIJ() version of these routines to make sure it does not
3843a90d84SBarry Smith      get the reduced (by inodes) version of I and J
3943a90d84SBarry Smith   */
4043a90d84SBarry Smith   ierr = MatGetColumnIJ_SeqAIJ(mat,0,PETSC_FALSE,&ncols,&ci,&cj,&done);CHKERRQ(ierr);
4170c3da92SBarry Smith 
4270c3da92SBarry Smith   /*
43639f9d9dSBarry Smith      Temporary option to allow for debugging/testing
4470c3da92SBarry Smith   */
45b0a32e0cSBarry Smith   ierr = PetscOptionsHasName(PETSC_NULL,"-matfdcoloring_slow",&flg);CHKERRQ(ierr);
4670c3da92SBarry Smith 
47b0a32e0cSBarry Smith   ierr = PetscMalloc((N+1)*sizeof(int),&rowhit);CHKERRQ(ierr);
48b0a32e0cSBarry Smith   ierr = PetscMalloc((N+1)*sizeof(int),&columnsforrow);CHKERRQ(ierr);
4970c3da92SBarry Smith 
50639f9d9dSBarry Smith   for (i=0; i<nis; i++) {
51b9b97703SBarry Smith     ierr = ISGetLocalSize(isa[i],&n);CHKERRQ(ierr);
52639f9d9dSBarry Smith     ierr = ISGetIndices(isa[i],&is);CHKERRQ(ierr);
53639f9d9dSBarry Smith     c->ncolumns[i] = n;
54639f9d9dSBarry Smith     if (n) {
55b0a32e0cSBarry Smith       ierr = PetscMalloc(n*sizeof(int),&c->columns[i]);CHKERRQ(ierr);
56549d3d68SSatish Balay       ierr = PetscMemcpy(c->columns[i],is,n*sizeof(int));CHKERRQ(ierr);
5770c3da92SBarry Smith     } else {
58639f9d9dSBarry Smith       c->columns[i]  = 0;
5970c3da92SBarry Smith     }
6070c3da92SBarry Smith 
613a7fca6bSBarry Smith     if (!flg) { /* ------------------------------------------------------------------------------*/
623a7fca6bSBarry Smith       /* fast, crude version requires O(N*N) work */
63549d3d68SSatish Balay       ierr = PetscMemzero(rowhit,N*sizeof(int));CHKERRQ(ierr);
64639f9d9dSBarry Smith       /* loop over columns*/
65639f9d9dSBarry Smith       for (j=0; j<n; j++) {
66639f9d9dSBarry Smith         col  = is[j];
67639f9d9dSBarry Smith         rows = cj + ci[col];
68639f9d9dSBarry Smith         m    = ci[col+1] - ci[col];
69639f9d9dSBarry Smith         /* loop over columns marking them in rowhit */
70639f9d9dSBarry Smith         for (k=0; k<m; k++) {
71639f9d9dSBarry Smith           rowhit[*rows++] = col + 1;
7270c3da92SBarry Smith         }
7370c3da92SBarry Smith       }
74639f9d9dSBarry Smith       /* count the number of hits */
75639f9d9dSBarry Smith       nrows = 0;
7670c3da92SBarry Smith       for (j=0; j<N; j++) {
77639f9d9dSBarry Smith         if (rowhit[j]) nrows++;
78639f9d9dSBarry Smith       }
79639f9d9dSBarry Smith       c->nrows[i] = nrows;
803a7fca6bSBarry Smith       ierr        = PetscMalloc((nrows+1)*sizeof(int),&c->rows[i]);CHKERRQ(ierr);
813a7fca6bSBarry Smith       ierr        = PetscMalloc((nrows+1)*sizeof(int),&c->columnsforrow[i]);CHKERRQ(ierr);
82639f9d9dSBarry Smith       nrows       = 0;
83639f9d9dSBarry Smith       for (j=0; j<N; j++) {
84639f9d9dSBarry Smith         if (rowhit[j]) {
85639f9d9dSBarry Smith           c->rows[i][nrows]          = j;
86639f9d9dSBarry Smith           c->columnsforrow[i][nrows] = rowhit[j] - 1;
87639f9d9dSBarry Smith           nrows++;
8870c3da92SBarry Smith         }
8970c3da92SBarry Smith       }
90639f9d9dSBarry Smith     } else {  /*-------------------------------------------------------------------------------*/
913a7fca6bSBarry Smith       /* slow version, using rowhit as a linked list */
92639f9d9dSBarry Smith       int currentcol,fm,mfm;
93639f9d9dSBarry Smith       rowhit[N] = N;
94639f9d9dSBarry Smith       nrows     = 0;
95639f9d9dSBarry Smith       /* loop over columns */
96639f9d9dSBarry Smith       for (j=0; j<n; j++) {
97639f9d9dSBarry Smith         col   = is[j];
98639f9d9dSBarry Smith         rows  = cj + ci[col];
99639f9d9dSBarry Smith         m     = ci[col+1] - ci[col];
100639f9d9dSBarry Smith         /* loop over columns marking them in rowhit */
101639f9d9dSBarry Smith         fm    = N; /* fm points to first entry in linked list */
102639f9d9dSBarry Smith         for (k=0; k<m; k++) {
103639f9d9dSBarry Smith           currentcol = *rows++;
104639f9d9dSBarry Smith 	  /* is it already in the list? */
105639f9d9dSBarry Smith           do {
106639f9d9dSBarry Smith             mfm  = fm;
107639f9d9dSBarry Smith             fm   = rowhit[fm];
108639f9d9dSBarry Smith           } while (fm < currentcol);
109639f9d9dSBarry Smith           /* not in list so add it */
110639f9d9dSBarry Smith           if (fm != currentcol) {
111639f9d9dSBarry Smith             nrows++;
112639f9d9dSBarry Smith             columnsforrow[currentcol] = col;
113639f9d9dSBarry Smith             /* next three lines insert new entry into linked list */
114639f9d9dSBarry Smith             rowhit[mfm]               = currentcol;
115639f9d9dSBarry Smith             rowhit[currentcol]        = fm;
116639f9d9dSBarry Smith             fm                        = currentcol;
117639f9d9dSBarry Smith             /* fm points to present position in list since we know the columns are sorted */
11870c3da92SBarry Smith           } else {
11929bbc08cSBarry Smith             SETERRQ(PETSC_ERR_PLIB,"Detected invalid coloring");
12070c3da92SBarry Smith           }
121639f9d9dSBarry Smith 
122639f9d9dSBarry Smith         }
123639f9d9dSBarry Smith       }
124639f9d9dSBarry Smith       c->nrows[i] = nrows;
125b0a32e0cSBarry Smith       ierr        = PetscMalloc((nrows+1)*sizeof(int),&c->rows[i]);CHKERRQ(ierr);
126b0a32e0cSBarry Smith       ierr        = PetscMalloc((nrows+1)*sizeof(int),&c->columnsforrow[i]);CHKERRQ(ierr);
127639f9d9dSBarry Smith       /* now store the linked list of rows into c->rows[i] */
128639f9d9dSBarry Smith       nrows       = 0;
129639f9d9dSBarry Smith       fm          = rowhit[N];
130639f9d9dSBarry Smith       do {
131639f9d9dSBarry Smith         c->rows[i][nrows]            = fm;
132639f9d9dSBarry Smith         c->columnsforrow[i][nrows++] = columnsforrow[fm];
133639f9d9dSBarry Smith         fm                           = rowhit[fm];
134639f9d9dSBarry Smith       } while (fm < N);
135639f9d9dSBarry Smith     } /* ---------------------------------------------------------------------------------------*/
136639f9d9dSBarry Smith     ierr = ISRestoreIndices(isa[i],&is);CHKERRQ(ierr);
137639f9d9dSBarry Smith   }
13843a90d84SBarry Smith   ierr = MatRestoreColumnIJ_SeqAIJ(mat,0,PETSC_FALSE,&ncols,&ci,&cj,&done);CHKERRQ(ierr);
139639f9d9dSBarry Smith 
140606d414cSSatish Balay   ierr = PetscFree(rowhit);CHKERRQ(ierr);
141606d414cSSatish Balay   ierr = PetscFree(columnsforrow);CHKERRQ(ierr);
142639f9d9dSBarry Smith 
14330b34957SBarry Smith   /* Optimize by adding the vscale, and scaleforrow[][] fields */
14430b34957SBarry Smith   /*
14530b34957SBarry Smith        see the version for MPIAIJ
14630b34957SBarry Smith   */
14730b34957SBarry Smith   ierr = VecCreateGhost(mat->comm,mat->m,PETSC_DETERMINE,0,PETSC_NULL,&c->vscale);CHKERRQ(ierr)
148b0a32e0cSBarry Smith   ierr = PetscMalloc(c->ncolors*sizeof(int*),&c->vscaleforrow);CHKERRQ(ierr);
14930b34957SBarry Smith   for (k=0; k<c->ncolors; k++) {
150b0a32e0cSBarry Smith     ierr = PetscMalloc((c->nrows[k]+1)*sizeof(int),&c->vscaleforrow[k]);CHKERRQ(ierr);
15130b34957SBarry Smith     for (l=0; l<c->nrows[k]; l++) {
15230b34957SBarry Smith       col = c->columnsforrow[k][l];
15330b34957SBarry Smith       c->vscaleforrow[k][l] = col;
15430b34957SBarry Smith     }
15530b34957SBarry Smith   }
156b9617806SBarry Smith   ierr = ISColoringRestoreIS(iscoloring,&isa);CHKERRQ(ierr);
1573a40ed3dSBarry Smith   PetscFunctionReturn(0);
15870c3da92SBarry Smith }
15970c3da92SBarry Smith 
160639f9d9dSBarry Smith /*
161639f9d9dSBarry Smith      Makes a longer coloring[] array and calls the usual code with that
162639f9d9dSBarry Smith */
1634a2ae208SSatish Balay #undef __FUNCT__
1644a2ae208SSatish Balay #define __FUNCT__ "MatColoringPatch_SeqAIJ_Inode"
1654e7234bfSBarry Smith int MatColoringPatch_SeqAIJ_Inode(Mat mat,int nin,int ncolors,const ISColoringValue coloring[],ISColoring *iscoloring)
16670c3da92SBarry Smith {
167639f9d9dSBarry Smith   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)mat->data;
168273d9f13SBarry Smith   int             n = mat->n,ierr,m = a->inode.node_count,j,*ns = a->inode.size,row;
16908b6dcc0SBarry Smith   int             *colorused,i;
17008b6dcc0SBarry Smith   ISColoringValue *newcolor;
17170c3da92SBarry Smith 
1723a40ed3dSBarry Smith   PetscFunctionBegin;
173b0a32e0cSBarry Smith   ierr = PetscMalloc((n+1)*sizeof(int),&newcolor);CHKERRQ(ierr);
174639f9d9dSBarry Smith   /* loop over inodes, marking a color for each column*/
175639f9d9dSBarry Smith   row = 0;
17670c3da92SBarry Smith   for (i=0; i<m; i++){
177639f9d9dSBarry Smith     for (j=0; j<ns[i]; j++) {
178639f9d9dSBarry Smith       newcolor[row++] = coloring[i] + j*ncolors;
17970c3da92SBarry Smith     }
18070c3da92SBarry Smith   }
18170c3da92SBarry Smith 
182639f9d9dSBarry Smith   /* eliminate unneeded colors */
183b0a32e0cSBarry Smith   ierr = PetscMalloc(5*ncolors*sizeof(int),&colorused);CHKERRQ(ierr);
184549d3d68SSatish Balay   ierr = PetscMemzero(colorused,5*ncolors*sizeof(int));CHKERRQ(ierr);
185639f9d9dSBarry Smith   for (i=0; i<n; i++) {
186b9617806SBarry Smith     colorused[newcolor[i]] = 1;
187639f9d9dSBarry Smith   }
18870c3da92SBarry Smith 
189639f9d9dSBarry Smith   for (i=1; i<5*ncolors; i++) {
190639f9d9dSBarry Smith     colorused[i] += colorused[i-1];
19170c3da92SBarry Smith   }
192639f9d9dSBarry Smith   ncolors = colorused[5*ncolors-1];
193639f9d9dSBarry Smith   for (i=0; i<n; i++) {
194b9617806SBarry Smith     newcolor[i] = colorused[newcolor[i]];
19570c3da92SBarry Smith   }
196606d414cSSatish Balay   ierr = PetscFree(colorused);CHKERRQ(ierr);
197b9617806SBarry Smith   ierr = ISColoringCreate(mat->comm,n,newcolor,iscoloring);CHKERRQ(ierr);
198*82eb8622SBarry Smith   ierr = PetscFree((void*)coloring);CHKERRQ(ierr);
1993a40ed3dSBarry Smith   PetscFunctionReturn(0);
20070c3da92SBarry Smith }
20170c3da92SBarry Smith 
2023a40ed3dSBarry Smith 
2033a40ed3dSBarry Smith 
2043a40ed3dSBarry Smith 
2053a40ed3dSBarry Smith 
2063a40ed3dSBarry Smith 
207