1*273d9f13SBarry Smith /*$Id: isltog.c,v 1.58 2000/09/28 21:10:07 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 21*273d9f13SBarry Smith Concepts: mapping^local to global 223b9aefa3SBarry Smith 233b9aefa3SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 243b9aefa3SBarry Smith @*/ 253b9aefa3SBarry Smith int ISLocalToGlobalMappingGetSize(ISLocalToGlobalMapping mapping,int *n) 263b9aefa3SBarry Smith { 273b9aefa3SBarry Smith PetscFunctionBegin; 283b9aefa3SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE); 293b9aefa3SBarry Smith *n = mapping->n; 303b9aefa3SBarry Smith PetscFunctionReturn(0); 313b9aefa3SBarry Smith } 323b9aefa3SBarry Smith 333b9aefa3SBarry Smith #undef __FUNC__ 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 46*273d9f13SBarry Smith Concepts: mapping^local to global 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 { 6929bbc08cSBarry Smith SETERRQ1(1,"Viewer type %s not supported for ISLocalToGlobalMapping",((PetscObject)viewer)->type_name); 705a5d4f66SBarry Smith } 715a5d4f66SBarry Smith 725a5d4f66SBarry Smith PetscFunctionReturn(0); 735a5d4f66SBarry Smith } 745a5d4f66SBarry Smith 755a5d4f66SBarry Smith #undef __FUNC__ 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 91*273d9f13SBarry Smith Concepts: mapping^local to global 922bdab257SBarry Smith 932bdab257SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 942bdab257SBarry Smith @*/ 952bdab257SBarry Smith int ISLocalToGlobalMappingCreateIS(IS is,ISLocalToGlobalMapping *mapping) 962bdab257SBarry Smith { 972bdab257SBarry Smith int n,*indices,ierr; 982bdab257SBarry Smith MPI_Comm comm; 993a40ed3dSBarry Smith 1003a40ed3dSBarry Smith PetscFunctionBegin; 1012bdab257SBarry Smith PetscValidHeaderSpecific(is,IS_COOKIE); 1022bdab257SBarry Smith 1032bdab257SBarry Smith ierr = PetscObjectGetComm((PetscObject)is,&comm);CHKERRQ(ierr); 1043b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 1052bdab257SBarry Smith ierr = ISGetIndices(is,&indices);CHKERRQ(ierr); 1062bdab257SBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,n,indices,mapping);CHKERRQ(ierr); 1072bdab257SBarry Smith ierr = ISRestoreIndices(is,&indices);CHKERRQ(ierr); 1082bdab257SBarry Smith 1093a40ed3dSBarry Smith PetscFunctionReturn(0); 1102bdab257SBarry Smith } 1115a5d4f66SBarry Smith 1122bdab257SBarry Smith #undef __FUNC__ 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 130*273d9f13SBarry Smith Concepts: mapping^local to global 1312362add9SBarry Smith 1322bdab257SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS() 1332362add9SBarry Smith @*/ 134987e4450SSatish Balay int ISLocalToGlobalMappingCreate(MPI_Comm cm,int n,const int indices[],ISLocalToGlobalMapping *mapping) 1352362add9SBarry Smith { 136549d3d68SSatish Balay int ierr; 137549d3d68SSatish Balay 1383a40ed3dSBarry Smith PetscFunctionBegin; 13990f02eecSBarry Smith PetscValidIntPointer(indices); 14090f02eecSBarry Smith PetscValidPointer(mapping); 1412362add9SBarry Smith 1423f1db9ecSBarry Smith PetscHeaderCreate(*mapping,_p_ISLocalToGlobalMapping,int,IS_LTOGM_COOKIE,0,"ISLocalToGlobalMapping", 1433f1db9ecSBarry Smith cm,ISLocalToGlobalMappingDestroy,ISLocalToGlobalMappingView); 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 .seealso: ISLocalToGlobalMappingCreate() 17390f02eecSBarry Smith @*/ 17490f02eecSBarry Smith int ISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping mapping) 17590f02eecSBarry Smith { 176606d414cSSatish Balay int ierr; 1773a40ed3dSBarry Smith PetscFunctionBegin; 17890f02eecSBarry Smith PetscValidPointer(mapping); 1793a40ed3dSBarry Smith if (--mapping->refct > 0) PetscFunctionReturn(0); 18085614651SBarry Smith if (mapping->refct < 0) { 18129bbc08cSBarry Smith SETERRQ(1,"Mapping already destroyed"); 18285614651SBarry Smith } 18390f02eecSBarry Smith 184606d414cSSatish Balay ierr = PetscFree(mapping->indices);CHKERRQ(ierr); 185606d414cSSatish Balay if (mapping->globals) {ierr = PetscFree(mapping->globals);CHKERRQ(ierr);} 186d4bb536fSBarry Smith PLogObjectDestroy(mapping); 187d4bb536fSBarry Smith PetscHeaderDestroy(mapping); 1883a40ed3dSBarry Smith PetscFunctionReturn(0); 18990f02eecSBarry Smith } 19090f02eecSBarry Smith 1915615d1e5SSatish Balay #undef __FUNC__ 192b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"ISLocalToGlobalMappingApplyIS" 19390f02eecSBarry Smith /*@ 1943acfe500SLois Curfman McInnes ISLocalToGlobalMappingApplyIS - Creates from an IS in the local numbering 1953acfe500SLois Curfman McInnes a new index set using the global numbering defined in an ISLocalToGlobalMapping 1963acfe500SLois Curfman McInnes context. 19790f02eecSBarry Smith 198b9cd556bSLois Curfman McInnes Not collective 199b9cd556bSLois Curfman McInnes 20090f02eecSBarry Smith Input Parameters: 201b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 202b9cd556bSLois Curfman McInnes - is - index set in local numbering 20390f02eecSBarry Smith 20490f02eecSBarry Smith Output Parameters: 20590f02eecSBarry Smith . newis - index set in global numbering 20690f02eecSBarry Smith 207a997ad1aSLois Curfman McInnes Level: advanced 208a997ad1aSLois Curfman McInnes 209*273d9f13SBarry Smith Concepts: mapping^local to global 2103acfe500SLois Curfman McInnes 21190f02eecSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 212d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy(), ISGlobalToLocalMappingApply() 21390f02eecSBarry Smith @*/ 21490f02eecSBarry Smith int ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping mapping,IS is,IS *newis) 21590f02eecSBarry Smith { 2163b9aefa3SBarry Smith int ierr,n,i,*idxin,*idxmap,*idxout,Nmax = mapping->n; 2173a40ed3dSBarry Smith 2183a40ed3dSBarry Smith PetscFunctionBegin; 21990f02eecSBarry Smith PetscValidPointer(mapping); 22090f02eecSBarry Smith PetscValidHeaderSpecific(is,IS_COOKIE); 22190f02eecSBarry Smith PetscValidPointer(newis); 22290f02eecSBarry Smith 2233b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 22490f02eecSBarry Smith ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 22590f02eecSBarry Smith idxmap = mapping->indices; 22690f02eecSBarry Smith 22790f02eecSBarry Smith idxout = (int*)PetscMalloc((n+1)*sizeof(int));CHKPTRQ(idxout); 22890f02eecSBarry Smith for (i=0; i<n; i++) { 22929bbc08cSBarry Smith if (idxin[i] >= Nmax) SETERRQ3(PETSC_ERR_ARG_OUTOFRANGE,"Local index %d too large %d (max) at %d",idxin[i],Nmax,i); 23090f02eecSBarry Smith idxout[i] = idxmap[idxin[i]]; 23190f02eecSBarry Smith } 2323b9aefa3SBarry Smith ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 233029af93fSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxout,newis);CHKERRQ(ierr); 234606d414cSSatish Balay ierr = PetscFree(idxout);CHKERRQ(ierr); 2353a40ed3dSBarry Smith PetscFunctionReturn(0); 23690f02eecSBarry Smith } 23790f02eecSBarry Smith 23889d82c54SBarry Smith /*MC 2393acfe500SLois Curfman McInnes ISLocalToGlobalMappingApply - Takes a list of integers in a local numbering 2403acfe500SLois Curfman McInnes and converts them to the global numbering. 24190f02eecSBarry Smith 242b9cd556bSLois Curfman McInnes Not collective 243b9cd556bSLois Curfman McInnes 244bb25748dSBarry Smith Input Parameters: 245b9cd556bSLois Curfman McInnes + mapping - the local to global mapping context 246bb25748dSBarry Smith . N - number of integers 247b9cd556bSLois Curfman McInnes - in - input indices in local numbering 248bb25748dSBarry Smith 249bb25748dSBarry Smith Output Parameter: 250bb25748dSBarry Smith . out - indices in global numbering 251bb25748dSBarry Smith 2523b9aefa3SBarry Smith Synopsis: 2533b9aefa3SBarry Smith ISLocalToGlobalMappingApply(ISLocalToGlobalMapping mapping,int N,int in[],int out[]) 2543b9aefa3SBarry Smith 255b9cd556bSLois Curfman McInnes Notes: 256b9cd556bSLois Curfman McInnes The in and out array parameters may be identical. 257d4bb536fSBarry Smith 258a997ad1aSLois Curfman McInnes Level: advanced 259a997ad1aSLois Curfman McInnes 260bb25748dSBarry Smith .seealso: ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 2610752156aSBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 262d4bb536fSBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 263bb25748dSBarry Smith 264*273d9f13SBarry Smith Concepts: mapping^local to global 265d4bb536fSBarry Smith 26689d82c54SBarry Smith M*/ 267d4bb536fSBarry Smith 268d4bb536fSBarry Smith /* -----------------------------------------------------------------------------------------*/ 269d4bb536fSBarry Smith 270d4bb536fSBarry Smith #undef __FUNC__ 271b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"ISGlobalToLocalMappingSetUp_Private" 272d4bb536fSBarry Smith /* 273d4bb536fSBarry Smith Creates the global fields in the ISLocalToGlobalMapping structure 274d4bb536fSBarry Smith */ 275d4bb536fSBarry Smith static int ISGlobalToLocalMappingSetUp_Private(ISLocalToGlobalMapping mapping) 276d4bb536fSBarry Smith { 277d4bb536fSBarry Smith int i,*idx = mapping->indices,n = mapping->n,end,start,*globals; 278d4bb536fSBarry Smith 2793a40ed3dSBarry Smith PetscFunctionBegin; 280d4bb536fSBarry Smith end = 0; 281d4bb536fSBarry Smith start = 100000000; 282d4bb536fSBarry Smith 283d4bb536fSBarry Smith for (i=0; i<n; i++) { 284d4bb536fSBarry Smith if (idx[i] < 0) continue; 285d4bb536fSBarry Smith if (idx[i] < start) start = idx[i]; 286d4bb536fSBarry Smith if (idx[i] > end) end = idx[i]; 287d4bb536fSBarry Smith } 288d4bb536fSBarry Smith if (start > end) {start = 0; end = -1;} 289d4bb536fSBarry Smith mapping->globalstart = start; 290d4bb536fSBarry Smith mapping->globalend = end; 291d4bb536fSBarry Smith 292d4bb536fSBarry Smith globals = mapping->globals = (int*)PetscMalloc((end-start+2)*sizeof(int));CHKPTRQ(mapping->globals); 293d4bb536fSBarry Smith for (i=0; i<end-start+1; i++) { 294d4bb536fSBarry Smith globals[i] = -1; 295d4bb536fSBarry Smith } 296d4bb536fSBarry Smith for (i=0; i<n; i++) { 297d4bb536fSBarry Smith if (idx[i] < 0) continue; 298d4bb536fSBarry Smith globals[idx[i] - start] = i; 299d4bb536fSBarry Smith } 300d4bb536fSBarry Smith 301d4bb536fSBarry Smith PLogObjectMemory(mapping,(end-start+1)*sizeof(int)); 3023a40ed3dSBarry Smith PetscFunctionReturn(0); 303d4bb536fSBarry Smith } 304d4bb536fSBarry Smith 305d4bb536fSBarry Smith #undef __FUNC__ 306b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"ISGlobalToLocalMappingApply" 307d4bb536fSBarry Smith /*@ 308a997ad1aSLois Curfman McInnes ISGlobalToLocalMappingApply - Provides the local numbering for a list of integers 309a997ad1aSLois Curfman McInnes specified with a global numbering. 310d4bb536fSBarry Smith 311b9cd556bSLois Curfman McInnes Not collective 312b9cd556bSLois Curfman McInnes 313d4bb536fSBarry Smith Input Parameters: 314b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 315d4bb536fSBarry Smith . type - IS_GTOLM_MASK - replaces global indices with no local value with -1 316d4bb536fSBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 317d4bb536fSBarry Smith . n - number of global indices to map 318b9cd556bSLois Curfman McInnes - idx - global indices to map 319d4bb536fSBarry Smith 320d4bb536fSBarry Smith Output Parameters: 321b9cd556bSLois Curfman McInnes + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 322b9cd556bSLois Curfman McInnes - idxout - local index of each global index, one must pass in an array long enough 323e182c471SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApply() with 324e182c471SBarry Smith idxout == PETSC_NULL to determine the required length (returned in nout) 325e182c471SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApply() 326e182c471SBarry Smith a second time to set the values. 327d4bb536fSBarry Smith 328b9cd556bSLois Curfman McInnes Notes: 329b9cd556bSLois Curfman McInnes Either nout or idxout may be PETSC_NULL. idx and idxout may be identical. 330d4bb536fSBarry Smith 3310f5bd95cSBarry Smith This is not scalable in memory usage. Each processor requires O(Nglobal) size 3320f5bd95cSBarry Smith array to compute these. 3330f5bd95cSBarry Smith 334a997ad1aSLois Curfman McInnes Level: advanced 335a997ad1aSLois Curfman McInnes 336*273d9f13SBarry Smith Concepts: mapping^global to local 337d4bb536fSBarry Smith 338d4bb536fSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 339d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy() 340d4bb536fSBarry Smith @*/ 341d4bb536fSBarry Smith int ISGlobalToLocalMappingApply(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, 342987e4450SSatish Balay int n,const int idx[],int *nout,int idxout[]) 343d4bb536fSBarry Smith { 344d4bb536fSBarry Smith int i,ierr,*globals,nf = 0,tmp,start,end; 345d4bb536fSBarry Smith 3463a40ed3dSBarry Smith PetscFunctionBegin; 347d4bb536fSBarry Smith if (!mapping->globals) { 348d4bb536fSBarry Smith ierr = ISGlobalToLocalMappingSetUp_Private(mapping);CHKERRQ(ierr); 349d4bb536fSBarry Smith } 350d4bb536fSBarry Smith globals = mapping->globals; 351d4bb536fSBarry Smith start = mapping->globalstart; 352d4bb536fSBarry Smith end = mapping->globalend; 353d4bb536fSBarry Smith 354d4bb536fSBarry Smith if (type == IS_GTOLM_MASK) { 355d4bb536fSBarry Smith if (idxout) { 356d4bb536fSBarry Smith for (i=0; i<n; i++) { 357d4bb536fSBarry Smith if (idx[i] < 0) idxout[i] = idx[i]; 358d4bb536fSBarry Smith else if (idx[i] < start) idxout[i] = -1; 359d4bb536fSBarry Smith else if (idx[i] > end) idxout[i] = -1; 360d4bb536fSBarry Smith else idxout[i] = globals[idx[i] - start]; 361d4bb536fSBarry Smith } 362d4bb536fSBarry Smith } 363d4bb536fSBarry Smith if (nout) *nout = n; 364d4bb536fSBarry Smith } else { 365d4bb536fSBarry Smith if (idxout) { 366d4bb536fSBarry Smith for (i=0; i<n; i++) { 367d4bb536fSBarry Smith if (idx[i] < 0) continue; 368d4bb536fSBarry Smith if (idx[i] < start) continue; 369d4bb536fSBarry Smith if (idx[i] > end) continue; 370d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 371d4bb536fSBarry Smith if (tmp < 0) continue; 372d4bb536fSBarry Smith idxout[nf++] = tmp; 373d4bb536fSBarry Smith } 374d4bb536fSBarry Smith } else { 375d4bb536fSBarry Smith for (i=0; i<n; i++) { 376d4bb536fSBarry Smith if (idx[i] < 0) continue; 377d4bb536fSBarry Smith if (idx[i] < start) continue; 378d4bb536fSBarry Smith if (idx[i] > end) continue; 379d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 380d4bb536fSBarry Smith if (tmp < 0) continue; 381d4bb536fSBarry Smith nf++; 382d4bb536fSBarry Smith } 383d4bb536fSBarry Smith } 384d4bb536fSBarry Smith if (nout) *nout = nf; 385d4bb536fSBarry Smith } 386d4bb536fSBarry Smith 3873a40ed3dSBarry Smith PetscFunctionReturn(0); 388d4bb536fSBarry Smith } 38990f02eecSBarry Smith 39089d82c54SBarry Smith #undef __FUNC__ 39189d82c54SBarry Smith #define __FUNC__ /*<a name=""></a>*/"ISLocalToGlobalMappingGetInfo" 39289d82c54SBarry Smith /*@C 39389d82c54SBarry Smith ISLocalToGlobalMappingGetInfo - Gets the neighbor information for each processor and 39489d82c54SBarry Smith each index shared by more than one processor 39589d82c54SBarry Smith 39689d82c54SBarry Smith Collective on ISLocalToGlobalMapping 39789d82c54SBarry Smith 39889d82c54SBarry Smith Input Parameters: 39989d82c54SBarry Smith . mapping - the mapping from local to global indexing 40089d82c54SBarry Smith 40189d82c54SBarry Smith Output Parameter: 40289d82c54SBarry Smith + nproc - number of processors that are connected to this one 40389d82c54SBarry Smith . proc - neighboring processors 40407b52d57SBarry Smith . numproc - number of indices for each subdomain (processor) 40507b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 40689d82c54SBarry Smith 40789d82c54SBarry Smith Level: advanced 40889d82c54SBarry Smith 409*273d9f13SBarry Smith Concepts: mapping^local to global 41089d82c54SBarry Smith 41107b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 41207b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo() 41389d82c54SBarry Smith @*/ 41430dcb7c9SBarry Smith int ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping mapping,int *nproc,int **procs,int **numprocs,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; 41824cf384cSBarry Smith int tag1,tag2,tag3,cnt,*len,*source,imdex,scale,*ownedsenders,*nownedsenders,rstart,nowned; 41907b52d57SBarry Smith int node,nownedm,nt,*sends2,nsends2,*starts2,*lens2,*dest,nrecvs2,*starts3,*recvs2,k,*bprocs,*tmp; 42024cf384cSBarry Smith int first_procs,first_numprocs,*first_indices; 42189d82c54SBarry Smith MPI_Request *recv_waits,*send_waits; 42230dcb7c9SBarry Smith MPI_Status recv_status,*send_status,*recv_statuses; 42389d82c54SBarry Smith MPI_Comm comm = mapping->comm; 42407b52d57SBarry Smith PetscTruth debug = PETSC_FALSE; 42589d82c54SBarry Smith 42689d82c54SBarry Smith PetscFunctionBegin; 42724cf384cSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 42824cf384cSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 42924cf384cSBarry Smith if (size == 1) { 43024cf384cSBarry Smith *nproc = 0; 43124cf384cSBarry Smith *procs = PETSC_NULL; 4321e2105dcSBarry Smith *numprocs = (int*)PetscMalloc(sizeof(int));CHKPTRQ(*numprocs); 4331e2105dcSBarry Smith (*numprocs)[0] = 0; 4341e2105dcSBarry Smith *indices = (int**)PetscMalloc(sizeof(int*));CHKPTRQ(*indices); 4351e2105dcSBarry Smith (*indices)[0] = PETSC_NULL; 43624cf384cSBarry Smith PetscFunctionReturn(0); 43724cf384cSBarry Smith } 43824cf384cSBarry Smith 43907b52d57SBarry Smith ierr = OptionsHasName(PETSC_NULL,"-islocaltoglobalmappinggetinfo_debug",&debug);CHKERRQ(ierr); 44007b52d57SBarry Smith 4413677ff5aSBarry Smith /* 4423677ff5aSBarry Smith Notes on ISLocalToGlobalMappingGetInfo 4433677ff5aSBarry Smith 4443677ff5aSBarry Smith globally owned node - the nodes that have been assigned to this processor in global 4453677ff5aSBarry Smith numbering, just for this routine. 4463677ff5aSBarry Smith 4473677ff5aSBarry Smith nontrivial globally owned node - node assigned to this processor that is on a subdomain 4483677ff5aSBarry Smith boundary (i.e. is has more than one local owner) 4493677ff5aSBarry Smith 4503677ff5aSBarry Smith locally owned node - node that exists on this processors subdomain 4513677ff5aSBarry Smith 4523677ff5aSBarry Smith nontrivial locally owned node - node that is not in the interior (i.e. has more than one 4533677ff5aSBarry Smith local subdomain 4543677ff5aSBarry Smith */ 45524cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag1);CHKERRQ(ierr); 45624cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag2);CHKERRQ(ierr); 45724cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag3);CHKERRQ(ierr); 45889d82c54SBarry Smith 45989d82c54SBarry Smith for (i=0; i<n; i++) { 46089d82c54SBarry Smith if (lindices[i] > max) max = lindices[i]; 46189d82c54SBarry Smith } 46289d82c54SBarry Smith ierr = MPI_Allreduce(&max,&Ng,1,MPI_INT,MPI_MAX,comm);CHKERRQ(ierr); 46378058e43SBarry Smith Ng++; 46489d82c54SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 46589d82c54SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 466bc8ff85bSBarry Smith scale = Ng/size + 1; 467a2e34c3dSBarry Smith ng = scale; if (rank == size-1) ng = Ng - scale*(size-1); ng = PetscMax(1,ng); 468caba0dd0SBarry Smith rstart = scale*rank; 46989d82c54SBarry Smith 47089d82c54SBarry Smith /* determine ownership ranges of global indices */ 4713a96401aSBarry Smith nprocs = (int*)PetscMalloc((2*size+1)*sizeof(int));CHKPTRQ(nprocs); 4722880cf29SBarry Smith ierr = PetscMemzero(nprocs,2*size*sizeof(int));CHKERRQ(ierr); 47389d82c54SBarry Smith 47489d82c54SBarry Smith /* determine owners of each local node */ 47589d82c54SBarry Smith owner = (int*)PetscMalloc((n+1)*sizeof(int));CHKPTRQ(owner); 47689d82c54SBarry Smith for (i=0; i<n; i++) { 4773677ff5aSBarry Smith proc = lindices[i]/scale; /* processor that globally owns this index */ 4783677ff5aSBarry Smith nprocs[size+proc] = 1; /* processor globally owns at least one of ours */ 4793677ff5aSBarry Smith owner[i] = proc; 4803677ff5aSBarry Smith nprocs[proc]++; /* count of how many that processor globally owns of ours */ 48189d82c54SBarry Smith } 48289d82c54SBarry Smith nsends = 0; for (i=0; i<size; i++) nsends += nprocs[size + i]; 48389d82c54SBarry Smith PLogInfo(0,"ISLocalToGlobalMappingGetInfo: Number of global owners for my local data %d\n",nsends); 48489d82c54SBarry Smith 48589d82c54SBarry Smith /* inform other processors of number of messages and max length*/ 48689d82c54SBarry Smith work = (int*)PetscMalloc(2*size*sizeof(int));CHKPTRQ(work); 48789d82c54SBarry Smith ierr = MPI_Allreduce(nprocs,work,2*size,MPI_INT,PetscMaxSum_Op,comm);CHKERRQ(ierr); 48889d82c54SBarry Smith nmax = work[rank]; 48989d82c54SBarry Smith nrecvs = work[size+rank]; 49089d82c54SBarry Smith ierr = PetscFree(work);CHKERRQ(ierr); 49189d82c54SBarry Smith PLogInfo(0,"ISLocalToGlobalMappingGetInfo: Number of local owners for my global data %d\n",nrecvs); 49289d82c54SBarry Smith 49389d82c54SBarry Smith /* post receives for owned rows */ 49430dcb7c9SBarry Smith recvs = (int*)PetscMalloc((2*nrecvs+1)*(nmax+1)*sizeof(int));CHKPTRQ(recvs); 49589d82c54SBarry Smith recv_waits = (MPI_Request*)PetscMalloc((nrecvs+1)*sizeof(MPI_Request));CHKPTRQ(recv_waits); 49689d82c54SBarry Smith for (i=0; i<nrecvs; i++) { 49724cf384cSBarry Smith ierr = MPI_Irecv(recvs+2*nmax*i,2*nmax,MPI_INT,MPI_ANY_SOURCE,tag1,comm,recv_waits+i);CHKERRQ(ierr); 49889d82c54SBarry Smith } 49989d82c54SBarry Smith 50089d82c54SBarry Smith /* pack messages containing lists of local nodes to owners */ 50130dcb7c9SBarry Smith sends = (int*)PetscMalloc((2*n+1)*sizeof(int));CHKPTRQ(sends); 50289d82c54SBarry Smith starts = (int*)PetscMalloc((size+1)*sizeof(int));CHKPTRQ(starts); 50389d82c54SBarry Smith starts[0] = 0; 50430dcb7c9SBarry Smith for (i=1; i<size; i++) { starts[i] = starts[i-1] + 2*nprocs[i-1];} 50589d82c54SBarry Smith for (i=0; i<n; i++) { 50689d82c54SBarry Smith sends[starts[owner[i]]++] = lindices[i]; 50730dcb7c9SBarry Smith sends[starts[owner[i]]++] = i; 50889d82c54SBarry Smith } 50989d82c54SBarry Smith ierr = PetscFree(owner);CHKERRQ(ierr); 51089d82c54SBarry Smith starts[0] = 0; 51130dcb7c9SBarry Smith for (i=1; i<size; i++) { starts[i] = starts[i-1] + 2*nprocs[i-1];} 51289d82c54SBarry Smith 51389d82c54SBarry Smith /* send the messages */ 51489d82c54SBarry Smith send_waits = (MPI_Request*)PetscMalloc((nsends+1)*sizeof(MPI_Request));CHKPTRQ(send_waits); 51530dcb7c9SBarry Smith dest = (int*)PetscMalloc((nsends+1)*sizeof(int));CHKPTRQ(dest); 51689d82c54SBarry Smith cnt = 0; 51789d82c54SBarry Smith for (i=0; i<size; i++) { 51889d82c54SBarry Smith if (nprocs[i]) { 51924cf384cSBarry Smith ierr = MPI_Isend(sends+starts[i],2*nprocs[i],MPI_INT,i,tag1,comm,send_waits+cnt);CHKERRQ(ierr); 52030dcb7c9SBarry Smith dest[cnt] = i; 52189d82c54SBarry Smith cnt++; 52289d82c54SBarry Smith } 52389d82c54SBarry Smith } 52489d82c54SBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 52589d82c54SBarry Smith 52689d82c54SBarry Smith /* wait on receives */ 5273a96401aSBarry Smith source = (int*)PetscMalloc((2*nrecvs+1)*sizeof(int));CHKPTRQ(source); 52889d82c54SBarry Smith len = source + nrecvs; 52989d82c54SBarry Smith cnt = nrecvs; 530caba0dd0SBarry Smith nownedsenders = (int*)PetscMalloc((ng+1)*sizeof(int));CHKPTRQ(nownedsenders); 531caba0dd0SBarry Smith ierr = PetscMemzero(nownedsenders,ng*sizeof(int));CHKERRQ(ierr); 53289d82c54SBarry Smith while (cnt) { 53389d82c54SBarry Smith ierr = MPI_Waitany(nrecvs,recv_waits,&imdex,&recv_status);CHKERRQ(ierr); 53489d82c54SBarry Smith /* unpack receives into our local space */ 53589d82c54SBarry Smith ierr = MPI_Get_count(&recv_status,MPI_INT,&len[imdex]);CHKERRQ(ierr); 53689d82c54SBarry Smith source[imdex] = recv_status.MPI_SOURCE; 53730dcb7c9SBarry Smith len[imdex] = len[imdex]/2; 538caba0dd0SBarry Smith /* count how many local owners for each of my global owned indices */ 53930dcb7c9SBarry Smith for (i=0; i<len[imdex]; i++) nownedsenders[recvs[2*imdex*nmax+2*i]-rstart]++; 54089d82c54SBarry Smith cnt--; 54189d82c54SBarry Smith } 54289d82c54SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 54389d82c54SBarry Smith 54430dcb7c9SBarry Smith /* count how many globally owned indices are on an edge multiplied by how many processors own them. */ 545bc8ff85bSBarry Smith nowned = 0; 546bc8ff85bSBarry Smith nownedm = 0; 547bc8ff85bSBarry Smith for (i=0; i<ng; i++) { 548bc8ff85bSBarry Smith if (nownedsenders[i] > 1) {nownedm += nownedsenders[i]; nowned++;} 549bc8ff85bSBarry Smith } 550bc8ff85bSBarry Smith 551bc8ff85bSBarry Smith /* create single array to contain rank of all local owners of each globally owned index */ 552bc8ff85bSBarry Smith ownedsenders = (int*)PetscMalloc((nownedm+1)*sizeof(int));CHKERRQ(ierr); 55330dcb7c9SBarry Smith starts = (int*)PetscMalloc((ng+1)*sizeof(int));CHKPTRQ(starts); 554bc8ff85bSBarry Smith starts[0] = 0; 555bc8ff85bSBarry Smith for (i=1; i<ng; i++) { 556bc8ff85bSBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 557bc8ff85bSBarry Smith else starts[i] = starts[i-1]; 558bc8ff85bSBarry Smith } 559bc8ff85bSBarry Smith 56030dcb7c9SBarry Smith /* for each nontrival globally owned node list all arriving processors */ 561bc8ff85bSBarry Smith for (i=0; i<nrecvs; i++) { 562bc8ff85bSBarry Smith for (j=0; j<len[i]; j++) { 56330dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 564bc8ff85bSBarry Smith if (nownedsenders[node] > 1) { 565bc8ff85bSBarry Smith ownedsenders[starts[node]++] = source[i]; 566bc8ff85bSBarry Smith } 567bc8ff85bSBarry Smith } 568bc8ff85bSBarry Smith } 569bc8ff85bSBarry Smith 57007b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 57130dcb7c9SBarry Smith starts[0] = 0; 57230dcb7c9SBarry Smith for (i=1; i<ng; i++) { 57330dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 57430dcb7c9SBarry Smith else starts[i] = starts[i-1]; 57530dcb7c9SBarry Smith } 57630dcb7c9SBarry Smith for (i=0; i<ng; i++) { 57730dcb7c9SBarry Smith if (nownedsenders[i] > 1) { 57830dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] global node %d local owner processors: ",rank,i+rstart);CHKERRQ(ierr); 57930dcb7c9SBarry Smith for (j=0; j<nownedsenders[i]; j++) { 58030dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",ownedsenders[starts[i]+j]);CHKERRQ(ierr); 58130dcb7c9SBarry Smith } 58230dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 58330dcb7c9SBarry Smith } 58430dcb7c9SBarry Smith } 58530dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 58607b52d57SBarry Smith }/* ----------------------------------- */ 58730dcb7c9SBarry Smith 5883677ff5aSBarry Smith /* wait on original sends */ 5893a96401aSBarry Smith if (nsends) { 5903a96401aSBarry Smith send_status = (MPI_Status*)PetscMalloc(nsends*sizeof(MPI_Status));CHKPTRQ(send_status); 5913a96401aSBarry Smith ierr = MPI_Waitall(nsends,send_waits,send_status);CHKERRQ(ierr); 5923a96401aSBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 5933a96401aSBarry Smith } 59489d82c54SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 5953a96401aSBarry Smith ierr = PetscFree(sends);CHKERRQ(ierr); 5963677ff5aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 5973677ff5aSBarry Smith 5983677ff5aSBarry Smith /* pack messages to send back to local owners */ 59930dcb7c9SBarry Smith starts[0] = 0; 60030dcb7c9SBarry Smith for (i=1; i<ng; i++) { 60130dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 60230dcb7c9SBarry Smith else starts[i] = starts[i-1]; 60330dcb7c9SBarry Smith } 60430dcb7c9SBarry Smith nsends2 = nrecvs; 60530dcb7c9SBarry Smith nprocs = (int*)PetscMalloc((nsends2+1)*sizeof(int));CHKPTRQ(nprocs); /* length of each message */ 60630dcb7c9SBarry Smith cnt = 0; 60730dcb7c9SBarry Smith for (i=0; i<nrecvs; i++) { 60830dcb7c9SBarry Smith nprocs[i] = 1; 60930dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 61030dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 61130dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 61230dcb7c9SBarry Smith nprocs[i] += 2 + nownedsenders[node]; 61330dcb7c9SBarry Smith } 61430dcb7c9SBarry Smith } 61530dcb7c9SBarry Smith } 61630dcb7c9SBarry Smith nt = 0; for (i=0; i<nsends2; i++) nt += nprocs[i]; 61730dcb7c9SBarry Smith sends2 = (int*)PetscMalloc((nt+1)*sizeof(int));CHKPTRQ(sends2); 61830dcb7c9SBarry Smith starts2 = (int*)PetscMalloc((nsends2+1)*sizeof(int));CHKPTRQ(starts2); 61930dcb7c9SBarry Smith starts2[0] = 0; for (i=1; i<nsends2; i++) starts2[i] = starts2[i-1] + nprocs[i-1]; 62030dcb7c9SBarry Smith /* 62130dcb7c9SBarry Smith Each message is 1 + nprocs[i] long, and consists of 62230dcb7c9SBarry Smith (0) the number of nodes being sent back 62330dcb7c9SBarry Smith (1) the local node number, 62430dcb7c9SBarry Smith (2) the number of processors sharing it, 62530dcb7c9SBarry Smith (3) the processors sharing it 62630dcb7c9SBarry Smith */ 62730dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 62830dcb7c9SBarry Smith cnt = 1; 62930dcb7c9SBarry Smith sends2[starts2[i]] = 0; 63030dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 63130dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 63230dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 63330dcb7c9SBarry Smith sends2[starts2[i]]++; 63430dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = recvs[2*i*nmax+2*j+1]; 63530dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = nownedsenders[node]; 63630dcb7c9SBarry Smith ierr = PetscMemcpy(&sends2[starts2[i]+cnt],&ownedsenders[starts[node]],nownedsenders[node]*sizeof(int));CHKERRQ(ierr); 63730dcb7c9SBarry Smith cnt += nownedsenders[node]; 63830dcb7c9SBarry Smith } 63930dcb7c9SBarry Smith } 64030dcb7c9SBarry Smith } 64130dcb7c9SBarry Smith 64230dcb7c9SBarry Smith /* send the message lengths */ 64330dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 64424cf384cSBarry Smith ierr = MPI_Send(&nprocs[i],1,MPI_INT,source[i],tag2,comm);CHKERRQ(ierr); 64530dcb7c9SBarry Smith } 64630dcb7c9SBarry Smith 64730dcb7c9SBarry Smith /* receive the message lengths */ 64830dcb7c9SBarry Smith nrecvs2 = nsends; 64930dcb7c9SBarry Smith lens2 = (int*)PetscMalloc((nrecvs2+1)*sizeof(int));CHKPTRQ(lens2); 65030dcb7c9SBarry Smith starts3 = (int*)PetscMalloc((nrecvs2+1)*sizeof(int));CHKPTRQ(starts3); 65130dcb7c9SBarry Smith nt = 0; 65230dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 65324cf384cSBarry Smith ierr = MPI_Recv(&lens2[i],1,MPI_INT,dest[i],tag2,comm,&recv_status);CHKERRQ(ierr); 65430dcb7c9SBarry Smith nt += lens2[i]; 65530dcb7c9SBarry Smith } 65630dcb7c9SBarry Smith starts3[0] = 0; 65730dcb7c9SBarry Smith for (i=0; i<nrecvs2-1; i++) { 65830dcb7c9SBarry Smith starts3[i+1] = starts3[i] + lens2[i]; 65930dcb7c9SBarry Smith } 66030dcb7c9SBarry Smith recvs2 = (int*)PetscMalloc((nt+1)*sizeof(int));CHKPTRQ(recvs2); 66152b72c4aSBarry Smith recv_waits = (MPI_Request*)PetscMalloc((nrecvs2+1)*sizeof(MPI_Request));CHKPTRQ(recv_waits); 66252b72c4aSBarry Smith for (i=0; i<nrecvs2; i++) { 66324cf384cSBarry Smith ierr = MPI_Irecv(recvs2+starts3[i],lens2[i],MPI_INT,dest[i],tag3,comm,recv_waits+i);CHKERRQ(ierr); 66430dcb7c9SBarry Smith } 66530dcb7c9SBarry Smith 66630dcb7c9SBarry Smith /* send the messages */ 66730dcb7c9SBarry Smith send_waits = (MPI_Request*)PetscMalloc((nsends2+1)*sizeof(MPI_Request));CHKPTRQ(send_waits); 66830dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 66924cf384cSBarry Smith ierr = MPI_Isend(sends2+starts2[i],nprocs[i],MPI_INT,source[i],tag3,comm,send_waits+i);CHKERRQ(ierr); 67030dcb7c9SBarry Smith } 67130dcb7c9SBarry Smith 67230dcb7c9SBarry Smith /* wait on receives */ 67352b72c4aSBarry Smith recv_statuses = (MPI_Status*)PetscMalloc((nrecvs2+1)*sizeof(MPI_Status));CHKPTRQ(recv_statuses); 67430dcb7c9SBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 67530dcb7c9SBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 67630dcb7c9SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 67730dcb7c9SBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 67830dcb7c9SBarry Smith 67907b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 68030dcb7c9SBarry Smith cnt = 0; 68130dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 68230dcb7c9SBarry Smith nt = recvs2[cnt++]; 68330dcb7c9SBarry Smith for (j=0; j<nt; j++) { 68430dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] local node %d number of subdomains %d: ",rank,recvs2[cnt],recvs2[cnt+1]);CHKERRQ(ierr); 68530dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 68630dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",recvs2[cnt+2+k]);CHKERRQ(ierr); 68730dcb7c9SBarry Smith } 68830dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 68930dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 69030dcb7c9SBarry Smith } 69130dcb7c9SBarry Smith } 69230dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 69307b52d57SBarry Smith } /* ----------------------------------- */ 69430dcb7c9SBarry Smith 69530dcb7c9SBarry Smith /* count number subdomains for each local node */ 69630dcb7c9SBarry Smith nprocs = (int*)PetscMalloc(size*sizeof(int));CHKPTRQ(nprocs); 69730dcb7c9SBarry Smith ierr = PetscMemzero(nprocs,size*sizeof(int));CHKERRQ(ierr); 69830dcb7c9SBarry Smith cnt = 0; 69930dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 70030dcb7c9SBarry Smith nt = recvs2[cnt++]; 70130dcb7c9SBarry Smith for (j=0; j<nt; j++) { 70230dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 70330dcb7c9SBarry Smith nprocs[recvs2[cnt+2+k]]++; 70430dcb7c9SBarry Smith } 70530dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 70630dcb7c9SBarry Smith } 70730dcb7c9SBarry Smith } 70830dcb7c9SBarry Smith nt = 0; for (i=0; i<size; i++) nt += (nprocs[i] > 0); 70930dcb7c9SBarry Smith *nproc = nt; 71030dcb7c9SBarry Smith *procs = (int*)PetscMalloc((nt+1)*sizeof(int));CHKPTRQ(procs); 71130dcb7c9SBarry Smith *numprocs = (int*)PetscMalloc((nt+1)*sizeof(int));CHKPTRQ(numprocs); 71230dcb7c9SBarry Smith *indices = (int**)PetscMalloc((nt+1)*sizeof(int*));CHKPTRQ(procs); 71330dcb7c9SBarry Smith bprocs = (int*)PetscMalloc(size*sizeof(int));CHKERRQ(ierr); 71430dcb7c9SBarry Smith cnt = 0; 71530dcb7c9SBarry Smith for (i=0; i<size; i++) { 71630dcb7c9SBarry Smith if (nprocs[i] > 0) { 71730dcb7c9SBarry Smith bprocs[i] = cnt; 71830dcb7c9SBarry Smith (*procs)[cnt] = i; 71930dcb7c9SBarry Smith (*numprocs)[cnt] = nprocs[i]; 72030dcb7c9SBarry Smith (*indices)[cnt] = (int*)PetscMalloc(nprocs[i]*sizeof(int));CHKPTRQ((*indices)[cnt]); 72130dcb7c9SBarry Smith cnt++; 72230dcb7c9SBarry Smith } 72330dcb7c9SBarry Smith } 72430dcb7c9SBarry Smith 72530dcb7c9SBarry Smith /* make the list of subdomains for each nontrivial local node */ 72630dcb7c9SBarry Smith ierr = PetscMemzero(*numprocs,nt*sizeof(int));CHKERRQ(ierr); 72730dcb7c9SBarry Smith cnt = 0; 72830dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 72930dcb7c9SBarry Smith nt = recvs2[cnt++]; 73030dcb7c9SBarry Smith for (j=0; j<nt; j++) { 73130dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 73230dcb7c9SBarry Smith (*indices)[bprocs[recvs2[cnt+2+k]]][(*numprocs)[bprocs[recvs2[cnt+2+k]]]++] = recvs2[cnt]; 73330dcb7c9SBarry Smith } 73430dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 73530dcb7c9SBarry Smith } 73630dcb7c9SBarry Smith } 73730dcb7c9SBarry Smith ierr = PetscFree(bprocs);CHKERRQ(ierr); 73807b52d57SBarry Smith ierr = PetscFree(recvs2);CHKERRQ(ierr); 73930dcb7c9SBarry Smith 74007b52d57SBarry Smith /* sort the node indexing by their global numbers */ 74107b52d57SBarry Smith nt = *nproc; 74207b52d57SBarry Smith for (i=0; i<nt; i++) { 74307b52d57SBarry Smith tmp = (int*)PetscMalloc(((*numprocs)[i])*sizeof(int));CHKPTRQ(tmp); 74407b52d57SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 74507b52d57SBarry Smith tmp[j] = lindices[(*indices)[i][j]]; 74607b52d57SBarry Smith } 74707b52d57SBarry Smith ierr = PetscSortIntWithArray((*numprocs)[i],tmp,(*indices)[i]);CHKERRQ(ierr); 74807b52d57SBarry Smith ierr = PetscFree(tmp);CHKERRQ(ierr); 74907b52d57SBarry Smith } 75007b52d57SBarry Smith 75107b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 75230dcb7c9SBarry Smith nt = *nproc; 75330dcb7c9SBarry Smith for (i=0; i<nt; i++) { 75430dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] subdomain %d number of indices %d: ",rank,(*procs)[i],(*numprocs)[i]);CHKERRQ(ierr); 75530dcb7c9SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 75630dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",(*indices)[i][j]);CHKERRQ(ierr); 75730dcb7c9SBarry Smith } 75830dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 75930dcb7c9SBarry Smith } 76030dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 76107b52d57SBarry Smith } /* ----------------------------------- */ 76230dcb7c9SBarry Smith 76330dcb7c9SBarry Smith /* wait on sends */ 76430dcb7c9SBarry Smith if (nsends2) { 76530dcb7c9SBarry Smith send_status = (MPI_Status*)PetscMalloc(nsends2*sizeof(MPI_Status));CHKPTRQ(send_status); 76630dcb7c9SBarry Smith ierr = MPI_Waitall(nsends2,send_waits,send_status);CHKERRQ(ierr); 76730dcb7c9SBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 76830dcb7c9SBarry Smith } 76930dcb7c9SBarry Smith 77030dcb7c9SBarry Smith ierr = PetscFree(starts3);CHKERRQ(ierr); 77130dcb7c9SBarry Smith ierr = PetscFree(dest);CHKERRQ(ierr); 77230dcb7c9SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 7733677ff5aSBarry Smith 774bc8ff85bSBarry Smith ierr = PetscFree(nownedsenders);CHKERRQ(ierr); 775bc8ff85bSBarry Smith ierr = PetscFree(ownedsenders);CHKERRQ(ierr); 776bc8ff85bSBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 77730dcb7c9SBarry Smith ierr = PetscFree(starts2);CHKERRQ(ierr); 77830dcb7c9SBarry Smith ierr = PetscFree(lens2);CHKERRQ(ierr); 77989d82c54SBarry Smith 78089d82c54SBarry Smith ierr = PetscFree(source);CHKERRQ(ierr); 78189d82c54SBarry Smith ierr = PetscFree(recvs);CHKERRQ(ierr); 7823a96401aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 78330dcb7c9SBarry Smith ierr = PetscFree(sends2);CHKERRQ(ierr); 78424cf384cSBarry Smith 78524cf384cSBarry Smith /* put the information about myself as the first entry in the list */ 78624cf384cSBarry Smith first_procs = (*procs)[0]; 78724cf384cSBarry Smith first_numprocs = (*numprocs)[0]; 78824cf384cSBarry Smith first_indices = (*indices)[0]; 78924cf384cSBarry Smith for (i=0; i<*nproc; i++) { 79024cf384cSBarry Smith if ((*procs)[i] == rank) { 79124cf384cSBarry Smith (*procs)[0] = (*procs)[i]; 79224cf384cSBarry Smith (*numprocs)[0] = (*numprocs)[i]; 79324cf384cSBarry Smith (*indices)[0] = (*indices)[i]; 79424cf384cSBarry Smith (*procs)[i] = first_procs; 79524cf384cSBarry Smith (*numprocs)[i] = first_numprocs; 79624cf384cSBarry Smith (*indices)[i] = first_indices; 79724cf384cSBarry Smith break; 79824cf384cSBarry Smith } 79924cf384cSBarry Smith } 80024cf384cSBarry Smith 80189d82c54SBarry Smith PetscFunctionReturn(0); 80289d82c54SBarry Smith } 80389d82c54SBarry Smith 80407b52d57SBarry Smith #undef __FUNC__ 80507b52d57SBarry Smith #define __FUNC__ /*<a name=""></a>*/"ISLocalToGlobalMappingRestoreInfo" 80607b52d57SBarry Smith /*@C 80707b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo - Frees the memory allocated by ISLocalToGlobalMappingGetInfo() 80889d82c54SBarry Smith 80907b52d57SBarry Smith Collective on ISLocalToGlobalMapping 81007b52d57SBarry Smith 81107b52d57SBarry Smith Input Parameters: 81207b52d57SBarry Smith . mapping - the mapping from local to global indexing 81307b52d57SBarry Smith 81407b52d57SBarry Smith Output Parameter: 81507b52d57SBarry Smith + nproc - number of processors that are connected to this one 81607b52d57SBarry Smith . proc - neighboring processors 81707b52d57SBarry Smith . numproc - number of indices for each processor 81807b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 81907b52d57SBarry Smith 82007b52d57SBarry Smith Level: advanced 82107b52d57SBarry Smith 82207b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 82307b52d57SBarry Smith ISLocalToGlobalMappingGetInfo() 82407b52d57SBarry Smith @*/ 82507b52d57SBarry Smith int ISLocalToGlobalMappingRestoreInfo(ISLocalToGlobalMapping mapping,int *nproc,int **procs,int **numprocs,int ***indices) 82607b52d57SBarry Smith { 82707b52d57SBarry Smith int ierr,i; 82807b52d57SBarry Smith 82907b52d57SBarry Smith PetscFunctionBegin; 83000ff320aSBarry Smith if (*procs) {ierr = PetscFree(*procs);CHKERRQ(ierr);} 83100ff320aSBarry Smith if (*numprocs) {ierr = PetscFree(*numprocs);CHKERRQ(ierr);} 83200ff320aSBarry Smith if (*indices) { 83300ff320aSBarry Smith if ((*indices)[0]) {ierr = PetscFree((*indices)[0]);CHKERRQ(ierr);} 83400ff320aSBarry Smith for (i=1; i<*nproc; i++) { 83524cf384cSBarry Smith if ((*indices)[i]) {ierr = PetscFree((*indices)[i]);CHKERRQ(ierr);} 83607b52d57SBarry Smith } 83707b52d57SBarry Smith ierr = PetscFree(*indices);CHKERRQ(ierr); 83824cf384cSBarry Smith } 83907b52d57SBarry Smith PetscFunctionReturn(0); 84007b52d57SBarry Smith } 84189d82c54SBarry Smith 842bc8ff85bSBarry Smith 843bc8ff85bSBarry Smith 844bc8ff85bSBarry Smith 845bc8ff85bSBarry Smith 846bc8ff85bSBarry Smith 847bc8ff85bSBarry Smith 848bc8ff85bSBarry Smith 849bc8ff85bSBarry Smith 850bc8ff85bSBarry Smith 851bc8ff85bSBarry Smith 852bc8ff85bSBarry Smith 853bc8ff85bSBarry Smith 854bc8ff85bSBarry Smith 855bc8ff85bSBarry Smith 856bc8ff85bSBarry Smith 857bc8ff85bSBarry Smith 85824cf384cSBarry Smith 859