1*216e7ba4SBarry Smith /*$Id: isltog.c,v 1.64 2001/03/23 23:21:16 balay 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 64a2ae208SSatish Balay #undef __FUNCT__ 74a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingGetSize" 83b9aefa3SBarry Smith /*@C 93b9aefa3SBarry Smith ISLocalToGlobalMappingGetSize - Gets the local size of a local to global mapping. 103b9aefa3SBarry Smith 113b9aefa3SBarry Smith Not Collective 123b9aefa3SBarry Smith 133b9aefa3SBarry Smith Input Parameter: 143b9aefa3SBarry Smith . ltog - local to global mapping 153b9aefa3SBarry Smith 163b9aefa3SBarry Smith Output Parameter: 173b9aefa3SBarry Smith . n - the number of entries in the local mapping 183b9aefa3SBarry Smith 193b9aefa3SBarry Smith Level: advanced 203b9aefa3SBarry Smith 21273d9f13SBarry Smith Concepts: mapping^local to global 223b9aefa3SBarry Smith 233b9aefa3SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 243b9aefa3SBarry Smith @*/ 253b9aefa3SBarry Smith int ISLocalToGlobalMappingGetSize(ISLocalToGlobalMapping mapping,int *n) 263b9aefa3SBarry Smith { 273b9aefa3SBarry Smith PetscFunctionBegin; 283b9aefa3SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE); 293b9aefa3SBarry Smith *n = mapping->n; 303b9aefa3SBarry Smith PetscFunctionReturn(0); 313b9aefa3SBarry Smith } 323b9aefa3SBarry Smith 334a2ae208SSatish Balay #undef __FUNCT__ 344a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingView" 355a5d4f66SBarry Smith /*@C 365a5d4f66SBarry Smith ISLocalToGlobalMappingView - View a local to global mapping 375a5d4f66SBarry Smith 38b9cd556bSLois Curfman McInnes Not Collective 39b9cd556bSLois Curfman McInnes 405a5d4f66SBarry Smith Input Parameters: 413b9aefa3SBarry Smith + ltog - local to global mapping 423b9aefa3SBarry Smith - viewer - viewer 435a5d4f66SBarry Smith 44a997ad1aSLois Curfman McInnes Level: advanced 45a997ad1aSLois Curfman McInnes 46273d9f13SBarry Smith Concepts: mapping^local to global 475a5d4f66SBarry Smith 485a5d4f66SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 495a5d4f66SBarry Smith @*/ 50b0a32e0cSBarry Smith int ISLocalToGlobalMappingView(ISLocalToGlobalMapping mapping,PetscViewer viewer) 515a5d4f66SBarry Smith { 52f1af5d2fSBarry Smith int i,ierr,rank; 536831982aSBarry Smith PetscTruth isascii; 545a5d4f66SBarry Smith 555a5d4f66SBarry Smith PetscFunctionBegin; 566831982aSBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE); 57b0a32e0cSBarry Smith if (!viewer) viewer = PETSC_VIEWER_STDOUT_(mapping->comm); 58b0a32e0cSBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE); 595a5d4f66SBarry Smith 60f1af5d2fSBarry Smith ierr = MPI_Comm_rank(mapping->comm,&rank);CHKERRQ(ierr); 61b0a32e0cSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr); 626831982aSBarry Smith if (isascii) { 635a5d4f66SBarry Smith for (i=0; i<mapping->n; i++) { 64b0a32e0cSBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d] %d %d\n",rank,i,mapping->indices[i]);CHKERRQ(ierr); 656831982aSBarry Smith } 66b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 676831982aSBarry Smith } else { 6829bbc08cSBarry Smith SETERRQ1(1,"Viewer type %s not supported for ISLocalToGlobalMapping",((PetscObject)viewer)->type_name); 695a5d4f66SBarry Smith } 705a5d4f66SBarry Smith 715a5d4f66SBarry Smith PetscFunctionReturn(0); 725a5d4f66SBarry Smith } 735a5d4f66SBarry Smith 744a2ae208SSatish Balay #undef __FUNCT__ 754a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreateIS" 762bdab257SBarry Smith /*@C 772bdab257SBarry Smith ISLocalToGlobalMappingCreateIS - Creates a mapping between a local (0 to n) 782bdab257SBarry Smith ordering and a global parallel ordering. 792bdab257SBarry Smith 800f5bd95cSBarry Smith Not collective 81b9cd556bSLois Curfman McInnes 82a997ad1aSLois Curfman McInnes Input Parameter: 832bdab257SBarry Smith . is - index set containing the global numbers for each local 842bdab257SBarry Smith 85a997ad1aSLois Curfman McInnes Output Parameter: 862bdab257SBarry Smith . mapping - new mapping data structure 872bdab257SBarry Smith 88a997ad1aSLois Curfman McInnes Level: advanced 89a997ad1aSLois Curfman McInnes 90273d9f13SBarry Smith Concepts: mapping^local to global 912bdab257SBarry Smith 922bdab257SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 932bdab257SBarry Smith @*/ 942bdab257SBarry Smith int ISLocalToGlobalMappingCreateIS(IS is,ISLocalToGlobalMapping *mapping) 952bdab257SBarry Smith { 962bdab257SBarry Smith int n,*indices,ierr; 972bdab257SBarry Smith MPI_Comm comm; 983a40ed3dSBarry Smith 993a40ed3dSBarry Smith PetscFunctionBegin; 1002bdab257SBarry Smith PetscValidHeaderSpecific(is,IS_COOKIE); 1012bdab257SBarry Smith 1022bdab257SBarry Smith ierr = PetscObjectGetComm((PetscObject)is,&comm);CHKERRQ(ierr); 1033b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 1042bdab257SBarry Smith ierr = ISGetIndices(is,&indices);CHKERRQ(ierr); 1052bdab257SBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,n,indices,mapping);CHKERRQ(ierr); 1062bdab257SBarry Smith ierr = ISRestoreIndices(is,&indices);CHKERRQ(ierr); 1072bdab257SBarry Smith 1083a40ed3dSBarry Smith PetscFunctionReturn(0); 1092bdab257SBarry Smith } 1105a5d4f66SBarry Smith 1114a2ae208SSatish Balay #undef __FUNCT__ 1124a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreate" 113dd7157adSSatish Balay /*@C 11490f02eecSBarry Smith ISLocalToGlobalMappingCreate - Creates a mapping between a local (0 to n) 11590f02eecSBarry Smith ordering and a global parallel ordering. 1162362add9SBarry Smith 11789d82c54SBarry Smith Not Collective, but communicator may have more than one process 118b9cd556bSLois Curfman McInnes 1192362add9SBarry Smith Input Parameters: 12089d82c54SBarry Smith + comm - MPI communicator 12190f02eecSBarry Smith . n - the number of local elements 122b9cd556bSLois Curfman McInnes - indices - the global index for each local element 1232362add9SBarry Smith 124a997ad1aSLois Curfman McInnes Output Parameter: 12590f02eecSBarry Smith . mapping - new mapping data structure 1262362add9SBarry Smith 127a997ad1aSLois Curfman McInnes Level: advanced 128a997ad1aSLois Curfman McInnes 129273d9f13SBarry Smith Concepts: mapping^local to global 1302362add9SBarry Smith 1312bdab257SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS() 1322362add9SBarry Smith @*/ 133987e4450SSatish Balay int ISLocalToGlobalMappingCreate(MPI_Comm cm,int n,const int indices[],ISLocalToGlobalMapping *mapping) 1342362add9SBarry Smith { 135549d3d68SSatish Balay int ierr; 136549d3d68SSatish Balay 1373a40ed3dSBarry Smith PetscFunctionBegin; 13890f02eecSBarry Smith PetscValidIntPointer(indices); 13990f02eecSBarry Smith PetscValidPointer(mapping); 1402362add9SBarry Smith 1413f1db9ecSBarry Smith PetscHeaderCreate(*mapping,_p_ISLocalToGlobalMapping,int,IS_LTOGM_COOKIE,0,"ISLocalToGlobalMapping", 1423f1db9ecSBarry Smith cm,ISLocalToGlobalMappingDestroy,ISLocalToGlobalMappingView); 143b0a32e0cSBarry Smith PetscLogObjectCreate(*mapping); 144b0a32e0cSBarry Smith PetscLogObjectMemory(*mapping,sizeof(struct _p_ISLocalToGlobalMapping)+n*sizeof(int)); 145d4bb536fSBarry Smith 146d4bb536fSBarry Smith (*mapping)->n = n; 147b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(int),&(*mapping)->indices);CHKERRQ(ierr); 148549d3d68SSatish Balay ierr = PetscMemcpy((*mapping)->indices,indices,n*sizeof(int));CHKERRQ(ierr); 149d4bb536fSBarry Smith 150d4bb536fSBarry Smith /* 151d4bb536fSBarry Smith Do not create the global to local mapping. This is only created if 152d4bb536fSBarry Smith ISGlobalToLocalMapping() is called 153d4bb536fSBarry Smith */ 154d4bb536fSBarry Smith (*mapping)->globals = 0; 1553a40ed3dSBarry Smith PetscFunctionReturn(0); 1562362add9SBarry Smith } 1572362add9SBarry Smith 1584a2ae208SSatish Balay #undef __FUNCT__ 1594a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingBlock" 160323b833fSBarry Smith /*@C 161323b833fSBarry Smith ISLocalToGlobalMappingBlock - Creates a blocked index version of an 162323b833fSBarry Smith ISLocalToGlobalMapping that is appropriate for MatSetLocalToGlobalMappingBlock() 163323b833fSBarry Smith and VecSetLocalToGlobalMappingBlock(). 164323b833fSBarry Smith 165323b833fSBarry Smith Not Collective, but communicator may have more than one process 166323b833fSBarry Smith 167323b833fSBarry Smith Input Parameters: 168323b833fSBarry Smith + inmap - original point-wise mapping 169323b833fSBarry Smith - bs - block size 170323b833fSBarry Smith 171323b833fSBarry Smith Output Parameter: 172323b833fSBarry Smith . outmap - block based mapping 173323b833fSBarry Smith 174323b833fSBarry Smith Level: advanced 175323b833fSBarry Smith 176323b833fSBarry Smith Concepts: mapping^local to global 177323b833fSBarry Smith 178323b833fSBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingCreateIS() 179323b833fSBarry Smith @*/ 180323b833fSBarry Smith int ISLocalToGlobalMappingBlock(ISLocalToGlobalMapping inmap,int bs,ISLocalToGlobalMapping *outmap) 181323b833fSBarry Smith { 182323b833fSBarry Smith int ierr,*ii,i,n; 183323b833fSBarry Smith 184323b833fSBarry Smith PetscFunctionBegin; 185323b833fSBarry Smith 186323b833fSBarry Smith if (bs > 1) { 187323b833fSBarry Smith n = inmap->n/bs; 188323b833fSBarry Smith ierr = PetscMalloc(n*sizeof(int),&ii);CHKERRQ(ierr); 189323b833fSBarry Smith for (i=0; i<n; i++) { 190b8ee7809SBarry Smith ii[i] = inmap->indices[bs*i]/bs; 191323b833fSBarry Smith } 192323b833fSBarry Smith ierr = ISLocalToGlobalMappingCreate(inmap->comm,n,ii,outmap);CHKERRQ(ierr); 193323b833fSBarry Smith ierr = PetscFree(ii);CHKERRQ(ierr); 194323b833fSBarry Smith } else { 195323b833fSBarry Smith *outmap = inmap; 196323b833fSBarry Smith ierr = PetscObjectReference((PetscObject)inmap);CHKERRQ(ierr); 197323b833fSBarry Smith } 198323b833fSBarry Smith PetscFunctionReturn(0); 199323b833fSBarry Smith } 200323b833fSBarry Smith 2014a2ae208SSatish Balay #undef __FUNCT__ 2024a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingDestroy" 20390f02eecSBarry Smith /*@ 20490f02eecSBarry Smith ISLocalToGlobalMappingDestroy - Destroys a mapping between a local (0 to n) 20590f02eecSBarry Smith ordering and a global parallel ordering. 20690f02eecSBarry Smith 2070f5bd95cSBarry Smith Note Collective 208b9cd556bSLois Curfman McInnes 20990f02eecSBarry Smith Input Parameters: 21090f02eecSBarry Smith . mapping - mapping data structure 21190f02eecSBarry Smith 212a997ad1aSLois Curfman McInnes Level: advanced 213a997ad1aSLois Curfman McInnes 2143acfe500SLois Curfman McInnes .seealso: ISLocalToGlobalMappingCreate() 21590f02eecSBarry Smith @*/ 21690f02eecSBarry Smith int ISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping mapping) 21790f02eecSBarry Smith { 218606d414cSSatish Balay int ierr; 2193a40ed3dSBarry Smith PetscFunctionBegin; 22090f02eecSBarry Smith PetscValidPointer(mapping); 2213a40ed3dSBarry Smith if (--mapping->refct > 0) PetscFunctionReturn(0); 22285614651SBarry Smith if (mapping->refct < 0) { 22329bbc08cSBarry Smith SETERRQ(1,"Mapping already destroyed"); 22485614651SBarry Smith } 22590f02eecSBarry Smith 226606d414cSSatish Balay ierr = PetscFree(mapping->indices);CHKERRQ(ierr); 227606d414cSSatish Balay if (mapping->globals) {ierr = PetscFree(mapping->globals);CHKERRQ(ierr);} 228b0a32e0cSBarry Smith PetscLogObjectDestroy(mapping); 229d4bb536fSBarry Smith PetscHeaderDestroy(mapping); 2303a40ed3dSBarry Smith PetscFunctionReturn(0); 23190f02eecSBarry Smith } 23290f02eecSBarry Smith 2334a2ae208SSatish Balay #undef __FUNCT__ 2344a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingApplyIS" 23590f02eecSBarry Smith /*@ 2363acfe500SLois Curfman McInnes ISLocalToGlobalMappingApplyIS - Creates from an IS in the local numbering 2373acfe500SLois Curfman McInnes a new index set using the global numbering defined in an ISLocalToGlobalMapping 2383acfe500SLois Curfman McInnes context. 23990f02eecSBarry Smith 240b9cd556bSLois Curfman McInnes Not collective 241b9cd556bSLois Curfman McInnes 24290f02eecSBarry Smith Input Parameters: 243b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 244b9cd556bSLois Curfman McInnes - is - index set in local numbering 24590f02eecSBarry Smith 24690f02eecSBarry Smith Output Parameters: 24790f02eecSBarry Smith . newis - index set in global numbering 24890f02eecSBarry Smith 249a997ad1aSLois Curfman McInnes Level: advanced 250a997ad1aSLois Curfman McInnes 251273d9f13SBarry Smith Concepts: mapping^local to global 2523acfe500SLois Curfman McInnes 25390f02eecSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 254d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy(), ISGlobalToLocalMappingApply() 25590f02eecSBarry Smith @*/ 25690f02eecSBarry Smith int ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping mapping,IS is,IS *newis) 25790f02eecSBarry Smith { 2583b9aefa3SBarry Smith int ierr,n,i,*idxin,*idxmap,*idxout,Nmax = mapping->n; 2593a40ed3dSBarry Smith 2603a40ed3dSBarry Smith PetscFunctionBegin; 26190f02eecSBarry Smith PetscValidPointer(mapping); 26290f02eecSBarry Smith PetscValidHeaderSpecific(is,IS_COOKIE); 26390f02eecSBarry Smith PetscValidPointer(newis); 26490f02eecSBarry Smith 2653b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 26690f02eecSBarry Smith ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 26790f02eecSBarry Smith idxmap = mapping->indices; 26890f02eecSBarry Smith 269b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(int),&idxout);CHKERRQ(ierr); 27090f02eecSBarry Smith for (i=0; i<n; i++) { 27129bbc08cSBarry Smith if (idxin[i] >= Nmax) SETERRQ3(PETSC_ERR_ARG_OUTOFRANGE,"Local index %d too large %d (max) at %d",idxin[i],Nmax,i); 27290f02eecSBarry Smith idxout[i] = idxmap[idxin[i]]; 27390f02eecSBarry Smith } 2743b9aefa3SBarry Smith ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 275029af93fSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxout,newis);CHKERRQ(ierr); 276606d414cSSatish Balay ierr = PetscFree(idxout);CHKERRQ(ierr); 2773a40ed3dSBarry Smith PetscFunctionReturn(0); 27890f02eecSBarry Smith } 27990f02eecSBarry Smith 28089d82c54SBarry Smith /*MC 2813acfe500SLois Curfman McInnes ISLocalToGlobalMappingApply - Takes a list of integers in a local numbering 2823acfe500SLois Curfman McInnes and converts them to the global numbering. 28390f02eecSBarry Smith 284b9cd556bSLois Curfman McInnes Not collective 285b9cd556bSLois Curfman McInnes 286bb25748dSBarry Smith Input Parameters: 287b9cd556bSLois Curfman McInnes + mapping - the local to global mapping context 288bb25748dSBarry Smith . N - number of integers 289b9cd556bSLois Curfman McInnes - in - input indices in local numbering 290bb25748dSBarry Smith 291bb25748dSBarry Smith Output Parameter: 292bb25748dSBarry Smith . out - indices in global numbering 293bb25748dSBarry Smith 2943b9aefa3SBarry Smith Synopsis: 295*216e7ba4SBarry Smith int ISLocalToGlobalMappingApply(ISLocalToGlobalMapping mapping,int N,int in[],int out[]) 2963b9aefa3SBarry Smith 297b9cd556bSLois Curfman McInnes Notes: 298b9cd556bSLois Curfman McInnes The in and out array parameters may be identical. 299d4bb536fSBarry Smith 300a997ad1aSLois Curfman McInnes Level: advanced 301a997ad1aSLois Curfman McInnes 302bb25748dSBarry Smith .seealso: ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 3030752156aSBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 304d4bb536fSBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 305bb25748dSBarry Smith 306273d9f13SBarry Smith Concepts: mapping^local to global 307d4bb536fSBarry Smith 30889d82c54SBarry Smith M*/ 309d4bb536fSBarry Smith 310d4bb536fSBarry Smith /* -----------------------------------------------------------------------------------------*/ 311d4bb536fSBarry Smith 3124a2ae208SSatish Balay #undef __FUNCT__ 3134a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingSetUp_Private" 314d4bb536fSBarry Smith /* 315d4bb536fSBarry Smith Creates the global fields in the ISLocalToGlobalMapping structure 316d4bb536fSBarry Smith */ 317d4bb536fSBarry Smith static int ISGlobalToLocalMappingSetUp_Private(ISLocalToGlobalMapping mapping) 318d4bb536fSBarry Smith { 319b0a32e0cSBarry Smith int ierr,i,*idx = mapping->indices,n = mapping->n,end,start,*globals; 320d4bb536fSBarry Smith 3213a40ed3dSBarry Smith PetscFunctionBegin; 322d4bb536fSBarry Smith end = 0; 323d4bb536fSBarry Smith start = 100000000; 324d4bb536fSBarry Smith 325d4bb536fSBarry Smith for (i=0; i<n; i++) { 326d4bb536fSBarry Smith if (idx[i] < 0) continue; 327d4bb536fSBarry Smith if (idx[i] < start) start = idx[i]; 328d4bb536fSBarry Smith if (idx[i] > end) end = idx[i]; 329d4bb536fSBarry Smith } 330d4bb536fSBarry Smith if (start > end) {start = 0; end = -1;} 331d4bb536fSBarry Smith mapping->globalstart = start; 332d4bb536fSBarry Smith mapping->globalend = end; 333d4bb536fSBarry Smith 334b0a32e0cSBarry Smith ierr = PetscMalloc((end-start+2)*sizeof(int),&globals);CHKERRQ(ierr); 335b0a32e0cSBarry Smith mapping->globals = globals; 336d4bb536fSBarry Smith for (i=0; i<end-start+1; i++) { 337d4bb536fSBarry Smith globals[i] = -1; 338d4bb536fSBarry Smith } 339d4bb536fSBarry Smith for (i=0; i<n; i++) { 340d4bb536fSBarry Smith if (idx[i] < 0) continue; 341d4bb536fSBarry Smith globals[idx[i] - start] = i; 342d4bb536fSBarry Smith } 343d4bb536fSBarry Smith 344b0a32e0cSBarry Smith PetscLogObjectMemory(mapping,(end-start+1)*sizeof(int)); 3453a40ed3dSBarry Smith PetscFunctionReturn(0); 346d4bb536fSBarry Smith } 347d4bb536fSBarry Smith 3484a2ae208SSatish Balay #undef __FUNCT__ 3494a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingApply" 350d4bb536fSBarry Smith /*@ 351a997ad1aSLois Curfman McInnes ISGlobalToLocalMappingApply - Provides the local numbering for a list of integers 352a997ad1aSLois Curfman McInnes specified with a global numbering. 353d4bb536fSBarry Smith 354b9cd556bSLois Curfman McInnes Not collective 355b9cd556bSLois Curfman McInnes 356d4bb536fSBarry Smith Input Parameters: 357b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 358d4bb536fSBarry Smith . type - IS_GTOLM_MASK - replaces global indices with no local value with -1 359d4bb536fSBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 360d4bb536fSBarry Smith . n - number of global indices to map 361b9cd556bSLois Curfman McInnes - idx - global indices to map 362d4bb536fSBarry Smith 363d4bb536fSBarry Smith Output Parameters: 364b9cd556bSLois Curfman McInnes + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 365b9cd556bSLois Curfman McInnes - idxout - local index of each global index, one must pass in an array long enough 366e182c471SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApply() with 367e182c471SBarry Smith idxout == PETSC_NULL to determine the required length (returned in nout) 368e182c471SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApply() 369e182c471SBarry Smith a second time to set the values. 370d4bb536fSBarry Smith 371b9cd556bSLois Curfman McInnes Notes: 372b9cd556bSLois Curfman McInnes Either nout or idxout may be PETSC_NULL. idx and idxout may be identical. 373d4bb536fSBarry Smith 3740f5bd95cSBarry Smith This is not scalable in memory usage. Each processor requires O(Nglobal) size 3750f5bd95cSBarry Smith array to compute these. 3760f5bd95cSBarry Smith 377a997ad1aSLois Curfman McInnes Level: advanced 378a997ad1aSLois Curfman McInnes 379273d9f13SBarry Smith Concepts: mapping^global to local 380d4bb536fSBarry Smith 381d4bb536fSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 382d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy() 383d4bb536fSBarry Smith @*/ 384d4bb536fSBarry Smith int ISGlobalToLocalMappingApply(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, 385987e4450SSatish Balay int n,const int idx[],int *nout,int idxout[]) 386d4bb536fSBarry Smith { 387d4bb536fSBarry Smith int i,ierr,*globals,nf = 0,tmp,start,end; 388d4bb536fSBarry Smith 3893a40ed3dSBarry Smith PetscFunctionBegin; 390d4bb536fSBarry Smith if (!mapping->globals) { 391d4bb536fSBarry Smith ierr = ISGlobalToLocalMappingSetUp_Private(mapping);CHKERRQ(ierr); 392d4bb536fSBarry Smith } 393d4bb536fSBarry Smith globals = mapping->globals; 394d4bb536fSBarry Smith start = mapping->globalstart; 395d4bb536fSBarry Smith end = mapping->globalend; 396d4bb536fSBarry Smith 397d4bb536fSBarry Smith if (type == IS_GTOLM_MASK) { 398d4bb536fSBarry Smith if (idxout) { 399d4bb536fSBarry Smith for (i=0; i<n; i++) { 400d4bb536fSBarry Smith if (idx[i] < 0) idxout[i] = idx[i]; 401d4bb536fSBarry Smith else if (idx[i] < start) idxout[i] = -1; 402d4bb536fSBarry Smith else if (idx[i] > end) idxout[i] = -1; 403d4bb536fSBarry Smith else idxout[i] = globals[idx[i] - start]; 404d4bb536fSBarry Smith } 405d4bb536fSBarry Smith } 406d4bb536fSBarry Smith if (nout) *nout = n; 407d4bb536fSBarry Smith } else { 408d4bb536fSBarry Smith if (idxout) { 409d4bb536fSBarry Smith for (i=0; i<n; i++) { 410d4bb536fSBarry Smith if (idx[i] < 0) continue; 411d4bb536fSBarry Smith if (idx[i] < start) continue; 412d4bb536fSBarry Smith if (idx[i] > end) continue; 413d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 414d4bb536fSBarry Smith if (tmp < 0) continue; 415d4bb536fSBarry Smith idxout[nf++] = tmp; 416d4bb536fSBarry Smith } 417d4bb536fSBarry Smith } else { 418d4bb536fSBarry Smith for (i=0; i<n; i++) { 419d4bb536fSBarry Smith if (idx[i] < 0) continue; 420d4bb536fSBarry Smith if (idx[i] < start) continue; 421d4bb536fSBarry Smith if (idx[i] > end) continue; 422d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 423d4bb536fSBarry Smith if (tmp < 0) continue; 424d4bb536fSBarry Smith nf++; 425d4bb536fSBarry Smith } 426d4bb536fSBarry Smith } 427d4bb536fSBarry Smith if (nout) *nout = nf; 428d4bb536fSBarry Smith } 429d4bb536fSBarry Smith 4303a40ed3dSBarry Smith PetscFunctionReturn(0); 431d4bb536fSBarry Smith } 43290f02eecSBarry Smith 4334a2ae208SSatish Balay #undef __FUNCT__ 4344a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingGetInfo" 43589d82c54SBarry Smith /*@C 43689d82c54SBarry Smith ISLocalToGlobalMappingGetInfo - Gets the neighbor information for each processor and 43789d82c54SBarry Smith each index shared by more than one processor 43889d82c54SBarry Smith 43989d82c54SBarry Smith Collective on ISLocalToGlobalMapping 44089d82c54SBarry Smith 44189d82c54SBarry Smith Input Parameters: 44289d82c54SBarry Smith . mapping - the mapping from local to global indexing 44389d82c54SBarry Smith 44489d82c54SBarry Smith Output Parameter: 44589d82c54SBarry Smith + nproc - number of processors that are connected to this one 44689d82c54SBarry Smith . proc - neighboring processors 44707b52d57SBarry Smith . numproc - number of indices for each subdomain (processor) 44807b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 44989d82c54SBarry Smith 45089d82c54SBarry Smith Level: advanced 45189d82c54SBarry Smith 452273d9f13SBarry Smith Concepts: mapping^local to global 45389d82c54SBarry Smith 45407b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 45507b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo() 45689d82c54SBarry Smith @*/ 45730dcb7c9SBarry Smith int ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping mapping,int *nproc,int **procs,int **numprocs,int ***indices) 45889d82c54SBarry Smith { 459fa7fbcffSSatish Balay int i,n = mapping->n,ierr,Ng,ng,max = 0,*lindices = mapping->indices; 4603a96401aSBarry Smith int size,rank,*nprocs,*owner,nsends,*sends,j,*starts,*work,nmax,nrecvs,*recvs,proc; 46124cf384cSBarry Smith int tag1,tag2,tag3,cnt,*len,*source,imdex,scale,*ownedsenders,*nownedsenders,rstart,nowned; 46207b52d57SBarry Smith int node,nownedm,nt,*sends2,nsends2,*starts2,*lens2,*dest,nrecvs2,*starts3,*recvs2,k,*bprocs,*tmp; 46324cf384cSBarry Smith int first_procs,first_numprocs,*first_indices; 46489d82c54SBarry Smith MPI_Request *recv_waits,*send_waits; 46530dcb7c9SBarry Smith MPI_Status recv_status,*send_status,*recv_statuses; 46689d82c54SBarry Smith MPI_Comm comm = mapping->comm; 46707b52d57SBarry Smith PetscTruth debug = PETSC_FALSE; 46889d82c54SBarry Smith 46989d82c54SBarry Smith PetscFunctionBegin; 47024cf384cSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 47124cf384cSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 47224cf384cSBarry Smith if (size == 1) { 47324cf384cSBarry Smith *nproc = 0; 47424cf384cSBarry Smith *procs = PETSC_NULL; 475b0a32e0cSBarry Smith ierr = PetscMalloc(sizeof(int),numprocs);CHKERRQ(ierr); 4761e2105dcSBarry Smith (*numprocs)[0] = 0; 477b0a32e0cSBarry Smith ierr = PetscMalloc(sizeof(int*),indices);CHKERRQ(ierr); 4781e2105dcSBarry Smith (*indices)[0] = PETSC_NULL; 47924cf384cSBarry Smith PetscFunctionReturn(0); 48024cf384cSBarry Smith } 48124cf384cSBarry Smith 482b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-islocaltoglobalmappinggetinfo_debug",&debug);CHKERRQ(ierr); 48307b52d57SBarry Smith 4843677ff5aSBarry Smith /* 4853677ff5aSBarry Smith Notes on ISLocalToGlobalMappingGetInfo 4863677ff5aSBarry Smith 4873677ff5aSBarry Smith globally owned node - the nodes that have been assigned to this processor in global 4883677ff5aSBarry Smith numbering, just for this routine. 4893677ff5aSBarry Smith 4903677ff5aSBarry Smith nontrivial globally owned node - node assigned to this processor that is on a subdomain 4913677ff5aSBarry Smith boundary (i.e. is has more than one local owner) 4923677ff5aSBarry Smith 4933677ff5aSBarry Smith locally owned node - node that exists on this processors subdomain 4943677ff5aSBarry Smith 4953677ff5aSBarry Smith nontrivial locally owned node - node that is not in the interior (i.e. has more than one 4963677ff5aSBarry Smith local subdomain 4973677ff5aSBarry Smith */ 49824cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag1);CHKERRQ(ierr); 49924cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag2);CHKERRQ(ierr); 50024cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag3);CHKERRQ(ierr); 50189d82c54SBarry Smith 50289d82c54SBarry Smith for (i=0; i<n; i++) { 50389d82c54SBarry Smith if (lindices[i] > max) max = lindices[i]; 50489d82c54SBarry Smith } 50589d82c54SBarry Smith ierr = MPI_Allreduce(&max,&Ng,1,MPI_INT,MPI_MAX,comm);CHKERRQ(ierr); 50678058e43SBarry Smith Ng++; 50789d82c54SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 50889d82c54SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 509bc8ff85bSBarry Smith scale = Ng/size + 1; 510a2e34c3dSBarry Smith ng = scale; if (rank == size-1) ng = Ng - scale*(size-1); ng = PetscMax(1,ng); 511caba0dd0SBarry Smith rstart = scale*rank; 51289d82c54SBarry Smith 51389d82c54SBarry Smith /* determine ownership ranges of global indices */ 514b0a32e0cSBarry Smith ierr = PetscMalloc((2*size+1)*sizeof(int),&nprocs);CHKERRQ(ierr); 5152880cf29SBarry Smith ierr = PetscMemzero(nprocs,2*size*sizeof(int));CHKERRQ(ierr); 51689d82c54SBarry Smith 51789d82c54SBarry Smith /* determine owners of each local node */ 518b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(int),&owner);CHKERRQ(ierr); 51989d82c54SBarry Smith for (i=0; i<n; i++) { 5203677ff5aSBarry Smith proc = lindices[i]/scale; /* processor that globally owns this index */ 5213677ff5aSBarry Smith nprocs[size+proc] = 1; /* processor globally owns at least one of ours */ 5223677ff5aSBarry Smith owner[i] = proc; 5233677ff5aSBarry Smith nprocs[proc]++; /* count of how many that processor globally owns of ours */ 52489d82c54SBarry Smith } 52589d82c54SBarry Smith nsends = 0; for (i=0; i<size; i++) nsends += nprocs[size + i]; 526b0a32e0cSBarry Smith PetscLogInfo(0,"ISLocalToGlobalMappingGetInfo: Number of global owners for my local data %d\n",nsends); 52789d82c54SBarry Smith 52889d82c54SBarry Smith /* inform other processors of number of messages and max length*/ 529b0a32e0cSBarry Smith ierr = PetscMalloc(2*size*sizeof(int),&work);CHKERRQ(ierr); 53089d82c54SBarry Smith ierr = MPI_Allreduce(nprocs,work,2*size,MPI_INT,PetscMaxSum_Op,comm);CHKERRQ(ierr); 53189d82c54SBarry Smith nmax = work[rank]; 53289d82c54SBarry Smith nrecvs = work[size+rank]; 53389d82c54SBarry Smith ierr = PetscFree(work);CHKERRQ(ierr); 534b0a32e0cSBarry Smith PetscLogInfo(0,"ISLocalToGlobalMappingGetInfo: Number of local owners for my global data %d\n",nrecvs); 53589d82c54SBarry Smith 53689d82c54SBarry Smith /* post receives for owned rows */ 537b0a32e0cSBarry Smith ierr = PetscMalloc((2*nrecvs+1)*(nmax+1)*sizeof(int),&recvs);CHKERRQ(ierr); 538b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs+1)*sizeof(MPI_Request),&recv_waits);CHKERRQ(ierr); 53989d82c54SBarry Smith for (i=0; i<nrecvs; i++) { 54024cf384cSBarry Smith ierr = MPI_Irecv(recvs+2*nmax*i,2*nmax,MPI_INT,MPI_ANY_SOURCE,tag1,comm,recv_waits+i);CHKERRQ(ierr); 54189d82c54SBarry Smith } 54289d82c54SBarry Smith 54389d82c54SBarry Smith /* pack messages containing lists of local nodes to owners */ 544b0a32e0cSBarry Smith ierr = PetscMalloc((2*n+1)*sizeof(int),&sends);CHKERRQ(ierr); 545b0a32e0cSBarry Smith ierr = PetscMalloc((size+1)*sizeof(int),&starts);CHKERRQ(ierr); 54689d82c54SBarry Smith starts[0] = 0; 54730dcb7c9SBarry Smith for (i=1; i<size; i++) { starts[i] = starts[i-1] + 2*nprocs[i-1];} 54889d82c54SBarry Smith for (i=0; i<n; i++) { 54989d82c54SBarry Smith sends[starts[owner[i]]++] = lindices[i]; 55030dcb7c9SBarry Smith sends[starts[owner[i]]++] = i; 55189d82c54SBarry Smith } 55289d82c54SBarry Smith ierr = PetscFree(owner);CHKERRQ(ierr); 55389d82c54SBarry Smith starts[0] = 0; 55430dcb7c9SBarry Smith for (i=1; i<size; i++) { starts[i] = starts[i-1] + 2*nprocs[i-1];} 55589d82c54SBarry Smith 55689d82c54SBarry Smith /* send the messages */ 557b0a32e0cSBarry Smith ierr = PetscMalloc((nsends+1)*sizeof(MPI_Request),&send_waits);CHKERRQ(ierr); 558b0a32e0cSBarry Smith ierr = PetscMalloc((nsends+1)*sizeof(int),&dest);CHKERRQ(ierr); 55989d82c54SBarry Smith cnt = 0; 56089d82c54SBarry Smith for (i=0; i<size; i++) { 56189d82c54SBarry Smith if (nprocs[i]) { 56224cf384cSBarry Smith ierr = MPI_Isend(sends+starts[i],2*nprocs[i],MPI_INT,i,tag1,comm,send_waits+cnt);CHKERRQ(ierr); 56330dcb7c9SBarry Smith dest[cnt] = i; 56489d82c54SBarry Smith cnt++; 56589d82c54SBarry Smith } 56689d82c54SBarry Smith } 56789d82c54SBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 56889d82c54SBarry Smith 56989d82c54SBarry Smith /* wait on receives */ 570b0a32e0cSBarry Smith ierr = PetscMalloc((2*nrecvs+1)*sizeof(int),&source);CHKERRQ(ierr); 57189d82c54SBarry Smith len = source + nrecvs; 57289d82c54SBarry Smith cnt = nrecvs; 573b0a32e0cSBarry Smith ierr = PetscMalloc((ng+1)*sizeof(int),&nownedsenders);CHKERRQ(ierr); 574caba0dd0SBarry Smith ierr = PetscMemzero(nownedsenders,ng*sizeof(int));CHKERRQ(ierr); 57589d82c54SBarry Smith while (cnt) { 57689d82c54SBarry Smith ierr = MPI_Waitany(nrecvs,recv_waits,&imdex,&recv_status);CHKERRQ(ierr); 57789d82c54SBarry Smith /* unpack receives into our local space */ 57889d82c54SBarry Smith ierr = MPI_Get_count(&recv_status,MPI_INT,&len[imdex]);CHKERRQ(ierr); 57989d82c54SBarry Smith source[imdex] = recv_status.MPI_SOURCE; 58030dcb7c9SBarry Smith len[imdex] = len[imdex]/2; 581caba0dd0SBarry Smith /* count how many local owners for each of my global owned indices */ 58230dcb7c9SBarry Smith for (i=0; i<len[imdex]; i++) nownedsenders[recvs[2*imdex*nmax+2*i]-rstart]++; 58389d82c54SBarry Smith cnt--; 58489d82c54SBarry Smith } 58589d82c54SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 58689d82c54SBarry Smith 58730dcb7c9SBarry Smith /* count how many globally owned indices are on an edge multiplied by how many processors own them. */ 588bc8ff85bSBarry Smith nowned = 0; 589bc8ff85bSBarry Smith nownedm = 0; 590bc8ff85bSBarry Smith for (i=0; i<ng; i++) { 591bc8ff85bSBarry Smith if (nownedsenders[i] > 1) {nownedm += nownedsenders[i]; nowned++;} 592bc8ff85bSBarry Smith } 593bc8ff85bSBarry Smith 594bc8ff85bSBarry Smith /* create single array to contain rank of all local owners of each globally owned index */ 595b0a32e0cSBarry Smith ierr = PetscMalloc((nownedm+1)*sizeof(int),&ownedsenders);CHKERRQ(ierr); 596b0a32e0cSBarry Smith ierr = PetscMalloc((ng+1)*sizeof(int),&starts);CHKERRQ(ierr); 597bc8ff85bSBarry Smith starts[0] = 0; 598bc8ff85bSBarry Smith for (i=1; i<ng; i++) { 599bc8ff85bSBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 600bc8ff85bSBarry Smith else starts[i] = starts[i-1]; 601bc8ff85bSBarry Smith } 602bc8ff85bSBarry Smith 60330dcb7c9SBarry Smith /* for each nontrival globally owned node list all arriving processors */ 604bc8ff85bSBarry Smith for (i=0; i<nrecvs; i++) { 605bc8ff85bSBarry Smith for (j=0; j<len[i]; j++) { 60630dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 607bc8ff85bSBarry Smith if (nownedsenders[node] > 1) { 608bc8ff85bSBarry Smith ownedsenders[starts[node]++] = source[i]; 609bc8ff85bSBarry Smith } 610bc8ff85bSBarry Smith } 611bc8ff85bSBarry Smith } 612bc8ff85bSBarry Smith 61307b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 61430dcb7c9SBarry Smith starts[0] = 0; 61530dcb7c9SBarry Smith for (i=1; i<ng; i++) { 61630dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 61730dcb7c9SBarry Smith else starts[i] = starts[i-1]; 61830dcb7c9SBarry Smith } 61930dcb7c9SBarry Smith for (i=0; i<ng; i++) { 62030dcb7c9SBarry Smith if (nownedsenders[i] > 1) { 62130dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] global node %d local owner processors: ",rank,i+rstart);CHKERRQ(ierr); 62230dcb7c9SBarry Smith for (j=0; j<nownedsenders[i]; j++) { 62330dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",ownedsenders[starts[i]+j]);CHKERRQ(ierr); 62430dcb7c9SBarry Smith } 62530dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 62630dcb7c9SBarry Smith } 62730dcb7c9SBarry Smith } 62830dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 62907b52d57SBarry Smith }/* ----------------------------------- */ 63030dcb7c9SBarry Smith 6313677ff5aSBarry Smith /* wait on original sends */ 6323a96401aSBarry Smith if (nsends) { 633b0a32e0cSBarry Smith ierr = PetscMalloc(nsends*sizeof(MPI_Status),&send_status);CHKERRQ(ierr); 6343a96401aSBarry Smith ierr = MPI_Waitall(nsends,send_waits,send_status);CHKERRQ(ierr); 6353a96401aSBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 6363a96401aSBarry Smith } 63789d82c54SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 6383a96401aSBarry Smith ierr = PetscFree(sends);CHKERRQ(ierr); 6393677ff5aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 6403677ff5aSBarry Smith 6413677ff5aSBarry Smith /* pack messages to send back to local owners */ 64230dcb7c9SBarry Smith starts[0] = 0; 64330dcb7c9SBarry Smith for (i=1; i<ng; i++) { 64430dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 64530dcb7c9SBarry Smith else starts[i] = starts[i-1]; 64630dcb7c9SBarry Smith } 64730dcb7c9SBarry Smith nsends2 = nrecvs; 648b0a32e0cSBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(int),&nprocs);CHKERRQ(ierr); /* length of each message */ 64930dcb7c9SBarry Smith for (i=0; i<nrecvs; i++) { 65030dcb7c9SBarry Smith nprocs[i] = 1; 65130dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 65230dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 65330dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 65430dcb7c9SBarry Smith nprocs[i] += 2 + nownedsenders[node]; 65530dcb7c9SBarry Smith } 65630dcb7c9SBarry Smith } 65730dcb7c9SBarry Smith } 65830dcb7c9SBarry Smith nt = 0; for (i=0; i<nsends2; i++) nt += nprocs[i]; 659b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int),&sends2);CHKERRQ(ierr); 660b0a32e0cSBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(int),&starts2);CHKERRQ(ierr); 66130dcb7c9SBarry Smith starts2[0] = 0; for (i=1; i<nsends2; i++) starts2[i] = starts2[i-1] + nprocs[i-1]; 66230dcb7c9SBarry Smith /* 66330dcb7c9SBarry Smith Each message is 1 + nprocs[i] long, and consists of 66430dcb7c9SBarry Smith (0) the number of nodes being sent back 66530dcb7c9SBarry Smith (1) the local node number, 66630dcb7c9SBarry Smith (2) the number of processors sharing it, 66730dcb7c9SBarry Smith (3) the processors sharing it 66830dcb7c9SBarry Smith */ 66930dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 67030dcb7c9SBarry Smith cnt = 1; 67130dcb7c9SBarry Smith sends2[starts2[i]] = 0; 67230dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 67330dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 67430dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 67530dcb7c9SBarry Smith sends2[starts2[i]]++; 67630dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = recvs[2*i*nmax+2*j+1]; 67730dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = nownedsenders[node]; 67830dcb7c9SBarry Smith ierr = PetscMemcpy(&sends2[starts2[i]+cnt],&ownedsenders[starts[node]],nownedsenders[node]*sizeof(int));CHKERRQ(ierr); 67930dcb7c9SBarry Smith cnt += nownedsenders[node]; 68030dcb7c9SBarry Smith } 68130dcb7c9SBarry Smith } 68230dcb7c9SBarry Smith } 68330dcb7c9SBarry Smith 68430dcb7c9SBarry Smith /* send the message lengths */ 68530dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 68624cf384cSBarry Smith ierr = MPI_Send(&nprocs[i],1,MPI_INT,source[i],tag2,comm);CHKERRQ(ierr); 68730dcb7c9SBarry Smith } 68830dcb7c9SBarry Smith 68930dcb7c9SBarry Smith /* receive the message lengths */ 69030dcb7c9SBarry Smith nrecvs2 = nsends; 691b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(int),&lens2);CHKERRQ(ierr); 692b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(int),&starts3);CHKERRQ(ierr); 69330dcb7c9SBarry Smith nt = 0; 69430dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 69524cf384cSBarry Smith ierr = MPI_Recv(&lens2[i],1,MPI_INT,dest[i],tag2,comm,&recv_status);CHKERRQ(ierr); 69630dcb7c9SBarry Smith nt += lens2[i]; 69730dcb7c9SBarry Smith } 69830dcb7c9SBarry Smith starts3[0] = 0; 69930dcb7c9SBarry Smith for (i=0; i<nrecvs2-1; i++) { 70030dcb7c9SBarry Smith starts3[i+1] = starts3[i] + lens2[i]; 70130dcb7c9SBarry Smith } 702b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int),&recvs2);CHKERRQ(ierr); 703b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(MPI_Request),&recv_waits);CHKERRQ(ierr); 70452b72c4aSBarry Smith for (i=0; i<nrecvs2; i++) { 70524cf384cSBarry Smith ierr = MPI_Irecv(recvs2+starts3[i],lens2[i],MPI_INT,dest[i],tag3,comm,recv_waits+i);CHKERRQ(ierr); 70630dcb7c9SBarry Smith } 70730dcb7c9SBarry Smith 70830dcb7c9SBarry Smith /* send the messages */ 709b0a32e0cSBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(MPI_Request),&send_waits);CHKERRQ(ierr); 71030dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 71124cf384cSBarry Smith ierr = MPI_Isend(sends2+starts2[i],nprocs[i],MPI_INT,source[i],tag3,comm,send_waits+i);CHKERRQ(ierr); 71230dcb7c9SBarry Smith } 71330dcb7c9SBarry Smith 71430dcb7c9SBarry Smith /* wait on receives */ 715b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(MPI_Status),&recv_statuses);CHKERRQ(ierr); 71630dcb7c9SBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 71730dcb7c9SBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 71830dcb7c9SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 71930dcb7c9SBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 72030dcb7c9SBarry Smith 72107b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 72230dcb7c9SBarry Smith cnt = 0; 72330dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 72430dcb7c9SBarry Smith nt = recvs2[cnt++]; 72530dcb7c9SBarry Smith for (j=0; j<nt; j++) { 72630dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] local node %d number of subdomains %d: ",rank,recvs2[cnt],recvs2[cnt+1]);CHKERRQ(ierr); 72730dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 72830dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",recvs2[cnt+2+k]);CHKERRQ(ierr); 72930dcb7c9SBarry Smith } 73030dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 73130dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 73230dcb7c9SBarry Smith } 73330dcb7c9SBarry Smith } 73430dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 73507b52d57SBarry Smith } /* ----------------------------------- */ 73630dcb7c9SBarry Smith 73730dcb7c9SBarry Smith /* count number subdomains for each local node */ 738b0a32e0cSBarry Smith ierr = PetscMalloc(size*sizeof(int),&nprocs);CHKERRQ(ierr); 73930dcb7c9SBarry Smith ierr = PetscMemzero(nprocs,size*sizeof(int));CHKERRQ(ierr); 74030dcb7c9SBarry Smith cnt = 0; 74130dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 74230dcb7c9SBarry Smith nt = recvs2[cnt++]; 74330dcb7c9SBarry Smith for (j=0; j<nt; j++) { 74430dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 74530dcb7c9SBarry Smith nprocs[recvs2[cnt+2+k]]++; 74630dcb7c9SBarry Smith } 74730dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 74830dcb7c9SBarry Smith } 74930dcb7c9SBarry Smith } 75030dcb7c9SBarry Smith nt = 0; for (i=0; i<size; i++) nt += (nprocs[i] > 0); 75130dcb7c9SBarry Smith *nproc = nt; 752b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int),procs);CHKERRQ(ierr); 753b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int),numprocs);CHKERRQ(ierr); 754b0a32e0cSBarry Smith ierr = PetscMalloc((nt+1)*sizeof(int*),indices);CHKERRQ(ierr); 755b0a32e0cSBarry Smith ierr = PetscMalloc(size*sizeof(int),&bprocs);CHKERRQ(ierr); 75630dcb7c9SBarry Smith cnt = 0; 75730dcb7c9SBarry Smith for (i=0; i<size; i++) { 75830dcb7c9SBarry Smith if (nprocs[i] > 0) { 75930dcb7c9SBarry Smith bprocs[i] = cnt; 76030dcb7c9SBarry Smith (*procs)[cnt] = i; 76130dcb7c9SBarry Smith (*numprocs)[cnt] = nprocs[i]; 762b0a32e0cSBarry Smith ierr = PetscMalloc(nprocs[i]*sizeof(int),&(*indices)[cnt]);CHKERRQ(ierr); 76330dcb7c9SBarry Smith cnt++; 76430dcb7c9SBarry Smith } 76530dcb7c9SBarry Smith } 76630dcb7c9SBarry Smith 76730dcb7c9SBarry Smith /* make the list of subdomains for each nontrivial local node */ 76830dcb7c9SBarry Smith ierr = PetscMemzero(*numprocs,nt*sizeof(int));CHKERRQ(ierr); 76930dcb7c9SBarry Smith cnt = 0; 77030dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 77130dcb7c9SBarry Smith nt = recvs2[cnt++]; 77230dcb7c9SBarry Smith for (j=0; j<nt; j++) { 77330dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 77430dcb7c9SBarry Smith (*indices)[bprocs[recvs2[cnt+2+k]]][(*numprocs)[bprocs[recvs2[cnt+2+k]]]++] = recvs2[cnt]; 77530dcb7c9SBarry Smith } 77630dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 77730dcb7c9SBarry Smith } 77830dcb7c9SBarry Smith } 77930dcb7c9SBarry Smith ierr = PetscFree(bprocs);CHKERRQ(ierr); 78007b52d57SBarry Smith ierr = PetscFree(recvs2);CHKERRQ(ierr); 78130dcb7c9SBarry Smith 78207b52d57SBarry Smith /* sort the node indexing by their global numbers */ 78307b52d57SBarry Smith nt = *nproc; 78407b52d57SBarry Smith for (i=0; i<nt; i++) { 785b0a32e0cSBarry Smith ierr = PetscMalloc(((*numprocs)[i])*sizeof(int),&tmp);CHKERRQ(ierr); 78607b52d57SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 78707b52d57SBarry Smith tmp[j] = lindices[(*indices)[i][j]]; 78807b52d57SBarry Smith } 78907b52d57SBarry Smith ierr = PetscSortIntWithArray((*numprocs)[i],tmp,(*indices)[i]);CHKERRQ(ierr); 79007b52d57SBarry Smith ierr = PetscFree(tmp);CHKERRQ(ierr); 79107b52d57SBarry Smith } 79207b52d57SBarry Smith 79307b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 79430dcb7c9SBarry Smith nt = *nproc; 79530dcb7c9SBarry Smith for (i=0; i<nt; i++) { 79630dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] subdomain %d number of indices %d: ",rank,(*procs)[i],(*numprocs)[i]);CHKERRQ(ierr); 79730dcb7c9SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 79830dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",(*indices)[i][j]);CHKERRQ(ierr); 79930dcb7c9SBarry Smith } 80030dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 80130dcb7c9SBarry Smith } 80230dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 80307b52d57SBarry Smith } /* ----------------------------------- */ 80430dcb7c9SBarry Smith 80530dcb7c9SBarry Smith /* wait on sends */ 80630dcb7c9SBarry Smith if (nsends2) { 807b0a32e0cSBarry Smith ierr = PetscMalloc(nsends2*sizeof(MPI_Status),&send_status);CHKERRQ(ierr); 80830dcb7c9SBarry Smith ierr = MPI_Waitall(nsends2,send_waits,send_status);CHKERRQ(ierr); 80930dcb7c9SBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 81030dcb7c9SBarry Smith } 81130dcb7c9SBarry Smith 81230dcb7c9SBarry Smith ierr = PetscFree(starts3);CHKERRQ(ierr); 81330dcb7c9SBarry Smith ierr = PetscFree(dest);CHKERRQ(ierr); 81430dcb7c9SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 8153677ff5aSBarry Smith 816bc8ff85bSBarry Smith ierr = PetscFree(nownedsenders);CHKERRQ(ierr); 817bc8ff85bSBarry Smith ierr = PetscFree(ownedsenders);CHKERRQ(ierr); 818bc8ff85bSBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 81930dcb7c9SBarry Smith ierr = PetscFree(starts2);CHKERRQ(ierr); 82030dcb7c9SBarry Smith ierr = PetscFree(lens2);CHKERRQ(ierr); 82189d82c54SBarry Smith 82289d82c54SBarry Smith ierr = PetscFree(source);CHKERRQ(ierr); 82389d82c54SBarry Smith ierr = PetscFree(recvs);CHKERRQ(ierr); 8243a96401aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 82530dcb7c9SBarry Smith ierr = PetscFree(sends2);CHKERRQ(ierr); 82624cf384cSBarry Smith 82724cf384cSBarry Smith /* put the information about myself as the first entry in the list */ 82824cf384cSBarry Smith first_procs = (*procs)[0]; 82924cf384cSBarry Smith first_numprocs = (*numprocs)[0]; 83024cf384cSBarry Smith first_indices = (*indices)[0]; 83124cf384cSBarry Smith for (i=0; i<*nproc; i++) { 83224cf384cSBarry Smith if ((*procs)[i] == rank) { 83324cf384cSBarry Smith (*procs)[0] = (*procs)[i]; 83424cf384cSBarry Smith (*numprocs)[0] = (*numprocs)[i]; 83524cf384cSBarry Smith (*indices)[0] = (*indices)[i]; 83624cf384cSBarry Smith (*procs)[i] = first_procs; 83724cf384cSBarry Smith (*numprocs)[i] = first_numprocs; 83824cf384cSBarry Smith (*indices)[i] = first_indices; 83924cf384cSBarry Smith break; 84024cf384cSBarry Smith } 84124cf384cSBarry Smith } 84224cf384cSBarry Smith 84389d82c54SBarry Smith PetscFunctionReturn(0); 84489d82c54SBarry Smith } 84589d82c54SBarry Smith 8464a2ae208SSatish Balay #undef __FUNCT__ 8474a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingRestoreInfo" 84807b52d57SBarry Smith /*@C 84907b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo - Frees the memory allocated by ISLocalToGlobalMappingGetInfo() 85089d82c54SBarry Smith 85107b52d57SBarry Smith Collective on ISLocalToGlobalMapping 85207b52d57SBarry Smith 85307b52d57SBarry Smith Input Parameters: 85407b52d57SBarry Smith . mapping - the mapping from local to global indexing 85507b52d57SBarry Smith 85607b52d57SBarry Smith Output Parameter: 85707b52d57SBarry Smith + nproc - number of processors that are connected to this one 85807b52d57SBarry Smith . proc - neighboring processors 85907b52d57SBarry Smith . numproc - number of indices for each processor 86007b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 86107b52d57SBarry Smith 86207b52d57SBarry Smith Level: advanced 86307b52d57SBarry Smith 86407b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 86507b52d57SBarry Smith ISLocalToGlobalMappingGetInfo() 86607b52d57SBarry Smith @*/ 86707b52d57SBarry Smith int ISLocalToGlobalMappingRestoreInfo(ISLocalToGlobalMapping mapping,int *nproc,int **procs,int **numprocs,int ***indices) 86807b52d57SBarry Smith { 86907b52d57SBarry Smith int ierr,i; 87007b52d57SBarry Smith 87107b52d57SBarry Smith PetscFunctionBegin; 87200ff320aSBarry Smith if (*procs) {ierr = PetscFree(*procs);CHKERRQ(ierr);} 87300ff320aSBarry Smith if (*numprocs) {ierr = PetscFree(*numprocs);CHKERRQ(ierr);} 87400ff320aSBarry Smith if (*indices) { 87500ff320aSBarry Smith if ((*indices)[0]) {ierr = PetscFree((*indices)[0]);CHKERRQ(ierr);} 87600ff320aSBarry Smith for (i=1; i<*nproc; i++) { 87724cf384cSBarry Smith if ((*indices)[i]) {ierr = PetscFree((*indices)[i]);CHKERRQ(ierr);} 87807b52d57SBarry Smith } 87907b52d57SBarry Smith ierr = PetscFree(*indices);CHKERRQ(ierr); 88024cf384cSBarry Smith } 88107b52d57SBarry Smith PetscFunctionReturn(0); 88207b52d57SBarry Smith } 88389d82c54SBarry Smith 884bc8ff85bSBarry Smith 885bc8ff85bSBarry Smith 886bc8ff85bSBarry Smith 887bc8ff85bSBarry Smith 888bc8ff85bSBarry Smith 889bc8ff85bSBarry Smith 890bc8ff85bSBarry Smith 891bc8ff85bSBarry Smith 892bc8ff85bSBarry Smith 893bc8ff85bSBarry Smith 894bc8ff85bSBarry Smith 895bc8ff85bSBarry Smith 896bc8ff85bSBarry Smith 897bc8ff85bSBarry Smith 898bc8ff85bSBarry Smith 899bc8ff85bSBarry Smith 90024cf384cSBarry Smith 901