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