173f4d377SMatthew Knepley /*$Id: mmsbaij.c,v 1.10 2001/08/07 03:03:05 balay Exp $*/ 2a30f8f8cSSatish Balay 3a30f8f8cSSatish Balay /* 4a30f8f8cSSatish Balay Support for the parallel SBAIJ matrix vector multiply 5a30f8f8cSSatish Balay */ 62896befeSSatish Balay #include "src/mat/impls/sbaij/mpi/mpisbaij.h" 7a30f8f8cSSatish Balay #include "src/vec/vecimpl.h" 887828ca2SBarry Smith extern int MatSetValues_SeqSBAIJ(Mat,int,int*,int,int*,PetscScalar*,InsertMode); 9a30f8f8cSSatish Balay 104a2ae208SSatish Balay #undef __FUNCT__ 114a2ae208SSatish Balay #define __FUNCT__ "MatSetUpMultiply_MPISBAIJ" 12a30f8f8cSSatish Balay int MatSetUpMultiply_MPISBAIJ(Mat mat) 13a30f8f8cSSatish Balay { 1440781036SHong Zhang Mat_MPISBAIJ *sbaij = (Mat_MPISBAIJ*)mat->data; 1540781036SHong Zhang Mat_SeqBAIJ *B = (Mat_SeqBAIJ*)(sbaij->B->data); 1640781036SHong Zhang int Nbs = sbaij->Nbs,i,j,*indices,*aj = B->j,ierr,ec = 0,*garray,*sgarray; 1740781036SHong Zhang int bs = sbaij->bs,*stmp,mbs=sbaij->mbs, vec_size,nt; 1840781036SHong Zhang IS from,to; 1940781036SHong Zhang Vec gvec; 2040781036SHong Zhang int rank=sbaij->rank,lsize,size=sbaij->size; 21*b424e231SHong Zhang int *owners=sbaij->rowners,*sowners,*ec_owner,k; 2240781036SHong Zhang PetscMap vecmap; 2340781036SHong Zhang PetscScalar *ptr; 2440781036SHong Zhang 2540781036SHong Zhang PetscFunctionBegin; 2640781036SHong Zhang if (sbaij->lvec) { 2740781036SHong Zhang ierr = VecDestroy(sbaij->lvec);CHKERRQ(ierr); 2840781036SHong Zhang sbaij->lvec = 0; 2940781036SHong Zhang } 3040781036SHong Zhang if (sbaij->Mvctx) { 3140781036SHong Zhang ierr = VecScatterDestroy(sbaij->Mvctx);CHKERRQ(ierr); 3240781036SHong Zhang sbaij->Mvctx = 0; 3340781036SHong Zhang } 3440781036SHong Zhang 3540781036SHong Zhang /* For the first stab we make an array as long as the number of columns */ 3640781036SHong Zhang /* mark those columns that are in sbaij->B */ 3740781036SHong Zhang ierr = PetscMalloc((Nbs+1)*sizeof(int),&indices);CHKERRQ(ierr); 3840781036SHong Zhang ierr = PetscMemzero(indices,Nbs*sizeof(int));CHKERRQ(ierr); 3940781036SHong Zhang for (i=0; i<mbs; i++) { 4040781036SHong Zhang for (j=0; j<B->ilen[i]; j++) { 4140781036SHong Zhang if (!indices[aj[B->i[i] + j]]) ec++; 4240781036SHong Zhang indices[aj[B->i[i] + j] ] = 1; 4340781036SHong Zhang } 4440781036SHong Zhang } 4540781036SHong Zhang 4640781036SHong Zhang /* form arrays of columns we need */ 4740781036SHong Zhang ierr = PetscMalloc((ec+1)*sizeof(int),&garray);CHKERRQ(ierr); 4840781036SHong Zhang ierr = PetscMalloc((3*ec+1)*sizeof(int),&sgarray);CHKERRQ(ierr); 4940781036SHong Zhang ec_owner = sgarray + 2*ec; 5040781036SHong Zhang 5140781036SHong Zhang ec = 0; 5240781036SHong Zhang for (j=0; j<size; j++){ 5340781036SHong Zhang for (i=owners[j]; i<owners[j+1]; i++){ 5440781036SHong Zhang if (indices[i]) { 5540781036SHong Zhang garray[ec] = i; 5640781036SHong Zhang ec_owner[ec] = j; 5740781036SHong Zhang ec++; 5840781036SHong Zhang } 5940781036SHong Zhang } 6040781036SHong Zhang } 6140781036SHong Zhang 6240781036SHong Zhang /* make indices now point into garray */ 63*b424e231SHong Zhang for (i=0; i<ec; i++) indices[garray[i]] = i; 6440781036SHong Zhang 6540781036SHong Zhang /* compact out the extra columns in B */ 6640781036SHong Zhang for (i=0; i<mbs; i++) { 6740781036SHong Zhang for (j=0; j<B->ilen[i]; j++) aj[B->i[i] + j] = indices[aj[B->i[i] + j]]; 6840781036SHong Zhang } 6940781036SHong Zhang B->nbs = ec; 7040781036SHong Zhang sbaij->B->n = ec*B->bs; 7140781036SHong Zhang ierr = PetscFree(indices);CHKERRQ(ierr); 7240781036SHong Zhang 7340781036SHong Zhang /* create local vector that is used to scatter into */ 7440781036SHong Zhang ierr = VecCreateSeq(PETSC_COMM_SELF,ec*bs,&sbaij->lvec);CHKERRQ(ierr); 7540781036SHong Zhang 7640781036SHong Zhang /* create two temporary index sets for building scatter-gather */ 7740781036SHong Zhang ierr = PetscMalloc((2*ec+1)*sizeof(int),&stmp);CHKERRQ(ierr); 7840781036SHong Zhang for (i=0; i<ec; i++) stmp[i] = bs*garray[i]; 7940781036SHong Zhang ierr = ISCreateBlock(PETSC_COMM_SELF,bs,ec,stmp,&from);CHKERRQ(ierr); 8040781036SHong Zhang 8140781036SHong Zhang for (i=0; i<ec; i++) { stmp[i] = bs*i; } 8240781036SHong Zhang ierr = ISCreateBlock(PETSC_COMM_SELF,bs,ec,stmp,&to);CHKERRQ(ierr); 8340781036SHong Zhang 8440781036SHong Zhang /* generate the scatter context */ 8540781036SHong Zhang ierr = VecCreateMPI(mat->comm,mat->n,mat->N,&gvec);CHKERRQ(ierr); 8640781036SHong Zhang ierr = VecScatterCreate(gvec,from,sbaij->lvec,to,&sbaij->Mvctx);CHKERRQ(ierr); 8740781036SHong Zhang ierr = VecScatterPostRecvs(gvec,sbaij->lvec,INSERT_VALUES,SCATTER_FORWARD,sbaij->Mvctx);CHKERRQ(ierr); 8840781036SHong Zhang 8940781036SHong Zhang sbaij->garray = garray; 9040781036SHong Zhang PetscLogObjectParent(mat,sbaij->Mvctx); 9140781036SHong Zhang PetscLogObjectParent(mat,sbaij->lvec); 9240781036SHong Zhang PetscLogObjectParent(mat,from); 9340781036SHong Zhang PetscLogObjectParent(mat,to); 9440781036SHong Zhang 9540781036SHong Zhang ierr = ISDestroy(from);CHKERRQ(ierr); 9640781036SHong Zhang ierr = ISDestroy(to);CHKERRQ(ierr); 9740781036SHong Zhang 9840781036SHong Zhang /* create parallel vector that is used by SBAIJ matrix to scatter from/into */ 9940781036SHong Zhang lsize = (mbs + ec)*bs; 10040781036SHong Zhang ierr = VecCreateMPI(mat->comm,lsize,PETSC_DETERMINE,&sbaij->slvec0);CHKERRQ(ierr); 10140781036SHong Zhang ierr = VecDuplicate(sbaij->slvec0,&sbaij->slvec1);CHKERRQ(ierr); 10240781036SHong Zhang ierr = VecGetSize(sbaij->slvec0,&vec_size);CHKERRQ(ierr); 10340781036SHong Zhang 10440781036SHong Zhang ierr = VecGetPetscMap(sbaij->slvec0,&vecmap);CHKERRQ(ierr); 10540781036SHong Zhang ierr = PetscMapGetGlobalRange(vecmap,&sowners);CHKERRQ(ierr); 10640781036SHong Zhang 10740781036SHong Zhang /* x index in the IS sfrom */ 10840781036SHong Zhang for (i=0; i<ec; i++) { 10940781036SHong Zhang j = ec_owner[i]; 11040781036SHong Zhang sgarray[i] = garray[i] + (sowners[j]/bs - owners[j]); 11140781036SHong Zhang } 11240781036SHong Zhang /* b index in the IS sfrom */ 11340781036SHong Zhang k = sowners[rank]/bs + mbs; 11440781036SHong Zhang for (i=ec,j=0; i< 2*ec; i++,j++) sgarray[i] = k + j; 11540781036SHong Zhang 11640781036SHong Zhang for (i=0; i<2*ec; i++) stmp[i] = bs*sgarray[i]; 11740781036SHong Zhang ierr = ISCreateBlock(PETSC_COMM_SELF,bs,2*ec,stmp,&from);CHKERRQ(ierr); 11840781036SHong Zhang 11940781036SHong Zhang /* x index in the IS sto */ 12040781036SHong Zhang k = sowners[rank]/bs + mbs; 12140781036SHong Zhang for (i=0; i<ec; i++) stmp[i] = bs*(k + i); 12240781036SHong Zhang /* b index in the IS sto */ 12340781036SHong Zhang for (i=ec; i<2*ec; i++) stmp[i] = bs*sgarray[i-ec]; 12440781036SHong Zhang 12540781036SHong Zhang ierr = ISCreateBlock(PETSC_COMM_SELF,bs,2*ec,stmp,&to);CHKERRQ(ierr); 12640781036SHong Zhang 12740781036SHong Zhang /* gnerate the SBAIJ scatter context */ 12840781036SHong Zhang ierr = VecScatterCreate(sbaij->slvec0,from,sbaij->slvec1,to,&sbaij->sMvctx);CHKERRQ(ierr); 12940781036SHong Zhang 13040781036SHong Zhang /* 13140781036SHong Zhang Post the receives for the first matrix vector product. We sync-chronize after 13240781036SHong Zhang this on the chance that the user immediately calls MatMult() after assemblying 13340781036SHong Zhang the matrix. 13440781036SHong Zhang */ 13540781036SHong Zhang ierr = VecScatterPostRecvs(sbaij->slvec0,sbaij->slvec1,INSERT_VALUES,SCATTER_FORWARD,sbaij->sMvctx);CHKERRQ(ierr); 13640781036SHong Zhang 13740781036SHong Zhang ierr = VecGetLocalSize(sbaij->slvec1,&nt);CHKERRQ(ierr); 13840781036SHong Zhang ierr = VecGetArray(sbaij->slvec1,&ptr);CHKERRQ(ierr); 13940781036SHong Zhang ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,bs*mbs,ptr,&sbaij->slvec1a);CHKERRQ(ierr); 14040781036SHong Zhang ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,nt-bs*mbs,ptr+bs*mbs,&sbaij->slvec1b);CHKERRQ(ierr); 14140781036SHong Zhang ierr = VecRestoreArray(sbaij->slvec1,&ptr);CHKERRQ(ierr); 14240781036SHong Zhang 14340781036SHong Zhang ierr = VecGetArray(sbaij->slvec0,&ptr);CHKERRQ(ierr); 14440781036SHong Zhang ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,nt-bs*mbs,ptr+bs*mbs,&sbaij->slvec0b);CHKERRQ(ierr); 14540781036SHong Zhang ierr = VecRestoreArray(sbaij->slvec0,&ptr);CHKERRQ(ierr); 14640781036SHong Zhang 14740781036SHong Zhang ierr = PetscFree(stmp);CHKERRQ(ierr); 14840781036SHong Zhang ierr = MPI_Barrier(mat->comm);CHKERRQ(ierr); 14940781036SHong Zhang 15040781036SHong Zhang PetscLogObjectParent(mat,sbaij->sMvctx); 15140781036SHong Zhang PetscLogObjectParent(mat,sbaij->slvec0); 15240781036SHong Zhang PetscLogObjectParent(mat,sbaij->slvec1); 15340781036SHong Zhang PetscLogObjectParent(mat,sbaij->slvec0b); 15440781036SHong Zhang PetscLogObjectParent(mat,sbaij->slvec1a); 15540781036SHong Zhang PetscLogObjectParent(mat,sbaij->slvec1b); 15640781036SHong Zhang PetscLogObjectParent(mat,from); 15740781036SHong Zhang PetscLogObjectParent(mat,to); 15840781036SHong Zhang 15940781036SHong Zhang PetscLogObjectMemory(mat,(ec+1)*sizeof(int)); 16040781036SHong Zhang ierr = ISDestroy(from);CHKERRQ(ierr); 16140781036SHong Zhang ierr = ISDestroy(to);CHKERRQ(ierr); 16240781036SHong Zhang ierr = VecDestroy(gvec);CHKERRQ(ierr); 16340781036SHong Zhang ierr = PetscFree(sgarray);CHKERRQ(ierr); 16440781036SHong Zhang 16540781036SHong Zhang PetscFunctionReturn(0); 16640781036SHong Zhang } 16740781036SHong Zhang 16840781036SHong Zhang #undef __FUNCT__ 16940781036SHong Zhang #define __FUNCT__ "MatSetUpMultiply_MPISBAIJ_2comm" 17040781036SHong Zhang int MatSetUpMultiply_MPISBAIJ_2comm(Mat mat) 17140781036SHong Zhang { 1722896befeSSatish Balay Mat_MPISBAIJ *baij = (Mat_MPISBAIJ*)mat->data; 173a30f8f8cSSatish Balay Mat_SeqBAIJ *B = (Mat_SeqBAIJ*)(baij->B->data); 174a30f8f8cSSatish Balay int Nbs = baij->Nbs,i,j,*indices,*aj = B->j,ierr,ec = 0,*garray; 17586e15631SSatish Balay int bs = baij->bs,*stmp; 176a30f8f8cSSatish Balay IS from,to; 177a30f8f8cSSatish Balay Vec gvec; 178a30f8f8cSSatish Balay #if defined (PETSC_USE_CTABLE) 179a30f8f8cSSatish Balay PetscTable gid1_lid1; 180a30f8f8cSSatish Balay PetscTablePosition tpos; 181a30f8f8cSSatish Balay int gid,lid; 182a30f8f8cSSatish Balay #endif 183a30f8f8cSSatish Balay 184a30f8f8cSSatish Balay PetscFunctionBegin; 185a30f8f8cSSatish Balay 186a30f8f8cSSatish Balay #if defined (PETSC_USE_CTABLE) 187a30f8f8cSSatish Balay /* use a table - Mark Adams */ 188a30f8f8cSSatish Balay PetscTableCreate(B->mbs,&gid1_lid1); 189a30f8f8cSSatish Balay for (i=0; i<B->mbs; i++) { 190a30f8f8cSSatish Balay for (j=0; j<B->ilen[i]; j++) { 191a30f8f8cSSatish Balay int data,gid1 = aj[B->i[i]+j] + 1; 192a30f8f8cSSatish Balay ierr = PetscTableFind(gid1_lid1,gid1,&data) ;CHKERRQ(ierr); 193a30f8f8cSSatish Balay if (!data) { 194a30f8f8cSSatish Balay /* one based table */ 195a30f8f8cSSatish Balay ierr = PetscTableAdd(gid1_lid1,gid1,++ec);CHKERRQ(ierr); 196a30f8f8cSSatish Balay } 197a30f8f8cSSatish Balay } 198a30f8f8cSSatish Balay } 199a30f8f8cSSatish Balay /* form array of columns we need */ 200b0a32e0cSBarry Smith ierr = PetscMalloc((ec+1)*sizeof(int),&garray);CHKERRQ(ierr); 201a30f8f8cSSatish Balay ierr = PetscTableGetHeadPosition(gid1_lid1,&tpos);CHKERRQ(ierr); 202a30f8f8cSSatish Balay while (tpos) { 203a30f8f8cSSatish Balay ierr = PetscTableGetNext(gid1_lid1,&tpos,&gid,&lid);CHKERRQ(ierr); 204a30f8f8cSSatish Balay gid--; lid--; 205a30f8f8cSSatish Balay garray[lid] = gid; 206a30f8f8cSSatish Balay } 207a30f8f8cSSatish Balay ierr = PetscSortInt(ec,garray);CHKERRQ(ierr); 208a30f8f8cSSatish Balay /* qsort(garray, ec, sizeof(int), intcomparcarc); */ 209a30f8f8cSSatish Balay ierr = PetscTableRemoveAll(gid1_lid1);CHKERRQ(ierr); 210a30f8f8cSSatish Balay for (i=0; i<ec; i++) { 211a30f8f8cSSatish Balay ierr = PetscTableAdd(gid1_lid1,garray[i]+1,i+1);CHKERRQ(ierr); 212a30f8f8cSSatish Balay } 213a30f8f8cSSatish Balay /* compact out the extra columns in B */ 214a30f8f8cSSatish Balay for (i=0; i<B->mbs; i++) { 215a30f8f8cSSatish Balay for (j=0; j<B->ilen[i]; j++) { 216a30f8f8cSSatish Balay int gid1 = aj[B->i[i] + j] + 1; 217a30f8f8cSSatish Balay ierr = PetscTableFind(gid1_lid1,gid1,&lid);CHKERRQ(ierr); 218a30f8f8cSSatish Balay lid --; 219a30f8f8cSSatish Balay aj[B->i[i]+j] = lid; 220a30f8f8cSSatish Balay } 221a30f8f8cSSatish Balay } 222a30f8f8cSSatish Balay B->nbs = ec; 223273d9f13SBarry Smith baij->B->n = ec*B->bs; 224a30f8f8cSSatish Balay ierr = PetscTableDelete(gid1_lid1);CHKERRQ(ierr); 225a30f8f8cSSatish Balay /* Mark Adams */ 226a30f8f8cSSatish Balay #else 227a30f8f8cSSatish Balay /* For the first stab we make an array as long as the number of columns */ 228a30f8f8cSSatish Balay /* mark those columns that are in baij->B */ 229b0a32e0cSBarry Smith ierr = PetscMalloc((Nbs+1)*sizeof(int),&indices);CHKERRQ(ierr); 230a30f8f8cSSatish Balay ierr = PetscMemzero(indices,Nbs*sizeof(int));CHKERRQ(ierr); 231a30f8f8cSSatish Balay for (i=0; i<B->mbs; i++) { 232a30f8f8cSSatish Balay for (j=0; j<B->ilen[i]; j++) { 233a30f8f8cSSatish Balay if (!indices[aj[B->i[i] + j]]) ec++; 234a30f8f8cSSatish Balay indices[aj[B->i[i] + j] ] = 1; 235a30f8f8cSSatish Balay } 236a30f8f8cSSatish Balay } 237a30f8f8cSSatish Balay 238a30f8f8cSSatish Balay /* form array of columns we need */ 239b0a32e0cSBarry Smith ierr = PetscMalloc((ec+1)*sizeof(int),&garray);CHKERRQ(ierr); 240f3ef73ceSBarry Smith ec = 0; 241f3ef73ceSBarry Smith for (i=0; i<Nbs; i++) { 242f3ef73ceSBarry Smith if (indices[i]) { 243f3ef73ceSBarry Smith garray[ec++] = i; 244f3ef73ceSBarry Smith } 245f3ef73ceSBarry Smith } 246a30f8f8cSSatish Balay 247a30f8f8cSSatish Balay /* make indices now point into garray */ 248a30f8f8cSSatish Balay for (i=0; i<ec; i++) { 249a30f8f8cSSatish Balay indices[garray[i]] = i; 250a30f8f8cSSatish Balay } 251a30f8f8cSSatish Balay 252a30f8f8cSSatish Balay /* compact out the extra columns in B */ 253a30f8f8cSSatish Balay for (i=0; i<B->mbs; i++) { 254a30f8f8cSSatish Balay for (j=0; j<B->ilen[i]; j++) { 255a30f8f8cSSatish Balay aj[B->i[i] + j] = indices[aj[B->i[i] + j]]; 256a30f8f8cSSatish Balay } 257a30f8f8cSSatish Balay } 258a30f8f8cSSatish Balay B->nbs = ec; 259273d9f13SBarry Smith baij->B->n = ec*B->bs; 260a30f8f8cSSatish Balay ierr = PetscFree(indices);CHKERRQ(ierr); 261a30f8f8cSSatish Balay #endif 262633e10c7SHong Zhang 263a30f8f8cSSatish Balay /* create local vector that is used to scatter into */ 264a30f8f8cSSatish Balay ierr = VecCreateSeq(PETSC_COMM_SELF,ec*bs,&baij->lvec);CHKERRQ(ierr); 265a30f8f8cSSatish Balay 266a30f8f8cSSatish Balay /* create two temporary index sets for building scatter-gather */ 267eb7adc28SSatish Balay for (i=0; i<ec; i++) { 268a30f8f8cSSatish Balay garray[i] = bs*garray[i]; 269a30f8f8cSSatish Balay } 270a30f8f8cSSatish Balay ierr = ISCreateBlock(PETSC_COMM_SELF,bs,ec,garray,&from);CHKERRQ(ierr); 27186e15631SSatish Balay for (i=0; i<ec; i++) { 272a30f8f8cSSatish Balay garray[i] = garray[i]/bs; 273a30f8f8cSSatish Balay } 274a30f8f8cSSatish Balay 275b0a32e0cSBarry Smith ierr = PetscMalloc((ec+1)*sizeof(int),&stmp);CHKERRQ(ierr); 276a30f8f8cSSatish Balay for (i=0; i<ec; i++) { stmp[i] = bs*i; } 277a30f8f8cSSatish Balay ierr = ISCreateBlock(PETSC_COMM_SELF,bs,ec,stmp,&to);CHKERRQ(ierr); 278a30f8f8cSSatish Balay ierr = PetscFree(stmp);CHKERRQ(ierr); 279a30f8f8cSSatish Balay 280a30f8f8cSSatish Balay /* create temporary global vector to generate scatter context */ 281a30f8f8cSSatish Balay /* this is inefficient, but otherwise we must do either 282a30f8f8cSSatish Balay 1) save garray until the first actual scatter when the vector is known or 283a30f8f8cSSatish Balay 2) have another way of generating a scatter context without a vector.*/ 284273d9f13SBarry Smith ierr = VecCreateMPI(mat->comm,mat->n,mat->N,&gvec);CHKERRQ(ierr); 285a30f8f8cSSatish Balay 286a30f8f8cSSatish Balay /* gnerate the scatter context */ 287a30f8f8cSSatish Balay ierr = VecScatterCreate(gvec,from,baij->lvec,to,&baij->Mvctx);CHKERRQ(ierr); 288a30f8f8cSSatish Balay 289a30f8f8cSSatish Balay /* 290a30f8f8cSSatish Balay Post the receives for the first matrix vector product. We sync-chronize after 291a30f8f8cSSatish Balay this on the chance that the user immediately calls MatMult() after assemblying 292a30f8f8cSSatish Balay the matrix. 293a30f8f8cSSatish Balay */ 294a30f8f8cSSatish Balay ierr = VecScatterPostRecvs(gvec,baij->lvec,INSERT_VALUES,SCATTER_FORWARD,baij->Mvctx);CHKERRQ(ierr); 295a30f8f8cSSatish Balay ierr = MPI_Barrier(mat->comm);CHKERRQ(ierr); 296a30f8f8cSSatish Balay 297b0a32e0cSBarry Smith PetscLogObjectParent(mat,baij->Mvctx); 298b0a32e0cSBarry Smith PetscLogObjectParent(mat,baij->lvec); 299b0a32e0cSBarry Smith PetscLogObjectParent(mat,from); 300b0a32e0cSBarry Smith PetscLogObjectParent(mat,to); 301a30f8f8cSSatish Balay baij->garray = garray; 302b0a32e0cSBarry Smith PetscLogObjectMemory(mat,(ec+1)*sizeof(int)); 303a30f8f8cSSatish Balay ierr = ISDestroy(from);CHKERRQ(ierr); 304a30f8f8cSSatish Balay ierr = ISDestroy(to);CHKERRQ(ierr); 305a30f8f8cSSatish Balay ierr = VecDestroy(gvec);CHKERRQ(ierr); 306a30f8f8cSSatish Balay PetscFunctionReturn(0); 307a30f8f8cSSatish Balay } 308a30f8f8cSSatish Balay 309a30f8f8cSSatish Balay 310a30f8f8cSSatish Balay /* 311a30f8f8cSSatish Balay Takes the local part of an already assembled MPIBAIJ matrix 312a30f8f8cSSatish Balay and disassembles it. This is to allow new nonzeros into the matrix 313a30f8f8cSSatish Balay that require more communication in the matrix vector multiply. 314a30f8f8cSSatish Balay Thus certain data-structures must be rebuilt. 315a30f8f8cSSatish Balay 316a30f8f8cSSatish Balay Kind of slow! But that's what application programmers get when 317a30f8f8cSSatish Balay they are sloppy. 318a30f8f8cSSatish Balay */ 3194a2ae208SSatish Balay #undef __FUNCT__ 3204a2ae208SSatish Balay #define __FUNCT__ "DisAssemble_MPISBAIJ" 321a30f8f8cSSatish Balay int DisAssemble_MPISBAIJ(Mat A) 322a30f8f8cSSatish Balay { 3232896befeSSatish Balay Mat_MPISBAIJ *baij = (Mat_MPISBAIJ*)A->data; 324a30f8f8cSSatish Balay Mat B = baij->B,Bnew; 325a30f8f8cSSatish Balay Mat_SeqBAIJ *Bbaij = (Mat_SeqBAIJ*)B->data; 326273d9f13SBarry Smith int ierr,i,j,mbs=Bbaij->mbs,n = A->N,col,*garray=baij->garray; 327273d9f13SBarry Smith int k,bs=baij->bs,bs2=baij->bs2,*rvals,*nz,ec,m=A->m; 328a30f8f8cSSatish Balay MatScalar *a = Bbaij->a; 32987828ca2SBarry Smith PetscScalar *atmp; 33082502324SSatish Balay #if defined(PETSC_USE_MAT_SINGLE) 33182502324SSatish Balay int l; 332a30f8f8cSSatish Balay #endif 333a30f8f8cSSatish Balay 334a30f8f8cSSatish Balay PetscFunctionBegin; 33582502324SSatish Balay #if defined(PETSC_USE_MAT_SINGLE) 33687828ca2SBarry Smith ierr = PetscMalloc(baij->bs*sizeof(PetscScalar),&atmp); 33782502324SSatish Balay #endif 338a30f8f8cSSatish Balay /* free stuff related to matrix-vec multiply */ 339b0a32e0cSBarry Smith ierr = VecGetSize(baij->lvec,&ec);CHKERRQ(ierr); /* needed for PetscLogObjectMemory below */ 340a30f8f8cSSatish Balay ierr = VecDestroy(baij->lvec);CHKERRQ(ierr); baij->lvec = 0; 341a30f8f8cSSatish Balay ierr = VecScatterDestroy(baij->Mvctx);CHKERRQ(ierr); baij->Mvctx = 0; 342a30f8f8cSSatish Balay if (baij->colmap) { 343a30f8f8cSSatish Balay #if defined (PETSC_USE_CTABLE) 344a30f8f8cSSatish Balay ierr = PetscTableDelete(baij->colmap); baij->colmap = 0;CHKERRQ(ierr); 345a30f8f8cSSatish Balay #else 346a30f8f8cSSatish Balay ierr = PetscFree(baij->colmap);CHKERRQ(ierr); 347a30f8f8cSSatish Balay baij->colmap = 0; 348b0a32e0cSBarry Smith PetscLogObjectMemory(A,-Bbaij->nbs*sizeof(int)); 349a30f8f8cSSatish Balay #endif 350a30f8f8cSSatish Balay } 351a30f8f8cSSatish Balay 352a30f8f8cSSatish Balay /* make sure that B is assembled so we can access its values */ 353a30f8f8cSSatish Balay ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 354a30f8f8cSSatish Balay ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 355a30f8f8cSSatish Balay 356a30f8f8cSSatish Balay /* invent new B and copy stuff over */ 35782502324SSatish Balay ierr = PetscMalloc(mbs*sizeof(int),&nz);CHKERRQ(ierr); 358a30f8f8cSSatish Balay for (i=0; i<mbs; i++) { 359a30f8f8cSSatish Balay nz[i] = Bbaij->i[i+1]-Bbaij->i[i]; 360a30f8f8cSSatish Balay } 361a30f8f8cSSatish Balay ierr = MatCreateSeqBAIJ(PETSC_COMM_SELF,baij->bs,m,n,0,nz,&Bnew);CHKERRQ(ierr); 362a30f8f8cSSatish Balay ierr = PetscFree(nz);CHKERRQ(ierr); 363a30f8f8cSSatish Balay 36482502324SSatish Balay ierr = PetscMalloc(bs*sizeof(int),&rvals);CHKERRQ(ierr); 365a30f8f8cSSatish Balay for (i=0; i<mbs; i++) { 366a30f8f8cSSatish Balay rvals[0] = bs*i; 367a30f8f8cSSatish Balay for (j=1; j<bs; j++) { rvals[j] = rvals[j-1] + 1; } 368a30f8f8cSSatish Balay for (j=Bbaij->i[i]; j<Bbaij->i[i+1]; j++) { 369a30f8f8cSSatish Balay col = garray[Bbaij->j[j]]*bs; 370a30f8f8cSSatish Balay for (k=0; k<bs; k++) { 371a30f8f8cSSatish Balay #if defined(PETSC_USE_MAT_SINGLE) 372a30f8f8cSSatish Balay for (l=0; l<bs; l++) atmp[l] = a[j*bs2+l]; 373a30f8f8cSSatish Balay #else 37471730473SSatish Balay atmp = a+j*bs2 + k*bs; 375a30f8f8cSSatish Balay #endif 376c8407628SSatish Balay ierr = MatSetValues_SeqSBAIJ(Bnew,bs,rvals,1,&col,atmp,B->insertmode);CHKERRQ(ierr); 377a30f8f8cSSatish Balay col++; 378a30f8f8cSSatish Balay } 379a30f8f8cSSatish Balay } 380a30f8f8cSSatish Balay } 381a30f8f8cSSatish Balay #if defined(PETSC_USE_MAT_SINGLE) 382a30f8f8cSSatish Balay ierr = PetscFree(atmp);CHKERRQ(ierr); 383a30f8f8cSSatish Balay #endif 384a30f8f8cSSatish Balay ierr = PetscFree(baij->garray);CHKERRQ(ierr); 385a30f8f8cSSatish Balay baij->garray = 0; 386a30f8f8cSSatish Balay ierr = PetscFree(rvals);CHKERRQ(ierr); 387b0a32e0cSBarry Smith PetscLogObjectMemory(A,-ec*sizeof(int)); 388a30f8f8cSSatish Balay ierr = MatDestroy(B);CHKERRQ(ierr); 389b0a32e0cSBarry Smith PetscLogObjectParent(A,Bnew); 390a30f8f8cSSatish Balay baij->B = Bnew; 391a30f8f8cSSatish Balay A->was_assembled = PETSC_FALSE; 392a30f8f8cSSatish Balay PetscFunctionReturn(0); 393a30f8f8cSSatish Balay } 394a30f8f8cSSatish Balay 395a30f8f8cSSatish Balay 396a30f8f8cSSatish Balay 397