1a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER 2*32e87ba3SBarry Smith static char vcid[] = "$Id: baij.c,v 1.168 1999/03/23 22:06:45 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 #include "sys.h" 1070f55243SBarry Smith #include "src/mat/impls/baij/seq/baij.h" 111a6a6d98SBarry Smith #include "src/vec/vecimpl.h" 121a6a6d98SBarry Smith #include "src/inline/spops.h" 133b547af2SSatish Balay 142d61bbb3SSatish Balay #define CHUNKSIZE 10 15de6a44a3SBarry Smith 16be5855fcSBarry Smith /* 17be5855fcSBarry Smith Checks for missing diagonals 18be5855fcSBarry Smith */ 19be5855fcSBarry Smith #undef __FUNC__ 20be5855fcSBarry Smith #define __FUNC__ "MatMissingDiag_SeqBAIJ" 21be5855fcSBarry Smith int MatMissingDiag_SeqBAIJ(Mat A) 22be5855fcSBarry Smith { 23be5855fcSBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 24be5855fcSBarry Smith int *diag = a->diag, *jj = a->j,i; 25be5855fcSBarry Smith 26be5855fcSBarry Smith PetscFunctionBegin; 270e8e8aceSBarry Smith for ( i=0; i<a->mbs; i++ ) { 28be5855fcSBarry Smith if (jj[diag[i]] != i) { 29be5855fcSBarry Smith SETERRQ1(1,1,"Matrix is missing diagonal number %d",i); 30be5855fcSBarry Smith } 31be5855fcSBarry Smith } 32be5855fcSBarry Smith PetscFunctionReturn(0); 33be5855fcSBarry Smith } 34be5855fcSBarry Smith 355615d1e5SSatish Balay #undef __FUNC__ 365615d1e5SSatish Balay #define __FUNC__ "MatMarkDiag_SeqBAIJ" 37de6a44a3SBarry Smith int MatMarkDiag_SeqBAIJ(Mat A) 38de6a44a3SBarry Smith { 39de6a44a3SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 407fc0212eSBarry Smith int i,j, *diag, m = a->mbs; 41de6a44a3SBarry Smith 423a40ed3dSBarry Smith PetscFunctionBegin; 43de6a44a3SBarry Smith diag = (int *) PetscMalloc( (m+1)*sizeof(int)); CHKPTRQ(diag); 44de6a44a3SBarry Smith PLogObjectMemory(A,(m+1)*sizeof(int)); 457fc0212eSBarry Smith for ( i=0; i<m; i++ ) { 46ecc615b2SBarry Smith diag[i] = a->i[i+1]; 47de6a44a3SBarry Smith for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 48de6a44a3SBarry Smith if (a->j[j] == i) { 49de6a44a3SBarry Smith diag[i] = j; 50de6a44a3SBarry Smith break; 51de6a44a3SBarry Smith } 52de6a44a3SBarry Smith } 53de6a44a3SBarry Smith } 54de6a44a3SBarry Smith a->diag = diag; 553a40ed3dSBarry Smith PetscFunctionReturn(0); 56de6a44a3SBarry Smith } 572593348eSBarry Smith 582593348eSBarry Smith 593b2fbd54SBarry Smith extern int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**); 603b2fbd54SBarry Smith 615615d1e5SSatish Balay #undef __FUNC__ 625615d1e5SSatish Balay #define __FUNC__ "MatGetRowIJ_SeqBAIJ" 633b2fbd54SBarry Smith static int MatGetRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja, 643b2fbd54SBarry Smith PetscTruth *done) 653b2fbd54SBarry Smith { 663b2fbd54SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 673b2fbd54SBarry Smith int ierr, n = a->mbs,i; 683b2fbd54SBarry Smith 693a40ed3dSBarry Smith PetscFunctionBegin; 703b2fbd54SBarry Smith *nn = n; 713a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 723b2fbd54SBarry Smith if (symmetric) { 733b2fbd54SBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(n,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr); 743b2fbd54SBarry Smith } else if (oshift == 1) { 753b2fbd54SBarry Smith /* temporarily add 1 to i and j indices */ 763b2fbd54SBarry Smith int nz = a->i[n] + 1; 773b2fbd54SBarry Smith for ( i=0; i<nz; i++ ) a->j[i]++; 783b2fbd54SBarry Smith for ( i=0; i<n+1; i++ ) a->i[i]++; 793b2fbd54SBarry Smith *ia = a->i; *ja = a->j; 803b2fbd54SBarry Smith } else { 813b2fbd54SBarry Smith *ia = a->i; *ja = a->j; 823b2fbd54SBarry Smith } 833b2fbd54SBarry Smith 843a40ed3dSBarry Smith PetscFunctionReturn(0); 853b2fbd54SBarry Smith } 863b2fbd54SBarry Smith 875615d1e5SSatish Balay #undef __FUNC__ 88d4bb536fSBarry Smith #define __FUNC__ "MatRestoreRowIJ_SeqBAIJ" 893b2fbd54SBarry Smith static int MatRestoreRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja, 903b2fbd54SBarry Smith PetscTruth *done) 913b2fbd54SBarry Smith { 923b2fbd54SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 933b2fbd54SBarry Smith int i,n = a->mbs; 943b2fbd54SBarry Smith 953a40ed3dSBarry Smith PetscFunctionBegin; 963a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 973b2fbd54SBarry Smith if (symmetric) { 983b2fbd54SBarry Smith PetscFree(*ia); 993b2fbd54SBarry Smith PetscFree(*ja); 100af5da2bfSBarry Smith } else if (oshift == 1) { 1013b2fbd54SBarry Smith int nz = a->i[n]; 1023b2fbd54SBarry Smith for ( i=0; i<nz; i++ ) a->j[i]--; 1033b2fbd54SBarry Smith for ( i=0; i<n+1; i++ ) a->i[i]--; 1043b2fbd54SBarry Smith } 1053a40ed3dSBarry Smith PetscFunctionReturn(0); 1063b2fbd54SBarry Smith } 1073b2fbd54SBarry Smith 1082d61bbb3SSatish Balay #undef __FUNC__ 1092d61bbb3SSatish Balay #define __FUNC__ "MatGetBlockSize_SeqBAIJ" 1102d61bbb3SSatish Balay int MatGetBlockSize_SeqBAIJ(Mat mat, int *bs) 1112d61bbb3SSatish Balay { 1122d61bbb3SSatish Balay Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *) mat->data; 1132d61bbb3SSatish Balay 1142d61bbb3SSatish Balay PetscFunctionBegin; 1152d61bbb3SSatish Balay *bs = baij->bs; 1162d61bbb3SSatish Balay PetscFunctionReturn(0); 1172d61bbb3SSatish Balay } 1182d61bbb3SSatish Balay 1192d61bbb3SSatish Balay 1202d61bbb3SSatish Balay #undef __FUNC__ 1212d61bbb3SSatish Balay #define __FUNC__ "MatDestroy_SeqBAIJ" 122e1311b90SBarry Smith int MatDestroy_SeqBAIJ(Mat A) 1232d61bbb3SSatish Balay { 1242d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 125e51c0b9cSSatish Balay int ierr; 1262d61bbb3SSatish Balay 12794d884c6SBarry Smith if (--A->refct > 0) PetscFunctionReturn(0); 12894d884c6SBarry Smith 12994d884c6SBarry Smith if (A->mapping) { 13094d884c6SBarry Smith ierr = ISLocalToGlobalMappingDestroy(A->mapping); CHKERRQ(ierr); 13194d884c6SBarry Smith } 13294d884c6SBarry Smith if (A->bmapping) { 13394d884c6SBarry Smith ierr = ISLocalToGlobalMappingDestroy(A->bmapping); CHKERRQ(ierr); 13494d884c6SBarry Smith } 13561b13de0SBarry Smith if (A->rmap) { 13661b13de0SBarry Smith ierr = MapDestroy(A->rmap);CHKERRQ(ierr); 13761b13de0SBarry Smith } 13861b13de0SBarry Smith if (A->cmap) { 13961b13de0SBarry Smith ierr = MapDestroy(A->cmap);CHKERRQ(ierr); 14061b13de0SBarry Smith } 1412d61bbb3SSatish Balay #if defined(USE_PETSC_LOG) 142e1311b90SBarry Smith PLogObjectState((PetscObject) A,"Rows=%d, Cols=%d, NZ=%d",a->m,a->n,a->nz); 1432d61bbb3SSatish Balay #endif 1442d61bbb3SSatish Balay PetscFree(a->a); 1452d61bbb3SSatish Balay if (!a->singlemalloc) { PetscFree(a->i); PetscFree(a->j);} 1462d61bbb3SSatish Balay if (a->diag) PetscFree(a->diag); 1472d61bbb3SSatish Balay if (a->ilen) PetscFree(a->ilen); 1482d61bbb3SSatish Balay if (a->imax) PetscFree(a->imax); 1492d61bbb3SSatish Balay if (a->solve_work) PetscFree(a->solve_work); 1502d61bbb3SSatish Balay if (a->mult_work) PetscFree(a->mult_work); 151e51c0b9cSSatish Balay if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} 1523e90b805SBarry Smith if (a->saved_values) PetscFree(a->saved_values); 1532d61bbb3SSatish Balay PetscFree(a); 1542d61bbb3SSatish Balay PLogObjectDestroy(A); 1552d61bbb3SSatish Balay PetscHeaderDestroy(A); 1562d61bbb3SSatish Balay PetscFunctionReturn(0); 1572d61bbb3SSatish Balay } 1582d61bbb3SSatish Balay 1592d61bbb3SSatish Balay #undef __FUNC__ 1602d61bbb3SSatish Balay #define __FUNC__ "MatSetOption_SeqBAIJ" 1612d61bbb3SSatish Balay int MatSetOption_SeqBAIJ(Mat A,MatOption op) 1622d61bbb3SSatish Balay { 1632d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 1642d61bbb3SSatish Balay 1652d61bbb3SSatish Balay PetscFunctionBegin; 1662d61bbb3SSatish Balay if (op == MAT_ROW_ORIENTED) a->roworiented = 1; 1672d61bbb3SSatish Balay else if (op == MAT_COLUMN_ORIENTED) a->roworiented = 0; 1682d61bbb3SSatish Balay else if (op == MAT_COLUMNS_SORTED) a->sorted = 1; 1692d61bbb3SSatish Balay else if (op == MAT_COLUMNS_UNSORTED) a->sorted = 0; 1702d61bbb3SSatish Balay else if (op == MAT_NO_NEW_NONZERO_LOCATIONS) a->nonew = 1; 1714787f768SSatish Balay else if (op == MAT_NEW_NONZERO_LOCATION_ERR) a->nonew = -1; 1724787f768SSatish Balay else if (op == MAT_NEW_NONZERO_ALLOCATION_ERR) a->nonew = -2; 1732d61bbb3SSatish Balay else if (op == MAT_YES_NEW_NONZERO_LOCATIONS) a->nonew = 0; 1742d61bbb3SSatish Balay else if (op == MAT_ROWS_SORTED || 1752d61bbb3SSatish Balay op == MAT_ROWS_UNSORTED || 1762d61bbb3SSatish Balay op == MAT_SYMMETRIC || 1772d61bbb3SSatish Balay op == MAT_STRUCTURALLY_SYMMETRIC || 1782d61bbb3SSatish Balay op == MAT_YES_NEW_DIAGONALS || 179b51ba29fSSatish Balay op == MAT_IGNORE_OFF_PROC_ENTRIES || 180b51ba29fSSatish Balay op == MAT_USE_HASH_TABLE) { 181981c4779SBarry Smith PLogInfo(A,"MatSetOption_SeqBAIJ:Option ignored\n"); 1822d61bbb3SSatish Balay } else if (op == MAT_NO_NEW_DIAGONALS) { 1832d61bbb3SSatish Balay SETERRQ(PETSC_ERR_SUP,0,"MAT_NO_NEW_DIAGONALS"); 1842d61bbb3SSatish Balay } else { 1852d61bbb3SSatish Balay SETERRQ(PETSC_ERR_SUP,0,"unknown option"); 1862d61bbb3SSatish Balay } 1872d61bbb3SSatish Balay PetscFunctionReturn(0); 1882d61bbb3SSatish Balay } 1892d61bbb3SSatish Balay 1902d61bbb3SSatish Balay 1912d61bbb3SSatish Balay #undef __FUNC__ 1922d61bbb3SSatish Balay #define __FUNC__ "MatGetSize_SeqBAIJ" 1932d61bbb3SSatish Balay int MatGetSize_SeqBAIJ(Mat A,int *m,int *n) 1942d61bbb3SSatish Balay { 1952d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 1962d61bbb3SSatish Balay 1972d61bbb3SSatish Balay PetscFunctionBegin; 1982d61bbb3SSatish Balay if (m) *m = a->m; 1992d61bbb3SSatish Balay if (n) *n = a->n; 2002d61bbb3SSatish Balay PetscFunctionReturn(0); 2012d61bbb3SSatish Balay } 2022d61bbb3SSatish Balay 2032d61bbb3SSatish Balay #undef __FUNC__ 2042d61bbb3SSatish Balay #define __FUNC__ "MatGetOwnershipRange_SeqBAIJ" 2052d61bbb3SSatish Balay int MatGetOwnershipRange_SeqBAIJ(Mat A,int *m,int *n) 2062d61bbb3SSatish Balay { 2072d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 2082d61bbb3SSatish Balay 2092d61bbb3SSatish Balay PetscFunctionBegin; 2102d61bbb3SSatish Balay *m = 0; *n = a->m; 2112d61bbb3SSatish Balay PetscFunctionReturn(0); 2122d61bbb3SSatish Balay } 2132d61bbb3SSatish Balay 2142d61bbb3SSatish Balay #undef __FUNC__ 2152d61bbb3SSatish Balay #define __FUNC__ "MatGetRow_SeqBAIJ" 2162d61bbb3SSatish Balay int MatGetRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 2172d61bbb3SSatish Balay { 2182d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 2192d61bbb3SSatish Balay int itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*idx_i,bs2; 2203f1db9ecSBarry Smith MatScalar *aa,*aa_i; 2213f1db9ecSBarry Smith Scalar *v_i; 2222d61bbb3SSatish Balay 2232d61bbb3SSatish Balay PetscFunctionBegin; 2242d61bbb3SSatish Balay bs = a->bs; 2252d61bbb3SSatish Balay ai = a->i; 2262d61bbb3SSatish Balay aj = a->j; 2272d61bbb3SSatish Balay aa = a->a; 2282d61bbb3SSatish Balay bs2 = a->bs2; 2292d61bbb3SSatish Balay 2302d61bbb3SSatish Balay if (row < 0 || row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row out of range"); 2312d61bbb3SSatish Balay 2322d61bbb3SSatish Balay bn = row/bs; /* Block number */ 2332d61bbb3SSatish Balay bp = row % bs; /* Block Position */ 2342d61bbb3SSatish Balay M = ai[bn+1] - ai[bn]; 2352d61bbb3SSatish Balay *nz = bs*M; 2362d61bbb3SSatish Balay 2372d61bbb3SSatish Balay if (v) { 2382d61bbb3SSatish Balay *v = 0; 2392d61bbb3SSatish Balay if (*nz) { 2402d61bbb3SSatish Balay *v = (Scalar *) PetscMalloc( (*nz)*sizeof(Scalar) ); CHKPTRQ(*v); 2412d61bbb3SSatish Balay for ( i=0; i<M; i++ ) { /* for each block in the block row */ 2422d61bbb3SSatish Balay v_i = *v + i*bs; 2432d61bbb3SSatish Balay aa_i = aa + bs2*(ai[bn] + i); 2442d61bbb3SSatish Balay for ( j=bp,k=0; j<bs2; j+=bs,k++ ) {v_i[k] = aa_i[j];} 2452d61bbb3SSatish Balay } 2462d61bbb3SSatish Balay } 2472d61bbb3SSatish Balay } 2482d61bbb3SSatish Balay 2492d61bbb3SSatish Balay if (idx) { 2502d61bbb3SSatish Balay *idx = 0; 2512d61bbb3SSatish Balay if (*nz) { 2522d61bbb3SSatish Balay *idx = (int *) PetscMalloc( (*nz)*sizeof(int) ); CHKPTRQ(*idx); 2532d61bbb3SSatish Balay for ( i=0; i<M; i++ ) { /* for each block in the block row */ 2542d61bbb3SSatish Balay idx_i = *idx + i*bs; 2552d61bbb3SSatish Balay itmp = bs*aj[ai[bn] + i]; 2562d61bbb3SSatish Balay for ( j=0; j<bs; j++ ) {idx_i[j] = itmp++;} 2572d61bbb3SSatish Balay } 2582d61bbb3SSatish Balay } 2592d61bbb3SSatish Balay } 2602d61bbb3SSatish Balay PetscFunctionReturn(0); 2612d61bbb3SSatish Balay } 2622d61bbb3SSatish Balay 2632d61bbb3SSatish Balay #undef __FUNC__ 2642d61bbb3SSatish Balay #define __FUNC__ "MatRestoreRow_SeqBAIJ" 2652d61bbb3SSatish Balay int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 2662d61bbb3SSatish Balay { 2672d61bbb3SSatish Balay PetscFunctionBegin; 2682d61bbb3SSatish Balay if (idx) {if (*idx) PetscFree(*idx);} 2692d61bbb3SSatish Balay if (v) {if (*v) PetscFree(*v);} 2702d61bbb3SSatish Balay PetscFunctionReturn(0); 2712d61bbb3SSatish Balay } 2722d61bbb3SSatish Balay 2732d61bbb3SSatish Balay #undef __FUNC__ 2742d61bbb3SSatish Balay #define __FUNC__ "MatTranspose_SeqBAIJ" 2752d61bbb3SSatish Balay int MatTranspose_SeqBAIJ(Mat A,Mat *B) 2762d61bbb3SSatish Balay { 2772d61bbb3SSatish Balay Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data; 2782d61bbb3SSatish Balay Mat C; 2792d61bbb3SSatish Balay int i,j,k,ierr,*aj=a->j,*ai=a->i,bs=a->bs,mbs=a->mbs,nbs=a->nbs,len,*col; 2802d61bbb3SSatish Balay int *rows,*cols,bs2=a->bs2; 2813f1db9ecSBarry Smith MatScalar *array = a->a; 2822d61bbb3SSatish Balay 2832d61bbb3SSatish Balay PetscFunctionBegin; 2842d61bbb3SSatish Balay if (B==PETSC_NULL && mbs!=nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Square matrix only for in-place"); 2852d61bbb3SSatish Balay col = (int *) PetscMalloc((1+nbs)*sizeof(int)); CHKPTRQ(col); 2862d61bbb3SSatish Balay PetscMemzero(col,(1+nbs)*sizeof(int)); 2872d61bbb3SSatish Balay 2882d61bbb3SSatish Balay for ( i=0; i<ai[mbs]; i++ ) col[aj[i]] += 1; 2892d61bbb3SSatish Balay ierr = MatCreateSeqBAIJ(A->comm,bs,a->n,a->m,PETSC_NULL,col,&C); CHKERRQ(ierr); 2902d61bbb3SSatish Balay PetscFree(col); 2912d61bbb3SSatish Balay rows = (int *) PetscMalloc(2*bs*sizeof(int)); CHKPTRQ(rows); 2922d61bbb3SSatish Balay cols = rows + bs; 2932d61bbb3SSatish Balay for ( i=0; i<mbs; i++ ) { 2942d61bbb3SSatish Balay cols[0] = i*bs; 2952d61bbb3SSatish Balay for (k=1; k<bs; k++ ) cols[k] = cols[k-1] + 1; 2962d61bbb3SSatish Balay len = ai[i+1] - ai[i]; 2972d61bbb3SSatish Balay for ( j=0; j<len; j++ ) { 2982d61bbb3SSatish Balay rows[0] = (*aj++)*bs; 2992d61bbb3SSatish Balay for (k=1; k<bs; k++ ) rows[k] = rows[k-1] + 1; 3002d61bbb3SSatish Balay ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES); CHKERRQ(ierr); 3012d61bbb3SSatish Balay array += bs2; 3022d61bbb3SSatish Balay } 3032d61bbb3SSatish Balay } 3042d61bbb3SSatish Balay PetscFree(rows); 3052d61bbb3SSatish Balay 3062d61bbb3SSatish Balay ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 3072d61bbb3SSatish Balay ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 3082d61bbb3SSatish Balay 3092d61bbb3SSatish Balay if (B != PETSC_NULL) { 3102d61bbb3SSatish Balay *B = C; 3112d61bbb3SSatish Balay } else { 312f830108cSBarry Smith PetscOps *Abops; 313cc2dc46cSBarry Smith MatOps Aops; 314f830108cSBarry Smith 3152d61bbb3SSatish Balay /* This isn't really an in-place transpose */ 3162d61bbb3SSatish Balay PetscFree(a->a); 3172d61bbb3SSatish Balay if (!a->singlemalloc) {PetscFree(a->i); PetscFree(a->j);} 3182d61bbb3SSatish Balay if (a->diag) PetscFree(a->diag); 3192d61bbb3SSatish Balay if (a->ilen) PetscFree(a->ilen); 3202d61bbb3SSatish Balay if (a->imax) PetscFree(a->imax); 3212d61bbb3SSatish Balay if (a->solve_work) PetscFree(a->solve_work); 3222d61bbb3SSatish Balay PetscFree(a); 323f830108cSBarry Smith 3247413bad6SBarry Smith 3257413bad6SBarry Smith ierr = MapDestroy(A->rmap);CHKERRQ(ierr); 3267413bad6SBarry Smith ierr = MapDestroy(A->cmap);CHKERRQ(ierr); 3277413bad6SBarry Smith 328f830108cSBarry Smith /* 329f830108cSBarry Smith This is horrible, horrible code. We need to keep the 330f830108cSBarry Smith A pointers for the bops and ops but copy everything 331f830108cSBarry Smith else from C. 332f830108cSBarry Smith */ 333f830108cSBarry Smith Abops = A->bops; 334f830108cSBarry Smith Aops = A->ops; 3352d61bbb3SSatish Balay PetscMemcpy(A,C,sizeof(struct _p_Mat)); 336f830108cSBarry Smith A->bops = Abops; 337f830108cSBarry Smith A->ops = Aops; 33827a8da17SBarry Smith A->qlist = 0; 339f830108cSBarry Smith 3402d61bbb3SSatish Balay PetscHeaderDestroy(C); 3412d61bbb3SSatish Balay } 3422d61bbb3SSatish Balay PetscFunctionReturn(0); 3432d61bbb3SSatish Balay } 3442d61bbb3SSatish Balay 3455615d1e5SSatish Balay #undef __FUNC__ 346d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Binary" 347b6490206SBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,Viewer viewer) 3482593348eSBarry Smith { 349b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 3509df24120SSatish Balay int i, fd, *col_lens, ierr, bs = a->bs,count,*jj,j,k,l,bs2=a->bs2; 351b6490206SBarry Smith Scalar *aa; 352ce6f0cecSBarry Smith FILE *file; 3532593348eSBarry Smith 3543a40ed3dSBarry Smith PetscFunctionBegin; 35590ace30eSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr); 3562593348eSBarry Smith col_lens = (int *) PetscMalloc((4+a->m)*sizeof(int));CHKPTRQ(col_lens); 3572593348eSBarry Smith col_lens[0] = MAT_COOKIE; 3583b2fbd54SBarry Smith 3592593348eSBarry Smith col_lens[1] = a->m; 3602593348eSBarry Smith col_lens[2] = a->n; 3617e67e3f9SSatish Balay col_lens[3] = a->nz*bs2; 3622593348eSBarry Smith 3632593348eSBarry Smith /* store lengths of each row and write (including header) to file */ 364b6490206SBarry Smith count = 0; 365b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 366b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 367b6490206SBarry Smith col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]); 368b6490206SBarry Smith } 3692593348eSBarry Smith } 3700752156aSBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+a->m,PETSC_INT,1); CHKERRQ(ierr); 3712593348eSBarry Smith PetscFree(col_lens); 3722593348eSBarry Smith 3732593348eSBarry Smith /* store column indices (zero start index) */ 37466963ce1SSatish Balay jj = (int *) PetscMalloc( (a->nz+1)*bs2*sizeof(int) ); CHKPTRQ(jj); 375b6490206SBarry Smith count = 0; 376b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 377b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 378b6490206SBarry Smith for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 379b6490206SBarry Smith for ( l=0; l<bs; l++ ) { 380b6490206SBarry Smith jj[count++] = bs*a->j[k] + l; 3812593348eSBarry Smith } 3822593348eSBarry Smith } 383b6490206SBarry Smith } 384b6490206SBarry Smith } 3850752156aSBarry Smith ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0); CHKERRQ(ierr); 386b6490206SBarry Smith PetscFree(jj); 3872593348eSBarry Smith 3882593348eSBarry Smith /* store nonzero values */ 38966963ce1SSatish Balay aa = (Scalar *) PetscMalloc((a->nz+1)*bs2*sizeof(Scalar)); CHKPTRQ(aa); 390b6490206SBarry Smith count = 0; 391b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 392b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 393b6490206SBarry Smith for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 394b6490206SBarry Smith for ( l=0; l<bs; l++ ) { 3957e67e3f9SSatish Balay aa[count++] = a->a[bs2*k + l*bs + j]; 396b6490206SBarry Smith } 397b6490206SBarry Smith } 398b6490206SBarry Smith } 399b6490206SBarry Smith } 4000752156aSBarry Smith ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0); CHKERRQ(ierr); 401b6490206SBarry Smith PetscFree(aa); 402ce6f0cecSBarry Smith 403ce6f0cecSBarry Smith ierr = ViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr); 404ce6f0cecSBarry Smith if (file) { 405ce6f0cecSBarry Smith fprintf(file,"-matload_block_size %d\n",a->bs); 406ce6f0cecSBarry Smith } 4073a40ed3dSBarry Smith PetscFunctionReturn(0); 4082593348eSBarry Smith } 4092593348eSBarry Smith 4105615d1e5SSatish Balay #undef __FUNC__ 411d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_ASCII" 412b6490206SBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,Viewer viewer) 4132593348eSBarry Smith { 414b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 4159df24120SSatish Balay int ierr, i,j,format,bs = a->bs,k,l,bs2=a->bs2; 4162593348eSBarry Smith FILE *fd; 4172593348eSBarry Smith char *outputname; 4182593348eSBarry Smith 4193a40ed3dSBarry Smith PetscFunctionBegin; 42090ace30eSBarry Smith ierr = ViewerASCIIGetPointer(viewer,&fd); CHKERRQ(ierr); 42177ed5343SBarry Smith ierr = ViewerGetOutputname(viewer,&outputname);CHKERRQ(ierr); 42290ace30eSBarry Smith ierr = ViewerGetFormat(viewer,&format); 423639f9d9dSBarry Smith if (format == VIEWER_FORMAT_ASCII_INFO || format == VIEWER_FORMAT_ASCII_INFO_LONG) { 4240ef38995SBarry Smith ViewerASCIIPrintf(viewer," block size is %d\n",bs); 4250ef38995SBarry Smith } else if (format == VIEWER_FORMAT_ASCII_MATLAB) { 4267b2a1423SBarry Smith SETERRQ(PETSC_ERR_SUP,0,"Socket format not supported"); 4270ef38995SBarry Smith } else if (format == VIEWER_FORMAT_ASCII_COMMON) { 42844cd7ae7SLois Curfman McInnes for ( i=0; i<a->mbs; i++ ) { 42944cd7ae7SLois Curfman McInnes for ( j=0; j<bs; j++ ) { 43044cd7ae7SLois Curfman McInnes fprintf(fd,"row %d:",i*bs+j); 43144cd7ae7SLois Curfman McInnes for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 43244cd7ae7SLois Curfman McInnes for ( l=0; l<bs; l++ ) { 4333a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX) 4340ef38995SBarry Smith if (PetscImaginary(a->a[bs2*k + l*bs + j]) > 0.0 && PetscReal(a->a[bs2*k + l*bs + j]) != 0.0) { 43544cd7ae7SLois Curfman McInnes fprintf(fd," %d %g + %g i",bs*a->j[k]+l, 436e20fef11SSatish Balay PetscReal(a->a[bs2*k + l*bs + j]),PetscImaginary(a->a[bs2*k + l*bs + j])); 4370ef38995SBarry Smith } else if (PetscImaginary(a->a[bs2*k + l*bs + j]) < 0.0 && PetscReal(a->a[bs2*k + l*bs + j]) != 0.0) { 438766eeae4SLois Curfman McInnes fprintf(fd," %d %g - %g i",bs*a->j[k]+l, 439e20fef11SSatish Balay PetscReal(a->a[bs2*k + l*bs + j]),-PetscImaginary(a->a[bs2*k + l*bs + j])); 4400ef38995SBarry Smith } else if (PetscReal(a->a[bs2*k + l*bs + j]) != 0.0) { 441e20fef11SSatish Balay fprintf(fd," %d %g ",bs*a->j[k]+l,PetscReal(a->a[bs2*k + l*bs + j])); 4420ef38995SBarry Smith } 44344cd7ae7SLois Curfman McInnes #else 4440ef38995SBarry Smith if (a->a[bs2*k + l*bs + j] != 0.0) { 44544cd7ae7SLois Curfman McInnes fprintf(fd," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]); 4460ef38995SBarry Smith } 44744cd7ae7SLois Curfman McInnes #endif 44844cd7ae7SLois Curfman McInnes } 44944cd7ae7SLois Curfman McInnes } 45044cd7ae7SLois Curfman McInnes fprintf(fd,"\n"); 45144cd7ae7SLois Curfman McInnes } 45244cd7ae7SLois Curfman McInnes } 4530ef38995SBarry Smith } else { 454b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 455b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 456b6490206SBarry Smith fprintf(fd,"row %d:",i*bs+j); 457b6490206SBarry Smith for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 458b6490206SBarry Smith for ( l=0; l<bs; l++ ) { 4593a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX) 460e20fef11SSatish Balay if (PetscImaginary(a->a[bs2*k + l*bs + j]) > 0.0) { 46188685aaeSLois Curfman McInnes fprintf(fd," %d %g + %g i",bs*a->j[k]+l, 462e20fef11SSatish Balay PetscReal(a->a[bs2*k + l*bs + j]),PetscImaginary(a->a[bs2*k + l*bs + j])); 4630ef38995SBarry Smith } else if (PetscImaginary(a->a[bs2*k + l*bs + j]) < 0.0) { 464766eeae4SLois Curfman McInnes fprintf(fd," %d %g - %g i",bs*a->j[k]+l, 465e20fef11SSatish Balay PetscReal(a->a[bs2*k + l*bs + j]),-PetscImaginary(a->a[bs2*k + l*bs + j])); 4660ef38995SBarry Smith } else { 467e20fef11SSatish Balay fprintf(fd," %d %g ",bs*a->j[k]+l,PetscReal(a->a[bs2*k + l*bs + j])); 46888685aaeSLois Curfman McInnes } 46988685aaeSLois Curfman McInnes #else 4707e67e3f9SSatish Balay fprintf(fd," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]); 47188685aaeSLois Curfman McInnes #endif 4722593348eSBarry Smith } 4732593348eSBarry Smith } 4742593348eSBarry Smith fprintf(fd,"\n"); 4752593348eSBarry Smith } 4762593348eSBarry Smith } 477b6490206SBarry Smith } 4782593348eSBarry Smith fflush(fd); 4793a40ed3dSBarry Smith PetscFunctionReturn(0); 4802593348eSBarry Smith } 4812593348eSBarry Smith 4825615d1e5SSatish Balay #undef __FUNC__ 48377ed5343SBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Draw_Zoom" 48477ed5343SBarry Smith static int MatView_SeqBAIJ_Draw_Zoom(Draw draw,void *Aa) 4853270192aSSatish Balay { 48677ed5343SBarry Smith Mat A = (Mat) Aa; 4873270192aSSatish Balay Mat_SeqBAIJ *a=(Mat_SeqBAIJ *) A->data; 4887dce120fSSatish Balay int row,ierr,i,j,k,l,mbs=a->mbs,color,bs=a->bs,bs2=a->bs2,rank; 489fae8c767SSatish Balay double xl,yl,xr,yr,x_l,x_r,y_l,y_r; 4903f1db9ecSBarry Smith MatScalar *aa; 49177ed5343SBarry Smith MPI_Comm comm; 49277ed5343SBarry Smith Viewer viewer; 4933270192aSSatish Balay 4943a40ed3dSBarry Smith PetscFunctionBegin; 49577ed5343SBarry Smith /* 49677ed5343SBarry Smith This is nasty. If this is called from an originally parallel matrix 49777ed5343SBarry Smith then all processes call this, but only the first has the matrix so the 49877ed5343SBarry Smith rest should return immediately. 49977ed5343SBarry Smith */ 50077ed5343SBarry Smith ierr = PetscObjectGetComm((PetscObject)draw,&comm);CHKERRQ(ierr); 50177ed5343SBarry Smith MPI_Comm_rank(comm,&rank); 50277ed5343SBarry Smith if (rank) PetscFunctionReturn(0); 5033270192aSSatish Balay 50477ed5343SBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*) &viewer);CHKERRQ(ierr); 50577ed5343SBarry Smith 50677ed5343SBarry Smith ierr = DrawGetCoordinates(draw,&xl,&yl,&xr,&yr); CHKERRQ(ierr); 50777ed5343SBarry Smith 5083270192aSSatish Balay /* loop over matrix elements drawing boxes */ 5093270192aSSatish Balay color = DRAW_BLUE; 5103270192aSSatish Balay for ( i=0,row=0; i<mbs; i++,row+=bs ) { 5113270192aSSatish Balay for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 5123270192aSSatish Balay y_l = a->m - row - 1.0; y_r = y_l + 1.0; 5133270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5143270192aSSatish Balay aa = a->a + j*bs2; 5153270192aSSatish Balay for ( k=0; k<bs; k++ ) { 5163270192aSSatish Balay for ( l=0; l<bs; l++ ) { 5173270192aSSatish Balay if (PetscReal(*aa++) >= 0.) continue; 518b34f160eSSatish Balay DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color); 5193270192aSSatish Balay } 5203270192aSSatish Balay } 5213270192aSSatish Balay } 5223270192aSSatish Balay } 5233270192aSSatish Balay color = DRAW_CYAN; 5243270192aSSatish Balay for ( i=0,row=0; i<mbs; i++,row+=bs ) { 5253270192aSSatish Balay for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 5263270192aSSatish Balay y_l = a->m - row - 1.0; y_r = y_l + 1.0; 5273270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5283270192aSSatish Balay aa = a->a + j*bs2; 5293270192aSSatish Balay for ( k=0; k<bs; k++ ) { 5303270192aSSatish Balay for ( l=0; l<bs; l++ ) { 5313270192aSSatish Balay if (PetscReal(*aa++) != 0.) continue; 532b34f160eSSatish Balay DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color); 5333270192aSSatish Balay } 5343270192aSSatish Balay } 5353270192aSSatish Balay } 5363270192aSSatish Balay } 5373270192aSSatish Balay 5383270192aSSatish Balay color = DRAW_RED; 5393270192aSSatish Balay for ( i=0,row=0; i<mbs; i++,row+=bs ) { 5403270192aSSatish Balay for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 5413270192aSSatish Balay y_l = a->m - row - 1.0; y_r = y_l + 1.0; 5423270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5433270192aSSatish Balay aa = a->a + j*bs2; 5443270192aSSatish Balay for ( k=0; k<bs; k++ ) { 5453270192aSSatish Balay for ( l=0; l<bs; l++ ) { 5463270192aSSatish Balay if (PetscReal(*aa++) <= 0.) continue; 547b34f160eSSatish Balay DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color); 5483270192aSSatish Balay } 5493270192aSSatish Balay } 5503270192aSSatish Balay } 5513270192aSSatish Balay } 55277ed5343SBarry Smith PetscFunctionReturn(0); 55377ed5343SBarry Smith } 5543270192aSSatish Balay 55577ed5343SBarry Smith #undef __FUNC__ 55677ed5343SBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Draw" 55777ed5343SBarry Smith static int MatView_SeqBAIJ_Draw(Mat A,Viewer viewer) 55877ed5343SBarry Smith { 55977ed5343SBarry Smith Mat_SeqBAIJ *a=(Mat_SeqBAIJ *) A->data; 5607dce120fSSatish Balay int ierr; 5617dce120fSSatish Balay double xl,yl,xr,yr,w,h; 56277ed5343SBarry Smith Draw draw; 56377ed5343SBarry Smith PetscTruth isnull; 5643270192aSSatish Balay 56577ed5343SBarry Smith PetscFunctionBegin; 56677ed5343SBarry Smith 56777ed5343SBarry Smith ierr = ViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 56877ed5343SBarry Smith ierr = DrawIsNull(draw,&isnull); CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0); 56977ed5343SBarry Smith 57077ed5343SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 57177ed5343SBarry Smith xr = a->n; yr = a->m; h = yr/10.0; w = xr/10.0; 57277ed5343SBarry Smith xr += w; yr += h; xl = -w; yl = -h; 5733270192aSSatish Balay ierr = DrawSetCoordinates(draw,xl,yl,xr,yr); CHKERRQ(ierr); 57477ed5343SBarry Smith ierr = DrawZoom(draw,MatView_SeqBAIJ_Draw_Zoom,A); CHKERRQ(ierr); 57577ed5343SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr); 5763a40ed3dSBarry Smith PetscFunctionReturn(0); 5773270192aSSatish Balay } 5783270192aSSatish Balay 5795615d1e5SSatish Balay #undef __FUNC__ 580d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ" 581e1311b90SBarry Smith int MatView_SeqBAIJ(Mat A,Viewer viewer) 5822593348eSBarry Smith { 58319bcc07fSBarry Smith ViewerType vtype; 58419bcc07fSBarry Smith int ierr; 5852593348eSBarry Smith 5863a40ed3dSBarry Smith PetscFunctionBegin; 58719bcc07fSBarry Smith ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr); 5887b2a1423SBarry Smith if (PetscTypeCompare(vtype,SOCKET_VIEWER)) { 5897b2a1423SBarry Smith SETERRQ(PETSC_ERR_SUP,0,"Socket viewer not supported"); 5903f1db9ecSBarry Smith } else if (PetscTypeCompare(vtype,ASCII_VIEWER)){ 5913a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr); 5923f1db9ecSBarry Smith } else if (PetscTypeCompare(vtype,BINARY_VIEWER)) { 5933a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr); 5943f1db9ecSBarry Smith } else if (PetscTypeCompare(vtype,DRAW_VIEWER)) { 5953a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr); 5965cd90555SBarry Smith } else { 5975cd90555SBarry Smith SETERRQ(1,1,"Viewer type not supported by PETSc object"); 5982593348eSBarry Smith } 5993a40ed3dSBarry Smith PetscFunctionReturn(0); 6002593348eSBarry Smith } 601b6490206SBarry Smith 602cd0e1443SSatish Balay 6035615d1e5SSatish Balay #undef __FUNC__ 6042d61bbb3SSatish Balay #define __FUNC__ "MatGetValues_SeqBAIJ" 6052d61bbb3SSatish Balay int MatGetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v) 606cd0e1443SSatish Balay { 607cd0e1443SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 6082d61bbb3SSatish Balay int *rp, k, low, high, t, row, nrow, i, col, l, *aj = a->j; 6092d61bbb3SSatish Balay int *ai = a->i, *ailen = a->ilen; 6102d61bbb3SSatish Balay int brow,bcol,ridx,cidx,bs=a->bs,bs2=a->bs2; 6113f1db9ecSBarry Smith MatScalar *ap, *aa = a->a, zero = 0.0; 612cd0e1443SSatish Balay 6133a40ed3dSBarry Smith PetscFunctionBegin; 6142d61bbb3SSatish Balay for ( k=0; k<m; k++ ) { /* loop over rows */ 615cd0e1443SSatish Balay row = im[k]; brow = row/bs; 616a8c6a408SBarry Smith if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row"); 617a8c6a408SBarry Smith if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 6182d61bbb3SSatish Balay rp = aj + ai[brow] ; ap = aa + bs2*ai[brow] ; 6192c3acbe9SBarry Smith nrow = ailen[brow]; 6202d61bbb3SSatish Balay for ( l=0; l<n; l++ ) { /* loop over columns */ 621a8c6a408SBarry Smith if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column"); 622a8c6a408SBarry Smith if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 6232d61bbb3SSatish Balay col = in[l] ; 6242d61bbb3SSatish Balay bcol = col/bs; 6252d61bbb3SSatish Balay cidx = col%bs; 6262d61bbb3SSatish Balay ridx = row%bs; 6272d61bbb3SSatish Balay high = nrow; 6282d61bbb3SSatish Balay low = 0; /* assume unsorted */ 6292d61bbb3SSatish Balay while (high-low > 5) { 630cd0e1443SSatish Balay t = (low+high)/2; 631cd0e1443SSatish Balay if (rp[t] > bcol) high = t; 632cd0e1443SSatish Balay else low = t; 633cd0e1443SSatish Balay } 634cd0e1443SSatish Balay for ( i=low; i<high; i++ ) { 635cd0e1443SSatish Balay if (rp[i] > bcol) break; 636cd0e1443SSatish Balay if (rp[i] == bcol) { 6372d61bbb3SSatish Balay *v++ = ap[bs2*i+bs*cidx+ridx]; 6382d61bbb3SSatish Balay goto finished; 639cd0e1443SSatish Balay } 640cd0e1443SSatish Balay } 6412d61bbb3SSatish Balay *v++ = zero; 6422d61bbb3SSatish Balay finished:; 643cd0e1443SSatish Balay } 644cd0e1443SSatish Balay } 6453a40ed3dSBarry Smith PetscFunctionReturn(0); 646cd0e1443SSatish Balay } 647cd0e1443SSatish Balay 6482d61bbb3SSatish Balay 6495615d1e5SSatish Balay #undef __FUNC__ 65005a5f48eSSatish Balay #define __FUNC__ "MatSetValuesBlocked_SeqBAIJ" 65192c4ed94SBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is) 65292c4ed94SBarry Smith { 65392c4ed94SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 6548a84c255SSatish Balay int *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted; 655dd9472c6SBarry Smith int *imax=a->imax,*ai=a->i,*ailen=a->ilen, roworiented=a->roworiented; 656dd9472c6SBarry Smith int *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval; 6573f1db9ecSBarry Smith Scalar *value = v; 6583f1db9ecSBarry Smith MatScalar *ap,*aa=a->a,*bap; 65992c4ed94SBarry Smith 6603a40ed3dSBarry Smith PetscFunctionBegin; 6610e324ae4SSatish Balay if (roworiented) { 6620e324ae4SSatish Balay stepval = (n-1)*bs; 6630e324ae4SSatish Balay } else { 6640e324ae4SSatish Balay stepval = (m-1)*bs; 6650e324ae4SSatish Balay } 66692c4ed94SBarry Smith for ( k=0; k<m; k++ ) { /* loop over added rows */ 66792c4ed94SBarry Smith row = im[k]; 6685ef9f2a5SBarry Smith if (row < 0) continue; 6693a40ed3dSBarry Smith #if defined(USE_PETSC_BOPT_g) 670a8c6a408SBarry Smith if (row >= a->mbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 67192c4ed94SBarry Smith #endif 67292c4ed94SBarry Smith rp = aj + ai[row]; 67392c4ed94SBarry Smith ap = aa + bs2*ai[row]; 67492c4ed94SBarry Smith rmax = imax[row]; 67592c4ed94SBarry Smith nrow = ailen[row]; 67692c4ed94SBarry Smith low = 0; 67792c4ed94SBarry Smith for ( l=0; l<n; l++ ) { /* loop over added columns */ 6785ef9f2a5SBarry Smith if (in[l] < 0) continue; 6793a40ed3dSBarry Smith #if defined(USE_PETSC_BOPT_g) 680a8c6a408SBarry Smith if (in[l] >= a->nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 68192c4ed94SBarry Smith #endif 68292c4ed94SBarry Smith col = in[l]; 68392c4ed94SBarry Smith if (roworiented) { 6840e324ae4SSatish Balay value = v + k*(stepval+bs)*bs + l*bs; 6850e324ae4SSatish Balay } else { 6860e324ae4SSatish Balay value = v + l*(stepval+bs)*bs + k*bs; 68792c4ed94SBarry Smith } 68892c4ed94SBarry Smith if (!sorted) low = 0; high = nrow; 68992c4ed94SBarry Smith while (high-low > 7) { 69092c4ed94SBarry Smith t = (low+high)/2; 69192c4ed94SBarry Smith if (rp[t] > col) high = t; 69292c4ed94SBarry Smith else low = t; 69392c4ed94SBarry Smith } 69492c4ed94SBarry Smith for ( i=low; i<high; i++ ) { 69592c4ed94SBarry Smith if (rp[i] > col) break; 69692c4ed94SBarry Smith if (rp[i] == col) { 6978a84c255SSatish Balay bap = ap + bs2*i; 6980e324ae4SSatish Balay if (roworiented) { 6998a84c255SSatish Balay if (is == ADD_VALUES) { 700dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval ) { 701dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs ) { 7028a84c255SSatish Balay bap[jj] += *value++; 703dd9472c6SBarry Smith } 704dd9472c6SBarry Smith } 7050e324ae4SSatish Balay } else { 706dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval ) { 707dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs ) { 7080e324ae4SSatish Balay bap[jj] = *value++; 7098a84c255SSatish Balay } 710dd9472c6SBarry Smith } 711dd9472c6SBarry Smith } 7120e324ae4SSatish Balay } else { 7130e324ae4SSatish Balay if (is == ADD_VALUES) { 714dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval ) { 715dd9472c6SBarry Smith for (jj=0; jj<bs; jj++ ) { 7160e324ae4SSatish Balay *bap++ += *value++; 717dd9472c6SBarry Smith } 718dd9472c6SBarry Smith } 7190e324ae4SSatish Balay } else { 720dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval ) { 721dd9472c6SBarry Smith for (jj=0; jj<bs; jj++ ) { 7220e324ae4SSatish Balay *bap++ = *value++; 7230e324ae4SSatish Balay } 7248a84c255SSatish Balay } 725dd9472c6SBarry Smith } 726dd9472c6SBarry Smith } 727f1241b54SBarry Smith goto noinsert2; 72892c4ed94SBarry Smith } 72992c4ed94SBarry Smith } 73089280ab3SLois Curfman McInnes if (nonew == 1) goto noinsert2; 731a8c6a408SBarry Smith else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 73292c4ed94SBarry Smith if (nrow >= rmax) { 73392c4ed94SBarry Smith /* there is no extra room in row, therefore enlarge */ 73492c4ed94SBarry Smith int new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j; 7353f1db9ecSBarry Smith MatScalar *new_a; 73692c4ed94SBarry Smith 737a8c6a408SBarry Smith if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 73889280ab3SLois Curfman McInnes 73992c4ed94SBarry Smith /* malloc new storage space */ 7403f1db9ecSBarry Smith len = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int); 7413f1db9ecSBarry Smith new_a = (MatScalar *) PetscMalloc( len ); CHKPTRQ(new_a); 74292c4ed94SBarry Smith new_j = (int *) (new_a + bs2*new_nz); 74392c4ed94SBarry Smith new_i = new_j + new_nz; 74492c4ed94SBarry Smith 74592c4ed94SBarry Smith /* copy over old data into new slots */ 74692c4ed94SBarry Smith for ( ii=0; ii<row+1; ii++ ) {new_i[ii] = ai[ii];} 74792c4ed94SBarry Smith for ( ii=row+1; ii<a->mbs+1; ii++ ) {new_i[ii] = ai[ii]+CHUNKSIZE;} 74892c4ed94SBarry Smith PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int)); 74992c4ed94SBarry Smith len = (new_nz - CHUNKSIZE - ai[row] - nrow); 750dd9472c6SBarry Smith PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int)); 7513f1db9ecSBarry Smith PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(MatScalar)); 7523f1db9ecSBarry Smith PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar)); 7533f1db9ecSBarry Smith PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(MatScalar)); 75492c4ed94SBarry Smith /* free up old matrix storage */ 75592c4ed94SBarry Smith PetscFree(a->a); 75692c4ed94SBarry Smith if (!a->singlemalloc) {PetscFree(a->i);PetscFree(a->j);} 75792c4ed94SBarry Smith aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 75892c4ed94SBarry Smith a->singlemalloc = 1; 75992c4ed94SBarry Smith 76092c4ed94SBarry Smith rp = aj + ai[row]; ap = aa + bs2*ai[row]; 76192c4ed94SBarry Smith rmax = imax[row] = imax[row] + CHUNKSIZE; 7623f1db9ecSBarry Smith PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar))); 76392c4ed94SBarry Smith a->maxnz += bs2*CHUNKSIZE; 76492c4ed94SBarry Smith a->reallocs++; 76592c4ed94SBarry Smith a->nz++; 76692c4ed94SBarry Smith } 76792c4ed94SBarry Smith N = nrow++ - 1; 76892c4ed94SBarry Smith /* shift up all the later entries in this row */ 76992c4ed94SBarry Smith for ( ii=N; ii>=i; ii-- ) { 77092c4ed94SBarry Smith rp[ii+1] = rp[ii]; 7713f1db9ecSBarry Smith PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar)); 77292c4ed94SBarry Smith } 7733f1db9ecSBarry Smith if (N >= i) PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar)); 77492c4ed94SBarry Smith rp[i] = col; 7758a84c255SSatish Balay bap = ap + bs2*i; 7760e324ae4SSatish Balay if (roworiented) { 777dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval) { 778dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs ) { 7790e324ae4SSatish Balay bap[jj] = *value++; 780dd9472c6SBarry Smith } 781dd9472c6SBarry Smith } 7820e324ae4SSatish Balay } else { 783dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval ) { 784dd9472c6SBarry Smith for (jj=0; jj<bs; jj++ ) { 7850e324ae4SSatish Balay *bap++ = *value++; 7860e324ae4SSatish Balay } 787dd9472c6SBarry Smith } 788dd9472c6SBarry Smith } 789f1241b54SBarry Smith noinsert2:; 79092c4ed94SBarry Smith low = i; 79192c4ed94SBarry Smith } 79292c4ed94SBarry Smith ailen[row] = nrow; 79392c4ed94SBarry Smith } 7943a40ed3dSBarry Smith PetscFunctionReturn(0); 79592c4ed94SBarry Smith } 79692c4ed94SBarry Smith 797f2501298SSatish Balay 7985615d1e5SSatish Balay #undef __FUNC__ 7995615d1e5SSatish Balay #define __FUNC__ "MatAssemblyEnd_SeqBAIJ" 8008f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode) 801584200bdSSatish Balay { 802584200bdSSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 803584200bdSSatish Balay int fshift = 0,i,j,*ai = a->i, *aj = a->j, *imax = a->imax; 804a7c10996SSatish Balay int m = a->m,*ip, N, *ailen = a->ilen; 80543ee02c3SBarry Smith int mbs = a->mbs, bs2 = a->bs2,rmax = 0; 8063f1db9ecSBarry Smith MatScalar *aa = a->a, *ap; 807584200bdSSatish Balay 8083a40ed3dSBarry Smith PetscFunctionBegin; 8093a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 810584200bdSSatish Balay 81143ee02c3SBarry Smith if (m) rmax = ailen[0]; 812584200bdSSatish Balay for ( i=1; i<mbs; i++ ) { 813584200bdSSatish Balay /* move each row back by the amount of empty slots (fshift) before it*/ 814584200bdSSatish Balay fshift += imax[i-1] - ailen[i-1]; 815d402145bSBarry Smith rmax = PetscMax(rmax,ailen[i]); 816584200bdSSatish Balay if (fshift) { 817a7c10996SSatish Balay ip = aj + ai[i]; ap = aa + bs2*ai[i]; 818584200bdSSatish Balay N = ailen[i]; 819584200bdSSatish Balay for ( j=0; j<N; j++ ) { 820584200bdSSatish Balay ip[j-fshift] = ip[j]; 8213f1db9ecSBarry Smith PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(MatScalar)); 822584200bdSSatish Balay } 823584200bdSSatish Balay } 824584200bdSSatish Balay ai[i] = ai[i-1] + ailen[i-1]; 825584200bdSSatish Balay } 826584200bdSSatish Balay if (mbs) { 827584200bdSSatish Balay fshift += imax[mbs-1] - ailen[mbs-1]; 828584200bdSSatish Balay ai[mbs] = ai[mbs-1] + ailen[mbs-1]; 829584200bdSSatish Balay } 830584200bdSSatish Balay /* reset ilen and imax for each row */ 831584200bdSSatish Balay for ( i=0; i<mbs; i++ ) { 832584200bdSSatish Balay ailen[i] = imax[i] = ai[i+1] - ai[i]; 833584200bdSSatish Balay } 834a7c10996SSatish Balay a->nz = ai[mbs]; 835584200bdSSatish Balay 836584200bdSSatish Balay /* diagonals may have moved, so kill the diagonal pointers */ 837584200bdSSatish Balay if (fshift && a->diag) { 838584200bdSSatish Balay PetscFree(a->diag); 839584200bdSSatish Balay PLogObjectMemory(A,-(m+1)*sizeof(int)); 840584200bdSSatish Balay a->diag = 0; 841584200bdSSatish Balay } 8423d2013a6SLois Curfman McInnes PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Matrix size: %d X %d, block size %d; storage space: %d unneeded, %d used\n", 843219d9a1aSLois Curfman McInnes m,a->n,a->bs,fshift*bs2,a->nz*bs2); 8443d2013a6SLois Curfman McInnes PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues is %d\n", 845584200bdSSatish Balay a->reallocs); 846d402145bSBarry Smith PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Most nonzeros blocks in any row is %d\n",rmax); 847e2f3b5e9SSatish Balay a->reallocs = 0; 8484e220ebcSLois Curfman McInnes A->info.nz_unneeded = (double)fshift*bs2; 8494e220ebcSLois Curfman McInnes 8503a40ed3dSBarry Smith PetscFunctionReturn(0); 851584200bdSSatish Balay } 852584200bdSSatish Balay 8535a838052SSatish Balay 854bea157c4SSatish Balay 855bea157c4SSatish Balay /* 856bea157c4SSatish Balay This function returns an array of flags which indicate the locations of contiguous 857bea157c4SSatish Balay blocks that should be zeroed. for eg: if bs = 3 and is = [0,1,2,3,5,6,7,8,9] 858bea157c4SSatish Balay then the resulting sizes = [3,1,1,3,1] correspondig to sets [(0,1,2),(3),(5),(6,7,8),(9)] 859bea157c4SSatish Balay Assume: sizes should be long enough to hold all the values. 860bea157c4SSatish Balay */ 8615615d1e5SSatish Balay #undef __FUNC__ 862bea157c4SSatish Balay #define __FUNC__ "MatZeroRows_SeqBAIJ_Check_Blocks" 863bea157c4SSatish Balay static int MatZeroRows_SeqBAIJ_Check_Blocks(int idx[],int n,int bs,int sizes[], int *bs_max) 864d9b7c43dSSatish Balay { 865bea157c4SSatish Balay int i,j,k,row; 866bea157c4SSatish Balay PetscTruth flg; 8673a40ed3dSBarry Smith 868bea157c4SSatish Balay /* PetscFunctionBegin;*/ 869bea157c4SSatish Balay for ( i=0,j=0; i<n; j++ ) { 870bea157c4SSatish Balay row = idx[i]; 871bea157c4SSatish Balay if (row%bs!=0) { /* Not the begining of a block */ 872bea157c4SSatish Balay sizes[j] = 1; 873bea157c4SSatish Balay i++; 874e4fda26cSSatish Balay } else if (i+bs > n) { /* complete block doesn't exist (at idx end) */ 875bea157c4SSatish Balay sizes[j] = 1; /* Also makes sure atleast 'bs' values exist for next else */ 876bea157c4SSatish Balay i++; 877bea157c4SSatish Balay } else { /* Begining of the block, so check if the complete block exists */ 878bea157c4SSatish Balay flg = PETSC_TRUE; 879bea157c4SSatish Balay for ( k=1; k<bs; k++ ) { 880bea157c4SSatish Balay if (row+k != idx[i+k]) { /* break in the block */ 881bea157c4SSatish Balay flg = PETSC_FALSE; 882bea157c4SSatish Balay break; 883d9b7c43dSSatish Balay } 884bea157c4SSatish Balay } 885bea157c4SSatish Balay if (flg == PETSC_TRUE) { /* No break in the bs */ 886bea157c4SSatish Balay sizes[j] = bs; 887bea157c4SSatish Balay i+= bs; 888bea157c4SSatish Balay } else { 889bea157c4SSatish Balay sizes[j] = 1; 890bea157c4SSatish Balay i++; 891bea157c4SSatish Balay } 892bea157c4SSatish Balay } 893bea157c4SSatish Balay } 894bea157c4SSatish Balay *bs_max = j; 8953a40ed3dSBarry Smith PetscFunctionReturn(0); 896d9b7c43dSSatish Balay } 897d9b7c43dSSatish Balay 8985615d1e5SSatish Balay #undef __FUNC__ 8995615d1e5SSatish Balay #define __FUNC__ "MatZeroRows_SeqBAIJ" 9008f6be9afSLois Curfman McInnes int MatZeroRows_SeqBAIJ(Mat A,IS is, Scalar *diag) 901d9b7c43dSSatish Balay { 902d9b7c43dSSatish Balay Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data; 903b6815fffSBarry Smith int ierr,i,j,k,count,is_n,*is_idx,*rows; 904bea157c4SSatish Balay int bs=baij->bs,bs2=baij->bs2,*sizes,row,bs_max; 9053f1db9ecSBarry Smith Scalar zero = 0.0; 9063f1db9ecSBarry Smith MatScalar *aa; 907d9b7c43dSSatish Balay 9083a40ed3dSBarry Smith PetscFunctionBegin; 909d9b7c43dSSatish Balay /* Make a copy of the IS and sort it */ 910d9b7c43dSSatish Balay ierr = ISGetSize(is,&is_n);CHKERRQ(ierr); 911d9b7c43dSSatish Balay ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr); 912d9b7c43dSSatish Balay 913bea157c4SSatish Balay /* allocate memory for rows,sizes */ 914bea157c4SSatish Balay rows = (int*)PetscMalloc((3*is_n+1)*sizeof(int)); CHKPTRQ(rows); 915bea157c4SSatish Balay sizes = rows + is_n; 916bea157c4SSatish Balay 917bea157c4SSatish Balay /* initialize copy IS valurs to rows, and sort them */ 918bea157c4SSatish Balay for (i=0; i<is_n; i++) { rows[i] = is_idx[i]; } 919bea157c4SSatish Balay ierr = PetscSortInt(is_n,rows); CHKERRQ(ierr); 920bea157c4SSatish Balay ierr = MatZeroRows_SeqBAIJ_Check_Blocks(rows,is_n,bs,sizes,&bs_max); CHKERRQ(ierr); 921b97a56abSSatish Balay ierr = ISRestoreIndices(is,&is_idx); CHKERRQ(ierr); 922bea157c4SSatish Balay 923bea157c4SSatish Balay for ( i=0,j=0; i<bs_max; j+=sizes[i],i++ ) { 924bea157c4SSatish Balay row = rows[j]; 925b6815fffSBarry Smith if (row < 0 || row > baij->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"row %d out of range",row); 926bea157c4SSatish Balay count = (baij->i[row/bs +1] - baij->i[row/bs])*bs; 927bea157c4SSatish Balay aa = baij->a + baij->i[row/bs]*bs2 + (row%bs); 928bea157c4SSatish Balay if (sizes[i] == bs) { 929bea157c4SSatish Balay if (diag) { 930bea157c4SSatish Balay if (baij->ilen[row/bs] > 0) { 931bea157c4SSatish Balay baij->ilen[row/bs] = 1; 932bea157c4SSatish Balay baij->j[baij->i[row/bs]] = row/bs; 933bea157c4SSatish Balay ierr = PetscMemzero(aa,count*bs*sizeof(MatScalar)); CHKERRQ(ierr); 934a07cd24cSSatish Balay } 935bea157c4SSatish Balay /* Now insert all the diagoanl values for this bs */ 936bea157c4SSatish Balay for ( k=0; k<bs; k++ ) { 937bea157c4SSatish Balay ierr = (*A->ops->setvalues)(A,1,rows+j+k,1,rows+j+k,diag,INSERT_VALUES);CHKERRQ(ierr); 938bea157c4SSatish Balay } 939bea157c4SSatish Balay } else { /* (!diag) */ 940bea157c4SSatish Balay baij->ilen[row/bs] = 0; 941bea157c4SSatish Balay } /* end (!diag) */ 942bea157c4SSatish Balay } else { /* (sizes[i] != bs) */ 943bea157c4SSatish Balay #if defined (USE_PETSC_DEBUG) 944bea157c4SSatish Balay if (sizes[i] != 1) SETERRQ(1,0,"Internal Error. Value should be 1"); 945bea157c4SSatish Balay #endif 946bea157c4SSatish Balay for ( k=0; k<count; k++ ) { 947d9b7c43dSSatish Balay aa[0] = zero; 948d9b7c43dSSatish Balay aa+=bs; 949d9b7c43dSSatish Balay } 950d9b7c43dSSatish Balay if (diag) { 951f830108cSBarry Smith ierr = (*A->ops->setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr); 952d9b7c43dSSatish Balay } 953d9b7c43dSSatish Balay } 954bea157c4SSatish Balay } 955bea157c4SSatish Balay 956bea157c4SSatish Balay PetscFree(rows); 9579a8dea36SBarry Smith ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 9583a40ed3dSBarry Smith PetscFunctionReturn(0); 959d9b7c43dSSatish Balay } 9601c351548SSatish Balay 9615615d1e5SSatish Balay #undef __FUNC__ 9622d61bbb3SSatish Balay #define __FUNC__ "MatSetValues_SeqBAIJ" 9632d61bbb3SSatish Balay int MatSetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is) 9642d61bbb3SSatish Balay { 9652d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 9662d61bbb3SSatish Balay int *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted; 9672d61bbb3SSatish Balay int *imax=a->imax,*ai=a->i,*ailen=a->ilen,roworiented=a->roworiented; 9682d61bbb3SSatish Balay int *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol; 9692d61bbb3SSatish Balay int ridx,cidx,bs2=a->bs2; 9703f1db9ecSBarry Smith MatScalar *ap,value,*aa=a->a,*bap; 9712d61bbb3SSatish Balay 9722d61bbb3SSatish Balay PetscFunctionBegin; 9732d61bbb3SSatish Balay for ( k=0; k<m; k++ ) { /* loop over added rows */ 9742d61bbb3SSatish Balay row = im[k]; brow = row/bs; 9755ef9f2a5SBarry Smith if (row < 0) continue; 9762d61bbb3SSatish Balay #if defined(USE_PETSC_BOPT_g) 977*32e87ba3SBarry Smith if (row >= a->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large: row %d max %d",row,a->m); 9782d61bbb3SSatish Balay #endif 9792d61bbb3SSatish Balay rp = aj + ai[brow]; 9802d61bbb3SSatish Balay ap = aa + bs2*ai[brow]; 9812d61bbb3SSatish Balay rmax = imax[brow]; 9822d61bbb3SSatish Balay nrow = ailen[brow]; 9832d61bbb3SSatish Balay low = 0; 9842d61bbb3SSatish Balay for ( l=0; l<n; l++ ) { /* loop over added columns */ 9855ef9f2a5SBarry Smith if (in[l] < 0) continue; 9862d61bbb3SSatish Balay #if defined(USE_PETSC_BOPT_g) 987*32e87ba3SBarry Smith if (in[l] >= a->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large: col %d max %d",in[l],a->n); 9882d61bbb3SSatish Balay #endif 9892d61bbb3SSatish Balay col = in[l]; bcol = col/bs; 9902d61bbb3SSatish Balay ridx = row % bs; cidx = col % bs; 9912d61bbb3SSatish Balay if (roworiented) { 9925ef9f2a5SBarry Smith value = v[l + k*n]; 9932d61bbb3SSatish Balay } else { 9942d61bbb3SSatish Balay value = v[k + l*m]; 9952d61bbb3SSatish Balay } 9962d61bbb3SSatish Balay if (!sorted) low = 0; high = nrow; 9972d61bbb3SSatish Balay while (high-low > 7) { 9982d61bbb3SSatish Balay t = (low+high)/2; 9992d61bbb3SSatish Balay if (rp[t] > bcol) high = t; 10002d61bbb3SSatish Balay else low = t; 10012d61bbb3SSatish Balay } 10022d61bbb3SSatish Balay for ( i=low; i<high; i++ ) { 10032d61bbb3SSatish Balay if (rp[i] > bcol) break; 10042d61bbb3SSatish Balay if (rp[i] == bcol) { 10052d61bbb3SSatish Balay bap = ap + bs2*i + bs*cidx + ridx; 10062d61bbb3SSatish Balay if (is == ADD_VALUES) *bap += value; 10072d61bbb3SSatish Balay else *bap = value; 10082d61bbb3SSatish Balay goto noinsert1; 10092d61bbb3SSatish Balay } 10102d61bbb3SSatish Balay } 10112d61bbb3SSatish Balay if (nonew == 1) goto noinsert1; 10122d61bbb3SSatish Balay else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 10132d61bbb3SSatish Balay if (nrow >= rmax) { 10142d61bbb3SSatish Balay /* there is no extra room in row, therefore enlarge */ 10152d61bbb3SSatish Balay int new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j; 10163f1db9ecSBarry Smith MatScalar *new_a; 10172d61bbb3SSatish Balay 10182d61bbb3SSatish Balay if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 10192d61bbb3SSatish Balay 10202d61bbb3SSatish Balay /* Malloc new storage space */ 10213f1db9ecSBarry Smith len = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int); 10223f1db9ecSBarry Smith new_a = (MatScalar *) PetscMalloc( len ); CHKPTRQ(new_a); 10232d61bbb3SSatish Balay new_j = (int *) (new_a + bs2*new_nz); 10242d61bbb3SSatish Balay new_i = new_j + new_nz; 10252d61bbb3SSatish Balay 10262d61bbb3SSatish Balay /* copy over old data into new slots */ 10272d61bbb3SSatish Balay for ( ii=0; ii<brow+1; ii++ ) {new_i[ii] = ai[ii];} 10282d61bbb3SSatish Balay for ( ii=brow+1; ii<a->mbs+1; ii++ ) {new_i[ii] = ai[ii]+CHUNKSIZE;} 10292d61bbb3SSatish Balay PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int)); 10302d61bbb3SSatish Balay len = (new_nz - CHUNKSIZE - ai[brow] - nrow); 10312d61bbb3SSatish Balay PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow, 10322d61bbb3SSatish Balay len*sizeof(int)); 10333f1db9ecSBarry Smith PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(MatScalar)); 10343f1db9ecSBarry Smith PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar)); 10352d61bbb3SSatish Balay PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE), 10363f1db9ecSBarry Smith aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(MatScalar)); 10372d61bbb3SSatish Balay /* free up old matrix storage */ 10382d61bbb3SSatish Balay PetscFree(a->a); 10392d61bbb3SSatish Balay if (!a->singlemalloc) {PetscFree(a->i);PetscFree(a->j);} 10402d61bbb3SSatish Balay aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 10412d61bbb3SSatish Balay a->singlemalloc = 1; 10422d61bbb3SSatish Balay 10432d61bbb3SSatish Balay rp = aj + ai[brow]; ap = aa + bs2*ai[brow]; 10442d61bbb3SSatish Balay rmax = imax[brow] = imax[brow] + CHUNKSIZE; 10453f1db9ecSBarry Smith PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar))); 10462d61bbb3SSatish Balay a->maxnz += bs2*CHUNKSIZE; 10472d61bbb3SSatish Balay a->reallocs++; 10482d61bbb3SSatish Balay a->nz++; 10492d61bbb3SSatish Balay } 10502d61bbb3SSatish Balay N = nrow++ - 1; 10512d61bbb3SSatish Balay /* shift up all the later entries in this row */ 10522d61bbb3SSatish Balay for ( ii=N; ii>=i; ii-- ) { 10532d61bbb3SSatish Balay rp[ii+1] = rp[ii]; 10543f1db9ecSBarry Smith PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar)); 10552d61bbb3SSatish Balay } 10563f1db9ecSBarry Smith if (N>=i) PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar)); 10572d61bbb3SSatish Balay rp[i] = bcol; 10582d61bbb3SSatish Balay ap[bs2*i + bs*cidx + ridx] = value; 10592d61bbb3SSatish Balay noinsert1:; 10602d61bbb3SSatish Balay low = i; 10612d61bbb3SSatish Balay } 10622d61bbb3SSatish Balay ailen[brow] = nrow; 10632d61bbb3SSatish Balay } 10642d61bbb3SSatish Balay PetscFunctionReturn(0); 10652d61bbb3SSatish Balay } 10662d61bbb3SSatish Balay 10672d61bbb3SSatish Balay extern int MatLUFactorSymbolic_SeqBAIJ(Mat,IS,IS,double,Mat*); 10682d61bbb3SSatish Balay extern int MatLUFactor_SeqBAIJ(Mat,IS,IS,double); 10692d61bbb3SSatish Balay extern int MatIncreaseOverlap_SeqBAIJ(Mat,int,IS*,int); 10707b2a1423SBarry Smith extern int MatGetSubMatrix_SeqBAIJ(Mat,IS,IS,int,MatReuse,Mat*); 10717b2a1423SBarry Smith extern int MatGetSubMatrices_SeqBAIJ(Mat,int,IS*,IS*,MatReuse,Mat**); 10722d61bbb3SSatish Balay extern int MatMultTrans_SeqBAIJ(Mat,Vec,Vec); 10732d61bbb3SSatish Balay extern int MatMultTransAdd_SeqBAIJ(Mat,Vec,Vec,Vec); 10742d61bbb3SSatish Balay extern int MatScale_SeqBAIJ(Scalar*,Mat); 10752d61bbb3SSatish Balay extern int MatNorm_SeqBAIJ(Mat,NormType,double *); 10762d61bbb3SSatish Balay extern int MatEqual_SeqBAIJ(Mat,Mat, PetscTruth*); 10772d61bbb3SSatish Balay extern int MatGetDiagonal_SeqBAIJ(Mat,Vec); 10782d61bbb3SSatish Balay extern int MatDiagonalScale_SeqBAIJ(Mat,Vec,Vec); 10792d61bbb3SSatish Balay extern int MatGetInfo_SeqBAIJ(Mat,MatInfoType,MatInfo *); 10802d61bbb3SSatish Balay extern int MatZeroEntries_SeqBAIJ(Mat); 10812d61bbb3SSatish Balay 10822d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_N(Mat,Vec,Vec); 10832d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_1(Mat,Vec,Vec); 10842d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_2(Mat,Vec,Vec); 10852d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_3(Mat,Vec,Vec); 10862d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_4(Mat,Vec,Vec); 10872d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_5(Mat,Vec,Vec); 108815091d37SBarry Smith extern int MatSolve_SeqBAIJ_6(Mat,Vec,Vec); 10892d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_7(Mat,Vec,Vec); 10902d61bbb3SSatish Balay 10912d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_N(Mat,Mat*); 10922d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_1(Mat,Mat*); 10932d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_2(Mat,Mat*); 10942d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_3(Mat,Mat*); 10952d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_4(Mat,Mat*); 10962d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_5(Mat,Mat*); 109715091d37SBarry Smith extern int MatLUFactorNumeric_SeqBAIJ_6(Mat,Mat*); 10982d61bbb3SSatish Balay 10992d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_1(Mat,Vec,Vec); 11002d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_2(Mat,Vec,Vec); 11012d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_3(Mat,Vec,Vec); 11022d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_4(Mat,Vec,Vec); 11032d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_5(Mat,Vec,Vec); 110415091d37SBarry Smith extern int MatMult_SeqBAIJ_6(Mat,Vec,Vec); 11052d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_7(Mat,Vec,Vec); 11062d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_N(Mat,Vec,Vec); 11072d61bbb3SSatish Balay 11082d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_1(Mat,Vec,Vec,Vec); 11092d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_2(Mat,Vec,Vec,Vec); 11102d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_3(Mat,Vec,Vec,Vec); 11112d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_4(Mat,Vec,Vec,Vec); 11122d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_5(Mat,Vec,Vec,Vec); 111315091d37SBarry Smith extern int MatMultAdd_SeqBAIJ_6(Mat,Vec,Vec,Vec); 11142d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_7(Mat,Vec,Vec,Vec); 11152d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_N(Mat,Vec,Vec,Vec); 11162d61bbb3SSatish Balay 11172d61bbb3SSatish Balay #undef __FUNC__ 11182d61bbb3SSatish Balay #define __FUNC__ "MatILUFactor_SeqBAIJ" 11195ef9f2a5SBarry Smith int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,MatILUInfo *info) 11202d61bbb3SSatish Balay { 11212d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) inA->data; 11222d61bbb3SSatish Balay Mat outA; 11232d61bbb3SSatish Balay int ierr; 1124667159a5SBarry Smith PetscTruth row_identity, col_identity; 11252d61bbb3SSatish Balay 11262d61bbb3SSatish Balay PetscFunctionBegin; 11275ef9f2a5SBarry Smith if (info && info->fill != 0) SETERRQ(PETSC_ERR_SUP,0,"Only fill=0 supported"); 1128667159a5SBarry Smith ierr = ISIdentity(row,&row_identity); CHKERRQ(ierr); 1129667159a5SBarry Smith ierr = ISIdentity(col,&col_identity); CHKERRQ(ierr); 1130667159a5SBarry Smith if (!row_identity || !col_identity) { 1131667159a5SBarry Smith SETERRQ(1,1,"Row and column permutations must be identity"); 1132667159a5SBarry Smith } 11332d61bbb3SSatish Balay 11342d61bbb3SSatish Balay outA = inA; 11352d61bbb3SSatish Balay inA->factor = FACTOR_LU; 11362d61bbb3SSatish Balay a->row = row; 11372d61bbb3SSatish Balay a->col = col; 11382d61bbb3SSatish Balay 1139e51c0b9cSSatish Balay /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */ 1140e51c0b9cSSatish Balay ierr = ISInvertPermutation(col,&(a->icol)); CHKERRQ(ierr); 11411e4dd532SSatish Balay PLogObjectParent(inA,a->icol); 1142e51c0b9cSSatish Balay 11432d61bbb3SSatish Balay if (!a->solve_work) { 11442d61bbb3SSatish Balay a->solve_work = (Scalar *) PetscMalloc((a->m+a->bs)*sizeof(Scalar));CHKPTRQ(a->solve_work); 11452d61bbb3SSatish Balay PLogObjectMemory(inA,(a->m+a->bs)*sizeof(Scalar)); 11462d61bbb3SSatish Balay } 11472d61bbb3SSatish Balay 11482d61bbb3SSatish Balay if (!a->diag) { 11492d61bbb3SSatish Balay ierr = MatMarkDiag_SeqBAIJ(inA); CHKERRQ(ierr); 11502d61bbb3SSatish Balay } 11512d61bbb3SSatish Balay /* 115215091d37SBarry Smith Blocksize 2, 3, 4, 5, 6 and 7 have a special faster factorization/solver 115315091d37SBarry Smith for ILU(0) factorization with natural ordering 11542d61bbb3SSatish Balay */ 115515091d37SBarry Smith switch (a->bs) { 115615091d37SBarry Smith case 2: 115715091d37SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2_NaturalOrdering; 115815091d37SBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_2_NaturalOrdering; 115915091d37SBarry Smith PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=2\n"); 116015091d37SBarry Smith break; 116115091d37SBarry Smith case 3: 116215091d37SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3_NaturalOrdering; 116315091d37SBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_3_NaturalOrdering; 116415091d37SBarry Smith PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=3\n"); 116515091d37SBarry Smith break; 116615091d37SBarry Smith case 4: 1167667159a5SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4_NaturalOrdering; 1168f830108cSBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_4_NaturalOrdering; 116915091d37SBarry Smith PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=4\n"); 117015091d37SBarry Smith break; 117115091d37SBarry Smith case 5: 1172667159a5SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5_NaturalOrdering; 1173667159a5SBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_5_NaturalOrdering; 117415091d37SBarry Smith PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=5\n"); 117515091d37SBarry Smith break; 117615091d37SBarry Smith case 6: 117715091d37SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6_NaturalOrdering; 117815091d37SBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_6_NaturalOrdering; 117915091d37SBarry Smith PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=6\n"); 118015091d37SBarry Smith break; 118115091d37SBarry Smith case 7: 118215091d37SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_7_NaturalOrdering; 118315091d37SBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_7_NaturalOrdering; 118415091d37SBarry Smith PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=7\n"); 118515091d37SBarry Smith break; 11862d61bbb3SSatish Balay } 11872d61bbb3SSatish Balay 1188667159a5SBarry Smith ierr = MatLUFactorNumeric(inA,&outA); CHKERRQ(ierr); 1189667159a5SBarry Smith 1190667159a5SBarry Smith 11912d61bbb3SSatish Balay PetscFunctionReturn(0); 11922d61bbb3SSatish Balay } 11932d61bbb3SSatish Balay #undef __FUNC__ 1194d4bb536fSBarry Smith #define __FUNC__ "MatPrintHelp_SeqBAIJ" 1195ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A) 1196ba4ca20aSSatish Balay { 1197ba4ca20aSSatish Balay static int called = 0; 1198ba4ca20aSSatish Balay MPI_Comm comm = A->comm; 1199ba4ca20aSSatish Balay 12003a40ed3dSBarry Smith PetscFunctionBegin; 12013a40ed3dSBarry Smith if (called) {PetscFunctionReturn(0);} else called = 1; 120276be9ce4SBarry Smith (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n"); 120376be9ce4SBarry Smith (*PetscHelpPrintf)(comm," -mat_block_size <block_size>\n"); 12043a40ed3dSBarry Smith PetscFunctionReturn(0); 1205ba4ca20aSSatish Balay } 1206d9b7c43dSSatish Balay 1207fb2e594dSBarry Smith EXTERN_C_BEGIN 120827a8da17SBarry Smith #undef __FUNC__ 120927a8da17SBarry Smith #define __FUNC__ "MatSeqBAIJSetColumnIndices_SeqBAIJ" 121027a8da17SBarry Smith int MatSeqBAIJSetColumnIndices_SeqBAIJ(Mat mat,int *indices) 121127a8da17SBarry Smith { 121227a8da17SBarry Smith Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *)mat->data; 121327a8da17SBarry Smith int i,nz,n; 121427a8da17SBarry Smith 121527a8da17SBarry Smith PetscFunctionBegin; 121627a8da17SBarry Smith nz = baij->maxnz; 121727a8da17SBarry Smith n = baij->n; 121827a8da17SBarry Smith for (i=0; i<nz; i++) { 121927a8da17SBarry Smith baij->j[i] = indices[i]; 122027a8da17SBarry Smith } 122127a8da17SBarry Smith baij->nz = nz; 122227a8da17SBarry Smith for ( i=0; i<n; i++ ) { 122327a8da17SBarry Smith baij->ilen[i] = baij->imax[i]; 122427a8da17SBarry Smith } 122527a8da17SBarry Smith 122627a8da17SBarry Smith PetscFunctionReturn(0); 122727a8da17SBarry Smith } 1228fb2e594dSBarry Smith EXTERN_C_END 122927a8da17SBarry Smith 123027a8da17SBarry Smith #undef __FUNC__ 123127a8da17SBarry Smith #define __FUNC__ "MatSeqBAIJSetColumnIndices" 123227a8da17SBarry Smith /*@ 123327a8da17SBarry Smith MatSeqBAIJSetColumnIndices - Set the column indices for all the rows 123427a8da17SBarry Smith in the matrix. 123527a8da17SBarry Smith 123627a8da17SBarry Smith Input Parameters: 123727a8da17SBarry Smith + mat - the SeqBAIJ matrix 123827a8da17SBarry Smith - indices - the column indices 123927a8da17SBarry Smith 124015091d37SBarry Smith Level: advanced 124115091d37SBarry Smith 124227a8da17SBarry Smith Notes: 124327a8da17SBarry Smith This can be called if you have precomputed the nonzero structure of the 124427a8da17SBarry Smith matrix and want to provide it to the matrix object to improve the performance 124527a8da17SBarry Smith of the MatSetValues() operation. 124627a8da17SBarry Smith 124727a8da17SBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 124827a8da17SBarry Smith MatCreateSeqBAIJ(). 124927a8da17SBarry Smith 125027a8da17SBarry Smith MUST be called before any calls to MatSetValues(); 125127a8da17SBarry Smith 125227a8da17SBarry Smith @*/ 125327a8da17SBarry Smith int MatSeqBAIJSetColumnIndices(Mat mat,int *indices) 125427a8da17SBarry Smith { 125527a8da17SBarry Smith int ierr,(*f)(Mat,int *); 125627a8da17SBarry Smith 125727a8da17SBarry Smith PetscFunctionBegin; 125827a8da17SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 125927a8da17SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqBAIJSetColumnIndices_C",(void **)&f); 126027a8da17SBarry Smith CHKERRQ(ierr); 126127a8da17SBarry Smith if (f) { 126227a8da17SBarry Smith ierr = (*f)(mat,indices);CHKERRQ(ierr); 126327a8da17SBarry Smith } else { 126427a8da17SBarry Smith SETERRQ(1,1,"Wrong type of matrix to set column indices"); 126527a8da17SBarry Smith } 126627a8da17SBarry Smith PetscFunctionReturn(0); 126727a8da17SBarry Smith } 126827a8da17SBarry Smith 12692593348eSBarry Smith /* -------------------------------------------------------------------*/ 1270cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqBAIJ, 1271cc2dc46cSBarry Smith MatGetRow_SeqBAIJ, 1272cc2dc46cSBarry Smith MatRestoreRow_SeqBAIJ, 1273cc2dc46cSBarry Smith MatMult_SeqBAIJ_N, 1274cc2dc46cSBarry Smith MatMultAdd_SeqBAIJ_N, 1275cc2dc46cSBarry Smith MatMultTrans_SeqBAIJ, 1276cc2dc46cSBarry Smith MatMultTransAdd_SeqBAIJ, 1277cc2dc46cSBarry Smith MatSolve_SeqBAIJ_N, 1278cc2dc46cSBarry Smith 0, 1279cc2dc46cSBarry Smith 0, 1280cc2dc46cSBarry Smith 0, 1281cc2dc46cSBarry Smith MatLUFactor_SeqBAIJ, 1282cc2dc46cSBarry Smith 0, 1283b6490206SBarry Smith 0, 1284f2501298SSatish Balay MatTranspose_SeqBAIJ, 1285cc2dc46cSBarry Smith MatGetInfo_SeqBAIJ, 1286cc2dc46cSBarry Smith MatEqual_SeqBAIJ, 1287cc2dc46cSBarry Smith MatGetDiagonal_SeqBAIJ, 1288cc2dc46cSBarry Smith MatDiagonalScale_SeqBAIJ, 1289cc2dc46cSBarry Smith MatNorm_SeqBAIJ, 1290b6490206SBarry Smith 0, 1291cc2dc46cSBarry Smith MatAssemblyEnd_SeqBAIJ, 1292cc2dc46cSBarry Smith 0, 1293cc2dc46cSBarry Smith MatSetOption_SeqBAIJ, 1294cc2dc46cSBarry Smith MatZeroEntries_SeqBAIJ, 1295cc2dc46cSBarry Smith MatZeroRows_SeqBAIJ, 1296cc2dc46cSBarry Smith MatLUFactorSymbolic_SeqBAIJ, 1297cc2dc46cSBarry Smith MatLUFactorNumeric_SeqBAIJ_N, 1298cc2dc46cSBarry Smith 0, 1299cc2dc46cSBarry Smith 0, 1300cc2dc46cSBarry Smith MatGetSize_SeqBAIJ, 1301cc2dc46cSBarry Smith MatGetSize_SeqBAIJ, 1302cc2dc46cSBarry Smith MatGetOwnershipRange_SeqBAIJ, 1303cc2dc46cSBarry Smith MatILUFactorSymbolic_SeqBAIJ, 1304cc2dc46cSBarry Smith 0, 1305cc2dc46cSBarry Smith 0, 1306cc2dc46cSBarry Smith 0, 13072e8a6d31SBarry Smith MatDuplicate_SeqBAIJ, 1308cc2dc46cSBarry Smith 0, 1309cc2dc46cSBarry Smith 0, 1310cc2dc46cSBarry Smith MatILUFactor_SeqBAIJ, 1311cc2dc46cSBarry Smith 0, 1312cc2dc46cSBarry Smith 0, 1313cc2dc46cSBarry Smith MatGetSubMatrices_SeqBAIJ, 1314cc2dc46cSBarry Smith MatIncreaseOverlap_SeqBAIJ, 1315cc2dc46cSBarry Smith MatGetValues_SeqBAIJ, 1316cc2dc46cSBarry Smith 0, 1317cc2dc46cSBarry Smith MatPrintHelp_SeqBAIJ, 1318cc2dc46cSBarry Smith MatScale_SeqBAIJ, 1319cc2dc46cSBarry Smith 0, 1320cc2dc46cSBarry Smith 0, 1321cc2dc46cSBarry Smith 0, 1322cc2dc46cSBarry Smith MatGetBlockSize_SeqBAIJ, 13233b2fbd54SBarry Smith MatGetRowIJ_SeqBAIJ, 132492c4ed94SBarry Smith MatRestoreRowIJ_SeqBAIJ, 1325cc2dc46cSBarry Smith 0, 1326cc2dc46cSBarry Smith 0, 1327cc2dc46cSBarry Smith 0, 1328cc2dc46cSBarry Smith 0, 1329cc2dc46cSBarry Smith 0, 1330cc2dc46cSBarry Smith 0, 1331d3825aa8SBarry Smith MatSetValuesBlocked_SeqBAIJ, 1332cc2dc46cSBarry Smith MatGetSubMatrix_SeqBAIJ, 1333cc2dc46cSBarry Smith 0, 1334cc2dc46cSBarry Smith 0, 1335cc2dc46cSBarry Smith MatGetMaps_Petsc}; 13362593348eSBarry Smith 13373e90b805SBarry Smith EXTERN_C_BEGIN 13383e90b805SBarry Smith #undef __FUNC__ 13393e90b805SBarry Smith #define __FUNC__ "MatStoreValues_SeqBAIJ" 13403e90b805SBarry Smith int MatStoreValues_SeqBAIJ(Mat mat) 13413e90b805SBarry Smith { 13423e90b805SBarry Smith Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data; 13433e90b805SBarry Smith int nz = aij->i[aij->m]*aij->bs*aij->bs2; 13443e90b805SBarry Smith 13453e90b805SBarry Smith PetscFunctionBegin; 13463e90b805SBarry Smith if (aij->nonew != 1) { 13473e90b805SBarry Smith SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 13483e90b805SBarry Smith } 13493e90b805SBarry Smith 13503e90b805SBarry Smith /* allocate space for values if not already there */ 13513e90b805SBarry Smith if (!aij->saved_values) { 13523e90b805SBarry Smith aij->saved_values = (Scalar *) PetscMalloc(nz*sizeof(Scalar));CHKPTRQ(aij->saved_values); 13533e90b805SBarry Smith } 13543e90b805SBarry Smith 13553e90b805SBarry Smith /* copy values over */ 13563e90b805SBarry Smith PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(Scalar)); 13573e90b805SBarry Smith PetscFunctionReturn(0); 13583e90b805SBarry Smith } 13593e90b805SBarry Smith EXTERN_C_END 13603e90b805SBarry Smith 13613e90b805SBarry Smith EXTERN_C_BEGIN 13623e90b805SBarry Smith #undef __FUNC__ 1363*32e87ba3SBarry Smith #define __FUNC__ "MatRetrieveValues_SeqBAIJ" 1364*32e87ba3SBarry Smith int MatRetrieveValues_SeqBAIJ(Mat mat) 13653e90b805SBarry Smith { 13663e90b805SBarry Smith Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data; 13673e90b805SBarry Smith int nz = aij->i[aij->m]*aij->bs*aij->bs2; 13683e90b805SBarry Smith 13693e90b805SBarry Smith PetscFunctionBegin; 13703e90b805SBarry Smith if (aij->nonew != 1) { 13713e90b805SBarry Smith SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 13723e90b805SBarry Smith } 13733e90b805SBarry Smith if (!aij->saved_values) { 13743e90b805SBarry Smith SETERRQ(1,1,"Must call MatStoreValues(A);first"); 13753e90b805SBarry Smith } 13763e90b805SBarry Smith 13773e90b805SBarry Smith /* copy values over */ 13783e90b805SBarry Smith PetscMemcpy(aij->a, aij->saved_values,nz*sizeof(Scalar)); 13793e90b805SBarry Smith PetscFunctionReturn(0); 13803e90b805SBarry Smith } 13813e90b805SBarry Smith EXTERN_C_END 13823e90b805SBarry Smith 13835615d1e5SSatish Balay #undef __FUNC__ 13845615d1e5SSatish Balay #define __FUNC__ "MatCreateSeqBAIJ" 13852593348eSBarry Smith /*@C 138644cd7ae7SLois Curfman McInnes MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block 138744cd7ae7SLois Curfman McInnes compressed row) format. For good matrix assembly performance the 138844cd7ae7SLois Curfman McInnes user should preallocate the matrix storage by setting the parameter nz 13892bd5e0b2SLois Curfman McInnes (or the array nzz). By setting these parameters accurately, performance 13902bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 13912593348eSBarry Smith 1392db81eaa0SLois Curfman McInnes Collective on MPI_Comm 1393db81eaa0SLois Curfman McInnes 13942593348eSBarry Smith Input Parameters: 1395db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 1396b6490206SBarry Smith . bs - size of block 13972593348eSBarry Smith . m - number of rows 13982593348eSBarry Smith . n - number of columns 1399b6490206SBarry Smith . nz - number of block nonzeros per block row (same for all rows) 1400db81eaa0SLois Curfman McInnes - nzz - array containing the number of block nonzeros in the various block rows 14012bd5e0b2SLois Curfman McInnes (possibly different for each block row) or PETSC_NULL 14022593348eSBarry Smith 14032593348eSBarry Smith Output Parameter: 14042593348eSBarry Smith . A - the matrix 14052593348eSBarry Smith 14060513a670SBarry Smith Options Database Keys: 1407db81eaa0SLois Curfman McInnes . -mat_no_unroll - uses code that does not unroll the loops in the 1408db81eaa0SLois Curfman McInnes block calculations (much slower) 1409db81eaa0SLois Curfman McInnes . -mat_block_size - size of the blocks to use 14100513a670SBarry Smith 141115091d37SBarry Smith Level: intermediate 141215091d37SBarry Smith 14132593348eSBarry Smith Notes: 141444cd7ae7SLois Curfman McInnes The block AIJ format is fully compatible with standard Fortran 77 14152593348eSBarry Smith storage. That is, the stored row and column indices can begin at 141644cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 14172593348eSBarry Smith 14182593348eSBarry Smith Specify the preallocated storage with either nz or nnz (not both). 14192593348eSBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 14202593348eSBarry Smith allocation. For additional details, see the users manual chapter on 14216da5968aSLois Curfman McInnes matrices. 14222593348eSBarry Smith 1423db81eaa0SLois Curfman McInnes .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ() 14242593348eSBarry Smith @*/ 1425b6490206SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz, Mat *A) 14262593348eSBarry Smith { 14272593348eSBarry Smith Mat B; 1428b6490206SBarry Smith Mat_SeqBAIJ *b; 14293b2fbd54SBarry Smith int i,len,ierr,flg,mbs=m/bs,nbs=n/bs,bs2=bs*bs,size; 14303b2fbd54SBarry Smith 14313a40ed3dSBarry Smith PetscFunctionBegin; 14323b2fbd54SBarry Smith MPI_Comm_size(comm,&size); 1433a8c6a408SBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"Comm must be of size 1"); 1434b6490206SBarry Smith 14350513a670SBarry Smith ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&bs,&flg);CHKERRQ(ierr); 14360513a670SBarry Smith 14373a40ed3dSBarry Smith if (mbs*bs!=m || nbs*bs!=n) { 1438a8c6a408SBarry Smith SETERRQ(PETSC_ERR_ARG_SIZ,0,"Number rows, cols must be divisible by blocksize"); 14393a40ed3dSBarry Smith } 14402593348eSBarry Smith 14412593348eSBarry Smith *A = 0; 14423f1db9ecSBarry Smith PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQBAIJ,"Mat",comm,MatDestroy,MatView); 14432593348eSBarry Smith PLogObjectCreate(B); 1444b6490206SBarry Smith B->data = (void *) (b = PetscNew(Mat_SeqBAIJ)); CHKPTRQ(b); 144544cd7ae7SLois Curfman McInnes PetscMemzero(b,sizeof(Mat_SeqBAIJ)); 1446cc2dc46cSBarry Smith PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps)); 14471a6a6d98SBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg); CHKERRQ(ierr); 14481a6a6d98SBarry Smith if (!flg) { 14497fc0212eSBarry Smith switch (bs) { 14507fc0212eSBarry Smith case 1: 1451f830108cSBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1; 1452f830108cSBarry Smith B->ops->solve = MatSolve_SeqBAIJ_1; 1453f830108cSBarry Smith B->ops->mult = MatMult_SeqBAIJ_1; 1454f830108cSBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_1; 14557fc0212eSBarry Smith break; 14564eeb42bcSBarry Smith case 2: 1457f830108cSBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2; 1458f830108cSBarry Smith B->ops->solve = MatSolve_SeqBAIJ_2; 1459f830108cSBarry Smith B->ops->mult = MatMult_SeqBAIJ_2; 1460f830108cSBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_2; 14616d84be18SBarry Smith break; 1462f327dd97SBarry Smith case 3: 1463f830108cSBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3; 1464f830108cSBarry Smith B->ops->solve = MatSolve_SeqBAIJ_3; 1465f830108cSBarry Smith B->ops->mult = MatMult_SeqBAIJ_3; 1466f830108cSBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_3; 14674eeb42bcSBarry Smith break; 14686d84be18SBarry Smith case 4: 1469f830108cSBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4; 1470f830108cSBarry Smith B->ops->solve = MatSolve_SeqBAIJ_4; 1471f830108cSBarry Smith B->ops->mult = MatMult_SeqBAIJ_4; 1472f830108cSBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_4; 14736d84be18SBarry Smith break; 14746d84be18SBarry Smith case 5: 1475f830108cSBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5; 1476f830108cSBarry Smith B->ops->solve = MatSolve_SeqBAIJ_5; 1477f830108cSBarry Smith B->ops->mult = MatMult_SeqBAIJ_5; 1478f830108cSBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_5; 14796d84be18SBarry Smith break; 148015091d37SBarry Smith case 6: 148115091d37SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6; 148215091d37SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_6; 148315091d37SBarry Smith B->ops->mult = MatMult_SeqBAIJ_6; 148415091d37SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_6; 148515091d37SBarry Smith break; 148648e9ddb2SSatish Balay case 7: 1487f830108cSBarry Smith B->ops->mult = MatMult_SeqBAIJ_7; 1488f830108cSBarry Smith B->ops->solve = MatSolve_SeqBAIJ_7; 1489f830108cSBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_7; 149048e9ddb2SSatish Balay break; 14917fc0212eSBarry Smith } 14921a6a6d98SBarry Smith } 1493e1311b90SBarry Smith B->ops->destroy = MatDestroy_SeqBAIJ; 1494e1311b90SBarry Smith B->ops->view = MatView_SeqBAIJ; 14952593348eSBarry Smith B->factor = 0; 14962593348eSBarry Smith B->lupivotthreshold = 1.0; 149790f02eecSBarry Smith B->mapping = 0; 14982593348eSBarry Smith b->row = 0; 14992593348eSBarry Smith b->col = 0; 1500e51c0b9cSSatish Balay b->icol = 0; 15012593348eSBarry Smith b->reallocs = 0; 15023e90b805SBarry Smith b->saved_values = 0; 15032593348eSBarry Smith 150444cd7ae7SLois Curfman McInnes b->m = m; B->m = m; B->M = m; 150544cd7ae7SLois Curfman McInnes b->n = n; B->n = n; B->N = n; 1506a5ae1ecdSBarry Smith 15077413bad6SBarry Smith ierr = MapCreateMPI(comm,m,m,&B->rmap);CHKERRQ(ierr); 15087413bad6SBarry Smith ierr = MapCreateMPI(comm,n,n,&B->cmap);CHKERRQ(ierr); 1509a5ae1ecdSBarry Smith 1510b6490206SBarry Smith b->mbs = mbs; 1511f2501298SSatish Balay b->nbs = nbs; 1512b6490206SBarry Smith b->imax = (int *) PetscMalloc( (mbs+1)*sizeof(int) ); CHKPTRQ(b->imax); 15132593348eSBarry Smith if (nnz == PETSC_NULL) { 1514119a934aSSatish Balay if (nz == PETSC_DEFAULT) nz = 5; 15152593348eSBarry Smith else if (nz <= 0) nz = 1; 1516b6490206SBarry Smith for ( i=0; i<mbs; i++ ) b->imax[i] = nz; 1517b6490206SBarry Smith nz = nz*mbs; 15183a40ed3dSBarry Smith } else { 15192593348eSBarry Smith nz = 0; 1520b6490206SBarry Smith for ( i=0; i<mbs; i++ ) {b->imax[i] = nnz[i]; nz += nnz[i];} 15212593348eSBarry Smith } 15222593348eSBarry Smith 15232593348eSBarry Smith /* allocate the matrix space */ 15243f1db9ecSBarry Smith len = nz*sizeof(int) + nz*bs2*sizeof(MatScalar) + (b->m+1)*sizeof(int); 15253f1db9ecSBarry Smith b->a = (MatScalar *) PetscMalloc( len ); CHKPTRQ(b->a); 15263f1db9ecSBarry Smith PetscMemzero(b->a,nz*bs2*sizeof(MatScalar)); 15277e67e3f9SSatish Balay b->j = (int *) (b->a + nz*bs2); 15282593348eSBarry Smith PetscMemzero(b->j,nz*sizeof(int)); 15292593348eSBarry Smith b->i = b->j + nz; 15302593348eSBarry Smith b->singlemalloc = 1; 15312593348eSBarry Smith 1532de6a44a3SBarry Smith b->i[0] = 0; 1533b6490206SBarry Smith for (i=1; i<mbs+1; i++) { 15342593348eSBarry Smith b->i[i] = b->i[i-1] + b->imax[i-1]; 15352593348eSBarry Smith } 15362593348eSBarry Smith 1537b6490206SBarry Smith /* b->ilen will count nonzeros in each block row so far. */ 1538b6490206SBarry Smith b->ilen = (int *) PetscMalloc((mbs+1)*sizeof(int)); 1539f09e8eb9SSatish Balay PLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ)); 1540b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { b->ilen[i] = 0;} 15412593348eSBarry Smith 1542b6490206SBarry Smith b->bs = bs; 15439df24120SSatish Balay b->bs2 = bs2; 1544b6490206SBarry Smith b->mbs = mbs; 15452593348eSBarry Smith b->nz = 0; 154618e7b8e4SLois Curfman McInnes b->maxnz = nz*bs2; 15472593348eSBarry Smith b->sorted = 0; 15482593348eSBarry Smith b->roworiented = 1; 15492593348eSBarry Smith b->nonew = 0; 15502593348eSBarry Smith b->diag = 0; 15512593348eSBarry Smith b->solve_work = 0; 1552de6a44a3SBarry Smith b->mult_work = 0; 15532593348eSBarry Smith b->spptr = 0; 15544e220ebcSLois Curfman McInnes B->info.nz_unneeded = (double)b->maxnz; 15554e220ebcSLois Curfman McInnes 15562593348eSBarry Smith *A = B; 15572593348eSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr); 15582593348eSBarry Smith if (flg) {ierr = MatPrintHelp(B); CHKERRQ(ierr); } 155927a8da17SBarry Smith 15603e90b805SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C", 15613e90b805SBarry Smith "MatStoreValues_SeqBAIJ", 15623e90b805SBarry Smith (void*)MatStoreValues_SeqBAIJ);CHKERRQ(ierr); 15633e90b805SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C", 15643e90b805SBarry Smith "MatRetrieveValues_SeqBAIJ", 15653e90b805SBarry Smith (void*)MatRetrieveValues_SeqBAIJ);CHKERRQ(ierr); 156627a8da17SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqBAIJSetColumnIndices_C", 156727a8da17SBarry Smith "MatSeqBAIJSetColumnIndices_SeqBAIJ", 156827a8da17SBarry Smith (void*)MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr); 15693a40ed3dSBarry Smith PetscFunctionReturn(0); 15702593348eSBarry Smith } 15712593348eSBarry Smith 15725615d1e5SSatish Balay #undef __FUNC__ 15732e8a6d31SBarry Smith #define __FUNC__ "MatDuplicate_SeqBAIJ" 15742e8a6d31SBarry Smith int MatDuplicate_SeqBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 15752593348eSBarry Smith { 15762593348eSBarry Smith Mat C; 1577b6490206SBarry Smith Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ *) A->data; 157827a8da17SBarry Smith int i,len, mbs = a->mbs,nz = a->nz,bs2 =a->bs2,ierr; 1579de6a44a3SBarry Smith 15803a40ed3dSBarry Smith PetscFunctionBegin; 1581a8c6a408SBarry Smith if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,0,"Corrupt matrix"); 15822593348eSBarry Smith 15832593348eSBarry Smith *B = 0; 15843f1db9ecSBarry Smith PetscHeaderCreate(C,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQBAIJ,"Mat",A->comm,MatDestroy,MatView); 15852593348eSBarry Smith PLogObjectCreate(C); 1586b6490206SBarry Smith C->data = (void *) (c = PetscNew(Mat_SeqBAIJ)); CHKPTRQ(c); 1587c3c66ee5SSatish Balay PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps)); 1588e1311b90SBarry Smith C->ops->destroy = MatDestroy_SeqBAIJ; 1589e1311b90SBarry Smith C->ops->view = MatView_SeqBAIJ; 15902593348eSBarry Smith C->factor = A->factor; 15912593348eSBarry Smith c->row = 0; 15922593348eSBarry Smith c->col = 0; 1593cac97260SSatish Balay c->icol = 0; 1594*32e87ba3SBarry Smith c->saved_values = 0; 15952593348eSBarry Smith C->assembled = PETSC_TRUE; 15962593348eSBarry Smith 159744cd7ae7SLois Curfman McInnes c->m = C->m = a->m; 159844cd7ae7SLois Curfman McInnes c->n = C->n = a->n; 159944cd7ae7SLois Curfman McInnes C->M = a->m; 160044cd7ae7SLois Curfman McInnes C->N = a->n; 160144cd7ae7SLois Curfman McInnes 1602b6490206SBarry Smith c->bs = a->bs; 16039df24120SSatish Balay c->bs2 = a->bs2; 1604b6490206SBarry Smith c->mbs = a->mbs; 1605b6490206SBarry Smith c->nbs = a->nbs; 16062593348eSBarry Smith 1607b6490206SBarry Smith c->imax = (int *) PetscMalloc((mbs+1)*sizeof(int)); CHKPTRQ(c->imax); 1608b6490206SBarry Smith c->ilen = (int *) PetscMalloc((mbs+1)*sizeof(int)); CHKPTRQ(c->ilen); 1609b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 16102593348eSBarry Smith c->imax[i] = a->imax[i]; 16112593348eSBarry Smith c->ilen[i] = a->ilen[i]; 16122593348eSBarry Smith } 16132593348eSBarry Smith 16142593348eSBarry Smith /* allocate the matrix space */ 16152593348eSBarry Smith c->singlemalloc = 1; 16163f1db9ecSBarry Smith len = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(MatScalar) + sizeof(int)); 16173f1db9ecSBarry Smith c->a = (MatScalar *) PetscMalloc( len ); CHKPTRQ(c->a); 16187e67e3f9SSatish Balay c->j = (int *) (c->a + nz*bs2); 1619de6a44a3SBarry Smith c->i = c->j + nz; 1620b6490206SBarry Smith PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int)); 1621b6490206SBarry Smith if (mbs > 0) { 1622de6a44a3SBarry Smith PetscMemcpy(c->j,a->j,nz*sizeof(int)); 16232e8a6d31SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 16243f1db9ecSBarry Smith PetscMemcpy(c->a,a->a,bs2*nz*sizeof(MatScalar)); 16252e8a6d31SBarry Smith } else { 16263f1db9ecSBarry Smith PetscMemzero(c->a,bs2*nz*sizeof(MatScalar)); 16272593348eSBarry Smith } 16282593348eSBarry Smith } 16292593348eSBarry Smith 1630f09e8eb9SSatish Balay PLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ)); 16312593348eSBarry Smith c->sorted = a->sorted; 16322593348eSBarry Smith c->roworiented = a->roworiented; 16332593348eSBarry Smith c->nonew = a->nonew; 16342593348eSBarry Smith 16352593348eSBarry Smith if (a->diag) { 1636b6490206SBarry Smith c->diag = (int *) PetscMalloc( (mbs+1)*sizeof(int) ); CHKPTRQ(c->diag); 1637b6490206SBarry Smith PLogObjectMemory(C,(mbs+1)*sizeof(int)); 1638b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 16392593348eSBarry Smith c->diag[i] = a->diag[i]; 16402593348eSBarry Smith } 164198305bb5SBarry Smith } else c->diag = 0; 16422593348eSBarry Smith c->nz = a->nz; 16432593348eSBarry Smith c->maxnz = a->maxnz; 16442593348eSBarry Smith c->solve_work = 0; 16452593348eSBarry Smith c->spptr = 0; /* Dangerous -I'm throwing away a->spptr */ 16467fc0212eSBarry Smith c->mult_work = 0; 16472593348eSBarry Smith *B = C; 16487b2a1423SBarry Smith ierr = FListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr); 16493a40ed3dSBarry Smith PetscFunctionReturn(0); 16502593348eSBarry Smith } 16512593348eSBarry Smith 16525615d1e5SSatish Balay #undef __FUNC__ 16535615d1e5SSatish Balay #define __FUNC__ "MatLoad_SeqBAIJ" 165419bcc07fSBarry Smith int MatLoad_SeqBAIJ(Viewer viewer,MatType type,Mat *A) 16552593348eSBarry Smith { 1656b6490206SBarry Smith Mat_SeqBAIJ *a; 16572593348eSBarry Smith Mat B; 1658de6a44a3SBarry Smith int i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1,flg; 1659b6490206SBarry Smith int *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount; 166035aab85fSBarry Smith int kmax,jcount,block,idx,point,nzcountb,extra_rows; 1661a7c10996SSatish Balay int *masked, nmask,tmp,bs2,ishift; 1662b6490206SBarry Smith Scalar *aa; 166319bcc07fSBarry Smith MPI_Comm comm = ((PetscObject) viewer)->comm; 16642593348eSBarry Smith 16653a40ed3dSBarry Smith PetscFunctionBegin; 16661a6a6d98SBarry Smith ierr = OptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,&flg);CHKERRQ(ierr); 1667de6a44a3SBarry Smith bs2 = bs*bs; 1668b6490206SBarry Smith 16692593348eSBarry Smith MPI_Comm_size(comm,&size); 1670cc0fae11SBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"view must have one processor"); 167190ace30eSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr); 16720752156aSBarry Smith ierr = PetscBinaryRead(fd,header,4,PETSC_INT); CHKERRQ(ierr); 1673a8c6a408SBarry Smith if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"not Mat object"); 16742593348eSBarry Smith M = header[1]; N = header[2]; nz = header[3]; 16752593348eSBarry Smith 1676d64ed03dSBarry Smith if (header[3] < 0) { 1677a8c6a408SBarry Smith SETERRQ(PETSC_ERR_FILE_UNEXPECTED,1,"Matrix stored in special format, cannot load as SeqBAIJ"); 1678d64ed03dSBarry Smith } 1679d64ed03dSBarry Smith 1680a8c6a408SBarry Smith if (M != N) SETERRQ(PETSC_ERR_SUP,0,"Can only do square matrices"); 168135aab85fSBarry Smith 168235aab85fSBarry Smith /* 168335aab85fSBarry Smith This code adds extra rows to make sure the number of rows is 168435aab85fSBarry Smith divisible by the blocksize 168535aab85fSBarry Smith */ 1686b6490206SBarry Smith mbs = M/bs; 168735aab85fSBarry Smith extra_rows = bs - M + bs*(mbs); 168835aab85fSBarry Smith if (extra_rows == bs) extra_rows = 0; 168935aab85fSBarry Smith else mbs++; 169035aab85fSBarry Smith if (extra_rows) { 1691537820f0SBarry Smith PLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n"); 169235aab85fSBarry Smith } 1693b6490206SBarry Smith 16942593348eSBarry Smith /* read in row lengths */ 169535aab85fSBarry Smith rowlengths = (int*) PetscMalloc((M+extra_rows)*sizeof(int));CHKPTRQ(rowlengths); 16960752156aSBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT); CHKERRQ(ierr); 169735aab85fSBarry Smith for ( i=0; i<extra_rows; i++ ) rowlengths[M+i] = 1; 16982593348eSBarry Smith 1699b6490206SBarry Smith /* read in column indices */ 170035aab85fSBarry Smith jj = (int*) PetscMalloc( (nz+extra_rows)*sizeof(int) ); CHKPTRQ(jj); 17010752156aSBarry Smith ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT); CHKERRQ(ierr); 170235aab85fSBarry Smith for ( i=0; i<extra_rows; i++ ) jj[nz+i] = M+i; 1703b6490206SBarry Smith 1704b6490206SBarry Smith /* loop over row lengths determining block row lengths */ 1705b6490206SBarry Smith browlengths = (int *) PetscMalloc(mbs*sizeof(int));CHKPTRQ(browlengths); 1706b6490206SBarry Smith PetscMemzero(browlengths,mbs*sizeof(int)); 170735aab85fSBarry Smith mask = (int *) PetscMalloc( 2*mbs*sizeof(int) ); CHKPTRQ(mask); 170835aab85fSBarry Smith PetscMemzero(mask,mbs*sizeof(int)); 170935aab85fSBarry Smith masked = mask + mbs; 1710b6490206SBarry Smith rowcount = 0; nzcount = 0; 1711b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 171235aab85fSBarry Smith nmask = 0; 1713b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 1714b6490206SBarry Smith kmax = rowlengths[rowcount]; 1715b6490206SBarry Smith for ( k=0; k<kmax; k++ ) { 171635aab85fSBarry Smith tmp = jj[nzcount++]/bs; 171735aab85fSBarry Smith if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;} 1718b6490206SBarry Smith } 1719b6490206SBarry Smith rowcount++; 1720b6490206SBarry Smith } 172135aab85fSBarry Smith browlengths[i] += nmask; 172235aab85fSBarry Smith /* zero out the mask elements we set */ 172335aab85fSBarry Smith for ( j=0; j<nmask; j++ ) mask[masked[j]] = 0; 1724b6490206SBarry Smith } 1725b6490206SBarry Smith 17262593348eSBarry Smith /* create our matrix */ 17273eee16b0SBarry Smith ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A);CHKERRQ(ierr); 17282593348eSBarry Smith B = *A; 1729b6490206SBarry Smith a = (Mat_SeqBAIJ *) B->data; 17302593348eSBarry Smith 17312593348eSBarry Smith /* set matrix "i" values */ 1732de6a44a3SBarry Smith a->i[0] = 0; 1733b6490206SBarry Smith for ( i=1; i<= mbs; i++ ) { 1734b6490206SBarry Smith a->i[i] = a->i[i-1] + browlengths[i-1]; 1735b6490206SBarry Smith a->ilen[i-1] = browlengths[i-1]; 17362593348eSBarry Smith } 1737b6490206SBarry Smith a->nz = 0; 1738b6490206SBarry Smith for ( i=0; i<mbs; i++ ) a->nz += browlengths[i]; 17392593348eSBarry Smith 1740b6490206SBarry Smith /* read in nonzero values */ 174135aab85fSBarry Smith aa = (Scalar *) PetscMalloc((nz+extra_rows)*sizeof(Scalar));CHKPTRQ(aa); 17420752156aSBarry Smith ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR); CHKERRQ(ierr); 174335aab85fSBarry Smith for ( i=0; i<extra_rows; i++ ) aa[nz+i] = 1.0; 1744b6490206SBarry Smith 1745b6490206SBarry Smith /* set "a" and "j" values into matrix */ 1746b6490206SBarry Smith nzcount = 0; jcount = 0; 1747b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 1748b6490206SBarry Smith nzcountb = nzcount; 174935aab85fSBarry Smith nmask = 0; 1750b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 1751b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 1752b6490206SBarry Smith for ( k=0; k<kmax; k++ ) { 175335aab85fSBarry Smith tmp = jj[nzcount++]/bs; 175435aab85fSBarry Smith if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;} 1755b6490206SBarry Smith } 1756b6490206SBarry Smith rowcount++; 1757b6490206SBarry Smith } 1758de6a44a3SBarry Smith /* sort the masked values */ 175977c4ece6SBarry Smith PetscSortInt(nmask,masked); 1760de6a44a3SBarry Smith 1761b6490206SBarry Smith /* set "j" values into matrix */ 1762b6490206SBarry Smith maskcount = 1; 176335aab85fSBarry Smith for ( j=0; j<nmask; j++ ) { 176435aab85fSBarry Smith a->j[jcount++] = masked[j]; 1765de6a44a3SBarry Smith mask[masked[j]] = maskcount++; 1766b6490206SBarry Smith } 1767b6490206SBarry Smith /* set "a" values into matrix */ 1768de6a44a3SBarry Smith ishift = bs2*a->i[i]; 1769b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 1770b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 1771b6490206SBarry Smith for ( k=0; k<kmax; k++ ) { 1772de6a44a3SBarry Smith tmp = jj[nzcountb]/bs ; 1773de6a44a3SBarry Smith block = mask[tmp] - 1; 1774de6a44a3SBarry Smith point = jj[nzcountb] - bs*tmp; 1775de6a44a3SBarry Smith idx = ishift + bs2*block + j + bs*point; 1776b6490206SBarry Smith a->a[idx] = aa[nzcountb++]; 1777b6490206SBarry Smith } 1778b6490206SBarry Smith } 177935aab85fSBarry Smith /* zero out the mask elements we set */ 178035aab85fSBarry Smith for ( j=0; j<nmask; j++ ) mask[masked[j]] = 0; 1781b6490206SBarry Smith } 1782a8c6a408SBarry Smith if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"Bad binary matrix"); 1783b6490206SBarry Smith 1784b6490206SBarry Smith PetscFree(rowlengths); 1785b6490206SBarry Smith PetscFree(browlengths); 1786b6490206SBarry Smith PetscFree(aa); 1787b6490206SBarry Smith PetscFree(jj); 1788b6490206SBarry Smith PetscFree(mask); 1789b6490206SBarry Smith 1790b6490206SBarry Smith B->assembled = PETSC_TRUE; 1791de6a44a3SBarry Smith 17929c01be13SBarry Smith ierr = MatView_Private(B); CHKERRQ(ierr); 17933a40ed3dSBarry Smith PetscFunctionReturn(0); 17942593348eSBarry Smith } 17952593348eSBarry Smith 17962593348eSBarry Smith 17972593348eSBarry Smith 1798