1*4a2ae208SSatish Balay /*$Id: isltog.c,v 1.63 2001/03/09 18:50:16 balay Exp balay $*/ 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*4a2ae208SSatish Balay #undef __FUNCT__ 7*4a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingGetSize" 83b9aefa3SBarry Smith /*@C 93b9aefa3SBarry Smith ISLocalToGlobalMappingGetSize - Gets the local size of a local to global mapping. 103b9aefa3SBarry Smith 113b9aefa3SBarry Smith Not Collective 123b9aefa3SBarry Smith 133b9aefa3SBarry Smith Input Parameter: 143b9aefa3SBarry Smith . ltog - local to global mapping 153b9aefa3SBarry Smith 163b9aefa3SBarry Smith Output Parameter: 173b9aefa3SBarry Smith . n - the number of entries in the local mapping 183b9aefa3SBarry Smith 193b9aefa3SBarry Smith Level: advanced 203b9aefa3SBarry Smith 21273d9f13SBarry Smith Concepts: mapping^local to global 223b9aefa3SBarry Smith 233b9aefa3SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 243b9aefa3SBarry Smith @*/ 253b9aefa3SBarry Smith int ISLocalToGlobalMappingGetSize(ISLocalToGlobalMapping mapping,int *n) 263b9aefa3SBarry Smith { 273b9aefa3SBarry Smith PetscFunctionBegin; 283b9aefa3SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE); 293b9aefa3SBarry Smith *n = mapping->n; 303b9aefa3SBarry Smith PetscFunctionReturn(0); 313b9aefa3SBarry Smith } 323b9aefa3SBarry Smith 33*4a2ae208SSatish Balay #undef __FUNCT__ 34*4a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingView" 355a5d4f66SBarry Smith /*@C 365a5d4f66SBarry Smith ISLocalToGlobalMappingView - View a local to global mapping 375a5d4f66SBarry Smith 38b9cd556bSLois Curfman McInnes Not Collective 39b9cd556bSLois Curfman McInnes 405a5d4f66SBarry Smith Input Parameters: 413b9aefa3SBarry Smith + ltog - local to global mapping 423b9aefa3SBarry Smith - viewer - viewer 435a5d4f66SBarry Smith 44a997ad1aSLois Curfman McInnes Level: advanced 45a997ad1aSLois Curfman McInnes 46273d9f13SBarry Smith Concepts: mapping^local to global 475a5d4f66SBarry Smith 485a5d4f66SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 495a5d4f66SBarry Smith @*/ 50b0a32e0cSBarry Smith int ISLocalToGlobalMappingView(ISLocalToGlobalMapping mapping,PetscViewer viewer) 515a5d4f66SBarry Smith { 52f1af5d2fSBarry Smith int i,ierr,rank; 536831982aSBarry Smith PetscTruth isascii; 545a5d4f66SBarry Smith 555a5d4f66SBarry Smith PetscFunctionBegin; 566831982aSBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE); 57b0a32e0cSBarry Smith if (!viewer) viewer = PETSC_VIEWER_STDOUT_(mapping->comm); 58b0a32e0cSBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE); 596831982aSBarry Smith PetscCheckSameComm(mapping,viewer); 605a5d4f66SBarry Smith 61f1af5d2fSBarry Smith ierr = MPI_Comm_rank(mapping->comm,&rank);CHKERRQ(ierr); 62b0a32e0cSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr); 636831982aSBarry Smith if (isascii) { 645a5d4f66SBarry Smith for (i=0; i<mapping->n; i++) { 65b0a32e0cSBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d] %d %d\n",rank,i,mapping->indices[i]);CHKERRQ(ierr); 666831982aSBarry Smith } 67b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 686831982aSBarry Smith } else { 6929bbc08cSBarry Smith SETERRQ1(1,"Viewer type %s not supported for ISLocalToGlobalMapping",((PetscObject)viewer)->type_name); 705a5d4f66SBarry Smith } 715a5d4f66SBarry Smith 725a5d4f66SBarry Smith PetscFunctionReturn(0); 735a5d4f66SBarry Smith } 745a5d4f66SBarry Smith 75*4a2ae208SSatish Balay #undef __FUNCT__ 76*4a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreateIS" 772bdab257SBarry Smith /*@C 782bdab257SBarry Smith ISLocalToGlobalMappingCreateIS - Creates a mapping between a local (0 to n) 792bdab257SBarry Smith ordering and a global parallel ordering. 802bdab257SBarry Smith 810f5bd95cSBarry Smith Not collective 82b9cd556bSLois Curfman McInnes 83a997ad1aSLois Curfman McInnes Input Parameter: 842bdab257SBarry Smith . is - index set containing the global numbers for each local 852bdab257SBarry Smith 86a997ad1aSLois Curfman McInnes Output Parameter: 872bdab257SBarry Smith . mapping - new mapping data structure 882bdab257SBarry Smith 89a997ad1aSLois Curfman McInnes Level: advanced 90a997ad1aSLois Curfman McInnes 91273d9f13SBarry Smith Concepts: mapping^local to global 922bdab257SBarry Smith 932bdab257SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 942bdab257SBarry Smith @*/ 952bdab257SBarry Smith int ISLocalToGlobalMappingCreateIS(IS is,ISLocalToGlobalMapping *mapping) 962bdab257SBarry Smith { 972bdab257SBarry Smith int n,*indices,ierr; 982bdab257SBarry Smith MPI_Comm comm; 993a40ed3dSBarry Smith 1003a40ed3dSBarry Smith PetscFunctionBegin; 1012bdab257SBarry Smith PetscValidHeaderSpecific(is,IS_COOKIE); 1022bdab257SBarry Smith 1032bdab257SBarry Smith ierr = PetscObjectGetComm((PetscObject)is,&comm);CHKERRQ(ierr); 1043b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 1052bdab257SBarry Smith ierr = ISGetIndices(is,&indices);CHKERRQ(ierr); 1062bdab257SBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,n,indices,mapping);CHKERRQ(ierr); 1072bdab257SBarry Smith ierr = ISRestoreIndices(is,&indices);CHKERRQ(ierr); 1082bdab257SBarry Smith 1093a40ed3dSBarry Smith PetscFunctionReturn(0); 1102bdab257SBarry Smith } 1115a5d4f66SBarry Smith 112*4a2ae208SSatish Balay #undef __FUNCT__ 113*4a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreate" 114dd7157adSSatish Balay /*@C 11590f02eecSBarry Smith ISLocalToGlobalMappingCreate - Creates a mapping between a local (0 to n) 11690f02eecSBarry Smith ordering and a global parallel ordering. 1172362add9SBarry Smith 11889d82c54SBarry Smith Not Collective, but communicator may have more than one process 119b9cd556bSLois Curfman McInnes 1202362add9SBarry Smith Input Parameters: 12189d82c54SBarry Smith + comm - MPI communicator 12290f02eecSBarry Smith . n - the number of local elements 123b9cd556bSLois Curfman McInnes - indices - the global index for each local element 1242362add9SBarry Smith 125a997ad1aSLois Curfman McInnes Output Parameter: 12690f02eecSBarry Smith . mapping - new mapping data structure 1272362add9SBarry Smith 128a997ad1aSLois Curfman McInnes Level: advanced 129a997ad1aSLois Curfman McInnes 130273d9f13SBarry Smith Concepts: mapping^local to global 1312362add9SBarry Smith 1322bdab257SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS() 1332362add9SBarry Smith @*/ 134987e4450SSatish Balay int ISLocalToGlobalMappingCreate(MPI_Comm cm,int n,const int indices[],ISLocalToGlobalMapping *mapping) 1352362add9SBarry Smith { 136549d3d68SSatish Balay int ierr; 137549d3d68SSatish Balay 1383a40ed3dSBarry Smith PetscFunctionBegin; 13990f02eecSBarry Smith PetscValidIntPointer(indices); 14090f02eecSBarry Smith PetscValidPointer(mapping); 1412362add9SBarry Smith 1423f1db9ecSBarry Smith PetscHeaderCreate(*mapping,_p_ISLocalToGlobalMapping,int,IS_LTOGM_COOKIE,0,"ISLocalToGlobalMapping", 1433f1db9ecSBarry Smith cm,ISLocalToGlobalMappingDestroy,ISLocalToGlobalMappingView); 144b0a32e0cSBarry Smith PetscLogObjectCreate(*mapping); 145b0a32e0cSBarry Smith PetscLogObjectMemory(*mapping,sizeof(struct _p_ISLocalToGlobalMapping)+n*sizeof(int)); 146d4bb536fSBarry Smith 147d4bb536fSBarry Smith (*mapping)->n = n; 148b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(int),&(*mapping)->indices);CHKERRQ(ierr); 149549d3d68SSatish Balay ierr = PetscMemcpy((*mapping)->indices,indices,n*sizeof(int));CHKERRQ(ierr); 150d4bb536fSBarry Smith 151d4bb536fSBarry Smith /* 152d4bb536fSBarry Smith Do not create the global to local mapping. This is only created if 153d4bb536fSBarry Smith ISGlobalToLocalMapping() is called 154d4bb536fSBarry Smith */ 155d4bb536fSBarry Smith (*mapping)->globals = 0; 1563a40ed3dSBarry Smith PetscFunctionReturn(0); 1572362add9SBarry Smith } 1582362add9SBarry Smith 159*4a2ae208SSatish Balay #undef __FUNCT__ 160*4a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingBlock" 161323b833fSBarry Smith /*@C 162323b833fSBarry Smith ISLocalToGlobalMappingBlock - Creates a blocked index version of an 163323b833fSBarry Smith ISLocalToGlobalMapping that is appropriate for MatSetLocalToGlobalMappingBlock() 164323b833fSBarry Smith and VecSetLocalToGlobalMappingBlock(). 165323b833fSBarry Smith 166323b833fSBarry Smith Not Collective, but communicator may have more than one process 167323b833fSBarry Smith 168323b833fSBarry Smith Input Parameters: 169323b833fSBarry Smith + inmap - original point-wise mapping 170323b833fSBarry Smith - bs - block size 171323b833fSBarry Smith 172323b833fSBarry Smith Output Parameter: 173323b833fSBarry Smith . outmap - block based mapping 174323b833fSBarry Smith 175323b833fSBarry Smith Level: advanced 176323b833fSBarry Smith 177323b833fSBarry Smith Concepts: mapping^local to global 178323b833fSBarry Smith 179323b833fSBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingCreateIS() 180323b833fSBarry Smith @*/ 181323b833fSBarry Smith int ISLocalToGlobalMappingBlock(ISLocalToGlobalMapping inmap,int bs,ISLocalToGlobalMapping *outmap) 182323b833fSBarry Smith { 183323b833fSBarry Smith int ierr,*ii,i,n; 184323b833fSBarry Smith 185323b833fSBarry Smith PetscFunctionBegin; 186323b833fSBarry Smith 187323b833fSBarry Smith if (bs > 1) { 188323b833fSBarry Smith n = inmap->n/bs; 189323b833fSBarry Smith ierr = PetscMalloc(n*sizeof(int),&ii);CHKERRQ(ierr); 190323b833fSBarry Smith for (i=0; i<n; i++) { 191b8ee7809SBarry Smith ii[i] = inmap->indices[bs*i]/bs; 192323b833fSBarry Smith } 193323b833fSBarry Smith ierr = ISLocalToGlobalMappingCreate(inmap->comm,n,ii,outmap);CHKERRQ(ierr); 194323b833fSBarry Smith ierr = PetscFree(ii);CHKERRQ(ierr); 195323b833fSBarry Smith } else { 196323b833fSBarry Smith *outmap = inmap; 197323b833fSBarry Smith ierr = PetscObjectReference((PetscObject)inmap);CHKERRQ(ierr); 198323b833fSBarry Smith } 199323b833fSBarry Smith PetscFunctionReturn(0); 200323b833fSBarry Smith } 201323b833fSBarry Smith 202*4a2ae208SSatish Balay #undef __FUNCT__ 203*4a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingDestroy" 20490f02eecSBarry Smith /*@ 20590f02eecSBarry Smith ISLocalToGlobalMappingDestroy - Destroys a mapping between a local (0 to n) 20690f02eecSBarry Smith ordering and a global parallel ordering. 20790f02eecSBarry Smith 2080f5bd95cSBarry Smith Note Collective 209b9cd556bSLois Curfman McInnes 21090f02eecSBarry Smith Input Parameters: 21190f02eecSBarry Smith . mapping - mapping data structure 21290f02eecSBarry Smith 213a997ad1aSLois Curfman McInnes Level: advanced 214a997ad1aSLois Curfman McInnes 2153acfe500SLois Curfman McInnes .seealso: ISLocalToGlobalMappingCreate() 21690f02eecSBarry Smith @*/ 21790f02eecSBarry Smith int ISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping mapping) 21890f02eecSBarry Smith { 219606d414cSSatish Balay int ierr; 2203a40ed3dSBarry Smith PetscFunctionBegin; 22190f02eecSBarry Smith PetscValidPointer(mapping); 2223a40ed3dSBarry Smith if (--mapping->refct > 0) PetscFunctionReturn(0); 22385614651SBarry Smith if (mapping->refct < 0) { 22429bbc08cSBarry Smith SETERRQ(1,"Mapping already destroyed"); 22585614651SBarry Smith } 22690f02eecSBarry Smith 227606d414cSSatish Balay ierr = PetscFree(mapping->indices);CHKERRQ(ierr); 228606d414cSSatish Balay if (mapping->globals) {ierr = PetscFree(mapping->globals);CHKERRQ(ierr);} 229b0a32e0cSBarry Smith PetscLogObjectDestroy(mapping); 230d4bb536fSBarry Smith PetscHeaderDestroy(mapping); 2313a40ed3dSBarry Smith PetscFunctionReturn(0); 23290f02eecSBarry Smith } 23390f02eecSBarry Smith 234*4a2ae208SSatish Balay #undef __FUNCT__ 235*4a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingApplyIS" 23690f02eecSBarry Smith /*@ 2373acfe500SLois Curfman McInnes ISLocalToGlobalMappingApplyIS - Creates from an IS in the local numbering 2383acfe500SLois Curfman McInnes a new index set using the global numbering defined in an ISLocalToGlobalMapping 2393acfe500SLois Curfman McInnes context. 24090f02eecSBarry Smith 241b9cd556bSLois Curfman McInnes Not collective 242b9cd556bSLois Curfman McInnes 24390f02eecSBarry Smith Input Parameters: 244b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 245b9cd556bSLois Curfman McInnes - is - index set in local numbering 24690f02eecSBarry Smith 24790f02eecSBarry Smith Output Parameters: 24890f02eecSBarry Smith . newis - index set in global numbering 24990f02eecSBarry Smith 250a997ad1aSLois Curfman McInnes Level: advanced 251a997ad1aSLois Curfman McInnes 252273d9f13SBarry Smith Concepts: mapping^local to global 2533acfe500SLois Curfman McInnes 25490f02eecSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 255d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy(), ISGlobalToLocalMappingApply() 25690f02eecSBarry Smith @*/ 25790f02eecSBarry Smith int ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping mapping,IS is,IS *newis) 25890f02eecSBarry Smith { 2593b9aefa3SBarry Smith int ierr,n,i,*idxin,*idxmap,*idxout,Nmax = mapping->n; 2603a40ed3dSBarry Smith 2613a40ed3dSBarry Smith PetscFunctionBegin; 26290f02eecSBarry Smith PetscValidPointer(mapping); 26390f02eecSBarry Smith PetscValidHeaderSpecific(is,IS_COOKIE); 26490f02eecSBarry Smith PetscValidPointer(newis); 26590f02eecSBarry Smith 2663b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 26790f02eecSBarry Smith ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 26890f02eecSBarry Smith idxmap = mapping->indices; 26990f02eecSBarry Smith 270b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(int),&idxout);CHKERRQ(ierr); 27190f02eecSBarry Smith for (i=0; i<n; i++) { 27229bbc08cSBarry Smith if (idxin[i] >= Nmax) SETERRQ3(PETSC_ERR_ARG_OUTOFRANGE,"Local index %d too large %d (max) at %d",idxin[i],Nmax,i); 27390f02eecSBarry Smith idxout[i] = idxmap[idxin[i]]; 27490f02eecSBarry Smith } 2753b9aefa3SBarry Smith ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 276029af93fSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxout,newis);CHKERRQ(ierr); 277606d414cSSatish Balay ierr = PetscFree(idxout);CHKERRQ(ierr); 2783a40ed3dSBarry Smith PetscFunctionReturn(0); 27990f02eecSBarry Smith } 28090f02eecSBarry Smith 28189d82c54SBarry Smith /*MC 2823acfe500SLois Curfman McInnes ISLocalToGlobalMappingApply - Takes a list of integers in a local numbering 2833acfe500SLois Curfman McInnes and converts them to the global numbering. 28490f02eecSBarry Smith 285b9cd556bSLois Curfman McInnes Not collective 286b9cd556bSLois Curfman McInnes 287bb25748dSBarry Smith Input Parameters: 288b9cd556bSLois Curfman McInnes + mapping - the local to global mapping context 289bb25748dSBarry Smith . N - number of integers 290b9cd556bSLois Curfman McInnes - in - input indices in local numbering 291bb25748dSBarry Smith 292bb25748dSBarry Smith Output Parameter: 293bb25748dSBarry Smith . out - indices in global numbering 294bb25748dSBarry Smith 2953b9aefa3SBarry Smith Synopsis: 2963b9aefa3SBarry Smith ISLocalToGlobalMappingApply(ISLocalToGlobalMapping mapping,int N,int in[],int out[]) 2973b9aefa3SBarry Smith 298b9cd556bSLois Curfman McInnes Notes: 299b9cd556bSLois Curfman McInnes The in and out array parameters may be identical. 300d4bb536fSBarry Smith 301a997ad1aSLois Curfman McInnes Level: advanced 302a997ad1aSLois Curfman McInnes 303bb25748dSBarry Smith .seealso: ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 3040752156aSBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 305d4bb536fSBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 306bb25748dSBarry Smith 307273d9f13SBarry Smith Concepts: mapping^local to global 308d4bb536fSBarry Smith 30989d82c54SBarry Smith M*/ 310d4bb536fSBarry Smith 311d4bb536fSBarry Smith /* -----------------------------------------------------------------------------------------*/ 312d4bb536fSBarry Smith 313*4a2ae208SSatish Balay #undef __FUNCT__ 314*4a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingSetUp_Private" 315d4bb536fSBarry Smith /* 316d4bb536fSBarry Smith Creates the global fields in the ISLocalToGlobalMapping structure 317d4bb536fSBarry Smith */ 318d4bb536fSBarry Smith static int ISGlobalToLocalMappingSetUp_Private(ISLocalToGlobalMapping mapping) 319d4bb536fSBarry Smith { 320b0a32e0cSBarry Smith int ierr,i,*idx = mapping->indices,n = mapping->n,end,start,*globals; 321d4bb536fSBarry Smith 3223a40ed3dSBarry Smith PetscFunctionBegin; 323d4bb536fSBarry Smith end = 0; 324d4bb536fSBarry Smith start = 100000000; 325d4bb536fSBarry Smith 326d4bb536fSBarry Smith for (i=0; i<n; i++) { 327d4bb536fSBarry Smith if (idx[i] < 0) continue; 328d4bb536fSBarry Smith if (idx[i] < start) start = idx[i]; 329d4bb536fSBarry Smith if (idx[i] > end) end = idx[i]; 330d4bb536fSBarry Smith } 331d4bb536fSBarry Smith if (start > end) {start = 0; end = -1;} 332d4bb536fSBarry Smith mapping->globalstart = start; 333d4bb536fSBarry Smith mapping->globalend = end; 334d4bb536fSBarry Smith 335b0a32e0cSBarry Smith ierr = PetscMalloc((end-start+2)*sizeof(int),&globals);CHKERRQ(ierr); 336b0a32e0cSBarry Smith mapping->globals = globals; 337d4bb536fSBarry Smith for (i=0; i<end-start+1; i++) { 338d4bb536fSBarry Smith globals[i] = -1; 339d4bb536fSBarry Smith } 340d4bb536fSBarry Smith for (i=0; i<n; i++) { 341d4bb536fSBarry Smith if (idx[i] < 0) continue; 342d4bb536fSBarry Smith globals[idx[i] - start] = i; 343d4bb536fSBarry Smith } 344d4bb536fSBarry Smith 345b0a32e0cSBarry Smith PetscLogObjectMemory(mapping,(end-start+1)*sizeof(int)); 3463a40ed3dSBarry Smith PetscFunctionReturn(0); 347d4bb536fSBarry Smith } 348d4bb536fSBarry Smith 349*4a2ae208SSatish Balay #undef __FUNCT__ 350*4a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingApply" 351d4bb536fSBarry Smith /*@ 352a997ad1aSLois Curfman McInnes ISGlobalToLocalMappingApply - Provides the local numbering for a list of integers 353a997ad1aSLois Curfman McInnes specified with a global numbering. 354d4bb536fSBarry Smith 355b9cd556bSLois Curfman McInnes Not collective 356b9cd556bSLois Curfman McInnes 357d4bb536fSBarry Smith Input Parameters: 358b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 359d4bb536fSBarry Smith . type - IS_GTOLM_MASK - replaces global indices with no local value with -1 360d4bb536fSBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 361d4bb536fSBarry Smith . n - number of global indices to map 362b9cd556bSLois Curfman McInnes - idx - global indices to map 363d4bb536fSBarry Smith 364d4bb536fSBarry Smith Output Parameters: 365b9cd556bSLois Curfman McInnes + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 366b9cd556bSLois Curfman McInnes - idxout - local index of each global index, one must pass in an array long enough 367e182c471SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApply() with 368e182c471SBarry Smith idxout == PETSC_NULL to determine the required length (returned in nout) 369e182c471SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApply() 370e182c471SBarry Smith a second time to set the values. 371d4bb536fSBarry Smith 372b9cd556bSLois Curfman McInnes Notes: 373b9cd556bSLois Curfman McInnes Either nout or idxout may be PETSC_NULL. idx and idxout may be identical. 374d4bb536fSBarry Smith 3750f5bd95cSBarry Smith This is not scalable in memory usage. Each processor requires O(Nglobal) size 3760f5bd95cSBarry Smith array to compute these. 3770f5bd95cSBarry Smith 378a997ad1aSLois Curfman McInnes Level: advanced 379a997ad1aSLois Curfman McInnes 380273d9f13SBarry Smith Concepts: mapping^global to local 381d4bb536fSBarry Smith 382d4bb536fSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 383d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy() 384d4bb536fSBarry Smith @*/ 385d4bb536fSBarry Smith int ISGlobalToLocalMappingApply(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, 386987e4450SSatish Balay int n,const int idx[],int *nout,int idxout[]) 387d4bb536fSBarry Smith { 388d4bb536fSBarry Smith int i,ierr,*globals,nf = 0,tmp,start,end; 389d4bb536fSBarry Smith 3903a40ed3dSBarry Smith PetscFunctionBegin; 391d4bb536fSBarry Smith if (!mapping->globals) { 392d4bb536fSBarry Smith ierr = ISGlobalToLocalMappingSetUp_Private(mapping);CHKERRQ(ierr); 393d4bb536fSBarry Smith } 394d4bb536fSBarry Smith globals = mapping->globals; 395d4bb536fSBarry Smith start = mapping->globalstart; 396d4bb536fSBarry Smith end = mapping->globalend; 397d4bb536fSBarry Smith 398d4bb536fSBarry Smith if (type == IS_GTOLM_MASK) { 399d4bb536fSBarry Smith if (idxout) { 400d4bb536fSBarry Smith for (i=0; i<n; i++) { 401d4bb536fSBarry Smith if (idx[i] < 0) idxout[i] = idx[i]; 402d4bb536fSBarry Smith else if (idx[i] < start) idxout[i] = -1; 403d4bb536fSBarry Smith else if (idx[i] > end) idxout[i] = -1; 404d4bb536fSBarry Smith else idxout[i] = globals[idx[i] - start]; 405d4bb536fSBarry Smith } 406d4bb536fSBarry Smith } 407d4bb536fSBarry Smith if (nout) *nout = n; 408d4bb536fSBarry Smith } else { 409d4bb536fSBarry Smith if (idxout) { 410d4bb536fSBarry Smith for (i=0; i<n; i++) { 411d4bb536fSBarry Smith if (idx[i] < 0) continue; 412d4bb536fSBarry Smith if (idx[i] < start) continue; 413d4bb536fSBarry Smith if (idx[i] > end) continue; 414d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 415d4bb536fSBarry Smith if (tmp < 0) continue; 416d4bb536fSBarry Smith idxout[nf++] = tmp; 417d4bb536fSBarry Smith } 418d4bb536fSBarry Smith } else { 419d4bb536fSBarry Smith for (i=0; i<n; i++) { 420d4bb536fSBarry Smith if (idx[i] < 0) continue; 421d4bb536fSBarry Smith if (idx[i] < start) continue; 422d4bb536fSBarry Smith if (idx[i] > end) continue; 423d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 424d4bb536fSBarry Smith if (tmp < 0) continue; 425d4bb536fSBarry Smith nf++; 426d4bb536fSBarry Smith } 427d4bb536fSBarry Smith } 428d4bb536fSBarry Smith if (nout) *nout = nf; 429d4bb536fSBarry Smith } 430d4bb536fSBarry Smith 4313a40ed3dSBarry Smith PetscFunctionReturn(0); 432d4bb536fSBarry Smith } 43390f02eecSBarry Smith 434*4a2ae208SSatish Balay #undef __FUNCT__ 435*4a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingGetInfo" 43689d82c54SBarry Smith /*@C 43789d82c54SBarry Smith ISLocalToGlobalMappingGetInfo - Gets the neighbor information for each processor and 43889d82c54SBarry Smith each index shared by more than one processor 43989d82c54SBarry Smith 44089d82c54SBarry Smith Collective on ISLocalToGlobalMapping 44189d82c54SBarry Smith 44289d82c54SBarry Smith Input Parameters: 44389d82c54SBarry Smith . mapping - the mapping from local to global indexing 44489d82c54SBarry Smith 44589d82c54SBarry Smith Output Parameter: 44689d82c54SBarry Smith + nproc - number of processors that are connected to this one 44789d82c54SBarry Smith . proc - neighboring processors 44807b52d57SBarry Smith . numproc - number of indices for each subdomain (processor) 44907b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 45089d82c54SBarry Smith 45189d82c54SBarry Smith Level: advanced 45289d82c54SBarry Smith 453273d9f13SBarry Smith Concepts: mapping^local to global 45489d82c54SBarry Smith 45507b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 45607b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo() 45789d82c54SBarry Smith @*/ 45830dcb7c9SBarry Smith int ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping mapping,int *nproc,int **procs,int **numprocs,int ***indices) 45989d82c54SBarry Smith { 460fa7fbcffSSatish Balay int i,n = mapping->n,ierr,Ng,ng,max = 0,*lindices = mapping->indices; 4613a96401aSBarry Smith int size,rank,*nprocs,*owner,nsends,*sends,j,*starts,*work,nmax,nrecvs,*recvs,proc; 46224cf384cSBarry Smith int tag1,tag2,tag3,cnt,*len,*source,imdex,scale,*ownedsenders,*nownedsenders,rstart,nowned; 46307b52d57SBarry Smith int node,nownedm,nt,*sends2,nsends2,*starts2,*lens2,*dest,nrecvs2,*starts3,*recvs2,k,*bprocs,*tmp; 46424cf384cSBarry Smith int first_procs,first_numprocs,*first_indices; 46589d82c54SBarry Smith MPI_Request *recv_waits,*send_waits; 46630dcb7c9SBarry Smith MPI_Status recv_status,*send_status,*recv_statuses; 46789d82c54SBarry Smith MPI_Comm comm = mapping->comm; 46807b52d57SBarry Smith PetscTruth debug = PETSC_FALSE; 46989d82c54SBarry Smith 47089d82c54SBarry Smith PetscFunctionBegin; 47124cf384cSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 47224cf384cSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 47324cf384cSBarry Smith if (size == 1) { 47424cf384cSBarry Smith *nproc = 0; 47524cf384cSBarry Smith *procs = PETSC_NULL; 476b0a32e0cSBarry Smith ierr = PetscMalloc(sizeof(int),numprocs);CHKERRQ(ierr); 4771e2105dcSBarry Smith (*numprocs)[0] = 0; 478b0a32e0cSBarry Smith ierr = PetscMalloc(sizeof(int*),indices);CHKERRQ(ierr); 4791e2105dcSBarry Smith (*indices)[0] = PETSC_NULL; 48024cf384cSBarry Smith PetscFunctionReturn(0); 48124cf384cSBarry Smith } 48224cf384cSBarry Smith 483b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-islocaltoglobalmappinggetinfo_debug",&debug);CHKERRQ(ierr); 48407b52d57SBarry Smith 4853677ff5aSBarry Smith /* 4863677ff5aSBarry Smith Notes on ISLocalToGlobalMappingGetInfo 4873677ff5aSBarry Smith 4883677ff5aSBarry Smith globally owned node - the nodes that have been assigned to this processor in global 4893677ff5aSBarry Smith numbering, just for this routine. 4903677ff5aSBarry Smith 4913677ff5aSBarry Smith nontrivial globally owned node - node assigned to this processor that is on a subdomain 4923677ff5aSBarry Smith boundary (i.e. is has more than one local owner) 4933677ff5aSBarry Smith 4943677ff5aSBarry Smith locally owned node - node that exists on this processors subdomain 4953677ff5aSBarry Smith 4963677ff5aSBarry Smith nontrivial locally owned node - node that is not in the interior (i.e. has more than one 4973677ff5aSBarry Smith local subdomain 4983677ff5aSBarry Smith */ 49924cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag1);CHKERRQ(ierr); 50024cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag2);CHKERRQ(ierr); 50124cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag3);CHKERRQ(ierr); 50289d82c54SBarry Smith 50389d82c54SBarry Smith for (i=0; i<n; i++) { 50489d82c54SBarry Smith if (lindices[i] > max) max = lindices[i]; 50589d82c54SBarry Smith } 50689d82c54SBarry Smith ierr = MPI_Allreduce(&max,&Ng,1,MPI_INT,MPI_MAX,comm);CHKERRQ(ierr); 50778058e43SBarry Smith Ng++; 50889d82c54SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 50989d82c54SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 510bc8ff85bSBarry Smith scale = Ng/size + 1; 511a2e34c3dSBarry Smith ng = scale; if (rank == size-1) ng = Ng - scale*(size-1); ng = PetscMax(1,ng); 512caba0dd0SBarry Smith rstart = scale*rank; 51389d82c54SBarry Smith 51489d82c54SBarry Smith /* determine ownership ranges of global indices */ 515b0a32e0cSBarry Smith ierr = PetscMalloc((2*size+1)*sizeof(int),&nprocs);CHKERRQ(ierr); 5162880cf29SBarry Smith ierr = PetscMemzero(nprocs,2*size*sizeof(int));CHKERRQ(ierr); 51789d82c54SBarry Smith 51889d82c54SBarry Smith /* determine owners of each local node */ 519b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(int),&owner);CHKERRQ(ierr); 52089d82c54SBarry Smith for (i=0; i<n; i++) { 5213677ff5aSBarry Smith proc = lindices[i]/scale; /* processor that globally owns this index */ 5223677ff5aSBarry Smith nprocs[size+proc] = 1; /* processor globally owns at least one of ours */ 5233677ff5aSBarry Smith owner[i] = proc; 5243677ff5aSBarry Smith nprocs[proc]++; /* count of how many that processor globally owns of ours */ 52589d82c54SBarry Smith } 52689d82c54SBarry Smith nsends = 0; for (i=0; i<size; i++) nsends += nprocs[size + i]; 527b0a32e0cSBarry Smith PetscLogInfo(0,"ISLocalToGlobalMappingGetInfo: Number of global owners for my local data %d\n",nsends); 52889d82c54SBarry Smith 52989d82c54SBarry Smith /* inform other processors of number of messages and max length*/ 530b0a32e0cSBarry Smith ierr = PetscMalloc(2*size*sizeof(int),&work);CHKERRQ(ierr); 53189d82c54SBarry Smith ierr = MPI_Allreduce(nprocs,work,2*size,MPI_INT,PetscMaxSum_Op,comm);CHKERRQ(ierr); 53289d82c54SBarry Smith nmax = work[rank]; 53389d82c54SBarry Smith nrecvs = work[size+rank]; 53489d82c54SBarry Smith ierr = PetscFree(work);CHKERRQ(ierr); 535b0a32e0cSBarry Smith PetscLogInfo(0,"ISLocalToGlobalMappingGetInfo: Number of local owners for my global data %d\n",nrecvs); 53689d82c54SBarry Smith 53789d82c54SBarry Smith /* post receives for owned rows */ 538b0a32e0cSBarry Smith ierr = PetscMalloc((2*nrecvs+1)*(nmax+1)*sizeof(int),&recvs);CHKERRQ(ierr); 539b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs+1)*sizeof(MPI_Request),&recv_waits);CHKERRQ(ierr); 54089d82c54SBarry Smith for (i=0; i<nrecvs; i++) { 54124cf384cSBarry Smith ierr = MPI_Irecv(recvs+2*nmax*i,2*nmax,MPI_INT,MPI_ANY_SOURCE,tag1,comm,recv_waits+i);CHKERRQ(ierr); 54289d82c54SBarry Smith } 54389d82c54SBarry Smith 54489d82c54SBarry Smith /* pack messages containing lists of local nodes to owners */ 545b0a32e0cSBarry Smith ierr = PetscMalloc((2*n+1)*sizeof(int),&sends);CHKERRQ(ierr); 546b0a32e0cSBarry Smith ierr = PetscMalloc((size+1)*sizeof(int),&starts);CHKERRQ(ierr); 54789d82c54SBarry Smith starts[0] = 0; 54830dcb7c9SBarry Smith for (i=1; i<size; i++) { starts[i] = starts[i-1] + 2*nprocs[i-1];} 54989d82c54SBarry Smith for (i=0; i<n; i++) { 55089d82c54SBarry Smith sends[starts[owner[i]]++] = lindices[i]; 55130dcb7c9SBarry Smith sends[starts[owner[i]]++] = i; 55289d82c54SBarry Smith } 55389d82c54SBarry Smith ierr = PetscFree(owner);CHKERRQ(ierr); 55489d82c54SBarry Smith starts[0] = 0; 55530dcb7c9SBarry Smith for (i=1; i<size; i++) { starts[i] = starts[i-1] + 2*nprocs[i-1];} 55689d82c54SBarry Smith 55789d82c54SBarry Smith /* send the messages */ 558b0a32e0cSBarry Smith ierr = PetscMalloc((nsends+1)*sizeof(MPI_Request),&send_waits);CHKERRQ(ierr); 559b0a32e0cSBarry Smith ierr = PetscMalloc((nsends+1)*sizeof(int),&dest);CHKERRQ(ierr); 56089d82c54SBarry Smith cnt = 0; 56189d82c54SBarry Smith for (i=0; i<size; i++) { 56289d82c54SBarry Smith if (nprocs[i]) { 56324cf384cSBarry Smith ierr = MPI_Isend(sends+starts[i],2*nprocs[i],MPI_INT,i,tag1,comm,send_waits+cnt);CHKERRQ(ierr); 56430dcb7c9SBarry Smith dest[cnt] = i; 56589d82c54SBarry Smith cnt++; 56689d82c54SBarry Smith } 56789d82c54SBarry Smith } 56889d82c54SBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 56989d82c54SBarry Smith 57089d82c54SBarry Smith /* wait on receives */ 571b0a32e0cSBarry Smith ierr = PetscMalloc((2*nrecvs+1)*sizeof(int),&source);CHKERRQ(ierr); 57289d82c54SBarry Smith len = source + nrecvs; 57389d82c54SBarry Smith cnt = nrecvs; 574b0a32e0cSBarry Smith ierr = PetscMalloc((ng+1)*sizeof(int),&nownedsenders);CHKERRQ(ierr); 575caba0dd0SBarry Smith ierr = PetscMemzero(nownedsenders,ng*sizeof(int));CHKERRQ(ierr); 57689d82c54SBarry Smith while (cnt) { 57789d82c54SBarry Smith ierr = MPI_Waitany(nrecvs,recv_waits,&imdex,&recv_status);CHKERRQ(ierr); 57889d82c54SBarry Smith /* unpack receives into our local space */ 57989d82c54SBarry Smith ierr = MPI_Get_count(&recv_status,MPI_INT,&len[imdex]);CHKERRQ(ierr); 58089d82c54SBarry Smith source[imdex] = recv_status.MPI_SOURCE; 58130dcb7c9SBarry Smith len[imdex] = len[imdex]/2; 582caba0dd0SBarry Smith /* count how many local owners for each of my global owned indices */ 58330dcb7c9SBarry Smith for (i=0; i<len[imdex]; i++) nownedsenders[recvs[2*imdex*nmax+2*i]-rstart]++; 58489d82c54SBarry Smith cnt--; 58589d82c54SBarry Smith } 58689d82c54SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 58789d82c54SBarry Smith 58830dcb7c9SBarry Smith /* count how many globally owned indices are on an edge multiplied by how many processors own them. */ 589bc8ff85bSBarry Smith nowned = 0; 590bc8ff85bSBarry Smith nownedm = 0; 591bc8ff85bSBarry Smith for (i=0; i<ng; i++) { 592bc8ff85bSBarry Smith if (nownedsenders[i] > 1) {nownedm += nownedsenders[i]; nowned++;} 593bc8ff85bSBarry Smith } 594bc8ff85bSBarry Smith 595bc8ff85bSBarry Smith /* create single array to contain rank of all local owners of each globally owned index */ 596b0a32e0cSBarry Smith ierr = PetscMalloc((nownedm+1)*sizeof(int),&ownedsenders);CHKERRQ(ierr); 597b0a32e0cSBarry Smith ierr = PetscMalloc((ng+1)*sizeof(int),&starts);CHKERRQ(ierr); 598bc8ff85bSBarry Smith starts[0] = 0; 599bc8ff85bSBarry Smith for (i=1; i<ng; i++) { 600bc8ff85bSBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 601bc8ff85bSBarry Smith else starts[i] = starts[i-1]; 602bc8ff85bSBarry Smith } 603bc8ff85bSBarry Smith 60430dcb7c9SBarry Smith /* for each nontrival globally owned node list all arriving processors */ 605bc8ff85bSBarry Smith for (i=0; i<nrecvs; i++) { 606bc8ff85bSBarry Smith for (j=0; j<len[i]; j++) { 60730dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 608bc8ff85bSBarry Smith if (nownedsenders[node] > 1) { 609bc8ff85bSBarry Smith ownedsenders[starts[node]++] = source[i]; 610bc8ff85bSBarry Smith } 611bc8ff85bSBarry Smith } 612bc8ff85bSBarry Smith } 613bc8ff85bSBarry Smith 61407b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 61530dcb7c9SBarry Smith starts[0] = 0; 61630dcb7c9SBarry Smith for (i=1; i<ng; i++) { 61730dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 61830dcb7c9SBarry Smith else starts[i] = starts[i-1]; 61930dcb7c9SBarry Smith } 62030dcb7c9SBarry Smith for (i=0; i<ng; i++) { 62130dcb7c9SBarry Smith if (nownedsenders[i] > 1) { 62230dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] global node %d local owner processors: ",rank,i+rstart);CHKERRQ(ierr); 62330dcb7c9SBarry Smith for (j=0; j<nownedsenders[i]; j++) { 62430dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",ownedsenders[starts[i]+j]);CHKERRQ(ierr); 62530dcb7c9SBarry Smith } 62630dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 62730dcb7c9SBarry Smith } 62830dcb7c9SBarry Smith } 62930dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 63007b52d57SBarry Smith }/* ----------------------------------- */ 63130dcb7c9SBarry Smith 6323677ff5aSBarry Smith /* wait on original sends */ 6333a96401aSBarry Smith if (nsends) { 634b0a32e0cSBarry Smith ierr = PetscMalloc(nsends*sizeof(MPI_Status),&send_status);CHKERRQ(ierr); 6353a96401aSBarry Smith ierr = MPI_Waitall(nsends,send_waits,send_status);CHKERRQ(ierr); 6363a96401aSBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 6373a96401aSBarry Smith } 63889d82c54SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 6393a96401aSBarry Smith ierr = PetscFree(sends);CHKERRQ(ierr); 6403677ff5aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 6413677ff5aSBarry Smith 6423677ff5aSBarry Smith /* pack messages to send back to local owners */ 64330dcb7c9SBarry Smith starts[0] = 0; 64430dcb7c9SBarry Smith for (i=1; i<ng; i++) { 64530dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 64630dcb7c9SBarry Smith else starts[i] = starts[i-1]; 64730dcb7c9SBarry Smith } 64830dcb7c9SBarry Smith nsends2 = nrecvs; 649b0a32e0cSBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(int),&nprocs);CHKERRQ(ierr); /* length of each message */ 65030dcb7c9SBarry Smith for (i=0; i<nrecvs; i++) { 65130dcb7c9SBarry Smith nprocs[i] = 1; 65230dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 65330dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 65430dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 65530dcb7c9SBarry Smith nprocs[i] += 2 + nownedsenders[node]; 65630dcb7c9SBarry Smith } 65730dcb7c9SBarry Smith } 65830dcb7c9SBarry Smith } 65930dcb7c9SBarry Smith nt = 0; for (i=0; i<nsends2; i++) nt += nprocs[i]; 660b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int),&sends2);CHKERRQ(ierr); 661b0a32e0cSBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(int),&starts2);CHKERRQ(ierr); 66230dcb7c9SBarry Smith starts2[0] = 0; for (i=1; i<nsends2; i++) starts2[i] = starts2[i-1] + nprocs[i-1]; 66330dcb7c9SBarry Smith /* 66430dcb7c9SBarry Smith Each message is 1 + nprocs[i] long, and consists of 66530dcb7c9SBarry Smith (0) the number of nodes being sent back 66630dcb7c9SBarry Smith (1) the local node number, 66730dcb7c9SBarry Smith (2) the number of processors sharing it, 66830dcb7c9SBarry Smith (3) the processors sharing it 66930dcb7c9SBarry Smith */ 67030dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 67130dcb7c9SBarry Smith cnt = 1; 67230dcb7c9SBarry Smith sends2[starts2[i]] = 0; 67330dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 67430dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 67530dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 67630dcb7c9SBarry Smith sends2[starts2[i]]++; 67730dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = recvs[2*i*nmax+2*j+1]; 67830dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = nownedsenders[node]; 67930dcb7c9SBarry Smith ierr = PetscMemcpy(&sends2[starts2[i]+cnt],&ownedsenders[starts[node]],nownedsenders[node]*sizeof(int));CHKERRQ(ierr); 68030dcb7c9SBarry Smith cnt += nownedsenders[node]; 68130dcb7c9SBarry Smith } 68230dcb7c9SBarry Smith } 68330dcb7c9SBarry Smith } 68430dcb7c9SBarry Smith 68530dcb7c9SBarry Smith /* send the message lengths */ 68630dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 68724cf384cSBarry Smith ierr = MPI_Send(&nprocs[i],1,MPI_INT,source[i],tag2,comm);CHKERRQ(ierr); 68830dcb7c9SBarry Smith } 68930dcb7c9SBarry Smith 69030dcb7c9SBarry Smith /* receive the message lengths */ 69130dcb7c9SBarry Smith nrecvs2 = nsends; 692b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(int),&lens2);CHKERRQ(ierr); 693b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(int),&starts3);CHKERRQ(ierr); 69430dcb7c9SBarry Smith nt = 0; 69530dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 69624cf384cSBarry Smith ierr = MPI_Recv(&lens2[i],1,MPI_INT,dest[i],tag2,comm,&recv_status);CHKERRQ(ierr); 69730dcb7c9SBarry Smith nt += lens2[i]; 69830dcb7c9SBarry Smith } 69930dcb7c9SBarry Smith starts3[0] = 0; 70030dcb7c9SBarry Smith for (i=0; i<nrecvs2-1; i++) { 70130dcb7c9SBarry Smith starts3[i+1] = starts3[i] + lens2[i]; 70230dcb7c9SBarry Smith } 703b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int),&recvs2);CHKERRQ(ierr); 704b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(MPI_Request),&recv_waits);CHKERRQ(ierr); 70552b72c4aSBarry Smith for (i=0; i<nrecvs2; i++) { 70624cf384cSBarry Smith ierr = MPI_Irecv(recvs2+starts3[i],lens2[i],MPI_INT,dest[i],tag3,comm,recv_waits+i);CHKERRQ(ierr); 70730dcb7c9SBarry Smith } 70830dcb7c9SBarry Smith 70930dcb7c9SBarry Smith /* send the messages */ 710b0a32e0cSBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(MPI_Request),&send_waits);CHKERRQ(ierr); 71130dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 71224cf384cSBarry Smith ierr = MPI_Isend(sends2+starts2[i],nprocs[i],MPI_INT,source[i],tag3,comm,send_waits+i);CHKERRQ(ierr); 71330dcb7c9SBarry Smith } 71430dcb7c9SBarry Smith 71530dcb7c9SBarry Smith /* wait on receives */ 716b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(MPI_Status),&recv_statuses);CHKERRQ(ierr); 71730dcb7c9SBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 71830dcb7c9SBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 71930dcb7c9SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 72030dcb7c9SBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 72130dcb7c9SBarry Smith 72207b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 72330dcb7c9SBarry Smith cnt = 0; 72430dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 72530dcb7c9SBarry Smith nt = recvs2[cnt++]; 72630dcb7c9SBarry Smith for (j=0; j<nt; j++) { 72730dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] local node %d number of subdomains %d: ",rank,recvs2[cnt],recvs2[cnt+1]);CHKERRQ(ierr); 72830dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 72930dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",recvs2[cnt+2+k]);CHKERRQ(ierr); 73030dcb7c9SBarry Smith } 73130dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 73230dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 73330dcb7c9SBarry Smith } 73430dcb7c9SBarry Smith } 73530dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 73607b52d57SBarry Smith } /* ----------------------------------- */ 73730dcb7c9SBarry Smith 73830dcb7c9SBarry Smith /* count number subdomains for each local node */ 739b0a32e0cSBarry Smith ierr = PetscMalloc(size*sizeof(int),&nprocs);CHKERRQ(ierr); 74030dcb7c9SBarry Smith ierr = PetscMemzero(nprocs,size*sizeof(int));CHKERRQ(ierr); 74130dcb7c9SBarry Smith cnt = 0; 74230dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 74330dcb7c9SBarry Smith nt = recvs2[cnt++]; 74430dcb7c9SBarry Smith for (j=0; j<nt; j++) { 74530dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 74630dcb7c9SBarry Smith nprocs[recvs2[cnt+2+k]]++; 74730dcb7c9SBarry Smith } 74830dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 74930dcb7c9SBarry Smith } 75030dcb7c9SBarry Smith } 75130dcb7c9SBarry Smith nt = 0; for (i=0; i<size; i++) nt += (nprocs[i] > 0); 75230dcb7c9SBarry Smith *nproc = nt; 753b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int),procs);CHKERRQ(ierr); 754b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int),numprocs);CHKERRQ(ierr); 755b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int*),indices);CHKERRQ(ierr); 756b0a32e0cSBarry Smith ierr = PetscMalloc(size*sizeof(int),&bprocs);CHKERRQ(ierr); 75730dcb7c9SBarry Smith cnt = 0; 75830dcb7c9SBarry Smith for (i=0; i<size; i++) { 75930dcb7c9SBarry Smith if (nprocs[i] > 0) { 76030dcb7c9SBarry Smith bprocs[i] = cnt; 76130dcb7c9SBarry Smith (*procs)[cnt] = i; 76230dcb7c9SBarry Smith (*numprocs)[cnt] = nprocs[i]; 763b0a32e0cSBarry Smith ierr = PetscMalloc(nprocs[i]*sizeof(int),&(*indices)[cnt]);CHKERRQ(ierr); 76430dcb7c9SBarry Smith cnt++; 76530dcb7c9SBarry Smith } 76630dcb7c9SBarry Smith } 76730dcb7c9SBarry Smith 76830dcb7c9SBarry Smith /* make the list of subdomains for each nontrivial local node */ 76930dcb7c9SBarry Smith ierr = PetscMemzero(*numprocs,nt*sizeof(int));CHKERRQ(ierr); 77030dcb7c9SBarry Smith cnt = 0; 77130dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 77230dcb7c9SBarry Smith nt = recvs2[cnt++]; 77330dcb7c9SBarry Smith for (j=0; j<nt; j++) { 77430dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 77530dcb7c9SBarry Smith (*indices)[bprocs[recvs2[cnt+2+k]]][(*numprocs)[bprocs[recvs2[cnt+2+k]]]++] = recvs2[cnt]; 77630dcb7c9SBarry Smith } 77730dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 77830dcb7c9SBarry Smith } 77930dcb7c9SBarry Smith } 78030dcb7c9SBarry Smith ierr = PetscFree(bprocs);CHKERRQ(ierr); 78107b52d57SBarry Smith ierr = PetscFree(recvs2);CHKERRQ(ierr); 78230dcb7c9SBarry Smith 78307b52d57SBarry Smith /* sort the node indexing by their global numbers */ 78407b52d57SBarry Smith nt = *nproc; 78507b52d57SBarry Smith for (i=0; i<nt; i++) { 786b0a32e0cSBarry Smith ierr = PetscMalloc(((*numprocs)[i])*sizeof(int),&tmp);CHKERRQ(ierr); 78707b52d57SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 78807b52d57SBarry Smith tmp[j] = lindices[(*indices)[i][j]]; 78907b52d57SBarry Smith } 79007b52d57SBarry Smith ierr = PetscSortIntWithArray((*numprocs)[i],tmp,(*indices)[i]);CHKERRQ(ierr); 79107b52d57SBarry Smith ierr = PetscFree(tmp);CHKERRQ(ierr); 79207b52d57SBarry Smith } 79307b52d57SBarry Smith 79407b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 79530dcb7c9SBarry Smith nt = *nproc; 79630dcb7c9SBarry Smith for (i=0; i<nt; i++) { 79730dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] subdomain %d number of indices %d: ",rank,(*procs)[i],(*numprocs)[i]);CHKERRQ(ierr); 79830dcb7c9SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 79930dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",(*indices)[i][j]);CHKERRQ(ierr); 80030dcb7c9SBarry Smith } 80130dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 80230dcb7c9SBarry Smith } 80330dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 80407b52d57SBarry Smith } /* ----------------------------------- */ 80530dcb7c9SBarry Smith 80630dcb7c9SBarry Smith /* wait on sends */ 80730dcb7c9SBarry Smith if (nsends2) { 808b0a32e0cSBarry Smith ierr = PetscMalloc(nsends2*sizeof(MPI_Status),&send_status);CHKERRQ(ierr); 80930dcb7c9SBarry Smith ierr = MPI_Waitall(nsends2,send_waits,send_status);CHKERRQ(ierr); 81030dcb7c9SBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 81130dcb7c9SBarry Smith } 81230dcb7c9SBarry Smith 81330dcb7c9SBarry Smith ierr = PetscFree(starts3);CHKERRQ(ierr); 81430dcb7c9SBarry Smith ierr = PetscFree(dest);CHKERRQ(ierr); 81530dcb7c9SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 8163677ff5aSBarry Smith 817bc8ff85bSBarry Smith ierr = PetscFree(nownedsenders);CHKERRQ(ierr); 818bc8ff85bSBarry Smith ierr = PetscFree(ownedsenders);CHKERRQ(ierr); 819bc8ff85bSBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 82030dcb7c9SBarry Smith ierr = PetscFree(starts2);CHKERRQ(ierr); 82130dcb7c9SBarry Smith ierr = PetscFree(lens2);CHKERRQ(ierr); 82289d82c54SBarry Smith 82389d82c54SBarry Smith ierr = PetscFree(source);CHKERRQ(ierr); 82489d82c54SBarry Smith ierr = PetscFree(recvs);CHKERRQ(ierr); 8253a96401aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 82630dcb7c9SBarry Smith ierr = PetscFree(sends2);CHKERRQ(ierr); 82724cf384cSBarry Smith 82824cf384cSBarry Smith /* put the information about myself as the first entry in the list */ 82924cf384cSBarry Smith first_procs = (*procs)[0]; 83024cf384cSBarry Smith first_numprocs = (*numprocs)[0]; 83124cf384cSBarry Smith first_indices = (*indices)[0]; 83224cf384cSBarry Smith for (i=0; i<*nproc; i++) { 83324cf384cSBarry Smith if ((*procs)[i] == rank) { 83424cf384cSBarry Smith (*procs)[0] = (*procs)[i]; 83524cf384cSBarry Smith (*numprocs)[0] = (*numprocs)[i]; 83624cf384cSBarry Smith (*indices)[0] = (*indices)[i]; 83724cf384cSBarry Smith (*procs)[i] = first_procs; 83824cf384cSBarry Smith (*numprocs)[i] = first_numprocs; 83924cf384cSBarry Smith (*indices)[i] = first_indices; 84024cf384cSBarry Smith break; 84124cf384cSBarry Smith } 84224cf384cSBarry Smith } 84324cf384cSBarry Smith 84489d82c54SBarry Smith PetscFunctionReturn(0); 84589d82c54SBarry Smith } 84689d82c54SBarry Smith 847*4a2ae208SSatish Balay #undef __FUNCT__ 848*4a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingRestoreInfo" 84907b52d57SBarry Smith /*@C 85007b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo - Frees the memory allocated by ISLocalToGlobalMappingGetInfo() 85189d82c54SBarry Smith 85207b52d57SBarry Smith Collective on ISLocalToGlobalMapping 85307b52d57SBarry Smith 85407b52d57SBarry Smith Input Parameters: 85507b52d57SBarry Smith . mapping - the mapping from local to global indexing 85607b52d57SBarry Smith 85707b52d57SBarry Smith Output Parameter: 85807b52d57SBarry Smith + nproc - number of processors that are connected to this one 85907b52d57SBarry Smith . proc - neighboring processors 86007b52d57SBarry Smith . numproc - number of indices for each processor 86107b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 86207b52d57SBarry Smith 86307b52d57SBarry Smith Level: advanced 86407b52d57SBarry Smith 86507b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 86607b52d57SBarry Smith ISLocalToGlobalMappingGetInfo() 86707b52d57SBarry Smith @*/ 86807b52d57SBarry Smith int ISLocalToGlobalMappingRestoreInfo(ISLocalToGlobalMapping mapping,int *nproc,int **procs,int **numprocs,int ***indices) 86907b52d57SBarry Smith { 87007b52d57SBarry Smith int ierr,i; 87107b52d57SBarry Smith 87207b52d57SBarry Smith PetscFunctionBegin; 87300ff320aSBarry Smith if (*procs) {ierr = PetscFree(*procs);CHKERRQ(ierr);} 87400ff320aSBarry Smith if (*numprocs) {ierr = PetscFree(*numprocs);CHKERRQ(ierr);} 87500ff320aSBarry Smith if (*indices) { 87600ff320aSBarry Smith if ((*indices)[0]) {ierr = PetscFree((*indices)[0]);CHKERRQ(ierr);} 87700ff320aSBarry Smith for (i=1; i<*nproc; i++) { 87824cf384cSBarry Smith if ((*indices)[i]) {ierr = PetscFree((*indices)[i]);CHKERRQ(ierr);} 87907b52d57SBarry Smith } 88007b52d57SBarry Smith ierr = PetscFree(*indices);CHKERRQ(ierr); 88124cf384cSBarry Smith } 88207b52d57SBarry Smith PetscFunctionReturn(0); 88307b52d57SBarry Smith } 88489d82c54SBarry Smith 885bc8ff85bSBarry Smith 886bc8ff85bSBarry Smith 887bc8ff85bSBarry Smith 888bc8ff85bSBarry Smith 889bc8ff85bSBarry Smith 890bc8ff85bSBarry Smith 891bc8ff85bSBarry Smith 892bc8ff85bSBarry Smith 893bc8ff85bSBarry Smith 894bc8ff85bSBarry Smith 895bc8ff85bSBarry Smith 896bc8ff85bSBarry Smith 897bc8ff85bSBarry Smith 898bc8ff85bSBarry Smith 899bc8ff85bSBarry Smith 900bc8ff85bSBarry Smith 90124cf384cSBarry Smith 902