173f4d377SMatthew Knepley /*$Id: isltog.c,v 1.65 2001/05/21 14:16:29 bsmith Exp $*/ 22362add9SBarry Smith 3e090d566SSatish Balay #include "petscsys.h" /*I "petscsys.h" I*/ 4e090d566SSatish Balay #include "src/vec/is/isimpl.h" /*I "petscis.h" I*/ 52362add9SBarry Smith 68e58c17dSMatthew Knepley EXTERN int VecInitializePackage(char *); 78e58c17dSMatthew Knepley 84a2ae208SSatish Balay #undef __FUNCT__ 94a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingGetSize" 103b9aefa3SBarry Smith /*@C 113b9aefa3SBarry Smith ISLocalToGlobalMappingGetSize - Gets the local size of a local to global mapping. 123b9aefa3SBarry Smith 133b9aefa3SBarry Smith Not Collective 143b9aefa3SBarry Smith 153b9aefa3SBarry Smith Input Parameter: 163b9aefa3SBarry Smith . ltog - local to global mapping 173b9aefa3SBarry Smith 183b9aefa3SBarry Smith Output Parameter: 193b9aefa3SBarry Smith . n - the number of entries in the local mapping 203b9aefa3SBarry Smith 213b9aefa3SBarry Smith Level: advanced 223b9aefa3SBarry Smith 23273d9f13SBarry Smith Concepts: mapping^local to global 243b9aefa3SBarry Smith 253b9aefa3SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 263b9aefa3SBarry Smith @*/ 273b9aefa3SBarry Smith int ISLocalToGlobalMappingGetSize(ISLocalToGlobalMapping mapping,int *n) 283b9aefa3SBarry Smith { 293b9aefa3SBarry Smith PetscFunctionBegin; 303b9aefa3SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE); 313b9aefa3SBarry Smith *n = mapping->n; 323b9aefa3SBarry Smith PetscFunctionReturn(0); 333b9aefa3SBarry Smith } 343b9aefa3SBarry Smith 354a2ae208SSatish Balay #undef __FUNCT__ 364a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingView" 375a5d4f66SBarry Smith /*@C 385a5d4f66SBarry Smith ISLocalToGlobalMappingView - View a local to global mapping 395a5d4f66SBarry Smith 40b9cd556bSLois Curfman McInnes Not Collective 41b9cd556bSLois Curfman McInnes 425a5d4f66SBarry Smith Input Parameters: 433b9aefa3SBarry Smith + ltog - local to global mapping 443b9aefa3SBarry Smith - viewer - viewer 455a5d4f66SBarry Smith 46a997ad1aSLois Curfman McInnes Level: advanced 47a997ad1aSLois Curfman McInnes 48273d9f13SBarry Smith Concepts: mapping^local to global 495a5d4f66SBarry Smith 505a5d4f66SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 515a5d4f66SBarry Smith @*/ 52b0a32e0cSBarry Smith int ISLocalToGlobalMappingView(ISLocalToGlobalMapping mapping,PetscViewer viewer) 535a5d4f66SBarry Smith { 54f1af5d2fSBarry Smith int i,ierr,rank; 556831982aSBarry Smith PetscTruth isascii; 565a5d4f66SBarry Smith 575a5d4f66SBarry Smith PetscFunctionBegin; 586831982aSBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE); 59b0a32e0cSBarry Smith if (!viewer) viewer = PETSC_VIEWER_STDOUT_(mapping->comm); 60b0a32e0cSBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE); 615a5d4f66SBarry Smith 62f1af5d2fSBarry Smith ierr = MPI_Comm_rank(mapping->comm,&rank);CHKERRQ(ierr); 63b0a32e0cSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr); 646831982aSBarry Smith if (isascii) { 655a5d4f66SBarry Smith for (i=0; i<mapping->n; i++) { 66b0a32e0cSBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d] %d %d\n",rank,i,mapping->indices[i]);CHKERRQ(ierr); 676831982aSBarry Smith } 68b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 696831982aSBarry Smith } else { 7029bbc08cSBarry Smith SETERRQ1(1,"Viewer type %s not supported for ISLocalToGlobalMapping",((PetscObject)viewer)->type_name); 715a5d4f66SBarry Smith } 725a5d4f66SBarry Smith 735a5d4f66SBarry Smith PetscFunctionReturn(0); 745a5d4f66SBarry Smith } 755a5d4f66SBarry Smith 764a2ae208SSatish Balay #undef __FUNCT__ 774a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreateIS" 782bdab257SBarry Smith /*@C 792bdab257SBarry Smith ISLocalToGlobalMappingCreateIS - Creates a mapping between a local (0 to n) 802bdab257SBarry Smith ordering and a global parallel ordering. 812bdab257SBarry Smith 820f5bd95cSBarry Smith Not collective 83b9cd556bSLois Curfman McInnes 84a997ad1aSLois Curfman McInnes Input Parameter: 852bdab257SBarry Smith . is - index set containing the global numbers for each local 862bdab257SBarry Smith 87a997ad1aSLois Curfman McInnes Output Parameter: 882bdab257SBarry Smith . mapping - new mapping data structure 892bdab257SBarry Smith 90a997ad1aSLois Curfman McInnes Level: advanced 91a997ad1aSLois Curfman McInnes 92273d9f13SBarry Smith Concepts: mapping^local to global 932bdab257SBarry Smith 942bdab257SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 952bdab257SBarry Smith @*/ 962bdab257SBarry Smith int ISLocalToGlobalMappingCreateIS(IS is,ISLocalToGlobalMapping *mapping) 972bdab257SBarry Smith { 982bdab257SBarry Smith int n,*indices,ierr; 992bdab257SBarry Smith MPI_Comm comm; 1003a40ed3dSBarry Smith 1013a40ed3dSBarry Smith PetscFunctionBegin; 1022bdab257SBarry Smith PetscValidHeaderSpecific(is,IS_COOKIE); 1032bdab257SBarry Smith 1042bdab257SBarry Smith ierr = PetscObjectGetComm((PetscObject)is,&comm);CHKERRQ(ierr); 1053b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 1062bdab257SBarry Smith ierr = ISGetIndices(is,&indices);CHKERRQ(ierr); 1072bdab257SBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,n,indices,mapping);CHKERRQ(ierr); 1082bdab257SBarry Smith ierr = ISRestoreIndices(is,&indices);CHKERRQ(ierr); 1092bdab257SBarry Smith 1103a40ed3dSBarry Smith PetscFunctionReturn(0); 1112bdab257SBarry Smith } 1125a5d4f66SBarry Smith 113*b46b645bSBarry Smith 1144a2ae208SSatish Balay #undef __FUNCT__ 1154a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreate" 116dd7157adSSatish Balay /*@C 11790f02eecSBarry Smith ISLocalToGlobalMappingCreate - Creates a mapping between a local (0 to n) 11890f02eecSBarry Smith ordering and a global parallel ordering. 1192362add9SBarry Smith 12089d82c54SBarry Smith Not Collective, but communicator may have more than one process 121b9cd556bSLois Curfman McInnes 1222362add9SBarry Smith Input Parameters: 12389d82c54SBarry Smith + comm - MPI communicator 12490f02eecSBarry Smith . n - the number of local elements 125b9cd556bSLois Curfman McInnes - indices - the global index for each local element 1262362add9SBarry Smith 127a997ad1aSLois Curfman McInnes Output Parameter: 12890f02eecSBarry Smith . mapping - new mapping data structure 1292362add9SBarry Smith 130a997ad1aSLois Curfman McInnes Level: advanced 131a997ad1aSLois Curfman McInnes 132273d9f13SBarry Smith Concepts: mapping^local to global 1332362add9SBarry Smith 134*b46b645bSBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreateNC() 1352362add9SBarry Smith @*/ 136987e4450SSatish Balay int ISLocalToGlobalMappingCreate(MPI_Comm cm,int n,const int indices[],ISLocalToGlobalMapping *mapping) 1372362add9SBarry Smith { 138*b46b645bSBarry Smith int *in,ierr; 139*b46b645bSBarry Smith 140*b46b645bSBarry Smith PetscFunctionBegin; 141*b46b645bSBarry Smith PetscValidIntPointer(indices); 142*b46b645bSBarry Smith PetscValidPointer(mapping); 143*b46b645bSBarry Smith ierr = PetscMalloc((n+1)*sizeof(int),&in);CHKERRQ(ierr); 144*b46b645bSBarry Smith ierr = PetscMemcpy(in,indices,n*sizeof(int));CHKERRQ(ierr); 145*b46b645bSBarry Smith ierr = ISLocalToGlobalMappingCreateNC(cm,n,in,mapping);CHKERRQ(ierr); 146*b46b645bSBarry Smith PetscFunctionReturn(0); 147*b46b645bSBarry Smith } 148*b46b645bSBarry Smith 149*b46b645bSBarry Smith #undef __FUNCT__ 150*b46b645bSBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingCreateNC" 151*b46b645bSBarry Smith /*@C 152*b46b645bSBarry Smith ISLocalToGlobalMappingCreateNC - Creates a mapping between a local (0 to n) 153*b46b645bSBarry Smith ordering and a global parallel ordering. 154*b46b645bSBarry Smith 155*b46b645bSBarry Smith Not Collective, but communicator may have more than one process 156*b46b645bSBarry Smith 157*b46b645bSBarry Smith Input Parameters: 158*b46b645bSBarry Smith + comm - MPI communicator 159*b46b645bSBarry Smith . n - the number of local elements 160*b46b645bSBarry Smith - indices - the global index for each local element 161*b46b645bSBarry Smith 162*b46b645bSBarry Smith Output Parameter: 163*b46b645bSBarry Smith . mapping - new mapping data structure 164*b46b645bSBarry Smith 165*b46b645bSBarry Smith Level: developer 166*b46b645bSBarry Smith 167*b46b645bSBarry Smith Notes: Does not copy the indices, just keeps the pointer to the indices. The ISLocalToGlobalMappingDestroy() 168*b46b645bSBarry Smith will free the space so it must be obtained with PetscMalloc() and it must not be freed elsewhere. 169*b46b645bSBarry Smith 170*b46b645bSBarry Smith Concepts: mapping^local to global 171*b46b645bSBarry Smith 172*b46b645bSBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate() 173*b46b645bSBarry Smith @*/ 174*b46b645bSBarry Smith int ISLocalToGlobalMappingCreateNC(MPI_Comm cm,int n,const int indices[],ISLocalToGlobalMapping *mapping) 175*b46b645bSBarry Smith { 176549d3d68SSatish Balay int ierr; 177549d3d68SSatish Balay 1783a40ed3dSBarry Smith PetscFunctionBegin; 17990f02eecSBarry Smith PetscValidIntPointer(indices); 18090f02eecSBarry Smith PetscValidPointer(mapping); 1818e58c17dSMatthew Knepley *mapping = PETSC_NULL; 1828e58c17dSMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 1838e58c17dSMatthew Knepley ierr = VecInitializePackage(PETSC_NULL); CHKERRQ(ierr); 1848e58c17dSMatthew Knepley #endif 1852362add9SBarry Smith 1863f1db9ecSBarry Smith PetscHeaderCreate(*mapping,_p_ISLocalToGlobalMapping,int,IS_LTOGM_COOKIE,0,"ISLocalToGlobalMapping", 1873f1db9ecSBarry Smith cm,ISLocalToGlobalMappingDestroy,ISLocalToGlobalMappingView); 188b0a32e0cSBarry Smith PetscLogObjectCreate(*mapping); 189b0a32e0cSBarry Smith PetscLogObjectMemory(*mapping,sizeof(struct _p_ISLocalToGlobalMapping)+n*sizeof(int)); 190d4bb536fSBarry Smith 191d4bb536fSBarry Smith (*mapping)->n = n; 192*b46b645bSBarry Smith (*mapping)->indices = (int*)indices; 193d4bb536fSBarry Smith 194d4bb536fSBarry Smith /* 195d4bb536fSBarry Smith Do not create the global to local mapping. This is only created if 196d4bb536fSBarry Smith ISGlobalToLocalMapping() is called 197d4bb536fSBarry Smith */ 198d4bb536fSBarry Smith (*mapping)->globals = 0; 1993a40ed3dSBarry Smith PetscFunctionReturn(0); 2002362add9SBarry Smith } 2012362add9SBarry Smith 2024a2ae208SSatish Balay #undef __FUNCT__ 2034a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingBlock" 204323b833fSBarry Smith /*@C 205323b833fSBarry Smith ISLocalToGlobalMappingBlock - Creates a blocked index version of an 206323b833fSBarry Smith ISLocalToGlobalMapping that is appropriate for MatSetLocalToGlobalMappingBlock() 207323b833fSBarry Smith and VecSetLocalToGlobalMappingBlock(). 208323b833fSBarry Smith 209323b833fSBarry Smith Not Collective, but communicator may have more than one process 210323b833fSBarry Smith 211323b833fSBarry Smith Input Parameters: 212323b833fSBarry Smith + inmap - original point-wise mapping 213323b833fSBarry Smith - bs - block size 214323b833fSBarry Smith 215323b833fSBarry Smith Output Parameter: 216323b833fSBarry Smith . outmap - block based mapping 217323b833fSBarry Smith 218323b833fSBarry Smith Level: advanced 219323b833fSBarry Smith 220323b833fSBarry Smith Concepts: mapping^local to global 221323b833fSBarry Smith 222323b833fSBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingCreateIS() 223323b833fSBarry Smith @*/ 224323b833fSBarry Smith int ISLocalToGlobalMappingBlock(ISLocalToGlobalMapping inmap,int bs,ISLocalToGlobalMapping *outmap) 225323b833fSBarry Smith { 226323b833fSBarry Smith int ierr,*ii,i,n; 227323b833fSBarry Smith 228323b833fSBarry Smith PetscFunctionBegin; 229323b833fSBarry Smith 230323b833fSBarry Smith if (bs > 1) { 231323b833fSBarry Smith n = inmap->n/bs; 232323b833fSBarry Smith ierr = PetscMalloc(n*sizeof(int),&ii);CHKERRQ(ierr); 233323b833fSBarry Smith for (i=0; i<n; i++) { 234b8ee7809SBarry Smith ii[i] = inmap->indices[bs*i]/bs; 235323b833fSBarry Smith } 236323b833fSBarry Smith ierr = ISLocalToGlobalMappingCreate(inmap->comm,n,ii,outmap);CHKERRQ(ierr); 237323b833fSBarry Smith ierr = PetscFree(ii);CHKERRQ(ierr); 238323b833fSBarry Smith } else { 239323b833fSBarry Smith *outmap = inmap; 240323b833fSBarry Smith ierr = PetscObjectReference((PetscObject)inmap);CHKERRQ(ierr); 241323b833fSBarry Smith } 242323b833fSBarry Smith PetscFunctionReturn(0); 243323b833fSBarry Smith } 244323b833fSBarry Smith 2454a2ae208SSatish Balay #undef __FUNCT__ 2464a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingDestroy" 24790f02eecSBarry Smith /*@ 24890f02eecSBarry Smith ISLocalToGlobalMappingDestroy - Destroys a mapping between a local (0 to n) 24990f02eecSBarry Smith ordering and a global parallel ordering. 25090f02eecSBarry Smith 2510f5bd95cSBarry Smith Note Collective 252b9cd556bSLois Curfman McInnes 25390f02eecSBarry Smith Input Parameters: 25490f02eecSBarry Smith . mapping - mapping data structure 25590f02eecSBarry Smith 256a997ad1aSLois Curfman McInnes Level: advanced 257a997ad1aSLois Curfman McInnes 2583acfe500SLois Curfman McInnes .seealso: ISLocalToGlobalMappingCreate() 25990f02eecSBarry Smith @*/ 26090f02eecSBarry Smith int ISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping mapping) 26190f02eecSBarry Smith { 262606d414cSSatish Balay int ierr; 2633a40ed3dSBarry Smith PetscFunctionBegin; 26490f02eecSBarry Smith PetscValidPointer(mapping); 2653a40ed3dSBarry Smith if (--mapping->refct > 0) PetscFunctionReturn(0); 26685614651SBarry Smith if (mapping->refct < 0) { 26729bbc08cSBarry Smith SETERRQ(1,"Mapping already destroyed"); 26885614651SBarry Smith } 26990f02eecSBarry Smith 270606d414cSSatish Balay ierr = PetscFree(mapping->indices);CHKERRQ(ierr); 271606d414cSSatish Balay if (mapping->globals) {ierr = PetscFree(mapping->globals);CHKERRQ(ierr);} 272b0a32e0cSBarry Smith PetscLogObjectDestroy(mapping); 273d4bb536fSBarry Smith PetscHeaderDestroy(mapping); 2743a40ed3dSBarry Smith PetscFunctionReturn(0); 27590f02eecSBarry Smith } 27690f02eecSBarry Smith 2774a2ae208SSatish Balay #undef __FUNCT__ 2784a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingApplyIS" 27990f02eecSBarry Smith /*@ 2803acfe500SLois Curfman McInnes ISLocalToGlobalMappingApplyIS - Creates from an IS in the local numbering 2813acfe500SLois Curfman McInnes a new index set using the global numbering defined in an ISLocalToGlobalMapping 2823acfe500SLois Curfman McInnes context. 28390f02eecSBarry Smith 284b9cd556bSLois Curfman McInnes Not collective 285b9cd556bSLois Curfman McInnes 28690f02eecSBarry Smith Input Parameters: 287b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 288b9cd556bSLois Curfman McInnes - is - index set in local numbering 28990f02eecSBarry Smith 29090f02eecSBarry Smith Output Parameters: 29190f02eecSBarry Smith . newis - index set in global numbering 29290f02eecSBarry Smith 293a997ad1aSLois Curfman McInnes Level: advanced 294a997ad1aSLois Curfman McInnes 295273d9f13SBarry Smith Concepts: mapping^local to global 2963acfe500SLois Curfman McInnes 29790f02eecSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 298d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy(), ISGlobalToLocalMappingApply() 29990f02eecSBarry Smith @*/ 30090f02eecSBarry Smith int ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping mapping,IS is,IS *newis) 30190f02eecSBarry Smith { 3023b9aefa3SBarry Smith int ierr,n,i,*idxin,*idxmap,*idxout,Nmax = mapping->n; 3033a40ed3dSBarry Smith 3043a40ed3dSBarry Smith PetscFunctionBegin; 30590f02eecSBarry Smith PetscValidPointer(mapping); 30690f02eecSBarry Smith PetscValidHeaderSpecific(is,IS_COOKIE); 30790f02eecSBarry Smith PetscValidPointer(newis); 30890f02eecSBarry Smith 3093b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 31090f02eecSBarry Smith ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 31190f02eecSBarry Smith idxmap = mapping->indices; 31290f02eecSBarry Smith 313b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(int),&idxout);CHKERRQ(ierr); 31490f02eecSBarry Smith for (i=0; i<n; i++) { 31529bbc08cSBarry Smith if (idxin[i] >= Nmax) SETERRQ3(PETSC_ERR_ARG_OUTOFRANGE,"Local index %d too large %d (max) at %d",idxin[i],Nmax,i); 31690f02eecSBarry Smith idxout[i] = idxmap[idxin[i]]; 31790f02eecSBarry Smith } 3183b9aefa3SBarry Smith ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 319029af93fSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxout,newis);CHKERRQ(ierr); 320606d414cSSatish Balay ierr = PetscFree(idxout);CHKERRQ(ierr); 3213a40ed3dSBarry Smith PetscFunctionReturn(0); 32290f02eecSBarry Smith } 32390f02eecSBarry Smith 32489d82c54SBarry Smith /*MC 3253acfe500SLois Curfman McInnes ISLocalToGlobalMappingApply - Takes a list of integers in a local numbering 3263acfe500SLois Curfman McInnes and converts them to the global numbering. 32790f02eecSBarry Smith 328b9cd556bSLois Curfman McInnes Not collective 329b9cd556bSLois Curfman McInnes 330bb25748dSBarry Smith Input Parameters: 331b9cd556bSLois Curfman McInnes + mapping - the local to global mapping context 332bb25748dSBarry Smith . N - number of integers 333b9cd556bSLois Curfman McInnes - in - input indices in local numbering 334bb25748dSBarry Smith 335bb25748dSBarry Smith Output Parameter: 336bb25748dSBarry Smith . out - indices in global numbering 337bb25748dSBarry Smith 3383b9aefa3SBarry Smith Synopsis: 339216e7ba4SBarry Smith int ISLocalToGlobalMappingApply(ISLocalToGlobalMapping mapping,int N,int in[],int out[]) 3403b9aefa3SBarry Smith 341b9cd556bSLois Curfman McInnes Notes: 342b9cd556bSLois Curfman McInnes The in and out array parameters may be identical. 343d4bb536fSBarry Smith 344a997ad1aSLois Curfman McInnes Level: advanced 345a997ad1aSLois Curfman McInnes 346bb25748dSBarry Smith .seealso: ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 3470752156aSBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 348d4bb536fSBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 349bb25748dSBarry Smith 350273d9f13SBarry Smith Concepts: mapping^local to global 351d4bb536fSBarry Smith 35289d82c54SBarry Smith M*/ 353d4bb536fSBarry Smith 354d4bb536fSBarry Smith /* -----------------------------------------------------------------------------------------*/ 355d4bb536fSBarry Smith 3564a2ae208SSatish Balay #undef __FUNCT__ 3574a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingSetUp_Private" 358d4bb536fSBarry Smith /* 359d4bb536fSBarry Smith Creates the global fields in the ISLocalToGlobalMapping structure 360d4bb536fSBarry Smith */ 361d4bb536fSBarry Smith static int ISGlobalToLocalMappingSetUp_Private(ISLocalToGlobalMapping mapping) 362d4bb536fSBarry Smith { 363b0a32e0cSBarry Smith int ierr,i,*idx = mapping->indices,n = mapping->n,end,start,*globals; 364d4bb536fSBarry Smith 3653a40ed3dSBarry Smith PetscFunctionBegin; 366d4bb536fSBarry Smith end = 0; 367d4bb536fSBarry Smith start = 100000000; 368d4bb536fSBarry Smith 369d4bb536fSBarry Smith for (i=0; i<n; i++) { 370d4bb536fSBarry Smith if (idx[i] < 0) continue; 371d4bb536fSBarry Smith if (idx[i] < start) start = idx[i]; 372d4bb536fSBarry Smith if (idx[i] > end) end = idx[i]; 373d4bb536fSBarry Smith } 374d4bb536fSBarry Smith if (start > end) {start = 0; end = -1;} 375d4bb536fSBarry Smith mapping->globalstart = start; 376d4bb536fSBarry Smith mapping->globalend = end; 377d4bb536fSBarry Smith 378b0a32e0cSBarry Smith ierr = PetscMalloc((end-start+2)*sizeof(int),&globals);CHKERRQ(ierr); 379b0a32e0cSBarry Smith mapping->globals = globals; 380d4bb536fSBarry Smith for (i=0; i<end-start+1; i++) { 381d4bb536fSBarry Smith globals[i] = -1; 382d4bb536fSBarry Smith } 383d4bb536fSBarry Smith for (i=0; i<n; i++) { 384d4bb536fSBarry Smith if (idx[i] < 0) continue; 385d4bb536fSBarry Smith globals[idx[i] - start] = i; 386d4bb536fSBarry Smith } 387d4bb536fSBarry Smith 388b0a32e0cSBarry Smith PetscLogObjectMemory(mapping,(end-start+1)*sizeof(int)); 3893a40ed3dSBarry Smith PetscFunctionReturn(0); 390d4bb536fSBarry Smith } 391d4bb536fSBarry Smith 3924a2ae208SSatish Balay #undef __FUNCT__ 3934a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingApply" 394d4bb536fSBarry Smith /*@ 395a997ad1aSLois Curfman McInnes ISGlobalToLocalMappingApply - Provides the local numbering for a list of integers 396a997ad1aSLois Curfman McInnes specified with a global numbering. 397d4bb536fSBarry Smith 398b9cd556bSLois Curfman McInnes Not collective 399b9cd556bSLois Curfman McInnes 400d4bb536fSBarry Smith Input Parameters: 401b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 402d4bb536fSBarry Smith . type - IS_GTOLM_MASK - replaces global indices with no local value with -1 403d4bb536fSBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 404d4bb536fSBarry Smith . n - number of global indices to map 405b9cd556bSLois Curfman McInnes - idx - global indices to map 406d4bb536fSBarry Smith 407d4bb536fSBarry Smith Output Parameters: 408b9cd556bSLois Curfman McInnes + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 409b9cd556bSLois Curfman McInnes - idxout - local index of each global index, one must pass in an array long enough 410e182c471SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApply() with 411e182c471SBarry Smith idxout == PETSC_NULL to determine the required length (returned in nout) 412e182c471SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApply() 413e182c471SBarry Smith a second time to set the values. 414d4bb536fSBarry Smith 415b9cd556bSLois Curfman McInnes Notes: 416b9cd556bSLois Curfman McInnes Either nout or idxout may be PETSC_NULL. idx and idxout may be identical. 417d4bb536fSBarry Smith 4180f5bd95cSBarry Smith This is not scalable in memory usage. Each processor requires O(Nglobal) size 4190f5bd95cSBarry Smith array to compute these. 4200f5bd95cSBarry Smith 421a997ad1aSLois Curfman McInnes Level: advanced 422a997ad1aSLois Curfman McInnes 423273d9f13SBarry Smith Concepts: mapping^global to local 424d4bb536fSBarry Smith 425d4bb536fSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 426d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy() 427d4bb536fSBarry Smith @*/ 428d4bb536fSBarry Smith int ISGlobalToLocalMappingApply(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, 429987e4450SSatish Balay int n,const int idx[],int *nout,int idxout[]) 430d4bb536fSBarry Smith { 431d4bb536fSBarry Smith int i,ierr,*globals,nf = 0,tmp,start,end; 432d4bb536fSBarry Smith 4333a40ed3dSBarry Smith PetscFunctionBegin; 434d4bb536fSBarry Smith if (!mapping->globals) { 435d4bb536fSBarry Smith ierr = ISGlobalToLocalMappingSetUp_Private(mapping);CHKERRQ(ierr); 436d4bb536fSBarry Smith } 437d4bb536fSBarry Smith globals = mapping->globals; 438d4bb536fSBarry Smith start = mapping->globalstart; 439d4bb536fSBarry Smith end = mapping->globalend; 440d4bb536fSBarry Smith 441d4bb536fSBarry Smith if (type == IS_GTOLM_MASK) { 442d4bb536fSBarry Smith if (idxout) { 443d4bb536fSBarry Smith for (i=0; i<n; i++) { 444d4bb536fSBarry Smith if (idx[i] < 0) idxout[i] = idx[i]; 445d4bb536fSBarry Smith else if (idx[i] < start) idxout[i] = -1; 446d4bb536fSBarry Smith else if (idx[i] > end) idxout[i] = -1; 447d4bb536fSBarry Smith else idxout[i] = globals[idx[i] - start]; 448d4bb536fSBarry Smith } 449d4bb536fSBarry Smith } 450d4bb536fSBarry Smith if (nout) *nout = n; 451d4bb536fSBarry Smith } else { 452d4bb536fSBarry Smith if (idxout) { 453d4bb536fSBarry Smith for (i=0; i<n; i++) { 454d4bb536fSBarry Smith if (idx[i] < 0) continue; 455d4bb536fSBarry Smith if (idx[i] < start) continue; 456d4bb536fSBarry Smith if (idx[i] > end) continue; 457d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 458d4bb536fSBarry Smith if (tmp < 0) continue; 459d4bb536fSBarry Smith idxout[nf++] = tmp; 460d4bb536fSBarry Smith } 461d4bb536fSBarry Smith } else { 462d4bb536fSBarry Smith for (i=0; i<n; i++) { 463d4bb536fSBarry Smith if (idx[i] < 0) continue; 464d4bb536fSBarry Smith if (idx[i] < start) continue; 465d4bb536fSBarry Smith if (idx[i] > end) continue; 466d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 467d4bb536fSBarry Smith if (tmp < 0) continue; 468d4bb536fSBarry Smith nf++; 469d4bb536fSBarry Smith } 470d4bb536fSBarry Smith } 471d4bb536fSBarry Smith if (nout) *nout = nf; 472d4bb536fSBarry Smith } 473d4bb536fSBarry Smith 4743a40ed3dSBarry Smith PetscFunctionReturn(0); 475d4bb536fSBarry Smith } 47690f02eecSBarry Smith 4774a2ae208SSatish Balay #undef __FUNCT__ 4784a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingGetInfo" 47989d82c54SBarry Smith /*@C 48089d82c54SBarry Smith ISLocalToGlobalMappingGetInfo - Gets the neighbor information for each processor and 48189d82c54SBarry Smith each index shared by more than one processor 48289d82c54SBarry Smith 48389d82c54SBarry Smith Collective on ISLocalToGlobalMapping 48489d82c54SBarry Smith 48589d82c54SBarry Smith Input Parameters: 48689d82c54SBarry Smith . mapping - the mapping from local to global indexing 48789d82c54SBarry Smith 48889d82c54SBarry Smith Output Parameter: 48989d82c54SBarry Smith + nproc - number of processors that are connected to this one 49089d82c54SBarry Smith . proc - neighboring processors 49107b52d57SBarry Smith . numproc - number of indices for each subdomain (processor) 49207b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 49389d82c54SBarry Smith 49489d82c54SBarry Smith Level: advanced 49589d82c54SBarry Smith 496273d9f13SBarry Smith Concepts: mapping^local to global 49789d82c54SBarry Smith 49807b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 49907b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo() 50089d82c54SBarry Smith @*/ 50130dcb7c9SBarry Smith int ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping mapping,int *nproc,int **procs,int **numprocs,int ***indices) 50289d82c54SBarry Smith { 503fa7fbcffSSatish Balay int i,n = mapping->n,ierr,Ng,ng,max = 0,*lindices = mapping->indices; 5043a96401aSBarry Smith int size,rank,*nprocs,*owner,nsends,*sends,j,*starts,*work,nmax,nrecvs,*recvs,proc; 50524cf384cSBarry Smith int tag1,tag2,tag3,cnt,*len,*source,imdex,scale,*ownedsenders,*nownedsenders,rstart,nowned; 50607b52d57SBarry Smith int node,nownedm,nt,*sends2,nsends2,*starts2,*lens2,*dest,nrecvs2,*starts3,*recvs2,k,*bprocs,*tmp; 50724cf384cSBarry Smith int first_procs,first_numprocs,*first_indices; 50889d82c54SBarry Smith MPI_Request *recv_waits,*send_waits; 50930dcb7c9SBarry Smith MPI_Status recv_status,*send_status,*recv_statuses; 51089d82c54SBarry Smith MPI_Comm comm = mapping->comm; 51107b52d57SBarry Smith PetscTruth debug = PETSC_FALSE; 51289d82c54SBarry Smith 51389d82c54SBarry Smith PetscFunctionBegin; 51424cf384cSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 51524cf384cSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 51624cf384cSBarry Smith if (size == 1) { 51724cf384cSBarry Smith *nproc = 0; 51824cf384cSBarry Smith *procs = PETSC_NULL; 519b0a32e0cSBarry Smith ierr = PetscMalloc(sizeof(int),numprocs);CHKERRQ(ierr); 5201e2105dcSBarry Smith (*numprocs)[0] = 0; 521b0a32e0cSBarry Smith ierr = PetscMalloc(sizeof(int*),indices);CHKERRQ(ierr); 5221e2105dcSBarry Smith (*indices)[0] = PETSC_NULL; 52324cf384cSBarry Smith PetscFunctionReturn(0); 52424cf384cSBarry Smith } 52524cf384cSBarry Smith 526b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-islocaltoglobalmappinggetinfo_debug",&debug);CHKERRQ(ierr); 52707b52d57SBarry Smith 5283677ff5aSBarry Smith /* 5293677ff5aSBarry Smith Notes on ISLocalToGlobalMappingGetInfo 5303677ff5aSBarry Smith 5313677ff5aSBarry Smith globally owned node - the nodes that have been assigned to this processor in global 5323677ff5aSBarry Smith numbering, just for this routine. 5333677ff5aSBarry Smith 5343677ff5aSBarry Smith nontrivial globally owned node - node assigned to this processor that is on a subdomain 5353677ff5aSBarry Smith boundary (i.e. is has more than one local owner) 5363677ff5aSBarry Smith 5373677ff5aSBarry Smith locally owned node - node that exists on this processors subdomain 5383677ff5aSBarry Smith 5393677ff5aSBarry Smith nontrivial locally owned node - node that is not in the interior (i.e. has more than one 5403677ff5aSBarry Smith local subdomain 5413677ff5aSBarry Smith */ 54224cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag1);CHKERRQ(ierr); 54324cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag2);CHKERRQ(ierr); 54424cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag3);CHKERRQ(ierr); 54589d82c54SBarry Smith 54689d82c54SBarry Smith for (i=0; i<n; i++) { 54789d82c54SBarry Smith if (lindices[i] > max) max = lindices[i]; 54889d82c54SBarry Smith } 54989d82c54SBarry Smith ierr = MPI_Allreduce(&max,&Ng,1,MPI_INT,MPI_MAX,comm);CHKERRQ(ierr); 55078058e43SBarry Smith Ng++; 55189d82c54SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 55289d82c54SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 553bc8ff85bSBarry Smith scale = Ng/size + 1; 554a2e34c3dSBarry Smith ng = scale; if (rank == size-1) ng = Ng - scale*(size-1); ng = PetscMax(1,ng); 555caba0dd0SBarry Smith rstart = scale*rank; 55689d82c54SBarry Smith 55789d82c54SBarry Smith /* determine ownership ranges of global indices */ 558b0a32e0cSBarry Smith ierr = PetscMalloc((2*size+1)*sizeof(int),&nprocs);CHKERRQ(ierr); 5592880cf29SBarry Smith ierr = PetscMemzero(nprocs,2*size*sizeof(int));CHKERRQ(ierr); 56089d82c54SBarry Smith 56189d82c54SBarry Smith /* determine owners of each local node */ 562b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(int),&owner);CHKERRQ(ierr); 56389d82c54SBarry Smith for (i=0; i<n; i++) { 5643677ff5aSBarry Smith proc = lindices[i]/scale; /* processor that globally owns this index */ 5653677ff5aSBarry Smith nprocs[size+proc] = 1; /* processor globally owns at least one of ours */ 5663677ff5aSBarry Smith owner[i] = proc; 5673677ff5aSBarry Smith nprocs[proc]++; /* count of how many that processor globally owns of ours */ 56889d82c54SBarry Smith } 56989d82c54SBarry Smith nsends = 0; for (i=0; i<size; i++) nsends += nprocs[size + i]; 570b0a32e0cSBarry Smith PetscLogInfo(0,"ISLocalToGlobalMappingGetInfo: Number of global owners for my local data %d\n",nsends); 57189d82c54SBarry Smith 57289d82c54SBarry Smith /* inform other processors of number of messages and max length*/ 573b0a32e0cSBarry Smith ierr = PetscMalloc(2*size*sizeof(int),&work);CHKERRQ(ierr); 57489d82c54SBarry Smith ierr = MPI_Allreduce(nprocs,work,2*size,MPI_INT,PetscMaxSum_Op,comm);CHKERRQ(ierr); 57589d82c54SBarry Smith nmax = work[rank]; 57689d82c54SBarry Smith nrecvs = work[size+rank]; 57789d82c54SBarry Smith ierr = PetscFree(work);CHKERRQ(ierr); 578b0a32e0cSBarry Smith PetscLogInfo(0,"ISLocalToGlobalMappingGetInfo: Number of local owners for my global data %d\n",nrecvs); 57989d82c54SBarry Smith 58089d82c54SBarry Smith /* post receives for owned rows */ 581b0a32e0cSBarry Smith ierr = PetscMalloc((2*nrecvs+1)*(nmax+1)*sizeof(int),&recvs);CHKERRQ(ierr); 582b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs+1)*sizeof(MPI_Request),&recv_waits);CHKERRQ(ierr); 58389d82c54SBarry Smith for (i=0; i<nrecvs; i++) { 58424cf384cSBarry Smith ierr = MPI_Irecv(recvs+2*nmax*i,2*nmax,MPI_INT,MPI_ANY_SOURCE,tag1,comm,recv_waits+i);CHKERRQ(ierr); 58589d82c54SBarry Smith } 58689d82c54SBarry Smith 58789d82c54SBarry Smith /* pack messages containing lists of local nodes to owners */ 588b0a32e0cSBarry Smith ierr = PetscMalloc((2*n+1)*sizeof(int),&sends);CHKERRQ(ierr); 589b0a32e0cSBarry Smith ierr = PetscMalloc((size+1)*sizeof(int),&starts);CHKERRQ(ierr); 59089d82c54SBarry Smith starts[0] = 0; 59130dcb7c9SBarry Smith for (i=1; i<size; i++) { starts[i] = starts[i-1] + 2*nprocs[i-1];} 59289d82c54SBarry Smith for (i=0; i<n; i++) { 59389d82c54SBarry Smith sends[starts[owner[i]]++] = lindices[i]; 59430dcb7c9SBarry Smith sends[starts[owner[i]]++] = i; 59589d82c54SBarry Smith } 59689d82c54SBarry Smith ierr = PetscFree(owner);CHKERRQ(ierr); 59789d82c54SBarry Smith starts[0] = 0; 59830dcb7c9SBarry Smith for (i=1; i<size; i++) { starts[i] = starts[i-1] + 2*nprocs[i-1];} 59989d82c54SBarry Smith 60089d82c54SBarry Smith /* send the messages */ 601b0a32e0cSBarry Smith ierr = PetscMalloc((nsends+1)*sizeof(MPI_Request),&send_waits);CHKERRQ(ierr); 602b0a32e0cSBarry Smith ierr = PetscMalloc((nsends+1)*sizeof(int),&dest);CHKERRQ(ierr); 60389d82c54SBarry Smith cnt = 0; 60489d82c54SBarry Smith for (i=0; i<size; i++) { 60589d82c54SBarry Smith if (nprocs[i]) { 60624cf384cSBarry Smith ierr = MPI_Isend(sends+starts[i],2*nprocs[i],MPI_INT,i,tag1,comm,send_waits+cnt);CHKERRQ(ierr); 60730dcb7c9SBarry Smith dest[cnt] = i; 60889d82c54SBarry Smith cnt++; 60989d82c54SBarry Smith } 61089d82c54SBarry Smith } 61189d82c54SBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 61289d82c54SBarry Smith 61389d82c54SBarry Smith /* wait on receives */ 614b0a32e0cSBarry Smith ierr = PetscMalloc((2*nrecvs+1)*sizeof(int),&source);CHKERRQ(ierr); 61589d82c54SBarry Smith len = source + nrecvs; 61689d82c54SBarry Smith cnt = nrecvs; 617b0a32e0cSBarry Smith ierr = PetscMalloc((ng+1)*sizeof(int),&nownedsenders);CHKERRQ(ierr); 618caba0dd0SBarry Smith ierr = PetscMemzero(nownedsenders,ng*sizeof(int));CHKERRQ(ierr); 61989d82c54SBarry Smith while (cnt) { 62089d82c54SBarry Smith ierr = MPI_Waitany(nrecvs,recv_waits,&imdex,&recv_status);CHKERRQ(ierr); 62189d82c54SBarry Smith /* unpack receives into our local space */ 62289d82c54SBarry Smith ierr = MPI_Get_count(&recv_status,MPI_INT,&len[imdex]);CHKERRQ(ierr); 62389d82c54SBarry Smith source[imdex] = recv_status.MPI_SOURCE; 62430dcb7c9SBarry Smith len[imdex] = len[imdex]/2; 625caba0dd0SBarry Smith /* count how many local owners for each of my global owned indices */ 62630dcb7c9SBarry Smith for (i=0; i<len[imdex]; i++) nownedsenders[recvs[2*imdex*nmax+2*i]-rstart]++; 62789d82c54SBarry Smith cnt--; 62889d82c54SBarry Smith } 62989d82c54SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 63089d82c54SBarry Smith 63130dcb7c9SBarry Smith /* count how many globally owned indices are on an edge multiplied by how many processors own them. */ 632bc8ff85bSBarry Smith nowned = 0; 633bc8ff85bSBarry Smith nownedm = 0; 634bc8ff85bSBarry Smith for (i=0; i<ng; i++) { 635bc8ff85bSBarry Smith if (nownedsenders[i] > 1) {nownedm += nownedsenders[i]; nowned++;} 636bc8ff85bSBarry Smith } 637bc8ff85bSBarry Smith 638bc8ff85bSBarry Smith /* create single array to contain rank of all local owners of each globally owned index */ 639b0a32e0cSBarry Smith ierr = PetscMalloc((nownedm+1)*sizeof(int),&ownedsenders);CHKERRQ(ierr); 640b0a32e0cSBarry Smith ierr = PetscMalloc((ng+1)*sizeof(int),&starts);CHKERRQ(ierr); 641bc8ff85bSBarry Smith starts[0] = 0; 642bc8ff85bSBarry Smith for (i=1; i<ng; i++) { 643bc8ff85bSBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 644bc8ff85bSBarry Smith else starts[i] = starts[i-1]; 645bc8ff85bSBarry Smith } 646bc8ff85bSBarry Smith 64730dcb7c9SBarry Smith /* for each nontrival globally owned node list all arriving processors */ 648bc8ff85bSBarry Smith for (i=0; i<nrecvs; i++) { 649bc8ff85bSBarry Smith for (j=0; j<len[i]; j++) { 65030dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 651bc8ff85bSBarry Smith if (nownedsenders[node] > 1) { 652bc8ff85bSBarry Smith ownedsenders[starts[node]++] = source[i]; 653bc8ff85bSBarry Smith } 654bc8ff85bSBarry Smith } 655bc8ff85bSBarry Smith } 656bc8ff85bSBarry Smith 65707b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 65830dcb7c9SBarry Smith starts[0] = 0; 65930dcb7c9SBarry Smith for (i=1; i<ng; i++) { 66030dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 66130dcb7c9SBarry Smith else starts[i] = starts[i-1]; 66230dcb7c9SBarry Smith } 66330dcb7c9SBarry Smith for (i=0; i<ng; i++) { 66430dcb7c9SBarry Smith if (nownedsenders[i] > 1) { 66530dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] global node %d local owner processors: ",rank,i+rstart);CHKERRQ(ierr); 66630dcb7c9SBarry Smith for (j=0; j<nownedsenders[i]; j++) { 66730dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",ownedsenders[starts[i]+j]);CHKERRQ(ierr); 66830dcb7c9SBarry Smith } 66930dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 67030dcb7c9SBarry Smith } 67130dcb7c9SBarry Smith } 67230dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 67307b52d57SBarry Smith }/* ----------------------------------- */ 67430dcb7c9SBarry Smith 6753677ff5aSBarry Smith /* wait on original sends */ 6763a96401aSBarry Smith if (nsends) { 677b0a32e0cSBarry Smith ierr = PetscMalloc(nsends*sizeof(MPI_Status),&send_status);CHKERRQ(ierr); 6783a96401aSBarry Smith ierr = MPI_Waitall(nsends,send_waits,send_status);CHKERRQ(ierr); 6793a96401aSBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 6803a96401aSBarry Smith } 68189d82c54SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 6823a96401aSBarry Smith ierr = PetscFree(sends);CHKERRQ(ierr); 6833677ff5aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 6843677ff5aSBarry Smith 6853677ff5aSBarry Smith /* pack messages to send back to local owners */ 68630dcb7c9SBarry Smith starts[0] = 0; 68730dcb7c9SBarry Smith for (i=1; i<ng; i++) { 68830dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 68930dcb7c9SBarry Smith else starts[i] = starts[i-1]; 69030dcb7c9SBarry Smith } 69130dcb7c9SBarry Smith nsends2 = nrecvs; 692b0a32e0cSBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(int),&nprocs);CHKERRQ(ierr); /* length of each message */ 69330dcb7c9SBarry Smith for (i=0; i<nrecvs; i++) { 69430dcb7c9SBarry Smith nprocs[i] = 1; 69530dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 69630dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 69730dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 69830dcb7c9SBarry Smith nprocs[i] += 2 + nownedsenders[node]; 69930dcb7c9SBarry Smith } 70030dcb7c9SBarry Smith } 70130dcb7c9SBarry Smith } 70230dcb7c9SBarry Smith nt = 0; for (i=0; i<nsends2; i++) nt += nprocs[i]; 703b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int),&sends2);CHKERRQ(ierr); 704b0a32e0cSBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(int),&starts2);CHKERRQ(ierr); 70530dcb7c9SBarry Smith starts2[0] = 0; for (i=1; i<nsends2; i++) starts2[i] = starts2[i-1] + nprocs[i-1]; 70630dcb7c9SBarry Smith /* 70730dcb7c9SBarry Smith Each message is 1 + nprocs[i] long, and consists of 70830dcb7c9SBarry Smith (0) the number of nodes being sent back 70930dcb7c9SBarry Smith (1) the local node number, 71030dcb7c9SBarry Smith (2) the number of processors sharing it, 71130dcb7c9SBarry Smith (3) the processors sharing it 71230dcb7c9SBarry Smith */ 71330dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 71430dcb7c9SBarry Smith cnt = 1; 71530dcb7c9SBarry Smith sends2[starts2[i]] = 0; 71630dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 71730dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 71830dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 71930dcb7c9SBarry Smith sends2[starts2[i]]++; 72030dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = recvs[2*i*nmax+2*j+1]; 72130dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = nownedsenders[node]; 72230dcb7c9SBarry Smith ierr = PetscMemcpy(&sends2[starts2[i]+cnt],&ownedsenders[starts[node]],nownedsenders[node]*sizeof(int));CHKERRQ(ierr); 72330dcb7c9SBarry Smith cnt += nownedsenders[node]; 72430dcb7c9SBarry Smith } 72530dcb7c9SBarry Smith } 72630dcb7c9SBarry Smith } 72730dcb7c9SBarry Smith 72830dcb7c9SBarry Smith /* send the message lengths */ 72930dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 73024cf384cSBarry Smith ierr = MPI_Send(&nprocs[i],1,MPI_INT,source[i],tag2,comm);CHKERRQ(ierr); 73130dcb7c9SBarry Smith } 73230dcb7c9SBarry Smith 73330dcb7c9SBarry Smith /* receive the message lengths */ 73430dcb7c9SBarry Smith nrecvs2 = nsends; 735b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(int),&lens2);CHKERRQ(ierr); 736b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(int),&starts3);CHKERRQ(ierr); 73730dcb7c9SBarry Smith nt = 0; 73830dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 73924cf384cSBarry Smith ierr = MPI_Recv(&lens2[i],1,MPI_INT,dest[i],tag2,comm,&recv_status);CHKERRQ(ierr); 74030dcb7c9SBarry Smith nt += lens2[i]; 74130dcb7c9SBarry Smith } 74230dcb7c9SBarry Smith starts3[0] = 0; 74330dcb7c9SBarry Smith for (i=0; i<nrecvs2-1; i++) { 74430dcb7c9SBarry Smith starts3[i+1] = starts3[i] + lens2[i]; 74530dcb7c9SBarry Smith } 746b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int),&recvs2);CHKERRQ(ierr); 747b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(MPI_Request),&recv_waits);CHKERRQ(ierr); 74852b72c4aSBarry Smith for (i=0; i<nrecvs2; i++) { 74924cf384cSBarry Smith ierr = MPI_Irecv(recvs2+starts3[i],lens2[i],MPI_INT,dest[i],tag3,comm,recv_waits+i);CHKERRQ(ierr); 75030dcb7c9SBarry Smith } 75130dcb7c9SBarry Smith 75230dcb7c9SBarry Smith /* send the messages */ 753b0a32e0cSBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(MPI_Request),&send_waits);CHKERRQ(ierr); 75430dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 75524cf384cSBarry Smith ierr = MPI_Isend(sends2+starts2[i],nprocs[i],MPI_INT,source[i],tag3,comm,send_waits+i);CHKERRQ(ierr); 75630dcb7c9SBarry Smith } 75730dcb7c9SBarry Smith 75830dcb7c9SBarry Smith /* wait on receives */ 759b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(MPI_Status),&recv_statuses);CHKERRQ(ierr); 76030dcb7c9SBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 76130dcb7c9SBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 76230dcb7c9SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 76330dcb7c9SBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 76430dcb7c9SBarry Smith 76507b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 76630dcb7c9SBarry Smith cnt = 0; 76730dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 76830dcb7c9SBarry Smith nt = recvs2[cnt++]; 76930dcb7c9SBarry Smith for (j=0; j<nt; j++) { 77030dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] local node %d number of subdomains %d: ",rank,recvs2[cnt],recvs2[cnt+1]);CHKERRQ(ierr); 77130dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 77230dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",recvs2[cnt+2+k]);CHKERRQ(ierr); 77330dcb7c9SBarry Smith } 77430dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 77530dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 77630dcb7c9SBarry Smith } 77730dcb7c9SBarry Smith } 77830dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 77907b52d57SBarry Smith } /* ----------------------------------- */ 78030dcb7c9SBarry Smith 78130dcb7c9SBarry Smith /* count number subdomains for each local node */ 782b0a32e0cSBarry Smith ierr = PetscMalloc(size*sizeof(int),&nprocs);CHKERRQ(ierr); 78330dcb7c9SBarry Smith ierr = PetscMemzero(nprocs,size*sizeof(int));CHKERRQ(ierr); 78430dcb7c9SBarry Smith cnt = 0; 78530dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 78630dcb7c9SBarry Smith nt = recvs2[cnt++]; 78730dcb7c9SBarry Smith for (j=0; j<nt; j++) { 78830dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 78930dcb7c9SBarry Smith nprocs[recvs2[cnt+2+k]]++; 79030dcb7c9SBarry Smith } 79130dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 79230dcb7c9SBarry Smith } 79330dcb7c9SBarry Smith } 79430dcb7c9SBarry Smith nt = 0; for (i=0; i<size; i++) nt += (nprocs[i] > 0); 79530dcb7c9SBarry Smith *nproc = nt; 796b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int),procs);CHKERRQ(ierr); 797b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int),numprocs);CHKERRQ(ierr); 798b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int*),indices);CHKERRQ(ierr); 799b0a32e0cSBarry Smith ierr = PetscMalloc(size*sizeof(int),&bprocs);CHKERRQ(ierr); 80030dcb7c9SBarry Smith cnt = 0; 80130dcb7c9SBarry Smith for (i=0; i<size; i++) { 80230dcb7c9SBarry Smith if (nprocs[i] > 0) { 80330dcb7c9SBarry Smith bprocs[i] = cnt; 80430dcb7c9SBarry Smith (*procs)[cnt] = i; 80530dcb7c9SBarry Smith (*numprocs)[cnt] = nprocs[i]; 806b0a32e0cSBarry Smith ierr = PetscMalloc(nprocs[i]*sizeof(int),&(*indices)[cnt]);CHKERRQ(ierr); 80730dcb7c9SBarry Smith cnt++; 80830dcb7c9SBarry Smith } 80930dcb7c9SBarry Smith } 81030dcb7c9SBarry Smith 81130dcb7c9SBarry Smith /* make the list of subdomains for each nontrivial local node */ 81230dcb7c9SBarry Smith ierr = PetscMemzero(*numprocs,nt*sizeof(int));CHKERRQ(ierr); 81330dcb7c9SBarry Smith cnt = 0; 81430dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 81530dcb7c9SBarry Smith nt = recvs2[cnt++]; 81630dcb7c9SBarry Smith for (j=0; j<nt; j++) { 81730dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 81830dcb7c9SBarry Smith (*indices)[bprocs[recvs2[cnt+2+k]]][(*numprocs)[bprocs[recvs2[cnt+2+k]]]++] = recvs2[cnt]; 81930dcb7c9SBarry Smith } 82030dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 82130dcb7c9SBarry Smith } 82230dcb7c9SBarry Smith } 82330dcb7c9SBarry Smith ierr = PetscFree(bprocs);CHKERRQ(ierr); 82407b52d57SBarry Smith ierr = PetscFree(recvs2);CHKERRQ(ierr); 82530dcb7c9SBarry Smith 82607b52d57SBarry Smith /* sort the node indexing by their global numbers */ 82707b52d57SBarry Smith nt = *nproc; 82807b52d57SBarry Smith for (i=0; i<nt; i++) { 829b0a32e0cSBarry Smith ierr = PetscMalloc(((*numprocs)[i])*sizeof(int),&tmp);CHKERRQ(ierr); 83007b52d57SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 83107b52d57SBarry Smith tmp[j] = lindices[(*indices)[i][j]]; 83207b52d57SBarry Smith } 83307b52d57SBarry Smith ierr = PetscSortIntWithArray((*numprocs)[i],tmp,(*indices)[i]);CHKERRQ(ierr); 83407b52d57SBarry Smith ierr = PetscFree(tmp);CHKERRQ(ierr); 83507b52d57SBarry Smith } 83607b52d57SBarry Smith 83707b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 83830dcb7c9SBarry Smith nt = *nproc; 83930dcb7c9SBarry Smith for (i=0; i<nt; i++) { 84030dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] subdomain %d number of indices %d: ",rank,(*procs)[i],(*numprocs)[i]);CHKERRQ(ierr); 84130dcb7c9SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 84230dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",(*indices)[i][j]);CHKERRQ(ierr); 84330dcb7c9SBarry Smith } 84430dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 84530dcb7c9SBarry Smith } 84630dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 84707b52d57SBarry Smith } /* ----------------------------------- */ 84830dcb7c9SBarry Smith 84930dcb7c9SBarry Smith /* wait on sends */ 85030dcb7c9SBarry Smith if (nsends2) { 851b0a32e0cSBarry Smith ierr = PetscMalloc(nsends2*sizeof(MPI_Status),&send_status);CHKERRQ(ierr); 85230dcb7c9SBarry Smith ierr = MPI_Waitall(nsends2,send_waits,send_status);CHKERRQ(ierr); 85330dcb7c9SBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 85430dcb7c9SBarry Smith } 85530dcb7c9SBarry Smith 85630dcb7c9SBarry Smith ierr = PetscFree(starts3);CHKERRQ(ierr); 85730dcb7c9SBarry Smith ierr = PetscFree(dest);CHKERRQ(ierr); 85830dcb7c9SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 8593677ff5aSBarry Smith 860bc8ff85bSBarry Smith ierr = PetscFree(nownedsenders);CHKERRQ(ierr); 861bc8ff85bSBarry Smith ierr = PetscFree(ownedsenders);CHKERRQ(ierr); 862bc8ff85bSBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 86330dcb7c9SBarry Smith ierr = PetscFree(starts2);CHKERRQ(ierr); 86430dcb7c9SBarry Smith ierr = PetscFree(lens2);CHKERRQ(ierr); 86589d82c54SBarry Smith 86689d82c54SBarry Smith ierr = PetscFree(source);CHKERRQ(ierr); 86789d82c54SBarry Smith ierr = PetscFree(recvs);CHKERRQ(ierr); 8683a96401aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 86930dcb7c9SBarry Smith ierr = PetscFree(sends2);CHKERRQ(ierr); 87024cf384cSBarry Smith 87124cf384cSBarry Smith /* put the information about myself as the first entry in the list */ 87224cf384cSBarry Smith first_procs = (*procs)[0]; 87324cf384cSBarry Smith first_numprocs = (*numprocs)[0]; 87424cf384cSBarry Smith first_indices = (*indices)[0]; 87524cf384cSBarry Smith for (i=0; i<*nproc; i++) { 87624cf384cSBarry Smith if ((*procs)[i] == rank) { 87724cf384cSBarry Smith (*procs)[0] = (*procs)[i]; 87824cf384cSBarry Smith (*numprocs)[0] = (*numprocs)[i]; 87924cf384cSBarry Smith (*indices)[0] = (*indices)[i]; 88024cf384cSBarry Smith (*procs)[i] = first_procs; 88124cf384cSBarry Smith (*numprocs)[i] = first_numprocs; 88224cf384cSBarry Smith (*indices)[i] = first_indices; 88324cf384cSBarry Smith break; 88424cf384cSBarry Smith } 88524cf384cSBarry Smith } 88624cf384cSBarry Smith 88789d82c54SBarry Smith PetscFunctionReturn(0); 88889d82c54SBarry Smith } 88989d82c54SBarry Smith 8904a2ae208SSatish Balay #undef __FUNCT__ 8914a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingRestoreInfo" 89207b52d57SBarry Smith /*@C 89307b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo - Frees the memory allocated by ISLocalToGlobalMappingGetInfo() 89489d82c54SBarry Smith 89507b52d57SBarry Smith Collective on ISLocalToGlobalMapping 89607b52d57SBarry Smith 89707b52d57SBarry Smith Input Parameters: 89807b52d57SBarry Smith . mapping - the mapping from local to global indexing 89907b52d57SBarry Smith 90007b52d57SBarry Smith Output Parameter: 90107b52d57SBarry Smith + nproc - number of processors that are connected to this one 90207b52d57SBarry Smith . proc - neighboring processors 90307b52d57SBarry Smith . numproc - number of indices for each processor 90407b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 90507b52d57SBarry Smith 90607b52d57SBarry Smith Level: advanced 90707b52d57SBarry Smith 90807b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 90907b52d57SBarry Smith ISLocalToGlobalMappingGetInfo() 91007b52d57SBarry Smith @*/ 91107b52d57SBarry Smith int ISLocalToGlobalMappingRestoreInfo(ISLocalToGlobalMapping mapping,int *nproc,int **procs,int **numprocs,int ***indices) 91207b52d57SBarry Smith { 91307b52d57SBarry Smith int ierr,i; 91407b52d57SBarry Smith 91507b52d57SBarry Smith PetscFunctionBegin; 91600ff320aSBarry Smith if (*procs) {ierr = PetscFree(*procs);CHKERRQ(ierr);} 91700ff320aSBarry Smith if (*numprocs) {ierr = PetscFree(*numprocs);CHKERRQ(ierr);} 91800ff320aSBarry Smith if (*indices) { 91900ff320aSBarry Smith if ((*indices)[0]) {ierr = PetscFree((*indices)[0]);CHKERRQ(ierr);} 92000ff320aSBarry Smith for (i=1; i<*nproc; i++) { 92124cf384cSBarry Smith if ((*indices)[i]) {ierr = PetscFree((*indices)[i]);CHKERRQ(ierr);} 92207b52d57SBarry Smith } 92307b52d57SBarry Smith ierr = PetscFree(*indices);CHKERRQ(ierr); 92424cf384cSBarry Smith } 92507b52d57SBarry Smith PetscFunctionReturn(0); 92607b52d57SBarry Smith } 92789d82c54SBarry Smith 928bc8ff85bSBarry Smith 929bc8ff85bSBarry Smith 930bc8ff85bSBarry Smith 931bc8ff85bSBarry Smith 932bc8ff85bSBarry Smith 933bc8ff85bSBarry Smith 934bc8ff85bSBarry Smith 935bc8ff85bSBarry Smith 936bc8ff85bSBarry Smith 937bc8ff85bSBarry Smith 938bc8ff85bSBarry Smith 939bc8ff85bSBarry Smith 940bc8ff85bSBarry Smith 941bc8ff85bSBarry Smith 942bc8ff85bSBarry Smith 943bc8ff85bSBarry Smith 94424cf384cSBarry Smith 945