10c735eedSKris Buschelman #define PETSCVEC_DLL 22362add9SBarry Smith 35f5f199fSBarry Smith #include "petscvec.h" /*I "petscvec.h" I*/ 47c4f633dSBarry Smith #include "private/isimpl.h" /*I "petscis.h" I*/ 52362add9SBarry Smith 60700a824SBarry Smith PetscClassId PETSCVEC_DLLEXPORT IS_LTOGM_CLASSID; 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 @*/ 270c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISLocalToGlobalMappingGetSize(ISLocalToGlobalMapping mapping,PetscInt *n) 283b9aefa3SBarry Smith { 293b9aefa3SBarry Smith PetscFunctionBegin; 300700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,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 @*/ 530c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISLocalToGlobalMappingView(ISLocalToGlobalMapping mapping,PetscViewer viewer) 545a5d4f66SBarry Smith { 5532dcc486SBarry Smith PetscInt i; 5632dcc486SBarry Smith PetscMPIInt rank; 57ace3abfcSBarry Smith PetscBool iascii; 586849ba73SBarry Smith PetscErrorCode ierr; 595a5d4f66SBarry Smith 605a5d4f66SBarry Smith PetscFunctionBegin; 610700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 623050cee2SBarry Smith if (!viewer) { 637adad957SLisandro Dalcin ierr = PetscViewerASCIIGetStdout(((PetscObject)mapping)->comm,&viewer);CHKERRQ(ierr); 643050cee2SBarry Smith } 650700a824SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 665a5d4f66SBarry Smith 677adad957SLisandro Dalcin ierr = MPI_Comm_rank(((PetscObject)mapping)->comm,&rank);CHKERRQ(ierr); 682692d6eeSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 6932077d6dSBarry Smith if (iascii) { 705a5d4f66SBarry Smith for (i=0; i<mapping->n; i++) { 71b0a32e0cSBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d] %d %d\n",rank,i,mapping->indices[i]);CHKERRQ(ierr); 726831982aSBarry Smith } 73b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 746831982aSBarry Smith } else { 75e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported for ISLocalToGlobalMapping",((PetscObject)viewer)->type_name); 765a5d4f66SBarry Smith } 775a5d4f66SBarry Smith 785a5d4f66SBarry Smith PetscFunctionReturn(0); 795a5d4f66SBarry Smith } 805a5d4f66SBarry Smith 814a2ae208SSatish Balay #undef __FUNCT__ 824a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreateIS" 831f428162SBarry Smith /*@ 842bdab257SBarry Smith ISLocalToGlobalMappingCreateIS - Creates a mapping between a local (0 to n) 852bdab257SBarry Smith ordering and a global parallel ordering. 862bdab257SBarry Smith 870f5bd95cSBarry Smith Not collective 88b9cd556bSLois Curfman McInnes 89a997ad1aSLois Curfman McInnes Input Parameter: 902bdab257SBarry Smith . is - index set containing the global numbers for each local 912bdab257SBarry Smith 92a997ad1aSLois Curfman McInnes Output Parameter: 932bdab257SBarry Smith . mapping - new mapping data structure 942bdab257SBarry Smith 95a997ad1aSLois Curfman McInnes Level: advanced 96a997ad1aSLois Curfman McInnes 97273d9f13SBarry Smith Concepts: mapping^local to global 982bdab257SBarry Smith 992bdab257SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 1002bdab257SBarry Smith @*/ 1010c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISLocalToGlobalMappingCreateIS(IS is,ISLocalToGlobalMapping *mapping) 1022bdab257SBarry Smith { 1036849ba73SBarry Smith PetscErrorCode ierr; 1045d0c19d7SBarry Smith PetscInt n; 1055d0c19d7SBarry Smith const PetscInt *indices; 1062bdab257SBarry Smith MPI_Comm comm; 1073a40ed3dSBarry Smith 1083a40ed3dSBarry Smith PetscFunctionBegin; 1090700a824SBarry Smith PetscValidHeaderSpecific(is,IS_CLASSID,1); 1104482741eSBarry Smith PetscValidPointer(mapping,2); 1112bdab257SBarry Smith 1122bdab257SBarry Smith ierr = PetscObjectGetComm((PetscObject)is,&comm);CHKERRQ(ierr); 1133b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 1142bdab257SBarry Smith ierr = ISGetIndices(is,&indices);CHKERRQ(ierr); 115d5ad8652SBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,n,indices,PETSC_COPY_VALUES,mapping);CHKERRQ(ierr); 1162bdab257SBarry Smith ierr = ISRestoreIndices(is,&indices);CHKERRQ(ierr); 1173a40ed3dSBarry Smith PetscFunctionReturn(0); 1182bdab257SBarry Smith } 1195a5d4f66SBarry Smith 120b46b645bSBarry Smith 1214a2ae208SSatish Balay #undef __FUNCT__ 1224a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreate" 123ba5bb76aSSatish Balay /*@ 12490f02eecSBarry Smith ISLocalToGlobalMappingCreate - Creates a mapping between a local (0 to n) 12590f02eecSBarry Smith ordering and a global parallel ordering. 1262362add9SBarry Smith 12789d82c54SBarry Smith Not Collective, but communicator may have more than one process 128b9cd556bSLois Curfman McInnes 1292362add9SBarry Smith Input Parameters: 13089d82c54SBarry Smith + comm - MPI communicator 13190f02eecSBarry Smith . n - the number of local elements 132d5ad8652SBarry Smith . indices - the global index for each local element 133d5ad8652SBarry Smith - mode - see PetscCopyMode 1342362add9SBarry Smith 135a997ad1aSLois Curfman McInnes Output Parameter: 13690f02eecSBarry Smith . mapping - new mapping data structure 1372362add9SBarry Smith 138a997ad1aSLois Curfman McInnes Level: advanced 139a997ad1aSLois Curfman McInnes 140273d9f13SBarry Smith Concepts: mapping^local to global 1412362add9SBarry Smith 142d5ad8652SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS() 1432362add9SBarry Smith @*/ 144d5ad8652SBarry Smith PetscErrorCode PETSCVEC_DLLEXPORT ISLocalToGlobalMappingCreate(MPI_Comm cm,PetscInt n,const PetscInt indices[],PetscCopyMode mode,ISLocalToGlobalMapping *mapping) 1452362add9SBarry Smith { 1466849ba73SBarry Smith PetscErrorCode ierr; 14732dcc486SBarry Smith PetscInt *in; 148b46b645bSBarry Smith 149b46b645bSBarry Smith PetscFunctionBegin; 15073911063SBarry Smith if (n) PetscValidIntPointer(indices,3); 1514482741eSBarry Smith PetscValidPointer(mapping,4); 152b46b645bSBarry Smith 1538e58c17dSMatthew Knepley *mapping = PETSC_NULL; 1548e58c17dSMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 1552b6de112SBarry Smith ierr = ISInitializePackage(PETSC_NULL);CHKERRQ(ierr); 1568e58c17dSMatthew Knepley #endif 1572362add9SBarry Smith 1580700a824SBarry Smith ierr = PetscHeaderCreate(*mapping,_p_ISLocalToGlobalMapping,int,IS_LTOGM_CLASSID,0,"ISLocalToGlobalMapping", 15952e6d16bSBarry Smith cm,ISLocalToGlobalMappingDestroy,ISLocalToGlobalMappingView);CHKERRQ(ierr); 160d4bb536fSBarry Smith (*mapping)->n = n; 161d4bb536fSBarry Smith /* 162d4bb536fSBarry Smith Do not create the global to local mapping. This is only created if 163d4bb536fSBarry Smith ISGlobalToLocalMapping() is called 164d4bb536fSBarry Smith */ 165d4bb536fSBarry Smith (*mapping)->globals = 0; 166d5ad8652SBarry Smith if (mode == PETSC_COPY_VALUES) { 167d5ad8652SBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&in);CHKERRQ(ierr); 168d5ad8652SBarry Smith ierr = PetscMemcpy(in,indices,n*sizeof(PetscInt));CHKERRQ(ierr); 169d5ad8652SBarry Smith ierr = PetscLogObjectMemory(*mapping,n*sizeof(PetscInt));CHKERRQ(ierr); 170d5ad8652SBarry Smith (*mapping)->indices = in; 171d5ad8652SBarry Smith } else if (mode == PETSC_OWN_POINTER) { 172d5ad8652SBarry Smith (*mapping)->indices = (PetscInt*)indices; 173d5ad8652SBarry Smith } else SETERRQ(cm,PETSC_ERR_SUP,"Cannot currently use PETSC_USE_POINTER"); 1743a40ed3dSBarry Smith PetscFunctionReturn(0); 1752362add9SBarry Smith } 1762362add9SBarry Smith 1774a2ae208SSatish Balay #undef __FUNCT__ 1784a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingBlock" 179bce096a4SSatish Balay /*@ 180323b833fSBarry Smith ISLocalToGlobalMappingBlock - Creates a blocked index version of an 181323b833fSBarry Smith ISLocalToGlobalMapping that is appropriate for MatSetLocalToGlobalMappingBlock() 182323b833fSBarry Smith and VecSetLocalToGlobalMappingBlock(). 183323b833fSBarry Smith 184323b833fSBarry Smith Not Collective, but communicator may have more than one process 185323b833fSBarry Smith 186323b833fSBarry Smith Input Parameters: 187323b833fSBarry Smith + inmap - original point-wise mapping 188323b833fSBarry Smith - bs - block size 189323b833fSBarry Smith 190323b833fSBarry Smith Output Parameter: 19169eb54c3SBarry Smith . outmap - block based mapping; the indices are relative to BLOCKS, not individual vector or matrix entries. 192323b833fSBarry Smith 193323b833fSBarry Smith Level: advanced 194323b833fSBarry Smith 195323b833fSBarry Smith Concepts: mapping^local to global 196323b833fSBarry Smith 197323b833fSBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingCreateIS() 198323b833fSBarry Smith @*/ 1990c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISLocalToGlobalMappingBlock(ISLocalToGlobalMapping inmap,PetscInt bs,ISLocalToGlobalMapping *outmap) 200323b833fSBarry Smith { 2016849ba73SBarry Smith PetscErrorCode ierr; 20232dcc486SBarry Smith PetscInt *ii,i,n; 203323b833fSBarry Smith 204323b833fSBarry Smith PetscFunctionBegin; 2050700a824SBarry Smith PetscValidHeaderSpecific(inmap,IS_LTOGM_CLASSID,1); 206ad48de64SLisandro Dalcin PetscValidPointer(outmap,1); 207323b833fSBarry Smith if (bs > 1) { 208323b833fSBarry Smith n = inmap->n/bs; 209e32f2f54SBarry Smith if (n*bs != inmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Pointwise mapping length is not divisible by block size"); 21032dcc486SBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&ii);CHKERRQ(ierr); 211323b833fSBarry Smith for (i=0; i<n; i++) { 212db032c9dSBarry Smith ii[i] = inmap->indices[bs*i]/bs; 213323b833fSBarry Smith } 214d5ad8652SBarry Smith ierr = ISLocalToGlobalMappingCreate(((PetscObject)inmap)->comm,n,ii,PETSC_OWN_POINTER,outmap);CHKERRQ(ierr); 215323b833fSBarry Smith } else { 216323b833fSBarry Smith ierr = PetscObjectReference((PetscObject)inmap);CHKERRQ(ierr); 217c3122656SLisandro Dalcin *outmap = inmap; 218323b833fSBarry Smith } 219323b833fSBarry Smith PetscFunctionReturn(0); 220323b833fSBarry Smith } 221323b833fSBarry Smith 2224a2ae208SSatish Balay #undef __FUNCT__ 2234a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingDestroy" 22490f02eecSBarry Smith /*@ 22590f02eecSBarry Smith ISLocalToGlobalMappingDestroy - Destroys a mapping between a local (0 to n) 22690f02eecSBarry Smith ordering and a global parallel ordering. 22790f02eecSBarry Smith 2280f5bd95cSBarry Smith Note Collective 229b9cd556bSLois Curfman McInnes 23090f02eecSBarry Smith Input Parameters: 23190f02eecSBarry Smith . mapping - mapping data structure 23290f02eecSBarry Smith 233a997ad1aSLois Curfman McInnes Level: advanced 234a997ad1aSLois Curfman McInnes 2353acfe500SLois Curfman McInnes .seealso: ISLocalToGlobalMappingCreate() 23690f02eecSBarry Smith @*/ 2370c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping mapping) 23890f02eecSBarry Smith { 239dfbe8321SBarry Smith PetscErrorCode ierr; 2403a40ed3dSBarry Smith PetscFunctionBegin; 2410700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 2427adad957SLisandro Dalcin if (--((PetscObject)mapping)->refct > 0) PetscFunctionReturn(0); 243606d414cSSatish Balay ierr = PetscFree(mapping->indices);CHKERRQ(ierr); 24405b42c5fSBarry Smith ierr = PetscFree(mapping->globals);CHKERRQ(ierr); 245d38fa0fbSBarry Smith ierr = PetscHeaderDestroy(mapping);CHKERRQ(ierr); 2463a40ed3dSBarry Smith PetscFunctionReturn(0); 24790f02eecSBarry Smith } 24890f02eecSBarry Smith 2494a2ae208SSatish Balay #undef __FUNCT__ 2504a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingApplyIS" 25190f02eecSBarry Smith /*@ 2523acfe500SLois Curfman McInnes ISLocalToGlobalMappingApplyIS - Creates from an IS in the local numbering 2533acfe500SLois Curfman McInnes a new index set using the global numbering defined in an ISLocalToGlobalMapping 2543acfe500SLois Curfman McInnes context. 25590f02eecSBarry Smith 256b9cd556bSLois Curfman McInnes Not collective 257b9cd556bSLois Curfman McInnes 25890f02eecSBarry Smith Input Parameters: 259b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 260b9cd556bSLois Curfman McInnes - is - index set in local numbering 26190f02eecSBarry Smith 26290f02eecSBarry Smith Output Parameters: 26390f02eecSBarry Smith . newis - index set in global numbering 26490f02eecSBarry Smith 265a997ad1aSLois Curfman McInnes Level: advanced 266a997ad1aSLois Curfman McInnes 267273d9f13SBarry Smith Concepts: mapping^local to global 2683acfe500SLois Curfman McInnes 26990f02eecSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 270d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy(), ISGlobalToLocalMappingApply() 27190f02eecSBarry Smith @*/ 2720c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping mapping,IS is,IS *newis) 27390f02eecSBarry Smith { 2746849ba73SBarry Smith PetscErrorCode ierr; 2755d0c19d7SBarry Smith PetscInt n,i,*idxmap,*idxout,Nmax = mapping->n; 2765d0c19d7SBarry Smith const PetscInt *idxin; 2773a40ed3dSBarry Smith 2783a40ed3dSBarry Smith PetscFunctionBegin; 2790700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 2800700a824SBarry Smith PetscValidHeaderSpecific(is,IS_CLASSID,2); 2814482741eSBarry Smith PetscValidPointer(newis,3); 28290f02eecSBarry Smith 2833b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 28490f02eecSBarry Smith ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 28590f02eecSBarry Smith idxmap = mapping->indices; 28690f02eecSBarry Smith 2877c334f02SBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&idxout);CHKERRQ(ierr); 28890f02eecSBarry Smith for (i=0; i<n; i++) { 289e32f2f54SBarry Smith if (idxin[i] >= Nmax) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local index %d too large %d (max) at %d",idxin[i],Nmax-1,i); 29090f02eecSBarry Smith idxout[i] = idxmap[idxin[i]]; 29190f02eecSBarry Smith } 2923b9aefa3SBarry Smith ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 29370b3c8c7SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxout,PETSC_OWN_POINTER,newis);CHKERRQ(ierr); 2943a40ed3dSBarry Smith PetscFunctionReturn(0); 29590f02eecSBarry Smith } 29690f02eecSBarry Smith 29789d82c54SBarry Smith /*MC 2983acfe500SLois Curfman McInnes ISLocalToGlobalMappingApply - Takes a list of integers in a local numbering 2993acfe500SLois Curfman McInnes and converts them to the global numbering. 30090f02eecSBarry Smith 301eca87e8dSBarry Smith Synopsis: 302eca87e8dSBarry Smith PetscErrorCode ISLocalToGlobalMappingApply(ISLocalToGlobalMapping mapping,int N,int in[],int out[]) 303eca87e8dSBarry Smith 304b9cd556bSLois Curfman McInnes Not collective 305b9cd556bSLois Curfman McInnes 306bb25748dSBarry Smith Input Parameters: 307b9cd556bSLois Curfman McInnes + mapping - the local to global mapping context 308bb25748dSBarry Smith . N - number of integers 309b9cd556bSLois Curfman McInnes - in - input indices in local numbering 310bb25748dSBarry Smith 311bb25748dSBarry Smith Output Parameter: 312bb25748dSBarry Smith . out - indices in global numbering 313bb25748dSBarry Smith 314b9cd556bSLois Curfman McInnes Notes: 315b9cd556bSLois Curfman McInnes The in and out array parameters may be identical. 316d4bb536fSBarry Smith 317a997ad1aSLois Curfman McInnes Level: advanced 318a997ad1aSLois Curfman McInnes 319bb25748dSBarry Smith .seealso: ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 3200752156aSBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 321d4bb536fSBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 322bb25748dSBarry Smith 323273d9f13SBarry Smith Concepts: mapping^local to global 324d4bb536fSBarry Smith 32589d82c54SBarry Smith M*/ 326d4bb536fSBarry Smith 327d4bb536fSBarry Smith /* -----------------------------------------------------------------------------------------*/ 328d4bb536fSBarry Smith 3294a2ae208SSatish Balay #undef __FUNCT__ 3304a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingSetUp_Private" 331d4bb536fSBarry Smith /* 332d4bb536fSBarry Smith Creates the global fields in the ISLocalToGlobalMapping structure 333d4bb536fSBarry Smith */ 3346849ba73SBarry Smith static PetscErrorCode ISGlobalToLocalMappingSetUp_Private(ISLocalToGlobalMapping mapping) 335d4bb536fSBarry Smith { 3366849ba73SBarry Smith PetscErrorCode ierr; 33732dcc486SBarry Smith PetscInt i,*idx = mapping->indices,n = mapping->n,end,start,*globals; 338d4bb536fSBarry Smith 3393a40ed3dSBarry Smith PetscFunctionBegin; 340d4bb536fSBarry Smith end = 0; 341d4bb536fSBarry Smith start = 100000000; 342d4bb536fSBarry Smith 343d4bb536fSBarry Smith for (i=0; i<n; i++) { 344d4bb536fSBarry Smith if (idx[i] < 0) continue; 345d4bb536fSBarry Smith if (idx[i] < start) start = idx[i]; 346d4bb536fSBarry Smith if (idx[i] > end) end = idx[i]; 347d4bb536fSBarry Smith } 348d4bb536fSBarry Smith if (start > end) {start = 0; end = -1;} 349d4bb536fSBarry Smith mapping->globalstart = start; 350d4bb536fSBarry Smith mapping->globalend = end; 351d4bb536fSBarry Smith 35232dcc486SBarry Smith ierr = PetscMalloc((end-start+2)*sizeof(PetscInt),&globals);CHKERRQ(ierr); 353b0a32e0cSBarry Smith mapping->globals = globals; 354d4bb536fSBarry Smith for (i=0; i<end-start+1; i++) { 355d4bb536fSBarry Smith globals[i] = -1; 356d4bb536fSBarry Smith } 357d4bb536fSBarry Smith for (i=0; i<n; i++) { 358d4bb536fSBarry Smith if (idx[i] < 0) continue; 359d4bb536fSBarry Smith globals[idx[i] - start] = i; 360d4bb536fSBarry Smith } 361d4bb536fSBarry Smith 36252e6d16bSBarry Smith ierr = PetscLogObjectMemory(mapping,(end-start+1)*sizeof(PetscInt));CHKERRQ(ierr); 3633a40ed3dSBarry Smith PetscFunctionReturn(0); 364d4bb536fSBarry Smith } 365d4bb536fSBarry Smith 3664a2ae208SSatish Balay #undef __FUNCT__ 3674a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingApply" 368d4bb536fSBarry Smith /*@ 369a997ad1aSLois Curfman McInnes ISGlobalToLocalMappingApply - Provides the local numbering for a list of integers 370a997ad1aSLois Curfman McInnes specified with a global numbering. 371d4bb536fSBarry Smith 372b9cd556bSLois Curfman McInnes Not collective 373b9cd556bSLois Curfman McInnes 374d4bb536fSBarry Smith Input Parameters: 375b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 376d4bb536fSBarry Smith . type - IS_GTOLM_MASK - replaces global indices with no local value with -1 377d4bb536fSBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 378d4bb536fSBarry Smith . n - number of global indices to map 379b9cd556bSLois Curfman McInnes - idx - global indices to map 380d4bb536fSBarry Smith 381d4bb536fSBarry Smith Output Parameters: 382b9cd556bSLois Curfman McInnes + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 383b9cd556bSLois Curfman McInnes - idxout - local index of each global index, one must pass in an array long enough 384e182c471SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApply() with 385e182c471SBarry Smith idxout == PETSC_NULL to determine the required length (returned in nout) 386e182c471SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApply() 387e182c471SBarry Smith a second time to set the values. 388d4bb536fSBarry Smith 389b9cd556bSLois Curfman McInnes Notes: 390b9cd556bSLois Curfman McInnes Either nout or idxout may be PETSC_NULL. idx and idxout may be identical. 391d4bb536fSBarry Smith 3920f5bd95cSBarry Smith This is not scalable in memory usage. Each processor requires O(Nglobal) size 3930f5bd95cSBarry Smith array to compute these. 3940f5bd95cSBarry Smith 395a997ad1aSLois Curfman McInnes Level: advanced 396a997ad1aSLois Curfman McInnes 397273d9f13SBarry Smith Concepts: mapping^global to local 398d4bb536fSBarry Smith 399d4bb536fSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 400d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy() 401d4bb536fSBarry Smith @*/ 4020c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISGlobalToLocalMappingApply(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, 40332dcc486SBarry Smith PetscInt n,const PetscInt idx[],PetscInt *nout,PetscInt idxout[]) 404d4bb536fSBarry Smith { 40532dcc486SBarry Smith PetscInt i,*globals,nf = 0,tmp,start,end; 4066849ba73SBarry Smith PetscErrorCode ierr; 407d4bb536fSBarry Smith 4083a40ed3dSBarry Smith PetscFunctionBegin; 4090700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 410d4bb536fSBarry Smith if (!mapping->globals) { 411d4bb536fSBarry Smith ierr = ISGlobalToLocalMappingSetUp_Private(mapping);CHKERRQ(ierr); 412d4bb536fSBarry Smith } 413d4bb536fSBarry Smith globals = mapping->globals; 414d4bb536fSBarry Smith start = mapping->globalstart; 415d4bb536fSBarry Smith end = mapping->globalend; 416d4bb536fSBarry Smith 417d4bb536fSBarry Smith if (type == IS_GTOLM_MASK) { 418d4bb536fSBarry Smith if (idxout) { 419d4bb536fSBarry Smith for (i=0; i<n; i++) { 420d4bb536fSBarry Smith if (idx[i] < 0) idxout[i] = idx[i]; 421d4bb536fSBarry Smith else if (idx[i] < start) idxout[i] = -1; 422d4bb536fSBarry Smith else if (idx[i] > end) idxout[i] = -1; 423d4bb536fSBarry Smith else idxout[i] = globals[idx[i] - start]; 424d4bb536fSBarry Smith } 425d4bb536fSBarry Smith } 426d4bb536fSBarry Smith if (nout) *nout = n; 427d4bb536fSBarry Smith } else { 428d4bb536fSBarry Smith if (idxout) { 429d4bb536fSBarry Smith for (i=0; i<n; i++) { 430d4bb536fSBarry Smith if (idx[i] < 0) continue; 431d4bb536fSBarry Smith if (idx[i] < start) continue; 432d4bb536fSBarry Smith if (idx[i] > end) continue; 433d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 434d4bb536fSBarry Smith if (tmp < 0) continue; 435d4bb536fSBarry Smith idxout[nf++] = tmp; 436d4bb536fSBarry Smith } 437d4bb536fSBarry Smith } else { 438d4bb536fSBarry Smith for (i=0; i<n; i++) { 439d4bb536fSBarry Smith if (idx[i] < 0) continue; 440d4bb536fSBarry Smith if (idx[i] < start) continue; 441d4bb536fSBarry Smith if (idx[i] > end) continue; 442d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 443d4bb536fSBarry Smith if (tmp < 0) continue; 444d4bb536fSBarry Smith nf++; 445d4bb536fSBarry Smith } 446d4bb536fSBarry Smith } 447d4bb536fSBarry Smith if (nout) *nout = nf; 448d4bb536fSBarry Smith } 449d4bb536fSBarry Smith 4503a40ed3dSBarry Smith PetscFunctionReturn(0); 451d4bb536fSBarry Smith } 45290f02eecSBarry Smith 4534a2ae208SSatish Balay #undef __FUNCT__ 4544a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingGetInfo" 45589d82c54SBarry Smith /*@C 45689d82c54SBarry Smith ISLocalToGlobalMappingGetInfo - Gets the neighbor information for each processor and 45789d82c54SBarry Smith each index shared by more than one processor 45889d82c54SBarry Smith 45989d82c54SBarry Smith Collective on ISLocalToGlobalMapping 46089d82c54SBarry Smith 46189d82c54SBarry Smith Input Parameters: 46289d82c54SBarry Smith . mapping - the mapping from local to global indexing 46389d82c54SBarry Smith 46489d82c54SBarry Smith Output Parameter: 46589d82c54SBarry Smith + nproc - number of processors that are connected to this one 46689d82c54SBarry Smith . proc - neighboring processors 46707b52d57SBarry Smith . numproc - number of indices for each subdomain (processor) 4683463a7baSJed Brown - indices - indices of nodes (in local numbering) shared with neighbors (sorted by global numbering) 46989d82c54SBarry Smith 47089d82c54SBarry Smith Level: advanced 47189d82c54SBarry Smith 472273d9f13SBarry Smith Concepts: mapping^local to global 47389d82c54SBarry Smith 4742cfcea29SBarry Smith Fortran Usage: 4752cfcea29SBarry Smith $ ISLocalToGlobalMpngGetInfoSize(ISLocalToGlobalMapping,PetscInt nproc,PetscInt numprocmax,ierr) followed by 4762cfcea29SBarry Smith $ ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping,PetscInt nproc, PetscInt procs[nproc],PetscInt numprocs[nproc], 4772cfcea29SBarry Smith PetscInt indices[nproc][numprocmax],ierr) 4782cfcea29SBarry Smith There is no ISLocalToGlobalMappingRestoreInfo() in Fortran. You must make sure that procs[], numprocs[] and 4792cfcea29SBarry Smith indices[][] are large enough arrays, either by allocating them dynamically or defining static ones large enough. 4802cfcea29SBarry Smith 4812cfcea29SBarry Smith 48207b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 48307b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo() 48489d82c54SBarry Smith @*/ 4850c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 48689d82c54SBarry Smith { 4876849ba73SBarry Smith PetscErrorCode ierr; 48897f1f81fSBarry Smith PetscMPIInt size,rank,tag1,tag2,tag3,*len,*source,imdex; 48932dcc486SBarry Smith PetscInt i,n = mapping->n,Ng,ng,max = 0,*lindices = mapping->indices; 49032dcc486SBarry Smith PetscInt *nprocs,*owner,nsends,*sends,j,*starts,nmax,nrecvs,*recvs,proc; 49197f1f81fSBarry Smith PetscInt cnt,scale,*ownedsenders,*nownedsenders,rstart,nowned; 49232dcc486SBarry Smith PetscInt node,nownedm,nt,*sends2,nsends2,*starts2,*lens2,*dest,nrecvs2,*starts3,*recvs2,k,*bprocs,*tmp; 49332dcc486SBarry Smith PetscInt first_procs,first_numprocs,*first_indices; 49489d82c54SBarry Smith MPI_Request *recv_waits,*send_waits; 49530dcb7c9SBarry Smith MPI_Status recv_status,*send_status,*recv_statuses; 4967adad957SLisandro Dalcin MPI_Comm comm = ((PetscObject)mapping)->comm; 497ace3abfcSBarry Smith PetscBool debug = PETSC_FALSE; 49889d82c54SBarry Smith 49989d82c54SBarry Smith PetscFunctionBegin; 5000700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 50124cf384cSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 50224cf384cSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 50324cf384cSBarry Smith if (size == 1) { 50424cf384cSBarry Smith *nproc = 0; 50524cf384cSBarry Smith *procs = PETSC_NULL; 50632dcc486SBarry Smith ierr = PetscMalloc(sizeof(PetscInt),numprocs);CHKERRQ(ierr); 5071e2105dcSBarry Smith (*numprocs)[0] = 0; 50832dcc486SBarry Smith ierr = PetscMalloc(sizeof(PetscInt*),indices);CHKERRQ(ierr); 5091e2105dcSBarry Smith (*indices)[0] = PETSC_NULL; 51024cf384cSBarry Smith PetscFunctionReturn(0); 51124cf384cSBarry Smith } 51224cf384cSBarry Smith 513*acfcf0e5SJed Brown ierr = PetscOptionsGetBool(PETSC_NULL,"-islocaltoglobalmappinggetinfo_debug",&debug,PETSC_NULL);CHKERRQ(ierr); 51407b52d57SBarry Smith 5153677ff5aSBarry Smith /* 5163677ff5aSBarry Smith Notes on ISLocalToGlobalMappingGetInfo 5173677ff5aSBarry Smith 5183677ff5aSBarry Smith globally owned node - the nodes that have been assigned to this processor in global 5193677ff5aSBarry Smith numbering, just for this routine. 5203677ff5aSBarry Smith 5213677ff5aSBarry Smith nontrivial globally owned node - node assigned to this processor that is on a subdomain 5223677ff5aSBarry Smith boundary (i.e. is has more than one local owner) 5233677ff5aSBarry Smith 5243677ff5aSBarry Smith locally owned node - node that exists on this processors subdomain 5253677ff5aSBarry Smith 5263677ff5aSBarry Smith nontrivial locally owned node - node that is not in the interior (i.e. has more than one 5273677ff5aSBarry Smith local subdomain 5283677ff5aSBarry Smith */ 52924cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag1);CHKERRQ(ierr); 53024cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag2);CHKERRQ(ierr); 53124cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag3);CHKERRQ(ierr); 53289d82c54SBarry Smith 53389d82c54SBarry Smith for (i=0; i<n; i++) { 53489d82c54SBarry Smith if (lindices[i] > max) max = lindices[i]; 53589d82c54SBarry Smith } 53632dcc486SBarry Smith ierr = MPI_Allreduce(&max,&Ng,1,MPIU_INT,MPI_MAX,comm);CHKERRQ(ierr); 53778058e43SBarry Smith Ng++; 53889d82c54SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 53989d82c54SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 540bc8ff85bSBarry Smith scale = Ng/size + 1; 541a2e34c3dSBarry Smith ng = scale; if (rank == size-1) ng = Ng - scale*(size-1); ng = PetscMax(1,ng); 542caba0dd0SBarry Smith rstart = scale*rank; 54389d82c54SBarry Smith 54489d82c54SBarry Smith /* determine ownership ranges of global indices */ 5457c334f02SBarry Smith ierr = PetscMalloc(2*size*sizeof(PetscInt),&nprocs);CHKERRQ(ierr); 54632dcc486SBarry Smith ierr = PetscMemzero(nprocs,2*size*sizeof(PetscInt));CHKERRQ(ierr); 54789d82c54SBarry Smith 54889d82c54SBarry Smith /* determine owners of each local node */ 5497c334f02SBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&owner);CHKERRQ(ierr); 55089d82c54SBarry Smith for (i=0; i<n; i++) { 5513677ff5aSBarry Smith proc = lindices[i]/scale; /* processor that globally owns this index */ 55227c402fcSBarry Smith nprocs[2*proc+1] = 1; /* processor globally owns at least one of ours */ 5533677ff5aSBarry Smith owner[i] = proc; 55427c402fcSBarry Smith nprocs[2*proc]++; /* count of how many that processor globally owns of ours */ 55589d82c54SBarry Smith } 55627c402fcSBarry Smith nsends = 0; for (i=0; i<size; i++) nsends += nprocs[2*i+1]; 5571e2582c4SBarry Smith ierr = PetscInfo1(mapping,"Number of global owners for my local data %d\n",nsends);CHKERRQ(ierr); 55889d82c54SBarry Smith 55989d82c54SBarry Smith /* inform other processors of number of messages and max length*/ 56027c402fcSBarry Smith ierr = PetscMaxSum(comm,nprocs,&nmax,&nrecvs);CHKERRQ(ierr); 5611e2582c4SBarry Smith ierr = PetscInfo1(mapping,"Number of local owners for my global data %d\n",nrecvs);CHKERRQ(ierr); 56289d82c54SBarry Smith 56389d82c54SBarry Smith /* post receives for owned rows */ 56432dcc486SBarry Smith ierr = PetscMalloc((2*nrecvs+1)*(nmax+1)*sizeof(PetscInt),&recvs);CHKERRQ(ierr); 565b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs+1)*sizeof(MPI_Request),&recv_waits);CHKERRQ(ierr); 56689d82c54SBarry Smith for (i=0; i<nrecvs; i++) { 56732dcc486SBarry Smith ierr = MPI_Irecv(recvs+2*nmax*i,2*nmax,MPIU_INT,MPI_ANY_SOURCE,tag1,comm,recv_waits+i);CHKERRQ(ierr); 56889d82c54SBarry Smith } 56989d82c54SBarry Smith 57089d82c54SBarry Smith /* pack messages containing lists of local nodes to owners */ 57132dcc486SBarry Smith ierr = PetscMalloc((2*n+1)*sizeof(PetscInt),&sends);CHKERRQ(ierr); 57232dcc486SBarry Smith ierr = PetscMalloc((size+1)*sizeof(PetscInt),&starts);CHKERRQ(ierr); 57389d82c54SBarry Smith starts[0] = 0; 57427c402fcSBarry Smith for (i=1; i<size; i++) { starts[i] = starts[i-1] + 2*nprocs[2*i-2];} 57589d82c54SBarry Smith for (i=0; i<n; i++) { 57689d82c54SBarry Smith sends[starts[owner[i]]++] = lindices[i]; 57730dcb7c9SBarry Smith sends[starts[owner[i]]++] = i; 57889d82c54SBarry Smith } 57989d82c54SBarry Smith ierr = PetscFree(owner);CHKERRQ(ierr); 58089d82c54SBarry Smith starts[0] = 0; 58127c402fcSBarry Smith for (i=1; i<size; i++) { starts[i] = starts[i-1] + 2*nprocs[2*i-2];} 58289d82c54SBarry Smith 58389d82c54SBarry Smith /* send the messages */ 584b0a32e0cSBarry Smith ierr = PetscMalloc((nsends+1)*sizeof(MPI_Request),&send_waits);CHKERRQ(ierr); 58532dcc486SBarry Smith ierr = PetscMalloc((nsends+1)*sizeof(PetscInt),&dest);CHKERRQ(ierr); 58689d82c54SBarry Smith cnt = 0; 58789d82c54SBarry Smith for (i=0; i<size; i++) { 58827c402fcSBarry Smith if (nprocs[2*i]) { 58932dcc486SBarry Smith ierr = MPI_Isend(sends+starts[i],2*nprocs[2*i],MPIU_INT,i,tag1,comm,send_waits+cnt);CHKERRQ(ierr); 59030dcb7c9SBarry Smith dest[cnt] = i; 59189d82c54SBarry Smith cnt++; 59289d82c54SBarry Smith } 59389d82c54SBarry Smith } 59489d82c54SBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 59589d82c54SBarry Smith 59689d82c54SBarry Smith /* wait on receives */ 59797f1f81fSBarry Smith ierr = PetscMalloc((nrecvs+1)*sizeof(PetscMPIInt),&source);CHKERRQ(ierr); 59897f1f81fSBarry Smith ierr = PetscMalloc((nrecvs+1)*sizeof(PetscMPIInt),&len);CHKERRQ(ierr); 59989d82c54SBarry Smith cnt = nrecvs; 60032dcc486SBarry Smith ierr = PetscMalloc((ng+1)*sizeof(PetscInt),&nownedsenders);CHKERRQ(ierr); 60132dcc486SBarry Smith ierr = PetscMemzero(nownedsenders,ng*sizeof(PetscInt));CHKERRQ(ierr); 60289d82c54SBarry Smith while (cnt) { 60389d82c54SBarry Smith ierr = MPI_Waitany(nrecvs,recv_waits,&imdex,&recv_status);CHKERRQ(ierr); 60489d82c54SBarry Smith /* unpack receives into our local space */ 60532dcc486SBarry Smith ierr = MPI_Get_count(&recv_status,MPIU_INT,&len[imdex]);CHKERRQ(ierr); 60689d82c54SBarry Smith source[imdex] = recv_status.MPI_SOURCE; 60730dcb7c9SBarry Smith len[imdex] = len[imdex]/2; 608caba0dd0SBarry Smith /* count how many local owners for each of my global owned indices */ 60930dcb7c9SBarry Smith for (i=0; i<len[imdex]; i++) nownedsenders[recvs[2*imdex*nmax+2*i]-rstart]++; 61089d82c54SBarry Smith cnt--; 61189d82c54SBarry Smith } 61289d82c54SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 61389d82c54SBarry Smith 61430dcb7c9SBarry Smith /* count how many globally owned indices are on an edge multiplied by how many processors own them. */ 615bc8ff85bSBarry Smith nowned = 0; 616bc8ff85bSBarry Smith nownedm = 0; 617bc8ff85bSBarry Smith for (i=0; i<ng; i++) { 618bc8ff85bSBarry Smith if (nownedsenders[i] > 1) {nownedm += nownedsenders[i]; nowned++;} 619bc8ff85bSBarry Smith } 620bc8ff85bSBarry Smith 621bc8ff85bSBarry Smith /* create single array to contain rank of all local owners of each globally owned index */ 62232dcc486SBarry Smith ierr = PetscMalloc((nownedm+1)*sizeof(PetscInt),&ownedsenders);CHKERRQ(ierr); 62332dcc486SBarry Smith ierr = PetscMalloc((ng+1)*sizeof(PetscInt),&starts);CHKERRQ(ierr); 624bc8ff85bSBarry Smith starts[0] = 0; 625bc8ff85bSBarry Smith for (i=1; i<ng; i++) { 626bc8ff85bSBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 627bc8ff85bSBarry Smith else starts[i] = starts[i-1]; 628bc8ff85bSBarry Smith } 629bc8ff85bSBarry Smith 63030dcb7c9SBarry Smith /* for each nontrival globally owned node list all arriving processors */ 631bc8ff85bSBarry Smith for (i=0; i<nrecvs; i++) { 632bc8ff85bSBarry Smith for (j=0; j<len[i]; j++) { 63330dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 634bc8ff85bSBarry Smith if (nownedsenders[node] > 1) { 635bc8ff85bSBarry Smith ownedsenders[starts[node]++] = source[i]; 636bc8ff85bSBarry Smith } 637bc8ff85bSBarry Smith } 638bc8ff85bSBarry Smith } 639bc8ff85bSBarry Smith 64007b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 64130dcb7c9SBarry Smith starts[0] = 0; 64230dcb7c9SBarry Smith for (i=1; i<ng; i++) { 64330dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 64430dcb7c9SBarry Smith else starts[i] = starts[i-1]; 64530dcb7c9SBarry Smith } 64630dcb7c9SBarry Smith for (i=0; i<ng; i++) { 64730dcb7c9SBarry Smith if (nownedsenders[i] > 1) { 64830dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] global node %d local owner processors: ",rank,i+rstart);CHKERRQ(ierr); 64930dcb7c9SBarry Smith for (j=0; j<nownedsenders[i]; j++) { 65030dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",ownedsenders[starts[i]+j]);CHKERRQ(ierr); 65130dcb7c9SBarry Smith } 65230dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 65330dcb7c9SBarry Smith } 65430dcb7c9SBarry Smith } 65530dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 65607b52d57SBarry Smith }/* ----------------------------------- */ 65730dcb7c9SBarry Smith 6583677ff5aSBarry Smith /* wait on original sends */ 6593a96401aSBarry Smith if (nsends) { 660b0a32e0cSBarry Smith ierr = PetscMalloc(nsends*sizeof(MPI_Status),&send_status);CHKERRQ(ierr); 6613a96401aSBarry Smith ierr = MPI_Waitall(nsends,send_waits,send_status);CHKERRQ(ierr); 6623a96401aSBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 6633a96401aSBarry Smith } 66489d82c54SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 6653a96401aSBarry Smith ierr = PetscFree(sends);CHKERRQ(ierr); 6663677ff5aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 6673677ff5aSBarry Smith 6683677ff5aSBarry Smith /* pack messages to send back to local owners */ 66930dcb7c9SBarry Smith starts[0] = 0; 67030dcb7c9SBarry Smith for (i=1; i<ng; i++) { 67130dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 67230dcb7c9SBarry Smith else starts[i] = starts[i-1]; 67330dcb7c9SBarry Smith } 67430dcb7c9SBarry Smith nsends2 = nrecvs; 67532dcc486SBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(PetscInt),&nprocs);CHKERRQ(ierr); /* length of each message */ 67630dcb7c9SBarry Smith for (i=0; i<nrecvs; i++) { 67730dcb7c9SBarry Smith nprocs[i] = 1; 67830dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 67930dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 68030dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 68130dcb7c9SBarry Smith nprocs[i] += 2 + nownedsenders[node]; 68230dcb7c9SBarry Smith } 68330dcb7c9SBarry Smith } 68430dcb7c9SBarry Smith } 68530dcb7c9SBarry Smith nt = 0; for (i=0; i<nsends2; i++) nt += nprocs[i]; 68632dcc486SBarry Smith ierr = PetscMalloc((nt+1)*sizeof(PetscInt),&sends2);CHKERRQ(ierr); 68732dcc486SBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(PetscInt),&starts2);CHKERRQ(ierr); 68830dcb7c9SBarry Smith starts2[0] = 0; for (i=1; i<nsends2; i++) starts2[i] = starts2[i-1] + nprocs[i-1]; 68930dcb7c9SBarry Smith /* 69030dcb7c9SBarry Smith Each message is 1 + nprocs[i] long, and consists of 69130dcb7c9SBarry Smith (0) the number of nodes being sent back 69230dcb7c9SBarry Smith (1) the local node number, 69330dcb7c9SBarry Smith (2) the number of processors sharing it, 69430dcb7c9SBarry Smith (3) the processors sharing it 69530dcb7c9SBarry Smith */ 69630dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 69730dcb7c9SBarry Smith cnt = 1; 69830dcb7c9SBarry Smith sends2[starts2[i]] = 0; 69930dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 70030dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 70130dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 70230dcb7c9SBarry Smith sends2[starts2[i]]++; 70330dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = recvs[2*i*nmax+2*j+1]; 70430dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = nownedsenders[node]; 70532dcc486SBarry Smith ierr = PetscMemcpy(&sends2[starts2[i]+cnt],&ownedsenders[starts[node]],nownedsenders[node]*sizeof(PetscInt));CHKERRQ(ierr); 70630dcb7c9SBarry Smith cnt += nownedsenders[node]; 70730dcb7c9SBarry Smith } 70830dcb7c9SBarry Smith } 70930dcb7c9SBarry Smith } 71030dcb7c9SBarry Smith 71130dcb7c9SBarry Smith /* receive the message lengths */ 71230dcb7c9SBarry Smith nrecvs2 = nsends; 71332dcc486SBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(PetscInt),&lens2);CHKERRQ(ierr); 71432dcc486SBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(PetscInt),&starts3);CHKERRQ(ierr); 715d44834fbSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(MPI_Request),&recv_waits);CHKERRQ(ierr); 71630dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 717d44834fbSBarry Smith ierr = MPI_Irecv(&lens2[i],1,MPIU_INT,dest[i],tag2,comm,recv_waits+i);CHKERRQ(ierr); 71830dcb7c9SBarry Smith } 719d44834fbSBarry Smith 7208a8e0b3aSBarry Smith /* send the message lengths */ 7218a8e0b3aSBarry Smith for (i=0; i<nsends2; i++) { 7228a8e0b3aSBarry Smith ierr = MPI_Send(&nprocs[i],1,MPIU_INT,source[i],tag2,comm);CHKERRQ(ierr); 7238a8e0b3aSBarry Smith } 7248a8e0b3aSBarry Smith 725d44834fbSBarry Smith /* wait on receives of lens */ 7260c468ba9SBarry Smith if (nrecvs2) { 7270c468ba9SBarry Smith ierr = PetscMalloc(nrecvs2*sizeof(MPI_Status),&recv_statuses);CHKERRQ(ierr); 728d44834fbSBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 729d44834fbSBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 7300c468ba9SBarry Smith } 731d44834fbSBarry Smith ierr = PetscFree(recv_waits); 732d44834fbSBarry Smith 73330dcb7c9SBarry Smith starts3[0] = 0; 734d44834fbSBarry Smith nt = 0; 73530dcb7c9SBarry Smith for (i=0; i<nrecvs2-1; i++) { 73630dcb7c9SBarry Smith starts3[i+1] = starts3[i] + lens2[i]; 737d44834fbSBarry Smith nt += lens2[i]; 73830dcb7c9SBarry Smith } 739d44834fbSBarry Smith nt += lens2[nrecvs2-1]; 740d44834fbSBarry Smith 74132dcc486SBarry Smith ierr = PetscMalloc((nt+1)*sizeof(PetscInt),&recvs2);CHKERRQ(ierr); 742b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(MPI_Request),&recv_waits);CHKERRQ(ierr); 74352b72c4aSBarry Smith for (i=0; i<nrecvs2; i++) { 74432dcc486SBarry Smith ierr = MPI_Irecv(recvs2+starts3[i],lens2[i],MPIU_INT,dest[i],tag3,comm,recv_waits+i);CHKERRQ(ierr); 74530dcb7c9SBarry Smith } 74630dcb7c9SBarry Smith 74730dcb7c9SBarry Smith /* send the messages */ 748b0a32e0cSBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(MPI_Request),&send_waits);CHKERRQ(ierr); 74930dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 75032dcc486SBarry Smith ierr = MPI_Isend(sends2+starts2[i],nprocs[i],MPIU_INT,source[i],tag3,comm,send_waits+i);CHKERRQ(ierr); 75130dcb7c9SBarry Smith } 75230dcb7c9SBarry Smith 75330dcb7c9SBarry Smith /* wait on receives */ 7540c468ba9SBarry Smith if (nrecvs2) { 7550c468ba9SBarry Smith ierr = PetscMalloc(nrecvs2*sizeof(MPI_Status),&recv_statuses);CHKERRQ(ierr); 75630dcb7c9SBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 75730dcb7c9SBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 7580c468ba9SBarry Smith } 75930dcb7c9SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 76030dcb7c9SBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 76130dcb7c9SBarry Smith 76207b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 76330dcb7c9SBarry Smith cnt = 0; 76430dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 76530dcb7c9SBarry Smith nt = recvs2[cnt++]; 76630dcb7c9SBarry Smith for (j=0; j<nt; j++) { 76730dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] local node %d number of subdomains %d: ",rank,recvs2[cnt],recvs2[cnt+1]);CHKERRQ(ierr); 76830dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 76930dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",recvs2[cnt+2+k]);CHKERRQ(ierr); 77030dcb7c9SBarry Smith } 77130dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 77230dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 77330dcb7c9SBarry Smith } 77430dcb7c9SBarry Smith } 77530dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 77607b52d57SBarry Smith } /* ----------------------------------- */ 77730dcb7c9SBarry Smith 77830dcb7c9SBarry Smith /* count number subdomains for each local node */ 77932dcc486SBarry Smith ierr = PetscMalloc(size*sizeof(PetscInt),&nprocs);CHKERRQ(ierr); 78032dcc486SBarry Smith ierr = PetscMemzero(nprocs,size*sizeof(PetscInt));CHKERRQ(ierr); 78130dcb7c9SBarry Smith cnt = 0; 78230dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 78330dcb7c9SBarry Smith nt = recvs2[cnt++]; 78430dcb7c9SBarry Smith for (j=0; j<nt; j++) { 78530dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 78630dcb7c9SBarry Smith nprocs[recvs2[cnt+2+k]]++; 78730dcb7c9SBarry Smith } 78830dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 78930dcb7c9SBarry Smith } 79030dcb7c9SBarry Smith } 79130dcb7c9SBarry Smith nt = 0; for (i=0; i<size; i++) nt += (nprocs[i] > 0); 79230dcb7c9SBarry Smith *nproc = nt; 79332dcc486SBarry Smith ierr = PetscMalloc((nt+1)*sizeof(PetscInt),procs);CHKERRQ(ierr); 79432dcc486SBarry Smith ierr = PetscMalloc((nt+1)*sizeof(PetscInt),numprocs);CHKERRQ(ierr); 79532dcc486SBarry Smith ierr = PetscMalloc((nt+1)*sizeof(PetscInt*),indices);CHKERRQ(ierr); 79632dcc486SBarry Smith ierr = PetscMalloc(size*sizeof(PetscInt),&bprocs);CHKERRQ(ierr); 79730dcb7c9SBarry Smith cnt = 0; 79830dcb7c9SBarry Smith for (i=0; i<size; i++) { 79930dcb7c9SBarry Smith if (nprocs[i] > 0) { 80030dcb7c9SBarry Smith bprocs[i] = cnt; 80130dcb7c9SBarry Smith (*procs)[cnt] = i; 80230dcb7c9SBarry Smith (*numprocs)[cnt] = nprocs[i]; 80332dcc486SBarry Smith ierr = PetscMalloc(nprocs[i]*sizeof(PetscInt),&(*indices)[cnt]);CHKERRQ(ierr); 80430dcb7c9SBarry Smith cnt++; 80530dcb7c9SBarry Smith } 80630dcb7c9SBarry Smith } 80730dcb7c9SBarry Smith 80830dcb7c9SBarry Smith /* make the list of subdomains for each nontrivial local node */ 80932dcc486SBarry Smith ierr = PetscMemzero(*numprocs,nt*sizeof(PetscInt));CHKERRQ(ierr); 81030dcb7c9SBarry Smith cnt = 0; 81130dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 81230dcb7c9SBarry Smith nt = recvs2[cnt++]; 81330dcb7c9SBarry Smith for (j=0; j<nt; j++) { 81430dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 81530dcb7c9SBarry Smith (*indices)[bprocs[recvs2[cnt+2+k]]][(*numprocs)[bprocs[recvs2[cnt+2+k]]]++] = recvs2[cnt]; 81630dcb7c9SBarry Smith } 81730dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 81830dcb7c9SBarry Smith } 81930dcb7c9SBarry Smith } 82030dcb7c9SBarry Smith ierr = PetscFree(bprocs);CHKERRQ(ierr); 82107b52d57SBarry Smith ierr = PetscFree(recvs2);CHKERRQ(ierr); 82230dcb7c9SBarry Smith 82307b52d57SBarry Smith /* sort the node indexing by their global numbers */ 82407b52d57SBarry Smith nt = *nproc; 82507b52d57SBarry Smith for (i=0; i<nt; i++) { 82632dcc486SBarry Smith ierr = PetscMalloc(((*numprocs)[i])*sizeof(PetscInt),&tmp);CHKERRQ(ierr); 82707b52d57SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 82807b52d57SBarry Smith tmp[j] = lindices[(*indices)[i][j]]; 82907b52d57SBarry Smith } 83007b52d57SBarry Smith ierr = PetscSortIntWithArray((*numprocs)[i],tmp,(*indices)[i]);CHKERRQ(ierr); 83107b52d57SBarry Smith ierr = PetscFree(tmp);CHKERRQ(ierr); 83207b52d57SBarry Smith } 83307b52d57SBarry Smith 83407b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 83530dcb7c9SBarry Smith nt = *nproc; 83630dcb7c9SBarry Smith for (i=0; i<nt; i++) { 83730dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] subdomain %d number of indices %d: ",rank,(*procs)[i],(*numprocs)[i]);CHKERRQ(ierr); 83830dcb7c9SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 83930dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",(*indices)[i][j]);CHKERRQ(ierr); 84030dcb7c9SBarry Smith } 84130dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 84230dcb7c9SBarry Smith } 84330dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 84407b52d57SBarry Smith } /* ----------------------------------- */ 84530dcb7c9SBarry Smith 84630dcb7c9SBarry Smith /* wait on sends */ 84730dcb7c9SBarry Smith if (nsends2) { 848b0a32e0cSBarry Smith ierr = PetscMalloc(nsends2*sizeof(MPI_Status),&send_status);CHKERRQ(ierr); 84930dcb7c9SBarry Smith ierr = MPI_Waitall(nsends2,send_waits,send_status);CHKERRQ(ierr); 85030dcb7c9SBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 85130dcb7c9SBarry Smith } 85230dcb7c9SBarry Smith 85330dcb7c9SBarry Smith ierr = PetscFree(starts3);CHKERRQ(ierr); 85430dcb7c9SBarry Smith ierr = PetscFree(dest);CHKERRQ(ierr); 85530dcb7c9SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 8563677ff5aSBarry Smith 857bc8ff85bSBarry Smith ierr = PetscFree(nownedsenders);CHKERRQ(ierr); 858bc8ff85bSBarry Smith ierr = PetscFree(ownedsenders);CHKERRQ(ierr); 859bc8ff85bSBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 86030dcb7c9SBarry Smith ierr = PetscFree(starts2);CHKERRQ(ierr); 86130dcb7c9SBarry Smith ierr = PetscFree(lens2);CHKERRQ(ierr); 86289d82c54SBarry Smith 86389d82c54SBarry Smith ierr = PetscFree(source);CHKERRQ(ierr); 86497f1f81fSBarry Smith ierr = PetscFree(len);CHKERRQ(ierr); 86589d82c54SBarry Smith ierr = PetscFree(recvs);CHKERRQ(ierr); 8663a96401aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 86730dcb7c9SBarry Smith ierr = PetscFree(sends2);CHKERRQ(ierr); 86824cf384cSBarry Smith 86924cf384cSBarry Smith /* put the information about myself as the first entry in the list */ 87024cf384cSBarry Smith first_procs = (*procs)[0]; 87124cf384cSBarry Smith first_numprocs = (*numprocs)[0]; 87224cf384cSBarry Smith first_indices = (*indices)[0]; 87324cf384cSBarry Smith for (i=0; i<*nproc; i++) { 87424cf384cSBarry Smith if ((*procs)[i] == rank) { 87524cf384cSBarry Smith (*procs)[0] = (*procs)[i]; 87624cf384cSBarry Smith (*numprocs)[0] = (*numprocs)[i]; 87724cf384cSBarry Smith (*indices)[0] = (*indices)[i]; 87824cf384cSBarry Smith (*procs)[i] = first_procs; 87924cf384cSBarry Smith (*numprocs)[i] = first_numprocs; 88024cf384cSBarry Smith (*indices)[i] = first_indices; 88124cf384cSBarry Smith break; 88224cf384cSBarry Smith } 88324cf384cSBarry Smith } 88489d82c54SBarry Smith PetscFunctionReturn(0); 88589d82c54SBarry Smith } 88689d82c54SBarry Smith 8874a2ae208SSatish Balay #undef __FUNCT__ 8884a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingRestoreInfo" 88907b52d57SBarry Smith /*@C 89007b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo - Frees the memory allocated by ISLocalToGlobalMappingGetInfo() 89189d82c54SBarry Smith 89207b52d57SBarry Smith Collective on ISLocalToGlobalMapping 89307b52d57SBarry Smith 89407b52d57SBarry Smith Input Parameters: 89507b52d57SBarry Smith . mapping - the mapping from local to global indexing 89607b52d57SBarry Smith 89707b52d57SBarry Smith Output Parameter: 89807b52d57SBarry Smith + nproc - number of processors that are connected to this one 89907b52d57SBarry Smith . proc - neighboring processors 90007b52d57SBarry Smith . numproc - number of indices for each processor 90107b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 90207b52d57SBarry Smith 90307b52d57SBarry Smith Level: advanced 90407b52d57SBarry Smith 90507b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 90607b52d57SBarry Smith ISLocalToGlobalMappingGetInfo() 90707b52d57SBarry Smith @*/ 9080c735eedSKris Buschelman PetscErrorCode PETSCVEC_DLLEXPORT ISLocalToGlobalMappingRestoreInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 90907b52d57SBarry Smith { 9106849ba73SBarry Smith PetscErrorCode ierr; 91132dcc486SBarry Smith PetscInt i; 91207b52d57SBarry Smith 91307b52d57SBarry Smith PetscFunctionBegin; 91405b42c5fSBarry Smith ierr = PetscFree(*procs);CHKERRQ(ierr); 91505b42c5fSBarry Smith ierr = PetscFree(*numprocs);CHKERRQ(ierr); 91600ff320aSBarry Smith if (*indices) { 91705b42c5fSBarry Smith ierr = PetscFree((*indices)[0]);CHKERRQ(ierr); 91800ff320aSBarry Smith for (i=1; i<*nproc; i++) { 91905b42c5fSBarry Smith ierr = PetscFree((*indices)[i]);CHKERRQ(ierr); 92007b52d57SBarry Smith } 92107b52d57SBarry Smith ierr = PetscFree(*indices);CHKERRQ(ierr); 92224cf384cSBarry Smith } 92307b52d57SBarry Smith PetscFunctionReturn(0); 92407b52d57SBarry Smith } 925