1b6490206SBarry Smith 22593348eSBarry Smith #ifndef lint 3*7fc0212eSBarry Smith static char vcid[] = "$Id: baij.c,v 1.4 1996/02/17 05:41:27 bsmith Exp bsmith $"; 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 15b6490206SBarry Smith extern int MatToSymmetricIJ_SeqAIJ(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; 20de6a44a3SBarry Smith int ierr, *ia, *ja,n = a->mbs,*idx,i; 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 40de6a44a3SBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(n,a->i,a->j,0,&ia,&ja);CHKERRQ(ierr); 41de6a44a3SBarry Smith ierr = MatGetReordering_IJ(n,ia,ja,type,rperm,cperm); CHKERRQ(ierr); 422593348eSBarry Smith 432593348eSBarry Smith PetscFree(ia); PetscFree(ja); 442593348eSBarry Smith return 0; 452593348eSBarry Smith } 462593348eSBarry Smith 47de6a44a3SBarry Smith /* 48de6a44a3SBarry Smith Adds diagonal pointers to sparse matrix structure. 49de6a44a3SBarry Smith */ 50de6a44a3SBarry Smith 51de6a44a3SBarry Smith int MatMarkDiag_SeqBAIJ(Mat A) 52de6a44a3SBarry Smith { 53de6a44a3SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 54*7fc0212eSBarry Smith int i,j, *diag, m = a->mbs; 55de6a44a3SBarry Smith 56de6a44a3SBarry Smith diag = (int *) PetscMalloc( (m+1)*sizeof(int)); CHKPTRQ(diag); 57de6a44a3SBarry Smith PLogObjectMemory(A,(m+1)*sizeof(int)); 58*7fc0212eSBarry Smith for ( i=0; i<m; i++ ) { 59de6a44a3SBarry Smith for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 60de6a44a3SBarry Smith if (a->j[j] == i) { 61de6a44a3SBarry Smith diag[i] = j; 62de6a44a3SBarry Smith break; 63de6a44a3SBarry Smith } 64de6a44a3SBarry Smith } 65de6a44a3SBarry Smith } 66de6a44a3SBarry Smith a->diag = diag; 67de6a44a3SBarry Smith return 0; 68de6a44a3SBarry Smith } 692593348eSBarry Smith 702593348eSBarry Smith #include "draw.h" 712593348eSBarry Smith #include "pinclude/pviewer.h" 722593348eSBarry Smith #include "sysio.h" 732593348eSBarry Smith 74b6490206SBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,Viewer viewer) 752593348eSBarry Smith { 76b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 77b6490206SBarry Smith int i, fd, *col_lens, ierr, bs = a->bs,count,*jj,j,k,l; 78b6490206SBarry Smith Scalar *aa; 792593348eSBarry Smith 802593348eSBarry Smith ierr = ViewerFileGetDescriptor_Private(viewer,&fd); CHKERRQ(ierr); 812593348eSBarry Smith col_lens = (int *) PetscMalloc((4+a->m)*sizeof(int));CHKPTRQ(col_lens); 822593348eSBarry Smith col_lens[0] = MAT_COOKIE; 832593348eSBarry Smith col_lens[1] = a->m; 842593348eSBarry Smith col_lens[2] = a->n; 85b6490206SBarry Smith col_lens[3] = a->nz*bs*bs; 862593348eSBarry Smith 872593348eSBarry Smith /* store lengths of each row and write (including header) to file */ 88b6490206SBarry Smith count = 0; 89b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 90b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 91b6490206SBarry Smith col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]); 92b6490206SBarry Smith } 932593348eSBarry Smith } 942593348eSBarry Smith ierr = SYWrite(fd,col_lens,4+a->m,SYINT,1); CHKERRQ(ierr); 952593348eSBarry Smith PetscFree(col_lens); 962593348eSBarry Smith 972593348eSBarry Smith /* store column indices (zero start index) */ 98b6490206SBarry Smith jj = (int *) PetscMalloc( a->nz*bs*bs*sizeof(int) ); CHKPTRQ(jj); 99b6490206SBarry Smith count = 0; 100b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 101b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 102b6490206SBarry Smith for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 103b6490206SBarry Smith for ( l=0; l<bs; l++ ) { 104b6490206SBarry Smith jj[count++] = bs*a->j[k] + l; 1052593348eSBarry Smith } 1062593348eSBarry Smith } 107b6490206SBarry Smith } 108b6490206SBarry Smith } 109b6490206SBarry Smith ierr = SYWrite(fd,jj,bs*bs*a->nz,SYINT,0); CHKERRQ(ierr); 110b6490206SBarry Smith PetscFree(jj); 1112593348eSBarry Smith 1122593348eSBarry Smith /* store nonzero values */ 113b6490206SBarry Smith aa = (Scalar *) PetscMalloc(a->nz*bs*bs*sizeof(Scalar)); CHKPTRQ(aa); 114b6490206SBarry Smith count = 0; 115b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 116b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 117b6490206SBarry Smith for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 118b6490206SBarry Smith for ( l=0; l<bs; l++ ) { 119b6490206SBarry Smith aa[count++] = a->a[bs*bs*k + l*bs + j]; 120b6490206SBarry Smith } 121b6490206SBarry Smith } 122b6490206SBarry Smith } 123b6490206SBarry Smith } 124b6490206SBarry Smith ierr = SYWrite(fd,aa,bs*bs*a->nz,SYSCALAR,0); CHKERRQ(ierr); 125b6490206SBarry Smith PetscFree(aa); 1262593348eSBarry Smith return 0; 1272593348eSBarry Smith } 1282593348eSBarry Smith 129b6490206SBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,Viewer viewer) 1302593348eSBarry Smith { 131b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 132de6a44a3SBarry Smith int ierr, i,j,format,bs = a->bs,k,l; 1332593348eSBarry Smith FILE *fd; 1342593348eSBarry Smith char *outputname; 1352593348eSBarry Smith 1362593348eSBarry Smith ierr = ViewerFileGetPointer(viewer,&fd); CHKERRQ(ierr); 1372593348eSBarry Smith ierr = ViewerFileGetOutputname_Private(viewer,&outputname);CHKERRQ(ierr); 1382593348eSBarry Smith ierr = ViewerFileGetFormat_Private(viewer,&format); 1392593348eSBarry Smith if (format == FILE_FORMAT_INFO) { 1402593348eSBarry Smith /* no need to print additional information */ ; 1412593348eSBarry Smith } 1422593348eSBarry Smith else if (format == FILE_FORMAT_MATLAB) { 143b6490206SBarry Smith SETERRQ(1,"MatView_SeqBAIJ_ASCII:Matlab format not supported"); 1442593348eSBarry Smith } 1452593348eSBarry Smith else { 146b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 147b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 148b6490206SBarry Smith fprintf(fd,"row %d:",i*bs+j); 149b6490206SBarry Smith for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 150b6490206SBarry Smith for ( l=0; l<bs; l++ ) { 151de6a44a3SBarry Smith fprintf(fd," %d %g",bs*a->j[k]+l,a->a[bs*bs*k + l*bs + j]); 1522593348eSBarry Smith } 1532593348eSBarry Smith } 1542593348eSBarry Smith fprintf(fd,"\n"); 1552593348eSBarry Smith } 1562593348eSBarry Smith } 157b6490206SBarry Smith } 1582593348eSBarry Smith fflush(fd); 1592593348eSBarry Smith return 0; 1602593348eSBarry Smith } 1612593348eSBarry Smith 162b6490206SBarry Smith static int MatView_SeqBAIJ(PetscObject obj,Viewer viewer) 1632593348eSBarry Smith { 1642593348eSBarry Smith Mat A = (Mat) obj; 1652593348eSBarry Smith PetscObject vobj = (PetscObject) viewer; 1662593348eSBarry Smith 1672593348eSBarry Smith if (!viewer) { 1682593348eSBarry Smith viewer = STDOUT_VIEWER_SELF; vobj = (PetscObject) viewer; 1692593348eSBarry Smith } 1702593348eSBarry Smith if (vobj->cookie == VIEWER_COOKIE) { 1712593348eSBarry Smith if (vobj->type == MATLAB_VIEWER) { 172b6490206SBarry Smith SETERRQ(1,"MatView_SeqBAIJ:Matlab viewer not supported"); 1732593348eSBarry Smith } 1742593348eSBarry Smith else if (vobj->type == ASCII_FILE_VIEWER||vobj->type == ASCII_FILES_VIEWER){ 175b6490206SBarry Smith return MatView_SeqBAIJ_ASCII(A,viewer); 1762593348eSBarry Smith } 1772593348eSBarry Smith else if (vobj->type == BINARY_FILE_VIEWER) { 178b6490206SBarry Smith return MatView_SeqBAIJ_Binary(A,viewer); 1792593348eSBarry Smith } 1802593348eSBarry Smith } 1812593348eSBarry Smith else if (vobj->cookie == DRAW_COOKIE) { 1822593348eSBarry Smith if (vobj->type == NULLWINDOW) return 0; 183b6490206SBarry Smith SETERRQ(1,"MatView_SeqBAIJ:Draw viewer not supported"); 1842593348eSBarry Smith } 1852593348eSBarry Smith return 0; 1862593348eSBarry Smith } 187b6490206SBarry Smith 188b6490206SBarry Smith 189b6490206SBarry Smith static int MatZeroEntries_SeqBAIJ(Mat A) 1902593348eSBarry Smith { 191b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 192de6a44a3SBarry Smith PetscMemzero(a->a,a->bs*a->bs*a->i[a->mbs]*sizeof(Scalar)); 1932593348eSBarry Smith return 0; 1942593348eSBarry Smith } 1952593348eSBarry Smith 196b6490206SBarry Smith int MatDestroy_SeqBAIJ(PetscObject obj) 1972593348eSBarry Smith { 1982593348eSBarry Smith Mat A = (Mat) obj; 199b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 2002593348eSBarry Smith 2012593348eSBarry Smith #if defined(PETSC_LOG) 2022593348eSBarry Smith PLogObjectState(obj,"Rows=%d, Cols=%d, NZ=%d",a->m,a->n,a->nz); 2032593348eSBarry Smith #endif 2042593348eSBarry Smith PetscFree(a->a); 2052593348eSBarry Smith if (!a->singlemalloc) { PetscFree(a->i); PetscFree(a->j);} 2062593348eSBarry Smith if (a->diag) PetscFree(a->diag); 2072593348eSBarry Smith if (a->ilen) PetscFree(a->ilen); 2082593348eSBarry Smith if (a->imax) PetscFree(a->imax); 2092593348eSBarry Smith if (a->solve_work) PetscFree(a->solve_work); 210de6a44a3SBarry Smith if (a->mult_work) PetscFree(a->mult_work); 2112593348eSBarry Smith PetscFree(a); 2122593348eSBarry Smith PLogObjectDestroy(A); 2132593348eSBarry Smith PetscHeaderDestroy(A); 2142593348eSBarry Smith return 0; 2152593348eSBarry Smith } 2162593348eSBarry Smith 217b6490206SBarry Smith static int MatSetOption_SeqBAIJ(Mat A,MatOption op) 2182593348eSBarry Smith { 219b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 2202593348eSBarry Smith if (op == ROW_ORIENTED) a->roworiented = 1; 2212593348eSBarry Smith else if (op == COLUMN_ORIENTED) a->roworiented = 0; 2222593348eSBarry Smith else if (op == COLUMNS_SORTED) a->sorted = 1; 2232593348eSBarry Smith else if (op == NO_NEW_NONZERO_LOCATIONS) a->nonew = 1; 2242593348eSBarry Smith else if (op == YES_NEW_NONZERO_LOCATIONS) a->nonew = 0; 2252593348eSBarry Smith else if (op == ROWS_SORTED || 2262593348eSBarry Smith op == SYMMETRIC_MATRIX || 2272593348eSBarry Smith op == STRUCTURALLY_SYMMETRIC_MATRIX || 2282593348eSBarry Smith op == YES_NEW_DIAGONALS) 229b6490206SBarry Smith PLogInfo((PetscObject)A,"Info:MatSetOption_SeqBAIJ:Option ignored\n"); 2302593348eSBarry Smith else if (op == NO_NEW_DIAGONALS) 231b6490206SBarry Smith {SETERRQ(PETSC_ERR_SUP,"MatSetOption_SeqBAIJ:NO_NEW_DIAGONALS");} 2322593348eSBarry Smith else 233b6490206SBarry Smith {SETERRQ(PETSC_ERR_SUP,"MatSetOption_SeqBAIJ:unknown option");} 2342593348eSBarry Smith return 0; 2352593348eSBarry Smith } 2362593348eSBarry Smith 2372593348eSBarry Smith 2382593348eSBarry Smith /* -------------------------------------------------------*/ 2392593348eSBarry Smith /* Should check that shapes of vectors and matrices match */ 2402593348eSBarry Smith /* -------------------------------------------------------*/ 241b6490206SBarry Smith #include "pinclude/plapack.h" 242b6490206SBarry Smith 243b6490206SBarry Smith static int MatMult_SeqBAIJ(Mat A,Vec xx,Vec yy) 2442593348eSBarry Smith { 245b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 246b6490206SBarry Smith Scalar *xg,*yg; 247b6490206SBarry Smith register Scalar *x, *y, *v, sum,*xb, sum1,sum2,sum3,sum4,sum5; 248b6490206SBarry Smith register Scalar x1,x2,x3,x4,x5; 249b6490206SBarry Smith int mbs = a->mbs, m = a->m, i, *idx,*ii; 250b6490206SBarry Smith int bs = a->bs,j,n,bs2 = bs*bs; 2512593348eSBarry Smith 252b6490206SBarry Smith VecGetArray(xx,&xg); x = xg; VecGetArray(yy,&yg); y = yg; 253b6490206SBarry Smith PetscMemzero(y,m*sizeof(Scalar)); 254b6490206SBarry Smith x = x; 2552593348eSBarry Smith idx = a->j; 2562593348eSBarry Smith v = a->a; 2572593348eSBarry Smith ii = a->i; 258b6490206SBarry Smith 259b6490206SBarry Smith switch (bs) { 260b6490206SBarry Smith case 1: 2612593348eSBarry Smith for ( i=0; i<m; i++ ) { 2622593348eSBarry Smith n = ii[1] - ii[0]; ii++; 2632593348eSBarry Smith sum = 0.0; 2642593348eSBarry Smith while (n--) sum += *v++ * x[*idx++]; 2652593348eSBarry Smith y[i] = sum; 2662593348eSBarry Smith } 2672593348eSBarry Smith break; 268b6490206SBarry Smith case 2: 269b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 270de6a44a3SBarry Smith n = ii[1] - ii[0]; ii++; 271b6490206SBarry Smith sum1 = 0.0; sum2 = 0.0; 272b6490206SBarry Smith for ( j=0; j<n; j++ ) { 273b6490206SBarry Smith xb = x + 2*(*idx++); x1 = xb[0]; x2 = xb[1]; 274b6490206SBarry Smith sum1 += v[0]*x1 + v[2]*x2; 275b6490206SBarry Smith sum2 += v[1]*x1 + v[3]*x2; 276b6490206SBarry Smith v += 4; 277b6490206SBarry Smith } 278b6490206SBarry Smith y[0] += sum1; y[1] += sum2; 279b6490206SBarry Smith y += 2; 280b6490206SBarry Smith } 281b6490206SBarry Smith break; 282b6490206SBarry Smith case 3: 283b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 284de6a44a3SBarry Smith n = ii[1] - ii[0]; ii++; 285b6490206SBarry Smith sum1 = 0.0; sum2 = 0.0; sum3 = 0.0; 286b6490206SBarry Smith for ( j=0; j<n; j++ ) { 287b6490206SBarry Smith xb = x + 3*(*idx++); x1 = xb[0]; x2 = xb[1]; x3 = xb[2]; 288b6490206SBarry Smith sum1 += v[0]*x1 + v[3]*x2 + v[6]*x3; 289b6490206SBarry Smith sum2 += v[1]*x1 + v[4]*x2 + v[7]*x3; 290b6490206SBarry Smith sum3 += v[2]*x1 + v[5]*x2 + v[8]*x3; 291b6490206SBarry Smith v += 9; 292b6490206SBarry Smith } 293b6490206SBarry Smith y[0] += sum1; y[1] += sum2; y[2] += sum3; 294b6490206SBarry Smith y += 3; 295b6490206SBarry Smith } 296b6490206SBarry Smith break; 297b6490206SBarry Smith case 4: 298b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 299de6a44a3SBarry Smith n = ii[1] - ii[0]; ii++; 300b6490206SBarry Smith sum1 = 0.0; sum2 = 0.0; sum3 = 0.0; sum4 = 0.0; 301b6490206SBarry Smith for ( j=0; j<n; j++ ) { 302b6490206SBarry Smith xb = x + 4*(*idx++); 303b6490206SBarry Smith x1 = xb[0]; x2 = xb[1]; x3 = xb[2]; x4 = xb[3]; 304b6490206SBarry Smith sum1 += v[0]*x1 + v[4]*x2 + v[8]*x3 + v[12]*x4; 305b6490206SBarry Smith sum2 += v[1]*x1 + v[5]*x2 + v[9]*x3 + v[13]*x4; 306b6490206SBarry Smith sum3 += v[2]*x1 + v[6]*x2 + v[10]*x3 + v[14]*x4; 307b6490206SBarry Smith sum4 += v[3]*x1 + v[7]*x2 + v[11]*x3 + v[15]*x4; 308b6490206SBarry Smith v += 16; 309b6490206SBarry Smith } 310b6490206SBarry Smith y[0] += sum1; y[1] += sum2; y[2] += sum3; y[3] += sum4; 311b6490206SBarry Smith y += 4; 312b6490206SBarry Smith } 313b6490206SBarry Smith break; 314b6490206SBarry Smith case 5: 315b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 316de6a44a3SBarry Smith n = ii[1] - ii[0]; ii++; 317b6490206SBarry Smith sum1 = 0.0; sum2 = 0.0; sum3 = 0.0; sum4 = 0.0; sum5 = 0.0; 318b6490206SBarry Smith for ( j=0; j<n; j++ ) { 319b6490206SBarry Smith xb = x + 5*(*idx++); 320b6490206SBarry Smith x1 = xb[0]; x2 = xb[1]; x3 = xb[2]; x4 = xb[3]; x5 = xb[4]; 321b6490206SBarry Smith sum1 += v[0]*x1 + v[5]*x2 + v[10]*x3 + v[15]*x4 + v[20]*x5; 322b6490206SBarry Smith sum2 += v[1]*x1 + v[6]*x2 + v[11]*x3 + v[16]*x4 + v[21]*x5; 323b6490206SBarry Smith sum3 += v[2]*x1 + v[7]*x2 + v[12]*x3 + v[17]*x4 + v[22]*x5; 324b6490206SBarry Smith sum4 += v[3]*x1 + v[8]*x2 + v[13]*x3 + v[18]*x4 + v[23]*x5; 325b6490206SBarry Smith sum5 += v[4]*x1 + v[9]*x2 + v[14]*x3 + v[19]*x4 + v[24]*x5; 326b6490206SBarry Smith v += 25; 327b6490206SBarry Smith } 328b6490206SBarry Smith y[0] += sum1; y[1] += sum2; y[2] += sum3; y[3] += sum4; y[4] += sum5; 329b6490206SBarry Smith y += 5; 330b6490206SBarry Smith } 331b6490206SBarry Smith break; 332b6490206SBarry Smith /* block sizes larger then 5 by 5 are handled by BLAS */ 333b6490206SBarry Smith default: { 334de6a44a3SBarry Smith int _One = 1,ncols,k; Scalar _DOne = 1.0, *work,*workt; 335de6a44a3SBarry Smith if (!a->mult_work) { 336de6a44a3SBarry Smith a->mult_work = (Scalar *) PetscMalloc(a->m*sizeof(Scalar)); 337de6a44a3SBarry Smith CHKPTRQ(a->mult_work); 338de6a44a3SBarry Smith } 339de6a44a3SBarry Smith work = a->mult_work; 340b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 341de6a44a3SBarry Smith n = ii[1] - ii[0]; ii++; 342de6a44a3SBarry Smith ncols = n*bs; 343de6a44a3SBarry Smith workt = work; 344b6490206SBarry Smith for ( j=0; j<n; j++ ) { 345b6490206SBarry Smith xb = x + bs*(*idx++); 346de6a44a3SBarry Smith for ( k=0; k<bs; k++ ) workt[k] = xb[k]; 347de6a44a3SBarry Smith workt += bs; 348b6490206SBarry Smith } 349de6a44a3SBarry Smith LAgemv_("N",&bs,&ncols,&_DOne,v,&bs,work,&_One,&_DOne,y,&_One); 350de6a44a3SBarry Smith v += n*bs2; 351b6490206SBarry Smith y += bs; 3522593348eSBarry Smith } 3532593348eSBarry Smith } 3542593348eSBarry Smith } 355b6490206SBarry Smith PLogFlops(2*bs2*a->nz - m); 3562593348eSBarry Smith return 0; 3572593348eSBarry Smith } 3582593348eSBarry Smith 359de6a44a3SBarry Smith static int MatGetInfo_SeqBAIJ(Mat A,MatInfoType flag,int *nz,int *nza,int *mem) 3602593348eSBarry Smith { 361b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 36235aab85fSBarry Smith *nz = a->bs*a->bs*a->nz; 363de6a44a3SBarry Smith *nza = a->maxnz; 3642593348eSBarry Smith *mem = (int)A->mem; 3652593348eSBarry Smith return 0; 3662593348eSBarry Smith } 3672593348eSBarry Smith 368b6490206SBarry Smith extern int MatLUFactorSymbolic_SeqBAIJ(Mat,IS,IS,double,Mat*); 369b6490206SBarry Smith extern int MatLUFactor_SeqBAIJ(Mat,IS,IS,double); 370b6490206SBarry Smith extern int MatSolve_SeqBAIJ(Mat,Vec,Vec); 371*7fc0212eSBarry Smith extern int MatLUFactorNumeric_SeqBAIJ_N(Mat,Mat*); 372*7fc0212eSBarry Smith extern int MatLUFactorNumeric_SeqBAIJ_1(Mat,Mat*); 373*7fc0212eSBarry Smith extern int MatLUFactorNumeric_SeqBAIJ_2(Mat,Mat*); 374*7fc0212eSBarry Smith extern int MatLUFactorNumeric_SeqBAIJ_3(Mat,Mat*); 375*7fc0212eSBarry Smith extern int MatLUFactorNumeric_SeqBAIJ_4(Mat,Mat*); 376*7fc0212eSBarry Smith extern int MatLUFactorNumeric_SeqBAIJ_5(Mat,Mat*); 3772593348eSBarry Smith 378b6490206SBarry Smith static int MatGetSize_SeqBAIJ(Mat A,int *m,int *n) 3792593348eSBarry Smith { 380b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 3812593348eSBarry Smith *m = a->m; *n = a->n; 3822593348eSBarry Smith return 0; 3832593348eSBarry Smith } 3842593348eSBarry Smith 385b6490206SBarry Smith static int MatGetOwnershipRange_SeqBAIJ(Mat A,int *m,int *n) 3862593348eSBarry Smith { 387b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 3882593348eSBarry Smith *m = 0; *n = a->m; 3892593348eSBarry Smith return 0; 3902593348eSBarry Smith } 391b6490206SBarry Smith 392b6490206SBarry Smith static int MatNorm_SeqBAIJ(Mat A,NormType type,double *norm) 3932593348eSBarry Smith { 394b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 3952593348eSBarry Smith Scalar *v = a->a; 3962593348eSBarry Smith double sum = 0.0; 397b6490206SBarry Smith int i; 3982593348eSBarry Smith 3992593348eSBarry Smith if (type == NORM_FROBENIUS) { 4002593348eSBarry Smith for (i=0; i<a->nz; i++ ) { 4012593348eSBarry Smith #if defined(PETSC_COMPLEX) 4022593348eSBarry Smith sum += real(conj(*v)*(*v)); v++; 4032593348eSBarry Smith #else 4042593348eSBarry Smith sum += (*v)*(*v); v++; 4052593348eSBarry Smith #endif 4062593348eSBarry Smith } 4072593348eSBarry Smith *norm = sqrt(sum); 4082593348eSBarry Smith } 4092593348eSBarry Smith else { 410b6490206SBarry Smith SETERRQ(1,"MatNorm_SeqBAIJ:No support for this norm yet"); 4112593348eSBarry Smith } 4122593348eSBarry Smith return 0; 4132593348eSBarry Smith } 4142593348eSBarry Smith 4152593348eSBarry Smith /* 4162593348eSBarry Smith note: This can only work for identity for row and col. It would 4172593348eSBarry Smith be good to check this and otherwise generate an error. 4182593348eSBarry Smith */ 419b6490206SBarry Smith static int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,double efill,int fill) 4202593348eSBarry Smith { 421b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) inA->data; 4222593348eSBarry Smith Mat outA; 423de6a44a3SBarry Smith int ierr; 4242593348eSBarry Smith 425b6490206SBarry Smith if (fill != 0) SETERRQ(1,"MatILUFactor_SeqBAIJ:Only fill=0 supported"); 4262593348eSBarry Smith 4272593348eSBarry Smith outA = inA; 4282593348eSBarry Smith inA->factor = FACTOR_LU; 4292593348eSBarry Smith a->row = row; 4302593348eSBarry Smith a->col = col; 4312593348eSBarry Smith 432de6a44a3SBarry Smith a->solve_work = (Scalar *) PetscMalloc((a->m+a->bs)*sizeof(Scalar));CHKPTRQ(a->solve_work); 4332593348eSBarry Smith 4342593348eSBarry Smith if (!a->diag) { 435b6490206SBarry Smith ierr = MatMarkDiag_SeqBAIJ(inA); CHKERRQ(ierr); 4362593348eSBarry Smith } 437*7fc0212eSBarry Smith ierr = MatLUFactorNumeric(inA,&outA); CHKERRQ(ierr); 4382593348eSBarry Smith return 0; 4392593348eSBarry Smith } 4402593348eSBarry Smith 441b6490206SBarry Smith static int MatScale_SeqBAIJ(Scalar *alpha,Mat inA) 4422593348eSBarry Smith { 443b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) inA->data; 444b6490206SBarry Smith int one = 1, totalnz = a->bs*a->bs*a->nz; 445b6490206SBarry Smith BLscal_( &totalnz, alpha, a->a, &one ); 446b6490206SBarry Smith PLogFlops(totalnz); 4472593348eSBarry Smith return 0; 4482593348eSBarry Smith } 4492593348eSBarry Smith 450b6490206SBarry Smith int MatPrintHelp_SeqBAIJ(Mat A) 4512593348eSBarry Smith { 4522593348eSBarry Smith static int called = 0; 4532593348eSBarry Smith 4542593348eSBarry Smith if (called) return 0; else called = 1; 4552593348eSBarry Smith return 0; 4562593348eSBarry Smith } 4572593348eSBarry Smith /* -------------------------------------------------------------------*/ 458b6490206SBarry Smith static struct _MatOps MatOps = {0, 459b6490206SBarry Smith 0,0, 460b6490206SBarry Smith MatMult_SeqBAIJ,0, 461b6490206SBarry Smith 0,0, 462de6a44a3SBarry Smith MatSolve_SeqBAIJ,0, 463b6490206SBarry Smith 0,0, 464de6a44a3SBarry Smith MatLUFactor_SeqBAIJ,0, 465b6490206SBarry Smith 0, 466b6490206SBarry Smith 0, 467b6490206SBarry Smith MatGetInfo_SeqBAIJ,0, 468b6490206SBarry Smith 0,0,MatNorm_SeqBAIJ, 469b6490206SBarry Smith 0,0, 470b6490206SBarry Smith 0, 471b6490206SBarry Smith MatSetOption_SeqBAIJ,MatZeroEntries_SeqBAIJ,0, 472b6490206SBarry Smith MatGetReordering_SeqBAIJ, 473*7fc0212eSBarry Smith MatLUFactorSymbolic_SeqBAIJ,MatLUFactorNumeric_SeqBAIJ_N,0,0, 474b6490206SBarry Smith MatGetSize_SeqBAIJ,MatGetSize_SeqBAIJ,MatGetOwnershipRange_SeqBAIJ, 475de6a44a3SBarry Smith MatILUFactorSymbolic_SeqBAIJ,0, 476b6490206SBarry Smith 0,0,/*MatConvert_SeqBAIJ*/ 0, 477b6490206SBarry Smith 0,0, 478b6490206SBarry Smith MatConvertSameType_SeqBAIJ,0,0, 479b6490206SBarry Smith MatILUFactor_SeqBAIJ,0,0, 480b6490206SBarry Smith 0,0, 481b6490206SBarry Smith 0,0, 482b6490206SBarry Smith MatPrintHelp_SeqBAIJ,MatScale_SeqBAIJ, 483b6490206SBarry Smith 0}; 4842593348eSBarry Smith 4852593348eSBarry Smith /*@C 486b6490206SBarry Smith MatCreateSeqBAIJ - Creates a sparse matrix in AIJ (compressed row) format 4872593348eSBarry Smith (the default parallel PETSc format). For good matrix assembly performance 4882593348eSBarry Smith the user should preallocate the matrix storage by setting the parameter nz 4892593348eSBarry Smith (or nzz). By setting these parameters accurately, performance can be 4902593348eSBarry Smith increased by more than a factor of 50. 4912593348eSBarry Smith 4922593348eSBarry Smith Input Parameters: 4932593348eSBarry Smith . comm - MPI communicator, set to MPI_COMM_SELF 494b6490206SBarry Smith . bs - size of block 4952593348eSBarry Smith . m - number of rows 4962593348eSBarry Smith . n - number of columns 497b6490206SBarry Smith . nz - number of block nonzeros per block row (same for all rows) 498b6490206SBarry Smith . nzz - number of block nonzeros per block row or PETSC_NULL 499b6490206SBarry Smith (possibly different for each row) 5002593348eSBarry Smith 5012593348eSBarry Smith Output Parameter: 5022593348eSBarry Smith . A - the matrix 5032593348eSBarry Smith 5042593348eSBarry Smith Notes: 505b6490206SBarry Smith The BAIJ format, is fully compatible with standard Fortran 77 5062593348eSBarry Smith storage. That is, the stored row and column indices can begin at 5072593348eSBarry Smith either one (as in Fortran) or zero. See the users manual for details. 5082593348eSBarry Smith 5092593348eSBarry Smith Specify the preallocated storage with either nz or nnz (not both). 5102593348eSBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 5112593348eSBarry Smith allocation. For additional details, see the users manual chapter on 5122593348eSBarry Smith matrices and the file $(PETSC_DIR)/Performance. 5132593348eSBarry Smith 5142593348eSBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues() 5152593348eSBarry Smith @*/ 516b6490206SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz, Mat *A) 5172593348eSBarry Smith { 5182593348eSBarry Smith Mat B; 519b6490206SBarry Smith Mat_SeqBAIJ *b; 520b6490206SBarry Smith int i,len,ierr, flg,mbs = m/bs; 521b6490206SBarry Smith 522b6490206SBarry Smith if (mbs*bs != m) 523b6490206SBarry Smith SETERRQ(1,"MatCreateSeqBAIJ:Number rows must be divisible by blocksize"); 5242593348eSBarry Smith 5252593348eSBarry Smith *A = 0; 526b6490206SBarry Smith PetscHeaderCreate(B,_Mat,MAT_COOKIE,MATSEQBAIJ,comm); 5272593348eSBarry Smith PLogObjectCreate(B); 528b6490206SBarry Smith B->data = (void *) (b = PetscNew(Mat_SeqBAIJ)); CHKPTRQ(b); 5292593348eSBarry Smith PetscMemcpy(&B->ops,&MatOps,sizeof(struct _MatOps)); 530*7fc0212eSBarry Smith switch (bs) { 531*7fc0212eSBarry Smith case 1: 532*7fc0212eSBarry Smith B->ops.lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1; 533*7fc0212eSBarry Smith break; 534*7fc0212eSBarry Smith } 535b6490206SBarry Smith B->destroy = MatDestroy_SeqBAIJ; 536b6490206SBarry Smith B->view = MatView_SeqBAIJ; 5372593348eSBarry Smith B->factor = 0; 5382593348eSBarry Smith B->lupivotthreshold = 1.0; 5392593348eSBarry Smith b->row = 0; 5402593348eSBarry Smith b->col = 0; 5412593348eSBarry Smith b->reallocs = 0; 5422593348eSBarry Smith 5432593348eSBarry Smith b->m = m; 544b6490206SBarry Smith b->mbs = mbs; 5452593348eSBarry Smith b->n = n; 546b6490206SBarry Smith b->imax = (int *) PetscMalloc( (mbs+1)*sizeof(int) ); CHKPTRQ(b->imax); 5472593348eSBarry Smith if (nnz == PETSC_NULL) { 548de6a44a3SBarry Smith if (nz == PETSC_DEFAULT) nz = 5; 5492593348eSBarry Smith else if (nz <= 0) nz = 1; 550b6490206SBarry Smith for ( i=0; i<mbs; i++ ) b->imax[i] = nz; 551b6490206SBarry Smith nz = nz*mbs; 5522593348eSBarry Smith } 5532593348eSBarry Smith else { 5542593348eSBarry Smith nz = 0; 555b6490206SBarry Smith for ( i=0; i<mbs; i++ ) {b->imax[i] = nnz[i]; nz += nnz[i];} 5562593348eSBarry Smith } 5572593348eSBarry Smith 5582593348eSBarry Smith /* allocate the matrix space */ 559b6490206SBarry Smith len = nz*sizeof(int) + nz*bs*bs*sizeof(Scalar) + (b->m+1)*sizeof(int); 5602593348eSBarry Smith b->a = (Scalar *) PetscMalloc( len ); CHKPTRQ(b->a); 561b6490206SBarry Smith PetscMemzero(b->a,nz*bs*bs*sizeof(Scalar)); 562b6490206SBarry Smith b->j = (int *) (b->a + nz*bs*bs); 5632593348eSBarry Smith PetscMemzero(b->j,nz*sizeof(int)); 5642593348eSBarry Smith b->i = b->j + nz; 5652593348eSBarry Smith b->singlemalloc = 1; 5662593348eSBarry Smith 567de6a44a3SBarry Smith b->i[0] = 0; 568b6490206SBarry Smith for (i=1; i<mbs+1; i++) { 5692593348eSBarry Smith b->i[i] = b->i[i-1] + b->imax[i-1]; 5702593348eSBarry Smith } 5712593348eSBarry Smith 572b6490206SBarry Smith /* b->ilen will count nonzeros in each block row so far. */ 573b6490206SBarry Smith b->ilen = (int *) PetscMalloc((mbs+1)*sizeof(int)); 574b6490206SBarry Smith PLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _Mat)+sizeof(Mat_SeqBAIJ)); 575b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { b->ilen[i] = 0;} 5762593348eSBarry Smith 577b6490206SBarry Smith b->bs = bs; 578b6490206SBarry Smith b->mbs = mbs; 5792593348eSBarry Smith b->nz = 0; 5802593348eSBarry Smith b->maxnz = nz; 5812593348eSBarry Smith b->sorted = 0; 5822593348eSBarry Smith b->roworiented = 1; 5832593348eSBarry Smith b->nonew = 0; 5842593348eSBarry Smith b->diag = 0; 5852593348eSBarry Smith b->solve_work = 0; 586de6a44a3SBarry Smith b->mult_work = 0; 5872593348eSBarry Smith b->spptr = 0; 5882593348eSBarry Smith 5892593348eSBarry Smith *A = B; 5902593348eSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr); 5912593348eSBarry Smith if (flg) {ierr = MatPrintHelp(B); CHKERRQ(ierr); } 5922593348eSBarry Smith return 0; 5932593348eSBarry Smith } 5942593348eSBarry Smith 595b6490206SBarry Smith int MatConvertSameType_SeqBAIJ(Mat A,Mat *B,int cpvalues) 5962593348eSBarry Smith { 5972593348eSBarry Smith Mat C; 598b6490206SBarry Smith Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ *) A->data; 599de6a44a3SBarry Smith int i,len, mbs = a->mbs, bs = a->bs,nz = a->nz; 600de6a44a3SBarry Smith 601de6a44a3SBarry Smith if (a->i[mbs] != nz) SETERRQ(1,"MatConvertSameType_SeqBAIJ:Corrupt matrix"); 6022593348eSBarry Smith 6032593348eSBarry Smith *B = 0; 604b6490206SBarry Smith PetscHeaderCreate(C,_Mat,MAT_COOKIE,MATSEQBAIJ,A->comm); 6052593348eSBarry Smith PLogObjectCreate(C); 606b6490206SBarry Smith C->data = (void *) (c = PetscNew(Mat_SeqBAIJ)); CHKPTRQ(c); 6072593348eSBarry Smith PetscMemcpy(&C->ops,&A->ops,sizeof(struct _MatOps)); 608b6490206SBarry Smith C->destroy = MatDestroy_SeqBAIJ; 609b6490206SBarry Smith C->view = MatView_SeqBAIJ; 6102593348eSBarry Smith C->factor = A->factor; 6112593348eSBarry Smith c->row = 0; 6122593348eSBarry Smith c->col = 0; 6132593348eSBarry Smith C->assembled = PETSC_TRUE; 6142593348eSBarry Smith 6152593348eSBarry Smith c->m = a->m; 6162593348eSBarry Smith c->n = a->n; 617b6490206SBarry Smith c->bs = a->bs; 618b6490206SBarry Smith c->mbs = a->mbs; 619b6490206SBarry Smith c->nbs = a->nbs; 6202593348eSBarry Smith 621b6490206SBarry Smith c->imax = (int *) PetscMalloc((mbs+1)*sizeof(int)); CHKPTRQ(c->imax); 622b6490206SBarry Smith c->ilen = (int *) PetscMalloc((mbs+1)*sizeof(int)); CHKPTRQ(c->ilen); 623b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 6242593348eSBarry Smith c->imax[i] = a->imax[i]; 6252593348eSBarry Smith c->ilen[i] = a->ilen[i]; 6262593348eSBarry Smith } 6272593348eSBarry Smith 6282593348eSBarry Smith /* allocate the matrix space */ 6292593348eSBarry Smith c->singlemalloc = 1; 630de6a44a3SBarry Smith len = (mbs+1)*sizeof(int) + nz*(bs*bs*sizeof(Scalar) + sizeof(int)); 6312593348eSBarry Smith c->a = (Scalar *) PetscMalloc( len ); CHKPTRQ(c->a); 632de6a44a3SBarry Smith c->j = (int *) (c->a + nz*bs*bs); 633de6a44a3SBarry Smith c->i = c->j + nz; 634b6490206SBarry Smith PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int)); 635b6490206SBarry Smith if (mbs > 0) { 636de6a44a3SBarry Smith PetscMemcpy(c->j,a->j,nz*sizeof(int)); 6372593348eSBarry Smith if (cpvalues == COPY_VALUES) { 638de6a44a3SBarry Smith PetscMemcpy(c->a,a->a,bs*bs*nz*sizeof(Scalar)); 6392593348eSBarry Smith } 6402593348eSBarry Smith } 6412593348eSBarry Smith 642b6490206SBarry Smith PLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _Mat)+sizeof(Mat_SeqBAIJ)); 6432593348eSBarry Smith c->sorted = a->sorted; 6442593348eSBarry Smith c->roworiented = a->roworiented; 6452593348eSBarry Smith c->nonew = a->nonew; 6462593348eSBarry Smith 6472593348eSBarry Smith if (a->diag) { 648b6490206SBarry Smith c->diag = (int *) PetscMalloc( (mbs+1)*sizeof(int) ); CHKPTRQ(c->diag); 649b6490206SBarry Smith PLogObjectMemory(C,(mbs+1)*sizeof(int)); 650b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 6512593348eSBarry Smith c->diag[i] = a->diag[i]; 6522593348eSBarry Smith } 6532593348eSBarry Smith } 6542593348eSBarry Smith else c->diag = 0; 6552593348eSBarry Smith c->nz = a->nz; 6562593348eSBarry Smith c->maxnz = a->maxnz; 6572593348eSBarry Smith c->solve_work = 0; 6582593348eSBarry Smith c->spptr = 0; /* Dangerous -I'm throwing away a->spptr */ 659*7fc0212eSBarry Smith c->mult_work = 0; 6602593348eSBarry Smith *B = C; 6612593348eSBarry Smith return 0; 6622593348eSBarry Smith } 6632593348eSBarry Smith 664b6490206SBarry Smith int MatLoad_SeqBAIJ(Viewer bview,MatType type,Mat *A) 6652593348eSBarry Smith { 666b6490206SBarry Smith Mat_SeqBAIJ *a; 6672593348eSBarry Smith Mat B; 668de6a44a3SBarry Smith int i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1,flg; 669b6490206SBarry Smith int *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount; 67035aab85fSBarry Smith int kmax,jcount,block,idx,point,nzcountb,extra_rows; 671de6a44a3SBarry Smith int *masked, nmask,tmp,ishift,bs2; 672b6490206SBarry Smith Scalar *aa; 6732593348eSBarry Smith PetscObject vobj = (PetscObject) bview; 6742593348eSBarry Smith MPI_Comm comm = vobj->comm; 6752593348eSBarry Smith 67635aab85fSBarry Smith ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&bs,&flg);CHKERRQ(ierr); 677de6a44a3SBarry Smith bs2 = bs*bs; 678b6490206SBarry Smith 6792593348eSBarry Smith MPI_Comm_size(comm,&size); 680b6490206SBarry Smith if (size > 1) SETERRQ(1,"MatLoad_SeqBAIJ:view must have one processor"); 6812593348eSBarry Smith ierr = ViewerFileGetDescriptor_Private(bview,&fd); CHKERRQ(ierr); 6822593348eSBarry Smith ierr = SYRead(fd,header,4,SYINT); CHKERRQ(ierr); 683de6a44a3SBarry Smith if (header[0] != MAT_COOKIE) SETERRQ(1,"MatLoad_SeqBAIJ:not Mat object"); 6842593348eSBarry Smith M = header[1]; N = header[2]; nz = header[3]; 6852593348eSBarry Smith 686b6490206SBarry Smith if (M != N) SETERRQ(1,"MatLoad_SeqBAIJ:Can only do square matrices"); 68735aab85fSBarry Smith 68835aab85fSBarry Smith /* 68935aab85fSBarry Smith This code adds extra rows to make sure the number of rows is 69035aab85fSBarry Smith divisible by the blocksize 69135aab85fSBarry Smith */ 692b6490206SBarry Smith mbs = M/bs; 69335aab85fSBarry Smith extra_rows = bs - M + bs*(mbs); 69435aab85fSBarry Smith if (extra_rows == bs) extra_rows = 0; 69535aab85fSBarry Smith else mbs++; 69635aab85fSBarry Smith if (extra_rows) { 69735aab85fSBarry Smith PLogInfo(0,"MatLoad_SeqBAIJ:Padding loading matrix to match blocksize"); 69835aab85fSBarry Smith } 699b6490206SBarry Smith 7002593348eSBarry Smith /* read in row lengths */ 70135aab85fSBarry Smith rowlengths = (int*) PetscMalloc((M+extra_rows)*sizeof(int));CHKPTRQ(rowlengths); 7022593348eSBarry Smith ierr = SYRead(fd,rowlengths,M,SYINT); CHKERRQ(ierr); 70335aab85fSBarry Smith for ( i=0; i<extra_rows; i++ ) rowlengths[M+i] = 1; 7042593348eSBarry Smith 705b6490206SBarry Smith /* read in column indices */ 70635aab85fSBarry Smith jj = (int*) PetscMalloc( (nz+extra_rows)*sizeof(int) ); CHKPTRQ(jj); 707b6490206SBarry Smith ierr = SYRead(fd,jj,nz,SYINT); CHKERRQ(ierr); 70835aab85fSBarry Smith for ( i=0; i<extra_rows; i++ ) jj[nz+i] = M+i; 709b6490206SBarry Smith 710b6490206SBarry Smith /* loop over row lengths determining block row lengths */ 711b6490206SBarry Smith browlengths = (int *) PetscMalloc(mbs*sizeof(int));CHKPTRQ(browlengths); 712b6490206SBarry Smith PetscMemzero(browlengths,mbs*sizeof(int)); 71335aab85fSBarry Smith mask = (int *) PetscMalloc( 2*mbs*sizeof(int) ); CHKPTRQ(mask); 71435aab85fSBarry Smith PetscMemzero(mask,mbs*sizeof(int)); 71535aab85fSBarry Smith masked = mask + mbs; 716b6490206SBarry Smith rowcount = 0; nzcount = 0; 717b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 71835aab85fSBarry Smith nmask = 0; 719b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 720b6490206SBarry Smith kmax = rowlengths[rowcount]; 721b6490206SBarry Smith for ( k=0; k<kmax; k++ ) { 72235aab85fSBarry Smith tmp = jj[nzcount++]/bs; 72335aab85fSBarry Smith if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;} 724b6490206SBarry Smith } 725b6490206SBarry Smith rowcount++; 726b6490206SBarry Smith } 72735aab85fSBarry Smith browlengths[i] += nmask; 72835aab85fSBarry Smith /* zero out the mask elements we set */ 72935aab85fSBarry Smith for ( j=0; j<nmask; j++ ) mask[masked[j]] = 0; 730b6490206SBarry Smith } 731b6490206SBarry Smith 7322593348eSBarry Smith /* create our matrix */ 73335aab85fSBarry Smith ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A); 73435aab85fSBarry Smith CHKERRQ(ierr); 7352593348eSBarry Smith B = *A; 736b6490206SBarry Smith a = (Mat_SeqBAIJ *) B->data; 7372593348eSBarry Smith 7382593348eSBarry Smith /* set matrix "i" values */ 739de6a44a3SBarry Smith a->i[0] = 0; 740b6490206SBarry Smith for ( i=1; i<= mbs; i++ ) { 741b6490206SBarry Smith a->i[i] = a->i[i-1] + browlengths[i-1]; 742b6490206SBarry Smith a->ilen[i-1] = browlengths[i-1]; 7432593348eSBarry Smith } 744b6490206SBarry Smith a->nz = 0; 745b6490206SBarry Smith for ( i=0; i<mbs; i++ ) a->nz += browlengths[i]; 7462593348eSBarry Smith 747b6490206SBarry Smith /* read in nonzero values */ 74835aab85fSBarry Smith aa = (Scalar *) PetscMalloc((nz+extra_rows)*sizeof(Scalar));CHKPTRQ(aa); 749b6490206SBarry Smith ierr = SYRead(fd,aa,nz,SYSCALAR); CHKERRQ(ierr); 75035aab85fSBarry Smith for ( i=0; i<extra_rows; i++ ) aa[nz+i] = 1.0; 751b6490206SBarry Smith 752b6490206SBarry Smith /* set "a" and "j" values into matrix */ 753b6490206SBarry Smith nzcount = 0; jcount = 0; 754b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 755b6490206SBarry Smith nzcountb = nzcount; 75635aab85fSBarry Smith nmask = 0; 757b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 758b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 759b6490206SBarry Smith for ( k=0; k<kmax; k++ ) { 76035aab85fSBarry Smith tmp = jj[nzcount++]/bs; 76135aab85fSBarry Smith if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;} 762b6490206SBarry Smith } 763b6490206SBarry Smith rowcount++; 764b6490206SBarry Smith } 765de6a44a3SBarry Smith /* sort the masked values */ 766de6a44a3SBarry Smith SYIsort(nmask,masked); 767de6a44a3SBarry Smith 768b6490206SBarry Smith /* set "j" values into matrix */ 769b6490206SBarry Smith maskcount = 1; 77035aab85fSBarry Smith for ( j=0; j<nmask; j++ ) { 77135aab85fSBarry Smith a->j[jcount++] = masked[j]; 772de6a44a3SBarry Smith mask[masked[j]] = maskcount++; 773b6490206SBarry Smith } 774b6490206SBarry Smith /* set "a" values into matrix */ 775de6a44a3SBarry Smith ishift = bs2*a->i[i]; 776b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 777b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 778b6490206SBarry Smith for ( k=0; k<kmax; k++ ) { 779de6a44a3SBarry Smith tmp = jj[nzcountb]/bs ; 780de6a44a3SBarry Smith block = mask[tmp] - 1; 781de6a44a3SBarry Smith point = jj[nzcountb] - bs*tmp; 782de6a44a3SBarry Smith idx = ishift + bs2*block + j + bs*point; 783b6490206SBarry Smith a->a[idx] = aa[nzcountb++]; 784b6490206SBarry Smith } 785b6490206SBarry Smith } 78635aab85fSBarry Smith /* zero out the mask elements we set */ 78735aab85fSBarry Smith for ( j=0; j<nmask; j++ ) mask[masked[j]] = 0; 788b6490206SBarry Smith } 78935aab85fSBarry Smith if (jcount != a->nz) SETERRQ(1,"MatLoad_SeqBAIJ:Error bad binary matrix"); 790b6490206SBarry Smith 791b6490206SBarry Smith PetscFree(rowlengths); 792b6490206SBarry Smith PetscFree(browlengths); 793b6490206SBarry Smith PetscFree(aa); 794b6490206SBarry Smith PetscFree(jj); 795b6490206SBarry Smith PetscFree(mask); 796b6490206SBarry Smith 797b6490206SBarry Smith B->assembled = PETSC_TRUE; 798de6a44a3SBarry Smith 799de6a44a3SBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_view_info",&flg); CHKERRQ(ierr); 800de6a44a3SBarry Smith if (flg) { 801de6a44a3SBarry Smith Viewer viewer; 802de6a44a3SBarry Smith ierr = ViewerFileOpenASCII(B->comm,"stdout",&viewer);CHKERRQ(ierr); 803de6a44a3SBarry Smith ierr = ViewerFileSetFormat(viewer,FILE_FORMAT_INFO,0);CHKERRQ(ierr); 804de6a44a3SBarry Smith ierr = MatView(B,viewer); CHKERRQ(ierr); 805de6a44a3SBarry Smith ierr = ViewerDestroy(viewer); CHKERRQ(ierr); 806de6a44a3SBarry Smith } 807de6a44a3SBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_view_info_detailed",&flg);CHKERRQ(ierr); 808de6a44a3SBarry Smith if (flg) { 809de6a44a3SBarry Smith Viewer viewer; 810de6a44a3SBarry Smith ierr = ViewerFileOpenASCII(B->comm,"stdout",&viewer);CHKERRQ(ierr); 811de6a44a3SBarry Smith ierr = ViewerFileSetFormat(viewer,FILE_FORMAT_INFO_DETAILED,0);CHKERRQ(ierr); 812de6a44a3SBarry Smith ierr = MatView(B,viewer); CHKERRQ(ierr); 813de6a44a3SBarry Smith ierr = ViewerDestroy(viewer); CHKERRQ(ierr); 814de6a44a3SBarry Smith } 815de6a44a3SBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_view",&flg); CHKERRQ(ierr); 816de6a44a3SBarry Smith if (flg) { 817de6a44a3SBarry Smith Viewer viewer; 818de6a44a3SBarry Smith ierr = ViewerFileOpenASCII(B->comm,"stdout",&viewer);CHKERRQ(ierr); 819de6a44a3SBarry Smith ierr = MatView(B,viewer); CHKERRQ(ierr); 820de6a44a3SBarry Smith ierr = ViewerDestroy(viewer); CHKERRQ(ierr); 821de6a44a3SBarry Smith } 822de6a44a3SBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_view_matlab",&flg); CHKERRQ(ierr); 823de6a44a3SBarry Smith if (flg) { 824de6a44a3SBarry Smith Viewer viewer; 825de6a44a3SBarry Smith ierr = ViewerFileOpenASCII(B->comm,"stdout",&viewer);CHKERRQ(ierr); 826de6a44a3SBarry Smith ierr = ViewerFileSetFormat(viewer,FILE_FORMAT_MATLAB,"M");CHKERRQ(ierr); 827de6a44a3SBarry Smith ierr = MatView(B,viewer); CHKERRQ(ierr); 828de6a44a3SBarry Smith ierr = ViewerDestroy(viewer); CHKERRQ(ierr); 829de6a44a3SBarry Smith } 830de6a44a3SBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_view_draw",&flg); CHKERRQ(ierr); 831de6a44a3SBarry Smith if (flg) { 832de6a44a3SBarry Smith Draw win; 833de6a44a3SBarry Smith ierr = DrawOpenX(B->comm,0,0,0,0,300,300,&win); CHKERRQ(ierr); 834de6a44a3SBarry Smith ierr = MatView(B,(Viewer)win); CHKERRQ(ierr); 835de6a44a3SBarry Smith ierr = DrawSyncFlush(win); CHKERRQ(ierr); 836de6a44a3SBarry Smith ierr = DrawDestroy(win); CHKERRQ(ierr); 837de6a44a3SBarry Smith } 8382593348eSBarry Smith return 0; 8392593348eSBarry Smith } 8402593348eSBarry Smith 8412593348eSBarry Smith 8422593348eSBarry Smith 843