1be1d678aSKris Buschelman #define PETSCMAT_DLL 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 813f74950SBarry Smith EXTERN PetscErrorCode MatSetValues_SeqSBAIJ(Mat,PetscInt,const PetscInt [],PetscInt,const PetscInt [],const PetscScalar [],InsertMode); 97cff1425SSatish Balay 10a30f8f8cSSatish Balay 114a2ae208SSatish Balay #undef __FUNCT__ 124a2ae208SSatish Balay #define __FUNCT__ "MatSetUpMultiply_MPISBAIJ" 13dfbe8321SBarry Smith PetscErrorCode 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); 176849ba73SBarry Smith PetscErrorCode ierr; 1813f74950SBarry Smith PetscInt Nbs = sbaij->Nbs,i,j,*indices,*aj = B->j,ec = 0,*garray,*sgarray; 1913f74950SBarry Smith PetscInt bs = mat->bs,*stmp,mbs=sbaij->mbs, vec_size,nt; 2040781036SHong Zhang IS from,to; 2140781036SHong Zhang Vec gvec; 2213f74950SBarry Smith PetscMPIInt rank=sbaij->rank,lsize,size=sbaij->size; 2313f74950SBarry Smith PetscInt *owners=sbaij->rowners,*sowners,*ec_owner,k; 2440781036SHong Zhang PetscScalar *ptr; 2540781036SHong Zhang 2640781036SHong Zhang PetscFunctionBegin; 2701b2bd88SHong Zhang if (sbaij->sMvctx) { 2801b2bd88SHong Zhang /* This two lines should be in DisAssemble_MPISBAIJ(). Don't know why it causes crash there? */ 2901b2bd88SHong Zhang ierr = VecScatterDestroy(sbaij->sMvctx);CHKERRQ(ierr); 3001b2bd88SHong Zhang sbaij->sMvctx = 0; 3140781036SHong Zhang } 3240781036SHong Zhang 3340781036SHong Zhang /* For the first stab we make an array as long as the number of columns */ 3440781036SHong Zhang /* mark those columns that are in sbaij->B */ 3513f74950SBarry Smith ierr = PetscMalloc((Nbs+1)*sizeof(PetscInt),&indices);CHKERRQ(ierr); 3613f74950SBarry Smith ierr = PetscMemzero(indices,Nbs*sizeof(PetscInt));CHKERRQ(ierr); 3740781036SHong Zhang for (i=0; i<mbs; i++) { 3840781036SHong Zhang for (j=0; j<B->ilen[i]; j++) { 3940781036SHong Zhang if (!indices[aj[B->i[i] + j]]) ec++; 4040781036SHong Zhang indices[aj[B->i[i] + j] ] = 1; 4140781036SHong Zhang } 4240781036SHong Zhang } 4340781036SHong Zhang 4440781036SHong Zhang /* form arrays of columns we need */ 4513f74950SBarry Smith ierr = PetscMalloc((ec+1)*sizeof(PetscInt),&garray);CHKERRQ(ierr); 4613f74950SBarry Smith ierr = PetscMalloc((3*ec+1)*sizeof(PetscInt),&sgarray);CHKERRQ(ierr); 4740781036SHong Zhang ec_owner = sgarray + 2*ec; 4840781036SHong Zhang 4940781036SHong Zhang ec = 0; 5040781036SHong Zhang for (j=0; j<size; j++){ 5140781036SHong Zhang for (i=owners[j]; i<owners[j+1]; i++){ 5240781036SHong Zhang if (indices[i]) { 5340781036SHong Zhang garray[ec] = i; 5440781036SHong Zhang ec_owner[ec] = j; 5540781036SHong Zhang ec++; 5640781036SHong Zhang } 5740781036SHong Zhang } 5840781036SHong Zhang } 5940781036SHong Zhang 6040781036SHong Zhang /* make indices now point into garray */ 61b424e231SHong Zhang for (i=0; i<ec; i++) indices[garray[i]] = i; 6240781036SHong Zhang 6340781036SHong Zhang /* compact out the extra columns in B */ 6440781036SHong Zhang for (i=0; i<mbs; i++) { 6540781036SHong Zhang for (j=0; j<B->ilen[i]; j++) aj[B->i[i] + j] = indices[aj[B->i[i] + j]]; 6640781036SHong Zhang } 6740781036SHong Zhang B->nbs = ec; 68521d7252SBarry Smith sbaij->B->n = ec*mat->bs; 6940781036SHong Zhang ierr = PetscFree(indices);CHKERRQ(ierr); 7040781036SHong Zhang 7140781036SHong Zhang /* create local vector that is used to scatter into */ 7240781036SHong Zhang ierr = VecCreateSeq(PETSC_COMM_SELF,ec*bs,&sbaij->lvec);CHKERRQ(ierr); 7340781036SHong Zhang 7440781036SHong Zhang /* create two temporary index sets for building scatter-gather */ 7513f74950SBarry Smith ierr = PetscMalloc((2*ec+1)*sizeof(PetscInt),&stmp);CHKERRQ(ierr); 7640781036SHong Zhang for (i=0; i<ec; i++) stmp[i] = bs*garray[i]; 7740781036SHong Zhang ierr = ISCreateBlock(PETSC_COMM_SELF,bs,ec,stmp,&from);CHKERRQ(ierr); 7840781036SHong Zhang 7940781036SHong Zhang for (i=0; i<ec; i++) { stmp[i] = bs*i; } 8040781036SHong Zhang ierr = ISCreateBlock(PETSC_COMM_SELF,bs,ec,stmp,&to);CHKERRQ(ierr); 8140781036SHong Zhang 8293d1592dSHong Zhang /* generate the scatter context 8393d1592dSHong Zhang -- Mvctx and lvec are not used by MatMult_MPISBAIJ(), but usefule for some applications */ 8440781036SHong Zhang ierr = VecCreateMPI(mat->comm,mat->n,mat->N,&gvec);CHKERRQ(ierr); 8540781036SHong Zhang ierr = VecScatterCreate(gvec,from,sbaij->lvec,to,&sbaij->Mvctx);CHKERRQ(ierr); 8640781036SHong Zhang ierr = VecScatterPostRecvs(gvec,sbaij->lvec,INSERT_VALUES,SCATTER_FORWARD,sbaij->Mvctx);CHKERRQ(ierr); 8740781036SHong Zhang 8840781036SHong Zhang sbaij->garray = garray; 8952e6d16bSBarry Smith ierr = PetscLogObjectParent(mat,sbaij->Mvctx);CHKERRQ(ierr); 9052e6d16bSBarry Smith ierr = PetscLogObjectParent(mat,sbaij->lvec);CHKERRQ(ierr); 9152e6d16bSBarry Smith ierr = PetscLogObjectParent(mat,from);CHKERRQ(ierr); 9252e6d16bSBarry Smith ierr = PetscLogObjectParent(mat,to);CHKERRQ(ierr); 9340781036SHong Zhang 9440781036SHong Zhang ierr = ISDestroy(from);CHKERRQ(ierr); 9540781036SHong Zhang ierr = ISDestroy(to);CHKERRQ(ierr); 9640781036SHong Zhang 9740781036SHong Zhang /* create parallel vector that is used by SBAIJ matrix to scatter from/into */ 9840781036SHong Zhang lsize = (mbs + ec)*bs; 9940781036SHong Zhang ierr = VecCreateMPI(mat->comm,lsize,PETSC_DETERMINE,&sbaij->slvec0);CHKERRQ(ierr); 10040781036SHong Zhang ierr = VecDuplicate(sbaij->slvec0,&sbaij->slvec1);CHKERRQ(ierr); 10140781036SHong Zhang ierr = VecGetSize(sbaij->slvec0,&vec_size);CHKERRQ(ierr); 10240781036SHong Zhang 103*bba805e6SBarry Smith sowners = sbaij->slvec0->map.range; 10440781036SHong Zhang 10540781036SHong Zhang /* x index in the IS sfrom */ 10640781036SHong Zhang for (i=0; i<ec; i++) { 10740781036SHong Zhang j = ec_owner[i]; 10840781036SHong Zhang sgarray[i] = garray[i] + (sowners[j]/bs - owners[j]); 10940781036SHong Zhang } 11040781036SHong Zhang /* b index in the IS sfrom */ 11140781036SHong Zhang k = sowners[rank]/bs + mbs; 11240781036SHong Zhang for (i=ec,j=0; i< 2*ec; i++,j++) sgarray[i] = k + j; 11340781036SHong Zhang 11440781036SHong Zhang for (i=0; i<2*ec; i++) stmp[i] = bs*sgarray[i]; 11540781036SHong Zhang ierr = ISCreateBlock(PETSC_COMM_SELF,bs,2*ec,stmp,&from);CHKERRQ(ierr); 11640781036SHong Zhang 11740781036SHong Zhang /* x index in the IS sto */ 11840781036SHong Zhang k = sowners[rank]/bs + mbs; 11940781036SHong Zhang for (i=0; i<ec; i++) stmp[i] = bs*(k + i); 12040781036SHong Zhang /* b index in the IS sto */ 12140781036SHong Zhang for (i=ec; i<2*ec; i++) stmp[i] = bs*sgarray[i-ec]; 12240781036SHong Zhang 12340781036SHong Zhang ierr = ISCreateBlock(PETSC_COMM_SELF,bs,2*ec,stmp,&to);CHKERRQ(ierr); 12440781036SHong Zhang 12540781036SHong Zhang /* gnerate the SBAIJ scatter context */ 12640781036SHong Zhang ierr = VecScatterCreate(sbaij->slvec0,from,sbaij->slvec1,to,&sbaij->sMvctx);CHKERRQ(ierr); 12740781036SHong Zhang 12840781036SHong Zhang /* 12940781036SHong Zhang Post the receives for the first matrix vector product. We sync-chronize after 13040781036SHong Zhang this on the chance that the user immediately calls MatMult() after assemblying 13140781036SHong Zhang the matrix. 13240781036SHong Zhang */ 13340781036SHong Zhang ierr = VecScatterPostRecvs(sbaij->slvec0,sbaij->slvec1,INSERT_VALUES,SCATTER_FORWARD,sbaij->sMvctx);CHKERRQ(ierr); 13440781036SHong Zhang 13540781036SHong Zhang ierr = VecGetLocalSize(sbaij->slvec1,&nt);CHKERRQ(ierr); 1361ebc52fbSHong Zhang ierr = VecGetArray(sbaij->slvec1,&ptr);CHKERRQ(ierr); 13740781036SHong Zhang ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,bs*mbs,ptr,&sbaij->slvec1a);CHKERRQ(ierr); 13840781036SHong Zhang ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,nt-bs*mbs,ptr+bs*mbs,&sbaij->slvec1b);CHKERRQ(ierr); 1391ebc52fbSHong Zhang ierr = VecRestoreArray(sbaij->slvec1,&ptr);CHKERRQ(ierr); 14040781036SHong Zhang 1411ebc52fbSHong Zhang ierr = VecGetArray(sbaij->slvec0,&ptr);CHKERRQ(ierr); 14240781036SHong Zhang ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,nt-bs*mbs,ptr+bs*mbs,&sbaij->slvec0b);CHKERRQ(ierr); 1431ebc52fbSHong Zhang ierr = VecRestoreArray(sbaij->slvec0,&ptr);CHKERRQ(ierr); 14440781036SHong Zhang 14540781036SHong Zhang ierr = PetscFree(stmp);CHKERRQ(ierr); 14640781036SHong Zhang ierr = MPI_Barrier(mat->comm);CHKERRQ(ierr); 14740781036SHong Zhang 14852e6d16bSBarry Smith ierr = PetscLogObjectParent(mat,sbaij->sMvctx);CHKERRQ(ierr); 14952e6d16bSBarry Smith ierr = PetscLogObjectParent(mat,sbaij->slvec0);CHKERRQ(ierr); 15052e6d16bSBarry Smith ierr = PetscLogObjectParent(mat,sbaij->slvec1);CHKERRQ(ierr); 15152e6d16bSBarry Smith ierr = PetscLogObjectParent(mat,sbaij->slvec0b);CHKERRQ(ierr); 15252e6d16bSBarry Smith ierr = PetscLogObjectParent(mat,sbaij->slvec1a);CHKERRQ(ierr); 15352e6d16bSBarry Smith ierr = PetscLogObjectParent(mat,sbaij->slvec1b);CHKERRQ(ierr); 15452e6d16bSBarry Smith ierr = PetscLogObjectParent(mat,from);CHKERRQ(ierr); 15552e6d16bSBarry Smith ierr = PetscLogObjectParent(mat,to);CHKERRQ(ierr); 15640781036SHong Zhang 15752e6d16bSBarry Smith ierr = PetscLogObjectMemory(mat,(ec+1)*sizeof(PetscInt));CHKERRQ(ierr); 15840781036SHong Zhang ierr = ISDestroy(from);CHKERRQ(ierr); 15940781036SHong Zhang ierr = ISDestroy(to);CHKERRQ(ierr); 16040781036SHong Zhang ierr = VecDestroy(gvec);CHKERRQ(ierr); 16140781036SHong Zhang ierr = PetscFree(sgarray);CHKERRQ(ierr); 16240781036SHong Zhang PetscFunctionReturn(0); 16340781036SHong Zhang } 16440781036SHong Zhang 16540781036SHong Zhang #undef __FUNCT__ 16640781036SHong Zhang #define __FUNCT__ "MatSetUpMultiply_MPISBAIJ_2comm" 167dfbe8321SBarry Smith PetscErrorCode MatSetUpMultiply_MPISBAIJ_2comm(Mat mat) 16840781036SHong Zhang { 1692896befeSSatish Balay Mat_MPISBAIJ *baij = (Mat_MPISBAIJ*)mat->data; 170a30f8f8cSSatish Balay Mat_SeqBAIJ *B = (Mat_SeqBAIJ*)(baij->B->data); 1716849ba73SBarry Smith PetscErrorCode ierr; 17213f74950SBarry Smith PetscInt i,j,*aj = B->j,ec = 0,*garray; 17313f74950SBarry Smith PetscInt bs = mat->bs,*stmp; 174a30f8f8cSSatish Balay IS from,to; 175a30f8f8cSSatish Balay Vec gvec; 176a30f8f8cSSatish Balay #if defined (PETSC_USE_CTABLE) 177a30f8f8cSSatish Balay PetscTable gid1_lid1; 178a30f8f8cSSatish Balay PetscTablePosition tpos; 17913f74950SBarry Smith PetscInt gid,lid; 1806f531f54SSatish Balay #else 18113f74950SBarry Smith PetscInt Nbs = baij->Nbs,*indices; 182a30f8f8cSSatish Balay #endif 183a30f8f8cSSatish Balay 184a30f8f8cSSatish Balay PetscFunctionBegin; 185a30f8f8cSSatish Balay #if defined (PETSC_USE_CTABLE) 186a30f8f8cSSatish Balay /* use a table - Mark Adams */ 187a30f8f8cSSatish Balay PetscTableCreate(B->mbs,&gid1_lid1); 188a30f8f8cSSatish Balay for (i=0; i<B->mbs; i++) { 189a30f8f8cSSatish Balay for (j=0; j<B->ilen[i]; j++) { 19013f74950SBarry Smith PetscInt data,gid1 = aj[B->i[i]+j] + 1; 191a30f8f8cSSatish Balay ierr = PetscTableFind(gid1_lid1,gid1,&data);CHKERRQ(ierr); 192a30f8f8cSSatish Balay if (!data) { 193a30f8f8cSSatish Balay /* one based table */ 194a30f8f8cSSatish Balay ierr = PetscTableAdd(gid1_lid1,gid1,++ec);CHKERRQ(ierr); 195a30f8f8cSSatish Balay } 196a30f8f8cSSatish Balay } 197a30f8f8cSSatish Balay } 198a30f8f8cSSatish Balay /* form array of columns we need */ 19913f74950SBarry Smith ierr = PetscMalloc((ec+1)*sizeof(PetscInt),&garray);CHKERRQ(ierr); 200a30f8f8cSSatish Balay ierr = PetscTableGetHeadPosition(gid1_lid1,&tpos);CHKERRQ(ierr); 201a30f8f8cSSatish Balay while (tpos) { 202a30f8f8cSSatish Balay ierr = PetscTableGetNext(gid1_lid1,&tpos,&gid,&lid);CHKERRQ(ierr); 203a30f8f8cSSatish Balay gid--; lid--; 204a30f8f8cSSatish Balay garray[lid] = gid; 205a30f8f8cSSatish Balay } 206a30f8f8cSSatish Balay ierr = PetscSortInt(ec,garray);CHKERRQ(ierr); 207a30f8f8cSSatish Balay ierr = PetscTableRemoveAll(gid1_lid1);CHKERRQ(ierr); 208a30f8f8cSSatish Balay for (i=0; i<ec; i++) { 209a30f8f8cSSatish Balay ierr = PetscTableAdd(gid1_lid1,garray[i]+1,i+1);CHKERRQ(ierr); 210a30f8f8cSSatish Balay } 211a30f8f8cSSatish Balay /* compact out the extra columns in B */ 212a30f8f8cSSatish Balay for (i=0; i<B->mbs; i++) { 213a30f8f8cSSatish Balay for (j=0; j<B->ilen[i]; j++) { 21413f74950SBarry Smith PetscInt gid1 = aj[B->i[i] + j] + 1; 215a30f8f8cSSatish Balay ierr = PetscTableFind(gid1_lid1,gid1,&lid);CHKERRQ(ierr); 216a30f8f8cSSatish Balay lid --; 217a30f8f8cSSatish Balay aj[B->i[i]+j] = lid; 218a30f8f8cSSatish Balay } 219a30f8f8cSSatish Balay } 220a30f8f8cSSatish Balay B->nbs = ec; 2213d30b1ffSBarry Smith baij->B->n = ec*mat->bs; 222a30f8f8cSSatish Balay ierr = PetscTableDelete(gid1_lid1);CHKERRQ(ierr); 223a30f8f8cSSatish Balay /* Mark Adams */ 224a30f8f8cSSatish Balay #else 225a30f8f8cSSatish Balay /* For the first stab we make an array as long as the number of columns */ 226a30f8f8cSSatish Balay /* mark those columns that are in baij->B */ 22713f74950SBarry Smith ierr = PetscMalloc((Nbs+1)*sizeof(PetscInt),&indices);CHKERRQ(ierr); 22813f74950SBarry Smith ierr = PetscMemzero(indices,Nbs*sizeof(PetscInt));CHKERRQ(ierr); 229a30f8f8cSSatish Balay for (i=0; i<B->mbs; i++) { 230a30f8f8cSSatish Balay for (j=0; j<B->ilen[i]; j++) { 231a30f8f8cSSatish Balay if (!indices[aj[B->i[i] + j]]) ec++; 232a30f8f8cSSatish Balay indices[aj[B->i[i] + j] ] = 1; 233a30f8f8cSSatish Balay } 234a30f8f8cSSatish Balay } 235a30f8f8cSSatish Balay 236a30f8f8cSSatish Balay /* form array of columns we need */ 23713f74950SBarry Smith ierr = PetscMalloc((ec+1)*sizeof(PetscInt),&garray);CHKERRQ(ierr); 238f3ef73ceSBarry Smith ec = 0; 239f3ef73ceSBarry Smith for (i=0; i<Nbs; i++) { 240f3ef73ceSBarry Smith if (indices[i]) { 241f3ef73ceSBarry Smith garray[ec++] = i; 242f3ef73ceSBarry Smith } 243f3ef73ceSBarry Smith } 244a30f8f8cSSatish Balay 245a30f8f8cSSatish Balay /* make indices now point into garray */ 246a30f8f8cSSatish Balay for (i=0; i<ec; i++) { 247a30f8f8cSSatish Balay indices[garray[i]] = i; 248a30f8f8cSSatish Balay } 249a30f8f8cSSatish Balay 250a30f8f8cSSatish Balay /* compact out the extra columns in B */ 251a30f8f8cSSatish Balay for (i=0; i<B->mbs; i++) { 252a30f8f8cSSatish Balay for (j=0; j<B->ilen[i]; j++) { 253a30f8f8cSSatish Balay aj[B->i[i] + j] = indices[aj[B->i[i] + j]]; 254a30f8f8cSSatish Balay } 255a30f8f8cSSatish Balay } 256a30f8f8cSSatish Balay B->nbs = ec; 257521d7252SBarry Smith baij->B->n = ec*mat->bs; 258a30f8f8cSSatish Balay ierr = PetscFree(indices);CHKERRQ(ierr); 259a30f8f8cSSatish Balay #endif 260633e10c7SHong Zhang 261a30f8f8cSSatish Balay /* create local vector that is used to scatter into */ 262a30f8f8cSSatish Balay ierr = VecCreateSeq(PETSC_COMM_SELF,ec*bs,&baij->lvec);CHKERRQ(ierr); 263a30f8f8cSSatish Balay 264a30f8f8cSSatish Balay /* create two temporary index sets for building scatter-gather */ 265eb7adc28SSatish Balay for (i=0; i<ec; i++) { 266a30f8f8cSSatish Balay garray[i] = bs*garray[i]; 267a30f8f8cSSatish Balay } 268a30f8f8cSSatish Balay ierr = ISCreateBlock(PETSC_COMM_SELF,bs,ec,garray,&from);CHKERRQ(ierr); 26986e15631SSatish Balay for (i=0; i<ec; i++) { 270a30f8f8cSSatish Balay garray[i] = garray[i]/bs; 271a30f8f8cSSatish Balay } 272a30f8f8cSSatish Balay 27313f74950SBarry Smith ierr = PetscMalloc((ec+1)*sizeof(PetscInt),&stmp);CHKERRQ(ierr); 274a30f8f8cSSatish Balay for (i=0; i<ec; i++) { stmp[i] = bs*i; } 275a30f8f8cSSatish Balay ierr = ISCreateBlock(PETSC_COMM_SELF,bs,ec,stmp,&to);CHKERRQ(ierr); 276a30f8f8cSSatish Balay ierr = PetscFree(stmp);CHKERRQ(ierr); 277a30f8f8cSSatish Balay 278a30f8f8cSSatish Balay /* create temporary global vector to generate scatter context */ 279a30f8f8cSSatish Balay /* this is inefficient, but otherwise we must do either 280a30f8f8cSSatish Balay 1) save garray until the first actual scatter when the vector is known or 281a30f8f8cSSatish Balay 2) have another way of generating a scatter context without a vector.*/ 282273d9f13SBarry Smith ierr = VecCreateMPI(mat->comm,mat->n,mat->N,&gvec);CHKERRQ(ierr); 283a30f8f8cSSatish Balay 284a30f8f8cSSatish Balay /* gnerate the scatter context */ 285a30f8f8cSSatish Balay ierr = VecScatterCreate(gvec,from,baij->lvec,to,&baij->Mvctx);CHKERRQ(ierr); 286a30f8f8cSSatish Balay 287a30f8f8cSSatish Balay /* 288a30f8f8cSSatish Balay Post the receives for the first matrix vector product. We sync-chronize after 289a30f8f8cSSatish Balay this on the chance that the user immediately calls MatMult() after assemblying 290a30f8f8cSSatish Balay the matrix. 291a30f8f8cSSatish Balay */ 292a30f8f8cSSatish Balay ierr = VecScatterPostRecvs(gvec,baij->lvec,INSERT_VALUES,SCATTER_FORWARD,baij->Mvctx);CHKERRQ(ierr); 293a30f8f8cSSatish Balay ierr = MPI_Barrier(mat->comm);CHKERRQ(ierr); 294a30f8f8cSSatish Balay 29552e6d16bSBarry Smith ierr = PetscLogObjectParent(mat,baij->Mvctx);CHKERRQ(ierr); 29652e6d16bSBarry Smith ierr = PetscLogObjectParent(mat,baij->lvec);CHKERRQ(ierr); 29752e6d16bSBarry Smith ierr = PetscLogObjectParent(mat,from);CHKERRQ(ierr); 29852e6d16bSBarry Smith ierr = PetscLogObjectParent(mat,to);CHKERRQ(ierr); 299a30f8f8cSSatish Balay baij->garray = garray; 30052e6d16bSBarry Smith ierr = PetscLogObjectMemory(mat,(ec+1)*sizeof(PetscInt));CHKERRQ(ierr); 301a30f8f8cSSatish Balay ierr = ISDestroy(from);CHKERRQ(ierr); 302a30f8f8cSSatish Balay ierr = ISDestroy(to);CHKERRQ(ierr); 303a30f8f8cSSatish Balay ierr = VecDestroy(gvec);CHKERRQ(ierr); 304a30f8f8cSSatish Balay PetscFunctionReturn(0); 305a30f8f8cSSatish Balay } 306a30f8f8cSSatish Balay 307a30f8f8cSSatish Balay /* 30801b2bd88SHong Zhang Takes the local part of an already assembled MPISBAIJ matrix 309a30f8f8cSSatish Balay and disassembles it. This is to allow new nonzeros into the matrix 310a30f8f8cSSatish Balay that require more communication in the matrix vector multiply. 311a30f8f8cSSatish Balay Thus certain data-structures must be rebuilt. 312a30f8f8cSSatish Balay 313a30f8f8cSSatish Balay Kind of slow! But that's what application programmers get when 314a30f8f8cSSatish Balay they are sloppy. 315a30f8f8cSSatish Balay */ 3164a2ae208SSatish Balay #undef __FUNCT__ 3174a2ae208SSatish Balay #define __FUNCT__ "DisAssemble_MPISBAIJ" 318dfbe8321SBarry Smith PetscErrorCode DisAssemble_MPISBAIJ(Mat A) 319a30f8f8cSSatish Balay { 3202896befeSSatish Balay Mat_MPISBAIJ *baij = (Mat_MPISBAIJ*)A->data; 321a30f8f8cSSatish Balay Mat B = baij->B,Bnew; 322a30f8f8cSSatish Balay Mat_SeqBAIJ *Bbaij = (Mat_SeqBAIJ*)B->data; 323dfbe8321SBarry Smith PetscErrorCode ierr; 32413f74950SBarry Smith PetscInt i,j,mbs=Bbaij->mbs,n = A->N,col,*garray=baij->garray; 32513f74950SBarry Smith PetscInt k,bs=A->bs,bs2=baij->bs2,*rvals,*nz,ec,m=A->m; 326a30f8f8cSSatish Balay MatScalar *a = Bbaij->a; 32787828ca2SBarry Smith PetscScalar *atmp; 32882502324SSatish Balay #if defined(PETSC_USE_MAT_SINGLE) 32913f74950SBarry Smith PetscInt l; 330a30f8f8cSSatish Balay #endif 331a30f8f8cSSatish Balay 332a30f8f8cSSatish Balay PetscFunctionBegin; 33382502324SSatish Balay #if defined(PETSC_USE_MAT_SINGLE) 3348b32f6a4SKris Buschelman ierr = PetscMalloc(A->bs*sizeof(PetscScalar),&atmp); 33582502324SSatish Balay #endif 336a30f8f8cSSatish Balay /* free stuff related to matrix-vec multiply */ 337b0a32e0cSBarry Smith ierr = VecGetSize(baij->lvec,&ec);CHKERRQ(ierr); /* needed for PetscLogObjectMemory below */ 33801b2bd88SHong Zhang ierr = VecDestroy(baij->lvec);CHKERRQ(ierr); 33901b2bd88SHong Zhang baij->lvec = 0; 34001b2bd88SHong Zhang ierr = VecScatterDestroy(baij->Mvctx);CHKERRQ(ierr); 34101b2bd88SHong Zhang baij->Mvctx = 0; 34201b2bd88SHong Zhang 34301b2bd88SHong Zhang ierr = VecDestroy(baij->slvec0);CHKERRQ(ierr); 34401b2bd88SHong Zhang ierr = VecDestroy(baij->slvec0b);CHKERRQ(ierr); 34501b2bd88SHong Zhang baij->slvec0 = 0; 34601b2bd88SHong Zhang ierr = VecDestroy(baij->slvec1);CHKERRQ(ierr); 34701b2bd88SHong Zhang ierr = VecDestroy(baij->slvec1a);CHKERRQ(ierr); 34801b2bd88SHong Zhang ierr = VecDestroy(baij->slvec1b);CHKERRQ(ierr); 34901b2bd88SHong Zhang baij->slvec1 = 0; 35001b2bd88SHong Zhang 351a30f8f8cSSatish Balay if (baij->colmap) { 352a30f8f8cSSatish Balay #if defined (PETSC_USE_CTABLE) 353a30f8f8cSSatish Balay ierr = PetscTableDelete(baij->colmap); baij->colmap = 0;CHKERRQ(ierr); 354a30f8f8cSSatish Balay #else 355a30f8f8cSSatish Balay ierr = PetscFree(baij->colmap);CHKERRQ(ierr); 356a30f8f8cSSatish Balay baij->colmap = 0; 35752e6d16bSBarry Smith ierr = PetscLogObjectMemory(A,-Bbaij->nbs*sizeof(PetscInt));CHKERRQ(ierr); 358a30f8f8cSSatish Balay #endif 359a30f8f8cSSatish Balay } 360a30f8f8cSSatish Balay 361a30f8f8cSSatish Balay /* make sure that B is assembled so we can access its values */ 362a30f8f8cSSatish Balay ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 363a30f8f8cSSatish Balay ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 364a30f8f8cSSatish Balay 365a30f8f8cSSatish Balay /* invent new B and copy stuff over */ 36613f74950SBarry Smith ierr = PetscMalloc(mbs*sizeof(PetscInt),&nz);CHKERRQ(ierr); 367a30f8f8cSSatish Balay for (i=0; i<mbs; i++) { 368a30f8f8cSSatish Balay nz[i] = Bbaij->i[i+1]-Bbaij->i[i]; 369a30f8f8cSSatish Balay } 370f69a0ea3SMatthew Knepley ierr = MatCreate(PETSC_COMM_SELF,&Bnew);CHKERRQ(ierr); 371f69a0ea3SMatthew Knepley ierr = MatSetSizes(Bnew,m,n,m,n);CHKERRQ(ierr); 372be5d1d56SKris Buschelman ierr = MatSetType(Bnew,B->type_name);CHKERRQ(ierr); 373521d7252SBarry Smith ierr = MatSeqBAIJSetPreallocation(Bnew,B->bs,0,nz);CHKERRQ(ierr); 374a30f8f8cSSatish Balay ierr = PetscFree(nz);CHKERRQ(ierr); 375a30f8f8cSSatish Balay 37613f74950SBarry Smith ierr = PetscMalloc(bs*sizeof(PetscInt),&rvals);CHKERRQ(ierr); 377a30f8f8cSSatish Balay for (i=0; i<mbs; i++) { 378a30f8f8cSSatish Balay rvals[0] = bs*i; 379a30f8f8cSSatish Balay for (j=1; j<bs; j++) { rvals[j] = rvals[j-1] + 1; } 380a30f8f8cSSatish Balay for (j=Bbaij->i[i]; j<Bbaij->i[i+1]; j++) { 381a30f8f8cSSatish Balay col = garray[Bbaij->j[j]]*bs; 382a30f8f8cSSatish Balay for (k=0; k<bs; k++) { 383a30f8f8cSSatish Balay #if defined(PETSC_USE_MAT_SINGLE) 384a30f8f8cSSatish Balay for (l=0; l<bs; l++) atmp[l] = a[j*bs2+l]; 385a30f8f8cSSatish Balay #else 38671730473SSatish Balay atmp = a+j*bs2 + k*bs; 387a30f8f8cSSatish Balay #endif 388c8407628SSatish Balay ierr = MatSetValues_SeqSBAIJ(Bnew,bs,rvals,1,&col,atmp,B->insertmode);CHKERRQ(ierr); 389a30f8f8cSSatish Balay col++; 390a30f8f8cSSatish Balay } 391a30f8f8cSSatish Balay } 392a30f8f8cSSatish Balay } 393a30f8f8cSSatish Balay #if defined(PETSC_USE_MAT_SINGLE) 394a30f8f8cSSatish Balay ierr = PetscFree(atmp);CHKERRQ(ierr); 395a30f8f8cSSatish Balay #endif 396a30f8f8cSSatish Balay ierr = PetscFree(baij->garray);CHKERRQ(ierr); 397a30f8f8cSSatish Balay baij->garray = 0; 398a30f8f8cSSatish Balay ierr = PetscFree(rvals);CHKERRQ(ierr); 39952e6d16bSBarry Smith ierr = PetscLogObjectMemory(A,-ec*sizeof(PetscInt));CHKERRQ(ierr); 400a30f8f8cSSatish Balay ierr = MatDestroy(B);CHKERRQ(ierr); 40152e6d16bSBarry Smith ierr = PetscLogObjectParent(A,Bnew);CHKERRQ(ierr); 402a30f8f8cSSatish Balay baij->B = Bnew; 403a30f8f8cSSatish Balay A->was_assembled = PETSC_FALSE; 404a30f8f8cSSatish Balay PetscFunctionReturn(0); 405a30f8f8cSSatish Balay } 406a30f8f8cSSatish Balay 407a30f8f8cSSatish Balay 408a30f8f8cSSatish Balay 409