static PetscErrorCode ISCopy_Block(IS is,IS isy) { IS_Block *is_block = (IS_Block*)is->data,*isy_block = (IS_Block*)isy->data; PetscInt bs, n, N, bsy, ny, Ny; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscLayoutGetBlockSize(is->map, &bs); CHKERRQ(ierr); ierr = PetscLayoutGetLocalSize(is->map, &n); CHKERRQ(ierr); ierr = PetscLayoutGetSize(is->map, &N); CHKERRQ(ierr); ierr = PetscLayoutGetBlockSize(isy->map, &bsy); CHKERRQ(ierr); ierr = PetscLayoutGetLocalSize(isy->map, &ny); CHKERRQ(ierr); ierr = PetscLayoutGetSize(isy->map, &Ny); CHKERRQ(ierr); if (n != ny || N != Ny || bs != bsy) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Index sets incompatible"); isy_block->sorted = is_block->sorted; ierr = PetscMemcpy(isy_block->idx,is_block->idx,(n/bs)*sizeof(PetscInt)); CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode ISInvertPermutation_Block(IS is,PetscInt nlocal,IS *isout) { IS_Block *sub = (IS_Block*)is->data; PetscInt i,*ii,bs,n,*idx = sub->idx; PetscMPIInt size; PetscErrorCode ierr; PetscFunctionBegin; ierr = MPI_Comm_size(PetscObjectComm((PetscObject)is),&size); CHKERRQ(ierr); ierr = PetscLayoutGetBlockSize(is->map, &bs); CHKERRQ(ierr); ierr = PetscLayoutGetLocalSize(is->map, &n); CHKERRQ(ierr); n /= bs; if (size == 1) { ierr = PetscMalloc1(n,&ii); CHKERRQ(ierr); for (i=0; i<n; i++) ii[idx[i]] = i; ierr = ISCreateBlock(PETSC_COMM_SELF,bs,n,ii,PETSC_OWN_POINTER,isout); CHKERRQ(ierr); ierr = ISSetPermutation(*isout); CHKERRQ(ierr); } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No inversion written yet for block IS"); PetscFunctionReturn(0); }
PetscErrorCode ISSetUp_General(IS is) { PetscErrorCode ierr; IS_General *sub = (IS_General*)is->data; const PetscInt *idx = sub->idx; PetscInt n,i,min,max; PetscFunctionBegin; ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); sub->sorted = PETSC_TRUE; for (i=1; i<n; i++) { if (idx[i] < idx[i-1]) {sub->sorted = PETSC_FALSE; break;} } if (n) { min = max = idx[0]; for (i=1; i<n; i++) { if (idx[i] < min) min = idx[i]; if (idx[i] > max) max = idx[i]; } is->min = min; is->max = max; } else { is->min = PETSC_MAX_INT; is->max = PETSC_MIN_INT; } is->isperm = PETSC_FALSE; is->isidentity = PETSC_FALSE; PetscFunctionReturn(0); }
PetscErrorCode ISCreateGeneral_Private(IS is) { PetscErrorCode ierr; IS_General *sub = (IS_General*)is->data; const PetscInt *idx = sub->idx; PetscBool sorted = PETSC_TRUE; PetscInt n,i,min,max; PetscFunctionBegin; ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); ierr = PetscLayoutSetUp(is->map);CHKERRQ(ierr); for (i=1; i<n; i++) { if (idx[i] < idx[i-1]) {sorted = PETSC_FALSE; break;} } if (n) min = max = idx[0]; else min = max = 0; for (i=1; i<n; i++) { if (idx[i] < min) min = idx[i]; if (idx[i] > max) max = idx[i]; } sub->sorted = sorted; is->min = min; is->max = max; is->isperm = PETSC_FALSE; is->isidentity = PETSC_FALSE; ierr = ISViewFromOptions(is,NULL,"-is_view");CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode ISCopy_General(IS is,IS isy) { IS_General *is_general = (IS_General*)is->data,*isy_general = (IS_General*)isy->data; PetscInt n, N, ny, Ny; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); ierr = PetscLayoutGetSize(is->map, &N);CHKERRQ(ierr); ierr = PetscLayoutGetLocalSize(isy->map, &ny);CHKERRQ(ierr); ierr = PetscLayoutGetSize(isy->map, &Ny);CHKERRQ(ierr); if (n != ny || N != Ny) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Index sets incompatible"); isy_general->sorted = is_general->sorted; ierr = PetscMemcpy(isy_general->idx,is_general->idx,n*sizeof(PetscInt));CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode ISGetIndices_Block(IS in,const PetscInt *idx[]) { IS_Block *sub = (IS_Block*)in->data; PetscErrorCode ierr; PetscInt i,j,k,bs,n,*ii,*jj; PetscFunctionBegin; ierr = PetscLayoutGetBlockSize(in->map, &bs); CHKERRQ(ierr); ierr = PetscLayoutGetLocalSize(in->map, &n); CHKERRQ(ierr); n /= bs; if (bs == 1) *idx = sub->idx; else { ierr = PetscMalloc1(bs*n,&jj); CHKERRQ(ierr); *idx = jj; k = 0; ii = sub->idx; for (i=0; i<n; i++) for (j=0; j<bs; j++) jj[k++] = bs*ii[i] + j; } PetscFunctionReturn(0); }
PetscErrorCode ISView_Block(IS is, PetscViewer viewer) { IS_Block *sub = (IS_Block*)is->data; PetscErrorCode ierr; PetscInt i,bs,n,*idx = sub->idx; PetscBool iascii; PetscFunctionBegin; ierr = PetscLayoutGetBlockSize(is->map, &bs);CHKERRQ(ierr); ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); n /= bs; ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); if (iascii) { ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);CHKERRQ(ierr); if (is->isperm) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Block Index set is permutation\n");CHKERRQ(ierr); } ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Block size %D\n",bs);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Number of block indices in set %D\n",n);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(viewer,"The first indices of each block are\n");CHKERRQ(ierr); for (i=0; i<n; i++) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Block %D Index %D\n",i,idx[i]);CHKERRQ(ierr); } ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_FALSE);CHKERRQ(ierr); } PetscFunctionReturn(0); }
PetscErrorCode ISGetLocalSize_General(IS is,PetscInt *size) { PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscLayoutGetLocalSize(is->map, size);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode ISBlockGetLocalSize_Block(IS is,PetscInt *size) { PetscInt bs, n; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscLayoutGetBlockSize(is->map, &bs);CHKERRQ(ierr); ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); *size = n/bs; PetscFunctionReturn(0); }
PetscErrorCode ISDuplicate_General(IS is,IS *newIS) { PetscErrorCode ierr; IS_General *sub = (IS_General*)is->data; PetscInt n; PetscFunctionBegin; ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); ierr = ISCreateGeneral(PetscObjectComm((PetscObject) is), n, sub->idx, PETSC_COPY_VALUES, newIS);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode ISOnComm_General(IS is,MPI_Comm comm,PetscCopyMode mode,IS *newis) { PetscErrorCode ierr; IS_General *sub = (IS_General*)is->data; PetscInt n; PetscFunctionBegin; if (mode == PETSC_OWN_POINTER) SETERRQ(comm,PETSC_ERR_ARG_WRONG,"Cannot use PETSC_OWN_POINTER"); ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); ierr = ISCreateGeneral(comm,n,sub->idx,mode,newis);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode ISDuplicate_Block(IS is,IS *newIS) { PetscErrorCode ierr; IS_Block *sub = (IS_Block*)is->data; PetscInt bs, n; PetscFunctionBegin; ierr = PetscLayoutGetBlockSize(is->map, &bs);CHKERRQ(ierr); ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); n /= bs; ierr = ISCreateBlock(PetscObjectComm((PetscObject)is),bs,n,sub->idx,PETSC_COPY_VALUES,newIS);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode ISSort_General(IS is) { IS_General *sub = (IS_General*)is->data; PetscInt n; PetscErrorCode ierr; PetscFunctionBegin; if (sub->sorted) PetscFunctionReturn(0); ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); ierr = PetscSortInt(n,sub->idx);CHKERRQ(ierr); sub->sorted = PETSC_TRUE; PetscFunctionReturn(0); }
PetscErrorCode ISSort_Block(IS is) { IS_Block *sub = (IS_Block*)is->data; PetscInt bs, n; PetscErrorCode ierr; PetscFunctionBegin; if (sub->sorted) PetscFunctionReturn(0); ierr = PetscLayoutGetBlockSize(is->map, &bs);CHKERRQ(ierr); ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); ierr = PetscSortInt(n/bs,sub->idx);CHKERRQ(ierr); sub->sorted = PETSC_TRUE; PetscFunctionReturn(0); }
PetscErrorCode ISView_General(IS is,PetscViewer viewer) { IS_General *sub = (IS_General*)is->data; PetscErrorCode ierr; PetscInt i,n,*idx = sub->idx; PetscBool iascii,isbinary,ishdf5; PetscFunctionBegin; ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr); if (iascii) { MPI_Comm comm; PetscMPIInt rank,size; ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);CHKERRQ(ierr); if (size > 1) { if (is->isperm) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d] Index set is permutation\n",rank);CHKERRQ(ierr); } ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d] Number of indices in set %D\n",rank,n);CHKERRQ(ierr); for (i=0; i<n; i++) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d] %D %D\n",rank,i,idx[i]);CHKERRQ(ierr); } } else { if (is->isperm) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Index set is permutation\n");CHKERRQ(ierr); } ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Number of indices in set %D\n",n);CHKERRQ(ierr); for (i=0; i<n; i++) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%D %D\n",i,idx[i]);CHKERRQ(ierr); } } ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_FALSE);CHKERRQ(ierr); } else if (isbinary) { ierr = ISView_General_Binary(is,viewer);CHKERRQ(ierr); } else if (ishdf5) { #if defined(PETSC_HAVE_HDF5) ierr = ISView_General_HDF5(is,viewer);CHKERRQ(ierr); #endif } PetscFunctionReturn(0); }
static PetscErrorCode ISView_Block(IS is, PetscViewer viewer) { IS_Block *sub = (IS_Block*)is->data; PetscErrorCode ierr; PetscInt i,bs,n,*idx = sub->idx; PetscBool iascii; PetscFunctionBegin; ierr = PetscLayoutGetBlockSize(is->map, &bs);CHKERRQ(ierr); ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); n /= bs; ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); if (iascii) { PetscViewerFormat fmt; ierr = PetscViewerGetFormat(viewer,&fmt);CHKERRQ(ierr); if (fmt == PETSC_VIEWER_ASCII_MATLAB) { IS ist; const char *name; const PetscInt *idx; PetscInt n; ierr = PetscObjectGetName((PetscObject)is,&name);CHKERRQ(ierr); ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); ierr = ISGetIndices(is,&idx);CHKERRQ(ierr); ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is),n,idx,PETSC_USE_POINTER,&ist);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)ist,name);CHKERRQ(ierr); ierr = ISView(ist,viewer);CHKERRQ(ierr); ierr = ISDestroy(&ist);CHKERRQ(ierr); ierr = ISRestoreIndices(is,&idx);CHKERRQ(ierr); } else { ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); if (is->isperm) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Block Index set is permutation\n");CHKERRQ(ierr); } ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Block size %D\n",bs);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Number of block indices in set %D\n",n);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(viewer,"The first indices of each block are\n");CHKERRQ(ierr); for (i=0; i<n; i++) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Block %D Index %D\n",i,idx[i]);CHKERRQ(ierr); } ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); } } PetscFunctionReturn(0); }
PetscErrorCode ISView_General_Binary(IS is,PetscViewer viewer) { PetscErrorCode ierr; IS_General *isa = (IS_General*) is->data; PetscMPIInt rank,size,mesgsize,tag = ((PetscObject)viewer)->tag, mesglen; PetscInt n,N,len,j,tr[2]; int fdes; MPI_Status status; PetscInt message_count,flowcontrolcount,*values; PetscFunctionBegin; ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); ierr = PetscLayoutGetSize(is->map, &N);CHKERRQ(ierr); ierr = PetscViewerBinaryGetDescriptor(viewer,&fdes);CHKERRQ(ierr); /* determine maximum message to arrive */ ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)is),&rank);CHKERRQ(ierr); ierr = MPI_Comm_size(PetscObjectComm((PetscObject)is),&size);CHKERRQ(ierr); tr[0] = IS_FILE_CLASSID; tr[1] = N; ierr = PetscViewerBinaryWrite(viewer,tr,2,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); ierr = MPI_Reduce(&n,&len,1,MPIU_INT,MPI_SUM,0,PetscObjectComm((PetscObject)is));CHKERRQ(ierr); ierr = PetscViewerFlowControlStart(viewer,&message_count,&flowcontrolcount);CHKERRQ(ierr); if (!rank) { ierr = PetscBinaryWrite(fdes,isa->idx,n,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); ierr = PetscMalloc1(len,&values);CHKERRQ(ierr); ierr = PetscMPIIntCast(len,&mesgsize);CHKERRQ(ierr); /* receive and save messages */ for (j=1; j<size; j++) { ierr = PetscViewerFlowControlStepMaster(viewer,j,&message_count,flowcontrolcount);CHKERRQ(ierr); ierr = MPI_Recv(values,mesgsize,MPIU_INT,j,tag,PetscObjectComm((PetscObject)is),&status);CHKERRQ(ierr); ierr = MPI_Get_count(&status,MPIU_INT,&mesglen);CHKERRQ(ierr); ierr = PetscBinaryWrite(fdes,values,(PetscInt)mesglen,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr); } ierr = PetscViewerFlowControlEndMaster(viewer,&message_count);CHKERRQ(ierr); ierr = PetscFree(values);CHKERRQ(ierr); } else { ierr = PetscViewerFlowControlStepWorker(viewer,rank,&message_count);CHKERRQ(ierr); ierr = PetscMPIIntCast(n,&mesgsize);CHKERRQ(ierr); ierr = MPI_Send(isa->idx,mesgsize,MPIU_INT,0,tag,PetscObjectComm((PetscObject)is));CHKERRQ(ierr); ierr = PetscViewerFlowControlEndWorker(viewer,&message_count);CHKERRQ(ierr); } PetscFunctionReturn(0); }
PetscErrorCode ISInvertPermutation_General(IS is,PetscInt nlocal,IS *isout) { IS_General *sub = (IS_General*)is->data; PetscInt i,*ii,n,nstart; const PetscInt *idx = sub->idx; PetscMPIInt size; IS istmp,nistmp; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); ierr = MPI_Comm_size(PetscObjectComm((PetscObject)is),&size);CHKERRQ(ierr); if (size == 1) { ierr = PetscMalloc1(n,&ii);CHKERRQ(ierr); for (i=0; i<n; i++) ii[idx[i]] = i; ierr = ISCreateGeneral(PETSC_COMM_SELF,n,ii,PETSC_OWN_POINTER,isout);CHKERRQ(ierr); ierr = ISSetPermutation(*isout);CHKERRQ(ierr); } else { /* crude, nonscalable get entire IS on each processor */ if (nlocal == PETSC_DECIDE) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Do not yet support nlocal of PETSC_DECIDE"); ierr = ISAllGather(is,&istmp);CHKERRQ(ierr); ierr = ISSetPermutation(istmp);CHKERRQ(ierr); ierr = ISInvertPermutation(istmp,PETSC_DECIDE,&nistmp);CHKERRQ(ierr); ierr = ISDestroy(&istmp);CHKERRQ(ierr); /* get the part we need */ ierr = MPI_Scan(&nlocal,&nstart,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)is));CHKERRQ(ierr); #if defined(PETSC_USE_DEBUG) { PetscInt N; PetscMPIInt rank; ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)is),&rank);CHKERRQ(ierr); ierr = PetscLayoutGetSize(is->map, &N);CHKERRQ(ierr); if (rank == size-1) { if (nstart != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Sum of nlocal lengths %d != total IS length %d",nstart,N); } } #endif nstart -= nlocal; ierr = ISGetIndices(nistmp,&idx);CHKERRQ(ierr); ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is),nlocal,idx+nstart,PETSC_COPY_VALUES,isout);CHKERRQ(ierr); ierr = ISRestoreIndices(nistmp,&idx);CHKERRQ(ierr); ierr = ISDestroy(&nistmp);CHKERRQ(ierr); } PetscFunctionReturn(0); }
/*@C PetscSFSetGraphLayout - Set a parallel star forest via global indices and a PetscLayout Collective Input Arguments: + sf - star forest . layout - PetscLayout defining the global space . nleaves - number of leaf vertices on the current process, each of these references a root on any process . ilocal - locations of leaves in leafdata buffers, pass NULL for contiguous storage - iremote - remote locations of root vertices for each leaf on the current process Level: intermediate .seealso: PetscSFCreate(), PetscSFView(), PetscSFSetGraph(), PetscSFGetGraph() @*/ PetscErrorCode PetscSFSetGraphLayout(PetscSF sf,PetscLayout layout,PetscInt nleaves,const PetscInt *ilocal,PetscCopyMode localmode,const PetscInt *iremote) { PetscErrorCode ierr; PetscInt i,nroots; PetscSFNode *remote; PetscFunctionBegin; ierr = PetscLayoutGetLocalSize(layout,&nroots);CHKERRQ(ierr); ierr = PetscMalloc(nleaves*sizeof(PetscSFNode),&remote);CHKERRQ(ierr); for (i=0; i<nleaves; i++) { PetscInt owner = -1; ierr = PetscLayoutFindOwner(layout,iremote[i],&owner);CHKERRQ(ierr); remote[i].rank = owner; remote[i].index = iremote[i] - layout->range[owner]; } ierr = PetscSFSetGraph(sf,nroots,nleaves,ilocal,localmode,remote,PETSC_OWN_POINTER);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode ISIdentity_General(IS is, PetscBool *ident) { IS_General *is_general = (IS_General*)is->data; PetscInt i,n,*idx = is_general->idx; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); is->isidentity = PETSC_TRUE; *ident = PETSC_TRUE; for (i=0; i<n; i++) { if (idx[i] != i) { is->isidentity = PETSC_FALSE; *ident = PETSC_FALSE; break; } } PetscFunctionReturn(0); }
static PetscErrorCode ISSortRemoveDups_General(IS is) { IS_General *sub = (IS_General*)is->data; PetscInt n; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); if (sub->sorted) { ierr = PetscSortedRemoveDupsInt(&n,sub->idx);CHKERRQ(ierr); } else { ierr = PetscSortRemoveDupsInt(&n,sub->idx);CHKERRQ(ierr); } ierr = PetscLayoutSetLocalSize(is->map, n);CHKERRQ(ierr); ierr = PetscLayoutSetSize(is->map, PETSC_DECIDE);CHKERRQ(ierr); ierr = PetscLayoutSetUp(is->map);CHKERRQ(ierr); sub->sorted = PETSC_TRUE; PetscFunctionReturn(0); }
static PetscErrorCode ISSortRemoveDups_Block(IS is) { IS_Block *sub = (IS_Block*)is->data; PetscInt bs, n, nb; PetscErrorCode ierr; PetscFunctionBegin; if (sub->sorted) PetscFunctionReturn(0); ierr = PetscLayoutGetBlockSize(is->map, &bs); CHKERRQ(ierr); ierr = PetscLayoutGetLocalSize(is->map, &n); CHKERRQ(ierr); nb = n/bs; ierr = PetscSortRemoveDupsInt(&nb,sub->idx); CHKERRQ(ierr); ierr = PetscLayoutSetLocalSize(is->map, nb*bs); CHKERRQ(ierr); sub->sorted = PETSC_TRUE; PetscFunctionReturn(0); }
PetscErrorCode ISIdentity_Block(IS is,PetscBool *ident) { IS_Block *is_block = (IS_Block*)is->data; PetscInt i,bs,n,*idx = is_block->idx; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscLayoutGetBlockSize(is->map, &bs);CHKERRQ(ierr); ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); n /= bs; is->isidentity = PETSC_TRUE; *ident = PETSC_TRUE; for (i=0; i<n; i++) { if (idx[i] != bs*i) { is->isidentity = PETSC_FALSE; *ident = PETSC_FALSE; PetscFunctionReturn(0); } } PetscFunctionReturn(0); }
static PetscErrorCode ISLocate_General(IS is,PetscInt key,PetscInt *location) { IS_General *sub = (IS_General*)is->data; PetscInt numIdx, i; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscLayoutGetLocalSize(is->map,&numIdx);CHKERRQ(ierr); if (sub->sorted) {ierr = PetscFindInt(key,numIdx,sub->idx,location);CHKERRQ(ierr);} else { const PetscInt *idx = sub->idx; *location = -1; for (i = 0; i < numIdx; i++) { if (idx[i] == key) { *location = i; PetscFunctionReturn(0); } } } PetscFunctionReturn(0); }
static PetscErrorCode ISSetBlockSize_General(IS is,PetscInt bs) { #if defined(PETSC_USE_DEBUG) IS_General *sub = (IS_General*)is->data; PetscInt n; #endif PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscLayoutSetBlockSize(is->map, bs);CHKERRQ(ierr); #if defined(PETSC_USE_DEBUG) ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); { PetscInt i,j; for (i=0; i<n; i+=bs) { for (j=0; j<bs; j++) { if (sub->idx[i+j] != sub->idx[i]+j) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Index set does not have block structure, cannot set block size to %D",bs); } } } #endif PetscFunctionReturn(0); }
static PetscErrorCode ISContiguousLocal_General(IS is,PetscInt gstart,PetscInt gend,PetscInt *start,PetscBool *contig) { IS_General *sub = (IS_General*)is->data; PetscInt n,i,p; PetscErrorCode ierr; PetscFunctionBegin; *start = 0; *contig = PETSC_TRUE; ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); if (!n) PetscFunctionReturn(0); p = sub->idx[0]; if (p < gstart) goto nomatch; *start = p - gstart; if (n > gend-p) goto nomatch; for (i=1; i<n; i++,p++) { if (sub->idx[i] != p+1) goto nomatch; } PetscFunctionReturn(0); nomatch: *start = -1; *contig = PETSC_FALSE; PetscFunctionReturn(0); }
static PetscErrorCode ISView_General_Binary(IS is,PetscViewer viewer) { PetscErrorCode ierr; PetscBool skipHeader,useMPIIO; IS_General *isa = (IS_General*) is->data; PetscMPIInt rank,size,mesgsize,tag = ((PetscObject)viewer)->tag, mesglen; PetscInt n,N,len,j,tr[2]; int fdes; MPI_Status status; PetscInt message_count,flowcontrolcount,*values; PetscFunctionBegin; /* ierr = ISGetLayout(is,&map);CHKERRQ(ierr); */ ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); ierr = PetscLayoutGetSize(is->map, &N);CHKERRQ(ierr); tr[0] = IS_FILE_CLASSID; tr[1] = N; ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr); if (!skipHeader) { ierr = PetscViewerBinaryWrite(viewer,tr,2,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); } ierr = PetscViewerBinaryGetUseMPIIO(viewer,&useMPIIO);CHKERRQ(ierr); #if defined(PETSC_HAVE_MPIIO) if (useMPIIO) { MPI_File mfdes; MPI_Offset off; PetscMPIInt lsize; PetscInt rstart; const PetscInt *iarray; ierr = PetscMPIIntCast(n,&lsize);CHKERRQ(ierr); ierr = PetscViewerBinaryGetMPIIODescriptor(viewer,&mfdes);CHKERRQ(ierr); ierr = PetscViewerBinaryGetMPIIOOffset(viewer,&off);CHKERRQ(ierr); ierr = PetscLayoutGetRange(is->map,&rstart,NULL);CHKERRQ(ierr); off += rstart*(MPI_Offset)sizeof(PetscInt); /* off is MPI_Offset, not PetscMPIInt */ ierr = MPI_File_set_view(mfdes,off,MPIU_INT,MPIU_INT,(char*)"native",MPI_INFO_NULL);CHKERRQ(ierr); ierr = ISGetIndices(is,&iarray);CHKERRQ(ierr); ierr = MPIU_File_write_all(mfdes,(void*)iarray,lsize,MPIU_INT,MPI_STATUS_IGNORE);CHKERRQ(ierr); ierr = ISRestoreIndices(is,&iarray);CHKERRQ(ierr); ierr = PetscViewerBinaryAddMPIIOOffset(viewer,N*(MPI_Offset)sizeof(PetscInt));CHKERRQ(ierr); PetscFunctionReturn(0); } #endif ierr = PetscViewerBinaryGetDescriptor(viewer,&fdes);CHKERRQ(ierr); ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)is),&rank);CHKERRQ(ierr); ierr = MPI_Comm_size(PetscObjectComm((PetscObject)is),&size);CHKERRQ(ierr); /* determine maximum message to arrive */ ierr = MPI_Reduce(&n,&len,1,MPIU_INT,MPI_MAX,0,PetscObjectComm((PetscObject)is));CHKERRQ(ierr); ierr = PetscViewerFlowControlStart(viewer,&message_count,&flowcontrolcount);CHKERRQ(ierr); if (!rank) { ierr = PetscBinaryWrite(fdes,isa->idx,n,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); ierr = PetscMalloc1(len,&values);CHKERRQ(ierr); ierr = PetscMPIIntCast(len,&mesgsize);CHKERRQ(ierr); /* receive and save messages */ for (j=1; j<size; j++) { ierr = PetscViewerFlowControlStepMaster(viewer,j,&message_count,flowcontrolcount);CHKERRQ(ierr); ierr = MPI_Recv(values,mesgsize,MPIU_INT,j,tag,PetscObjectComm((PetscObject)is),&status);CHKERRQ(ierr); ierr = MPI_Get_count(&status,MPIU_INT,&mesglen);CHKERRQ(ierr); ierr = PetscBinaryWrite(fdes,values,(PetscInt)mesglen,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr); } ierr = PetscViewerFlowControlEndMaster(viewer,&message_count);CHKERRQ(ierr); ierr = PetscFree(values);CHKERRQ(ierr); } else { ierr = PetscViewerFlowControlStepWorker(viewer,rank,&message_count);CHKERRQ(ierr); ierr = PetscMPIIntCast(n,&mesgsize);CHKERRQ(ierr); ierr = MPI_Send(isa->idx,mesgsize,MPIU_INT,0,tag,PetscObjectComm((PetscObject)is));CHKERRQ(ierr); ierr = PetscViewerFlowControlEndWorker(viewer,&message_count);CHKERRQ(ierr); } PetscFunctionReturn(0); }
static PetscErrorCode ISView_General(IS is,PetscViewer viewer) { IS_General *sub = (IS_General*)is->data; PetscErrorCode ierr; PetscInt i,n,*idx = sub->idx; PetscBool iascii,isbinary,ishdf5; PetscFunctionBegin; ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr); if (iascii) { MPI_Comm comm; PetscMPIInt rank,size; PetscViewerFormat fmt; ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); ierr = PetscViewerGetFormat(viewer,&fmt);CHKERRQ(ierr); ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); if (size > 1) { if (fmt == PETSC_VIEWER_ASCII_MATLAB) { const char* name; ierr = PetscObjectGetName((PetscObject)is,&name);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%s_%d = [...\n",name,rank);CHKERRQ(ierr); for (i=0; i<n; i++) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%D\n",idx[i]+1);CHKERRQ(ierr); } ierr = PetscViewerASCIISynchronizedPrintf(viewer,"];\n");CHKERRQ(ierr); } else { PetscInt st = 0; if (fmt == PETSC_VIEWER_ASCII_INDEX) st = is->map->rstart; if (is->isperm) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d] Index set is permutation\n",rank);CHKERRQ(ierr); } ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d] Number of indices in set %D\n",rank,n);CHKERRQ(ierr); for (i=0; i<n; i++) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d] %D %D\n",rank,i + st,idx[i]);CHKERRQ(ierr); } } } else { if (fmt == PETSC_VIEWER_ASCII_MATLAB) { const char* name; ierr = PetscObjectGetName((PetscObject)is,&name);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%s = [...\n",name);CHKERRQ(ierr); for (i=0; i<n; i++) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%D\n",idx[i]+1);CHKERRQ(ierr); } ierr = PetscViewerASCIISynchronizedPrintf(viewer,"];\n");CHKERRQ(ierr); } else { PetscInt st = 0; if (fmt == PETSC_VIEWER_ASCII_INDEX) st = is->map->rstart; if (is->isperm) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Index set is permutation\n");CHKERRQ(ierr); } ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Number of indices in set %D\n",n);CHKERRQ(ierr); for (i=0; i<n; i++) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%D %D\n",i + st,idx[i]);CHKERRQ(ierr); } } } ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); } else if (isbinary) { ierr = ISView_General_Binary(is,viewer);CHKERRQ(ierr); } else if (ishdf5) { #if defined(PETSC_HAVE_HDF5) ierr = ISView_General_HDF5(is,viewer);CHKERRQ(ierr); #endif } PetscFunctionReturn(0); }