12362add9SBarry Smith 2e090d566SSatish Balay #include "petscsys.h" /*I "petscsys.h" I*/ 3e090d566SSatish Balay #include "src/vec/is/isimpl.h" /*I "petscis.h" I*/ 42362add9SBarry Smith 58e58c17dSMatthew Knepley EXTERN int VecInitializePackage(char *); 623f7533aSBarry Smith int IS_LTOGM_COOKIE = -1; 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; 304482741eSBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE,1); 314482741eSBarry Smith PetscValidIntPointer(n,2); 323b9aefa3SBarry Smith *n = mapping->n; 333b9aefa3SBarry Smith PetscFunctionReturn(0); 343b9aefa3SBarry Smith } 353b9aefa3SBarry Smith 364a2ae208SSatish Balay #undef __FUNCT__ 374a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingView" 385a5d4f66SBarry Smith /*@C 395a5d4f66SBarry Smith ISLocalToGlobalMappingView - View a local to global mapping 405a5d4f66SBarry Smith 41b9cd556bSLois Curfman McInnes Not Collective 42b9cd556bSLois Curfman McInnes 435a5d4f66SBarry Smith Input Parameters: 443b9aefa3SBarry Smith + ltog - local to global mapping 453b9aefa3SBarry Smith - viewer - viewer 465a5d4f66SBarry Smith 47a997ad1aSLois Curfman McInnes Level: advanced 48a997ad1aSLois Curfman McInnes 49273d9f13SBarry Smith Concepts: mapping^local to global 505a5d4f66SBarry Smith 515a5d4f66SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 525a5d4f66SBarry Smith @*/ 53b0a32e0cSBarry Smith int ISLocalToGlobalMappingView(ISLocalToGlobalMapping mapping,PetscViewer viewer) 545a5d4f66SBarry Smith { 55f1af5d2fSBarry Smith int i,ierr,rank; 5632077d6dSBarry Smith PetscTruth iascii; 575a5d4f66SBarry Smith 585a5d4f66SBarry Smith PetscFunctionBegin; 594482741eSBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE,1); 60b0a32e0cSBarry Smith if (!viewer) viewer = PETSC_VIEWER_STDOUT_(mapping->comm); 614482741eSBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE,2); 625a5d4f66SBarry Smith 63f1af5d2fSBarry Smith ierr = MPI_Comm_rank(mapping->comm,&rank);CHKERRQ(ierr); 6432077d6dSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 6532077d6dSBarry Smith if (iascii) { 665a5d4f66SBarry Smith for (i=0; i<mapping->n; i++) { 67b0a32e0cSBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d] %d %d\n",rank,i,mapping->indices[i]);CHKERRQ(ierr); 686831982aSBarry Smith } 69b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 706831982aSBarry Smith } else { 71958c9bccSBarry Smith SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported for ISLocalToGlobalMapping",((PetscObject)viewer)->type_name); 725a5d4f66SBarry Smith } 735a5d4f66SBarry Smith 745a5d4f66SBarry Smith PetscFunctionReturn(0); 755a5d4f66SBarry Smith } 765a5d4f66SBarry Smith 774a2ae208SSatish Balay #undef __FUNCT__ 784a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreateIS" 792bdab257SBarry Smith /*@C 802bdab257SBarry Smith ISLocalToGlobalMappingCreateIS - Creates a mapping between a local (0 to n) 812bdab257SBarry Smith ordering and a global parallel ordering. 822bdab257SBarry Smith 830f5bd95cSBarry Smith Not collective 84b9cd556bSLois Curfman McInnes 85a997ad1aSLois Curfman McInnes Input Parameter: 862bdab257SBarry Smith . is - index set containing the global numbers for each local 872bdab257SBarry Smith 88a997ad1aSLois Curfman McInnes Output Parameter: 892bdab257SBarry Smith . mapping - new mapping data structure 902bdab257SBarry Smith 91a997ad1aSLois Curfman McInnes Level: advanced 92a997ad1aSLois Curfman McInnes 93273d9f13SBarry Smith Concepts: mapping^local to global 942bdab257SBarry Smith 952bdab257SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 962bdab257SBarry Smith @*/ 972bdab257SBarry Smith int ISLocalToGlobalMappingCreateIS(IS is,ISLocalToGlobalMapping *mapping) 982bdab257SBarry Smith { 992bdab257SBarry Smith int n,*indices,ierr; 1002bdab257SBarry Smith MPI_Comm comm; 1013a40ed3dSBarry Smith 1023a40ed3dSBarry Smith PetscFunctionBegin; 1034482741eSBarry Smith PetscValidHeaderSpecific(is,IS_COOKIE,1); 1044482741eSBarry Smith PetscValidPointer(mapping,2); 1052bdab257SBarry Smith 1062bdab257SBarry Smith ierr = PetscObjectGetComm((PetscObject)is,&comm);CHKERRQ(ierr); 1073b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 1082bdab257SBarry Smith ierr = ISGetIndices(is,&indices);CHKERRQ(ierr); 1092bdab257SBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,n,indices,mapping);CHKERRQ(ierr); 1102bdab257SBarry Smith ierr = ISRestoreIndices(is,&indices);CHKERRQ(ierr); 1112bdab257SBarry Smith 1123a40ed3dSBarry Smith PetscFunctionReturn(0); 1132bdab257SBarry Smith } 1145a5d4f66SBarry Smith 115b46b645bSBarry Smith 1164a2ae208SSatish Balay #undef __FUNCT__ 1174a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreate" 118dd7157adSSatish Balay /*@C 11990f02eecSBarry Smith ISLocalToGlobalMappingCreate - Creates a mapping between a local (0 to n) 12090f02eecSBarry Smith ordering and a global parallel ordering. 1212362add9SBarry Smith 12289d82c54SBarry Smith Not Collective, but communicator may have more than one process 123b9cd556bSLois Curfman McInnes 1242362add9SBarry Smith Input Parameters: 12589d82c54SBarry Smith + comm - MPI communicator 12690f02eecSBarry Smith . n - the number of local elements 127b9cd556bSLois Curfman McInnes - indices - the global index for each local element 1282362add9SBarry Smith 129a997ad1aSLois Curfman McInnes Output Parameter: 13090f02eecSBarry Smith . mapping - new mapping data structure 1312362add9SBarry Smith 132a997ad1aSLois Curfman McInnes Level: advanced 133a997ad1aSLois Curfman McInnes 134273d9f13SBarry Smith Concepts: mapping^local to global 1352362add9SBarry Smith 136b46b645bSBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreateNC() 1372362add9SBarry Smith @*/ 138987e4450SSatish Balay int ISLocalToGlobalMappingCreate(MPI_Comm cm,int n,const int indices[],ISLocalToGlobalMapping *mapping) 1392362add9SBarry Smith { 140b46b645bSBarry Smith int *in,ierr; 141b46b645bSBarry Smith 142b46b645bSBarry Smith PetscFunctionBegin; 1434482741eSBarry Smith PetscValidIntPointer(indices,3); 1444482741eSBarry Smith PetscValidPointer(mapping,4); 145b46b645bSBarry Smith ierr = PetscMalloc((n+1)*sizeof(int),&in);CHKERRQ(ierr); 146b46b645bSBarry Smith ierr = PetscMemcpy(in,indices,n*sizeof(int));CHKERRQ(ierr); 147b46b645bSBarry Smith ierr = ISLocalToGlobalMappingCreateNC(cm,n,in,mapping);CHKERRQ(ierr); 148b46b645bSBarry Smith PetscFunctionReturn(0); 149b46b645bSBarry Smith } 150b46b645bSBarry Smith 151b46b645bSBarry Smith #undef __FUNCT__ 152b46b645bSBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingCreateNC" 153b46b645bSBarry Smith /*@C 154b46b645bSBarry Smith ISLocalToGlobalMappingCreateNC - Creates a mapping between a local (0 to n) 155b46b645bSBarry Smith ordering and a global parallel ordering. 156b46b645bSBarry Smith 157b46b645bSBarry Smith Not Collective, but communicator may have more than one process 158b46b645bSBarry Smith 159b46b645bSBarry Smith Input Parameters: 160b46b645bSBarry Smith + comm - MPI communicator 161b46b645bSBarry Smith . n - the number of local elements 162b46b645bSBarry Smith - indices - the global index for each local element 163b46b645bSBarry Smith 164b46b645bSBarry Smith Output Parameter: 165b46b645bSBarry Smith . mapping - new mapping data structure 166b46b645bSBarry Smith 167b46b645bSBarry Smith Level: developer 168b46b645bSBarry Smith 169b46b645bSBarry Smith Notes: Does not copy the indices, just keeps the pointer to the indices. The ISLocalToGlobalMappingDestroy() 170b46b645bSBarry Smith will free the space so it must be obtained with PetscMalloc() and it must not be freed elsewhere. 171b46b645bSBarry Smith 172b46b645bSBarry Smith Concepts: mapping^local to global 173b46b645bSBarry Smith 174b46b645bSBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate() 175b46b645bSBarry Smith @*/ 176b46b645bSBarry Smith int ISLocalToGlobalMappingCreateNC(MPI_Comm cm,int n,const int indices[],ISLocalToGlobalMapping *mapping) 177b46b645bSBarry Smith { 17823f7533aSBarry Smith int ierr; 17923f7533aSBarry Smith 1803a40ed3dSBarry Smith PetscFunctionBegin; 1814482741eSBarry Smith PetscValidIntPointer(indices,3); 1824482741eSBarry Smith PetscValidPointer(mapping,4); 1838e58c17dSMatthew Knepley *mapping = PETSC_NULL; 1848e58c17dSMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 18523f7533aSBarry Smith ierr = VecInitializePackage(PETSC_NULL);CHKERRQ(ierr); 1868e58c17dSMatthew Knepley #endif 18723f7533aSBarry Smith if (IS_LTOGM_COOKIE == -1) { 18823f7533aSBarry Smith ierr = PetscLogClassRegister(&IS_LTOGM_COOKIE,"IS Local to global mapping");CHKERRQ(ierr); 18923f7533aSBarry Smith } 1902362add9SBarry Smith 1913f1db9ecSBarry Smith PetscHeaderCreate(*mapping,_p_ISLocalToGlobalMapping,int,IS_LTOGM_COOKIE,0,"ISLocalToGlobalMapping", 1923f1db9ecSBarry Smith cm,ISLocalToGlobalMappingDestroy,ISLocalToGlobalMappingView); 193b0a32e0cSBarry Smith PetscLogObjectCreate(*mapping); 194b0a32e0cSBarry Smith PetscLogObjectMemory(*mapping,sizeof(struct _p_ISLocalToGlobalMapping)+n*sizeof(int)); 195d4bb536fSBarry Smith 196d4bb536fSBarry Smith (*mapping)->n = n; 197b46b645bSBarry Smith (*mapping)->indices = (int*)indices; 198d4bb536fSBarry Smith 199d4bb536fSBarry Smith /* 200d4bb536fSBarry Smith Do not create the global to local mapping. This is only created if 201d4bb536fSBarry Smith ISGlobalToLocalMapping() is called 202d4bb536fSBarry Smith */ 203d4bb536fSBarry Smith (*mapping)->globals = 0; 2043a40ed3dSBarry Smith PetscFunctionReturn(0); 2052362add9SBarry Smith } 2062362add9SBarry Smith 2074a2ae208SSatish Balay #undef __FUNCT__ 2084a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingBlock" 209323b833fSBarry Smith /*@C 210323b833fSBarry Smith ISLocalToGlobalMappingBlock - Creates a blocked index version of an 211323b833fSBarry Smith ISLocalToGlobalMapping that is appropriate for MatSetLocalToGlobalMappingBlock() 212323b833fSBarry Smith and VecSetLocalToGlobalMappingBlock(). 213323b833fSBarry Smith 214323b833fSBarry Smith Not Collective, but communicator may have more than one process 215323b833fSBarry Smith 216323b833fSBarry Smith Input Parameters: 217323b833fSBarry Smith + inmap - original point-wise mapping 218323b833fSBarry Smith - bs - block size 219323b833fSBarry Smith 220323b833fSBarry Smith Output Parameter: 221323b833fSBarry Smith . outmap - block based mapping 222323b833fSBarry Smith 223323b833fSBarry Smith Level: advanced 224323b833fSBarry Smith 225323b833fSBarry Smith Concepts: mapping^local to global 226323b833fSBarry Smith 227323b833fSBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingCreateIS() 228323b833fSBarry Smith @*/ 229323b833fSBarry Smith int ISLocalToGlobalMappingBlock(ISLocalToGlobalMapping inmap,int bs,ISLocalToGlobalMapping *outmap) 230323b833fSBarry Smith { 231323b833fSBarry Smith int ierr,*ii,i,n; 232323b833fSBarry Smith 233323b833fSBarry Smith PetscFunctionBegin; 234323b833fSBarry Smith 235323b833fSBarry Smith if (bs > 1) { 236323b833fSBarry Smith n = inmap->n/bs; 237323b833fSBarry Smith ierr = PetscMalloc(n*sizeof(int),&ii);CHKERRQ(ierr); 238323b833fSBarry Smith for (i=0; i<n; i++) { 239b8ee7809SBarry Smith ii[i] = inmap->indices[bs*i]/bs; 240323b833fSBarry Smith } 241323b833fSBarry Smith ierr = ISLocalToGlobalMappingCreate(inmap->comm,n,ii,outmap);CHKERRQ(ierr); 242323b833fSBarry Smith ierr = PetscFree(ii);CHKERRQ(ierr); 243323b833fSBarry Smith } else { 244323b833fSBarry Smith *outmap = inmap; 245323b833fSBarry Smith ierr = PetscObjectReference((PetscObject)inmap);CHKERRQ(ierr); 246323b833fSBarry Smith } 247323b833fSBarry Smith PetscFunctionReturn(0); 248323b833fSBarry Smith } 249323b833fSBarry Smith 2504a2ae208SSatish Balay #undef __FUNCT__ 2514a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingDestroy" 25290f02eecSBarry Smith /*@ 25390f02eecSBarry Smith ISLocalToGlobalMappingDestroy - Destroys a mapping between a local (0 to n) 25490f02eecSBarry Smith ordering and a global parallel ordering. 25590f02eecSBarry Smith 2560f5bd95cSBarry Smith Note Collective 257b9cd556bSLois Curfman McInnes 25890f02eecSBarry Smith Input Parameters: 25990f02eecSBarry Smith . mapping - mapping data structure 26090f02eecSBarry Smith 261a997ad1aSLois Curfman McInnes Level: advanced 262a997ad1aSLois Curfman McInnes 2633acfe500SLois Curfman McInnes .seealso: ISLocalToGlobalMappingCreate() 26490f02eecSBarry Smith @*/ 26590f02eecSBarry Smith int ISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping mapping) 26690f02eecSBarry Smith { 267606d414cSSatish Balay int ierr; 2683a40ed3dSBarry Smith PetscFunctionBegin; 2694482741eSBarry Smith PetscValidPointer(mapping,1); 2703a40ed3dSBarry Smith if (--mapping->refct > 0) PetscFunctionReturn(0); 27185614651SBarry Smith if (mapping->refct < 0) { 272*634064b4SBarry Smith SETERRQ(PETSC_ERR_PLIB,"Mapping already destroyed"); 27385614651SBarry Smith } 27490f02eecSBarry Smith 275606d414cSSatish Balay ierr = PetscFree(mapping->indices);CHKERRQ(ierr); 276606d414cSSatish Balay if (mapping->globals) {ierr = PetscFree(mapping->globals);CHKERRQ(ierr);} 277b0a32e0cSBarry Smith PetscLogObjectDestroy(mapping); 278d4bb536fSBarry Smith PetscHeaderDestroy(mapping); 2793a40ed3dSBarry Smith PetscFunctionReturn(0); 28090f02eecSBarry Smith } 28190f02eecSBarry Smith 2824a2ae208SSatish Balay #undef __FUNCT__ 2834a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingApplyIS" 28490f02eecSBarry Smith /*@ 2853acfe500SLois Curfman McInnes ISLocalToGlobalMappingApplyIS - Creates from an IS in the local numbering 2863acfe500SLois Curfman McInnes a new index set using the global numbering defined in an ISLocalToGlobalMapping 2873acfe500SLois Curfman McInnes context. 28890f02eecSBarry Smith 289b9cd556bSLois Curfman McInnes Not collective 290b9cd556bSLois Curfman McInnes 29190f02eecSBarry Smith Input Parameters: 292b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 293b9cd556bSLois Curfman McInnes - is - index set in local numbering 29490f02eecSBarry Smith 29590f02eecSBarry Smith Output Parameters: 29690f02eecSBarry Smith . newis - index set in global numbering 29790f02eecSBarry Smith 298a997ad1aSLois Curfman McInnes Level: advanced 299a997ad1aSLois Curfman McInnes 300273d9f13SBarry Smith Concepts: mapping^local to global 3013acfe500SLois Curfman McInnes 30290f02eecSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 303d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy(), ISGlobalToLocalMappingApply() 30490f02eecSBarry Smith @*/ 30590f02eecSBarry Smith int ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping mapping,IS is,IS *newis) 30690f02eecSBarry Smith { 3073b9aefa3SBarry Smith int ierr,n,i,*idxin,*idxmap,*idxout,Nmax = mapping->n; 3083a40ed3dSBarry Smith 3093a40ed3dSBarry Smith PetscFunctionBegin; 3104482741eSBarry Smith PetscValidPointer(mapping,1); 3114482741eSBarry Smith PetscValidHeaderSpecific(is,IS_COOKIE,2); 3124482741eSBarry Smith PetscValidPointer(newis,3); 31390f02eecSBarry Smith 3143b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 31590f02eecSBarry Smith ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 31690f02eecSBarry Smith idxmap = mapping->indices; 31790f02eecSBarry Smith 318b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(int),&idxout);CHKERRQ(ierr); 31990f02eecSBarry Smith for (i=0; i<n; i++) { 320590ac198SBarry Smith if (idxin[i] >= Nmax) SETERRQ3(PETSC_ERR_ARG_OUTOFRANGE,"Local index %d too large %d (max) at %d",idxin[i],Nmax-1,i); 32190f02eecSBarry Smith idxout[i] = idxmap[idxin[i]]; 32290f02eecSBarry Smith } 3233b9aefa3SBarry Smith ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 324029af93fSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxout,newis);CHKERRQ(ierr); 325606d414cSSatish Balay ierr = PetscFree(idxout);CHKERRQ(ierr); 3263a40ed3dSBarry Smith PetscFunctionReturn(0); 32790f02eecSBarry Smith } 32890f02eecSBarry Smith 32989d82c54SBarry Smith /*MC 3303acfe500SLois Curfman McInnes ISLocalToGlobalMappingApply - Takes a list of integers in a local numbering 3313acfe500SLois Curfman McInnes and converts them to the global numbering. 33290f02eecSBarry Smith 333b9cd556bSLois Curfman McInnes Not collective 334b9cd556bSLois Curfman McInnes 335bb25748dSBarry Smith Input Parameters: 336b9cd556bSLois Curfman McInnes + mapping - the local to global mapping context 337bb25748dSBarry Smith . N - number of integers 338b9cd556bSLois Curfman McInnes - in - input indices in local numbering 339bb25748dSBarry Smith 340bb25748dSBarry Smith Output Parameter: 341bb25748dSBarry Smith . out - indices in global numbering 342bb25748dSBarry Smith 3433b9aefa3SBarry Smith Synopsis: 344216e7ba4SBarry Smith int ISLocalToGlobalMappingApply(ISLocalToGlobalMapping mapping,int N,int in[],int out[]) 3453b9aefa3SBarry Smith 346b9cd556bSLois Curfman McInnes Notes: 347b9cd556bSLois Curfman McInnes The in and out array parameters may be identical. 348d4bb536fSBarry Smith 349a997ad1aSLois Curfman McInnes Level: advanced 350a997ad1aSLois Curfman McInnes 351bb25748dSBarry Smith .seealso: ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 3520752156aSBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 353d4bb536fSBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 354bb25748dSBarry Smith 355273d9f13SBarry Smith Concepts: mapping^local to global 356d4bb536fSBarry Smith 35789d82c54SBarry Smith M*/ 358d4bb536fSBarry Smith 359d4bb536fSBarry Smith /* -----------------------------------------------------------------------------------------*/ 360d4bb536fSBarry Smith 3614a2ae208SSatish Balay #undef __FUNCT__ 3624a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingSetUp_Private" 363d4bb536fSBarry Smith /* 364d4bb536fSBarry Smith Creates the global fields in the ISLocalToGlobalMapping structure 365d4bb536fSBarry Smith */ 366d4bb536fSBarry Smith static int ISGlobalToLocalMappingSetUp_Private(ISLocalToGlobalMapping mapping) 367d4bb536fSBarry Smith { 368b0a32e0cSBarry Smith int ierr,i,*idx = mapping->indices,n = mapping->n,end,start,*globals; 369d4bb536fSBarry Smith 3703a40ed3dSBarry Smith PetscFunctionBegin; 371d4bb536fSBarry Smith end = 0; 372d4bb536fSBarry Smith start = 100000000; 373d4bb536fSBarry Smith 374d4bb536fSBarry Smith for (i=0; i<n; i++) { 375d4bb536fSBarry Smith if (idx[i] < 0) continue; 376d4bb536fSBarry Smith if (idx[i] < start) start = idx[i]; 377d4bb536fSBarry Smith if (idx[i] > end) end = idx[i]; 378d4bb536fSBarry Smith } 379d4bb536fSBarry Smith if (start > end) {start = 0; end = -1;} 380d4bb536fSBarry Smith mapping->globalstart = start; 381d4bb536fSBarry Smith mapping->globalend = end; 382d4bb536fSBarry Smith 383b0a32e0cSBarry Smith ierr = PetscMalloc((end-start+2)*sizeof(int),&globals);CHKERRQ(ierr); 384b0a32e0cSBarry Smith mapping->globals = globals; 385d4bb536fSBarry Smith for (i=0; i<end-start+1; i++) { 386d4bb536fSBarry Smith globals[i] = -1; 387d4bb536fSBarry Smith } 388d4bb536fSBarry Smith for (i=0; i<n; i++) { 389d4bb536fSBarry Smith if (idx[i] < 0) continue; 390d4bb536fSBarry Smith globals[idx[i] - start] = i; 391d4bb536fSBarry Smith } 392d4bb536fSBarry Smith 393b0a32e0cSBarry Smith PetscLogObjectMemory(mapping,(end-start+1)*sizeof(int)); 3943a40ed3dSBarry Smith PetscFunctionReturn(0); 395d4bb536fSBarry Smith } 396d4bb536fSBarry Smith 3974a2ae208SSatish Balay #undef __FUNCT__ 3984a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingApply" 399d4bb536fSBarry Smith /*@ 400a997ad1aSLois Curfman McInnes ISGlobalToLocalMappingApply - Provides the local numbering for a list of integers 401a997ad1aSLois Curfman McInnes specified with a global numbering. 402d4bb536fSBarry Smith 403b9cd556bSLois Curfman McInnes Not collective 404b9cd556bSLois Curfman McInnes 405d4bb536fSBarry Smith Input Parameters: 406b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 407d4bb536fSBarry Smith . type - IS_GTOLM_MASK - replaces global indices with no local value with -1 408d4bb536fSBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 409d4bb536fSBarry Smith . n - number of global indices to map 410b9cd556bSLois Curfman McInnes - idx - global indices to map 411d4bb536fSBarry Smith 412d4bb536fSBarry Smith Output Parameters: 413b9cd556bSLois Curfman McInnes + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 414b9cd556bSLois Curfman McInnes - idxout - local index of each global index, one must pass in an array long enough 415e182c471SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApply() with 416e182c471SBarry Smith idxout == PETSC_NULL to determine the required length (returned in nout) 417e182c471SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApply() 418e182c471SBarry Smith a second time to set the values. 419d4bb536fSBarry Smith 420b9cd556bSLois Curfman McInnes Notes: 421b9cd556bSLois Curfman McInnes Either nout or idxout may be PETSC_NULL. idx and idxout may be identical. 422d4bb536fSBarry Smith 4230f5bd95cSBarry Smith This is not scalable in memory usage. Each processor requires O(Nglobal) size 4240f5bd95cSBarry Smith array to compute these. 4250f5bd95cSBarry Smith 426a997ad1aSLois Curfman McInnes Level: advanced 427a997ad1aSLois Curfman McInnes 428273d9f13SBarry Smith Concepts: mapping^global to local 429d4bb536fSBarry Smith 430d4bb536fSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 431d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy() 432d4bb536fSBarry Smith @*/ 433d4bb536fSBarry Smith int ISGlobalToLocalMappingApply(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, 434987e4450SSatish Balay int n,const int idx[],int *nout,int idxout[]) 435d4bb536fSBarry Smith { 436d4bb536fSBarry Smith int i,ierr,*globals,nf = 0,tmp,start,end; 437d4bb536fSBarry Smith 4383a40ed3dSBarry Smith PetscFunctionBegin; 439d4bb536fSBarry Smith if (!mapping->globals) { 440d4bb536fSBarry Smith ierr = ISGlobalToLocalMappingSetUp_Private(mapping);CHKERRQ(ierr); 441d4bb536fSBarry Smith } 442d4bb536fSBarry Smith globals = mapping->globals; 443d4bb536fSBarry Smith start = mapping->globalstart; 444d4bb536fSBarry Smith end = mapping->globalend; 445d4bb536fSBarry Smith 446d4bb536fSBarry Smith if (type == IS_GTOLM_MASK) { 447d4bb536fSBarry Smith if (idxout) { 448d4bb536fSBarry Smith for (i=0; i<n; i++) { 449d4bb536fSBarry Smith if (idx[i] < 0) idxout[i] = idx[i]; 450d4bb536fSBarry Smith else if (idx[i] < start) idxout[i] = -1; 451d4bb536fSBarry Smith else if (idx[i] > end) idxout[i] = -1; 452d4bb536fSBarry Smith else idxout[i] = globals[idx[i] - start]; 453d4bb536fSBarry Smith } 454d4bb536fSBarry Smith } 455d4bb536fSBarry Smith if (nout) *nout = n; 456d4bb536fSBarry Smith } else { 457d4bb536fSBarry Smith if (idxout) { 458d4bb536fSBarry Smith for (i=0; i<n; i++) { 459d4bb536fSBarry Smith if (idx[i] < 0) continue; 460d4bb536fSBarry Smith if (idx[i] < start) continue; 461d4bb536fSBarry Smith if (idx[i] > end) continue; 462d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 463d4bb536fSBarry Smith if (tmp < 0) continue; 464d4bb536fSBarry Smith idxout[nf++] = tmp; 465d4bb536fSBarry Smith } 466d4bb536fSBarry Smith } else { 467d4bb536fSBarry Smith for (i=0; i<n; i++) { 468d4bb536fSBarry Smith if (idx[i] < 0) continue; 469d4bb536fSBarry Smith if (idx[i] < start) continue; 470d4bb536fSBarry Smith if (idx[i] > end) continue; 471d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 472d4bb536fSBarry Smith if (tmp < 0) continue; 473d4bb536fSBarry Smith nf++; 474d4bb536fSBarry Smith } 475d4bb536fSBarry Smith } 476d4bb536fSBarry Smith if (nout) *nout = nf; 477d4bb536fSBarry Smith } 478d4bb536fSBarry Smith 4793a40ed3dSBarry Smith PetscFunctionReturn(0); 480d4bb536fSBarry Smith } 48190f02eecSBarry Smith 4824a2ae208SSatish Balay #undef __FUNCT__ 4834a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingGetInfo" 48489d82c54SBarry Smith /*@C 48589d82c54SBarry Smith ISLocalToGlobalMappingGetInfo - Gets the neighbor information for each processor and 48689d82c54SBarry Smith each index shared by more than one processor 48789d82c54SBarry Smith 48889d82c54SBarry Smith Collective on ISLocalToGlobalMapping 48989d82c54SBarry Smith 49089d82c54SBarry Smith Input Parameters: 49189d82c54SBarry Smith . mapping - the mapping from local to global indexing 49289d82c54SBarry Smith 49389d82c54SBarry Smith Output Parameter: 49489d82c54SBarry Smith + nproc - number of processors that are connected to this one 49589d82c54SBarry Smith . proc - neighboring processors 49607b52d57SBarry Smith . numproc - number of indices for each subdomain (processor) 49707b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 49889d82c54SBarry Smith 49989d82c54SBarry Smith Level: advanced 50089d82c54SBarry Smith 501273d9f13SBarry Smith Concepts: mapping^local to global 50289d82c54SBarry Smith 50307b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 50407b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo() 50589d82c54SBarry Smith @*/ 506ca01db9bSBarry Smith int ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping mapping,int *nproc,int *procs[],int *numprocs[],int **indices[]) 50789d82c54SBarry Smith { 508fa7fbcffSSatish Balay int i,n = mapping->n,ierr,Ng,ng,max = 0,*lindices = mapping->indices; 50927c402fcSBarry Smith int size,rank,*nprocs,*owner,nsends,*sends,j,*starts,nmax,nrecvs,*recvs,proc; 51024cf384cSBarry Smith int tag1,tag2,tag3,cnt,*len,*source,imdex,scale,*ownedsenders,*nownedsenders,rstart,nowned; 51107b52d57SBarry Smith int node,nownedm,nt,*sends2,nsends2,*starts2,*lens2,*dest,nrecvs2,*starts3,*recvs2,k,*bprocs,*tmp; 51224cf384cSBarry Smith int first_procs,first_numprocs,*first_indices; 51389d82c54SBarry Smith MPI_Request *recv_waits,*send_waits; 51430dcb7c9SBarry Smith MPI_Status recv_status,*send_status,*recv_statuses; 51589d82c54SBarry Smith MPI_Comm comm = mapping->comm; 51607b52d57SBarry Smith PetscTruth debug = PETSC_FALSE; 51789d82c54SBarry Smith 51889d82c54SBarry Smith PetscFunctionBegin; 51924cf384cSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 52024cf384cSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 52124cf384cSBarry Smith if (size == 1) { 52224cf384cSBarry Smith *nproc = 0; 52324cf384cSBarry Smith *procs = PETSC_NULL; 524b0a32e0cSBarry Smith ierr = PetscMalloc(sizeof(int),numprocs);CHKERRQ(ierr); 5251e2105dcSBarry Smith (*numprocs)[0] = 0; 526b0a32e0cSBarry Smith ierr = PetscMalloc(sizeof(int*),indices);CHKERRQ(ierr); 5271e2105dcSBarry Smith (*indices)[0] = PETSC_NULL; 52824cf384cSBarry Smith PetscFunctionReturn(0); 52924cf384cSBarry Smith } 53024cf384cSBarry Smith 531b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-islocaltoglobalmappinggetinfo_debug",&debug);CHKERRQ(ierr); 53207b52d57SBarry Smith 5333677ff5aSBarry Smith /* 5343677ff5aSBarry Smith Notes on ISLocalToGlobalMappingGetInfo 5353677ff5aSBarry Smith 5363677ff5aSBarry Smith globally owned node - the nodes that have been assigned to this processor in global 5373677ff5aSBarry Smith numbering, just for this routine. 5383677ff5aSBarry Smith 5393677ff5aSBarry Smith nontrivial globally owned node - node assigned to this processor that is on a subdomain 5403677ff5aSBarry Smith boundary (i.e. is has more than one local owner) 5413677ff5aSBarry Smith 5423677ff5aSBarry Smith locally owned node - node that exists on this processors subdomain 5433677ff5aSBarry Smith 5443677ff5aSBarry Smith nontrivial locally owned node - node that is not in the interior (i.e. has more than one 5453677ff5aSBarry Smith local subdomain 5463677ff5aSBarry Smith */ 54724cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag1);CHKERRQ(ierr); 54824cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag2);CHKERRQ(ierr); 54924cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag3);CHKERRQ(ierr); 55089d82c54SBarry Smith 55189d82c54SBarry Smith for (i=0; i<n; i++) { 55289d82c54SBarry Smith if (lindices[i] > max) max = lindices[i]; 55389d82c54SBarry Smith } 55489d82c54SBarry Smith ierr = MPI_Allreduce(&max,&Ng,1,MPI_INT,MPI_MAX,comm);CHKERRQ(ierr); 55578058e43SBarry Smith Ng++; 55689d82c54SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 55789d82c54SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 558bc8ff85bSBarry Smith scale = Ng/size + 1; 559a2e34c3dSBarry Smith ng = scale; if (rank == size-1) ng = Ng - scale*(size-1); ng = PetscMax(1,ng); 560caba0dd0SBarry Smith rstart = scale*rank; 56189d82c54SBarry Smith 56289d82c54SBarry Smith /* determine ownership ranges of global indices */ 563b0a32e0cSBarry Smith ierr = PetscMalloc((2*size+1)*sizeof(int),&nprocs);CHKERRQ(ierr); 5642880cf29SBarry Smith ierr = PetscMemzero(nprocs,2*size*sizeof(int));CHKERRQ(ierr); 56589d82c54SBarry Smith 56689d82c54SBarry Smith /* determine owners of each local node */ 567b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(int),&owner);CHKERRQ(ierr); 56889d82c54SBarry Smith for (i=0; i<n; i++) { 5693677ff5aSBarry Smith proc = lindices[i]/scale; /* processor that globally owns this index */ 57027c402fcSBarry Smith nprocs[2*proc+1] = 1; /* processor globally owns at least one of ours */ 5713677ff5aSBarry Smith owner[i] = proc; 57227c402fcSBarry Smith nprocs[2*proc]++; /* count of how many that processor globally owns of ours */ 57389d82c54SBarry Smith } 57427c402fcSBarry Smith nsends = 0; for (i=0; i<size; i++) nsends += nprocs[2*i+1]; 575b0a32e0cSBarry Smith PetscLogInfo(0,"ISLocalToGlobalMappingGetInfo: Number of global owners for my local data %d\n",nsends); 57689d82c54SBarry Smith 57789d82c54SBarry Smith /* inform other processors of number of messages and max length*/ 57827c402fcSBarry Smith ierr = PetscMaxSum(comm,nprocs,&nmax,&nrecvs);CHKERRQ(ierr); 579b0a32e0cSBarry Smith PetscLogInfo(0,"ISLocalToGlobalMappingGetInfo: Number of local owners for my global data %d\n",nrecvs); 58089d82c54SBarry Smith 58189d82c54SBarry Smith /* post receives for owned rows */ 582b0a32e0cSBarry Smith ierr = PetscMalloc((2*nrecvs+1)*(nmax+1)*sizeof(int),&recvs);CHKERRQ(ierr); 583b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs+1)*sizeof(MPI_Request),&recv_waits);CHKERRQ(ierr); 58489d82c54SBarry Smith for (i=0; i<nrecvs; i++) { 58524cf384cSBarry Smith ierr = MPI_Irecv(recvs+2*nmax*i,2*nmax,MPI_INT,MPI_ANY_SOURCE,tag1,comm,recv_waits+i);CHKERRQ(ierr); 58689d82c54SBarry Smith } 58789d82c54SBarry Smith 58889d82c54SBarry Smith /* pack messages containing lists of local nodes to owners */ 589b0a32e0cSBarry Smith ierr = PetscMalloc((2*n+1)*sizeof(int),&sends);CHKERRQ(ierr); 590b0a32e0cSBarry Smith ierr = PetscMalloc((size+1)*sizeof(int),&starts);CHKERRQ(ierr); 59189d82c54SBarry Smith starts[0] = 0; 59227c402fcSBarry Smith for (i=1; i<size; i++) { starts[i] = starts[i-1] + 2*nprocs[2*i-2];} 59389d82c54SBarry Smith for (i=0; i<n; i++) { 59489d82c54SBarry Smith sends[starts[owner[i]]++] = lindices[i]; 59530dcb7c9SBarry Smith sends[starts[owner[i]]++] = i; 59689d82c54SBarry Smith } 59789d82c54SBarry Smith ierr = PetscFree(owner);CHKERRQ(ierr); 59889d82c54SBarry Smith starts[0] = 0; 59927c402fcSBarry Smith for (i=1; i<size; i++) { starts[i] = starts[i-1] + 2*nprocs[2*i-2];} 60089d82c54SBarry Smith 60189d82c54SBarry Smith /* send the messages */ 602b0a32e0cSBarry Smith ierr = PetscMalloc((nsends+1)*sizeof(MPI_Request),&send_waits);CHKERRQ(ierr); 603b0a32e0cSBarry Smith ierr = PetscMalloc((nsends+1)*sizeof(int),&dest);CHKERRQ(ierr); 60489d82c54SBarry Smith cnt = 0; 60589d82c54SBarry Smith for (i=0; i<size; i++) { 60627c402fcSBarry Smith if (nprocs[2*i]) { 60727c402fcSBarry Smith ierr = MPI_Isend(sends+starts[i],2*nprocs[2*i],MPI_INT,i,tag1,comm,send_waits+cnt);CHKERRQ(ierr); 60830dcb7c9SBarry Smith dest[cnt] = i; 60989d82c54SBarry Smith cnt++; 61089d82c54SBarry Smith } 61189d82c54SBarry Smith } 61289d82c54SBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 61389d82c54SBarry Smith 61489d82c54SBarry Smith /* wait on receives */ 615b0a32e0cSBarry Smith ierr = PetscMalloc((2*nrecvs+1)*sizeof(int),&source);CHKERRQ(ierr); 61689d82c54SBarry Smith len = source + nrecvs; 61789d82c54SBarry Smith cnt = nrecvs; 618b0a32e0cSBarry Smith ierr = PetscMalloc((ng+1)*sizeof(int),&nownedsenders);CHKERRQ(ierr); 619caba0dd0SBarry Smith ierr = PetscMemzero(nownedsenders,ng*sizeof(int));CHKERRQ(ierr); 62089d82c54SBarry Smith while (cnt) { 62189d82c54SBarry Smith ierr = MPI_Waitany(nrecvs,recv_waits,&imdex,&recv_status);CHKERRQ(ierr); 62289d82c54SBarry Smith /* unpack receives into our local space */ 62389d82c54SBarry Smith ierr = MPI_Get_count(&recv_status,MPI_INT,&len[imdex]);CHKERRQ(ierr); 62489d82c54SBarry Smith source[imdex] = recv_status.MPI_SOURCE; 62530dcb7c9SBarry Smith len[imdex] = len[imdex]/2; 626caba0dd0SBarry Smith /* count how many local owners for each of my global owned indices */ 62730dcb7c9SBarry Smith for (i=0; i<len[imdex]; i++) nownedsenders[recvs[2*imdex*nmax+2*i]-rstart]++; 62889d82c54SBarry Smith cnt--; 62989d82c54SBarry Smith } 63089d82c54SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 63189d82c54SBarry Smith 63230dcb7c9SBarry Smith /* count how many globally owned indices are on an edge multiplied by how many processors own them. */ 633bc8ff85bSBarry Smith nowned = 0; 634bc8ff85bSBarry Smith nownedm = 0; 635bc8ff85bSBarry Smith for (i=0; i<ng; i++) { 636bc8ff85bSBarry Smith if (nownedsenders[i] > 1) {nownedm += nownedsenders[i]; nowned++;} 637bc8ff85bSBarry Smith } 638bc8ff85bSBarry Smith 639bc8ff85bSBarry Smith /* create single array to contain rank of all local owners of each globally owned index */ 640b0a32e0cSBarry Smith ierr = PetscMalloc((nownedm+1)*sizeof(int),&ownedsenders);CHKERRQ(ierr); 641b0a32e0cSBarry Smith ierr = PetscMalloc((ng+1)*sizeof(int),&starts);CHKERRQ(ierr); 642bc8ff85bSBarry Smith starts[0] = 0; 643bc8ff85bSBarry Smith for (i=1; i<ng; i++) { 644bc8ff85bSBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 645bc8ff85bSBarry Smith else starts[i] = starts[i-1]; 646bc8ff85bSBarry Smith } 647bc8ff85bSBarry Smith 64830dcb7c9SBarry Smith /* for each nontrival globally owned node list all arriving processors */ 649bc8ff85bSBarry Smith for (i=0; i<nrecvs; i++) { 650bc8ff85bSBarry Smith for (j=0; j<len[i]; j++) { 65130dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 652bc8ff85bSBarry Smith if (nownedsenders[node] > 1) { 653bc8ff85bSBarry Smith ownedsenders[starts[node]++] = source[i]; 654bc8ff85bSBarry Smith } 655bc8ff85bSBarry Smith } 656bc8ff85bSBarry Smith } 657bc8ff85bSBarry Smith 65807b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 65930dcb7c9SBarry Smith starts[0] = 0; 66030dcb7c9SBarry Smith for (i=1; i<ng; i++) { 66130dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 66230dcb7c9SBarry Smith else starts[i] = starts[i-1]; 66330dcb7c9SBarry Smith } 66430dcb7c9SBarry Smith for (i=0; i<ng; i++) { 66530dcb7c9SBarry Smith if (nownedsenders[i] > 1) { 66630dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] global node %d local owner processors: ",rank,i+rstart);CHKERRQ(ierr); 66730dcb7c9SBarry Smith for (j=0; j<nownedsenders[i]; j++) { 66830dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",ownedsenders[starts[i]+j]);CHKERRQ(ierr); 66930dcb7c9SBarry Smith } 67030dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 67130dcb7c9SBarry Smith } 67230dcb7c9SBarry Smith } 67330dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 67407b52d57SBarry Smith }/* ----------------------------------- */ 67530dcb7c9SBarry Smith 6763677ff5aSBarry Smith /* wait on original sends */ 6773a96401aSBarry Smith if (nsends) { 678b0a32e0cSBarry Smith ierr = PetscMalloc(nsends*sizeof(MPI_Status),&send_status);CHKERRQ(ierr); 6793a96401aSBarry Smith ierr = MPI_Waitall(nsends,send_waits,send_status);CHKERRQ(ierr); 6803a96401aSBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 6813a96401aSBarry Smith } 68289d82c54SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 6833a96401aSBarry Smith ierr = PetscFree(sends);CHKERRQ(ierr); 6843677ff5aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 6853677ff5aSBarry Smith 6863677ff5aSBarry Smith /* pack messages to send back to local owners */ 68730dcb7c9SBarry Smith starts[0] = 0; 68830dcb7c9SBarry Smith for (i=1; i<ng; i++) { 68930dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 69030dcb7c9SBarry Smith else starts[i] = starts[i-1]; 69130dcb7c9SBarry Smith } 69230dcb7c9SBarry Smith nsends2 = nrecvs; 693b0a32e0cSBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(int),&nprocs);CHKERRQ(ierr); /* length of each message */ 69430dcb7c9SBarry Smith for (i=0; i<nrecvs; i++) { 69530dcb7c9SBarry Smith nprocs[i] = 1; 69630dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 69730dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 69830dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 69930dcb7c9SBarry Smith nprocs[i] += 2 + nownedsenders[node]; 70030dcb7c9SBarry Smith } 70130dcb7c9SBarry Smith } 70230dcb7c9SBarry Smith } 70330dcb7c9SBarry Smith nt = 0; for (i=0; i<nsends2; i++) nt += nprocs[i]; 704b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int),&sends2);CHKERRQ(ierr); 705b0a32e0cSBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(int),&starts2);CHKERRQ(ierr); 70630dcb7c9SBarry Smith starts2[0] = 0; for (i=1; i<nsends2; i++) starts2[i] = starts2[i-1] + nprocs[i-1]; 70730dcb7c9SBarry Smith /* 70830dcb7c9SBarry Smith Each message is 1 + nprocs[i] long, and consists of 70930dcb7c9SBarry Smith (0) the number of nodes being sent back 71030dcb7c9SBarry Smith (1) the local node number, 71130dcb7c9SBarry Smith (2) the number of processors sharing it, 71230dcb7c9SBarry Smith (3) the processors sharing it 71330dcb7c9SBarry Smith */ 71430dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 71530dcb7c9SBarry Smith cnt = 1; 71630dcb7c9SBarry Smith sends2[starts2[i]] = 0; 71730dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 71830dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 71930dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 72030dcb7c9SBarry Smith sends2[starts2[i]]++; 72130dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = recvs[2*i*nmax+2*j+1]; 72230dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = nownedsenders[node]; 72330dcb7c9SBarry Smith ierr = PetscMemcpy(&sends2[starts2[i]+cnt],&ownedsenders[starts[node]],nownedsenders[node]*sizeof(int));CHKERRQ(ierr); 72430dcb7c9SBarry Smith cnt += nownedsenders[node]; 72530dcb7c9SBarry Smith } 72630dcb7c9SBarry Smith } 72730dcb7c9SBarry Smith } 72830dcb7c9SBarry Smith 72930dcb7c9SBarry Smith /* send the message lengths */ 73030dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 73124cf384cSBarry Smith ierr = MPI_Send(&nprocs[i],1,MPI_INT,source[i],tag2,comm);CHKERRQ(ierr); 73230dcb7c9SBarry Smith } 73330dcb7c9SBarry Smith 73430dcb7c9SBarry Smith /* receive the message lengths */ 73530dcb7c9SBarry Smith nrecvs2 = nsends; 736b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(int),&lens2);CHKERRQ(ierr); 737b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(int),&starts3);CHKERRQ(ierr); 73830dcb7c9SBarry Smith nt = 0; 73930dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 74024cf384cSBarry Smith ierr = MPI_Recv(&lens2[i],1,MPI_INT,dest[i],tag2,comm,&recv_status);CHKERRQ(ierr); 74130dcb7c9SBarry Smith nt += lens2[i]; 74230dcb7c9SBarry Smith } 74330dcb7c9SBarry Smith starts3[0] = 0; 74430dcb7c9SBarry Smith for (i=0; i<nrecvs2-1; i++) { 74530dcb7c9SBarry Smith starts3[i+1] = starts3[i] + lens2[i]; 74630dcb7c9SBarry Smith } 747b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int),&recvs2);CHKERRQ(ierr); 748b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(MPI_Request),&recv_waits);CHKERRQ(ierr); 74952b72c4aSBarry Smith for (i=0; i<nrecvs2; i++) { 75024cf384cSBarry Smith ierr = MPI_Irecv(recvs2+starts3[i],lens2[i],MPI_INT,dest[i],tag3,comm,recv_waits+i);CHKERRQ(ierr); 75130dcb7c9SBarry Smith } 75230dcb7c9SBarry Smith 75330dcb7c9SBarry Smith /* send the messages */ 754b0a32e0cSBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(MPI_Request),&send_waits);CHKERRQ(ierr); 75530dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 75624cf384cSBarry Smith ierr = MPI_Isend(sends2+starts2[i],nprocs[i],MPI_INT,source[i],tag3,comm,send_waits+i);CHKERRQ(ierr); 75730dcb7c9SBarry Smith } 75830dcb7c9SBarry Smith 75930dcb7c9SBarry Smith /* wait on receives */ 760b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(MPI_Status),&recv_statuses);CHKERRQ(ierr); 76130dcb7c9SBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 76230dcb7c9SBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 76330dcb7c9SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 76430dcb7c9SBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 76530dcb7c9SBarry Smith 76607b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 76730dcb7c9SBarry Smith cnt = 0; 76830dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 76930dcb7c9SBarry Smith nt = recvs2[cnt++]; 77030dcb7c9SBarry Smith for (j=0; j<nt; j++) { 77130dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] local node %d number of subdomains %d: ",rank,recvs2[cnt],recvs2[cnt+1]);CHKERRQ(ierr); 77230dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 77330dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",recvs2[cnt+2+k]);CHKERRQ(ierr); 77430dcb7c9SBarry Smith } 77530dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 77630dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 77730dcb7c9SBarry Smith } 77830dcb7c9SBarry Smith } 77930dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 78007b52d57SBarry Smith } /* ----------------------------------- */ 78130dcb7c9SBarry Smith 78230dcb7c9SBarry Smith /* count number subdomains for each local node */ 783b0a32e0cSBarry Smith ierr = PetscMalloc(size*sizeof(int),&nprocs);CHKERRQ(ierr); 78430dcb7c9SBarry Smith ierr = PetscMemzero(nprocs,size*sizeof(int));CHKERRQ(ierr); 78530dcb7c9SBarry Smith cnt = 0; 78630dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 78730dcb7c9SBarry Smith nt = recvs2[cnt++]; 78830dcb7c9SBarry Smith for (j=0; j<nt; j++) { 78930dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 79030dcb7c9SBarry Smith nprocs[recvs2[cnt+2+k]]++; 79130dcb7c9SBarry Smith } 79230dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 79330dcb7c9SBarry Smith } 79430dcb7c9SBarry Smith } 79530dcb7c9SBarry Smith nt = 0; for (i=0; i<size; i++) nt += (nprocs[i] > 0); 79630dcb7c9SBarry Smith *nproc = nt; 797b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int),procs);CHKERRQ(ierr); 798b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int),numprocs);CHKERRQ(ierr); 799b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int*),indices);CHKERRQ(ierr); 800b0a32e0cSBarry Smith ierr = PetscMalloc(size*sizeof(int),&bprocs);CHKERRQ(ierr); 80130dcb7c9SBarry Smith cnt = 0; 80230dcb7c9SBarry Smith for (i=0; i<size; i++) { 80330dcb7c9SBarry Smith if (nprocs[i] > 0) { 80430dcb7c9SBarry Smith bprocs[i] = cnt; 80530dcb7c9SBarry Smith (*procs)[cnt] = i; 80630dcb7c9SBarry Smith (*numprocs)[cnt] = nprocs[i]; 807b0a32e0cSBarry Smith ierr = PetscMalloc(nprocs[i]*sizeof(int),&(*indices)[cnt]);CHKERRQ(ierr); 80830dcb7c9SBarry Smith cnt++; 80930dcb7c9SBarry Smith } 81030dcb7c9SBarry Smith } 81130dcb7c9SBarry Smith 81230dcb7c9SBarry Smith /* make the list of subdomains for each nontrivial local node */ 81330dcb7c9SBarry Smith ierr = PetscMemzero(*numprocs,nt*sizeof(int));CHKERRQ(ierr); 81430dcb7c9SBarry Smith cnt = 0; 81530dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 81630dcb7c9SBarry Smith nt = recvs2[cnt++]; 81730dcb7c9SBarry Smith for (j=0; j<nt; j++) { 81830dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 81930dcb7c9SBarry Smith (*indices)[bprocs[recvs2[cnt+2+k]]][(*numprocs)[bprocs[recvs2[cnt+2+k]]]++] = recvs2[cnt]; 82030dcb7c9SBarry Smith } 82130dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 82230dcb7c9SBarry Smith } 82330dcb7c9SBarry Smith } 82430dcb7c9SBarry Smith ierr = PetscFree(bprocs);CHKERRQ(ierr); 82507b52d57SBarry Smith ierr = PetscFree(recvs2);CHKERRQ(ierr); 82630dcb7c9SBarry Smith 82707b52d57SBarry Smith /* sort the node indexing by their global numbers */ 82807b52d57SBarry Smith nt = *nproc; 82907b52d57SBarry Smith for (i=0; i<nt; i++) { 830b0a32e0cSBarry Smith ierr = PetscMalloc(((*numprocs)[i])*sizeof(int),&tmp);CHKERRQ(ierr); 83107b52d57SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 83207b52d57SBarry Smith tmp[j] = lindices[(*indices)[i][j]]; 83307b52d57SBarry Smith } 83407b52d57SBarry Smith ierr = PetscSortIntWithArray((*numprocs)[i],tmp,(*indices)[i]);CHKERRQ(ierr); 83507b52d57SBarry Smith ierr = PetscFree(tmp);CHKERRQ(ierr); 83607b52d57SBarry Smith } 83707b52d57SBarry Smith 83807b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 83930dcb7c9SBarry Smith nt = *nproc; 84030dcb7c9SBarry Smith for (i=0; i<nt; i++) { 84130dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] subdomain %d number of indices %d: ",rank,(*procs)[i],(*numprocs)[i]);CHKERRQ(ierr); 84230dcb7c9SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 84330dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",(*indices)[i][j]);CHKERRQ(ierr); 84430dcb7c9SBarry Smith } 84530dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 84630dcb7c9SBarry Smith } 84730dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 84807b52d57SBarry Smith } /* ----------------------------------- */ 84930dcb7c9SBarry Smith 85030dcb7c9SBarry Smith /* wait on sends */ 85130dcb7c9SBarry Smith if (nsends2) { 852b0a32e0cSBarry Smith ierr = PetscMalloc(nsends2*sizeof(MPI_Status),&send_status);CHKERRQ(ierr); 85330dcb7c9SBarry Smith ierr = MPI_Waitall(nsends2,send_waits,send_status);CHKERRQ(ierr); 85430dcb7c9SBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 85530dcb7c9SBarry Smith } 85630dcb7c9SBarry Smith 85730dcb7c9SBarry Smith ierr = PetscFree(starts3);CHKERRQ(ierr); 85830dcb7c9SBarry Smith ierr = PetscFree(dest);CHKERRQ(ierr); 85930dcb7c9SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 8603677ff5aSBarry Smith 861bc8ff85bSBarry Smith ierr = PetscFree(nownedsenders);CHKERRQ(ierr); 862bc8ff85bSBarry Smith ierr = PetscFree(ownedsenders);CHKERRQ(ierr); 863bc8ff85bSBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 86430dcb7c9SBarry Smith ierr = PetscFree(starts2);CHKERRQ(ierr); 86530dcb7c9SBarry Smith ierr = PetscFree(lens2);CHKERRQ(ierr); 86689d82c54SBarry Smith 86789d82c54SBarry Smith ierr = PetscFree(source);CHKERRQ(ierr); 86889d82c54SBarry Smith ierr = PetscFree(recvs);CHKERRQ(ierr); 8693a96401aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 87030dcb7c9SBarry Smith ierr = PetscFree(sends2);CHKERRQ(ierr); 87124cf384cSBarry Smith 87224cf384cSBarry Smith /* put the information about myself as the first entry in the list */ 87324cf384cSBarry Smith first_procs = (*procs)[0]; 87424cf384cSBarry Smith first_numprocs = (*numprocs)[0]; 87524cf384cSBarry Smith first_indices = (*indices)[0]; 87624cf384cSBarry Smith for (i=0; i<*nproc; i++) { 87724cf384cSBarry Smith if ((*procs)[i] == rank) { 87824cf384cSBarry Smith (*procs)[0] = (*procs)[i]; 87924cf384cSBarry Smith (*numprocs)[0] = (*numprocs)[i]; 88024cf384cSBarry Smith (*indices)[0] = (*indices)[i]; 88124cf384cSBarry Smith (*procs)[i] = first_procs; 88224cf384cSBarry Smith (*numprocs)[i] = first_numprocs; 88324cf384cSBarry Smith (*indices)[i] = first_indices; 88424cf384cSBarry Smith break; 88524cf384cSBarry Smith } 88624cf384cSBarry Smith } 88724cf384cSBarry Smith 88889d82c54SBarry Smith PetscFunctionReturn(0); 88989d82c54SBarry Smith } 89089d82c54SBarry Smith 8914a2ae208SSatish Balay #undef __FUNCT__ 8924a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingRestoreInfo" 89307b52d57SBarry Smith /*@C 89407b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo - Frees the memory allocated by ISLocalToGlobalMappingGetInfo() 89589d82c54SBarry Smith 89607b52d57SBarry Smith Collective on ISLocalToGlobalMapping 89707b52d57SBarry Smith 89807b52d57SBarry Smith Input Parameters: 89907b52d57SBarry Smith . mapping - the mapping from local to global indexing 90007b52d57SBarry Smith 90107b52d57SBarry Smith Output Parameter: 90207b52d57SBarry Smith + nproc - number of processors that are connected to this one 90307b52d57SBarry Smith . proc - neighboring processors 90407b52d57SBarry Smith . numproc - number of indices for each processor 90507b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 90607b52d57SBarry Smith 90707b52d57SBarry Smith Level: advanced 90807b52d57SBarry Smith 90907b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 91007b52d57SBarry Smith ISLocalToGlobalMappingGetInfo() 91107b52d57SBarry Smith @*/ 912ca01db9bSBarry Smith int ISLocalToGlobalMappingRestoreInfo(ISLocalToGlobalMapping mapping,int *nproc,int *procs[],int *numprocs[],int **indices[]) 91307b52d57SBarry Smith { 91407b52d57SBarry Smith int ierr,i; 91507b52d57SBarry Smith 91607b52d57SBarry Smith PetscFunctionBegin; 91700ff320aSBarry Smith if (*procs) {ierr = PetscFree(*procs);CHKERRQ(ierr);} 91800ff320aSBarry Smith if (*numprocs) {ierr = PetscFree(*numprocs);CHKERRQ(ierr);} 91900ff320aSBarry Smith if (*indices) { 92000ff320aSBarry Smith if ((*indices)[0]) {ierr = PetscFree((*indices)[0]);CHKERRQ(ierr);} 92100ff320aSBarry Smith for (i=1; i<*nproc; i++) { 92224cf384cSBarry Smith if ((*indices)[i]) {ierr = PetscFree((*indices)[i]);CHKERRQ(ierr);} 92307b52d57SBarry Smith } 92407b52d57SBarry Smith ierr = PetscFree(*indices);CHKERRQ(ierr); 92524cf384cSBarry Smith } 92607b52d57SBarry Smith PetscFunctionReturn(0); 92707b52d57SBarry Smith } 92889d82c54SBarry 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 944bc8ff85bSBarry Smith 94524cf384cSBarry Smith 946