xref: /petsc/src/mat/impls/baij/seq/baij2.c (revision 736121d41ed498147adfb28afb4752aac0794cb6)
1cac129eeSSatish Balay #ifndef lint
2*736121d4SSatish Balay static char vcid[] = "$Id: baij2.c,v 1.2 1996/04/30 18:59:24 balay Exp balay $";
3cac129eeSSatish Balay #endif
4cac129eeSSatish Balay 
5cac129eeSSatish Balay #include "baij.h"
6cac129eeSSatish Balay #include "petsc.h"
7*736121d4SSatish Balay #include "src/inline/bitarray.h"
8cac129eeSSatish Balay 
9*736121d4SSatish Balay int MatIncreaseOverlap_SeqBAIJ(Mat A,int is_max,IS *is,int ov)
10a3192f15SSatish Balay {
11a3192f15SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
12a3192f15SSatish Balay   int         row, i,j,k,l,m,n, *idx,ierr, *nidx, isz, val;
13a3192f15SSatish Balay   int         start, end, *ai, *aj;
14a3192f15SSatish Balay   char        *table;
15a3192f15SSatish Balay 
16a3192f15SSatish Balay   m     = a->mbs;
17a3192f15SSatish Balay   ai    = a->i;
18a3192f15SSatish Balay   aj    = a->j;
19a3192f15SSatish Balay 
20a3192f15SSatish Balay   if (ov < 0)  SETERRQ(1,"MatIncreaseOverlap_SeqBAIJ: illegal overlap value used");
21a3192f15SSatish Balay 
22a3192f15SSatish Balay   table = (char *) PetscMalloc((m/BITSPERBYTE +1)*sizeof(char)); CHKPTRQ(table);
23a3192f15SSatish Balay   nidx  = (int *) PetscMalloc((m+1)*sizeof(int)); CHKPTRQ(nidx);
24a3192f15SSatish Balay 
25a3192f15SSatish Balay   for ( i=0; i<is_max; i++ ) {
26a3192f15SSatish Balay     /* Initialise the two local arrays */
27a3192f15SSatish Balay     isz  = 0;
28a3192f15SSatish Balay     PetscMemzero(table,(m/BITSPERBYTE +1)*sizeof(char));
29a3192f15SSatish Balay 
30a3192f15SSatish Balay                 /* Extract the indices, assume there can be duplicate entries */
31a3192f15SSatish Balay     ierr = ISGetIndices(is[i],&idx);  CHKERRQ(ierr);
32a3192f15SSatish Balay     ierr = ISGetSize(is[i],&n);  CHKERRQ(ierr);
33a3192f15SSatish Balay 
34a3192f15SSatish Balay     /* Enter these into the temp arrays i.e mark table[row], enter row into new index */
35a3192f15SSatish Balay     for ( j=0; j<n ; ++j){
36*736121d4SSatish Balay       if (idx[j]>m) SETERRQ(1,"MatIncreaseOverlap_SeqBAIJ: index greater than mat-dim");
37a3192f15SSatish Balay       if(!BT_LOOKUP(table, idx[j])) { nidx[isz++] = idx[j];}
38a3192f15SSatish Balay     }
39a3192f15SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);  CHKERRQ(ierr);
40a3192f15SSatish Balay     ierr = ISDestroy(is[i]); CHKERRQ(ierr);
41a3192f15SSatish Balay 
42a3192f15SSatish Balay     k = 0;
43a3192f15SSatish Balay     for ( j=0; j<ov; j++){ /* for each overlap*/
44a3192f15SSatish Balay       n = isz;
45a3192f15SSatish Balay       for ( ; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */
46a3192f15SSatish Balay         row   = nidx[k];
47a3192f15SSatish Balay         start = ai[row];
48a3192f15SSatish Balay         end   = ai[row+1];
49a3192f15SSatish Balay         for ( l = start; l<end ; l++){
50a3192f15SSatish Balay           val = aj[l];
51a3192f15SSatish Balay           if (!BT_LOOKUP(table,val)) {nidx[isz++] = val;}
52a3192f15SSatish Balay         }
53a3192f15SSatish Balay       }
54a3192f15SSatish Balay     }
55a3192f15SSatish Balay     ierr = ISCreateSeq(MPI_COMM_SELF, isz, nidx, (is+i)); CHKERRQ(ierr);
56a3192f15SSatish Balay   }
57a3192f15SSatish Balay   PetscFree(table);
58a3192f15SSatish Balay   PetscFree(nidx);
59a3192f15SSatish Balay   return 0;
60a3192f15SSatish Balay }
61*736121d4SSatish Balay int MatGetSubMatrix_SeqBAIJ(Mat A,IS isrow,IS iscol,MatGetSubMatrixCall scall,Mat *B)
62*736121d4SSatish Balay {
63*736121d4SSatish Balay   Mat_SeqBAIJ  *a = (Mat_SeqBAIJ *) A->data,*c;
64*736121d4SSatish Balay   int          nznew, *smap, i, k, kstart, kend, ierr, oldcols = a->nbs,*lens;
65*736121d4SSatish Balay   int          row,mat_i,*mat_j,tcol,first,step,*mat_ilen;
66*736121d4SSatish Balay   register int sum,lensi;
67*736121d4SSatish Balay   int          *irow, *icol, nrows, ncols,*ssmap,bs=a->bs, bs2=a->bs2;
68*736121d4SSatish Balay   int          *starts,*j_new,*i_new,*aj = a->j, *ai = a->i,ii,*ailen = a->ilen;
69*736121d4SSatish Balay   Scalar       *a_new,*mat_a;
70*736121d4SSatish Balay   Mat          C;
71*736121d4SSatish Balay 
72*736121d4SSatish Balay   ierr = ISSorted(iscol,(PetscTruth*)&i);
73*736121d4SSatish Balay   if (!i) SETERRQ(1,"MatGetSubmatrices_SeqBAIJ:IS is not sorted");
74*736121d4SSatish Balay 
75*736121d4SSatish Balay   ierr = ISGetIndices(isrow,&irow); CHKERRQ(ierr);
76*736121d4SSatish Balay   ierr = ISGetSize(isrow,&nrows); CHKERRQ(ierr);
77*736121d4SSatish Balay   ierr = ISGetSize(iscol,&ncols); CHKERRQ(ierr);
78*736121d4SSatish Balay 
79*736121d4SSatish Balay   if (ISStrideGetInfo(iscol,&first,&step) && step == 1) { /* no need to sort */
80*736121d4SSatish Balay     /* special case of contiguous rows */
81*736121d4SSatish Balay     lens   = (int *) PetscMalloc((ncols+nrows+1)*sizeof(int)); CHKPTRQ(lens);
82*736121d4SSatish Balay     starts = lens + ncols;
83*736121d4SSatish Balay     /* loop over new rows determining lens and starting points */
84*736121d4SSatish Balay     for (i=0; i<nrows; i++) {
85*736121d4SSatish Balay       kstart  = ai[irow[i]];
86*736121d4SSatish Balay       kend    = kstart + ailen[irow[i]];
87*736121d4SSatish Balay       for ( k=kstart; k<kend; k++ ) {
88*736121d4SSatish Balay         if (aj[k] >= first) {
89*736121d4SSatish Balay           starts[i] = k;
90*736121d4SSatish Balay           break;
91*736121d4SSatish Balay 	}
92*736121d4SSatish Balay       }
93*736121d4SSatish Balay       sum = 0;
94*736121d4SSatish Balay       while (k < kend) {
95*736121d4SSatish Balay         if (aj[k++] >= first+ncols) break;
96*736121d4SSatish Balay         sum++;
97*736121d4SSatish Balay       }
98*736121d4SSatish Balay       lens[i] = sum;
99*736121d4SSatish Balay     }
100*736121d4SSatish Balay     /* create submatrix */
101*736121d4SSatish Balay     if (scall == MAT_REUSE_MATRIX) {
102*736121d4SSatish Balay       c = (Mat_SeqBAIJ *)((*B)->data);
103*736121d4SSatish Balay 
104*736121d4SSatish Balay       if (c->mbs!=nrows || c->nbs!=ncols || c->bs!=bs)
105*736121d4SSatish Balay         SETERRQ(1,"MatGetSubMatrix_SeqBAIJ:");
106*736121d4SSatish Balay       ierr = MatZeroEntries(*B); CHKERRQ(ierr);
107*736121d4SSatish Balay       C = *B;
108*736121d4SSatish Balay     }
109*736121d4SSatish Balay     else {
110*736121d4SSatish Balay       ierr = MatCreateSeqBAIJ(A->comm,bs,nrows*bs,ncols*bs,0,lens,&C);CHKERRQ(ierr);
111*736121d4SSatish Balay     }
112*736121d4SSatish Balay     c = (Mat_SeqBAIJ*) C->data;
113*736121d4SSatish Balay 
114*736121d4SSatish Balay     /* loop over rows inserting into submatrix */
115*736121d4SSatish Balay     a_new    = c->a;
116*736121d4SSatish Balay     j_new    = c->j;
117*736121d4SSatish Balay     i_new    = c->i;
118*736121d4SSatish Balay     i_new[0] = 0;
119*736121d4SSatish Balay     for (i=0; i<nrows; i++) {
120*736121d4SSatish Balay       ii    = starts[i];
121*736121d4SSatish Balay       lensi = lens[i];
122*736121d4SSatish Balay       for ( k=0; k<lensi; k++ ) {
123*736121d4SSatish Balay         *j_new++ = aj[ii+k] - first;
124*736121d4SSatish Balay       }
125*736121d4SSatish Balay       PetscMemcpy(a_new,a->a + starts[i],lensi*bs2*sizeof(Scalar));
126*736121d4SSatish Balay       a_new      += lensi*bs2;
127*736121d4SSatish Balay       i_new[i+1]  = i_new[i] + lensi;
128*736121d4SSatish Balay       c->ilen[i]  = lensi;
129*736121d4SSatish Balay     }
130*736121d4SSatish Balay     PetscFree(lens);
131*736121d4SSatish Balay   }
132*736121d4SSatish Balay   else {
133*736121d4SSatish Balay     ierr = ISGetIndices(iscol,&icol); CHKERRQ(ierr);
134*736121d4SSatish Balay     smap  = (int *) PetscMalloc((1+oldcols)*sizeof(int)); CHKPTRQ(smap);
135*736121d4SSatish Balay     ssmap = smap;
136*736121d4SSatish Balay     lens  = (int *) PetscMalloc((1+nrows)*sizeof(int)); CHKPTRQ(lens);
137*736121d4SSatish Balay     PetscMemzero(smap,oldcols*sizeof(int));
138*736121d4SSatish Balay     for ( i=0; i<ncols; i++ ) smap[icol[i]] = i+1;
139*736121d4SSatish Balay     /* determine lens of each row */
140*736121d4SSatish Balay     for (i=0; i<nrows; i++) {
141*736121d4SSatish Balay       kstart  = ai[irow[i]];
142*736121d4SSatish Balay       kend    = kstart + a->ilen[irow[i]];
143*736121d4SSatish Balay       lens[i] = 0;
144*736121d4SSatish Balay       for ( k=kstart; k<kend; k++ ) {
145*736121d4SSatish Balay         if (ssmap[aj[k]]) {
146*736121d4SSatish Balay           lens[i]++;
147*736121d4SSatish Balay         }
148*736121d4SSatish Balay       }
149*736121d4SSatish Balay     }
150*736121d4SSatish Balay     /* Create and fill new matrix */
151*736121d4SSatish Balay     if (scall == MAT_REUSE_MATRIX) {
152*736121d4SSatish Balay       c = (Mat_SeqBAIJ *)((*B)->data);
153*736121d4SSatish Balay 
154*736121d4SSatish Balay       if (c->mbs!=nrows || c->nbs!=ncols || c->bs!=bs)
155*736121d4SSatish Balay         SETERRQ(1,"MatGetSubMatrix_SeqBAIJ:");
156*736121d4SSatish Balay       if (PetscMemcmp(c->ilen,lens, c->mbs *sizeof(int))) {
157*736121d4SSatish Balay         SETERRQ(1,"MatGetSubmatrix_SeqBAIJ:Cannot reuse matrix. wrong no of nonzeros");
158*736121d4SSatish Balay       }
159*736121d4SSatish Balay       PetscMemzero(c->ilen,c->mbs*sizeof(int));
160*736121d4SSatish Balay       C = *B;
161*736121d4SSatish Balay     }
162*736121d4SSatish Balay     else {
163*736121d4SSatish Balay       ierr = MatCreateSeqBAIJ(A->comm,bs,nrows*bs,ncols*bs,0,lens,&C);CHKERRQ(ierr);
164*736121d4SSatish Balay     }
165*736121d4SSatish Balay     c = (Mat_SeqBAIJ *)(C->data);
166*736121d4SSatish Balay     for (i=0; i<nrows; i++) {
167*736121d4SSatish Balay       row    = irow[i];
168*736121d4SSatish Balay       nznew  = 0;
169*736121d4SSatish Balay       kstart = ai[row];
170*736121d4SSatish Balay       kend   = kstart + a->ilen[row];
171*736121d4SSatish Balay       mat_i  = c->i[i];
172*736121d4SSatish Balay       mat_j  = c->j + mat_i;
173*736121d4SSatish Balay       mat_a  = c->a + mat_i;
174*736121d4SSatish Balay       mat_ilen = c->ilen + i;
175*736121d4SSatish Balay       for ( k=kstart; k<kend; k++ ) {
176*736121d4SSatish Balay         if ((tcol=ssmap[a->j[k]])) {
177*736121d4SSatish Balay           *mat_j++ = tcol - 1;
178*736121d4SSatish Balay           PetscMemcpy(mat_a,a->a+k*bs2,bs2*sizeof(Scalar)); mat_a+=bs2;
179*736121d4SSatish Balay           (*mat_ilen)++;
180*736121d4SSatish Balay 
181*736121d4SSatish Balay         }
182*736121d4SSatish Balay       }
183*736121d4SSatish Balay     }
184*736121d4SSatish Balay     /* Free work space */
185*736121d4SSatish Balay     ierr = ISRestoreIndices(iscol,&icol); CHKERRQ(ierr);
186*736121d4SSatish Balay     PetscFree(smap); PetscFree(lens);
187*736121d4SSatish Balay   }
188*736121d4SSatish Balay   ierr = MatAssemblyBegin(C,FINAL_ASSEMBLY); CHKERRQ(ierr);
189*736121d4SSatish Balay   ierr = MatAssemblyEnd(C,FINAL_ASSEMBLY); CHKERRQ(ierr);
190*736121d4SSatish Balay 
191*736121d4SSatish Balay   ierr = ISRestoreIndices(isrow,&irow); CHKERRQ(ierr);
192*736121d4SSatish Balay   *B = C;
193*736121d4SSatish Balay   return 0;
194*736121d4SSatish Balay }
195*736121d4SSatish Balay 
196*736121d4SSatish Balay int MatGetSubMatrices_SeqBAIJ(Mat A,int n, IS *irow,IS *icol,MatGetSubMatrixCall scall,
197*736121d4SSatish Balay                                     Mat **B)
198*736121d4SSatish Balay {
199*736121d4SSatish Balay   int ierr,i;
200*736121d4SSatish Balay 
201*736121d4SSatish Balay   if (scall == MAT_INITIAL_MATRIX) {
202*736121d4SSatish Balay     *B = (Mat *) PetscMalloc( (n+1)*sizeof(Mat) ); CHKPTRQ(*B);
203*736121d4SSatish Balay   }
204*736121d4SSatish Balay 
205*736121d4SSatish Balay   for ( i=0; i<n; i++ ) {
206*736121d4SSatish Balay     ierr = MatGetSubMatrix(A,irow[i],icol[i],scall,&(*B)[i]); CHKERRQ(ierr);
207*736121d4SSatish Balay   }
208*736121d4SSatish Balay   return 0;
209*736121d4SSatish Balay }
210