179bdfe76SSatish Balay 2e090d566SSatish Balay #include "src/mat/impls/baij/mpi/mpibaij.h" /*I "petscmat.h" I*/ 379bdfe76SSatish Balay 4dfbe8321SBarry Smith EXTERN PetscErrorCode MatSetUpMultiply_MPIBAIJ(Mat); 5dfbe8321SBarry Smith EXTERN PetscErrorCode DisAssemble_MPIBAIJ(Mat); 6b24ad042SBarry Smith EXTERN PetscErrorCode MatIncreaseOverlap_MPIBAIJ(Mat,PetscInt,IS[],PetscInt); 7b24ad042SBarry Smith EXTERN PetscErrorCode MatGetSubMatrices_MPIBAIJ(Mat,PetscInt,const IS[],const IS[],MatReuse,Mat *[]); 8b24ad042SBarry Smith EXTERN PetscErrorCode MatGetValues_SeqBAIJ(Mat,PetscInt,const PetscInt[],PetscInt,const PetscInt [],PetscScalar []); 9b24ad042SBarry Smith EXTERN PetscErrorCode MatSetValues_SeqBAIJ(Mat,PetscInt,const PetscInt[],PetscInt,const PetscInt [],const PetscScalar [],InsertMode); 10b24ad042SBarry Smith EXTERN PetscErrorCode MatSetValuesBlocked_SeqBAIJ(Mat,PetscInt,const PetscInt[],PetscInt,const PetscInt[],const PetscScalar[],InsertMode); 11b24ad042SBarry Smith EXTERN PetscErrorCode MatGetRow_SeqBAIJ(Mat,PetscInt,PetscInt*,PetscInt*[],PetscScalar*[]); 12b24ad042SBarry Smith EXTERN PetscErrorCode MatRestoreRow_SeqBAIJ(Mat,PetscInt,PetscInt*,PetscInt*[],PetscScalar*[]); 13dfbe8321SBarry Smith EXTERN PetscErrorCode MatPrintHelp_SeqBAIJ(Mat); 14dfbe8321SBarry Smith EXTERN PetscErrorCode MatZeroRows_SeqBAIJ(Mat,IS,const PetscScalar*); 1593fea6afSBarry Smith 1693fea6afSBarry Smith /* UGLY, ugly, ugly 1787828ca2SBarry Smith When MatScalar == PetscScalar the function MatSetValuesBlocked_MPIBAIJ_MatScalar() does 1893fea6afSBarry Smith not exist. Otherwise ..._MatScalar() takes matrix elements in single precision and 1993fea6afSBarry Smith inserts them into the single precision data structure. The function MatSetValuesBlocked_MPIBAIJ() 2093fea6afSBarry Smith converts the entries into single precision and then calls ..._MatScalar() to put them 2193fea6afSBarry Smith into the single precision data structures. 2293fea6afSBarry Smith */ 2393fea6afSBarry Smith #if defined(PETSC_USE_MAT_SINGLE) 24b24ad042SBarry Smith EXTERN PetscErrorCode MatSetValuesBlocked_SeqBAIJ_MatScalar(Mat,PetscInt,const PetscInt*,PetscInt,const PetscInt*,const MatScalar*,InsertMode); 25b24ad042SBarry Smith EXTERN PetscErrorCode MatSetValues_MPIBAIJ_MatScalar(Mat,PetscInt,const PetscInt*,PetscInt,const PetscInt*,const MatScalar*,InsertMode); 26b24ad042SBarry Smith EXTERN PetscErrorCode MatSetValuesBlocked_MPIBAIJ_MatScalar(Mat,PetscInt,const PetscInt*,PetscInt,const PetscInt*,const MatScalar*,InsertMode); 27b24ad042SBarry Smith EXTERN PetscErrorCode MatSetValues_MPIBAIJ_HT_MatScalar(Mat,PetscInt,const PetscInt*,PetscInt,const PetscInt*,const MatScalar*,InsertMode); 28b24ad042SBarry Smith EXTERN PetscErrorCode MatSetValuesBlocked_MPIBAIJ_HT_MatScalar(Mat,PetscInt,const PetscInt*,PetscInt,const PetscInt*,const MatScalar*,InsertMode); 2993fea6afSBarry Smith #else 306fa18ffdSBarry Smith #define MatSetValuesBlocked_SeqBAIJ_MatScalar MatSetValuesBlocked_SeqBAIJ 3193fea6afSBarry Smith #define MatSetValues_MPIBAIJ_MatScalar MatSetValues_MPIBAIJ 3293fea6afSBarry Smith #define MatSetValuesBlocked_MPIBAIJ_MatScalar MatSetValuesBlocked_MPIBAIJ 336fa18ffdSBarry Smith #define MatSetValues_MPIBAIJ_HT_MatScalar MatSetValues_MPIBAIJ_HT 346fa18ffdSBarry Smith #define MatSetValuesBlocked_MPIBAIJ_HT_MatScalar MatSetValuesBlocked_MPIBAIJ_HT 3593fea6afSBarry Smith #endif 363b2fbd54SBarry Smith 374a2ae208SSatish Balay #undef __FUNCT__ 384a2ae208SSatish Balay #define __FUNCT__ "MatGetRowMax_MPIBAIJ" 39dfbe8321SBarry Smith PetscErrorCode MatGetRowMax_MPIBAIJ(Mat A,Vec v) 407843d17aSBarry Smith { 417843d17aSBarry Smith Mat_MPIBAIJ *a = (Mat_MPIBAIJ*)A->data; 42dfbe8321SBarry Smith PetscErrorCode ierr; 43b24ad042SBarry Smith PetscInt i; 4487828ca2SBarry Smith PetscScalar *va,*vb; 457843d17aSBarry Smith Vec vtmp; 467843d17aSBarry Smith 477843d17aSBarry Smith PetscFunctionBegin; 487843d17aSBarry Smith 497843d17aSBarry Smith ierr = MatGetRowMax(a->A,v);CHKERRQ(ierr); 501ebc52fbSHong Zhang ierr = VecGetArray(v,&va);CHKERRQ(ierr); 517843d17aSBarry Smith 52ac355199SBarry Smith ierr = VecCreateSeq(PETSC_COMM_SELF,A->m,&vtmp);CHKERRQ(ierr); 537843d17aSBarry Smith ierr = MatGetRowMax(a->B,vtmp);CHKERRQ(ierr); 541ebc52fbSHong Zhang ierr = VecGetArray(vtmp,&vb);CHKERRQ(ierr); 557843d17aSBarry Smith 56273d9f13SBarry Smith for (i=0; i<A->m; i++){ 57273d9f13SBarry Smith if (PetscAbsScalar(va[i]) < PetscAbsScalar(vb[i])) va[i] = vb[i]; 587843d17aSBarry Smith } 597843d17aSBarry Smith 601ebc52fbSHong Zhang ierr = VecRestoreArray(v,&va);CHKERRQ(ierr); 611ebc52fbSHong Zhang ierr = VecRestoreArray(vtmp,&vb);CHKERRQ(ierr); 62ac355199SBarry Smith ierr = VecDestroy(vtmp);CHKERRQ(ierr); 637843d17aSBarry Smith 647843d17aSBarry Smith PetscFunctionReturn(0); 657843d17aSBarry Smith } 667843d17aSBarry Smith 677fc3c18eSBarry Smith EXTERN_C_BEGIN 684a2ae208SSatish Balay #undef __FUNCT__ 694a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_MPIBAIJ" 70dfbe8321SBarry Smith PetscErrorCode MatStoreValues_MPIBAIJ(Mat mat) 717fc3c18eSBarry Smith { 727fc3c18eSBarry Smith Mat_MPIBAIJ *aij = (Mat_MPIBAIJ *)mat->data; 73dfbe8321SBarry Smith PetscErrorCode ierr; 747fc3c18eSBarry Smith 757fc3c18eSBarry Smith PetscFunctionBegin; 767fc3c18eSBarry Smith ierr = MatStoreValues(aij->A);CHKERRQ(ierr); 777fc3c18eSBarry Smith ierr = MatStoreValues(aij->B);CHKERRQ(ierr); 787fc3c18eSBarry Smith PetscFunctionReturn(0); 797fc3c18eSBarry Smith } 807fc3c18eSBarry Smith EXTERN_C_END 817fc3c18eSBarry Smith 827fc3c18eSBarry Smith EXTERN_C_BEGIN 834a2ae208SSatish Balay #undef __FUNCT__ 844a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_MPIBAIJ" 85dfbe8321SBarry Smith PetscErrorCode MatRetrieveValues_MPIBAIJ(Mat mat) 867fc3c18eSBarry Smith { 877fc3c18eSBarry Smith Mat_MPIBAIJ *aij = (Mat_MPIBAIJ *)mat->data; 88dfbe8321SBarry Smith PetscErrorCode ierr; 897fc3c18eSBarry Smith 907fc3c18eSBarry Smith PetscFunctionBegin; 917fc3c18eSBarry Smith ierr = MatRetrieveValues(aij->A);CHKERRQ(ierr); 927fc3c18eSBarry Smith ierr = MatRetrieveValues(aij->B);CHKERRQ(ierr); 937fc3c18eSBarry Smith PetscFunctionReturn(0); 947fc3c18eSBarry Smith } 957fc3c18eSBarry Smith EXTERN_C_END 967fc3c18eSBarry Smith 97537820f0SBarry Smith /* 98537820f0SBarry Smith Local utility routine that creates a mapping from the global column 9957b952d6SSatish Balay number to the local number in the off-diagonal part of the local 10057b952d6SSatish Balay storage of the matrix. This is done in a non scable way since the 10157b952d6SSatish Balay length of colmap equals the global matrix length. 10257b952d6SSatish Balay */ 1034a2ae208SSatish Balay #undef __FUNCT__ 1044a2ae208SSatish Balay #define __FUNCT__ "CreateColmap_MPIBAIJ_Private" 105dfbe8321SBarry Smith PetscErrorCode CreateColmap_MPIBAIJ_Private(Mat mat) 10657b952d6SSatish Balay { 10757b952d6SSatish Balay Mat_MPIBAIJ *baij = (Mat_MPIBAIJ*)mat->data; 10857b952d6SSatish Balay Mat_SeqBAIJ *B = (Mat_SeqBAIJ*)baij->B->data; 1096849ba73SBarry Smith PetscErrorCode ierr; 110521d7252SBarry Smith PetscInt nbs = B->nbs,i,bs=mat->bs; 11157b952d6SSatish Balay 112d64ed03dSBarry Smith PetscFunctionBegin; 113aa482453SBarry Smith #if defined (PETSC_USE_CTABLE) 114f14a1c24SBarry Smith ierr = PetscTableCreate(baij->nbs,&baij->colmap);CHKERRQ(ierr); 11548e59246SSatish Balay for (i=0; i<nbs; i++){ 1160f5bd95cSBarry Smith ierr = PetscTableAdd(baij->colmap,baij->garray[i]+1,i*bs+1);CHKERRQ(ierr); 11748e59246SSatish Balay } 11848e59246SSatish Balay #else 119b24ad042SBarry Smith ierr = PetscMalloc((baij->Nbs+1)*sizeof(PetscInt),&baij->colmap);CHKERRQ(ierr); 12052e6d16bSBarry Smith ierr = PetscLogObjectMemory(mat,baij->Nbs*sizeof(PetscInt));CHKERRQ(ierr); 121b24ad042SBarry Smith ierr = PetscMemzero(baij->colmap,baij->Nbs*sizeof(PetscInt));CHKERRQ(ierr); 122928fc39bSSatish Balay for (i=0; i<nbs; i++) baij->colmap[baij->garray[i]] = i*bs+1; 12348e59246SSatish Balay #endif 1243a40ed3dSBarry Smith PetscFunctionReturn(0); 12557b952d6SSatish Balay } 12657b952d6SSatish Balay 12780c1aa95SSatish Balay #define CHUNKSIZE 10 12880c1aa95SSatish Balay 129f5e9677aSSatish Balay #define MatSetValues_SeqBAIJ_A_Private(row,col,value,addv) \ 13080c1aa95SSatish Balay { \ 13180c1aa95SSatish Balay \ 13280c1aa95SSatish Balay brow = row/bs; \ 13380c1aa95SSatish Balay rp = aj + ai[brow]; ap = aa + bs2*ai[brow]; \ 134ac7a638eSSatish Balay rmax = aimax[brow]; nrow = ailen[brow]; \ 13580c1aa95SSatish Balay bcol = col/bs; \ 13680c1aa95SSatish Balay ridx = row % bs; cidx = col % bs; \ 137ab26458aSBarry Smith low = 0; high = nrow; \ 138ab26458aSBarry Smith while (high-low > 3) { \ 139ab26458aSBarry Smith t = (low+high)/2; \ 140ab26458aSBarry Smith if (rp[t] > bcol) high = t; \ 141ab26458aSBarry Smith else low = t; \ 142ab26458aSBarry Smith } \ 143ab26458aSBarry Smith for (_i=low; _i<high; _i++) { \ 14480c1aa95SSatish Balay if (rp[_i] > bcol) break; \ 14580c1aa95SSatish Balay if (rp[_i] == bcol) { \ 14680c1aa95SSatish Balay bap = ap + bs2*_i + bs*cidx + ridx; \ 147eada6651SSatish Balay if (addv == ADD_VALUES) *bap += value; \ 148eada6651SSatish Balay else *bap = value; \ 149ac7a638eSSatish Balay goto a_noinsert; \ 15080c1aa95SSatish Balay } \ 15180c1aa95SSatish Balay } \ 15289280ab3SLois Curfman McInnes if (a->nonew == 1) goto a_noinsert; \ 15377431f27SBarry Smith else if (a->nonew == -1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero (%D, %D) into matrix", row, col); \ 15480c1aa95SSatish Balay if (nrow >= rmax) { \ 15580c1aa95SSatish Balay /* there is no extra room in row, therefore enlarge */ \ 156b24ad042SBarry Smith PetscInt new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j; \ 1573eda8832SBarry Smith MatScalar *new_a; \ 15880c1aa95SSatish Balay \ 15977431f27SBarry Smith if (a->nonew == -2) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero (%D, %D) in the matrix", row, col); \ 16089280ab3SLois Curfman McInnes \ 16180c1aa95SSatish Balay /* malloc new storage space */ \ 162b24ad042SBarry Smith len = new_nz*(sizeof(PetscInt)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(PetscInt); \ 16382502324SSatish Balay ierr = PetscMalloc(len,&new_a);CHKERRQ(ierr); \ 164b24ad042SBarry Smith new_j = (PetscInt*)(new_a + bs2*new_nz); \ 16580c1aa95SSatish Balay new_i = new_j + new_nz; \ 16680c1aa95SSatish Balay \ 16780c1aa95SSatish Balay /* copy over old data into new slots */ \ 16880c1aa95SSatish Balay for (ii=0; ii<brow+1; ii++) {new_i[ii] = ai[ii];} \ 16980c1aa95SSatish Balay for (ii=brow+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;} \ 170b24ad042SBarry Smith ierr = PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(PetscInt));CHKERRQ(ierr); \ 17180c1aa95SSatish Balay len = (new_nz - CHUNKSIZE - ai[brow] - nrow); \ 172b24ad042SBarry Smith ierr = PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow,len*sizeof(PetscInt));CHKERRQ(ierr); \ 1733eda8832SBarry Smith ierr = PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr); \ 17487828ca2SBarry Smith ierr = PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(PetscScalar));CHKERRQ(ierr); \ 175549d3d68SSatish Balay ierr = PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE), \ 1763eda8832SBarry Smith aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr); \ 17780c1aa95SSatish Balay /* free up old matrix storage */ \ 178606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); \ 179606d414cSSatish Balay if (!a->singlemalloc) { \ 180606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); \ 181606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr);\ 182606d414cSSatish Balay } \ 18380c1aa95SSatish Balay aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; \ 1847c922b88SBarry Smith a->singlemalloc = PETSC_TRUE; \ 18580c1aa95SSatish Balay \ 18680c1aa95SSatish Balay rp = aj + ai[brow]; ap = aa + bs2*ai[brow]; \ 187ac7a638eSSatish Balay rmax = aimax[brow] = aimax[brow] + CHUNKSIZE; \ 18852e6d16bSBarry Smith ierr = PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(PetscInt) + bs2*sizeof(MatScalar)));CHKERRQ(ierr); \ 18980c1aa95SSatish Balay a->maxnz += bs2*CHUNKSIZE; \ 19080c1aa95SSatish Balay a->reallocs++; \ 19180c1aa95SSatish Balay a->nz++; \ 19280c1aa95SSatish Balay } \ 19380c1aa95SSatish Balay N = nrow++ - 1; \ 19480c1aa95SSatish Balay /* shift up all the later entries in this row */ \ 19580c1aa95SSatish Balay for (ii=N; ii>=_i; ii--) { \ 19680c1aa95SSatish Balay rp[ii+1] = rp[ii]; \ 1973eda8832SBarry Smith ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr); \ 19880c1aa95SSatish Balay } \ 1993eda8832SBarry Smith if (N>=_i) { ierr = PetscMemzero(ap+bs2*_i,bs2*sizeof(MatScalar));CHKERRQ(ierr); } \ 20080c1aa95SSatish Balay rp[_i] = bcol; \ 20180c1aa95SSatish Balay ap[bs2*_i + bs*cidx + ridx] = value; \ 202ac7a638eSSatish Balay a_noinsert:; \ 20380c1aa95SSatish Balay ailen[brow] = nrow; \ 20480c1aa95SSatish Balay } 20557b952d6SSatish Balay 206ac7a638eSSatish Balay #define MatSetValues_SeqBAIJ_B_Private(row,col,value,addv) \ 207ac7a638eSSatish Balay { \ 208ac7a638eSSatish Balay brow = row/bs; \ 209ac7a638eSSatish Balay rp = bj + bi[brow]; ap = ba + bs2*bi[brow]; \ 210ac7a638eSSatish Balay rmax = bimax[brow]; nrow = bilen[brow]; \ 211ac7a638eSSatish Balay bcol = col/bs; \ 212ac7a638eSSatish Balay ridx = row % bs; cidx = col % bs; \ 213ac7a638eSSatish Balay low = 0; high = nrow; \ 214ac7a638eSSatish Balay while (high-low > 3) { \ 215ac7a638eSSatish Balay t = (low+high)/2; \ 216ac7a638eSSatish Balay if (rp[t] > bcol) high = t; \ 217ac7a638eSSatish Balay else low = t; \ 218ac7a638eSSatish Balay } \ 219ac7a638eSSatish Balay for (_i=low; _i<high; _i++) { \ 220ac7a638eSSatish Balay if (rp[_i] > bcol) break; \ 221ac7a638eSSatish Balay if (rp[_i] == bcol) { \ 222ac7a638eSSatish Balay bap = ap + bs2*_i + bs*cidx + ridx; \ 223ac7a638eSSatish Balay if (addv == ADD_VALUES) *bap += value; \ 224ac7a638eSSatish Balay else *bap = value; \ 225ac7a638eSSatish Balay goto b_noinsert; \ 226ac7a638eSSatish Balay } \ 227ac7a638eSSatish Balay } \ 22889280ab3SLois Curfman McInnes if (b->nonew == 1) goto b_noinsert; \ 22977431f27SBarry Smith else if (b->nonew == -1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero (%D, %D) into matrix", row, col); \ 230ac7a638eSSatish Balay if (nrow >= rmax) { \ 231ac7a638eSSatish Balay /* there is no extra room in row, therefore enlarge */ \ 232b24ad042SBarry Smith PetscInt new_nz = bi[b->mbs] + CHUNKSIZE,len,*new_i,*new_j; \ 2333eda8832SBarry Smith MatScalar *new_a; \ 234ac7a638eSSatish Balay \ 23577431f27SBarry Smith if (b->nonew == -2) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero (%D, %D) in the matrix", row, col); \ 23689280ab3SLois Curfman McInnes \ 237ac7a638eSSatish Balay /* malloc new storage space */ \ 238b24ad042SBarry Smith len = new_nz*(sizeof(PetscInt)+bs2*sizeof(MatScalar))+(b->mbs+1)*sizeof(PetscInt); \ 23982502324SSatish Balay ierr = PetscMalloc(len,&new_a);CHKERRQ(ierr); \ 240b24ad042SBarry Smith new_j = (PetscInt*)(new_a + bs2*new_nz); \ 241ac7a638eSSatish Balay new_i = new_j + new_nz; \ 242ac7a638eSSatish Balay \ 243ac7a638eSSatish Balay /* copy over old data into new slots */ \ 244ac7a638eSSatish Balay for (ii=0; ii<brow+1; ii++) {new_i[ii] = bi[ii];} \ 24574c639caSSatish Balay for (ii=brow+1; ii<b->mbs+1; ii++) {new_i[ii] = bi[ii]+CHUNKSIZE;} \ 246b24ad042SBarry Smith ierr = PetscMemcpy(new_j,bj,(bi[brow]+nrow)*sizeof(PetscInt));CHKERRQ(ierr); \ 247ac7a638eSSatish Balay len = (new_nz - CHUNKSIZE - bi[brow] - nrow); \ 248b24ad042SBarry Smith ierr = PetscMemcpy(new_j+bi[brow]+nrow+CHUNKSIZE,bj+bi[brow]+nrow,len*sizeof(PetscInt));CHKERRQ(ierr); \ 2493eda8832SBarry Smith ierr = PetscMemcpy(new_a,ba,(bi[brow]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr); \ 2503eda8832SBarry Smith ierr = PetscMemzero(new_a+bs2*(bi[brow]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr); \ 251549d3d68SSatish Balay ierr = PetscMemcpy(new_a+bs2*(bi[brow]+nrow+CHUNKSIZE), \ 2523eda8832SBarry Smith ba+bs2*(bi[brow]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr); \ 253ac7a638eSSatish Balay /* free up old matrix storage */ \ 254606d414cSSatish Balay ierr = PetscFree(b->a);CHKERRQ(ierr); \ 255606d414cSSatish Balay if (!b->singlemalloc) { \ 256606d414cSSatish Balay ierr = PetscFree(b->i);CHKERRQ(ierr); \ 257606d414cSSatish Balay ierr = PetscFree(b->j);CHKERRQ(ierr); \ 258606d414cSSatish Balay } \ 25974c639caSSatish Balay ba = b->a = new_a; bi = b->i = new_i; bj = b->j = new_j; \ 2607c922b88SBarry Smith b->singlemalloc = PETSC_TRUE; \ 261ac7a638eSSatish Balay \ 262ac7a638eSSatish Balay rp = bj + bi[brow]; ap = ba + bs2*bi[brow]; \ 263ac7a638eSSatish Balay rmax = bimax[brow] = bimax[brow] + CHUNKSIZE; \ 26452e6d16bSBarry Smith ierr = PetscLogObjectMemory(B,CHUNKSIZE*(sizeof(PetscInt) + bs2*sizeof(MatScalar)));CHKERRQ(ierr); \ 26574c639caSSatish Balay b->maxnz += bs2*CHUNKSIZE; \ 26674c639caSSatish Balay b->reallocs++; \ 26774c639caSSatish Balay b->nz++; \ 268ac7a638eSSatish Balay } \ 269ac7a638eSSatish Balay N = nrow++ - 1; \ 270ac7a638eSSatish Balay /* shift up all the later entries in this row */ \ 271ac7a638eSSatish Balay for (ii=N; ii>=_i; ii--) { \ 272ac7a638eSSatish Balay rp[ii+1] = rp[ii]; \ 2733eda8832SBarry Smith ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr); \ 274ac7a638eSSatish Balay } \ 2753eda8832SBarry Smith if (N>=_i) { ierr = PetscMemzero(ap+bs2*_i,bs2*sizeof(MatScalar));CHKERRQ(ierr);} \ 276ac7a638eSSatish Balay rp[_i] = bcol; \ 277ac7a638eSSatish Balay ap[bs2*_i + bs*cidx + ridx] = value; \ 278ac7a638eSSatish Balay b_noinsert:; \ 279ac7a638eSSatish Balay bilen[brow] = nrow; \ 280ac7a638eSSatish Balay } 281ac7a638eSSatish Balay 28293fea6afSBarry Smith #if defined(PETSC_USE_MAT_SINGLE) 2834a2ae208SSatish Balay #undef __FUNCT__ 2844a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_MPIBAIJ" 285b24ad042SBarry Smith PetscErrorCode MatSetValues_MPIBAIJ(Mat mat,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode addv) 28657b952d6SSatish Balay { 2876fa18ffdSBarry Smith Mat_MPIBAIJ *b = (Mat_MPIBAIJ*)mat->data; 288dfbe8321SBarry Smith PetscErrorCode ierr; 289b24ad042SBarry Smith PetscInt i,N = m*n; 2906fa18ffdSBarry Smith MatScalar *vsingle; 29193fea6afSBarry Smith 29293fea6afSBarry Smith PetscFunctionBegin; 2936fa18ffdSBarry Smith if (N > b->setvalueslen) { 2946fa18ffdSBarry Smith if (b->setvaluescopy) {ierr = PetscFree(b->setvaluescopy);CHKERRQ(ierr);} 29582502324SSatish Balay ierr = PetscMalloc(N*sizeof(MatScalar),&b->setvaluescopy);CHKERRQ(ierr); 2966fa18ffdSBarry Smith b->setvalueslen = N; 2976fa18ffdSBarry Smith } 2986fa18ffdSBarry Smith vsingle = b->setvaluescopy; 2996fa18ffdSBarry Smith 30093fea6afSBarry Smith for (i=0; i<N; i++) { 30193fea6afSBarry Smith vsingle[i] = v[i]; 30293fea6afSBarry Smith } 30393fea6afSBarry Smith ierr = MatSetValues_MPIBAIJ_MatScalar(mat,m,im,n,in,vsingle,addv);CHKERRQ(ierr); 30493fea6afSBarry Smith PetscFunctionReturn(0); 30593fea6afSBarry Smith } 30693fea6afSBarry Smith 3074a2ae208SSatish Balay #undef __FUNCT__ 3084a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_MPIBAIJ" 309b24ad042SBarry Smith PetscErrorCode MatSetValuesBlocked_MPIBAIJ(Mat mat,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode addv) 31093fea6afSBarry Smith { 3116fa18ffdSBarry Smith Mat_MPIBAIJ *b = (Mat_MPIBAIJ*)mat->data; 312dfbe8321SBarry Smith PetscErrorCode ierr; 313b24ad042SBarry Smith PetscInt i,N = m*n*b->bs2; 3146fa18ffdSBarry Smith MatScalar *vsingle; 31593fea6afSBarry Smith 31693fea6afSBarry Smith PetscFunctionBegin; 3176fa18ffdSBarry Smith if (N > b->setvalueslen) { 3186fa18ffdSBarry Smith if (b->setvaluescopy) {ierr = PetscFree(b->setvaluescopy);CHKERRQ(ierr);} 31982502324SSatish Balay ierr = PetscMalloc(N*sizeof(MatScalar),&b->setvaluescopy);CHKERRQ(ierr); 3206fa18ffdSBarry Smith b->setvalueslen = N; 3216fa18ffdSBarry Smith } 3226fa18ffdSBarry Smith vsingle = b->setvaluescopy; 32393fea6afSBarry Smith for (i=0; i<N; i++) { 32493fea6afSBarry Smith vsingle[i] = v[i]; 32593fea6afSBarry Smith } 32693fea6afSBarry Smith ierr = MatSetValuesBlocked_MPIBAIJ_MatScalar(mat,m,im,n,in,vsingle,addv);CHKERRQ(ierr); 32793fea6afSBarry Smith PetscFunctionReturn(0); 32893fea6afSBarry Smith } 3296fa18ffdSBarry Smith 3304a2ae208SSatish Balay #undef __FUNCT__ 3314a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_MPIBAIJ_HT" 332b24ad042SBarry Smith PetscErrorCode MatSetValues_MPIBAIJ_HT(Mat mat,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode addv) 3336fa18ffdSBarry Smith { 3346fa18ffdSBarry Smith Mat_MPIBAIJ *b = (Mat_MPIBAIJ*)mat->data; 335dfbe8321SBarry Smith PetscErrorCode ierr; 336b24ad042SBarry Smith PetscInt i,N = m*n; 3376fa18ffdSBarry Smith MatScalar *vsingle; 3386fa18ffdSBarry Smith 3396fa18ffdSBarry Smith PetscFunctionBegin; 3406fa18ffdSBarry Smith if (N > b->setvalueslen) { 3416fa18ffdSBarry Smith if (b->setvaluescopy) {ierr = PetscFree(b->setvaluescopy);CHKERRQ(ierr);} 34282502324SSatish Balay ierr = PetscMalloc(N*sizeof(MatScalar),&b->setvaluescopy);CHKERRQ(ierr); 3436fa18ffdSBarry Smith b->setvalueslen = N; 3446fa18ffdSBarry Smith } 3456fa18ffdSBarry Smith vsingle = b->setvaluescopy; 3466fa18ffdSBarry Smith for (i=0; i<N; i++) { 3476fa18ffdSBarry Smith vsingle[i] = v[i]; 3486fa18ffdSBarry Smith } 3496fa18ffdSBarry Smith ierr = MatSetValues_MPIBAIJ_HT_MatScalar(mat,m,im,n,in,vsingle,addv);CHKERRQ(ierr); 3506fa18ffdSBarry Smith PetscFunctionReturn(0); 3516fa18ffdSBarry Smith } 3526fa18ffdSBarry Smith 3534a2ae208SSatish Balay #undef __FUNCT__ 3544a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_MPIBAIJ_HT" 355b24ad042SBarry Smith PetscErrorCode MatSetValuesBlocked_MPIBAIJ_HT(Mat mat,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode addv) 3566fa18ffdSBarry Smith { 3576fa18ffdSBarry Smith Mat_MPIBAIJ *b = (Mat_MPIBAIJ*)mat->data; 358dfbe8321SBarry Smith PetscErrorCode ierr; 359b24ad042SBarry Smith PetscInt i,N = m*n*b->bs2; 3606fa18ffdSBarry Smith MatScalar *vsingle; 3616fa18ffdSBarry Smith 3626fa18ffdSBarry Smith PetscFunctionBegin; 3636fa18ffdSBarry Smith if (N > b->setvalueslen) { 3646fa18ffdSBarry Smith if (b->setvaluescopy) {ierr = PetscFree(b->setvaluescopy);CHKERRQ(ierr);} 36582502324SSatish Balay ierr = PetscMalloc(N*sizeof(MatScalar),&b->setvaluescopy);CHKERRQ(ierr); 3666fa18ffdSBarry Smith b->setvalueslen = N; 3676fa18ffdSBarry Smith } 3686fa18ffdSBarry Smith vsingle = b->setvaluescopy; 3696fa18ffdSBarry Smith for (i=0; i<N; i++) { 3706fa18ffdSBarry Smith vsingle[i] = v[i]; 3716fa18ffdSBarry Smith } 3726fa18ffdSBarry Smith ierr = MatSetValuesBlocked_MPIBAIJ_HT_MatScalar(mat,m,im,n,in,vsingle,addv);CHKERRQ(ierr); 3736fa18ffdSBarry Smith PetscFunctionReturn(0); 3746fa18ffdSBarry Smith } 37593fea6afSBarry Smith #endif 37693fea6afSBarry Smith 3774a2ae208SSatish Balay #undef __FUNCT__ 378e03e44c9SSatish Balay #define __FUNCT__ "MatSetValues_MPIBAIJ_MatScalar" 379b24ad042SBarry Smith PetscErrorCode MatSetValues_MPIBAIJ_MatScalar(Mat mat,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const MatScalar v[],InsertMode addv) 38093fea6afSBarry Smith { 38157b952d6SSatish Balay Mat_MPIBAIJ *baij = (Mat_MPIBAIJ*)mat->data; 38293fea6afSBarry Smith MatScalar value; 383273d9f13SBarry Smith PetscTruth roworiented = baij->roworiented; 384dfbe8321SBarry Smith PetscErrorCode ierr; 385b24ad042SBarry Smith PetscInt i,j,row,col; 386b24ad042SBarry Smith PetscInt rstart_orig=baij->rstart_bs; 387b24ad042SBarry Smith PetscInt rend_orig=baij->rend_bs,cstart_orig=baij->cstart_bs; 388521d7252SBarry Smith PetscInt cend_orig=baij->cend_bs,bs=mat->bs; 38957b952d6SSatish Balay 390eada6651SSatish Balay /* Some Variables required in the macro */ 39180c1aa95SSatish Balay Mat A = baij->A; 39280c1aa95SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)(A)->data; 393b24ad042SBarry Smith PetscInt *aimax=a->imax,*ai=a->i,*ailen=a->ilen,*aj=a->j; 3943eda8832SBarry Smith MatScalar *aa=a->a; 395ac7a638eSSatish Balay 396ac7a638eSSatish Balay Mat B = baij->B; 397ac7a638eSSatish Balay Mat_SeqBAIJ *b = (Mat_SeqBAIJ*)(B)->data; 398b24ad042SBarry Smith PetscInt *bimax=b->imax,*bi=b->i,*bilen=b->ilen,*bj=b->j; 3993eda8832SBarry Smith MatScalar *ba=b->a; 400ac7a638eSSatish Balay 401b24ad042SBarry Smith PetscInt *rp,ii,nrow,_i,rmax,N,brow,bcol; 402b24ad042SBarry Smith PetscInt low,high,t,ridx,cidx,bs2=a->bs2; 4033eda8832SBarry Smith MatScalar *ap,*bap; 40480c1aa95SSatish Balay 405d64ed03dSBarry Smith PetscFunctionBegin; 40657b952d6SSatish Balay for (i=0; i<m; i++) { 4075ef9f2a5SBarry Smith if (im[i] < 0) continue; 4082515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 40977431f27SBarry Smith if (im[i] >= mat->M) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",im[i],mat->M-1); 410639f9d9dSBarry Smith #endif 41157b952d6SSatish Balay if (im[i] >= rstart_orig && im[i] < rend_orig) { 41257b952d6SSatish Balay row = im[i] - rstart_orig; 41357b952d6SSatish Balay for (j=0; j<n; j++) { 41457b952d6SSatish Balay if (in[j] >= cstart_orig && in[j] < cend_orig){ 41557b952d6SSatish Balay col = in[j] - cstart_orig; 41657b952d6SSatish Balay if (roworiented) value = v[i*n+j]; else value = v[i+j*m]; 417f5e9677aSSatish Balay MatSetValues_SeqBAIJ_A_Private(row,col,value,addv); 41880c1aa95SSatish Balay /* ierr = MatSetValues_SeqBAIJ(baij->A,1,&row,1,&col,&value,addv);CHKERRQ(ierr); */ 41973959e64SBarry Smith } else if (in[j] < 0) continue; 4202515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 42177431f27SBarry Smith else if (in[j] >= mat->N) {SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",in[i],mat->N-1);} 422639f9d9dSBarry Smith #endif 42357b952d6SSatish Balay else { 42457b952d6SSatish Balay if (mat->was_assembled) { 425905e6a2fSBarry Smith if (!baij->colmap) { 426905e6a2fSBarry Smith ierr = CreateColmap_MPIBAIJ_Private(mat);CHKERRQ(ierr); 427905e6a2fSBarry Smith } 428aa482453SBarry Smith #if defined (PETSC_USE_CTABLE) 4290f5bd95cSBarry Smith ierr = PetscTableFind(baij->colmap,in[j]/bs + 1,&col);CHKERRQ(ierr); 430bba1ac68SSatish Balay col = col - 1; 43148e59246SSatish Balay #else 432bba1ac68SSatish Balay col = baij->colmap[in[j]/bs] - 1; 43348e59246SSatish Balay #endif 43457b952d6SSatish Balay if (col < 0 && !((Mat_SeqBAIJ*)(baij->A->data))->nonew) { 43557b952d6SSatish Balay ierr = DisAssemble_MPIBAIJ(mat);CHKERRQ(ierr); 4368295de27SSatish Balay col = in[j]; 4379bf004c3SSatish Balay /* Reinitialize the variables required by MatSetValues_SeqBAIJ_B_Private() */ 4389bf004c3SSatish Balay B = baij->B; 4399bf004c3SSatish Balay b = (Mat_SeqBAIJ*)(B)->data; 4409bf004c3SSatish Balay bimax=b->imax;bi=b->i;bilen=b->ilen;bj=b->j; 4419bf004c3SSatish Balay ba=b->a; 442bba1ac68SSatish Balay } else col += in[j]%bs; 4438295de27SSatish Balay } else col = in[j]; 44457b952d6SSatish Balay if (roworiented) value = v[i*n+j]; else value = v[i+j*m]; 44590da58bdSSatish Balay MatSetValues_SeqBAIJ_B_Private(row,col,value,addv); 44690da58bdSSatish Balay /* ierr = MatSetValues_SeqBAIJ(baij->B,1,&row,1,&col,&value,addv);CHKERRQ(ierr); */ 44757b952d6SSatish Balay } 44857b952d6SSatish Balay } 449d64ed03dSBarry Smith } else { 45090f02eecSBarry Smith if (!baij->donotstash) { 451ff2fd236SBarry Smith if (roworiented) { 4526fa18ffdSBarry Smith ierr = MatStashValuesRow_Private(&mat->stash,im[i],n,in,v+i*n);CHKERRQ(ierr); 453ff2fd236SBarry Smith } else { 4546fa18ffdSBarry Smith ierr = MatStashValuesCol_Private(&mat->stash,im[i],n,in,v+i,m);CHKERRQ(ierr); 45557b952d6SSatish Balay } 45657b952d6SSatish Balay } 45757b952d6SSatish Balay } 45890f02eecSBarry Smith } 4593a40ed3dSBarry Smith PetscFunctionReturn(0); 46057b952d6SSatish Balay } 46157b952d6SSatish Balay 4624a2ae208SSatish Balay #undef __FUNCT__ 4634a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_MPIBAIJ_MatScalar" 464b24ad042SBarry Smith PetscErrorCode MatSetValuesBlocked_MPIBAIJ_MatScalar(Mat mat,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const MatScalar v[],InsertMode addv) 465ab26458aSBarry Smith { 466ab26458aSBarry Smith Mat_MPIBAIJ *baij = (Mat_MPIBAIJ*)mat->data; 467f15d580aSBarry Smith const MatScalar *value; 468f15d580aSBarry Smith MatScalar *barray=baij->barray; 469273d9f13SBarry Smith PetscTruth roworiented = baij->roworiented; 470dfbe8321SBarry Smith PetscErrorCode ierr; 471b24ad042SBarry Smith PetscInt i,j,ii,jj,row,col,rstart=baij->rstart; 472b24ad042SBarry Smith PetscInt rend=baij->rend,cstart=baij->cstart,stepval; 473521d7252SBarry Smith PetscInt cend=baij->cend,bs=mat->bs,bs2=baij->bs2; 474ab26458aSBarry Smith 475b16ae2b1SBarry Smith PetscFunctionBegin; 47630793edcSSatish Balay if(!barray) { 47782502324SSatish Balay ierr = PetscMalloc(bs2*sizeof(MatScalar),&barray);CHKERRQ(ierr); 47882502324SSatish Balay baij->barray = barray; 47930793edcSSatish Balay } 48030793edcSSatish Balay 481ab26458aSBarry Smith if (roworiented) { 482ab26458aSBarry Smith stepval = (n-1)*bs; 483ab26458aSBarry Smith } else { 484ab26458aSBarry Smith stepval = (m-1)*bs; 485ab26458aSBarry Smith } 486ab26458aSBarry Smith for (i=0; i<m; i++) { 4875ef9f2a5SBarry Smith if (im[i] < 0) continue; 4882515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 48977431f27SBarry Smith if (im[i] >= baij->Mbs) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large, row %D max %D",im[i],baij->Mbs-1); 490ab26458aSBarry Smith #endif 491ab26458aSBarry Smith if (im[i] >= rstart && im[i] < rend) { 492ab26458aSBarry Smith row = im[i] - rstart; 493ab26458aSBarry Smith for (j=0; j<n; j++) { 49415b57d14SSatish Balay /* If NumCol = 1 then a copy is not required */ 49515b57d14SSatish Balay if ((roworiented) && (n == 1)) { 496f15d580aSBarry Smith barray = (MatScalar*)v + i*bs2; 49715b57d14SSatish Balay } else if((!roworiented) && (m == 1)) { 498f15d580aSBarry Smith barray = (MatScalar*)v + j*bs2; 49915b57d14SSatish Balay } else { /* Here a copy is required */ 500ab26458aSBarry Smith if (roworiented) { 501ab26458aSBarry Smith value = v + i*(stepval+bs)*bs + j*bs; 502ab26458aSBarry Smith } else { 503ab26458aSBarry Smith value = v + j*(stepval+bs)*bs + i*bs; 504abef11f7SSatish Balay } 50547513183SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 50647513183SBarry Smith for (jj=0; jj<bs; jj++) { 50730793edcSSatish Balay *barray++ = *value++; 50847513183SBarry Smith } 50947513183SBarry Smith } 51030793edcSSatish Balay barray -=bs2; 51115b57d14SSatish Balay } 512abef11f7SSatish Balay 513abef11f7SSatish Balay if (in[j] >= cstart && in[j] < cend){ 514abef11f7SSatish Balay col = in[j] - cstart; 51593fea6afSBarry Smith ierr = MatSetValuesBlocked_SeqBAIJ_MatScalar(baij->A,1,&row,1,&col,barray,addv);CHKERRQ(ierr); 516ab26458aSBarry Smith } 5175ef9f2a5SBarry Smith else if (in[j] < 0) continue; 5182515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 51977431f27SBarry Smith else if (in[j] >= baij->Nbs) {SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large, col %D max %D",in[j],baij->Nbs-1);} 520ab26458aSBarry Smith #endif 521ab26458aSBarry Smith else { 522ab26458aSBarry Smith if (mat->was_assembled) { 523ab26458aSBarry Smith if (!baij->colmap) { 524ab26458aSBarry Smith ierr = CreateColmap_MPIBAIJ_Private(mat);CHKERRQ(ierr); 525ab26458aSBarry Smith } 526a5eb4965SSatish Balay 5272515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 528aa482453SBarry Smith #if defined (PETSC_USE_CTABLE) 529b24ad042SBarry Smith { PetscInt data; 5300f5bd95cSBarry Smith ierr = PetscTableFind(baij->colmap,in[j]+1,&data);CHKERRQ(ierr); 53129bbc08cSBarry Smith if ((data - 1) % bs) SETERRQ(PETSC_ERR_PLIB,"Incorrect colmap"); 532fa46199cSSatish Balay } 53348e59246SSatish Balay #else 53429bbc08cSBarry Smith if ((baij->colmap[in[j]] - 1) % bs) SETERRQ(PETSC_ERR_PLIB,"Incorrect colmap"); 535a5eb4965SSatish Balay #endif 53648e59246SSatish Balay #endif 537aa482453SBarry Smith #if defined (PETSC_USE_CTABLE) 5380f5bd95cSBarry Smith ierr = PetscTableFind(baij->colmap,in[j]+1,&col);CHKERRQ(ierr); 539fa46199cSSatish Balay col = (col - 1)/bs; 54048e59246SSatish Balay #else 541a5eb4965SSatish Balay col = (baij->colmap[in[j]] - 1)/bs; 54248e59246SSatish Balay #endif 543ab26458aSBarry Smith if (col < 0 && !((Mat_SeqBAIJ*)(baij->A->data))->nonew) { 544ab26458aSBarry Smith ierr = DisAssemble_MPIBAIJ(mat);CHKERRQ(ierr); 545ab26458aSBarry Smith col = in[j]; 546ab26458aSBarry Smith } 547ab26458aSBarry Smith } 548ab26458aSBarry Smith else col = in[j]; 54993fea6afSBarry Smith ierr = MatSetValuesBlocked_SeqBAIJ_MatScalar(baij->B,1,&row,1,&col,barray,addv);CHKERRQ(ierr); 550ab26458aSBarry Smith } 551ab26458aSBarry Smith } 552d64ed03dSBarry Smith } else { 553ab26458aSBarry Smith if (!baij->donotstash) { 554ff2fd236SBarry Smith if (roworiented) { 5556fa18ffdSBarry Smith ierr = MatStashValuesRowBlocked_Private(&mat->bstash,im[i],n,in,v,m,n,i);CHKERRQ(ierr); 556ff2fd236SBarry Smith } else { 5576fa18ffdSBarry Smith ierr = MatStashValuesColBlocked_Private(&mat->bstash,im[i],n,in,v,m,n,i);CHKERRQ(ierr); 558ff2fd236SBarry Smith } 559abef11f7SSatish Balay } 560ab26458aSBarry Smith } 561ab26458aSBarry Smith } 5623a40ed3dSBarry Smith PetscFunctionReturn(0); 563ab26458aSBarry Smith } 5646fa18ffdSBarry Smith 5650bdbc534SSatish Balay #define HASH_KEY 0.6180339887 566b24ad042SBarry Smith #define HASH(size,key,tmp) (tmp = (key)*HASH_KEY,(PetscInt)((size)*(tmp-(PetscInt)tmp))) 567b24ad042SBarry Smith /* #define HASH(size,key) ((PetscInt)((size)*fmod(((key)*HASH_KEY),1))) */ 568b24ad042SBarry Smith /* #define HASH(size,key,tmp) ((PetscInt)((size)*fmod(((key)*HASH_KEY),1))) */ 5694a2ae208SSatish Balay #undef __FUNCT__ 5704a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_MPIBAIJ_HT_MatScalar" 571b24ad042SBarry Smith PetscErrorCode MatSetValues_MPIBAIJ_HT_MatScalar(Mat mat,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const MatScalar v[],InsertMode addv) 5720bdbc534SSatish Balay { 5730bdbc534SSatish Balay Mat_MPIBAIJ *baij = (Mat_MPIBAIJ*)mat->data; 574273d9f13SBarry Smith PetscTruth roworiented = baij->roworiented; 575dfbe8321SBarry Smith PetscErrorCode ierr; 576b24ad042SBarry Smith PetscInt i,j,row,col; 577b24ad042SBarry Smith PetscInt rstart_orig=baij->rstart_bs; 578b24ad042SBarry Smith PetscInt rend_orig=baij->rend_bs,Nbs=baij->Nbs; 579521d7252SBarry Smith PetscInt h1,key,size=baij->ht_size,bs=mat->bs,*HT=baij->ht,idx; 580329f5518SBarry Smith PetscReal tmp; 5813eda8832SBarry Smith MatScalar **HD = baij->hd,value; 5822515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 583b24ad042SBarry Smith PetscInt total_ct=baij->ht_total_ct,insert_ct=baij->ht_insert_ct; 5844a15367fSSatish Balay #endif 5850bdbc534SSatish Balay 5860bdbc534SSatish Balay PetscFunctionBegin; 5870bdbc534SSatish Balay 5880bdbc534SSatish Balay for (i=0; i<m; i++) { 5892515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 59029bbc08cSBarry Smith if (im[i] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative row"); 59177431f27SBarry Smith if (im[i] >= mat->M) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",im[i],mat->M-1); 5920bdbc534SSatish Balay #endif 5930bdbc534SSatish Balay row = im[i]; 594c2760754SSatish Balay if (row >= rstart_orig && row < rend_orig) { 5950bdbc534SSatish Balay for (j=0; j<n; j++) { 5960bdbc534SSatish Balay col = in[j]; 5976fa18ffdSBarry Smith if (roworiented) value = v[i*n+j]; else value = v[i+j*m]; 598b24ad042SBarry Smith /* Look up PetscInto the Hash Table */ 599c2760754SSatish Balay key = (row/bs)*Nbs+(col/bs)+1; 600c2760754SSatish Balay h1 = HASH(size,key,tmp); 6010bdbc534SSatish Balay 602c2760754SSatish Balay 603c2760754SSatish Balay idx = h1; 6042515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 605187ce0cbSSatish Balay insert_ct++; 606187ce0cbSSatish Balay total_ct++; 607187ce0cbSSatish Balay if (HT[idx] != key) { 608187ce0cbSSatish Balay for (idx=h1; (idx<size) && (HT[idx]!=key); idx++,total_ct++); 609187ce0cbSSatish Balay if (idx == size) { 610187ce0cbSSatish Balay for (idx=0; (idx<h1) && (HT[idx]!=key); idx++,total_ct++); 611187ce0cbSSatish Balay if (idx == h1) { 61277431f27SBarry Smith SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"(%D,%D) has no entry in the hash table", row, col); 613187ce0cbSSatish Balay } 614187ce0cbSSatish Balay } 615187ce0cbSSatish Balay } 616187ce0cbSSatish Balay #else 617c2760754SSatish Balay if (HT[idx] != key) { 618c2760754SSatish Balay for (idx=h1; (idx<size) && (HT[idx]!=key); idx++); 619c2760754SSatish Balay if (idx == size) { 620c2760754SSatish Balay for (idx=0; (idx<h1) && (HT[idx]!=key); idx++); 621c2760754SSatish Balay if (idx == h1) { 62277431f27SBarry Smith SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"(%D,%D) has no entry in the hash table", row, col); 623c2760754SSatish Balay } 624c2760754SSatish Balay } 625c2760754SSatish Balay } 626187ce0cbSSatish Balay #endif 627c2760754SSatish Balay /* A HASH table entry is found, so insert the values at the correct address */ 628c2760754SSatish Balay if (addv == ADD_VALUES) *(HD[idx]+ (col % bs)*bs + (row % bs)) += value; 629c2760754SSatish Balay else *(HD[idx]+ (col % bs)*bs + (row % bs)) = value; 6300bdbc534SSatish Balay } 6310bdbc534SSatish Balay } else { 6320bdbc534SSatish Balay if (!baij->donotstash) { 633ff2fd236SBarry Smith if (roworiented) { 6348798bf22SSatish Balay ierr = MatStashValuesRow_Private(&mat->stash,im[i],n,in,v+i*n);CHKERRQ(ierr); 635ff2fd236SBarry Smith } else { 6368798bf22SSatish Balay ierr = MatStashValuesCol_Private(&mat->stash,im[i],n,in,v+i,m);CHKERRQ(ierr); 6370bdbc534SSatish Balay } 6380bdbc534SSatish Balay } 6390bdbc534SSatish Balay } 6400bdbc534SSatish Balay } 6412515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 642187ce0cbSSatish Balay baij->ht_total_ct = total_ct; 643187ce0cbSSatish Balay baij->ht_insert_ct = insert_ct; 644187ce0cbSSatish Balay #endif 6450bdbc534SSatish Balay PetscFunctionReturn(0); 6460bdbc534SSatish Balay } 6470bdbc534SSatish Balay 6484a2ae208SSatish Balay #undef __FUNCT__ 6494a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_MPIBAIJ_HT_MatScalar" 650b24ad042SBarry Smith PetscErrorCode MatSetValuesBlocked_MPIBAIJ_HT_MatScalar(Mat mat,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const MatScalar v[],InsertMode addv) 6510bdbc534SSatish Balay { 6520bdbc534SSatish Balay Mat_MPIBAIJ *baij = (Mat_MPIBAIJ*)mat->data; 653273d9f13SBarry Smith PetscTruth roworiented = baij->roworiented; 654dfbe8321SBarry Smith PetscErrorCode ierr; 655b24ad042SBarry Smith PetscInt i,j,ii,jj,row,col; 656b24ad042SBarry Smith PetscInt rstart=baij->rstart ; 657521d7252SBarry Smith PetscInt rend=baij->rend,stepval,bs=mat->bs,bs2=baij->bs2; 658b24ad042SBarry Smith PetscInt h1,key,size=baij->ht_size,idx,*HT=baij->ht,Nbs=baij->Nbs; 659329f5518SBarry Smith PetscReal tmp; 6603eda8832SBarry Smith MatScalar **HD = baij->hd,*baij_a; 661f15d580aSBarry Smith const MatScalar *v_t,*value; 6622515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 663b24ad042SBarry Smith PetscInt total_ct=baij->ht_total_ct,insert_ct=baij->ht_insert_ct; 6644a15367fSSatish Balay #endif 6650bdbc534SSatish Balay 666d0a41580SSatish Balay PetscFunctionBegin; 667d0a41580SSatish Balay 6680bdbc534SSatish Balay if (roworiented) { 6690bdbc534SSatish Balay stepval = (n-1)*bs; 6700bdbc534SSatish Balay } else { 6710bdbc534SSatish Balay stepval = (m-1)*bs; 6720bdbc534SSatish Balay } 6730bdbc534SSatish Balay for (i=0; i<m; i++) { 6742515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 67577431f27SBarry Smith if (im[i] < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",im[i]); 67677431f27SBarry Smith if (im[i] >= baij->Mbs) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",im[i],baij->Mbs-1); 6770bdbc534SSatish Balay #endif 6780bdbc534SSatish Balay row = im[i]; 679187ce0cbSSatish Balay v_t = v + i*bs2; 680c2760754SSatish Balay if (row >= rstart && row < rend) { 6810bdbc534SSatish Balay for (j=0; j<n; j++) { 6820bdbc534SSatish Balay col = in[j]; 6830bdbc534SSatish Balay 6840bdbc534SSatish Balay /* Look up into the Hash Table */ 685c2760754SSatish Balay key = row*Nbs+col+1; 686c2760754SSatish Balay h1 = HASH(size,key,tmp); 6870bdbc534SSatish Balay 688c2760754SSatish Balay idx = h1; 6892515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 690187ce0cbSSatish Balay total_ct++; 691187ce0cbSSatish Balay insert_ct++; 692187ce0cbSSatish Balay if (HT[idx] != key) { 693187ce0cbSSatish Balay for (idx=h1; (idx<size) && (HT[idx]!=key); idx++,total_ct++); 694187ce0cbSSatish Balay if (idx == size) { 695187ce0cbSSatish Balay for (idx=0; (idx<h1) && (HT[idx]!=key); idx++,total_ct++); 696187ce0cbSSatish Balay if (idx == h1) { 69777431f27SBarry Smith SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"(%D,%D) has no entry in the hash table", row, col); 698187ce0cbSSatish Balay } 699187ce0cbSSatish Balay } 700187ce0cbSSatish Balay } 701187ce0cbSSatish Balay #else 702c2760754SSatish Balay if (HT[idx] != key) { 703c2760754SSatish Balay for (idx=h1; (idx<size) && (HT[idx]!=key); idx++); 704c2760754SSatish Balay if (idx == size) { 705c2760754SSatish Balay for (idx=0; (idx<h1) && (HT[idx]!=key); idx++); 706c2760754SSatish Balay if (idx == h1) { 70777431f27SBarry Smith SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"(%D,%D) has no entry in the hash table", row, col); 708c2760754SSatish Balay } 709c2760754SSatish Balay } 710c2760754SSatish Balay } 711187ce0cbSSatish Balay #endif 712c2760754SSatish Balay baij_a = HD[idx]; 7130bdbc534SSatish Balay if (roworiented) { 714c2760754SSatish Balay /*value = v + i*(stepval+bs)*bs + j*bs;*/ 715187ce0cbSSatish Balay /* value = v + (i*(stepval+bs)+j)*bs; */ 716187ce0cbSSatish Balay value = v_t; 717187ce0cbSSatish Balay v_t += bs; 718fef45726SSatish Balay if (addv == ADD_VALUES) { 719c2760754SSatish Balay for (ii=0; ii<bs; ii++,value+=stepval) { 720c2760754SSatish Balay for (jj=ii; jj<bs2; jj+=bs) { 721fef45726SSatish Balay baij_a[jj] += *value++; 722b4cc0f5aSSatish Balay } 723b4cc0f5aSSatish Balay } 724fef45726SSatish Balay } else { 725c2760754SSatish Balay for (ii=0; ii<bs; ii++,value+=stepval) { 726c2760754SSatish Balay for (jj=ii; jj<bs2; jj+=bs) { 727fef45726SSatish Balay baij_a[jj] = *value++; 728fef45726SSatish Balay } 729fef45726SSatish Balay } 730fef45726SSatish Balay } 7310bdbc534SSatish Balay } else { 7320bdbc534SSatish Balay value = v + j*(stepval+bs)*bs + i*bs; 733fef45726SSatish Balay if (addv == ADD_VALUES) { 734b4cc0f5aSSatish Balay for (ii=0; ii<bs; ii++,value+=stepval,baij_a+=bs) { 7350bdbc534SSatish Balay for (jj=0; jj<bs; jj++) { 736fef45726SSatish Balay baij_a[jj] += *value++; 737fef45726SSatish Balay } 738fef45726SSatish Balay } 739fef45726SSatish Balay } else { 740fef45726SSatish Balay for (ii=0; ii<bs; ii++,value+=stepval,baij_a+=bs) { 741fef45726SSatish Balay for (jj=0; jj<bs; jj++) { 742fef45726SSatish Balay baij_a[jj] = *value++; 743fef45726SSatish Balay } 744b4cc0f5aSSatish Balay } 7450bdbc534SSatish Balay } 7460bdbc534SSatish Balay } 7470bdbc534SSatish Balay } 7480bdbc534SSatish Balay } else { 7490bdbc534SSatish Balay if (!baij->donotstash) { 7500bdbc534SSatish Balay if (roworiented) { 7518798bf22SSatish Balay ierr = MatStashValuesRowBlocked_Private(&mat->bstash,im[i],n,in,v,m,n,i);CHKERRQ(ierr); 7520bdbc534SSatish Balay } else { 7538798bf22SSatish Balay ierr = MatStashValuesColBlocked_Private(&mat->bstash,im[i],n,in,v,m,n,i);CHKERRQ(ierr); 7540bdbc534SSatish Balay } 7550bdbc534SSatish Balay } 7560bdbc534SSatish Balay } 7570bdbc534SSatish Balay } 7582515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 759187ce0cbSSatish Balay baij->ht_total_ct = total_ct; 760187ce0cbSSatish Balay baij->ht_insert_ct = insert_ct; 761187ce0cbSSatish Balay #endif 7620bdbc534SSatish Balay PetscFunctionReturn(0); 7630bdbc534SSatish Balay } 764133cdb44SSatish Balay 7654a2ae208SSatish Balay #undef __FUNCT__ 7664a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_MPIBAIJ" 767b24ad042SBarry Smith PetscErrorCode MatGetValues_MPIBAIJ(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[]) 768d6de1c52SSatish Balay { 769d6de1c52SSatish Balay Mat_MPIBAIJ *baij = (Mat_MPIBAIJ*)mat->data; 7706849ba73SBarry Smith PetscErrorCode ierr; 771521d7252SBarry Smith PetscInt bs=mat->bs,i,j,bsrstart = baij->rstart*bs,bsrend = baij->rend*bs; 772b24ad042SBarry Smith PetscInt bscstart = baij->cstart*bs,bscend = baij->cend*bs,row,col,data; 773d6de1c52SSatish Balay 774133cdb44SSatish Balay PetscFunctionBegin; 775d6de1c52SSatish Balay for (i=0; i<m; i++) { 77677431f27SBarry Smith if (idxm[i] < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",idxm[i]); 77777431f27SBarry Smith if (idxm[i] >= mat->M) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",idxm[i],mat->M-1); 778d6de1c52SSatish Balay if (idxm[i] >= bsrstart && idxm[i] < bsrend) { 779d6de1c52SSatish Balay row = idxm[i] - bsrstart; 780d6de1c52SSatish Balay for (j=0; j<n; j++) { 78177431f27SBarry Smith if (idxn[j] < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",idxn[j]); 78277431f27SBarry Smith if (idxn[j] >= mat->N) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",idxn[j],mat->N-1); 783d6de1c52SSatish Balay if (idxn[j] >= bscstart && idxn[j] < bscend){ 784d6de1c52SSatish Balay col = idxn[j] - bscstart; 78598dd23e9SBarry Smith ierr = MatGetValues_SeqBAIJ(baij->A,1,&row,1,&col,v+i*n+j);CHKERRQ(ierr); 786d64ed03dSBarry Smith } else { 787905e6a2fSBarry Smith if (!baij->colmap) { 788905e6a2fSBarry Smith ierr = CreateColmap_MPIBAIJ_Private(mat);CHKERRQ(ierr); 789905e6a2fSBarry Smith } 790aa482453SBarry Smith #if defined (PETSC_USE_CTABLE) 7910f5bd95cSBarry Smith ierr = PetscTableFind(baij->colmap,idxn[j]/bs+1,&data);CHKERRQ(ierr); 792fa46199cSSatish Balay data --; 79348e59246SSatish Balay #else 79448e59246SSatish Balay data = baij->colmap[idxn[j]/bs]-1; 79548e59246SSatish Balay #endif 79648e59246SSatish Balay if((data < 0) || (baij->garray[data/bs] != idxn[j]/bs)) *(v+i*n+j) = 0.0; 797d9d09a02SSatish Balay else { 79848e59246SSatish Balay col = data + idxn[j]%bs; 79998dd23e9SBarry Smith ierr = MatGetValues_SeqBAIJ(baij->B,1,&row,1,&col,v+i*n+j);CHKERRQ(ierr); 800d6de1c52SSatish Balay } 801d6de1c52SSatish Balay } 802d6de1c52SSatish Balay } 803d64ed03dSBarry Smith } else { 80429bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"Only local values currently supported"); 805d6de1c52SSatish Balay } 806d6de1c52SSatish Balay } 8073a40ed3dSBarry Smith PetscFunctionReturn(0); 808d6de1c52SSatish Balay } 809d6de1c52SSatish Balay 8104a2ae208SSatish Balay #undef __FUNCT__ 8114a2ae208SSatish Balay #define __FUNCT__ "MatNorm_MPIBAIJ" 812dfbe8321SBarry Smith PetscErrorCode MatNorm_MPIBAIJ(Mat mat,NormType type,PetscReal *nrm) 813d6de1c52SSatish Balay { 814d6de1c52SSatish Balay Mat_MPIBAIJ *baij = (Mat_MPIBAIJ*)mat->data; 815d6de1c52SSatish Balay Mat_SeqBAIJ *amat = (Mat_SeqBAIJ*)baij->A->data,*bmat = (Mat_SeqBAIJ*)baij->B->data; 816dfbe8321SBarry Smith PetscErrorCode ierr; 817*8a62d963SHong Zhang PetscInt i,j,bs2=baij->bs2,bs=baij->A->bs,nz,row,col; 818329f5518SBarry Smith PetscReal sum = 0.0; 8193eda8832SBarry Smith MatScalar *v; 820d6de1c52SSatish Balay 821d64ed03dSBarry Smith PetscFunctionBegin; 822d6de1c52SSatish Balay if (baij->size == 1) { 823064f8208SBarry Smith ierr = MatNorm(baij->A,type,nrm);CHKERRQ(ierr); 824d6de1c52SSatish Balay } else { 825d6de1c52SSatish Balay if (type == NORM_FROBENIUS) { 826d6de1c52SSatish Balay v = amat->a; 827*8a62d963SHong Zhang nz = amat->nz*bs2; 828*8a62d963SHong Zhang for (i=0; i<nz; i++) { 829aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 830329f5518SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 831d6de1c52SSatish Balay #else 832d6de1c52SSatish Balay sum += (*v)*(*v); v++; 833d6de1c52SSatish Balay #endif 834d6de1c52SSatish Balay } 835d6de1c52SSatish Balay v = bmat->a; 836*8a62d963SHong Zhang nz = bmat->nz*bs2; 837*8a62d963SHong Zhang for (i=0; i<nz; i++) { 838aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 839329f5518SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 840d6de1c52SSatish Balay #else 841d6de1c52SSatish Balay sum += (*v)*(*v); v++; 842d6de1c52SSatish Balay #endif 843d6de1c52SSatish Balay } 844064f8208SBarry Smith ierr = MPI_Allreduce(&sum,nrm,1,MPIU_REAL,MPI_SUM,mat->comm);CHKERRQ(ierr); 845064f8208SBarry Smith *nrm = sqrt(*nrm); 846*8a62d963SHong Zhang } else if (type == NORM_1) { /* max column sum */ 847*8a62d963SHong Zhang PetscReal *tmp,*tmp2; 848*8a62d963SHong Zhang PetscInt *jj,*garray=baij->garray,cstart=baij->cstart; 849*8a62d963SHong Zhang ierr = PetscMalloc((2*mat->N+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr); 850*8a62d963SHong Zhang tmp2 = tmp + mat->N; 851*8a62d963SHong Zhang ierr = PetscMemzero(tmp,mat->N*sizeof(PetscReal));CHKERRQ(ierr); 852*8a62d963SHong Zhang v = amat->a; jj = amat->j; 853*8a62d963SHong Zhang for (i=0; i<amat->nz; i++) { 854*8a62d963SHong Zhang for (j=0; j<bs; j++){ 855*8a62d963SHong Zhang col = bs*(cstart + *jj) + j; /* column index */ 856*8a62d963SHong Zhang for (row=0; row<bs; row++){ 857*8a62d963SHong Zhang tmp[col] += PetscAbsScalar(*v); v++; 858*8a62d963SHong Zhang } 859*8a62d963SHong Zhang } 860*8a62d963SHong Zhang jj++; 861*8a62d963SHong Zhang } 862*8a62d963SHong Zhang v = bmat->a; jj = bmat->j; 863*8a62d963SHong Zhang for (i=0; i<bmat->nz; i++) { 864*8a62d963SHong Zhang for (j=0; j<bs; j++){ 865*8a62d963SHong Zhang col = bs*garray[*jj] + j; 866*8a62d963SHong Zhang for (row=0; row<bs; row++){ 867*8a62d963SHong Zhang tmp[col] += PetscAbsScalar(*v); v++; 868*8a62d963SHong Zhang } 869*8a62d963SHong Zhang } 870*8a62d963SHong Zhang jj++; 871*8a62d963SHong Zhang } 872*8a62d963SHong Zhang ierr = MPI_Allreduce(tmp,tmp2,mat->N,MPIU_REAL,MPI_SUM,mat->comm);CHKERRQ(ierr); 873*8a62d963SHong Zhang *nrm = 0.0; 874*8a62d963SHong Zhang for (j=0; j<mat->N; j++) { 875*8a62d963SHong Zhang if (tmp2[j] > *nrm) *nrm = tmp2[j]; 876*8a62d963SHong Zhang } 877*8a62d963SHong Zhang ierr = PetscFree(tmp);CHKERRQ(ierr); 878*8a62d963SHong Zhang } else if (type == NORM_INFINITY) { /* max row sum */ 879*8a62d963SHong Zhang PetscReal sums[bs]; 880*8a62d963SHong Zhang sum = 0.0; 881*8a62d963SHong Zhang for (j=0; j<amat->mbs; j++) { 882*8a62d963SHong Zhang for (row=0; row<bs; row++) sums[row] = 0.0; 883*8a62d963SHong Zhang v = amat->a + bs2*amat->i[j]; 884*8a62d963SHong Zhang nz = amat->i[j+1]-amat->i[j]; 885*8a62d963SHong Zhang for (i=0; i<nz; i++) { 886*8a62d963SHong Zhang for (col=0; col<bs; col++){ 887*8a62d963SHong Zhang for (row=0; row<bs; row++){ 888*8a62d963SHong Zhang sums[row] += PetscAbsScalar(*v); v++; 889*8a62d963SHong Zhang } 890*8a62d963SHong Zhang } 891*8a62d963SHong Zhang } 892*8a62d963SHong Zhang v = bmat->a + bs2*bmat->i[j]; 893*8a62d963SHong Zhang nz = bmat->i[j+1]-bmat->i[j]; 894*8a62d963SHong Zhang for (i=0; i<nz; i++) { 895*8a62d963SHong Zhang for (col=0; col<bs; col++){ 896*8a62d963SHong Zhang for (row=0; row<bs; row++){ 897*8a62d963SHong Zhang sums[row] += PetscAbsScalar(*v); v++; 898*8a62d963SHong Zhang } 899*8a62d963SHong Zhang } 900*8a62d963SHong Zhang } 901*8a62d963SHong Zhang for (row=0; row<bs; row++){ 902*8a62d963SHong Zhang if (sums[row] > sum) sum = sums[row]; 903*8a62d963SHong Zhang } 904*8a62d963SHong Zhang } 905*8a62d963SHong Zhang ierr = MPI_Allreduce(&sum,nrm,1,MPIU_REAL,MPI_MAX,mat->comm);CHKERRQ(ierr); 906d64ed03dSBarry Smith } else { 90729bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"No support for this norm yet"); 908d6de1c52SSatish Balay } 909d64ed03dSBarry Smith } 9103a40ed3dSBarry Smith PetscFunctionReturn(0); 911d6de1c52SSatish Balay } 91257b952d6SSatish Balay 913fef45726SSatish Balay /* 914fef45726SSatish Balay Creates the hash table, and sets the table 915fef45726SSatish Balay This table is created only once. 916fef45726SSatish Balay If new entried need to be added to the matrix 917fef45726SSatish Balay then the hash table has to be destroyed and 918fef45726SSatish Balay recreated. 919fef45726SSatish Balay */ 9204a2ae208SSatish Balay #undef __FUNCT__ 9214a2ae208SSatish Balay #define __FUNCT__ "MatCreateHashTable_MPIBAIJ_Private" 922dfbe8321SBarry Smith PetscErrorCode MatCreateHashTable_MPIBAIJ_Private(Mat mat,PetscReal factor) 923596b8d2eSBarry Smith { 924596b8d2eSBarry Smith Mat_MPIBAIJ *baij = (Mat_MPIBAIJ*)mat->data; 925596b8d2eSBarry Smith Mat A = baij->A,B=baij->B; 926596b8d2eSBarry Smith Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data,*b=(Mat_SeqBAIJ *)B->data; 927b24ad042SBarry Smith PetscInt i,j,k,nz=a->nz+b->nz,h1,*ai=a->i,*aj=a->j,*bi=b->i,*bj=b->j; 9286849ba73SBarry Smith PetscErrorCode ierr; 929b24ad042SBarry Smith PetscInt size,bs2=baij->bs2,rstart=baij->rstart; 930b24ad042SBarry Smith PetscInt cstart=baij->cstart,*garray=baij->garray,row,col,Nbs=baij->Nbs; 931b24ad042SBarry Smith PetscInt *HT,key; 9323eda8832SBarry Smith MatScalar **HD; 933329f5518SBarry Smith PetscReal tmp; 9342515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 935b24ad042SBarry Smith PetscInt ct=0,max=0; 9364a15367fSSatish Balay #endif 937fef45726SSatish Balay 938d64ed03dSBarry Smith PetscFunctionBegin; 939b24ad042SBarry Smith baij->ht_size=(PetscInt)(factor*nz); 9400bdbc534SSatish Balay size = baij->ht_size; 941fef45726SSatish Balay 9420bdbc534SSatish Balay if (baij->ht) { 9430bdbc534SSatish Balay PetscFunctionReturn(0); 944596b8d2eSBarry Smith } 9450bdbc534SSatish Balay 946fef45726SSatish Balay /* Allocate Memory for Hash Table */ 947b24ad042SBarry Smith ierr = PetscMalloc((size)*(sizeof(PetscInt)+sizeof(MatScalar*))+1,&baij->hd);CHKERRQ(ierr); 948b24ad042SBarry Smith baij->ht = (PetscInt*)(baij->hd + size); 949b9e4cc15SSatish Balay HD = baij->hd; 950a07cd24cSSatish Balay HT = baij->ht; 951b9e4cc15SSatish Balay 952b9e4cc15SSatish Balay 953b24ad042SBarry Smith ierr = PetscMemzero(HD,size*(sizeof(PetscInt)+sizeof(PetscScalar*)));CHKERRQ(ierr); 9540bdbc534SSatish Balay 955596b8d2eSBarry Smith 956596b8d2eSBarry Smith /* Loop Over A */ 9570bdbc534SSatish Balay for (i=0; i<a->mbs; i++) { 958596b8d2eSBarry Smith for (j=ai[i]; j<ai[i+1]; j++) { 9590bdbc534SSatish Balay row = i+rstart; 9600bdbc534SSatish Balay col = aj[j]+cstart; 961596b8d2eSBarry Smith 962187ce0cbSSatish Balay key = row*Nbs + col + 1; 963c2760754SSatish Balay h1 = HASH(size,key,tmp); 9640bdbc534SSatish Balay for (k=0; k<size; k++){ 965958c9bccSBarry Smith if (!HT[(h1+k)%size]) { 9660bdbc534SSatish Balay HT[(h1+k)%size] = key; 9670bdbc534SSatish Balay HD[(h1+k)%size] = a->a + j*bs2; 968596b8d2eSBarry Smith break; 9692515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 970187ce0cbSSatish Balay } else { 971187ce0cbSSatish Balay ct++; 972187ce0cbSSatish Balay #endif 973596b8d2eSBarry Smith } 974187ce0cbSSatish Balay } 9752515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 976187ce0cbSSatish Balay if (k> max) max = k; 977187ce0cbSSatish Balay #endif 978596b8d2eSBarry Smith } 979596b8d2eSBarry Smith } 980596b8d2eSBarry Smith /* Loop Over B */ 9810bdbc534SSatish Balay for (i=0; i<b->mbs; i++) { 982596b8d2eSBarry Smith for (j=bi[i]; j<bi[i+1]; j++) { 9830bdbc534SSatish Balay row = i+rstart; 9840bdbc534SSatish Balay col = garray[bj[j]]; 985187ce0cbSSatish Balay key = row*Nbs + col + 1; 986c2760754SSatish Balay h1 = HASH(size,key,tmp); 9870bdbc534SSatish Balay for (k=0; k<size; k++){ 988958c9bccSBarry Smith if (!HT[(h1+k)%size]) { 9890bdbc534SSatish Balay HT[(h1+k)%size] = key; 9900bdbc534SSatish Balay HD[(h1+k)%size] = b->a + j*bs2; 991596b8d2eSBarry Smith break; 9922515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 993187ce0cbSSatish Balay } else { 994187ce0cbSSatish Balay ct++; 995187ce0cbSSatish Balay #endif 996596b8d2eSBarry Smith } 997187ce0cbSSatish Balay } 9982515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 999187ce0cbSSatish Balay if (k> max) max = k; 1000187ce0cbSSatish Balay #endif 1001596b8d2eSBarry Smith } 1002596b8d2eSBarry Smith } 1003596b8d2eSBarry Smith 1004596b8d2eSBarry Smith /* Print Summary */ 10052515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 1006c38d4ed2SBarry Smith for (i=0,j=0; i<size; i++) { 1007596b8d2eSBarry Smith if (HT[i]) {j++;} 1008c38d4ed2SBarry Smith } 100963ba0a88SBarry Smith ierr = PetscLogInfo((0,"MatCreateHashTable_MPIBAIJ_Private: Average Search = %5.2f,max search = %D\n",(!j)? 0.0:((PetscReal)(ct+j))/j,max));CHKERRQ(ierr); 1010187ce0cbSSatish Balay #endif 10113a40ed3dSBarry Smith PetscFunctionReturn(0); 1012596b8d2eSBarry Smith } 101357b952d6SSatish Balay 10144a2ae208SSatish Balay #undef __FUNCT__ 10154a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyBegin_MPIBAIJ" 1016dfbe8321SBarry Smith PetscErrorCode MatAssemblyBegin_MPIBAIJ(Mat mat,MatAssemblyType mode) 1017bbb85fb3SSatish Balay { 1018bbb85fb3SSatish Balay Mat_MPIBAIJ *baij = (Mat_MPIBAIJ*)mat->data; 1019dfbe8321SBarry Smith PetscErrorCode ierr; 1020b24ad042SBarry Smith PetscInt nstash,reallocs; 1021bbb85fb3SSatish Balay InsertMode addv; 1022bbb85fb3SSatish Balay 1023bbb85fb3SSatish Balay PetscFunctionBegin; 1024bbb85fb3SSatish Balay if (baij->donotstash) { 1025bbb85fb3SSatish Balay PetscFunctionReturn(0); 1026bbb85fb3SSatish Balay } 1027bbb85fb3SSatish Balay 1028bbb85fb3SSatish Balay /* make sure all processors are either in INSERTMODE or ADDMODE */ 1029bbb85fb3SSatish Balay ierr = MPI_Allreduce(&mat->insertmode,&addv,1,MPI_INT,MPI_BOR,mat->comm);CHKERRQ(ierr); 1030bbb85fb3SSatish Balay if (addv == (ADD_VALUES|INSERT_VALUES)) { 103129bbc08cSBarry Smith SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Some processors inserted others added"); 1032bbb85fb3SSatish Balay } 1033bbb85fb3SSatish Balay mat->insertmode = addv; /* in case this processor had no cache */ 1034bbb85fb3SSatish Balay 10358798bf22SSatish Balay ierr = MatStashScatterBegin_Private(&mat->stash,baij->rowners_bs);CHKERRQ(ierr); 10368798bf22SSatish Balay ierr = MatStashScatterBegin_Private(&mat->bstash,baij->rowners);CHKERRQ(ierr); 10378798bf22SSatish Balay ierr = MatStashGetInfo_Private(&mat->stash,&nstash,&reallocs);CHKERRQ(ierr); 103863ba0a88SBarry Smith ierr = PetscLogInfo((0,"MatAssemblyBegin_MPIBAIJ:Stash has %D entries,uses %D mallocs.\n",nstash,reallocs));CHKERRQ(ierr); 103946680499SSatish Balay ierr = MatStashGetInfo_Private(&mat->bstash,&nstash,&reallocs);CHKERRQ(ierr); 104063ba0a88SBarry Smith ierr = PetscLogInfo((0,"MatAssemblyBegin_MPIBAIJ:Block-Stash has %D entries, uses %D mallocs.\n",nstash,reallocs));CHKERRQ(ierr); 1041bbb85fb3SSatish Balay PetscFunctionReturn(0); 1042bbb85fb3SSatish Balay } 1043bbb85fb3SSatish Balay 10444a2ae208SSatish Balay #undef __FUNCT__ 10454a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_MPIBAIJ" 1046dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_MPIBAIJ(Mat mat,MatAssemblyType mode) 1047bbb85fb3SSatish Balay { 1048bbb85fb3SSatish Balay Mat_MPIBAIJ *baij=(Mat_MPIBAIJ*)mat->data; 1049a2d1c673SSatish Balay Mat_SeqBAIJ *a=(Mat_SeqBAIJ*)baij->A->data,*b=(Mat_SeqBAIJ*)baij->B->data; 10506849ba73SBarry Smith PetscErrorCode ierr; 1051b24ad042SBarry Smith PetscInt i,j,rstart,ncols,flg,bs2=baij->bs2; 1052b24ad042SBarry Smith PetscInt *row,*col,other_disassembled; 10537c922b88SBarry Smith PetscTruth r1,r2,r3; 10543eda8832SBarry Smith MatScalar *val; 1055bbb85fb3SSatish Balay InsertMode addv = mat->insertmode; 1056b24ad042SBarry Smith PetscMPIInt n; 1057bbb85fb3SSatish Balay 1058bbb85fb3SSatish Balay PetscFunctionBegin; 1059bbb85fb3SSatish Balay if (!baij->donotstash) { 1060a2d1c673SSatish Balay while (1) { 10618798bf22SSatish Balay ierr = MatStashScatterGetMesg_Private(&mat->stash,&n,&row,&col,&val,&flg);CHKERRQ(ierr); 1062a2d1c673SSatish Balay if (!flg) break; 1063a2d1c673SSatish Balay 1064bbb85fb3SSatish Balay for (i=0; i<n;) { 1065bbb85fb3SSatish Balay /* Now identify the consecutive vals belonging to the same row */ 1066bbb85fb3SSatish Balay for (j=i,rstart=row[j]; j<n; j++) { if (row[j] != rstart) break; } 1067bbb85fb3SSatish Balay if (j < n) ncols = j-i; 1068bbb85fb3SSatish Balay else ncols = n-i; 1069bbb85fb3SSatish Balay /* Now assemble all these values with a single function call */ 107093fea6afSBarry Smith ierr = MatSetValues_MPIBAIJ_MatScalar(mat,1,row+i,ncols,col+i,val+i,addv);CHKERRQ(ierr); 1071bbb85fb3SSatish Balay i = j; 1072bbb85fb3SSatish Balay } 1073bbb85fb3SSatish Balay } 10748798bf22SSatish Balay ierr = MatStashScatterEnd_Private(&mat->stash);CHKERRQ(ierr); 1075a2d1c673SSatish Balay /* Now process the block-stash. Since the values are stashed column-oriented, 1076a2d1c673SSatish Balay set the roworiented flag to column oriented, and after MatSetValues() 1077a2d1c673SSatish Balay restore the original flags */ 1078a2d1c673SSatish Balay r1 = baij->roworiented; 1079a2d1c673SSatish Balay r2 = a->roworiented; 1080a2d1c673SSatish Balay r3 = b->roworiented; 10817c922b88SBarry Smith baij->roworiented = PETSC_FALSE; 10827c922b88SBarry Smith a->roworiented = PETSC_FALSE; 10837c922b88SBarry Smith b->roworiented = PETSC_FALSE; 1084a2d1c673SSatish Balay while (1) { 10858798bf22SSatish Balay ierr = MatStashScatterGetMesg_Private(&mat->bstash,&n,&row,&col,&val,&flg);CHKERRQ(ierr); 1086a2d1c673SSatish Balay if (!flg) break; 1087a2d1c673SSatish Balay 1088a2d1c673SSatish Balay for (i=0; i<n;) { 1089a2d1c673SSatish Balay /* Now identify the consecutive vals belonging to the same row */ 1090a2d1c673SSatish Balay for (j=i,rstart=row[j]; j<n; j++) { if (row[j] != rstart) break; } 1091a2d1c673SSatish Balay if (j < n) ncols = j-i; 1092a2d1c673SSatish Balay else ncols = n-i; 109393fea6afSBarry Smith ierr = MatSetValuesBlocked_MPIBAIJ_MatScalar(mat,1,row+i,ncols,col+i,val+i*bs2,addv);CHKERRQ(ierr); 1094a2d1c673SSatish Balay i = j; 1095a2d1c673SSatish Balay } 1096a2d1c673SSatish Balay } 10978798bf22SSatish Balay ierr = MatStashScatterEnd_Private(&mat->bstash);CHKERRQ(ierr); 1098a2d1c673SSatish Balay baij->roworiented = r1; 1099a2d1c673SSatish Balay a->roworiented = r2; 1100a2d1c673SSatish Balay b->roworiented = r3; 1101bbb85fb3SSatish Balay } 1102bbb85fb3SSatish Balay 1103bbb85fb3SSatish Balay ierr = MatAssemblyBegin(baij->A,mode);CHKERRQ(ierr); 1104bbb85fb3SSatish Balay ierr = MatAssemblyEnd(baij->A,mode);CHKERRQ(ierr); 1105bbb85fb3SSatish Balay 1106bbb85fb3SSatish Balay /* determine if any processor has disassembled, if so we must 1107bbb85fb3SSatish Balay also disassemble ourselfs, in order that we may reassemble. */ 1108bbb85fb3SSatish Balay /* 1109bbb85fb3SSatish Balay if nonzero structure of submatrix B cannot change then we know that 1110bbb85fb3SSatish Balay no processor disassembled thus we can skip this stuff 1111bbb85fb3SSatish Balay */ 1112bbb85fb3SSatish Balay if (!((Mat_SeqBAIJ*)baij->B->data)->nonew) { 1113bbb85fb3SSatish Balay ierr = MPI_Allreduce(&mat->was_assembled,&other_disassembled,1,MPI_INT,MPI_PROD,mat->comm);CHKERRQ(ierr); 1114bbb85fb3SSatish Balay if (mat->was_assembled && !other_disassembled) { 1115bbb85fb3SSatish Balay ierr = DisAssemble_MPIBAIJ(mat);CHKERRQ(ierr); 1116bbb85fb3SSatish Balay } 1117bbb85fb3SSatish Balay } 1118bbb85fb3SSatish Balay 1119bbb85fb3SSatish Balay if (!mat->was_assembled && mode == MAT_FINAL_ASSEMBLY) { 1120bbb85fb3SSatish Balay ierr = MatSetUpMultiply_MPIBAIJ(mat);CHKERRQ(ierr); 1121bbb85fb3SSatish Balay } 112273e7a558SHong Zhang b->compressedrow.use = PETSC_TRUE; 1123bbb85fb3SSatish Balay ierr = MatAssemblyBegin(baij->B,mode);CHKERRQ(ierr); 1124bbb85fb3SSatish Balay ierr = MatAssemblyEnd(baij->B,mode);CHKERRQ(ierr); 1125bbb85fb3SSatish Balay 11262515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 1127bbb85fb3SSatish Balay if (baij->ht && mode== MAT_FINAL_ASSEMBLY) { 112863ba0a88SBarry Smith ierr = PetscLogInfo((0,"MatAssemblyEnd_MPIBAIJ:Average Hash Table Search in MatSetValues = %5.2f\n",((PetscReal)baij->ht_total_ct)/baij->ht_insert_ct));CHKERRQ(ierr); 1129bbb85fb3SSatish Balay baij->ht_total_ct = 0; 1130bbb85fb3SSatish Balay baij->ht_insert_ct = 0; 1131bbb85fb3SSatish Balay } 1132bbb85fb3SSatish Balay #endif 1133bbb85fb3SSatish Balay if (baij->ht_flag && !baij->ht && mode == MAT_FINAL_ASSEMBLY) { 1134bbb85fb3SSatish Balay ierr = MatCreateHashTable_MPIBAIJ_Private(mat,baij->ht_fact);CHKERRQ(ierr); 1135bbb85fb3SSatish Balay mat->ops->setvalues = MatSetValues_MPIBAIJ_HT; 1136bbb85fb3SSatish Balay mat->ops->setvaluesblocked = MatSetValuesBlocked_MPIBAIJ_HT; 1137bbb85fb3SSatish Balay } 1138bbb85fb3SSatish Balay 1139606d414cSSatish Balay if (baij->rowvalues) { 1140606d414cSSatish Balay ierr = PetscFree(baij->rowvalues);CHKERRQ(ierr); 1141606d414cSSatish Balay baij->rowvalues = 0; 1142606d414cSSatish Balay } 1143bbb85fb3SSatish Balay PetscFunctionReturn(0); 1144bbb85fb3SSatish Balay } 114557b952d6SSatish Balay 11464a2ae208SSatish Balay #undef __FUNCT__ 11474a2ae208SSatish Balay #define __FUNCT__ "MatView_MPIBAIJ_ASCIIorDraworSocket" 11486849ba73SBarry Smith static PetscErrorCode MatView_MPIBAIJ_ASCIIorDraworSocket(Mat mat,PetscViewer viewer) 114957b952d6SSatish Balay { 115057b952d6SSatish Balay Mat_MPIBAIJ *baij = (Mat_MPIBAIJ*)mat->data; 1151dfbe8321SBarry Smith PetscErrorCode ierr; 1152b24ad042SBarry Smith PetscMPIInt size = baij->size,rank = baij->rank; 1153521d7252SBarry Smith PetscInt bs = mat->bs; 115432077d6dSBarry Smith PetscTruth iascii,isdraw; 1155b0a32e0cSBarry Smith PetscViewer sviewer; 1156f3ef73ceSBarry Smith PetscViewerFormat format; 115757b952d6SSatish Balay 1158d64ed03dSBarry Smith PetscFunctionBegin; 1159f81bd7ccSHong Zhang /* printf(" MatView_MPIBAIJ_ASCIIorDraworSocket is called ...\n"); */ 116032077d6dSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 1161fb9695e5SSatish Balay ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr); 116232077d6dSBarry Smith if (iascii) { 1163b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1164456192e2SBarry Smith if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 11654e220ebcSLois Curfman McInnes MatInfo info; 1166d132466eSBarry Smith ierr = MPI_Comm_rank(mat->comm,&rank);CHKERRQ(ierr); 1167d41123aaSBarry Smith ierr = MatGetInfo(mat,MAT_LOCAL,&info);CHKERRQ(ierr); 116877431f27SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d] Local rows %D nz %D nz alloced %D bs %D mem %D\n", 116977431f27SBarry Smith rank,mat->m,(PetscInt)info.nz_used*bs,(PetscInt)info.nz_allocated*bs, 1170521d7252SBarry Smith mat->bs,(PetscInt)info.memory);CHKERRQ(ierr); 1171d132466eSBarry Smith ierr = MatGetInfo(baij->A,MAT_LOCAL,&info);CHKERRQ(ierr); 117277431f27SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d] on-diagonal part: nz %D \n",rank,(PetscInt)info.nz_used*bs);CHKERRQ(ierr); 1173d132466eSBarry Smith ierr = MatGetInfo(baij->B,MAT_LOCAL,&info);CHKERRQ(ierr); 117477431f27SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d] off-diagonal part: nz %D \n",rank,(PetscInt)info.nz_used*bs);CHKERRQ(ierr); 1175b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 117657b952d6SSatish Balay ierr = VecScatterView(baij->Mvctx,viewer);CHKERRQ(ierr); 11773a40ed3dSBarry Smith PetscFunctionReturn(0); 1178fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_INFO) { 117977431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," block size is %D\n",bs);CHKERRQ(ierr); 11803a40ed3dSBarry Smith PetscFunctionReturn(0); 118104929863SHong Zhang } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) { 118204929863SHong Zhang PetscFunctionReturn(0); 118357b952d6SSatish Balay } 118457b952d6SSatish Balay } 118557b952d6SSatish Balay 11860f5bd95cSBarry Smith if (isdraw) { 1187b0a32e0cSBarry Smith PetscDraw draw; 118857b952d6SSatish Balay PetscTruth isnull; 1189b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 1190b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0); 119157b952d6SSatish Balay } 119257b952d6SSatish Balay 119357b952d6SSatish Balay if (size == 1) { 1194873048abSBarry Smith ierr = PetscObjectSetName((PetscObject)baij->A,mat->name);CHKERRQ(ierr); 119557b952d6SSatish Balay ierr = MatView(baij->A,viewer);CHKERRQ(ierr); 1196d64ed03dSBarry Smith } else { 119757b952d6SSatish Balay /* assemble the entire matrix onto first processor. */ 119857b952d6SSatish Balay Mat A; 119957b952d6SSatish Balay Mat_SeqBAIJ *Aloc; 1200b24ad042SBarry Smith PetscInt M = mat->M,N = mat->N,*ai,*aj,col,i,j,k,*rvals,mbs = baij->mbs; 12013eda8832SBarry Smith MatScalar *a; 120257b952d6SSatish Balay 1203f204ca49SKris Buschelman /* Here we are creating a temporary matrix, so will assume MPIBAIJ is acceptable */ 1204f204ca49SKris Buschelman /* Perhaps this should be the type of mat? */ 120557b952d6SSatish Balay if (!rank) { 1206f204ca49SKris Buschelman ierr = MatCreate(mat->comm,M,N,M,N,&A);CHKERRQ(ierr); 1207d64ed03dSBarry Smith } else { 1208f204ca49SKris Buschelman ierr = MatCreate(mat->comm,0,0,M,N,&A);CHKERRQ(ierr); 120957b952d6SSatish Balay } 1210f204ca49SKris Buschelman ierr = MatSetType(A,MATMPIBAIJ);CHKERRQ(ierr); 1211521d7252SBarry Smith ierr = MatMPIBAIJSetPreallocation(A,mat->bs,0,PETSC_NULL,0,PETSC_NULL);CHKERRQ(ierr); 121252e6d16bSBarry Smith ierr = PetscLogObjectParent(mat,A);CHKERRQ(ierr); 121357b952d6SSatish Balay 121457b952d6SSatish Balay /* copy over the A part */ 121557b952d6SSatish Balay Aloc = (Mat_SeqBAIJ*)baij->A->data; 121657b952d6SSatish Balay ai = Aloc->i; aj = Aloc->j; a = Aloc->a; 1217b24ad042SBarry Smith ierr = PetscMalloc(bs*sizeof(PetscInt),&rvals);CHKERRQ(ierr); 121857b952d6SSatish Balay 121957b952d6SSatish Balay for (i=0; i<mbs; i++) { 122057b952d6SSatish Balay rvals[0] = bs*(baij->rstart + i); 122157b952d6SSatish Balay for (j=1; j<bs; j++) { rvals[j] = rvals[j-1] + 1; } 122257b952d6SSatish Balay for (j=ai[i]; j<ai[i+1]; j++) { 122357b952d6SSatish Balay col = (baij->cstart+aj[j])*bs; 122457b952d6SSatish Balay for (k=0; k<bs; k++) { 122593fea6afSBarry Smith ierr = MatSetValues_MPIBAIJ_MatScalar(A,bs,rvals,1,&col,a,INSERT_VALUES);CHKERRQ(ierr); 1226cee3aa6bSSatish Balay col++; a += bs; 122757b952d6SSatish Balay } 122857b952d6SSatish Balay } 122957b952d6SSatish Balay } 123057b952d6SSatish Balay /* copy over the B part */ 123157b952d6SSatish Balay Aloc = (Mat_SeqBAIJ*)baij->B->data; 123257b952d6SSatish Balay ai = Aloc->i; aj = Aloc->j; a = Aloc->a; 123357b952d6SSatish Balay for (i=0; i<mbs; i++) { 123457b952d6SSatish Balay rvals[0] = bs*(baij->rstart + i); 123557b952d6SSatish Balay for (j=1; j<bs; j++) { rvals[j] = rvals[j-1] + 1; } 123657b952d6SSatish Balay for (j=ai[i]; j<ai[i+1]; j++) { 123757b952d6SSatish Balay col = baij->garray[aj[j]]*bs; 123857b952d6SSatish Balay for (k=0; k<bs; k++) { 123993fea6afSBarry Smith ierr = MatSetValues_MPIBAIJ_MatScalar(A,bs,rvals,1,&col,a,INSERT_VALUES);CHKERRQ(ierr); 1240cee3aa6bSSatish Balay col++; a += bs; 124157b952d6SSatish Balay } 124257b952d6SSatish Balay } 124357b952d6SSatish Balay } 1244606d414cSSatish Balay ierr = PetscFree(rvals);CHKERRQ(ierr); 12456d4a8577SBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 12466d4a8577SBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 124755843e3eSBarry Smith /* 124855843e3eSBarry Smith Everyone has to call to draw the matrix since the graphics waits are 1249b0a32e0cSBarry Smith synchronized across all processors that share the PetscDraw object 125055843e3eSBarry Smith */ 1251b0a32e0cSBarry Smith ierr = PetscViewerGetSingleton(viewer,&sviewer);CHKERRQ(ierr); 1252f14a1c24SBarry Smith if (!rank) { 1253e36acaf3SBarry Smith ierr = PetscObjectSetName((PetscObject)((Mat_MPIBAIJ*)(A->data))->A,mat->name);CHKERRQ(ierr); 12546831982aSBarry Smith ierr = MatView(((Mat_MPIBAIJ*)(A->data))->A,sviewer);CHKERRQ(ierr); 125557b952d6SSatish Balay } 1256b0a32e0cSBarry Smith ierr = PetscViewerRestoreSingleton(viewer,&sviewer);CHKERRQ(ierr); 125757b952d6SSatish Balay ierr = MatDestroy(A);CHKERRQ(ierr); 125857b952d6SSatish Balay } 12593a40ed3dSBarry Smith PetscFunctionReturn(0); 126057b952d6SSatish Balay } 126157b952d6SSatish Balay 12624a2ae208SSatish Balay #undef __FUNCT__ 12634a2ae208SSatish Balay #define __FUNCT__ "MatView_MPIBAIJ" 1264dfbe8321SBarry Smith PetscErrorCode MatView_MPIBAIJ(Mat mat,PetscViewer viewer) 126557b952d6SSatish Balay { 1266dfbe8321SBarry Smith PetscErrorCode ierr; 126732077d6dSBarry Smith PetscTruth iascii,isdraw,issocket,isbinary; 126857b952d6SSatish Balay 1269d64ed03dSBarry Smith PetscFunctionBegin; 127032077d6dSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 1271fb9695e5SSatish Balay ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr); 1272b0a32e0cSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr); 1273fb9695e5SSatish Balay ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr); 127432077d6dSBarry Smith if (iascii || isdraw || issocket || isbinary) { 12757b2a1423SBarry Smith ierr = MatView_MPIBAIJ_ASCIIorDraworSocket(mat,viewer);CHKERRQ(ierr); 12765cd90555SBarry Smith } else { 127779a5c55eSBarry Smith SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported by MPIBAIJ matrices",((PetscObject)viewer)->type_name); 127857b952d6SSatish Balay } 12793a40ed3dSBarry Smith PetscFunctionReturn(0); 128057b952d6SSatish Balay } 128157b952d6SSatish Balay 12824a2ae208SSatish Balay #undef __FUNCT__ 12834a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_MPIBAIJ" 1284dfbe8321SBarry Smith PetscErrorCode MatDestroy_MPIBAIJ(Mat mat) 128579bdfe76SSatish Balay { 128679bdfe76SSatish Balay Mat_MPIBAIJ *baij = (Mat_MPIBAIJ*)mat->data; 1287dfbe8321SBarry Smith PetscErrorCode ierr; 128879bdfe76SSatish Balay 1289d64ed03dSBarry Smith PetscFunctionBegin; 1290aa482453SBarry Smith #if defined(PETSC_USE_LOG) 129177431f27SBarry Smith PetscLogObjectState((PetscObject)mat,"Rows=%D,Cols=%D",mat->M,mat->N); 129279bdfe76SSatish Balay #endif 12938798bf22SSatish Balay ierr = MatStashDestroy_Private(&mat->stash);CHKERRQ(ierr); 12948798bf22SSatish Balay ierr = MatStashDestroy_Private(&mat->bstash);CHKERRQ(ierr); 1295606d414cSSatish Balay ierr = PetscFree(baij->rowners);CHKERRQ(ierr); 129679bdfe76SSatish Balay ierr = MatDestroy(baij->A);CHKERRQ(ierr); 129779bdfe76SSatish Balay ierr = MatDestroy(baij->B);CHKERRQ(ierr); 1298aa482453SBarry Smith #if defined (PETSC_USE_CTABLE) 12990f5bd95cSBarry Smith if (baij->colmap) {ierr = PetscTableDelete(baij->colmap);CHKERRQ(ierr);} 130048e59246SSatish Balay #else 1301606d414cSSatish Balay if (baij->colmap) {ierr = PetscFree(baij->colmap);CHKERRQ(ierr);} 130248e59246SSatish Balay #endif 1303606d414cSSatish Balay if (baij->garray) {ierr = PetscFree(baij->garray);CHKERRQ(ierr);} 1304606d414cSSatish Balay if (baij->lvec) {ierr = VecDestroy(baij->lvec);CHKERRQ(ierr);} 1305606d414cSSatish Balay if (baij->Mvctx) {ierr = VecScatterDestroy(baij->Mvctx);CHKERRQ(ierr);} 1306606d414cSSatish Balay if (baij->rowvalues) {ierr = PetscFree(baij->rowvalues);CHKERRQ(ierr);} 1307606d414cSSatish Balay if (baij->barray) {ierr = PetscFree(baij->barray);CHKERRQ(ierr);} 1308606d414cSSatish Balay if (baij->hd) {ierr = PetscFree(baij->hd);CHKERRQ(ierr);} 13096fa18ffdSBarry Smith #if defined(PETSC_USE_MAT_SINGLE) 13106fa18ffdSBarry Smith if (baij->setvaluescopy) {ierr = PetscFree(baij->setvaluescopy);CHKERRQ(ierr);} 13116fa18ffdSBarry Smith #endif 1312606d414cSSatish Balay ierr = PetscFree(baij);CHKERRQ(ierr); 1313901853e0SKris Buschelman 1314901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)mat,"MatStoreValues_C","",PETSC_NULL);CHKERRQ(ierr); 1315901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)mat,"MatRetrieveValues_C","",PETSC_NULL);CHKERRQ(ierr); 1316901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)mat,"MatGetDiagonalBlock_C","",PETSC_NULL);CHKERRQ(ierr); 1317901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMPIBAIJSetPreallocation_C","",PETSC_NULL);CHKERRQ(ierr); 1318aac34f13SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMPIBAIJSetPreallocationCSR_C","",PETSC_NULL);CHKERRQ(ierr); 1319901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDiagonalScaleLocal_C","",PETSC_NULL);CHKERRQ(ierr); 1320901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)mat,"MatSetHashTableFactor_C","",PETSC_NULL);CHKERRQ(ierr); 13213a40ed3dSBarry Smith PetscFunctionReturn(0); 132279bdfe76SSatish Balay } 132379bdfe76SSatish Balay 13244a2ae208SSatish Balay #undef __FUNCT__ 13254a2ae208SSatish Balay #define __FUNCT__ "MatMult_MPIBAIJ" 1326dfbe8321SBarry Smith PetscErrorCode MatMult_MPIBAIJ(Mat A,Vec xx,Vec yy) 1327cee3aa6bSSatish Balay { 1328cee3aa6bSSatish Balay Mat_MPIBAIJ *a = (Mat_MPIBAIJ*)A->data; 1329dfbe8321SBarry Smith PetscErrorCode ierr; 1330b24ad042SBarry Smith PetscInt nt; 1331cee3aa6bSSatish Balay 1332d64ed03dSBarry Smith PetscFunctionBegin; 1333e1311b90SBarry Smith ierr = VecGetLocalSize(xx,&nt);CHKERRQ(ierr); 1334273d9f13SBarry Smith if (nt != A->n) { 133529bbc08cSBarry Smith SETERRQ(PETSC_ERR_ARG_SIZ,"Incompatible partition of A and xx"); 133647b4a8eaSLois Curfman McInnes } 1337e1311b90SBarry Smith ierr = VecGetLocalSize(yy,&nt);CHKERRQ(ierr); 1338273d9f13SBarry Smith if (nt != A->m) { 133929bbc08cSBarry Smith SETERRQ(PETSC_ERR_ARG_SIZ,"Incompatible parition of A and yy"); 134047b4a8eaSLois Curfman McInnes } 134143a90d84SBarry Smith ierr = VecScatterBegin(xx,a->lvec,INSERT_VALUES,SCATTER_FORWARD,a->Mvctx);CHKERRQ(ierr); 1342f830108cSBarry Smith ierr = (*a->A->ops->mult)(a->A,xx,yy);CHKERRQ(ierr); 134343a90d84SBarry Smith ierr = VecScatterEnd(xx,a->lvec,INSERT_VALUES,SCATTER_FORWARD,a->Mvctx);CHKERRQ(ierr); 1344f830108cSBarry Smith ierr = (*a->B->ops->multadd)(a->B,a->lvec,yy,yy);CHKERRQ(ierr); 134543a90d84SBarry Smith ierr = VecScatterPostRecvs(xx,a->lvec,INSERT_VALUES,SCATTER_FORWARD,a->Mvctx);CHKERRQ(ierr); 13463a40ed3dSBarry Smith PetscFunctionReturn(0); 1347cee3aa6bSSatish Balay } 1348cee3aa6bSSatish Balay 13494a2ae208SSatish Balay #undef __FUNCT__ 13504a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_MPIBAIJ" 1351dfbe8321SBarry Smith PetscErrorCode MatMultAdd_MPIBAIJ(Mat A,Vec xx,Vec yy,Vec zz) 1352cee3aa6bSSatish Balay { 1353cee3aa6bSSatish Balay Mat_MPIBAIJ *a = (Mat_MPIBAIJ*)A->data; 1354dfbe8321SBarry Smith PetscErrorCode ierr; 1355d64ed03dSBarry Smith 1356d64ed03dSBarry Smith PetscFunctionBegin; 135743a90d84SBarry Smith ierr = VecScatterBegin(xx,a->lvec,INSERT_VALUES,SCATTER_FORWARD,a->Mvctx);CHKERRQ(ierr); 1358f830108cSBarry Smith ierr = (*a->A->ops->multadd)(a->A,xx,yy,zz);CHKERRQ(ierr); 135943a90d84SBarry Smith ierr = VecScatterEnd(xx,a->lvec,INSERT_VALUES,SCATTER_FORWARD,a->Mvctx);CHKERRQ(ierr); 1360f830108cSBarry Smith ierr = (*a->B->ops->multadd)(a->B,a->lvec,zz,zz);CHKERRQ(ierr); 13613a40ed3dSBarry Smith PetscFunctionReturn(0); 1362cee3aa6bSSatish Balay } 1363cee3aa6bSSatish Balay 13644a2ae208SSatish Balay #undef __FUNCT__ 13654a2ae208SSatish Balay #define __FUNCT__ "MatMultTranspose_MPIBAIJ" 1366dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_MPIBAIJ(Mat A,Vec xx,Vec yy) 1367cee3aa6bSSatish Balay { 1368cee3aa6bSSatish Balay Mat_MPIBAIJ *a = (Mat_MPIBAIJ*)A->data; 1369dfbe8321SBarry Smith PetscErrorCode ierr; 1370a5ff213dSBarry Smith PetscTruth merged; 1371cee3aa6bSSatish Balay 1372d64ed03dSBarry Smith PetscFunctionBegin; 1373a5ff213dSBarry Smith ierr = VecScatterGetMerged(a->Mvctx,&merged);CHKERRQ(ierr); 1374cee3aa6bSSatish Balay /* do nondiagonal part */ 13757c922b88SBarry Smith ierr = (*a->B->ops->multtranspose)(a->B,xx,a->lvec);CHKERRQ(ierr); 1376a5ff213dSBarry Smith if (!merged) { 1377cee3aa6bSSatish Balay /* send it on its way */ 1378537820f0SBarry Smith ierr = VecScatterBegin(a->lvec,yy,ADD_VALUES,SCATTER_REVERSE,a->Mvctx);CHKERRQ(ierr); 1379cee3aa6bSSatish Balay /* do local part */ 13807c922b88SBarry Smith ierr = (*a->A->ops->multtranspose)(a->A,xx,yy);CHKERRQ(ierr); 1381cee3aa6bSSatish Balay /* receive remote parts: note this assumes the values are not actually */ 1382a5ff213dSBarry Smith /* inserted in yy until the next line */ 1383639f9d9dSBarry Smith ierr = VecScatterEnd(a->lvec,yy,ADD_VALUES,SCATTER_REVERSE,a->Mvctx);CHKERRQ(ierr); 1384a5ff213dSBarry Smith } else { 1385a5ff213dSBarry Smith /* do local part */ 1386a5ff213dSBarry Smith ierr = (*a->A->ops->multtranspose)(a->A,xx,yy);CHKERRQ(ierr); 1387a5ff213dSBarry Smith /* send it on its way */ 1388a5ff213dSBarry Smith ierr = VecScatterBegin(a->lvec,yy,ADD_VALUES,SCATTER_REVERSE,a->Mvctx);CHKERRQ(ierr); 1389a5ff213dSBarry Smith /* values actually were received in the Begin() but we need to call this nop */ 1390a5ff213dSBarry Smith ierr = VecScatterEnd(a->lvec,yy,ADD_VALUES,SCATTER_REVERSE,a->Mvctx);CHKERRQ(ierr); 1391a5ff213dSBarry Smith } 13923a40ed3dSBarry Smith PetscFunctionReturn(0); 1393cee3aa6bSSatish Balay } 1394cee3aa6bSSatish Balay 13954a2ae208SSatish Balay #undef __FUNCT__ 13964a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_MPIBAIJ" 1397dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_MPIBAIJ(Mat A,Vec xx,Vec yy,Vec zz) 1398cee3aa6bSSatish Balay { 1399cee3aa6bSSatish Balay Mat_MPIBAIJ *a = (Mat_MPIBAIJ*)A->data; 1400dfbe8321SBarry Smith PetscErrorCode ierr; 1401cee3aa6bSSatish Balay 1402d64ed03dSBarry Smith PetscFunctionBegin; 1403cee3aa6bSSatish Balay /* do nondiagonal part */ 14047c922b88SBarry Smith ierr = (*a->B->ops->multtranspose)(a->B,xx,a->lvec);CHKERRQ(ierr); 1405cee3aa6bSSatish Balay /* send it on its way */ 1406537820f0SBarry Smith ierr = VecScatterBegin(a->lvec,zz,ADD_VALUES,SCATTER_REVERSE,a->Mvctx);CHKERRQ(ierr); 1407cee3aa6bSSatish Balay /* do local part */ 14087c922b88SBarry Smith ierr = (*a->A->ops->multtransposeadd)(a->A,xx,yy,zz);CHKERRQ(ierr); 1409cee3aa6bSSatish Balay /* receive remote parts: note this assumes the values are not actually */ 1410cee3aa6bSSatish Balay /* inserted in yy until the next line, which is true for my implementation*/ 1411cee3aa6bSSatish Balay /* but is not perhaps always true. */ 1412537820f0SBarry Smith ierr = VecScatterEnd(a->lvec,zz,ADD_VALUES,SCATTER_REVERSE,a->Mvctx);CHKERRQ(ierr); 14133a40ed3dSBarry Smith PetscFunctionReturn(0); 1414cee3aa6bSSatish Balay } 1415cee3aa6bSSatish Balay 1416cee3aa6bSSatish Balay /* 1417cee3aa6bSSatish Balay This only works correctly for square matrices where the subblock A->A is the 1418cee3aa6bSSatish Balay diagonal block 1419cee3aa6bSSatish Balay */ 14204a2ae208SSatish Balay #undef __FUNCT__ 14214a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_MPIBAIJ" 1422dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_MPIBAIJ(Mat A,Vec v) 1423cee3aa6bSSatish Balay { 1424cee3aa6bSSatish Balay Mat_MPIBAIJ *a = (Mat_MPIBAIJ*)A->data; 1425dfbe8321SBarry Smith PetscErrorCode ierr; 1426d64ed03dSBarry Smith 1427d64ed03dSBarry Smith PetscFunctionBegin; 1428273d9f13SBarry Smith if (A->M != A->N) SETERRQ(PETSC_ERR_SUP,"Supports only square matrix where A->A is diag block"); 14293a40ed3dSBarry Smith ierr = MatGetDiagonal(a->A,v);CHKERRQ(ierr); 14303a40ed3dSBarry Smith PetscFunctionReturn(0); 1431cee3aa6bSSatish Balay } 1432cee3aa6bSSatish Balay 14334a2ae208SSatish Balay #undef __FUNCT__ 14344a2ae208SSatish Balay #define __FUNCT__ "MatScale_MPIBAIJ" 1435dfbe8321SBarry Smith PetscErrorCode MatScale_MPIBAIJ(const PetscScalar *aa,Mat A) 1436cee3aa6bSSatish Balay { 1437cee3aa6bSSatish Balay Mat_MPIBAIJ *a = (Mat_MPIBAIJ*)A->data; 1438dfbe8321SBarry Smith PetscErrorCode ierr; 1439d64ed03dSBarry Smith 1440d64ed03dSBarry Smith PetscFunctionBegin; 1441cee3aa6bSSatish Balay ierr = MatScale(aa,a->A);CHKERRQ(ierr); 1442cee3aa6bSSatish Balay ierr = MatScale(aa,a->B);CHKERRQ(ierr); 14433a40ed3dSBarry Smith PetscFunctionReturn(0); 1444cee3aa6bSSatish Balay } 1445026e39d0SSatish Balay 14464a2ae208SSatish Balay #undef __FUNCT__ 14474a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_MPIBAIJ" 1448b24ad042SBarry Smith PetscErrorCode MatGetRow_MPIBAIJ(Mat matin,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 1449acdf5bf4SSatish Balay { 1450acdf5bf4SSatish Balay Mat_MPIBAIJ *mat = (Mat_MPIBAIJ*)matin->data; 145187828ca2SBarry Smith PetscScalar *vworkA,*vworkB,**pvA,**pvB,*v_p; 14526849ba73SBarry Smith PetscErrorCode ierr; 1453521d7252SBarry Smith PetscInt bs = matin->bs,bs2 = mat->bs2,i,*cworkA,*cworkB,**pcA,**pcB; 1454b24ad042SBarry Smith PetscInt nztot,nzA,nzB,lrow,brstart = mat->rstart*bs,brend = mat->rend*bs; 1455b24ad042SBarry Smith PetscInt *cmap,*idx_p,cstart = mat->cstart; 1456acdf5bf4SSatish Balay 1457d64ed03dSBarry Smith PetscFunctionBegin; 1458abc0a331SBarry Smith if (mat->getrowactive) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Already active"); 1459acdf5bf4SSatish Balay mat->getrowactive = PETSC_TRUE; 1460acdf5bf4SSatish Balay 1461acdf5bf4SSatish Balay if (!mat->rowvalues && (idx || v)) { 1462acdf5bf4SSatish Balay /* 1463acdf5bf4SSatish Balay allocate enough space to hold information from the longest row. 1464acdf5bf4SSatish Balay */ 1465acdf5bf4SSatish Balay Mat_SeqBAIJ *Aa = (Mat_SeqBAIJ*)mat->A->data,*Ba = (Mat_SeqBAIJ*)mat->B->data; 1466b24ad042SBarry Smith PetscInt max = 1,mbs = mat->mbs,tmp; 1467bd16c2feSSatish Balay for (i=0; i<mbs; i++) { 1468acdf5bf4SSatish Balay tmp = Aa->i[i+1] - Aa->i[i] + Ba->i[i+1] - Ba->i[i]; 1469acdf5bf4SSatish Balay if (max < tmp) { max = tmp; } 1470acdf5bf4SSatish Balay } 1471b24ad042SBarry Smith ierr = PetscMalloc(max*bs2*(sizeof(PetscInt)+sizeof(PetscScalar)),&mat->rowvalues);CHKERRQ(ierr); 1472b24ad042SBarry Smith mat->rowindices = (PetscInt*)(mat->rowvalues + max*bs2); 1473acdf5bf4SSatish Balay } 1474acdf5bf4SSatish Balay 147529bbc08cSBarry Smith if (row < brstart || row >= brend) SETERRQ(PETSC_ERR_SUP,"Only local rows") 1476d9d09a02SSatish Balay lrow = row - brstart; 1477acdf5bf4SSatish Balay 1478acdf5bf4SSatish Balay pvA = &vworkA; pcA = &cworkA; pvB = &vworkB; pcB = &cworkB; 1479acdf5bf4SSatish Balay if (!v) {pvA = 0; pvB = 0;} 1480acdf5bf4SSatish Balay if (!idx) {pcA = 0; if (!v) pcB = 0;} 1481f830108cSBarry Smith ierr = (*mat->A->ops->getrow)(mat->A,lrow,&nzA,pcA,pvA);CHKERRQ(ierr); 1482f830108cSBarry Smith ierr = (*mat->B->ops->getrow)(mat->B,lrow,&nzB,pcB,pvB);CHKERRQ(ierr); 1483acdf5bf4SSatish Balay nztot = nzA + nzB; 1484acdf5bf4SSatish Balay 1485acdf5bf4SSatish Balay cmap = mat->garray; 1486acdf5bf4SSatish Balay if (v || idx) { 1487acdf5bf4SSatish Balay if (nztot) { 1488acdf5bf4SSatish Balay /* Sort by increasing column numbers, assuming A and B already sorted */ 1489b24ad042SBarry Smith PetscInt imark = -1; 1490acdf5bf4SSatish Balay if (v) { 1491acdf5bf4SSatish Balay *v = v_p = mat->rowvalues; 1492acdf5bf4SSatish Balay for (i=0; i<nzB; i++) { 1493d9d09a02SSatish Balay if (cmap[cworkB[i]/bs] < cstart) v_p[i] = vworkB[i]; 1494acdf5bf4SSatish Balay else break; 1495acdf5bf4SSatish Balay } 1496acdf5bf4SSatish Balay imark = i; 1497acdf5bf4SSatish Balay for (i=0; i<nzA; i++) v_p[imark+i] = vworkA[i]; 1498acdf5bf4SSatish Balay for (i=imark; i<nzB; i++) v_p[nzA+i] = vworkB[i]; 1499acdf5bf4SSatish Balay } 1500acdf5bf4SSatish Balay if (idx) { 1501acdf5bf4SSatish Balay *idx = idx_p = mat->rowindices; 1502acdf5bf4SSatish Balay if (imark > -1) { 1503acdf5bf4SSatish Balay for (i=0; i<imark; i++) { 1504bd16c2feSSatish Balay idx_p[i] = cmap[cworkB[i]/bs]*bs + cworkB[i]%bs; 1505acdf5bf4SSatish Balay } 1506acdf5bf4SSatish Balay } else { 1507acdf5bf4SSatish Balay for (i=0; i<nzB; i++) { 1508d9d09a02SSatish Balay if (cmap[cworkB[i]/bs] < cstart) 1509d9d09a02SSatish Balay idx_p[i] = cmap[cworkB[i]/bs]*bs + cworkB[i]%bs ; 1510acdf5bf4SSatish Balay else break; 1511acdf5bf4SSatish Balay } 1512acdf5bf4SSatish Balay imark = i; 1513acdf5bf4SSatish Balay } 1514d9d09a02SSatish Balay for (i=0; i<nzA; i++) idx_p[imark+i] = cstart*bs + cworkA[i]; 1515d9d09a02SSatish Balay for (i=imark; i<nzB; i++) idx_p[nzA+i] = cmap[cworkB[i]/bs]*bs + cworkB[i]%bs ; 1516acdf5bf4SSatish Balay } 1517d64ed03dSBarry Smith } else { 1518d212a18eSSatish Balay if (idx) *idx = 0; 1519d212a18eSSatish Balay if (v) *v = 0; 1520d212a18eSSatish Balay } 1521acdf5bf4SSatish Balay } 1522acdf5bf4SSatish Balay *nz = nztot; 1523f830108cSBarry Smith ierr = (*mat->A->ops->restorerow)(mat->A,lrow,&nzA,pcA,pvA);CHKERRQ(ierr); 1524f830108cSBarry Smith ierr = (*mat->B->ops->restorerow)(mat->B,lrow,&nzB,pcB,pvB);CHKERRQ(ierr); 15253a40ed3dSBarry Smith PetscFunctionReturn(0); 1526acdf5bf4SSatish Balay } 1527acdf5bf4SSatish Balay 15284a2ae208SSatish Balay #undef __FUNCT__ 15294a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_MPIBAIJ" 1530b24ad042SBarry Smith PetscErrorCode MatRestoreRow_MPIBAIJ(Mat mat,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 1531acdf5bf4SSatish Balay { 1532acdf5bf4SSatish Balay Mat_MPIBAIJ *baij = (Mat_MPIBAIJ*)mat->data; 1533d64ed03dSBarry Smith 1534d64ed03dSBarry Smith PetscFunctionBegin; 1535abc0a331SBarry Smith if (!baij->getrowactive) { 153629bbc08cSBarry Smith SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"MatGetRow not called"); 1537acdf5bf4SSatish Balay } 1538acdf5bf4SSatish Balay baij->getrowactive = PETSC_FALSE; 15393a40ed3dSBarry Smith PetscFunctionReturn(0); 1540acdf5bf4SSatish Balay } 1541acdf5bf4SSatish Balay 15424a2ae208SSatish Balay #undef __FUNCT__ 15434a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_MPIBAIJ" 1544dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_MPIBAIJ(Mat A) 154558667388SSatish Balay { 154658667388SSatish Balay Mat_MPIBAIJ *l = (Mat_MPIBAIJ*)A->data; 1547dfbe8321SBarry Smith PetscErrorCode ierr; 1548d64ed03dSBarry Smith 1549d64ed03dSBarry Smith PetscFunctionBegin; 155058667388SSatish Balay ierr = MatZeroEntries(l->A);CHKERRQ(ierr); 155158667388SSatish Balay ierr = MatZeroEntries(l->B);CHKERRQ(ierr); 15523a40ed3dSBarry Smith PetscFunctionReturn(0); 155358667388SSatish Balay } 15540ac07820SSatish Balay 15554a2ae208SSatish Balay #undef __FUNCT__ 15564a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_MPIBAIJ" 1557dfbe8321SBarry Smith PetscErrorCode MatGetInfo_MPIBAIJ(Mat matin,MatInfoType flag,MatInfo *info) 15580ac07820SSatish Balay { 15594e220ebcSLois Curfman McInnes Mat_MPIBAIJ *a = (Mat_MPIBAIJ*)matin->data; 15604e220ebcSLois Curfman McInnes Mat A = a->A,B = a->B; 1561dfbe8321SBarry Smith PetscErrorCode ierr; 1562329f5518SBarry Smith PetscReal isend[5],irecv[5]; 15630ac07820SSatish Balay 1564d64ed03dSBarry Smith PetscFunctionBegin; 1565521d7252SBarry Smith info->block_size = (PetscReal)matin->bs; 15664e220ebcSLois Curfman McInnes ierr = MatGetInfo(A,MAT_LOCAL,info);CHKERRQ(ierr); 15670e4b21beSBarry Smith isend[0] = info->nz_used; isend[1] = info->nz_allocated; isend[2] = info->nz_unneeded; 1568de87f314SBarry Smith isend[3] = info->memory; isend[4] = info->mallocs; 15694e220ebcSLois Curfman McInnes ierr = MatGetInfo(B,MAT_LOCAL,info);CHKERRQ(ierr); 15700e4b21beSBarry Smith isend[0] += info->nz_used; isend[1] += info->nz_allocated; isend[2] += info->nz_unneeded; 1571de87f314SBarry Smith isend[3] += info->memory; isend[4] += info->mallocs; 15720ac07820SSatish Balay if (flag == MAT_LOCAL) { 15734e220ebcSLois Curfman McInnes info->nz_used = isend[0]; 15744e220ebcSLois Curfman McInnes info->nz_allocated = isend[1]; 15754e220ebcSLois Curfman McInnes info->nz_unneeded = isend[2]; 15764e220ebcSLois Curfman McInnes info->memory = isend[3]; 15774e220ebcSLois Curfman McInnes info->mallocs = isend[4]; 15780ac07820SSatish Balay } else if (flag == MAT_GLOBAL_MAX) { 1579d7d1e502SBarry Smith ierr = MPI_Allreduce(isend,irecv,5,MPIU_REAL,MPI_MAX,matin->comm);CHKERRQ(ierr); 15804e220ebcSLois Curfman McInnes info->nz_used = irecv[0]; 15814e220ebcSLois Curfman McInnes info->nz_allocated = irecv[1]; 15824e220ebcSLois Curfman McInnes info->nz_unneeded = irecv[2]; 15834e220ebcSLois Curfman McInnes info->memory = irecv[3]; 15844e220ebcSLois Curfman McInnes info->mallocs = irecv[4]; 15850ac07820SSatish Balay } else if (flag == MAT_GLOBAL_SUM) { 1586d7d1e502SBarry Smith ierr = MPI_Allreduce(isend,irecv,5,MPIU_REAL,MPI_SUM,matin->comm);CHKERRQ(ierr); 15874e220ebcSLois Curfman McInnes info->nz_used = irecv[0]; 15884e220ebcSLois Curfman McInnes info->nz_allocated = irecv[1]; 15894e220ebcSLois Curfman McInnes info->nz_unneeded = irecv[2]; 15904e220ebcSLois Curfman McInnes info->memory = irecv[3]; 15914e220ebcSLois Curfman McInnes info->mallocs = irecv[4]; 1592d41123aaSBarry Smith } else { 159377431f27SBarry Smith SETERRQ1(PETSC_ERR_ARG_WRONG,"Unknown MatInfoType argument %d",(int)flag); 15940ac07820SSatish Balay } 1595f6275e2eSBarry Smith info->rows_global = (PetscReal)A->M; 1596f6275e2eSBarry Smith info->columns_global = (PetscReal)A->N; 1597f6275e2eSBarry Smith info->rows_local = (PetscReal)A->m; 1598f6275e2eSBarry Smith info->columns_local = (PetscReal)A->N; 15994e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; /* no parallel LU/ILU/Cholesky */ 16004e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 16014e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 16023a40ed3dSBarry Smith PetscFunctionReturn(0); 16030ac07820SSatish Balay } 16040ac07820SSatish Balay 16054a2ae208SSatish Balay #undef __FUNCT__ 16064a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_MPIBAIJ" 1607dfbe8321SBarry Smith PetscErrorCode MatSetOption_MPIBAIJ(Mat A,MatOption op) 160858667388SSatish Balay { 160958667388SSatish Balay Mat_MPIBAIJ *a = (Mat_MPIBAIJ*)A->data; 1610dfbe8321SBarry Smith PetscErrorCode ierr; 161158667388SSatish Balay 1612d64ed03dSBarry Smith PetscFunctionBegin; 161312c028f9SKris Buschelman switch (op) { 161412c028f9SKris Buschelman case MAT_NO_NEW_NONZERO_LOCATIONS: 161512c028f9SKris Buschelman case MAT_YES_NEW_NONZERO_LOCATIONS: 161612c028f9SKris Buschelman case MAT_COLUMNS_UNSORTED: 161712c028f9SKris Buschelman case MAT_COLUMNS_SORTED: 161812c028f9SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 161912c028f9SKris Buschelman case MAT_KEEP_ZEROED_ROWS: 162012c028f9SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 162198305bb5SBarry Smith ierr = MatSetOption(a->A,op);CHKERRQ(ierr); 162298305bb5SBarry Smith ierr = MatSetOption(a->B,op);CHKERRQ(ierr); 162312c028f9SKris Buschelman break; 162412c028f9SKris Buschelman case MAT_ROW_ORIENTED: 16257c922b88SBarry Smith a->roworiented = PETSC_TRUE; 162698305bb5SBarry Smith ierr = MatSetOption(a->A,op);CHKERRQ(ierr); 162798305bb5SBarry Smith ierr = MatSetOption(a->B,op);CHKERRQ(ierr); 162812c028f9SKris Buschelman break; 162912c028f9SKris Buschelman case MAT_ROWS_SORTED: 163012c028f9SKris Buschelman case MAT_ROWS_UNSORTED: 163112c028f9SKris Buschelman case MAT_YES_NEW_DIAGONALS: 163263ba0a88SBarry Smith ierr = PetscLogInfo((A,"Info:MatSetOption_MPIBAIJ:Option ignored\n"));CHKERRQ(ierr); 163312c028f9SKris Buschelman break; 163412c028f9SKris Buschelman case MAT_COLUMN_ORIENTED: 16357c922b88SBarry Smith a->roworiented = PETSC_FALSE; 163698305bb5SBarry Smith ierr = MatSetOption(a->A,op);CHKERRQ(ierr); 163798305bb5SBarry Smith ierr = MatSetOption(a->B,op);CHKERRQ(ierr); 163812c028f9SKris Buschelman break; 163912c028f9SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 16407c922b88SBarry Smith a->donotstash = PETSC_TRUE; 164112c028f9SKris Buschelman break; 164212c028f9SKris Buschelman case MAT_NO_NEW_DIAGONALS: 164329bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS"); 164412c028f9SKris Buschelman case MAT_USE_HASH_TABLE: 16457c922b88SBarry Smith a->ht_flag = PETSC_TRUE; 164612c028f9SKris Buschelman break; 164777e54ba9SKris Buschelman case MAT_SYMMETRIC: 164877e54ba9SKris Buschelman case MAT_STRUCTURALLY_SYMMETRIC: 16492188ac68SBarry Smith case MAT_HERMITIAN: 16502188ac68SBarry Smith case MAT_SYMMETRY_ETERNAL: 16512188ac68SBarry Smith ierr = MatSetOption(a->A,op);CHKERRQ(ierr); 16522188ac68SBarry Smith break; 16539a4540c5SBarry Smith case MAT_NOT_SYMMETRIC: 16549a4540c5SBarry Smith case MAT_NOT_STRUCTURALLY_SYMMETRIC: 16559a4540c5SBarry Smith case MAT_NOT_HERMITIAN: 16569a4540c5SBarry Smith case MAT_NOT_SYMMETRY_ETERNAL: 165777e54ba9SKris Buschelman break; 165812c028f9SKris Buschelman default: 165929bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"unknown option"); 1660d64ed03dSBarry Smith } 16613a40ed3dSBarry Smith PetscFunctionReturn(0); 166258667388SSatish Balay } 166358667388SSatish Balay 16644a2ae208SSatish Balay #undef __FUNCT__ 16654a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_MPIBAIJ(" 1666dfbe8321SBarry Smith PetscErrorCode MatTranspose_MPIBAIJ(Mat A,Mat *matout) 16670ac07820SSatish Balay { 16680ac07820SSatish Balay Mat_MPIBAIJ *baij = (Mat_MPIBAIJ*)A->data; 16690ac07820SSatish Balay Mat_SeqBAIJ *Aloc; 16700ac07820SSatish Balay Mat B; 1671dfbe8321SBarry Smith PetscErrorCode ierr; 1672b24ad042SBarry Smith PetscInt M=A->M,N=A->N,*ai,*aj,i,*rvals,j,k,col; 1673521d7252SBarry Smith PetscInt bs=A->bs,mbs=baij->mbs; 16743eda8832SBarry Smith MatScalar *a; 16750ac07820SSatish Balay 1676d64ed03dSBarry Smith PetscFunctionBegin; 167729bbc08cSBarry Smith if (!matout && M != N) SETERRQ(PETSC_ERR_ARG_SIZ,"Square matrix only for in-place"); 1678f204ca49SKris Buschelman ierr = MatCreate(A->comm,A->n,A->m,N,M,&B);CHKERRQ(ierr); 1679f204ca49SKris Buschelman ierr = MatSetType(B,A->type_name);CHKERRQ(ierr); 1680521d7252SBarry Smith ierr = MatMPIBAIJSetPreallocation(B,A->bs,0,PETSC_NULL,0,PETSC_NULL);CHKERRQ(ierr); 16810ac07820SSatish Balay 16820ac07820SSatish Balay /* copy over the A part */ 16830ac07820SSatish Balay Aloc = (Mat_SeqBAIJ*)baij->A->data; 16840ac07820SSatish Balay ai = Aloc->i; aj = Aloc->j; a = Aloc->a; 1685b24ad042SBarry Smith ierr = PetscMalloc(bs*sizeof(PetscInt),&rvals);CHKERRQ(ierr); 16860ac07820SSatish Balay 16870ac07820SSatish Balay for (i=0; i<mbs; i++) { 16880ac07820SSatish Balay rvals[0] = bs*(baij->rstart + i); 16890ac07820SSatish Balay for (j=1; j<bs; j++) { rvals[j] = rvals[j-1] + 1; } 16900ac07820SSatish Balay for (j=ai[i]; j<ai[i+1]; j++) { 16910ac07820SSatish Balay col = (baij->cstart+aj[j])*bs; 16920ac07820SSatish Balay for (k=0; k<bs; k++) { 169393fea6afSBarry Smith ierr = MatSetValues_MPIBAIJ_MatScalar(B,1,&col,bs,rvals,a,INSERT_VALUES);CHKERRQ(ierr); 16940ac07820SSatish Balay col++; a += bs; 16950ac07820SSatish Balay } 16960ac07820SSatish Balay } 16970ac07820SSatish Balay } 16980ac07820SSatish Balay /* copy over the B part */ 16990ac07820SSatish Balay Aloc = (Mat_SeqBAIJ*)baij->B->data; 17000ac07820SSatish Balay ai = Aloc->i; aj = Aloc->j; a = Aloc->a; 17010ac07820SSatish Balay for (i=0; i<mbs; i++) { 17020ac07820SSatish Balay rvals[0] = bs*(baij->rstart + i); 17030ac07820SSatish Balay for (j=1; j<bs; j++) { rvals[j] = rvals[j-1] + 1; } 17040ac07820SSatish Balay for (j=ai[i]; j<ai[i+1]; j++) { 17050ac07820SSatish Balay col = baij->garray[aj[j]]*bs; 17060ac07820SSatish Balay for (k=0; k<bs; k++) { 170793fea6afSBarry Smith ierr = MatSetValues_MPIBAIJ_MatScalar(B,1,&col,bs,rvals,a,INSERT_VALUES);CHKERRQ(ierr); 17080ac07820SSatish Balay col++; a += bs; 17090ac07820SSatish Balay } 17100ac07820SSatish Balay } 17110ac07820SSatish Balay } 1712606d414cSSatish Balay ierr = PetscFree(rvals);CHKERRQ(ierr); 17130ac07820SSatish Balay ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 17140ac07820SSatish Balay ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 17150ac07820SSatish Balay 17167c922b88SBarry Smith if (matout) { 17170ac07820SSatish Balay *matout = B; 17180ac07820SSatish Balay } else { 1719273d9f13SBarry Smith ierr = MatHeaderCopy(A,B);CHKERRQ(ierr); 17200ac07820SSatish Balay } 17213a40ed3dSBarry Smith PetscFunctionReturn(0); 17220ac07820SSatish Balay } 17230e95ebc0SSatish Balay 17244a2ae208SSatish Balay #undef __FUNCT__ 17254a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_MPIBAIJ" 1726dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_MPIBAIJ(Mat mat,Vec ll,Vec rr) 17270e95ebc0SSatish Balay { 172836c4a09eSSatish Balay Mat_MPIBAIJ *baij = (Mat_MPIBAIJ*)mat->data; 172936c4a09eSSatish Balay Mat a = baij->A,b = baij->B; 1730dfbe8321SBarry Smith PetscErrorCode ierr; 1731b24ad042SBarry Smith PetscInt s1,s2,s3; 17320e95ebc0SSatish Balay 1733d64ed03dSBarry Smith PetscFunctionBegin; 173436c4a09eSSatish Balay ierr = MatGetLocalSize(mat,&s2,&s3);CHKERRQ(ierr); 173536c4a09eSSatish Balay if (rr) { 173636c4a09eSSatish Balay ierr = VecGetLocalSize(rr,&s1);CHKERRQ(ierr); 173729bbc08cSBarry Smith if (s1!=s3) SETERRQ(PETSC_ERR_ARG_SIZ,"right vector non-conforming local size"); 173836c4a09eSSatish Balay /* Overlap communication with computation. */ 173936c4a09eSSatish Balay ierr = VecScatterBegin(rr,baij->lvec,INSERT_VALUES,SCATTER_FORWARD,baij->Mvctx);CHKERRQ(ierr); 174036c4a09eSSatish Balay } 17410e95ebc0SSatish Balay if (ll) { 17420e95ebc0SSatish Balay ierr = VecGetLocalSize(ll,&s1);CHKERRQ(ierr); 174329bbc08cSBarry Smith if (s1!=s2) SETERRQ(PETSC_ERR_ARG_SIZ,"left vector non-conforming local size"); 1744a21fb8cbSBarry Smith ierr = (*b->ops->diagonalscale)(b,ll,PETSC_NULL);CHKERRQ(ierr); 17450e95ebc0SSatish Balay } 174636c4a09eSSatish Balay /* scale the diagonal block */ 174736c4a09eSSatish Balay ierr = (*a->ops->diagonalscale)(a,ll,rr);CHKERRQ(ierr); 174836c4a09eSSatish Balay 174936c4a09eSSatish Balay if (rr) { 175036c4a09eSSatish Balay /* Do a scatter end and then right scale the off-diagonal block */ 175136c4a09eSSatish Balay ierr = VecScatterEnd(rr,baij->lvec,INSERT_VALUES,SCATTER_FORWARD,baij->Mvctx);CHKERRQ(ierr); 1752a21fb8cbSBarry Smith ierr = (*b->ops->diagonalscale)(b,PETSC_NULL,baij->lvec);CHKERRQ(ierr); 175336c4a09eSSatish Balay } 175436c4a09eSSatish Balay 17553a40ed3dSBarry Smith PetscFunctionReturn(0); 17560e95ebc0SSatish Balay } 17570e95ebc0SSatish Balay 17584a2ae208SSatish Balay #undef __FUNCT__ 17594a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_MPIBAIJ" 1760dfbe8321SBarry Smith PetscErrorCode MatZeroRows_MPIBAIJ(Mat A,IS is,const PetscScalar *diag) 17610ac07820SSatish Balay { 17620ac07820SSatish Balay Mat_MPIBAIJ *l = (Mat_MPIBAIJ*)A->data; 17636849ba73SBarry Smith PetscErrorCode ierr; 1764b24ad042SBarry Smith PetscMPIInt imdex,size = l->size,n,rank = l->rank; 1765b24ad042SBarry Smith PetscInt i,N,*rows,*owners = l->rowners; 1766b24ad042SBarry Smith PetscInt *nprocs,j,idx,nsends,row; 1767b24ad042SBarry Smith PetscInt nmax,*svalues,*starts,*owner,nrecvs; 17686543fbbaSBarry Smith PetscInt *rvalues,tag = A->tag,count,base,slen,*source,lastidx = -1; 1769521d7252SBarry Smith PetscInt *lens,*lrows,*values,bs=A->bs,rstart_bs=l->rstart_bs; 17700ac07820SSatish Balay MPI_Comm comm = A->comm; 17710ac07820SSatish Balay MPI_Request *send_waits,*recv_waits; 17720ac07820SSatish Balay MPI_Status recv_status,*send_status; 17730ac07820SSatish Balay IS istmp; 17746543fbbaSBarry Smith #if defined(PETSC_DEBUG) 17756543fbbaSBarry Smith PetscTruth found = PETSC_FALSE; 17766543fbbaSBarry Smith #endif 17770ac07820SSatish Balay 1778d64ed03dSBarry Smith PetscFunctionBegin; 1779f14a1c24SBarry Smith ierr = ISGetLocalSize(is,&N);CHKERRQ(ierr); 17800ac07820SSatish Balay ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 17810ac07820SSatish Balay 17820ac07820SSatish Balay /* first count number of contributors to each processor */ 1783b24ad042SBarry Smith ierr = PetscMalloc(2*size*sizeof(PetscInt),&nprocs);CHKERRQ(ierr); 1784b24ad042SBarry Smith ierr = PetscMemzero(nprocs,2*size*sizeof(PetscInt));CHKERRQ(ierr); 1785b24ad042SBarry Smith ierr = PetscMalloc((N+1)*sizeof(PetscInt),&owner);CHKERRQ(ierr); /* see note*/ 17866543fbbaSBarry Smith j = 0; 17870ac07820SSatish Balay for (i=0; i<N; i++) { 17886543fbbaSBarry Smith if (lastidx > (idx = rows[i])) j = 0; 17896543fbbaSBarry Smith lastidx = idx; 17906543fbbaSBarry Smith for (; j<size; j++) { 17910ac07820SSatish Balay if (idx >= owners[j]*bs && idx < owners[j+1]*bs) { 17926543fbbaSBarry Smith nprocs[2*j]++; 17936543fbbaSBarry Smith nprocs[2*j+1] = 1; 17946543fbbaSBarry Smith owner[i] = j; 17956543fbbaSBarry Smith #if defined(PETSC_DEBUG) 17966543fbbaSBarry Smith found = PETSC_TRUE; 17976543fbbaSBarry Smith #endif 17986543fbbaSBarry Smith break; 17990ac07820SSatish Balay } 18000ac07820SSatish Balay } 18016543fbbaSBarry Smith #if defined(PETSC_DEBUG) 180229bbc08cSBarry Smith if (!found) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Index out of range"); 18036543fbbaSBarry Smith found = PETSC_FALSE; 18046543fbbaSBarry Smith #endif 18050ac07820SSatish Balay } 1806c1dc657dSBarry Smith nsends = 0; for (i=0; i<size; i++) { nsends += nprocs[2*i+1];} 18070ac07820SSatish Balay 18080ac07820SSatish Balay /* inform other processors of number of messages and max length*/ 1809c1dc657dSBarry Smith ierr = PetscMaxSum(comm,nprocs,&nmax,&nrecvs);CHKERRQ(ierr); 18100ac07820SSatish Balay 18110ac07820SSatish Balay /* post receives: */ 1812b24ad042SBarry Smith ierr = PetscMalloc((nrecvs+1)*(nmax+1)*sizeof(PetscInt),&rvalues);CHKERRQ(ierr); 1813b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs+1)*sizeof(MPI_Request),&recv_waits);CHKERRQ(ierr); 18140ac07820SSatish Balay for (i=0; i<nrecvs; i++) { 1815b24ad042SBarry Smith ierr = MPI_Irecv(rvalues+nmax*i,nmax,MPIU_INT,MPI_ANY_SOURCE,tag,comm,recv_waits+i);CHKERRQ(ierr); 18160ac07820SSatish Balay } 18170ac07820SSatish Balay 18180ac07820SSatish Balay /* do sends: 18190ac07820SSatish Balay 1) starts[i] gives the starting index in svalues for stuff going to 18200ac07820SSatish Balay the ith processor 18210ac07820SSatish Balay */ 1822b24ad042SBarry Smith ierr = PetscMalloc((N+1)*sizeof(PetscInt),&svalues);CHKERRQ(ierr); 1823b0a32e0cSBarry Smith ierr = PetscMalloc((nsends+1)*sizeof(MPI_Request),&send_waits);CHKERRQ(ierr); 1824b24ad042SBarry Smith ierr = PetscMalloc((size+1)*sizeof(PetscInt),&starts);CHKERRQ(ierr); 18250ac07820SSatish Balay starts[0] = 0; 1826c1dc657dSBarry Smith for (i=1; i<size; i++) { starts[i] = starts[i-1] + nprocs[2*i-2];} 18270ac07820SSatish Balay for (i=0; i<N; i++) { 18280ac07820SSatish Balay svalues[starts[owner[i]]++] = rows[i]; 18290ac07820SSatish Balay } 18306831982aSBarry Smith ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 18310ac07820SSatish Balay 18320ac07820SSatish Balay starts[0] = 0; 1833c1dc657dSBarry Smith for (i=1; i<size+1; i++) { starts[i] = starts[i-1] + nprocs[2*i-2];} 18340ac07820SSatish Balay count = 0; 18350ac07820SSatish Balay for (i=0; i<size; i++) { 1836c1dc657dSBarry Smith if (nprocs[2*i+1]) { 1837b24ad042SBarry Smith ierr = MPI_Isend(svalues+starts[i],nprocs[2*i],MPIU_INT,i,tag,comm,send_waits+count++);CHKERRQ(ierr); 18380ac07820SSatish Balay } 18390ac07820SSatish Balay } 1840606d414cSSatish Balay ierr = PetscFree(starts);CHKERRQ(ierr); 18410ac07820SSatish Balay 18420ac07820SSatish Balay base = owners[rank]*bs; 18430ac07820SSatish Balay 18440ac07820SSatish Balay /* wait on receives */ 1845b24ad042SBarry Smith ierr = PetscMalloc(2*(nrecvs+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr); 18460ac07820SSatish Balay source = lens + nrecvs; 18470ac07820SSatish Balay count = nrecvs; slen = 0; 18480ac07820SSatish Balay while (count) { 1849ca161407SBarry Smith ierr = MPI_Waitany(nrecvs,recv_waits,&imdex,&recv_status);CHKERRQ(ierr); 18500ac07820SSatish Balay /* unpack receives into our local space */ 1851b24ad042SBarry Smith ierr = MPI_Get_count(&recv_status,MPIU_INT,&n);CHKERRQ(ierr); 18520ac07820SSatish Balay source[imdex] = recv_status.MPI_SOURCE; 18530ac07820SSatish Balay lens[imdex] = n; 18540ac07820SSatish Balay slen += n; 18550ac07820SSatish Balay count--; 18560ac07820SSatish Balay } 1857606d414cSSatish Balay ierr = PetscFree(recv_waits);CHKERRQ(ierr); 18580ac07820SSatish Balay 18590ac07820SSatish Balay /* move the data into the send scatter */ 1860b24ad042SBarry Smith ierr = PetscMalloc((slen+1)*sizeof(PetscInt),&lrows);CHKERRQ(ierr); 18610ac07820SSatish Balay count = 0; 18620ac07820SSatish Balay for (i=0; i<nrecvs; i++) { 18630ac07820SSatish Balay values = rvalues + i*nmax; 18640ac07820SSatish Balay for (j=0; j<lens[i]; j++) { 18650ac07820SSatish Balay lrows[count++] = values[j] - base; 18660ac07820SSatish Balay } 18670ac07820SSatish Balay } 1868606d414cSSatish Balay ierr = PetscFree(rvalues);CHKERRQ(ierr); 1869606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 1870606d414cSSatish Balay ierr = PetscFree(owner);CHKERRQ(ierr); 1871606d414cSSatish Balay ierr = PetscFree(nprocs);CHKERRQ(ierr); 18720ac07820SSatish Balay 18730ac07820SSatish Balay /* actually zap the local rows */ 1874029af93fSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,slen,lrows,&istmp);CHKERRQ(ierr); 187552e6d16bSBarry Smith ierr = PetscLogObjectParent(A,istmp);CHKERRQ(ierr); 1876a07cd24cSSatish Balay 187772dacd9aSBarry Smith /* 187872dacd9aSBarry Smith Zero the required rows. If the "diagonal block" of the matrix 187972dacd9aSBarry Smith is square and the user wishes to set the diagonal we use seperate 188072dacd9aSBarry Smith code so that MatSetValues() is not called for each diagonal allocating 188172dacd9aSBarry Smith new memory, thus calling lots of mallocs and slowing things down. 188272dacd9aSBarry Smith 188372dacd9aSBarry Smith Contributed by: Mathew Knepley 188472dacd9aSBarry Smith */ 18859c957beeSSatish Balay /* must zero l->B before l->A because the (diag) case below may put values into l->B*/ 18866fa18ffdSBarry Smith ierr = MatZeroRows_SeqBAIJ(l->B,istmp,0);CHKERRQ(ierr); 18879c957beeSSatish Balay if (diag && (l->A->M == l->A->N)) { 18886fa18ffdSBarry Smith ierr = MatZeroRows_SeqBAIJ(l->A,istmp,diag);CHKERRQ(ierr); 18899c957beeSSatish Balay } else if (diag) { 18906fa18ffdSBarry Smith ierr = MatZeroRows_SeqBAIJ(l->A,istmp,0);CHKERRQ(ierr); 1891fa46199cSSatish Balay if (((Mat_SeqBAIJ*)l->A->data)->nonew) { 189229bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"MatZeroRows() on rectangular matrices cannot be used with the Mat options \n\ 1893fa46199cSSatish Balay MAT_NO_NEW_NONZERO_LOCATIONS,MAT_NEW_NONZERO_LOCATION_ERR,MAT_NEW_NONZERO_ALLOCATION_ERR"); 18946525c446SSatish Balay } 1895a07cd24cSSatish Balay for (i=0; i<slen; i++) { 1896a07cd24cSSatish Balay row = lrows[i] + rstart_bs; 18973f11ea53SBarry Smith ierr = MatSetValues(A,1,&row,1,&row,diag,INSERT_VALUES);CHKERRQ(ierr); 1898a07cd24cSSatish Balay } 1899a07cd24cSSatish Balay ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1900a07cd24cSSatish Balay ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 19019c957beeSSatish Balay } else { 19026fa18ffdSBarry Smith ierr = MatZeroRows_SeqBAIJ(l->A,istmp,0);CHKERRQ(ierr); 1903a07cd24cSSatish Balay } 19049c957beeSSatish Balay 19059c957beeSSatish Balay ierr = ISDestroy(istmp);CHKERRQ(ierr); 1906606d414cSSatish Balay ierr = PetscFree(lrows);CHKERRQ(ierr); 1907a07cd24cSSatish Balay 19080ac07820SSatish Balay /* wait on sends */ 19090ac07820SSatish Balay if (nsends) { 191082502324SSatish Balay ierr = PetscMalloc(nsends*sizeof(MPI_Status),&send_status);CHKERRQ(ierr); 1911ca161407SBarry Smith ierr = MPI_Waitall(nsends,send_waits,send_status);CHKERRQ(ierr); 1912606d414cSSatish Balay ierr = PetscFree(send_status);CHKERRQ(ierr); 19130ac07820SSatish Balay } 1914606d414cSSatish Balay ierr = PetscFree(send_waits);CHKERRQ(ierr); 1915606d414cSSatish Balay ierr = PetscFree(svalues);CHKERRQ(ierr); 19160ac07820SSatish Balay 19173a40ed3dSBarry Smith PetscFunctionReturn(0); 19180ac07820SSatish Balay } 191972dacd9aSBarry Smith 19204a2ae208SSatish Balay #undef __FUNCT__ 19214a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_MPIBAIJ" 1922dfbe8321SBarry Smith PetscErrorCode MatPrintHelp_MPIBAIJ(Mat A) 1923ba4ca20aSSatish Balay { 1924ba4ca20aSSatish Balay Mat_MPIBAIJ *a = (Mat_MPIBAIJ*)A->data; 192525fdafccSSatish Balay MPI_Comm comm = A->comm; 1926b24ad042SBarry Smith static PetscTruth called = PETSC_FALSE; 1927dfbe8321SBarry Smith PetscErrorCode ierr; 1928ba4ca20aSSatish Balay 1929d64ed03dSBarry Smith PetscFunctionBegin; 19303a40ed3dSBarry Smith if (!a->rank) { 19313a40ed3dSBarry Smith ierr = MatPrintHelp_SeqBAIJ(a->A);CHKERRQ(ierr); 193225fdafccSSatish Balay } 1933b24ad042SBarry Smith if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE; 1934d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," Options for MATMPIBAIJ matrix format (the defaults):\n");CHKERRQ(ierr); 1935d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_use_hash_table <factor>: Use hashtable for efficient matrix assembly\n");CHKERRQ(ierr); 19363a40ed3dSBarry Smith PetscFunctionReturn(0); 1937ba4ca20aSSatish Balay } 19380ac07820SSatish Balay 19394a2ae208SSatish Balay #undef __FUNCT__ 19404a2ae208SSatish Balay #define __FUNCT__ "MatSetUnfactored_MPIBAIJ" 1941dfbe8321SBarry Smith PetscErrorCode MatSetUnfactored_MPIBAIJ(Mat A) 1942bb5a7306SBarry Smith { 1943bb5a7306SBarry Smith Mat_MPIBAIJ *a = (Mat_MPIBAIJ*)A->data; 1944dfbe8321SBarry Smith PetscErrorCode ierr; 1945d64ed03dSBarry Smith 1946d64ed03dSBarry Smith PetscFunctionBegin; 1947bb5a7306SBarry Smith ierr = MatSetUnfactored(a->A);CHKERRQ(ierr); 19483a40ed3dSBarry Smith PetscFunctionReturn(0); 1949bb5a7306SBarry Smith } 1950bb5a7306SBarry Smith 19516849ba73SBarry Smith static PetscErrorCode MatDuplicate_MPIBAIJ(Mat,MatDuplicateOption,Mat *); 19520ac07820SSatish Balay 19534a2ae208SSatish Balay #undef __FUNCT__ 19544a2ae208SSatish Balay #define __FUNCT__ "MatEqual_MPIBAIJ" 1955dfbe8321SBarry Smith PetscErrorCode MatEqual_MPIBAIJ(Mat A,Mat B,PetscTruth *flag) 19567fc3c18eSBarry Smith { 19577fc3c18eSBarry Smith Mat_MPIBAIJ *matB = (Mat_MPIBAIJ*)B->data,*matA = (Mat_MPIBAIJ*)A->data; 19587fc3c18eSBarry Smith Mat a,b,c,d; 19597fc3c18eSBarry Smith PetscTruth flg; 1960dfbe8321SBarry Smith PetscErrorCode ierr; 19617fc3c18eSBarry Smith 19627fc3c18eSBarry Smith PetscFunctionBegin; 19637fc3c18eSBarry Smith a = matA->A; b = matA->B; 19647fc3c18eSBarry Smith c = matB->A; d = matB->B; 19657fc3c18eSBarry Smith 19667fc3c18eSBarry Smith ierr = MatEqual(a,c,&flg);CHKERRQ(ierr); 1967abc0a331SBarry Smith if (flg) { 19687fc3c18eSBarry Smith ierr = MatEqual(b,d,&flg);CHKERRQ(ierr); 19697fc3c18eSBarry Smith } 19707fc3c18eSBarry Smith ierr = MPI_Allreduce(&flg,flag,1,MPI_INT,MPI_LAND,A->comm);CHKERRQ(ierr); 19717fc3c18eSBarry Smith PetscFunctionReturn(0); 19727fc3c18eSBarry Smith } 19737fc3c18eSBarry Smith 1974273d9f13SBarry Smith 19754a2ae208SSatish Balay #undef __FUNCT__ 19764a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_MPIBAIJ" 1977dfbe8321SBarry Smith PetscErrorCode MatSetUpPreallocation_MPIBAIJ(Mat A) 1978273d9f13SBarry Smith { 1979dfbe8321SBarry Smith PetscErrorCode ierr; 1980273d9f13SBarry Smith 1981273d9f13SBarry Smith PetscFunctionBegin; 1982273d9f13SBarry Smith ierr = MatMPIBAIJSetPreallocation(A,1,PETSC_DEFAULT,0,PETSC_DEFAULT,0);CHKERRQ(ierr); 1983273d9f13SBarry Smith PetscFunctionReturn(0); 1984273d9f13SBarry Smith } 1985273d9f13SBarry Smith 198679bdfe76SSatish Balay /* -------------------------------------------------------------------*/ 1987cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = { 1988cc2dc46cSBarry Smith MatSetValues_MPIBAIJ, 1989cc2dc46cSBarry Smith MatGetRow_MPIBAIJ, 1990cc2dc46cSBarry Smith MatRestoreRow_MPIBAIJ, 1991cc2dc46cSBarry Smith MatMult_MPIBAIJ, 199297304618SKris Buschelman /* 4*/ MatMultAdd_MPIBAIJ, 19937c922b88SBarry Smith MatMultTranspose_MPIBAIJ, 19947c922b88SBarry Smith MatMultTransposeAdd_MPIBAIJ, 1995cc2dc46cSBarry Smith 0, 1996cc2dc46cSBarry Smith 0, 1997cc2dc46cSBarry Smith 0, 199897304618SKris Buschelman /*10*/ 0, 1999cc2dc46cSBarry Smith 0, 2000cc2dc46cSBarry Smith 0, 2001cc2dc46cSBarry Smith 0, 2002cc2dc46cSBarry Smith MatTranspose_MPIBAIJ, 200397304618SKris Buschelman /*15*/ MatGetInfo_MPIBAIJ, 20047fc3c18eSBarry Smith MatEqual_MPIBAIJ, 2005cc2dc46cSBarry Smith MatGetDiagonal_MPIBAIJ, 2006cc2dc46cSBarry Smith MatDiagonalScale_MPIBAIJ, 2007cc2dc46cSBarry Smith MatNorm_MPIBAIJ, 200897304618SKris Buschelman /*20*/ MatAssemblyBegin_MPIBAIJ, 2009cc2dc46cSBarry Smith MatAssemblyEnd_MPIBAIJ, 2010cc2dc46cSBarry Smith 0, 2011cc2dc46cSBarry Smith MatSetOption_MPIBAIJ, 2012cc2dc46cSBarry Smith MatZeroEntries_MPIBAIJ, 201397304618SKris Buschelman /*25*/ MatZeroRows_MPIBAIJ, 2014cc2dc46cSBarry Smith 0, 2015cc2dc46cSBarry Smith 0, 2016cc2dc46cSBarry Smith 0, 2017cc2dc46cSBarry Smith 0, 201897304618SKris Buschelman /*30*/ MatSetUpPreallocation_MPIBAIJ, 2019273d9f13SBarry Smith 0, 2020cc2dc46cSBarry Smith 0, 2021cc2dc46cSBarry Smith 0, 2022cc2dc46cSBarry Smith 0, 202397304618SKris Buschelman /*35*/ MatDuplicate_MPIBAIJ, 2024cc2dc46cSBarry Smith 0, 2025cc2dc46cSBarry Smith 0, 2026cc2dc46cSBarry Smith 0, 2027cc2dc46cSBarry Smith 0, 202897304618SKris Buschelman /*40*/ 0, 2029cc2dc46cSBarry Smith MatGetSubMatrices_MPIBAIJ, 2030cc2dc46cSBarry Smith MatIncreaseOverlap_MPIBAIJ, 2031cc2dc46cSBarry Smith MatGetValues_MPIBAIJ, 2032cc2dc46cSBarry Smith 0, 203397304618SKris Buschelman /*45*/ MatPrintHelp_MPIBAIJ, 2034cc2dc46cSBarry Smith MatScale_MPIBAIJ, 2035cc2dc46cSBarry Smith 0, 2036cc2dc46cSBarry Smith 0, 2037cc2dc46cSBarry Smith 0, 2038521d7252SBarry Smith /*50*/ 0, 2039cc2dc46cSBarry Smith 0, 2040cc2dc46cSBarry Smith 0, 2041cc2dc46cSBarry Smith 0, 2042cc2dc46cSBarry Smith 0, 204397304618SKris Buschelman /*55*/ 0, 2044cc2dc46cSBarry Smith 0, 2045cc2dc46cSBarry Smith MatSetUnfactored_MPIBAIJ, 2046cc2dc46cSBarry Smith 0, 2047cc2dc46cSBarry Smith MatSetValuesBlocked_MPIBAIJ, 204897304618SKris Buschelman /*60*/ 0, 2049f14a1c24SBarry Smith MatDestroy_MPIBAIJ, 2050f14a1c24SBarry Smith MatView_MPIBAIJ, 20518a124369SBarry Smith MatGetPetscMaps_Petsc, 20527843d17aSBarry Smith 0, 205397304618SKris Buschelman /*65*/ 0, 20547843d17aSBarry Smith 0, 20557843d17aSBarry Smith 0, 20567843d17aSBarry Smith 0, 20577843d17aSBarry Smith 0, 205897304618SKris Buschelman /*70*/ MatGetRowMax_MPIBAIJ, 20597843d17aSBarry Smith 0, 206097304618SKris Buschelman 0, 206197304618SKris Buschelman 0, 206297304618SKris Buschelman 0, 206397304618SKris Buschelman /*75*/ 0, 206497304618SKris Buschelman 0, 206597304618SKris Buschelman 0, 206697304618SKris Buschelman 0, 206797304618SKris Buschelman 0, 206897304618SKris Buschelman /*80*/ 0, 206997304618SKris Buschelman 0, 207097304618SKris Buschelman 0, 207197304618SKris Buschelman 0, 2072865e5f61SKris Buschelman MatLoad_MPIBAIJ, 2073865e5f61SKris Buschelman /*85*/ 0, 2074865e5f61SKris Buschelman 0, 2075865e5f61SKris Buschelman 0, 2076865e5f61SKris Buschelman 0, 2077865e5f61SKris Buschelman 0, 2078865e5f61SKris Buschelman /*90*/ 0, 2079865e5f61SKris Buschelman 0, 2080865e5f61SKris Buschelman 0, 2081865e5f61SKris Buschelman 0, 2082865e5f61SKris Buschelman 0, 2083865e5f61SKris Buschelman /*95*/ 0, 2084865e5f61SKris Buschelman 0, 2085865e5f61SKris Buschelman 0, 2086865e5f61SKris Buschelman 0}; 208779bdfe76SSatish Balay 20885ef9f2a5SBarry Smith 2089e18c124aSSatish Balay EXTERN_C_BEGIN 20904a2ae208SSatish Balay #undef __FUNCT__ 20914a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonalBlock_MPIBAIJ" 2092dfbe8321SBarry Smith PetscErrorCode MatGetDiagonalBlock_MPIBAIJ(Mat A,PetscTruth *iscopy,MatReuse reuse,Mat *a) 20935ef9f2a5SBarry Smith { 20945ef9f2a5SBarry Smith PetscFunctionBegin; 20955ef9f2a5SBarry Smith *a = ((Mat_MPIBAIJ *)A->data)->A; 20965ef9f2a5SBarry Smith *iscopy = PETSC_FALSE; 20975ef9f2a5SBarry Smith PetscFunctionReturn(0); 20985ef9f2a5SBarry Smith } 2099e18c124aSSatish Balay EXTERN_C_END 210079bdfe76SSatish Balay 2101273d9f13SBarry Smith EXTERN_C_BEGIN 2102ceb03754SKris Buschelman extern int MatConvert_MPIBAIJ_MPISBAIJ(Mat,const MatType,MatReuse,Mat*); 2103d94109b8SHong Zhang EXTERN_C_END 2104d94109b8SHong Zhang 2105aac34f13SBarry Smith #undef __FUNCT__ 2106aac34f13SBarry Smith #define __FUNCT__ "MatMPIBAIJSetPreallocationCSR_MPIBAIJ" 2107aac34f13SBarry Smith PetscErrorCode MatMPIBAIJSetPreallocationCSR_MPIBAIJ(Mat B,PetscInt bs,const PetscInt I[],const PetscInt J[],const PetscScalar v[]) 2108aac34f13SBarry Smith { 2109aac34f13SBarry Smith Mat_MPIBAIJ *b = (Mat_MPIBAIJ *)B->data; 2110aac34f13SBarry Smith PetscInt m = B->m/bs,cstart = b->cstart, cend = b->cend,j,nnz,i,d; 2111aac34f13SBarry Smith PetscInt *d_nnz,*o_nnz,nnz_max = 0,rstart = b->rstart,ii; 2112aac34f13SBarry Smith const PetscInt *JJ; 2113aac34f13SBarry Smith PetscScalar *values; 2114aac34f13SBarry Smith PetscErrorCode ierr; 2115aac34f13SBarry Smith 2116aac34f13SBarry Smith PetscFunctionBegin; 2117aac34f13SBarry Smith #if defined(PETSC_OPT_g) 2118aac34f13SBarry Smith if (I[0]) SETERRQ1(PETSC_ERR_ARG_RANGE,"I[0] must be 0 it is %D",I[0]); 2119aac34f13SBarry Smith #endif 2120aac34f13SBarry Smith ierr = PetscMalloc((2*m+1)*sizeof(PetscInt),&d_nnz);CHKERRQ(ierr); 2121aac34f13SBarry Smith o_nnz = d_nnz + m; 2122aac34f13SBarry Smith 2123aac34f13SBarry Smith for (i=0; i<m; i++) { 2124aac34f13SBarry Smith nnz = I[i+1]- I[i]; 2125aac34f13SBarry Smith JJ = J + I[i]; 2126aac34f13SBarry Smith nnz_max = PetscMax(nnz_max,nnz); 2127aac34f13SBarry Smith #if defined(PETSC_OPT_g) 2128aac34f13SBarry Smith if (nnz < 0) SETERRQ1(PETSC_ERR_ARG_RANGE,"Local row %D has a negative %D number of columns",i,nnz); 2129aac34f13SBarry Smith #endif 2130aac34f13SBarry Smith for (j=0; j<nnz; j++) { 2131aac34f13SBarry Smith if (*JJ >= cstart) break; 2132aac34f13SBarry Smith JJ++; 2133aac34f13SBarry Smith } 2134aac34f13SBarry Smith d = 0; 2135aac34f13SBarry Smith for (; j<nnz; j++) { 2136aac34f13SBarry Smith if (*JJ++ >= cend) break; 2137aac34f13SBarry Smith d++; 2138aac34f13SBarry Smith } 2139aac34f13SBarry Smith d_nnz[i] = d; 2140aac34f13SBarry Smith o_nnz[i] = nnz - d; 2141aac34f13SBarry Smith } 2142aac34f13SBarry Smith ierr = MatMPIBAIJSetPreallocation(B,bs,0,d_nnz,0,o_nnz);CHKERRQ(ierr); 2143aac34f13SBarry Smith ierr = PetscFree(d_nnz);CHKERRQ(ierr); 2144aac34f13SBarry Smith 2145aac34f13SBarry Smith if (v) values = (PetscScalar*)v; 2146aac34f13SBarry Smith else { 2147aac34f13SBarry Smith ierr = PetscMalloc(bs*bs*(nnz_max+1)*sizeof(PetscScalar),&values);CHKERRQ(ierr); 2148aac34f13SBarry Smith ierr = PetscMemzero(values,bs*bs*nnz_max*sizeof(PetscScalar));CHKERRQ(ierr); 2149aac34f13SBarry Smith } 2150aac34f13SBarry Smith 2151aac34f13SBarry Smith ierr = MatSetOption(B,MAT_COLUMNS_SORTED);CHKERRQ(ierr); 2152aac34f13SBarry Smith for (i=0; i<m; i++) { 2153aac34f13SBarry Smith ii = i + rstart; 2154aac34f13SBarry Smith nnz = I[i+1]- I[i]; 2155aac34f13SBarry Smith ierr = MatSetValuesBlocked_MPIBAIJ(B,1,&ii,nnz,J+I[i],values,INSERT_VALUES);CHKERRQ(ierr); 2156aac34f13SBarry Smith } 2157aac34f13SBarry Smith ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2158aac34f13SBarry Smith ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2159aac34f13SBarry Smith ierr = MatSetOption(B,MAT_COLUMNS_UNSORTED);CHKERRQ(ierr); 2160aac34f13SBarry Smith 2161aac34f13SBarry Smith if (!v) { 2162aac34f13SBarry Smith ierr = PetscFree(values);CHKERRQ(ierr); 2163aac34f13SBarry Smith } 2164aac34f13SBarry Smith PetscFunctionReturn(0); 2165aac34f13SBarry Smith } 2166aac34f13SBarry Smith 2167aac34f13SBarry Smith #undef __FUNCT__ 2168aac34f13SBarry Smith #define __FUNCT__ "MatMPIBAIJSetPreallocationCSR" 2169aac34f13SBarry Smith /*@C 2170aac34f13SBarry Smith MatMPIBAIJSetPreallocationCSR - Allocates memory for a sparse parallel matrix in AIJ format 2171aac34f13SBarry Smith (the default parallel PETSc format). 2172aac34f13SBarry Smith 2173aac34f13SBarry Smith Collective on MPI_Comm 2174aac34f13SBarry Smith 2175aac34f13SBarry Smith Input Parameters: 2176aac34f13SBarry Smith + A - the matrix 2177aac34f13SBarry Smith . i - the indices into j for the start of each local row (starts with zero) 2178aac34f13SBarry Smith . j - the column indices for each local row (starts with zero) these must be sorted for each row 2179aac34f13SBarry Smith - v - optional values in the matrix 2180aac34f13SBarry Smith 2181aac34f13SBarry Smith Level: developer 2182aac34f13SBarry Smith 2183aac34f13SBarry Smith .keywords: matrix, aij, compressed row, sparse, parallel 2184aac34f13SBarry Smith 2185aac34f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatMPIBAIJSetPreallocation(), MatCreateMPIAIJ(), MPIAIJ 2186aac34f13SBarry Smith @*/ 2187aac34f13SBarry Smith PetscErrorCode MatMPIBAIJSetPreallocationCSR(Mat B,PetscInt bs,const PetscInt i[],const PetscInt j[], const PetscScalar v[]) 2188aac34f13SBarry Smith { 2189aac34f13SBarry Smith PetscErrorCode ierr,(*f)(Mat,PetscInt,const PetscInt[],const PetscInt[],const PetscScalar[]); 2190aac34f13SBarry Smith 2191aac34f13SBarry Smith PetscFunctionBegin; 2192aac34f13SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)B,"MatMPIBAIJSetPreallocationCSR_C",(void (**)(void))&f);CHKERRQ(ierr); 2193aac34f13SBarry Smith if (f) { 2194aac34f13SBarry Smith ierr = (*f)(B,bs,i,j,v);CHKERRQ(ierr); 2195aac34f13SBarry Smith } 2196aac34f13SBarry Smith PetscFunctionReturn(0); 2197aac34f13SBarry Smith } 2198aac34f13SBarry Smith 2199d94109b8SHong Zhang EXTERN_C_BEGIN 22004a2ae208SSatish Balay #undef __FUNCT__ 2201a23d5eceSKris Buschelman #define __FUNCT__ "MatMPIBAIJSetPreallocation_MPIBAIJ" 2202b24ad042SBarry Smith PetscErrorCode MatMPIBAIJSetPreallocation_MPIBAIJ(Mat B,PetscInt bs,PetscInt d_nz,PetscInt *d_nnz,PetscInt o_nz,PetscInt *o_nnz) 2203a23d5eceSKris Buschelman { 2204a23d5eceSKris Buschelman Mat_MPIBAIJ *b; 2205dfbe8321SBarry Smith PetscErrorCode ierr; 2206b24ad042SBarry Smith PetscInt i; 2207a23d5eceSKris Buschelman 2208a23d5eceSKris Buschelman PetscFunctionBegin; 2209a23d5eceSKris Buschelman B->preallocated = PETSC_TRUE; 2210a23d5eceSKris Buschelman ierr = PetscOptionsGetInt(PETSC_NULL,"-mat_block_size",&bs,PETSC_NULL);CHKERRQ(ierr); 2211a23d5eceSKris Buschelman 2212a23d5eceSKris Buschelman if (bs < 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Invalid block size specified, must be positive"); 2213a23d5eceSKris Buschelman if (d_nz == PETSC_DEFAULT || d_nz == PETSC_DECIDE) d_nz = 5; 2214a23d5eceSKris Buschelman if (o_nz == PETSC_DEFAULT || o_nz == PETSC_DECIDE) o_nz = 2; 221577431f27SBarry Smith if (d_nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"d_nz cannot be less than 0: value %D",d_nz); 221677431f27SBarry Smith if (o_nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"o_nz cannot be less than 0: value %D",o_nz); 2217a23d5eceSKris Buschelman if (d_nnz) { 2218a23d5eceSKris Buschelman for (i=0; i<B->m/bs; i++) { 221977431f27SBarry Smith if (d_nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"d_nnz cannot be less than -1: local row %D value %D",i,d_nnz[i]); 2220a23d5eceSKris Buschelman } 2221a23d5eceSKris Buschelman } 2222a23d5eceSKris Buschelman if (o_nnz) { 2223a23d5eceSKris Buschelman for (i=0; i<B->m/bs; i++) { 222477431f27SBarry Smith if (o_nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"o_nnz cannot be less than -1: local row %D value %D",i,o_nnz[i]); 2225a23d5eceSKris Buschelman } 2226a23d5eceSKris Buschelman } 2227a23d5eceSKris Buschelman 2228a23d5eceSKris Buschelman ierr = PetscSplitOwnershipBlock(B->comm,bs,&B->m,&B->M);CHKERRQ(ierr); 2229a23d5eceSKris Buschelman ierr = PetscSplitOwnershipBlock(B->comm,bs,&B->n,&B->N);CHKERRQ(ierr); 2230a23d5eceSKris Buschelman ierr = PetscMapCreateMPI(B->comm,B->m,B->M,&B->rmap);CHKERRQ(ierr); 2231a23d5eceSKris Buschelman ierr = PetscMapCreateMPI(B->comm,B->n,B->N,&B->cmap);CHKERRQ(ierr); 2232a23d5eceSKris Buschelman 2233a23d5eceSKris Buschelman b = (Mat_MPIBAIJ*)B->data; 2234521d7252SBarry Smith B->bs = bs; 2235a23d5eceSKris Buschelman b->bs2 = bs*bs; 2236a23d5eceSKris Buschelman b->mbs = B->m/bs; 2237a23d5eceSKris Buschelman b->nbs = B->n/bs; 2238a23d5eceSKris Buschelman b->Mbs = B->M/bs; 2239a23d5eceSKris Buschelman b->Nbs = B->N/bs; 2240a23d5eceSKris Buschelman 2241b24ad042SBarry Smith ierr = MPI_Allgather(&b->mbs,1,MPIU_INT,b->rowners+1,1,MPIU_INT,B->comm);CHKERRQ(ierr); 2242a23d5eceSKris Buschelman b->rowners[0] = 0; 2243a23d5eceSKris Buschelman for (i=2; i<=b->size; i++) { 2244a23d5eceSKris Buschelman b->rowners[i] += b->rowners[i-1]; 2245a23d5eceSKris Buschelman } 2246a23d5eceSKris Buschelman b->rstart = b->rowners[b->rank]; 2247a23d5eceSKris Buschelman b->rend = b->rowners[b->rank+1]; 2248a23d5eceSKris Buschelman 2249b24ad042SBarry Smith ierr = MPI_Allgather(&b->nbs,1,MPIU_INT,b->cowners+1,1,MPIU_INT,B->comm);CHKERRQ(ierr); 2250a23d5eceSKris Buschelman b->cowners[0] = 0; 2251a23d5eceSKris Buschelman for (i=2; i<=b->size; i++) { 2252a23d5eceSKris Buschelman b->cowners[i] += b->cowners[i-1]; 2253a23d5eceSKris Buschelman } 2254a23d5eceSKris Buschelman b->cstart = b->cowners[b->rank]; 2255a23d5eceSKris Buschelman b->cend = b->cowners[b->rank+1]; 2256a23d5eceSKris Buschelman 2257a23d5eceSKris Buschelman for (i=0; i<=b->size; i++) { 2258a23d5eceSKris Buschelman b->rowners_bs[i] = b->rowners[i]*bs; 2259a23d5eceSKris Buschelman } 2260a23d5eceSKris Buschelman b->rstart_bs = b->rstart*bs; 2261a23d5eceSKris Buschelman b->rend_bs = b->rend*bs; 2262a23d5eceSKris Buschelman b->cstart_bs = b->cstart*bs; 2263a23d5eceSKris Buschelman b->cend_bs = b->cend*bs; 2264a23d5eceSKris Buschelman 22659c097c71SKris Buschelman ierr = MatCreate(PETSC_COMM_SELF,B->m,B->n,B->m,B->n,&b->A);CHKERRQ(ierr); 22669c097c71SKris Buschelman ierr = MatSetType(b->A,MATSEQBAIJ);CHKERRQ(ierr); 2267c60e587dSKris Buschelman ierr = MatSeqBAIJSetPreallocation(b->A,bs,d_nz,d_nnz);CHKERRQ(ierr); 226852e6d16bSBarry Smith ierr = PetscLogObjectParent(B,b->A);CHKERRQ(ierr); 22699c097c71SKris Buschelman ierr = MatCreate(PETSC_COMM_SELF,B->m,B->N,B->m,B->N,&b->B);CHKERRQ(ierr); 22709c097c71SKris Buschelman ierr = MatSetType(b->B,MATSEQBAIJ);CHKERRQ(ierr); 2271c60e587dSKris Buschelman ierr = MatSeqBAIJSetPreallocation(b->B,bs,o_nz,o_nnz);CHKERRQ(ierr); 227252e6d16bSBarry Smith ierr = PetscLogObjectParent(B,b->B);CHKERRQ(ierr); 2273c60e587dSKris Buschelman 2274a23d5eceSKris Buschelman ierr = MatStashCreate_Private(B->comm,bs,&B->bstash);CHKERRQ(ierr); 2275a23d5eceSKris Buschelman 2276a23d5eceSKris Buschelman PetscFunctionReturn(0); 2277a23d5eceSKris Buschelman } 2278a23d5eceSKris Buschelman EXTERN_C_END 2279a23d5eceSKris Buschelman 2280a23d5eceSKris Buschelman EXTERN_C_BEGIN 2281dfbe8321SBarry Smith EXTERN PetscErrorCode MatDiagonalScaleLocal_MPIBAIJ(Mat,Vec); 2282dfbe8321SBarry Smith EXTERN PetscErrorCode MatSetHashTableFactor_MPIBAIJ(Mat,PetscReal); 228392b32695SKris Buschelman EXTERN_C_END 22845bf65638SKris Buschelman 22850bad9183SKris Buschelman /*MC 2286fafad747SKris Buschelman MATMPIBAIJ - MATMPIBAIJ = "mpibaij" - A matrix type to be used for distributed block sparse matrices. 22870bad9183SKris Buschelman 22880bad9183SKris Buschelman Options Database Keys: 22890bad9183SKris Buschelman . -mat_type mpibaij - sets the matrix type to "mpibaij" during a call to MatSetFromOptions() 22900bad9183SKris Buschelman 22910bad9183SKris Buschelman Level: beginner 22920bad9183SKris Buschelman 22930bad9183SKris Buschelman .seealso: MatCreateMPIBAIJ 22940bad9183SKris Buschelman M*/ 22950bad9183SKris Buschelman 229692b32695SKris Buschelman EXTERN_C_BEGIN 2297a23d5eceSKris Buschelman #undef __FUNCT__ 22984a2ae208SSatish Balay #define __FUNCT__ "MatCreate_MPIBAIJ" 2299dfbe8321SBarry Smith PetscErrorCode MatCreate_MPIBAIJ(Mat B) 2300273d9f13SBarry Smith { 2301273d9f13SBarry Smith Mat_MPIBAIJ *b; 2302dfbe8321SBarry Smith PetscErrorCode ierr; 2303273d9f13SBarry Smith PetscTruth flg; 2304273d9f13SBarry Smith 2305273d9f13SBarry Smith PetscFunctionBegin; 230682502324SSatish Balay ierr = PetscNew(Mat_MPIBAIJ,&b);CHKERRQ(ierr); 230782502324SSatish Balay B->data = (void*)b; 230882502324SSatish Balay 2309273d9f13SBarry Smith ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 2310273d9f13SBarry Smith B->mapping = 0; 2311273d9f13SBarry Smith B->factor = 0; 2312273d9f13SBarry Smith B->assembled = PETSC_FALSE; 2313273d9f13SBarry Smith 2314273d9f13SBarry Smith B->insertmode = NOT_SET_VALUES; 2315273d9f13SBarry Smith ierr = MPI_Comm_rank(B->comm,&b->rank);CHKERRQ(ierr); 2316273d9f13SBarry Smith ierr = MPI_Comm_size(B->comm,&b->size);CHKERRQ(ierr); 2317273d9f13SBarry Smith 2318273d9f13SBarry Smith /* build local table of row and column ownerships */ 2319b24ad042SBarry Smith ierr = PetscMalloc(3*(b->size+2)*sizeof(PetscInt),&b->rowners);CHKERRQ(ierr); 232052e6d16bSBarry Smith ierr = PetscLogObjectMemory(B,3*(b->size+2)*sizeof(PetscInt)+sizeof(struct _p_Mat)+sizeof(Mat_MPIBAIJ));CHKERRQ(ierr); 2321273d9f13SBarry Smith b->cowners = b->rowners + b->size + 2; 2322273d9f13SBarry Smith b->rowners_bs = b->cowners + b->size + 2; 2323273d9f13SBarry Smith 2324273d9f13SBarry Smith /* build cache for off array entries formed */ 2325273d9f13SBarry Smith ierr = MatStashCreate_Private(B->comm,1,&B->stash);CHKERRQ(ierr); 2326273d9f13SBarry Smith b->donotstash = PETSC_FALSE; 2327273d9f13SBarry Smith b->colmap = PETSC_NULL; 2328273d9f13SBarry Smith b->garray = PETSC_NULL; 2329273d9f13SBarry Smith b->roworiented = PETSC_TRUE; 2330273d9f13SBarry Smith 2331cfce73b9SSatish Balay #if defined(PETSC_USE_MAT_SINGLE) 2332273d9f13SBarry Smith /* stuff for MatSetValues_XXX in single precision */ 233364a35ccbSBarry Smith b->setvalueslen = 0; 2334273d9f13SBarry Smith b->setvaluescopy = PETSC_NULL; 2335273d9f13SBarry Smith #endif 2336273d9f13SBarry Smith 2337273d9f13SBarry Smith /* stuff used in block assembly */ 2338273d9f13SBarry Smith b->barray = 0; 2339273d9f13SBarry Smith 2340273d9f13SBarry Smith /* stuff used for matrix vector multiply */ 2341273d9f13SBarry Smith b->lvec = 0; 2342273d9f13SBarry Smith b->Mvctx = 0; 2343273d9f13SBarry Smith 2344273d9f13SBarry Smith /* stuff for MatGetRow() */ 2345273d9f13SBarry Smith b->rowindices = 0; 2346273d9f13SBarry Smith b->rowvalues = 0; 2347273d9f13SBarry Smith b->getrowactive = PETSC_FALSE; 2348273d9f13SBarry Smith 2349273d9f13SBarry Smith /* hash table stuff */ 2350273d9f13SBarry Smith b->ht = 0; 2351273d9f13SBarry Smith b->hd = 0; 2352273d9f13SBarry Smith b->ht_size = 0; 2353273d9f13SBarry Smith b->ht_flag = PETSC_FALSE; 2354273d9f13SBarry Smith b->ht_fact = 0; 2355273d9f13SBarry Smith b->ht_total_ct = 0; 2356273d9f13SBarry Smith b->ht_insert_ct = 0; 2357273d9f13SBarry Smith 2358b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-mat_use_hash_table",&flg);CHKERRQ(ierr); 2359273d9f13SBarry Smith if (flg) { 2360f6275e2eSBarry Smith PetscReal fact = 1.39; 2361273d9f13SBarry Smith ierr = MatSetOption(B,MAT_USE_HASH_TABLE);CHKERRQ(ierr); 236287828ca2SBarry Smith ierr = PetscOptionsGetReal(PETSC_NULL,"-mat_use_hash_table",&fact,PETSC_NULL);CHKERRQ(ierr); 2363273d9f13SBarry Smith if (fact <= 1.0) fact = 1.39; 2364273d9f13SBarry Smith ierr = MatMPIBAIJSetHashTableFactor(B,fact);CHKERRQ(ierr); 236563ba0a88SBarry Smith ierr = PetscLogInfo((0,"MatCreateMPIBAIJ:Hash table Factor used %5.2f\n",fact));CHKERRQ(ierr); 2366273d9f13SBarry Smith } 2367273d9f13SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C", 2368273d9f13SBarry Smith "MatStoreValues_MPIBAIJ", 2369273d9f13SBarry Smith MatStoreValues_MPIBAIJ);CHKERRQ(ierr); 2370273d9f13SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C", 2371273d9f13SBarry Smith "MatRetrieveValues_MPIBAIJ", 2372273d9f13SBarry Smith MatRetrieveValues_MPIBAIJ);CHKERRQ(ierr); 2373273d9f13SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetDiagonalBlock_C", 2374273d9f13SBarry Smith "MatGetDiagonalBlock_MPIBAIJ", 2375273d9f13SBarry Smith MatGetDiagonalBlock_MPIBAIJ);CHKERRQ(ierr); 2376a23d5eceSKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMPIBAIJSetPreallocation_C", 2377a23d5eceSKris Buschelman "MatMPIBAIJSetPreallocation_MPIBAIJ", 2378a23d5eceSKris Buschelman MatMPIBAIJSetPreallocation_MPIBAIJ);CHKERRQ(ierr); 2379aac34f13SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMPIBAIJSetPreallocationCSR_C", 2380aac34f13SBarry Smith "MatMPIBAIJSetPreallocationCSR_MPIAIJ", 2381aac34f13SBarry Smith MatMPIBAIJSetPreallocationCSR_MPIBAIJ);CHKERRQ(ierr); 238292b32695SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatDiagonalScaleLocal_C", 238392b32695SKris Buschelman "MatDiagonalScaleLocal_MPIBAIJ", 238492b32695SKris Buschelman MatDiagonalScaleLocal_MPIBAIJ);CHKERRQ(ierr); 23855bf65638SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSetHashTableFactor_C", 23865bf65638SKris Buschelman "MatSetHashTableFactor_MPIBAIJ", 23875bf65638SKris Buschelman MatSetHashTableFactor_MPIBAIJ);CHKERRQ(ierr); 2388273d9f13SBarry Smith PetscFunctionReturn(0); 2389273d9f13SBarry Smith } 2390273d9f13SBarry Smith EXTERN_C_END 2391273d9f13SBarry Smith 2392209238afSKris Buschelman /*MC 2393002d173eSKris Buschelman MATBAIJ - MATBAIJ = "baij" - A matrix type to be used for block sparse matrices. 2394209238afSKris Buschelman 2395209238afSKris Buschelman This matrix type is identical to MATSEQBAIJ when constructed with a single process communicator, 2396209238afSKris Buschelman and MATMPIBAIJ otherwise. 2397209238afSKris Buschelman 2398209238afSKris Buschelman Options Database Keys: 2399209238afSKris Buschelman . -mat_type baij - sets the matrix type to "baij" during a call to MatSetFromOptions() 2400209238afSKris Buschelman 2401209238afSKris Buschelman Level: beginner 2402209238afSKris Buschelman 2403aac34f13SBarry Smith .seealso: MatCreateMPIBAIJ(),MATSEQBAIJ,MATMPIBAIJ, MatMPIBAIJSetPreallocation(), MatMPIBAIJSetPreallocationCSR() 2404209238afSKris Buschelman M*/ 2405209238afSKris Buschelman 2406209238afSKris Buschelman EXTERN_C_BEGIN 2407209238afSKris Buschelman #undef __FUNCT__ 2408209238afSKris Buschelman #define __FUNCT__ "MatCreate_BAIJ" 2409dfbe8321SBarry Smith PetscErrorCode MatCreate_BAIJ(Mat A) 2410dfbe8321SBarry Smith { 24116849ba73SBarry Smith PetscErrorCode ierr; 2412b24ad042SBarry Smith PetscMPIInt size; 2413209238afSKris Buschelman 2414209238afSKris Buschelman PetscFunctionBegin; 2415209238afSKris Buschelman ierr = PetscObjectChangeTypeName((PetscObject)A,MATBAIJ);CHKERRQ(ierr); 2416209238afSKris Buschelman ierr = MPI_Comm_size(A->comm,&size);CHKERRQ(ierr); 2417209238afSKris Buschelman if (size == 1) { 2418209238afSKris Buschelman ierr = MatSetType(A,MATSEQBAIJ);CHKERRQ(ierr); 2419209238afSKris Buschelman } else { 2420209238afSKris Buschelman ierr = MatSetType(A,MATMPIBAIJ);CHKERRQ(ierr); 2421209238afSKris Buschelman } 2422209238afSKris Buschelman PetscFunctionReturn(0); 2423209238afSKris Buschelman } 2424209238afSKris Buschelman EXTERN_C_END 2425209238afSKris Buschelman 24264a2ae208SSatish Balay #undef __FUNCT__ 24274a2ae208SSatish Balay #define __FUNCT__ "MatMPIBAIJSetPreallocation" 2428273d9f13SBarry Smith /*@C 2429aac34f13SBarry Smith MatMPIBAIJSetPreallocation - Allocates memory for a sparse parallel matrix in block AIJ format 2430273d9f13SBarry Smith (block compressed row). For good matrix assembly performance 2431273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameters 2432273d9f13SBarry Smith d_nz (or d_nnz) and o_nz (or o_nnz). By setting these parameters accurately, 2433273d9f13SBarry Smith performance can be increased by more than a factor of 50. 2434273d9f13SBarry Smith 2435273d9f13SBarry Smith Collective on Mat 2436273d9f13SBarry Smith 2437273d9f13SBarry Smith Input Parameters: 2438273d9f13SBarry Smith + A - the matrix 2439273d9f13SBarry Smith . bs - size of blockk 2440273d9f13SBarry Smith . d_nz - number of block nonzeros per block row in diagonal portion of local 2441273d9f13SBarry Smith submatrix (same for all local rows) 2442273d9f13SBarry Smith . d_nnz - array containing the number of block nonzeros in the various block rows 2443273d9f13SBarry Smith of the in diagonal portion of the local (possibly different for each block 2444273d9f13SBarry Smith row) or PETSC_NULL. You must leave room for the diagonal entry even if it is zero. 2445273d9f13SBarry Smith . o_nz - number of block nonzeros per block row in the off-diagonal portion of local 2446273d9f13SBarry Smith submatrix (same for all local rows). 2447273d9f13SBarry Smith - o_nnz - array containing the number of nonzeros in the various block rows of the 2448273d9f13SBarry Smith off-diagonal portion of the local submatrix (possibly different for 2449273d9f13SBarry Smith each block row) or PETSC_NULL. 2450273d9f13SBarry Smith 245149a6f317SBarry Smith If the *_nnz parameter is given then the *_nz parameter is ignored 2452273d9f13SBarry Smith 2453273d9f13SBarry Smith Options Database Keys: 2454273d9f13SBarry Smith . -mat_no_unroll - uses code that does not unroll the loops in the 2455273d9f13SBarry Smith block calculations (much slower) 2456273d9f13SBarry Smith . -mat_block_size - size of the blocks to use 2457273d9f13SBarry Smith 2458273d9f13SBarry Smith Notes: 2459273d9f13SBarry Smith If PETSC_DECIDE or PETSC_DETERMINE is used for a particular argument on one processor 2460273d9f13SBarry Smith than it must be used on all processors that share the object for that argument. 2461273d9f13SBarry Smith 2462273d9f13SBarry Smith Storage Information: 2463273d9f13SBarry Smith For a square global matrix we define each processor's diagonal portion 2464273d9f13SBarry Smith to be its local rows and the corresponding columns (a square submatrix); 2465273d9f13SBarry Smith each processor's off-diagonal portion encompasses the remainder of the 2466273d9f13SBarry Smith local matrix (a rectangular submatrix). 2467273d9f13SBarry Smith 2468273d9f13SBarry Smith The user can specify preallocated storage for the diagonal part of 2469273d9f13SBarry Smith the local submatrix with either d_nz or d_nnz (not both). Set 2470273d9f13SBarry Smith d_nz=PETSC_DEFAULT and d_nnz=PETSC_NULL for PETSc to control dynamic 2471273d9f13SBarry Smith memory allocation. Likewise, specify preallocated storage for the 2472273d9f13SBarry Smith off-diagonal part of the local submatrix with o_nz or o_nnz (not both). 2473273d9f13SBarry Smith 2474273d9f13SBarry Smith Consider a processor that owns rows 3, 4 and 5 of a parallel matrix. In 2475273d9f13SBarry Smith the figure below we depict these three local rows and all columns (0-11). 2476273d9f13SBarry Smith 2477273d9f13SBarry Smith .vb 2478273d9f13SBarry Smith 0 1 2 3 4 5 6 7 8 9 10 11 2479273d9f13SBarry Smith ------------------- 2480273d9f13SBarry Smith row 3 | o o o d d d o o o o o o 2481273d9f13SBarry Smith row 4 | o o o d d d o o o o o o 2482273d9f13SBarry Smith row 5 | o o o d d d o o o o o o 2483273d9f13SBarry Smith ------------------- 2484273d9f13SBarry Smith .ve 2485273d9f13SBarry Smith 2486273d9f13SBarry Smith Thus, any entries in the d locations are stored in the d (diagonal) 2487273d9f13SBarry Smith submatrix, and any entries in the o locations are stored in the 2488273d9f13SBarry Smith o (off-diagonal) submatrix. Note that the d and the o submatrices are 2489273d9f13SBarry Smith stored simply in the MATSEQBAIJ format for compressed row storage. 2490273d9f13SBarry Smith 2491273d9f13SBarry Smith Now d_nz should indicate the number of block nonzeros per row in the d matrix, 2492273d9f13SBarry Smith and o_nz should indicate the number of block nonzeros per row in the o matrix. 2493273d9f13SBarry Smith In general, for PDE problems in which most nonzeros are near the diagonal, 2494273d9f13SBarry Smith one expects d_nz >> o_nz. For large problems you MUST preallocate memory 2495273d9f13SBarry Smith or you will get TERRIBLE performance; see the users' manual chapter on 2496273d9f13SBarry Smith matrices. 2497273d9f13SBarry Smith 2498273d9f13SBarry Smith Level: intermediate 2499273d9f13SBarry Smith 2500273d9f13SBarry Smith .keywords: matrix, block, aij, compressed row, sparse, parallel 2501273d9f13SBarry Smith 2502aac34f13SBarry Smith .seealso: MatCreate(), MatCreateSeqBAIJ(), MatSetValues(), MatCreateMPIBAIJ(), MatMPIBAIJSetPreallocationCSR() 2503273d9f13SBarry Smith @*/ 2504b24ad042SBarry Smith PetscErrorCode MatMPIBAIJSetPreallocation(Mat B,PetscInt bs,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) 2505273d9f13SBarry Smith { 2506b24ad042SBarry Smith PetscErrorCode ierr,(*f)(Mat,PetscInt,PetscInt,const PetscInt[],PetscInt,const PetscInt[]); 2507273d9f13SBarry Smith 2508273d9f13SBarry Smith PetscFunctionBegin; 2509a23d5eceSKris Buschelman ierr = PetscObjectQueryFunction((PetscObject)B,"MatMPIBAIJSetPreallocation_C",(void (**)(void))&f);CHKERRQ(ierr); 2510a23d5eceSKris Buschelman if (f) { 2511a23d5eceSKris Buschelman ierr = (*f)(B,bs,d_nz,d_nnz,o_nz,o_nnz);CHKERRQ(ierr); 2512273d9f13SBarry Smith } 2513273d9f13SBarry Smith PetscFunctionReturn(0); 2514273d9f13SBarry Smith } 2515273d9f13SBarry Smith 25164a2ae208SSatish Balay #undef __FUNCT__ 25174a2ae208SSatish Balay #define __FUNCT__ "MatCreateMPIBAIJ" 251879bdfe76SSatish Balay /*@C 251979bdfe76SSatish Balay MatCreateMPIBAIJ - Creates a sparse parallel matrix in block AIJ format 252079bdfe76SSatish Balay (block compressed row). For good matrix assembly performance 252179bdfe76SSatish Balay the user should preallocate the matrix storage by setting the parameters 252279bdfe76SSatish Balay d_nz (or d_nnz) and o_nz (or o_nnz). By setting these parameters accurately, 252379bdfe76SSatish Balay performance can be increased by more than a factor of 50. 252479bdfe76SSatish Balay 2525db81eaa0SLois Curfman McInnes Collective on MPI_Comm 2526db81eaa0SLois Curfman McInnes 252779bdfe76SSatish Balay Input Parameters: 2528db81eaa0SLois Curfman McInnes + comm - MPI communicator 252979bdfe76SSatish Balay . bs - size of blockk 253079bdfe76SSatish Balay . m - number of local rows (or PETSC_DECIDE to have calculated if M is given) 253192e8d321SLois Curfman McInnes This value should be the same as the local size used in creating the 253292e8d321SLois Curfman McInnes y vector for the matrix-vector product y = Ax. 253392e8d321SLois Curfman McInnes . n - number of local columns (or PETSC_DECIDE to have calculated if N is given) 253492e8d321SLois Curfman McInnes This value should be the same as the local size used in creating the 253592e8d321SLois Curfman McInnes x vector for the matrix-vector product y = Ax. 2536be79a94dSBarry Smith . M - number of global rows (or PETSC_DETERMINE to have calculated if m is given) 2537be79a94dSBarry Smith . N - number of global columns (or PETSC_DETERMINE to have calculated if n is given) 253847a75d0bSBarry Smith . d_nz - number of nonzero blocks per block row in diagonal portion of local 253979bdfe76SSatish Balay submatrix (same for all local rows) 254047a75d0bSBarry Smith . d_nnz - array containing the number of nonzero blocks in the various block rows 254192e8d321SLois Curfman McInnes of the in diagonal portion of the local (possibly different for each block 2542db81eaa0SLois Curfman McInnes row) or PETSC_NULL. You must leave room for the diagonal entry even if it is zero. 254347a75d0bSBarry Smith . o_nz - number of nonzero blocks per block row in the off-diagonal portion of local 254479bdfe76SSatish Balay submatrix (same for all local rows). 254547a75d0bSBarry Smith - o_nnz - array containing the number of nonzero blocks in the various block rows of the 254692e8d321SLois Curfman McInnes off-diagonal portion of the local submatrix (possibly different for 254792e8d321SLois Curfman McInnes each block row) or PETSC_NULL. 254879bdfe76SSatish Balay 254979bdfe76SSatish Balay Output Parameter: 255079bdfe76SSatish Balay . A - the matrix 255179bdfe76SSatish Balay 2552db81eaa0SLois Curfman McInnes Options Database Keys: 2553db81eaa0SLois Curfman McInnes . -mat_no_unroll - uses code that does not unroll the loops in the 2554db81eaa0SLois Curfman McInnes block calculations (much slower) 2555db81eaa0SLois Curfman McInnes . -mat_block_size - size of the blocks to use 25563ffaccefSLois Curfman McInnes 2557b259b22eSLois Curfman McInnes Notes: 255849a6f317SBarry Smith If the *_nnz parameter is given then the *_nz parameter is ignored 255949a6f317SBarry Smith 256047a75d0bSBarry Smith A nonzero block is any block that as 1 or more nonzeros in it 256147a75d0bSBarry Smith 256279bdfe76SSatish Balay The user MUST specify either the local or global matrix dimensions 256379bdfe76SSatish Balay (possibly both). 256479bdfe76SSatish Balay 2565be79a94dSBarry Smith If PETSC_DECIDE or PETSC_DETERMINE is used for a particular argument on one processor 2566be79a94dSBarry Smith than it must be used on all processors that share the object for that argument. 2567be79a94dSBarry Smith 256879bdfe76SSatish Balay Storage Information: 256979bdfe76SSatish Balay For a square global matrix we define each processor's diagonal portion 257079bdfe76SSatish Balay to be its local rows and the corresponding columns (a square submatrix); 257179bdfe76SSatish Balay each processor's off-diagonal portion encompasses the remainder of the 257279bdfe76SSatish Balay local matrix (a rectangular submatrix). 257379bdfe76SSatish Balay 257479bdfe76SSatish Balay The user can specify preallocated storage for the diagonal part of 257579bdfe76SSatish Balay the local submatrix with either d_nz or d_nnz (not both). Set 257679bdfe76SSatish Balay d_nz=PETSC_DEFAULT and d_nnz=PETSC_NULL for PETSc to control dynamic 257779bdfe76SSatish Balay memory allocation. Likewise, specify preallocated storage for the 257879bdfe76SSatish Balay off-diagonal part of the local submatrix with o_nz or o_nnz (not both). 257979bdfe76SSatish Balay 258079bdfe76SSatish Balay Consider a processor that owns rows 3, 4 and 5 of a parallel matrix. In 258179bdfe76SSatish Balay the figure below we depict these three local rows and all columns (0-11). 258279bdfe76SSatish Balay 2583db81eaa0SLois Curfman McInnes .vb 2584db81eaa0SLois Curfman McInnes 0 1 2 3 4 5 6 7 8 9 10 11 2585db81eaa0SLois Curfman McInnes ------------------- 2586db81eaa0SLois Curfman McInnes row 3 | o o o d d d o o o o o o 2587db81eaa0SLois Curfman McInnes row 4 | o o o d d d o o o o o o 2588db81eaa0SLois Curfman McInnes row 5 | o o o d d d o o o o o o 2589db81eaa0SLois Curfman McInnes ------------------- 2590db81eaa0SLois Curfman McInnes .ve 259179bdfe76SSatish Balay 259279bdfe76SSatish Balay Thus, any entries in the d locations are stored in the d (diagonal) 259379bdfe76SSatish Balay submatrix, and any entries in the o locations are stored in the 259479bdfe76SSatish Balay o (off-diagonal) submatrix. Note that the d and the o submatrices are 259557b952d6SSatish Balay stored simply in the MATSEQBAIJ format for compressed row storage. 259679bdfe76SSatish Balay 2597d64ed03dSBarry Smith Now d_nz should indicate the number of block nonzeros per row in the d matrix, 2598d64ed03dSBarry Smith and o_nz should indicate the number of block nonzeros per row in the o matrix. 259979bdfe76SSatish Balay In general, for PDE problems in which most nonzeros are near the diagonal, 260092e8d321SLois Curfman McInnes one expects d_nz >> o_nz. For large problems you MUST preallocate memory 260192e8d321SLois Curfman McInnes or you will get TERRIBLE performance; see the users' manual chapter on 26026da5968aSLois Curfman McInnes matrices. 260379bdfe76SSatish Balay 2604027ccd11SLois Curfman McInnes Level: intermediate 2605027ccd11SLois Curfman McInnes 260692e8d321SLois Curfman McInnes .keywords: matrix, block, aij, compressed row, sparse, parallel 260779bdfe76SSatish Balay 2608aac34f13SBarry Smith .seealso: MatCreate(), MatCreateSeqBAIJ(), MatSetValues(), MatCreateMPIBAIJ(), MatMPIBAIJSetPreallocation(), MatMPIBAIJSetPreallocationCSR() 260979bdfe76SSatish Balay @*/ 2610b24ad042SBarry Smith PetscErrorCode MatCreateMPIBAIJ(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt M,PetscInt N,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[],Mat *A) 261179bdfe76SSatish Balay { 26126849ba73SBarry Smith PetscErrorCode ierr; 2613b24ad042SBarry Smith PetscMPIInt size; 261479bdfe76SSatish Balay 2615d64ed03dSBarry Smith PetscFunctionBegin; 2616273d9f13SBarry Smith ierr = MatCreate(comm,m,n,M,N,A);CHKERRQ(ierr); 2617d132466eSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 2618273d9f13SBarry Smith if (size > 1) { 2619273d9f13SBarry Smith ierr = MatSetType(*A,MATMPIBAIJ);CHKERRQ(ierr); 2620273d9f13SBarry Smith ierr = MatMPIBAIJSetPreallocation(*A,bs,d_nz,d_nnz,o_nz,o_nnz);CHKERRQ(ierr); 2621273d9f13SBarry Smith } else { 2622273d9f13SBarry Smith ierr = MatSetType(*A,MATSEQBAIJ);CHKERRQ(ierr); 2623273d9f13SBarry Smith ierr = MatSeqBAIJSetPreallocation(*A,bs,d_nz,d_nnz);CHKERRQ(ierr); 26243914022bSBarry Smith } 26253a40ed3dSBarry Smith PetscFunctionReturn(0); 262679bdfe76SSatish Balay } 2627026e39d0SSatish Balay 26284a2ae208SSatish Balay #undef __FUNCT__ 26294a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_MPIBAIJ" 26306849ba73SBarry Smith static PetscErrorCode MatDuplicate_MPIBAIJ(Mat matin,MatDuplicateOption cpvalues,Mat *newmat) 26310ac07820SSatish Balay { 26320ac07820SSatish Balay Mat mat; 26330ac07820SSatish Balay Mat_MPIBAIJ *a,*oldmat = (Mat_MPIBAIJ*)matin->data; 2634dfbe8321SBarry Smith PetscErrorCode ierr; 2635b24ad042SBarry Smith PetscInt len=0; 26360ac07820SSatish Balay 2637d64ed03dSBarry Smith PetscFunctionBegin; 26380ac07820SSatish Balay *newmat = 0; 2639273d9f13SBarry Smith ierr = MatCreate(matin->comm,matin->m,matin->n,matin->M,matin->N,&mat);CHKERRQ(ierr); 2640be5d1d56SKris Buschelman ierr = MatSetType(mat,matin->type_name);CHKERRQ(ierr); 26411d5dac46SHong Zhang ierr = PetscMemcpy(mat->ops,matin->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 26427fff6886SHong Zhang 26434beb1cfeSHong Zhang mat->factor = matin->factor; 2644273d9f13SBarry Smith mat->preallocated = PETSC_TRUE; 26450ac07820SSatish Balay mat->assembled = PETSC_TRUE; 26467fff6886SHong Zhang mat->insertmode = NOT_SET_VALUES; 26477fff6886SHong Zhang 2648273d9f13SBarry Smith a = (Mat_MPIBAIJ*)mat->data; 2649521d7252SBarry Smith mat->bs = matin->bs; 26500ac07820SSatish Balay a->bs2 = oldmat->bs2; 26510ac07820SSatish Balay a->mbs = oldmat->mbs; 26520ac07820SSatish Balay a->nbs = oldmat->nbs; 26530ac07820SSatish Balay a->Mbs = oldmat->Mbs; 26540ac07820SSatish Balay a->Nbs = oldmat->Nbs; 26550ac07820SSatish Balay 26560ac07820SSatish Balay a->rstart = oldmat->rstart; 26570ac07820SSatish Balay a->rend = oldmat->rend; 26580ac07820SSatish Balay a->cstart = oldmat->cstart; 26590ac07820SSatish Balay a->cend = oldmat->cend; 26600ac07820SSatish Balay a->size = oldmat->size; 26610ac07820SSatish Balay a->rank = oldmat->rank; 2662aef5e8e0SSatish Balay a->donotstash = oldmat->donotstash; 2663aef5e8e0SSatish Balay a->roworiented = oldmat->roworiented; 2664aef5e8e0SSatish Balay a->rowindices = 0; 26650ac07820SSatish Balay a->rowvalues = 0; 26660ac07820SSatish Balay a->getrowactive = PETSC_FALSE; 266730793edcSSatish Balay a->barray = 0; 26683123a43fSSatish Balay a->rstart_bs = oldmat->rstart_bs; 26693123a43fSSatish Balay a->rend_bs = oldmat->rend_bs; 26703123a43fSSatish Balay a->cstart_bs = oldmat->cstart_bs; 26713123a43fSSatish Balay a->cend_bs = oldmat->cend_bs; 26720ac07820SSatish Balay 2673133cdb44SSatish Balay /* hash table stuff */ 2674133cdb44SSatish Balay a->ht = 0; 2675133cdb44SSatish Balay a->hd = 0; 2676133cdb44SSatish Balay a->ht_size = 0; 2677133cdb44SSatish Balay a->ht_flag = oldmat->ht_flag; 267825fdafccSSatish Balay a->ht_fact = oldmat->ht_fact; 2679133cdb44SSatish Balay a->ht_total_ct = 0; 2680133cdb44SSatish Balay a->ht_insert_ct = 0; 2681133cdb44SSatish Balay 2682b24ad042SBarry Smith ierr = PetscMemcpy(a->rowners,oldmat->rowners,3*(a->size+2)*sizeof(PetscInt));CHKERRQ(ierr); 26838798bf22SSatish Balay ierr = MatStashCreate_Private(matin->comm,1,&mat->stash);CHKERRQ(ierr); 2684521d7252SBarry Smith ierr = MatStashCreate_Private(matin->comm,matin->bs,&mat->bstash);CHKERRQ(ierr); 26850ac07820SSatish Balay if (oldmat->colmap) { 2686aa482453SBarry Smith #if defined (PETSC_USE_CTABLE) 26870f5bd95cSBarry Smith ierr = PetscTableCreateCopy(oldmat->colmap,&a->colmap);CHKERRQ(ierr); 268848e59246SSatish Balay #else 2689b24ad042SBarry Smith ierr = PetscMalloc((a->Nbs)*sizeof(PetscInt),&a->colmap);CHKERRQ(ierr); 269052e6d16bSBarry Smith ierr = PetscLogObjectMemory(mat,(a->Nbs)*sizeof(PetscInt));CHKERRQ(ierr); 2691b24ad042SBarry Smith ierr = PetscMemcpy(a->colmap,oldmat->colmap,(a->Nbs)*sizeof(PetscInt));CHKERRQ(ierr); 269248e59246SSatish Balay #endif 26930ac07820SSatish Balay } else a->colmap = 0; 26944beb1cfeSHong Zhang 26950ac07820SSatish Balay if (oldmat->garray && (len = ((Mat_SeqBAIJ*)(oldmat->B->data))->nbs)) { 2696b24ad042SBarry Smith ierr = PetscMalloc(len*sizeof(PetscInt),&a->garray);CHKERRQ(ierr); 269752e6d16bSBarry Smith ierr = PetscLogObjectMemory(mat,len*sizeof(PetscInt));CHKERRQ(ierr); 2698b24ad042SBarry Smith ierr = PetscMemcpy(a->garray,oldmat->garray,len*sizeof(PetscInt));CHKERRQ(ierr); 26990ac07820SSatish Balay } else a->garray = 0; 27000ac07820SSatish Balay 27010ac07820SSatish Balay ierr = VecDuplicate(oldmat->lvec,&a->lvec);CHKERRQ(ierr); 270252e6d16bSBarry Smith ierr = PetscLogObjectParent(mat,a->lvec);CHKERRQ(ierr); 27030ac07820SSatish Balay ierr = VecScatterCopy(oldmat->Mvctx,&a->Mvctx);CHKERRQ(ierr); 270452e6d16bSBarry Smith ierr = PetscLogObjectParent(mat,a->Mvctx);CHKERRQ(ierr); 27057fff6886SHong Zhang 27062e8a6d31SBarry Smith ierr = MatDuplicate(oldmat->A,cpvalues,&a->A);CHKERRQ(ierr); 270752e6d16bSBarry Smith ierr = PetscLogObjectParent(mat,a->A);CHKERRQ(ierr); 27082e8a6d31SBarry Smith ierr = MatDuplicate(oldmat->B,cpvalues,&a->B);CHKERRQ(ierr); 270952e6d16bSBarry Smith ierr = PetscLogObjectParent(mat,a->B);CHKERRQ(ierr); 2710b0a32e0cSBarry Smith ierr = PetscFListDuplicate(matin->qlist,&mat->qlist);CHKERRQ(ierr); 27110ac07820SSatish Balay *newmat = mat; 27124beb1cfeSHong Zhang 27133a40ed3dSBarry Smith PetscFunctionReturn(0); 27140ac07820SSatish Balay } 271557b952d6SSatish Balay 2716e090d566SSatish Balay #include "petscsys.h" 271757b952d6SSatish Balay 27184a2ae208SSatish Balay #undef __FUNCT__ 27194a2ae208SSatish Balay #define __FUNCT__ "MatLoad_MPIBAIJ" 2720dfbe8321SBarry Smith PetscErrorCode MatLoad_MPIBAIJ(PetscViewer viewer,const MatType type,Mat *newmat) 272157b952d6SSatish Balay { 272257b952d6SSatish Balay Mat A; 27236849ba73SBarry Smith PetscErrorCode ierr; 2724b24ad042SBarry Smith int fd; 2725b24ad042SBarry Smith PetscInt i,nz,j,rstart,rend; 272687828ca2SBarry Smith PetscScalar *vals,*buf; 272757b952d6SSatish Balay MPI_Comm comm = ((PetscObject)viewer)->comm; 272857b952d6SSatish Balay MPI_Status status; 2729b24ad042SBarry Smith PetscMPIInt rank,size,maxnz; 2730b24ad042SBarry Smith PetscInt header[4],*rowlengths = 0,M,N,m,*rowners,*cols; 2731dc231df0SBarry Smith PetscInt *locrowlens,*procsnz = 0,*browners; 2732167e7480SBarry Smith PetscInt jj,*mycols,*ibuf,bs=1,Mbs,mbs,extra_rows,mmax; 2733dc231df0SBarry Smith PetscMPIInt tag = ((PetscObject)viewer)->tag; 2734b24ad042SBarry Smith PetscInt *dlens,*odlens,*mask,*masked1,*masked2,rowcount,odcount; 2735dc231df0SBarry Smith PetscInt dcount,kmax,k,nzcount,tmp,mend; 273657b952d6SSatish Balay 2737d64ed03dSBarry Smith PetscFunctionBegin; 2738b0a32e0cSBarry Smith ierr = PetscOptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,PETSC_NULL);CHKERRQ(ierr); 273957b952d6SSatish Balay 2740d132466eSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 2741d132466eSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 274257b952d6SSatish Balay if (!rank) { 2743b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 2744e5638eb3SBarry Smith ierr = PetscBinaryRead(fd,(char *)header,4,PETSC_INT);CHKERRQ(ierr); 2745552e946dSBarry Smith if (header[0] != MAT_FILE_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not matrix object"); 27466c5fab8fSBarry Smith } 2747d64ed03dSBarry Smith 2748b24ad042SBarry Smith ierr = MPI_Bcast(header+1,3,MPIU_INT,0,comm);CHKERRQ(ierr); 274957b952d6SSatish Balay M = header[1]; N = header[2]; 275057b952d6SSatish Balay 275129bbc08cSBarry Smith if (M != N) SETERRQ(PETSC_ERR_SUP,"Can only do square matrices"); 275257b952d6SSatish Balay 275357b952d6SSatish Balay /* 275457b952d6SSatish Balay This code adds extra rows to make sure the number of rows is 275557b952d6SSatish Balay divisible by the blocksize 275657b952d6SSatish Balay */ 275757b952d6SSatish Balay Mbs = M/bs; 2758dc231df0SBarry Smith extra_rows = bs - M + bs*Mbs; 275957b952d6SSatish Balay if (extra_rows == bs) extra_rows = 0; 276057b952d6SSatish Balay else Mbs++; 276157b952d6SSatish Balay if (extra_rows && !rank) { 276263ba0a88SBarry Smith ierr = PetscLogInfo((0,"MatLoad_MPIBAIJ:Padding loaded matrix to match blocksize\n"));CHKERRQ(ierr); 276357b952d6SSatish Balay } 2764537820f0SBarry Smith 276557b952d6SSatish Balay /* determine ownership of all rows */ 276657b952d6SSatish Balay mbs = Mbs/size + ((Mbs % size) > rank); 276757b952d6SSatish Balay m = mbs*bs; 2768dc231df0SBarry Smith ierr = PetscMalloc2(size+1,PetscInt,&rowners,size+1,PetscInt,&browners);CHKERRQ(ierr); 2769b24ad042SBarry Smith ierr = MPI_Allgather(&mbs,1,MPIU_INT,rowners+1,1,MPIU_INT,comm);CHKERRQ(ierr); 2770167e7480SBarry Smith 2771167e7480SBarry Smith /* process 0 needs enough room for process with most rows */ 2772167e7480SBarry Smith if (!rank) { 2773167e7480SBarry Smith mmax = rowners[1]; 2774167e7480SBarry Smith for (i=2; i<size; i++) { 2775167e7480SBarry Smith mmax = PetscMax(mmax,rowners[i]); 2776167e7480SBarry Smith } 2777ca02efcfSSatish Balay mmax*=bs; 2778167e7480SBarry Smith } else mmax = m; 2779167e7480SBarry Smith 278057b952d6SSatish Balay rowners[0] = 0; 2781cee3aa6bSSatish Balay for (i=2; i<=size; i++) rowners[i] += rowners[i-1]; 2782cee3aa6bSSatish Balay for (i=0; i<=size; i++) browners[i] = rowners[i]*bs; 278357b952d6SSatish Balay rstart = rowners[rank]; 278457b952d6SSatish Balay rend = rowners[rank+1]; 278557b952d6SSatish Balay 278657b952d6SSatish Balay /* distribute row lengths to all processors */ 278719c38ff2SBarry Smith ierr = PetscMalloc((mmax+1)*sizeof(PetscInt),&locrowlens);CHKERRQ(ierr); 278857b952d6SSatish Balay if (!rank) { 2789dc231df0SBarry Smith mend = m; 2790dc231df0SBarry Smith if (size == 1) mend = mend - extra_rows; 2791dc231df0SBarry Smith ierr = PetscBinaryRead(fd,locrowlens,mend,PETSC_INT);CHKERRQ(ierr); 2792dc231df0SBarry Smith for (j=mend; j<m; j++) locrowlens[j] = 1; 2793dc231df0SBarry Smith ierr = PetscMalloc(m*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr); 2794b24ad042SBarry Smith ierr = PetscMalloc(size*sizeof(PetscInt),&procsnz);CHKERRQ(ierr); 2795b24ad042SBarry Smith ierr = PetscMemzero(procsnz,size*sizeof(PetscInt));CHKERRQ(ierr); 2796dc231df0SBarry Smith for (j=0; j<m; j++) { 2797dc231df0SBarry Smith procsnz[0] += locrowlens[j]; 2798dc231df0SBarry Smith } 2799dc231df0SBarry Smith for (i=1; i<size; i++) { 2800dc231df0SBarry Smith mend = browners[i+1] - browners[i]; 2801dc231df0SBarry Smith if (i == size-1) mend = mend - extra_rows; 2802dc231df0SBarry Smith ierr = PetscBinaryRead(fd,rowlengths,mend,PETSC_INT);CHKERRQ(ierr); 2803dc231df0SBarry Smith for (j=mend; j<browners[i+1] - browners[i]; j++) rowlengths[j] = 1; 2804dc231df0SBarry Smith /* calculate the number of nonzeros on each processor */ 2805dc231df0SBarry Smith for (j=0; j<browners[i+1]-browners[i]; j++) { 280657b952d6SSatish Balay procsnz[i] += rowlengths[j]; 280757b952d6SSatish Balay } 2808dc231df0SBarry Smith ierr = MPI_Send(rowlengths,browners[i+1]-browners[i],MPIU_INT,i,tag,comm);CHKERRQ(ierr); 280957b952d6SSatish Balay } 2810606d414cSSatish Balay ierr = PetscFree(rowlengths);CHKERRQ(ierr); 2811dc231df0SBarry Smith } else { 2812dc231df0SBarry Smith ierr = MPI_Recv(locrowlens,m,MPIU_INT,0,tag,comm,&status);CHKERRQ(ierr); 2813dc231df0SBarry Smith } 281457b952d6SSatish Balay 2815dc231df0SBarry Smith if (!rank) { 281657b952d6SSatish Balay /* determine max buffer needed and allocate it */ 28178a8e0b3aSBarry Smith maxnz = procsnz[0]; 2818cdc0ba36SBarry Smith for (i=1; i<size; i++) { 281957b952d6SSatish Balay maxnz = PetscMax(maxnz,procsnz[i]); 282057b952d6SSatish Balay } 2821b24ad042SBarry Smith ierr = PetscMalloc(maxnz*sizeof(PetscInt),&cols);CHKERRQ(ierr); 282257b952d6SSatish Balay 282357b952d6SSatish Balay /* read in my part of the matrix column indices */ 282457b952d6SSatish Balay nz = procsnz[0]; 282519c38ff2SBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&ibuf);CHKERRQ(ierr); 282657b952d6SSatish Balay mycols = ibuf; 2827cee3aa6bSSatish Balay if (size == 1) nz -= extra_rows; 2828e5638eb3SBarry Smith ierr = PetscBinaryRead(fd,mycols,nz,PETSC_INT);CHKERRQ(ierr); 2829cee3aa6bSSatish Balay if (size == 1) for (i=0; i< extra_rows; i++) { mycols[nz+i] = M+i; } 2830cee3aa6bSSatish Balay 283157b952d6SSatish Balay /* read in every ones (except the last) and ship off */ 283257b952d6SSatish Balay for (i=1; i<size-1; i++) { 283357b952d6SSatish Balay nz = procsnz[i]; 2834e5638eb3SBarry Smith ierr = PetscBinaryRead(fd,cols,nz,PETSC_INT);CHKERRQ(ierr); 2835b24ad042SBarry Smith ierr = MPI_Send(cols,nz,MPIU_INT,i,tag,comm);CHKERRQ(ierr); 283657b952d6SSatish Balay } 283757b952d6SSatish Balay /* read in the stuff for the last proc */ 283857b952d6SSatish Balay if (size != 1) { 283957b952d6SSatish Balay nz = procsnz[size-1] - extra_rows; /* the extra rows are not on the disk */ 2840e5638eb3SBarry Smith ierr = PetscBinaryRead(fd,cols,nz,PETSC_INT);CHKERRQ(ierr); 284157b952d6SSatish Balay for (i=0; i<extra_rows; i++) cols[nz+i] = M+i; 2842b24ad042SBarry Smith ierr = MPI_Send(cols,nz+extra_rows,MPIU_INT,size-1,tag,comm);CHKERRQ(ierr); 284357b952d6SSatish Balay } 2844606d414cSSatish Balay ierr = PetscFree(cols);CHKERRQ(ierr); 2845d64ed03dSBarry Smith } else { 284657b952d6SSatish Balay /* determine buffer space needed for message */ 284757b952d6SSatish Balay nz = 0; 284857b952d6SSatish Balay for (i=0; i<m; i++) { 284957b952d6SSatish Balay nz += locrowlens[i]; 285057b952d6SSatish Balay } 285119c38ff2SBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&ibuf);CHKERRQ(ierr); 285257b952d6SSatish Balay mycols = ibuf; 285357b952d6SSatish Balay /* receive message of column indices*/ 2854b24ad042SBarry Smith ierr = MPI_Recv(mycols,nz,MPIU_INT,0,tag,comm,&status);CHKERRQ(ierr); 2855b24ad042SBarry Smith ierr = MPI_Get_count(&status,MPIU_INT,&maxnz);CHKERRQ(ierr); 285629bbc08cSBarry Smith if (maxnz != nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"something is wrong with file"); 285757b952d6SSatish Balay } 285857b952d6SSatish Balay 285957b952d6SSatish Balay /* loop over local rows, determining number of off diagonal entries */ 2860dc231df0SBarry Smith ierr = PetscMalloc2(rend-rstart,PetscInt,&dlens,rend-rstart,PetscInt,&odlens);CHKERRQ(ierr); 2861dc231df0SBarry Smith ierr = PetscMalloc3(Mbs,PetscInt,&mask,Mbs,PetscInt,&masked1,Mbs,PetscInt,&masked2);CHKERRQ(ierr); 2862dc231df0SBarry Smith ierr = PetscMemzero(mask,Mbs*sizeof(PetscInt));CHKERRQ(ierr); 2863dc231df0SBarry Smith ierr = PetscMemzero(masked1,Mbs*sizeof(PetscInt));CHKERRQ(ierr); 2864dc231df0SBarry Smith ierr = PetscMemzero(masked2,Mbs*sizeof(PetscInt));CHKERRQ(ierr); 286557b952d6SSatish Balay rowcount = 0; nzcount = 0; 286657b952d6SSatish Balay for (i=0; i<mbs; i++) { 286757b952d6SSatish Balay dcount = 0; 286857b952d6SSatish Balay odcount = 0; 286957b952d6SSatish Balay for (j=0; j<bs; j++) { 287057b952d6SSatish Balay kmax = locrowlens[rowcount]; 287157b952d6SSatish Balay for (k=0; k<kmax; k++) { 287257b952d6SSatish Balay tmp = mycols[nzcount++]/bs; 287357b952d6SSatish Balay if (!mask[tmp]) { 287457b952d6SSatish Balay mask[tmp] = 1; 287557b952d6SSatish Balay if (tmp < rstart || tmp >= rend) masked2[odcount++] = tmp; 287657b952d6SSatish Balay else masked1[dcount++] = tmp; 287757b952d6SSatish Balay } 287857b952d6SSatish Balay } 287957b952d6SSatish Balay rowcount++; 288057b952d6SSatish Balay } 2881cee3aa6bSSatish Balay 288257b952d6SSatish Balay dlens[i] = dcount; 288357b952d6SSatish Balay odlens[i] = odcount; 2884cee3aa6bSSatish Balay 288557b952d6SSatish Balay /* zero out the mask elements we set */ 288657b952d6SSatish Balay for (j=0; j<dcount; j++) mask[masked1[j]] = 0; 288757b952d6SSatish Balay for (j=0; j<odcount; j++) mask[masked2[j]] = 0; 288857b952d6SSatish Balay } 2889cee3aa6bSSatish Balay 289057b952d6SSatish Balay /* create our matrix */ 289178ae41b4SKris Buschelman ierr = MatCreate(comm,m,m,M+extra_rows,N+extra_rows,&A);CHKERRQ(ierr); 289278ae41b4SKris Buschelman ierr = MatSetType(A,type);CHKERRQ(ierr) 289378ae41b4SKris Buschelman ierr = MatMPIBAIJSetPreallocation(A,bs,0,dlens,0,odlens);CHKERRQ(ierr); 289478ae41b4SKris Buschelman 289578ae41b4SKris Buschelman /* Why doesn't this called using ierr = MatSetOption(A,MAT_COLUMNS_SORTED);CHKERRQ(ierr); */ 2896dc231df0SBarry Smith ierr = MatSetOption(A,MAT_COLUMNS_SORTED);CHKERRQ(ierr); 289757b952d6SSatish Balay 289857b952d6SSatish Balay if (!rank) { 289919c38ff2SBarry Smith ierr = PetscMalloc((maxnz+1)*sizeof(PetscScalar),&buf);CHKERRQ(ierr); 290057b952d6SSatish Balay /* read in my part of the matrix numerical values */ 290157b952d6SSatish Balay nz = procsnz[0]; 290257b952d6SSatish Balay vals = buf; 2903cee3aa6bSSatish Balay mycols = ibuf; 2904cee3aa6bSSatish Balay if (size == 1) nz -= extra_rows; 2905e5638eb3SBarry Smith ierr = PetscBinaryRead(fd,vals,nz,PETSC_SCALAR);CHKERRQ(ierr); 2906cee3aa6bSSatish Balay if (size == 1) for (i=0; i< extra_rows; i++) { vals[nz+i] = 1.0; } 2907537820f0SBarry Smith 290857b952d6SSatish Balay /* insert into matrix */ 290957b952d6SSatish Balay jj = rstart*bs; 291057b952d6SSatish Balay for (i=0; i<m; i++) { 2911dc231df0SBarry Smith ierr = MatSetValues_MPIBAIJ(A,1,&jj,locrowlens[i],mycols,vals,INSERT_VALUES);CHKERRQ(ierr); 291257b952d6SSatish Balay mycols += locrowlens[i]; 291357b952d6SSatish Balay vals += locrowlens[i]; 291457b952d6SSatish Balay jj++; 291557b952d6SSatish Balay } 291657b952d6SSatish Balay /* read in other processors (except the last one) and ship out */ 291757b952d6SSatish Balay for (i=1; i<size-1; i++) { 291857b952d6SSatish Balay nz = procsnz[i]; 291957b952d6SSatish Balay vals = buf; 2920e5638eb3SBarry Smith ierr = PetscBinaryRead(fd,vals,nz,PETSC_SCALAR);CHKERRQ(ierr); 2921ca161407SBarry Smith ierr = MPI_Send(vals,nz,MPIU_SCALAR,i,A->tag,comm);CHKERRQ(ierr); 292257b952d6SSatish Balay } 292357b952d6SSatish Balay /* the last proc */ 292457b952d6SSatish Balay if (size != 1){ 292557b952d6SSatish Balay nz = procsnz[i] - extra_rows; 2926cee3aa6bSSatish Balay vals = buf; 2927e5638eb3SBarry Smith ierr = PetscBinaryRead(fd,vals,nz,PETSC_SCALAR);CHKERRQ(ierr); 292857b952d6SSatish Balay for (i=0; i<extra_rows; i++) vals[nz+i] = 1.0; 2929ca161407SBarry Smith ierr = MPI_Send(vals,nz+extra_rows,MPIU_SCALAR,size-1,A->tag,comm);CHKERRQ(ierr); 293057b952d6SSatish Balay } 2931606d414cSSatish Balay ierr = PetscFree(procsnz);CHKERRQ(ierr); 2932d64ed03dSBarry Smith } else { 293357b952d6SSatish Balay /* receive numeric values */ 293419c38ff2SBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&buf);CHKERRQ(ierr); 293557b952d6SSatish Balay 293657b952d6SSatish Balay /* receive message of values*/ 293757b952d6SSatish Balay vals = buf; 2938cee3aa6bSSatish Balay mycols = ibuf; 2939ca161407SBarry Smith ierr = MPI_Recv(vals,nz,MPIU_SCALAR,0,A->tag,comm,&status);CHKERRQ(ierr); 2940ca161407SBarry Smith ierr = MPI_Get_count(&status,MPIU_SCALAR,&maxnz);CHKERRQ(ierr); 294129bbc08cSBarry Smith if (maxnz != nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"something is wrong with file"); 294257b952d6SSatish Balay 294357b952d6SSatish Balay /* insert into matrix */ 294457b952d6SSatish Balay jj = rstart*bs; 2945cee3aa6bSSatish Balay for (i=0; i<m; i++) { 2946dc231df0SBarry Smith ierr = MatSetValues_MPIBAIJ(A,1,&jj,locrowlens[i],mycols,vals,INSERT_VALUES);CHKERRQ(ierr); 294757b952d6SSatish Balay mycols += locrowlens[i]; 294857b952d6SSatish Balay vals += locrowlens[i]; 294957b952d6SSatish Balay jj++; 295057b952d6SSatish Balay } 295157b952d6SSatish Balay } 2952606d414cSSatish Balay ierr = PetscFree(locrowlens);CHKERRQ(ierr); 2953606d414cSSatish Balay ierr = PetscFree(buf);CHKERRQ(ierr); 2954606d414cSSatish Balay ierr = PetscFree(ibuf);CHKERRQ(ierr); 2955dc231df0SBarry Smith ierr = PetscFree2(rowners,browners);CHKERRQ(ierr); 2956dc231df0SBarry Smith ierr = PetscFree2(dlens,odlens);CHKERRQ(ierr); 2957dc231df0SBarry Smith ierr = PetscFree3(mask,masked1,masked2);CHKERRQ(ierr); 29586d4a8577SBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 29596d4a8577SBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 296078ae41b4SKris Buschelman 296178ae41b4SKris Buschelman *newmat = A; 29623a40ed3dSBarry Smith PetscFunctionReturn(0); 296357b952d6SSatish Balay } 296457b952d6SSatish Balay 29654a2ae208SSatish Balay #undef __FUNCT__ 29664a2ae208SSatish Balay #define __FUNCT__ "MatMPIBAIJSetHashTableFactor" 2967133cdb44SSatish Balay /*@ 2968133cdb44SSatish Balay MatMPIBAIJSetHashTableFactor - Sets the factor required to compute the size of the HashTable. 2969133cdb44SSatish Balay 2970133cdb44SSatish Balay Input Parameters: 2971133cdb44SSatish Balay . mat - the matrix 2972133cdb44SSatish Balay . fact - factor 2973133cdb44SSatish Balay 2974fee21e36SBarry Smith Collective on Mat 2975fee21e36SBarry Smith 29768c890885SBarry Smith Level: advanced 29778c890885SBarry Smith 2978133cdb44SSatish Balay Notes: 2979133cdb44SSatish Balay This can also be set by the command line option: -mat_use_hash_table fact 2980133cdb44SSatish Balay 2981133cdb44SSatish Balay .keywords: matrix, hashtable, factor, HT 2982133cdb44SSatish Balay 2983133cdb44SSatish Balay .seealso: MatSetOption() 2984133cdb44SSatish Balay @*/ 2985dfbe8321SBarry Smith PetscErrorCode MatMPIBAIJSetHashTableFactor(Mat mat,PetscReal fact) 2986133cdb44SSatish Balay { 2987dfbe8321SBarry Smith PetscErrorCode ierr,(*f)(Mat,PetscReal); 29885bf65638SKris Buschelman 29895bf65638SKris Buschelman PetscFunctionBegin; 29905bf65638SKris Buschelman ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSetHashTableFactor_C",(void (**)(void))&f);CHKERRQ(ierr); 29915bf65638SKris Buschelman if (f) { 29925bf65638SKris Buschelman ierr = (*f)(mat,fact);CHKERRQ(ierr); 29935bf65638SKris Buschelman } 29945bf65638SKris Buschelman PetscFunctionReturn(0); 29955bf65638SKris Buschelman } 29965bf65638SKris Buschelman 29975bf65638SKris Buschelman #undef __FUNCT__ 29985bf65638SKris Buschelman #define __FUNCT__ "MatSetHashTableFactor_MPIBAIJ" 2999dfbe8321SBarry Smith PetscErrorCode MatSetHashTableFactor_MPIBAIJ(Mat mat,PetscReal fact) 30005bf65638SKris Buschelman { 300125fdafccSSatish Balay Mat_MPIBAIJ *baij; 3002133cdb44SSatish Balay 3003133cdb44SSatish Balay PetscFunctionBegin; 3004133cdb44SSatish Balay baij = (Mat_MPIBAIJ*)mat->data; 3005133cdb44SSatish Balay baij->ht_fact = fact; 3006133cdb44SSatish Balay PetscFunctionReturn(0); 3007133cdb44SSatish Balay } 3008f2a5309cSSatish Balay 30094a2ae208SSatish Balay #undef __FUNCT__ 30104a2ae208SSatish Balay #define __FUNCT__ "MatMPIBAIJGetSeqBAIJ" 3011b24ad042SBarry Smith PetscErrorCode MatMPIBAIJGetSeqBAIJ(Mat A,Mat *Ad,Mat *Ao,PetscInt *colmap[]) 3012f2a5309cSSatish Balay { 3013f2a5309cSSatish Balay Mat_MPIBAIJ *a = (Mat_MPIBAIJ *)A->data; 3014f2a5309cSSatish Balay PetscFunctionBegin; 3015f2a5309cSSatish Balay *Ad = a->A; 3016f2a5309cSSatish Balay *Ao = a->B; 3017195d93cdSBarry Smith *colmap = a->garray; 3018f2a5309cSSatish Balay PetscFunctionReturn(0); 3019f2a5309cSSatish Balay } 3020