173f4d377SMatthew Knepley /*$Id: isltog.c,v 1.65 2001/05/21 14:16:29 bsmith Exp $*/ 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 68e58c17dSMatthew Knepley EXTERN int VecInitializePackage(char *); 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 @*/ 273b9aefa3SBarry Smith int ISLocalToGlobalMappingGetSize(ISLocalToGlobalMapping mapping,int *n) 283b9aefa3SBarry Smith { 293b9aefa3SBarry Smith PetscFunctionBegin; 303b9aefa3SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE); 313b9aefa3SBarry Smith *n = mapping->n; 323b9aefa3SBarry Smith PetscFunctionReturn(0); 333b9aefa3SBarry Smith } 343b9aefa3SBarry Smith 354a2ae208SSatish Balay #undef __FUNCT__ 364a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingView" 375a5d4f66SBarry Smith /*@C 385a5d4f66SBarry Smith ISLocalToGlobalMappingView - View a local to global mapping 395a5d4f66SBarry Smith 40b9cd556bSLois Curfman McInnes Not Collective 41b9cd556bSLois Curfman McInnes 425a5d4f66SBarry Smith Input Parameters: 433b9aefa3SBarry Smith + ltog - local to global mapping 443b9aefa3SBarry Smith - viewer - viewer 455a5d4f66SBarry Smith 46a997ad1aSLois Curfman McInnes Level: advanced 47a997ad1aSLois Curfman McInnes 48273d9f13SBarry Smith Concepts: mapping^local to global 495a5d4f66SBarry Smith 505a5d4f66SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 515a5d4f66SBarry Smith @*/ 52b0a32e0cSBarry Smith int ISLocalToGlobalMappingView(ISLocalToGlobalMapping mapping,PetscViewer viewer) 535a5d4f66SBarry Smith { 54f1af5d2fSBarry Smith int i,ierr,rank; 556831982aSBarry Smith PetscTruth isascii; 565a5d4f66SBarry Smith 575a5d4f66SBarry Smith PetscFunctionBegin; 586831982aSBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE); 59b0a32e0cSBarry Smith if (!viewer) viewer = PETSC_VIEWER_STDOUT_(mapping->comm); 60b0a32e0cSBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE); 615a5d4f66SBarry Smith 62f1af5d2fSBarry Smith ierr = MPI_Comm_rank(mapping->comm,&rank);CHKERRQ(ierr); 63b0a32e0cSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr); 646831982aSBarry Smith if (isascii) { 655a5d4f66SBarry Smith for (i=0; i<mapping->n; i++) { 66b0a32e0cSBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d] %d %d\n",rank,i,mapping->indices[i]);CHKERRQ(ierr); 676831982aSBarry Smith } 68b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 696831982aSBarry Smith } else { 7029bbc08cSBarry Smith SETERRQ1(1,"Viewer type %s not supported for ISLocalToGlobalMapping",((PetscObject)viewer)->type_name); 715a5d4f66SBarry Smith } 725a5d4f66SBarry Smith 735a5d4f66SBarry Smith PetscFunctionReturn(0); 745a5d4f66SBarry Smith } 755a5d4f66SBarry Smith 764a2ae208SSatish Balay #undef __FUNCT__ 774a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreateIS" 782bdab257SBarry Smith /*@C 792bdab257SBarry Smith ISLocalToGlobalMappingCreateIS - Creates a mapping between a local (0 to n) 802bdab257SBarry Smith ordering and a global parallel ordering. 812bdab257SBarry Smith 820f5bd95cSBarry Smith Not collective 83b9cd556bSLois Curfman McInnes 84a997ad1aSLois Curfman McInnes Input Parameter: 852bdab257SBarry Smith . is - index set containing the global numbers for each local 862bdab257SBarry Smith 87a997ad1aSLois Curfman McInnes Output Parameter: 882bdab257SBarry Smith . mapping - new mapping data structure 892bdab257SBarry Smith 90a997ad1aSLois Curfman McInnes Level: advanced 91a997ad1aSLois Curfman McInnes 92273d9f13SBarry Smith Concepts: mapping^local to global 932bdab257SBarry Smith 942bdab257SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 952bdab257SBarry Smith @*/ 962bdab257SBarry Smith int ISLocalToGlobalMappingCreateIS(IS is,ISLocalToGlobalMapping *mapping) 972bdab257SBarry Smith { 982bdab257SBarry Smith int n,*indices,ierr; 992bdab257SBarry Smith MPI_Comm comm; 1003a40ed3dSBarry Smith 1013a40ed3dSBarry Smith PetscFunctionBegin; 1022bdab257SBarry Smith PetscValidHeaderSpecific(is,IS_COOKIE); 1032bdab257SBarry Smith 1042bdab257SBarry Smith ierr = PetscObjectGetComm((PetscObject)is,&comm);CHKERRQ(ierr); 1053b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 1062bdab257SBarry Smith ierr = ISGetIndices(is,&indices);CHKERRQ(ierr); 1072bdab257SBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,n,indices,mapping);CHKERRQ(ierr); 1082bdab257SBarry Smith ierr = ISRestoreIndices(is,&indices);CHKERRQ(ierr); 1092bdab257SBarry Smith 1103a40ed3dSBarry Smith PetscFunctionReturn(0); 1112bdab257SBarry Smith } 1125a5d4f66SBarry Smith 113b46b645bSBarry Smith 1144a2ae208SSatish Balay #undef __FUNCT__ 1154a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreate" 116dd7157adSSatish Balay /*@C 11790f02eecSBarry Smith ISLocalToGlobalMappingCreate - Creates a mapping between a local (0 to n) 11890f02eecSBarry Smith ordering and a global parallel ordering. 1192362add9SBarry Smith 12089d82c54SBarry Smith Not Collective, but communicator may have more than one process 121b9cd556bSLois Curfman McInnes 1222362add9SBarry Smith Input Parameters: 12389d82c54SBarry Smith + comm - MPI communicator 12490f02eecSBarry Smith . n - the number of local elements 125b9cd556bSLois Curfman McInnes - indices - the global index for each local element 1262362add9SBarry Smith 127a997ad1aSLois Curfman McInnes Output Parameter: 12890f02eecSBarry Smith . mapping - new mapping data structure 1292362add9SBarry Smith 130a997ad1aSLois Curfman McInnes Level: advanced 131a997ad1aSLois Curfman McInnes 132273d9f13SBarry Smith Concepts: mapping^local to global 1332362add9SBarry Smith 134b46b645bSBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreateNC() 1352362add9SBarry Smith @*/ 136987e4450SSatish Balay int ISLocalToGlobalMappingCreate(MPI_Comm cm,int n,const int indices[],ISLocalToGlobalMapping *mapping) 1372362add9SBarry Smith { 138b46b645bSBarry Smith int *in,ierr; 139b46b645bSBarry Smith 140b46b645bSBarry Smith PetscFunctionBegin; 141b46b645bSBarry Smith PetscValidIntPointer(indices); 142b46b645bSBarry Smith PetscValidPointer(mapping); 143b46b645bSBarry Smith ierr = PetscMalloc((n+1)*sizeof(int),&in);CHKERRQ(ierr); 144b46b645bSBarry Smith ierr = PetscMemcpy(in,indices,n*sizeof(int));CHKERRQ(ierr); 145b46b645bSBarry Smith ierr = ISLocalToGlobalMappingCreateNC(cm,n,in,mapping);CHKERRQ(ierr); 146b46b645bSBarry Smith PetscFunctionReturn(0); 147b46b645bSBarry Smith } 148b46b645bSBarry Smith 149b46b645bSBarry Smith #undef __FUNCT__ 150b46b645bSBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingCreateNC" 151b46b645bSBarry Smith /*@C 152b46b645bSBarry Smith ISLocalToGlobalMappingCreateNC - Creates a mapping between a local (0 to n) 153b46b645bSBarry Smith ordering and a global parallel ordering. 154b46b645bSBarry Smith 155b46b645bSBarry Smith Not Collective, but communicator may have more than one process 156b46b645bSBarry Smith 157b46b645bSBarry Smith Input Parameters: 158b46b645bSBarry Smith + comm - MPI communicator 159b46b645bSBarry Smith . n - the number of local elements 160b46b645bSBarry Smith - indices - the global index for each local element 161b46b645bSBarry Smith 162b46b645bSBarry Smith Output Parameter: 163b46b645bSBarry Smith . mapping - new mapping data structure 164b46b645bSBarry Smith 165b46b645bSBarry Smith Level: developer 166b46b645bSBarry Smith 167b46b645bSBarry Smith Notes: Does not copy the indices, just keeps the pointer to the indices. The ISLocalToGlobalMappingDestroy() 168b46b645bSBarry Smith will free the space so it must be obtained with PetscMalloc() and it must not be freed elsewhere. 169b46b645bSBarry Smith 170b46b645bSBarry Smith Concepts: mapping^local to global 171b46b645bSBarry Smith 172b46b645bSBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate() 173b46b645bSBarry Smith @*/ 174b46b645bSBarry Smith int ISLocalToGlobalMappingCreateNC(MPI_Comm cm,int n,const int indices[],ISLocalToGlobalMapping *mapping) 175b46b645bSBarry Smith { 1763a40ed3dSBarry Smith PetscFunctionBegin; 17790f02eecSBarry Smith PetscValidIntPointer(indices); 17890f02eecSBarry Smith PetscValidPointer(mapping); 1798e58c17dSMatthew Knepley *mapping = PETSC_NULL; 1808e58c17dSMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 18158d3e684SBarry Smith {int ierr = VecInitializePackage(PETSC_NULL); CHKERRQ(ierr);} 1828e58c17dSMatthew Knepley #endif 1832362add9SBarry Smith 1843f1db9ecSBarry Smith PetscHeaderCreate(*mapping,_p_ISLocalToGlobalMapping,int,IS_LTOGM_COOKIE,0,"ISLocalToGlobalMapping", 1853f1db9ecSBarry Smith cm,ISLocalToGlobalMappingDestroy,ISLocalToGlobalMappingView); 186b0a32e0cSBarry Smith PetscLogObjectCreate(*mapping); 187b0a32e0cSBarry Smith PetscLogObjectMemory(*mapping,sizeof(struct _p_ISLocalToGlobalMapping)+n*sizeof(int)); 188d4bb536fSBarry Smith 189d4bb536fSBarry Smith (*mapping)->n = n; 190b46b645bSBarry Smith (*mapping)->indices = (int*)indices; 191d4bb536fSBarry Smith 192d4bb536fSBarry Smith /* 193d4bb536fSBarry Smith Do not create the global to local mapping. This is only created if 194d4bb536fSBarry Smith ISGlobalToLocalMapping() is called 195d4bb536fSBarry Smith */ 196d4bb536fSBarry Smith (*mapping)->globals = 0; 1973a40ed3dSBarry Smith PetscFunctionReturn(0); 1982362add9SBarry Smith } 1992362add9SBarry Smith 2004a2ae208SSatish Balay #undef __FUNCT__ 2014a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingBlock" 202323b833fSBarry Smith /*@C 203323b833fSBarry Smith ISLocalToGlobalMappingBlock - Creates a blocked index version of an 204323b833fSBarry Smith ISLocalToGlobalMapping that is appropriate for MatSetLocalToGlobalMappingBlock() 205323b833fSBarry Smith and VecSetLocalToGlobalMappingBlock(). 206323b833fSBarry Smith 207323b833fSBarry Smith Not Collective, but communicator may have more than one process 208323b833fSBarry Smith 209323b833fSBarry Smith Input Parameters: 210323b833fSBarry Smith + inmap - original point-wise mapping 211323b833fSBarry Smith - bs - block size 212323b833fSBarry Smith 213323b833fSBarry Smith Output Parameter: 214323b833fSBarry Smith . outmap - block based mapping 215323b833fSBarry Smith 216323b833fSBarry Smith Level: advanced 217323b833fSBarry Smith 218323b833fSBarry Smith Concepts: mapping^local to global 219323b833fSBarry Smith 220323b833fSBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingCreateIS() 221323b833fSBarry Smith @*/ 222323b833fSBarry Smith int ISLocalToGlobalMappingBlock(ISLocalToGlobalMapping inmap,int bs,ISLocalToGlobalMapping *outmap) 223323b833fSBarry Smith { 224323b833fSBarry Smith int ierr,*ii,i,n; 225323b833fSBarry Smith 226323b833fSBarry Smith PetscFunctionBegin; 227323b833fSBarry Smith 228323b833fSBarry Smith if (bs > 1) { 229323b833fSBarry Smith n = inmap->n/bs; 230323b833fSBarry Smith ierr = PetscMalloc(n*sizeof(int),&ii);CHKERRQ(ierr); 231323b833fSBarry Smith for (i=0; i<n; i++) { 232b8ee7809SBarry Smith ii[i] = inmap->indices[bs*i]/bs; 233323b833fSBarry Smith } 234323b833fSBarry Smith ierr = ISLocalToGlobalMappingCreate(inmap->comm,n,ii,outmap);CHKERRQ(ierr); 235323b833fSBarry Smith ierr = PetscFree(ii);CHKERRQ(ierr); 236323b833fSBarry Smith } else { 237323b833fSBarry Smith *outmap = inmap; 238323b833fSBarry Smith ierr = PetscObjectReference((PetscObject)inmap);CHKERRQ(ierr); 239323b833fSBarry Smith } 240323b833fSBarry Smith PetscFunctionReturn(0); 241323b833fSBarry Smith } 242323b833fSBarry Smith 2434a2ae208SSatish Balay #undef __FUNCT__ 2444a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingDestroy" 24590f02eecSBarry Smith /*@ 24690f02eecSBarry Smith ISLocalToGlobalMappingDestroy - Destroys a mapping between a local (0 to n) 24790f02eecSBarry Smith ordering and a global parallel ordering. 24890f02eecSBarry Smith 2490f5bd95cSBarry Smith Note Collective 250b9cd556bSLois Curfman McInnes 25190f02eecSBarry Smith Input Parameters: 25290f02eecSBarry Smith . mapping - mapping data structure 25390f02eecSBarry Smith 254a997ad1aSLois Curfman McInnes Level: advanced 255a997ad1aSLois Curfman McInnes 2563acfe500SLois Curfman McInnes .seealso: ISLocalToGlobalMappingCreate() 25790f02eecSBarry Smith @*/ 25890f02eecSBarry Smith int ISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping mapping) 25990f02eecSBarry Smith { 260606d414cSSatish Balay int ierr; 2613a40ed3dSBarry Smith PetscFunctionBegin; 26290f02eecSBarry Smith PetscValidPointer(mapping); 2633a40ed3dSBarry Smith if (--mapping->refct > 0) PetscFunctionReturn(0); 26485614651SBarry Smith if (mapping->refct < 0) { 26529bbc08cSBarry Smith SETERRQ(1,"Mapping already destroyed"); 26685614651SBarry Smith } 26790f02eecSBarry Smith 268606d414cSSatish Balay ierr = PetscFree(mapping->indices);CHKERRQ(ierr); 269606d414cSSatish Balay if (mapping->globals) {ierr = PetscFree(mapping->globals);CHKERRQ(ierr);} 270b0a32e0cSBarry Smith PetscLogObjectDestroy(mapping); 271d4bb536fSBarry Smith PetscHeaderDestroy(mapping); 2723a40ed3dSBarry Smith PetscFunctionReturn(0); 27390f02eecSBarry Smith } 27490f02eecSBarry Smith 2754a2ae208SSatish Balay #undef __FUNCT__ 2764a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingApplyIS" 27790f02eecSBarry Smith /*@ 2783acfe500SLois Curfman McInnes ISLocalToGlobalMappingApplyIS - Creates from an IS in the local numbering 2793acfe500SLois Curfman McInnes a new index set using the global numbering defined in an ISLocalToGlobalMapping 2803acfe500SLois Curfman McInnes context. 28190f02eecSBarry Smith 282b9cd556bSLois Curfman McInnes Not collective 283b9cd556bSLois Curfman McInnes 28490f02eecSBarry Smith Input Parameters: 285b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 286b9cd556bSLois Curfman McInnes - is - index set in local numbering 28790f02eecSBarry Smith 28890f02eecSBarry Smith Output Parameters: 28990f02eecSBarry Smith . newis - index set in global numbering 29090f02eecSBarry Smith 291a997ad1aSLois Curfman McInnes Level: advanced 292a997ad1aSLois Curfman McInnes 293273d9f13SBarry Smith Concepts: mapping^local to global 2943acfe500SLois Curfman McInnes 29590f02eecSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 296d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy(), ISGlobalToLocalMappingApply() 29790f02eecSBarry Smith @*/ 29890f02eecSBarry Smith int ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping mapping,IS is,IS *newis) 29990f02eecSBarry Smith { 3003b9aefa3SBarry Smith int ierr,n,i,*idxin,*idxmap,*idxout,Nmax = mapping->n; 3013a40ed3dSBarry Smith 3023a40ed3dSBarry Smith PetscFunctionBegin; 30390f02eecSBarry Smith PetscValidPointer(mapping); 30490f02eecSBarry Smith PetscValidHeaderSpecific(is,IS_COOKIE); 30590f02eecSBarry Smith PetscValidPointer(newis); 30690f02eecSBarry Smith 3073b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 30890f02eecSBarry Smith ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 30990f02eecSBarry Smith idxmap = mapping->indices; 31090f02eecSBarry Smith 311b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(int),&idxout);CHKERRQ(ierr); 31290f02eecSBarry Smith for (i=0; i<n; i++) { 313590ac198SBarry Smith if (idxin[i] >= Nmax) SETERRQ3(PETSC_ERR_ARG_OUTOFRANGE,"Local index %d too large %d (max) at %d",idxin[i],Nmax-1,i); 31490f02eecSBarry Smith idxout[i] = idxmap[idxin[i]]; 31590f02eecSBarry Smith } 3163b9aefa3SBarry Smith ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 317029af93fSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxout,newis);CHKERRQ(ierr); 318606d414cSSatish Balay ierr = PetscFree(idxout);CHKERRQ(ierr); 3193a40ed3dSBarry Smith PetscFunctionReturn(0); 32090f02eecSBarry Smith } 32190f02eecSBarry Smith 32289d82c54SBarry Smith /*MC 3233acfe500SLois Curfman McInnes ISLocalToGlobalMappingApply - Takes a list of integers in a local numbering 3243acfe500SLois Curfman McInnes and converts them to the global numbering. 32590f02eecSBarry Smith 326b9cd556bSLois Curfman McInnes Not collective 327b9cd556bSLois Curfman McInnes 328bb25748dSBarry Smith Input Parameters: 329b9cd556bSLois Curfman McInnes + mapping - the local to global mapping context 330bb25748dSBarry Smith . N - number of integers 331b9cd556bSLois Curfman McInnes - in - input indices in local numbering 332bb25748dSBarry Smith 333bb25748dSBarry Smith Output Parameter: 334bb25748dSBarry Smith . out - indices in global numbering 335bb25748dSBarry Smith 3363b9aefa3SBarry Smith Synopsis: 337216e7ba4SBarry Smith int ISLocalToGlobalMappingApply(ISLocalToGlobalMapping mapping,int N,int in[],int out[]) 3383b9aefa3SBarry Smith 339b9cd556bSLois Curfman McInnes Notes: 340b9cd556bSLois Curfman McInnes The in and out array parameters may be identical. 341d4bb536fSBarry Smith 342a997ad1aSLois Curfman McInnes Level: advanced 343a997ad1aSLois Curfman McInnes 344bb25748dSBarry Smith .seealso: ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 3450752156aSBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 346d4bb536fSBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 347bb25748dSBarry Smith 348273d9f13SBarry Smith Concepts: mapping^local to global 349d4bb536fSBarry Smith 35089d82c54SBarry Smith M*/ 351d4bb536fSBarry Smith 352d4bb536fSBarry Smith /* -----------------------------------------------------------------------------------------*/ 353d4bb536fSBarry Smith 3544a2ae208SSatish Balay #undef __FUNCT__ 3554a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingSetUp_Private" 356d4bb536fSBarry Smith /* 357d4bb536fSBarry Smith Creates the global fields in the ISLocalToGlobalMapping structure 358d4bb536fSBarry Smith */ 359d4bb536fSBarry Smith static int ISGlobalToLocalMappingSetUp_Private(ISLocalToGlobalMapping mapping) 360d4bb536fSBarry Smith { 361b0a32e0cSBarry Smith int ierr,i,*idx = mapping->indices,n = mapping->n,end,start,*globals; 362d4bb536fSBarry Smith 3633a40ed3dSBarry Smith PetscFunctionBegin; 364d4bb536fSBarry Smith end = 0; 365d4bb536fSBarry Smith start = 100000000; 366d4bb536fSBarry Smith 367d4bb536fSBarry Smith for (i=0; i<n; i++) { 368d4bb536fSBarry Smith if (idx[i] < 0) continue; 369d4bb536fSBarry Smith if (idx[i] < start) start = idx[i]; 370d4bb536fSBarry Smith if (idx[i] > end) end = idx[i]; 371d4bb536fSBarry Smith } 372d4bb536fSBarry Smith if (start > end) {start = 0; end = -1;} 373d4bb536fSBarry Smith mapping->globalstart = start; 374d4bb536fSBarry Smith mapping->globalend = end; 375d4bb536fSBarry Smith 376b0a32e0cSBarry Smith ierr = PetscMalloc((end-start+2)*sizeof(int),&globals);CHKERRQ(ierr); 377b0a32e0cSBarry Smith mapping->globals = globals; 378d4bb536fSBarry Smith for (i=0; i<end-start+1; i++) { 379d4bb536fSBarry Smith globals[i] = -1; 380d4bb536fSBarry Smith } 381d4bb536fSBarry Smith for (i=0; i<n; i++) { 382d4bb536fSBarry Smith if (idx[i] < 0) continue; 383d4bb536fSBarry Smith globals[idx[i] - start] = i; 384d4bb536fSBarry Smith } 385d4bb536fSBarry Smith 386b0a32e0cSBarry Smith PetscLogObjectMemory(mapping,(end-start+1)*sizeof(int)); 3873a40ed3dSBarry Smith PetscFunctionReturn(0); 388d4bb536fSBarry Smith } 389d4bb536fSBarry Smith 3904a2ae208SSatish Balay #undef __FUNCT__ 3914a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingApply" 392d4bb536fSBarry Smith /*@ 393a997ad1aSLois Curfman McInnes ISGlobalToLocalMappingApply - Provides the local numbering for a list of integers 394a997ad1aSLois Curfman McInnes specified with a global numbering. 395d4bb536fSBarry Smith 396b9cd556bSLois Curfman McInnes Not collective 397b9cd556bSLois Curfman McInnes 398d4bb536fSBarry Smith Input Parameters: 399b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 400d4bb536fSBarry Smith . type - IS_GTOLM_MASK - replaces global indices with no local value with -1 401d4bb536fSBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 402d4bb536fSBarry Smith . n - number of global indices to map 403b9cd556bSLois Curfman McInnes - idx - global indices to map 404d4bb536fSBarry Smith 405d4bb536fSBarry Smith Output Parameters: 406b9cd556bSLois Curfman McInnes + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 407b9cd556bSLois Curfman McInnes - idxout - local index of each global index, one must pass in an array long enough 408e182c471SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApply() with 409e182c471SBarry Smith idxout == PETSC_NULL to determine the required length (returned in nout) 410e182c471SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApply() 411e182c471SBarry Smith a second time to set the values. 412d4bb536fSBarry Smith 413b9cd556bSLois Curfman McInnes Notes: 414b9cd556bSLois Curfman McInnes Either nout or idxout may be PETSC_NULL. idx and idxout may be identical. 415d4bb536fSBarry Smith 4160f5bd95cSBarry Smith This is not scalable in memory usage. Each processor requires O(Nglobal) size 4170f5bd95cSBarry Smith array to compute these. 4180f5bd95cSBarry Smith 419a997ad1aSLois Curfman McInnes Level: advanced 420a997ad1aSLois Curfman McInnes 421273d9f13SBarry Smith Concepts: mapping^global to local 422d4bb536fSBarry Smith 423d4bb536fSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 424d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy() 425d4bb536fSBarry Smith @*/ 426d4bb536fSBarry Smith int ISGlobalToLocalMappingApply(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, 427987e4450SSatish Balay int n,const int idx[],int *nout,int idxout[]) 428d4bb536fSBarry Smith { 429d4bb536fSBarry Smith int i,ierr,*globals,nf = 0,tmp,start,end; 430d4bb536fSBarry Smith 4313a40ed3dSBarry Smith PetscFunctionBegin; 432d4bb536fSBarry Smith if (!mapping->globals) { 433d4bb536fSBarry Smith ierr = ISGlobalToLocalMappingSetUp_Private(mapping);CHKERRQ(ierr); 434d4bb536fSBarry Smith } 435d4bb536fSBarry Smith globals = mapping->globals; 436d4bb536fSBarry Smith start = mapping->globalstart; 437d4bb536fSBarry Smith end = mapping->globalend; 438d4bb536fSBarry Smith 439d4bb536fSBarry Smith if (type == IS_GTOLM_MASK) { 440d4bb536fSBarry Smith if (idxout) { 441d4bb536fSBarry Smith for (i=0; i<n; i++) { 442d4bb536fSBarry Smith if (idx[i] < 0) idxout[i] = idx[i]; 443d4bb536fSBarry Smith else if (idx[i] < start) idxout[i] = -1; 444d4bb536fSBarry Smith else if (idx[i] > end) idxout[i] = -1; 445d4bb536fSBarry Smith else idxout[i] = globals[idx[i] - start]; 446d4bb536fSBarry Smith } 447d4bb536fSBarry Smith } 448d4bb536fSBarry Smith if (nout) *nout = n; 449d4bb536fSBarry Smith } else { 450d4bb536fSBarry Smith if (idxout) { 451d4bb536fSBarry Smith for (i=0; i<n; i++) { 452d4bb536fSBarry Smith if (idx[i] < 0) continue; 453d4bb536fSBarry Smith if (idx[i] < start) continue; 454d4bb536fSBarry Smith if (idx[i] > end) continue; 455d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 456d4bb536fSBarry Smith if (tmp < 0) continue; 457d4bb536fSBarry Smith idxout[nf++] = tmp; 458d4bb536fSBarry Smith } 459d4bb536fSBarry Smith } else { 460d4bb536fSBarry Smith for (i=0; i<n; i++) { 461d4bb536fSBarry Smith if (idx[i] < 0) continue; 462d4bb536fSBarry Smith if (idx[i] < start) continue; 463d4bb536fSBarry Smith if (idx[i] > end) continue; 464d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 465d4bb536fSBarry Smith if (tmp < 0) continue; 466d4bb536fSBarry Smith nf++; 467d4bb536fSBarry Smith } 468d4bb536fSBarry Smith } 469d4bb536fSBarry Smith if (nout) *nout = nf; 470d4bb536fSBarry Smith } 471d4bb536fSBarry Smith 4723a40ed3dSBarry Smith PetscFunctionReturn(0); 473d4bb536fSBarry Smith } 47490f02eecSBarry Smith 4754a2ae208SSatish Balay #undef __FUNCT__ 4764a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingGetInfo" 47789d82c54SBarry Smith /*@C 47889d82c54SBarry Smith ISLocalToGlobalMappingGetInfo - Gets the neighbor information for each processor and 47989d82c54SBarry Smith each index shared by more than one processor 48089d82c54SBarry Smith 48189d82c54SBarry Smith Collective on ISLocalToGlobalMapping 48289d82c54SBarry Smith 48389d82c54SBarry Smith Input Parameters: 48489d82c54SBarry Smith . mapping - the mapping from local to global indexing 48589d82c54SBarry Smith 48689d82c54SBarry Smith Output Parameter: 48789d82c54SBarry Smith + nproc - number of processors that are connected to this one 48889d82c54SBarry Smith . proc - neighboring processors 48907b52d57SBarry Smith . numproc - number of indices for each subdomain (processor) 49007b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 49189d82c54SBarry Smith 49289d82c54SBarry Smith Level: advanced 49389d82c54SBarry Smith 494273d9f13SBarry Smith Concepts: mapping^local to global 49589d82c54SBarry Smith 49607b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 49707b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo() 49889d82c54SBarry Smith @*/ 499*ca01db9bSBarry Smith int ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping mapping,int *nproc,int *procs[],int *numprocs[],int **indices[]) 50089d82c54SBarry Smith { 501fa7fbcffSSatish Balay int i,n = mapping->n,ierr,Ng,ng,max = 0,*lindices = mapping->indices; 50227c402fcSBarry Smith int size,rank,*nprocs,*owner,nsends,*sends,j,*starts,nmax,nrecvs,*recvs,proc; 50324cf384cSBarry Smith int tag1,tag2,tag3,cnt,*len,*source,imdex,scale,*ownedsenders,*nownedsenders,rstart,nowned; 50407b52d57SBarry Smith int node,nownedm,nt,*sends2,nsends2,*starts2,*lens2,*dest,nrecvs2,*starts3,*recvs2,k,*bprocs,*tmp; 50524cf384cSBarry Smith int first_procs,first_numprocs,*first_indices; 50689d82c54SBarry Smith MPI_Request *recv_waits,*send_waits; 50730dcb7c9SBarry Smith MPI_Status recv_status,*send_status,*recv_statuses; 50889d82c54SBarry Smith MPI_Comm comm = mapping->comm; 50907b52d57SBarry Smith PetscTruth debug = PETSC_FALSE; 51089d82c54SBarry Smith 51189d82c54SBarry Smith PetscFunctionBegin; 51224cf384cSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 51324cf384cSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 51424cf384cSBarry Smith if (size == 1) { 51524cf384cSBarry Smith *nproc = 0; 51624cf384cSBarry Smith *procs = PETSC_NULL; 517b0a32e0cSBarry Smith ierr = PetscMalloc(sizeof(int),numprocs);CHKERRQ(ierr); 5181e2105dcSBarry Smith (*numprocs)[0] = 0; 519b0a32e0cSBarry Smith ierr = PetscMalloc(sizeof(int*),indices);CHKERRQ(ierr); 5201e2105dcSBarry Smith (*indices)[0] = PETSC_NULL; 52124cf384cSBarry Smith PetscFunctionReturn(0); 52224cf384cSBarry Smith } 52324cf384cSBarry Smith 524b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-islocaltoglobalmappinggetinfo_debug",&debug);CHKERRQ(ierr); 52507b52d57SBarry Smith 5263677ff5aSBarry Smith /* 5273677ff5aSBarry Smith Notes on ISLocalToGlobalMappingGetInfo 5283677ff5aSBarry Smith 5293677ff5aSBarry Smith globally owned node - the nodes that have been assigned to this processor in global 5303677ff5aSBarry Smith numbering, just for this routine. 5313677ff5aSBarry Smith 5323677ff5aSBarry Smith nontrivial globally owned node - node assigned to this processor that is on a subdomain 5333677ff5aSBarry Smith boundary (i.e. is has more than one local owner) 5343677ff5aSBarry Smith 5353677ff5aSBarry Smith locally owned node - node that exists on this processors subdomain 5363677ff5aSBarry Smith 5373677ff5aSBarry Smith nontrivial locally owned node - node that is not in the interior (i.e. has more than one 5383677ff5aSBarry Smith local subdomain 5393677ff5aSBarry Smith */ 54024cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag1);CHKERRQ(ierr); 54124cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag2);CHKERRQ(ierr); 54224cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag3);CHKERRQ(ierr); 54389d82c54SBarry Smith 54489d82c54SBarry Smith for (i=0; i<n; i++) { 54589d82c54SBarry Smith if (lindices[i] > max) max = lindices[i]; 54689d82c54SBarry Smith } 54789d82c54SBarry Smith ierr = MPI_Allreduce(&max,&Ng,1,MPI_INT,MPI_MAX,comm);CHKERRQ(ierr); 54878058e43SBarry Smith Ng++; 54989d82c54SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 55089d82c54SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 551bc8ff85bSBarry Smith scale = Ng/size + 1; 552a2e34c3dSBarry Smith ng = scale; if (rank == size-1) ng = Ng - scale*(size-1); ng = PetscMax(1,ng); 553caba0dd0SBarry Smith rstart = scale*rank; 55489d82c54SBarry Smith 55589d82c54SBarry Smith /* determine ownership ranges of global indices */ 556b0a32e0cSBarry Smith ierr = PetscMalloc((2*size+1)*sizeof(int),&nprocs);CHKERRQ(ierr); 5572880cf29SBarry Smith ierr = PetscMemzero(nprocs,2*size*sizeof(int));CHKERRQ(ierr); 55889d82c54SBarry Smith 55989d82c54SBarry Smith /* determine owners of each local node */ 560b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(int),&owner);CHKERRQ(ierr); 56189d82c54SBarry Smith for (i=0; i<n; i++) { 5623677ff5aSBarry Smith proc = lindices[i]/scale; /* processor that globally owns this index */ 56327c402fcSBarry Smith nprocs[2*proc+1] = 1; /* processor globally owns at least one of ours */ 5643677ff5aSBarry Smith owner[i] = proc; 56527c402fcSBarry Smith nprocs[2*proc]++; /* count of how many that processor globally owns of ours */ 56689d82c54SBarry Smith } 56727c402fcSBarry Smith nsends = 0; for (i=0; i<size; i++) nsends += nprocs[2*i+1]; 568b0a32e0cSBarry Smith PetscLogInfo(0,"ISLocalToGlobalMappingGetInfo: Number of global owners for my local data %d\n",nsends); 56989d82c54SBarry Smith 57089d82c54SBarry Smith /* inform other processors of number of messages and max length*/ 57127c402fcSBarry Smith ierr = PetscMaxSum(comm,nprocs,&nmax,&nrecvs);CHKERRQ(ierr); 572b0a32e0cSBarry Smith PetscLogInfo(0,"ISLocalToGlobalMappingGetInfo: Number of local owners for my global data %d\n",nrecvs); 57389d82c54SBarry Smith 57489d82c54SBarry Smith /* post receives for owned rows */ 575b0a32e0cSBarry Smith ierr = PetscMalloc((2*nrecvs+1)*(nmax+1)*sizeof(int),&recvs);CHKERRQ(ierr); 576b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs+1)*sizeof(MPI_Request),&recv_waits);CHKERRQ(ierr); 57789d82c54SBarry Smith for (i=0; i<nrecvs; i++) { 57824cf384cSBarry Smith ierr = MPI_Irecv(recvs+2*nmax*i,2*nmax,MPI_INT,MPI_ANY_SOURCE,tag1,comm,recv_waits+i);CHKERRQ(ierr); 57989d82c54SBarry Smith } 58089d82c54SBarry Smith 58189d82c54SBarry Smith /* pack messages containing lists of local nodes to owners */ 582b0a32e0cSBarry Smith ierr = PetscMalloc((2*n+1)*sizeof(int),&sends);CHKERRQ(ierr); 583b0a32e0cSBarry Smith ierr = PetscMalloc((size+1)*sizeof(int),&starts);CHKERRQ(ierr); 58489d82c54SBarry Smith starts[0] = 0; 58527c402fcSBarry Smith for (i=1; i<size; i++) { starts[i] = starts[i-1] + 2*nprocs[2*i-2];} 58689d82c54SBarry Smith for (i=0; i<n; i++) { 58789d82c54SBarry Smith sends[starts[owner[i]]++] = lindices[i]; 58830dcb7c9SBarry Smith sends[starts[owner[i]]++] = i; 58989d82c54SBarry Smith } 59089d82c54SBarry Smith ierr = PetscFree(owner);CHKERRQ(ierr); 59189d82c54SBarry Smith starts[0] = 0; 59227c402fcSBarry Smith for (i=1; i<size; i++) { starts[i] = starts[i-1] + 2*nprocs[2*i-2];} 59389d82c54SBarry Smith 59489d82c54SBarry Smith /* send the messages */ 595b0a32e0cSBarry Smith ierr = PetscMalloc((nsends+1)*sizeof(MPI_Request),&send_waits);CHKERRQ(ierr); 596b0a32e0cSBarry Smith ierr = PetscMalloc((nsends+1)*sizeof(int),&dest);CHKERRQ(ierr); 59789d82c54SBarry Smith cnt = 0; 59889d82c54SBarry Smith for (i=0; i<size; i++) { 59927c402fcSBarry Smith if (nprocs[2*i]) { 60027c402fcSBarry Smith ierr = MPI_Isend(sends+starts[i],2*nprocs[2*i],MPI_INT,i,tag1,comm,send_waits+cnt);CHKERRQ(ierr); 60130dcb7c9SBarry Smith dest[cnt] = i; 60289d82c54SBarry Smith cnt++; 60389d82c54SBarry Smith } 60489d82c54SBarry Smith } 60589d82c54SBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 60689d82c54SBarry Smith 60789d82c54SBarry Smith /* wait on receives */ 608b0a32e0cSBarry Smith ierr = PetscMalloc((2*nrecvs+1)*sizeof(int),&source);CHKERRQ(ierr); 60989d82c54SBarry Smith len = source + nrecvs; 61089d82c54SBarry Smith cnt = nrecvs; 611b0a32e0cSBarry Smith ierr = PetscMalloc((ng+1)*sizeof(int),&nownedsenders);CHKERRQ(ierr); 612caba0dd0SBarry Smith ierr = PetscMemzero(nownedsenders,ng*sizeof(int));CHKERRQ(ierr); 61389d82c54SBarry Smith while (cnt) { 61489d82c54SBarry Smith ierr = MPI_Waitany(nrecvs,recv_waits,&imdex,&recv_status);CHKERRQ(ierr); 61589d82c54SBarry Smith /* unpack receives into our local space */ 61689d82c54SBarry Smith ierr = MPI_Get_count(&recv_status,MPI_INT,&len[imdex]);CHKERRQ(ierr); 61789d82c54SBarry Smith source[imdex] = recv_status.MPI_SOURCE; 61830dcb7c9SBarry Smith len[imdex] = len[imdex]/2; 619caba0dd0SBarry Smith /* count how many local owners for each of my global owned indices */ 62030dcb7c9SBarry Smith for (i=0; i<len[imdex]; i++) nownedsenders[recvs[2*imdex*nmax+2*i]-rstart]++; 62189d82c54SBarry Smith cnt--; 62289d82c54SBarry Smith } 62389d82c54SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 62489d82c54SBarry Smith 62530dcb7c9SBarry Smith /* count how many globally owned indices are on an edge multiplied by how many processors own them. */ 626bc8ff85bSBarry Smith nowned = 0; 627bc8ff85bSBarry Smith nownedm = 0; 628bc8ff85bSBarry Smith for (i=0; i<ng; i++) { 629bc8ff85bSBarry Smith if (nownedsenders[i] > 1) {nownedm += nownedsenders[i]; nowned++;} 630bc8ff85bSBarry Smith } 631bc8ff85bSBarry Smith 632bc8ff85bSBarry Smith /* create single array to contain rank of all local owners of each globally owned index */ 633b0a32e0cSBarry Smith ierr = PetscMalloc((nownedm+1)*sizeof(int),&ownedsenders);CHKERRQ(ierr); 634b0a32e0cSBarry Smith ierr = PetscMalloc((ng+1)*sizeof(int),&starts);CHKERRQ(ierr); 635bc8ff85bSBarry Smith starts[0] = 0; 636bc8ff85bSBarry Smith for (i=1; i<ng; i++) { 637bc8ff85bSBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 638bc8ff85bSBarry Smith else starts[i] = starts[i-1]; 639bc8ff85bSBarry Smith } 640bc8ff85bSBarry Smith 64130dcb7c9SBarry Smith /* for each nontrival globally owned node list all arriving processors */ 642bc8ff85bSBarry Smith for (i=0; i<nrecvs; i++) { 643bc8ff85bSBarry Smith for (j=0; j<len[i]; j++) { 64430dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 645bc8ff85bSBarry Smith if (nownedsenders[node] > 1) { 646bc8ff85bSBarry Smith ownedsenders[starts[node]++] = source[i]; 647bc8ff85bSBarry Smith } 648bc8ff85bSBarry Smith } 649bc8ff85bSBarry Smith } 650bc8ff85bSBarry Smith 65107b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 65230dcb7c9SBarry Smith starts[0] = 0; 65330dcb7c9SBarry Smith for (i=1; i<ng; i++) { 65430dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 65530dcb7c9SBarry Smith else starts[i] = starts[i-1]; 65630dcb7c9SBarry Smith } 65730dcb7c9SBarry Smith for (i=0; i<ng; i++) { 65830dcb7c9SBarry Smith if (nownedsenders[i] > 1) { 65930dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] global node %d local owner processors: ",rank,i+rstart);CHKERRQ(ierr); 66030dcb7c9SBarry Smith for (j=0; j<nownedsenders[i]; j++) { 66130dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",ownedsenders[starts[i]+j]);CHKERRQ(ierr); 66230dcb7c9SBarry Smith } 66330dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 66430dcb7c9SBarry Smith } 66530dcb7c9SBarry Smith } 66630dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 66707b52d57SBarry Smith }/* ----------------------------------- */ 66830dcb7c9SBarry Smith 6693677ff5aSBarry Smith /* wait on original sends */ 6703a96401aSBarry Smith if (nsends) { 671b0a32e0cSBarry Smith ierr = PetscMalloc(nsends*sizeof(MPI_Status),&send_status);CHKERRQ(ierr); 6723a96401aSBarry Smith ierr = MPI_Waitall(nsends,send_waits,send_status);CHKERRQ(ierr); 6733a96401aSBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 6743a96401aSBarry Smith } 67589d82c54SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 6763a96401aSBarry Smith ierr = PetscFree(sends);CHKERRQ(ierr); 6773677ff5aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 6783677ff5aSBarry Smith 6793677ff5aSBarry Smith /* pack messages to send back to local owners */ 68030dcb7c9SBarry Smith starts[0] = 0; 68130dcb7c9SBarry Smith for (i=1; i<ng; i++) { 68230dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 68330dcb7c9SBarry Smith else starts[i] = starts[i-1]; 68430dcb7c9SBarry Smith } 68530dcb7c9SBarry Smith nsends2 = nrecvs; 686b0a32e0cSBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(int),&nprocs);CHKERRQ(ierr); /* length of each message */ 68730dcb7c9SBarry Smith for (i=0; i<nrecvs; i++) { 68830dcb7c9SBarry Smith nprocs[i] = 1; 68930dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 69030dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 69130dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 69230dcb7c9SBarry Smith nprocs[i] += 2 + nownedsenders[node]; 69330dcb7c9SBarry Smith } 69430dcb7c9SBarry Smith } 69530dcb7c9SBarry Smith } 69630dcb7c9SBarry Smith nt = 0; for (i=0; i<nsends2; i++) nt += nprocs[i]; 697b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int),&sends2);CHKERRQ(ierr); 698b0a32e0cSBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(int),&starts2);CHKERRQ(ierr); 69930dcb7c9SBarry Smith starts2[0] = 0; for (i=1; i<nsends2; i++) starts2[i] = starts2[i-1] + nprocs[i-1]; 70030dcb7c9SBarry Smith /* 70130dcb7c9SBarry Smith Each message is 1 + nprocs[i] long, and consists of 70230dcb7c9SBarry Smith (0) the number of nodes being sent back 70330dcb7c9SBarry Smith (1) the local node number, 70430dcb7c9SBarry Smith (2) the number of processors sharing it, 70530dcb7c9SBarry Smith (3) the processors sharing it 70630dcb7c9SBarry Smith */ 70730dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 70830dcb7c9SBarry Smith cnt = 1; 70930dcb7c9SBarry Smith sends2[starts2[i]] = 0; 71030dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 71130dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 71230dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 71330dcb7c9SBarry Smith sends2[starts2[i]]++; 71430dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = recvs[2*i*nmax+2*j+1]; 71530dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = nownedsenders[node]; 71630dcb7c9SBarry Smith ierr = PetscMemcpy(&sends2[starts2[i]+cnt],&ownedsenders[starts[node]],nownedsenders[node]*sizeof(int));CHKERRQ(ierr); 71730dcb7c9SBarry Smith cnt += nownedsenders[node]; 71830dcb7c9SBarry Smith } 71930dcb7c9SBarry Smith } 72030dcb7c9SBarry Smith } 72130dcb7c9SBarry Smith 72230dcb7c9SBarry Smith /* send the message lengths */ 72330dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 72424cf384cSBarry Smith ierr = MPI_Send(&nprocs[i],1,MPI_INT,source[i],tag2,comm);CHKERRQ(ierr); 72530dcb7c9SBarry Smith } 72630dcb7c9SBarry Smith 72730dcb7c9SBarry Smith /* receive the message lengths */ 72830dcb7c9SBarry Smith nrecvs2 = nsends; 729b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(int),&lens2);CHKERRQ(ierr); 730b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(int),&starts3);CHKERRQ(ierr); 73130dcb7c9SBarry Smith nt = 0; 73230dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 73324cf384cSBarry Smith ierr = MPI_Recv(&lens2[i],1,MPI_INT,dest[i],tag2,comm,&recv_status);CHKERRQ(ierr); 73430dcb7c9SBarry Smith nt += lens2[i]; 73530dcb7c9SBarry Smith } 73630dcb7c9SBarry Smith starts3[0] = 0; 73730dcb7c9SBarry Smith for (i=0; i<nrecvs2-1; i++) { 73830dcb7c9SBarry Smith starts3[i+1] = starts3[i] + lens2[i]; 73930dcb7c9SBarry Smith } 740b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int),&recvs2);CHKERRQ(ierr); 741b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(MPI_Request),&recv_waits);CHKERRQ(ierr); 74252b72c4aSBarry Smith for (i=0; i<nrecvs2; i++) { 74324cf384cSBarry Smith ierr = MPI_Irecv(recvs2+starts3[i],lens2[i],MPI_INT,dest[i],tag3,comm,recv_waits+i);CHKERRQ(ierr); 74430dcb7c9SBarry Smith } 74530dcb7c9SBarry Smith 74630dcb7c9SBarry Smith /* send the messages */ 747b0a32e0cSBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(MPI_Request),&send_waits);CHKERRQ(ierr); 74830dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 74924cf384cSBarry Smith ierr = MPI_Isend(sends2+starts2[i],nprocs[i],MPI_INT,source[i],tag3,comm,send_waits+i);CHKERRQ(ierr); 75030dcb7c9SBarry Smith } 75130dcb7c9SBarry Smith 75230dcb7c9SBarry Smith /* wait on receives */ 753b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(MPI_Status),&recv_statuses);CHKERRQ(ierr); 75430dcb7c9SBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 75530dcb7c9SBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 75630dcb7c9SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 75730dcb7c9SBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 75830dcb7c9SBarry Smith 75907b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 76030dcb7c9SBarry Smith cnt = 0; 76130dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 76230dcb7c9SBarry Smith nt = recvs2[cnt++]; 76330dcb7c9SBarry Smith for (j=0; j<nt; j++) { 76430dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] local node %d number of subdomains %d: ",rank,recvs2[cnt],recvs2[cnt+1]);CHKERRQ(ierr); 76530dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 76630dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",recvs2[cnt+2+k]);CHKERRQ(ierr); 76730dcb7c9SBarry Smith } 76830dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 76930dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 77030dcb7c9SBarry Smith } 77130dcb7c9SBarry Smith } 77230dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 77307b52d57SBarry Smith } /* ----------------------------------- */ 77430dcb7c9SBarry Smith 77530dcb7c9SBarry Smith /* count number subdomains for each local node */ 776b0a32e0cSBarry Smith ierr = PetscMalloc(size*sizeof(int),&nprocs);CHKERRQ(ierr); 77730dcb7c9SBarry Smith ierr = PetscMemzero(nprocs,size*sizeof(int));CHKERRQ(ierr); 77830dcb7c9SBarry Smith cnt = 0; 77930dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 78030dcb7c9SBarry Smith nt = recvs2[cnt++]; 78130dcb7c9SBarry Smith for (j=0; j<nt; j++) { 78230dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 78330dcb7c9SBarry Smith nprocs[recvs2[cnt+2+k]]++; 78430dcb7c9SBarry Smith } 78530dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 78630dcb7c9SBarry Smith } 78730dcb7c9SBarry Smith } 78830dcb7c9SBarry Smith nt = 0; for (i=0; i<size; i++) nt += (nprocs[i] > 0); 78930dcb7c9SBarry Smith *nproc = nt; 790b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int),procs);CHKERRQ(ierr); 791b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int),numprocs);CHKERRQ(ierr); 792b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int*),indices);CHKERRQ(ierr); 793b0a32e0cSBarry Smith ierr = PetscMalloc(size*sizeof(int),&bprocs);CHKERRQ(ierr); 79430dcb7c9SBarry Smith cnt = 0; 79530dcb7c9SBarry Smith for (i=0; i<size; i++) { 79630dcb7c9SBarry Smith if (nprocs[i] > 0) { 79730dcb7c9SBarry Smith bprocs[i] = cnt; 79830dcb7c9SBarry Smith (*procs)[cnt] = i; 79930dcb7c9SBarry Smith (*numprocs)[cnt] = nprocs[i]; 800b0a32e0cSBarry Smith ierr = PetscMalloc(nprocs[i]*sizeof(int),&(*indices)[cnt]);CHKERRQ(ierr); 80130dcb7c9SBarry Smith cnt++; 80230dcb7c9SBarry Smith } 80330dcb7c9SBarry Smith } 80430dcb7c9SBarry Smith 80530dcb7c9SBarry Smith /* make the list of subdomains for each nontrivial local node */ 80630dcb7c9SBarry Smith ierr = PetscMemzero(*numprocs,nt*sizeof(int));CHKERRQ(ierr); 80730dcb7c9SBarry Smith cnt = 0; 80830dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 80930dcb7c9SBarry Smith nt = recvs2[cnt++]; 81030dcb7c9SBarry Smith for (j=0; j<nt; j++) { 81130dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 81230dcb7c9SBarry Smith (*indices)[bprocs[recvs2[cnt+2+k]]][(*numprocs)[bprocs[recvs2[cnt+2+k]]]++] = recvs2[cnt]; 81330dcb7c9SBarry Smith } 81430dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 81530dcb7c9SBarry Smith } 81630dcb7c9SBarry Smith } 81730dcb7c9SBarry Smith ierr = PetscFree(bprocs);CHKERRQ(ierr); 81807b52d57SBarry Smith ierr = PetscFree(recvs2);CHKERRQ(ierr); 81930dcb7c9SBarry Smith 82007b52d57SBarry Smith /* sort the node indexing by their global numbers */ 82107b52d57SBarry Smith nt = *nproc; 82207b52d57SBarry Smith for (i=0; i<nt; i++) { 823b0a32e0cSBarry Smith ierr = PetscMalloc(((*numprocs)[i])*sizeof(int),&tmp);CHKERRQ(ierr); 82407b52d57SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 82507b52d57SBarry Smith tmp[j] = lindices[(*indices)[i][j]]; 82607b52d57SBarry Smith } 82707b52d57SBarry Smith ierr = PetscSortIntWithArray((*numprocs)[i],tmp,(*indices)[i]);CHKERRQ(ierr); 82807b52d57SBarry Smith ierr = PetscFree(tmp);CHKERRQ(ierr); 82907b52d57SBarry Smith } 83007b52d57SBarry Smith 83107b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 83230dcb7c9SBarry Smith nt = *nproc; 83330dcb7c9SBarry Smith for (i=0; i<nt; i++) { 83430dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] subdomain %d number of indices %d: ",rank,(*procs)[i],(*numprocs)[i]);CHKERRQ(ierr); 83530dcb7c9SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 83630dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",(*indices)[i][j]);CHKERRQ(ierr); 83730dcb7c9SBarry Smith } 83830dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 83930dcb7c9SBarry Smith } 84030dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 84107b52d57SBarry Smith } /* ----------------------------------- */ 84230dcb7c9SBarry Smith 84330dcb7c9SBarry Smith /* wait on sends */ 84430dcb7c9SBarry Smith if (nsends2) { 845b0a32e0cSBarry Smith ierr = PetscMalloc(nsends2*sizeof(MPI_Status),&send_status);CHKERRQ(ierr); 84630dcb7c9SBarry Smith ierr = MPI_Waitall(nsends2,send_waits,send_status);CHKERRQ(ierr); 84730dcb7c9SBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 84830dcb7c9SBarry Smith } 84930dcb7c9SBarry Smith 85030dcb7c9SBarry Smith ierr = PetscFree(starts3);CHKERRQ(ierr); 85130dcb7c9SBarry Smith ierr = PetscFree(dest);CHKERRQ(ierr); 85230dcb7c9SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 8533677ff5aSBarry Smith 854bc8ff85bSBarry Smith ierr = PetscFree(nownedsenders);CHKERRQ(ierr); 855bc8ff85bSBarry Smith ierr = PetscFree(ownedsenders);CHKERRQ(ierr); 856bc8ff85bSBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 85730dcb7c9SBarry Smith ierr = PetscFree(starts2);CHKERRQ(ierr); 85830dcb7c9SBarry Smith ierr = PetscFree(lens2);CHKERRQ(ierr); 85989d82c54SBarry Smith 86089d82c54SBarry Smith ierr = PetscFree(source);CHKERRQ(ierr); 86189d82c54SBarry Smith ierr = PetscFree(recvs);CHKERRQ(ierr); 8623a96401aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 86330dcb7c9SBarry Smith ierr = PetscFree(sends2);CHKERRQ(ierr); 86424cf384cSBarry Smith 86524cf384cSBarry Smith /* put the information about myself as the first entry in the list */ 86624cf384cSBarry Smith first_procs = (*procs)[0]; 86724cf384cSBarry Smith first_numprocs = (*numprocs)[0]; 86824cf384cSBarry Smith first_indices = (*indices)[0]; 86924cf384cSBarry Smith for (i=0; i<*nproc; i++) { 87024cf384cSBarry Smith if ((*procs)[i] == rank) { 87124cf384cSBarry Smith (*procs)[0] = (*procs)[i]; 87224cf384cSBarry Smith (*numprocs)[0] = (*numprocs)[i]; 87324cf384cSBarry Smith (*indices)[0] = (*indices)[i]; 87424cf384cSBarry Smith (*procs)[i] = first_procs; 87524cf384cSBarry Smith (*numprocs)[i] = first_numprocs; 87624cf384cSBarry Smith (*indices)[i] = first_indices; 87724cf384cSBarry Smith break; 87824cf384cSBarry Smith } 87924cf384cSBarry Smith } 88024cf384cSBarry Smith 88189d82c54SBarry Smith PetscFunctionReturn(0); 88289d82c54SBarry Smith } 88389d82c54SBarry Smith 8844a2ae208SSatish Balay #undef __FUNCT__ 8854a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingRestoreInfo" 88607b52d57SBarry Smith /*@C 88707b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo - Frees the memory allocated by ISLocalToGlobalMappingGetInfo() 88889d82c54SBarry Smith 88907b52d57SBarry Smith Collective on ISLocalToGlobalMapping 89007b52d57SBarry Smith 89107b52d57SBarry Smith Input Parameters: 89207b52d57SBarry Smith . mapping - the mapping from local to global indexing 89307b52d57SBarry Smith 89407b52d57SBarry Smith Output Parameter: 89507b52d57SBarry Smith + nproc - number of processors that are connected to this one 89607b52d57SBarry Smith . proc - neighboring processors 89707b52d57SBarry Smith . numproc - number of indices for each processor 89807b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 89907b52d57SBarry Smith 90007b52d57SBarry Smith Level: advanced 90107b52d57SBarry Smith 90207b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 90307b52d57SBarry Smith ISLocalToGlobalMappingGetInfo() 90407b52d57SBarry Smith @*/ 905*ca01db9bSBarry Smith int ISLocalToGlobalMappingRestoreInfo(ISLocalToGlobalMapping mapping,int *nproc,int *procs[],int *numprocs[],int **indices[]) 90607b52d57SBarry Smith { 90707b52d57SBarry Smith int ierr,i; 90807b52d57SBarry Smith 90907b52d57SBarry Smith PetscFunctionBegin; 91000ff320aSBarry Smith if (*procs) {ierr = PetscFree(*procs);CHKERRQ(ierr);} 91100ff320aSBarry Smith if (*numprocs) {ierr = PetscFree(*numprocs);CHKERRQ(ierr);} 91200ff320aSBarry Smith if (*indices) { 91300ff320aSBarry Smith if ((*indices)[0]) {ierr = PetscFree((*indices)[0]);CHKERRQ(ierr);} 91400ff320aSBarry Smith for (i=1; i<*nproc; i++) { 91524cf384cSBarry Smith if ((*indices)[i]) {ierr = PetscFree((*indices)[i]);CHKERRQ(ierr);} 91607b52d57SBarry Smith } 91707b52d57SBarry Smith ierr = PetscFree(*indices);CHKERRQ(ierr); 91824cf384cSBarry Smith } 91907b52d57SBarry Smith PetscFunctionReturn(0); 92007b52d57SBarry Smith } 92189d82c54SBarry Smith 922bc8ff85bSBarry Smith 923bc8ff85bSBarry Smith 924bc8ff85bSBarry Smith 925bc8ff85bSBarry Smith 926bc8ff85bSBarry Smith 927bc8ff85bSBarry Smith 928bc8ff85bSBarry Smith 929bc8ff85bSBarry Smith 930bc8ff85bSBarry Smith 931bc8ff85bSBarry Smith 932bc8ff85bSBarry Smith 933bc8ff85bSBarry Smith 934bc8ff85bSBarry Smith 935bc8ff85bSBarry Smith 936bc8ff85bSBarry Smith 937bc8ff85bSBarry Smith 93824cf384cSBarry Smith 939