xref: /petsc/src/mat/impls/sbaij/mpi/mmsbaij.c (revision ce63c4c16a990ef3f7b411630a7c76f93edb2e1f)
1a30f8f8cSSatish Balay 
2a30f8f8cSSatish Balay /*
3a30f8f8cSSatish Balay    Support for the parallel SBAIJ matrix vector multiply
4a30f8f8cSSatish Balay */
5c6db04a5SJed Brown #include <../src/mat/impls/sbaij/mpi/mpisbaij.h>
67cff1425SSatish Balay 
709573ac7SBarry Smith extern PetscErrorCode MatSetValues_SeqSBAIJ(Mat,PetscInt,const PetscInt [],PetscInt,const PetscInt [],const PetscScalar [],InsertMode);
87cff1425SSatish Balay 
9a30f8f8cSSatish Balay 
104a2ae208SSatish Balay #undef __FUNCT__
114a2ae208SSatish Balay #define __FUNCT__ "MatSetUpMultiply_MPISBAIJ"
12dfbe8321SBarry Smith PetscErrorCode 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);
166849ba73SBarry Smith   PetscErrorCode ierr;
1713f74950SBarry Smith   PetscInt       Nbs = sbaij->Nbs,i,j,*indices,*aj = B->j,ec = 0,*garray,*sgarray;
18d0f46423SBarry Smith   PetscInt       bs = mat->rmap->bs,*stmp,mbs=sbaij->mbs, vec_size,nt;
1940781036SHong Zhang   IS             from,to;
2040781036SHong Zhang   Vec            gvec;
2113f74950SBarry Smith   PetscMPIInt    rank=sbaij->rank,lsize,size=sbaij->size;
22899cda47SBarry Smith   PetscInt       *owners=sbaij->rangebs,*sowners,*ec_owner,k;
2340781036SHong Zhang   PetscScalar    *ptr;
2440781036SHong Zhang 
2540781036SHong Zhang   PetscFunctionBegin;
2601b2bd88SHong Zhang   if (sbaij->sMvctx) {
2701b2bd88SHong Zhang     /* This two lines should be in DisAssemble_MPISBAIJ(). Don't know why it causes crash there? */
2801b2bd88SHong Zhang     ierr = VecScatterDestroy(sbaij->sMvctx);CHKERRQ(ierr);
2901b2bd88SHong Zhang     sbaij->sMvctx = 0;
3040781036SHong Zhang   }
3140781036SHong Zhang 
3240781036SHong Zhang   /* For the first stab we make an array as long as the number of columns */
3340781036SHong Zhang   /* mark those columns that are in sbaij->B */
3474ed9c26SBarry Smith   ierr = PetscMalloc(Nbs*sizeof(PetscInt),&indices);CHKERRQ(ierr);
3513f74950SBarry Smith   ierr = PetscMemzero(indices,Nbs*sizeof(PetscInt));CHKERRQ(ierr);
3640781036SHong Zhang   for (i=0; i<mbs; i++) {
3740781036SHong Zhang     for (j=0; j<B->ilen[i]; j++) {
3840781036SHong Zhang       if (!indices[aj[B->i[i] + j]]) ec++;
3940781036SHong Zhang       indices[aj[B->i[i] + j] ] = 1;
4040781036SHong Zhang     }
4140781036SHong Zhang   }
4240781036SHong Zhang 
4340781036SHong Zhang   /* form arrays of columns we need */
4474ed9c26SBarry Smith   ierr = PetscMalloc(ec*sizeof(PetscInt),&garray);CHKERRQ(ierr);
4574ed9c26SBarry Smith   ierr = PetscMalloc2(2*ec,PetscInt,&sgarray,ec,PetscInt,&ec_owner);CHKERRQ(ierr);
4640781036SHong Zhang 
4740781036SHong Zhang   ec = 0;
4840781036SHong Zhang   for (j=0; j<size; j++){
4940781036SHong Zhang     for (i=owners[j]; i<owners[j+1]; i++){
5040781036SHong Zhang       if (indices[i]) {
5140781036SHong Zhang         garray[ec]   = i;
5240781036SHong Zhang         ec_owner[ec] = j;
5340781036SHong Zhang         ec++;
5440781036SHong Zhang       }
5540781036SHong Zhang     }
5640781036SHong Zhang   }
5740781036SHong Zhang 
5840781036SHong Zhang   /* make indices now point into garray */
59b424e231SHong Zhang   for (i=0; i<ec; i++) indices[garray[i]] = i;
6040781036SHong Zhang 
6140781036SHong Zhang   /* compact out the extra columns in B */
6240781036SHong Zhang   for (i=0; i<mbs; i++) {
6340781036SHong Zhang     for (j=0; j<B->ilen[i]; j++) aj[B->i[i] + j] = indices[aj[B->i[i] + j]];
6440781036SHong Zhang   }
6540781036SHong Zhang   B->nbs      = ec;
66d0f46423SBarry Smith   sbaij->B->cmap->n = sbaij->B->cmap->N = ec*mat->rmap->bs;
6726283091SBarry Smith   ierr = PetscLayoutSetUp((sbaij->B->cmap));CHKERRQ(ierr);
6840781036SHong Zhang   ierr = PetscFree(indices);CHKERRQ(ierr);
6940781036SHong Zhang 
7040781036SHong Zhang   /* create local vector that is used to scatter into */
7140781036SHong Zhang   ierr = VecCreateSeq(PETSC_COMM_SELF,ec*bs,&sbaij->lvec);CHKERRQ(ierr);
7240781036SHong Zhang 
7340781036SHong Zhang   /* create two temporary index sets for building scatter-gather */
7474ed9c26SBarry Smith   ierr = PetscMalloc(2*ec*sizeof(PetscInt),&stmp);CHKERRQ(ierr);
75deff0451SBarry Smith   ierr = ISCreateBlock(PETSC_COMM_SELF,bs,ec,garray,PETSC_COPY_VALUES,&from);CHKERRQ(ierr);
76e82e9f6bSBarry Smith   for (i=0; i<ec; i++) { stmp[i] = i; }
77deff0451SBarry Smith   ierr = ISCreateBlock(PETSC_COMM_SELF,bs,ec,stmp,PETSC_COPY_VALUES,&to);CHKERRQ(ierr);
7840781036SHong Zhang 
7993d1592dSHong Zhang   /* generate the scatter context
8093d1592dSHong Zhang      -- Mvctx and lvec are not used by MatMult_MPISBAIJ(), but usefule for some applications */
81d0f46423SBarry Smith   ierr = VecCreateMPIWithArray(((PetscObject)mat)->comm,mat->cmap->n,mat->cmap->N,PETSC_NULL,&gvec);CHKERRQ(ierr);
8240781036SHong Zhang   ierr = VecScatterCreate(gvec,from,sbaij->lvec,to,&sbaij->Mvctx);CHKERRQ(ierr);
83b5eb4454SBarry Smith   ierr = VecDestroy(gvec);CHKERRQ(ierr);
8440781036SHong Zhang 
8540781036SHong Zhang   sbaij->garray = garray;
8652e6d16bSBarry Smith   ierr = PetscLogObjectParent(mat,sbaij->Mvctx);CHKERRQ(ierr);
8752e6d16bSBarry Smith   ierr = PetscLogObjectParent(mat,sbaij->lvec);CHKERRQ(ierr);
8852e6d16bSBarry Smith   ierr = PetscLogObjectParent(mat,from);CHKERRQ(ierr);
8952e6d16bSBarry Smith   ierr = PetscLogObjectParent(mat,to);CHKERRQ(ierr);
9040781036SHong Zhang 
9140781036SHong Zhang   ierr = ISDestroy(from);CHKERRQ(ierr);
9240781036SHong Zhang   ierr = ISDestroy(to);CHKERRQ(ierr);
9340781036SHong Zhang 
9440781036SHong Zhang   /* create parallel vector that is used by SBAIJ matrix to scatter from/into */
9540781036SHong Zhang   lsize = (mbs + ec)*bs;
967adad957SLisandro Dalcin   ierr = VecCreateMPI(((PetscObject)mat)->comm,lsize,PETSC_DETERMINE,&sbaij->slvec0);CHKERRQ(ierr);
9740781036SHong Zhang   ierr = VecDuplicate(sbaij->slvec0,&sbaij->slvec1);CHKERRQ(ierr);
9840781036SHong Zhang   ierr = VecGetSize(sbaij->slvec0,&vec_size);CHKERRQ(ierr);
9940781036SHong Zhang 
100d0f46423SBarry Smith   sowners = sbaij->slvec0->map->range;
10140781036SHong Zhang 
10240781036SHong Zhang   /* x index in the IS sfrom */
10340781036SHong Zhang   for (i=0; i<ec; i++) {
10440781036SHong Zhang     j = ec_owner[i];
10540781036SHong Zhang     sgarray[i]  = garray[i] + (sowners[j]/bs - owners[j]);
10640781036SHong Zhang   }
10740781036SHong Zhang   /* b index in the IS sfrom */
10840781036SHong Zhang   k = sowners[rank]/bs + mbs;
10940781036SHong Zhang   for (i=ec,j=0; i< 2*ec; i++,j++) sgarray[i] = k + j;
110deff0451SBarry Smith   ierr = ISCreateBlock(PETSC_COMM_SELF,bs,2*ec,sgarray,PETSC_COPY_VALUES,&from);CHKERRQ(ierr);
11140781036SHong Zhang 
11240781036SHong Zhang   /* x index in the IS sto */
11340781036SHong Zhang   k = sowners[rank]/bs + mbs;
114e82e9f6bSBarry Smith   for (i=0; i<ec; i++) stmp[i] = (k + i);
11540781036SHong Zhang   /* b index in the IS sto */
116e82e9f6bSBarry Smith   for (i=ec; i<2*ec; i++) stmp[i] = sgarray[i-ec];
11740781036SHong Zhang 
118deff0451SBarry Smith   ierr = ISCreateBlock(PETSC_COMM_SELF,bs,2*ec,stmp,PETSC_COPY_VALUES,&to);CHKERRQ(ierr);
11940781036SHong Zhang 
12040781036SHong Zhang   ierr = VecScatterCreate(sbaij->slvec0,from,sbaij->slvec1,to,&sbaij->sMvctx);CHKERRQ(ierr);
12140781036SHong Zhang 
12240781036SHong Zhang   ierr = VecGetLocalSize(sbaij->slvec1,&nt);CHKERRQ(ierr);
1231ebc52fbSHong Zhang   ierr = VecGetArray(sbaij->slvec1,&ptr);CHKERRQ(ierr);
12440781036SHong Zhang   ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,bs*mbs,ptr,&sbaij->slvec1a);CHKERRQ(ierr);
12540781036SHong Zhang   ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,nt-bs*mbs,ptr+bs*mbs,&sbaij->slvec1b);CHKERRQ(ierr);
1261ebc52fbSHong Zhang   ierr = VecRestoreArray(sbaij->slvec1,&ptr);CHKERRQ(ierr);
12740781036SHong Zhang 
1281ebc52fbSHong Zhang   ierr = VecGetArray(sbaij->slvec0,&ptr);CHKERRQ(ierr);
12940781036SHong Zhang   ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,nt-bs*mbs,ptr+bs*mbs,&sbaij->slvec0b);CHKERRQ(ierr);
1301ebc52fbSHong Zhang   ierr = VecRestoreArray(sbaij->slvec0,&ptr);CHKERRQ(ierr);
13140781036SHong Zhang 
13240781036SHong Zhang   ierr = PetscFree(stmp);CHKERRQ(ierr);
1337adad957SLisandro Dalcin   ierr = MPI_Barrier(((PetscObject)mat)->comm);CHKERRQ(ierr);
13440781036SHong Zhang 
13552e6d16bSBarry Smith   ierr = PetscLogObjectParent(mat,sbaij->sMvctx);CHKERRQ(ierr);
13652e6d16bSBarry Smith   ierr = PetscLogObjectParent(mat,sbaij->slvec0);CHKERRQ(ierr);
13752e6d16bSBarry Smith   ierr = PetscLogObjectParent(mat,sbaij->slvec1);CHKERRQ(ierr);
13852e6d16bSBarry Smith   ierr = PetscLogObjectParent(mat,sbaij->slvec0b);CHKERRQ(ierr);
13952e6d16bSBarry Smith   ierr = PetscLogObjectParent(mat,sbaij->slvec1a);CHKERRQ(ierr);
14052e6d16bSBarry Smith   ierr = PetscLogObjectParent(mat,sbaij->slvec1b);CHKERRQ(ierr);
14152e6d16bSBarry Smith   ierr = PetscLogObjectParent(mat,from);CHKERRQ(ierr);
14252e6d16bSBarry Smith   ierr = PetscLogObjectParent(mat,to);CHKERRQ(ierr);
14340781036SHong Zhang 
14452e6d16bSBarry Smith   ierr = PetscLogObjectMemory(mat,(ec+1)*sizeof(PetscInt));CHKERRQ(ierr);
14540781036SHong Zhang   ierr = ISDestroy(from);CHKERRQ(ierr);
14640781036SHong Zhang   ierr = ISDestroy(to);CHKERRQ(ierr);
14774ed9c26SBarry Smith   ierr = PetscFree2(sgarray,ec_owner);CHKERRQ(ierr);
14840781036SHong Zhang   PetscFunctionReturn(0);
14940781036SHong Zhang }
15040781036SHong Zhang 
15140781036SHong Zhang #undef __FUNCT__
15240781036SHong Zhang #define __FUNCT__ "MatSetUpMultiply_MPISBAIJ_2comm"
153dfbe8321SBarry Smith PetscErrorCode MatSetUpMultiply_MPISBAIJ_2comm(Mat mat)
15440781036SHong Zhang {
1552896befeSSatish Balay   Mat_MPISBAIJ       *baij = (Mat_MPISBAIJ*)mat->data;
156a30f8f8cSSatish Balay   Mat_SeqBAIJ        *B = (Mat_SeqBAIJ*)(baij->B->data);
1576849ba73SBarry Smith   PetscErrorCode     ierr;
15813f74950SBarry Smith   PetscInt           i,j,*aj = B->j,ec = 0,*garray;
159d0f46423SBarry Smith   PetscInt           bs = mat->rmap->bs,*stmp;
160a30f8f8cSSatish Balay   IS                 from,to;
161a30f8f8cSSatish Balay   Vec                gvec;
162a30f8f8cSSatish Balay #if defined (PETSC_USE_CTABLE)
163a30f8f8cSSatish Balay   PetscTable         gid1_lid1;
164a30f8f8cSSatish Balay   PetscTablePosition tpos;
16513f74950SBarry Smith   PetscInt           gid,lid;
1666f531f54SSatish Balay #else
16713f74950SBarry Smith   PetscInt           Nbs = baij->Nbs,*indices;
168a30f8f8cSSatish Balay #endif
169a30f8f8cSSatish Balay 
170a30f8f8cSSatish Balay   PetscFunctionBegin;
171a30f8f8cSSatish Balay #if defined (PETSC_USE_CTABLE)
172a30f8f8cSSatish Balay   /* use a table - Mark Adams */
173a30f8f8cSSatish Balay   PetscTableCreate(B->mbs,&gid1_lid1);
174a30f8f8cSSatish Balay   for (i=0; i<B->mbs; i++) {
175a30f8f8cSSatish Balay     for (j=0; j<B->ilen[i]; j++) {
17613f74950SBarry Smith       PetscInt data,gid1 = aj[B->i[i]+j] + 1;
177a30f8f8cSSatish Balay       ierr = PetscTableFind(gid1_lid1,gid1,&data);CHKERRQ(ierr);
178a30f8f8cSSatish Balay       if (!data) {
179a30f8f8cSSatish Balay         /* one based table */
180a30f8f8cSSatish Balay         ierr = PetscTableAdd(gid1_lid1,gid1,++ec);CHKERRQ(ierr);
181a30f8f8cSSatish Balay       }
182a30f8f8cSSatish Balay     }
183a30f8f8cSSatish Balay   }
184a30f8f8cSSatish Balay   /* form array of columns we need */
18574ed9c26SBarry Smith   ierr = PetscMalloc(ec*sizeof(PetscInt),&garray);CHKERRQ(ierr);
186a30f8f8cSSatish Balay   ierr = PetscTableGetHeadPosition(gid1_lid1,&tpos);CHKERRQ(ierr);
187a30f8f8cSSatish Balay   while (tpos) {
188a30f8f8cSSatish Balay     ierr = PetscTableGetNext(gid1_lid1,&tpos,&gid,&lid);CHKERRQ(ierr);
189a30f8f8cSSatish Balay     gid--; lid--;
190a30f8f8cSSatish Balay     garray[lid] = gid;
191a30f8f8cSSatish Balay   }
192a30f8f8cSSatish Balay   ierr = PetscSortInt(ec,garray);CHKERRQ(ierr);
193a30f8f8cSSatish Balay   ierr = PetscTableRemoveAll(gid1_lid1);CHKERRQ(ierr);
194a30f8f8cSSatish Balay   for (i=0; i<ec; i++) {
195a30f8f8cSSatish Balay     ierr = PetscTableAdd(gid1_lid1,garray[i]+1,i+1);CHKERRQ(ierr);
196a30f8f8cSSatish Balay   }
197a30f8f8cSSatish Balay   /* compact out the extra columns in B */
198a30f8f8cSSatish Balay   for (i=0; i<B->mbs; i++) {
199a30f8f8cSSatish Balay     for (j=0; j<B->ilen[i]; j++) {
20013f74950SBarry Smith       PetscInt gid1 = aj[B->i[i] + j] + 1;
201a30f8f8cSSatish Balay       ierr = PetscTableFind(gid1_lid1,gid1,&lid);CHKERRQ(ierr);
202a30f8f8cSSatish Balay       lid --;
203a30f8f8cSSatish Balay       aj[B->i[i]+j] = lid;
204a30f8f8cSSatish Balay     }
205a30f8f8cSSatish Balay   }
206a30f8f8cSSatish Balay   B->nbs     = ec;
207d0f46423SBarry Smith   baij->B->cmap->n = baij->B->cmap->N = ec*mat->rmap->bs;
20826283091SBarry Smith   ierr = PetscLayoutSetUp((baij->B->cmap));CHKERRQ(ierr);
2099c666560SBarry Smith   ierr = PetscTableDestroy(gid1_lid1);CHKERRQ(ierr);
210a30f8f8cSSatish Balay   /* Mark Adams */
211a30f8f8cSSatish Balay #else
212a30f8f8cSSatish Balay   /* For the first stab we make an array as long as the number of columns */
213a30f8f8cSSatish Balay   /* mark those columns that are in baij->B */
21474ed9c26SBarry Smith   ierr = PetscMalloc(Nbs*sizeof(PetscInt),&indices);CHKERRQ(ierr);
21513f74950SBarry Smith   ierr = PetscMemzero(indices,Nbs*sizeof(PetscInt));CHKERRQ(ierr);
216a30f8f8cSSatish Balay   for (i=0; i<B->mbs; i++) {
217a30f8f8cSSatish Balay     for (j=0; j<B->ilen[i]; j++) {
218a30f8f8cSSatish Balay       if (!indices[aj[B->i[i] + j]]) ec++;
219a30f8f8cSSatish Balay       indices[aj[B->i[i] + j] ] = 1;
220a30f8f8cSSatish Balay     }
221a30f8f8cSSatish Balay   }
222a30f8f8cSSatish Balay 
223a30f8f8cSSatish Balay   /* form array of columns we need */
22474ed9c26SBarry Smith   ierr = PetscMalloc(ec*sizeof(PetscInt),&garray);CHKERRQ(ierr);
225f3ef73ceSBarry Smith   ec = 0;
226f3ef73ceSBarry Smith   for (i=0; i<Nbs; i++) {
227f3ef73ceSBarry Smith     if (indices[i]) {
228f3ef73ceSBarry Smith       garray[ec++] = i;
229f3ef73ceSBarry Smith     }
230f3ef73ceSBarry Smith   }
231a30f8f8cSSatish Balay 
232a30f8f8cSSatish Balay   /* make indices now point into garray */
233a30f8f8cSSatish Balay   for (i=0; i<ec; i++) {
234a30f8f8cSSatish Balay     indices[garray[i]] = i;
235a30f8f8cSSatish Balay   }
236a30f8f8cSSatish Balay 
237a30f8f8cSSatish Balay   /* compact out the extra columns in B */
238a30f8f8cSSatish Balay   for (i=0; i<B->mbs; i++) {
239a30f8f8cSSatish Balay     for (j=0; j<B->ilen[i]; j++) {
240a30f8f8cSSatish Balay       aj[B->i[i] + j] = indices[aj[B->i[i] + j]];
241a30f8f8cSSatish Balay     }
242a30f8f8cSSatish Balay   }
243a30f8f8cSSatish Balay   B->nbs       = ec;
244d0f46423SBarry Smith   baij->B->cmap->n   = ec*mat->rmap->bs;
245a30f8f8cSSatish Balay   ierr = PetscFree(indices);CHKERRQ(ierr);
246a30f8f8cSSatish Balay #endif
247633e10c7SHong Zhang 
248a30f8f8cSSatish Balay   /* create local vector that is used to scatter into */
249a30f8f8cSSatish Balay   ierr = VecCreateSeq(PETSC_COMM_SELF,ec*bs,&baij->lvec);CHKERRQ(ierr);
250a30f8f8cSSatish Balay 
251a30f8f8cSSatish Balay   /* create two temporary index sets for building scatter-gather */
252deff0451SBarry Smith   ierr = ISCreateBlock(PETSC_COMM_SELF,bs,ec,garray,PETSC_COPY_VALUES,&from);CHKERRQ(ierr);
253a30f8f8cSSatish Balay 
25474ed9c26SBarry Smith   ierr = PetscMalloc(ec*sizeof(PetscInt),&stmp);CHKERRQ(ierr);
255e82e9f6bSBarry Smith   for (i=0; i<ec; i++) { stmp[i] = i; }
256deff0451SBarry Smith   ierr = ISCreateBlock(PETSC_COMM_SELF,bs,ec,stmp,PETSC_OWN_POINTER,&to);CHKERRQ(ierr);
257a30f8f8cSSatish Balay 
258a30f8f8cSSatish Balay   /* create temporary global vector to generate scatter context */
259d0f46423SBarry Smith   ierr = VecCreateMPIWithArray(((PetscObject)mat)->comm,mat->cmap->n,mat->cmap->N,PETSC_NULL,&gvec);CHKERRQ(ierr);
260a30f8f8cSSatish Balay   ierr = VecScatterCreate(gvec,from,baij->lvec,to,&baij->Mvctx);CHKERRQ(ierr);
261b5eb4454SBarry Smith   ierr = VecDestroy(gvec);CHKERRQ(ierr);
262a30f8f8cSSatish Balay 
26352e6d16bSBarry Smith   ierr = PetscLogObjectParent(mat,baij->Mvctx);CHKERRQ(ierr);
26452e6d16bSBarry Smith   ierr = PetscLogObjectParent(mat,baij->lvec);CHKERRQ(ierr);
26552e6d16bSBarry Smith   ierr = PetscLogObjectParent(mat,from);CHKERRQ(ierr);
26652e6d16bSBarry Smith   ierr = PetscLogObjectParent(mat,to);CHKERRQ(ierr);
267a30f8f8cSSatish Balay   baij->garray = garray;
26852e6d16bSBarry Smith   ierr = PetscLogObjectMemory(mat,(ec+1)*sizeof(PetscInt));CHKERRQ(ierr);
269a30f8f8cSSatish Balay   ierr = ISDestroy(from);CHKERRQ(ierr);
270a30f8f8cSSatish Balay   ierr = ISDestroy(to);CHKERRQ(ierr);
271a30f8f8cSSatish Balay   PetscFunctionReturn(0);
272a30f8f8cSSatish Balay }
273a30f8f8cSSatish Balay 
274a30f8f8cSSatish Balay /*
27501b2bd88SHong Zhang      Takes the local part of an already assembled MPISBAIJ matrix
276a30f8f8cSSatish Balay    and disassembles it. This is to allow new nonzeros into the matrix
277a30f8f8cSSatish Balay    that require more communication in the matrix vector multiply.
278a30f8f8cSSatish Balay    Thus certain data-structures must be rebuilt.
279a30f8f8cSSatish Balay 
280a30f8f8cSSatish Balay    Kind of slow! But that's what application programmers get when
281a30f8f8cSSatish Balay    they are sloppy.
282a30f8f8cSSatish Balay */
2834a2ae208SSatish Balay #undef __FUNCT__
2844a2ae208SSatish Balay #define __FUNCT__ "DisAssemble_MPISBAIJ"
285dfbe8321SBarry Smith PetscErrorCode DisAssemble_MPISBAIJ(Mat A)
286a30f8f8cSSatish Balay {
2872896befeSSatish Balay   Mat_MPISBAIJ   *baij = (Mat_MPISBAIJ*)A->data;
288a30f8f8cSSatish Balay   Mat            B = baij->B,Bnew;
289a30f8f8cSSatish Balay   Mat_SeqBAIJ    *Bbaij = (Mat_SeqBAIJ*)B->data;
290dfbe8321SBarry Smith   PetscErrorCode ierr;
291d0f46423SBarry Smith   PetscInt       i,j,mbs=Bbaij->mbs,n = A->cmap->N,col,*garray=baij->garray;
292d0f46423SBarry Smith   PetscInt       k,bs=A->rmap->bs,bs2=baij->bs2,*rvals,*nz,ec,m=A->rmap->n;
293a30f8f8cSSatish Balay   MatScalar      *a = Bbaij->a;
29487828ca2SBarry Smith   PetscScalar    *atmp;
295*ce63c4c1SBarry Smith #if defined(PETSC_USE_REAL_MAT_SINGLE)
29613f74950SBarry Smith   PetscInt       l;
297a30f8f8cSSatish Balay #endif
298a30f8f8cSSatish Balay 
299a30f8f8cSSatish Balay   PetscFunctionBegin;
300*ce63c4c1SBarry Smith #if defined(PETSC_USE_REAL_MAT_SINGLE)
301d0f46423SBarry Smith   ierr = PetscMalloc(A->rmap->bs*sizeof(PetscScalar),&atmp);
30282502324SSatish Balay #endif
303a30f8f8cSSatish Balay   /* free stuff related to matrix-vec multiply */
304b0a32e0cSBarry Smith   ierr = VecGetSize(baij->lvec,&ec);CHKERRQ(ierr); /* needed for PetscLogObjectMemory below */
30501b2bd88SHong Zhang   ierr = VecDestroy(baij->lvec);CHKERRQ(ierr);
30601b2bd88SHong Zhang   baij->lvec = 0;
30701b2bd88SHong Zhang   ierr = VecScatterDestroy(baij->Mvctx);CHKERRQ(ierr);
30801b2bd88SHong Zhang   baij->Mvctx = 0;
30901b2bd88SHong Zhang 
31001b2bd88SHong Zhang   ierr = VecDestroy(baij->slvec0);CHKERRQ(ierr);
31101b2bd88SHong Zhang   ierr = VecDestroy(baij->slvec0b);CHKERRQ(ierr);
31201b2bd88SHong Zhang   baij->slvec0 = 0;
31301b2bd88SHong Zhang   ierr = VecDestroy(baij->slvec1);CHKERRQ(ierr);
31401b2bd88SHong Zhang   ierr = VecDestroy(baij->slvec1a);CHKERRQ(ierr);
31501b2bd88SHong Zhang   ierr = VecDestroy(baij->slvec1b);CHKERRQ(ierr);
31601b2bd88SHong Zhang   baij->slvec1 = 0;
31701b2bd88SHong Zhang 
318a30f8f8cSSatish Balay   if (baij->colmap) {
319a30f8f8cSSatish Balay #if defined (PETSC_USE_CTABLE)
3209c666560SBarry Smith     ierr = PetscTableDestroy(baij->colmap); baij->colmap = 0;CHKERRQ(ierr);
321a30f8f8cSSatish Balay #else
322a30f8f8cSSatish Balay     ierr = PetscFree(baij->colmap);CHKERRQ(ierr);
323a30f8f8cSSatish Balay     baij->colmap = 0;
32452e6d16bSBarry Smith     ierr = PetscLogObjectMemory(A,-Bbaij->nbs*sizeof(PetscInt));CHKERRQ(ierr);
325a30f8f8cSSatish Balay #endif
326a30f8f8cSSatish Balay   }
327a30f8f8cSSatish Balay 
328a30f8f8cSSatish Balay   /* make sure that B is assembled so we can access its values */
329a30f8f8cSSatish Balay   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
330a30f8f8cSSatish Balay   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
331a30f8f8cSSatish Balay 
332a30f8f8cSSatish Balay   /* invent new B and copy stuff over */
33313f74950SBarry Smith   ierr = PetscMalloc(mbs*sizeof(PetscInt),&nz);CHKERRQ(ierr);
334a30f8f8cSSatish Balay   for (i=0; i<mbs; i++) {
335a30f8f8cSSatish Balay     nz[i] = Bbaij->i[i+1]-Bbaij->i[i];
336a30f8f8cSSatish Balay   }
337f69a0ea3SMatthew Knepley   ierr = MatCreate(PETSC_COMM_SELF,&Bnew);CHKERRQ(ierr);
338f69a0ea3SMatthew Knepley   ierr = MatSetSizes(Bnew,m,n,m,n);CHKERRQ(ierr);
3397adad957SLisandro Dalcin   ierr = MatSetType(Bnew,((PetscObject)B)->type_name);CHKERRQ(ierr);
340d0f46423SBarry Smith   ierr = MatSeqBAIJSetPreallocation(Bnew,B->rmap->bs,0,nz);CHKERRQ(ierr);
341a30f8f8cSSatish Balay   ierr = PetscFree(nz);CHKERRQ(ierr);
342a30f8f8cSSatish Balay 
34313f74950SBarry Smith   ierr = PetscMalloc(bs*sizeof(PetscInt),&rvals);CHKERRQ(ierr);
344a30f8f8cSSatish Balay   for (i=0; i<mbs; i++) {
345a30f8f8cSSatish Balay     rvals[0] = bs*i;
346a30f8f8cSSatish Balay     for (j=1; j<bs; j++) { rvals[j] = rvals[j-1] + 1; }
347a30f8f8cSSatish Balay     for (j=Bbaij->i[i]; j<Bbaij->i[i+1]; j++) {
348a30f8f8cSSatish Balay       col = garray[Bbaij->j[j]]*bs;
349a30f8f8cSSatish Balay       for (k=0; k<bs; k++) {
350*ce63c4c1SBarry Smith #if defined(PETSC_USE_REAL_MAT_SINGLE)
351a30f8f8cSSatish Balay         for (l=0; l<bs; l++) atmp[l] = a[j*bs2+l];
352a30f8f8cSSatish Balay #else
35371730473SSatish Balay         atmp = a+j*bs2 + k*bs;
354a30f8f8cSSatish Balay #endif
355c8407628SSatish Balay         ierr = MatSetValues_SeqSBAIJ(Bnew,bs,rvals,1,&col,atmp,B->insertmode);CHKERRQ(ierr);
356a30f8f8cSSatish Balay         col++;
357a30f8f8cSSatish Balay       }
358a30f8f8cSSatish Balay     }
359a30f8f8cSSatish Balay   }
360*ce63c4c1SBarry Smith #if defined(PETSC_USE_REAL_MAT_SINGLE)
361a30f8f8cSSatish Balay   ierr = PetscFree(atmp);CHKERRQ(ierr);
362a30f8f8cSSatish Balay #endif
363a30f8f8cSSatish Balay   ierr = PetscFree(baij->garray);CHKERRQ(ierr);
364a30f8f8cSSatish Balay   baij->garray = 0;
365a30f8f8cSSatish Balay   ierr = PetscFree(rvals);CHKERRQ(ierr);
36652e6d16bSBarry Smith   ierr = PetscLogObjectMemory(A,-ec*sizeof(PetscInt));CHKERRQ(ierr);
367a30f8f8cSSatish Balay   ierr = MatDestroy(B);CHKERRQ(ierr);
36852e6d16bSBarry Smith   ierr = PetscLogObjectParent(A,Bnew);CHKERRQ(ierr);
369a30f8f8cSSatish Balay   baij->B = Bnew;
370a30f8f8cSSatish Balay   A->was_assembled = PETSC_FALSE;
371a30f8f8cSSatish Balay   PetscFunctionReturn(0);
372a30f8f8cSSatish Balay }
373a30f8f8cSSatish Balay 
374a30f8f8cSSatish Balay 
375a30f8f8cSSatish Balay 
376