xref: /petsc/src/mat/impls/sbaij/mpi/mmsbaij.c (revision b1d4fb267e72f6b087ed013bbfbbee1418c3f503)
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"
77cff1425SSatish Balay 
87cff1425SSatish Balay extern int MatSetValues_SeqSBAIJ(Mat,int,const int [],int,const int [],const PetscScalar [],InsertMode);
97cff1425SSatish Balay 
10a30f8f8cSSatish Balay 
114a2ae208SSatish Balay #undef __FUNCT__
124a2ae208SSatish Balay #define __FUNCT__ "MatSetUpMultiply_MPISBAIJ"
13a30f8f8cSSatish Balay int MatSetUpMultiply_MPISBAIJ(Mat mat)
14a30f8f8cSSatish Balay {
1540781036SHong Zhang   Mat_MPISBAIJ       *sbaij = (Mat_MPISBAIJ*)mat->data;
1640781036SHong Zhang   Mat_SeqBAIJ        *B = (Mat_SeqBAIJ*)(sbaij->B->data);
1740781036SHong Zhang   int                Nbs = sbaij->Nbs,i,j,*indices,*aj = B->j,ierr,ec = 0,*garray,*sgarray;
1840781036SHong Zhang   int                bs = sbaij->bs,*stmp,mbs=sbaij->mbs, vec_size,nt;
1940781036SHong Zhang   IS                 from,to;
2040781036SHong Zhang   Vec                gvec;
2140781036SHong Zhang   int                rank=sbaij->rank,lsize,size=sbaij->size;
22b424e231SHong Zhang   int                *owners=sbaij->rowners,*sowners,*ec_owner,k;
2340781036SHong Zhang   PetscMap           vecmap;
2440781036SHong Zhang   PetscScalar        *ptr;
2540781036SHong Zhang 
2640781036SHong Zhang   PetscFunctionBegin;
2740781036SHong Zhang   if (sbaij->lvec) {
2840781036SHong Zhang     ierr = VecDestroy(sbaij->lvec);CHKERRQ(ierr);
2940781036SHong Zhang     sbaij->lvec = 0;
3040781036SHong Zhang   }
3140781036SHong Zhang   if (sbaij->Mvctx) {
3240781036SHong Zhang     ierr = VecScatterDestroy(sbaij->Mvctx);CHKERRQ(ierr);
3340781036SHong Zhang     sbaij->Mvctx = 0;
3440781036SHong Zhang   }
3540781036SHong Zhang 
3640781036SHong Zhang   /* For the first stab we make an array as long as the number of columns */
3740781036SHong Zhang   /* mark those columns that are in sbaij->B */
3840781036SHong Zhang   ierr = PetscMalloc((Nbs+1)*sizeof(int),&indices);CHKERRQ(ierr);
3940781036SHong Zhang   ierr = PetscMemzero(indices,Nbs*sizeof(int));CHKERRQ(ierr);
4040781036SHong Zhang   for (i=0; i<mbs; i++) {
4140781036SHong Zhang     for (j=0; j<B->ilen[i]; j++) {
4240781036SHong Zhang       if (!indices[aj[B->i[i] + j]]) ec++;
4340781036SHong Zhang       indices[aj[B->i[i] + j] ] = 1;
4440781036SHong Zhang     }
4540781036SHong Zhang   }
4640781036SHong Zhang 
4740781036SHong Zhang   /* form arrays of columns we need */
4840781036SHong Zhang   ierr = PetscMalloc((ec+1)*sizeof(int),&garray);CHKERRQ(ierr);
4940781036SHong Zhang   ierr = PetscMalloc((3*ec+1)*sizeof(int),&sgarray);CHKERRQ(ierr);
5040781036SHong Zhang   ec_owner = sgarray + 2*ec;
5140781036SHong Zhang 
5240781036SHong Zhang   ec = 0;
5340781036SHong Zhang   for (j=0; j<size; j++){
5440781036SHong Zhang     for (i=owners[j]; i<owners[j+1]; i++){
5540781036SHong Zhang       if (indices[i]) {
5640781036SHong Zhang         garray[ec]   = i;
5740781036SHong Zhang         ec_owner[ec] = j;
5840781036SHong Zhang         ec++;
5940781036SHong Zhang       }
6040781036SHong Zhang     }
6140781036SHong Zhang   }
6240781036SHong Zhang 
6340781036SHong Zhang   /* make indices now point into garray */
64b424e231SHong Zhang   for (i=0; i<ec; i++) indices[garray[i]] = i;
6540781036SHong Zhang 
6640781036SHong Zhang   /* compact out the extra columns in B */
6740781036SHong Zhang   for (i=0; i<mbs; i++) {
6840781036SHong Zhang     for (j=0; j<B->ilen[i]; j++) aj[B->i[i] + j] = indices[aj[B->i[i] + j]];
6940781036SHong Zhang   }
7040781036SHong Zhang   B->nbs       = ec;
7140781036SHong Zhang   sbaij->B->n   = ec*B->bs;
7240781036SHong Zhang   ierr = PetscFree(indices);CHKERRQ(ierr);
7340781036SHong Zhang 
7440781036SHong Zhang   /* create local vector that is used to scatter into */
7540781036SHong Zhang   ierr = VecCreateSeq(PETSC_COMM_SELF,ec*bs,&sbaij->lvec);CHKERRQ(ierr);
7640781036SHong Zhang 
7740781036SHong Zhang   /* create two temporary index sets for building scatter-gather */
7840781036SHong Zhang   ierr = PetscMalloc((2*ec+1)*sizeof(int),&stmp);CHKERRQ(ierr);
7940781036SHong Zhang   for (i=0; i<ec; i++) stmp[i] = bs*garray[i];
8040781036SHong Zhang   ierr = ISCreateBlock(PETSC_COMM_SELF,bs,ec,stmp,&from);CHKERRQ(ierr);
8140781036SHong Zhang 
8240781036SHong Zhang   for (i=0; i<ec; i++) { stmp[i] = bs*i; }
8340781036SHong Zhang   ierr = ISCreateBlock(PETSC_COMM_SELF,bs,ec,stmp,&to);CHKERRQ(ierr);
8440781036SHong Zhang 
8540781036SHong Zhang   /* generate the scatter context */
8640781036SHong Zhang   ierr = VecCreateMPI(mat->comm,mat->n,mat->N,&gvec);CHKERRQ(ierr);
8740781036SHong Zhang   ierr = VecScatterCreate(gvec,from,sbaij->lvec,to,&sbaij->Mvctx);CHKERRQ(ierr);
8840781036SHong Zhang   ierr = VecScatterPostRecvs(gvec,sbaij->lvec,INSERT_VALUES,SCATTER_FORWARD,sbaij->Mvctx);CHKERRQ(ierr);
8940781036SHong Zhang 
9040781036SHong Zhang   sbaij->garray = garray;
9140781036SHong Zhang   PetscLogObjectParent(mat,sbaij->Mvctx);
9240781036SHong Zhang   PetscLogObjectParent(mat,sbaij->lvec);
9340781036SHong Zhang   PetscLogObjectParent(mat,from);
9440781036SHong Zhang   PetscLogObjectParent(mat,to);
9540781036SHong Zhang 
9640781036SHong Zhang   ierr = ISDestroy(from);CHKERRQ(ierr);
9740781036SHong Zhang   ierr = ISDestroy(to);CHKERRQ(ierr);
9840781036SHong Zhang 
9940781036SHong Zhang   /* create parallel vector that is used by SBAIJ matrix to scatter from/into */
10040781036SHong Zhang   lsize = (mbs + ec)*bs;
10140781036SHong Zhang   ierr = VecCreateMPI(mat->comm,lsize,PETSC_DETERMINE,&sbaij->slvec0);CHKERRQ(ierr);
10240781036SHong Zhang   ierr = VecDuplicate(sbaij->slvec0,&sbaij->slvec1);CHKERRQ(ierr);
10340781036SHong Zhang   ierr = VecGetSize(sbaij->slvec0,&vec_size);CHKERRQ(ierr);
10440781036SHong Zhang 
10540781036SHong Zhang   ierr = VecGetPetscMap(sbaij->slvec0,&vecmap);CHKERRQ(ierr);
10640781036SHong Zhang   ierr = PetscMapGetGlobalRange(vecmap,&sowners);CHKERRQ(ierr);
10740781036SHong Zhang 
10840781036SHong Zhang   /* x index in the IS sfrom */
10940781036SHong Zhang   for (i=0; i<ec; i++) {
11040781036SHong Zhang     j = ec_owner[i];
11140781036SHong Zhang     sgarray[i]  = garray[i] + (sowners[j]/bs - owners[j]);
11240781036SHong Zhang   }
11340781036SHong Zhang   /* b index in the IS sfrom */
11440781036SHong Zhang   k = sowners[rank]/bs + mbs;
11540781036SHong Zhang   for (i=ec,j=0; i< 2*ec; i++,j++) sgarray[i] = k + j;
11640781036SHong Zhang 
11740781036SHong Zhang   for (i=0; i<2*ec; i++) stmp[i] = bs*sgarray[i];
11840781036SHong Zhang   ierr = ISCreateBlock(PETSC_COMM_SELF,bs,2*ec,stmp,&from);CHKERRQ(ierr);
11940781036SHong Zhang 
12040781036SHong Zhang   /* x index in the IS sto */
12140781036SHong Zhang   k = sowners[rank]/bs + mbs;
12240781036SHong Zhang   for (i=0; i<ec; i++) stmp[i] = bs*(k + i);
12340781036SHong Zhang   /* b index in the IS sto */
12440781036SHong Zhang   for (i=ec; i<2*ec; i++) stmp[i] = bs*sgarray[i-ec];
12540781036SHong Zhang 
12640781036SHong Zhang   ierr = ISCreateBlock(PETSC_COMM_SELF,bs,2*ec,stmp,&to);CHKERRQ(ierr);
12740781036SHong Zhang 
12840781036SHong Zhang   /* gnerate the SBAIJ scatter context */
12940781036SHong Zhang   ierr = VecScatterCreate(sbaij->slvec0,from,sbaij->slvec1,to,&sbaij->sMvctx);CHKERRQ(ierr);
13040781036SHong Zhang 
13140781036SHong Zhang    /*
13240781036SHong Zhang       Post the receives for the first matrix vector product. We sync-chronize after
13340781036SHong Zhang     this on the chance that the user immediately calls MatMult() after assemblying
13440781036SHong Zhang     the matrix.
13540781036SHong Zhang   */
13640781036SHong Zhang   ierr = VecScatterPostRecvs(sbaij->slvec0,sbaij->slvec1,INSERT_VALUES,SCATTER_FORWARD,sbaij->sMvctx);CHKERRQ(ierr);
13740781036SHong Zhang 
13840781036SHong Zhang   ierr = VecGetLocalSize(sbaij->slvec1,&nt);CHKERRQ(ierr);
139*b1d4fb26SBarry Smith   ierr = VecGetArrayFast(sbaij->slvec1,&ptr);CHKERRQ(ierr);
14040781036SHong Zhang   ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,bs*mbs,ptr,&sbaij->slvec1a);CHKERRQ(ierr);
14140781036SHong Zhang   ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,nt-bs*mbs,ptr+bs*mbs,&sbaij->slvec1b);CHKERRQ(ierr);
142*b1d4fb26SBarry Smith   ierr = VecRestoreArrayFast(sbaij->slvec1,&ptr);CHKERRQ(ierr);
14340781036SHong Zhang 
144*b1d4fb26SBarry Smith   ierr = VecGetArrayFast(sbaij->slvec0,&ptr);CHKERRQ(ierr);
14540781036SHong Zhang   ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,nt-bs*mbs,ptr+bs*mbs,&sbaij->slvec0b);CHKERRQ(ierr);
146*b1d4fb26SBarry Smith   ierr = VecRestoreArrayFast(sbaij->slvec0,&ptr);CHKERRQ(ierr);
14740781036SHong Zhang 
14840781036SHong Zhang   ierr = PetscFree(stmp);CHKERRQ(ierr);
14940781036SHong Zhang   ierr = MPI_Barrier(mat->comm);CHKERRQ(ierr);
15040781036SHong Zhang 
15140781036SHong Zhang   PetscLogObjectParent(mat,sbaij->sMvctx);
15240781036SHong Zhang   PetscLogObjectParent(mat,sbaij->slvec0);
15340781036SHong Zhang   PetscLogObjectParent(mat,sbaij->slvec1);
15440781036SHong Zhang   PetscLogObjectParent(mat,sbaij->slvec0b);
15540781036SHong Zhang   PetscLogObjectParent(mat,sbaij->slvec1a);
15640781036SHong Zhang   PetscLogObjectParent(mat,sbaij->slvec1b);
15740781036SHong Zhang   PetscLogObjectParent(mat,from);
15840781036SHong Zhang   PetscLogObjectParent(mat,to);
15940781036SHong Zhang 
16040781036SHong Zhang   PetscLogObjectMemory(mat,(ec+1)*sizeof(int));
16140781036SHong Zhang   ierr = ISDestroy(from);CHKERRQ(ierr);
16240781036SHong Zhang   ierr = ISDestroy(to);CHKERRQ(ierr);
16340781036SHong Zhang   ierr = VecDestroy(gvec);CHKERRQ(ierr);
16440781036SHong Zhang   ierr = PetscFree(sgarray);CHKERRQ(ierr);
16540781036SHong Zhang 
16640781036SHong Zhang   PetscFunctionReturn(0);
16740781036SHong Zhang }
16840781036SHong Zhang 
16940781036SHong Zhang #undef __FUNCT__
17040781036SHong Zhang #define __FUNCT__ "MatSetUpMultiply_MPISBAIJ_2comm"
17140781036SHong Zhang int MatSetUpMultiply_MPISBAIJ_2comm(Mat mat)
17240781036SHong Zhang {
1732896befeSSatish Balay   Mat_MPISBAIJ       *baij = (Mat_MPISBAIJ*)mat->data;
174a30f8f8cSSatish Balay   Mat_SeqBAIJ        *B = (Mat_SeqBAIJ*)(baij->B->data);
175a30f8f8cSSatish Balay   int                Nbs = baij->Nbs,i,j,*indices,*aj = B->j,ierr,ec = 0,*garray;
17686e15631SSatish Balay   int                bs = baij->bs,*stmp;
177a30f8f8cSSatish Balay   IS                 from,to;
178a30f8f8cSSatish Balay   Vec                gvec;
179a30f8f8cSSatish Balay #if defined (PETSC_USE_CTABLE)
180a30f8f8cSSatish Balay   PetscTable         gid1_lid1;
181a30f8f8cSSatish Balay   PetscTablePosition tpos;
182a30f8f8cSSatish Balay   int                gid,lid;
183a30f8f8cSSatish Balay #endif
184a30f8f8cSSatish Balay 
185a30f8f8cSSatish Balay   PetscFunctionBegin;
186a30f8f8cSSatish Balay 
187a30f8f8cSSatish Balay #if defined (PETSC_USE_CTABLE)
188a30f8f8cSSatish Balay   /* use a table - Mark Adams */
189a30f8f8cSSatish Balay   PetscTableCreate(B->mbs,&gid1_lid1);
190a30f8f8cSSatish Balay   for (i=0; i<B->mbs; i++) {
191a30f8f8cSSatish Balay     for (j=0; j<B->ilen[i]; j++) {
192a30f8f8cSSatish Balay       int data,gid1 = aj[B->i[i]+j] + 1;
193a30f8f8cSSatish Balay       ierr = PetscTableFind(gid1_lid1,gid1,&data) ;CHKERRQ(ierr);
194a30f8f8cSSatish Balay       if (!data) {
195a30f8f8cSSatish Balay         /* one based table */
196a30f8f8cSSatish Balay         ierr = PetscTableAdd(gid1_lid1,gid1,++ec);CHKERRQ(ierr);
197a30f8f8cSSatish Balay       }
198a30f8f8cSSatish Balay     }
199a30f8f8cSSatish Balay   }
200a30f8f8cSSatish Balay   /* form array of columns we need */
201b0a32e0cSBarry Smith   ierr = PetscMalloc((ec+1)*sizeof(int),&garray);CHKERRQ(ierr);
202a30f8f8cSSatish Balay   ierr = PetscTableGetHeadPosition(gid1_lid1,&tpos);CHKERRQ(ierr);
203a30f8f8cSSatish Balay   while (tpos) {
204a30f8f8cSSatish Balay     ierr = PetscTableGetNext(gid1_lid1,&tpos,&gid,&lid);CHKERRQ(ierr);
205a30f8f8cSSatish Balay     gid--; lid--;
206a30f8f8cSSatish Balay     garray[lid] = gid;
207a30f8f8cSSatish Balay   }
208a30f8f8cSSatish Balay   ierr = PetscSortInt(ec,garray);CHKERRQ(ierr);
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