/*$Id: sbaijov.c,v 1.65 2001/08/06 21:15:42 bsmith Exp $*/ /* Routines to compute overlapping regions of a parallel MPI matrix. Used for finding submatrices that were shared across processors. */ #include "src/mat/impls/sbaij/mpi/mpisbaij.h" #include "petscbt.h" static int MatIncreaseOverlap_MPISBAIJ_Once(Mat,int,IS *); static int MatIncreaseOverlap_MPISBAIJ_Local(Mat,int *,int,int **,PetscBT*); #undef __FUNCT__ #define __FUNCT__ "MatIncreaseOverlap_MPISBAIJ" int MatIncreaseOverlap_MPISBAIJ(Mat C,int is_max,IS is[],int ov) { Mat_MPISBAIJ *c = (Mat_MPISBAIJ*)C->data; int i,ierr,N=C->N, bs=c->bs; IS *is_new; PetscFunctionBegin; ierr = PetscMalloc(is_max*sizeof(IS),&is_new);CHKERRQ(ierr); /* Convert the indices into block format */ ierr = ISCompressIndicesGeneral(N,bs,is_max,is,is_new);CHKERRQ(ierr); if (ov < 0){ SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative overlap specified\n");} for (i=0; idata; int len,idx,*idx_i,isz,col,*n,*data1,**data1_start,*data2,*data2_i,*data,*data_i, size,rank,Mbs,i,j,k,ierr,nrqs,nrqr,*odata1,*odata2, tag1,tag2,flag,proc_id,**odata2_ptr,*ctable=0,*btable,len_b; int *id_r1,*len_r1,proc_end=0,*iwork,*len_s; char *t_p; MPI_Comm comm; MPI_Request *s_waits1,*s_waits2,r_req; MPI_Status *s_status,r_status; PetscBT *table=0; /* mark indices of this processor's is[] */ PetscBT table_i; PetscBT otable; /* mark indices of other processors' is[] */ int bs=c->bs,Bn = c->B->n,Bnbs = Bn/bs,*Bowners; IS is_local,is_gl; PetscFunctionBegin; comm = C->comm; size = c->size; rank = c->rank; Mbs = c->Mbs; ierr = PetscObjectGetNewTag((PetscObject)C,&tag1);CHKERRQ(ierr); ierr = PetscObjectGetNewTag((PetscObject)C,&tag2);CHKERRQ(ierr); /* 1. Send this processor's is[] to other processors */ /*---------------------------------------------------*/ /* allocate spaces */ ierr = PetscMalloc(is_max*sizeof(int),&n);CHKERRQ(ierr); len = 0; for (i=0; irow to proc_id) */ ierr = PetscMalloc(Mbs*sizeof(int),&ctable);CHKERRQ(ierr); for (proc_id=0,j=0; proc_idrowners[proc_id+1]; j++) { ctable[j] = proc_id; } } /* create tables for marking indices */ len_b = is_max*sizeof(PetscBT) + (Mbs/PETSC_BITS_PER_BYTE+1)*is_max*sizeof(char) + 1; ierr = PetscMalloc(len_b,&table);CHKERRQ(ierr); t_p = (char *)(table + is_max); for (i=0; igarray,&is_local);CHKERRQ(ierr); ierr = ISAllGather(is_local, &is_gl);CHKERRQ(ierr); ierr = ISDestroy(is_local);CHKERRQ(ierr); ierr = PetscMalloc((size+1)*sizeof(int),&Bowners);CHKERRQ(ierr); ierr = MPI_Allgather(&Bnbs,1,MPI_INT,Bowners+1,1,MPI_INT,comm);CHKERRQ(ierr); Bowners[0] = 0; for (i=0; i len)len = len_r1[i]; /* ierr = PetscPrintf(PETSC_COMM_SELF, "[%d] expect to recv len=%d from [%d]\n",rank,len_r1[i],id_r1[i]); */ } ierr = PetscMalloc((len+1)*sizeof(int),&odata1);CHKERRQ(ierr); ierr = PetscMalloc(size*sizeof(int**),&odata2_ptr);CHKERRQ(ierr); k = 0; while (k < nrqr){ /* Receive messages */ ierr = MPI_Iprobe(MPI_ANY_SOURCE,tag1,comm,&flag,&r_status);CHKERRQ(ierr); if (flag){ ierr = MPI_Get_count(&r_status,MPI_INT,&len);CHKERRQ(ierr); proc_id = r_status.MPI_SOURCE; ierr = MPI_Irecv(odata1,len,MPI_INT,proc_id,r_status.MPI_TAG,comm,&r_req);CHKERRQ(ierr); ierr = MPI_Wait(&r_req,&r_status);CHKERRQ(ierr); /* ierr = PetscPrintf(PETSC_COMM_SELF, " [%d] recv %d from [%d]\n",rank,len,proc_id); */ /* Process messages */ ierr = MatIncreaseOverlap_MPISBAIJ_Local(C,odata1,OTHER,&odata2_ptr[k],&otable);CHKERRQ(ierr); odata2 = odata2_ptr[k]; len = 1 + odata2[0]; for (i=0; i 1+is_max){ /* Add data2 into data */ data2_i = data2 + 1 + is_max; for (i=0; idata; Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)(c->A)->data; Mat_SeqBAIJ *b = (Mat_SeqBAIJ*)(c->B)->data; int ierr,row,mbs,Mbs,*nidx,*nidx_i,col,isz,isz0,*ai,*aj,*bi,*bj,*garray,rstart,l; int a_start,a_end,b_start,b_end,i,j,k,is_max,*idx_i,n; PetscBT table0; /* mark the indices of input is[] for look up */ PetscBT table_i; /* poits to i-th table. When whose=OTHER, a single table is used for all is[] */ PetscFunctionBegin; Mbs = c->Mbs; mbs = a->mbs; ai = a->i; aj = a->j; bi = b->i; bj = b->j; garray = c->garray; rstart = c->rstart; is_max = data[0]; ierr = PetscBTCreate(Mbs,table0);CHKERRQ(ierr); ierr = PetscMalloc((1+is_max*(Mbs+1))*sizeof(int),&nidx);CHKERRQ(ierr); nidx[0] = is_max; idx_i = data + is_max + 1; /* ptr to input is[0] array */ nidx_i = nidx + is_max + 1; /* ptr to output is[0] array */ for (i=0; i 0) { isz0 = 0; for (j=0; j= Mbs) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"index col %d >= Mbs %d",col,Mbs); if(!PetscBTLookupSet(table_i,col)) { ierr = PetscBTSet(table0,col);CHKERRQ(ierr); if (whose == MINE) {nidx_i[isz0] = col;} isz0++; } } if (whose == MINE) {isz = isz0;} k = 0; /* no. of indices from input is[i] that have been examined */ for (row=0; row= isz0) break; /* for (row=0; row 0) */ if (i < is_max - 1){ idx_i += n; /* ptr to input is[i+1] array */ nidx_i += isz; /* ptr to output is[i+1] array */ } nidx[1+i] = isz; /* size of new is[i] */ } /* for each is */ *data_new = nidx; ierr = PetscBTDestroy(table0);CHKERRQ(ierr); PetscFunctionReturn(0); }