xref: /petsc/src/mat/impls/baij/mpi/mmbaij.c (revision 2c71b3e237ead271e4f3aa1505f92bf476e3413d)
1be1d678aSKris Buschelman 
28016bdd1SSatish Balay /*
3d9653453SSatish Balay    Support for the parallel BAIJ matrix vector multiply
48016bdd1SSatish Balay */
5c6db04a5SJed Brown #include <../src/mat/impls/baij/mpi/mpibaij.h>
6af0996ceSBarry Smith #include <petsc/private/isimpl.h>    /* needed because accesses data structure of ISLocalToGlobalMapping directly */
7bba1ac68SSatish Balay 
8dfbe8321SBarry Smith PetscErrorCode MatSetUpMultiply_MPIBAIJ(Mat mat)
98016bdd1SSatish Balay {
10d9653453SSatish Balay   Mat_MPIBAIJ    *baij = (Mat_MPIBAIJ*)mat->data;
11d9653453SSatish Balay   Mat_SeqBAIJ    *B    = (Mat_SeqBAIJ*)(baij->B->data);
126849ba73SBarry Smith   PetscErrorCode ierr;
13b24ad042SBarry Smith   PetscInt       i,j,*aj = B->j,ec = 0,*garray;
14d0f46423SBarry Smith   PetscInt       bs = mat->rmap->bs,*stmp;
158016bdd1SSatish Balay   IS             from,to;
168016bdd1SSatish Balay   Vec            gvec;
17aa482453SBarry Smith #if defined(PETSC_USE_CTABLE)
180f5bd95cSBarry Smith   PetscTable         gid1_lid1;
190f5bd95cSBarry Smith   PetscTablePosition tpos;
20b24ad042SBarry Smith   PetscInt           gid,lid;
216f531f54SSatish Balay #else
22b24ad042SBarry Smith   PetscInt Nbs = baij->Nbs,*indices;
2373a2e727SSatish Balay #endif
248016bdd1SSatish Balay 
253a40ed3dSBarry Smith   PetscFunctionBegin;
26aa482453SBarry Smith #if defined(PETSC_USE_CTABLE)
2773a2e727SSatish Balay   /* use a table - Mark Adams */
28e23dfa41SBarry Smith   ierr = PetscTableCreate(B->mbs,baij->Nbs+1,&gid1_lid1);CHKERRQ(ierr);
2973a2e727SSatish Balay   for (i=0; i<B->mbs; i++) {
3073a2e727SSatish Balay     for (j=0; j<B->ilen[i]; j++) {
31b24ad042SBarry Smith       PetscInt data,gid1 = aj[B->i[i]+j] + 1;
320f5bd95cSBarry Smith       ierr = PetscTableFind(gid1_lid1,gid1,&data);CHKERRQ(ierr);
33fa46199cSSatish Balay       if (!data) {
3473a2e727SSatish Balay         /* one based table */
353861aac3SJed Brown         ierr = PetscTableAdd(gid1_lid1,gid1,++ec,INSERT_VALUES);CHKERRQ(ierr);
3673a2e727SSatish Balay       }
3773a2e727SSatish Balay     }
3873a2e727SSatish Balay   }
3973a2e727SSatish Balay   /* form array of columns we need */
40b3c64f9dSJunchao Zhang   ierr = PetscMalloc1(ec,&garray);CHKERRQ(ierr);
410f5bd95cSBarry Smith   ierr = PetscTableGetHeadPosition(gid1_lid1,&tpos);CHKERRQ(ierr);
4273a2e727SSatish Balay   while (tpos) {
430f5bd95cSBarry Smith     ierr = PetscTableGetNext(gid1_lid1,&tpos,&gid,&lid);CHKERRQ(ierr);
4473a2e727SSatish Balay     gid--; lid--;
4573a2e727SSatish Balay     garray[lid] = gid;
4673a2e727SSatish Balay   }
470064e2bbSSatish Balay   ierr = PetscSortInt(ec,garray);CHKERRQ(ierr);
480f5bd95cSBarry Smith   ierr = PetscTableRemoveAll(gid1_lid1);CHKERRQ(ierr);
4973a2e727SSatish Balay   for (i=0; i<ec; i++) {
503861aac3SJed Brown     ierr = PetscTableAdd(gid1_lid1,garray[i]+1,i+1,INSERT_VALUES);CHKERRQ(ierr);
5173a2e727SSatish Balay   }
5273a2e727SSatish Balay   /* compact out the extra columns in B */
5373a2e727SSatish Balay   for (i=0; i<B->mbs; i++) {
5473a2e727SSatish Balay     for (j=0; j<B->ilen[i]; j++) {
55b24ad042SBarry Smith       PetscInt gid1 = aj[B->i[i] + j] + 1;
560f5bd95cSBarry Smith       ierr = PetscTableFind(gid1_lid1,gid1,&lid);CHKERRQ(ierr);
57fa46199cSSatish Balay       lid--;
5873a2e727SSatish Balay       aj[B->i[i]+j] = lid;
5973a2e727SSatish Balay     }
6073a2e727SSatish Balay   }
6173a2e727SSatish Balay   B->nbs           = ec;
62ca5434daSLawrence Mitchell   ierr = PetscLayoutDestroy(&baij->B->cmap);CHKERRQ(ierr);
63ca5434daSLawrence Mitchell   ierr = PetscLayoutCreateFromSizes(PetscObjectComm((PetscObject)baij->B),ec*mat->rmap->bs,ec*mat->rmap->bs,mat->rmap->bs,&baij->B->cmap);CHKERRQ(ierr);
646bc0bbbfSBarry Smith   ierr = PetscTableDestroy(&gid1_lid1);CHKERRQ(ierr);
6573a2e727SSatish Balay #else
66435da068SBarry Smith   /* Make an array as long as the number of columns */
67d9653453SSatish Balay   /* mark those columns that are in baij->B */
68b3c64f9dSJunchao Zhang   ierr = PetscCalloc1(Nbs,&indices);CHKERRQ(ierr);
69d9653453SSatish Balay   for (i=0; i<B->mbs; i++) {
708016bdd1SSatish Balay     for (j=0; j<B->ilen[i]; j++) {
71d9653453SSatish Balay       if (!indices[aj[B->i[i] + j]]) ec++;
72d9653453SSatish Balay       indices[aj[B->i[i] + j]] = 1;
738016bdd1SSatish Balay     }
748016bdd1SSatish Balay   }
758016bdd1SSatish Balay 
768016bdd1SSatish Balay   /* form array of columns we need */
77b3c64f9dSJunchao Zhang   ierr = PetscMalloc1(ec,&garray);CHKERRQ(ierr);
788016bdd1SSatish Balay   ec   = 0;
79d9653453SSatish Balay   for (i=0; i<Nbs; i++) {
800bdbc534SSatish Balay     if (indices[i]) {
810bdbc534SSatish Balay       garray[ec++] = i;
820bdbc534SSatish Balay     }
838016bdd1SSatish Balay   }
848016bdd1SSatish Balay 
858016bdd1SSatish Balay   /* make indices now point into garray */
868016bdd1SSatish Balay   for (i=0; i<ec; i++) {
87d9653453SSatish Balay     indices[garray[i]] = i;
888016bdd1SSatish Balay   }
898016bdd1SSatish Balay 
908016bdd1SSatish Balay   /* compact out the extra columns in B */
91d9653453SSatish Balay   for (i=0; i<B->mbs; i++) {
928016bdd1SSatish Balay     for (j=0; j<B->ilen[i]; j++) {
93d9653453SSatish Balay       aj[B->i[i] + j] = indices[aj[B->i[i] + j]];
948016bdd1SSatish Balay     }
958016bdd1SSatish Balay   }
96d9653453SSatish Balay   B->nbs           = ec;
97ca5434daSLawrence Mitchell   ierr = PetscLayoutDestroy(&baij->B->cmap);CHKERRQ(ierr);
98ca5434daSLawrence Mitchell   ierr = PetscLayoutCreateFromSizes(PetscObjectComm((PetscObject)baij->B),ec*mat->rmap->bs,ec*mat->rmap->bs,mat->rmap->bs,&baij->B->cmap);CHKERRQ(ierr);
99606d414cSSatish Balay   ierr = PetscFree(indices);CHKERRQ(ierr);
10073a2e727SSatish Balay #endif
1018016bdd1SSatish Balay 
1028016bdd1SSatish Balay   /* create local vector that is used to scatter into */
103029af93fSBarry Smith   ierr = VecCreateSeq(PETSC_COMM_SELF,ec*bs,&baij->lvec);CHKERRQ(ierr);
1048016bdd1SSatish Balay 
105c16cb8f2SBarry Smith   /* create two temporary index sets for building scatter-gather */
106deff0451SBarry Smith   ierr = ISCreateBlock(PETSC_COMM_SELF,bs,ec,garray,PETSC_COPY_VALUES,&from);CHKERRQ(ierr);
107c16cb8f2SBarry Smith 
108ad1b2038SJunchao Zhang   ierr = PetscMalloc1(ec,&stmp);CHKERRQ(ierr);
10926fbe8dcSKarl Rupp   for (i=0; i<ec; i++) stmp[i] = i;
110deff0451SBarry Smith   ierr = ISCreateBlock(PETSC_COMM_SELF,bs,ec,stmp,PETSC_OWN_POINTER,&to);CHKERRQ(ierr);
1118016bdd1SSatish Balay 
1128016bdd1SSatish Balay   /* create temporary global vector to generate scatter context */
113ce94432eSBarry Smith   ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)mat),1,mat->cmap->n,mat->cmap->N,NULL,&gvec);CHKERRQ(ierr);
1148016bdd1SSatish Balay 
1159448b7f1SJunchao Zhang   ierr = VecScatterCreate(gvec,from,baij->lvec,to,&baij->Mvctx);CHKERRQ(ierr);
1162f3b2168SJunchao Zhang   ierr = VecScatterViewFromOptions(baij->Mvctx,(PetscObject)mat,"-matmult_vecscatter_view");CHKERRQ(ierr);
11790f02eecSBarry Smith 
1183bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)baij->Mvctx);CHKERRQ(ierr);
1193bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)baij->lvec);CHKERRQ(ierr);
1203bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)from);CHKERRQ(ierr);
1213bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)to);CHKERRQ(ierr);
12226fbe8dcSKarl Rupp 
123d9653453SSatish Balay   baij->garray = garray;
12426fbe8dcSKarl Rupp 
125ad1b2038SJunchao Zhang   ierr = PetscLogObjectMemory((PetscObject)mat,ec*sizeof(PetscInt));CHKERRQ(ierr);
1266bf464f9SBarry Smith   ierr = ISDestroy(&from);CHKERRQ(ierr);
1276bf464f9SBarry Smith   ierr = ISDestroy(&to);CHKERRQ(ierr);
1286bf464f9SBarry Smith   ierr = VecDestroy(&gvec);CHKERRQ(ierr);
1293a40ed3dSBarry Smith   PetscFunctionReturn(0);
1308016bdd1SSatish Balay }
1318016bdd1SSatish Balay 
1328016bdd1SSatish Balay /*
133d9653453SSatish Balay      Takes the local part of an already assembled MPIBAIJ matrix
1348016bdd1SSatish Balay    and disassembles it. This is to allow new nonzeros into the matrix
1358016bdd1SSatish Balay    that require more communication in the matrix vector multiply.
1368016bdd1SSatish Balay    Thus certain data-structures must be rebuilt.
1378016bdd1SSatish Balay 
1388016bdd1SSatish Balay    Kind of slow! But that's what application programmers get when
1398016bdd1SSatish Balay    they are sloppy.
1408016bdd1SSatish Balay */
141ab9863d7SBarry Smith PetscErrorCode MatDisAssemble_MPIBAIJ(Mat A)
1428016bdd1SSatish Balay {
143d9653453SSatish Balay   Mat_MPIBAIJ    *baij  = (Mat_MPIBAIJ*)A->data;
144d9653453SSatish Balay   Mat            B      = baij->B,Bnew;
145d9653453SSatish Balay   Mat_SeqBAIJ    *Bbaij = (Mat_SeqBAIJ*)B->data;
146dfbe8321SBarry Smith   PetscErrorCode ierr;
147d0f46423SBarry Smith   PetscInt       i,j,mbs=Bbaij->mbs,n = A->cmap->N,col,*garray=baij->garray;
148d0f46423SBarry Smith   PetscInt       bs2 = baij->bs2,*nz,ec,m = A->rmap->n;
1493eda8832SBarry Smith   MatScalar      *a  = Bbaij->a;
150dd6ea824SBarry Smith   MatScalar      *atmp;
15197e5c40aSBarry Smith 
1523a40ed3dSBarry Smith   PetscFunctionBegin;
1538016bdd1SSatish Balay   /* free stuff related to matrix-vec multiply */
154b0a32e0cSBarry Smith   ierr = VecGetSize(baij->lvec,&ec);CHKERRQ(ierr); /* needed for PetscLogObjectMemory below */
155f4259b30SLisandro Dalcin   ierr = VecDestroy(&baij->lvec);CHKERRQ(ierr); baij->lvec = NULL;
156f4259b30SLisandro Dalcin   ierr = VecScatterDestroy(&baij->Mvctx);CHKERRQ(ierr); baij->Mvctx = NULL;
157d9653453SSatish Balay   if (baij->colmap) {
158aa482453SBarry Smith #if defined(PETSC_USE_CTABLE)
1596bc0bbbfSBarry Smith     ierr = PetscTableDestroy(&baij->colmap);CHKERRQ(ierr);
16048e59246SSatish Balay #else
161606d414cSSatish Balay     ierr = PetscFree(baij->colmap);CHKERRQ(ierr);
1623bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,-Bbaij->nbs*sizeof(PetscInt));CHKERRQ(ierr);
16348e59246SSatish Balay #endif
1648016bdd1SSatish Balay   }
1658016bdd1SSatish Balay 
1668016bdd1SSatish Balay   /* make sure that B is assembled so we can access its values */
1676d4a8577SBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1683eda8832SBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1698016bdd1SSatish Balay 
1708016bdd1SSatish Balay   /* invent new B and copy stuff over */
171785e854fSJed Brown   ierr = PetscMalloc1(mbs,&nz);CHKERRQ(ierr);
172d9653453SSatish Balay   for (i=0; i<mbs; i++) {
173d9653453SSatish Balay     nz[i] = Bbaij->i[i+1]-Bbaij->i[i];
1748016bdd1SSatish Balay   }
175ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)B),&Bnew);CHKERRQ(ierr);
176f69a0ea3SMatthew Knepley   ierr = MatSetSizes(Bnew,m,n,m,n);CHKERRQ(ierr);
1777adad957SLisandro Dalcin   ierr = MatSetType(Bnew,((PetscObject)B)->type_name);CHKERRQ(ierr);
178d0f46423SBarry Smith   ierr = MatSeqBAIJSetPreallocation(Bnew,B->rmap->bs,0,nz);CHKERRQ(ierr);
179b38c15b3SStefano Zampini   if (Bbaij->nonew >= 0) { /* Inherit insertion error options (if positive). */
180b38c15b3SStefano Zampini     ((Mat_SeqBAIJ*)Bnew->data)->nonew = Bbaij->nonew;
181b38c15b3SStefano Zampini   }
18226fbe8dcSKarl Rupp 
1834e0d8c25SBarry Smith   ierr = MatSetOption(Bnew,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr);
18477341eacSDmitry Karpeev   /*
18577341eacSDmitry Karpeev    Ensure that B's nonzerostate is monotonically increasing.
18677341eacSDmitry Karpeev    Or should this follow the MatSetValuesBlocked() loop to preserve B's nonzerstate across a MatDisAssemble() call?
18777341eacSDmitry Karpeev    */
18877341eacSDmitry Karpeev   Bnew->nonzerostate = B->nonzerostate;
189d9653453SSatish Balay 
190bba1ac68SSatish Balay   for (i=0; i<mbs; i++) {
191bba1ac68SSatish Balay     for (j=Bbaij->i[i]; j<Bbaij->i[i+1]; j++) {
192bba1ac68SSatish Balay       col  = garray[Bbaij->j[j]];
1933eda8832SBarry Smith       atmp = a + j*bs2;
194bba1ac68SSatish Balay       ierr = MatSetValuesBlocked_SeqBAIJ(Bnew,1,&i,1,&col,atmp,B->insertmode);CHKERRQ(ierr);
1958016bdd1SSatish Balay     }
1968016bdd1SSatish Balay   }
1974e0d8c25SBarry Smith   ierr = MatSetOption(Bnew,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr);
198bba1ac68SSatish Balay 
199bba1ac68SSatish Balay   ierr = PetscFree(nz);CHKERRQ(ierr);
200606d414cSSatish Balay   ierr = PetscFree(baij->garray);CHKERRQ(ierr);
2013bb1ff40SBarry Smith   ierr = PetscLogObjectMemory((PetscObject)A,-ec*sizeof(PetscInt));CHKERRQ(ierr);
2026bf464f9SBarry Smith   ierr = MatDestroy(&B);CHKERRQ(ierr);
2033bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)Bnew);CHKERRQ(ierr);
20426fbe8dcSKarl Rupp 
205d9653453SSatish Balay   baij->B          = Bnew;
2068016bdd1SSatish Balay   A->was_assembled = PETSC_FALSE;
2076a719282SBarry Smith   A->assembled     = PETSC_FALSE;
2083a40ed3dSBarry Smith   PetscFunctionReturn(0);
2098016bdd1SSatish Balay }
2108016bdd1SSatish Balay 
21104f1ad80SBarry Smith /*      ugly stuff added for Glenn someday we should fix this up */
21204f1ad80SBarry Smith 
213f4259b30SLisandro Dalcin static PetscInt *uglyrmapd = NULL,*uglyrmapo = NULL;  /* mapping from the local ordering to the "diagonal" and "off-diagonal" parts of the local matrix */
214f4259b30SLisandro Dalcin static Vec      uglydd     = NULL,uglyoo     = NULL;  /* work vectors used to scale the two parts of the local matrix */
21504f1ad80SBarry Smith 
216dfbe8321SBarry Smith PetscErrorCode MatMPIBAIJDiagonalScaleLocalSetUp(Mat inA,Vec scale)
21704f1ad80SBarry Smith {
21804f1ad80SBarry Smith   Mat_MPIBAIJ    *ina = (Mat_MPIBAIJ*) inA->data; /*access private part of matrix */
21904f1ad80SBarry Smith   Mat_SeqBAIJ    *B   = (Mat_SeqBAIJ*)ina->B->data;
220dfbe8321SBarry Smith   PetscErrorCode ierr;
221d0f46423SBarry Smith   PetscInt       bs = inA->rmap->bs,i,n,nt,j,cstart,cend,no,*garray = ina->garray,*lindices;
222b24ad042SBarry Smith   PetscInt       *r_rmapd,*r_rmapo;
22304f1ad80SBarry Smith 
22404f1ad80SBarry Smith   PetscFunctionBegin;
22504f1ad80SBarry Smith   ierr = MatGetOwnershipRange(inA,&cstart,&cend);CHKERRQ(ierr);
2260298fd71SBarry Smith   ierr = MatGetSize(ina->A,NULL,&n);CHKERRQ(ierr);
227854ce69bSBarry Smith   ierr = PetscCalloc1(inA->rmap->mapping->n+1,&r_rmapd);CHKERRQ(ierr);
22804f1ad80SBarry Smith   nt   = 0;
22945b6f7e9SBarry Smith   for (i=0; i<inA->rmap->mapping->n; i++) {
23045b6f7e9SBarry Smith     if (inA->rmap->mapping->indices[i]*bs >= cstart && inA->rmap->mapping->indices[i]*bs < cend) {
23104f1ad80SBarry Smith       nt++;
23245b6f7e9SBarry Smith       r_rmapd[i] = inA->rmap->mapping->indices[i] + 1;
23304f1ad80SBarry Smith     }
23404f1ad80SBarry Smith   }
235*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(nt*bs != n,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Hmm nt*bs %" PetscInt_FMT " n %" PetscInt_FMT,nt*bs,n);
236854ce69bSBarry Smith   ierr = PetscMalloc1(n+1,&uglyrmapd);CHKERRQ(ierr);
23745b6f7e9SBarry Smith   for (i=0; i<inA->rmap->mapping->n; i++) {
23804f1ad80SBarry Smith     if (r_rmapd[i]) {
23904f1ad80SBarry Smith       for (j=0; j<bs; j++) {
24004f1ad80SBarry Smith         uglyrmapd[(r_rmapd[i]-1)*bs+j-cstart] = i*bs + j;
24104f1ad80SBarry Smith       }
24204f1ad80SBarry Smith     }
24304f1ad80SBarry Smith   }
24404f1ad80SBarry Smith   ierr = PetscFree(r_rmapd);CHKERRQ(ierr);
24504f1ad80SBarry Smith   ierr = VecCreateSeq(PETSC_COMM_SELF,n,&uglydd);CHKERRQ(ierr);
24604f1ad80SBarry Smith 
247854ce69bSBarry Smith   ierr = PetscCalloc1(ina->Nbs+1,&lindices);CHKERRQ(ierr);
24804f1ad80SBarry Smith   for (i=0; i<B->nbs; i++) {
24904f1ad80SBarry Smith     lindices[garray[i]] = i+1;
25004f1ad80SBarry Smith   }
25145b6f7e9SBarry Smith   no   = inA->rmap->mapping->n - nt;
252854ce69bSBarry Smith   ierr = PetscCalloc1(inA->rmap->mapping->n+1,&r_rmapo);CHKERRQ(ierr);
25304f1ad80SBarry Smith   nt   = 0;
25445b6f7e9SBarry Smith   for (i=0; i<inA->rmap->mapping->n; i++) {
25545b6f7e9SBarry Smith     if (lindices[inA->rmap->mapping->indices[i]]) {
25604f1ad80SBarry Smith       nt++;
25745b6f7e9SBarry Smith       r_rmapo[i] = lindices[inA->rmap->mapping->indices[i]];
25804f1ad80SBarry Smith     }
25904f1ad80SBarry Smith   }
260*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(nt > no,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Hmm nt %" PetscInt_FMT " no %" PetscInt_FMT,nt,n);
26104f1ad80SBarry Smith   ierr = PetscFree(lindices);CHKERRQ(ierr);
262854ce69bSBarry Smith   ierr = PetscMalloc1(nt*bs+1,&uglyrmapo);CHKERRQ(ierr);
26345b6f7e9SBarry Smith   for (i=0; i<inA->rmap->mapping->n; i++) {
26404f1ad80SBarry Smith     if (r_rmapo[i]) {
26504f1ad80SBarry Smith       for (j=0; j<bs; j++) {
26604f1ad80SBarry Smith         uglyrmapo[(r_rmapo[i]-1)*bs+j] = i*bs + j;
26704f1ad80SBarry Smith       }
26804f1ad80SBarry Smith     }
26904f1ad80SBarry Smith   }
27004f1ad80SBarry Smith   ierr = PetscFree(r_rmapo);CHKERRQ(ierr);
27104f1ad80SBarry Smith   ierr = VecCreateSeq(PETSC_COMM_SELF,nt*bs,&uglyoo);CHKERRQ(ierr);
27204f1ad80SBarry Smith   PetscFunctionReturn(0);
27304f1ad80SBarry Smith }
27404f1ad80SBarry Smith 
2757087cfbeSBarry Smith PetscErrorCode  MatMPIBAIJDiagonalScaleLocal(Mat A,Vec scale)
27604f1ad80SBarry Smith {
27792b32695SKris Buschelman   /* This routine should really be abandoned as it duplicates MatDiagonalScaleLocal */
2784ac538c5SBarry Smith   PetscErrorCode ierr;
27992b32695SKris Buschelman 
28092b32695SKris Buschelman   PetscFunctionBegin;
2814ac538c5SBarry Smith   ierr = PetscTryMethod(A,"MatDiagonalScaleLocal_C",(Mat,Vec),(A,scale));CHKERRQ(ierr);
28292b32695SKris Buschelman   PetscFunctionReturn(0);
28392b32695SKris Buschelman }
28492b32695SKris Buschelman 
2857087cfbeSBarry Smith PetscErrorCode  MatDiagonalScaleLocal_MPIBAIJ(Mat A,Vec scale)
28692b32695SKris Buschelman {
28704f1ad80SBarry Smith   Mat_MPIBAIJ       *a = (Mat_MPIBAIJ*) A->data; /*access private part of matrix */
288dfbe8321SBarry Smith   PetscErrorCode    ierr;
289b24ad042SBarry Smith   PetscInt          n,i;
290bca11509SBarry Smith   PetscScalar       *d,*o;
291bca11509SBarry Smith   const PetscScalar *s;
29204f1ad80SBarry Smith 
29304f1ad80SBarry Smith   PetscFunctionBegin;
2942cd6534aSBarry Smith   if (!uglyrmapd) {
2952cd6534aSBarry Smith     ierr = MatMPIBAIJDiagonalScaleLocalSetUp(A,scale);CHKERRQ(ierr);
2962cd6534aSBarry Smith   }
2972cd6534aSBarry Smith 
298bca11509SBarry Smith   ierr = VecGetArrayRead(scale,&s);CHKERRQ(ierr);
29904f1ad80SBarry Smith 
30004f1ad80SBarry Smith   ierr = VecGetLocalSize(uglydd,&n);CHKERRQ(ierr);
3011ebc52fbSHong Zhang   ierr = VecGetArray(uglydd,&d);CHKERRQ(ierr);
30204f1ad80SBarry Smith   for (i=0; i<n; i++) {
30304f1ad80SBarry Smith     d[i] = s[uglyrmapd[i]]; /* copy "diagonal" (true local) portion of scale into dd vector */
30404f1ad80SBarry Smith   }
3051ebc52fbSHong Zhang   ierr = VecRestoreArray(uglydd,&d);CHKERRQ(ierr);
30604f1ad80SBarry Smith   /* column scale "diagonal" portion of local matrix */
3070298fd71SBarry Smith   ierr = MatDiagonalScale(a->A,NULL,uglydd);CHKERRQ(ierr);
30804f1ad80SBarry Smith 
30904f1ad80SBarry Smith   ierr = VecGetLocalSize(uglyoo,&n);CHKERRQ(ierr);
3101ebc52fbSHong Zhang   ierr = VecGetArray(uglyoo,&o);CHKERRQ(ierr);
31104f1ad80SBarry Smith   for (i=0; i<n; i++) {
31204f1ad80SBarry Smith     o[i] = s[uglyrmapo[i]]; /* copy "off-diagonal" portion of scale into oo vector */
31304f1ad80SBarry Smith   }
314bca11509SBarry Smith   ierr = VecRestoreArrayRead(scale,&s);CHKERRQ(ierr);
3151ebc52fbSHong Zhang   ierr = VecRestoreArray(uglyoo,&o);CHKERRQ(ierr);
31604f1ad80SBarry Smith   /* column scale "off-diagonal" portion of local matrix */
3170298fd71SBarry Smith   ierr = MatDiagonalScale(a->B,NULL,uglyoo);CHKERRQ(ierr);
31804f1ad80SBarry Smith   PetscFunctionReturn(0);
31904f1ad80SBarry Smith }
320