1b6490206SBarry Smith 22593348eSBarry Smith #ifndef lint 3*f327dd97SBarry Smith static char vcid[] = "$Id: baij.c,v 1.7 1996/02/20 18:52:36 curfman 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; 547fc0212eSBarry 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)); 587fc0212eSBarry 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++ ) { 15188685aaeSLois Curfman McInnes #if defined(PETSC_COMPLEX) 15288685aaeSLois Curfman McInnes if (imag(a->a[bs*bs*k + l*bs + j]) != 0.0) { 15388685aaeSLois Curfman McInnes fprintf(fd," %d %g + %g i",bs*a->j[k]+l, 15488685aaeSLois Curfman McInnes real(a->a[bs*bs*k + l*bs + j]),imag(a->a[bs*bs*k + l*bs + j])); 15588685aaeSLois Curfman McInnes } 15688685aaeSLois Curfman McInnes else { 15788685aaeSLois Curfman McInnes fprintf(fd," %d %g",bs*a->j[k]+l,real(a->a[bs*bs*k + l*bs + j])); 15888685aaeSLois Curfman McInnes } 15988685aaeSLois Curfman McInnes #else 160de6a44a3SBarry Smith fprintf(fd," %d %g",bs*a->j[k]+l,a->a[bs*bs*k + l*bs + j]); 16188685aaeSLois Curfman McInnes #endif 1622593348eSBarry Smith } 1632593348eSBarry Smith } 1642593348eSBarry Smith fprintf(fd,"\n"); 1652593348eSBarry Smith } 1662593348eSBarry Smith } 167b6490206SBarry Smith } 1682593348eSBarry Smith fflush(fd); 1692593348eSBarry Smith return 0; 1702593348eSBarry Smith } 1712593348eSBarry Smith 172b6490206SBarry Smith static int MatView_SeqBAIJ(PetscObject obj,Viewer viewer) 1732593348eSBarry Smith { 1742593348eSBarry Smith Mat A = (Mat) obj; 1752593348eSBarry Smith PetscObject vobj = (PetscObject) viewer; 1762593348eSBarry Smith 1772593348eSBarry Smith if (!viewer) { 1782593348eSBarry Smith viewer = STDOUT_VIEWER_SELF; vobj = (PetscObject) viewer; 1792593348eSBarry Smith } 1802593348eSBarry Smith if (vobj->cookie == VIEWER_COOKIE) { 1812593348eSBarry Smith if (vobj->type == MATLAB_VIEWER) { 182b6490206SBarry Smith SETERRQ(1,"MatView_SeqBAIJ:Matlab viewer not supported"); 1832593348eSBarry Smith } 1842593348eSBarry Smith else if (vobj->type == ASCII_FILE_VIEWER||vobj->type == ASCII_FILES_VIEWER){ 185b6490206SBarry Smith return MatView_SeqBAIJ_ASCII(A,viewer); 1862593348eSBarry Smith } 1872593348eSBarry Smith else if (vobj->type == BINARY_FILE_VIEWER) { 188b6490206SBarry Smith return MatView_SeqBAIJ_Binary(A,viewer); 1892593348eSBarry Smith } 1902593348eSBarry Smith } 1912593348eSBarry Smith else if (vobj->cookie == DRAW_COOKIE) { 1922593348eSBarry Smith if (vobj->type == NULLWINDOW) return 0; 193b6490206SBarry Smith SETERRQ(1,"MatView_SeqBAIJ:Draw viewer not supported"); 1942593348eSBarry Smith } 1952593348eSBarry Smith return 0; 1962593348eSBarry Smith } 197b6490206SBarry Smith 198b6490206SBarry Smith 199b6490206SBarry Smith static int MatZeroEntries_SeqBAIJ(Mat A) 2002593348eSBarry Smith { 201b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 202de6a44a3SBarry Smith PetscMemzero(a->a,a->bs*a->bs*a->i[a->mbs]*sizeof(Scalar)); 2032593348eSBarry Smith return 0; 2042593348eSBarry Smith } 2052593348eSBarry Smith 206b6490206SBarry Smith int MatDestroy_SeqBAIJ(PetscObject obj) 2072593348eSBarry Smith { 2082593348eSBarry Smith Mat A = (Mat) obj; 209b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 2102593348eSBarry Smith 2112593348eSBarry Smith #if defined(PETSC_LOG) 2122593348eSBarry Smith PLogObjectState(obj,"Rows=%d, Cols=%d, NZ=%d",a->m,a->n,a->nz); 2132593348eSBarry Smith #endif 2142593348eSBarry Smith PetscFree(a->a); 2152593348eSBarry Smith if (!a->singlemalloc) { PetscFree(a->i); PetscFree(a->j);} 2162593348eSBarry Smith if (a->diag) PetscFree(a->diag); 2172593348eSBarry Smith if (a->ilen) PetscFree(a->ilen); 2182593348eSBarry Smith if (a->imax) PetscFree(a->imax); 2192593348eSBarry Smith if (a->solve_work) PetscFree(a->solve_work); 220de6a44a3SBarry Smith if (a->mult_work) PetscFree(a->mult_work); 2212593348eSBarry Smith PetscFree(a); 2222593348eSBarry Smith PLogObjectDestroy(A); 2232593348eSBarry Smith PetscHeaderDestroy(A); 2242593348eSBarry Smith return 0; 2252593348eSBarry Smith } 2262593348eSBarry Smith 227b6490206SBarry Smith static int MatSetOption_SeqBAIJ(Mat A,MatOption op) 2282593348eSBarry Smith { 229b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 2302593348eSBarry Smith if (op == ROW_ORIENTED) a->roworiented = 1; 2312593348eSBarry Smith else if (op == COLUMN_ORIENTED) a->roworiented = 0; 2322593348eSBarry Smith else if (op == COLUMNS_SORTED) a->sorted = 1; 2332593348eSBarry Smith else if (op == NO_NEW_NONZERO_LOCATIONS) a->nonew = 1; 2342593348eSBarry Smith else if (op == YES_NEW_NONZERO_LOCATIONS) a->nonew = 0; 2352593348eSBarry Smith else if (op == ROWS_SORTED || 2362593348eSBarry Smith op == SYMMETRIC_MATRIX || 2372593348eSBarry Smith op == STRUCTURALLY_SYMMETRIC_MATRIX || 2382593348eSBarry Smith op == YES_NEW_DIAGONALS) 239b6490206SBarry Smith PLogInfo((PetscObject)A,"Info:MatSetOption_SeqBAIJ:Option ignored\n"); 2402593348eSBarry Smith else if (op == NO_NEW_DIAGONALS) 241b6490206SBarry Smith {SETERRQ(PETSC_ERR_SUP,"MatSetOption_SeqBAIJ:NO_NEW_DIAGONALS");} 2422593348eSBarry Smith else 243b6490206SBarry Smith {SETERRQ(PETSC_ERR_SUP,"MatSetOption_SeqBAIJ:unknown option");} 2442593348eSBarry Smith return 0; 2452593348eSBarry Smith } 2462593348eSBarry Smith 2472593348eSBarry Smith 2482593348eSBarry Smith /* -------------------------------------------------------*/ 2492593348eSBarry Smith /* Should check that shapes of vectors and matrices match */ 2502593348eSBarry Smith /* -------------------------------------------------------*/ 251b6490206SBarry Smith #include "pinclude/plapack.h" 252b6490206SBarry Smith 253b6490206SBarry Smith static int MatMult_SeqBAIJ(Mat A,Vec xx,Vec yy) 2542593348eSBarry Smith { 255b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 256b6490206SBarry Smith Scalar *xg,*yg; 257b6490206SBarry Smith register Scalar *x, *y, *v, sum,*xb, sum1,sum2,sum3,sum4,sum5; 258b6490206SBarry Smith register Scalar x1,x2,x3,x4,x5; 259b6490206SBarry Smith int mbs = a->mbs, m = a->m, i, *idx,*ii; 260b6490206SBarry Smith int bs = a->bs,j,n,bs2 = bs*bs; 2612593348eSBarry Smith 262b6490206SBarry Smith VecGetArray(xx,&xg); x = xg; VecGetArray(yy,&yg); y = yg; 263b6490206SBarry Smith PetscMemzero(y,m*sizeof(Scalar)); 264b6490206SBarry Smith x = x; 2652593348eSBarry Smith idx = a->j; 2662593348eSBarry Smith v = a->a; 2672593348eSBarry Smith ii = a->i; 268b6490206SBarry Smith 269b6490206SBarry Smith switch (bs) { 270b6490206SBarry Smith case 1: 2712593348eSBarry Smith for ( i=0; i<m; i++ ) { 2722593348eSBarry Smith n = ii[1] - ii[0]; ii++; 2732593348eSBarry Smith sum = 0.0; 2742593348eSBarry Smith while (n--) sum += *v++ * x[*idx++]; 2752593348eSBarry Smith y[i] = sum; 2762593348eSBarry Smith } 2772593348eSBarry Smith break; 278b6490206SBarry Smith case 2: 279b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 280de6a44a3SBarry Smith n = ii[1] - ii[0]; ii++; 281b6490206SBarry Smith sum1 = 0.0; sum2 = 0.0; 282b6490206SBarry Smith for ( j=0; j<n; j++ ) { 283b6490206SBarry Smith xb = x + 2*(*idx++); x1 = xb[0]; x2 = xb[1]; 284b6490206SBarry Smith sum1 += v[0]*x1 + v[2]*x2; 285b6490206SBarry Smith sum2 += v[1]*x1 + v[3]*x2; 286b6490206SBarry Smith v += 4; 287b6490206SBarry Smith } 288b6490206SBarry Smith y[0] += sum1; y[1] += sum2; 289b6490206SBarry Smith y += 2; 290b6490206SBarry Smith } 291b6490206SBarry Smith break; 292b6490206SBarry Smith case 3: 293b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 294de6a44a3SBarry Smith n = ii[1] - ii[0]; ii++; 295b6490206SBarry Smith sum1 = 0.0; sum2 = 0.0; sum3 = 0.0; 296b6490206SBarry Smith for ( j=0; j<n; j++ ) { 297b6490206SBarry Smith xb = x + 3*(*idx++); x1 = xb[0]; x2 = xb[1]; x3 = xb[2]; 298b6490206SBarry Smith sum1 += v[0]*x1 + v[3]*x2 + v[6]*x3; 299b6490206SBarry Smith sum2 += v[1]*x1 + v[4]*x2 + v[7]*x3; 300b6490206SBarry Smith sum3 += v[2]*x1 + v[5]*x2 + v[8]*x3; 301b6490206SBarry Smith v += 9; 302b6490206SBarry Smith } 303b6490206SBarry Smith y[0] += sum1; y[1] += sum2; y[2] += sum3; 304b6490206SBarry Smith y += 3; 305b6490206SBarry Smith } 306b6490206SBarry Smith break; 307b6490206SBarry Smith case 4: 308b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 309de6a44a3SBarry Smith n = ii[1] - ii[0]; ii++; 310b6490206SBarry Smith sum1 = 0.0; sum2 = 0.0; sum3 = 0.0; sum4 = 0.0; 311b6490206SBarry Smith for ( j=0; j<n; j++ ) { 312b6490206SBarry Smith xb = x + 4*(*idx++); 313b6490206SBarry Smith x1 = xb[0]; x2 = xb[1]; x3 = xb[2]; x4 = xb[3]; 314b6490206SBarry Smith sum1 += v[0]*x1 + v[4]*x2 + v[8]*x3 + v[12]*x4; 315b6490206SBarry Smith sum2 += v[1]*x1 + v[5]*x2 + v[9]*x3 + v[13]*x4; 316b6490206SBarry Smith sum3 += v[2]*x1 + v[6]*x2 + v[10]*x3 + v[14]*x4; 317b6490206SBarry Smith sum4 += v[3]*x1 + v[7]*x2 + v[11]*x3 + v[15]*x4; 318b6490206SBarry Smith v += 16; 319b6490206SBarry Smith } 320b6490206SBarry Smith y[0] += sum1; y[1] += sum2; y[2] += sum3; y[3] += sum4; 321b6490206SBarry Smith y += 4; 322b6490206SBarry Smith } 323b6490206SBarry Smith break; 324b6490206SBarry Smith case 5: 325b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 326de6a44a3SBarry Smith n = ii[1] - ii[0]; ii++; 327b6490206SBarry Smith sum1 = 0.0; sum2 = 0.0; sum3 = 0.0; sum4 = 0.0; sum5 = 0.0; 328b6490206SBarry Smith for ( j=0; j<n; j++ ) { 329b6490206SBarry Smith xb = x + 5*(*idx++); 330b6490206SBarry Smith x1 = xb[0]; x2 = xb[1]; x3 = xb[2]; x4 = xb[3]; x5 = xb[4]; 331b6490206SBarry Smith sum1 += v[0]*x1 + v[5]*x2 + v[10]*x3 + v[15]*x4 + v[20]*x5; 332b6490206SBarry Smith sum2 += v[1]*x1 + v[6]*x2 + v[11]*x3 + v[16]*x4 + v[21]*x5; 333b6490206SBarry Smith sum3 += v[2]*x1 + v[7]*x2 + v[12]*x3 + v[17]*x4 + v[22]*x5; 334b6490206SBarry Smith sum4 += v[3]*x1 + v[8]*x2 + v[13]*x3 + v[18]*x4 + v[23]*x5; 335b6490206SBarry Smith sum5 += v[4]*x1 + v[9]*x2 + v[14]*x3 + v[19]*x4 + v[24]*x5; 336b6490206SBarry Smith v += 25; 337b6490206SBarry Smith } 338b6490206SBarry Smith y[0] += sum1; y[1] += sum2; y[2] += sum3; y[3] += sum4; y[4] += sum5; 339b6490206SBarry Smith y += 5; 340b6490206SBarry Smith } 341b6490206SBarry Smith break; 342b6490206SBarry Smith /* block sizes larger then 5 by 5 are handled by BLAS */ 343b6490206SBarry Smith default: { 344de6a44a3SBarry Smith int _One = 1,ncols,k; Scalar _DOne = 1.0, *work,*workt; 345de6a44a3SBarry Smith if (!a->mult_work) { 346de6a44a3SBarry Smith a->mult_work = (Scalar *) PetscMalloc(a->m*sizeof(Scalar)); 347de6a44a3SBarry Smith CHKPTRQ(a->mult_work); 348de6a44a3SBarry Smith } 349de6a44a3SBarry Smith work = a->mult_work; 350b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 351de6a44a3SBarry Smith n = ii[1] - ii[0]; ii++; 352de6a44a3SBarry Smith ncols = n*bs; 353de6a44a3SBarry Smith workt = work; 354b6490206SBarry Smith for ( j=0; j<n; j++ ) { 355b6490206SBarry Smith xb = x + bs*(*idx++); 356de6a44a3SBarry Smith for ( k=0; k<bs; k++ ) workt[k] = xb[k]; 357de6a44a3SBarry Smith workt += bs; 358b6490206SBarry Smith } 359de6a44a3SBarry Smith LAgemv_("N",&bs,&ncols,&_DOne,v,&bs,work,&_One,&_DOne,y,&_One); 360de6a44a3SBarry Smith v += n*bs2; 361b6490206SBarry Smith y += bs; 3622593348eSBarry Smith } 3632593348eSBarry Smith } 3642593348eSBarry Smith } 365b6490206SBarry Smith PLogFlops(2*bs2*a->nz - m); 3662593348eSBarry Smith return 0; 3672593348eSBarry Smith } 3682593348eSBarry Smith 369de6a44a3SBarry Smith static int MatGetInfo_SeqBAIJ(Mat A,MatInfoType flag,int *nz,int *nza,int *mem) 3702593348eSBarry Smith { 371b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 37235aab85fSBarry Smith *nz = a->bs*a->bs*a->nz; 373de6a44a3SBarry Smith *nza = a->maxnz; 3742593348eSBarry Smith *mem = (int)A->mem; 3752593348eSBarry Smith return 0; 3762593348eSBarry Smith } 3772593348eSBarry Smith 378b6490206SBarry Smith extern int MatLUFactorSymbolic_SeqBAIJ(Mat,IS,IS,double,Mat*); 379b6490206SBarry Smith extern int MatLUFactor_SeqBAIJ(Mat,IS,IS,double); 380b6490206SBarry Smith extern int MatSolve_SeqBAIJ(Mat,Vec,Vec); 3817fc0212eSBarry Smith extern int MatLUFactorNumeric_SeqBAIJ_N(Mat,Mat*); 3827fc0212eSBarry Smith extern int MatLUFactorNumeric_SeqBAIJ_1(Mat,Mat*); 3837fc0212eSBarry Smith extern int MatLUFactorNumeric_SeqBAIJ_2(Mat,Mat*); 3847fc0212eSBarry Smith extern int MatLUFactorNumeric_SeqBAIJ_3(Mat,Mat*); 3857fc0212eSBarry Smith extern int MatLUFactorNumeric_SeqBAIJ_4(Mat,Mat*); 3867fc0212eSBarry Smith extern int MatLUFactorNumeric_SeqBAIJ_5(Mat,Mat*); 3872593348eSBarry Smith 388b6490206SBarry Smith static int MatGetSize_SeqBAIJ(Mat A,int *m,int *n) 3892593348eSBarry Smith { 390b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 3912593348eSBarry Smith *m = a->m; *n = a->n; 3922593348eSBarry Smith return 0; 3932593348eSBarry Smith } 3942593348eSBarry Smith 395b6490206SBarry Smith static int MatGetOwnershipRange_SeqBAIJ(Mat A,int *m,int *n) 3962593348eSBarry Smith { 397b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 3982593348eSBarry Smith *m = 0; *n = a->m; 3992593348eSBarry Smith return 0; 4002593348eSBarry Smith } 401b6490206SBarry Smith 402b6490206SBarry Smith static int MatNorm_SeqBAIJ(Mat A,NormType type,double *norm) 4032593348eSBarry Smith { 404b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 4052593348eSBarry Smith Scalar *v = a->a; 4062593348eSBarry Smith double sum = 0.0; 407b6490206SBarry Smith int i; 4082593348eSBarry Smith 4092593348eSBarry Smith if (type == NORM_FROBENIUS) { 4102593348eSBarry Smith for (i=0; i<a->nz; i++ ) { 4112593348eSBarry Smith #if defined(PETSC_COMPLEX) 4122593348eSBarry Smith sum += real(conj(*v)*(*v)); v++; 4132593348eSBarry Smith #else 4142593348eSBarry Smith sum += (*v)*(*v); v++; 4152593348eSBarry Smith #endif 4162593348eSBarry Smith } 4172593348eSBarry Smith *norm = sqrt(sum); 4182593348eSBarry Smith } 4192593348eSBarry Smith else { 420b6490206SBarry Smith SETERRQ(1,"MatNorm_SeqBAIJ:No support for this norm yet"); 4212593348eSBarry Smith } 4222593348eSBarry Smith return 0; 4232593348eSBarry Smith } 4242593348eSBarry Smith 4252593348eSBarry Smith /* 4262593348eSBarry Smith note: This can only work for identity for row and col. It would 4272593348eSBarry Smith be good to check this and otherwise generate an error. 4282593348eSBarry Smith */ 429b6490206SBarry Smith static int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,double efill,int fill) 4302593348eSBarry Smith { 431b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) inA->data; 4322593348eSBarry Smith Mat outA; 433de6a44a3SBarry Smith int ierr; 4342593348eSBarry Smith 435b6490206SBarry Smith if (fill != 0) SETERRQ(1,"MatILUFactor_SeqBAIJ:Only fill=0 supported"); 4362593348eSBarry Smith 4372593348eSBarry Smith outA = inA; 4382593348eSBarry Smith inA->factor = FACTOR_LU; 4392593348eSBarry Smith a->row = row; 4402593348eSBarry Smith a->col = col; 4412593348eSBarry Smith 442de6a44a3SBarry Smith a->solve_work = (Scalar *) PetscMalloc((a->m+a->bs)*sizeof(Scalar));CHKPTRQ(a->solve_work); 4432593348eSBarry Smith 4442593348eSBarry Smith if (!a->diag) { 445b6490206SBarry Smith ierr = MatMarkDiag_SeqBAIJ(inA); CHKERRQ(ierr); 4462593348eSBarry Smith } 4477fc0212eSBarry Smith ierr = MatLUFactorNumeric(inA,&outA); CHKERRQ(ierr); 4482593348eSBarry Smith return 0; 4492593348eSBarry Smith } 4502593348eSBarry Smith 451b6490206SBarry Smith static int MatScale_SeqBAIJ(Scalar *alpha,Mat inA) 4522593348eSBarry Smith { 453b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) inA->data; 454b6490206SBarry Smith int one = 1, totalnz = a->bs*a->bs*a->nz; 455b6490206SBarry Smith BLscal_( &totalnz, alpha, a->a, &one ); 456b6490206SBarry Smith PLogFlops(totalnz); 4572593348eSBarry Smith return 0; 4582593348eSBarry Smith } 4592593348eSBarry Smith 460b6490206SBarry Smith int MatPrintHelp_SeqBAIJ(Mat A) 4612593348eSBarry Smith { 4622593348eSBarry Smith static int called = 0; 4632593348eSBarry Smith 4642593348eSBarry Smith if (called) return 0; else called = 1; 4652593348eSBarry Smith return 0; 4662593348eSBarry Smith } 4672593348eSBarry Smith /* -------------------------------------------------------------------*/ 468b6490206SBarry Smith static struct _MatOps MatOps = {0, 469b6490206SBarry Smith 0,0, 470b6490206SBarry Smith MatMult_SeqBAIJ,0, 471b6490206SBarry Smith 0,0, 472de6a44a3SBarry Smith MatSolve_SeqBAIJ,0, 473b6490206SBarry Smith 0,0, 474de6a44a3SBarry Smith MatLUFactor_SeqBAIJ,0, 475b6490206SBarry Smith 0, 476b6490206SBarry Smith 0, 477b6490206SBarry Smith MatGetInfo_SeqBAIJ,0, 478b6490206SBarry Smith 0,0,MatNorm_SeqBAIJ, 479b6490206SBarry Smith 0,0, 480b6490206SBarry Smith 0, 481b6490206SBarry Smith MatSetOption_SeqBAIJ,MatZeroEntries_SeqBAIJ,0, 482b6490206SBarry Smith MatGetReordering_SeqBAIJ, 4837fc0212eSBarry Smith MatLUFactorSymbolic_SeqBAIJ,MatLUFactorNumeric_SeqBAIJ_N,0,0, 484b6490206SBarry Smith MatGetSize_SeqBAIJ,MatGetSize_SeqBAIJ,MatGetOwnershipRange_SeqBAIJ, 485de6a44a3SBarry Smith MatILUFactorSymbolic_SeqBAIJ,0, 486b6490206SBarry Smith 0,0,/*MatConvert_SeqBAIJ*/ 0, 487b6490206SBarry Smith 0,0, 488b6490206SBarry Smith MatConvertSameType_SeqBAIJ,0,0, 489b6490206SBarry Smith MatILUFactor_SeqBAIJ,0,0, 490b6490206SBarry Smith 0,0, 491b6490206SBarry Smith 0,0, 492b6490206SBarry Smith MatPrintHelp_SeqBAIJ,MatScale_SeqBAIJ, 493b6490206SBarry Smith 0}; 4942593348eSBarry Smith 4952593348eSBarry Smith /*@C 496b6490206SBarry Smith MatCreateSeqBAIJ - Creates a sparse matrix in AIJ (compressed row) format 4972593348eSBarry Smith (the default parallel PETSc format). For good matrix assembly performance 4982593348eSBarry Smith the user should preallocate the matrix storage by setting the parameter nz 4992593348eSBarry Smith (or nzz). By setting these parameters accurately, performance can be 5002593348eSBarry Smith increased by more than a factor of 50. 5012593348eSBarry Smith 5022593348eSBarry Smith Input Parameters: 5032593348eSBarry Smith . comm - MPI communicator, set to MPI_COMM_SELF 504b6490206SBarry Smith . bs - size of block 5052593348eSBarry Smith . m - number of rows 5062593348eSBarry Smith . n - number of columns 507b6490206SBarry Smith . nz - number of block nonzeros per block row (same for all rows) 508b6490206SBarry Smith . nzz - number of block nonzeros per block row or PETSC_NULL 509b6490206SBarry Smith (possibly different for each row) 5102593348eSBarry Smith 5112593348eSBarry Smith Output Parameter: 5122593348eSBarry Smith . A - the matrix 5132593348eSBarry Smith 5142593348eSBarry Smith Notes: 515b6490206SBarry Smith The BAIJ format, is fully compatible with standard Fortran 77 5162593348eSBarry Smith storage. That is, the stored row and column indices can begin at 5172593348eSBarry Smith either one (as in Fortran) or zero. See the users manual for details. 5182593348eSBarry Smith 5192593348eSBarry Smith Specify the preallocated storage with either nz or nnz (not both). 5202593348eSBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 5212593348eSBarry Smith allocation. For additional details, see the users manual chapter on 5222593348eSBarry Smith matrices and the file $(PETSC_DIR)/Performance. 5232593348eSBarry Smith 5242593348eSBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues() 5252593348eSBarry Smith @*/ 526b6490206SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz, Mat *A) 5272593348eSBarry Smith { 5282593348eSBarry Smith Mat B; 529b6490206SBarry Smith Mat_SeqBAIJ *b; 530b6490206SBarry Smith int i,len,ierr, flg,mbs = m/bs; 531b6490206SBarry Smith 532b6490206SBarry Smith if (mbs*bs != m) 533b6490206SBarry Smith SETERRQ(1,"MatCreateSeqBAIJ:Number rows must be divisible by blocksize"); 5342593348eSBarry Smith 5352593348eSBarry Smith *A = 0; 536b6490206SBarry Smith PetscHeaderCreate(B,_Mat,MAT_COOKIE,MATSEQBAIJ,comm); 5372593348eSBarry Smith PLogObjectCreate(B); 538b6490206SBarry Smith B->data = (void *) (b = PetscNew(Mat_SeqBAIJ)); CHKPTRQ(b); 5392593348eSBarry Smith PetscMemcpy(&B->ops,&MatOps,sizeof(struct _MatOps)); 5407fc0212eSBarry Smith switch (bs) { 5417fc0212eSBarry Smith case 1: 5427fc0212eSBarry Smith B->ops.lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1; 5437fc0212eSBarry Smith break; 5444eeb42bcSBarry Smith case 2: 5454eeb42bcSBarry Smith B->ops.lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2; 546*f327dd97SBarry Smith case 3: 547*f327dd97SBarry Smith B->ops.lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3; 5484eeb42bcSBarry Smith break; 5497fc0212eSBarry Smith } 550b6490206SBarry Smith B->destroy = MatDestroy_SeqBAIJ; 551b6490206SBarry Smith B->view = MatView_SeqBAIJ; 5522593348eSBarry Smith B->factor = 0; 5532593348eSBarry Smith B->lupivotthreshold = 1.0; 5542593348eSBarry Smith b->row = 0; 5552593348eSBarry Smith b->col = 0; 5562593348eSBarry Smith b->reallocs = 0; 5572593348eSBarry Smith 5582593348eSBarry Smith b->m = m; 559b6490206SBarry Smith b->mbs = mbs; 5602593348eSBarry Smith b->n = n; 561b6490206SBarry Smith b->imax = (int *) PetscMalloc( (mbs+1)*sizeof(int) ); CHKPTRQ(b->imax); 5622593348eSBarry Smith if (nnz == PETSC_NULL) { 563de6a44a3SBarry Smith if (nz == PETSC_DEFAULT) nz = 5; 5642593348eSBarry Smith else if (nz <= 0) nz = 1; 565b6490206SBarry Smith for ( i=0; i<mbs; i++ ) b->imax[i] = nz; 566b6490206SBarry Smith nz = nz*mbs; 5672593348eSBarry Smith } 5682593348eSBarry Smith else { 5692593348eSBarry Smith nz = 0; 570b6490206SBarry Smith for ( i=0; i<mbs; i++ ) {b->imax[i] = nnz[i]; nz += nnz[i];} 5712593348eSBarry Smith } 5722593348eSBarry Smith 5732593348eSBarry Smith /* allocate the matrix space */ 574b6490206SBarry Smith len = nz*sizeof(int) + nz*bs*bs*sizeof(Scalar) + (b->m+1)*sizeof(int); 5752593348eSBarry Smith b->a = (Scalar *) PetscMalloc( len ); CHKPTRQ(b->a); 576b6490206SBarry Smith PetscMemzero(b->a,nz*bs*bs*sizeof(Scalar)); 577b6490206SBarry Smith b->j = (int *) (b->a + nz*bs*bs); 5782593348eSBarry Smith PetscMemzero(b->j,nz*sizeof(int)); 5792593348eSBarry Smith b->i = b->j + nz; 5802593348eSBarry Smith b->singlemalloc = 1; 5812593348eSBarry Smith 582de6a44a3SBarry Smith b->i[0] = 0; 583b6490206SBarry Smith for (i=1; i<mbs+1; i++) { 5842593348eSBarry Smith b->i[i] = b->i[i-1] + b->imax[i-1]; 5852593348eSBarry Smith } 5862593348eSBarry Smith 587b6490206SBarry Smith /* b->ilen will count nonzeros in each block row so far. */ 588b6490206SBarry Smith b->ilen = (int *) PetscMalloc((mbs+1)*sizeof(int)); 589b6490206SBarry Smith PLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _Mat)+sizeof(Mat_SeqBAIJ)); 590b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { b->ilen[i] = 0;} 5912593348eSBarry Smith 592b6490206SBarry Smith b->bs = bs; 593b6490206SBarry Smith b->mbs = mbs; 5942593348eSBarry Smith b->nz = 0; 5952593348eSBarry Smith b->maxnz = nz; 5962593348eSBarry Smith b->sorted = 0; 5972593348eSBarry Smith b->roworiented = 1; 5982593348eSBarry Smith b->nonew = 0; 5992593348eSBarry Smith b->diag = 0; 6002593348eSBarry Smith b->solve_work = 0; 601de6a44a3SBarry Smith b->mult_work = 0; 6022593348eSBarry Smith b->spptr = 0; 6032593348eSBarry Smith 6042593348eSBarry Smith *A = B; 6052593348eSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr); 6062593348eSBarry Smith if (flg) {ierr = MatPrintHelp(B); CHKERRQ(ierr); } 6072593348eSBarry Smith return 0; 6082593348eSBarry Smith } 6092593348eSBarry Smith 610b6490206SBarry Smith int MatConvertSameType_SeqBAIJ(Mat A,Mat *B,int cpvalues) 6112593348eSBarry Smith { 6122593348eSBarry Smith Mat C; 613b6490206SBarry Smith Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ *) A->data; 614de6a44a3SBarry Smith int i,len, mbs = a->mbs, bs = a->bs,nz = a->nz; 615de6a44a3SBarry Smith 616de6a44a3SBarry Smith if (a->i[mbs] != nz) SETERRQ(1,"MatConvertSameType_SeqBAIJ:Corrupt matrix"); 6172593348eSBarry Smith 6182593348eSBarry Smith *B = 0; 619b6490206SBarry Smith PetscHeaderCreate(C,_Mat,MAT_COOKIE,MATSEQBAIJ,A->comm); 6202593348eSBarry Smith PLogObjectCreate(C); 621b6490206SBarry Smith C->data = (void *) (c = PetscNew(Mat_SeqBAIJ)); CHKPTRQ(c); 6222593348eSBarry Smith PetscMemcpy(&C->ops,&A->ops,sizeof(struct _MatOps)); 623b6490206SBarry Smith C->destroy = MatDestroy_SeqBAIJ; 624b6490206SBarry Smith C->view = MatView_SeqBAIJ; 6252593348eSBarry Smith C->factor = A->factor; 6262593348eSBarry Smith c->row = 0; 6272593348eSBarry Smith c->col = 0; 6282593348eSBarry Smith C->assembled = PETSC_TRUE; 6292593348eSBarry Smith 6302593348eSBarry Smith c->m = a->m; 6312593348eSBarry Smith c->n = a->n; 632b6490206SBarry Smith c->bs = a->bs; 633b6490206SBarry Smith c->mbs = a->mbs; 634b6490206SBarry Smith c->nbs = a->nbs; 6352593348eSBarry Smith 636b6490206SBarry Smith c->imax = (int *) PetscMalloc((mbs+1)*sizeof(int)); CHKPTRQ(c->imax); 637b6490206SBarry Smith c->ilen = (int *) PetscMalloc((mbs+1)*sizeof(int)); CHKPTRQ(c->ilen); 638b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 6392593348eSBarry Smith c->imax[i] = a->imax[i]; 6402593348eSBarry Smith c->ilen[i] = a->ilen[i]; 6412593348eSBarry Smith } 6422593348eSBarry Smith 6432593348eSBarry Smith /* allocate the matrix space */ 6442593348eSBarry Smith c->singlemalloc = 1; 645de6a44a3SBarry Smith len = (mbs+1)*sizeof(int) + nz*(bs*bs*sizeof(Scalar) + sizeof(int)); 6462593348eSBarry Smith c->a = (Scalar *) PetscMalloc( len ); CHKPTRQ(c->a); 647de6a44a3SBarry Smith c->j = (int *) (c->a + nz*bs*bs); 648de6a44a3SBarry Smith c->i = c->j + nz; 649b6490206SBarry Smith PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int)); 650b6490206SBarry Smith if (mbs > 0) { 651de6a44a3SBarry Smith PetscMemcpy(c->j,a->j,nz*sizeof(int)); 6522593348eSBarry Smith if (cpvalues == COPY_VALUES) { 653de6a44a3SBarry Smith PetscMemcpy(c->a,a->a,bs*bs*nz*sizeof(Scalar)); 6542593348eSBarry Smith } 6552593348eSBarry Smith } 6562593348eSBarry Smith 657b6490206SBarry Smith PLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _Mat)+sizeof(Mat_SeqBAIJ)); 6582593348eSBarry Smith c->sorted = a->sorted; 6592593348eSBarry Smith c->roworiented = a->roworiented; 6602593348eSBarry Smith c->nonew = a->nonew; 6612593348eSBarry Smith 6622593348eSBarry Smith if (a->diag) { 663b6490206SBarry Smith c->diag = (int *) PetscMalloc( (mbs+1)*sizeof(int) ); CHKPTRQ(c->diag); 664b6490206SBarry Smith PLogObjectMemory(C,(mbs+1)*sizeof(int)); 665b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 6662593348eSBarry Smith c->diag[i] = a->diag[i]; 6672593348eSBarry Smith } 6682593348eSBarry Smith } 6692593348eSBarry Smith else c->diag = 0; 6702593348eSBarry Smith c->nz = a->nz; 6712593348eSBarry Smith c->maxnz = a->maxnz; 6722593348eSBarry Smith c->solve_work = 0; 6732593348eSBarry Smith c->spptr = 0; /* Dangerous -I'm throwing away a->spptr */ 6747fc0212eSBarry Smith c->mult_work = 0; 6752593348eSBarry Smith *B = C; 6762593348eSBarry Smith return 0; 6772593348eSBarry Smith } 6782593348eSBarry Smith 679b6490206SBarry Smith int MatLoad_SeqBAIJ(Viewer bview,MatType type,Mat *A) 6802593348eSBarry Smith { 681b6490206SBarry Smith Mat_SeqBAIJ *a; 6822593348eSBarry Smith Mat B; 683de6a44a3SBarry Smith int i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1,flg; 684b6490206SBarry Smith int *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount; 68535aab85fSBarry Smith int kmax,jcount,block,idx,point,nzcountb,extra_rows; 686de6a44a3SBarry Smith int *masked, nmask,tmp,ishift,bs2; 687b6490206SBarry Smith Scalar *aa; 6882593348eSBarry Smith PetscObject vobj = (PetscObject) bview; 6892593348eSBarry Smith MPI_Comm comm = vobj->comm; 6902593348eSBarry Smith 69135aab85fSBarry Smith ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&bs,&flg);CHKERRQ(ierr); 692de6a44a3SBarry Smith bs2 = bs*bs; 693b6490206SBarry Smith 6942593348eSBarry Smith MPI_Comm_size(comm,&size); 695b6490206SBarry Smith if (size > 1) SETERRQ(1,"MatLoad_SeqBAIJ:view must have one processor"); 6962593348eSBarry Smith ierr = ViewerFileGetDescriptor_Private(bview,&fd); CHKERRQ(ierr); 6972593348eSBarry Smith ierr = SYRead(fd,header,4,SYINT); CHKERRQ(ierr); 698de6a44a3SBarry Smith if (header[0] != MAT_COOKIE) SETERRQ(1,"MatLoad_SeqBAIJ:not Mat object"); 6992593348eSBarry Smith M = header[1]; N = header[2]; nz = header[3]; 7002593348eSBarry Smith 701b6490206SBarry Smith if (M != N) SETERRQ(1,"MatLoad_SeqBAIJ:Can only do square matrices"); 70235aab85fSBarry Smith 70335aab85fSBarry Smith /* 70435aab85fSBarry Smith This code adds extra rows to make sure the number of rows is 70535aab85fSBarry Smith divisible by the blocksize 70635aab85fSBarry Smith */ 707b6490206SBarry Smith mbs = M/bs; 70835aab85fSBarry Smith extra_rows = bs - M + bs*(mbs); 70935aab85fSBarry Smith if (extra_rows == bs) extra_rows = 0; 71035aab85fSBarry Smith else mbs++; 71135aab85fSBarry Smith if (extra_rows) { 71235aab85fSBarry Smith PLogInfo(0,"MatLoad_SeqBAIJ:Padding loading matrix to match blocksize"); 71335aab85fSBarry Smith } 714b6490206SBarry Smith 7152593348eSBarry Smith /* read in row lengths */ 71635aab85fSBarry Smith rowlengths = (int*) PetscMalloc((M+extra_rows)*sizeof(int));CHKPTRQ(rowlengths); 7172593348eSBarry Smith ierr = SYRead(fd,rowlengths,M,SYINT); CHKERRQ(ierr); 71835aab85fSBarry Smith for ( i=0; i<extra_rows; i++ ) rowlengths[M+i] = 1; 7192593348eSBarry Smith 720b6490206SBarry Smith /* read in column indices */ 72135aab85fSBarry Smith jj = (int*) PetscMalloc( (nz+extra_rows)*sizeof(int) ); CHKPTRQ(jj); 722b6490206SBarry Smith ierr = SYRead(fd,jj,nz,SYINT); CHKERRQ(ierr); 72335aab85fSBarry Smith for ( i=0; i<extra_rows; i++ ) jj[nz+i] = M+i; 724b6490206SBarry Smith 725b6490206SBarry Smith /* loop over row lengths determining block row lengths */ 726b6490206SBarry Smith browlengths = (int *) PetscMalloc(mbs*sizeof(int));CHKPTRQ(browlengths); 727b6490206SBarry Smith PetscMemzero(browlengths,mbs*sizeof(int)); 72835aab85fSBarry Smith mask = (int *) PetscMalloc( 2*mbs*sizeof(int) ); CHKPTRQ(mask); 72935aab85fSBarry Smith PetscMemzero(mask,mbs*sizeof(int)); 73035aab85fSBarry Smith masked = mask + mbs; 731b6490206SBarry Smith rowcount = 0; nzcount = 0; 732b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 73335aab85fSBarry Smith nmask = 0; 734b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 735b6490206SBarry Smith kmax = rowlengths[rowcount]; 736b6490206SBarry Smith for ( k=0; k<kmax; k++ ) { 73735aab85fSBarry Smith tmp = jj[nzcount++]/bs; 73835aab85fSBarry Smith if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;} 739b6490206SBarry Smith } 740b6490206SBarry Smith rowcount++; 741b6490206SBarry Smith } 74235aab85fSBarry Smith browlengths[i] += nmask; 74335aab85fSBarry Smith /* zero out the mask elements we set */ 74435aab85fSBarry Smith for ( j=0; j<nmask; j++ ) mask[masked[j]] = 0; 745b6490206SBarry Smith } 746b6490206SBarry Smith 7472593348eSBarry Smith /* create our matrix */ 74835aab85fSBarry Smith ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A); 74935aab85fSBarry Smith CHKERRQ(ierr); 7502593348eSBarry Smith B = *A; 751b6490206SBarry Smith a = (Mat_SeqBAIJ *) B->data; 7522593348eSBarry Smith 7532593348eSBarry Smith /* set matrix "i" values */ 754de6a44a3SBarry Smith a->i[0] = 0; 755b6490206SBarry Smith for ( i=1; i<= mbs; i++ ) { 756b6490206SBarry Smith a->i[i] = a->i[i-1] + browlengths[i-1]; 757b6490206SBarry Smith a->ilen[i-1] = browlengths[i-1]; 7582593348eSBarry Smith } 759b6490206SBarry Smith a->nz = 0; 760b6490206SBarry Smith for ( i=0; i<mbs; i++ ) a->nz += browlengths[i]; 7612593348eSBarry Smith 762b6490206SBarry Smith /* read in nonzero values */ 76335aab85fSBarry Smith aa = (Scalar *) PetscMalloc((nz+extra_rows)*sizeof(Scalar));CHKPTRQ(aa); 764b6490206SBarry Smith ierr = SYRead(fd,aa,nz,SYSCALAR); CHKERRQ(ierr); 76535aab85fSBarry Smith for ( i=0; i<extra_rows; i++ ) aa[nz+i] = 1.0; 766b6490206SBarry Smith 767b6490206SBarry Smith /* set "a" and "j" values into matrix */ 768b6490206SBarry Smith nzcount = 0; jcount = 0; 769b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 770b6490206SBarry Smith nzcountb = nzcount; 77135aab85fSBarry Smith nmask = 0; 772b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 773b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 774b6490206SBarry Smith for ( k=0; k<kmax; k++ ) { 77535aab85fSBarry Smith tmp = jj[nzcount++]/bs; 77635aab85fSBarry Smith if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;} 777b6490206SBarry Smith } 778b6490206SBarry Smith rowcount++; 779b6490206SBarry Smith } 780de6a44a3SBarry Smith /* sort the masked values */ 781de6a44a3SBarry Smith SYIsort(nmask,masked); 782de6a44a3SBarry Smith 783b6490206SBarry Smith /* set "j" values into matrix */ 784b6490206SBarry Smith maskcount = 1; 78535aab85fSBarry Smith for ( j=0; j<nmask; j++ ) { 78635aab85fSBarry Smith a->j[jcount++] = masked[j]; 787de6a44a3SBarry Smith mask[masked[j]] = maskcount++; 788b6490206SBarry Smith } 789b6490206SBarry Smith /* set "a" values into matrix */ 790de6a44a3SBarry Smith ishift = bs2*a->i[i]; 791b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 792b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 793b6490206SBarry Smith for ( k=0; k<kmax; k++ ) { 794de6a44a3SBarry Smith tmp = jj[nzcountb]/bs ; 795de6a44a3SBarry Smith block = mask[tmp] - 1; 796de6a44a3SBarry Smith point = jj[nzcountb] - bs*tmp; 797de6a44a3SBarry Smith idx = ishift + bs2*block + j + bs*point; 798b6490206SBarry Smith a->a[idx] = aa[nzcountb++]; 799b6490206SBarry Smith } 800b6490206SBarry Smith } 80135aab85fSBarry Smith /* zero out the mask elements we set */ 80235aab85fSBarry Smith for ( j=0; j<nmask; j++ ) mask[masked[j]] = 0; 803b6490206SBarry Smith } 80435aab85fSBarry Smith if (jcount != a->nz) SETERRQ(1,"MatLoad_SeqBAIJ:Error bad binary matrix"); 805b6490206SBarry Smith 806b6490206SBarry Smith PetscFree(rowlengths); 807b6490206SBarry Smith PetscFree(browlengths); 808b6490206SBarry Smith PetscFree(aa); 809b6490206SBarry Smith PetscFree(jj); 810b6490206SBarry Smith PetscFree(mask); 811b6490206SBarry Smith 812b6490206SBarry Smith B->assembled = PETSC_TRUE; 813de6a44a3SBarry Smith 814de6a44a3SBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_view_info",&flg); CHKERRQ(ierr); 815de6a44a3SBarry Smith if (flg) { 816de6a44a3SBarry Smith Viewer viewer; 817de6a44a3SBarry Smith ierr = ViewerFileOpenASCII(B->comm,"stdout",&viewer);CHKERRQ(ierr); 818de6a44a3SBarry Smith ierr = ViewerFileSetFormat(viewer,FILE_FORMAT_INFO,0);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_info_detailed",&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_INFO_DETAILED,0);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",&flg); CHKERRQ(ierr); 831de6a44a3SBarry Smith if (flg) { 832de6a44a3SBarry Smith Viewer viewer; 833de6a44a3SBarry Smith ierr = ViewerFileOpenASCII(B->comm,"stdout",&viewer);CHKERRQ(ierr); 834de6a44a3SBarry Smith ierr = MatView(B,viewer); CHKERRQ(ierr); 835de6a44a3SBarry Smith ierr = ViewerDestroy(viewer); CHKERRQ(ierr); 836de6a44a3SBarry Smith } 837de6a44a3SBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_view_matlab",&flg); CHKERRQ(ierr); 838de6a44a3SBarry Smith if (flg) { 839de6a44a3SBarry Smith Viewer viewer; 840de6a44a3SBarry Smith ierr = ViewerFileOpenASCII(B->comm,"stdout",&viewer);CHKERRQ(ierr); 841de6a44a3SBarry Smith ierr = ViewerFileSetFormat(viewer,FILE_FORMAT_MATLAB,"M");CHKERRQ(ierr); 842de6a44a3SBarry Smith ierr = MatView(B,viewer); CHKERRQ(ierr); 843de6a44a3SBarry Smith ierr = ViewerDestroy(viewer); CHKERRQ(ierr); 844de6a44a3SBarry Smith } 845de6a44a3SBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_view_draw",&flg); CHKERRQ(ierr); 846de6a44a3SBarry Smith if (flg) { 847de6a44a3SBarry Smith Draw win; 848de6a44a3SBarry Smith ierr = DrawOpenX(B->comm,0,0,0,0,300,300,&win); CHKERRQ(ierr); 849de6a44a3SBarry Smith ierr = MatView(B,(Viewer)win); CHKERRQ(ierr); 850de6a44a3SBarry Smith ierr = DrawSyncFlush(win); CHKERRQ(ierr); 851de6a44a3SBarry Smith ierr = DrawDestroy(win); CHKERRQ(ierr); 852de6a44a3SBarry Smith } 8532593348eSBarry Smith return 0; 8542593348eSBarry Smith } 8552593348eSBarry Smith 8562593348eSBarry Smith 8572593348eSBarry Smith 858