1632d0f97SHong Zhang /*$Id: sbaijov.c,v 1.65 2001/08/06 21:15:42 bsmith Exp $*/ 2632d0f97SHong Zhang 3632d0f97SHong Zhang /* 4632d0f97SHong Zhang Routines to compute overlapping regions of a parallel MPI matrix. 5632d0f97SHong Zhang Used for finding submatrices that were shared across processors. 6632d0f97SHong Zhang */ 7632d0f97SHong Zhang #include "src/mat/impls/sbaij/mpi/mpisbaij.h" 8632d0f97SHong Zhang #include "petscbt.h" 9632d0f97SHong Zhang 10632d0f97SHong Zhang static int MatIncreaseOverlap_MPISBAIJ_Once(Mat,int,IS *); 11bfc6803cSHong Zhang static int MatIncreaseOverlap_MPISBAIJ_Local(Mat,int *,int,int **,PetscBT*); 12632d0f97SHong Zhang 13632d0f97SHong Zhang #undef __FUNCT__ 14632d0f97SHong Zhang #define __FUNCT__ "MatIncreaseOverlap_MPISBAIJ" 15c910923dSHong Zhang int MatIncreaseOverlap_MPISBAIJ(Mat C,int is_max,IS is[],int ov) 16632d0f97SHong Zhang { 17*d9489beaSHong Zhang Mat_MPISBAIJ *c = (Mat_MPISBAIJ*)C->data; 18*d9489beaSHong Zhang int i,ierr,N=C->N, bs=c->bs; 19632d0f97SHong Zhang IS *is_new; 20632d0f97SHong Zhang 21632d0f97SHong Zhang PetscFunctionBegin; 22c910923dSHong Zhang ierr = PetscMalloc(is_max*sizeof(IS),&is_new);CHKERRQ(ierr); 23632d0f97SHong Zhang /* Convert the indices into block format */ 24*d9489beaSHong Zhang ierr = IsCompressIndicesGeneral(N,bs,is_max,is,is_new);CHKERRQ(ierr); 25632d0f97SHong Zhang if (ov < 0){ SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative overlap specified\n");} 26632d0f97SHong Zhang for (i=0; i<ov; ++i) { 27c910923dSHong Zhang ierr = MatIncreaseOverlap_MPISBAIJ_Once(C,is_max,is_new);CHKERRQ(ierr); 28632d0f97SHong Zhang } 29c910923dSHong Zhang for (i=0; i<is_max; i++) {ierr = ISDestroy(is[i]);CHKERRQ(ierr);} 30*d9489beaSHong Zhang ierr = IsExpandIndicesGeneral(N,bs,is_max,is_new,is);CHKERRQ(ierr); 31c910923dSHong Zhang for (i=0; i<is_max; i++) {ierr = ISDestroy(is_new[i]);CHKERRQ(ierr);} 32632d0f97SHong Zhang ierr = PetscFree(is_new);CHKERRQ(ierr); 33632d0f97SHong Zhang PetscFunctionReturn(0); 34632d0f97SHong Zhang } 35632d0f97SHong Zhang 364a69c536SBarry Smith typedef enum {MINE,OTHER} WhoseOwner; 370472cc68SHong Zhang /* data1, odata1 and odata2 are packed in the format (for communication): 38a2a9f22aSHong Zhang data[0] = is_max, no of is 39a2a9f22aSHong Zhang data[1] = size of is[0] 40a2a9f22aSHong Zhang ... 41a2a9f22aSHong Zhang data[is_max] = size of is[is_max-1] 42a2a9f22aSHong Zhang data[is_max + 1] = data(is[0]) 43a2a9f22aSHong Zhang ... 44a2a9f22aSHong Zhang data[is_max+1+sum(size of is[k]), k=0,...,i-1] = data(is[i]) 45a2a9f22aSHong Zhang ... 460472cc68SHong Zhang data2 is packed in the format (for creating output is[]): 470472cc68SHong Zhang data[0] = is_max, no of is 480472cc68SHong Zhang data[1] = size of is[0] 490472cc68SHong Zhang ... 500472cc68SHong Zhang data[is_max] = size of is[is_max-1] 510472cc68SHong Zhang data[is_max + 1] = data(is[0]) 520472cc68SHong Zhang ... 530472cc68SHong Zhang data[is_max + 1 + Mbs*i) = data(is[i]) 540472cc68SHong Zhang ... 55a2a9f22aSHong Zhang */ 56632d0f97SHong Zhang #undef __FUNCT__ 57632d0f97SHong Zhang #define __FUNCT__ "MatIncreaseOverlap_MPISBAIJ_Once" 58c910923dSHong Zhang static int MatIncreaseOverlap_MPISBAIJ_Once(Mat C,int is_max,IS is[]) 59632d0f97SHong Zhang { 60632d0f97SHong Zhang Mat_MPISBAIJ *c = (Mat_MPISBAIJ*)C->data; 610472cc68SHong Zhang int len,*idx_i,isz,col,*n,*data1,*data2,*data2_i,*data,*data_i, 620472cc68SHong Zhang size,rank,Mbs,i,j,k,ierr,nrqs,*odata1,*odata2, 630472cc68SHong Zhang tag1,tag2,flag,proc_id,**odata2_ptr; 64bfc6803cSHong Zhang char *t_p; 65632d0f97SHong Zhang MPI_Comm comm; 660472cc68SHong Zhang MPI_Request *s_waits,r_req; 67632d0f97SHong Zhang MPI_Status *s_status,r_status; 68bfc6803cSHong Zhang PetscBT *table; /* mark indices of this processor's is[] */ 69fc70d14eSHong Zhang PetscBT table_i; 70bfc6803cSHong Zhang PetscBT otable; /* mark indices of other processors' is[] */ 71632d0f97SHong Zhang PetscFunctionBegin; 72632d0f97SHong Zhang 73632d0f97SHong Zhang comm = C->comm; 74632d0f97SHong Zhang size = c->size; 75632d0f97SHong Zhang rank = c->rank; 76632d0f97SHong Zhang Mbs = c->Mbs; 77632d0f97SHong Zhang 78c910923dSHong Zhang ierr = PetscObjectGetNewTag((PetscObject)C,&tag1);CHKERRQ(ierr); 79c910923dSHong Zhang ierr = PetscObjectGetNewTag((PetscObject)C,&tag2);CHKERRQ(ierr); 80c910923dSHong Zhang 81a2a9f22aSHong Zhang /* create tables for marking indices */ 82a2a9f22aSHong Zhang len = is_max*sizeof(PetscBT) + (Mbs/PETSC_BITS_PER_BYTE+1)*is_max*sizeof(char) + 1; 83bfc6803cSHong Zhang ierr = PetscMalloc(len,&table);CHKERRQ(ierr); 84a2a9f22aSHong Zhang t_p = (char *)(table + is_max); 85a2a9f22aSHong Zhang for (i=0; i<is_max; i++) { 86bfc6803cSHong Zhang table[i] = t_p + (Mbs/PETSC_BITS_PER_BYTE+1)*i; 87a2a9f22aSHong Zhang } 880472cc68SHong Zhang ierr = PetscBTCreate(Mbs,otable);CHKERRQ(ierr); 89632d0f97SHong Zhang 90bfc6803cSHong Zhang /* 1. Send this processor's is[] to all other processors */ 91bfc6803cSHong Zhang /*-------------------------------------------------------*/ 92632d0f97SHong Zhang /* Allocate Memory for outgoing messages */ 93a2a9f22aSHong Zhang len = is_max*sizeof(int); 94a2a9f22aSHong Zhang ierr = PetscMalloc(len,&n);CHKERRQ(ierr); 95a2a9f22aSHong Zhang 96c910923dSHong Zhang len = 1 + is_max; 97c910923dSHong Zhang for (i=0; i<is_max; i++) { 98632d0f97SHong Zhang ierr = ISGetLocalSize(is[i],&n[i]);CHKERRQ(ierr); 99632d0f97SHong Zhang len += n[i]; 100632d0f97SHong Zhang } 101a2a9f22aSHong Zhang ierr = PetscMalloc(len*sizeof(int),&data1);CHKERRQ(ierr); 102632d0f97SHong Zhang 103632d0f97SHong Zhang /* Form the outgoing messages */ 104a2a9f22aSHong Zhang data1[0] = is_max; 105c910923dSHong Zhang k = is_max + 1; 106a2a9f22aSHong Zhang for (i=0; i<is_max; i++) { 107a2a9f22aSHong Zhang data1[1+i] = n[i]; 108a2a9f22aSHong Zhang ierr = ISGetIndices(is[i],&idx_i);CHKERRQ(ierr); 109a2a9f22aSHong Zhang for (j=0; j<data1[i+1]; j++){ 110a2a9f22aSHong Zhang data1[k++] = idx_i[j]; 111632d0f97SHong Zhang } 112a2a9f22aSHong Zhang ierr = ISRestoreIndices(is[i],&idx_i);CHKERRQ(ierr); 113a2a9f22aSHong Zhang ierr = ISDestroy(is[i]);CHKERRQ(ierr); 114632d0f97SHong Zhang } 115fc70d14eSHong Zhang if (k != len) SETERRQ2(1,"Error on forming the outgoing messages: k %d != len %d",k,len); 116bfc6803cSHong Zhang ierr = PetscFree(n);CHKERRQ(ierr); 117632d0f97SHong Zhang 118632d0f97SHong Zhang /* Now post the sends */ 1190472cc68SHong Zhang ierr = PetscMalloc(size*sizeof(MPI_Request),&s_waits);CHKERRQ(ierr); 120632d0f97SHong Zhang k = 0; 121a2a9f22aSHong Zhang for (proc_id=0; proc_id<size; ++proc_id) { /* send data1 to processor [proc_id] */ 122c910923dSHong Zhang if (proc_id != rank){ 1230472cc68SHong Zhang ierr = MPI_Isend(data1,len,MPI_INT,proc_id,tag1,comm,s_waits+k);CHKERRQ(ierr); 124bfc6803cSHong Zhang /* printf(" [%d] send %d msg to [%d], data1: \n",rank,len,proc_id); */ 125632d0f97SHong Zhang k++; 126632d0f97SHong Zhang } 127632d0f97SHong Zhang } 128632d0f97SHong Zhang 129dc008846SHong Zhang /* 2. Do local work on this processor's is[] */ 130dc008846SHong Zhang /*-------------------------------------------*/ 1310472cc68SHong Zhang ierr = MatIncreaseOverlap_MPISBAIJ_Local(C,data1,MINE,&data,table);CHKERRQ(ierr); 132632d0f97SHong Zhang 133632d0f97SHong Zhang /* 3. Receive other's is[] and process. Then send back */ 134bfc6803cSHong Zhang /*-----------------------------------------------------*/ 1350472cc68SHong Zhang /* Sending this processor's is[] is done */ 136632d0f97SHong Zhang nrqs = size-1; 137632d0f97SHong Zhang ierr = PetscMalloc(size*sizeof(MPI_Status),&s_status);CHKERRQ(ierr); 1380472cc68SHong Zhang ierr = MPI_Waitall(nrqs,s_waits,s_status);CHKERRQ(ierr); 139dc008846SHong Zhang 140bfc6803cSHong Zhang ierr = PetscMalloc(size*sizeof(int**),&odata2_ptr);CHKERRQ(ierr); 141632d0f97SHong Zhang k = 0; 142632d0f97SHong Zhang do { 143632d0f97SHong Zhang /* Receive messages */ 144bfc6803cSHong Zhang ierr = MPI_Iprobe(MPI_ANY_SOURCE,tag1,comm,&flag,&r_status);CHKERRQ(ierr); 145632d0f97SHong Zhang if (flag){ 146bfc6803cSHong Zhang ierr = MPI_Get_count(&r_status,MPI_INT,&len);CHKERRQ(ierr); 147632d0f97SHong Zhang proc_id = r_status.MPI_SOURCE; 148a2a9f22aSHong Zhang ierr = PetscMalloc(len*sizeof(int),&odata1);CHKERRQ(ierr); 149bfc6803cSHong Zhang ierr = MPI_Irecv(odata1,len,MPI_INT,proc_id,r_status.MPI_TAG,comm,&r_req);CHKERRQ(ierr); 150fc70d14eSHong Zhang /* printf(" [%d] recv %d msg from [%d]\n",rank,len,proc_id); */ 151632d0f97SHong Zhang 152fc70d14eSHong Zhang /* Process messages */ 153bfc6803cSHong Zhang ierr = MatIncreaseOverlap_MPISBAIJ_Local(C,odata1,OTHER,&odata2_ptr[k],&otable);CHKERRQ(ierr); 154a2a9f22aSHong Zhang odata2 = odata2_ptr[k]; 155a2a9f22aSHong Zhang len = 1 + odata2[0]; 156a2a9f22aSHong Zhang for (i=0; i<odata2[0]; i++){ 157a2a9f22aSHong Zhang len += odata2[1 + i]; 158fc70d14eSHong Zhang } 159632d0f97SHong Zhang 160632d0f97SHong Zhang /* Send messages back */ 1610472cc68SHong Zhang ierr = MPI_Isend(odata2,len,MPI_INT,proc_id,tag2,comm,s_waits+k);CHKERRQ(ierr); 162bfc6803cSHong Zhang /* printf(" [%d] send %d msg back to [%d] \n",rank,len,proc_id); */ 163632d0f97SHong Zhang 164a2a9f22aSHong Zhang ierr = PetscFree(odata1);CHKERRQ(ierr); 165fc70d14eSHong Zhang k++; 166632d0f97SHong Zhang } 167632d0f97SHong Zhang } while (k < nrqs); 168632d0f97SHong Zhang 169fc70d14eSHong Zhang /* 4. Receive work done on other processors, then merge */ 170632d0f97SHong Zhang /*--------------------------------------------------------*/ 1710472cc68SHong Zhang /* Allocate memory for incoming data */ 172bfc6803cSHong Zhang len = (1+is_max*(Mbs+1)); 1730472cc68SHong Zhang ierr = PetscMalloc(len*sizeof(int),&data2);CHKERRQ(ierr); 174bfc6803cSHong Zhang 175bfc6803cSHong Zhang /* Sending others' is[] is done */ 1760472cc68SHong Zhang ierr = MPI_Waitall(nrqs,s_waits,s_status);CHKERRQ(ierr); 177fc70d14eSHong Zhang for (k=0; k<nrqs; k++){ 178a2a9f22aSHong Zhang ierr = PetscFree(odata2_ptr[k]);CHKERRQ(ierr); 179fc70d14eSHong Zhang } 180a2a9f22aSHong Zhang ierr = PetscFree(odata2_ptr);CHKERRQ(ierr); 181fc70d14eSHong Zhang 182632d0f97SHong Zhang k = 0; 183632d0f97SHong Zhang do { 184632d0f97SHong Zhang /* Receive messages */ 185c910923dSHong Zhang ierr = MPI_Iprobe(MPI_ANY_SOURCE,tag2,comm,&flag,&r_status); 186632d0f97SHong Zhang if (flag){ 187bfc6803cSHong Zhang ierr = MPI_Get_count(&r_status,MPI_INT,&len);CHKERRQ(ierr); 188632d0f97SHong Zhang proc_id = r_status.MPI_SOURCE; 1890472cc68SHong Zhang ierr = MPI_Irecv(data2,len,MPI_INT,proc_id,r_status.MPI_TAG,comm,&r_req);CHKERRQ(ierr); 1900472cc68SHong Zhang /* printf(" [%d] recv %d msg from [%d], data2:\n",rank,len,proc_id); */ 191632d0f97SHong Zhang 1920472cc68SHong Zhang /* Add data2 into data */ 1930472cc68SHong Zhang data2_i = data2 + 1 + is_max; 194fc70d14eSHong Zhang for (i=0; i<is_max; i++){ 195fc70d14eSHong Zhang table_i = table[i]; 196bfc6803cSHong Zhang data_i = data + 1 + is_max + Mbs*i; 197bfc6803cSHong Zhang isz = data[1+i]; 1980472cc68SHong Zhang for (j=0; j<data2[1+i]; j++){ 1990472cc68SHong Zhang col = data2_i[j]; 200bfc6803cSHong Zhang if (!PetscBTLookupSet(table_i,col)) {data_i[isz++] = col;} 201fc70d14eSHong Zhang } 202bfc6803cSHong Zhang data[1+i] = isz; 2030472cc68SHong Zhang if (i < is_max - 1) data2_i += data2[1+i]; 204fc70d14eSHong Zhang } 205632d0f97SHong Zhang k++; 206632d0f97SHong Zhang } 207632d0f97SHong Zhang } while (k < nrqs); 208632d0f97SHong Zhang 209c910923dSHong Zhang /* 5. Create new is[] */ 210c910923dSHong Zhang /*--------------------*/ 211c910923dSHong Zhang for (i=0; i<is_max; i++) { 212bfc6803cSHong Zhang data_i = data + 1 + is_max + Mbs*i; 213bfc6803cSHong Zhang ierr = ISCreateGeneral(PETSC_COMM_SELF,data[1+i],data_i,is+i);CHKERRQ(ierr); 214632d0f97SHong Zhang } 215bfc6803cSHong Zhang ierr = PetscFree(data1);CHKERRQ(ierr); 216a2a9f22aSHong Zhang ierr = PetscFree(data2);CHKERRQ(ierr); 2170472cc68SHong Zhang ierr = PetscFree(data);CHKERRQ(ierr); 2180472cc68SHong Zhang ierr = PetscFree(s_waits);CHKERRQ(ierr); 219632d0f97SHong Zhang ierr = PetscFree(s_status);CHKERRQ(ierr); 220fc70d14eSHong Zhang ierr = PetscFree(table);CHKERRQ(ierr); 221bfc6803cSHong Zhang ierr = PetscBTDestroy(otable);CHKERRQ(ierr); 222632d0f97SHong Zhang PetscFunctionReturn(0); 223632d0f97SHong Zhang } 224632d0f97SHong Zhang 225632d0f97SHong Zhang #undef __FUNCT__ 226632d0f97SHong Zhang #define __FUNCT__ "MatIncreaseOverlap_MPISBAIJ_Local" 227632d0f97SHong Zhang /* 228dc008846SHong Zhang MatIncreaseOverlap_MPISBAIJ_Local - Called by MatIncreaseOverlap, to do 229632d0f97SHong Zhang the work on the local processor. 230632d0f97SHong Zhang 231632d0f97SHong Zhang Inputs: 232632d0f97SHong Zhang C - MAT_MPISBAIJ; 233bfc6803cSHong Zhang data - holds is[]. See MatIncreaseOverlap_MPISBAIJ_Once() for the format. 234bfc6803cSHong Zhang whose - whose is[] to be processed, 235bfc6803cSHong Zhang MINE: this processor's is[] 236bfc6803cSHong Zhang OTHER: other processor's is[] 237632d0f97SHong Zhang Output: 2380472cc68SHong Zhang data_new - whose = MINE: 2390472cc68SHong Zhang holds input and newly found indices in the same format as data 2400472cc68SHong Zhang whose = OTHER: 2410472cc68SHong Zhang only holds the newly found indices 2420472cc68SHong Zhang table - table[i]: mark the indices of is[i], i=0,...,is_max. Used only in the case 'whose=MINE'. 243632d0f97SHong Zhang */ 244bfc6803cSHong Zhang static int MatIncreaseOverlap_MPISBAIJ_Local(Mat C,int *data,int whose,int **data_new,PetscBT *table) 245632d0f97SHong Zhang { 246632d0f97SHong Zhang Mat_MPISBAIJ *c = (Mat_MPISBAIJ*)C->data; 247dc008846SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)(c->A)->data; 248dc008846SHong Zhang Mat_SeqBAIJ *b = (Mat_SeqBAIJ*)(c->B)->data; 24931f99336SHong Zhang int ierr,row,mbs,Mbs,*nidx,*nidx_i,col,isz,isz0,*ai,*aj,*bi,*bj,*garray,rstart,l; 250dc008846SHong Zhang int a_start,a_end,b_start,b_end,i,j,k,is_max,*idx_i,n; 251bfc6803cSHong Zhang PetscBT table0; /* mark the indices of input is[] for look up */ 252bfc6803cSHong Zhang PetscBT table_i; /* poits to i-th table. When whose=OTHER, a single table is used for all is[] */ 253632d0f97SHong Zhang 254632d0f97SHong Zhang PetscFunctionBegin; 25531f99336SHong Zhang Mbs = c->Mbs; mbs = a->mbs; 256dc008846SHong Zhang ai = a->i; aj = a->j; 257dc008846SHong Zhang bi = b->i; bj = b->j; 258632d0f97SHong Zhang garray = c->garray; 259dc008846SHong Zhang rstart = c->rstart; 260dc008846SHong Zhang is_max = data[0]; 261632d0f97SHong Zhang 262fc70d14eSHong Zhang ierr = PetscBTCreate(Mbs,table0);CHKERRQ(ierr); 263fc70d14eSHong Zhang 264fc70d14eSHong Zhang ierr = PetscMalloc((1+is_max*(Mbs+1))*sizeof(int),&nidx);CHKERRQ(ierr); 265fc70d14eSHong Zhang nidx[0] = is_max; 266fc70d14eSHong Zhang 267fc70d14eSHong Zhang idx_i = data + is_max + 1; /* ptr to input is[0] array */ 268bfc6803cSHong Zhang nidx_i = nidx + is_max + 1; /* ptr to output is[0] array */ 269dc008846SHong Zhang for (i=0; i<is_max; i++) { /* for each is */ 270dc008846SHong Zhang isz = 0; 271fc70d14eSHong Zhang n = data[1+i]; /* size of input is[i] */ 272dc008846SHong Zhang 273bfc6803cSHong Zhang /* initialize table_i, set table0 */ 274bfc6803cSHong Zhang if (whose == MINE){ /* process this processor's is[] */ 275bfc6803cSHong Zhang table_i = table[i]; 2760472cc68SHong Zhang nidx_i = nidx + 1+ is_max + Mbs*i; 277bfc6803cSHong Zhang } else { /* process other processor's is[] - only use one temp table */ 278bfc6803cSHong Zhang table_i = *table; 279bfc6803cSHong Zhang } 280bfc6803cSHong Zhang ierr = PetscBTMemzero(Mbs,table_i);CHKERRQ(ierr); 281bfc6803cSHong Zhang ierr = PetscBTMemzero(Mbs,table0);CHKERRQ(ierr); 282fc70d14eSHong Zhang if (n > 0) { 283bfc6803cSHong Zhang isz0 = 0; 284dc008846SHong Zhang for (j=0; j<n; j++){ 285dc008846SHong Zhang col = idx_i[j]; 286dc008846SHong Zhang if (col >= Mbs) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"index col %d >= Mbs %d",col,Mbs); 287bfc6803cSHong Zhang if(!PetscBTLookupSet(table_i,col)) { 288bfc6803cSHong Zhang ierr = PetscBTSet(table0,col);CHKERRQ(ierr); 2890472cc68SHong Zhang if (whose == MINE) {nidx_i[isz0] = col;} 290bfc6803cSHong Zhang isz0++; 291bfc6803cSHong Zhang } 292632d0f97SHong Zhang } 293dc008846SHong Zhang 2940472cc68SHong Zhang if (whose == MINE) {isz = isz0;} 295fc70d14eSHong Zhang k = 0; /* no. of indices from input is[i] that have been examined */ 296dc008846SHong Zhang for (row=0; row<mbs; row++){ 297dc008846SHong Zhang a_start = ai[row]; a_end = ai[row+1]; 298dc008846SHong Zhang b_start = bi[row]; b_end = bi[row+1]; 2990472cc68SHong Zhang if (PetscBTLookup(table0,row+rstart)){ /* row is on input is[i]: 3000472cc68SHong Zhang do row search: collect all col in this row */ 301dc008846SHong Zhang for (l = a_start; l<a_end ; l++){ /* Amat */ 302dc008846SHong Zhang col = aj[l] + rstart; 303fc70d14eSHong Zhang if (!PetscBTLookupSet(table_i,col)) {nidx_i[isz++] = col;} 304dc008846SHong Zhang } 305dc008846SHong Zhang for (l = b_start; l<b_end ; l++){ /* Bmat */ 306dc008846SHong Zhang col = garray[bj[l]]; 307fc70d14eSHong Zhang if (!PetscBTLookupSet(table_i,col)) {nidx_i[isz++] = col;} 308dc008846SHong Zhang } 309dc008846SHong Zhang k++; 310dc008846SHong Zhang if (k >= isz0) break; /* for (row=0; row<mbs; row++) */ 3110472cc68SHong Zhang } else { /* row is not on input is[i]: 3120472cc68SHong Zhang do col serach: add row onto nidx_i if there is a col in nidx_i */ 313dc008846SHong Zhang for (l = a_start; l<a_end ; l++){ /* Amat */ 314dc008846SHong Zhang col = aj[l] + rstart; 315dc008846SHong Zhang if (PetscBTLookup(table0,col)){ 316fc70d14eSHong Zhang if (!PetscBTLookupSet(table_i,row+rstart)) {nidx_i[isz++] = row+rstart;} 317dc008846SHong Zhang break; /* for l = start; l<end ; l++) */ 318632d0f97SHong Zhang } 319632d0f97SHong Zhang } 320dc008846SHong Zhang for (l = b_start; l<b_end ; l++){ /* Bmat */ 321dc008846SHong Zhang col = garray[bj[l]]; 322dc008846SHong Zhang if (PetscBTLookup(table0,col)){ 323fc70d14eSHong Zhang if (!PetscBTLookupSet(table_i,row+rstart)) {nidx_i[isz++] = row+rstart;} 324dc008846SHong Zhang break; /* for l = start; l<end ; l++) */ 325632d0f97SHong Zhang } 326dc008846SHong Zhang } 327dc008846SHong Zhang } 328bfc6803cSHong Zhang } 329fc70d14eSHong Zhang } /* if (n > 0) */ 330dc008846SHong Zhang 331dc008846SHong Zhang if (i < is_max - 1){ 332fc70d14eSHong Zhang idx_i += n; /* ptr to input is[i+1] array */ 333bfc6803cSHong Zhang nidx_i += isz; /* ptr to output is[i+1] array */ 334dc008846SHong Zhang } 335fc70d14eSHong Zhang nidx[1+i] = isz; /* size of new is[i] */ 3361ab97a2aSSatish Balay } /* for each is */ 337dc008846SHong Zhang *data_new = nidx; 338dc008846SHong Zhang ierr = PetscBTDestroy(table0);CHKERRQ(ierr); 339632d0f97SHong Zhang 340632d0f97SHong Zhang PetscFunctionReturn(0); 341632d0f97SHong Zhang } 342632d0f97SHong Zhang 343632d0f97SHong Zhang 344