1*bc8ff85bSBarry Smith /*$Id: isltog.c,v 1.44 2000/06/25 03:53:23 bsmith Exp bsmith $*/ 22362add9SBarry Smith 3e090d566SSatish Balay #include "petscsys.h" /*I "petscsys.h" I*/ 4e090d566SSatish Balay #include "src/vec/is/isimpl.h" /*I "petscis.h" I*/ 52362add9SBarry Smith 65615d1e5SSatish Balay #undef __FUNC__ 73b9aefa3SBarry Smith #define __FUNC__ /*<a name="ISLocalToGlobalMappingGetSize"></a>*/"ISLocalToGlobalMappingGetSize" 83b9aefa3SBarry Smith /*@C 93b9aefa3SBarry Smith ISLocalToGlobalMappingGetSize - Gets the local size of a local to global mapping. 103b9aefa3SBarry Smith 113b9aefa3SBarry Smith Not Collective 123b9aefa3SBarry Smith 133b9aefa3SBarry Smith Input Parameter: 143b9aefa3SBarry Smith . ltog - local to global mapping 153b9aefa3SBarry Smith 163b9aefa3SBarry Smith Output Parameter: 173b9aefa3SBarry Smith . n - the number of entries in the local mapping 183b9aefa3SBarry Smith 193b9aefa3SBarry Smith Level: advanced 203b9aefa3SBarry Smith 213b9aefa3SBarry Smith .keywords: IS, local-to-global mapping, create 223b9aefa3SBarry Smith 233b9aefa3SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 243b9aefa3SBarry Smith @*/ 253b9aefa3SBarry Smith int ISLocalToGlobalMappingGetSize(ISLocalToGlobalMapping mapping,int *n) 263b9aefa3SBarry Smith { 273b9aefa3SBarry Smith PetscFunctionBegin; 283b9aefa3SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE); 293b9aefa3SBarry Smith *n = mapping->n; 303b9aefa3SBarry Smith PetscFunctionReturn(0); 313b9aefa3SBarry Smith } 323b9aefa3SBarry Smith 333b9aefa3SBarry Smith #undef __FUNC__ 34b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"ISLocalToGlobalMappingView" 355a5d4f66SBarry Smith /*@C 365a5d4f66SBarry Smith ISLocalToGlobalMappingView - View a local to global mapping 375a5d4f66SBarry Smith 38b9cd556bSLois Curfman McInnes Not Collective 39b9cd556bSLois Curfman McInnes 405a5d4f66SBarry Smith Input Parameters: 413b9aefa3SBarry Smith + ltog - local to global mapping 423b9aefa3SBarry Smith - viewer - viewer 435a5d4f66SBarry Smith 44a997ad1aSLois Curfman McInnes Level: advanced 45a997ad1aSLois Curfman McInnes 465a5d4f66SBarry Smith .keywords: IS, local-to-global mapping, create 475a5d4f66SBarry Smith 485a5d4f66SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 495a5d4f66SBarry Smith @*/ 505a5d4f66SBarry Smith int ISLocalToGlobalMappingView(ISLocalToGlobalMapping mapping,Viewer viewer) 515a5d4f66SBarry Smith { 52f1af5d2fSBarry Smith int i,ierr,rank; 536831982aSBarry Smith PetscTruth isascii; 545a5d4f66SBarry Smith 555a5d4f66SBarry Smith PetscFunctionBegin; 566831982aSBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE); 573eda8832SBarry Smith if (!viewer) viewer = VIEWER_STDOUT_(mapping->comm); 586831982aSBarry Smith PetscValidHeaderSpecific(viewer,VIEWER_COOKIE); 596831982aSBarry Smith PetscCheckSameComm(mapping,viewer); 605a5d4f66SBarry Smith 61f1af5d2fSBarry Smith ierr = MPI_Comm_rank(mapping->comm,&rank);CHKERRQ(ierr); 626831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,ASCII_VIEWER,&isascii);CHKERRQ(ierr); 636831982aSBarry Smith if (isascii) { 645a5d4f66SBarry Smith for (i=0; i<mapping->n; i++) { 65f1af5d2fSBarry Smith ierr = ViewerASCIISynchronizedPrintf(viewer,"[%d] %d %d\n",rank,i,mapping->indices[i]);CHKERRQ(ierr); 666831982aSBarry Smith } 676831982aSBarry Smith ierr = ViewerFlush(viewer);CHKERRQ(ierr); 686831982aSBarry Smith } else { 696831982aSBarry Smith SETERRQ1(1,1,"Viewer type %s not supported for ISLocalToGlobalMapping",((PetscObject)viewer)->type_name); 705a5d4f66SBarry Smith } 715a5d4f66SBarry Smith 725a5d4f66SBarry Smith PetscFunctionReturn(0); 735a5d4f66SBarry Smith } 745a5d4f66SBarry Smith 755a5d4f66SBarry Smith #undef __FUNC__ 76b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"ISLocalToGlobalMappingCreateIS" 772bdab257SBarry Smith /*@C 782bdab257SBarry Smith ISLocalToGlobalMappingCreateIS - Creates a mapping between a local (0 to n) 792bdab257SBarry Smith ordering and a global parallel ordering. 802bdab257SBarry Smith 810f5bd95cSBarry Smith Not collective 82b9cd556bSLois Curfman McInnes 83a997ad1aSLois Curfman McInnes Input Parameter: 842bdab257SBarry Smith . is - index set containing the global numbers for each local 852bdab257SBarry Smith 86a997ad1aSLois Curfman McInnes Output Parameter: 872bdab257SBarry Smith . mapping - new mapping data structure 882bdab257SBarry Smith 89a997ad1aSLois Curfman McInnes Level: advanced 90a997ad1aSLois Curfman McInnes 912bdab257SBarry Smith .keywords: IS, local-to-global mapping, create 922bdab257SBarry Smith 932bdab257SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 942bdab257SBarry Smith @*/ 952bdab257SBarry Smith int ISLocalToGlobalMappingCreateIS(IS is,ISLocalToGlobalMapping *mapping) 962bdab257SBarry Smith { 972bdab257SBarry Smith int n,*indices,ierr; 982bdab257SBarry Smith MPI_Comm comm; 993a40ed3dSBarry Smith 1003a40ed3dSBarry Smith PetscFunctionBegin; 1012bdab257SBarry Smith PetscValidHeaderSpecific(is,IS_COOKIE); 1022bdab257SBarry Smith 1032bdab257SBarry Smith ierr = PetscObjectGetComm((PetscObject)is,&comm);CHKERRQ(ierr); 1043b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 1052bdab257SBarry Smith ierr = ISGetIndices(is,&indices);CHKERRQ(ierr); 1062bdab257SBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,n,indices,mapping);CHKERRQ(ierr); 1072bdab257SBarry Smith ierr = ISRestoreIndices(is,&indices);CHKERRQ(ierr); 1082bdab257SBarry Smith 1093a40ed3dSBarry Smith PetscFunctionReturn(0); 1102bdab257SBarry Smith } 1115a5d4f66SBarry Smith 1122bdab257SBarry Smith #undef __FUNC__ 113b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"ISLocalToGlobalMappingCreate" 114dd7157adSSatish Balay /*@C 11590f02eecSBarry Smith ISLocalToGlobalMappingCreate - Creates a mapping between a local (0 to n) 11690f02eecSBarry Smith ordering and a global parallel ordering. 1172362add9SBarry Smith 11889d82c54SBarry Smith Not Collective, but communicator may have more than one process 119b9cd556bSLois Curfman McInnes 1202362add9SBarry Smith Input Parameters: 12189d82c54SBarry Smith + comm - MPI communicator 12290f02eecSBarry Smith . n - the number of local elements 123b9cd556bSLois Curfman McInnes - indices - the global index for each local element 1242362add9SBarry Smith 125a997ad1aSLois Curfman McInnes Output Parameter: 12690f02eecSBarry Smith . mapping - new mapping data structure 1272362add9SBarry Smith 128a997ad1aSLois Curfman McInnes Level: advanced 129a997ad1aSLois Curfman McInnes 1303acfe500SLois Curfman McInnes .keywords: IS, local-to-global mapping, create 1312362add9SBarry Smith 1322bdab257SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS() 1332362add9SBarry Smith @*/ 134987e4450SSatish Balay int ISLocalToGlobalMappingCreate(MPI_Comm cm,int n,const int indices[],ISLocalToGlobalMapping *mapping) 1352362add9SBarry Smith { 136549d3d68SSatish Balay int ierr; 137549d3d68SSatish Balay 1383a40ed3dSBarry Smith PetscFunctionBegin; 13990f02eecSBarry Smith PetscValidIntPointer(indices); 14090f02eecSBarry Smith PetscValidPointer(mapping); 1412362add9SBarry Smith 1423f1db9ecSBarry Smith PetscHeaderCreate(*mapping,_p_ISLocalToGlobalMapping,int,IS_LTOGM_COOKIE,0,"ISLocalToGlobalMapping", 1433f1db9ecSBarry Smith cm,ISLocalToGlobalMappingDestroy,ISLocalToGlobalMappingView); 144d4bb536fSBarry Smith PLogObjectCreate(*mapping); 145d4bb536fSBarry Smith PLogObjectMemory(*mapping,sizeof(struct _p_ISLocalToGlobalMapping)+n*sizeof(int)); 146d4bb536fSBarry Smith 147d4bb536fSBarry Smith (*mapping)->n = n; 14890f02eecSBarry Smith (*mapping)->indices = (int*)PetscMalloc((n+1)*sizeof(int));CHKPTRQ((*mapping)->indices); 149549d3d68SSatish Balay ierr = PetscMemcpy((*mapping)->indices,indices,n*sizeof(int));CHKERRQ(ierr); 150d4bb536fSBarry Smith 151d4bb536fSBarry Smith /* 152d4bb536fSBarry Smith Do not create the global to local mapping. This is only created if 153d4bb536fSBarry Smith ISGlobalToLocalMapping() is called 154d4bb536fSBarry Smith */ 155d4bb536fSBarry Smith (*mapping)->globals = 0; 1563a40ed3dSBarry Smith PetscFunctionReturn(0); 1572362add9SBarry Smith } 1582362add9SBarry Smith 1595615d1e5SSatish Balay #undef __FUNC__ 160b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"ISLocalToGlobalMappingDestroy" 16190f02eecSBarry Smith /*@ 16290f02eecSBarry Smith ISLocalToGlobalMappingDestroy - Destroys a mapping between a local (0 to n) 16390f02eecSBarry Smith ordering and a global parallel ordering. 16490f02eecSBarry Smith 1650f5bd95cSBarry Smith Note Collective 166b9cd556bSLois Curfman McInnes 16790f02eecSBarry Smith Input Parameters: 16890f02eecSBarry Smith . mapping - mapping data structure 16990f02eecSBarry Smith 170a997ad1aSLois Curfman McInnes Level: advanced 171a997ad1aSLois Curfman McInnes 1723acfe500SLois Curfman McInnes .keywords: IS, local-to-global mapping, destroy 17390f02eecSBarry Smith 1743acfe500SLois Curfman McInnes .seealso: ISLocalToGlobalMappingCreate() 17590f02eecSBarry Smith @*/ 17690f02eecSBarry Smith int ISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping mapping) 17790f02eecSBarry Smith { 178606d414cSSatish Balay int ierr; 1793a40ed3dSBarry Smith PetscFunctionBegin; 18090f02eecSBarry Smith PetscValidPointer(mapping); 1813a40ed3dSBarry Smith if (--mapping->refct > 0) PetscFunctionReturn(0); 18285614651SBarry Smith if (mapping->refct < 0) { 18385614651SBarry Smith SETERRQ(1,1,"Mapping already destroyed"); 18485614651SBarry Smith } 18590f02eecSBarry Smith 186606d414cSSatish Balay ierr = PetscFree(mapping->indices);CHKERRQ(ierr); 187606d414cSSatish Balay if (mapping->globals) {ierr = PetscFree(mapping->globals);CHKERRQ(ierr);} 188d4bb536fSBarry Smith PLogObjectDestroy(mapping); 189d4bb536fSBarry Smith PetscHeaderDestroy(mapping); 1903a40ed3dSBarry Smith PetscFunctionReturn(0); 19190f02eecSBarry Smith } 19290f02eecSBarry Smith 1935615d1e5SSatish Balay #undef __FUNC__ 194b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"ISLocalToGlobalMappingApplyIS" 19590f02eecSBarry Smith /*@ 1963acfe500SLois Curfman McInnes ISLocalToGlobalMappingApplyIS - Creates from an IS in the local numbering 1973acfe500SLois Curfman McInnes a new index set using the global numbering defined in an ISLocalToGlobalMapping 1983acfe500SLois Curfman McInnes context. 19990f02eecSBarry Smith 200b9cd556bSLois Curfman McInnes Not collective 201b9cd556bSLois Curfman McInnes 20290f02eecSBarry Smith Input Parameters: 203b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 204b9cd556bSLois Curfman McInnes - is - index set in local numbering 20590f02eecSBarry Smith 20690f02eecSBarry Smith Output Parameters: 20790f02eecSBarry Smith . newis - index set in global numbering 20890f02eecSBarry Smith 209a997ad1aSLois Curfman McInnes Level: advanced 210a997ad1aSLois Curfman McInnes 2113acfe500SLois Curfman McInnes .keywords: IS, local-to-global mapping, apply 2123acfe500SLois Curfman McInnes 21390f02eecSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 214d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy(), ISGlobalToLocalMappingApply() 21590f02eecSBarry Smith @*/ 21690f02eecSBarry Smith int ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping mapping,IS is,IS *newis) 21790f02eecSBarry Smith { 2183b9aefa3SBarry Smith int ierr,n,i,*idxin,*idxmap,*idxout,Nmax = mapping->n; 2193a40ed3dSBarry Smith 2203a40ed3dSBarry Smith PetscFunctionBegin; 22190f02eecSBarry Smith PetscValidPointer(mapping); 22290f02eecSBarry Smith PetscValidHeaderSpecific(is,IS_COOKIE); 22390f02eecSBarry Smith PetscValidPointer(newis); 22490f02eecSBarry Smith 2253b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 22690f02eecSBarry Smith ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 22790f02eecSBarry Smith idxmap = mapping->indices; 22890f02eecSBarry Smith 22990f02eecSBarry Smith idxout = (int*)PetscMalloc((n+1)*sizeof(int));CHKPTRQ(idxout); 23090f02eecSBarry Smith for (i=0; i<n; i++) { 2313b9aefa3SBarry Smith if (idxin[i] >= Nmax) SETERRQ3(PETSC_ERR_ARG_OUTOFRANGE,1,"Local index %d too large %d (max) at %d",idxin[i],Nmax,i); 23290f02eecSBarry Smith idxout[i] = idxmap[idxin[i]]; 23390f02eecSBarry Smith } 2343b9aefa3SBarry Smith ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 235029af93fSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxout,newis);CHKERRQ(ierr); 236606d414cSSatish Balay ierr = PetscFree(idxout);CHKERRQ(ierr); 2373a40ed3dSBarry Smith PetscFunctionReturn(0); 23890f02eecSBarry Smith } 23990f02eecSBarry Smith 24089d82c54SBarry Smith /*MC 2413acfe500SLois Curfman McInnes ISLocalToGlobalMappingApply - Takes a list of integers in a local numbering 2423acfe500SLois Curfman McInnes and converts them to the global numbering. 24390f02eecSBarry Smith 244b9cd556bSLois Curfman McInnes Not collective 245b9cd556bSLois Curfman McInnes 246bb25748dSBarry Smith Input Parameters: 247b9cd556bSLois Curfman McInnes + mapping - the local to global mapping context 248bb25748dSBarry Smith . N - number of integers 249b9cd556bSLois Curfman McInnes - in - input indices in local numbering 250bb25748dSBarry Smith 251bb25748dSBarry Smith Output Parameter: 252bb25748dSBarry Smith . out - indices in global numbering 253bb25748dSBarry Smith 2543b9aefa3SBarry Smith Synopsis: 2553b9aefa3SBarry Smith ISLocalToGlobalMappingApply(ISLocalToGlobalMapping mapping,int N,int in[],int out[]) 2563b9aefa3SBarry Smith 257b9cd556bSLois Curfman McInnes Notes: 258b9cd556bSLois Curfman McInnes The in and out array parameters may be identical. 259d4bb536fSBarry Smith 260a997ad1aSLois Curfman McInnes Level: advanced 261a997ad1aSLois Curfman McInnes 262bb25748dSBarry Smith .seealso: ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 2630752156aSBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 264d4bb536fSBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 265bb25748dSBarry Smith 2663acfe500SLois Curfman McInnes .keywords: local-to-global, mapping, apply 267d4bb536fSBarry Smith 26889d82c54SBarry Smith M*/ 269d4bb536fSBarry Smith 270d4bb536fSBarry Smith /* -----------------------------------------------------------------------------------------*/ 271d4bb536fSBarry Smith 272d4bb536fSBarry Smith #undef __FUNC__ 273b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"ISGlobalToLocalMappingSetUp_Private" 274d4bb536fSBarry Smith /* 275d4bb536fSBarry Smith Creates the global fields in the ISLocalToGlobalMapping structure 276d4bb536fSBarry Smith */ 277d4bb536fSBarry Smith static int ISGlobalToLocalMappingSetUp_Private(ISLocalToGlobalMapping mapping) 278d4bb536fSBarry Smith { 279d4bb536fSBarry Smith int i,*idx = mapping->indices,n = mapping->n,end,start,*globals; 280d4bb536fSBarry Smith 2813a40ed3dSBarry Smith PetscFunctionBegin; 282d4bb536fSBarry Smith end = 0; 283d4bb536fSBarry Smith start = 100000000; 284d4bb536fSBarry Smith 285d4bb536fSBarry Smith for (i=0; i<n; i++) { 286d4bb536fSBarry Smith if (idx[i] < 0) continue; 287d4bb536fSBarry Smith if (idx[i] < start) start = idx[i]; 288d4bb536fSBarry Smith if (idx[i] > end) end = idx[i]; 289d4bb536fSBarry Smith } 290d4bb536fSBarry Smith if (start > end) {start = 0; end = -1;} 291d4bb536fSBarry Smith mapping->globalstart = start; 292d4bb536fSBarry Smith mapping->globalend = end; 293d4bb536fSBarry Smith 294d4bb536fSBarry Smith globals = mapping->globals = (int*)PetscMalloc((end-start+2)*sizeof(int));CHKPTRQ(mapping->globals); 295d4bb536fSBarry Smith for (i=0; i<end-start+1; i++) { 296d4bb536fSBarry Smith globals[i] = -1; 297d4bb536fSBarry Smith } 298d4bb536fSBarry Smith for (i=0; i<n; i++) { 299d4bb536fSBarry Smith if (idx[i] < 0) continue; 300d4bb536fSBarry Smith globals[idx[i] - start] = i; 301d4bb536fSBarry Smith } 302d4bb536fSBarry Smith 303d4bb536fSBarry Smith PLogObjectMemory(mapping,(end-start+1)*sizeof(int)); 3043a40ed3dSBarry Smith PetscFunctionReturn(0); 305d4bb536fSBarry Smith } 306d4bb536fSBarry Smith 307d4bb536fSBarry Smith #undef __FUNC__ 308b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"ISGlobalToLocalMappingApply" 309d4bb536fSBarry Smith /*@ 310a997ad1aSLois Curfman McInnes ISGlobalToLocalMappingApply - Provides the local numbering for a list of integers 311a997ad1aSLois Curfman McInnes specified with a global numbering. 312d4bb536fSBarry Smith 313b9cd556bSLois Curfman McInnes Not collective 314b9cd556bSLois Curfman McInnes 315d4bb536fSBarry Smith Input Parameters: 316b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 317d4bb536fSBarry Smith . type - IS_GTOLM_MASK - replaces global indices with no local value with -1 318d4bb536fSBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 319d4bb536fSBarry Smith . n - number of global indices to map 320b9cd556bSLois Curfman McInnes - idx - global indices to map 321d4bb536fSBarry Smith 322d4bb536fSBarry Smith Output Parameters: 323b9cd556bSLois Curfman McInnes + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 324b9cd556bSLois Curfman McInnes - idxout - local index of each global index, one must pass in an array long enough 325e182c471SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApply() with 326e182c471SBarry Smith idxout == PETSC_NULL to determine the required length (returned in nout) 327e182c471SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApply() 328e182c471SBarry Smith a second time to set the values. 329d4bb536fSBarry Smith 330b9cd556bSLois Curfman McInnes Notes: 331b9cd556bSLois Curfman McInnes Either nout or idxout may be PETSC_NULL. idx and idxout may be identical. 332d4bb536fSBarry Smith 3330f5bd95cSBarry Smith This is not scalable in memory usage. Each processor requires O(Nglobal) size 3340f5bd95cSBarry Smith array to compute these. 3350f5bd95cSBarry Smith 336a997ad1aSLois Curfman McInnes Level: advanced 337a997ad1aSLois Curfman McInnes 338d4bb536fSBarry Smith .keywords: IS, global-to-local mapping, apply 339d4bb536fSBarry Smith 340d4bb536fSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 341d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy() 342d4bb536fSBarry Smith @*/ 343d4bb536fSBarry Smith int ISGlobalToLocalMappingApply(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, 344987e4450SSatish Balay int n,const int idx[],int *nout,int idxout[]) 345d4bb536fSBarry Smith { 346d4bb536fSBarry Smith int i,ierr,*globals,nf = 0,tmp,start,end; 347d4bb536fSBarry Smith 3483a40ed3dSBarry Smith PetscFunctionBegin; 349d4bb536fSBarry Smith if (!mapping->globals) { 350d4bb536fSBarry Smith ierr = ISGlobalToLocalMappingSetUp_Private(mapping);CHKERRQ(ierr); 351d4bb536fSBarry Smith } 352d4bb536fSBarry Smith globals = mapping->globals; 353d4bb536fSBarry Smith start = mapping->globalstart; 354d4bb536fSBarry Smith end = mapping->globalend; 355d4bb536fSBarry Smith 356d4bb536fSBarry Smith if (type == IS_GTOLM_MASK) { 357d4bb536fSBarry Smith if (idxout) { 358d4bb536fSBarry Smith for (i=0; i<n; i++) { 359d4bb536fSBarry Smith if (idx[i] < 0) idxout[i] = idx[i]; 360d4bb536fSBarry Smith else if (idx[i] < start) idxout[i] = -1; 361d4bb536fSBarry Smith else if (idx[i] > end) idxout[i] = -1; 362d4bb536fSBarry Smith else idxout[i] = globals[idx[i] - start]; 363d4bb536fSBarry Smith } 364d4bb536fSBarry Smith } 365d4bb536fSBarry Smith if (nout) *nout = n; 366d4bb536fSBarry Smith } else { 367d4bb536fSBarry Smith if (idxout) { 368d4bb536fSBarry Smith for (i=0; i<n; i++) { 369d4bb536fSBarry Smith if (idx[i] < 0) continue; 370d4bb536fSBarry Smith if (idx[i] < start) continue; 371d4bb536fSBarry Smith if (idx[i] > end) continue; 372d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 373d4bb536fSBarry Smith if (tmp < 0) continue; 374d4bb536fSBarry Smith idxout[nf++] = tmp; 375d4bb536fSBarry Smith } 376d4bb536fSBarry Smith } else { 377d4bb536fSBarry Smith for (i=0; i<n; i++) { 378d4bb536fSBarry Smith if (idx[i] < 0) continue; 379d4bb536fSBarry Smith if (idx[i] < start) continue; 380d4bb536fSBarry Smith if (idx[i] > end) continue; 381d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 382d4bb536fSBarry Smith if (tmp < 0) continue; 383d4bb536fSBarry Smith nf++; 384d4bb536fSBarry Smith } 385d4bb536fSBarry Smith } 386d4bb536fSBarry Smith if (nout) *nout = nf; 387d4bb536fSBarry Smith } 388d4bb536fSBarry Smith 3893a40ed3dSBarry Smith PetscFunctionReturn(0); 390d4bb536fSBarry Smith } 39190f02eecSBarry Smith 39289d82c54SBarry Smith #undef __FUNC__ 39389d82c54SBarry Smith #define __FUNC__ /*<a name=""></a>*/"ISLocalToGlobalMappingGetInfo" 39489d82c54SBarry Smith /*@C 39589d82c54SBarry Smith ISLocalToGlobalMappingGetInfo - Gets the neighbor information for each processor and 39689d82c54SBarry Smith each index shared by more than one processor 39789d82c54SBarry Smith 39889d82c54SBarry Smith Collective on ISLocalToGlobalMapping 39989d82c54SBarry Smith 40089d82c54SBarry Smith Input Parameters: 40189d82c54SBarry Smith . mapping - the mapping from local to global indexing 40289d82c54SBarry Smith 40389d82c54SBarry Smith Output Parameter: 40489d82c54SBarry Smith + nproc - number of processors that are connected to this one 40589d82c54SBarry Smith . proc - neighboring processors 40689d82c54SBarry Smith . indices - indices of local nodes shared with neighbor (sorted by global numbering) 40789d82c54SBarry Smith 40889d82c54SBarry Smith Level: advanced 40989d82c54SBarry Smith 41089d82c54SBarry Smith .keywords: IS, local-to-global mapping, neighbors 41189d82c54SBarry Smith 41289d82c54SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate() 41389d82c54SBarry Smith @*/ 41489d82c54SBarry Smith int ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping mapping,int *nproc,int **procs,int ***indices) 41589d82c54SBarry Smith { 4163a96401aSBarry Smith int i,n = mapping->n,ierr,Ng,ng = PETSC_DECIDE,max = 0,*lindices = mapping->indices; 4173a96401aSBarry Smith int size,rank,*nprocs,*owner,nsends,*sends,j,*starts,*work,nmax,nrecvs,*recvs,proc; 418*bc8ff85bSBarry Smith int tag,cnt,*len,*source,imdex,scale,*ownedsenders,*nownedsenders,rstart,nowned; 419*bc8ff85bSBarry Smith int node,nownedm; 42089d82c54SBarry Smith MPI_Request *recv_waits,*send_waits; 42189d82c54SBarry Smith MPI_Status recv_status,*send_status; 42289d82c54SBarry Smith MPI_Comm comm = mapping->comm; 42389d82c54SBarry Smith 42489d82c54SBarry Smith PetscFunctionBegin; 42589d82c54SBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag);CHKERRQ(ierr); 42689d82c54SBarry Smith 42789d82c54SBarry Smith for (i=0; i<n; i++) { 42889d82c54SBarry Smith if (lindices[i] > max) max = lindices[i]; 42989d82c54SBarry Smith } 43089d82c54SBarry Smith ierr = MPI_Allreduce(&max,&Ng,1,MPI_INT,MPI_MAX,comm);CHKERRQ(ierr); 43189d82c54SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 43289d82c54SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 433*bc8ff85bSBarry Smith scale = Ng/size + 1; 434*bc8ff85bSBarry Smith ng = scale; if (rank == size-1) ng = Ng - scale*(size-1); 435caba0dd0SBarry Smith rstart = scale*rank; 43689d82c54SBarry Smith 43789d82c54SBarry Smith /* determine ownership ranges of global indices */ 4383a96401aSBarry Smith nprocs = (int*)PetscMalloc((2*size+1)*sizeof(int));CHKPTRQ(nprocs); 43989d82c54SBarry Smith ierr = PetscMemzero(nprocs,size*sizeof(int));CHKERRQ(ierr); 44089d82c54SBarry Smith 44189d82c54SBarry Smith /* determine owners of each local node */ 44289d82c54SBarry Smith owner = (int*)PetscMalloc((n+1)*sizeof(int));CHKPTRQ(owner); 44389d82c54SBarry Smith for (i=0; i<n; i++) { 444*bc8ff85bSBarry Smith proc = lindices[i]/scale; 4453a96401aSBarry Smith nprocs[proc]++; nprocs[size+proc] = 1; owner[i] = proc; 44689d82c54SBarry Smith } 44789d82c54SBarry Smith nsends = 0; for (i=0; i<size; i++) nsends += nprocs[size + i]; 44889d82c54SBarry Smith PLogInfo(0,"ISLocalToGlobalMappingGetInfo: Number of global owners for my local data %d\n",nsends); 44989d82c54SBarry Smith 45089d82c54SBarry Smith /* inform other processors of number of messages and max length*/ 45189d82c54SBarry Smith work = (int*)PetscMalloc(2*size*sizeof(int));CHKPTRQ(work); 45289d82c54SBarry Smith ierr = MPI_Allreduce(nprocs,work,2*size,MPI_INT,PetscMaxSum_Op,comm);CHKERRQ(ierr); 45389d82c54SBarry Smith nmax = work[rank]; 45489d82c54SBarry Smith nrecvs = work[size+rank]; 45589d82c54SBarry Smith ierr = PetscFree(work);CHKERRQ(ierr); 45689d82c54SBarry Smith PLogInfo(0,"ISLocalToGlobalMappingGetInfo: Number of local owners for my global data %d\n",nrecvs); 45789d82c54SBarry Smith 45889d82c54SBarry Smith /* post receives for owned rows */ 45989d82c54SBarry Smith recvs = (int*)PetscMalloc((nrecvs+1)*(nmax+1)*sizeof(int));CHKPTRQ(recvs); 46089d82c54SBarry Smith recv_waits = (MPI_Request*)PetscMalloc((nrecvs+1)*sizeof(MPI_Request));CHKPTRQ(recv_waits); 46189d82c54SBarry Smith for (i=0; i<nrecvs; i++) { 46289d82c54SBarry Smith ierr = MPI_Irecv(recvs+nmax*i,nmax,MPI_INT,MPI_ANY_SOURCE,tag,comm,recv_waits+i);CHKERRQ(ierr); 46389d82c54SBarry Smith } 46489d82c54SBarry Smith 46589d82c54SBarry Smith /* pack messages containing lists of local nodes to owners */ 46689d82c54SBarry Smith sends = (int*)PetscMalloc((n+1)*sizeof(int));CHKPTRQ(sends); 46789d82c54SBarry Smith starts = (int*)PetscMalloc((size+1)*sizeof(int));CHKPTRQ(starts); 46889d82c54SBarry Smith starts[0] = 0; 46989d82c54SBarry Smith for (i=1; i<size; i++) { starts[i] = starts[i-1] + nprocs[i-1];} 47089d82c54SBarry Smith for (i=0; i<n; i++) { 47189d82c54SBarry Smith sends[starts[owner[i]]++] = lindices[i]; 47289d82c54SBarry Smith } 47389d82c54SBarry Smith ierr = PetscFree(owner);CHKERRQ(ierr); 47489d82c54SBarry Smith starts[0] = 0; 47589d82c54SBarry Smith for (i=1; i<size; i++) { starts[i] = starts[i-1] + nprocs[i-1];} 47689d82c54SBarry Smith 47789d82c54SBarry Smith /* send the messages */ 47889d82c54SBarry Smith send_waits = (MPI_Request*)PetscMalloc((nsends+1)*sizeof(MPI_Request));CHKPTRQ(send_waits); 47989d82c54SBarry Smith cnt = 0; 48089d82c54SBarry Smith for (i=0; i<size; i++) { 48189d82c54SBarry Smith if (nprocs[i]) { 48289d82c54SBarry Smith ierr = MPI_Isend(sends+starts[i],nprocs[i],MPI_INT,i,tag,comm,send_waits+cnt);CHKERRQ(ierr); 48389d82c54SBarry Smith cnt++; 48489d82c54SBarry Smith } 48589d82c54SBarry Smith } 48689d82c54SBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 48789d82c54SBarry Smith 48889d82c54SBarry Smith /* wait on receives */ 4893a96401aSBarry Smith source = (int*)PetscMalloc((2*nrecvs+1)*sizeof(int));CHKPTRQ(source); 49089d82c54SBarry Smith len = source + nrecvs; 49189d82c54SBarry Smith cnt = nrecvs; 492caba0dd0SBarry Smith nownedsenders = (int*)PetscMalloc((ng+1)*sizeof(int));CHKPTRQ(nownedsenders); 493caba0dd0SBarry Smith ierr = PetscMemzero(nownedsenders,ng*sizeof(int));CHKERRQ(ierr); 49489d82c54SBarry Smith while (cnt) { 49589d82c54SBarry Smith ierr = MPI_Waitany(nrecvs,recv_waits,&imdex,&recv_status);CHKERRQ(ierr); 49689d82c54SBarry Smith /* unpack receives into our local space */ 49789d82c54SBarry Smith ierr = MPI_Get_count(&recv_status,MPI_INT,&len[imdex]);CHKERRQ(ierr); 49889d82c54SBarry Smith source[imdex] = recv_status.MPI_SOURCE; 499caba0dd0SBarry Smith /* count how many local owners for each of my global owned indices */ 500caba0dd0SBarry Smith for (i=0; i<len[imdex]; i++) nownedsenders[recvs[imdex*nmax+i]-rstart]++; 50189d82c54SBarry Smith cnt--; 50289d82c54SBarry Smith } 50389d82c54SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 50489d82c54SBarry Smith 505*bc8ff85bSBarry Smith /* count how many globally owned indices are on an edge multiplied by how many processors 506*bc8ff85bSBarry Smith own them. */ 507*bc8ff85bSBarry Smith nowned = 0; 508*bc8ff85bSBarry Smith nownedm = 0; 509*bc8ff85bSBarry Smith for (i=0; i<ng; i++) { 510*bc8ff85bSBarry Smith if (nownedsenders[i] > 1) {nownedm += nownedsenders[i]; nowned++;} 511*bc8ff85bSBarry Smith } 512*bc8ff85bSBarry Smith 513*bc8ff85bSBarry Smith /* create single array to contain rank of all local owners of each globally owned index */ 514*bc8ff85bSBarry Smith ownedsenders = (int*)PetscMalloc((nownedm+1)*sizeof(int));CHKERRQ(ierr); 515*bc8ff85bSBarry Smith starts = (int*)PetscMalloc((nowned+1)*sizeof(int));CHKPTRQ(starts); 516*bc8ff85bSBarry Smith starts[0] = 0; 517*bc8ff85bSBarry Smith for (i=1; i<ng; i++) { 518*bc8ff85bSBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 519*bc8ff85bSBarry Smith else starts[i] = starts[i-1]; 520*bc8ff85bSBarry Smith } 521*bc8ff85bSBarry Smith 522*bc8ff85bSBarry Smith /* for each globally owned node list all ariving processors */ 523*bc8ff85bSBarry Smith for (i=0; i<nrecvs; i++) { 524*bc8ff85bSBarry Smith for (j=0; j<len[i]; j++) { 525*bc8ff85bSBarry Smith node = recvs[i*nmax+j]-rstart; 526*bc8ff85bSBarry Smith if (nownedsenders[node] > 1) { 527*bc8ff85bSBarry Smith ownedsenders[starts[node]++] = source[i]; 528*bc8ff85bSBarry Smith } 529*bc8ff85bSBarry Smith } 530*bc8ff85bSBarry Smith } 531*bc8ff85bSBarry Smith 53289d82c54SBarry Smith /* wait on sends */ 5333a96401aSBarry Smith if (nsends) { 5343a96401aSBarry Smith send_status = (MPI_Status*)PetscMalloc(nsends*sizeof(MPI_Status));CHKPTRQ(send_status); 5353a96401aSBarry Smith ierr = MPI_Waitall(nsends,send_waits,send_status);CHKERRQ(ierr); 5363a96401aSBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 5373a96401aSBarry Smith } 53889d82c54SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 5393a96401aSBarry Smith ierr = PetscFree(sends);CHKERRQ(ierr); 540*bc8ff85bSBarry Smith ierr = PetscFree(nownedsenders);CHKERRQ(ierr); 541*bc8ff85bSBarry Smith ierr = PetscFree(ownedsenders);CHKERRQ(ierr); 542*bc8ff85bSBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 54389d82c54SBarry Smith 54489d82c54SBarry Smith ierr = PetscFree(source);CHKERRQ(ierr); 54589d82c54SBarry Smith ierr = PetscFree(recvs);CHKERRQ(ierr); 5463a96401aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 54789d82c54SBarry Smith PetscFunctionReturn(0); 54889d82c54SBarry Smith } 54989d82c54SBarry Smith 55089d82c54SBarry Smith 55189d82c54SBarry Smith 552*bc8ff85bSBarry Smith 553*bc8ff85bSBarry Smith 554*bc8ff85bSBarry Smith 555*bc8ff85bSBarry Smith 556*bc8ff85bSBarry Smith 557*bc8ff85bSBarry Smith 558*bc8ff85bSBarry Smith 559*bc8ff85bSBarry Smith 560*bc8ff85bSBarry Smith 561*bc8ff85bSBarry Smith 562*bc8ff85bSBarry Smith 563*bc8ff85bSBarry Smith 564*bc8ff85bSBarry Smith 565*bc8ff85bSBarry Smith 566*bc8ff85bSBarry Smith 567*bc8ff85bSBarry Smith 568