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 6*8e58c17dSMatthew Knepley EXTERN int VecInitializePackage(char *); 7*8e58c17dSMatthew 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 1134a2ae208SSatish Balay #undef __FUNCT__ 1144a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreate" 115dd7157adSSatish Balay /*@C 11690f02eecSBarry Smith ISLocalToGlobalMappingCreate - Creates a mapping between a local (0 to n) 11790f02eecSBarry Smith ordering and a global parallel ordering. 1182362add9SBarry Smith 11989d82c54SBarry Smith Not Collective, but communicator may have more than one process 120b9cd556bSLois Curfman McInnes 1212362add9SBarry Smith Input Parameters: 12289d82c54SBarry Smith + comm - MPI communicator 12390f02eecSBarry Smith . n - the number of local elements 124b9cd556bSLois Curfman McInnes - indices - the global index for each local element 1252362add9SBarry Smith 126a997ad1aSLois Curfman McInnes Output Parameter: 12790f02eecSBarry Smith . mapping - new mapping data structure 1282362add9SBarry Smith 129a997ad1aSLois Curfman McInnes Level: advanced 130a997ad1aSLois Curfman McInnes 131273d9f13SBarry Smith Concepts: mapping^local to global 1322362add9SBarry Smith 1332bdab257SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS() 1342362add9SBarry Smith @*/ 135987e4450SSatish Balay int ISLocalToGlobalMappingCreate(MPI_Comm cm,int n,const int indices[],ISLocalToGlobalMapping *mapping) 1362362add9SBarry Smith { 137549d3d68SSatish Balay int ierr; 138549d3d68SSatish Balay 1393a40ed3dSBarry Smith PetscFunctionBegin; 14090f02eecSBarry Smith PetscValidIntPointer(indices); 14190f02eecSBarry Smith PetscValidPointer(mapping); 142*8e58c17dSMatthew Knepley *mapping = PETSC_NULL; 143*8e58c17dSMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 144*8e58c17dSMatthew Knepley ierr = VecInitializePackage(PETSC_NULL); CHKERRQ(ierr); 145*8e58c17dSMatthew Knepley #endif 1462362add9SBarry Smith 1473f1db9ecSBarry Smith PetscHeaderCreate(*mapping,_p_ISLocalToGlobalMapping,int,IS_LTOGM_COOKIE,0,"ISLocalToGlobalMapping", 1483f1db9ecSBarry Smith cm,ISLocalToGlobalMappingDestroy,ISLocalToGlobalMappingView); 149b0a32e0cSBarry Smith PetscLogObjectCreate(*mapping); 150b0a32e0cSBarry Smith PetscLogObjectMemory(*mapping,sizeof(struct _p_ISLocalToGlobalMapping)+n*sizeof(int)); 151d4bb536fSBarry Smith 152d4bb536fSBarry Smith (*mapping)->n = n; 153b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(int),&(*mapping)->indices);CHKERRQ(ierr); 154549d3d68SSatish Balay ierr = PetscMemcpy((*mapping)->indices,indices,n*sizeof(int));CHKERRQ(ierr); 155d4bb536fSBarry Smith 156d4bb536fSBarry Smith /* 157d4bb536fSBarry Smith Do not create the global to local mapping. This is only created if 158d4bb536fSBarry Smith ISGlobalToLocalMapping() is called 159d4bb536fSBarry Smith */ 160d4bb536fSBarry Smith (*mapping)->globals = 0; 1613a40ed3dSBarry Smith PetscFunctionReturn(0); 1622362add9SBarry Smith } 1632362add9SBarry Smith 1644a2ae208SSatish Balay #undef __FUNCT__ 1654a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingBlock" 166323b833fSBarry Smith /*@C 167323b833fSBarry Smith ISLocalToGlobalMappingBlock - Creates a blocked index version of an 168323b833fSBarry Smith ISLocalToGlobalMapping that is appropriate for MatSetLocalToGlobalMappingBlock() 169323b833fSBarry Smith and VecSetLocalToGlobalMappingBlock(). 170323b833fSBarry Smith 171323b833fSBarry Smith Not Collective, but communicator may have more than one process 172323b833fSBarry Smith 173323b833fSBarry Smith Input Parameters: 174323b833fSBarry Smith + inmap - original point-wise mapping 175323b833fSBarry Smith - bs - block size 176323b833fSBarry Smith 177323b833fSBarry Smith Output Parameter: 178323b833fSBarry Smith . outmap - block based mapping 179323b833fSBarry Smith 180323b833fSBarry Smith Level: advanced 181323b833fSBarry Smith 182323b833fSBarry Smith Concepts: mapping^local to global 183323b833fSBarry Smith 184323b833fSBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingCreateIS() 185323b833fSBarry Smith @*/ 186323b833fSBarry Smith int ISLocalToGlobalMappingBlock(ISLocalToGlobalMapping inmap,int bs,ISLocalToGlobalMapping *outmap) 187323b833fSBarry Smith { 188323b833fSBarry Smith int ierr,*ii,i,n; 189323b833fSBarry Smith 190323b833fSBarry Smith PetscFunctionBegin; 191323b833fSBarry Smith 192323b833fSBarry Smith if (bs > 1) { 193323b833fSBarry Smith n = inmap->n/bs; 194323b833fSBarry Smith ierr = PetscMalloc(n*sizeof(int),&ii);CHKERRQ(ierr); 195323b833fSBarry Smith for (i=0; i<n; i++) { 196b8ee7809SBarry Smith ii[i] = inmap->indices[bs*i]/bs; 197323b833fSBarry Smith } 198323b833fSBarry Smith ierr = ISLocalToGlobalMappingCreate(inmap->comm,n,ii,outmap);CHKERRQ(ierr); 199323b833fSBarry Smith ierr = PetscFree(ii);CHKERRQ(ierr); 200323b833fSBarry Smith } else { 201323b833fSBarry Smith *outmap = inmap; 202323b833fSBarry Smith ierr = PetscObjectReference((PetscObject)inmap);CHKERRQ(ierr); 203323b833fSBarry Smith } 204323b833fSBarry Smith PetscFunctionReturn(0); 205323b833fSBarry Smith } 206323b833fSBarry Smith 2074a2ae208SSatish Balay #undef __FUNCT__ 2084a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingDestroy" 20990f02eecSBarry Smith /*@ 21090f02eecSBarry Smith ISLocalToGlobalMappingDestroy - Destroys a mapping between a local (0 to n) 21190f02eecSBarry Smith ordering and a global parallel ordering. 21290f02eecSBarry Smith 2130f5bd95cSBarry Smith Note Collective 214b9cd556bSLois Curfman McInnes 21590f02eecSBarry Smith Input Parameters: 21690f02eecSBarry Smith . mapping - mapping data structure 21790f02eecSBarry Smith 218a997ad1aSLois Curfman McInnes Level: advanced 219a997ad1aSLois Curfman McInnes 2203acfe500SLois Curfman McInnes .seealso: ISLocalToGlobalMappingCreate() 22190f02eecSBarry Smith @*/ 22290f02eecSBarry Smith int ISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping mapping) 22390f02eecSBarry Smith { 224606d414cSSatish Balay int ierr; 2253a40ed3dSBarry Smith PetscFunctionBegin; 22690f02eecSBarry Smith PetscValidPointer(mapping); 2273a40ed3dSBarry Smith if (--mapping->refct > 0) PetscFunctionReturn(0); 22885614651SBarry Smith if (mapping->refct < 0) { 22929bbc08cSBarry Smith SETERRQ(1,"Mapping already destroyed"); 23085614651SBarry Smith } 23190f02eecSBarry Smith 232606d414cSSatish Balay ierr = PetscFree(mapping->indices);CHKERRQ(ierr); 233606d414cSSatish Balay if (mapping->globals) {ierr = PetscFree(mapping->globals);CHKERRQ(ierr);} 234b0a32e0cSBarry Smith PetscLogObjectDestroy(mapping); 235d4bb536fSBarry Smith PetscHeaderDestroy(mapping); 2363a40ed3dSBarry Smith PetscFunctionReturn(0); 23790f02eecSBarry Smith } 23890f02eecSBarry Smith 2394a2ae208SSatish Balay #undef __FUNCT__ 2404a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingApplyIS" 24190f02eecSBarry Smith /*@ 2423acfe500SLois Curfman McInnes ISLocalToGlobalMappingApplyIS - Creates from an IS in the local numbering 2433acfe500SLois Curfman McInnes a new index set using the global numbering defined in an ISLocalToGlobalMapping 2443acfe500SLois Curfman McInnes context. 24590f02eecSBarry Smith 246b9cd556bSLois Curfman McInnes Not collective 247b9cd556bSLois Curfman McInnes 24890f02eecSBarry Smith Input Parameters: 249b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 250b9cd556bSLois Curfman McInnes - is - index set in local numbering 25190f02eecSBarry Smith 25290f02eecSBarry Smith Output Parameters: 25390f02eecSBarry Smith . newis - index set in global numbering 25490f02eecSBarry Smith 255a997ad1aSLois Curfman McInnes Level: advanced 256a997ad1aSLois Curfman McInnes 257273d9f13SBarry Smith Concepts: mapping^local to global 2583acfe500SLois Curfman McInnes 25990f02eecSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 260d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy(), ISGlobalToLocalMappingApply() 26190f02eecSBarry Smith @*/ 26290f02eecSBarry Smith int ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping mapping,IS is,IS *newis) 26390f02eecSBarry Smith { 2643b9aefa3SBarry Smith int ierr,n,i,*idxin,*idxmap,*idxout,Nmax = mapping->n; 2653a40ed3dSBarry Smith 2663a40ed3dSBarry Smith PetscFunctionBegin; 26790f02eecSBarry Smith PetscValidPointer(mapping); 26890f02eecSBarry Smith PetscValidHeaderSpecific(is,IS_COOKIE); 26990f02eecSBarry Smith PetscValidPointer(newis); 27090f02eecSBarry Smith 2713b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 27290f02eecSBarry Smith ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 27390f02eecSBarry Smith idxmap = mapping->indices; 27490f02eecSBarry Smith 275b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(int),&idxout);CHKERRQ(ierr); 27690f02eecSBarry Smith for (i=0; i<n; i++) { 27729bbc08cSBarry Smith if (idxin[i] >= Nmax) SETERRQ3(PETSC_ERR_ARG_OUTOFRANGE,"Local index %d too large %d (max) at %d",idxin[i],Nmax,i); 27890f02eecSBarry Smith idxout[i] = idxmap[idxin[i]]; 27990f02eecSBarry Smith } 2803b9aefa3SBarry Smith ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 281029af93fSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxout,newis);CHKERRQ(ierr); 282606d414cSSatish Balay ierr = PetscFree(idxout);CHKERRQ(ierr); 2833a40ed3dSBarry Smith PetscFunctionReturn(0); 28490f02eecSBarry Smith } 28590f02eecSBarry Smith 28689d82c54SBarry Smith /*MC 2873acfe500SLois Curfman McInnes ISLocalToGlobalMappingApply - Takes a list of integers in a local numbering 2883acfe500SLois Curfman McInnes and converts them to the global numbering. 28990f02eecSBarry Smith 290b9cd556bSLois Curfman McInnes Not collective 291b9cd556bSLois Curfman McInnes 292bb25748dSBarry Smith Input Parameters: 293b9cd556bSLois Curfman McInnes + mapping - the local to global mapping context 294bb25748dSBarry Smith . N - number of integers 295b9cd556bSLois Curfman McInnes - in - input indices in local numbering 296bb25748dSBarry Smith 297bb25748dSBarry Smith Output Parameter: 298bb25748dSBarry Smith . out - indices in global numbering 299bb25748dSBarry Smith 3003b9aefa3SBarry Smith Synopsis: 301216e7ba4SBarry Smith int ISLocalToGlobalMappingApply(ISLocalToGlobalMapping mapping,int N,int in[],int out[]) 3023b9aefa3SBarry Smith 303b9cd556bSLois Curfman McInnes Notes: 304b9cd556bSLois Curfman McInnes The in and out array parameters may be identical. 305d4bb536fSBarry Smith 306a997ad1aSLois Curfman McInnes Level: advanced 307a997ad1aSLois Curfman McInnes 308bb25748dSBarry Smith .seealso: ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 3090752156aSBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 310d4bb536fSBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 311bb25748dSBarry Smith 312273d9f13SBarry Smith Concepts: mapping^local to global 313d4bb536fSBarry Smith 31489d82c54SBarry Smith M*/ 315d4bb536fSBarry Smith 316d4bb536fSBarry Smith /* -----------------------------------------------------------------------------------------*/ 317d4bb536fSBarry Smith 3184a2ae208SSatish Balay #undef __FUNCT__ 3194a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingSetUp_Private" 320d4bb536fSBarry Smith /* 321d4bb536fSBarry Smith Creates the global fields in the ISLocalToGlobalMapping structure 322d4bb536fSBarry Smith */ 323d4bb536fSBarry Smith static int ISGlobalToLocalMappingSetUp_Private(ISLocalToGlobalMapping mapping) 324d4bb536fSBarry Smith { 325b0a32e0cSBarry Smith int ierr,i,*idx = mapping->indices,n = mapping->n,end,start,*globals; 326d4bb536fSBarry Smith 3273a40ed3dSBarry Smith PetscFunctionBegin; 328d4bb536fSBarry Smith end = 0; 329d4bb536fSBarry Smith start = 100000000; 330d4bb536fSBarry Smith 331d4bb536fSBarry Smith for (i=0; i<n; i++) { 332d4bb536fSBarry Smith if (idx[i] < 0) continue; 333d4bb536fSBarry Smith if (idx[i] < start) start = idx[i]; 334d4bb536fSBarry Smith if (idx[i] > end) end = idx[i]; 335d4bb536fSBarry Smith } 336d4bb536fSBarry Smith if (start > end) {start = 0; end = -1;} 337d4bb536fSBarry Smith mapping->globalstart = start; 338d4bb536fSBarry Smith mapping->globalend = end; 339d4bb536fSBarry Smith 340b0a32e0cSBarry Smith ierr = PetscMalloc((end-start+2)*sizeof(int),&globals);CHKERRQ(ierr); 341b0a32e0cSBarry Smith mapping->globals = globals; 342d4bb536fSBarry Smith for (i=0; i<end-start+1; i++) { 343d4bb536fSBarry Smith globals[i] = -1; 344d4bb536fSBarry Smith } 345d4bb536fSBarry Smith for (i=0; i<n; i++) { 346d4bb536fSBarry Smith if (idx[i] < 0) continue; 347d4bb536fSBarry Smith globals[idx[i] - start] = i; 348d4bb536fSBarry Smith } 349d4bb536fSBarry Smith 350b0a32e0cSBarry Smith PetscLogObjectMemory(mapping,(end-start+1)*sizeof(int)); 3513a40ed3dSBarry Smith PetscFunctionReturn(0); 352d4bb536fSBarry Smith } 353d4bb536fSBarry Smith 3544a2ae208SSatish Balay #undef __FUNCT__ 3554a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingApply" 356d4bb536fSBarry Smith /*@ 357a997ad1aSLois Curfman McInnes ISGlobalToLocalMappingApply - Provides the local numbering for a list of integers 358a997ad1aSLois Curfman McInnes specified with a global numbering. 359d4bb536fSBarry Smith 360b9cd556bSLois Curfman McInnes Not collective 361b9cd556bSLois Curfman McInnes 362d4bb536fSBarry Smith Input Parameters: 363b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 364d4bb536fSBarry Smith . type - IS_GTOLM_MASK - replaces global indices with no local value with -1 365d4bb536fSBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 366d4bb536fSBarry Smith . n - number of global indices to map 367b9cd556bSLois Curfman McInnes - idx - global indices to map 368d4bb536fSBarry Smith 369d4bb536fSBarry Smith Output Parameters: 370b9cd556bSLois Curfman McInnes + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 371b9cd556bSLois Curfman McInnes - idxout - local index of each global index, one must pass in an array long enough 372e182c471SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApply() with 373e182c471SBarry Smith idxout == PETSC_NULL to determine the required length (returned in nout) 374e182c471SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApply() 375e182c471SBarry Smith a second time to set the values. 376d4bb536fSBarry Smith 377b9cd556bSLois Curfman McInnes Notes: 378b9cd556bSLois Curfman McInnes Either nout or idxout may be PETSC_NULL. idx and idxout may be identical. 379d4bb536fSBarry Smith 3800f5bd95cSBarry Smith This is not scalable in memory usage. Each processor requires O(Nglobal) size 3810f5bd95cSBarry Smith array to compute these. 3820f5bd95cSBarry Smith 383a997ad1aSLois Curfman McInnes Level: advanced 384a997ad1aSLois Curfman McInnes 385273d9f13SBarry Smith Concepts: mapping^global to local 386d4bb536fSBarry Smith 387d4bb536fSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 388d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy() 389d4bb536fSBarry Smith @*/ 390d4bb536fSBarry Smith int ISGlobalToLocalMappingApply(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, 391987e4450SSatish Balay int n,const int idx[],int *nout,int idxout[]) 392d4bb536fSBarry Smith { 393d4bb536fSBarry Smith int i,ierr,*globals,nf = 0,tmp,start,end; 394d4bb536fSBarry Smith 3953a40ed3dSBarry Smith PetscFunctionBegin; 396d4bb536fSBarry Smith if (!mapping->globals) { 397d4bb536fSBarry Smith ierr = ISGlobalToLocalMappingSetUp_Private(mapping);CHKERRQ(ierr); 398d4bb536fSBarry Smith } 399d4bb536fSBarry Smith globals = mapping->globals; 400d4bb536fSBarry Smith start = mapping->globalstart; 401d4bb536fSBarry Smith end = mapping->globalend; 402d4bb536fSBarry Smith 403d4bb536fSBarry Smith if (type == IS_GTOLM_MASK) { 404d4bb536fSBarry Smith if (idxout) { 405d4bb536fSBarry Smith for (i=0; i<n; i++) { 406d4bb536fSBarry Smith if (idx[i] < 0) idxout[i] = idx[i]; 407d4bb536fSBarry Smith else if (idx[i] < start) idxout[i] = -1; 408d4bb536fSBarry Smith else if (idx[i] > end) idxout[i] = -1; 409d4bb536fSBarry Smith else idxout[i] = globals[idx[i] - start]; 410d4bb536fSBarry Smith } 411d4bb536fSBarry Smith } 412d4bb536fSBarry Smith if (nout) *nout = n; 413d4bb536fSBarry Smith } else { 414d4bb536fSBarry Smith if (idxout) { 415d4bb536fSBarry Smith for (i=0; i<n; i++) { 416d4bb536fSBarry Smith if (idx[i] < 0) continue; 417d4bb536fSBarry Smith if (idx[i] < start) continue; 418d4bb536fSBarry Smith if (idx[i] > end) continue; 419d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 420d4bb536fSBarry Smith if (tmp < 0) continue; 421d4bb536fSBarry Smith idxout[nf++] = tmp; 422d4bb536fSBarry Smith } 423d4bb536fSBarry Smith } else { 424d4bb536fSBarry Smith for (i=0; i<n; i++) { 425d4bb536fSBarry Smith if (idx[i] < 0) continue; 426d4bb536fSBarry Smith if (idx[i] < start) continue; 427d4bb536fSBarry Smith if (idx[i] > end) continue; 428d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 429d4bb536fSBarry Smith if (tmp < 0) continue; 430d4bb536fSBarry Smith nf++; 431d4bb536fSBarry Smith } 432d4bb536fSBarry Smith } 433d4bb536fSBarry Smith if (nout) *nout = nf; 434d4bb536fSBarry Smith } 435d4bb536fSBarry Smith 4363a40ed3dSBarry Smith PetscFunctionReturn(0); 437d4bb536fSBarry Smith } 43890f02eecSBarry Smith 4394a2ae208SSatish Balay #undef __FUNCT__ 4404a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingGetInfo" 44189d82c54SBarry Smith /*@C 44289d82c54SBarry Smith ISLocalToGlobalMappingGetInfo - Gets the neighbor information for each processor and 44389d82c54SBarry Smith each index shared by more than one processor 44489d82c54SBarry Smith 44589d82c54SBarry Smith Collective on ISLocalToGlobalMapping 44689d82c54SBarry Smith 44789d82c54SBarry Smith Input Parameters: 44889d82c54SBarry Smith . mapping - the mapping from local to global indexing 44989d82c54SBarry Smith 45089d82c54SBarry Smith Output Parameter: 45189d82c54SBarry Smith + nproc - number of processors that are connected to this one 45289d82c54SBarry Smith . proc - neighboring processors 45307b52d57SBarry Smith . numproc - number of indices for each subdomain (processor) 45407b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 45589d82c54SBarry Smith 45689d82c54SBarry Smith Level: advanced 45789d82c54SBarry Smith 458273d9f13SBarry Smith Concepts: mapping^local to global 45989d82c54SBarry Smith 46007b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 46107b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo() 46289d82c54SBarry Smith @*/ 46330dcb7c9SBarry Smith int ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping mapping,int *nproc,int **procs,int **numprocs,int ***indices) 46489d82c54SBarry Smith { 465fa7fbcffSSatish Balay int i,n = mapping->n,ierr,Ng,ng,max = 0,*lindices = mapping->indices; 4663a96401aSBarry Smith int size,rank,*nprocs,*owner,nsends,*sends,j,*starts,*work,nmax,nrecvs,*recvs,proc; 46724cf384cSBarry Smith int tag1,tag2,tag3,cnt,*len,*source,imdex,scale,*ownedsenders,*nownedsenders,rstart,nowned; 46807b52d57SBarry Smith int node,nownedm,nt,*sends2,nsends2,*starts2,*lens2,*dest,nrecvs2,*starts3,*recvs2,k,*bprocs,*tmp; 46924cf384cSBarry Smith int first_procs,first_numprocs,*first_indices; 47089d82c54SBarry Smith MPI_Request *recv_waits,*send_waits; 47130dcb7c9SBarry Smith MPI_Status recv_status,*send_status,*recv_statuses; 47289d82c54SBarry Smith MPI_Comm comm = mapping->comm; 47307b52d57SBarry Smith PetscTruth debug = PETSC_FALSE; 47489d82c54SBarry Smith 47589d82c54SBarry Smith PetscFunctionBegin; 47624cf384cSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 47724cf384cSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 47824cf384cSBarry Smith if (size == 1) { 47924cf384cSBarry Smith *nproc = 0; 48024cf384cSBarry Smith *procs = PETSC_NULL; 481b0a32e0cSBarry Smith ierr = PetscMalloc(sizeof(int),numprocs);CHKERRQ(ierr); 4821e2105dcSBarry Smith (*numprocs)[0] = 0; 483b0a32e0cSBarry Smith ierr = PetscMalloc(sizeof(int*),indices);CHKERRQ(ierr); 4841e2105dcSBarry Smith (*indices)[0] = PETSC_NULL; 48524cf384cSBarry Smith PetscFunctionReturn(0); 48624cf384cSBarry Smith } 48724cf384cSBarry Smith 488b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-islocaltoglobalmappinggetinfo_debug",&debug);CHKERRQ(ierr); 48907b52d57SBarry Smith 4903677ff5aSBarry Smith /* 4913677ff5aSBarry Smith Notes on ISLocalToGlobalMappingGetInfo 4923677ff5aSBarry Smith 4933677ff5aSBarry Smith globally owned node - the nodes that have been assigned to this processor in global 4943677ff5aSBarry Smith numbering, just for this routine. 4953677ff5aSBarry Smith 4963677ff5aSBarry Smith nontrivial globally owned node - node assigned to this processor that is on a subdomain 4973677ff5aSBarry Smith boundary (i.e. is has more than one local owner) 4983677ff5aSBarry Smith 4993677ff5aSBarry Smith locally owned node - node that exists on this processors subdomain 5003677ff5aSBarry Smith 5013677ff5aSBarry Smith nontrivial locally owned node - node that is not in the interior (i.e. has more than one 5023677ff5aSBarry Smith local subdomain 5033677ff5aSBarry Smith */ 50424cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag1);CHKERRQ(ierr); 50524cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag2);CHKERRQ(ierr); 50624cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag3);CHKERRQ(ierr); 50789d82c54SBarry Smith 50889d82c54SBarry Smith for (i=0; i<n; i++) { 50989d82c54SBarry Smith if (lindices[i] > max) max = lindices[i]; 51089d82c54SBarry Smith } 51189d82c54SBarry Smith ierr = MPI_Allreduce(&max,&Ng,1,MPI_INT,MPI_MAX,comm);CHKERRQ(ierr); 51278058e43SBarry Smith Ng++; 51389d82c54SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 51489d82c54SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 515bc8ff85bSBarry Smith scale = Ng/size + 1; 516a2e34c3dSBarry Smith ng = scale; if (rank == size-1) ng = Ng - scale*(size-1); ng = PetscMax(1,ng); 517caba0dd0SBarry Smith rstart = scale*rank; 51889d82c54SBarry Smith 51989d82c54SBarry Smith /* determine ownership ranges of global indices */ 520b0a32e0cSBarry Smith ierr = PetscMalloc((2*size+1)*sizeof(int),&nprocs);CHKERRQ(ierr); 5212880cf29SBarry Smith ierr = PetscMemzero(nprocs,2*size*sizeof(int));CHKERRQ(ierr); 52289d82c54SBarry Smith 52389d82c54SBarry Smith /* determine owners of each local node */ 524b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(int),&owner);CHKERRQ(ierr); 52589d82c54SBarry Smith for (i=0; i<n; i++) { 5263677ff5aSBarry Smith proc = lindices[i]/scale; /* processor that globally owns this index */ 5273677ff5aSBarry Smith nprocs[size+proc] = 1; /* processor globally owns at least one of ours */ 5283677ff5aSBarry Smith owner[i] = proc; 5293677ff5aSBarry Smith nprocs[proc]++; /* count of how many that processor globally owns of ours */ 53089d82c54SBarry Smith } 53189d82c54SBarry Smith nsends = 0; for (i=0; i<size; i++) nsends += nprocs[size + i]; 532b0a32e0cSBarry Smith PetscLogInfo(0,"ISLocalToGlobalMappingGetInfo: Number of global owners for my local data %d\n",nsends); 53389d82c54SBarry Smith 53489d82c54SBarry Smith /* inform other processors of number of messages and max length*/ 535b0a32e0cSBarry Smith ierr = PetscMalloc(2*size*sizeof(int),&work);CHKERRQ(ierr); 53689d82c54SBarry Smith ierr = MPI_Allreduce(nprocs,work,2*size,MPI_INT,PetscMaxSum_Op,comm);CHKERRQ(ierr); 53789d82c54SBarry Smith nmax = work[rank]; 53889d82c54SBarry Smith nrecvs = work[size+rank]; 53989d82c54SBarry Smith ierr = PetscFree(work);CHKERRQ(ierr); 540b0a32e0cSBarry Smith PetscLogInfo(0,"ISLocalToGlobalMappingGetInfo: Number of local owners for my global data %d\n",nrecvs); 54189d82c54SBarry Smith 54289d82c54SBarry Smith /* post receives for owned rows */ 543b0a32e0cSBarry Smith ierr = PetscMalloc((2*nrecvs+1)*(nmax+1)*sizeof(int),&recvs);CHKERRQ(ierr); 544b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs+1)*sizeof(MPI_Request),&recv_waits);CHKERRQ(ierr); 54589d82c54SBarry Smith for (i=0; i<nrecvs; i++) { 54624cf384cSBarry Smith ierr = MPI_Irecv(recvs+2*nmax*i,2*nmax,MPI_INT,MPI_ANY_SOURCE,tag1,comm,recv_waits+i);CHKERRQ(ierr); 54789d82c54SBarry Smith } 54889d82c54SBarry Smith 54989d82c54SBarry Smith /* pack messages containing lists of local nodes to owners */ 550b0a32e0cSBarry Smith ierr = PetscMalloc((2*n+1)*sizeof(int),&sends);CHKERRQ(ierr); 551b0a32e0cSBarry Smith ierr = PetscMalloc((size+1)*sizeof(int),&starts);CHKERRQ(ierr); 55289d82c54SBarry Smith starts[0] = 0; 55330dcb7c9SBarry Smith for (i=1; i<size; i++) { starts[i] = starts[i-1] + 2*nprocs[i-1];} 55489d82c54SBarry Smith for (i=0; i<n; i++) { 55589d82c54SBarry Smith sends[starts[owner[i]]++] = lindices[i]; 55630dcb7c9SBarry Smith sends[starts[owner[i]]++] = i; 55789d82c54SBarry Smith } 55889d82c54SBarry Smith ierr = PetscFree(owner);CHKERRQ(ierr); 55989d82c54SBarry Smith starts[0] = 0; 56030dcb7c9SBarry Smith for (i=1; i<size; i++) { starts[i] = starts[i-1] + 2*nprocs[i-1];} 56189d82c54SBarry Smith 56289d82c54SBarry Smith /* send the messages */ 563b0a32e0cSBarry Smith ierr = PetscMalloc((nsends+1)*sizeof(MPI_Request),&send_waits);CHKERRQ(ierr); 564b0a32e0cSBarry Smith ierr = PetscMalloc((nsends+1)*sizeof(int),&dest);CHKERRQ(ierr); 56589d82c54SBarry Smith cnt = 0; 56689d82c54SBarry Smith for (i=0; i<size; i++) { 56789d82c54SBarry Smith if (nprocs[i]) { 56824cf384cSBarry Smith ierr = MPI_Isend(sends+starts[i],2*nprocs[i],MPI_INT,i,tag1,comm,send_waits+cnt);CHKERRQ(ierr); 56930dcb7c9SBarry Smith dest[cnt] = i; 57089d82c54SBarry Smith cnt++; 57189d82c54SBarry Smith } 57289d82c54SBarry Smith } 57389d82c54SBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 57489d82c54SBarry Smith 57589d82c54SBarry Smith /* wait on receives */ 576b0a32e0cSBarry Smith ierr = PetscMalloc((2*nrecvs+1)*sizeof(int),&source);CHKERRQ(ierr); 57789d82c54SBarry Smith len = source + nrecvs; 57889d82c54SBarry Smith cnt = nrecvs; 579b0a32e0cSBarry Smith ierr = PetscMalloc((ng+1)*sizeof(int),&nownedsenders);CHKERRQ(ierr); 580caba0dd0SBarry Smith ierr = PetscMemzero(nownedsenders,ng*sizeof(int));CHKERRQ(ierr); 58189d82c54SBarry Smith while (cnt) { 58289d82c54SBarry Smith ierr = MPI_Waitany(nrecvs,recv_waits,&imdex,&recv_status);CHKERRQ(ierr); 58389d82c54SBarry Smith /* unpack receives into our local space */ 58489d82c54SBarry Smith ierr = MPI_Get_count(&recv_status,MPI_INT,&len[imdex]);CHKERRQ(ierr); 58589d82c54SBarry Smith source[imdex] = recv_status.MPI_SOURCE; 58630dcb7c9SBarry Smith len[imdex] = len[imdex]/2; 587caba0dd0SBarry Smith /* count how many local owners for each of my global owned indices */ 58830dcb7c9SBarry Smith for (i=0; i<len[imdex]; i++) nownedsenders[recvs[2*imdex*nmax+2*i]-rstart]++; 58989d82c54SBarry Smith cnt--; 59089d82c54SBarry Smith } 59189d82c54SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 59289d82c54SBarry Smith 59330dcb7c9SBarry Smith /* count how many globally owned indices are on an edge multiplied by how many processors own them. */ 594bc8ff85bSBarry Smith nowned = 0; 595bc8ff85bSBarry Smith nownedm = 0; 596bc8ff85bSBarry Smith for (i=0; i<ng; i++) { 597bc8ff85bSBarry Smith if (nownedsenders[i] > 1) {nownedm += nownedsenders[i]; nowned++;} 598bc8ff85bSBarry Smith } 599bc8ff85bSBarry Smith 600bc8ff85bSBarry Smith /* create single array to contain rank of all local owners of each globally owned index */ 601b0a32e0cSBarry Smith ierr = PetscMalloc((nownedm+1)*sizeof(int),&ownedsenders);CHKERRQ(ierr); 602b0a32e0cSBarry Smith ierr = PetscMalloc((ng+1)*sizeof(int),&starts);CHKERRQ(ierr); 603bc8ff85bSBarry Smith starts[0] = 0; 604bc8ff85bSBarry Smith for (i=1; i<ng; i++) { 605bc8ff85bSBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 606bc8ff85bSBarry Smith else starts[i] = starts[i-1]; 607bc8ff85bSBarry Smith } 608bc8ff85bSBarry Smith 60930dcb7c9SBarry Smith /* for each nontrival globally owned node list all arriving processors */ 610bc8ff85bSBarry Smith for (i=0; i<nrecvs; i++) { 611bc8ff85bSBarry Smith for (j=0; j<len[i]; j++) { 61230dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 613bc8ff85bSBarry Smith if (nownedsenders[node] > 1) { 614bc8ff85bSBarry Smith ownedsenders[starts[node]++] = source[i]; 615bc8ff85bSBarry Smith } 616bc8ff85bSBarry Smith } 617bc8ff85bSBarry Smith } 618bc8ff85bSBarry Smith 61907b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 62030dcb7c9SBarry Smith starts[0] = 0; 62130dcb7c9SBarry Smith for (i=1; i<ng; i++) { 62230dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 62330dcb7c9SBarry Smith else starts[i] = starts[i-1]; 62430dcb7c9SBarry Smith } 62530dcb7c9SBarry Smith for (i=0; i<ng; i++) { 62630dcb7c9SBarry Smith if (nownedsenders[i] > 1) { 62730dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] global node %d local owner processors: ",rank,i+rstart);CHKERRQ(ierr); 62830dcb7c9SBarry Smith for (j=0; j<nownedsenders[i]; j++) { 62930dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",ownedsenders[starts[i]+j]);CHKERRQ(ierr); 63030dcb7c9SBarry Smith } 63130dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 63230dcb7c9SBarry Smith } 63330dcb7c9SBarry Smith } 63430dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 63507b52d57SBarry Smith }/* ----------------------------------- */ 63630dcb7c9SBarry Smith 6373677ff5aSBarry Smith /* wait on original sends */ 6383a96401aSBarry Smith if (nsends) { 639b0a32e0cSBarry Smith ierr = PetscMalloc(nsends*sizeof(MPI_Status),&send_status);CHKERRQ(ierr); 6403a96401aSBarry Smith ierr = MPI_Waitall(nsends,send_waits,send_status);CHKERRQ(ierr); 6413a96401aSBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 6423a96401aSBarry Smith } 64389d82c54SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 6443a96401aSBarry Smith ierr = PetscFree(sends);CHKERRQ(ierr); 6453677ff5aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 6463677ff5aSBarry Smith 6473677ff5aSBarry Smith /* pack messages to send back to local owners */ 64830dcb7c9SBarry Smith starts[0] = 0; 64930dcb7c9SBarry Smith for (i=1; i<ng; i++) { 65030dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 65130dcb7c9SBarry Smith else starts[i] = starts[i-1]; 65230dcb7c9SBarry Smith } 65330dcb7c9SBarry Smith nsends2 = nrecvs; 654b0a32e0cSBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(int),&nprocs);CHKERRQ(ierr); /* length of each message */ 65530dcb7c9SBarry Smith for (i=0; i<nrecvs; i++) { 65630dcb7c9SBarry Smith nprocs[i] = 1; 65730dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 65830dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 65930dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 66030dcb7c9SBarry Smith nprocs[i] += 2 + nownedsenders[node]; 66130dcb7c9SBarry Smith } 66230dcb7c9SBarry Smith } 66330dcb7c9SBarry Smith } 66430dcb7c9SBarry Smith nt = 0; for (i=0; i<nsends2; i++) nt += nprocs[i]; 665b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int),&sends2);CHKERRQ(ierr); 666b0a32e0cSBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(int),&starts2);CHKERRQ(ierr); 66730dcb7c9SBarry Smith starts2[0] = 0; for (i=1; i<nsends2; i++) starts2[i] = starts2[i-1] + nprocs[i-1]; 66830dcb7c9SBarry Smith /* 66930dcb7c9SBarry Smith Each message is 1 + nprocs[i] long, and consists of 67030dcb7c9SBarry Smith (0) the number of nodes being sent back 67130dcb7c9SBarry Smith (1) the local node number, 67230dcb7c9SBarry Smith (2) the number of processors sharing it, 67330dcb7c9SBarry Smith (3) the processors sharing it 67430dcb7c9SBarry Smith */ 67530dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 67630dcb7c9SBarry Smith cnt = 1; 67730dcb7c9SBarry Smith sends2[starts2[i]] = 0; 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 sends2[starts2[i]]++; 68230dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = recvs[2*i*nmax+2*j+1]; 68330dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = nownedsenders[node]; 68430dcb7c9SBarry Smith ierr = PetscMemcpy(&sends2[starts2[i]+cnt],&ownedsenders[starts[node]],nownedsenders[node]*sizeof(int));CHKERRQ(ierr); 68530dcb7c9SBarry Smith cnt += nownedsenders[node]; 68630dcb7c9SBarry Smith } 68730dcb7c9SBarry Smith } 68830dcb7c9SBarry Smith } 68930dcb7c9SBarry Smith 69030dcb7c9SBarry Smith /* send the message lengths */ 69130dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 69224cf384cSBarry Smith ierr = MPI_Send(&nprocs[i],1,MPI_INT,source[i],tag2,comm);CHKERRQ(ierr); 69330dcb7c9SBarry Smith } 69430dcb7c9SBarry Smith 69530dcb7c9SBarry Smith /* receive the message lengths */ 69630dcb7c9SBarry Smith nrecvs2 = nsends; 697b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(int),&lens2);CHKERRQ(ierr); 698b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(int),&starts3);CHKERRQ(ierr); 69930dcb7c9SBarry Smith nt = 0; 70030dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 70124cf384cSBarry Smith ierr = MPI_Recv(&lens2[i],1,MPI_INT,dest[i],tag2,comm,&recv_status);CHKERRQ(ierr); 70230dcb7c9SBarry Smith nt += lens2[i]; 70330dcb7c9SBarry Smith } 70430dcb7c9SBarry Smith starts3[0] = 0; 70530dcb7c9SBarry Smith for (i=0; i<nrecvs2-1; i++) { 70630dcb7c9SBarry Smith starts3[i+1] = starts3[i] + lens2[i]; 70730dcb7c9SBarry Smith } 708b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int),&recvs2);CHKERRQ(ierr); 709b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(MPI_Request),&recv_waits);CHKERRQ(ierr); 71052b72c4aSBarry Smith for (i=0; i<nrecvs2; i++) { 71124cf384cSBarry Smith ierr = MPI_Irecv(recvs2+starts3[i],lens2[i],MPI_INT,dest[i],tag3,comm,recv_waits+i);CHKERRQ(ierr); 71230dcb7c9SBarry Smith } 71330dcb7c9SBarry Smith 71430dcb7c9SBarry Smith /* send the messages */ 715b0a32e0cSBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(MPI_Request),&send_waits);CHKERRQ(ierr); 71630dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 71724cf384cSBarry Smith ierr = MPI_Isend(sends2+starts2[i],nprocs[i],MPI_INT,source[i],tag3,comm,send_waits+i);CHKERRQ(ierr); 71830dcb7c9SBarry Smith } 71930dcb7c9SBarry Smith 72030dcb7c9SBarry Smith /* wait on receives */ 721b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(MPI_Status),&recv_statuses);CHKERRQ(ierr); 72230dcb7c9SBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 72330dcb7c9SBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 72430dcb7c9SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 72530dcb7c9SBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 72630dcb7c9SBarry Smith 72707b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 72830dcb7c9SBarry Smith cnt = 0; 72930dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 73030dcb7c9SBarry Smith nt = recvs2[cnt++]; 73130dcb7c9SBarry Smith for (j=0; j<nt; j++) { 73230dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] local node %d number of subdomains %d: ",rank,recvs2[cnt],recvs2[cnt+1]);CHKERRQ(ierr); 73330dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 73430dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",recvs2[cnt+2+k]);CHKERRQ(ierr); 73530dcb7c9SBarry Smith } 73630dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 73730dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 73830dcb7c9SBarry Smith } 73930dcb7c9SBarry Smith } 74030dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 74107b52d57SBarry Smith } /* ----------------------------------- */ 74230dcb7c9SBarry Smith 74330dcb7c9SBarry Smith /* count number subdomains for each local node */ 744b0a32e0cSBarry Smith ierr = PetscMalloc(size*sizeof(int),&nprocs);CHKERRQ(ierr); 74530dcb7c9SBarry Smith ierr = PetscMemzero(nprocs,size*sizeof(int));CHKERRQ(ierr); 74630dcb7c9SBarry Smith cnt = 0; 74730dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 74830dcb7c9SBarry Smith nt = recvs2[cnt++]; 74930dcb7c9SBarry Smith for (j=0; j<nt; j++) { 75030dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 75130dcb7c9SBarry Smith nprocs[recvs2[cnt+2+k]]++; 75230dcb7c9SBarry Smith } 75330dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 75430dcb7c9SBarry Smith } 75530dcb7c9SBarry Smith } 75630dcb7c9SBarry Smith nt = 0; for (i=0; i<size; i++) nt += (nprocs[i] > 0); 75730dcb7c9SBarry Smith *nproc = nt; 758b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int),procs);CHKERRQ(ierr); 759b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int),numprocs);CHKERRQ(ierr); 760b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int*),indices);CHKERRQ(ierr); 761b0a32e0cSBarry Smith ierr = PetscMalloc(size*sizeof(int),&bprocs);CHKERRQ(ierr); 76230dcb7c9SBarry Smith cnt = 0; 76330dcb7c9SBarry Smith for (i=0; i<size; i++) { 76430dcb7c9SBarry Smith if (nprocs[i] > 0) { 76530dcb7c9SBarry Smith bprocs[i] = cnt; 76630dcb7c9SBarry Smith (*procs)[cnt] = i; 76730dcb7c9SBarry Smith (*numprocs)[cnt] = nprocs[i]; 768b0a32e0cSBarry Smith ierr = PetscMalloc(nprocs[i]*sizeof(int),&(*indices)[cnt]);CHKERRQ(ierr); 76930dcb7c9SBarry Smith cnt++; 77030dcb7c9SBarry Smith } 77130dcb7c9SBarry Smith } 77230dcb7c9SBarry Smith 77330dcb7c9SBarry Smith /* make the list of subdomains for each nontrivial local node */ 77430dcb7c9SBarry Smith ierr = PetscMemzero(*numprocs,nt*sizeof(int));CHKERRQ(ierr); 77530dcb7c9SBarry Smith cnt = 0; 77630dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 77730dcb7c9SBarry Smith nt = recvs2[cnt++]; 77830dcb7c9SBarry Smith for (j=0; j<nt; j++) { 77930dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 78030dcb7c9SBarry Smith (*indices)[bprocs[recvs2[cnt+2+k]]][(*numprocs)[bprocs[recvs2[cnt+2+k]]]++] = recvs2[cnt]; 78130dcb7c9SBarry Smith } 78230dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 78330dcb7c9SBarry Smith } 78430dcb7c9SBarry Smith } 78530dcb7c9SBarry Smith ierr = PetscFree(bprocs);CHKERRQ(ierr); 78607b52d57SBarry Smith ierr = PetscFree(recvs2);CHKERRQ(ierr); 78730dcb7c9SBarry Smith 78807b52d57SBarry Smith /* sort the node indexing by their global numbers */ 78907b52d57SBarry Smith nt = *nproc; 79007b52d57SBarry Smith for (i=0; i<nt; i++) { 791b0a32e0cSBarry Smith ierr = PetscMalloc(((*numprocs)[i])*sizeof(int),&tmp);CHKERRQ(ierr); 79207b52d57SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 79307b52d57SBarry Smith tmp[j] = lindices[(*indices)[i][j]]; 79407b52d57SBarry Smith } 79507b52d57SBarry Smith ierr = PetscSortIntWithArray((*numprocs)[i],tmp,(*indices)[i]);CHKERRQ(ierr); 79607b52d57SBarry Smith ierr = PetscFree(tmp);CHKERRQ(ierr); 79707b52d57SBarry Smith } 79807b52d57SBarry Smith 79907b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 80030dcb7c9SBarry Smith nt = *nproc; 80130dcb7c9SBarry Smith for (i=0; i<nt; i++) { 80230dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] subdomain %d number of indices %d: ",rank,(*procs)[i],(*numprocs)[i]);CHKERRQ(ierr); 80330dcb7c9SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 80430dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",(*indices)[i][j]);CHKERRQ(ierr); 80530dcb7c9SBarry Smith } 80630dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 80730dcb7c9SBarry Smith } 80830dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 80907b52d57SBarry Smith } /* ----------------------------------- */ 81030dcb7c9SBarry Smith 81130dcb7c9SBarry Smith /* wait on sends */ 81230dcb7c9SBarry Smith if (nsends2) { 813b0a32e0cSBarry Smith ierr = PetscMalloc(nsends2*sizeof(MPI_Status),&send_status);CHKERRQ(ierr); 81430dcb7c9SBarry Smith ierr = MPI_Waitall(nsends2,send_waits,send_status);CHKERRQ(ierr); 81530dcb7c9SBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 81630dcb7c9SBarry Smith } 81730dcb7c9SBarry Smith 81830dcb7c9SBarry Smith ierr = PetscFree(starts3);CHKERRQ(ierr); 81930dcb7c9SBarry Smith ierr = PetscFree(dest);CHKERRQ(ierr); 82030dcb7c9SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 8213677ff5aSBarry Smith 822bc8ff85bSBarry Smith ierr = PetscFree(nownedsenders);CHKERRQ(ierr); 823bc8ff85bSBarry Smith ierr = PetscFree(ownedsenders);CHKERRQ(ierr); 824bc8ff85bSBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 82530dcb7c9SBarry Smith ierr = PetscFree(starts2);CHKERRQ(ierr); 82630dcb7c9SBarry Smith ierr = PetscFree(lens2);CHKERRQ(ierr); 82789d82c54SBarry Smith 82889d82c54SBarry Smith ierr = PetscFree(source);CHKERRQ(ierr); 82989d82c54SBarry Smith ierr = PetscFree(recvs);CHKERRQ(ierr); 8303a96401aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 83130dcb7c9SBarry Smith ierr = PetscFree(sends2);CHKERRQ(ierr); 83224cf384cSBarry Smith 83324cf384cSBarry Smith /* put the information about myself as the first entry in the list */ 83424cf384cSBarry Smith first_procs = (*procs)[0]; 83524cf384cSBarry Smith first_numprocs = (*numprocs)[0]; 83624cf384cSBarry Smith first_indices = (*indices)[0]; 83724cf384cSBarry Smith for (i=0; i<*nproc; i++) { 83824cf384cSBarry Smith if ((*procs)[i] == rank) { 83924cf384cSBarry Smith (*procs)[0] = (*procs)[i]; 84024cf384cSBarry Smith (*numprocs)[0] = (*numprocs)[i]; 84124cf384cSBarry Smith (*indices)[0] = (*indices)[i]; 84224cf384cSBarry Smith (*procs)[i] = first_procs; 84324cf384cSBarry Smith (*numprocs)[i] = first_numprocs; 84424cf384cSBarry Smith (*indices)[i] = first_indices; 84524cf384cSBarry Smith break; 84624cf384cSBarry Smith } 84724cf384cSBarry Smith } 84824cf384cSBarry Smith 84989d82c54SBarry Smith PetscFunctionReturn(0); 85089d82c54SBarry Smith } 85189d82c54SBarry Smith 8524a2ae208SSatish Balay #undef __FUNCT__ 8534a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingRestoreInfo" 85407b52d57SBarry Smith /*@C 85507b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo - Frees the memory allocated by ISLocalToGlobalMappingGetInfo() 85689d82c54SBarry Smith 85707b52d57SBarry Smith Collective on ISLocalToGlobalMapping 85807b52d57SBarry Smith 85907b52d57SBarry Smith Input Parameters: 86007b52d57SBarry Smith . mapping - the mapping from local to global indexing 86107b52d57SBarry Smith 86207b52d57SBarry Smith Output Parameter: 86307b52d57SBarry Smith + nproc - number of processors that are connected to this one 86407b52d57SBarry Smith . proc - neighboring processors 86507b52d57SBarry Smith . numproc - number of indices for each processor 86607b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 86707b52d57SBarry Smith 86807b52d57SBarry Smith Level: advanced 86907b52d57SBarry Smith 87007b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 87107b52d57SBarry Smith ISLocalToGlobalMappingGetInfo() 87207b52d57SBarry Smith @*/ 87307b52d57SBarry Smith int ISLocalToGlobalMappingRestoreInfo(ISLocalToGlobalMapping mapping,int *nproc,int **procs,int **numprocs,int ***indices) 87407b52d57SBarry Smith { 87507b52d57SBarry Smith int ierr,i; 87607b52d57SBarry Smith 87707b52d57SBarry Smith PetscFunctionBegin; 87800ff320aSBarry Smith if (*procs) {ierr = PetscFree(*procs);CHKERRQ(ierr);} 87900ff320aSBarry Smith if (*numprocs) {ierr = PetscFree(*numprocs);CHKERRQ(ierr);} 88000ff320aSBarry Smith if (*indices) { 88100ff320aSBarry Smith if ((*indices)[0]) {ierr = PetscFree((*indices)[0]);CHKERRQ(ierr);} 88200ff320aSBarry Smith for (i=1; i<*nproc; i++) { 88324cf384cSBarry Smith if ((*indices)[i]) {ierr = PetscFree((*indices)[i]);CHKERRQ(ierr);} 88407b52d57SBarry Smith } 88507b52d57SBarry Smith ierr = PetscFree(*indices);CHKERRQ(ierr); 88624cf384cSBarry Smith } 88707b52d57SBarry Smith PetscFunctionReturn(0); 88807b52d57SBarry Smith } 88989d82c54SBarry Smith 890bc8ff85bSBarry Smith 891bc8ff85bSBarry Smith 892bc8ff85bSBarry Smith 893bc8ff85bSBarry Smith 894bc8ff85bSBarry Smith 895bc8ff85bSBarry Smith 896bc8ff85bSBarry Smith 897bc8ff85bSBarry Smith 898bc8ff85bSBarry Smith 899bc8ff85bSBarry Smith 900bc8ff85bSBarry Smith 901bc8ff85bSBarry Smith 902bc8ff85bSBarry Smith 903bc8ff85bSBarry Smith 904bc8ff85bSBarry Smith 905bc8ff85bSBarry Smith 90624cf384cSBarry Smith 907