1*323b833fSBarry Smith /*$Id: isltog.c,v 1.60 2001/01/15 21:44:35 bsmith Exp bsmith $*/ 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 65615d1e5SSatish Balay #undef __FUNC__ 7b0a32e0cSBarry Smith #define __FUNC__ "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 333b9aefa3SBarry Smith #undef __FUNC__ 34b0a32e0cSBarry Smith #define __FUNC__ "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 755a5d4f66SBarry Smith #undef __FUNC__ 76b0a32e0cSBarry Smith #define __FUNC__ "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 1122bdab257SBarry Smith #undef __FUNC__ 113b0a32e0cSBarry Smith #define __FUNC__ "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 1595615d1e5SSatish Balay #undef __FUNC__ 160*323b833fSBarry Smith #define __FUNC__ "ISLocalToGlobalMappingBlock" 161*323b833fSBarry Smith /*@C 162*323b833fSBarry Smith ISLocalToGlobalMappingBlock - Creates a blocked index version of an 163*323b833fSBarry Smith ISLocalToGlobalMapping that is appropriate for MatSetLocalToGlobalMappingBlock() 164*323b833fSBarry Smith and VecSetLocalToGlobalMappingBlock(). 165*323b833fSBarry Smith 166*323b833fSBarry Smith Not Collective, but communicator may have more than one process 167*323b833fSBarry Smith 168*323b833fSBarry Smith Input Parameters: 169*323b833fSBarry Smith + inmap - original point-wise mapping 170*323b833fSBarry Smith - bs - block size 171*323b833fSBarry Smith 172*323b833fSBarry Smith Output Parameter: 173*323b833fSBarry Smith . outmap - block based mapping 174*323b833fSBarry Smith 175*323b833fSBarry Smith Level: advanced 176*323b833fSBarry Smith 177*323b833fSBarry Smith Concepts: mapping^local to global 178*323b833fSBarry Smith 179*323b833fSBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingCreateIS() 180*323b833fSBarry Smith @*/ 181*323b833fSBarry Smith int ISLocalToGlobalMappingBlock(ISLocalToGlobalMapping inmap,int bs,ISLocalToGlobalMapping *outmap) 182*323b833fSBarry Smith { 183*323b833fSBarry Smith int ierr,*ii,i,n; 184*323b833fSBarry Smith 185*323b833fSBarry Smith PetscFunctionBegin; 186*323b833fSBarry Smith 187*323b833fSBarry Smith if (bs > 1) { 188*323b833fSBarry Smith n = inmap->n/bs; 189*323b833fSBarry Smith ierr = PetscMalloc(n*sizeof(int),&ii);CHKERRQ(ierr); 190*323b833fSBarry Smith for (i=0; i<n; i++) { 191*323b833fSBarry Smith ii[i] = inmap->indices[bs*i]; 192*323b833fSBarry Smith } 193*323b833fSBarry Smith ierr = ISLocalToGlobalMappingCreate(inmap->comm,n,ii,outmap);CHKERRQ(ierr); 194*323b833fSBarry Smith ierr = PetscFree(ii);CHKERRQ(ierr); 195*323b833fSBarry Smith } else { 196*323b833fSBarry Smith *outmap = inmap; 197*323b833fSBarry Smith ierr = PetscObjectReference((PetscObject)inmap);CHKERRQ(ierr); 198*323b833fSBarry Smith } 199*323b833fSBarry Smith PetscFunctionReturn(0); 200*323b833fSBarry Smith } 201*323b833fSBarry Smith 202*323b833fSBarry Smith #undef __FUNC__ 203b0a32e0cSBarry Smith #define __FUNC__ "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 2345615d1e5SSatish Balay #undef __FUNC__ 235b0a32e0cSBarry Smith #define __FUNC__ "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 313d4bb536fSBarry Smith #undef __FUNC__ 314b0a32e0cSBarry Smith #define __FUNC__ "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 349d4bb536fSBarry Smith #undef __FUNC__ 350b0a32e0cSBarry Smith #define __FUNC__ "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 43489d82c54SBarry Smith #undef __FUNC__ 435b0a32e0cSBarry Smith #define __FUNC__ "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 { 4603a96401aSBarry Smith int i,n = mapping->n,ierr,Ng,ng = PETSC_DECIDE,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 cnt = 0; 65130dcb7c9SBarry Smith for (i=0; i<nrecvs; i++) { 65230dcb7c9SBarry Smith nprocs[i] = 1; 65330dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 65430dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 65530dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 65630dcb7c9SBarry Smith nprocs[i] += 2 + nownedsenders[node]; 65730dcb7c9SBarry Smith } 65830dcb7c9SBarry Smith } 65930dcb7c9SBarry Smith } 66030dcb7c9SBarry Smith nt = 0; for (i=0; i<nsends2; i++) nt += nprocs[i]; 661b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int),&sends2);CHKERRQ(ierr); 662b0a32e0cSBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(int),&starts2);CHKERRQ(ierr); 66330dcb7c9SBarry Smith starts2[0] = 0; for (i=1; i<nsends2; i++) starts2[i] = starts2[i-1] + nprocs[i-1]; 66430dcb7c9SBarry Smith /* 66530dcb7c9SBarry Smith Each message is 1 + nprocs[i] long, and consists of 66630dcb7c9SBarry Smith (0) the number of nodes being sent back 66730dcb7c9SBarry Smith (1) the local node number, 66830dcb7c9SBarry Smith (2) the number of processors sharing it, 66930dcb7c9SBarry Smith (3) the processors sharing it 67030dcb7c9SBarry Smith */ 67130dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 67230dcb7c9SBarry Smith cnt = 1; 67330dcb7c9SBarry Smith sends2[starts2[i]] = 0; 67430dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 67530dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 67630dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 67730dcb7c9SBarry Smith sends2[starts2[i]]++; 67830dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = recvs[2*i*nmax+2*j+1]; 67930dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = nownedsenders[node]; 68030dcb7c9SBarry Smith ierr = PetscMemcpy(&sends2[starts2[i]+cnt],&ownedsenders[starts[node]],nownedsenders[node]*sizeof(int));CHKERRQ(ierr); 68130dcb7c9SBarry Smith cnt += nownedsenders[node]; 68230dcb7c9SBarry Smith } 68330dcb7c9SBarry Smith } 68430dcb7c9SBarry Smith } 68530dcb7c9SBarry Smith 68630dcb7c9SBarry Smith /* send the message lengths */ 68730dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 68824cf384cSBarry Smith ierr = MPI_Send(&nprocs[i],1,MPI_INT,source[i],tag2,comm);CHKERRQ(ierr); 68930dcb7c9SBarry Smith } 69030dcb7c9SBarry Smith 69130dcb7c9SBarry Smith /* receive the message lengths */ 69230dcb7c9SBarry Smith nrecvs2 = nsends; 693b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(int),&lens2);CHKERRQ(ierr); 694b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(int),&starts3);CHKERRQ(ierr); 69530dcb7c9SBarry Smith nt = 0; 69630dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 69724cf384cSBarry Smith ierr = MPI_Recv(&lens2[i],1,MPI_INT,dest[i],tag2,comm,&recv_status);CHKERRQ(ierr); 69830dcb7c9SBarry Smith nt += lens2[i]; 69930dcb7c9SBarry Smith } 70030dcb7c9SBarry Smith starts3[0] = 0; 70130dcb7c9SBarry Smith for (i=0; i<nrecvs2-1; i++) { 70230dcb7c9SBarry Smith starts3[i+1] = starts3[i] + lens2[i]; 70330dcb7c9SBarry Smith } 704b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int),&recvs2);CHKERRQ(ierr); 705b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(MPI_Request),&recv_waits);CHKERRQ(ierr); 70652b72c4aSBarry Smith for (i=0; i<nrecvs2; i++) { 70724cf384cSBarry Smith ierr = MPI_Irecv(recvs2+starts3[i],lens2[i],MPI_INT,dest[i],tag3,comm,recv_waits+i);CHKERRQ(ierr); 70830dcb7c9SBarry Smith } 70930dcb7c9SBarry Smith 71030dcb7c9SBarry Smith /* send the messages */ 711b0a32e0cSBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(MPI_Request),&send_waits);CHKERRQ(ierr); 71230dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 71324cf384cSBarry Smith ierr = MPI_Isend(sends2+starts2[i],nprocs[i],MPI_INT,source[i],tag3,comm,send_waits+i);CHKERRQ(ierr); 71430dcb7c9SBarry Smith } 71530dcb7c9SBarry Smith 71630dcb7c9SBarry Smith /* wait on receives */ 717b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(MPI_Status),&recv_statuses);CHKERRQ(ierr); 71830dcb7c9SBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 71930dcb7c9SBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 72030dcb7c9SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 72130dcb7c9SBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 72230dcb7c9SBarry Smith 72307b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 72430dcb7c9SBarry Smith cnt = 0; 72530dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 72630dcb7c9SBarry Smith nt = recvs2[cnt++]; 72730dcb7c9SBarry Smith for (j=0; j<nt; j++) { 72830dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] local node %d number of subdomains %d: ",rank,recvs2[cnt],recvs2[cnt+1]);CHKERRQ(ierr); 72930dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 73030dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",recvs2[cnt+2+k]);CHKERRQ(ierr); 73130dcb7c9SBarry Smith } 73230dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 73330dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 73430dcb7c9SBarry Smith } 73530dcb7c9SBarry Smith } 73630dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 73707b52d57SBarry Smith } /* ----------------------------------- */ 73830dcb7c9SBarry Smith 73930dcb7c9SBarry Smith /* count number subdomains for each local node */ 740b0a32e0cSBarry Smith ierr = PetscMalloc(size*sizeof(int),&nprocs);CHKERRQ(ierr); 74130dcb7c9SBarry Smith ierr = PetscMemzero(nprocs,size*sizeof(int));CHKERRQ(ierr); 74230dcb7c9SBarry Smith cnt = 0; 74330dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 74430dcb7c9SBarry Smith nt = recvs2[cnt++]; 74530dcb7c9SBarry Smith for (j=0; j<nt; j++) { 74630dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 74730dcb7c9SBarry Smith nprocs[recvs2[cnt+2+k]]++; 74830dcb7c9SBarry Smith } 74930dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 75030dcb7c9SBarry Smith } 75130dcb7c9SBarry Smith } 75230dcb7c9SBarry Smith nt = 0; for (i=0; i<size; i++) nt += (nprocs[i] > 0); 75330dcb7c9SBarry Smith *nproc = nt; 754b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int),procs);CHKERRQ(ierr); 755b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int),numprocs);CHKERRQ(ierr); 756b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int*),indices);CHKERRQ(ierr); 757b0a32e0cSBarry Smith ierr = PetscMalloc(size*sizeof(int),&bprocs);CHKERRQ(ierr); 75830dcb7c9SBarry Smith cnt = 0; 75930dcb7c9SBarry Smith for (i=0; i<size; i++) { 76030dcb7c9SBarry Smith if (nprocs[i] > 0) { 76130dcb7c9SBarry Smith bprocs[i] = cnt; 76230dcb7c9SBarry Smith (*procs)[cnt] = i; 76330dcb7c9SBarry Smith (*numprocs)[cnt] = nprocs[i]; 764b0a32e0cSBarry Smith ierr = PetscMalloc(nprocs[i]*sizeof(int),&(*indices)[cnt]);CHKERRQ(ierr); 76530dcb7c9SBarry Smith cnt++; 76630dcb7c9SBarry Smith } 76730dcb7c9SBarry Smith } 76830dcb7c9SBarry Smith 76930dcb7c9SBarry Smith /* make the list of subdomains for each nontrivial local node */ 77030dcb7c9SBarry Smith ierr = PetscMemzero(*numprocs,nt*sizeof(int));CHKERRQ(ierr); 77130dcb7c9SBarry Smith cnt = 0; 77230dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 77330dcb7c9SBarry Smith nt = recvs2[cnt++]; 77430dcb7c9SBarry Smith for (j=0; j<nt; j++) { 77530dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 77630dcb7c9SBarry Smith (*indices)[bprocs[recvs2[cnt+2+k]]][(*numprocs)[bprocs[recvs2[cnt+2+k]]]++] = recvs2[cnt]; 77730dcb7c9SBarry Smith } 77830dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 77930dcb7c9SBarry Smith } 78030dcb7c9SBarry Smith } 78130dcb7c9SBarry Smith ierr = PetscFree(bprocs);CHKERRQ(ierr); 78207b52d57SBarry Smith ierr = PetscFree(recvs2);CHKERRQ(ierr); 78330dcb7c9SBarry Smith 78407b52d57SBarry Smith /* sort the node indexing by their global numbers */ 78507b52d57SBarry Smith nt = *nproc; 78607b52d57SBarry Smith for (i=0; i<nt; i++) { 787b0a32e0cSBarry Smith ierr = PetscMalloc(((*numprocs)[i])*sizeof(int),&tmp);CHKERRQ(ierr); 78807b52d57SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 78907b52d57SBarry Smith tmp[j] = lindices[(*indices)[i][j]]; 79007b52d57SBarry Smith } 79107b52d57SBarry Smith ierr = PetscSortIntWithArray((*numprocs)[i],tmp,(*indices)[i]);CHKERRQ(ierr); 79207b52d57SBarry Smith ierr = PetscFree(tmp);CHKERRQ(ierr); 79307b52d57SBarry Smith } 79407b52d57SBarry Smith 79507b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 79630dcb7c9SBarry Smith nt = *nproc; 79730dcb7c9SBarry Smith for (i=0; i<nt; i++) { 79830dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] subdomain %d number of indices %d: ",rank,(*procs)[i],(*numprocs)[i]);CHKERRQ(ierr); 79930dcb7c9SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 80030dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",(*indices)[i][j]);CHKERRQ(ierr); 80130dcb7c9SBarry Smith } 80230dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 80330dcb7c9SBarry Smith } 80430dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 80507b52d57SBarry Smith } /* ----------------------------------- */ 80630dcb7c9SBarry Smith 80730dcb7c9SBarry Smith /* wait on sends */ 80830dcb7c9SBarry Smith if (nsends2) { 809b0a32e0cSBarry Smith ierr = PetscMalloc(nsends2*sizeof(MPI_Status),&send_status);CHKERRQ(ierr); 81030dcb7c9SBarry Smith ierr = MPI_Waitall(nsends2,send_waits,send_status);CHKERRQ(ierr); 81130dcb7c9SBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 81230dcb7c9SBarry Smith } 81330dcb7c9SBarry Smith 81430dcb7c9SBarry Smith ierr = PetscFree(starts3);CHKERRQ(ierr); 81530dcb7c9SBarry Smith ierr = PetscFree(dest);CHKERRQ(ierr); 81630dcb7c9SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 8173677ff5aSBarry Smith 818bc8ff85bSBarry Smith ierr = PetscFree(nownedsenders);CHKERRQ(ierr); 819bc8ff85bSBarry Smith ierr = PetscFree(ownedsenders);CHKERRQ(ierr); 820bc8ff85bSBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 82130dcb7c9SBarry Smith ierr = PetscFree(starts2);CHKERRQ(ierr); 82230dcb7c9SBarry Smith ierr = PetscFree(lens2);CHKERRQ(ierr); 82389d82c54SBarry Smith 82489d82c54SBarry Smith ierr = PetscFree(source);CHKERRQ(ierr); 82589d82c54SBarry Smith ierr = PetscFree(recvs);CHKERRQ(ierr); 8263a96401aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 82730dcb7c9SBarry Smith ierr = PetscFree(sends2);CHKERRQ(ierr); 82824cf384cSBarry Smith 82924cf384cSBarry Smith /* put the information about myself as the first entry in the list */ 83024cf384cSBarry Smith first_procs = (*procs)[0]; 83124cf384cSBarry Smith first_numprocs = (*numprocs)[0]; 83224cf384cSBarry Smith first_indices = (*indices)[0]; 83324cf384cSBarry Smith for (i=0; i<*nproc; i++) { 83424cf384cSBarry Smith if ((*procs)[i] == rank) { 83524cf384cSBarry Smith (*procs)[0] = (*procs)[i]; 83624cf384cSBarry Smith (*numprocs)[0] = (*numprocs)[i]; 83724cf384cSBarry Smith (*indices)[0] = (*indices)[i]; 83824cf384cSBarry Smith (*procs)[i] = first_procs; 83924cf384cSBarry Smith (*numprocs)[i] = first_numprocs; 84024cf384cSBarry Smith (*indices)[i] = first_indices; 84124cf384cSBarry Smith break; 84224cf384cSBarry Smith } 84324cf384cSBarry Smith } 84424cf384cSBarry Smith 84589d82c54SBarry Smith PetscFunctionReturn(0); 84689d82c54SBarry Smith } 84789d82c54SBarry Smith 84807b52d57SBarry Smith #undef __FUNC__ 849b0a32e0cSBarry Smith #define __FUNC__ "ISLocalToGlobalMappingRestoreInfo" 85007b52d57SBarry Smith /*@C 85107b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo - Frees the memory allocated by ISLocalToGlobalMappingGetInfo() 85289d82c54SBarry Smith 85307b52d57SBarry Smith Collective on ISLocalToGlobalMapping 85407b52d57SBarry Smith 85507b52d57SBarry Smith Input Parameters: 85607b52d57SBarry Smith . mapping - the mapping from local to global indexing 85707b52d57SBarry Smith 85807b52d57SBarry Smith Output Parameter: 85907b52d57SBarry Smith + nproc - number of processors that are connected to this one 86007b52d57SBarry Smith . proc - neighboring processors 86107b52d57SBarry Smith . numproc - number of indices for each processor 86207b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 86307b52d57SBarry Smith 86407b52d57SBarry Smith Level: advanced 86507b52d57SBarry Smith 86607b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 86707b52d57SBarry Smith ISLocalToGlobalMappingGetInfo() 86807b52d57SBarry Smith @*/ 86907b52d57SBarry Smith int ISLocalToGlobalMappingRestoreInfo(ISLocalToGlobalMapping mapping,int *nproc,int **procs,int **numprocs,int ***indices) 87007b52d57SBarry Smith { 87107b52d57SBarry Smith int ierr,i; 87207b52d57SBarry Smith 87307b52d57SBarry Smith PetscFunctionBegin; 87400ff320aSBarry Smith if (*procs) {ierr = PetscFree(*procs);CHKERRQ(ierr);} 87500ff320aSBarry Smith if (*numprocs) {ierr = PetscFree(*numprocs);CHKERRQ(ierr);} 87600ff320aSBarry Smith if (*indices) { 87700ff320aSBarry Smith if ((*indices)[0]) {ierr = PetscFree((*indices)[0]);CHKERRQ(ierr);} 87800ff320aSBarry Smith for (i=1; i<*nproc; i++) { 87924cf384cSBarry Smith if ((*indices)[i]) {ierr = PetscFree((*indices)[i]);CHKERRQ(ierr);} 88007b52d57SBarry Smith } 88107b52d57SBarry Smith ierr = PetscFree(*indices);CHKERRQ(ierr); 88224cf384cSBarry Smith } 88307b52d57SBarry Smith PetscFunctionReturn(0); 88407b52d57SBarry Smith } 88589d82c54SBarry 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 901bc8ff85bSBarry Smith 90224cf384cSBarry Smith 903