10c735eedSKris Buschelman #define PETSCVEC_DLL 22362add9SBarry Smith 3e090d566SSatish Balay #include "petscsys.h" /*I "petscsys.h" I*/ 4e090d566SSatish Balay #include "src/vec/is/isimpl.h" /*I "petscis.h" I*/ 52362add9SBarry Smith 60c735eedSKris Buschelman EXTERN PetscErrorCode PETSCVEC_DLLEXPORT VecInitializePackage(char *); 70c735eedSKris Buschelman PetscCookie PETSCVEC_DLLEXPORT IS_LTOGM_COOKIE = -1; 88e58c17dSMatthew Knepley 94a2ae208SSatish Balay #undef __FUNCT__ 104a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingGetSize" 113b9aefa3SBarry Smith /*@C 123b9aefa3SBarry Smith ISLocalToGlobalMappingGetSize - Gets the local size of a local to global mapping. 133b9aefa3SBarry Smith 143b9aefa3SBarry Smith Not Collective 153b9aefa3SBarry Smith 163b9aefa3SBarry Smith Input Parameter: 173b9aefa3SBarry Smith . ltog - local to global mapping 183b9aefa3SBarry Smith 193b9aefa3SBarry Smith Output Parameter: 203b9aefa3SBarry Smith . n - the number of entries in the local mapping 213b9aefa3SBarry Smith 223b9aefa3SBarry Smith Level: advanced 233b9aefa3SBarry Smith 24273d9f13SBarry Smith Concepts: mapping^local to global 253b9aefa3SBarry Smith 263b9aefa3SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 273b9aefa3SBarry Smith @*/ 280c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISLocalToGlobalMappingGetSize(ISLocalToGlobalMapping mapping,PetscInt *n) 293b9aefa3SBarry Smith { 303b9aefa3SBarry Smith PetscFunctionBegin; 314482741eSBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE,1); 324482741eSBarry Smith PetscValidIntPointer(n,2); 333b9aefa3SBarry Smith *n = mapping->n; 343b9aefa3SBarry Smith PetscFunctionReturn(0); 353b9aefa3SBarry Smith } 363b9aefa3SBarry Smith 374a2ae208SSatish Balay #undef __FUNCT__ 384a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingView" 395a5d4f66SBarry Smith /*@C 405a5d4f66SBarry Smith ISLocalToGlobalMappingView - View a local to global mapping 415a5d4f66SBarry Smith 42b9cd556bSLois Curfman McInnes Not Collective 43b9cd556bSLois Curfman McInnes 445a5d4f66SBarry Smith Input Parameters: 453b9aefa3SBarry Smith + ltog - local to global mapping 463b9aefa3SBarry Smith - viewer - viewer 475a5d4f66SBarry Smith 48a997ad1aSLois Curfman McInnes Level: advanced 49a997ad1aSLois Curfman McInnes 50273d9f13SBarry Smith Concepts: mapping^local to global 515a5d4f66SBarry Smith 525a5d4f66SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 535a5d4f66SBarry Smith @*/ 540c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISLocalToGlobalMappingView(ISLocalToGlobalMapping mapping,PetscViewer viewer) 555a5d4f66SBarry Smith { 5632dcc486SBarry Smith PetscInt i; 5732dcc486SBarry Smith PetscMPIInt rank; 5832077d6dSBarry Smith PetscTruth iascii; 596849ba73SBarry Smith PetscErrorCode ierr; 605a5d4f66SBarry Smith 615a5d4f66SBarry Smith PetscFunctionBegin; 624482741eSBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE,1); 63b0a32e0cSBarry Smith if (!viewer) viewer = PETSC_VIEWER_STDOUT_(mapping->comm); 644482741eSBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE,2); 655a5d4f66SBarry Smith 66f1af5d2fSBarry Smith ierr = MPI_Comm_rank(mapping->comm,&rank);CHKERRQ(ierr); 6732077d6dSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 6832077d6dSBarry Smith if (iascii) { 695a5d4f66SBarry Smith for (i=0; i<mapping->n; i++) { 70b0a32e0cSBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d] %d %d\n",rank,i,mapping->indices[i]);CHKERRQ(ierr); 716831982aSBarry Smith } 72b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 736831982aSBarry Smith } else { 74958c9bccSBarry Smith SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported for ISLocalToGlobalMapping",((PetscObject)viewer)->type_name); 755a5d4f66SBarry Smith } 765a5d4f66SBarry Smith 775a5d4f66SBarry Smith PetscFunctionReturn(0); 785a5d4f66SBarry Smith } 795a5d4f66SBarry Smith 804a2ae208SSatish Balay #undef __FUNCT__ 814a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreateIS" 822bdab257SBarry Smith /*@C 832bdab257SBarry Smith ISLocalToGlobalMappingCreateIS - Creates a mapping between a local (0 to n) 842bdab257SBarry Smith ordering and a global parallel ordering. 852bdab257SBarry Smith 860f5bd95cSBarry Smith Not collective 87b9cd556bSLois Curfman McInnes 88a997ad1aSLois Curfman McInnes Input Parameter: 892bdab257SBarry Smith . is - index set containing the global numbers for each local 902bdab257SBarry Smith 91a997ad1aSLois Curfman McInnes Output Parameter: 922bdab257SBarry Smith . mapping - new mapping data structure 932bdab257SBarry Smith 94a997ad1aSLois Curfman McInnes Level: advanced 95a997ad1aSLois Curfman McInnes 96273d9f13SBarry Smith Concepts: mapping^local to global 972bdab257SBarry Smith 982bdab257SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 992bdab257SBarry Smith @*/ 1000c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISLocalToGlobalMappingCreateIS(IS is,ISLocalToGlobalMapping *mapping) 1012bdab257SBarry Smith { 1026849ba73SBarry Smith PetscErrorCode ierr; 10332dcc486SBarry Smith PetscInt n,*indices; 1042bdab257SBarry Smith MPI_Comm comm; 1053a40ed3dSBarry Smith 1063a40ed3dSBarry Smith PetscFunctionBegin; 1074482741eSBarry Smith PetscValidHeaderSpecific(is,IS_COOKIE,1); 1084482741eSBarry Smith PetscValidPointer(mapping,2); 1092bdab257SBarry Smith 1102bdab257SBarry Smith ierr = PetscObjectGetComm((PetscObject)is,&comm);CHKERRQ(ierr); 1113b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 1122bdab257SBarry Smith ierr = ISGetIndices(is,&indices);CHKERRQ(ierr); 1132bdab257SBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,n,indices,mapping);CHKERRQ(ierr); 1142bdab257SBarry Smith ierr = ISRestoreIndices(is,&indices);CHKERRQ(ierr); 1152bdab257SBarry Smith 1163a40ed3dSBarry Smith PetscFunctionReturn(0); 1172bdab257SBarry Smith } 1185a5d4f66SBarry Smith 119b46b645bSBarry Smith 1204a2ae208SSatish Balay #undef __FUNCT__ 1214a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreate" 122*ba5bb76aSSatish Balay /*@ 12390f02eecSBarry Smith ISLocalToGlobalMappingCreate - Creates a mapping between a local (0 to n) 12490f02eecSBarry Smith ordering and a global parallel ordering. 1252362add9SBarry Smith 12689d82c54SBarry Smith Not Collective, but communicator may have more than one process 127b9cd556bSLois Curfman McInnes 1282362add9SBarry Smith Input Parameters: 12989d82c54SBarry Smith + comm - MPI communicator 13090f02eecSBarry Smith . n - the number of local elements 131b9cd556bSLois Curfman McInnes - indices - the global index for each local element 1322362add9SBarry Smith 133a997ad1aSLois Curfman McInnes Output Parameter: 13490f02eecSBarry Smith . mapping - new mapping data structure 1352362add9SBarry Smith 136a997ad1aSLois Curfman McInnes Level: advanced 137a997ad1aSLois Curfman McInnes 138273d9f13SBarry Smith Concepts: mapping^local to global 1392362add9SBarry Smith 140b46b645bSBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreateNC() 1412362add9SBarry Smith @*/ 1420c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISLocalToGlobalMappingCreate(MPI_Comm cm,PetscInt n,const PetscInt indices[],ISLocalToGlobalMapping *mapping) 1432362add9SBarry Smith { 1446849ba73SBarry Smith PetscErrorCode ierr; 14532dcc486SBarry Smith PetscInt *in; 146b46b645bSBarry Smith 147b46b645bSBarry Smith PetscFunctionBegin; 1484482741eSBarry Smith PetscValidIntPointer(indices,3); 1494482741eSBarry Smith PetscValidPointer(mapping,4); 1507c334f02SBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&in);CHKERRQ(ierr); 15132dcc486SBarry Smith ierr = PetscMemcpy(in,indices,n*sizeof(PetscInt));CHKERRQ(ierr); 152b46b645bSBarry Smith ierr = ISLocalToGlobalMappingCreateNC(cm,n,in,mapping);CHKERRQ(ierr); 153b46b645bSBarry Smith PetscFunctionReturn(0); 154b46b645bSBarry Smith } 155b46b645bSBarry Smith 156b46b645bSBarry Smith #undef __FUNCT__ 157b46b645bSBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingCreateNC" 158b46b645bSBarry Smith /*@C 159b46b645bSBarry Smith ISLocalToGlobalMappingCreateNC - Creates a mapping between a local (0 to n) 160b46b645bSBarry Smith ordering and a global parallel ordering. 161b46b645bSBarry Smith 162b46b645bSBarry Smith Not Collective, but communicator may have more than one process 163b46b645bSBarry Smith 164b46b645bSBarry Smith Input Parameters: 165b46b645bSBarry Smith + comm - MPI communicator 166b46b645bSBarry Smith . n - the number of local elements 167b46b645bSBarry Smith - indices - the global index for each local element 168b46b645bSBarry Smith 169b46b645bSBarry Smith Output Parameter: 170b46b645bSBarry Smith . mapping - new mapping data structure 171b46b645bSBarry Smith 172b46b645bSBarry Smith Level: developer 173b46b645bSBarry Smith 174b46b645bSBarry Smith Notes: Does not copy the indices, just keeps the pointer to the indices. The ISLocalToGlobalMappingDestroy() 175b46b645bSBarry Smith will free the space so it must be obtained with PetscMalloc() and it must not be freed elsewhere. 176b46b645bSBarry Smith 177b46b645bSBarry Smith Concepts: mapping^local to global 178b46b645bSBarry Smith 179b46b645bSBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate() 180b46b645bSBarry Smith @*/ 1810c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISLocalToGlobalMappingCreateNC(MPI_Comm cm,PetscInt n,const PetscInt indices[],ISLocalToGlobalMapping *mapping) 182b46b645bSBarry Smith { 183dfbe8321SBarry Smith PetscErrorCode ierr; 18423f7533aSBarry Smith 1853a40ed3dSBarry Smith PetscFunctionBegin; 1864482741eSBarry Smith PetscValidIntPointer(indices,3); 1874482741eSBarry Smith PetscValidPointer(mapping,4); 1888e58c17dSMatthew Knepley *mapping = PETSC_NULL; 1898e58c17dSMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 19023f7533aSBarry Smith ierr = VecInitializePackage(PETSC_NULL);CHKERRQ(ierr); 1918e58c17dSMatthew Knepley #endif 19223f7533aSBarry Smith if (IS_LTOGM_COOKIE == -1) { 19323f7533aSBarry Smith ierr = PetscLogClassRegister(&IS_LTOGM_COOKIE,"IS Local to global mapping");CHKERRQ(ierr); 19423f7533aSBarry Smith } 1952362add9SBarry Smith 19652e6d16bSBarry Smith ierr = PetscHeaderCreate(*mapping,_p_ISLocalToGlobalMapping,int,IS_LTOGM_COOKIE,0,"ISLocalToGlobalMapping", 19752e6d16bSBarry Smith cm,ISLocalToGlobalMappingDestroy,ISLocalToGlobalMappingView);CHKERRQ(ierr); 19852e6d16bSBarry Smith ierr = PetscLogObjectMemory(*mapping,sizeof(struct _p_ISLocalToGlobalMapping)+n*sizeof(PetscInt));CHKERRQ(ierr); 199d4bb536fSBarry Smith 200d4bb536fSBarry Smith (*mapping)->n = n; 20132dcc486SBarry Smith (*mapping)->indices = (PetscInt*)indices; 202d4bb536fSBarry Smith 203d4bb536fSBarry Smith /* 204d4bb536fSBarry Smith Do not create the global to local mapping. This is only created if 205d4bb536fSBarry Smith ISGlobalToLocalMapping() is called 206d4bb536fSBarry Smith */ 207d4bb536fSBarry Smith (*mapping)->globals = 0; 2083a40ed3dSBarry Smith PetscFunctionReturn(0); 2092362add9SBarry Smith } 2102362add9SBarry Smith 2114a2ae208SSatish Balay #undef __FUNCT__ 2124a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingBlock" 213bce096a4SSatish Balay /*@ 214323b833fSBarry Smith ISLocalToGlobalMappingBlock - Creates a blocked index version of an 215323b833fSBarry Smith ISLocalToGlobalMapping that is appropriate for MatSetLocalToGlobalMappingBlock() 216323b833fSBarry Smith and VecSetLocalToGlobalMappingBlock(). 217323b833fSBarry Smith 218323b833fSBarry Smith Not Collective, but communicator may have more than one process 219323b833fSBarry Smith 220323b833fSBarry Smith Input Parameters: 221323b833fSBarry Smith + inmap - original point-wise mapping 222323b833fSBarry Smith - bs - block size 223323b833fSBarry Smith 224323b833fSBarry Smith Output Parameter: 22569eb54c3SBarry Smith . outmap - block based mapping; the indices are relative to BLOCKS, not individual vector or matrix entries. 226323b833fSBarry Smith 227323b833fSBarry Smith Level: advanced 228323b833fSBarry Smith 229323b833fSBarry Smith Concepts: mapping^local to global 230323b833fSBarry Smith 231323b833fSBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingCreateIS() 232323b833fSBarry Smith @*/ 2330c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISLocalToGlobalMappingBlock(ISLocalToGlobalMapping inmap,PetscInt bs,ISLocalToGlobalMapping *outmap) 234323b833fSBarry Smith { 2356849ba73SBarry Smith PetscErrorCode ierr; 23632dcc486SBarry Smith PetscInt *ii,i,n; 237323b833fSBarry Smith 238323b833fSBarry Smith PetscFunctionBegin; 239323b833fSBarry Smith if (bs > 1) { 240323b833fSBarry Smith n = inmap->n/bs; 24112ce3465SBarry Smith if (n*bs != inmap->n) SETERRQ(PETSC_ERR_ARG_INCOMP,"Pointwise mapping length is not divisible by block size"); 24232dcc486SBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&ii);CHKERRQ(ierr); 243323b833fSBarry Smith for (i=0; i<n; i++) { 244db032c9dSBarry Smith ii[i] = inmap->indices[bs*i]/bs; 245323b833fSBarry Smith } 246323b833fSBarry Smith ierr = ISLocalToGlobalMappingCreate(inmap->comm,n,ii,outmap);CHKERRQ(ierr); 247323b833fSBarry Smith ierr = PetscFree(ii);CHKERRQ(ierr); 248323b833fSBarry Smith } else { 249323b833fSBarry Smith *outmap = inmap; 250323b833fSBarry Smith ierr = PetscObjectReference((PetscObject)inmap);CHKERRQ(ierr); 251323b833fSBarry Smith } 252323b833fSBarry Smith PetscFunctionReturn(0); 253323b833fSBarry Smith } 254323b833fSBarry Smith 2554a2ae208SSatish Balay #undef __FUNCT__ 2564a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingDestroy" 25790f02eecSBarry Smith /*@ 25890f02eecSBarry Smith ISLocalToGlobalMappingDestroy - Destroys a mapping between a local (0 to n) 25990f02eecSBarry Smith ordering and a global parallel ordering. 26090f02eecSBarry Smith 2610f5bd95cSBarry Smith Note Collective 262b9cd556bSLois Curfman McInnes 26390f02eecSBarry Smith Input Parameters: 26490f02eecSBarry Smith . mapping - mapping data structure 26590f02eecSBarry Smith 266a997ad1aSLois Curfman McInnes Level: advanced 267a997ad1aSLois Curfman McInnes 2683acfe500SLois Curfman McInnes .seealso: ISLocalToGlobalMappingCreate() 26990f02eecSBarry Smith @*/ 2700c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping mapping) 27190f02eecSBarry Smith { 272dfbe8321SBarry Smith PetscErrorCode ierr; 2733a40ed3dSBarry Smith PetscFunctionBegin; 2744482741eSBarry Smith PetscValidPointer(mapping,1); 2753a40ed3dSBarry Smith if (--mapping->refct > 0) PetscFunctionReturn(0); 27685614651SBarry Smith if (mapping->refct < 0) { 277634064b4SBarry Smith SETERRQ(PETSC_ERR_PLIB,"Mapping already destroyed"); 27885614651SBarry Smith } 27990f02eecSBarry Smith 280606d414cSSatish Balay ierr = PetscFree(mapping->indices);CHKERRQ(ierr); 281606d414cSSatish Balay if (mapping->globals) {ierr = PetscFree(mapping->globals);CHKERRQ(ierr);} 282d38fa0fbSBarry Smith ierr = PetscHeaderDestroy(mapping);CHKERRQ(ierr); 2833a40ed3dSBarry Smith PetscFunctionReturn(0); 28490f02eecSBarry Smith } 28590f02eecSBarry Smith 2864a2ae208SSatish Balay #undef __FUNCT__ 2874a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingApplyIS" 28890f02eecSBarry Smith /*@ 2893acfe500SLois Curfman McInnes ISLocalToGlobalMappingApplyIS - Creates from an IS in the local numbering 2903acfe500SLois Curfman McInnes a new index set using the global numbering defined in an ISLocalToGlobalMapping 2913acfe500SLois Curfman McInnes context. 29290f02eecSBarry Smith 293b9cd556bSLois Curfman McInnes Not collective 294b9cd556bSLois Curfman McInnes 29590f02eecSBarry Smith Input Parameters: 296b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 297b9cd556bSLois Curfman McInnes - is - index set in local numbering 29890f02eecSBarry Smith 29990f02eecSBarry Smith Output Parameters: 30090f02eecSBarry Smith . newis - index set in global numbering 30190f02eecSBarry Smith 302a997ad1aSLois Curfman McInnes Level: advanced 303a997ad1aSLois Curfman McInnes 304273d9f13SBarry Smith Concepts: mapping^local to global 3053acfe500SLois Curfman McInnes 30690f02eecSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 307d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy(), ISGlobalToLocalMappingApply() 30890f02eecSBarry Smith @*/ 3090c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping mapping,IS is,IS *newis) 31090f02eecSBarry Smith { 3116849ba73SBarry Smith PetscErrorCode ierr; 31232dcc486SBarry Smith PetscInt n,i,*idxin,*idxmap,*idxout,Nmax = mapping->n; 3133a40ed3dSBarry Smith 3143a40ed3dSBarry Smith PetscFunctionBegin; 3154482741eSBarry Smith PetscValidPointer(mapping,1); 3164482741eSBarry Smith PetscValidHeaderSpecific(is,IS_COOKIE,2); 3174482741eSBarry Smith PetscValidPointer(newis,3); 31890f02eecSBarry Smith 3193b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 32090f02eecSBarry Smith ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 32190f02eecSBarry Smith idxmap = mapping->indices; 32290f02eecSBarry Smith 3237c334f02SBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&idxout);CHKERRQ(ierr); 32490f02eecSBarry Smith for (i=0; i<n; i++) { 325590ac198SBarry Smith if (idxin[i] >= Nmax) SETERRQ3(PETSC_ERR_ARG_OUTOFRANGE,"Local index %d too large %d (max) at %d",idxin[i],Nmax-1,i); 32690f02eecSBarry Smith idxout[i] = idxmap[idxin[i]]; 32790f02eecSBarry Smith } 3283b9aefa3SBarry Smith ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 329029af93fSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxout,newis);CHKERRQ(ierr); 330606d414cSSatish Balay ierr = PetscFree(idxout);CHKERRQ(ierr); 3313a40ed3dSBarry Smith PetscFunctionReturn(0); 33290f02eecSBarry Smith } 33390f02eecSBarry Smith 33489d82c54SBarry Smith /*MC 3353acfe500SLois Curfman McInnes ISLocalToGlobalMappingApply - Takes a list of integers in a local numbering 3363acfe500SLois Curfman McInnes and converts them to the global numbering. 33790f02eecSBarry Smith 338b9cd556bSLois Curfman McInnes Not collective 339b9cd556bSLois Curfman McInnes 340bb25748dSBarry Smith Input Parameters: 341b9cd556bSLois Curfman McInnes + mapping - the local to global mapping context 342bb25748dSBarry Smith . N - number of integers 343b9cd556bSLois Curfman McInnes - in - input indices in local numbering 344bb25748dSBarry Smith 345bb25748dSBarry Smith Output Parameter: 346bb25748dSBarry Smith . out - indices in global numbering 347bb25748dSBarry Smith 3483b9aefa3SBarry Smith Synopsis: 349d360dc6fSBarry Smith PetscErrorCode ISLocalToGlobalMappingApply(ISLocalToGlobalMapping mapping,int N,int in[],int out[]) 3503b9aefa3SBarry Smith 351b9cd556bSLois Curfman McInnes Notes: 352b9cd556bSLois Curfman McInnes The in and out array parameters may be identical. 353d4bb536fSBarry Smith 354a997ad1aSLois Curfman McInnes Level: advanced 355a997ad1aSLois Curfman McInnes 356bb25748dSBarry Smith .seealso: ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 3570752156aSBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 358d4bb536fSBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 359bb25748dSBarry Smith 360273d9f13SBarry Smith Concepts: mapping^local to global 361d4bb536fSBarry Smith 36289d82c54SBarry Smith M*/ 363d4bb536fSBarry Smith 364d4bb536fSBarry Smith /* -----------------------------------------------------------------------------------------*/ 365d4bb536fSBarry Smith 3664a2ae208SSatish Balay #undef __FUNCT__ 3674a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingSetUp_Private" 368d4bb536fSBarry Smith /* 369d4bb536fSBarry Smith Creates the global fields in the ISLocalToGlobalMapping structure 370d4bb536fSBarry Smith */ 3716849ba73SBarry Smith static PetscErrorCode ISGlobalToLocalMappingSetUp_Private(ISLocalToGlobalMapping mapping) 372d4bb536fSBarry Smith { 3736849ba73SBarry Smith PetscErrorCode ierr; 37432dcc486SBarry Smith PetscInt i,*idx = mapping->indices,n = mapping->n,end,start,*globals; 375d4bb536fSBarry Smith 3763a40ed3dSBarry Smith PetscFunctionBegin; 377d4bb536fSBarry Smith end = 0; 378d4bb536fSBarry Smith start = 100000000; 379d4bb536fSBarry Smith 380d4bb536fSBarry Smith for (i=0; i<n; i++) { 381d4bb536fSBarry Smith if (idx[i] < 0) continue; 382d4bb536fSBarry Smith if (idx[i] < start) start = idx[i]; 383d4bb536fSBarry Smith if (idx[i] > end) end = idx[i]; 384d4bb536fSBarry Smith } 385d4bb536fSBarry Smith if (start > end) {start = 0; end = -1;} 386d4bb536fSBarry Smith mapping->globalstart = start; 387d4bb536fSBarry Smith mapping->globalend = end; 388d4bb536fSBarry Smith 38932dcc486SBarry Smith ierr = PetscMalloc((end-start+2)*sizeof(PetscInt),&globals);CHKERRQ(ierr); 390b0a32e0cSBarry Smith mapping->globals = globals; 391d4bb536fSBarry Smith for (i=0; i<end-start+1; i++) { 392d4bb536fSBarry Smith globals[i] = -1; 393d4bb536fSBarry Smith } 394d4bb536fSBarry Smith for (i=0; i<n; i++) { 395d4bb536fSBarry Smith if (idx[i] < 0) continue; 396d4bb536fSBarry Smith globals[idx[i] - start] = i; 397d4bb536fSBarry Smith } 398d4bb536fSBarry Smith 39952e6d16bSBarry Smith ierr = PetscLogObjectMemory(mapping,(end-start+1)*sizeof(PetscInt));CHKERRQ(ierr); 4003a40ed3dSBarry Smith PetscFunctionReturn(0); 401d4bb536fSBarry Smith } 402d4bb536fSBarry Smith 4034a2ae208SSatish Balay #undef __FUNCT__ 4044a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingApply" 405d4bb536fSBarry Smith /*@ 406a997ad1aSLois Curfman McInnes ISGlobalToLocalMappingApply - Provides the local numbering for a list of integers 407a997ad1aSLois Curfman McInnes specified with a global numbering. 408d4bb536fSBarry Smith 409b9cd556bSLois Curfman McInnes Not collective 410b9cd556bSLois Curfman McInnes 411d4bb536fSBarry Smith Input Parameters: 412b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 413d4bb536fSBarry Smith . type - IS_GTOLM_MASK - replaces global indices with no local value with -1 414d4bb536fSBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 415d4bb536fSBarry Smith . n - number of global indices to map 416b9cd556bSLois Curfman McInnes - idx - global indices to map 417d4bb536fSBarry Smith 418d4bb536fSBarry Smith Output Parameters: 419b9cd556bSLois Curfman McInnes + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 420b9cd556bSLois Curfman McInnes - idxout - local index of each global index, one must pass in an array long enough 421e182c471SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApply() with 422e182c471SBarry Smith idxout == PETSC_NULL to determine the required length (returned in nout) 423e182c471SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApply() 424e182c471SBarry Smith a second time to set the values. 425d4bb536fSBarry Smith 426b9cd556bSLois Curfman McInnes Notes: 427b9cd556bSLois Curfman McInnes Either nout or idxout may be PETSC_NULL. idx and idxout may be identical. 428d4bb536fSBarry Smith 4290f5bd95cSBarry Smith This is not scalable in memory usage. Each processor requires O(Nglobal) size 4300f5bd95cSBarry Smith array to compute these. 4310f5bd95cSBarry Smith 432a997ad1aSLois Curfman McInnes Level: advanced 433a997ad1aSLois Curfman McInnes 434273d9f13SBarry Smith Concepts: mapping^global to local 435d4bb536fSBarry Smith 436d4bb536fSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 437d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy() 438d4bb536fSBarry Smith @*/ 4390c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISGlobalToLocalMappingApply(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, 44032dcc486SBarry Smith PetscInt n,const PetscInt idx[],PetscInt *nout,PetscInt idxout[]) 441d4bb536fSBarry Smith { 44232dcc486SBarry Smith PetscInt i,*globals,nf = 0,tmp,start,end; 4436849ba73SBarry Smith PetscErrorCode ierr; 444d4bb536fSBarry Smith 4453a40ed3dSBarry Smith PetscFunctionBegin; 446d4bb536fSBarry Smith if (!mapping->globals) { 447d4bb536fSBarry Smith ierr = ISGlobalToLocalMappingSetUp_Private(mapping);CHKERRQ(ierr); 448d4bb536fSBarry Smith } 449d4bb536fSBarry Smith globals = mapping->globals; 450d4bb536fSBarry Smith start = mapping->globalstart; 451d4bb536fSBarry Smith end = mapping->globalend; 452d4bb536fSBarry Smith 453d4bb536fSBarry Smith if (type == IS_GTOLM_MASK) { 454d4bb536fSBarry Smith if (idxout) { 455d4bb536fSBarry Smith for (i=0; i<n; i++) { 456d4bb536fSBarry Smith if (idx[i] < 0) idxout[i] = idx[i]; 457d4bb536fSBarry Smith else if (idx[i] < start) idxout[i] = -1; 458d4bb536fSBarry Smith else if (idx[i] > end) idxout[i] = -1; 459d4bb536fSBarry Smith else idxout[i] = globals[idx[i] - start]; 460d4bb536fSBarry Smith } 461d4bb536fSBarry Smith } 462d4bb536fSBarry Smith if (nout) *nout = n; 463d4bb536fSBarry Smith } else { 464d4bb536fSBarry Smith if (idxout) { 465d4bb536fSBarry Smith for (i=0; i<n; i++) { 466d4bb536fSBarry Smith if (idx[i] < 0) continue; 467d4bb536fSBarry Smith if (idx[i] < start) continue; 468d4bb536fSBarry Smith if (idx[i] > end) continue; 469d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 470d4bb536fSBarry Smith if (tmp < 0) continue; 471d4bb536fSBarry Smith idxout[nf++] = tmp; 472d4bb536fSBarry Smith } 473d4bb536fSBarry Smith } else { 474d4bb536fSBarry Smith for (i=0; i<n; i++) { 475d4bb536fSBarry Smith if (idx[i] < 0) continue; 476d4bb536fSBarry Smith if (idx[i] < start) continue; 477d4bb536fSBarry Smith if (idx[i] > end) continue; 478d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 479d4bb536fSBarry Smith if (tmp < 0) continue; 480d4bb536fSBarry Smith nf++; 481d4bb536fSBarry Smith } 482d4bb536fSBarry Smith } 483d4bb536fSBarry Smith if (nout) *nout = nf; 484d4bb536fSBarry Smith } 485d4bb536fSBarry Smith 4863a40ed3dSBarry Smith PetscFunctionReturn(0); 487d4bb536fSBarry Smith } 48890f02eecSBarry Smith 4894a2ae208SSatish Balay #undef __FUNCT__ 4904a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingGetInfo" 49189d82c54SBarry Smith /*@C 49289d82c54SBarry Smith ISLocalToGlobalMappingGetInfo - Gets the neighbor information for each processor and 49389d82c54SBarry Smith each index shared by more than one processor 49489d82c54SBarry Smith 49589d82c54SBarry Smith Collective on ISLocalToGlobalMapping 49689d82c54SBarry Smith 49789d82c54SBarry Smith Input Parameters: 49889d82c54SBarry Smith . mapping - the mapping from local to global indexing 49989d82c54SBarry Smith 50089d82c54SBarry Smith Output Parameter: 50189d82c54SBarry Smith + nproc - number of processors that are connected to this one 50289d82c54SBarry Smith . proc - neighboring processors 50307b52d57SBarry Smith . numproc - number of indices for each subdomain (processor) 50407b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 50589d82c54SBarry Smith 50689d82c54SBarry Smith Level: advanced 50789d82c54SBarry Smith 508273d9f13SBarry Smith Concepts: mapping^local to global 50989d82c54SBarry Smith 51007b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 51107b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo() 51289d82c54SBarry Smith @*/ 5130c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 51489d82c54SBarry Smith { 5156849ba73SBarry Smith PetscErrorCode ierr; 51697f1f81fSBarry Smith PetscMPIInt size,rank,tag1,tag2,tag3,*len,*source,imdex; 51732dcc486SBarry Smith PetscInt i,n = mapping->n,Ng,ng,max = 0,*lindices = mapping->indices; 51832dcc486SBarry Smith PetscInt *nprocs,*owner,nsends,*sends,j,*starts,nmax,nrecvs,*recvs,proc; 51997f1f81fSBarry Smith PetscInt cnt,scale,*ownedsenders,*nownedsenders,rstart,nowned; 52032dcc486SBarry Smith PetscInt node,nownedm,nt,*sends2,nsends2,*starts2,*lens2,*dest,nrecvs2,*starts3,*recvs2,k,*bprocs,*tmp; 52132dcc486SBarry Smith PetscInt first_procs,first_numprocs,*first_indices; 52289d82c54SBarry Smith MPI_Request *recv_waits,*send_waits; 52330dcb7c9SBarry Smith MPI_Status recv_status,*send_status,*recv_statuses; 52489d82c54SBarry Smith MPI_Comm comm = mapping->comm; 52507b52d57SBarry Smith PetscTruth debug = PETSC_FALSE; 52689d82c54SBarry Smith 52789d82c54SBarry Smith PetscFunctionBegin; 52824cf384cSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 52924cf384cSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 53024cf384cSBarry Smith if (size == 1) { 53124cf384cSBarry Smith *nproc = 0; 53224cf384cSBarry Smith *procs = PETSC_NULL; 53332dcc486SBarry Smith ierr = PetscMalloc(sizeof(PetscInt),numprocs);CHKERRQ(ierr); 5341e2105dcSBarry Smith (*numprocs)[0] = 0; 53532dcc486SBarry Smith ierr = PetscMalloc(sizeof(PetscInt*),indices);CHKERRQ(ierr); 5361e2105dcSBarry Smith (*indices)[0] = PETSC_NULL; 53724cf384cSBarry Smith PetscFunctionReturn(0); 53824cf384cSBarry Smith } 53924cf384cSBarry Smith 540b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-islocaltoglobalmappinggetinfo_debug",&debug);CHKERRQ(ierr); 54107b52d57SBarry Smith 5423677ff5aSBarry Smith /* 5433677ff5aSBarry Smith Notes on ISLocalToGlobalMappingGetInfo 5443677ff5aSBarry Smith 5453677ff5aSBarry Smith globally owned node - the nodes that have been assigned to this processor in global 5463677ff5aSBarry Smith numbering, just for this routine. 5473677ff5aSBarry Smith 5483677ff5aSBarry Smith nontrivial globally owned node - node assigned to this processor that is on a subdomain 5493677ff5aSBarry Smith boundary (i.e. is has more than one local owner) 5503677ff5aSBarry Smith 5513677ff5aSBarry Smith locally owned node - node that exists on this processors subdomain 5523677ff5aSBarry Smith 5533677ff5aSBarry Smith nontrivial locally owned node - node that is not in the interior (i.e. has more than one 5543677ff5aSBarry Smith local subdomain 5553677ff5aSBarry Smith */ 55624cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag1);CHKERRQ(ierr); 55724cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag2);CHKERRQ(ierr); 55824cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag3);CHKERRQ(ierr); 55989d82c54SBarry Smith 56089d82c54SBarry Smith for (i=0; i<n; i++) { 56189d82c54SBarry Smith if (lindices[i] > max) max = lindices[i]; 56289d82c54SBarry Smith } 56332dcc486SBarry Smith ierr = MPI_Allreduce(&max,&Ng,1,MPIU_INT,MPI_MAX,comm);CHKERRQ(ierr); 56478058e43SBarry Smith Ng++; 56589d82c54SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 56689d82c54SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 567bc8ff85bSBarry Smith scale = Ng/size + 1; 568a2e34c3dSBarry Smith ng = scale; if (rank == size-1) ng = Ng - scale*(size-1); ng = PetscMax(1,ng); 569caba0dd0SBarry Smith rstart = scale*rank; 57089d82c54SBarry Smith 57189d82c54SBarry Smith /* determine ownership ranges of global indices */ 5727c334f02SBarry Smith ierr = PetscMalloc(2*size*sizeof(PetscInt),&nprocs);CHKERRQ(ierr); 57332dcc486SBarry Smith ierr = PetscMemzero(nprocs,2*size*sizeof(PetscInt));CHKERRQ(ierr); 57489d82c54SBarry Smith 57589d82c54SBarry Smith /* determine owners of each local node */ 5767c334f02SBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&owner);CHKERRQ(ierr); 57789d82c54SBarry Smith for (i=0; i<n; i++) { 5783677ff5aSBarry Smith proc = lindices[i]/scale; /* processor that globally owns this index */ 57927c402fcSBarry Smith nprocs[2*proc+1] = 1; /* processor globally owns at least one of ours */ 5803677ff5aSBarry Smith owner[i] = proc; 58127c402fcSBarry Smith nprocs[2*proc]++; /* count of how many that processor globally owns of ours */ 58289d82c54SBarry Smith } 58327c402fcSBarry Smith nsends = 0; for (i=0; i<size; i++) nsends += nprocs[2*i+1]; 58463ba0a88SBarry Smith ierr = PetscLogInfo((0,"ISLocalToGlobalMappingGetInfo: Number of global owners for my local data %d\n",nsends));CHKERRQ(ierr); 58589d82c54SBarry Smith 58689d82c54SBarry Smith /* inform other processors of number of messages and max length*/ 58727c402fcSBarry Smith ierr = PetscMaxSum(comm,nprocs,&nmax,&nrecvs);CHKERRQ(ierr); 58863ba0a88SBarry Smith ierr = PetscLogInfo((0,"ISLocalToGlobalMappingGetInfo: Number of local owners for my global data %d\n",nrecvs));CHKERRQ(ierr); 58989d82c54SBarry Smith 59089d82c54SBarry Smith /* post receives for owned rows */ 59132dcc486SBarry Smith ierr = PetscMalloc((2*nrecvs+1)*(nmax+1)*sizeof(PetscInt),&recvs);CHKERRQ(ierr); 592b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs+1)*sizeof(MPI_Request),&recv_waits);CHKERRQ(ierr); 59389d82c54SBarry Smith for (i=0; i<nrecvs; i++) { 59432dcc486SBarry Smith ierr = MPI_Irecv(recvs+2*nmax*i,2*nmax,MPIU_INT,MPI_ANY_SOURCE,tag1,comm,recv_waits+i);CHKERRQ(ierr); 59589d82c54SBarry Smith } 59689d82c54SBarry Smith 59789d82c54SBarry Smith /* pack messages containing lists of local nodes to owners */ 59832dcc486SBarry Smith ierr = PetscMalloc((2*n+1)*sizeof(PetscInt),&sends);CHKERRQ(ierr); 59932dcc486SBarry Smith ierr = PetscMalloc((size+1)*sizeof(PetscInt),&starts);CHKERRQ(ierr); 60089d82c54SBarry Smith starts[0] = 0; 60127c402fcSBarry Smith for (i=1; i<size; i++) { starts[i] = starts[i-1] + 2*nprocs[2*i-2];} 60289d82c54SBarry Smith for (i=0; i<n; i++) { 60389d82c54SBarry Smith sends[starts[owner[i]]++] = lindices[i]; 60430dcb7c9SBarry Smith sends[starts[owner[i]]++] = i; 60589d82c54SBarry Smith } 60689d82c54SBarry Smith ierr = PetscFree(owner);CHKERRQ(ierr); 60789d82c54SBarry Smith starts[0] = 0; 60827c402fcSBarry Smith for (i=1; i<size; i++) { starts[i] = starts[i-1] + 2*nprocs[2*i-2];} 60989d82c54SBarry Smith 61089d82c54SBarry Smith /* send the messages */ 611b0a32e0cSBarry Smith ierr = PetscMalloc((nsends+1)*sizeof(MPI_Request),&send_waits);CHKERRQ(ierr); 61232dcc486SBarry Smith ierr = PetscMalloc((nsends+1)*sizeof(PetscInt),&dest);CHKERRQ(ierr); 61389d82c54SBarry Smith cnt = 0; 61489d82c54SBarry Smith for (i=0; i<size; i++) { 61527c402fcSBarry Smith if (nprocs[2*i]) { 61632dcc486SBarry Smith ierr = MPI_Isend(sends+starts[i],2*nprocs[2*i],MPIU_INT,i,tag1,comm,send_waits+cnt);CHKERRQ(ierr); 61730dcb7c9SBarry Smith dest[cnt] = i; 61889d82c54SBarry Smith cnt++; 61989d82c54SBarry Smith } 62089d82c54SBarry Smith } 62189d82c54SBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 62289d82c54SBarry Smith 62389d82c54SBarry Smith /* wait on receives */ 62497f1f81fSBarry Smith ierr = PetscMalloc((nrecvs+1)*sizeof(PetscMPIInt),&source);CHKERRQ(ierr); 62597f1f81fSBarry Smith ierr = PetscMalloc((nrecvs+1)*sizeof(PetscMPIInt),&len);CHKERRQ(ierr); 62689d82c54SBarry Smith cnt = nrecvs; 62732dcc486SBarry Smith ierr = PetscMalloc((ng+1)*sizeof(PetscInt),&nownedsenders);CHKERRQ(ierr); 62832dcc486SBarry Smith ierr = PetscMemzero(nownedsenders,ng*sizeof(PetscInt));CHKERRQ(ierr); 62989d82c54SBarry Smith while (cnt) { 63089d82c54SBarry Smith ierr = MPI_Waitany(nrecvs,recv_waits,&imdex,&recv_status);CHKERRQ(ierr); 63189d82c54SBarry Smith /* unpack receives into our local space */ 63232dcc486SBarry Smith ierr = MPI_Get_count(&recv_status,MPIU_INT,&len[imdex]);CHKERRQ(ierr); 63389d82c54SBarry Smith source[imdex] = recv_status.MPI_SOURCE; 63430dcb7c9SBarry Smith len[imdex] = len[imdex]/2; 635caba0dd0SBarry Smith /* count how many local owners for each of my global owned indices */ 63630dcb7c9SBarry Smith for (i=0; i<len[imdex]; i++) nownedsenders[recvs[2*imdex*nmax+2*i]-rstart]++; 63789d82c54SBarry Smith cnt--; 63889d82c54SBarry Smith } 63989d82c54SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 64089d82c54SBarry Smith 64130dcb7c9SBarry Smith /* count how many globally owned indices are on an edge multiplied by how many processors own them. */ 642bc8ff85bSBarry Smith nowned = 0; 643bc8ff85bSBarry Smith nownedm = 0; 644bc8ff85bSBarry Smith for (i=0; i<ng; i++) { 645bc8ff85bSBarry Smith if (nownedsenders[i] > 1) {nownedm += nownedsenders[i]; nowned++;} 646bc8ff85bSBarry Smith } 647bc8ff85bSBarry Smith 648bc8ff85bSBarry Smith /* create single array to contain rank of all local owners of each globally owned index */ 64932dcc486SBarry Smith ierr = PetscMalloc((nownedm+1)*sizeof(PetscInt),&ownedsenders);CHKERRQ(ierr); 65032dcc486SBarry Smith ierr = PetscMalloc((ng+1)*sizeof(PetscInt),&starts);CHKERRQ(ierr); 651bc8ff85bSBarry Smith starts[0] = 0; 652bc8ff85bSBarry Smith for (i=1; i<ng; i++) { 653bc8ff85bSBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 654bc8ff85bSBarry Smith else starts[i] = starts[i-1]; 655bc8ff85bSBarry Smith } 656bc8ff85bSBarry Smith 65730dcb7c9SBarry Smith /* for each nontrival globally owned node list all arriving processors */ 658bc8ff85bSBarry Smith for (i=0; i<nrecvs; i++) { 659bc8ff85bSBarry Smith for (j=0; j<len[i]; j++) { 66030dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 661bc8ff85bSBarry Smith if (nownedsenders[node] > 1) { 662bc8ff85bSBarry Smith ownedsenders[starts[node]++] = source[i]; 663bc8ff85bSBarry Smith } 664bc8ff85bSBarry Smith } 665bc8ff85bSBarry Smith } 666bc8ff85bSBarry Smith 66707b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 66830dcb7c9SBarry Smith starts[0] = 0; 66930dcb7c9SBarry Smith for (i=1; i<ng; i++) { 67030dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 67130dcb7c9SBarry Smith else starts[i] = starts[i-1]; 67230dcb7c9SBarry Smith } 67330dcb7c9SBarry Smith for (i=0; i<ng; i++) { 67430dcb7c9SBarry Smith if (nownedsenders[i] > 1) { 67530dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] global node %d local owner processors: ",rank,i+rstart);CHKERRQ(ierr); 67630dcb7c9SBarry Smith for (j=0; j<nownedsenders[i]; j++) { 67730dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",ownedsenders[starts[i]+j]);CHKERRQ(ierr); 67830dcb7c9SBarry Smith } 67930dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 68030dcb7c9SBarry Smith } 68130dcb7c9SBarry Smith } 68230dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 68307b52d57SBarry Smith }/* ----------------------------------- */ 68430dcb7c9SBarry Smith 6853677ff5aSBarry Smith /* wait on original sends */ 6863a96401aSBarry Smith if (nsends) { 687b0a32e0cSBarry Smith ierr = PetscMalloc(nsends*sizeof(MPI_Status),&send_status);CHKERRQ(ierr); 6883a96401aSBarry Smith ierr = MPI_Waitall(nsends,send_waits,send_status);CHKERRQ(ierr); 6893a96401aSBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 6903a96401aSBarry Smith } 69189d82c54SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 6923a96401aSBarry Smith ierr = PetscFree(sends);CHKERRQ(ierr); 6933677ff5aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 6943677ff5aSBarry Smith 6953677ff5aSBarry Smith /* pack messages to send back to local owners */ 69630dcb7c9SBarry Smith starts[0] = 0; 69730dcb7c9SBarry Smith for (i=1; i<ng; i++) { 69830dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 69930dcb7c9SBarry Smith else starts[i] = starts[i-1]; 70030dcb7c9SBarry Smith } 70130dcb7c9SBarry Smith nsends2 = nrecvs; 70232dcc486SBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(PetscInt),&nprocs);CHKERRQ(ierr); /* length of each message */ 70330dcb7c9SBarry Smith for (i=0; i<nrecvs; i++) { 70430dcb7c9SBarry Smith nprocs[i] = 1; 70530dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 70630dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 70730dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 70830dcb7c9SBarry Smith nprocs[i] += 2 + nownedsenders[node]; 70930dcb7c9SBarry Smith } 71030dcb7c9SBarry Smith } 71130dcb7c9SBarry Smith } 71230dcb7c9SBarry Smith nt = 0; for (i=0; i<nsends2; i++) nt += nprocs[i]; 71332dcc486SBarry Smith ierr = PetscMalloc((nt+1)*sizeof(PetscInt),&sends2);CHKERRQ(ierr); 71432dcc486SBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(PetscInt),&starts2);CHKERRQ(ierr); 71530dcb7c9SBarry Smith starts2[0] = 0; for (i=1; i<nsends2; i++) starts2[i] = starts2[i-1] + nprocs[i-1]; 71630dcb7c9SBarry Smith /* 71730dcb7c9SBarry Smith Each message is 1 + nprocs[i] long, and consists of 71830dcb7c9SBarry Smith (0) the number of nodes being sent back 71930dcb7c9SBarry Smith (1) the local node number, 72030dcb7c9SBarry Smith (2) the number of processors sharing it, 72130dcb7c9SBarry Smith (3) the processors sharing it 72230dcb7c9SBarry Smith */ 72330dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 72430dcb7c9SBarry Smith cnt = 1; 72530dcb7c9SBarry Smith sends2[starts2[i]] = 0; 72630dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 72730dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 72830dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 72930dcb7c9SBarry Smith sends2[starts2[i]]++; 73030dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = recvs[2*i*nmax+2*j+1]; 73130dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = nownedsenders[node]; 73232dcc486SBarry Smith ierr = PetscMemcpy(&sends2[starts2[i]+cnt],&ownedsenders[starts[node]],nownedsenders[node]*sizeof(PetscInt));CHKERRQ(ierr); 73330dcb7c9SBarry Smith cnt += nownedsenders[node]; 73430dcb7c9SBarry Smith } 73530dcb7c9SBarry Smith } 73630dcb7c9SBarry Smith } 73730dcb7c9SBarry Smith 73830dcb7c9SBarry Smith /* receive the message lengths */ 73930dcb7c9SBarry Smith nrecvs2 = nsends; 74032dcc486SBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(PetscInt),&lens2);CHKERRQ(ierr); 74132dcc486SBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(PetscInt),&starts3);CHKERRQ(ierr); 742d44834fbSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(MPI_Request),&recv_waits);CHKERRQ(ierr); 74330dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 744d44834fbSBarry Smith ierr = MPI_Irecv(&lens2[i],1,MPIU_INT,dest[i],tag2,comm,recv_waits+i);CHKERRQ(ierr); 74530dcb7c9SBarry Smith } 746d44834fbSBarry Smith 7478a8e0b3aSBarry Smith /* send the message lengths */ 7488a8e0b3aSBarry Smith for (i=0; i<nsends2; i++) { 7498a8e0b3aSBarry Smith ierr = MPI_Send(&nprocs[i],1,MPIU_INT,source[i],tag2,comm);CHKERRQ(ierr); 7508a8e0b3aSBarry Smith } 7518a8e0b3aSBarry Smith 752d44834fbSBarry Smith /* wait on receives of lens */ 7530c468ba9SBarry Smith if (nrecvs2) { 7540c468ba9SBarry Smith ierr = PetscMalloc(nrecvs2*sizeof(MPI_Status),&recv_statuses);CHKERRQ(ierr); 755d44834fbSBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 756d44834fbSBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 7570c468ba9SBarry Smith } 758d44834fbSBarry Smith ierr = PetscFree(recv_waits); 759d44834fbSBarry Smith 76030dcb7c9SBarry Smith starts3[0] = 0; 761d44834fbSBarry Smith nt = 0; 76230dcb7c9SBarry Smith for (i=0; i<nrecvs2-1; i++) { 76330dcb7c9SBarry Smith starts3[i+1] = starts3[i] + lens2[i]; 764d44834fbSBarry Smith nt += lens2[i]; 76530dcb7c9SBarry Smith } 766d44834fbSBarry Smith nt += lens2[nrecvs2-1]; 767d44834fbSBarry Smith 76832dcc486SBarry Smith ierr = PetscMalloc((nt+1)*sizeof(PetscInt),&recvs2);CHKERRQ(ierr); 769b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(MPI_Request),&recv_waits);CHKERRQ(ierr); 77052b72c4aSBarry Smith for (i=0; i<nrecvs2; i++) { 77132dcc486SBarry Smith ierr = MPI_Irecv(recvs2+starts3[i],lens2[i],MPIU_INT,dest[i],tag3,comm,recv_waits+i);CHKERRQ(ierr); 77230dcb7c9SBarry Smith } 77330dcb7c9SBarry Smith 77430dcb7c9SBarry Smith /* send the messages */ 775b0a32e0cSBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(MPI_Request),&send_waits);CHKERRQ(ierr); 77630dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 77732dcc486SBarry Smith ierr = MPI_Isend(sends2+starts2[i],nprocs[i],MPIU_INT,source[i],tag3,comm,send_waits+i);CHKERRQ(ierr); 77830dcb7c9SBarry Smith } 77930dcb7c9SBarry Smith 78030dcb7c9SBarry Smith /* wait on receives */ 7810c468ba9SBarry Smith if (nrecvs2) { 7820c468ba9SBarry Smith ierr = PetscMalloc(nrecvs2*sizeof(MPI_Status),&recv_statuses);CHKERRQ(ierr); 78330dcb7c9SBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 78430dcb7c9SBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 7850c468ba9SBarry Smith } 78630dcb7c9SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 78730dcb7c9SBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 78830dcb7c9SBarry Smith 78907b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 79030dcb7c9SBarry Smith cnt = 0; 79130dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 79230dcb7c9SBarry Smith nt = recvs2[cnt++]; 79330dcb7c9SBarry Smith for (j=0; j<nt; j++) { 79430dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] local node %d number of subdomains %d: ",rank,recvs2[cnt],recvs2[cnt+1]);CHKERRQ(ierr); 79530dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 79630dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",recvs2[cnt+2+k]);CHKERRQ(ierr); 79730dcb7c9SBarry Smith } 79830dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 79930dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 80030dcb7c9SBarry Smith } 80130dcb7c9SBarry Smith } 80230dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 80307b52d57SBarry Smith } /* ----------------------------------- */ 80430dcb7c9SBarry Smith 80530dcb7c9SBarry Smith /* count number subdomains for each local node */ 80632dcc486SBarry Smith ierr = PetscMalloc(size*sizeof(PetscInt),&nprocs);CHKERRQ(ierr); 80732dcc486SBarry Smith ierr = PetscMemzero(nprocs,size*sizeof(PetscInt));CHKERRQ(ierr); 80830dcb7c9SBarry Smith cnt = 0; 80930dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 81030dcb7c9SBarry Smith nt = recvs2[cnt++]; 81130dcb7c9SBarry Smith for (j=0; j<nt; j++) { 81230dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 81330dcb7c9SBarry Smith nprocs[recvs2[cnt+2+k]]++; 81430dcb7c9SBarry Smith } 81530dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 81630dcb7c9SBarry Smith } 81730dcb7c9SBarry Smith } 81830dcb7c9SBarry Smith nt = 0; for (i=0; i<size; i++) nt += (nprocs[i] > 0); 81930dcb7c9SBarry Smith *nproc = nt; 82032dcc486SBarry Smith ierr = PetscMalloc((nt+1)*sizeof(PetscInt),procs);CHKERRQ(ierr); 82132dcc486SBarry Smith ierr = PetscMalloc((nt+1)*sizeof(PetscInt),numprocs);CHKERRQ(ierr); 82232dcc486SBarry Smith ierr = PetscMalloc((nt+1)*sizeof(PetscInt*),indices);CHKERRQ(ierr); 82332dcc486SBarry Smith ierr = PetscMalloc(size*sizeof(PetscInt),&bprocs);CHKERRQ(ierr); 82430dcb7c9SBarry Smith cnt = 0; 82530dcb7c9SBarry Smith for (i=0; i<size; i++) { 82630dcb7c9SBarry Smith if (nprocs[i] > 0) { 82730dcb7c9SBarry Smith bprocs[i] = cnt; 82830dcb7c9SBarry Smith (*procs)[cnt] = i; 82930dcb7c9SBarry Smith (*numprocs)[cnt] = nprocs[i]; 83032dcc486SBarry Smith ierr = PetscMalloc(nprocs[i]*sizeof(PetscInt),&(*indices)[cnt]);CHKERRQ(ierr); 83130dcb7c9SBarry Smith cnt++; 83230dcb7c9SBarry Smith } 83330dcb7c9SBarry Smith } 83430dcb7c9SBarry Smith 83530dcb7c9SBarry Smith /* make the list of subdomains for each nontrivial local node */ 83632dcc486SBarry Smith ierr = PetscMemzero(*numprocs,nt*sizeof(PetscInt));CHKERRQ(ierr); 83730dcb7c9SBarry Smith cnt = 0; 83830dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 83930dcb7c9SBarry Smith nt = recvs2[cnt++]; 84030dcb7c9SBarry Smith for (j=0; j<nt; j++) { 84130dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 84230dcb7c9SBarry Smith (*indices)[bprocs[recvs2[cnt+2+k]]][(*numprocs)[bprocs[recvs2[cnt+2+k]]]++] = recvs2[cnt]; 84330dcb7c9SBarry Smith } 84430dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 84530dcb7c9SBarry Smith } 84630dcb7c9SBarry Smith } 84730dcb7c9SBarry Smith ierr = PetscFree(bprocs);CHKERRQ(ierr); 84807b52d57SBarry Smith ierr = PetscFree(recvs2);CHKERRQ(ierr); 84930dcb7c9SBarry Smith 85007b52d57SBarry Smith /* sort the node indexing by their global numbers */ 85107b52d57SBarry Smith nt = *nproc; 85207b52d57SBarry Smith for (i=0; i<nt; i++) { 85332dcc486SBarry Smith ierr = PetscMalloc(((*numprocs)[i])*sizeof(PetscInt),&tmp);CHKERRQ(ierr); 85407b52d57SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 85507b52d57SBarry Smith tmp[j] = lindices[(*indices)[i][j]]; 85607b52d57SBarry Smith } 85707b52d57SBarry Smith ierr = PetscSortIntWithArray((*numprocs)[i],tmp,(*indices)[i]);CHKERRQ(ierr); 85807b52d57SBarry Smith ierr = PetscFree(tmp);CHKERRQ(ierr); 85907b52d57SBarry Smith } 86007b52d57SBarry Smith 86107b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 86230dcb7c9SBarry Smith nt = *nproc; 86330dcb7c9SBarry Smith for (i=0; i<nt; i++) { 86430dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] subdomain %d number of indices %d: ",rank,(*procs)[i],(*numprocs)[i]);CHKERRQ(ierr); 86530dcb7c9SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 86630dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",(*indices)[i][j]);CHKERRQ(ierr); 86730dcb7c9SBarry Smith } 86830dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 86930dcb7c9SBarry Smith } 87030dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 87107b52d57SBarry Smith } /* ----------------------------------- */ 87230dcb7c9SBarry Smith 87330dcb7c9SBarry Smith /* wait on sends */ 87430dcb7c9SBarry Smith if (nsends2) { 875b0a32e0cSBarry Smith ierr = PetscMalloc(nsends2*sizeof(MPI_Status),&send_status);CHKERRQ(ierr); 87630dcb7c9SBarry Smith ierr = MPI_Waitall(nsends2,send_waits,send_status);CHKERRQ(ierr); 87730dcb7c9SBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 87830dcb7c9SBarry Smith } 87930dcb7c9SBarry Smith 88030dcb7c9SBarry Smith ierr = PetscFree(starts3);CHKERRQ(ierr); 88130dcb7c9SBarry Smith ierr = PetscFree(dest);CHKERRQ(ierr); 88230dcb7c9SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 8833677ff5aSBarry Smith 884bc8ff85bSBarry Smith ierr = PetscFree(nownedsenders);CHKERRQ(ierr); 885bc8ff85bSBarry Smith ierr = PetscFree(ownedsenders);CHKERRQ(ierr); 886bc8ff85bSBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 88730dcb7c9SBarry Smith ierr = PetscFree(starts2);CHKERRQ(ierr); 88830dcb7c9SBarry Smith ierr = PetscFree(lens2);CHKERRQ(ierr); 88989d82c54SBarry Smith 89089d82c54SBarry Smith ierr = PetscFree(source);CHKERRQ(ierr); 89197f1f81fSBarry Smith ierr = PetscFree(len);CHKERRQ(ierr); 89289d82c54SBarry Smith ierr = PetscFree(recvs);CHKERRQ(ierr); 8933a96401aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 89430dcb7c9SBarry Smith ierr = PetscFree(sends2);CHKERRQ(ierr); 89524cf384cSBarry Smith 89624cf384cSBarry Smith /* put the information about myself as the first entry in the list */ 89724cf384cSBarry Smith first_procs = (*procs)[0]; 89824cf384cSBarry Smith first_numprocs = (*numprocs)[0]; 89924cf384cSBarry Smith first_indices = (*indices)[0]; 90024cf384cSBarry Smith for (i=0; i<*nproc; i++) { 90124cf384cSBarry Smith if ((*procs)[i] == rank) { 90224cf384cSBarry Smith (*procs)[0] = (*procs)[i]; 90324cf384cSBarry Smith (*numprocs)[0] = (*numprocs)[i]; 90424cf384cSBarry Smith (*indices)[0] = (*indices)[i]; 90524cf384cSBarry Smith (*procs)[i] = first_procs; 90624cf384cSBarry Smith (*numprocs)[i] = first_numprocs; 90724cf384cSBarry Smith (*indices)[i] = first_indices; 90824cf384cSBarry Smith break; 90924cf384cSBarry Smith } 91024cf384cSBarry Smith } 91189d82c54SBarry Smith PetscFunctionReturn(0); 91289d82c54SBarry Smith } 91389d82c54SBarry Smith 9144a2ae208SSatish Balay #undef __FUNCT__ 9154a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingRestoreInfo" 91607b52d57SBarry Smith /*@C 91707b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo - Frees the memory allocated by ISLocalToGlobalMappingGetInfo() 91889d82c54SBarry Smith 91907b52d57SBarry Smith Collective on ISLocalToGlobalMapping 92007b52d57SBarry Smith 92107b52d57SBarry Smith Input Parameters: 92207b52d57SBarry Smith . mapping - the mapping from local to global indexing 92307b52d57SBarry Smith 92407b52d57SBarry Smith Output Parameter: 92507b52d57SBarry Smith + nproc - number of processors that are connected to this one 92607b52d57SBarry Smith . proc - neighboring processors 92707b52d57SBarry Smith . numproc - number of indices for each processor 92807b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 92907b52d57SBarry Smith 93007b52d57SBarry Smith Level: advanced 93107b52d57SBarry Smith 93207b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 93307b52d57SBarry Smith ISLocalToGlobalMappingGetInfo() 93407b52d57SBarry Smith @*/ 9350c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISLocalToGlobalMappingRestoreInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 93607b52d57SBarry Smith { 9376849ba73SBarry Smith PetscErrorCode ierr; 93832dcc486SBarry Smith PetscInt i; 93907b52d57SBarry Smith 94007b52d57SBarry Smith PetscFunctionBegin; 94100ff320aSBarry Smith if (*procs) {ierr = PetscFree(*procs);CHKERRQ(ierr);} 94200ff320aSBarry Smith if (*numprocs) {ierr = PetscFree(*numprocs);CHKERRQ(ierr);} 94300ff320aSBarry Smith if (*indices) { 94400ff320aSBarry Smith if ((*indices)[0]) {ierr = PetscFree((*indices)[0]);CHKERRQ(ierr);} 94500ff320aSBarry Smith for (i=1; i<*nproc; i++) { 94624cf384cSBarry Smith if ((*indices)[i]) {ierr = PetscFree((*indices)[i]);CHKERRQ(ierr);} 94707b52d57SBarry Smith } 94807b52d57SBarry Smith ierr = PetscFree(*indices);CHKERRQ(ierr); 94924cf384cSBarry Smith } 95007b52d57SBarry Smith PetscFunctionReturn(0); 95107b52d57SBarry Smith } 95289d82c54SBarry Smith 953bc8ff85bSBarry Smith 954bc8ff85bSBarry Smith 955bc8ff85bSBarry Smith 956bc8ff85bSBarry Smith 957bc8ff85bSBarry Smith 958bc8ff85bSBarry Smith 959bc8ff85bSBarry Smith 960bc8ff85bSBarry Smith 961bc8ff85bSBarry Smith 962bc8ff85bSBarry Smith 963bc8ff85bSBarry Smith 964bc8ff85bSBarry Smith 965bc8ff85bSBarry Smith 966bc8ff85bSBarry Smith 967bc8ff85bSBarry Smith 968bc8ff85bSBarry Smith 96924cf384cSBarry Smith 970