1b6490206SBarry Smith 22593348eSBarry Smith #ifndef lint 3*584200bdSSatish Balay static char vcid[] = "$Id: baij.c,v 1.25 1996/04/04 00:27:51 balay Exp balay $"; 42593348eSBarry Smith #endif 52593348eSBarry Smith 62593348eSBarry Smith /* 7b6490206SBarry Smith Defines the basic matrix operations for the BAIJ (compressed row) 82593348eSBarry Smith matrix storage format. 92593348eSBarry Smith */ 10b6490206SBarry Smith #include "baij.h" 112593348eSBarry Smith #include "vec/vecimpl.h" 122593348eSBarry Smith #include "inline/spops.h" 132593348eSBarry Smith #include "petsc.h" 142593348eSBarry Smith 15bcd2baecSBarry Smith extern int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**); 162593348eSBarry Smith 17b6490206SBarry Smith static int MatGetReordering_SeqBAIJ(Mat A,MatOrdering type,IS *rperm,IS *cperm) 182593348eSBarry Smith { 19b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 20bcd2baecSBarry Smith int ierr, *ia, *ja,n = a->mbs,*idx,i,ishift,oshift; 212593348eSBarry Smith 222593348eSBarry Smith /* 232593348eSBarry Smith this is tacky: In the future when we have written special factorization 242593348eSBarry Smith and solve routines for the identity permutation we should use a 252593348eSBarry Smith stride index set instead of the general one. 262593348eSBarry Smith */ 272593348eSBarry Smith if (type == ORDER_NATURAL) { 282593348eSBarry Smith idx = (int *) PetscMalloc( n*sizeof(int) ); CHKPTRQ(idx); 292593348eSBarry Smith for ( i=0; i<n; i++ ) idx[i] = i; 302593348eSBarry Smith ierr = ISCreateSeq(MPI_COMM_SELF,n,idx,rperm); CHKERRQ(ierr); 312593348eSBarry Smith ierr = ISCreateSeq(MPI_COMM_SELF,n,idx,cperm); CHKERRQ(ierr); 322593348eSBarry Smith PetscFree(idx); 332593348eSBarry Smith ISSetPermutation(*rperm); 342593348eSBarry Smith ISSetPermutation(*cperm); 352593348eSBarry Smith ISSetIdentity(*rperm); 362593348eSBarry Smith ISSetIdentity(*cperm); 372593348eSBarry Smith return 0; 382593348eSBarry Smith } 392593348eSBarry Smith 40bcd2baecSBarry Smith MatReorderingRegisterAll(); 41bcd2baecSBarry Smith ishift = a->indexshift; 42bcd2baecSBarry Smith oshift = -MatReorderingIndexShift[(int)type]; 43bcd2baecSBarry Smith if (MatReorderingRequiresSymmetric[(int)type]) { 44bcd2baecSBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(a->n,a->i,a->j,ishift,oshift,&ia,&ja); 45bcd2baecSBarry Smith CHKERRQ(ierr); 46bcd2baecSBarry Smith ierr = MatGetReordering_IJ(a->n,ia,ja,type,rperm,cperm); CHKERRQ(ierr); 472593348eSBarry Smith PetscFree(ia); PetscFree(ja); 48bcd2baecSBarry Smith } else { 49bcd2baecSBarry Smith if (ishift == oshift) { 50bcd2baecSBarry Smith ierr = MatGetReordering_IJ(a->n,a->i,a->j,type,rperm,cperm);CHKERRQ(ierr); 51bcd2baecSBarry Smith } 52bcd2baecSBarry Smith else if (ishift == -1) { 53bcd2baecSBarry Smith /* temporarily subtract 1 from i and j indices */ 54bcd2baecSBarry Smith int nz = a->i[a->n] - 1; 55bcd2baecSBarry Smith for ( i=0; i<nz; i++ ) a->j[i]--; 56bcd2baecSBarry Smith for ( i=0; i<a->n+1; i++ ) a->i[i]--; 57bcd2baecSBarry Smith ierr = MatGetReordering_IJ(a->n,a->i,a->j,type,rperm,cperm);CHKERRQ(ierr); 58bcd2baecSBarry Smith for ( i=0; i<nz; i++ ) a->j[i]++; 59bcd2baecSBarry Smith for ( i=0; i<a->n+1; i++ ) a->i[i]++; 60bcd2baecSBarry Smith } else { 61bcd2baecSBarry Smith /* temporarily add 1 to i and j indices */ 62bcd2baecSBarry Smith int nz = a->i[a->n] - 1; 63bcd2baecSBarry Smith for ( i=0; i<nz; i++ ) a->j[i]++; 64bcd2baecSBarry Smith for ( i=0; i<a->n+1; i++ ) a->i[i]++; 65bcd2baecSBarry Smith ierr = MatGetReordering_IJ(a->n,a->i,a->j,type,rperm,cperm);CHKERRQ(ierr); 66bcd2baecSBarry Smith for ( i=0; i<nz; i++ ) a->j[i]--; 67bcd2baecSBarry Smith for ( i=0; i<a->n+1; i++ ) a->i[i]--; 68bcd2baecSBarry Smith } 69bcd2baecSBarry Smith } 702593348eSBarry Smith return 0; 712593348eSBarry Smith } 722593348eSBarry Smith 73de6a44a3SBarry Smith /* 74de6a44a3SBarry Smith Adds diagonal pointers to sparse matrix structure. 75de6a44a3SBarry Smith */ 76de6a44a3SBarry Smith 77de6a44a3SBarry Smith int MatMarkDiag_SeqBAIJ(Mat A) 78de6a44a3SBarry Smith { 79de6a44a3SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 807fc0212eSBarry Smith int i,j, *diag, m = a->mbs; 81de6a44a3SBarry Smith 82de6a44a3SBarry Smith diag = (int *) PetscMalloc( (m+1)*sizeof(int)); CHKPTRQ(diag); 83de6a44a3SBarry Smith PLogObjectMemory(A,(m+1)*sizeof(int)); 847fc0212eSBarry Smith for ( i=0; i<m; i++ ) { 85de6a44a3SBarry Smith for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 86de6a44a3SBarry Smith if (a->j[j] == i) { 87de6a44a3SBarry Smith diag[i] = j; 88de6a44a3SBarry Smith break; 89de6a44a3SBarry Smith } 90de6a44a3SBarry Smith } 91de6a44a3SBarry Smith } 92de6a44a3SBarry Smith a->diag = diag; 93de6a44a3SBarry Smith return 0; 94de6a44a3SBarry Smith } 952593348eSBarry Smith 962593348eSBarry Smith #include "draw.h" 972593348eSBarry Smith #include "pinclude/pviewer.h" 9877c4ece6SBarry Smith #include "sys.h" 992593348eSBarry Smith 100b6490206SBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,Viewer viewer) 1012593348eSBarry Smith { 102b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 103b6490206SBarry Smith int i, fd, *col_lens, ierr, bs = a->bs,count,*jj,j,k,l; 104b6490206SBarry Smith Scalar *aa; 1052593348eSBarry Smith 10690ace30eSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr); 1072593348eSBarry Smith col_lens = (int *) PetscMalloc((4+a->m)*sizeof(int));CHKPTRQ(col_lens); 1082593348eSBarry Smith col_lens[0] = MAT_COOKIE; 1092593348eSBarry Smith col_lens[1] = a->m; 1102593348eSBarry Smith col_lens[2] = a->n; 111b6490206SBarry Smith col_lens[3] = a->nz*bs*bs; 1122593348eSBarry Smith 1132593348eSBarry Smith /* store lengths of each row and write (including header) to file */ 114b6490206SBarry Smith count = 0; 115b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 116b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 117b6490206SBarry Smith col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]); 118b6490206SBarry Smith } 1192593348eSBarry Smith } 12077c4ece6SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+a->m,BINARY_INT,1); CHKERRQ(ierr); 1212593348eSBarry Smith PetscFree(col_lens); 1222593348eSBarry Smith 1232593348eSBarry Smith /* store column indices (zero start index) */ 124b6490206SBarry Smith jj = (int *) PetscMalloc( a->nz*bs*bs*sizeof(int) ); CHKPTRQ(jj); 125b6490206SBarry Smith count = 0; 126b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 127b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 128b6490206SBarry Smith for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 129b6490206SBarry Smith for ( l=0; l<bs; l++ ) { 130b6490206SBarry Smith jj[count++] = bs*a->j[k] + l; 1312593348eSBarry Smith } 1322593348eSBarry Smith } 133b6490206SBarry Smith } 134b6490206SBarry Smith } 13577c4ece6SBarry Smith ierr = PetscBinaryWrite(fd,jj,bs*bs*a->nz,BINARY_INT,0); CHKERRQ(ierr); 136b6490206SBarry Smith PetscFree(jj); 1372593348eSBarry Smith 1382593348eSBarry Smith /* store nonzero values */ 139b6490206SBarry Smith aa = (Scalar *) PetscMalloc(a->nz*bs*bs*sizeof(Scalar)); CHKPTRQ(aa); 140b6490206SBarry Smith count = 0; 141b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 142b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 143b6490206SBarry Smith for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 144b6490206SBarry Smith for ( l=0; l<bs; l++ ) { 145b6490206SBarry Smith aa[count++] = a->a[bs*bs*k + l*bs + j]; 146b6490206SBarry Smith } 147b6490206SBarry Smith } 148b6490206SBarry Smith } 149b6490206SBarry Smith } 15077c4ece6SBarry Smith ierr = PetscBinaryWrite(fd,aa,bs*bs*a->nz,BINARY_SCALAR,0); CHKERRQ(ierr); 151b6490206SBarry Smith PetscFree(aa); 1522593348eSBarry Smith return 0; 1532593348eSBarry Smith } 1542593348eSBarry Smith 155b6490206SBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,Viewer viewer) 1562593348eSBarry Smith { 157b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 158de6a44a3SBarry Smith int ierr, i,j,format,bs = a->bs,k,l; 1592593348eSBarry Smith FILE *fd; 1602593348eSBarry Smith char *outputname; 1612593348eSBarry Smith 16290ace30eSBarry Smith ierr = ViewerASCIIGetPointer(viewer,&fd); CHKERRQ(ierr); 1632593348eSBarry Smith ierr = ViewerFileGetOutputname_Private(viewer,&outputname);CHKERRQ(ierr); 16490ace30eSBarry Smith ierr = ViewerGetFormat(viewer,&format); 16590ace30eSBarry Smith if (format == ASCII_FORMAT_INFO) { 1662593348eSBarry Smith /* no need to print additional information */ ; 1672593348eSBarry Smith } 16890ace30eSBarry Smith else if (format == ASCII_FORMAT_MATLAB) { 169b6490206SBarry Smith SETERRQ(1,"MatView_SeqBAIJ_ASCII:Matlab format not supported"); 1702593348eSBarry Smith } 1712593348eSBarry Smith else { 172b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 173b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 174b6490206SBarry Smith fprintf(fd,"row %d:",i*bs+j); 175b6490206SBarry Smith for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 176b6490206SBarry Smith for ( l=0; l<bs; l++ ) { 17788685aaeSLois Curfman McInnes #if defined(PETSC_COMPLEX) 17888685aaeSLois Curfman McInnes if (imag(a->a[bs*bs*k + l*bs + j]) != 0.0) { 17988685aaeSLois Curfman McInnes fprintf(fd," %d %g + %g i",bs*a->j[k]+l, 18088685aaeSLois Curfman McInnes real(a->a[bs*bs*k + l*bs + j]),imag(a->a[bs*bs*k + l*bs + j])); 18188685aaeSLois Curfman McInnes } 18288685aaeSLois Curfman McInnes else { 18388685aaeSLois Curfman McInnes fprintf(fd," %d %g",bs*a->j[k]+l,real(a->a[bs*bs*k + l*bs + j])); 18488685aaeSLois Curfman McInnes } 18588685aaeSLois Curfman McInnes #else 186de6a44a3SBarry Smith fprintf(fd," %d %g",bs*a->j[k]+l,a->a[bs*bs*k + l*bs + j]); 18788685aaeSLois Curfman McInnes #endif 1882593348eSBarry Smith } 1892593348eSBarry Smith } 1902593348eSBarry Smith fprintf(fd,"\n"); 1912593348eSBarry Smith } 1922593348eSBarry Smith } 193b6490206SBarry Smith } 1942593348eSBarry Smith fflush(fd); 1952593348eSBarry Smith return 0; 1962593348eSBarry Smith } 1972593348eSBarry Smith 198b6490206SBarry Smith static int MatView_SeqBAIJ(PetscObject obj,Viewer viewer) 1992593348eSBarry Smith { 2002593348eSBarry Smith Mat A = (Mat) obj; 20119bcc07fSBarry Smith ViewerType vtype; 20219bcc07fSBarry Smith int ierr; 2032593348eSBarry Smith 2042593348eSBarry Smith if (!viewer) { 20519bcc07fSBarry Smith viewer = STDOUT_VIEWER_SELF; 2062593348eSBarry Smith } 20719bcc07fSBarry Smith 20819bcc07fSBarry Smith ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr); 20919bcc07fSBarry Smith if (vtype == MATLAB_VIEWER) { 210b6490206SBarry Smith SETERRQ(1,"MatView_SeqBAIJ:Matlab viewer not supported"); 2112593348eSBarry Smith } 21219bcc07fSBarry Smith else if (vtype == ASCII_FILE_VIEWER || vtype == ASCII_FILES_VIEWER){ 213b6490206SBarry Smith return MatView_SeqBAIJ_ASCII(A,viewer); 2142593348eSBarry Smith } 21519bcc07fSBarry Smith else if (vtype == BINARY_FILE_VIEWER) { 216b6490206SBarry Smith return MatView_SeqBAIJ_Binary(A,viewer); 2172593348eSBarry Smith } 21819bcc07fSBarry Smith else if (vtype == DRAW_VIEWER) { 219b6490206SBarry Smith SETERRQ(1,"MatView_SeqBAIJ:Draw viewer not supported"); 2202593348eSBarry Smith } 2212593348eSBarry Smith return 0; 2222593348eSBarry Smith } 223b6490206SBarry Smith 224*584200bdSSatish Balay #define CHUNKSIZE 2 225cd0e1443SSatish Balay 226cd0e1443SSatish Balay /* This version has row oriented v */ 227cd0e1443SSatish Balay static int MatSetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is) 228cd0e1443SSatish Balay { 229cd0e1443SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 230cd0e1443SSatish Balay int *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted; 231cd0e1443SSatish Balay int *imax=a->imax,*ai=a->i,*ailen=a->ilen,roworiented=a->roworiented; 232cd0e1443SSatish Balay int *aj=a->j,nonew=a->nonew,shift=a->indexshift,bs=a->bs,brow,bcol; 233cd0e1443SSatish Balay int ridx,cidx; 234cd0e1443SSatish Balay Scalar *ap,value,*aa=a->a,*bap; 235cd0e1443SSatish Balay 236cd0e1443SSatish Balay for ( k=0; k<m; k++ ) { /* loop over added rows */ 237cd0e1443SSatish Balay row = im[k]; brow = row/bs; 238cd0e1443SSatish Balay if (row < 0) SETERRQ(1,"MatSetValues_SeqBAIJ:Negative row"); 239cd0e1443SSatish Balay if (row >= a->m) SETERRQ(1,"MatSetValues_SeqBAIJ:Row too large"); 240cd0e1443SSatish Balay rp = aj + ai[brow] + shift; ap = aa + bs*bs*ai[brow] + shift; 241cd0e1443SSatish Balay rmax = imax[brow]; nrow = ailen[brow]; 242cd0e1443SSatish Balay low = 0; 243cd0e1443SSatish Balay for ( l=0; l<n; l++ ) { /* loop over added columns */ 244cd0e1443SSatish Balay if (in[l] < 0) SETERRQ(1,"MatSetValues_SeqBAIJ:Negative column"); 245cd0e1443SSatish Balay if (in[l] >= a->n) SETERRQ(1,"MatSetValues_SeqBAIJ:Column too large"); 246cd0e1443SSatish Balay col = in[l] - shift; bcol = col/bs; 247cd0e1443SSatish Balay ridx = row % bs; cidx = col % bs; 248cd0e1443SSatish Balay if (roworiented) { 249cd0e1443SSatish Balay value = *v++; 250cd0e1443SSatish Balay } 251cd0e1443SSatish Balay else { 252cd0e1443SSatish Balay value = v[k + l*m]; 253cd0e1443SSatish Balay } 254cd0e1443SSatish Balay if (!sorted) low = 0; high = nrow; 255cd0e1443SSatish Balay while (high-low > 5) { 256cd0e1443SSatish Balay t = (low+high)/2; 257cd0e1443SSatish Balay if (rp[t] > bcol) high = t; 258cd0e1443SSatish Balay else low = t; 259cd0e1443SSatish Balay } 260cd0e1443SSatish Balay for ( i=low; i<high; i++ ) { 261cd0e1443SSatish Balay if (rp[i] > bcol) break; 262cd0e1443SSatish Balay if (rp[i] == bcol) { 263cd0e1443SSatish Balay bap = ap + bs*bs*i + bs*ridx + cidx; 264cd0e1443SSatish Balay if (is == ADD_VALUES) *bap += value; 265cd0e1443SSatish Balay else *bap = value; 266cd0e1443SSatish Balay goto noinsert; 267cd0e1443SSatish Balay } 268cd0e1443SSatish Balay } 269cd0e1443SSatish Balay if (nonew) goto noinsert; 270cd0e1443SSatish Balay if (nrow >= rmax) { 271cd0e1443SSatish Balay /* there is no extra room in row, therefore enlarge */ 272cd0e1443SSatish Balay int new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j; 273cd0e1443SSatish Balay Scalar *new_a; 274cd0e1443SSatish Balay 275cd0e1443SSatish Balay /* malloc new storage space */ 276cd0e1443SSatish Balay len = new_nz*(sizeof(int)+bs*bs*sizeof(Scalar))+(a->mbs+1)*sizeof(int); 277cd0e1443SSatish Balay new_a = (Scalar *) PetscMalloc( len ); CHKPTRQ(new_a); 278cd0e1443SSatish Balay new_j = (int *) (new_a + bs*bs*new_nz); 279cd0e1443SSatish Balay new_i = new_j + new_nz; 280cd0e1443SSatish Balay 281cd0e1443SSatish Balay /* copy over old data into new slots */ 282cd0e1443SSatish Balay for ( ii=0; ii<brow+1; ii++ ) {new_i[ii] = ai[ii];} 283cd0e1443SSatish Balay for ( ii=row+1; ii<a->mbs+1; ii++ ) {new_i[ii] = ai[ii]+CHUNKSIZE;} 284cd0e1443SSatish Balay PetscMemcpy(new_j,aj,(ai[row]+nrow+shift)*sizeof(int)); 285cd0e1443SSatish Balay len = (new_nz - CHUNKSIZE - ai[brow] - nrow - shift); 286cd0e1443SSatish Balay PetscMemcpy(new_j+ai[brow]+shift+nrow+CHUNKSIZE,aj+ai[brow]+shift+nrow, 287cd0e1443SSatish Balay len*sizeof(int)); 288cd0e1443SSatish Balay PetscMemcpy(new_a,aa,(ai[brow]+nrow+shift)*bs*bs*sizeof(Scalar)); 289cd0e1443SSatish Balay PetscMemzero(new_a+bs*bs*(ai[brow]+shift+nrow),bs*bs*CHUNKSIZE); 290cd0e1443SSatish Balay PetscMemcpy(new_a+bs*bs*(ai[brow]+shift+nrow+CHUNKSIZE), 291cd0e1443SSatish Balay aa+bs*bs*(ai[brow]+shift+nrow),bs*bs*len*sizeof(Scalar)); 292cd0e1443SSatish Balay /* free up old matrix storage */ 293cd0e1443SSatish Balay PetscFree(a->a); 294cd0e1443SSatish Balay if (!a->singlemalloc) {PetscFree(a->i);PetscFree(a->j);} 295cd0e1443SSatish Balay aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 296cd0e1443SSatish Balay a->singlemalloc = 1; 297cd0e1443SSatish Balay 298cd0e1443SSatish Balay rp = aj + ai[brow] + shift; ap = aa + ai[brow] + shift; 299cd0e1443SSatish Balay rmax = imax[brow] = imax[brow] + CHUNKSIZE; 300cd0e1443SSatish Balay PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs*bs*sizeof(Scalar))); 301cd0e1443SSatish Balay a->maxnz += bs*bs*CHUNKSIZE; 302cd0e1443SSatish Balay a->reallocs++; 303cd0e1443SSatish Balay } 304cd0e1443SSatish Balay N = nrow++ - 1; a->nz++; 305cd0e1443SSatish Balay /* shift up all the later entries in this row */ 306cd0e1443SSatish Balay for ( ii=N; ii>=i; ii-- ) { 307cd0e1443SSatish Balay rp[ii+1] = rp[ii]; 308cd0e1443SSatish Balay PetscMemcpy(ap+bs*bs*(ii+1),ap+bs*bs*(ii),bs*bs); 309cd0e1443SSatish Balay } 310cd0e1443SSatish Balay rp[i] = bcol; 311cd0e1443SSatish Balay ap[bs*bs*i + bs*ridx + cidx] = value; 312cd0e1443SSatish Balay noinsert:; 313cd0e1443SSatish Balay low = i; 314cd0e1443SSatish Balay } 315cd0e1443SSatish Balay ailen[brow] = nrow; 316cd0e1443SSatish Balay } 317cd0e1443SSatish Balay return 0; 318cd0e1443SSatish Balay } 319cd0e1443SSatish Balay 3200b824a48SSatish Balay static int MatGetSize_SeqBAIJ(Mat A,int *m,int *n) 3210b824a48SSatish Balay { 3220b824a48SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 3230b824a48SSatish Balay *m = a->m; *n = a->n; 3240b824a48SSatish Balay return 0; 3250b824a48SSatish Balay } 3260b824a48SSatish Balay 3270b824a48SSatish Balay static int MatGetOwnershipRange_SeqBAIJ(Mat A,int *m,int *n) 3280b824a48SSatish Balay { 3290b824a48SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 3300b824a48SSatish Balay *m = 0; *n = a->m; 3310b824a48SSatish Balay return 0; 3320b824a48SSatish Balay } 3330b824a48SSatish Balay 3349867e207SSatish Balay int MatGetRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 3359867e207SSatish Balay { 3369867e207SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 3379867e207SSatish Balay int itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*idx_i; 3389867e207SSatish Balay Scalar *aa,*v_i,*aa_i; 3399867e207SSatish Balay 3409867e207SSatish Balay bs = a->bs; 3419867e207SSatish Balay ai = a->i; 3429867e207SSatish Balay aj = a->j; 3439867e207SSatish Balay aa = a->a; 3449867e207SSatish Balay 3459867e207SSatish Balay if (row < 0 || row >= a->m) SETERRQ(1,"MatGetRow_SeqBAIJ:Row out of range"); 3469867e207SSatish Balay 3479867e207SSatish Balay bn = row/bs; /* Block number */ 3489867e207SSatish Balay bp = row % bs; /* Block Position */ 3499867e207SSatish Balay M = ai[bn+1] - ai[bn]; 3509867e207SSatish Balay *nz = bs*M; 3519867e207SSatish Balay 3529867e207SSatish Balay if (v) { 3539867e207SSatish Balay *v = 0; 3549867e207SSatish Balay if (*nz) { 3559867e207SSatish Balay *v = (Scalar *) PetscMalloc( (*nz)*sizeof(Scalar) ); CHKPTRQ(*v); 3569867e207SSatish Balay for ( i=0; i<M; i++ ) { /* for each block in the block row */ 3579867e207SSatish Balay v_i = *v + i*bs; 3589867e207SSatish Balay aa_i = aa + bs*bs*(ai[bn] + i); 3599867e207SSatish Balay for ( j=bp,k=0; j<bs*bs; j+=bs,k++ ) {v_i[k] = aa_i[j];} 3609867e207SSatish Balay } 3619867e207SSatish Balay } 3629867e207SSatish Balay } 3639867e207SSatish Balay 3649867e207SSatish Balay if (idx) { 3659867e207SSatish Balay *idx = 0; 3669867e207SSatish Balay if (*nz) { 3679867e207SSatish Balay *idx = (int *) PetscMalloc( (*nz)*sizeof(int) ); CHKPTRQ(*idx); 3689867e207SSatish Balay for ( i=0; i<M; i++ ) { /* for each block in the block row */ 3699867e207SSatish Balay idx_i = *idx + i*bs; 3709867e207SSatish Balay itmp = bs*aj[ai[bn] + i]; 3719867e207SSatish Balay for ( j=0; j<bs; j++ ) {idx_i[j] = itmp++;} 3729867e207SSatish Balay } 3739867e207SSatish Balay } 3749867e207SSatish Balay } 3759867e207SSatish Balay return 0; 3769867e207SSatish Balay } 3779867e207SSatish Balay 3789867e207SSatish Balay int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 3799867e207SSatish Balay { 3809867e207SSatish Balay if (idx) {if (*idx) PetscFree(*idx);} 3819867e207SSatish Balay if (v) {if (*v) PetscFree(*v);} 3829867e207SSatish Balay return 0; 3839867e207SSatish Balay } 384b6490206SBarry Smith 385*584200bdSSatish Balay static int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode) 386*584200bdSSatish Balay { 387*584200bdSSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 388*584200bdSSatish Balay int fshift = 0,i,j,*ai = a->i, *aj = a->j, *imax = a->imax; 389*584200bdSSatish Balay int m = a->m, *ip, N, *ailen = a->ilen,shift = a->indexshift; 390*584200bdSSatish Balay int bs = a->bs, mbs = a->mbs, bs2 = bs*bs; 391*584200bdSSatish Balay Scalar *aa = a->a, *ap; 392*584200bdSSatish Balay 393*584200bdSSatish Balay if (mode == FLUSH_ASSEMBLY) return 0; 394*584200bdSSatish Balay 395*584200bdSSatish Balay for ( i=1; i<mbs; i++ ) { 396*584200bdSSatish Balay /* move each row back by the amount of empty slots (fshift) before it*/ 397*584200bdSSatish Balay fshift += imax[i-1] - ailen[i-1]; 398*584200bdSSatish Balay if (fshift) { 399*584200bdSSatish Balay ip = aj + ai[i] + shift; ap = aa + bs2*ai[i] + shift; 400*584200bdSSatish Balay N = ailen[i]; 401*584200bdSSatish Balay for ( j=0; j<N; j++ ) { 402*584200bdSSatish Balay ip[j-fshift] = ip[j]; 403*584200bdSSatish Balay PetscMemcpy(ap+(j-fshift)*bs2,ap+j+bs2,bs2); 404*584200bdSSatish Balay } 405*584200bdSSatish Balay } 406*584200bdSSatish Balay ai[i] = ai[i-1] + ailen[i-1]; 407*584200bdSSatish Balay } 408*584200bdSSatish Balay if (mbs) { 409*584200bdSSatish Balay fshift += imax[mbs-1] - ailen[mbs-1]; 410*584200bdSSatish Balay ai[mbs] = ai[mbs-1] + ailen[mbs-1]; 411*584200bdSSatish Balay } 412*584200bdSSatish Balay /* reset ilen and imax for each row */ 413*584200bdSSatish Balay for ( i=0; i<mbs; i++ ) { 414*584200bdSSatish Balay ailen[i] = imax[i] = ai[i+1] - ai[i]; 415*584200bdSSatish Balay } 416*584200bdSSatish Balay a->nz = (ai[m] + shift)*bs2; 417*584200bdSSatish Balay 418*584200bdSSatish Balay /* diagonals may have moved, so kill the diagonal pointers */ 419*584200bdSSatish Balay if (fshift && a->diag) { 420*584200bdSSatish Balay PetscFree(a->diag); 421*584200bdSSatish Balay PLogObjectMemory(A,-(m+1)*sizeof(int)); 422*584200bdSSatish Balay a->diag = 0; 423*584200bdSSatish Balay } 424*584200bdSSatish Balay PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Unneeded storage space %d used %d rows %d\n", 425*584200bdSSatish Balay fshift,a->nz,m); 426*584200bdSSatish Balay PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues %d\n", 427*584200bdSSatish Balay a->reallocs); 428*584200bdSSatish Balay return 0; 429*584200bdSSatish Balay } 430*584200bdSSatish Balay 431b6490206SBarry Smith static int MatZeroEntries_SeqBAIJ(Mat A) 4322593348eSBarry Smith { 433b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 434de6a44a3SBarry Smith PetscMemzero(a->a,a->bs*a->bs*a->i[a->mbs]*sizeof(Scalar)); 4352593348eSBarry Smith return 0; 4362593348eSBarry Smith } 4372593348eSBarry Smith 438b6490206SBarry Smith int MatDestroy_SeqBAIJ(PetscObject obj) 4392593348eSBarry Smith { 4402593348eSBarry Smith Mat A = (Mat) obj; 441b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 4422593348eSBarry Smith 4432593348eSBarry Smith #if defined(PETSC_LOG) 4442593348eSBarry Smith PLogObjectState(obj,"Rows=%d, Cols=%d, NZ=%d",a->m,a->n,a->nz); 4452593348eSBarry Smith #endif 4462593348eSBarry Smith PetscFree(a->a); 4472593348eSBarry Smith if (!a->singlemalloc) { PetscFree(a->i); PetscFree(a->j);} 4482593348eSBarry Smith if (a->diag) PetscFree(a->diag); 4492593348eSBarry Smith if (a->ilen) PetscFree(a->ilen); 4502593348eSBarry Smith if (a->imax) PetscFree(a->imax); 4512593348eSBarry Smith if (a->solve_work) PetscFree(a->solve_work); 452de6a44a3SBarry Smith if (a->mult_work) PetscFree(a->mult_work); 4532593348eSBarry Smith PetscFree(a); 454f2655603SLois Curfman McInnes PLogObjectDestroy(A); 455f2655603SLois Curfman McInnes PetscHeaderDestroy(A); 4562593348eSBarry Smith return 0; 4572593348eSBarry Smith } 4582593348eSBarry Smith 459b6490206SBarry Smith static int MatSetOption_SeqBAIJ(Mat A,MatOption op) 4602593348eSBarry Smith { 461b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 4622593348eSBarry Smith if (op == ROW_ORIENTED) a->roworiented = 1; 4632593348eSBarry Smith else if (op == COLUMN_ORIENTED) a->roworiented = 0; 4642593348eSBarry Smith else if (op == COLUMNS_SORTED) a->sorted = 1; 4652593348eSBarry Smith else if (op == NO_NEW_NONZERO_LOCATIONS) a->nonew = 1; 4662593348eSBarry Smith else if (op == YES_NEW_NONZERO_LOCATIONS) a->nonew = 0; 4672593348eSBarry Smith else if (op == ROWS_SORTED || 4682593348eSBarry Smith op == SYMMETRIC_MATRIX || 4692593348eSBarry Smith op == STRUCTURALLY_SYMMETRIC_MATRIX || 4702593348eSBarry Smith op == YES_NEW_DIAGONALS) 47194a424c1SBarry Smith PLogInfo(A,"Info:MatSetOption_SeqBAIJ:Option ignored\n"); 4722593348eSBarry Smith else if (op == NO_NEW_DIAGONALS) 473b6490206SBarry Smith {SETERRQ(PETSC_ERR_SUP,"MatSetOption_SeqBAIJ:NO_NEW_DIAGONALS");} 4742593348eSBarry Smith else 475b6490206SBarry Smith {SETERRQ(PETSC_ERR_SUP,"MatSetOption_SeqBAIJ:unknown option");} 4762593348eSBarry Smith return 0; 4772593348eSBarry Smith } 4782593348eSBarry Smith 4792593348eSBarry Smith 4802593348eSBarry Smith /* -------------------------------------------------------*/ 4812593348eSBarry Smith /* Should check that shapes of vectors and matrices match */ 4822593348eSBarry Smith /* -------------------------------------------------------*/ 483b6490206SBarry Smith #include "pinclude/plapack.h" 484b6490206SBarry Smith 485b6490206SBarry Smith static int MatMult_SeqBAIJ(Mat A,Vec xx,Vec yy) 4862593348eSBarry Smith { 487b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 488b6490206SBarry Smith Scalar *xg,*yg; 489b6490206SBarry Smith register Scalar *x, *y, *v, sum,*xb, sum1,sum2,sum3,sum4,sum5; 490b6490206SBarry Smith register Scalar x1,x2,x3,x4,x5; 491b6490206SBarry Smith int mbs = a->mbs, m = a->m, i, *idx,*ii; 492b6490206SBarry Smith int bs = a->bs,j,n,bs2 = bs*bs; 4932593348eSBarry Smith 494b6490206SBarry Smith VecGetArray(xx,&xg); x = xg; VecGetArray(yy,&yg); y = yg; 495b6490206SBarry Smith PetscMemzero(y,m*sizeof(Scalar)); 496b6490206SBarry Smith x = x; 4972593348eSBarry Smith idx = a->j; 4982593348eSBarry Smith v = a->a; 4992593348eSBarry Smith ii = a->i; 500b6490206SBarry Smith 501b6490206SBarry Smith switch (bs) { 502b6490206SBarry Smith case 1: 5032593348eSBarry Smith for ( i=0; i<m; i++ ) { 5042593348eSBarry Smith n = ii[1] - ii[0]; ii++; 5052593348eSBarry Smith sum = 0.0; 5062593348eSBarry Smith while (n--) sum += *v++ * x[*idx++]; 5072593348eSBarry Smith y[i] = sum; 5082593348eSBarry Smith } 5092593348eSBarry Smith break; 510b6490206SBarry Smith case 2: 511b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 512de6a44a3SBarry Smith n = ii[1] - ii[0]; ii++; 513b6490206SBarry Smith sum1 = 0.0; sum2 = 0.0; 514b6490206SBarry Smith for ( j=0; j<n; j++ ) { 515b6490206SBarry Smith xb = x + 2*(*idx++); x1 = xb[0]; x2 = xb[1]; 516b6490206SBarry Smith sum1 += v[0]*x1 + v[2]*x2; 517b6490206SBarry Smith sum2 += v[1]*x1 + v[3]*x2; 518b6490206SBarry Smith v += 4; 519b6490206SBarry Smith } 520b6490206SBarry Smith y[0] += sum1; y[1] += sum2; 521b6490206SBarry Smith y += 2; 522b6490206SBarry Smith } 523b6490206SBarry Smith break; 524b6490206SBarry Smith case 3: 525b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 526de6a44a3SBarry Smith n = ii[1] - ii[0]; ii++; 527b6490206SBarry Smith sum1 = 0.0; sum2 = 0.0; sum3 = 0.0; 528b6490206SBarry Smith for ( j=0; j<n; j++ ) { 529b6490206SBarry Smith xb = x + 3*(*idx++); x1 = xb[0]; x2 = xb[1]; x3 = xb[2]; 530b6490206SBarry Smith sum1 += v[0]*x1 + v[3]*x2 + v[6]*x3; 531b6490206SBarry Smith sum2 += v[1]*x1 + v[4]*x2 + v[7]*x3; 532b6490206SBarry Smith sum3 += v[2]*x1 + v[5]*x2 + v[8]*x3; 533b6490206SBarry Smith v += 9; 534b6490206SBarry Smith } 535b6490206SBarry Smith y[0] += sum1; y[1] += sum2; y[2] += sum3; 536b6490206SBarry Smith y += 3; 537b6490206SBarry Smith } 538b6490206SBarry Smith break; 539b6490206SBarry Smith case 4: 540b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 541de6a44a3SBarry Smith n = ii[1] - ii[0]; ii++; 542b6490206SBarry Smith sum1 = 0.0; sum2 = 0.0; sum3 = 0.0; sum4 = 0.0; 543b6490206SBarry Smith for ( j=0; j<n; j++ ) { 544b6490206SBarry Smith xb = x + 4*(*idx++); 545b6490206SBarry Smith x1 = xb[0]; x2 = xb[1]; x3 = xb[2]; x4 = xb[3]; 546b6490206SBarry Smith sum1 += v[0]*x1 + v[4]*x2 + v[8]*x3 + v[12]*x4; 547b6490206SBarry Smith sum2 += v[1]*x1 + v[5]*x2 + v[9]*x3 + v[13]*x4; 548b6490206SBarry Smith sum3 += v[2]*x1 + v[6]*x2 + v[10]*x3 + v[14]*x4; 549b6490206SBarry Smith sum4 += v[3]*x1 + v[7]*x2 + v[11]*x3 + v[15]*x4; 550b6490206SBarry Smith v += 16; 551b6490206SBarry Smith } 552b6490206SBarry Smith y[0] += sum1; y[1] += sum2; y[2] += sum3; y[3] += sum4; 553b6490206SBarry Smith y += 4; 554b6490206SBarry Smith } 555b6490206SBarry Smith break; 556b6490206SBarry Smith case 5: 557b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 558de6a44a3SBarry Smith n = ii[1] - ii[0]; ii++; 559b6490206SBarry Smith sum1 = 0.0; sum2 = 0.0; sum3 = 0.0; sum4 = 0.0; sum5 = 0.0; 560b6490206SBarry Smith for ( j=0; j<n; j++ ) { 561b6490206SBarry Smith xb = x + 5*(*idx++); 562b6490206SBarry Smith x1 = xb[0]; x2 = xb[1]; x3 = xb[2]; x4 = xb[3]; x5 = xb[4]; 563b6490206SBarry Smith sum1 += v[0]*x1 + v[5]*x2 + v[10]*x3 + v[15]*x4 + v[20]*x5; 564b6490206SBarry Smith sum2 += v[1]*x1 + v[6]*x2 + v[11]*x3 + v[16]*x4 + v[21]*x5; 565b6490206SBarry Smith sum3 += v[2]*x1 + v[7]*x2 + v[12]*x3 + v[17]*x4 + v[22]*x5; 566b6490206SBarry Smith sum4 += v[3]*x1 + v[8]*x2 + v[13]*x3 + v[18]*x4 + v[23]*x5; 567b6490206SBarry Smith sum5 += v[4]*x1 + v[9]*x2 + v[14]*x3 + v[19]*x4 + v[24]*x5; 568b6490206SBarry Smith v += 25; 569b6490206SBarry Smith } 570b6490206SBarry Smith y[0] += sum1; y[1] += sum2; y[2] += sum3; y[3] += sum4; y[4] += sum5; 571b6490206SBarry Smith y += 5; 572b6490206SBarry Smith } 573b6490206SBarry Smith break; 574b6490206SBarry Smith /* block sizes larger then 5 by 5 are handled by BLAS */ 575b6490206SBarry Smith default: { 576de6a44a3SBarry Smith int _One = 1,ncols,k; Scalar _DOne = 1.0, *work,*workt; 577de6a44a3SBarry Smith if (!a->mult_work) { 578de6a44a3SBarry Smith a->mult_work = (Scalar *) PetscMalloc(a->m*sizeof(Scalar)); 579de6a44a3SBarry Smith CHKPTRQ(a->mult_work); 580de6a44a3SBarry Smith } 581de6a44a3SBarry Smith work = a->mult_work; 582b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 583de6a44a3SBarry Smith n = ii[1] - ii[0]; ii++; 584de6a44a3SBarry Smith ncols = n*bs; 585de6a44a3SBarry Smith workt = work; 586b6490206SBarry Smith for ( j=0; j<n; j++ ) { 587b6490206SBarry Smith xb = x + bs*(*idx++); 588de6a44a3SBarry Smith for ( k=0; k<bs; k++ ) workt[k] = xb[k]; 589de6a44a3SBarry Smith workt += bs; 590b6490206SBarry Smith } 591de6a44a3SBarry Smith LAgemv_("N",&bs,&ncols,&_DOne,v,&bs,work,&_One,&_DOne,y,&_One); 592de6a44a3SBarry Smith v += n*bs2; 593b6490206SBarry Smith y += bs; 5942593348eSBarry Smith } 5952593348eSBarry Smith } 5962593348eSBarry Smith } 597b6490206SBarry Smith PLogFlops(2*bs2*a->nz - m); 5982593348eSBarry Smith return 0; 5992593348eSBarry Smith } 6002593348eSBarry Smith 601de6a44a3SBarry Smith static int MatGetInfo_SeqBAIJ(Mat A,MatInfoType flag,int *nz,int *nza,int *mem) 6022593348eSBarry Smith { 603b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 604bcd2baecSBarry Smith if (nz) *nz = a->bs*a->bs*a->nz; 605bcd2baecSBarry Smith if (nza) *nza = a->maxnz; 606bcd2baecSBarry Smith if (mem) *mem = (int)A->mem; 6072593348eSBarry Smith return 0; 6082593348eSBarry Smith } 6092593348eSBarry Smith 61091d316f6SSatish Balay static int MatEqual_SeqBAIJ(Mat A,Mat B, PetscTruth* flg) 61191d316f6SSatish Balay { 61291d316f6SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *)A->data, *b = (Mat_SeqBAIJ *)B->data; 61391d316f6SSatish Balay 61491d316f6SSatish Balay if (B->type !=MATSEQBAIJ)SETERRQ(1,"MatEqual_SeqBAIJ:Matrices must be same type"); 61591d316f6SSatish Balay 61691d316f6SSatish Balay /* If the matrix/block dimensions are not equal, or no of nonzeros or shift */ 61791d316f6SSatish Balay if ((a->m != b->m) || (a->n !=b->n) || (a->bs != b->bs)|| 61891d316f6SSatish Balay (a->nz != b->nz)||(a->indexshift != b->indexshift)) { 61991d316f6SSatish Balay *flg = PETSC_FALSE; return 0; 62091d316f6SSatish Balay } 62191d316f6SSatish Balay 62291d316f6SSatish Balay /* if the a->i are the same */ 62391d316f6SSatish Balay if (PetscMemcmp(a->i,b->i, (a->mbs+1)*sizeof(int))) { 62491d316f6SSatish Balay *flg = PETSC_FALSE; return 0; 62591d316f6SSatish Balay } 62691d316f6SSatish Balay 62791d316f6SSatish Balay /* if a->j are the same */ 62891d316f6SSatish Balay if (PetscMemcmp(a->j,b->j,(a->nz)*sizeof(int))) { 62991d316f6SSatish Balay *flg = PETSC_FALSE; return 0; 63091d316f6SSatish Balay } 63191d316f6SSatish Balay 63291d316f6SSatish Balay /* if a->a are the same */ 63391d316f6SSatish Balay if (PetscMemcmp(a->a, b->a,(a->nz)*(a->bs)*(a->bs)*sizeof(Scalar))) { 63491d316f6SSatish Balay *flg = PETSC_FALSE; return 0; 63591d316f6SSatish Balay } 63691d316f6SSatish Balay *flg = PETSC_TRUE; 63791d316f6SSatish Balay return 0; 63891d316f6SSatish Balay 63991d316f6SSatish Balay } 64091d316f6SSatish Balay 64191d316f6SSatish Balay static int MatGetDiagonal_SeqBAIJ(Mat A,Vec v) 64291d316f6SSatish Balay { 64391d316f6SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 64417e48fc4SSatish Balay int i,j,k,n,row,bs,*ai,*aj,ambs; 64517e48fc4SSatish Balay Scalar *x, zero = 0.0,*aa,*aa_j; 64617e48fc4SSatish Balay 64717e48fc4SSatish Balay bs = a->bs; 64817e48fc4SSatish Balay aa = a->a; 64917e48fc4SSatish Balay ai = a->i; 65017e48fc4SSatish Balay aj = a->j; 65117e48fc4SSatish Balay ambs = a->mbs; 65291d316f6SSatish Balay 65391d316f6SSatish Balay VecSet(&zero,v); 65491d316f6SSatish Balay VecGetArray(v,&x); VecGetLocalSize(v,&n); 6559867e207SSatish Balay if (n != a->m) SETERRQ(1,"MatGetDiagonal_SeqBAIJ:Nonconforming matrix and vector"); 65617e48fc4SSatish Balay for ( i=0; i<ambs; i++ ) { 65717e48fc4SSatish Balay for ( j=ai[i]; j<ai[i+1]; j++ ) { 65817e48fc4SSatish Balay if (aj[j] == i) { 65917e48fc4SSatish Balay row = i*bs; 66017e48fc4SSatish Balay aa_j = aa+j*bs*bs; 66117e48fc4SSatish Balay for (k=0; k<bs*bs; k+=(bs+1),row++) x[row] = aa_j[k]; 66291d316f6SSatish Balay break; 66391d316f6SSatish Balay } 66491d316f6SSatish Balay } 66591d316f6SSatish Balay } 66691d316f6SSatish Balay return 0; 66791d316f6SSatish Balay } 66891d316f6SSatish Balay 6699867e207SSatish Balay static int MatDiagonalScale_SeqBAIJ(Mat A,Vec ll,Vec rr) 6709867e207SSatish Balay { 6719867e207SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 6729867e207SSatish Balay Scalar *l,*r,x,*v,*aa,*li,*ri; 6739867e207SSatish Balay int i,j,k,lm,rn,M,m,n,*ai,*aj,mbs,tmp,bs; 6749867e207SSatish Balay 6759867e207SSatish Balay ai = a->i; 6769867e207SSatish Balay aj = a->j; 6779867e207SSatish Balay aa = a->a; 6789867e207SSatish Balay m = a->m; 6799867e207SSatish Balay n = a->n; 6809867e207SSatish Balay bs = a->bs; 6819867e207SSatish Balay mbs = a->mbs; 6829867e207SSatish Balay 6839867e207SSatish Balay if (ll) { 6849867e207SSatish Balay VecGetArray(ll,&l); VecGetSize(ll,&lm); 6859867e207SSatish Balay if (lm != m) SETERRQ(1,"MatDiagonalScale_SeqBAIJ:Left scaling vector wrong length"); 6869867e207SSatish Balay for ( i=0; i<mbs; i++ ) { /* for each block row */ 6879867e207SSatish Balay M = ai[i+1] - ai[i]; 6889867e207SSatish Balay li = l + i*bs; 6899867e207SSatish Balay v = aa + bs*bs*ai[i]; 6909867e207SSatish Balay for ( j=0; j<M; j++ ) { /* for each block */ 6919867e207SSatish Balay for ( k=0; k<bs*bs; k++ ) { 6929867e207SSatish Balay (*v++) *= li[k%bs]; 6939867e207SSatish Balay } 6949867e207SSatish Balay } 6959867e207SSatish Balay } 6969867e207SSatish Balay } 6979867e207SSatish Balay 6989867e207SSatish Balay if (rr) { 6999867e207SSatish Balay VecGetArray(rr,&r); VecGetSize(rr,&rn); 7009867e207SSatish Balay if (rn != n) SETERRQ(1,"MatDiagonalScale_SeqBAIJ:Right scaling vector wrong length"); 7019867e207SSatish Balay for ( i=0; i<mbs; i++ ) { /* for each block row */ 7029867e207SSatish Balay M = ai[i+1] - ai[i]; 7039867e207SSatish Balay v = aa + bs*bs*ai[i]; 7049867e207SSatish Balay for ( j=0; j<M; j++ ) { /* for each block */ 7059867e207SSatish Balay ri = r + bs*aj[ai[i]+j]; 7069867e207SSatish Balay for ( k=0; k<bs; k++ ) { 7079867e207SSatish Balay x = ri[k]; 7089867e207SSatish Balay for ( tmp=0; tmp<bs; tmp++ ) (*v++) *= x; 7099867e207SSatish Balay } 7109867e207SSatish Balay } 7119867e207SSatish Balay } 7129867e207SSatish Balay } 7139867e207SSatish Balay return 0; 7149867e207SSatish Balay } 7159867e207SSatish Balay 7169867e207SSatish Balay 717b6490206SBarry Smith extern int MatLUFactorSymbolic_SeqBAIJ(Mat,IS,IS,double,Mat*); 718b6490206SBarry Smith extern int MatLUFactor_SeqBAIJ(Mat,IS,IS,double); 719b6490206SBarry Smith extern int MatSolve_SeqBAIJ(Mat,Vec,Vec); 7207fc0212eSBarry Smith extern int MatLUFactorNumeric_SeqBAIJ_N(Mat,Mat*); 7217fc0212eSBarry Smith extern int MatLUFactorNumeric_SeqBAIJ_1(Mat,Mat*); 7227fc0212eSBarry Smith extern int MatLUFactorNumeric_SeqBAIJ_2(Mat,Mat*); 7237fc0212eSBarry Smith extern int MatLUFactorNumeric_SeqBAIJ_3(Mat,Mat*); 7247fc0212eSBarry Smith extern int MatLUFactorNumeric_SeqBAIJ_4(Mat,Mat*); 7257fc0212eSBarry Smith extern int MatLUFactorNumeric_SeqBAIJ_5(Mat,Mat*); 7262593348eSBarry Smith 727b6490206SBarry Smith static int MatNorm_SeqBAIJ(Mat A,NormType type,double *norm) 7282593348eSBarry Smith { 729b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 7302593348eSBarry Smith Scalar *v = a->a; 7312593348eSBarry Smith double sum = 0.0; 732b6490206SBarry Smith int i; 7332593348eSBarry Smith 7342593348eSBarry Smith if (type == NORM_FROBENIUS) { 7352593348eSBarry Smith for (i=0; i<a->nz; i++ ) { 7362593348eSBarry Smith #if defined(PETSC_COMPLEX) 7372593348eSBarry Smith sum += real(conj(*v)*(*v)); v++; 7382593348eSBarry Smith #else 7392593348eSBarry Smith sum += (*v)*(*v); v++; 7402593348eSBarry Smith #endif 7412593348eSBarry Smith } 7422593348eSBarry Smith *norm = sqrt(sum); 7432593348eSBarry Smith } 7442593348eSBarry Smith else { 745b6490206SBarry Smith SETERRQ(1,"MatNorm_SeqBAIJ:No support for this norm yet"); 7462593348eSBarry Smith } 7472593348eSBarry Smith return 0; 7482593348eSBarry Smith } 7492593348eSBarry Smith 7502593348eSBarry Smith /* 7512593348eSBarry Smith note: This can only work for identity for row and col. It would 7522593348eSBarry Smith be good to check this and otherwise generate an error. 7532593348eSBarry Smith */ 754b6490206SBarry Smith static int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,double efill,int fill) 7552593348eSBarry Smith { 756b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) inA->data; 7572593348eSBarry Smith Mat outA; 758de6a44a3SBarry Smith int ierr; 7592593348eSBarry Smith 760b6490206SBarry Smith if (fill != 0) SETERRQ(1,"MatILUFactor_SeqBAIJ:Only fill=0 supported"); 7612593348eSBarry Smith 7622593348eSBarry Smith outA = inA; 7632593348eSBarry Smith inA->factor = FACTOR_LU; 7642593348eSBarry Smith a->row = row; 7652593348eSBarry Smith a->col = col; 7662593348eSBarry Smith 767de6a44a3SBarry Smith a->solve_work = (Scalar *) PetscMalloc((a->m+a->bs)*sizeof(Scalar));CHKPTRQ(a->solve_work); 7682593348eSBarry Smith 7692593348eSBarry Smith if (!a->diag) { 770b6490206SBarry Smith ierr = MatMarkDiag_SeqBAIJ(inA); CHKERRQ(ierr); 7712593348eSBarry Smith } 7727fc0212eSBarry Smith ierr = MatLUFactorNumeric(inA,&outA); CHKERRQ(ierr); 7732593348eSBarry Smith return 0; 7742593348eSBarry Smith } 7752593348eSBarry Smith 776b6490206SBarry Smith static int MatScale_SeqBAIJ(Scalar *alpha,Mat inA) 7772593348eSBarry Smith { 778b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) inA->data; 779b6490206SBarry Smith int one = 1, totalnz = a->bs*a->bs*a->nz; 780b6490206SBarry Smith BLscal_( &totalnz, alpha, a->a, &one ); 781b6490206SBarry Smith PLogFlops(totalnz); 7822593348eSBarry Smith return 0; 7832593348eSBarry Smith } 7842593348eSBarry Smith 785b6490206SBarry Smith int MatPrintHelp_SeqBAIJ(Mat A) 7862593348eSBarry Smith { 7872593348eSBarry Smith static int called = 0; 7882593348eSBarry Smith 7892593348eSBarry Smith if (called) return 0; else called = 1; 7902593348eSBarry Smith return 0; 7912593348eSBarry Smith } 7922593348eSBarry Smith /* -------------------------------------------------------------------*/ 793cd0e1443SSatish Balay static struct _MatOps MatOps = {MatSetValues_SeqBAIJ, 7949867e207SSatish Balay MatGetRow_SeqBAIJ,MatRestoreRow_SeqBAIJ, 795b6490206SBarry Smith MatMult_SeqBAIJ,0, 796b6490206SBarry Smith 0,0, 797de6a44a3SBarry Smith MatSolve_SeqBAIJ,0, 798b6490206SBarry Smith 0,0, 799de6a44a3SBarry Smith MatLUFactor_SeqBAIJ,0, 800b6490206SBarry Smith 0, 801b6490206SBarry Smith 0, 80217e48fc4SSatish Balay MatGetInfo_SeqBAIJ,MatEqual_SeqBAIJ, 8039867e207SSatish Balay MatGetDiagonal_SeqBAIJ,MatDiagonalScale_SeqBAIJ,MatNorm_SeqBAIJ, 804*584200bdSSatish Balay 0,MatAssemblyEnd_SeqBAIJ, 805b6490206SBarry Smith 0, 806b6490206SBarry Smith MatSetOption_SeqBAIJ,MatZeroEntries_SeqBAIJ,0, 807b6490206SBarry Smith MatGetReordering_SeqBAIJ, 8087fc0212eSBarry Smith MatLUFactorSymbolic_SeqBAIJ,MatLUFactorNumeric_SeqBAIJ_N,0,0, 809b6490206SBarry Smith MatGetSize_SeqBAIJ,MatGetSize_SeqBAIJ,MatGetOwnershipRange_SeqBAIJ, 810de6a44a3SBarry Smith MatILUFactorSymbolic_SeqBAIJ,0, 811b6490206SBarry Smith 0,0,/* MatConvert_SeqBAIJ */ 0, 812b6490206SBarry Smith 0,0, 813b6490206SBarry Smith MatConvertSameType_SeqBAIJ,0,0, 814b6490206SBarry Smith MatILUFactor_SeqBAIJ,0,0, 815b6490206SBarry Smith 0,0, 816b6490206SBarry Smith 0,0, 817b6490206SBarry Smith MatPrintHelp_SeqBAIJ,MatScale_SeqBAIJ, 818b6490206SBarry Smith 0}; 8192593348eSBarry Smith 8202593348eSBarry Smith /*@C 821b6490206SBarry Smith MatCreateSeqBAIJ - Creates a sparse matrix in AIJ (compressed row) format 8222593348eSBarry Smith (the default parallel PETSc format). For good matrix assembly performance 8232593348eSBarry Smith the user should preallocate the matrix storage by setting the parameter nz 8242593348eSBarry Smith (or nzz). By setting these parameters accurately, performance can be 8252593348eSBarry Smith increased by more than a factor of 50. 8262593348eSBarry Smith 8272593348eSBarry Smith Input Parameters: 8282593348eSBarry Smith . comm - MPI communicator, set to MPI_COMM_SELF 829b6490206SBarry Smith . bs - size of block 8302593348eSBarry Smith . m - number of rows 8312593348eSBarry Smith . n - number of columns 832b6490206SBarry Smith . nz - number of block nonzeros per block row (same for all rows) 833b6490206SBarry Smith . nzz - number of block nonzeros per block row or PETSC_NULL 834b6490206SBarry Smith (possibly different for each row) 8352593348eSBarry Smith 8362593348eSBarry Smith Output Parameter: 8372593348eSBarry Smith . A - the matrix 8382593348eSBarry Smith 8392593348eSBarry Smith Notes: 840b6490206SBarry Smith The BAIJ format, is fully compatible with standard Fortran 77 8412593348eSBarry Smith storage. That is, the stored row and column indices can begin at 8422593348eSBarry Smith either one (as in Fortran) or zero. See the users manual for details. 8432593348eSBarry Smith 8442593348eSBarry Smith Specify the preallocated storage with either nz or nnz (not both). 8452593348eSBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 8462593348eSBarry Smith allocation. For additional details, see the users manual chapter on 8472593348eSBarry Smith matrices and the file $(PETSC_DIR)/Performance. 8482593348eSBarry Smith 8492593348eSBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues() 8502593348eSBarry Smith @*/ 851b6490206SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz, Mat *A) 8522593348eSBarry Smith { 8532593348eSBarry Smith Mat B; 854b6490206SBarry Smith Mat_SeqBAIJ *b; 855b6490206SBarry Smith int i,len,ierr, flg,mbs = m/bs; 856b6490206SBarry Smith 857b6490206SBarry Smith if (mbs*bs != m) 858b6490206SBarry Smith SETERRQ(1,"MatCreateSeqBAIJ:Number rows must be divisible by blocksize"); 8592593348eSBarry Smith 8602593348eSBarry Smith *A = 0; 861b6490206SBarry Smith PetscHeaderCreate(B,_Mat,MAT_COOKIE,MATSEQBAIJ,comm); 8622593348eSBarry Smith PLogObjectCreate(B); 863b6490206SBarry Smith B->data = (void *) (b = PetscNew(Mat_SeqBAIJ)); CHKPTRQ(b); 8642593348eSBarry Smith PetscMemcpy(&B->ops,&MatOps,sizeof(struct _MatOps)); 8657fc0212eSBarry Smith switch (bs) { 8667fc0212eSBarry Smith case 1: 8677fc0212eSBarry Smith B->ops.lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1; 8687fc0212eSBarry Smith break; 8694eeb42bcSBarry Smith case 2: 8704eeb42bcSBarry Smith B->ops.lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2; 8716d84be18SBarry Smith break; 872f327dd97SBarry Smith case 3: 873f327dd97SBarry Smith B->ops.lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3; 8744eeb42bcSBarry Smith break; 8756d84be18SBarry Smith case 4: 8766d84be18SBarry Smith B->ops.lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4; 8776d84be18SBarry Smith break; 8786d84be18SBarry Smith case 5: 8796d84be18SBarry Smith B->ops.lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5; 8806d84be18SBarry Smith break; 8817fc0212eSBarry Smith } 882b6490206SBarry Smith B->destroy = MatDestroy_SeqBAIJ; 883b6490206SBarry Smith B->view = MatView_SeqBAIJ; 8842593348eSBarry Smith B->factor = 0; 8852593348eSBarry Smith B->lupivotthreshold = 1.0; 8862593348eSBarry Smith b->row = 0; 8872593348eSBarry Smith b->col = 0; 8882593348eSBarry Smith b->reallocs = 0; 8892593348eSBarry Smith 8902593348eSBarry Smith b->m = m; 891b6490206SBarry Smith b->mbs = mbs; 8922593348eSBarry Smith b->n = n; 893b6490206SBarry Smith b->imax = (int *) PetscMalloc( (mbs+1)*sizeof(int) ); CHKPTRQ(b->imax); 8942593348eSBarry Smith if (nnz == PETSC_NULL) { 895de6a44a3SBarry Smith if (nz == PETSC_DEFAULT) nz = 5; 8962593348eSBarry Smith else if (nz <= 0) nz = 1; 897b6490206SBarry Smith for ( i=0; i<mbs; i++ ) b->imax[i] = nz; 898b6490206SBarry Smith nz = nz*mbs; 8992593348eSBarry Smith } 9002593348eSBarry Smith else { 9012593348eSBarry Smith nz = 0; 902b6490206SBarry Smith for ( i=0; i<mbs; i++ ) {b->imax[i] = nnz[i]; nz += nnz[i];} 9032593348eSBarry Smith } 9042593348eSBarry Smith 9052593348eSBarry Smith /* allocate the matrix space */ 906b6490206SBarry Smith len = nz*sizeof(int) + nz*bs*bs*sizeof(Scalar) + (b->m+1)*sizeof(int); 9072593348eSBarry Smith b->a = (Scalar *) PetscMalloc( len ); CHKPTRQ(b->a); 908b6490206SBarry Smith PetscMemzero(b->a,nz*bs*bs*sizeof(Scalar)); 909b6490206SBarry Smith b->j = (int *) (b->a + nz*bs*bs); 9102593348eSBarry Smith PetscMemzero(b->j,nz*sizeof(int)); 9112593348eSBarry Smith b->i = b->j + nz; 9122593348eSBarry Smith b->singlemalloc = 1; 9132593348eSBarry Smith 914de6a44a3SBarry Smith b->i[0] = 0; 915b6490206SBarry Smith for (i=1; i<mbs+1; i++) { 9162593348eSBarry Smith b->i[i] = b->i[i-1] + b->imax[i-1]; 9172593348eSBarry Smith } 9182593348eSBarry Smith 919b6490206SBarry Smith /* b->ilen will count nonzeros in each block row so far. */ 920b6490206SBarry Smith b->ilen = (int *) PetscMalloc((mbs+1)*sizeof(int)); 921b6490206SBarry Smith PLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _Mat)+sizeof(Mat_SeqBAIJ)); 922b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { b->ilen[i] = 0;} 9232593348eSBarry Smith 924b6490206SBarry Smith b->bs = bs; 925b6490206SBarry Smith b->mbs = mbs; 9262593348eSBarry Smith b->nz = 0; 9272593348eSBarry Smith b->maxnz = nz; 9282593348eSBarry Smith b->sorted = 0; 9292593348eSBarry Smith b->roworiented = 1; 9302593348eSBarry Smith b->nonew = 0; 9312593348eSBarry Smith b->diag = 0; 9322593348eSBarry Smith b->solve_work = 0; 933de6a44a3SBarry Smith b->mult_work = 0; 9342593348eSBarry Smith b->spptr = 0; 9352593348eSBarry Smith 9362593348eSBarry Smith *A = B; 9372593348eSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr); 9382593348eSBarry Smith if (flg) {ierr = MatPrintHelp(B); CHKERRQ(ierr); } 9392593348eSBarry Smith return 0; 9402593348eSBarry Smith } 9412593348eSBarry Smith 942b6490206SBarry Smith int MatConvertSameType_SeqBAIJ(Mat A,Mat *B,int cpvalues) 9432593348eSBarry Smith { 9442593348eSBarry Smith Mat C; 945b6490206SBarry Smith Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ *) A->data; 946de6a44a3SBarry Smith int i,len, mbs = a->mbs, bs = a->bs,nz = a->nz; 947de6a44a3SBarry Smith 948de6a44a3SBarry Smith if (a->i[mbs] != nz) SETERRQ(1,"MatConvertSameType_SeqBAIJ:Corrupt matrix"); 9492593348eSBarry Smith 9502593348eSBarry Smith *B = 0; 951b6490206SBarry Smith PetscHeaderCreate(C,_Mat,MAT_COOKIE,MATSEQBAIJ,A->comm); 9522593348eSBarry Smith PLogObjectCreate(C); 953b6490206SBarry Smith C->data = (void *) (c = PetscNew(Mat_SeqBAIJ)); CHKPTRQ(c); 9542593348eSBarry Smith PetscMemcpy(&C->ops,&A->ops,sizeof(struct _MatOps)); 955b6490206SBarry Smith C->destroy = MatDestroy_SeqBAIJ; 956b6490206SBarry Smith C->view = MatView_SeqBAIJ; 9572593348eSBarry Smith C->factor = A->factor; 9582593348eSBarry Smith c->row = 0; 9592593348eSBarry Smith c->col = 0; 9602593348eSBarry Smith C->assembled = PETSC_TRUE; 9612593348eSBarry Smith 9622593348eSBarry Smith c->m = a->m; 9632593348eSBarry Smith c->n = a->n; 964b6490206SBarry Smith c->bs = a->bs; 965b6490206SBarry Smith c->mbs = a->mbs; 966b6490206SBarry Smith c->nbs = a->nbs; 9672593348eSBarry Smith 968b6490206SBarry Smith c->imax = (int *) PetscMalloc((mbs+1)*sizeof(int)); CHKPTRQ(c->imax); 969b6490206SBarry Smith c->ilen = (int *) PetscMalloc((mbs+1)*sizeof(int)); CHKPTRQ(c->ilen); 970b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 9712593348eSBarry Smith c->imax[i] = a->imax[i]; 9722593348eSBarry Smith c->ilen[i] = a->ilen[i]; 9732593348eSBarry Smith } 9742593348eSBarry Smith 9752593348eSBarry Smith /* allocate the matrix space */ 9762593348eSBarry Smith c->singlemalloc = 1; 977de6a44a3SBarry Smith len = (mbs+1)*sizeof(int) + nz*(bs*bs*sizeof(Scalar) + sizeof(int)); 9782593348eSBarry Smith c->a = (Scalar *) PetscMalloc( len ); CHKPTRQ(c->a); 979de6a44a3SBarry Smith c->j = (int *) (c->a + nz*bs*bs); 980de6a44a3SBarry Smith c->i = c->j + nz; 981b6490206SBarry Smith PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int)); 982b6490206SBarry Smith if (mbs > 0) { 983de6a44a3SBarry Smith PetscMemcpy(c->j,a->j,nz*sizeof(int)); 9842593348eSBarry Smith if (cpvalues == COPY_VALUES) { 985de6a44a3SBarry Smith PetscMemcpy(c->a,a->a,bs*bs*nz*sizeof(Scalar)); 9862593348eSBarry Smith } 9872593348eSBarry Smith } 9882593348eSBarry Smith 989b6490206SBarry Smith PLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _Mat)+sizeof(Mat_SeqBAIJ)); 9902593348eSBarry Smith c->sorted = a->sorted; 9912593348eSBarry Smith c->roworiented = a->roworiented; 9922593348eSBarry Smith c->nonew = a->nonew; 9932593348eSBarry Smith 9942593348eSBarry Smith if (a->diag) { 995b6490206SBarry Smith c->diag = (int *) PetscMalloc( (mbs+1)*sizeof(int) ); CHKPTRQ(c->diag); 996b6490206SBarry Smith PLogObjectMemory(C,(mbs+1)*sizeof(int)); 997b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 9982593348eSBarry Smith c->diag[i] = a->diag[i]; 9992593348eSBarry Smith } 10002593348eSBarry Smith } 10012593348eSBarry Smith else c->diag = 0; 10022593348eSBarry Smith c->nz = a->nz; 10032593348eSBarry Smith c->maxnz = a->maxnz; 10042593348eSBarry Smith c->solve_work = 0; 10052593348eSBarry Smith c->spptr = 0; /* Dangerous -I'm throwing away a->spptr */ 10067fc0212eSBarry Smith c->mult_work = 0; 10072593348eSBarry Smith *B = C; 10082593348eSBarry Smith return 0; 10092593348eSBarry Smith } 10102593348eSBarry Smith 101119bcc07fSBarry Smith int MatLoad_SeqBAIJ(Viewer viewer,MatType type,Mat *A) 10122593348eSBarry Smith { 1013b6490206SBarry Smith Mat_SeqBAIJ *a; 10142593348eSBarry Smith Mat B; 1015de6a44a3SBarry Smith int i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1,flg; 1016b6490206SBarry Smith int *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount; 101735aab85fSBarry Smith int kmax,jcount,block,idx,point,nzcountb,extra_rows; 1018de6a44a3SBarry Smith int *masked, nmask,tmp,ishift,bs2; 1019b6490206SBarry Smith Scalar *aa; 102019bcc07fSBarry Smith MPI_Comm comm = ((PetscObject) viewer)->comm; 10212593348eSBarry Smith 102235aab85fSBarry Smith ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&bs,&flg);CHKERRQ(ierr); 1023de6a44a3SBarry Smith bs2 = bs*bs; 1024b6490206SBarry Smith 10252593348eSBarry Smith MPI_Comm_size(comm,&size); 1026b6490206SBarry Smith if (size > 1) SETERRQ(1,"MatLoad_SeqBAIJ:view must have one processor"); 102790ace30eSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr); 102877c4ece6SBarry Smith ierr = PetscBinaryRead(fd,header,4,BINARY_INT); CHKERRQ(ierr); 1029de6a44a3SBarry Smith if (header[0] != MAT_COOKIE) SETERRQ(1,"MatLoad_SeqBAIJ:not Mat object"); 10302593348eSBarry Smith M = header[1]; N = header[2]; nz = header[3]; 10312593348eSBarry Smith 1032b6490206SBarry Smith if (M != N) SETERRQ(1,"MatLoad_SeqBAIJ:Can only do square matrices"); 103335aab85fSBarry Smith 103435aab85fSBarry Smith /* 103535aab85fSBarry Smith This code adds extra rows to make sure the number of rows is 103635aab85fSBarry Smith divisible by the blocksize 103735aab85fSBarry Smith */ 1038b6490206SBarry Smith mbs = M/bs; 103935aab85fSBarry Smith extra_rows = bs - M + bs*(mbs); 104035aab85fSBarry Smith if (extra_rows == bs) extra_rows = 0; 104135aab85fSBarry Smith else mbs++; 104235aab85fSBarry Smith if (extra_rows) { 104335aab85fSBarry Smith PLogInfo(0,"MatLoad_SeqBAIJ:Padding loading matrix to match blocksize"); 104435aab85fSBarry Smith } 1045b6490206SBarry Smith 10462593348eSBarry Smith /* read in row lengths */ 104735aab85fSBarry Smith rowlengths = (int*) PetscMalloc((M+extra_rows)*sizeof(int));CHKPTRQ(rowlengths); 104877c4ece6SBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,BINARY_INT); CHKERRQ(ierr); 104935aab85fSBarry Smith for ( i=0; i<extra_rows; i++ ) rowlengths[M+i] = 1; 10502593348eSBarry Smith 1051b6490206SBarry Smith /* read in column indices */ 105235aab85fSBarry Smith jj = (int*) PetscMalloc( (nz+extra_rows)*sizeof(int) ); CHKPTRQ(jj); 105377c4ece6SBarry Smith ierr = PetscBinaryRead(fd,jj,nz,BINARY_INT); CHKERRQ(ierr); 105435aab85fSBarry Smith for ( i=0; i<extra_rows; i++ ) jj[nz+i] = M+i; 1055b6490206SBarry Smith 1056b6490206SBarry Smith /* loop over row lengths determining block row lengths */ 1057b6490206SBarry Smith browlengths = (int *) PetscMalloc(mbs*sizeof(int));CHKPTRQ(browlengths); 1058b6490206SBarry Smith PetscMemzero(browlengths,mbs*sizeof(int)); 105935aab85fSBarry Smith mask = (int *) PetscMalloc( 2*mbs*sizeof(int) ); CHKPTRQ(mask); 106035aab85fSBarry Smith PetscMemzero(mask,mbs*sizeof(int)); 106135aab85fSBarry Smith masked = mask + mbs; 1062b6490206SBarry Smith rowcount = 0; nzcount = 0; 1063b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 106435aab85fSBarry Smith nmask = 0; 1065b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 1066b6490206SBarry Smith kmax = rowlengths[rowcount]; 1067b6490206SBarry Smith for ( k=0; k<kmax; k++ ) { 106835aab85fSBarry Smith tmp = jj[nzcount++]/bs; 106935aab85fSBarry Smith if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;} 1070b6490206SBarry Smith } 1071b6490206SBarry Smith rowcount++; 1072b6490206SBarry Smith } 107335aab85fSBarry Smith browlengths[i] += nmask; 107435aab85fSBarry Smith /* zero out the mask elements we set */ 107535aab85fSBarry Smith for ( j=0; j<nmask; j++ ) mask[masked[j]] = 0; 1076b6490206SBarry Smith } 1077b6490206SBarry Smith 10782593348eSBarry Smith /* create our matrix */ 107935aab85fSBarry Smith ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A); 108035aab85fSBarry Smith CHKERRQ(ierr); 10812593348eSBarry Smith B = *A; 1082b6490206SBarry Smith a = (Mat_SeqBAIJ *) B->data; 10832593348eSBarry Smith 10842593348eSBarry Smith /* set matrix "i" values */ 1085de6a44a3SBarry Smith a->i[0] = 0; 1086b6490206SBarry Smith for ( i=1; i<= mbs; i++ ) { 1087b6490206SBarry Smith a->i[i] = a->i[i-1] + browlengths[i-1]; 1088b6490206SBarry Smith a->ilen[i-1] = browlengths[i-1]; 10892593348eSBarry Smith } 10909867e207SSatish Balay a->indexshift = 0; 1091b6490206SBarry Smith a->nz = 0; 1092b6490206SBarry Smith for ( i=0; i<mbs; i++ ) a->nz += browlengths[i]; 10932593348eSBarry Smith 1094b6490206SBarry Smith /* read in nonzero values */ 109535aab85fSBarry Smith aa = (Scalar *) PetscMalloc((nz+extra_rows)*sizeof(Scalar));CHKPTRQ(aa); 109677c4ece6SBarry Smith ierr = PetscBinaryRead(fd,aa,nz,BINARY_SCALAR); CHKERRQ(ierr); 109735aab85fSBarry Smith for ( i=0; i<extra_rows; i++ ) aa[nz+i] = 1.0; 1098b6490206SBarry Smith 1099b6490206SBarry Smith /* set "a" and "j" values into matrix */ 1100b6490206SBarry Smith nzcount = 0; jcount = 0; 1101b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 1102b6490206SBarry Smith nzcountb = nzcount; 110335aab85fSBarry Smith nmask = 0; 1104b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 1105b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 1106b6490206SBarry Smith for ( k=0; k<kmax; k++ ) { 110735aab85fSBarry Smith tmp = jj[nzcount++]/bs; 110835aab85fSBarry Smith if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;} 1109b6490206SBarry Smith } 1110b6490206SBarry Smith rowcount++; 1111b6490206SBarry Smith } 1112de6a44a3SBarry Smith /* sort the masked values */ 111377c4ece6SBarry Smith PetscSortInt(nmask,masked); 1114de6a44a3SBarry Smith 1115b6490206SBarry Smith /* set "j" values into matrix */ 1116b6490206SBarry Smith maskcount = 1; 111735aab85fSBarry Smith for ( j=0; j<nmask; j++ ) { 111835aab85fSBarry Smith a->j[jcount++] = masked[j]; 1119de6a44a3SBarry Smith mask[masked[j]] = maskcount++; 1120b6490206SBarry Smith } 1121b6490206SBarry Smith /* set "a" values into matrix */ 1122de6a44a3SBarry Smith ishift = bs2*a->i[i]; 1123b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 1124b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 1125b6490206SBarry Smith for ( k=0; k<kmax; k++ ) { 1126de6a44a3SBarry Smith tmp = jj[nzcountb]/bs ; 1127de6a44a3SBarry Smith block = mask[tmp] - 1; 1128de6a44a3SBarry Smith point = jj[nzcountb] - bs*tmp; 1129de6a44a3SBarry Smith idx = ishift + bs2*block + j + bs*point; 1130b6490206SBarry Smith a->a[idx] = aa[nzcountb++]; 1131b6490206SBarry Smith } 1132b6490206SBarry Smith } 113335aab85fSBarry Smith /* zero out the mask elements we set */ 113435aab85fSBarry Smith for ( j=0; j<nmask; j++ ) mask[masked[j]] = 0; 1135b6490206SBarry Smith } 113635aab85fSBarry Smith if (jcount != a->nz) SETERRQ(1,"MatLoad_SeqBAIJ:Error bad binary matrix"); 1137b6490206SBarry Smith 1138b6490206SBarry Smith PetscFree(rowlengths); 1139b6490206SBarry Smith PetscFree(browlengths); 1140b6490206SBarry Smith PetscFree(aa); 1141b6490206SBarry Smith PetscFree(jj); 1142b6490206SBarry Smith PetscFree(mask); 1143b6490206SBarry Smith 1144b6490206SBarry Smith B->assembled = PETSC_TRUE; 1145de6a44a3SBarry Smith 1146de6a44a3SBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_view_info",&flg); CHKERRQ(ierr); 1147de6a44a3SBarry Smith if (flg) { 114819bcc07fSBarry Smith Viewer tviewer; 114919bcc07fSBarry Smith ierr = ViewerFileOpenASCII(B->comm,"stdout",&tviewer);CHKERRQ(ierr); 115090ace30eSBarry Smith ierr = ViewerSetFormat(tviewer,ASCII_FORMAT_INFO,0);CHKERRQ(ierr); 115119bcc07fSBarry Smith ierr = MatView(B,tviewer); CHKERRQ(ierr); 115219bcc07fSBarry Smith ierr = ViewerDestroy(tviewer); CHKERRQ(ierr); 1153de6a44a3SBarry Smith } 1154de6a44a3SBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_view_info_detailed",&flg);CHKERRQ(ierr); 1155de6a44a3SBarry Smith if (flg) { 115619bcc07fSBarry Smith Viewer tviewer; 115719bcc07fSBarry Smith ierr = ViewerFileOpenASCII(B->comm,"stdout",&tviewer);CHKERRQ(ierr); 115890ace30eSBarry Smith ierr = ViewerSetFormat(tviewer,ASCII_FORMAT_INFO_DETAILED,0);CHKERRQ(ierr); 115919bcc07fSBarry Smith ierr = MatView(B,tviewer); CHKERRQ(ierr); 116019bcc07fSBarry Smith ierr = ViewerDestroy(tviewer); CHKERRQ(ierr); 1161de6a44a3SBarry Smith } 1162de6a44a3SBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_view",&flg); CHKERRQ(ierr); 1163de6a44a3SBarry Smith if (flg) { 116419bcc07fSBarry Smith Viewer tviewer; 116519bcc07fSBarry Smith ierr = ViewerFileOpenASCII(B->comm,"stdout",&tviewer);CHKERRQ(ierr); 116619bcc07fSBarry Smith ierr = MatView(B,tviewer); CHKERRQ(ierr); 116719bcc07fSBarry Smith ierr = ViewerDestroy(tviewer); CHKERRQ(ierr); 1168de6a44a3SBarry Smith } 1169de6a44a3SBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_view_matlab",&flg); CHKERRQ(ierr); 1170de6a44a3SBarry Smith if (flg) { 117119bcc07fSBarry Smith Viewer tviewer; 117219bcc07fSBarry Smith ierr = ViewerFileOpenASCII(B->comm,"stdout",&tviewer);CHKERRQ(ierr); 117390ace30eSBarry Smith ierr = ViewerSetFormat(tviewer,ASCII_FORMAT_MATLAB,"M");CHKERRQ(ierr); 117419bcc07fSBarry Smith ierr = MatView(B,tviewer); CHKERRQ(ierr); 117519bcc07fSBarry Smith ierr = ViewerDestroy(tviewer); CHKERRQ(ierr); 1176de6a44a3SBarry Smith } 1177de6a44a3SBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_view_draw",&flg); CHKERRQ(ierr); 1178de6a44a3SBarry Smith if (flg) { 117919bcc07fSBarry Smith Viewer tviewer; 118019bcc07fSBarry Smith ierr = ViewerDrawOpenX(B->comm,0,0,0,0,300,300,&tviewer); CHKERRQ(ierr); 118119bcc07fSBarry Smith ierr = MatView(B,(Viewer)tviewer); CHKERRQ(ierr); 118219bcc07fSBarry Smith ierr = ViewerFlush(tviewer); CHKERRQ(ierr); 118319bcc07fSBarry Smith ierr = ViewerDestroy(tviewer); CHKERRQ(ierr); 1184de6a44a3SBarry Smith } 11852593348eSBarry Smith return 0; 11862593348eSBarry Smith } 11872593348eSBarry Smith 11882593348eSBarry Smith 11892593348eSBarry Smith 1190