1a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER 2*61b13de0SBarry Smith static char vcid[] = "$Id: baij.c,v 1.139 1998/07/13 20:42:20 bsmith Exp bsmith $"; 32593348eSBarry Smith #endif 42593348eSBarry Smith 52593348eSBarry Smith /* 6b6490206SBarry Smith Defines the basic matrix operations for the BAIJ (compressed row) 72593348eSBarry Smith matrix storage format. 82593348eSBarry Smith */ 93369ce9aSBarry Smith 103369ce9aSBarry Smith #include "pinclude/pviewer.h" 113369ce9aSBarry Smith #include "sys.h" 1270f55243SBarry Smith #include "src/mat/impls/baij/seq/baij.h" 131a6a6d98SBarry Smith #include "src/vec/vecimpl.h" 141a6a6d98SBarry Smith #include "src/inline/spops.h" 152593348eSBarry Smith #include "petsc.h" 163b547af2SSatish Balay 172d61bbb3SSatish Balay #define CHUNKSIZE 10 18de6a44a3SBarry Smith 195615d1e5SSatish Balay #undef __FUNC__ 205615d1e5SSatish Balay #define __FUNC__ "MatMarkDiag_SeqBAIJ" 21de6a44a3SBarry Smith int MatMarkDiag_SeqBAIJ(Mat A) 22de6a44a3SBarry Smith { 23de6a44a3SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 247fc0212eSBarry Smith int i,j, *diag, m = a->mbs; 25de6a44a3SBarry Smith 263a40ed3dSBarry Smith PetscFunctionBegin; 27de6a44a3SBarry Smith diag = (int *) PetscMalloc( (m+1)*sizeof(int)); CHKPTRQ(diag); 28de6a44a3SBarry Smith PLogObjectMemory(A,(m+1)*sizeof(int)); 297fc0212eSBarry Smith for ( i=0; i<m; i++ ) { 30de6a44a3SBarry Smith for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 31de6a44a3SBarry Smith if (a->j[j] == i) { 32de6a44a3SBarry Smith diag[i] = j; 33de6a44a3SBarry Smith break; 34de6a44a3SBarry Smith } 35de6a44a3SBarry Smith } 36de6a44a3SBarry Smith } 37de6a44a3SBarry Smith a->diag = diag; 383a40ed3dSBarry Smith PetscFunctionReturn(0); 39de6a44a3SBarry Smith } 402593348eSBarry Smith 412593348eSBarry Smith 423b2fbd54SBarry Smith extern int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**); 433b2fbd54SBarry Smith 445615d1e5SSatish Balay #undef __FUNC__ 455615d1e5SSatish Balay #define __FUNC__ "MatGetRowIJ_SeqBAIJ" 463b2fbd54SBarry Smith static int MatGetRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja, 473b2fbd54SBarry Smith PetscTruth *done) 483b2fbd54SBarry Smith { 493b2fbd54SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 503b2fbd54SBarry Smith int ierr, n = a->mbs,i; 513b2fbd54SBarry Smith 523a40ed3dSBarry Smith PetscFunctionBegin; 533b2fbd54SBarry Smith *nn = n; 543a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 553b2fbd54SBarry Smith if (symmetric) { 563b2fbd54SBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(n,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr); 573b2fbd54SBarry Smith } else if (oshift == 1) { 583b2fbd54SBarry Smith /* temporarily add 1 to i and j indices */ 593b2fbd54SBarry Smith int nz = a->i[n] + 1; 603b2fbd54SBarry Smith for ( i=0; i<nz; i++ ) a->j[i]++; 613b2fbd54SBarry Smith for ( i=0; i<n+1; i++ ) a->i[i]++; 623b2fbd54SBarry Smith *ia = a->i; *ja = a->j; 633b2fbd54SBarry Smith } else { 643b2fbd54SBarry Smith *ia = a->i; *ja = a->j; 653b2fbd54SBarry Smith } 663b2fbd54SBarry Smith 673a40ed3dSBarry Smith PetscFunctionReturn(0); 683b2fbd54SBarry Smith } 693b2fbd54SBarry Smith 705615d1e5SSatish Balay #undef __FUNC__ 71d4bb536fSBarry Smith #define __FUNC__ "MatRestoreRowIJ_SeqBAIJ" 723b2fbd54SBarry Smith static int MatRestoreRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja, 733b2fbd54SBarry Smith PetscTruth *done) 743b2fbd54SBarry Smith { 753b2fbd54SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 763b2fbd54SBarry Smith int i,n = a->mbs; 773b2fbd54SBarry Smith 783a40ed3dSBarry Smith PetscFunctionBegin; 793a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 803b2fbd54SBarry Smith if (symmetric) { 813b2fbd54SBarry Smith PetscFree(*ia); 823b2fbd54SBarry Smith PetscFree(*ja); 83af5da2bfSBarry Smith } else if (oshift == 1) { 843b2fbd54SBarry Smith int nz = a->i[n]; 853b2fbd54SBarry Smith for ( i=0; i<nz; i++ ) a->j[i]--; 863b2fbd54SBarry Smith for ( i=0; i<n+1; i++ ) a->i[i]--; 873b2fbd54SBarry Smith } 883a40ed3dSBarry Smith PetscFunctionReturn(0); 893b2fbd54SBarry Smith } 903b2fbd54SBarry Smith 912d61bbb3SSatish Balay #undef __FUNC__ 922d61bbb3SSatish Balay #define __FUNC__ "MatGetBlockSize_SeqBAIJ" 932d61bbb3SSatish Balay int MatGetBlockSize_SeqBAIJ(Mat mat, int *bs) 942d61bbb3SSatish Balay { 952d61bbb3SSatish Balay Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *) mat->data; 962d61bbb3SSatish Balay 972d61bbb3SSatish Balay PetscFunctionBegin; 982d61bbb3SSatish Balay *bs = baij->bs; 992d61bbb3SSatish Balay PetscFunctionReturn(0); 1002d61bbb3SSatish Balay } 1012d61bbb3SSatish Balay 1022d61bbb3SSatish Balay 1032d61bbb3SSatish Balay #undef __FUNC__ 1042d61bbb3SSatish Balay #define __FUNC__ "MatDestroy_SeqBAIJ" 105e1311b90SBarry Smith int MatDestroy_SeqBAIJ(Mat A) 1062d61bbb3SSatish Balay { 1072d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 108e51c0b9cSSatish Balay int ierr; 1092d61bbb3SSatish Balay 11094d884c6SBarry Smith if (--A->refct > 0) PetscFunctionReturn(0); 11194d884c6SBarry Smith 11294d884c6SBarry Smith if (A->mapping) { 11394d884c6SBarry Smith ierr = ISLocalToGlobalMappingDestroy(A->mapping); CHKERRQ(ierr); 11494d884c6SBarry Smith } 11594d884c6SBarry Smith if (A->bmapping) { 11694d884c6SBarry Smith ierr = ISLocalToGlobalMappingDestroy(A->bmapping); CHKERRQ(ierr); 11794d884c6SBarry Smith } 118*61b13de0SBarry Smith if (A->rmap) { 119*61b13de0SBarry Smith ierr = MapDestroy(A->rmap);CHKERRQ(ierr); 120*61b13de0SBarry Smith } 121*61b13de0SBarry Smith if (A->cmap) { 122*61b13de0SBarry Smith ierr = MapDestroy(A->cmap);CHKERRQ(ierr); 123*61b13de0SBarry Smith } 1242d61bbb3SSatish Balay #if defined(USE_PETSC_LOG) 125e1311b90SBarry Smith PLogObjectState((PetscObject) A,"Rows=%d, Cols=%d, NZ=%d",a->m,a->n,a->nz); 1262d61bbb3SSatish Balay #endif 1272d61bbb3SSatish Balay PetscFree(a->a); 1282d61bbb3SSatish Balay if (!a->singlemalloc) { PetscFree(a->i); PetscFree(a->j);} 1292d61bbb3SSatish Balay if (a->diag) PetscFree(a->diag); 1302d61bbb3SSatish Balay if (a->ilen) PetscFree(a->ilen); 1312d61bbb3SSatish Balay if (a->imax) PetscFree(a->imax); 1322d61bbb3SSatish Balay if (a->solve_work) PetscFree(a->solve_work); 1332d61bbb3SSatish Balay if (a->mult_work) PetscFree(a->mult_work); 134e51c0b9cSSatish Balay if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} 1352d61bbb3SSatish Balay PetscFree(a); 1362d61bbb3SSatish Balay PLogObjectDestroy(A); 1372d61bbb3SSatish Balay PetscHeaderDestroy(A); 1382d61bbb3SSatish Balay PetscFunctionReturn(0); 1392d61bbb3SSatish Balay } 1402d61bbb3SSatish Balay 1412d61bbb3SSatish Balay #undef __FUNC__ 1422d61bbb3SSatish Balay #define __FUNC__ "MatSetOption_SeqBAIJ" 1432d61bbb3SSatish Balay int MatSetOption_SeqBAIJ(Mat A,MatOption op) 1442d61bbb3SSatish Balay { 1452d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 1462d61bbb3SSatish Balay 1472d61bbb3SSatish Balay PetscFunctionBegin; 1482d61bbb3SSatish Balay if (op == MAT_ROW_ORIENTED) a->roworiented = 1; 1492d61bbb3SSatish Balay else if (op == MAT_COLUMN_ORIENTED) a->roworiented = 0; 1502d61bbb3SSatish Balay else if (op == MAT_COLUMNS_SORTED) a->sorted = 1; 1512d61bbb3SSatish Balay else if (op == MAT_COLUMNS_UNSORTED) a->sorted = 0; 1522d61bbb3SSatish Balay else if (op == MAT_NO_NEW_NONZERO_LOCATIONS) a->nonew = 1; 1532d61bbb3SSatish Balay else if (op == MAT_NEW_NONZERO_LOCATION_ERROR) a->nonew = -1; 1542d61bbb3SSatish Balay else if (op == MAT_NEW_NONZERO_ALLOCATION_ERROR) a->nonew = -2; 1552d61bbb3SSatish Balay else if (op == MAT_YES_NEW_NONZERO_LOCATIONS) a->nonew = 0; 1562d61bbb3SSatish Balay else if (op == MAT_ROWS_SORTED || 1572d61bbb3SSatish Balay op == MAT_ROWS_UNSORTED || 1582d61bbb3SSatish Balay op == MAT_SYMMETRIC || 1592d61bbb3SSatish Balay op == MAT_STRUCTURALLY_SYMMETRIC || 1602d61bbb3SSatish Balay op == MAT_YES_NEW_DIAGONALS || 161b51ba29fSSatish Balay op == MAT_IGNORE_OFF_PROC_ENTRIES || 162b51ba29fSSatish Balay op == MAT_USE_HASH_TABLE) { 163981c4779SBarry Smith PLogInfo(A,"MatSetOption_SeqBAIJ:Option ignored\n"); 1642d61bbb3SSatish Balay } else if (op == MAT_NO_NEW_DIAGONALS) { 1652d61bbb3SSatish Balay SETERRQ(PETSC_ERR_SUP,0,"MAT_NO_NEW_DIAGONALS"); 1662d61bbb3SSatish Balay } else { 1672d61bbb3SSatish Balay SETERRQ(PETSC_ERR_SUP,0,"unknown option"); 1682d61bbb3SSatish Balay } 1692d61bbb3SSatish Balay PetscFunctionReturn(0); 1702d61bbb3SSatish Balay } 1712d61bbb3SSatish Balay 1722d61bbb3SSatish Balay 1732d61bbb3SSatish Balay #undef __FUNC__ 1742d61bbb3SSatish Balay #define __FUNC__ "MatGetSize_SeqBAIJ" 1752d61bbb3SSatish Balay int MatGetSize_SeqBAIJ(Mat A,int *m,int *n) 1762d61bbb3SSatish Balay { 1772d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 1782d61bbb3SSatish Balay 1792d61bbb3SSatish Balay PetscFunctionBegin; 1802d61bbb3SSatish Balay if (m) *m = a->m; 1812d61bbb3SSatish Balay if (n) *n = a->n; 1822d61bbb3SSatish Balay PetscFunctionReturn(0); 1832d61bbb3SSatish Balay } 1842d61bbb3SSatish Balay 1852d61bbb3SSatish Balay #undef __FUNC__ 1862d61bbb3SSatish Balay #define __FUNC__ "MatGetOwnershipRange_SeqBAIJ" 1872d61bbb3SSatish Balay int MatGetOwnershipRange_SeqBAIJ(Mat A,int *m,int *n) 1882d61bbb3SSatish Balay { 1892d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 1902d61bbb3SSatish Balay 1912d61bbb3SSatish Balay PetscFunctionBegin; 1922d61bbb3SSatish Balay *m = 0; *n = a->m; 1932d61bbb3SSatish Balay PetscFunctionReturn(0); 1942d61bbb3SSatish Balay } 1952d61bbb3SSatish Balay 1962d61bbb3SSatish Balay #undef __FUNC__ 1972d61bbb3SSatish Balay #define __FUNC__ "MatGetRow_SeqBAIJ" 1982d61bbb3SSatish Balay int MatGetRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 1992d61bbb3SSatish Balay { 2002d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 2012d61bbb3SSatish Balay int itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*idx_i,bs2; 2022d61bbb3SSatish Balay Scalar *aa,*v_i,*aa_i; 2032d61bbb3SSatish Balay 2042d61bbb3SSatish Balay PetscFunctionBegin; 2052d61bbb3SSatish Balay bs = a->bs; 2062d61bbb3SSatish Balay ai = a->i; 2072d61bbb3SSatish Balay aj = a->j; 2082d61bbb3SSatish Balay aa = a->a; 2092d61bbb3SSatish Balay bs2 = a->bs2; 2102d61bbb3SSatish Balay 2112d61bbb3SSatish Balay if (row < 0 || row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row out of range"); 2122d61bbb3SSatish Balay 2132d61bbb3SSatish Balay bn = row/bs; /* Block number */ 2142d61bbb3SSatish Balay bp = row % bs; /* Block Position */ 2152d61bbb3SSatish Balay M = ai[bn+1] - ai[bn]; 2162d61bbb3SSatish Balay *nz = bs*M; 2172d61bbb3SSatish Balay 2182d61bbb3SSatish Balay if (v) { 2192d61bbb3SSatish Balay *v = 0; 2202d61bbb3SSatish Balay if (*nz) { 2212d61bbb3SSatish Balay *v = (Scalar *) PetscMalloc( (*nz)*sizeof(Scalar) ); CHKPTRQ(*v); 2222d61bbb3SSatish Balay for ( i=0; i<M; i++ ) { /* for each block in the block row */ 2232d61bbb3SSatish Balay v_i = *v + i*bs; 2242d61bbb3SSatish Balay aa_i = aa + bs2*(ai[bn] + i); 2252d61bbb3SSatish Balay for ( j=bp,k=0; j<bs2; j+=bs,k++ ) {v_i[k] = aa_i[j];} 2262d61bbb3SSatish Balay } 2272d61bbb3SSatish Balay } 2282d61bbb3SSatish Balay } 2292d61bbb3SSatish Balay 2302d61bbb3SSatish Balay if (idx) { 2312d61bbb3SSatish Balay *idx = 0; 2322d61bbb3SSatish Balay if (*nz) { 2332d61bbb3SSatish Balay *idx = (int *) PetscMalloc( (*nz)*sizeof(int) ); CHKPTRQ(*idx); 2342d61bbb3SSatish Balay for ( i=0; i<M; i++ ) { /* for each block in the block row */ 2352d61bbb3SSatish Balay idx_i = *idx + i*bs; 2362d61bbb3SSatish Balay itmp = bs*aj[ai[bn] + i]; 2372d61bbb3SSatish Balay for ( j=0; j<bs; j++ ) {idx_i[j] = itmp++;} 2382d61bbb3SSatish Balay } 2392d61bbb3SSatish Balay } 2402d61bbb3SSatish Balay } 2412d61bbb3SSatish Balay PetscFunctionReturn(0); 2422d61bbb3SSatish Balay } 2432d61bbb3SSatish Balay 2442d61bbb3SSatish Balay #undef __FUNC__ 2452d61bbb3SSatish Balay #define __FUNC__ "MatRestoreRow_SeqBAIJ" 2462d61bbb3SSatish Balay int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 2472d61bbb3SSatish Balay { 2482d61bbb3SSatish Balay PetscFunctionBegin; 2492d61bbb3SSatish Balay if (idx) {if (*idx) PetscFree(*idx);} 2502d61bbb3SSatish Balay if (v) {if (*v) PetscFree(*v);} 2512d61bbb3SSatish Balay PetscFunctionReturn(0); 2522d61bbb3SSatish Balay } 2532d61bbb3SSatish Balay 2542d61bbb3SSatish Balay #undef __FUNC__ 2552d61bbb3SSatish Balay #define __FUNC__ "MatTranspose_SeqBAIJ" 2562d61bbb3SSatish Balay int MatTranspose_SeqBAIJ(Mat A,Mat *B) 2572d61bbb3SSatish Balay { 2582d61bbb3SSatish Balay Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data; 2592d61bbb3SSatish Balay Mat C; 2602d61bbb3SSatish Balay int i,j,k,ierr,*aj=a->j,*ai=a->i,bs=a->bs,mbs=a->mbs,nbs=a->nbs,len,*col; 2612d61bbb3SSatish Balay int *rows,*cols,bs2=a->bs2; 2622d61bbb3SSatish Balay Scalar *array=a->a; 2632d61bbb3SSatish Balay 2642d61bbb3SSatish Balay PetscFunctionBegin; 2652d61bbb3SSatish Balay if (B==PETSC_NULL && mbs!=nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Square matrix only for in-place"); 2662d61bbb3SSatish Balay col = (int *) PetscMalloc((1+nbs)*sizeof(int)); CHKPTRQ(col); 2672d61bbb3SSatish Balay PetscMemzero(col,(1+nbs)*sizeof(int)); 2682d61bbb3SSatish Balay 2692d61bbb3SSatish Balay for ( i=0; i<ai[mbs]; i++ ) col[aj[i]] += 1; 2702d61bbb3SSatish Balay ierr = MatCreateSeqBAIJ(A->comm,bs,a->n,a->m,PETSC_NULL,col,&C); CHKERRQ(ierr); 2712d61bbb3SSatish Balay PetscFree(col); 2722d61bbb3SSatish Balay rows = (int *) PetscMalloc(2*bs*sizeof(int)); CHKPTRQ(rows); 2732d61bbb3SSatish Balay cols = rows + bs; 2742d61bbb3SSatish Balay for ( i=0; i<mbs; i++ ) { 2752d61bbb3SSatish Balay cols[0] = i*bs; 2762d61bbb3SSatish Balay for (k=1; k<bs; k++ ) cols[k] = cols[k-1] + 1; 2772d61bbb3SSatish Balay len = ai[i+1] - ai[i]; 2782d61bbb3SSatish Balay for ( j=0; j<len; j++ ) { 2792d61bbb3SSatish Balay rows[0] = (*aj++)*bs; 2802d61bbb3SSatish Balay for (k=1; k<bs; k++ ) rows[k] = rows[k-1] + 1; 2812d61bbb3SSatish Balay ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES); CHKERRQ(ierr); 2822d61bbb3SSatish Balay array += bs2; 2832d61bbb3SSatish Balay } 2842d61bbb3SSatish Balay } 2852d61bbb3SSatish Balay PetscFree(rows); 2862d61bbb3SSatish Balay 2872d61bbb3SSatish Balay ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 2882d61bbb3SSatish Balay ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 2892d61bbb3SSatish Balay 2902d61bbb3SSatish Balay if (B != PETSC_NULL) { 2912d61bbb3SSatish Balay *B = C; 2922d61bbb3SSatish Balay } else { 293f830108cSBarry Smith PetscOps *Abops; 294cc2dc46cSBarry Smith MatOps Aops; 295f830108cSBarry Smith 2962d61bbb3SSatish Balay /* This isn't really an in-place transpose */ 2972d61bbb3SSatish Balay PetscFree(a->a); 2982d61bbb3SSatish Balay if (!a->singlemalloc) {PetscFree(a->i); PetscFree(a->j);} 2992d61bbb3SSatish Balay if (a->diag) PetscFree(a->diag); 3002d61bbb3SSatish Balay if (a->ilen) PetscFree(a->ilen); 3012d61bbb3SSatish Balay if (a->imax) PetscFree(a->imax); 3022d61bbb3SSatish Balay if (a->solve_work) PetscFree(a->solve_work); 3032d61bbb3SSatish Balay PetscFree(a); 304f830108cSBarry Smith 305f830108cSBarry Smith /* 306f830108cSBarry Smith This is horrible, horrible code. We need to keep the 307f830108cSBarry Smith A pointers for the bops and ops but copy everything 308f830108cSBarry Smith else from C. 309f830108cSBarry Smith */ 310f830108cSBarry Smith Abops = A->bops; 311f830108cSBarry Smith Aops = A->ops; 3122d61bbb3SSatish Balay PetscMemcpy(A,C,sizeof(struct _p_Mat)); 313f830108cSBarry Smith A->bops = Abops; 314f830108cSBarry Smith A->ops = Aops; 31527a8da17SBarry Smith A->qlist = 0; 316f830108cSBarry Smith 3172d61bbb3SSatish Balay PetscHeaderDestroy(C); 3182d61bbb3SSatish Balay } 3192d61bbb3SSatish Balay PetscFunctionReturn(0); 3202d61bbb3SSatish Balay } 3212d61bbb3SSatish Balay 3222d61bbb3SSatish Balay 3232d61bbb3SSatish Balay 3243b2fbd54SBarry Smith 3255615d1e5SSatish Balay #undef __FUNC__ 326d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Binary" 327b6490206SBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,Viewer viewer) 3282593348eSBarry Smith { 329b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 3309df24120SSatish Balay int i, fd, *col_lens, ierr, bs = a->bs,count,*jj,j,k,l,bs2=a->bs2; 331b6490206SBarry Smith Scalar *aa; 3322593348eSBarry Smith 3333a40ed3dSBarry Smith PetscFunctionBegin; 33490ace30eSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr); 3352593348eSBarry Smith col_lens = (int *) PetscMalloc((4+a->m)*sizeof(int));CHKPTRQ(col_lens); 3362593348eSBarry Smith col_lens[0] = MAT_COOKIE; 3373b2fbd54SBarry Smith 3382593348eSBarry Smith col_lens[1] = a->m; 3392593348eSBarry Smith col_lens[2] = a->n; 3407e67e3f9SSatish Balay col_lens[3] = a->nz*bs2; 3412593348eSBarry Smith 3422593348eSBarry Smith /* store lengths of each row and write (including header) to file */ 343b6490206SBarry Smith count = 0; 344b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 345b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 346b6490206SBarry Smith col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]); 347b6490206SBarry Smith } 3482593348eSBarry Smith } 3490752156aSBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+a->m,PETSC_INT,1); CHKERRQ(ierr); 3502593348eSBarry Smith PetscFree(col_lens); 3512593348eSBarry Smith 3522593348eSBarry Smith /* store column indices (zero start index) */ 35366963ce1SSatish Balay jj = (int *) PetscMalloc( (a->nz+1)*bs2*sizeof(int) ); CHKPTRQ(jj); 354b6490206SBarry Smith count = 0; 355b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 356b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 357b6490206SBarry Smith for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 358b6490206SBarry Smith for ( l=0; l<bs; l++ ) { 359b6490206SBarry Smith jj[count++] = bs*a->j[k] + l; 3602593348eSBarry Smith } 3612593348eSBarry Smith } 362b6490206SBarry Smith } 363b6490206SBarry Smith } 3640752156aSBarry Smith ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0); CHKERRQ(ierr); 365b6490206SBarry Smith PetscFree(jj); 3662593348eSBarry Smith 3672593348eSBarry Smith /* store nonzero values */ 36866963ce1SSatish Balay aa = (Scalar *) PetscMalloc((a->nz+1)*bs2*sizeof(Scalar)); CHKPTRQ(aa); 369b6490206SBarry Smith count = 0; 370b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 371b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 372b6490206SBarry Smith for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 373b6490206SBarry Smith for ( l=0; l<bs; l++ ) { 3747e67e3f9SSatish Balay aa[count++] = a->a[bs2*k + l*bs + j]; 375b6490206SBarry Smith } 376b6490206SBarry Smith } 377b6490206SBarry Smith } 378b6490206SBarry Smith } 3790752156aSBarry Smith ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0); CHKERRQ(ierr); 380b6490206SBarry Smith PetscFree(aa); 3813a40ed3dSBarry Smith PetscFunctionReturn(0); 3822593348eSBarry Smith } 3832593348eSBarry Smith 3845615d1e5SSatish Balay #undef __FUNC__ 385d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_ASCII" 386b6490206SBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,Viewer viewer) 3872593348eSBarry Smith { 388b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 3899df24120SSatish Balay int ierr, i,j,format,bs = a->bs,k,l,bs2=a->bs2; 3902593348eSBarry Smith FILE *fd; 3912593348eSBarry Smith char *outputname; 3922593348eSBarry Smith 3933a40ed3dSBarry Smith PetscFunctionBegin; 39490ace30eSBarry Smith ierr = ViewerASCIIGetPointer(viewer,&fd); CHKERRQ(ierr); 3952593348eSBarry Smith ierr = ViewerFileGetOutputname_Private(viewer,&outputname);CHKERRQ(ierr); 39690ace30eSBarry Smith ierr = ViewerGetFormat(viewer,&format); 397639f9d9dSBarry Smith if (format == VIEWER_FORMAT_ASCII_INFO || format == VIEWER_FORMAT_ASCII_INFO_LONG) { 3987ddc982cSLois Curfman McInnes fprintf(fd," block size is %d\n",bs); 3992593348eSBarry Smith } 400639f9d9dSBarry Smith else if (format == VIEWER_FORMAT_ASCII_MATLAB) { 401a8c6a408SBarry Smith SETERRQ(PETSC_ERR_SUP,0,"Matlab format not supported"); 4022593348eSBarry Smith } 403639f9d9dSBarry Smith else if (format == VIEWER_FORMAT_ASCII_COMMON) { 40444cd7ae7SLois Curfman McInnes for ( i=0; i<a->mbs; i++ ) { 40544cd7ae7SLois Curfman McInnes for ( j=0; j<bs; j++ ) { 40644cd7ae7SLois Curfman McInnes fprintf(fd,"row %d:",i*bs+j); 40744cd7ae7SLois Curfman McInnes for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 40844cd7ae7SLois Curfman McInnes for ( l=0; l<bs; l++ ) { 4093a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX) 410e20fef11SSatish Balay if (PetscImaginary(a->a[bs2*k + l*bs + j]) > 0.0 && PetscReal(a->a[bs2*k + l*bs + j]) != 0.0) 41144cd7ae7SLois Curfman McInnes fprintf(fd," %d %g + %g i",bs*a->j[k]+l, 412e20fef11SSatish Balay PetscReal(a->a[bs2*k + l*bs + j]),PetscImaginary(a->a[bs2*k + l*bs + j])); 413e20fef11SSatish Balay else if (PetscImaginary(a->a[bs2*k + l*bs + j]) < 0.0 && PetscReal(a->a[bs2*k + l*bs + j]) != 0.0) 414766eeae4SLois Curfman McInnes fprintf(fd," %d %g - %g i",bs*a->j[k]+l, 415e20fef11SSatish Balay PetscReal(a->a[bs2*k + l*bs + j]),-PetscImaginary(a->a[bs2*k + l*bs + j])); 416e20fef11SSatish Balay else if (PetscReal(a->a[bs2*k + l*bs + j]) != 0.0) 417e20fef11SSatish Balay fprintf(fd," %d %g ",bs*a->j[k]+l,PetscReal(a->a[bs2*k + l*bs + j])); 41844cd7ae7SLois Curfman McInnes #else 41944cd7ae7SLois Curfman McInnes if (a->a[bs2*k + l*bs + j] != 0.0) 42044cd7ae7SLois Curfman McInnes fprintf(fd," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]); 42144cd7ae7SLois Curfman McInnes #endif 42244cd7ae7SLois Curfman McInnes } 42344cd7ae7SLois Curfman McInnes } 42444cd7ae7SLois Curfman McInnes fprintf(fd,"\n"); 42544cd7ae7SLois Curfman McInnes } 42644cd7ae7SLois Curfman McInnes } 42744cd7ae7SLois Curfman McInnes } 4282593348eSBarry Smith else { 429b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 430b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 431b6490206SBarry Smith fprintf(fd,"row %d:",i*bs+j); 432b6490206SBarry Smith for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 433b6490206SBarry Smith for ( l=0; l<bs; l++ ) { 4343a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX) 435e20fef11SSatish Balay if (PetscImaginary(a->a[bs2*k + l*bs + j]) > 0.0) { 43688685aaeSLois Curfman McInnes fprintf(fd," %d %g + %g i",bs*a->j[k]+l, 437e20fef11SSatish Balay PetscReal(a->a[bs2*k + l*bs + j]),PetscImaginary(a->a[bs2*k + l*bs + j])); 43888685aaeSLois Curfman McInnes } 439e20fef11SSatish Balay else if (PetscImaginary(a->a[bs2*k + l*bs + j]) < 0.0) { 440766eeae4SLois Curfman McInnes fprintf(fd," %d %g - %g i",bs*a->j[k]+l, 441e20fef11SSatish Balay PetscReal(a->a[bs2*k + l*bs + j]),-PetscImaginary(a->a[bs2*k + l*bs + j])); 442766eeae4SLois Curfman McInnes } 44388685aaeSLois Curfman McInnes else { 444e20fef11SSatish Balay fprintf(fd," %d %g ",bs*a->j[k]+l,PetscReal(a->a[bs2*k + l*bs + j])); 44588685aaeSLois Curfman McInnes } 44688685aaeSLois Curfman McInnes #else 4477e67e3f9SSatish Balay fprintf(fd," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]); 44888685aaeSLois Curfman McInnes #endif 4492593348eSBarry Smith } 4502593348eSBarry Smith } 4512593348eSBarry Smith fprintf(fd,"\n"); 4522593348eSBarry Smith } 4532593348eSBarry Smith } 454b6490206SBarry Smith } 4552593348eSBarry Smith fflush(fd); 4563a40ed3dSBarry Smith PetscFunctionReturn(0); 4572593348eSBarry Smith } 4582593348eSBarry Smith 4595615d1e5SSatish Balay #undef __FUNC__ 460d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Draw" 4613270192aSSatish Balay static int MatView_SeqBAIJ_Draw(Mat A,Viewer viewer) 4623270192aSSatish Balay { 4633270192aSSatish Balay Mat_SeqBAIJ *a=(Mat_SeqBAIJ *) A->data; 4643270192aSSatish Balay int row,ierr,i,j,k,l,mbs=a->mbs,pause,color,bs=a->bs,bs2=a->bs2; 4653270192aSSatish Balay double xl,yl,xr,yr,w,h,xc,yc,scale = 1.0,x_l,x_r,y_l,y_r; 4663270192aSSatish Balay Scalar *aa; 4673270192aSSatish Balay Draw draw; 4683270192aSSatish Balay DrawButton button; 4693270192aSSatish Balay PetscTruth isnull; 4703270192aSSatish Balay 4713a40ed3dSBarry Smith PetscFunctionBegin; 4723a40ed3dSBarry Smith ierr = ViewerDrawGetDraw(viewer,&draw);CHKERRQ(ierr); 4733a40ed3dSBarry Smith ierr = DrawIsNull(draw,&isnull); CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0); 4743270192aSSatish Balay 4753270192aSSatish Balay xr = a->n; yr = a->m; h = yr/10.0; w = xr/10.0; 4763270192aSSatish Balay xr += w; yr += h; xl = -w; yl = -h; 4773270192aSSatish Balay ierr = DrawSetCoordinates(draw,xl,yl,xr,yr); CHKERRQ(ierr); 4783270192aSSatish Balay /* loop over matrix elements drawing boxes */ 4793270192aSSatish Balay color = DRAW_BLUE; 4803270192aSSatish Balay for ( i=0,row=0; i<mbs; i++,row+=bs ) { 4813270192aSSatish Balay for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 4823270192aSSatish Balay y_l = a->m - row - 1.0; y_r = y_l + 1.0; 4833270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 4843270192aSSatish Balay aa = a->a + j*bs2; 4853270192aSSatish Balay for ( k=0; k<bs; k++ ) { 4863270192aSSatish Balay for ( l=0; l<bs; l++ ) { 4873270192aSSatish Balay if (PetscReal(*aa++) >= 0.) continue; 488b34f160eSSatish Balay DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color); 4893270192aSSatish Balay } 4903270192aSSatish Balay } 4913270192aSSatish Balay } 4923270192aSSatish Balay } 4933270192aSSatish Balay color = DRAW_CYAN; 4943270192aSSatish Balay for ( i=0,row=0; i<mbs; i++,row+=bs ) { 4953270192aSSatish Balay for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 4963270192aSSatish Balay y_l = a->m - row - 1.0; y_r = y_l + 1.0; 4973270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 4983270192aSSatish Balay aa = a->a + j*bs2; 4993270192aSSatish Balay for ( k=0; k<bs; k++ ) { 5003270192aSSatish Balay for ( l=0; l<bs; l++ ) { 5013270192aSSatish Balay if (PetscReal(*aa++) != 0.) continue; 502b34f160eSSatish Balay DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color); 5033270192aSSatish Balay } 5043270192aSSatish Balay } 5053270192aSSatish Balay } 5063270192aSSatish Balay } 5073270192aSSatish Balay 5083270192aSSatish Balay color = DRAW_RED; 5093270192aSSatish Balay for ( i=0,row=0; i<mbs; i++,row+=bs ) { 5103270192aSSatish Balay for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 5113270192aSSatish Balay y_l = a->m - row - 1.0; y_r = y_l + 1.0; 5123270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5133270192aSSatish Balay aa = a->a + j*bs2; 5143270192aSSatish Balay for ( k=0; k<bs; k++ ) { 5153270192aSSatish Balay for ( l=0; l<bs; l++ ) { 5163270192aSSatish Balay if (PetscReal(*aa++) <= 0.) continue; 517b34f160eSSatish Balay DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color); 5183270192aSSatish Balay } 5193270192aSSatish Balay } 5203270192aSSatish Balay } 5213270192aSSatish Balay } 5223270192aSSatish Balay 52355843e3eSBarry Smith DrawSynchronizedFlush(draw); 5243270192aSSatish Balay DrawGetPause(draw,&pause); 5253a40ed3dSBarry Smith if (pause >= 0) { PetscSleep(pause); PetscFunctionReturn(0);} 5263270192aSSatish Balay 5273270192aSSatish Balay /* allow the matrix to zoom or shrink */ 52855843e3eSBarry Smith ierr = DrawSynchronizedGetMouseButton(draw,&button,&xc,&yc,0,0); 5293270192aSSatish Balay while (button != BUTTON_RIGHT) { 53055843e3eSBarry Smith DrawSynchronizedClear(draw); 5313270192aSSatish Balay if (button == BUTTON_LEFT) scale = .5; 5323270192aSSatish Balay else if (button == BUTTON_CENTER) scale = 2.; 5333270192aSSatish Balay xl = scale*(xl + w - xc) + xc - w*scale; 5343270192aSSatish Balay xr = scale*(xr - w - xc) + xc + w*scale; 5353270192aSSatish Balay yl = scale*(yl + h - yc) + yc - h*scale; 5363270192aSSatish Balay yr = scale*(yr - h - yc) + yc + h*scale; 5373270192aSSatish Balay w *= scale; h *= scale; 5383270192aSSatish Balay ierr = DrawSetCoordinates(draw,xl,yl,xr,yr); CHKERRQ(ierr); 5393270192aSSatish Balay color = DRAW_BLUE; 5403270192aSSatish Balay for ( i=0,row=0; i<mbs; i++,row+=bs ) { 5413270192aSSatish Balay for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 5423270192aSSatish Balay y_l = a->m - row - 1.0; y_r = y_l + 1.0; 5433270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5443270192aSSatish Balay aa = a->a + j*bs2; 5453270192aSSatish Balay for ( k=0; k<bs; k++ ) { 5463270192aSSatish Balay for ( l=0; l<bs; l++ ) { 5473270192aSSatish Balay if (PetscReal(*aa++) >= 0.) continue; 548b34f160eSSatish Balay DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color); 5493270192aSSatish Balay } 5503270192aSSatish Balay } 5513270192aSSatish Balay } 5523270192aSSatish Balay } 5533270192aSSatish Balay color = DRAW_CYAN; 5543270192aSSatish Balay for ( i=0,row=0; i<mbs; i++,row+=bs ) { 5553270192aSSatish Balay for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 5563270192aSSatish Balay y_l = a->m - row - 1.0; y_r = y_l + 1.0; 5573270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5583270192aSSatish Balay aa = a->a + j*bs2; 5593270192aSSatish Balay for ( k=0; k<bs; k++ ) { 5603270192aSSatish Balay for ( l=0; l<bs; l++ ) { 5613270192aSSatish Balay if (PetscReal(*aa++) != 0.) continue; 562b34f160eSSatish Balay DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color); 5633270192aSSatish Balay } 5643270192aSSatish Balay } 5653270192aSSatish Balay } 5663270192aSSatish Balay } 5673270192aSSatish Balay 5683270192aSSatish Balay color = DRAW_RED; 5693270192aSSatish Balay for ( i=0,row=0; i<mbs; i++,row+=bs ) { 5703270192aSSatish Balay for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 5713270192aSSatish Balay y_l = a->m - row - 1.0; y_r = y_l + 1.0; 5723270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5733270192aSSatish Balay aa = a->a + j*bs2; 5743270192aSSatish Balay for ( k=0; k<bs; k++ ) { 5753270192aSSatish Balay for ( l=0; l<bs; l++ ) { 5763270192aSSatish Balay if (PetscReal(*aa++) <= 0.) continue; 577b34f160eSSatish Balay DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color); 5783270192aSSatish Balay } 5793270192aSSatish Balay } 5803270192aSSatish Balay } 5813270192aSSatish Balay } 58255843e3eSBarry Smith ierr = DrawSynchronizedGetMouseButton(draw,&button,&xc,&yc,0,0); 5833270192aSSatish Balay } 5843a40ed3dSBarry Smith PetscFunctionReturn(0); 5853270192aSSatish Balay } 5863270192aSSatish Balay 5875615d1e5SSatish Balay #undef __FUNC__ 588d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ" 589e1311b90SBarry Smith int MatView_SeqBAIJ(Mat A,Viewer viewer) 5902593348eSBarry Smith { 59119bcc07fSBarry Smith ViewerType vtype; 59219bcc07fSBarry Smith int ierr; 5932593348eSBarry Smith 5943a40ed3dSBarry Smith PetscFunctionBegin; 59519bcc07fSBarry Smith ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr); 59619bcc07fSBarry Smith if (vtype == MATLAB_VIEWER) { 597a8c6a408SBarry Smith SETERRQ(PETSC_ERR_SUP,0,"Matlab viewer not supported"); 5983a40ed3dSBarry Smith } else if (vtype == ASCII_FILE_VIEWER || vtype == ASCII_FILES_VIEWER){ 5993a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr); 6003a40ed3dSBarry Smith } else if (vtype == BINARY_FILE_VIEWER) { 6013a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr); 6023a40ed3dSBarry Smith } else if (vtype == DRAW_VIEWER) { 6033a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr); 6045cd90555SBarry Smith } else { 6055cd90555SBarry Smith SETERRQ(1,1,"Viewer type not supported by PETSc object"); 6062593348eSBarry Smith } 6073a40ed3dSBarry Smith PetscFunctionReturn(0); 6082593348eSBarry Smith } 609b6490206SBarry Smith 610cd0e1443SSatish Balay 6115615d1e5SSatish Balay #undef __FUNC__ 6122d61bbb3SSatish Balay #define __FUNC__ "MatGetValues_SeqBAIJ" 6132d61bbb3SSatish Balay int MatGetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v) 614cd0e1443SSatish Balay { 615cd0e1443SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 6162d61bbb3SSatish Balay int *rp, k, low, high, t, row, nrow, i, col, l, *aj = a->j; 6172d61bbb3SSatish Balay int *ai = a->i, *ailen = a->ilen; 6182d61bbb3SSatish Balay int brow,bcol,ridx,cidx,bs=a->bs,bs2=a->bs2; 6192d61bbb3SSatish Balay Scalar *ap, *aa = a->a, zero = 0.0; 620cd0e1443SSatish Balay 6213a40ed3dSBarry Smith PetscFunctionBegin; 6222d61bbb3SSatish Balay for ( k=0; k<m; k++ ) { /* loop over rows */ 623cd0e1443SSatish Balay row = im[k]; brow = row/bs; 624a8c6a408SBarry Smith if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row"); 625a8c6a408SBarry Smith if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 6262d61bbb3SSatish Balay rp = aj + ai[brow] ; ap = aa + bs2*ai[brow] ; 6272c3acbe9SBarry Smith nrow = ailen[brow]; 6282d61bbb3SSatish Balay for ( l=0; l<n; l++ ) { /* loop over columns */ 629a8c6a408SBarry Smith if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column"); 630a8c6a408SBarry Smith if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 6312d61bbb3SSatish Balay col = in[l] ; 6322d61bbb3SSatish Balay bcol = col/bs; 6332d61bbb3SSatish Balay cidx = col%bs; 6342d61bbb3SSatish Balay ridx = row%bs; 6352d61bbb3SSatish Balay high = nrow; 6362d61bbb3SSatish Balay low = 0; /* assume unsorted */ 6372d61bbb3SSatish Balay while (high-low > 5) { 638cd0e1443SSatish Balay t = (low+high)/2; 639cd0e1443SSatish Balay if (rp[t] > bcol) high = t; 640cd0e1443SSatish Balay else low = t; 641cd0e1443SSatish Balay } 642cd0e1443SSatish Balay for ( i=low; i<high; i++ ) { 643cd0e1443SSatish Balay if (rp[i] > bcol) break; 644cd0e1443SSatish Balay if (rp[i] == bcol) { 6452d61bbb3SSatish Balay *v++ = ap[bs2*i+bs*cidx+ridx]; 6462d61bbb3SSatish Balay goto finished; 647cd0e1443SSatish Balay } 648cd0e1443SSatish Balay } 6492d61bbb3SSatish Balay *v++ = zero; 6502d61bbb3SSatish Balay finished:; 651cd0e1443SSatish Balay } 652cd0e1443SSatish Balay } 6533a40ed3dSBarry Smith PetscFunctionReturn(0); 654cd0e1443SSatish Balay } 655cd0e1443SSatish Balay 6562d61bbb3SSatish Balay 6575615d1e5SSatish Balay #undef __FUNC__ 65805a5f48eSSatish Balay #define __FUNC__ "MatSetValuesBlocked_SeqBAIJ" 65992c4ed94SBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is) 66092c4ed94SBarry Smith { 66192c4ed94SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 6628a84c255SSatish Balay int *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted; 663dd9472c6SBarry Smith int *imax=a->imax,*ai=a->i,*ailen=a->ilen, roworiented=a->roworiented; 664dd9472c6SBarry Smith int *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval; 6650e324ae4SSatish Balay Scalar *ap,*value=v,*aa=a->a,*bap; 66692c4ed94SBarry Smith 6673a40ed3dSBarry Smith PetscFunctionBegin; 6680e324ae4SSatish Balay if (roworiented) { 6690e324ae4SSatish Balay stepval = (n-1)*bs; 6700e324ae4SSatish Balay } else { 6710e324ae4SSatish Balay stepval = (m-1)*bs; 6720e324ae4SSatish Balay } 67392c4ed94SBarry Smith for ( k=0; k<m; k++ ) { /* loop over added rows */ 67492c4ed94SBarry Smith row = im[k]; 6753a40ed3dSBarry Smith #if defined(USE_PETSC_BOPT_g) 676a8c6a408SBarry Smith if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row"); 677a8c6a408SBarry Smith if (row >= a->mbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 67892c4ed94SBarry Smith #endif 67992c4ed94SBarry Smith rp = aj + ai[row]; 68092c4ed94SBarry Smith ap = aa + bs2*ai[row]; 68192c4ed94SBarry Smith rmax = imax[row]; 68292c4ed94SBarry Smith nrow = ailen[row]; 68392c4ed94SBarry Smith low = 0; 68492c4ed94SBarry Smith for ( l=0; l<n; l++ ) { /* loop over added columns */ 6853a40ed3dSBarry Smith #if defined(USE_PETSC_BOPT_g) 686a8c6a408SBarry Smith if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column"); 687a8c6a408SBarry Smith if (in[l] >= a->nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 68892c4ed94SBarry Smith #endif 68992c4ed94SBarry Smith col = in[l]; 69092c4ed94SBarry Smith if (roworiented) { 6910e324ae4SSatish Balay value = v + k*(stepval+bs)*bs + l*bs; 6920e324ae4SSatish Balay } else { 6930e324ae4SSatish Balay value = v + l*(stepval+bs)*bs + k*bs; 69492c4ed94SBarry Smith } 69592c4ed94SBarry Smith if (!sorted) low = 0; high = nrow; 69692c4ed94SBarry Smith while (high-low > 7) { 69792c4ed94SBarry Smith t = (low+high)/2; 69892c4ed94SBarry Smith if (rp[t] > col) high = t; 69992c4ed94SBarry Smith else low = t; 70092c4ed94SBarry Smith } 70192c4ed94SBarry Smith for ( i=low; i<high; i++ ) { 70292c4ed94SBarry Smith if (rp[i] > col) break; 70392c4ed94SBarry Smith if (rp[i] == col) { 7048a84c255SSatish Balay bap = ap + bs2*i; 7050e324ae4SSatish Balay if (roworiented) { 7068a84c255SSatish Balay if (is == ADD_VALUES) { 707dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval ) { 708dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs ) { 7098a84c255SSatish Balay bap[jj] += *value++; 710dd9472c6SBarry Smith } 711dd9472c6SBarry Smith } 7120e324ae4SSatish Balay } else { 713dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval ) { 714dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs ) { 7150e324ae4SSatish Balay bap[jj] = *value++; 7168a84c255SSatish Balay } 717dd9472c6SBarry Smith } 718dd9472c6SBarry Smith } 7190e324ae4SSatish Balay } else { 7200e324ae4SSatish Balay if (is == ADD_VALUES) { 721dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval ) { 722dd9472c6SBarry Smith for (jj=0; jj<bs; jj++ ) { 7230e324ae4SSatish Balay *bap++ += *value++; 724dd9472c6SBarry Smith } 725dd9472c6SBarry Smith } 7260e324ae4SSatish Balay } else { 727dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval ) { 728dd9472c6SBarry Smith for (jj=0; jj<bs; jj++ ) { 7290e324ae4SSatish Balay *bap++ = *value++; 7300e324ae4SSatish Balay } 7318a84c255SSatish Balay } 732dd9472c6SBarry Smith } 733dd9472c6SBarry Smith } 734f1241b54SBarry Smith goto noinsert2; 73592c4ed94SBarry Smith } 73692c4ed94SBarry Smith } 73789280ab3SLois Curfman McInnes if (nonew == 1) goto noinsert2; 738a8c6a408SBarry Smith else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 73992c4ed94SBarry Smith if (nrow >= rmax) { 74092c4ed94SBarry Smith /* there is no extra room in row, therefore enlarge */ 74192c4ed94SBarry Smith int new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j; 74292c4ed94SBarry Smith Scalar *new_a; 74392c4ed94SBarry Smith 744a8c6a408SBarry Smith if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 74589280ab3SLois Curfman McInnes 74692c4ed94SBarry Smith /* malloc new storage space */ 74792c4ed94SBarry Smith len = new_nz*(sizeof(int)+bs2*sizeof(Scalar))+(a->mbs+1)*sizeof(int); 74892c4ed94SBarry Smith new_a = (Scalar *) PetscMalloc( len ); CHKPTRQ(new_a); 74992c4ed94SBarry Smith new_j = (int *) (new_a + bs2*new_nz); 75092c4ed94SBarry Smith new_i = new_j + new_nz; 75192c4ed94SBarry Smith 75292c4ed94SBarry Smith /* copy over old data into new slots */ 75392c4ed94SBarry Smith for ( ii=0; ii<row+1; ii++ ) {new_i[ii] = ai[ii];} 75492c4ed94SBarry Smith for ( ii=row+1; ii<a->mbs+1; ii++ ) {new_i[ii] = ai[ii]+CHUNKSIZE;} 75592c4ed94SBarry Smith PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int)); 75692c4ed94SBarry Smith len = (new_nz - CHUNKSIZE - ai[row] - nrow); 757dd9472c6SBarry Smith PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int)); 75892c4ed94SBarry Smith PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(Scalar)); 75992c4ed94SBarry Smith PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(Scalar)); 760dd9472c6SBarry Smith PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(Scalar)); 76192c4ed94SBarry Smith /* free up old matrix storage */ 76292c4ed94SBarry Smith PetscFree(a->a); 76392c4ed94SBarry Smith if (!a->singlemalloc) {PetscFree(a->i);PetscFree(a->j);} 76492c4ed94SBarry Smith aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 76592c4ed94SBarry Smith a->singlemalloc = 1; 76692c4ed94SBarry Smith 76792c4ed94SBarry Smith rp = aj + ai[row]; ap = aa + bs2*ai[row]; 76892c4ed94SBarry Smith rmax = imax[row] = imax[row] + CHUNKSIZE; 76992c4ed94SBarry Smith PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(Scalar))); 77092c4ed94SBarry Smith a->maxnz += bs2*CHUNKSIZE; 77192c4ed94SBarry Smith a->reallocs++; 77292c4ed94SBarry Smith a->nz++; 77392c4ed94SBarry Smith } 77492c4ed94SBarry Smith N = nrow++ - 1; 77592c4ed94SBarry Smith /* shift up all the later entries in this row */ 77692c4ed94SBarry Smith for ( ii=N; ii>=i; ii-- ) { 77792c4ed94SBarry Smith rp[ii+1] = rp[ii]; 77892c4ed94SBarry Smith PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(Scalar)); 77992c4ed94SBarry Smith } 78092c4ed94SBarry Smith if (N >= i) PetscMemzero(ap+bs2*i,bs2*sizeof(Scalar)); 78192c4ed94SBarry Smith rp[i] = col; 7828a84c255SSatish Balay bap = ap + bs2*i; 7830e324ae4SSatish Balay if (roworiented) { 784dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval) { 785dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs ) { 7860e324ae4SSatish Balay bap[jj] = *value++; 787dd9472c6SBarry Smith } 788dd9472c6SBarry Smith } 7890e324ae4SSatish Balay } else { 790dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval ) { 791dd9472c6SBarry Smith for (jj=0; jj<bs; jj++ ) { 7920e324ae4SSatish Balay *bap++ = *value++; 7930e324ae4SSatish Balay } 794dd9472c6SBarry Smith } 795dd9472c6SBarry Smith } 796f1241b54SBarry Smith noinsert2:; 79792c4ed94SBarry Smith low = i; 79892c4ed94SBarry Smith } 79992c4ed94SBarry Smith ailen[row] = nrow; 80092c4ed94SBarry Smith } 8013a40ed3dSBarry Smith PetscFunctionReturn(0); 80292c4ed94SBarry Smith } 80392c4ed94SBarry Smith 804f2501298SSatish Balay 8055615d1e5SSatish Balay #undef __FUNC__ 8065615d1e5SSatish Balay #define __FUNC__ "MatAssemblyEnd_SeqBAIJ" 8078f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode) 808584200bdSSatish Balay { 809584200bdSSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 810584200bdSSatish Balay int fshift = 0,i,j,*ai = a->i, *aj = a->j, *imax = a->imax; 811a7c10996SSatish Balay int m = a->m,*ip, N, *ailen = a->ilen; 81243ee02c3SBarry Smith int mbs = a->mbs, bs2 = a->bs2,rmax = 0; 813584200bdSSatish Balay Scalar *aa = a->a, *ap; 814584200bdSSatish Balay 8153a40ed3dSBarry Smith PetscFunctionBegin; 8163a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 817584200bdSSatish Balay 81843ee02c3SBarry Smith if (m) rmax = ailen[0]; 819584200bdSSatish Balay for ( i=1; i<mbs; i++ ) { 820584200bdSSatish Balay /* move each row back by the amount of empty slots (fshift) before it*/ 821584200bdSSatish Balay fshift += imax[i-1] - ailen[i-1]; 822d402145bSBarry Smith rmax = PetscMax(rmax,ailen[i]); 823584200bdSSatish Balay if (fshift) { 824a7c10996SSatish Balay ip = aj + ai[i]; ap = aa + bs2*ai[i]; 825584200bdSSatish Balay N = ailen[i]; 826584200bdSSatish Balay for ( j=0; j<N; j++ ) { 827584200bdSSatish Balay ip[j-fshift] = ip[j]; 8287e67e3f9SSatish Balay PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(Scalar)); 829584200bdSSatish Balay } 830584200bdSSatish Balay } 831584200bdSSatish Balay ai[i] = ai[i-1] + ailen[i-1]; 832584200bdSSatish Balay } 833584200bdSSatish Balay if (mbs) { 834584200bdSSatish Balay fshift += imax[mbs-1] - ailen[mbs-1]; 835584200bdSSatish Balay ai[mbs] = ai[mbs-1] + ailen[mbs-1]; 836584200bdSSatish Balay } 837584200bdSSatish Balay /* reset ilen and imax for each row */ 838584200bdSSatish Balay for ( i=0; i<mbs; i++ ) { 839584200bdSSatish Balay ailen[i] = imax[i] = ai[i+1] - ai[i]; 840584200bdSSatish Balay } 841a7c10996SSatish Balay a->nz = ai[mbs]; 842584200bdSSatish Balay 843584200bdSSatish Balay /* diagonals may have moved, so kill the diagonal pointers */ 844584200bdSSatish Balay if (fshift && a->diag) { 845584200bdSSatish Balay PetscFree(a->diag); 846584200bdSSatish Balay PLogObjectMemory(A,-(m+1)*sizeof(int)); 847584200bdSSatish Balay a->diag = 0; 848584200bdSSatish Balay } 8493d2013a6SLois Curfman McInnes PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Matrix size: %d X %d, block size %d; storage space: %d unneeded, %d used\n", 850219d9a1aSLois Curfman McInnes m,a->n,a->bs,fshift*bs2,a->nz*bs2); 8513d2013a6SLois Curfman McInnes PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues is %d\n", 852584200bdSSatish Balay a->reallocs); 853d402145bSBarry Smith PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Most nonzeros blocks in any row is %d\n",rmax); 854e2f3b5e9SSatish Balay a->reallocs = 0; 8554e220ebcSLois Curfman McInnes A->info.nz_unneeded = (double)fshift*bs2; 8564e220ebcSLois Curfman McInnes 8573a40ed3dSBarry Smith PetscFunctionReturn(0); 858584200bdSSatish Balay } 859584200bdSSatish Balay 8605a838052SSatish Balay 861d9b7c43dSSatish Balay /* idx should be of length atlease bs */ 8625615d1e5SSatish Balay #undef __FUNC__ 8635615d1e5SSatish Balay #define __FUNC__ "MatZeroRows_SeqBAIJ_Check_Block" 864d9b7c43dSSatish Balay static int MatZeroRows_SeqBAIJ_Check_Block(int *idx, int bs, PetscTruth *flg) 865d9b7c43dSSatish Balay { 866d9b7c43dSSatish Balay int i,row; 8673a40ed3dSBarry Smith 8683a40ed3dSBarry Smith PetscFunctionBegin; 869d9b7c43dSSatish Balay row = idx[0]; 8703a40ed3dSBarry Smith if (row%bs!=0) { *flg = PETSC_FALSE; PetscFunctionReturn(0); } 871d9b7c43dSSatish Balay 872d9b7c43dSSatish Balay for ( i=1; i<bs; i++ ) { 8733a40ed3dSBarry Smith if (row+i != idx[i]) { *flg = PETSC_FALSE; PetscFunctionReturn(0); } 874d9b7c43dSSatish Balay } 875d9b7c43dSSatish Balay *flg = PETSC_TRUE; 8763a40ed3dSBarry Smith PetscFunctionReturn(0); 877d9b7c43dSSatish Balay } 878d9b7c43dSSatish Balay 8795615d1e5SSatish Balay #undef __FUNC__ 8805615d1e5SSatish Balay #define __FUNC__ "MatZeroRows_SeqBAIJ" 8818f6be9afSLois Curfman McInnes int MatZeroRows_SeqBAIJ(Mat A,IS is, Scalar *diag) 882d9b7c43dSSatish Balay { 883d9b7c43dSSatish Balay Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data; 884d9b7c43dSSatish Balay IS is_local; 885d9b7c43dSSatish Balay int ierr,i,j,count,m=baij->m,is_n,*is_idx,*rows,bs=baij->bs,bs2=baij->bs2; 886d9b7c43dSSatish Balay PetscTruth flg; 887d9b7c43dSSatish Balay Scalar zero = 0.0,*aa; 888d9b7c43dSSatish Balay 8893a40ed3dSBarry Smith PetscFunctionBegin; 890d9b7c43dSSatish Balay /* Make a copy of the IS and sort it */ 891d9b7c43dSSatish Balay ierr = ISGetSize(is,&is_n);CHKERRQ(ierr); 892d9b7c43dSSatish Balay ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr); 893537820f0SBarry Smith ierr = ISCreateGeneral(A->comm,is_n,is_idx,&is_local); CHKERRQ(ierr); 894d9b7c43dSSatish Balay ierr = ISSort(is_local); CHKERRQ(ierr); 895d9b7c43dSSatish Balay ierr = ISGetIndices(is_local,&rows); CHKERRQ(ierr); 896d9b7c43dSSatish Balay 897d9b7c43dSSatish Balay i = 0; 898d9b7c43dSSatish Balay while (i < is_n) { 899a8c6a408SBarry Smith if (rows[i]<0 || rows[i]>m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range"); 900d9b7c43dSSatish Balay flg = PETSC_FALSE; 901d9b7c43dSSatish Balay if (i+bs <= is_n) {ierr = MatZeroRows_SeqBAIJ_Check_Block(rows+i,bs,&flg); CHKERRQ(ierr); } 902d9b7c43dSSatish Balay count = (baij->i[rows[i]/bs +1] - baij->i[rows[i]/bs])*bs; 903d9b7c43dSSatish Balay aa = baij->a + baij->i[rows[i]/bs]*bs2 + (rows[i]%bs); 9042d61bbb3SSatish Balay if (flg) { /* There exists a block of rows to be Zerowed */ 905a07cd24cSSatish Balay if (baij->ilen[rows[i]/bs] > 0) { 9062d61bbb3SSatish Balay PetscMemzero(aa,count*bs*sizeof(Scalar)); 9072d61bbb3SSatish Balay baij->ilen[rows[i]/bs] = 1; 9082d61bbb3SSatish Balay baij->j[baij->i[rows[i]/bs]] = rows[i]/bs; 909a07cd24cSSatish Balay } 9102d61bbb3SSatish Balay i += bs; 9112d61bbb3SSatish Balay } else { /* Zero out only the requested row */ 912d9b7c43dSSatish Balay for ( j=0; j<count; j++ ) { 913d9b7c43dSSatish Balay aa[0] = zero; 914d9b7c43dSSatish Balay aa+=bs; 915d9b7c43dSSatish Balay } 916d9b7c43dSSatish Balay i++; 917d9b7c43dSSatish Balay } 918d9b7c43dSSatish Balay } 919d9b7c43dSSatish Balay if (diag) { 920d9b7c43dSSatish Balay for ( j=0; j<is_n; j++ ) { 921f830108cSBarry Smith ierr = (*A->ops->setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr); 9222d61bbb3SSatish Balay /* ierr = MatSetValues(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr); */ 923d9b7c43dSSatish Balay } 924d9b7c43dSSatish Balay } 925d9b7c43dSSatish Balay ierr = ISRestoreIndices(is,&is_idx); CHKERRQ(ierr); 926d9b7c43dSSatish Balay ierr = ISRestoreIndices(is_local,&rows); CHKERRQ(ierr); 927d9b7c43dSSatish Balay ierr = ISDestroy(is_local); CHKERRQ(ierr); 9289a8dea36SBarry Smith ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 9293a40ed3dSBarry Smith PetscFunctionReturn(0); 930d9b7c43dSSatish Balay } 9311c351548SSatish Balay 9325615d1e5SSatish Balay #undef __FUNC__ 9332d61bbb3SSatish Balay #define __FUNC__ "MatSetValues_SeqBAIJ" 9342d61bbb3SSatish Balay int MatSetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is) 9352d61bbb3SSatish Balay { 9362d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 9372d61bbb3SSatish Balay int *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted; 9382d61bbb3SSatish Balay int *imax=a->imax,*ai=a->i,*ailen=a->ilen,roworiented=a->roworiented; 9392d61bbb3SSatish Balay int *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol; 9402d61bbb3SSatish Balay int ridx,cidx,bs2=a->bs2; 9412d61bbb3SSatish Balay Scalar *ap,value,*aa=a->a,*bap; 9422d61bbb3SSatish Balay 9432d61bbb3SSatish Balay PetscFunctionBegin; 9442d61bbb3SSatish Balay for ( k=0; k<m; k++ ) { /* loop over added rows */ 9452d61bbb3SSatish Balay row = im[k]; brow = row/bs; 9462d61bbb3SSatish Balay #if defined(USE_PETSC_BOPT_g) 9472d61bbb3SSatish Balay if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row"); 9482d61bbb3SSatish Balay if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 9492d61bbb3SSatish Balay #endif 9502d61bbb3SSatish Balay rp = aj + ai[brow]; 9512d61bbb3SSatish Balay ap = aa + bs2*ai[brow]; 9522d61bbb3SSatish Balay rmax = imax[brow]; 9532d61bbb3SSatish Balay nrow = ailen[brow]; 9542d61bbb3SSatish Balay low = 0; 9552d61bbb3SSatish Balay for ( l=0; l<n; l++ ) { /* loop over added columns */ 9562d61bbb3SSatish Balay #if defined(USE_PETSC_BOPT_g) 9572d61bbb3SSatish Balay if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column"); 9582d61bbb3SSatish Balay if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 9592d61bbb3SSatish Balay #endif 9602d61bbb3SSatish Balay col = in[l]; bcol = col/bs; 9612d61bbb3SSatish Balay ridx = row % bs; cidx = col % bs; 9622d61bbb3SSatish Balay if (roworiented) { 9632d61bbb3SSatish Balay value = *v++; 9642d61bbb3SSatish Balay } else { 9652d61bbb3SSatish Balay value = v[k + l*m]; 9662d61bbb3SSatish Balay } 9672d61bbb3SSatish Balay if (!sorted) low = 0; high = nrow; 9682d61bbb3SSatish Balay while (high-low > 7) { 9692d61bbb3SSatish Balay t = (low+high)/2; 9702d61bbb3SSatish Balay if (rp[t] > bcol) high = t; 9712d61bbb3SSatish Balay else low = t; 9722d61bbb3SSatish Balay } 9732d61bbb3SSatish Balay for ( i=low; i<high; i++ ) { 9742d61bbb3SSatish Balay if (rp[i] > bcol) break; 9752d61bbb3SSatish Balay if (rp[i] == bcol) { 9762d61bbb3SSatish Balay bap = ap + bs2*i + bs*cidx + ridx; 9772d61bbb3SSatish Balay if (is == ADD_VALUES) *bap += value; 9782d61bbb3SSatish Balay else *bap = value; 9792d61bbb3SSatish Balay goto noinsert1; 9802d61bbb3SSatish Balay } 9812d61bbb3SSatish Balay } 9822d61bbb3SSatish Balay if (nonew == 1) goto noinsert1; 9832d61bbb3SSatish Balay else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 9842d61bbb3SSatish Balay if (nrow >= rmax) { 9852d61bbb3SSatish Balay /* there is no extra room in row, therefore enlarge */ 9862d61bbb3SSatish Balay int new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j; 9872d61bbb3SSatish Balay Scalar *new_a; 9882d61bbb3SSatish Balay 9892d61bbb3SSatish Balay if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 9902d61bbb3SSatish Balay 9912d61bbb3SSatish Balay /* Malloc new storage space */ 9922d61bbb3SSatish Balay len = new_nz*(sizeof(int)+bs2*sizeof(Scalar))+(a->mbs+1)*sizeof(int); 9932d61bbb3SSatish Balay new_a = (Scalar *) PetscMalloc( len ); CHKPTRQ(new_a); 9942d61bbb3SSatish Balay new_j = (int *) (new_a + bs2*new_nz); 9952d61bbb3SSatish Balay new_i = new_j + new_nz; 9962d61bbb3SSatish Balay 9972d61bbb3SSatish Balay /* copy over old data into new slots */ 9982d61bbb3SSatish Balay for ( ii=0; ii<brow+1; ii++ ) {new_i[ii] = ai[ii];} 9992d61bbb3SSatish Balay for ( ii=brow+1; ii<a->mbs+1; ii++ ) {new_i[ii] = ai[ii]+CHUNKSIZE;} 10002d61bbb3SSatish Balay PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int)); 10012d61bbb3SSatish Balay len = (new_nz - CHUNKSIZE - ai[brow] - nrow); 10022d61bbb3SSatish Balay PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow, 10032d61bbb3SSatish Balay len*sizeof(int)); 10042d61bbb3SSatish Balay PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(Scalar)); 10052d61bbb3SSatish Balay PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(Scalar)); 10062d61bbb3SSatish Balay PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE), 10072d61bbb3SSatish Balay aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(Scalar)); 10082d61bbb3SSatish Balay /* free up old matrix storage */ 10092d61bbb3SSatish Balay PetscFree(a->a); 10102d61bbb3SSatish Balay if (!a->singlemalloc) {PetscFree(a->i);PetscFree(a->j);} 10112d61bbb3SSatish Balay aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 10122d61bbb3SSatish Balay a->singlemalloc = 1; 10132d61bbb3SSatish Balay 10142d61bbb3SSatish Balay rp = aj + ai[brow]; ap = aa + bs2*ai[brow]; 10152d61bbb3SSatish Balay rmax = imax[brow] = imax[brow] + CHUNKSIZE; 10162d61bbb3SSatish Balay PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(Scalar))); 10172d61bbb3SSatish Balay a->maxnz += bs2*CHUNKSIZE; 10182d61bbb3SSatish Balay a->reallocs++; 10192d61bbb3SSatish Balay a->nz++; 10202d61bbb3SSatish Balay } 10212d61bbb3SSatish Balay N = nrow++ - 1; 10222d61bbb3SSatish Balay /* shift up all the later entries in this row */ 10232d61bbb3SSatish Balay for ( ii=N; ii>=i; ii-- ) { 10242d61bbb3SSatish Balay rp[ii+1] = rp[ii]; 10252d61bbb3SSatish Balay PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(Scalar)); 10262d61bbb3SSatish Balay } 10272d61bbb3SSatish Balay if (N>=i) PetscMemzero(ap+bs2*i,bs2*sizeof(Scalar)); 10282d61bbb3SSatish Balay rp[i] = bcol; 10292d61bbb3SSatish Balay ap[bs2*i + bs*cidx + ridx] = value; 10302d61bbb3SSatish Balay noinsert1:; 10312d61bbb3SSatish Balay low = i; 10322d61bbb3SSatish Balay } 10332d61bbb3SSatish Balay ailen[brow] = nrow; 10342d61bbb3SSatish Balay } 10352d61bbb3SSatish Balay PetscFunctionReturn(0); 10362d61bbb3SSatish Balay } 10372d61bbb3SSatish Balay 10382d61bbb3SSatish Balay extern int MatLUFactorSymbolic_SeqBAIJ(Mat,IS,IS,double,Mat*); 10392d61bbb3SSatish Balay extern int MatLUFactor_SeqBAIJ(Mat,IS,IS,double); 10402d61bbb3SSatish Balay extern int MatIncreaseOverlap_SeqBAIJ(Mat,int,IS*,int); 1041d3825aa8SBarry Smith extern int MatGetSubMatrix_SeqBAIJ(Mat,IS,IS,int,MatGetSubMatrixCall,Mat*); 10422d61bbb3SSatish Balay extern int MatGetSubMatrices_SeqBAIJ(Mat,int,IS*,IS*,MatGetSubMatrixCall,Mat**); 10432d61bbb3SSatish Balay extern int MatMultTrans_SeqBAIJ(Mat,Vec,Vec); 10442d61bbb3SSatish Balay extern int MatMultTransAdd_SeqBAIJ(Mat,Vec,Vec,Vec); 10452d61bbb3SSatish Balay extern int MatScale_SeqBAIJ(Scalar*,Mat); 10462d61bbb3SSatish Balay extern int MatNorm_SeqBAIJ(Mat,NormType,double *); 10472d61bbb3SSatish Balay extern int MatEqual_SeqBAIJ(Mat,Mat, PetscTruth*); 10482d61bbb3SSatish Balay extern int MatGetDiagonal_SeqBAIJ(Mat,Vec); 10492d61bbb3SSatish Balay extern int MatDiagonalScale_SeqBAIJ(Mat,Vec,Vec); 10502d61bbb3SSatish Balay extern int MatGetInfo_SeqBAIJ(Mat,MatInfoType,MatInfo *); 10512d61bbb3SSatish Balay extern int MatZeroEntries_SeqBAIJ(Mat); 10522d61bbb3SSatish Balay 10532d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_N(Mat,Vec,Vec); 10542d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_1(Mat,Vec,Vec); 10552d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_2(Mat,Vec,Vec); 10562d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_3(Mat,Vec,Vec); 10572d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_4(Mat,Vec,Vec); 10582d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_5(Mat,Vec,Vec); 10592d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_7(Mat,Vec,Vec); 10602d61bbb3SSatish Balay 10612d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_N(Mat,Mat*); 10622d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_1(Mat,Mat*); 10632d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_2(Mat,Mat*); 10642d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_3(Mat,Mat*); 10652d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_4(Mat,Mat*); 10662d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_5(Mat,Mat*); 10672d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_4_NaturalOrdering(Mat,Vec,Vec); 10682d61bbb3SSatish Balay 10692d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_1(Mat,Vec,Vec); 10702d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_2(Mat,Vec,Vec); 10712d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_3(Mat,Vec,Vec); 10722d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_4(Mat,Vec,Vec); 10732d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_5(Mat,Vec,Vec); 10742d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_7(Mat,Vec,Vec); 10752d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_N(Mat,Vec,Vec); 10762d61bbb3SSatish Balay 10772d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_1(Mat,Vec,Vec,Vec); 10782d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_2(Mat,Vec,Vec,Vec); 10792d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_3(Mat,Vec,Vec,Vec); 10802d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_4(Mat,Vec,Vec,Vec); 10812d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_5(Mat,Vec,Vec,Vec); 10822d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_7(Mat,Vec,Vec,Vec); 10832d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_N(Mat,Vec,Vec,Vec); 10842d61bbb3SSatish Balay 10852d61bbb3SSatish Balay /* 10862d61bbb3SSatish Balay note: This can only work for identity for row and col. It would 10872d61bbb3SSatish Balay be good to check this and otherwise generate an error. 10882d61bbb3SSatish Balay */ 10892d61bbb3SSatish Balay #undef __FUNC__ 10902d61bbb3SSatish Balay #define __FUNC__ "MatILUFactor_SeqBAIJ" 10912d61bbb3SSatish Balay int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,double efill,int fill) 10922d61bbb3SSatish Balay { 10932d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) inA->data; 10942d61bbb3SSatish Balay Mat outA; 10952d61bbb3SSatish Balay int ierr; 10962d61bbb3SSatish Balay 10972d61bbb3SSatish Balay PetscFunctionBegin; 10982d61bbb3SSatish Balay if (fill != 0) SETERRQ(PETSC_ERR_SUP,0,"Only fill=0 supported"); 10992d61bbb3SSatish Balay 11002d61bbb3SSatish Balay outA = inA; 11012d61bbb3SSatish Balay inA->factor = FACTOR_LU; 11022d61bbb3SSatish Balay a->row = row; 11032d61bbb3SSatish Balay a->col = col; 11042d61bbb3SSatish Balay 1105e51c0b9cSSatish Balay /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */ 1106e51c0b9cSSatish Balay ierr = ISInvertPermutation(col,&(a->icol)); CHKERRQ(ierr); 11071e4dd532SSatish Balay PLogObjectParent(inA,a->icol); 1108e51c0b9cSSatish Balay 11092d61bbb3SSatish Balay if (!a->solve_work) { 11102d61bbb3SSatish Balay a->solve_work = (Scalar *) PetscMalloc((a->m+a->bs)*sizeof(Scalar));CHKPTRQ(a->solve_work); 11112d61bbb3SSatish Balay PLogObjectMemory(inA,(a->m+a->bs)*sizeof(Scalar)); 11122d61bbb3SSatish Balay } 11132d61bbb3SSatish Balay 11142d61bbb3SSatish Balay if (!a->diag) { 11152d61bbb3SSatish Balay ierr = MatMarkDiag_SeqBAIJ(inA); CHKERRQ(ierr); 11162d61bbb3SSatish Balay } 11172d61bbb3SSatish Balay ierr = MatLUFactorNumeric(inA,&outA); CHKERRQ(ierr); 11182d61bbb3SSatish Balay 11192d61bbb3SSatish Balay /* 11202d61bbb3SSatish Balay Blocksize 4 has a special faster solver for ILU(0) factorization 11212d61bbb3SSatish Balay with natural ordering 11222d61bbb3SSatish Balay */ 11232d61bbb3SSatish Balay if (a->bs == 4) { 1124f830108cSBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_4_NaturalOrdering; 11252d61bbb3SSatish Balay } 11262d61bbb3SSatish Balay 11272d61bbb3SSatish Balay PetscFunctionReturn(0); 11282d61bbb3SSatish Balay } 11292d61bbb3SSatish Balay #undef __FUNC__ 1130d4bb536fSBarry Smith #define __FUNC__ "MatPrintHelp_SeqBAIJ" 1131ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A) 1132ba4ca20aSSatish Balay { 1133ba4ca20aSSatish Balay static int called = 0; 1134ba4ca20aSSatish Balay MPI_Comm comm = A->comm; 1135ba4ca20aSSatish Balay 11363a40ed3dSBarry Smith PetscFunctionBegin; 11373a40ed3dSBarry Smith if (called) {PetscFunctionReturn(0);} else called = 1; 113876be9ce4SBarry Smith (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n"); 113976be9ce4SBarry Smith (*PetscHelpPrintf)(comm," -mat_block_size <block_size>\n"); 11403a40ed3dSBarry Smith PetscFunctionReturn(0); 1141ba4ca20aSSatish Balay } 1142d9b7c43dSSatish Balay 114327a8da17SBarry Smith #undef __FUNC__ 114427a8da17SBarry Smith #define __FUNC__ "MatSeqBAIJSetColumnIndices_SeqBAIJ" 114527a8da17SBarry Smith int MatSeqBAIJSetColumnIndices_SeqBAIJ(Mat mat,int *indices) 114627a8da17SBarry Smith { 114727a8da17SBarry Smith Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *)mat->data; 114827a8da17SBarry Smith int i,nz,n; 114927a8da17SBarry Smith 115027a8da17SBarry Smith PetscFunctionBegin; 115127a8da17SBarry Smith nz = baij->maxnz; 115227a8da17SBarry Smith n = baij->n; 115327a8da17SBarry Smith for (i=0; i<nz; i++) { 115427a8da17SBarry Smith baij->j[i] = indices[i]; 115527a8da17SBarry Smith } 115627a8da17SBarry Smith baij->nz = nz; 115727a8da17SBarry Smith for ( i=0; i<n; i++ ) { 115827a8da17SBarry Smith baij->ilen[i] = baij->imax[i]; 115927a8da17SBarry Smith } 116027a8da17SBarry Smith 116127a8da17SBarry Smith PetscFunctionReturn(0); 116227a8da17SBarry Smith } 116327a8da17SBarry Smith 116427a8da17SBarry Smith #undef __FUNC__ 116527a8da17SBarry Smith #define __FUNC__ "MatSeqBAIJSetColumnIndices" 116627a8da17SBarry Smith /*@ 116727a8da17SBarry Smith MatSeqBAIJSetColumnIndices - Set the column indices for all the rows 116827a8da17SBarry Smith in the matrix. 116927a8da17SBarry Smith 117027a8da17SBarry Smith Input Parameters: 117127a8da17SBarry Smith + mat - the SeqBAIJ matrix 117227a8da17SBarry Smith - indices - the column indices 117327a8da17SBarry Smith 117427a8da17SBarry Smith Notes: 117527a8da17SBarry Smith This can be called if you have precomputed the nonzero structure of the 117627a8da17SBarry Smith matrix and want to provide it to the matrix object to improve the performance 117727a8da17SBarry Smith of the MatSetValues() operation. 117827a8da17SBarry Smith 117927a8da17SBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 118027a8da17SBarry Smith MatCreateSeqBAIJ(). 118127a8da17SBarry Smith 118227a8da17SBarry Smith MUST be called before any calls to MatSetValues(); 118327a8da17SBarry Smith 118427a8da17SBarry Smith @*/ 118527a8da17SBarry Smith int MatSeqBAIJSetColumnIndices(Mat mat,int *indices) 118627a8da17SBarry Smith { 118727a8da17SBarry Smith int ierr,(*f)(Mat,int *); 118827a8da17SBarry Smith 118927a8da17SBarry Smith PetscFunctionBegin; 119027a8da17SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 119127a8da17SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqBAIJSetColumnIndices_C",(void **)&f); 119227a8da17SBarry Smith CHKERRQ(ierr); 119327a8da17SBarry Smith if (f) { 119427a8da17SBarry Smith ierr = (*f)(mat,indices);CHKERRQ(ierr); 119527a8da17SBarry Smith } else { 119627a8da17SBarry Smith SETERRQ(1,1,"Wrong type of matrix to set column indices"); 119727a8da17SBarry Smith } 119827a8da17SBarry Smith PetscFunctionReturn(0); 119927a8da17SBarry Smith } 120027a8da17SBarry Smith 12012593348eSBarry Smith /* -------------------------------------------------------------------*/ 1202cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqBAIJ, 1203cc2dc46cSBarry Smith MatGetRow_SeqBAIJ, 1204cc2dc46cSBarry Smith MatRestoreRow_SeqBAIJ, 1205cc2dc46cSBarry Smith MatMult_SeqBAIJ_N, 1206cc2dc46cSBarry Smith MatMultAdd_SeqBAIJ_N, 1207cc2dc46cSBarry Smith MatMultTrans_SeqBAIJ, 1208cc2dc46cSBarry Smith MatMultTransAdd_SeqBAIJ, 1209cc2dc46cSBarry Smith MatSolve_SeqBAIJ_N, 1210cc2dc46cSBarry Smith 0, 1211cc2dc46cSBarry Smith 0, 1212cc2dc46cSBarry Smith 0, 1213cc2dc46cSBarry Smith MatLUFactor_SeqBAIJ, 1214cc2dc46cSBarry Smith 0, 1215b6490206SBarry Smith 0, 1216f2501298SSatish Balay MatTranspose_SeqBAIJ, 1217cc2dc46cSBarry Smith MatGetInfo_SeqBAIJ, 1218cc2dc46cSBarry Smith MatEqual_SeqBAIJ, 1219cc2dc46cSBarry Smith MatGetDiagonal_SeqBAIJ, 1220cc2dc46cSBarry Smith MatDiagonalScale_SeqBAIJ, 1221cc2dc46cSBarry Smith MatNorm_SeqBAIJ, 1222b6490206SBarry Smith 0, 1223cc2dc46cSBarry Smith MatAssemblyEnd_SeqBAIJ, 1224cc2dc46cSBarry Smith 0, 1225cc2dc46cSBarry Smith MatSetOption_SeqBAIJ, 1226cc2dc46cSBarry Smith MatZeroEntries_SeqBAIJ, 1227cc2dc46cSBarry Smith MatZeroRows_SeqBAIJ, 1228cc2dc46cSBarry Smith MatLUFactorSymbolic_SeqBAIJ, 1229cc2dc46cSBarry Smith MatLUFactorNumeric_SeqBAIJ_N, 1230cc2dc46cSBarry Smith 0, 1231cc2dc46cSBarry Smith 0, 1232cc2dc46cSBarry Smith MatGetSize_SeqBAIJ, 1233cc2dc46cSBarry Smith MatGetSize_SeqBAIJ, 1234cc2dc46cSBarry Smith MatGetOwnershipRange_SeqBAIJ, 1235cc2dc46cSBarry Smith MatILUFactorSymbolic_SeqBAIJ, 1236cc2dc46cSBarry Smith 0, 1237cc2dc46cSBarry Smith 0, 1238cc2dc46cSBarry Smith 0, 1239cc2dc46cSBarry Smith MatConvertSameType_SeqBAIJ, 1240cc2dc46cSBarry Smith 0, 1241cc2dc46cSBarry Smith 0, 1242cc2dc46cSBarry Smith MatILUFactor_SeqBAIJ, 1243cc2dc46cSBarry Smith 0, 1244cc2dc46cSBarry Smith 0, 1245cc2dc46cSBarry Smith MatGetSubMatrices_SeqBAIJ, 1246cc2dc46cSBarry Smith MatIncreaseOverlap_SeqBAIJ, 1247cc2dc46cSBarry Smith MatGetValues_SeqBAIJ, 1248cc2dc46cSBarry Smith 0, 1249cc2dc46cSBarry Smith MatPrintHelp_SeqBAIJ, 1250cc2dc46cSBarry Smith MatScale_SeqBAIJ, 1251cc2dc46cSBarry Smith 0, 1252cc2dc46cSBarry Smith 0, 1253cc2dc46cSBarry Smith 0, 1254cc2dc46cSBarry Smith MatGetBlockSize_SeqBAIJ, 12553b2fbd54SBarry Smith MatGetRowIJ_SeqBAIJ, 125692c4ed94SBarry Smith MatRestoreRowIJ_SeqBAIJ, 1257cc2dc46cSBarry Smith 0, 1258cc2dc46cSBarry Smith 0, 1259cc2dc46cSBarry Smith 0, 1260cc2dc46cSBarry Smith 0, 1261cc2dc46cSBarry Smith 0, 1262cc2dc46cSBarry Smith 0, 1263d3825aa8SBarry Smith MatSetValuesBlocked_SeqBAIJ, 1264cc2dc46cSBarry Smith MatGetSubMatrix_SeqBAIJ, 1265cc2dc46cSBarry Smith 0, 1266cc2dc46cSBarry Smith 0, 1267cc2dc46cSBarry Smith MatGetMaps_Petsc}; 12682593348eSBarry Smith 12695615d1e5SSatish Balay #undef __FUNC__ 12705615d1e5SSatish Balay #define __FUNC__ "MatCreateSeqBAIJ" 12712593348eSBarry Smith /*@C 127244cd7ae7SLois Curfman McInnes MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block 127344cd7ae7SLois Curfman McInnes compressed row) format. For good matrix assembly performance the 127444cd7ae7SLois Curfman McInnes user should preallocate the matrix storage by setting the parameter nz 12752bd5e0b2SLois Curfman McInnes (or the array nzz). By setting these parameters accurately, performance 12762bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 12772593348eSBarry Smith 1278db81eaa0SLois Curfman McInnes Collective on MPI_Comm 1279db81eaa0SLois Curfman McInnes 12802593348eSBarry Smith Input Parameters: 1281db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 1282b6490206SBarry Smith . bs - size of block 12832593348eSBarry Smith . m - number of rows 12842593348eSBarry Smith . n - number of columns 1285b6490206SBarry Smith . nz - number of block nonzeros per block row (same for all rows) 1286db81eaa0SLois Curfman McInnes - nzz - array containing the number of block nonzeros in the various block rows 12872bd5e0b2SLois Curfman McInnes (possibly different for each block row) or PETSC_NULL 12882593348eSBarry Smith 12892593348eSBarry Smith Output Parameter: 12902593348eSBarry Smith . A - the matrix 12912593348eSBarry Smith 12920513a670SBarry Smith Options Database Keys: 1293db81eaa0SLois Curfman McInnes . -mat_no_unroll - uses code that does not unroll the loops in the 1294db81eaa0SLois Curfman McInnes block calculations (much slower) 1295db81eaa0SLois Curfman McInnes . -mat_block_size - size of the blocks to use 12960513a670SBarry Smith 12972593348eSBarry Smith Notes: 129844cd7ae7SLois Curfman McInnes The block AIJ format is fully compatible with standard Fortran 77 12992593348eSBarry Smith storage. That is, the stored row and column indices can begin at 130044cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 13012593348eSBarry Smith 13022593348eSBarry Smith Specify the preallocated storage with either nz or nnz (not both). 13032593348eSBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 13042593348eSBarry Smith allocation. For additional details, see the users manual chapter on 13056da5968aSLois Curfman McInnes matrices. 13062593348eSBarry Smith 1307db81eaa0SLois Curfman McInnes .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ() 13082593348eSBarry Smith @*/ 1309b6490206SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz, Mat *A) 13102593348eSBarry Smith { 13112593348eSBarry Smith Mat B; 1312b6490206SBarry Smith Mat_SeqBAIJ *b; 13133b2fbd54SBarry Smith int i,len,ierr,flg,mbs=m/bs,nbs=n/bs,bs2=bs*bs,size; 13143b2fbd54SBarry Smith 13153a40ed3dSBarry Smith PetscFunctionBegin; 13163b2fbd54SBarry Smith MPI_Comm_size(comm,&size); 1317a8c6a408SBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"Comm must be of size 1"); 1318b6490206SBarry Smith 13190513a670SBarry Smith ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&bs,&flg);CHKERRQ(ierr); 13200513a670SBarry Smith 13213a40ed3dSBarry Smith if (mbs*bs!=m || nbs*bs!=n) { 1322a8c6a408SBarry Smith SETERRQ(PETSC_ERR_ARG_SIZ,0,"Number rows, cols must be divisible by blocksize"); 13233a40ed3dSBarry Smith } 13242593348eSBarry Smith 13252593348eSBarry Smith *A = 0; 1326f830108cSBarry Smith PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQBAIJ,comm,MatDestroy,MatView); 13272593348eSBarry Smith PLogObjectCreate(B); 1328b6490206SBarry Smith B->data = (void *) (b = PetscNew(Mat_SeqBAIJ)); CHKPTRQ(b); 132944cd7ae7SLois Curfman McInnes PetscMemzero(b,sizeof(Mat_SeqBAIJ)); 1330cc2dc46cSBarry Smith PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps)); 13311a6a6d98SBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg); CHKERRQ(ierr); 13321a6a6d98SBarry Smith if (!flg) { 13337fc0212eSBarry Smith switch (bs) { 13347fc0212eSBarry Smith case 1: 1335f830108cSBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1; 1336f830108cSBarry Smith B->ops->solve = MatSolve_SeqBAIJ_1; 1337f830108cSBarry Smith B->ops->mult = MatMult_SeqBAIJ_1; 1338f830108cSBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_1; 13397fc0212eSBarry Smith break; 13404eeb42bcSBarry Smith case 2: 1341f830108cSBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2; 1342f830108cSBarry Smith B->ops->solve = MatSolve_SeqBAIJ_2; 1343f830108cSBarry Smith B->ops->mult = MatMult_SeqBAIJ_2; 1344f830108cSBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_2; 13456d84be18SBarry Smith break; 1346f327dd97SBarry Smith case 3: 1347f830108cSBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3; 1348f830108cSBarry Smith B->ops->solve = MatSolve_SeqBAIJ_3; 1349f830108cSBarry Smith B->ops->mult = MatMult_SeqBAIJ_3; 1350f830108cSBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_3; 13514eeb42bcSBarry Smith break; 13526d84be18SBarry Smith case 4: 1353f830108cSBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4; 1354f830108cSBarry Smith B->ops->solve = MatSolve_SeqBAIJ_4; 1355f830108cSBarry Smith B->ops->mult = MatMult_SeqBAIJ_4; 1356f830108cSBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_4; 13576d84be18SBarry Smith break; 13586d84be18SBarry Smith case 5: 1359f830108cSBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5; 1360f830108cSBarry Smith B->ops->solve = MatSolve_SeqBAIJ_5; 1361f830108cSBarry Smith B->ops->mult = MatMult_SeqBAIJ_5; 1362f830108cSBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_5; 13636d84be18SBarry Smith break; 136448e9ddb2SSatish Balay case 7: 1365f830108cSBarry Smith B->ops->mult = MatMult_SeqBAIJ_7; 1366f830108cSBarry Smith B->ops->solve = MatSolve_SeqBAIJ_7; 1367f830108cSBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_7; 136848e9ddb2SSatish Balay break; 13697fc0212eSBarry Smith } 13701a6a6d98SBarry Smith } 1371e1311b90SBarry Smith B->ops->destroy = MatDestroy_SeqBAIJ; 1372e1311b90SBarry Smith B->ops->view = MatView_SeqBAIJ; 13732593348eSBarry Smith B->factor = 0; 13742593348eSBarry Smith B->lupivotthreshold = 1.0; 137590f02eecSBarry Smith B->mapping = 0; 13762593348eSBarry Smith b->row = 0; 13772593348eSBarry Smith b->col = 0; 1378e51c0b9cSSatish Balay b->icol = 0; 13792593348eSBarry Smith b->reallocs = 0; 13802593348eSBarry Smith 138144cd7ae7SLois Curfman McInnes b->m = m; B->m = m; B->M = m; 138244cd7ae7SLois Curfman McInnes b->n = n; B->n = n; B->N = n; 1383b6490206SBarry Smith b->mbs = mbs; 1384f2501298SSatish Balay b->nbs = nbs; 1385b6490206SBarry Smith b->imax = (int *) PetscMalloc( (mbs+1)*sizeof(int) ); CHKPTRQ(b->imax); 13862593348eSBarry Smith if (nnz == PETSC_NULL) { 1387119a934aSSatish Balay if (nz == PETSC_DEFAULT) nz = 5; 13882593348eSBarry Smith else if (nz <= 0) nz = 1; 1389b6490206SBarry Smith for ( i=0; i<mbs; i++ ) b->imax[i] = nz; 1390b6490206SBarry Smith nz = nz*mbs; 13913a40ed3dSBarry Smith } else { 13922593348eSBarry Smith nz = 0; 1393b6490206SBarry Smith for ( i=0; i<mbs; i++ ) {b->imax[i] = nnz[i]; nz += nnz[i];} 13942593348eSBarry Smith } 13952593348eSBarry Smith 13962593348eSBarry Smith /* allocate the matrix space */ 13977e67e3f9SSatish Balay len = nz*sizeof(int) + nz*bs2*sizeof(Scalar) + (b->m+1)*sizeof(int); 13982593348eSBarry Smith b->a = (Scalar *) PetscMalloc( len ); CHKPTRQ(b->a); 13997e67e3f9SSatish Balay PetscMemzero(b->a,nz*bs2*sizeof(Scalar)); 14007e67e3f9SSatish Balay b->j = (int *) (b->a + nz*bs2); 14012593348eSBarry Smith PetscMemzero(b->j,nz*sizeof(int)); 14022593348eSBarry Smith b->i = b->j + nz; 14032593348eSBarry Smith b->singlemalloc = 1; 14042593348eSBarry Smith 1405de6a44a3SBarry Smith b->i[0] = 0; 1406b6490206SBarry Smith for (i=1; i<mbs+1; i++) { 14072593348eSBarry Smith b->i[i] = b->i[i-1] + b->imax[i-1]; 14082593348eSBarry Smith } 14092593348eSBarry Smith 1410b6490206SBarry Smith /* b->ilen will count nonzeros in each block row so far. */ 1411b6490206SBarry Smith b->ilen = (int *) PetscMalloc((mbs+1)*sizeof(int)); 1412f09e8eb9SSatish Balay PLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ)); 1413b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { b->ilen[i] = 0;} 14142593348eSBarry Smith 1415b6490206SBarry Smith b->bs = bs; 14169df24120SSatish Balay b->bs2 = bs2; 1417b6490206SBarry Smith b->mbs = mbs; 14182593348eSBarry Smith b->nz = 0; 141918e7b8e4SLois Curfman McInnes b->maxnz = nz*bs2; 14202593348eSBarry Smith b->sorted = 0; 14212593348eSBarry Smith b->roworiented = 1; 14222593348eSBarry Smith b->nonew = 0; 14232593348eSBarry Smith b->diag = 0; 14242593348eSBarry Smith b->solve_work = 0; 1425de6a44a3SBarry Smith b->mult_work = 0; 14262593348eSBarry Smith b->spptr = 0; 14274e220ebcSLois Curfman McInnes B->info.nz_unneeded = (double)b->maxnz; 14284e220ebcSLois Curfman McInnes 14292593348eSBarry Smith *A = B; 14302593348eSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr); 14312593348eSBarry Smith if (flg) {ierr = MatPrintHelp(B); CHKERRQ(ierr); } 143227a8da17SBarry Smith 143327a8da17SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqBAIJSetColumnIndices_C", 143427a8da17SBarry Smith "MatSeqBAIJSetColumnIndices_SeqBAIJ", 143527a8da17SBarry Smith (void*)MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr); 143627a8da17SBarry Smith 14373a40ed3dSBarry Smith PetscFunctionReturn(0); 14382593348eSBarry Smith } 14392593348eSBarry Smith 14405615d1e5SSatish Balay #undef __FUNC__ 14415615d1e5SSatish Balay #define __FUNC__ "MatConvertSameType_SeqBAIJ" 1442b6490206SBarry Smith int MatConvertSameType_SeqBAIJ(Mat A,Mat *B,int cpvalues) 14432593348eSBarry Smith { 14442593348eSBarry Smith Mat C; 1445b6490206SBarry Smith Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ *) A->data; 144627a8da17SBarry Smith int i,len, mbs = a->mbs,nz = a->nz,bs2 =a->bs2,ierr; 1447de6a44a3SBarry Smith 14483a40ed3dSBarry Smith PetscFunctionBegin; 1449a8c6a408SBarry Smith if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,0,"Corrupt matrix"); 14502593348eSBarry Smith 14512593348eSBarry Smith *B = 0; 1452f830108cSBarry Smith PetscHeaderCreate(C,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQBAIJ,A->comm,MatDestroy,MatView); 14532593348eSBarry Smith PLogObjectCreate(C); 1454b6490206SBarry Smith C->data = (void *) (c = PetscNew(Mat_SeqBAIJ)); CHKPTRQ(c); 1455c3c66ee5SSatish Balay PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps)); 1456e1311b90SBarry Smith C->ops->destroy = MatDestroy_SeqBAIJ; 1457e1311b90SBarry Smith C->ops->view = MatView_SeqBAIJ; 14582593348eSBarry Smith C->factor = A->factor; 14592593348eSBarry Smith c->row = 0; 14602593348eSBarry Smith c->col = 0; 14612593348eSBarry Smith C->assembled = PETSC_TRUE; 14622593348eSBarry Smith 146344cd7ae7SLois Curfman McInnes c->m = C->m = a->m; 146444cd7ae7SLois Curfman McInnes c->n = C->n = a->n; 146544cd7ae7SLois Curfman McInnes C->M = a->m; 146644cd7ae7SLois Curfman McInnes C->N = a->n; 146744cd7ae7SLois Curfman McInnes 1468b6490206SBarry Smith c->bs = a->bs; 14699df24120SSatish Balay c->bs2 = a->bs2; 1470b6490206SBarry Smith c->mbs = a->mbs; 1471b6490206SBarry Smith c->nbs = a->nbs; 14722593348eSBarry Smith 1473b6490206SBarry Smith c->imax = (int *) PetscMalloc((mbs+1)*sizeof(int)); CHKPTRQ(c->imax); 1474b6490206SBarry Smith c->ilen = (int *) PetscMalloc((mbs+1)*sizeof(int)); CHKPTRQ(c->ilen); 1475b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 14762593348eSBarry Smith c->imax[i] = a->imax[i]; 14772593348eSBarry Smith c->ilen[i] = a->ilen[i]; 14782593348eSBarry Smith } 14792593348eSBarry Smith 14802593348eSBarry Smith /* allocate the matrix space */ 14812593348eSBarry Smith c->singlemalloc = 1; 14827e67e3f9SSatish Balay len = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(Scalar) + sizeof(int)); 14832593348eSBarry Smith c->a = (Scalar *) PetscMalloc( len ); CHKPTRQ(c->a); 14847e67e3f9SSatish Balay c->j = (int *) (c->a + nz*bs2); 1485de6a44a3SBarry Smith c->i = c->j + nz; 1486b6490206SBarry Smith PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int)); 1487b6490206SBarry Smith if (mbs > 0) { 1488de6a44a3SBarry Smith PetscMemcpy(c->j,a->j,nz*sizeof(int)); 14892593348eSBarry Smith if (cpvalues == COPY_VALUES) { 14907e67e3f9SSatish Balay PetscMemcpy(c->a,a->a,bs2*nz*sizeof(Scalar)); 14912593348eSBarry Smith } 14922593348eSBarry Smith } 14932593348eSBarry Smith 1494f09e8eb9SSatish Balay PLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ)); 14952593348eSBarry Smith c->sorted = a->sorted; 14962593348eSBarry Smith c->roworiented = a->roworiented; 14972593348eSBarry Smith c->nonew = a->nonew; 14982593348eSBarry Smith 14992593348eSBarry Smith if (a->diag) { 1500b6490206SBarry Smith c->diag = (int *) PetscMalloc( (mbs+1)*sizeof(int) ); CHKPTRQ(c->diag); 1501b6490206SBarry Smith PLogObjectMemory(C,(mbs+1)*sizeof(int)); 1502b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 15032593348eSBarry Smith c->diag[i] = a->diag[i]; 15042593348eSBarry Smith } 15052593348eSBarry Smith } 15062593348eSBarry Smith else c->diag = 0; 15072593348eSBarry Smith c->nz = a->nz; 15082593348eSBarry Smith c->maxnz = a->maxnz; 15092593348eSBarry Smith c->solve_work = 0; 15102593348eSBarry Smith c->spptr = 0; /* Dangerous -I'm throwing away a->spptr */ 15117fc0212eSBarry Smith c->mult_work = 0; 15122593348eSBarry Smith *B = C; 151327a8da17SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)C,"MatSeqBAIJSetColumnIndices_C", 151427a8da17SBarry Smith "MatSeqBAIJSetColumnIndices_SeqBAIJ", 151527a8da17SBarry Smith (void*)MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr); 15163a40ed3dSBarry Smith PetscFunctionReturn(0); 15172593348eSBarry Smith } 15182593348eSBarry Smith 15195615d1e5SSatish Balay #undef __FUNC__ 15205615d1e5SSatish Balay #define __FUNC__ "MatLoad_SeqBAIJ" 152119bcc07fSBarry Smith int MatLoad_SeqBAIJ(Viewer viewer,MatType type,Mat *A) 15222593348eSBarry Smith { 1523b6490206SBarry Smith Mat_SeqBAIJ *a; 15242593348eSBarry Smith Mat B; 1525de6a44a3SBarry Smith int i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1,flg; 1526b6490206SBarry Smith int *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount; 152735aab85fSBarry Smith int kmax,jcount,block,idx,point,nzcountb,extra_rows; 1528a7c10996SSatish Balay int *masked, nmask,tmp,bs2,ishift; 1529b6490206SBarry Smith Scalar *aa; 153019bcc07fSBarry Smith MPI_Comm comm = ((PetscObject) viewer)->comm; 15312593348eSBarry Smith 15323a40ed3dSBarry Smith PetscFunctionBegin; 15331a6a6d98SBarry Smith ierr = OptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,&flg);CHKERRQ(ierr); 1534de6a44a3SBarry Smith bs2 = bs*bs; 1535b6490206SBarry Smith 15362593348eSBarry Smith MPI_Comm_size(comm,&size); 1537cc0fae11SBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"view must have one processor"); 153890ace30eSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr); 15390752156aSBarry Smith ierr = PetscBinaryRead(fd,header,4,PETSC_INT); CHKERRQ(ierr); 1540a8c6a408SBarry Smith if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"not Mat object"); 15412593348eSBarry Smith M = header[1]; N = header[2]; nz = header[3]; 15422593348eSBarry Smith 1543d64ed03dSBarry Smith if (header[3] < 0) { 1544a8c6a408SBarry Smith SETERRQ(PETSC_ERR_FILE_UNEXPECTED,1,"Matrix stored in special format, cannot load as SeqBAIJ"); 1545d64ed03dSBarry Smith } 1546d64ed03dSBarry Smith 1547a8c6a408SBarry Smith if (M != N) SETERRQ(PETSC_ERR_SUP,0,"Can only do square matrices"); 154835aab85fSBarry Smith 154935aab85fSBarry Smith /* 155035aab85fSBarry Smith This code adds extra rows to make sure the number of rows is 155135aab85fSBarry Smith divisible by the blocksize 155235aab85fSBarry Smith */ 1553b6490206SBarry Smith mbs = M/bs; 155435aab85fSBarry Smith extra_rows = bs - M + bs*(mbs); 155535aab85fSBarry Smith if (extra_rows == bs) extra_rows = 0; 155635aab85fSBarry Smith else mbs++; 155735aab85fSBarry Smith if (extra_rows) { 1558537820f0SBarry Smith PLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n"); 155935aab85fSBarry Smith } 1560b6490206SBarry Smith 15612593348eSBarry Smith /* read in row lengths */ 156235aab85fSBarry Smith rowlengths = (int*) PetscMalloc((M+extra_rows)*sizeof(int));CHKPTRQ(rowlengths); 15630752156aSBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT); CHKERRQ(ierr); 156435aab85fSBarry Smith for ( i=0; i<extra_rows; i++ ) rowlengths[M+i] = 1; 15652593348eSBarry Smith 1566b6490206SBarry Smith /* read in column indices */ 156735aab85fSBarry Smith jj = (int*) PetscMalloc( (nz+extra_rows)*sizeof(int) ); CHKPTRQ(jj); 15680752156aSBarry Smith ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT); CHKERRQ(ierr); 156935aab85fSBarry Smith for ( i=0; i<extra_rows; i++ ) jj[nz+i] = M+i; 1570b6490206SBarry Smith 1571b6490206SBarry Smith /* loop over row lengths determining block row lengths */ 1572b6490206SBarry Smith browlengths = (int *) PetscMalloc(mbs*sizeof(int));CHKPTRQ(browlengths); 1573b6490206SBarry Smith PetscMemzero(browlengths,mbs*sizeof(int)); 157435aab85fSBarry Smith mask = (int *) PetscMalloc( 2*mbs*sizeof(int) ); CHKPTRQ(mask); 157535aab85fSBarry Smith PetscMemzero(mask,mbs*sizeof(int)); 157635aab85fSBarry Smith masked = mask + mbs; 1577b6490206SBarry Smith rowcount = 0; nzcount = 0; 1578b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 157935aab85fSBarry Smith nmask = 0; 1580b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 1581b6490206SBarry Smith kmax = rowlengths[rowcount]; 1582b6490206SBarry Smith for ( k=0; k<kmax; k++ ) { 158335aab85fSBarry Smith tmp = jj[nzcount++]/bs; 158435aab85fSBarry Smith if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;} 1585b6490206SBarry Smith } 1586b6490206SBarry Smith rowcount++; 1587b6490206SBarry Smith } 158835aab85fSBarry Smith browlengths[i] += nmask; 158935aab85fSBarry Smith /* zero out the mask elements we set */ 159035aab85fSBarry Smith for ( j=0; j<nmask; j++ ) mask[masked[j]] = 0; 1591b6490206SBarry Smith } 1592b6490206SBarry Smith 15932593348eSBarry Smith /* create our matrix */ 15943eee16b0SBarry Smith ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A);CHKERRQ(ierr); 15952593348eSBarry Smith B = *A; 1596b6490206SBarry Smith a = (Mat_SeqBAIJ *) B->data; 15972593348eSBarry Smith 15982593348eSBarry Smith /* set matrix "i" values */ 1599de6a44a3SBarry Smith a->i[0] = 0; 1600b6490206SBarry Smith for ( i=1; i<= mbs; i++ ) { 1601b6490206SBarry Smith a->i[i] = a->i[i-1] + browlengths[i-1]; 1602b6490206SBarry Smith a->ilen[i-1] = browlengths[i-1]; 16032593348eSBarry Smith } 1604b6490206SBarry Smith a->nz = 0; 1605b6490206SBarry Smith for ( i=0; i<mbs; i++ ) a->nz += browlengths[i]; 16062593348eSBarry Smith 1607b6490206SBarry Smith /* read in nonzero values */ 160835aab85fSBarry Smith aa = (Scalar *) PetscMalloc((nz+extra_rows)*sizeof(Scalar));CHKPTRQ(aa); 16090752156aSBarry Smith ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR); CHKERRQ(ierr); 161035aab85fSBarry Smith for ( i=0; i<extra_rows; i++ ) aa[nz+i] = 1.0; 1611b6490206SBarry Smith 1612b6490206SBarry Smith /* set "a" and "j" values into matrix */ 1613b6490206SBarry Smith nzcount = 0; jcount = 0; 1614b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 1615b6490206SBarry Smith nzcountb = nzcount; 161635aab85fSBarry Smith nmask = 0; 1617b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 1618b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 1619b6490206SBarry Smith for ( k=0; k<kmax; k++ ) { 162035aab85fSBarry Smith tmp = jj[nzcount++]/bs; 162135aab85fSBarry Smith if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;} 1622b6490206SBarry Smith } 1623b6490206SBarry Smith rowcount++; 1624b6490206SBarry Smith } 1625de6a44a3SBarry Smith /* sort the masked values */ 162677c4ece6SBarry Smith PetscSortInt(nmask,masked); 1627de6a44a3SBarry Smith 1628b6490206SBarry Smith /* set "j" values into matrix */ 1629b6490206SBarry Smith maskcount = 1; 163035aab85fSBarry Smith for ( j=0; j<nmask; j++ ) { 163135aab85fSBarry Smith a->j[jcount++] = masked[j]; 1632de6a44a3SBarry Smith mask[masked[j]] = maskcount++; 1633b6490206SBarry Smith } 1634b6490206SBarry Smith /* set "a" values into matrix */ 1635de6a44a3SBarry Smith ishift = bs2*a->i[i]; 1636b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 1637b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 1638b6490206SBarry Smith for ( k=0; k<kmax; k++ ) { 1639de6a44a3SBarry Smith tmp = jj[nzcountb]/bs ; 1640de6a44a3SBarry Smith block = mask[tmp] - 1; 1641de6a44a3SBarry Smith point = jj[nzcountb] - bs*tmp; 1642de6a44a3SBarry Smith idx = ishift + bs2*block + j + bs*point; 1643b6490206SBarry Smith a->a[idx] = aa[nzcountb++]; 1644b6490206SBarry Smith } 1645b6490206SBarry Smith } 164635aab85fSBarry Smith /* zero out the mask elements we set */ 164735aab85fSBarry Smith for ( j=0; j<nmask; j++ ) mask[masked[j]] = 0; 1648b6490206SBarry Smith } 1649a8c6a408SBarry Smith if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"Bad binary matrix"); 1650b6490206SBarry Smith 1651b6490206SBarry Smith PetscFree(rowlengths); 1652b6490206SBarry Smith PetscFree(browlengths); 1653b6490206SBarry Smith PetscFree(aa); 1654b6490206SBarry Smith PetscFree(jj); 1655b6490206SBarry Smith PetscFree(mask); 1656b6490206SBarry Smith 1657b6490206SBarry Smith B->assembled = PETSC_TRUE; 1658de6a44a3SBarry Smith 16599c01be13SBarry Smith ierr = MatView_Private(B); CHKERRQ(ierr); 16603a40ed3dSBarry Smith PetscFunctionReturn(0); 16612593348eSBarry Smith } 16622593348eSBarry Smith 16632593348eSBarry Smith 16642593348eSBarry Smith 1665