static PetscErrorCode ISToGeneral_Block(IS inis) { IS_Block *sub = (IS_Block*)inis->data; PetscInt bs,n; const PetscInt *idx; PetscErrorCode ierr; PetscFunctionBegin; ierr = ISGetBlockSize(inis,&bs); CHKERRQ(ierr); ierr = ISGetLocalSize(inis,&n); CHKERRQ(ierr); ierr = ISGetIndices(inis,&idx); CHKERRQ(ierr); if (bs == 1) { PetscCopyMode mode = sub->borrowed_indices ? PETSC_USE_POINTER : PETSC_OWN_POINTER; sub->borrowed_indices = PETSC_TRUE; /* prevent deallocation when changing the subtype*/ ierr = ISSetType(inis,ISGENERAL); CHKERRQ(ierr); ierr = ISGeneralSetIndices(inis,n,idx,mode); CHKERRQ(ierr); } else { ierr = ISSetType(inis,ISGENERAL); CHKERRQ(ierr); ierr = ISGeneralSetIndices(inis,n,idx,PETSC_OWN_POINTER); CHKERRQ(ierr); } PetscFunctionReturn(0); }
/*@ ISCreateGeneral - Creates a data structure for an index set containing a list of integers. Collective on MPI_Comm Input Parameters: + comm - the MPI communicator . n - the length of the index set . idx - the list of integers - mode - see PetscCopyMode for meaning of this flag. Output Parameter: . is - the new index set Notes: When the communicator is not MPI_COMM_SELF, the operations on IS are NOT conceptually the same as MPI_Group operations. The IS are then distributed sets of indices and thus certain operations on them are collective. Level: beginner Concepts: index sets^creating Concepts: IS^creating .seealso: ISCreateStride(), ISCreateBlock(), ISAllGather() @*/ PetscErrorCode ISCreateGeneral(MPI_Comm comm,PetscInt n,const PetscInt idx[],PetscCopyMode mode,IS *is) { PetscErrorCode ierr; PetscFunctionBegin; ierr = ISCreate(comm,is);CHKERRQ(ierr); ierr = ISSetType(*is,ISGENERAL);CHKERRQ(ierr); ierr = ISGeneralSetIndices(*is,n,idx,mode);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ ISCreateStride - Creates a data structure for an index set containing a list of evenly spaced integers. Collective on MPI_Comm Input Parameters: + comm - the MPI communicator . n - the length of the locally owned portion of the index set . first - the first element of the locally owned portion of the index set - step - the change to the next index Output Parameter: . is - the new index set Notes: When the communicator is not MPI_COMM_SELF, the operations on IS are NOT conceptually the same as MPI_Group operations. The IS are the distributed sets of indices and thus certain operations on them are collective. Level: beginner Concepts: IS^stride Concepts: index sets^stride Concepts: stride^index set .seealso: ISCreateGeneral(), ISCreateBlock(), ISAllGather() @*/ PetscErrorCode ISCreateStride(MPI_Comm comm,PetscInt n,PetscInt first,PetscInt step,IS *is) { PetscErrorCode ierr; PetscFunctionBegin; ierr = ISCreate(comm,is);CHKERRQ(ierr); ierr = ISSetType(*is,ISSTRIDE);CHKERRQ(ierr); ierr = ISStrideSetStride(*is,n,first,step);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode ISToGeneral_Stride(IS inis) { PetscErrorCode ierr; const PetscInt *idx; PetscInt n; PetscFunctionBegin; ierr = ISGetLocalSize(inis,&n);CHKERRQ(ierr); ierr = ISGetIndices(inis,&idx);CHKERRQ(ierr); ierr = ISSetType(inis,ISGENERAL);CHKERRQ(ierr); ierr = ISGeneralSetIndices(inis,n,idx,PETSC_OWN_POINTER);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ ISCreateBlock - Creates a data structure for an index set containing a list of integers. The indices are relative to entries, not blocks. Collective on MPI_Comm Input Parameters: + comm - the MPI communicator . bs - number of elements in each block . n - the length of the index set (the number of blocks) . idx - the list of integers, one for each block and count of block not indices - mode - see PetscCopyMode, only PETSC_COPY_VALUES and PETSC_OWN_POINTER are supported in this routine Output Parameter: . is - the new index set Notes: When the communicator is not MPI_COMM_SELF, the operations on the index sets, IS, are NOT conceptually the same as MPI_Group operations. The index sets are then distributed sets of indices and thus certain operations on them are collective. Example: If you wish to index the values {0,1,6,7}, then use a block size of 2 and idx of {0,3}. Level: beginner Concepts: IS^block Concepts: index sets^block Concepts: block^index set .seealso: ISCreateStride(), ISCreateGeneral(), ISAllGather() @*/ PetscErrorCode ISCreateBlock(MPI_Comm comm,PetscInt bs,PetscInt n,const PetscInt idx[],PetscCopyMode mode,IS *is) { PetscErrorCode ierr; PetscFunctionBegin; PetscValidPointer(is,5); if (n < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"length < 0"); if (n) PetscValidIntPointer(idx,4); ierr = ISCreate(comm,is);CHKERRQ(ierr); ierr = ISSetType(*is,ISBLOCK);CHKERRQ(ierr); ierr = ISBlockSetIndices(*is,bs,n,idx,mode);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ ISLoad - Loads a vector that has been stored in binary or HDF5 format with ISView(). Collective on PetscViewer Input Parameters: + is - the newly loaded vector, this needs to have been created with ISCreate() or some related function before a call to ISLoad(). - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() or HDF5 file viewer, obtained from PetscViewerHDF5Open() Level: intermediate Notes: IF using HDF5, you must assign the IS the same name as was used in the IS that was stored in the file using PetscObjectSetName(). Otherwise you will get the error message: "Cannot H5DOpen2() with Vec name NAMEOFOBJECT" Concepts: index set^loading from file .seealso: PetscViewerBinaryOpen(), ISView(), MatLoad(), VecLoad() @*/ PetscErrorCode ISLoad(IS is, PetscViewer viewer) { PetscBool isbinary, ishdf5; PetscErrorCode ierr; PetscFunctionBegin; PetscValidHeaderSpecific(is, IS_CLASSID, 1); PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERBINARY, &isbinary); CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5); CHKERRQ(ierr); if (!isbinary && !ishdf5) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()"); if (!((PetscObject)is)->type_name) { ierr = ISSetType(is, ISGENERAL); CHKERRQ(ierr); } ierr = (*is->ops->load)(is, viewer); CHKERRQ(ierr); PetscFunctionReturn(0); }
-m # : the size of the vectors\n \ -n # : the numer of indices (with n<=m)\n \ -toFirst # : the starting index of the output vector for strided scatters\n \ -toStep # : the step size into the output vector for strided scatters\n \ -fromFirst # : the starting index of the input vector for strided scatters\n\ -fromStep # : the step size into the input vector for strided scatters\n\n"; int main(int argc, char * argv[]) { Vec X,Y; PetscInt m,n,i,n1,n2; PetscInt toFirst,toStep,fromFirst,fromStep; PetscInt *idx,*idy; PetscBool flg; IS toISStrided,fromISStrided,toISGeneral,fromISGeneral; VecScatter vscatSStoSS,vscatSStoSG,vscatSGtoSS,vscatSGtoSG; ScatterMode mode; InsertMode addv; PetscErrorCode ierr; ierr = PetscInitialize(&argc,&argv,0,help);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-m",&m,&flg);CHKERRQ(ierr); if (!flg) m = 100; ierr = PetscOptionsGetInt(NULL,"-n",&n,&flg);CHKERRQ(ierr); if (!flg) n = 30; ierr = PetscOptionsGetInt(NULL,"-toFirst",&toFirst,&flg);CHKERRQ(ierr); if (!flg) toFirst = 3; ierr = PetscOptionsGetInt(NULL,"-toStep",&toStep,&flg);CHKERRQ(ierr); if (!flg) toStep = 3; ierr = PetscOptionsGetInt(NULL,"-fromFirst",&fromFirst,&flg);CHKERRQ(ierr); if (!flg) fromFirst = 2; ierr = PetscOptionsGetInt(NULL,"-fromStep",&fromStep,&flg);CHKERRQ(ierr); if (!flg) fromStep = 2; if (n>m) { PetscPrintf(PETSC_COMM_WORLD,"The vector sizes are %d. The number of elements being scattered is %d\n",m,n);CHKERRQ(ierr); PetscPrintf(PETSC_COMM_WORLD,"Adjust the parameters such that m>=n\n");CHKERRQ(ierr); } else if (toFirst+(n-1)*toStep >=m) { PetscPrintf(PETSC_COMM_WORLD,"The vector sizes are %d. The number of elements being scattered is %d\n",m,n);CHKERRQ(ierr); PetscPrintf(PETSC_COMM_WORLD,"For the Strided Scatter, toFirst=%d and toStep=%d.\n",toFirst,toStep);CHKERRQ(ierr); PetscPrintf(PETSC_COMM_WORLD,"This produces an index (toFirst+(n-1)*toStep)>=m\n");CHKERRQ(ierr); PetscPrintf(PETSC_COMM_WORLD,"Adjust the parameterrs accordingly with -m, -n, -toFirst, or -toStep\n");CHKERRQ(ierr); } else if (fromFirst+(n-1)*fromStep>=m) { PetscPrintf(PETSC_COMM_WORLD,"The vector sizes are %d. The number of elements being scattered is %d\n",m,n);CHKERRQ(ierr); PetscPrintf(PETSC_COMM_WORLD,"For the Strided Scatter, fromFirst=%d and fromStep=%d.\n",fromFirst,toStep);CHKERRQ(ierr); PetscPrintf(PETSC_COMM_WORLD,"This produces an index (fromFirst+(n-1)*fromStep)>=m\n");CHKERRQ(ierr); PetscPrintf(PETSC_COMM_WORLD,"Adjust the parameterrs accordingly with -m, -n, -fromFirst, or -fromStep\n");CHKERRQ(ierr); } else { PetscPrintf(PETSC_COMM_WORLD,"m=%d\tn=%d\tfromFirst=%d\tfromStep=%d\ttoFirst=%d\ttoStep=%d\n",m,n,fromFirst,fromStep,toFirst,toStep);CHKERRQ(ierr); PetscPrintf(PETSC_COMM_WORLD,"fromFirst+(n-1)*fromStep=%d\ttoFirst+(n-1)*toStep=%d\n",fromFirst+(n-1)*fromStep,toFirst+(n-1)*toStep);CHKERRQ(ierr); /* Build the vectors */ ierr = VecCreate(PETSC_COMM_WORLD,&Y);CHKERRQ(ierr); ierr = VecSetSizes(Y,m,PETSC_DECIDE);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_WORLD,&X);CHKERRQ(ierr); ierr = VecSetSizes(X,m,PETSC_DECIDE);CHKERRQ(ierr); ierr = VecSetFromOptions(Y);CHKERRQ(ierr); ierr = VecSetFromOptions(X);CHKERRQ(ierr); ierr = VecSet(X,2.0);CHKERRQ(ierr); ierr = VecSet(Y,1.0);CHKERRQ(ierr); /* Build the strided index sets */ ierr = ISCreate(PETSC_COMM_WORLD,&toISStrided);CHKERRQ(ierr); ierr = ISCreate(PETSC_COMM_WORLD,&fromISStrided);CHKERRQ(ierr); ierr = ISSetType(toISStrided, ISSTRIDE);CHKERRQ(ierr); ierr = ISSetType(fromISStrided, ISSTRIDE);CHKERRQ(ierr); ierr = ISStrideSetStride(fromISStrided,n,fromFirst,fromStep);CHKERRQ(ierr); ierr = ISStrideSetStride(toISStrided,n,toFirst,toStep);CHKERRQ(ierr); /* Build the general index sets */ ierr = PetscMalloc1(n,&idx);CHKERRQ(ierr); ierr = PetscMalloc1(n,&idy);CHKERRQ(ierr); for (i=0; i<n; i++) { idx[i] = i % m; idy[i] = (i+m) % m; } n1 = n; n2 = n; ierr = PetscSortRemoveDupsInt(&n1,idx);CHKERRQ(ierr); ierr = PetscSortRemoveDupsInt(&n2,idy);CHKERRQ(ierr); ierr = ISCreateGeneral(PETSC_COMM_WORLD,n1,idx,PETSC_COPY_VALUES,&toISGeneral);CHKERRQ(ierr); ierr = ISCreateGeneral(PETSC_COMM_WORLD,n2,idy,PETSC_COPY_VALUES,&fromISGeneral);CHKERRQ(ierr); /* set the mode and the insert/add parameter */ mode = SCATTER_FORWARD; addv = ADD_VALUES; /* VecScatter : Seq Strided to Seq Strided */ ierr = VecScatterCreate(X,fromISStrided,Y,toISStrided,&vscatSStoSS);CHKERRQ(ierr); ierr = VecScatterBegin(vscatSStoSS,X,Y,addv,mode);CHKERRQ(ierr); ierr = VecScatterEnd(vscatSStoSS,X,Y,addv,mode);CHKERRQ(ierr); ierr = VecScatterDestroy(&vscatSStoSS);CHKERRQ(ierr); /* VecScatter : Seq General to Seq Strided */ ierr = VecScatterCreate(Y,fromISGeneral,X,toISStrided,&vscatSGtoSS);CHKERRQ(ierr); ierr = VecScatterBegin(vscatSGtoSS,Y,X,addv,mode);CHKERRQ(ierr); ierr = VecScatterEnd(vscatSGtoSS,Y,X,addv,mode);CHKERRQ(ierr); ierr = VecScatterDestroy(&vscatSGtoSS);CHKERRQ(ierr); /* VecScatter : Seq General to Seq General */ ierr = VecScatterCreate(X,fromISGeneral,Y,toISGeneral,&vscatSGtoSG);CHKERRQ(ierr); ierr = VecScatterBegin(vscatSGtoSG,X,Y,addv,mode);CHKERRQ(ierr); ierr = VecScatterEnd(vscatSGtoSG,X,Y,addv,mode);CHKERRQ(ierr); ierr = VecScatterDestroy(&vscatSGtoSG);CHKERRQ(ierr); /* VecScatter : Seq Strided to Seq General */ ierr = VecScatterCreate(Y,fromISStrided,X,toISGeneral,&vscatSStoSG);CHKERRQ(ierr); ierr = VecScatterBegin(vscatSStoSG,Y,X,addv,mode);CHKERRQ(ierr); ierr = VecScatterEnd(vscatSStoSG,Y,X,addv,mode);CHKERRQ(ierr); ierr = VecScatterDestroy(&vscatSStoSG);CHKERRQ(ierr); /* view the results */ ierr = VecView(Y,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* Cleanup */ ierr = VecDestroy(&X);CHKERRQ(ierr); ierr = VecDestroy(&Y);CHKERRQ(ierr); ierr = ISDestroy(&toISStrided);CHKERRQ(ierr); ierr = ISDestroy(&fromISStrided);CHKERRQ(ierr); ierr = ISDestroy(&toISGeneral);CHKERRQ(ierr); ierr = ISDestroy(&fromISGeneral);CHKERRQ(ierr); ierr = PetscFree(idx);CHKERRQ(ierr); ierr = PetscFree(idy);CHKERRQ(ierr); } PetscFinalize(); return 0; }