12362add9SBarry Smith 2e090d566SSatish Balay #include "petscsys.h" /*I "petscsys.h" I*/ 3e090d566SSatish Balay #include "src/vec/is/isimpl.h" /*I "petscis.h" I*/ 42362add9SBarry Smith 5dfbe8321SBarry Smith EXTERN PetscErrorCode VecInitializePackage(char *); 66849ba73SBarry Smith PetscCookie IS_LTOGM_COOKIE = -1; 78e58c17dSMatthew Knepley 84a2ae208SSatish Balay #undef __FUNCT__ 94a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingGetSize" 103b9aefa3SBarry Smith /*@C 113b9aefa3SBarry Smith ISLocalToGlobalMappingGetSize - Gets the local size of a local to global mapping. 123b9aefa3SBarry Smith 133b9aefa3SBarry Smith Not Collective 143b9aefa3SBarry Smith 153b9aefa3SBarry Smith Input Parameter: 163b9aefa3SBarry Smith . ltog - local to global mapping 173b9aefa3SBarry Smith 183b9aefa3SBarry Smith Output Parameter: 193b9aefa3SBarry Smith . n - the number of entries in the local mapping 203b9aefa3SBarry Smith 213b9aefa3SBarry Smith Level: advanced 223b9aefa3SBarry Smith 23273d9f13SBarry Smith Concepts: mapping^local to global 243b9aefa3SBarry Smith 253b9aefa3SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 263b9aefa3SBarry Smith @*/ 2732dcc486SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetSize(ISLocalToGlobalMapping mapping,PetscInt *n) 283b9aefa3SBarry Smith { 293b9aefa3SBarry Smith PetscFunctionBegin; 304482741eSBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE,1); 314482741eSBarry Smith PetscValidIntPointer(n,2); 323b9aefa3SBarry Smith *n = mapping->n; 333b9aefa3SBarry Smith PetscFunctionReturn(0); 343b9aefa3SBarry Smith } 353b9aefa3SBarry Smith 364a2ae208SSatish Balay #undef __FUNCT__ 374a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingView" 385a5d4f66SBarry Smith /*@C 395a5d4f66SBarry Smith ISLocalToGlobalMappingView - View a local to global mapping 405a5d4f66SBarry Smith 41b9cd556bSLois Curfman McInnes Not Collective 42b9cd556bSLois Curfman McInnes 435a5d4f66SBarry Smith Input Parameters: 443b9aefa3SBarry Smith + ltog - local to global mapping 453b9aefa3SBarry Smith - viewer - viewer 465a5d4f66SBarry Smith 47a997ad1aSLois Curfman McInnes Level: advanced 48a997ad1aSLois Curfman McInnes 49273d9f13SBarry Smith Concepts: mapping^local to global 505a5d4f66SBarry Smith 515a5d4f66SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 525a5d4f66SBarry Smith @*/ 53dfbe8321SBarry Smith PetscErrorCode ISLocalToGlobalMappingView(ISLocalToGlobalMapping mapping,PetscViewer viewer) 545a5d4f66SBarry Smith { 5532dcc486SBarry Smith PetscInt i; 5632dcc486SBarry Smith PetscMPIInt rank; 5732077d6dSBarry Smith PetscTruth iascii; 586849ba73SBarry Smith PetscErrorCode ierr; 595a5d4f66SBarry Smith 605a5d4f66SBarry Smith PetscFunctionBegin; 614482741eSBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE,1); 62b0a32e0cSBarry Smith if (!viewer) viewer = PETSC_VIEWER_STDOUT_(mapping->comm); 634482741eSBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE,2); 645a5d4f66SBarry Smith 65f1af5d2fSBarry Smith ierr = MPI_Comm_rank(mapping->comm,&rank);CHKERRQ(ierr); 6632077d6dSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 6732077d6dSBarry Smith if (iascii) { 685a5d4f66SBarry Smith for (i=0; i<mapping->n; i++) { 69b0a32e0cSBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d] %d %d\n",rank,i,mapping->indices[i]);CHKERRQ(ierr); 706831982aSBarry Smith } 71b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 726831982aSBarry Smith } else { 73958c9bccSBarry Smith SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported for ISLocalToGlobalMapping",((PetscObject)viewer)->type_name); 745a5d4f66SBarry Smith } 755a5d4f66SBarry Smith 765a5d4f66SBarry Smith PetscFunctionReturn(0); 775a5d4f66SBarry Smith } 785a5d4f66SBarry Smith 794a2ae208SSatish Balay #undef __FUNCT__ 804a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreateIS" 812bdab257SBarry Smith /*@C 822bdab257SBarry Smith ISLocalToGlobalMappingCreateIS - Creates a mapping between a local (0 to n) 832bdab257SBarry Smith ordering and a global parallel ordering. 842bdab257SBarry Smith 850f5bd95cSBarry Smith Not collective 86b9cd556bSLois Curfman McInnes 87a997ad1aSLois Curfman McInnes Input Parameter: 882bdab257SBarry Smith . is - index set containing the global numbers for each local 892bdab257SBarry Smith 90a997ad1aSLois Curfman McInnes Output Parameter: 912bdab257SBarry Smith . mapping - new mapping data structure 922bdab257SBarry Smith 93a997ad1aSLois Curfman McInnes Level: advanced 94a997ad1aSLois Curfman McInnes 95273d9f13SBarry Smith Concepts: mapping^local to global 962bdab257SBarry Smith 972bdab257SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 982bdab257SBarry Smith @*/ 99dfbe8321SBarry Smith PetscErrorCode ISLocalToGlobalMappingCreateIS(IS is,ISLocalToGlobalMapping *mapping) 1002bdab257SBarry Smith { 1016849ba73SBarry Smith PetscErrorCode ierr; 10232dcc486SBarry Smith PetscInt n,*indices; 1032bdab257SBarry Smith MPI_Comm comm; 1043a40ed3dSBarry Smith 1053a40ed3dSBarry Smith PetscFunctionBegin; 1064482741eSBarry Smith PetscValidHeaderSpecific(is,IS_COOKIE,1); 1074482741eSBarry Smith PetscValidPointer(mapping,2); 1082bdab257SBarry Smith 1092bdab257SBarry Smith ierr = PetscObjectGetComm((PetscObject)is,&comm);CHKERRQ(ierr); 1103b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 1112bdab257SBarry Smith ierr = ISGetIndices(is,&indices);CHKERRQ(ierr); 1122bdab257SBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,n,indices,mapping);CHKERRQ(ierr); 1132bdab257SBarry Smith ierr = ISRestoreIndices(is,&indices);CHKERRQ(ierr); 1142bdab257SBarry Smith 1153a40ed3dSBarry Smith PetscFunctionReturn(0); 1162bdab257SBarry Smith } 1175a5d4f66SBarry Smith 118b46b645bSBarry Smith 1194a2ae208SSatish Balay #undef __FUNCT__ 1204a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreate" 121dd7157adSSatish Balay /*@C 12290f02eecSBarry Smith ISLocalToGlobalMappingCreate - Creates a mapping between a local (0 to n) 12390f02eecSBarry Smith ordering and a global parallel ordering. 1242362add9SBarry Smith 12589d82c54SBarry Smith Not Collective, but communicator may have more than one process 126b9cd556bSLois Curfman McInnes 1272362add9SBarry Smith Input Parameters: 12889d82c54SBarry Smith + comm - MPI communicator 12990f02eecSBarry Smith . n - the number of local elements 130b9cd556bSLois Curfman McInnes - indices - the global index for each local element 1312362add9SBarry Smith 132a997ad1aSLois Curfman McInnes Output Parameter: 13390f02eecSBarry Smith . mapping - new mapping data structure 1342362add9SBarry Smith 135a997ad1aSLois Curfman McInnes Level: advanced 136a997ad1aSLois Curfman McInnes 137273d9f13SBarry Smith Concepts: mapping^local to global 1382362add9SBarry Smith 139b46b645bSBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreateNC() 1402362add9SBarry Smith @*/ 14132dcc486SBarry Smith PetscErrorCode ISLocalToGlobalMappingCreate(MPI_Comm cm,PetscInt n,const PetscInt indices[],ISLocalToGlobalMapping *mapping) 1422362add9SBarry Smith { 1436849ba73SBarry Smith PetscErrorCode ierr; 14432dcc486SBarry Smith PetscInt *in; 145b46b645bSBarry Smith 146b46b645bSBarry Smith PetscFunctionBegin; 1474482741eSBarry Smith PetscValidIntPointer(indices,3); 1484482741eSBarry Smith PetscValidPointer(mapping,4); 1497c334f02SBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&in);CHKERRQ(ierr); 15032dcc486SBarry Smith ierr = PetscMemcpy(in,indices,n*sizeof(PetscInt));CHKERRQ(ierr); 151b46b645bSBarry Smith ierr = ISLocalToGlobalMappingCreateNC(cm,n,in,mapping);CHKERRQ(ierr); 152b46b645bSBarry Smith PetscFunctionReturn(0); 153b46b645bSBarry Smith } 154b46b645bSBarry Smith 155b46b645bSBarry Smith #undef __FUNCT__ 156b46b645bSBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingCreateNC" 157b46b645bSBarry Smith /*@C 158b46b645bSBarry Smith ISLocalToGlobalMappingCreateNC - Creates a mapping between a local (0 to n) 159b46b645bSBarry Smith ordering and a global parallel ordering. 160b46b645bSBarry Smith 161b46b645bSBarry Smith Not Collective, but communicator may have more than one process 162b46b645bSBarry Smith 163b46b645bSBarry Smith Input Parameters: 164b46b645bSBarry Smith + comm - MPI communicator 165b46b645bSBarry Smith . n - the number of local elements 166b46b645bSBarry Smith - indices - the global index for each local element 167b46b645bSBarry Smith 168b46b645bSBarry Smith Output Parameter: 169b46b645bSBarry Smith . mapping - new mapping data structure 170b46b645bSBarry Smith 171b46b645bSBarry Smith Level: developer 172b46b645bSBarry Smith 173b46b645bSBarry Smith Notes: Does not copy the indices, just keeps the pointer to the indices. The ISLocalToGlobalMappingDestroy() 174b46b645bSBarry Smith will free the space so it must be obtained with PetscMalloc() and it must not be freed elsewhere. 175b46b645bSBarry Smith 176b46b645bSBarry Smith Concepts: mapping^local to global 177b46b645bSBarry Smith 178b46b645bSBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate() 179b46b645bSBarry Smith @*/ 18032dcc486SBarry Smith PetscErrorCode ISLocalToGlobalMappingCreateNC(MPI_Comm cm,PetscInt n,const PetscInt indices[],ISLocalToGlobalMapping *mapping) 181b46b645bSBarry Smith { 182dfbe8321SBarry Smith PetscErrorCode ierr; 18323f7533aSBarry Smith 1843a40ed3dSBarry Smith PetscFunctionBegin; 1854482741eSBarry Smith PetscValidIntPointer(indices,3); 1864482741eSBarry Smith PetscValidPointer(mapping,4); 1878e58c17dSMatthew Knepley *mapping = PETSC_NULL; 1888e58c17dSMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 18923f7533aSBarry Smith ierr = VecInitializePackage(PETSC_NULL);CHKERRQ(ierr); 1908e58c17dSMatthew Knepley #endif 19123f7533aSBarry Smith if (IS_LTOGM_COOKIE == -1) { 19223f7533aSBarry Smith ierr = PetscLogClassRegister(&IS_LTOGM_COOKIE,"IS Local to global mapping");CHKERRQ(ierr); 19323f7533aSBarry Smith } 1942362add9SBarry Smith 195*52e6d16bSBarry Smith ierr = PetscHeaderCreate(*mapping,_p_ISLocalToGlobalMapping,int,IS_LTOGM_COOKIE,0,"ISLocalToGlobalMapping", 196*52e6d16bSBarry Smith cm,ISLocalToGlobalMappingDestroy,ISLocalToGlobalMappingView);CHKERRQ(ierr); 197*52e6d16bSBarry Smith ierr = PetscLogObjectMemory(*mapping,sizeof(struct _p_ISLocalToGlobalMapping)+n*sizeof(PetscInt));CHKERRQ(ierr); 198d4bb536fSBarry Smith 199d4bb536fSBarry Smith (*mapping)->n = n; 20032dcc486SBarry Smith (*mapping)->indices = (PetscInt*)indices; 201d4bb536fSBarry Smith 202d4bb536fSBarry Smith /* 203d4bb536fSBarry Smith Do not create the global to local mapping. This is only created if 204d4bb536fSBarry Smith ISGlobalToLocalMapping() is called 205d4bb536fSBarry Smith */ 206d4bb536fSBarry Smith (*mapping)->globals = 0; 2073a40ed3dSBarry Smith PetscFunctionReturn(0); 2082362add9SBarry Smith } 2092362add9SBarry Smith 2104a2ae208SSatish Balay #undef __FUNCT__ 2114a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingBlock" 212323b833fSBarry Smith /*@C 213323b833fSBarry Smith ISLocalToGlobalMappingBlock - Creates a blocked index version of an 214323b833fSBarry Smith ISLocalToGlobalMapping that is appropriate for MatSetLocalToGlobalMappingBlock() 215323b833fSBarry Smith and VecSetLocalToGlobalMappingBlock(). 216323b833fSBarry Smith 217323b833fSBarry Smith Not Collective, but communicator may have more than one process 218323b833fSBarry Smith 219323b833fSBarry Smith Input Parameters: 220323b833fSBarry Smith + inmap - original point-wise mapping 221323b833fSBarry Smith - bs - block size 222323b833fSBarry Smith 223323b833fSBarry Smith Output Parameter: 22469eb54c3SBarry Smith . outmap - block based mapping; the indices are relative to BLOCKS, not individual vector or matrix entries. 225323b833fSBarry Smith 226323b833fSBarry Smith Level: advanced 227323b833fSBarry Smith 228323b833fSBarry Smith Concepts: mapping^local to global 229323b833fSBarry Smith 230323b833fSBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingCreateIS() 231323b833fSBarry Smith @*/ 23232dcc486SBarry Smith PetscErrorCode ISLocalToGlobalMappingBlock(ISLocalToGlobalMapping inmap,PetscInt bs,ISLocalToGlobalMapping *outmap) 233323b833fSBarry Smith { 2346849ba73SBarry Smith PetscErrorCode ierr; 23532dcc486SBarry Smith PetscInt *ii,i,n; 236323b833fSBarry Smith 237323b833fSBarry Smith PetscFunctionBegin; 238323b833fSBarry Smith if (bs > 1) { 239323b833fSBarry Smith n = inmap->n/bs; 24012ce3465SBarry Smith if (n*bs != inmap->n) SETERRQ(PETSC_ERR_ARG_INCOMP,"Pointwise mapping length is not divisible by block size"); 24132dcc486SBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&ii);CHKERRQ(ierr); 242323b833fSBarry Smith for (i=0; i<n; i++) { 243db032c9dSBarry Smith ii[i] = inmap->indices[bs*i]/bs; 244323b833fSBarry Smith } 245323b833fSBarry Smith ierr = ISLocalToGlobalMappingCreate(inmap->comm,n,ii,outmap);CHKERRQ(ierr); 246323b833fSBarry Smith ierr = PetscFree(ii);CHKERRQ(ierr); 247323b833fSBarry Smith } else { 248323b833fSBarry Smith *outmap = inmap; 249323b833fSBarry Smith ierr = PetscObjectReference((PetscObject)inmap);CHKERRQ(ierr); 250323b833fSBarry Smith } 251323b833fSBarry Smith PetscFunctionReturn(0); 252323b833fSBarry Smith } 253323b833fSBarry Smith 2544a2ae208SSatish Balay #undef __FUNCT__ 2554a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingDestroy" 25690f02eecSBarry Smith /*@ 25790f02eecSBarry Smith ISLocalToGlobalMappingDestroy - Destroys a mapping between a local (0 to n) 25890f02eecSBarry Smith ordering and a global parallel ordering. 25990f02eecSBarry Smith 2600f5bd95cSBarry Smith Note Collective 261b9cd556bSLois Curfman McInnes 26290f02eecSBarry Smith Input Parameters: 26390f02eecSBarry Smith . mapping - mapping data structure 26490f02eecSBarry Smith 265a997ad1aSLois Curfman McInnes Level: advanced 266a997ad1aSLois Curfman McInnes 2673acfe500SLois Curfman McInnes .seealso: ISLocalToGlobalMappingCreate() 26890f02eecSBarry Smith @*/ 269dfbe8321SBarry Smith PetscErrorCode ISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping mapping) 27090f02eecSBarry Smith { 271dfbe8321SBarry Smith PetscErrorCode ierr; 2723a40ed3dSBarry Smith PetscFunctionBegin; 2734482741eSBarry Smith PetscValidPointer(mapping,1); 2743a40ed3dSBarry Smith if (--mapping->refct > 0) PetscFunctionReturn(0); 27585614651SBarry Smith if (mapping->refct < 0) { 276634064b4SBarry Smith SETERRQ(PETSC_ERR_PLIB,"Mapping already destroyed"); 27785614651SBarry Smith } 27890f02eecSBarry Smith 279606d414cSSatish Balay ierr = PetscFree(mapping->indices);CHKERRQ(ierr); 280606d414cSSatish Balay if (mapping->globals) {ierr = PetscFree(mapping->globals);CHKERRQ(ierr);} 281d38fa0fbSBarry Smith ierr = PetscHeaderDestroy(mapping);CHKERRQ(ierr); 2823a40ed3dSBarry Smith PetscFunctionReturn(0); 28390f02eecSBarry Smith } 28490f02eecSBarry Smith 2854a2ae208SSatish Balay #undef __FUNCT__ 2864a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingApplyIS" 28790f02eecSBarry Smith /*@ 2883acfe500SLois Curfman McInnes ISLocalToGlobalMappingApplyIS - Creates from an IS in the local numbering 2893acfe500SLois Curfman McInnes a new index set using the global numbering defined in an ISLocalToGlobalMapping 2903acfe500SLois Curfman McInnes context. 29190f02eecSBarry Smith 292b9cd556bSLois Curfman McInnes Not collective 293b9cd556bSLois Curfman McInnes 29490f02eecSBarry Smith Input Parameters: 295b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 296b9cd556bSLois Curfman McInnes - is - index set in local numbering 29790f02eecSBarry Smith 29890f02eecSBarry Smith Output Parameters: 29990f02eecSBarry Smith . newis - index set in global numbering 30090f02eecSBarry Smith 301a997ad1aSLois Curfman McInnes Level: advanced 302a997ad1aSLois Curfman McInnes 303273d9f13SBarry Smith Concepts: mapping^local to global 3043acfe500SLois Curfman McInnes 30590f02eecSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 306d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy(), ISGlobalToLocalMappingApply() 30790f02eecSBarry Smith @*/ 308dfbe8321SBarry Smith PetscErrorCode ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping mapping,IS is,IS *newis) 30990f02eecSBarry Smith { 3106849ba73SBarry Smith PetscErrorCode ierr; 31132dcc486SBarry Smith PetscInt n,i,*idxin,*idxmap,*idxout,Nmax = mapping->n; 3123a40ed3dSBarry Smith 3133a40ed3dSBarry Smith PetscFunctionBegin; 3144482741eSBarry Smith PetscValidPointer(mapping,1); 3154482741eSBarry Smith PetscValidHeaderSpecific(is,IS_COOKIE,2); 3164482741eSBarry Smith PetscValidPointer(newis,3); 31790f02eecSBarry Smith 3183b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 31990f02eecSBarry Smith ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 32090f02eecSBarry Smith idxmap = mapping->indices; 32190f02eecSBarry Smith 3227c334f02SBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&idxout);CHKERRQ(ierr); 32390f02eecSBarry Smith for (i=0; i<n; i++) { 324590ac198SBarry Smith if (idxin[i] >= Nmax) SETERRQ3(PETSC_ERR_ARG_OUTOFRANGE,"Local index %d too large %d (max) at %d",idxin[i],Nmax-1,i); 32590f02eecSBarry Smith idxout[i] = idxmap[idxin[i]]; 32690f02eecSBarry Smith } 3273b9aefa3SBarry Smith ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 328029af93fSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxout,newis);CHKERRQ(ierr); 329606d414cSSatish Balay ierr = PetscFree(idxout);CHKERRQ(ierr); 3303a40ed3dSBarry Smith PetscFunctionReturn(0); 33190f02eecSBarry Smith } 33290f02eecSBarry Smith 33389d82c54SBarry Smith /*MC 3343acfe500SLois Curfman McInnes ISLocalToGlobalMappingApply - Takes a list of integers in a local numbering 3353acfe500SLois Curfman McInnes and converts them to the global numbering. 33690f02eecSBarry Smith 337b9cd556bSLois Curfman McInnes Not collective 338b9cd556bSLois Curfman McInnes 339bb25748dSBarry Smith Input Parameters: 340b9cd556bSLois Curfman McInnes + mapping - the local to global mapping context 341bb25748dSBarry Smith . N - number of integers 342b9cd556bSLois Curfman McInnes - in - input indices in local numbering 343bb25748dSBarry Smith 344bb25748dSBarry Smith Output Parameter: 345bb25748dSBarry Smith . out - indices in global numbering 346bb25748dSBarry Smith 3473b9aefa3SBarry Smith Synopsis: 348d360dc6fSBarry Smith PetscErrorCode ISLocalToGlobalMappingApply(ISLocalToGlobalMapping mapping,int N,int in[],int out[]) 3493b9aefa3SBarry Smith 350b9cd556bSLois Curfman McInnes Notes: 351b9cd556bSLois Curfman McInnes The in and out array parameters may be identical. 352d4bb536fSBarry Smith 353a997ad1aSLois Curfman McInnes Level: advanced 354a997ad1aSLois Curfman McInnes 355bb25748dSBarry Smith .seealso: ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 3560752156aSBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 357d4bb536fSBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 358bb25748dSBarry Smith 359273d9f13SBarry Smith Concepts: mapping^local to global 360d4bb536fSBarry Smith 36189d82c54SBarry Smith M*/ 362d4bb536fSBarry Smith 363d4bb536fSBarry Smith /* -----------------------------------------------------------------------------------------*/ 364d4bb536fSBarry Smith 3654a2ae208SSatish Balay #undef __FUNCT__ 3664a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingSetUp_Private" 367d4bb536fSBarry Smith /* 368d4bb536fSBarry Smith Creates the global fields in the ISLocalToGlobalMapping structure 369d4bb536fSBarry Smith */ 3706849ba73SBarry Smith static PetscErrorCode ISGlobalToLocalMappingSetUp_Private(ISLocalToGlobalMapping mapping) 371d4bb536fSBarry Smith { 3726849ba73SBarry Smith PetscErrorCode ierr; 37332dcc486SBarry Smith PetscInt i,*idx = mapping->indices,n = mapping->n,end,start,*globals; 374d4bb536fSBarry Smith 3753a40ed3dSBarry Smith PetscFunctionBegin; 376d4bb536fSBarry Smith end = 0; 377d4bb536fSBarry Smith start = 100000000; 378d4bb536fSBarry Smith 379d4bb536fSBarry Smith for (i=0; i<n; i++) { 380d4bb536fSBarry Smith if (idx[i] < 0) continue; 381d4bb536fSBarry Smith if (idx[i] < start) start = idx[i]; 382d4bb536fSBarry Smith if (idx[i] > end) end = idx[i]; 383d4bb536fSBarry Smith } 384d4bb536fSBarry Smith if (start > end) {start = 0; end = -1;} 385d4bb536fSBarry Smith mapping->globalstart = start; 386d4bb536fSBarry Smith mapping->globalend = end; 387d4bb536fSBarry Smith 38832dcc486SBarry Smith ierr = PetscMalloc((end-start+2)*sizeof(PetscInt),&globals);CHKERRQ(ierr); 389b0a32e0cSBarry Smith mapping->globals = globals; 390d4bb536fSBarry Smith for (i=0; i<end-start+1; i++) { 391d4bb536fSBarry Smith globals[i] = -1; 392d4bb536fSBarry Smith } 393d4bb536fSBarry Smith for (i=0; i<n; i++) { 394d4bb536fSBarry Smith if (idx[i] < 0) continue; 395d4bb536fSBarry Smith globals[idx[i] - start] = i; 396d4bb536fSBarry Smith } 397d4bb536fSBarry Smith 398*52e6d16bSBarry Smith ierr = PetscLogObjectMemory(mapping,(end-start+1)*sizeof(PetscInt));CHKERRQ(ierr); 3993a40ed3dSBarry Smith PetscFunctionReturn(0); 400d4bb536fSBarry Smith } 401d4bb536fSBarry Smith 4024a2ae208SSatish Balay #undef __FUNCT__ 4034a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingApply" 404d4bb536fSBarry Smith /*@ 405a997ad1aSLois Curfman McInnes ISGlobalToLocalMappingApply - Provides the local numbering for a list of integers 406a997ad1aSLois Curfman McInnes specified with a global numbering. 407d4bb536fSBarry Smith 408b9cd556bSLois Curfman McInnes Not collective 409b9cd556bSLois Curfman McInnes 410d4bb536fSBarry Smith Input Parameters: 411b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 412d4bb536fSBarry Smith . type - IS_GTOLM_MASK - replaces global indices with no local value with -1 413d4bb536fSBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 414d4bb536fSBarry Smith . n - number of global indices to map 415b9cd556bSLois Curfman McInnes - idx - global indices to map 416d4bb536fSBarry Smith 417d4bb536fSBarry Smith Output Parameters: 418b9cd556bSLois Curfman McInnes + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 419b9cd556bSLois Curfman McInnes - idxout - local index of each global index, one must pass in an array long enough 420e182c471SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApply() with 421e182c471SBarry Smith idxout == PETSC_NULL to determine the required length (returned in nout) 422e182c471SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApply() 423e182c471SBarry Smith a second time to set the values. 424d4bb536fSBarry Smith 425b9cd556bSLois Curfman McInnes Notes: 426b9cd556bSLois Curfman McInnes Either nout or idxout may be PETSC_NULL. idx and idxout may be identical. 427d4bb536fSBarry Smith 4280f5bd95cSBarry Smith This is not scalable in memory usage. Each processor requires O(Nglobal) size 4290f5bd95cSBarry Smith array to compute these. 4300f5bd95cSBarry Smith 431a997ad1aSLois Curfman McInnes Level: advanced 432a997ad1aSLois Curfman McInnes 433273d9f13SBarry Smith Concepts: mapping^global to local 434d4bb536fSBarry Smith 435d4bb536fSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 436d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy() 437d4bb536fSBarry Smith @*/ 438dfbe8321SBarry Smith PetscErrorCode ISGlobalToLocalMappingApply(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, 43932dcc486SBarry Smith PetscInt n,const PetscInt idx[],PetscInt *nout,PetscInt idxout[]) 440d4bb536fSBarry Smith { 44132dcc486SBarry Smith PetscInt i,*globals,nf = 0,tmp,start,end; 4426849ba73SBarry Smith PetscErrorCode ierr; 443d4bb536fSBarry Smith 4443a40ed3dSBarry Smith PetscFunctionBegin; 445d4bb536fSBarry Smith if (!mapping->globals) { 446d4bb536fSBarry Smith ierr = ISGlobalToLocalMappingSetUp_Private(mapping);CHKERRQ(ierr); 447d4bb536fSBarry Smith } 448d4bb536fSBarry Smith globals = mapping->globals; 449d4bb536fSBarry Smith start = mapping->globalstart; 450d4bb536fSBarry Smith end = mapping->globalend; 451d4bb536fSBarry Smith 452d4bb536fSBarry Smith if (type == IS_GTOLM_MASK) { 453d4bb536fSBarry Smith if (idxout) { 454d4bb536fSBarry Smith for (i=0; i<n; i++) { 455d4bb536fSBarry Smith if (idx[i] < 0) idxout[i] = idx[i]; 456d4bb536fSBarry Smith else if (idx[i] < start) idxout[i] = -1; 457d4bb536fSBarry Smith else if (idx[i] > end) idxout[i] = -1; 458d4bb536fSBarry Smith else idxout[i] = globals[idx[i] - start]; 459d4bb536fSBarry Smith } 460d4bb536fSBarry Smith } 461d4bb536fSBarry Smith if (nout) *nout = n; 462d4bb536fSBarry Smith } else { 463d4bb536fSBarry Smith if (idxout) { 464d4bb536fSBarry Smith for (i=0; i<n; i++) { 465d4bb536fSBarry Smith if (idx[i] < 0) continue; 466d4bb536fSBarry Smith if (idx[i] < start) continue; 467d4bb536fSBarry Smith if (idx[i] > end) continue; 468d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 469d4bb536fSBarry Smith if (tmp < 0) continue; 470d4bb536fSBarry Smith idxout[nf++] = tmp; 471d4bb536fSBarry Smith } 472d4bb536fSBarry Smith } else { 473d4bb536fSBarry Smith for (i=0; i<n; i++) { 474d4bb536fSBarry Smith if (idx[i] < 0) continue; 475d4bb536fSBarry Smith if (idx[i] < start) continue; 476d4bb536fSBarry Smith if (idx[i] > end) continue; 477d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 478d4bb536fSBarry Smith if (tmp < 0) continue; 479d4bb536fSBarry Smith nf++; 480d4bb536fSBarry Smith } 481d4bb536fSBarry Smith } 482d4bb536fSBarry Smith if (nout) *nout = nf; 483d4bb536fSBarry Smith } 484d4bb536fSBarry Smith 4853a40ed3dSBarry Smith PetscFunctionReturn(0); 486d4bb536fSBarry Smith } 48790f02eecSBarry Smith 4884a2ae208SSatish Balay #undef __FUNCT__ 4894a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingGetInfo" 49089d82c54SBarry Smith /*@C 49189d82c54SBarry Smith ISLocalToGlobalMappingGetInfo - Gets the neighbor information for each processor and 49289d82c54SBarry Smith each index shared by more than one processor 49389d82c54SBarry Smith 49489d82c54SBarry Smith Collective on ISLocalToGlobalMapping 49589d82c54SBarry Smith 49689d82c54SBarry Smith Input Parameters: 49789d82c54SBarry Smith . mapping - the mapping from local to global indexing 49889d82c54SBarry Smith 49989d82c54SBarry Smith Output Parameter: 50089d82c54SBarry Smith + nproc - number of processors that are connected to this one 50189d82c54SBarry Smith . proc - neighboring processors 50207b52d57SBarry Smith . numproc - number of indices for each subdomain (processor) 50307b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 50489d82c54SBarry Smith 50589d82c54SBarry Smith Level: advanced 50689d82c54SBarry Smith 507273d9f13SBarry Smith Concepts: mapping^local to global 50889d82c54SBarry Smith 50907b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 51007b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo() 51189d82c54SBarry Smith @*/ 51232dcc486SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 51389d82c54SBarry Smith { 5146849ba73SBarry Smith PetscErrorCode ierr; 51597f1f81fSBarry Smith PetscMPIInt size,rank,tag1,tag2,tag3,*len,*source,imdex; 51632dcc486SBarry Smith PetscInt i,n = mapping->n,Ng,ng,max = 0,*lindices = mapping->indices; 51732dcc486SBarry Smith PetscInt *nprocs,*owner,nsends,*sends,j,*starts,nmax,nrecvs,*recvs,proc; 51897f1f81fSBarry Smith PetscInt cnt,scale,*ownedsenders,*nownedsenders,rstart,nowned; 51932dcc486SBarry Smith PetscInt node,nownedm,nt,*sends2,nsends2,*starts2,*lens2,*dest,nrecvs2,*starts3,*recvs2,k,*bprocs,*tmp; 52032dcc486SBarry Smith PetscInt first_procs,first_numprocs,*first_indices; 52189d82c54SBarry Smith MPI_Request *recv_waits,*send_waits; 52230dcb7c9SBarry Smith MPI_Status recv_status,*send_status,*recv_statuses; 52389d82c54SBarry Smith MPI_Comm comm = mapping->comm; 52407b52d57SBarry Smith PetscTruth debug = PETSC_FALSE; 52589d82c54SBarry Smith 52689d82c54SBarry Smith PetscFunctionBegin; 52724cf384cSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 52824cf384cSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 52924cf384cSBarry Smith if (size == 1) { 53024cf384cSBarry Smith *nproc = 0; 53124cf384cSBarry Smith *procs = PETSC_NULL; 53232dcc486SBarry Smith ierr = PetscMalloc(sizeof(PetscInt),numprocs);CHKERRQ(ierr); 5331e2105dcSBarry Smith (*numprocs)[0] = 0; 53432dcc486SBarry Smith ierr = PetscMalloc(sizeof(PetscInt*),indices);CHKERRQ(ierr); 5351e2105dcSBarry Smith (*indices)[0] = PETSC_NULL; 53624cf384cSBarry Smith PetscFunctionReturn(0); 53724cf384cSBarry Smith } 53824cf384cSBarry Smith 539b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-islocaltoglobalmappinggetinfo_debug",&debug);CHKERRQ(ierr); 54007b52d57SBarry Smith 5413677ff5aSBarry Smith /* 5423677ff5aSBarry Smith Notes on ISLocalToGlobalMappingGetInfo 5433677ff5aSBarry Smith 5443677ff5aSBarry Smith globally owned node - the nodes that have been assigned to this processor in global 5453677ff5aSBarry Smith numbering, just for this routine. 5463677ff5aSBarry Smith 5473677ff5aSBarry Smith nontrivial globally owned node - node assigned to this processor that is on a subdomain 5483677ff5aSBarry Smith boundary (i.e. is has more than one local owner) 5493677ff5aSBarry Smith 5503677ff5aSBarry Smith locally owned node - node that exists on this processors subdomain 5513677ff5aSBarry Smith 5523677ff5aSBarry Smith nontrivial locally owned node - node that is not in the interior (i.e. has more than one 5533677ff5aSBarry Smith local subdomain 5543677ff5aSBarry Smith */ 55524cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag1);CHKERRQ(ierr); 55624cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag2);CHKERRQ(ierr); 55724cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag3);CHKERRQ(ierr); 55889d82c54SBarry Smith 55989d82c54SBarry Smith for (i=0; i<n; i++) { 56089d82c54SBarry Smith if (lindices[i] > max) max = lindices[i]; 56189d82c54SBarry Smith } 56232dcc486SBarry Smith ierr = MPI_Allreduce(&max,&Ng,1,MPIU_INT,MPI_MAX,comm);CHKERRQ(ierr); 56378058e43SBarry Smith Ng++; 56489d82c54SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 56589d82c54SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 566bc8ff85bSBarry Smith scale = Ng/size + 1; 567a2e34c3dSBarry Smith ng = scale; if (rank == size-1) ng = Ng - scale*(size-1); ng = PetscMax(1,ng); 568caba0dd0SBarry Smith rstart = scale*rank; 56989d82c54SBarry Smith 57089d82c54SBarry Smith /* determine ownership ranges of global indices */ 5717c334f02SBarry Smith ierr = PetscMalloc(2*size*sizeof(PetscInt),&nprocs);CHKERRQ(ierr); 57232dcc486SBarry Smith ierr = PetscMemzero(nprocs,2*size*sizeof(PetscInt));CHKERRQ(ierr); 57389d82c54SBarry Smith 57489d82c54SBarry Smith /* determine owners of each local node */ 5757c334f02SBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&owner);CHKERRQ(ierr); 57689d82c54SBarry Smith for (i=0; i<n; i++) { 5773677ff5aSBarry Smith proc = lindices[i]/scale; /* processor that globally owns this index */ 57827c402fcSBarry Smith nprocs[2*proc+1] = 1; /* processor globally owns at least one of ours */ 5793677ff5aSBarry Smith owner[i] = proc; 58027c402fcSBarry Smith nprocs[2*proc]++; /* count of how many that processor globally owns of ours */ 58189d82c54SBarry Smith } 58227c402fcSBarry Smith nsends = 0; for (i=0; i<size; i++) nsends += nprocs[2*i+1]; 583b0a32e0cSBarry Smith PetscLogInfo(0,"ISLocalToGlobalMappingGetInfo: Number of global owners for my local data %d\n",nsends); 58489d82c54SBarry Smith 58589d82c54SBarry Smith /* inform other processors of number of messages and max length*/ 58627c402fcSBarry Smith ierr = PetscMaxSum(comm,nprocs,&nmax,&nrecvs);CHKERRQ(ierr); 587b0a32e0cSBarry Smith PetscLogInfo(0,"ISLocalToGlobalMappingGetInfo: Number of local owners for my global data %d\n",nrecvs); 58889d82c54SBarry Smith 58989d82c54SBarry Smith /* post receives for owned rows */ 59032dcc486SBarry Smith ierr = PetscMalloc((2*nrecvs+1)*(nmax+1)*sizeof(PetscInt),&recvs);CHKERRQ(ierr); 591b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs+1)*sizeof(MPI_Request),&recv_waits);CHKERRQ(ierr); 59289d82c54SBarry Smith for (i=0; i<nrecvs; i++) { 59332dcc486SBarry Smith ierr = MPI_Irecv(recvs+2*nmax*i,2*nmax,MPIU_INT,MPI_ANY_SOURCE,tag1,comm,recv_waits+i);CHKERRQ(ierr); 59489d82c54SBarry Smith } 59589d82c54SBarry Smith 59689d82c54SBarry Smith /* pack messages containing lists of local nodes to owners */ 59732dcc486SBarry Smith ierr = PetscMalloc((2*n+1)*sizeof(PetscInt),&sends);CHKERRQ(ierr); 59832dcc486SBarry Smith ierr = PetscMalloc((size+1)*sizeof(PetscInt),&starts);CHKERRQ(ierr); 59989d82c54SBarry Smith starts[0] = 0; 60027c402fcSBarry Smith for (i=1; i<size; i++) { starts[i] = starts[i-1] + 2*nprocs[2*i-2];} 60189d82c54SBarry Smith for (i=0; i<n; i++) { 60289d82c54SBarry Smith sends[starts[owner[i]]++] = lindices[i]; 60330dcb7c9SBarry Smith sends[starts[owner[i]]++] = i; 60489d82c54SBarry Smith } 60589d82c54SBarry Smith ierr = PetscFree(owner);CHKERRQ(ierr); 60689d82c54SBarry Smith starts[0] = 0; 60727c402fcSBarry Smith for (i=1; i<size; i++) { starts[i] = starts[i-1] + 2*nprocs[2*i-2];} 60889d82c54SBarry Smith 60989d82c54SBarry Smith /* send the messages */ 610b0a32e0cSBarry Smith ierr = PetscMalloc((nsends+1)*sizeof(MPI_Request),&send_waits);CHKERRQ(ierr); 61132dcc486SBarry Smith ierr = PetscMalloc((nsends+1)*sizeof(PetscInt),&dest);CHKERRQ(ierr); 61289d82c54SBarry Smith cnt = 0; 61389d82c54SBarry Smith for (i=0; i<size; i++) { 61427c402fcSBarry Smith if (nprocs[2*i]) { 61532dcc486SBarry Smith ierr = MPI_Isend(sends+starts[i],2*nprocs[2*i],MPIU_INT,i,tag1,comm,send_waits+cnt);CHKERRQ(ierr); 61630dcb7c9SBarry Smith dest[cnt] = i; 61789d82c54SBarry Smith cnt++; 61889d82c54SBarry Smith } 61989d82c54SBarry Smith } 62089d82c54SBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 62189d82c54SBarry Smith 62289d82c54SBarry Smith /* wait on receives */ 62397f1f81fSBarry Smith ierr = PetscMalloc((nrecvs+1)*sizeof(PetscMPIInt),&source);CHKERRQ(ierr); 62497f1f81fSBarry Smith ierr = PetscMalloc((nrecvs+1)*sizeof(PetscMPIInt),&len);CHKERRQ(ierr); 62589d82c54SBarry Smith cnt = nrecvs; 62632dcc486SBarry Smith ierr = PetscMalloc((ng+1)*sizeof(PetscInt),&nownedsenders);CHKERRQ(ierr); 62732dcc486SBarry Smith ierr = PetscMemzero(nownedsenders,ng*sizeof(PetscInt));CHKERRQ(ierr); 62889d82c54SBarry Smith while (cnt) { 62989d82c54SBarry Smith ierr = MPI_Waitany(nrecvs,recv_waits,&imdex,&recv_status);CHKERRQ(ierr); 63089d82c54SBarry Smith /* unpack receives into our local space */ 63132dcc486SBarry Smith ierr = MPI_Get_count(&recv_status,MPIU_INT,&len[imdex]);CHKERRQ(ierr); 63289d82c54SBarry Smith source[imdex] = recv_status.MPI_SOURCE; 63330dcb7c9SBarry Smith len[imdex] = len[imdex]/2; 634caba0dd0SBarry Smith /* count how many local owners for each of my global owned indices */ 63530dcb7c9SBarry Smith for (i=0; i<len[imdex]; i++) nownedsenders[recvs[2*imdex*nmax+2*i]-rstart]++; 63689d82c54SBarry Smith cnt--; 63789d82c54SBarry Smith } 63889d82c54SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 63989d82c54SBarry Smith 64030dcb7c9SBarry Smith /* count how many globally owned indices are on an edge multiplied by how many processors own them. */ 641bc8ff85bSBarry Smith nowned = 0; 642bc8ff85bSBarry Smith nownedm = 0; 643bc8ff85bSBarry Smith for (i=0; i<ng; i++) { 644bc8ff85bSBarry Smith if (nownedsenders[i] > 1) {nownedm += nownedsenders[i]; nowned++;} 645bc8ff85bSBarry Smith } 646bc8ff85bSBarry Smith 647bc8ff85bSBarry Smith /* create single array to contain rank of all local owners of each globally owned index */ 64832dcc486SBarry Smith ierr = PetscMalloc((nownedm+1)*sizeof(PetscInt),&ownedsenders);CHKERRQ(ierr); 64932dcc486SBarry Smith ierr = PetscMalloc((ng+1)*sizeof(PetscInt),&starts);CHKERRQ(ierr); 650bc8ff85bSBarry Smith starts[0] = 0; 651bc8ff85bSBarry Smith for (i=1; i<ng; i++) { 652bc8ff85bSBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 653bc8ff85bSBarry Smith else starts[i] = starts[i-1]; 654bc8ff85bSBarry Smith } 655bc8ff85bSBarry Smith 65630dcb7c9SBarry Smith /* for each nontrival globally owned node list all arriving processors */ 657bc8ff85bSBarry Smith for (i=0; i<nrecvs; i++) { 658bc8ff85bSBarry Smith for (j=0; j<len[i]; j++) { 65930dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 660bc8ff85bSBarry Smith if (nownedsenders[node] > 1) { 661bc8ff85bSBarry Smith ownedsenders[starts[node]++] = source[i]; 662bc8ff85bSBarry Smith } 663bc8ff85bSBarry Smith } 664bc8ff85bSBarry Smith } 665bc8ff85bSBarry Smith 66607b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 66730dcb7c9SBarry Smith starts[0] = 0; 66830dcb7c9SBarry Smith for (i=1; i<ng; i++) { 66930dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 67030dcb7c9SBarry Smith else starts[i] = starts[i-1]; 67130dcb7c9SBarry Smith } 67230dcb7c9SBarry Smith for (i=0; i<ng; i++) { 67330dcb7c9SBarry Smith if (nownedsenders[i] > 1) { 67430dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] global node %d local owner processors: ",rank,i+rstart);CHKERRQ(ierr); 67530dcb7c9SBarry Smith for (j=0; j<nownedsenders[i]; j++) { 67630dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",ownedsenders[starts[i]+j]);CHKERRQ(ierr); 67730dcb7c9SBarry Smith } 67830dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 67930dcb7c9SBarry Smith } 68030dcb7c9SBarry Smith } 68130dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 68207b52d57SBarry Smith }/* ----------------------------------- */ 68330dcb7c9SBarry Smith 6843677ff5aSBarry Smith /* wait on original sends */ 6853a96401aSBarry Smith if (nsends) { 686b0a32e0cSBarry Smith ierr = PetscMalloc(nsends*sizeof(MPI_Status),&send_status);CHKERRQ(ierr); 6873a96401aSBarry Smith ierr = MPI_Waitall(nsends,send_waits,send_status);CHKERRQ(ierr); 6883a96401aSBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 6893a96401aSBarry Smith } 69089d82c54SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 6913a96401aSBarry Smith ierr = PetscFree(sends);CHKERRQ(ierr); 6923677ff5aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 6933677ff5aSBarry Smith 6943677ff5aSBarry Smith /* pack messages to send back to local owners */ 69530dcb7c9SBarry Smith starts[0] = 0; 69630dcb7c9SBarry Smith for (i=1; i<ng; i++) { 69730dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 69830dcb7c9SBarry Smith else starts[i] = starts[i-1]; 69930dcb7c9SBarry Smith } 70030dcb7c9SBarry Smith nsends2 = nrecvs; 70132dcc486SBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(PetscInt),&nprocs);CHKERRQ(ierr); /* length of each message */ 70230dcb7c9SBarry Smith for (i=0; i<nrecvs; i++) { 70330dcb7c9SBarry Smith nprocs[i] = 1; 70430dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 70530dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 70630dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 70730dcb7c9SBarry Smith nprocs[i] += 2 + nownedsenders[node]; 70830dcb7c9SBarry Smith } 70930dcb7c9SBarry Smith } 71030dcb7c9SBarry Smith } 71130dcb7c9SBarry Smith nt = 0; for (i=0; i<nsends2; i++) nt += nprocs[i]; 71232dcc486SBarry Smith ierr = PetscMalloc((nt+1)*sizeof(PetscInt),&sends2);CHKERRQ(ierr); 71332dcc486SBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(PetscInt),&starts2);CHKERRQ(ierr); 71430dcb7c9SBarry Smith starts2[0] = 0; for (i=1; i<nsends2; i++) starts2[i] = starts2[i-1] + nprocs[i-1]; 71530dcb7c9SBarry Smith /* 71630dcb7c9SBarry Smith Each message is 1 + nprocs[i] long, and consists of 71730dcb7c9SBarry Smith (0) the number of nodes being sent back 71830dcb7c9SBarry Smith (1) the local node number, 71930dcb7c9SBarry Smith (2) the number of processors sharing it, 72030dcb7c9SBarry Smith (3) the processors sharing it 72130dcb7c9SBarry Smith */ 72230dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 72330dcb7c9SBarry Smith cnt = 1; 72430dcb7c9SBarry Smith sends2[starts2[i]] = 0; 72530dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 72630dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 72730dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 72830dcb7c9SBarry Smith sends2[starts2[i]]++; 72930dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = recvs[2*i*nmax+2*j+1]; 73030dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = nownedsenders[node]; 73132dcc486SBarry Smith ierr = PetscMemcpy(&sends2[starts2[i]+cnt],&ownedsenders[starts[node]],nownedsenders[node]*sizeof(PetscInt));CHKERRQ(ierr); 73230dcb7c9SBarry Smith cnt += nownedsenders[node]; 73330dcb7c9SBarry Smith } 73430dcb7c9SBarry Smith } 73530dcb7c9SBarry Smith } 73630dcb7c9SBarry Smith 73730dcb7c9SBarry Smith /* receive the message lengths */ 73830dcb7c9SBarry Smith nrecvs2 = nsends; 73932dcc486SBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(PetscInt),&lens2);CHKERRQ(ierr); 74032dcc486SBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(PetscInt),&starts3);CHKERRQ(ierr); 741d44834fbSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(MPI_Request),&recv_waits);CHKERRQ(ierr); 74230dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 743d44834fbSBarry Smith ierr = MPI_Irecv(&lens2[i],1,MPIU_INT,dest[i],tag2,comm,recv_waits+i);CHKERRQ(ierr); 74430dcb7c9SBarry Smith } 745d44834fbSBarry Smith 7468a8e0b3aSBarry Smith /* send the message lengths */ 7478a8e0b3aSBarry Smith for (i=0; i<nsends2; i++) { 7488a8e0b3aSBarry Smith ierr = MPI_Send(&nprocs[i],1,MPIU_INT,source[i],tag2,comm);CHKERRQ(ierr); 7498a8e0b3aSBarry Smith } 7508a8e0b3aSBarry Smith 751d44834fbSBarry Smith /* wait on receives of lens */ 752d44834fbSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(MPI_Status),&recv_statuses);CHKERRQ(ierr); 753d44834fbSBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 754d44834fbSBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 755d44834fbSBarry Smith ierr = PetscFree(recv_waits); 756d44834fbSBarry Smith 75730dcb7c9SBarry Smith starts3[0] = 0; 758d44834fbSBarry Smith nt = 0; 75930dcb7c9SBarry Smith for (i=0; i<nrecvs2-1; i++) { 76030dcb7c9SBarry Smith starts3[i+1] = starts3[i] + lens2[i]; 761d44834fbSBarry Smith nt += lens2[i]; 76230dcb7c9SBarry Smith } 763d44834fbSBarry Smith nt += lens2[nrecvs2-1]; 764d44834fbSBarry Smith 76532dcc486SBarry Smith ierr = PetscMalloc((nt+1)*sizeof(PetscInt),&recvs2);CHKERRQ(ierr); 766b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(MPI_Request),&recv_waits);CHKERRQ(ierr); 76752b72c4aSBarry Smith for (i=0; i<nrecvs2; i++) { 76832dcc486SBarry Smith ierr = MPI_Irecv(recvs2+starts3[i],lens2[i],MPIU_INT,dest[i],tag3,comm,recv_waits+i);CHKERRQ(ierr); 76930dcb7c9SBarry Smith } 77030dcb7c9SBarry Smith 77130dcb7c9SBarry Smith /* send the messages */ 772b0a32e0cSBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(MPI_Request),&send_waits);CHKERRQ(ierr); 77330dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 77432dcc486SBarry Smith ierr = MPI_Isend(sends2+starts2[i],nprocs[i],MPIU_INT,source[i],tag3,comm,send_waits+i);CHKERRQ(ierr); 77530dcb7c9SBarry Smith } 77630dcb7c9SBarry Smith 77730dcb7c9SBarry Smith /* wait on receives */ 778b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(MPI_Status),&recv_statuses);CHKERRQ(ierr); 77930dcb7c9SBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 78030dcb7c9SBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 78130dcb7c9SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 78230dcb7c9SBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 78330dcb7c9SBarry Smith 78407b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 78530dcb7c9SBarry Smith cnt = 0; 78630dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 78730dcb7c9SBarry Smith nt = recvs2[cnt++]; 78830dcb7c9SBarry Smith for (j=0; j<nt; j++) { 78930dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] local node %d number of subdomains %d: ",rank,recvs2[cnt],recvs2[cnt+1]);CHKERRQ(ierr); 79030dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 79130dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",recvs2[cnt+2+k]);CHKERRQ(ierr); 79230dcb7c9SBarry Smith } 79330dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 79430dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 79530dcb7c9SBarry Smith } 79630dcb7c9SBarry Smith } 79730dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 79807b52d57SBarry Smith } /* ----------------------------------- */ 79930dcb7c9SBarry Smith 80030dcb7c9SBarry Smith /* count number subdomains for each local node */ 80132dcc486SBarry Smith ierr = PetscMalloc(size*sizeof(PetscInt),&nprocs);CHKERRQ(ierr); 80232dcc486SBarry Smith ierr = PetscMemzero(nprocs,size*sizeof(PetscInt));CHKERRQ(ierr); 80330dcb7c9SBarry Smith cnt = 0; 80430dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 80530dcb7c9SBarry Smith nt = recvs2[cnt++]; 80630dcb7c9SBarry Smith for (j=0; j<nt; j++) { 80730dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 80830dcb7c9SBarry Smith nprocs[recvs2[cnt+2+k]]++; 80930dcb7c9SBarry Smith } 81030dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 81130dcb7c9SBarry Smith } 81230dcb7c9SBarry Smith } 81330dcb7c9SBarry Smith nt = 0; for (i=0; i<size; i++) nt += (nprocs[i] > 0); 81430dcb7c9SBarry Smith *nproc = nt; 81532dcc486SBarry Smith ierr = PetscMalloc((nt+1)*sizeof(PetscInt),procs);CHKERRQ(ierr); 81632dcc486SBarry Smith ierr = PetscMalloc((nt+1)*sizeof(PetscInt),numprocs);CHKERRQ(ierr); 81732dcc486SBarry Smith ierr = PetscMalloc((nt+1)*sizeof(PetscInt*),indices);CHKERRQ(ierr); 81832dcc486SBarry Smith ierr = PetscMalloc(size*sizeof(PetscInt),&bprocs);CHKERRQ(ierr); 81930dcb7c9SBarry Smith cnt = 0; 82030dcb7c9SBarry Smith for (i=0; i<size; i++) { 82130dcb7c9SBarry Smith if (nprocs[i] > 0) { 82230dcb7c9SBarry Smith bprocs[i] = cnt; 82330dcb7c9SBarry Smith (*procs)[cnt] = i; 82430dcb7c9SBarry Smith (*numprocs)[cnt] = nprocs[i]; 82532dcc486SBarry Smith ierr = PetscMalloc(nprocs[i]*sizeof(PetscInt),&(*indices)[cnt]);CHKERRQ(ierr); 82630dcb7c9SBarry Smith cnt++; 82730dcb7c9SBarry Smith } 82830dcb7c9SBarry Smith } 82930dcb7c9SBarry Smith 83030dcb7c9SBarry Smith /* make the list of subdomains for each nontrivial local node */ 83132dcc486SBarry Smith ierr = PetscMemzero(*numprocs,nt*sizeof(PetscInt));CHKERRQ(ierr); 83230dcb7c9SBarry Smith cnt = 0; 83330dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 83430dcb7c9SBarry Smith nt = recvs2[cnt++]; 83530dcb7c9SBarry Smith for (j=0; j<nt; j++) { 83630dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 83730dcb7c9SBarry Smith (*indices)[bprocs[recvs2[cnt+2+k]]][(*numprocs)[bprocs[recvs2[cnt+2+k]]]++] = recvs2[cnt]; 83830dcb7c9SBarry Smith } 83930dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 84030dcb7c9SBarry Smith } 84130dcb7c9SBarry Smith } 84230dcb7c9SBarry Smith ierr = PetscFree(bprocs);CHKERRQ(ierr); 84307b52d57SBarry Smith ierr = PetscFree(recvs2);CHKERRQ(ierr); 84430dcb7c9SBarry Smith 84507b52d57SBarry Smith /* sort the node indexing by their global numbers */ 84607b52d57SBarry Smith nt = *nproc; 84707b52d57SBarry Smith for (i=0; i<nt; i++) { 84832dcc486SBarry Smith ierr = PetscMalloc(((*numprocs)[i])*sizeof(PetscInt),&tmp);CHKERRQ(ierr); 84907b52d57SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 85007b52d57SBarry Smith tmp[j] = lindices[(*indices)[i][j]]; 85107b52d57SBarry Smith } 85207b52d57SBarry Smith ierr = PetscSortIntWithArray((*numprocs)[i],tmp,(*indices)[i]);CHKERRQ(ierr); 85307b52d57SBarry Smith ierr = PetscFree(tmp);CHKERRQ(ierr); 85407b52d57SBarry Smith } 85507b52d57SBarry Smith 85607b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 85730dcb7c9SBarry Smith nt = *nproc; 85830dcb7c9SBarry Smith for (i=0; i<nt; i++) { 85930dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] subdomain %d number of indices %d: ",rank,(*procs)[i],(*numprocs)[i]);CHKERRQ(ierr); 86030dcb7c9SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 86130dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",(*indices)[i][j]);CHKERRQ(ierr); 86230dcb7c9SBarry Smith } 86330dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 86430dcb7c9SBarry Smith } 86530dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 86607b52d57SBarry Smith } /* ----------------------------------- */ 86730dcb7c9SBarry Smith 86830dcb7c9SBarry Smith /* wait on sends */ 86930dcb7c9SBarry Smith if (nsends2) { 870b0a32e0cSBarry Smith ierr = PetscMalloc(nsends2*sizeof(MPI_Status),&send_status);CHKERRQ(ierr); 87130dcb7c9SBarry Smith ierr = MPI_Waitall(nsends2,send_waits,send_status);CHKERRQ(ierr); 87230dcb7c9SBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 87330dcb7c9SBarry Smith } 87430dcb7c9SBarry Smith 87530dcb7c9SBarry Smith ierr = PetscFree(starts3);CHKERRQ(ierr); 87630dcb7c9SBarry Smith ierr = PetscFree(dest);CHKERRQ(ierr); 87730dcb7c9SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 8783677ff5aSBarry Smith 879bc8ff85bSBarry Smith ierr = PetscFree(nownedsenders);CHKERRQ(ierr); 880bc8ff85bSBarry Smith ierr = PetscFree(ownedsenders);CHKERRQ(ierr); 881bc8ff85bSBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 88230dcb7c9SBarry Smith ierr = PetscFree(starts2);CHKERRQ(ierr); 88330dcb7c9SBarry Smith ierr = PetscFree(lens2);CHKERRQ(ierr); 88489d82c54SBarry Smith 88589d82c54SBarry Smith ierr = PetscFree(source);CHKERRQ(ierr); 88697f1f81fSBarry Smith ierr = PetscFree(len);CHKERRQ(ierr); 88789d82c54SBarry Smith ierr = PetscFree(recvs);CHKERRQ(ierr); 8883a96401aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 88930dcb7c9SBarry Smith ierr = PetscFree(sends2);CHKERRQ(ierr); 89024cf384cSBarry Smith 89124cf384cSBarry Smith /* put the information about myself as the first entry in the list */ 89224cf384cSBarry Smith first_procs = (*procs)[0]; 89324cf384cSBarry Smith first_numprocs = (*numprocs)[0]; 89424cf384cSBarry Smith first_indices = (*indices)[0]; 89524cf384cSBarry Smith for (i=0; i<*nproc; i++) { 89624cf384cSBarry Smith if ((*procs)[i] == rank) { 89724cf384cSBarry Smith (*procs)[0] = (*procs)[i]; 89824cf384cSBarry Smith (*numprocs)[0] = (*numprocs)[i]; 89924cf384cSBarry Smith (*indices)[0] = (*indices)[i]; 90024cf384cSBarry Smith (*procs)[i] = first_procs; 90124cf384cSBarry Smith (*numprocs)[i] = first_numprocs; 90224cf384cSBarry Smith (*indices)[i] = first_indices; 90324cf384cSBarry Smith break; 90424cf384cSBarry Smith } 90524cf384cSBarry Smith } 90689d82c54SBarry Smith PetscFunctionReturn(0); 90789d82c54SBarry Smith } 90889d82c54SBarry Smith 9094a2ae208SSatish Balay #undef __FUNCT__ 9104a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingRestoreInfo" 91107b52d57SBarry Smith /*@C 91207b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo - Frees the memory allocated by ISLocalToGlobalMappingGetInfo() 91389d82c54SBarry Smith 91407b52d57SBarry Smith Collective on ISLocalToGlobalMapping 91507b52d57SBarry Smith 91607b52d57SBarry Smith Input Parameters: 91707b52d57SBarry Smith . mapping - the mapping from local to global indexing 91807b52d57SBarry Smith 91907b52d57SBarry Smith Output Parameter: 92007b52d57SBarry Smith + nproc - number of processors that are connected to this one 92107b52d57SBarry Smith . proc - neighboring processors 92207b52d57SBarry Smith . numproc - number of indices for each processor 92307b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 92407b52d57SBarry Smith 92507b52d57SBarry Smith Level: advanced 92607b52d57SBarry Smith 92707b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 92807b52d57SBarry Smith ISLocalToGlobalMappingGetInfo() 92907b52d57SBarry Smith @*/ 93032dcc486SBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 93107b52d57SBarry Smith { 9326849ba73SBarry Smith PetscErrorCode ierr; 93332dcc486SBarry Smith PetscInt i; 93407b52d57SBarry Smith 93507b52d57SBarry Smith PetscFunctionBegin; 93600ff320aSBarry Smith if (*procs) {ierr = PetscFree(*procs);CHKERRQ(ierr);} 93700ff320aSBarry Smith if (*numprocs) {ierr = PetscFree(*numprocs);CHKERRQ(ierr);} 93800ff320aSBarry Smith if (*indices) { 93900ff320aSBarry Smith if ((*indices)[0]) {ierr = PetscFree((*indices)[0]);CHKERRQ(ierr);} 94000ff320aSBarry Smith for (i=1; i<*nproc; i++) { 94124cf384cSBarry Smith if ((*indices)[i]) {ierr = PetscFree((*indices)[i]);CHKERRQ(ierr);} 94207b52d57SBarry Smith } 94307b52d57SBarry Smith ierr = PetscFree(*indices);CHKERRQ(ierr); 94424cf384cSBarry Smith } 94507b52d57SBarry Smith PetscFunctionReturn(0); 94607b52d57SBarry Smith } 94789d82c54SBarry Smith 948bc8ff85bSBarry Smith 949bc8ff85bSBarry Smith 950bc8ff85bSBarry Smith 951bc8ff85bSBarry Smith 952bc8ff85bSBarry Smith 953bc8ff85bSBarry Smith 954bc8ff85bSBarry Smith 955bc8ff85bSBarry Smith 956bc8ff85bSBarry Smith 957bc8ff85bSBarry Smith 958bc8ff85bSBarry Smith 959bc8ff85bSBarry Smith 960bc8ff85bSBarry Smith 961bc8ff85bSBarry Smith 962bc8ff85bSBarry Smith 963bc8ff85bSBarry Smith 96424cf384cSBarry Smith 965