12362add9SBarry Smith 2b45d2f2cSJed Brown #include <petsc-private/isimpl.h> /*I "petscis.h" I*/ 30c312b8eSJed Brown #include <petscsf.h> 4665c2dedSJed Brown #include <petscviewer.h> 52362add9SBarry Smith 67087cfbeSBarry Smith PetscClassId IS_LTOGM_CLASSID; 78e58c17dSMatthew Knepley 8*04a59952SBarry Smith 94a2ae208SSatish Balay #undef __FUNCT__ 10743c9b42SStefano Zampini #define __FUNCT__ "ISG2LMapApply" 11186d4ecdSBarry Smith PetscErrorCode ISG2LMapApply(ISLocalToGlobalMapping mapping,PetscInt n,const PetscInt in[],PetscInt out[]) 12186d4ecdSBarry Smith { 13186d4ecdSBarry Smith PetscErrorCode ierr; 14743c9b42SStefano Zampini PetscInt i,start,end; 15186d4ecdSBarry Smith 16186d4ecdSBarry Smith PetscFunctionBegin; 17186d4ecdSBarry Smith if (!mapping->globals) { 18186d4ecdSBarry Smith ierr = ISGlobalToLocalMappingApply(mapping,IS_GTOLM_MASK,0,0,0,0);CHKERRQ(ierr); 19186d4ecdSBarry Smith } 20743c9b42SStefano Zampini start = mapping->globalstart; 21743c9b42SStefano Zampini end = mapping->globalend; 22186d4ecdSBarry Smith for (i=0; i<n; i++) { 23186d4ecdSBarry Smith if (in[i] < 0) out[i] = in[i]; 24186d4ecdSBarry Smith else if (in[i] < start) out[i] = -1; 25186d4ecdSBarry Smith else if (in[i] > end) out[i] = -1; 26743c9b42SStefano Zampini else out[i] = mapping->globals[in[i] - start]; 27186d4ecdSBarry Smith } 28186d4ecdSBarry Smith PetscFunctionReturn(0); 29186d4ecdSBarry Smith } 30186d4ecdSBarry Smith 31186d4ecdSBarry Smith 32186d4ecdSBarry Smith #undef __FUNCT__ 334a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingGetSize" 343b9aefa3SBarry Smith /*@C 353b9aefa3SBarry Smith ISLocalToGlobalMappingGetSize - Gets the local size of a local to global mapping. 363b9aefa3SBarry Smith 373b9aefa3SBarry Smith Not Collective 383b9aefa3SBarry Smith 393b9aefa3SBarry Smith Input Parameter: 403b9aefa3SBarry Smith . ltog - local to global mapping 413b9aefa3SBarry Smith 423b9aefa3SBarry Smith Output Parameter: 433b9aefa3SBarry Smith . n - the number of entries in the local mapping 443b9aefa3SBarry Smith 453b9aefa3SBarry Smith Level: advanced 463b9aefa3SBarry Smith 47273d9f13SBarry Smith Concepts: mapping^local to global 483b9aefa3SBarry Smith 493b9aefa3SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 503b9aefa3SBarry Smith @*/ 517087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingGetSize(ISLocalToGlobalMapping mapping,PetscInt *n) 523b9aefa3SBarry Smith { 533b9aefa3SBarry Smith PetscFunctionBegin; 540700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 554482741eSBarry Smith PetscValidIntPointer(n,2); 563b9aefa3SBarry Smith *n = mapping->n; 573b9aefa3SBarry Smith PetscFunctionReturn(0); 583b9aefa3SBarry Smith } 593b9aefa3SBarry Smith 604a2ae208SSatish Balay #undef __FUNCT__ 614a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingView" 625a5d4f66SBarry Smith /*@C 635a5d4f66SBarry Smith ISLocalToGlobalMappingView - View a local to global mapping 645a5d4f66SBarry Smith 65b9cd556bSLois Curfman McInnes Not Collective 66b9cd556bSLois Curfman McInnes 675a5d4f66SBarry Smith Input Parameters: 683b9aefa3SBarry Smith + ltog - local to global mapping 693b9aefa3SBarry Smith - viewer - viewer 705a5d4f66SBarry Smith 71a997ad1aSLois Curfman McInnes Level: advanced 72a997ad1aSLois Curfman McInnes 73273d9f13SBarry Smith Concepts: mapping^local to global 745a5d4f66SBarry Smith 755a5d4f66SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 765a5d4f66SBarry Smith @*/ 777087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingView(ISLocalToGlobalMapping mapping,PetscViewer viewer) 785a5d4f66SBarry Smith { 7932dcc486SBarry Smith PetscInt i; 8032dcc486SBarry Smith PetscMPIInt rank; 81ace3abfcSBarry Smith PetscBool iascii; 826849ba73SBarry Smith PetscErrorCode ierr; 835a5d4f66SBarry Smith 845a5d4f66SBarry Smith PetscFunctionBegin; 850700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 863050cee2SBarry Smith if (!viewer) { 87ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mapping),&viewer);CHKERRQ(ierr); 883050cee2SBarry Smith } 890700a824SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 905a5d4f66SBarry Smith 91ce94432eSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mapping),&rank);CHKERRQ(ierr); 92251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 9332077d6dSBarry Smith if (iascii) { 947b23a99aSBarry Smith ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);CHKERRQ(ierr); 955a5d4f66SBarry Smith for (i=0; i<mapping->n; i++) { 96b0a32e0cSBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d] %d %d\n",rank,i,mapping->indices[i]);CHKERRQ(ierr); 976831982aSBarry Smith } 98b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 997b23a99aSBarry Smith ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_FALSE);CHKERRQ(ierr); 1007b23a99aSBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported for ISLocalToGlobalMapping",((PetscObject)viewer)->type_name); 1015a5d4f66SBarry Smith PetscFunctionReturn(0); 1025a5d4f66SBarry Smith } 1035a5d4f66SBarry Smith 1044a2ae208SSatish Balay #undef __FUNCT__ 1054a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreateIS" 1061f428162SBarry Smith /*@ 1072bdab257SBarry Smith ISLocalToGlobalMappingCreateIS - Creates a mapping between a local (0 to n) 1082bdab257SBarry Smith ordering and a global parallel ordering. 1092bdab257SBarry Smith 1100f5bd95cSBarry Smith Not collective 111b9cd556bSLois Curfman McInnes 112a997ad1aSLois Curfman McInnes Input Parameter: 1138c03b21aSDmitry Karpeev . is - index set containing the global numbers for each local number 1142bdab257SBarry Smith 115a997ad1aSLois Curfman McInnes Output Parameter: 1162bdab257SBarry Smith . mapping - new mapping data structure 1172bdab257SBarry Smith 118a997ad1aSLois Curfman McInnes Level: advanced 119a997ad1aSLois Curfman McInnes 120273d9f13SBarry Smith Concepts: mapping^local to global 1212bdab257SBarry Smith 1222bdab257SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 1232bdab257SBarry Smith @*/ 1247087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingCreateIS(IS is,ISLocalToGlobalMapping *mapping) 1252bdab257SBarry Smith { 1266849ba73SBarry Smith PetscErrorCode ierr; 1275d0c19d7SBarry Smith PetscInt n; 1285d0c19d7SBarry Smith const PetscInt *indices; 1292bdab257SBarry Smith MPI_Comm comm; 1303a40ed3dSBarry Smith 1313a40ed3dSBarry Smith PetscFunctionBegin; 1320700a824SBarry Smith PetscValidHeaderSpecific(is,IS_CLASSID,1); 1334482741eSBarry Smith PetscValidPointer(mapping,2); 1342bdab257SBarry Smith 1352bdab257SBarry Smith ierr = PetscObjectGetComm((PetscObject)is,&comm);CHKERRQ(ierr); 1363b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 1372bdab257SBarry Smith ierr = ISGetIndices(is,&indices);CHKERRQ(ierr); 138d5ad8652SBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,n,indices,PETSC_COPY_VALUES,mapping);CHKERRQ(ierr); 1392bdab257SBarry Smith ierr = ISRestoreIndices(is,&indices);CHKERRQ(ierr); 1403a40ed3dSBarry Smith PetscFunctionReturn(0); 1412bdab257SBarry Smith } 1425a5d4f66SBarry Smith 143a4d96a55SJed Brown #undef __FUNCT__ 144a4d96a55SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingCreateSF" 145a4d96a55SJed Brown /*@C 146a4d96a55SJed Brown ISLocalToGlobalMappingCreateSF - Creates a mapping between a local (0 to n) 147a4d96a55SJed Brown ordering and a global parallel ordering. 148a4d96a55SJed Brown 149a4d96a55SJed Brown Collective 150a4d96a55SJed Brown 151a4d96a55SJed Brown Input Parameter: 152a4d96a55SJed Brown + sf - star forest mapping contiguous local indices to (rank, offset) 153a4d96a55SJed Brown - start - first global index on this process 154a4d96a55SJed Brown 155a4d96a55SJed Brown Output Parameter: 156a4d96a55SJed Brown . mapping - new mapping data structure 157a4d96a55SJed Brown 158a4d96a55SJed Brown Level: advanced 159a4d96a55SJed Brown 160a4d96a55SJed Brown Concepts: mapping^local to global 161a4d96a55SJed Brown 162a4d96a55SJed Brown .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingCreateIS() 163a4d96a55SJed Brown @*/ 164a4d96a55SJed Brown PetscErrorCode ISLocalToGlobalMappingCreateSF(PetscSF sf,PetscInt start,ISLocalToGlobalMapping *mapping) 165a4d96a55SJed Brown { 166a4d96a55SJed Brown PetscErrorCode ierr; 167a4d96a55SJed Brown PetscInt i,maxlocal,nroots,nleaves,*globals,*ltog; 168a4d96a55SJed Brown const PetscInt *ilocal; 169a4d96a55SJed Brown MPI_Comm comm; 170a4d96a55SJed Brown 171a4d96a55SJed Brown PetscFunctionBegin; 172a4d96a55SJed Brown PetscValidHeaderSpecific(sf,PETSCSF_CLASSID,1); 173a4d96a55SJed Brown PetscValidPointer(mapping,3); 174a4d96a55SJed Brown 175a4d96a55SJed Brown ierr = PetscObjectGetComm((PetscObject)sf,&comm);CHKERRQ(ierr); 1760298fd71SBarry Smith ierr = PetscSFGetGraph(sf,&nroots,&nleaves,&ilocal,NULL);CHKERRQ(ierr); 177f6e5521dSKarl Rupp if (ilocal) { 178f6e5521dSKarl Rupp for (i=0,maxlocal=0; i<nleaves; i++) maxlocal = PetscMax(maxlocal,ilocal[i]+1); 179f6e5521dSKarl Rupp } 180a4d96a55SJed Brown else maxlocal = nleaves; 181a4d96a55SJed Brown ierr = PetscMalloc(nroots*sizeof(PetscInt),&globals);CHKERRQ(ierr); 182a4d96a55SJed Brown ierr = PetscMalloc(maxlocal*sizeof(PetscInt),<og);CHKERRQ(ierr); 183a4d96a55SJed Brown for (i=0; i<nroots; i++) globals[i] = start + i; 184a4d96a55SJed Brown for (i=0; i<maxlocal; i++) ltog[i] = -1; 185a4d96a55SJed Brown ierr = PetscSFBcastBegin(sf,MPIU_INT,globals,ltog);CHKERRQ(ierr); 186a4d96a55SJed Brown ierr = PetscSFBcastEnd(sf,MPIU_INT,globals,ltog);CHKERRQ(ierr); 187a4d96a55SJed Brown ierr = ISLocalToGlobalMappingCreate(comm,maxlocal,ltog,PETSC_OWN_POINTER,mapping);CHKERRQ(ierr); 188a4d96a55SJed Brown ierr = PetscFree(globals);CHKERRQ(ierr); 189a4d96a55SJed Brown PetscFunctionReturn(0); 190a4d96a55SJed Brown } 191b46b645bSBarry Smith 1924a2ae208SSatish Balay #undef __FUNCT__ 1934a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreate" 194ba5bb76aSSatish Balay /*@ 19590f02eecSBarry Smith ISLocalToGlobalMappingCreate - Creates a mapping between a local (0 to n) 19690f02eecSBarry Smith ordering and a global parallel ordering. 1972362add9SBarry Smith 19889d82c54SBarry Smith Not Collective, but communicator may have more than one process 199b9cd556bSLois Curfman McInnes 2002362add9SBarry Smith Input Parameters: 20189d82c54SBarry Smith + comm - MPI communicator 20290f02eecSBarry Smith . n - the number of local elements 2039669e4d8SBarry Smith . indices - the global index for each local element, these do not need to be in increasing order (sorted) 204d5ad8652SBarry Smith - mode - see PetscCopyMode 2052362add9SBarry Smith 206a997ad1aSLois Curfman McInnes Output Parameter: 20790f02eecSBarry Smith . mapping - new mapping data structure 2082362add9SBarry Smith 209a997ad1aSLois Curfman McInnes Level: advanced 210a997ad1aSLois Curfman McInnes 211273d9f13SBarry Smith Concepts: mapping^local to global 2122362add9SBarry Smith 213d5ad8652SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS() 2142362add9SBarry Smith @*/ 2157087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingCreate(MPI_Comm cm,PetscInt n,const PetscInt indices[],PetscCopyMode mode,ISLocalToGlobalMapping *mapping) 2162362add9SBarry Smith { 2176849ba73SBarry Smith PetscErrorCode ierr; 21832dcc486SBarry Smith PetscInt *in; 219b46b645bSBarry Smith 220b46b645bSBarry Smith PetscFunctionBegin; 22173911063SBarry Smith if (n) PetscValidIntPointer(indices,3); 2224482741eSBarry Smith PetscValidPointer(mapping,4); 223b46b645bSBarry Smith 2240298fd71SBarry Smith *mapping = NULL; 225519f805aSKarl Rupp #if !defined(PETSC_USE_DYNAMIC_LIBRARIES) 226607a6623SBarry Smith ierr = ISInitializePackage();CHKERRQ(ierr); 2278e58c17dSMatthew Knepley #endif 2282362add9SBarry Smith 22967c2884eSBarry Smith ierr = PetscHeaderCreate(*mapping,_p_ISLocalToGlobalMapping,int,IS_LTOGM_CLASSID,"ISLocalToGlobalMapping","Local to global mapping","IS", 23052e6d16bSBarry Smith cm,ISLocalToGlobalMappingDestroy,ISLocalToGlobalMappingView);CHKERRQ(ierr); 231d4bb536fSBarry Smith (*mapping)->n = n; 232d4bb536fSBarry Smith /* 233d4bb536fSBarry Smith Do not create the global to local mapping. This is only created if 234d4bb536fSBarry Smith ISGlobalToLocalMapping() is called 235d4bb536fSBarry Smith */ 236d4bb536fSBarry Smith (*mapping)->globals = 0; 237d5ad8652SBarry Smith if (mode == PETSC_COPY_VALUES) { 238d5ad8652SBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&in);CHKERRQ(ierr); 239d5ad8652SBarry Smith ierr = PetscMemcpy(in,indices,n*sizeof(PetscInt));CHKERRQ(ierr); 2403bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)*mapping,n*sizeof(PetscInt));CHKERRQ(ierr); 241d5ad8652SBarry Smith (*mapping)->indices = in; 242f6e5521dSKarl Rupp } else if (mode == PETSC_OWN_POINTER) (*mapping)->indices = (PetscInt*)indices; 243f6e5521dSKarl Rupp else SETERRQ(cm,PETSC_ERR_SUP,"Cannot currently use PETSC_USE_POINTER"); 2443a40ed3dSBarry Smith PetscFunctionReturn(0); 2452362add9SBarry Smith } 2462362add9SBarry Smith 2474a2ae208SSatish Balay #undef __FUNCT__ 2484a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingBlock" 249bce096a4SSatish Balay /*@ 250323b833fSBarry Smith ISLocalToGlobalMappingBlock - Creates a blocked index version of an 251323b833fSBarry Smith ISLocalToGlobalMapping that is appropriate for MatSetLocalToGlobalMappingBlock() 252323b833fSBarry Smith and VecSetLocalToGlobalMappingBlock(). 253323b833fSBarry Smith 254323b833fSBarry Smith Not Collective, but communicator may have more than one process 255323b833fSBarry Smith 256323b833fSBarry Smith Input Parameters: 257323b833fSBarry Smith + inmap - original point-wise mapping 258323b833fSBarry Smith - bs - block size 259323b833fSBarry Smith 260323b833fSBarry Smith Output Parameter: 26169eb54c3SBarry Smith . outmap - block based mapping; the indices are relative to BLOCKS, not individual vector or matrix entries. 262323b833fSBarry Smith 263323b833fSBarry Smith Level: advanced 264323b833fSBarry Smith 265323b833fSBarry Smith Concepts: mapping^local to global 266323b833fSBarry Smith 267323b833fSBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingCreateIS() 268323b833fSBarry Smith @*/ 2697087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingBlock(ISLocalToGlobalMapping inmap,PetscInt bs,ISLocalToGlobalMapping *outmap) 270323b833fSBarry Smith { 2716849ba73SBarry Smith PetscErrorCode ierr; 27232dcc486SBarry Smith PetscInt *ii,i,n; 273323b833fSBarry Smith 274323b833fSBarry Smith PetscFunctionBegin; 2750700a824SBarry Smith PetscValidHeaderSpecific(inmap,IS_LTOGM_CLASSID,1); 276b2beed0aSJed Brown PetscValidPointer(outmap,3); 277323b833fSBarry Smith if (bs > 1) { 278323b833fSBarry Smith n = inmap->n/bs; 279e32f2f54SBarry Smith if (n*bs != inmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Pointwise mapping length is not divisible by block size"); 28032dcc486SBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&ii);CHKERRQ(ierr); 281f6e5521dSKarl Rupp for (i=0; i<n; i++) ii[i] = inmap->indices[bs*i]/bs; 282ce94432eSBarry Smith ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)inmap),n,ii,PETSC_OWN_POINTER,outmap);CHKERRQ(ierr); 283323b833fSBarry Smith } else { 284323b833fSBarry Smith ierr = PetscObjectReference((PetscObject)inmap);CHKERRQ(ierr); 285c3122656SLisandro Dalcin *outmap = inmap; 286323b833fSBarry Smith } 287323b833fSBarry Smith PetscFunctionReturn(0); 288323b833fSBarry Smith } 289323b833fSBarry Smith 2904a2ae208SSatish Balay #undef __FUNCT__ 2918ab951edSJed Brown #define __FUNCT__ "ISLocalToGlobalMappingUnBlock" 292b2beed0aSJed Brown /*@ 293b2beed0aSJed Brown ISLocalToGlobalMappingUnBlock - Creates a scalar index version of a blocked 294b2beed0aSJed Brown ISLocalToGlobalMapping 295b2beed0aSJed Brown 296b2beed0aSJed Brown Not Collective, but communicator may have more than one process 297b2beed0aSJed Brown 298b2beed0aSJed Brown Input Parameter: 299b2beed0aSJed Brown + inmap - block based mapping; the indices are relative to BLOCKS, not individual vector or matrix entries. 300b2beed0aSJed Brown - bs - block size 301b2beed0aSJed Brown 302b2beed0aSJed Brown Output Parameter: 303b2beed0aSJed Brown . outmap - pointwise mapping 304b2beed0aSJed Brown 305b2beed0aSJed Brown Level: advanced 306b2beed0aSJed Brown 307b2beed0aSJed Brown Concepts: mapping^local to global 308b2beed0aSJed Brown 309b2beed0aSJed Brown .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingBlock() 310b2beed0aSJed Brown @*/ 3117087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingUnBlock(ISLocalToGlobalMapping inmap,PetscInt bs,ISLocalToGlobalMapping *outmap) 312b2beed0aSJed Brown { 313b2beed0aSJed Brown PetscErrorCode ierr; 314b2beed0aSJed Brown PetscInt *ii,i,n; 315b2beed0aSJed Brown 316b2beed0aSJed Brown PetscFunctionBegin; 317b2beed0aSJed Brown PetscValidHeaderSpecific(inmap,IS_LTOGM_CLASSID,1); 318b2beed0aSJed Brown PetscValidPointer(outmap,2); 319b2beed0aSJed Brown if (bs > 1) { 320b2beed0aSJed Brown n = inmap->n*bs; 321b2beed0aSJed Brown ierr = PetscMalloc(n*sizeof(PetscInt),&ii);CHKERRQ(ierr); 322f6e5521dSKarl Rupp for (i=0; i<n; i++) ii[i] = inmap->indices[i/bs]*bs + (i%bs); 323ce94432eSBarry Smith ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)inmap),n,ii,PETSC_OWN_POINTER,outmap);CHKERRQ(ierr); 324b2beed0aSJed Brown } else { 325b2beed0aSJed Brown ierr = PetscObjectReference((PetscObject)inmap);CHKERRQ(ierr); 326b2beed0aSJed Brown *outmap = inmap; 327b2beed0aSJed Brown } 328b2beed0aSJed Brown PetscFunctionReturn(0); 329b2beed0aSJed Brown } 330b2beed0aSJed Brown 331b2beed0aSJed Brown #undef __FUNCT__ 3324a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingDestroy" 33390f02eecSBarry Smith /*@ 33490f02eecSBarry Smith ISLocalToGlobalMappingDestroy - Destroys a mapping between a local (0 to n) 33590f02eecSBarry Smith ordering and a global parallel ordering. 33690f02eecSBarry Smith 3370f5bd95cSBarry Smith Note Collective 338b9cd556bSLois Curfman McInnes 33990f02eecSBarry Smith Input Parameters: 34090f02eecSBarry Smith . mapping - mapping data structure 34190f02eecSBarry Smith 342a997ad1aSLois Curfman McInnes Level: advanced 343a997ad1aSLois Curfman McInnes 3443acfe500SLois Curfman McInnes .seealso: ISLocalToGlobalMappingCreate() 34590f02eecSBarry Smith @*/ 3466bf464f9SBarry Smith PetscErrorCode ISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping *mapping) 34790f02eecSBarry Smith { 348dfbe8321SBarry Smith PetscErrorCode ierr; 3495fd66863SKarl Rupp 3503a40ed3dSBarry Smith PetscFunctionBegin; 3516bf464f9SBarry Smith if (!*mapping) PetscFunctionReturn(0); 3526bf464f9SBarry Smith PetscValidHeaderSpecific((*mapping),IS_LTOGM_CLASSID,1); 353997056adSBarry Smith if (--((PetscObject)(*mapping))->refct > 0) {*mapping = 0;PetscFunctionReturn(0);} 3546bf464f9SBarry Smith ierr = PetscFree((*mapping)->indices);CHKERRQ(ierr); 3556bf464f9SBarry Smith ierr = PetscFree((*mapping)->globals);CHKERRQ(ierr); 356d38fa0fbSBarry Smith ierr = PetscHeaderDestroy(mapping);CHKERRQ(ierr); 357992144d0SBarry Smith *mapping = 0; 3583a40ed3dSBarry Smith PetscFunctionReturn(0); 35990f02eecSBarry Smith } 36090f02eecSBarry Smith 3614a2ae208SSatish Balay #undef __FUNCT__ 3624a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingApplyIS" 36390f02eecSBarry Smith /*@ 3643acfe500SLois Curfman McInnes ISLocalToGlobalMappingApplyIS - Creates from an IS in the local numbering 3653acfe500SLois Curfman McInnes a new index set using the global numbering defined in an ISLocalToGlobalMapping 3663acfe500SLois Curfman McInnes context. 36790f02eecSBarry Smith 368b9cd556bSLois Curfman McInnes Not collective 369b9cd556bSLois Curfman McInnes 37090f02eecSBarry Smith Input Parameters: 371b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 372b9cd556bSLois Curfman McInnes - is - index set in local numbering 37390f02eecSBarry Smith 37490f02eecSBarry Smith Output Parameters: 37590f02eecSBarry Smith . newis - index set in global numbering 37690f02eecSBarry Smith 377a997ad1aSLois Curfman McInnes Level: advanced 378a997ad1aSLois Curfman McInnes 379273d9f13SBarry Smith Concepts: mapping^local to global 3803acfe500SLois Curfman McInnes 38190f02eecSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 382d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy(), ISGlobalToLocalMappingApply() 38390f02eecSBarry Smith @*/ 3847087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping mapping,IS is,IS *newis) 38590f02eecSBarry Smith { 3866849ba73SBarry Smith PetscErrorCode ierr; 3875d0c19d7SBarry Smith PetscInt n,i,*idxmap,*idxout,Nmax = mapping->n; 3885d0c19d7SBarry Smith const PetscInt *idxin; 3893a40ed3dSBarry Smith 3903a40ed3dSBarry Smith PetscFunctionBegin; 3910700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 3920700a824SBarry Smith PetscValidHeaderSpecific(is,IS_CLASSID,2); 3934482741eSBarry Smith PetscValidPointer(newis,3); 39490f02eecSBarry Smith 3953b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 39690f02eecSBarry Smith ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 39790f02eecSBarry Smith idxmap = mapping->indices; 39890f02eecSBarry Smith 3997c334f02SBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&idxout);CHKERRQ(ierr); 40090f02eecSBarry Smith for (i=0; i<n; i++) { 401e32f2f54SBarry Smith if (idxin[i] >= Nmax) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local index %d too large %d (max) at %d",idxin[i],Nmax-1,i); 40290f02eecSBarry Smith idxout[i] = idxmap[idxin[i]]; 40390f02eecSBarry Smith } 4043b9aefa3SBarry Smith ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 40570b3c8c7SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxout,PETSC_OWN_POINTER,newis);CHKERRQ(ierr); 4063a40ed3dSBarry Smith PetscFunctionReturn(0); 40790f02eecSBarry Smith } 40890f02eecSBarry Smith 409afcb2eb5SJed Brown #undef __FUNCT__ 410afcb2eb5SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingApply" 411b89cb25eSSatish Balay /*@ 4123acfe500SLois Curfman McInnes ISLocalToGlobalMappingApply - Takes a list of integers in a local numbering 4133acfe500SLois Curfman McInnes and converts them to the global numbering. 41490f02eecSBarry Smith 415b9cd556bSLois Curfman McInnes Not collective 416b9cd556bSLois Curfman McInnes 417bb25748dSBarry Smith Input Parameters: 418b9cd556bSLois Curfman McInnes + mapping - the local to global mapping context 419bb25748dSBarry Smith . N - number of integers 420b9cd556bSLois Curfman McInnes - in - input indices in local numbering 421bb25748dSBarry Smith 422bb25748dSBarry Smith Output Parameter: 423bb25748dSBarry Smith . out - indices in global numbering 424bb25748dSBarry Smith 425b9cd556bSLois Curfman McInnes Notes: 426b9cd556bSLois Curfman McInnes The in and out array parameters may be identical. 427d4bb536fSBarry Smith 428a997ad1aSLois Curfman McInnes Level: advanced 429a997ad1aSLois Curfman McInnes 430bb25748dSBarry Smith .seealso: ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 4310752156aSBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 432d4bb536fSBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 433bb25748dSBarry Smith 434273d9f13SBarry Smith Concepts: mapping^local to global 435afcb2eb5SJed Brown @*/ 436afcb2eb5SJed Brown PetscErrorCode ISLocalToGlobalMappingApply(ISLocalToGlobalMapping mapping,PetscInt N,const PetscInt in[],PetscInt out[]) 437afcb2eb5SJed Brown { 438afcb2eb5SJed Brown PetscInt i,Nmax = mapping->n; 439afcb2eb5SJed Brown const PetscInt *idx = mapping->indices; 440d4bb536fSBarry Smith 441afcb2eb5SJed Brown PetscFunctionBegin; 442afcb2eb5SJed Brown for (i=0; i<N; i++) { 443afcb2eb5SJed Brown if (in[i] < 0) { 444afcb2eb5SJed Brown out[i] = in[i]; 445afcb2eb5SJed Brown continue; 446afcb2eb5SJed Brown } 447afcb2eb5SJed Brown if (in[i] >= Nmax) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local index %D too large %D (max) at %D",in[i],Nmax,i); 448afcb2eb5SJed Brown out[i] = idx[in[i]]; 449afcb2eb5SJed Brown } 450afcb2eb5SJed Brown PetscFunctionReturn(0); 451afcb2eb5SJed Brown } 452d4bb536fSBarry Smith 453d4bb536fSBarry Smith /* -----------------------------------------------------------------------------------------*/ 454d4bb536fSBarry Smith 4554a2ae208SSatish Balay #undef __FUNCT__ 4564a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingSetUp_Private" 457d4bb536fSBarry Smith /* 458d4bb536fSBarry Smith Creates the global fields in the ISLocalToGlobalMapping structure 459d4bb536fSBarry Smith */ 4606849ba73SBarry Smith static PetscErrorCode ISGlobalToLocalMappingSetUp_Private(ISLocalToGlobalMapping mapping) 461d4bb536fSBarry Smith { 4626849ba73SBarry Smith PetscErrorCode ierr; 46332dcc486SBarry Smith PetscInt i,*idx = mapping->indices,n = mapping->n,end,start,*globals; 464d4bb536fSBarry Smith 4653a40ed3dSBarry Smith PetscFunctionBegin; 466d4bb536fSBarry Smith end = 0; 467ec268f7cSJed Brown start = PETSC_MAX_INT; 468d4bb536fSBarry Smith 469d4bb536fSBarry Smith for (i=0; i<n; i++) { 470d4bb536fSBarry Smith if (idx[i] < 0) continue; 471d4bb536fSBarry Smith if (idx[i] < start) start = idx[i]; 472d4bb536fSBarry Smith if (idx[i] > end) end = idx[i]; 473d4bb536fSBarry Smith } 474d4bb536fSBarry Smith if (start > end) {start = 0; end = -1;} 475d4bb536fSBarry Smith mapping->globalstart = start; 476d4bb536fSBarry Smith mapping->globalend = end; 477d4bb536fSBarry Smith 47832dcc486SBarry Smith ierr = PetscMalloc((end-start+2)*sizeof(PetscInt),&globals);CHKERRQ(ierr); 479b0a32e0cSBarry Smith mapping->globals = globals; 480f6e5521dSKarl Rupp for (i=0; i<end-start+1; i++) globals[i] = -1; 481d4bb536fSBarry Smith for (i=0; i<n; i++) { 482d4bb536fSBarry Smith if (idx[i] < 0) continue; 483d4bb536fSBarry Smith globals[idx[i] - start] = i; 484d4bb536fSBarry Smith } 485d4bb536fSBarry Smith 4863bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mapping,(end-start+1)*sizeof(PetscInt));CHKERRQ(ierr); 4873a40ed3dSBarry Smith PetscFunctionReturn(0); 488d4bb536fSBarry Smith } 489d4bb536fSBarry Smith 4904a2ae208SSatish Balay #undef __FUNCT__ 4914a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingApply" 492d4bb536fSBarry Smith /*@ 493a997ad1aSLois Curfman McInnes ISGlobalToLocalMappingApply - Provides the local numbering for a list of integers 494a997ad1aSLois Curfman McInnes specified with a global numbering. 495d4bb536fSBarry Smith 496b9cd556bSLois Curfman McInnes Not collective 497b9cd556bSLois Curfman McInnes 498d4bb536fSBarry Smith Input Parameters: 499b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 500d4bb536fSBarry Smith . type - IS_GTOLM_MASK - replaces global indices with no local value with -1 501d4bb536fSBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 502d4bb536fSBarry Smith . n - number of global indices to map 503b9cd556bSLois Curfman McInnes - idx - global indices to map 504d4bb536fSBarry Smith 505d4bb536fSBarry Smith Output Parameters: 506b9cd556bSLois Curfman McInnes + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 507b9cd556bSLois Curfman McInnes - idxout - local index of each global index, one must pass in an array long enough 508e182c471SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApply() with 5090298fd71SBarry Smith idxout == NULL to determine the required length (returned in nout) 510e182c471SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApply() 511e182c471SBarry Smith a second time to set the values. 512d4bb536fSBarry Smith 513b9cd556bSLois Curfman McInnes Notes: 5140298fd71SBarry Smith Either nout or idxout may be NULL. idx and idxout may be identical. 515d4bb536fSBarry Smith 5160f5bd95cSBarry Smith This is not scalable in memory usage. Each processor requires O(Nglobal) size 5170f5bd95cSBarry Smith array to compute these. 5180f5bd95cSBarry Smith 519a997ad1aSLois Curfman McInnes Level: advanced 520a997ad1aSLois Curfman McInnes 52132fd6b96SBarry Smith Developer Note: The manual page states that idx and idxout may be identical but the calling 52232fd6b96SBarry Smith sequence declares idx as const so it cannot be the same as idxout. 52332fd6b96SBarry Smith 524273d9f13SBarry Smith Concepts: mapping^global to local 525d4bb536fSBarry Smith 526d4bb536fSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 527d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy() 528d4bb536fSBarry Smith @*/ 5297087cfbeSBarry Smith PetscErrorCode ISGlobalToLocalMappingApply(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, 53032dcc486SBarry Smith PetscInt n,const PetscInt idx[],PetscInt *nout,PetscInt idxout[]) 531d4bb536fSBarry Smith { 53232dcc486SBarry Smith PetscInt i,*globals,nf = 0,tmp,start,end; 5336849ba73SBarry Smith PetscErrorCode ierr; 534d4bb536fSBarry Smith 5353a40ed3dSBarry Smith PetscFunctionBegin; 5360700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 537d4bb536fSBarry Smith if (!mapping->globals) { 538d4bb536fSBarry Smith ierr = ISGlobalToLocalMappingSetUp_Private(mapping);CHKERRQ(ierr); 539d4bb536fSBarry Smith } 540d4bb536fSBarry Smith globals = mapping->globals; 541d4bb536fSBarry Smith start = mapping->globalstart; 542d4bb536fSBarry Smith end = mapping->globalend; 543d4bb536fSBarry Smith 544d4bb536fSBarry Smith if (type == IS_GTOLM_MASK) { 545d4bb536fSBarry Smith if (idxout) { 546d4bb536fSBarry Smith for (i=0; i<n; i++) { 547d4bb536fSBarry Smith if (idx[i] < 0) idxout[i] = idx[i]; 548d4bb536fSBarry Smith else if (idx[i] < start) idxout[i] = -1; 549d4bb536fSBarry Smith else if (idx[i] > end) idxout[i] = -1; 550d4bb536fSBarry Smith else idxout[i] = globals[idx[i] - start]; 551d4bb536fSBarry Smith } 552d4bb536fSBarry Smith } 553d4bb536fSBarry Smith if (nout) *nout = n; 554d4bb536fSBarry Smith } else { 555d4bb536fSBarry Smith if (idxout) { 556d4bb536fSBarry Smith for (i=0; i<n; i++) { 557d4bb536fSBarry Smith if (idx[i] < 0) continue; 558d4bb536fSBarry Smith if (idx[i] < start) continue; 559d4bb536fSBarry Smith if (idx[i] > end) continue; 560d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 561d4bb536fSBarry Smith if (tmp < 0) continue; 562d4bb536fSBarry Smith idxout[nf++] = tmp; 563d4bb536fSBarry Smith } 564d4bb536fSBarry Smith } else { 565d4bb536fSBarry Smith for (i=0; i<n; i++) { 566d4bb536fSBarry Smith if (idx[i] < 0) continue; 567d4bb536fSBarry Smith if (idx[i] < start) continue; 568d4bb536fSBarry Smith if (idx[i] > end) continue; 569d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 570d4bb536fSBarry Smith if (tmp < 0) continue; 571d4bb536fSBarry Smith nf++; 572d4bb536fSBarry Smith } 573d4bb536fSBarry Smith } 574d4bb536fSBarry Smith if (nout) *nout = nf; 575d4bb536fSBarry Smith } 5763a40ed3dSBarry Smith PetscFunctionReturn(0); 577d4bb536fSBarry Smith } 57890f02eecSBarry Smith 5794a2ae208SSatish Balay #undef __FUNCT__ 5804a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingGetInfo" 58189d82c54SBarry Smith /*@C 58289d82c54SBarry Smith ISLocalToGlobalMappingGetInfo - Gets the neighbor information for each processor and 58389d82c54SBarry Smith each index shared by more than one processor 58489d82c54SBarry Smith 58589d82c54SBarry Smith Collective on ISLocalToGlobalMapping 58689d82c54SBarry Smith 58789d82c54SBarry Smith Input Parameters: 58889d82c54SBarry Smith . mapping - the mapping from local to global indexing 58989d82c54SBarry Smith 59089d82c54SBarry Smith Output Parameter: 59189d82c54SBarry Smith + nproc - number of processors that are connected to this one 59289d82c54SBarry Smith . proc - neighboring processors 59307b52d57SBarry Smith . numproc - number of indices for each subdomain (processor) 5943463a7baSJed Brown - indices - indices of nodes (in local numbering) shared with neighbors (sorted by global numbering) 59589d82c54SBarry Smith 59689d82c54SBarry Smith Level: advanced 59789d82c54SBarry Smith 598273d9f13SBarry Smith Concepts: mapping^local to global 59989d82c54SBarry Smith 6002cfcea29SBarry Smith Fortran Usage: 6012cfcea29SBarry Smith $ ISLocalToGlobalMpngGetInfoSize(ISLocalToGlobalMapping,PetscInt nproc,PetscInt numprocmax,ierr) followed by 6022cfcea29SBarry Smith $ ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping,PetscInt nproc, PetscInt procs[nproc],PetscInt numprocs[nproc], 6032cfcea29SBarry Smith PetscInt indices[nproc][numprocmax],ierr) 6042cfcea29SBarry Smith There is no ISLocalToGlobalMappingRestoreInfo() in Fortran. You must make sure that procs[], numprocs[] and 6052cfcea29SBarry Smith indices[][] are large enough arrays, either by allocating them dynamically or defining static ones large enough. 6062cfcea29SBarry Smith 6072cfcea29SBarry Smith 60807b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 60907b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo() 61089d82c54SBarry Smith @*/ 6117087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 61289d82c54SBarry Smith { 6136849ba73SBarry Smith PetscErrorCode ierr; 61497f1f81fSBarry Smith PetscMPIInt size,rank,tag1,tag2,tag3,*len,*source,imdex; 61532dcc486SBarry Smith PetscInt i,n = mapping->n,Ng,ng,max = 0,*lindices = mapping->indices; 61632dcc486SBarry Smith PetscInt *nprocs,*owner,nsends,*sends,j,*starts,nmax,nrecvs,*recvs,proc; 61797f1f81fSBarry Smith PetscInt cnt,scale,*ownedsenders,*nownedsenders,rstart,nowned; 61832dcc486SBarry Smith PetscInt node,nownedm,nt,*sends2,nsends2,*starts2,*lens2,*dest,nrecvs2,*starts3,*recvs2,k,*bprocs,*tmp; 61932dcc486SBarry Smith PetscInt first_procs,first_numprocs,*first_indices; 62089d82c54SBarry Smith MPI_Request *recv_waits,*send_waits; 62130dcb7c9SBarry Smith MPI_Status recv_status,*send_status,*recv_statuses; 622ce94432eSBarry Smith MPI_Comm comm; 623ace3abfcSBarry Smith PetscBool debug = PETSC_FALSE; 62489d82c54SBarry Smith 62589d82c54SBarry Smith PetscFunctionBegin; 6260700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 627ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)mapping,&comm);CHKERRQ(ierr); 62824cf384cSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 62924cf384cSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 63024cf384cSBarry Smith if (size == 1) { 63124cf384cSBarry Smith *nproc = 0; 6320298fd71SBarry Smith *procs = NULL; 63332dcc486SBarry Smith ierr = PetscMalloc(sizeof(PetscInt),numprocs);CHKERRQ(ierr); 6341e2105dcSBarry Smith (*numprocs)[0] = 0; 63532dcc486SBarry Smith ierr = PetscMalloc(sizeof(PetscInt*),indices);CHKERRQ(ierr); 6360298fd71SBarry Smith (*indices)[0] = NULL; 63724cf384cSBarry Smith PetscFunctionReturn(0); 63824cf384cSBarry Smith } 63924cf384cSBarry Smith 6400298fd71SBarry Smith ierr = PetscOptionsGetBool(NULL,"-islocaltoglobalmappinggetinfo_debug",&debug,NULL);CHKERRQ(ierr); 64107b52d57SBarry Smith 6423677ff5aSBarry Smith /* 6433677ff5aSBarry Smith Notes on ISLocalToGlobalMappingGetInfo 6443677ff5aSBarry Smith 6453677ff5aSBarry Smith globally owned node - the nodes that have been assigned to this processor in global 6463677ff5aSBarry Smith numbering, just for this routine. 6473677ff5aSBarry Smith 6483677ff5aSBarry Smith nontrivial globally owned node - node assigned to this processor that is on a subdomain 6493677ff5aSBarry Smith boundary (i.e. is has more than one local owner) 6503677ff5aSBarry Smith 6513677ff5aSBarry Smith locally owned node - node that exists on this processors subdomain 6523677ff5aSBarry Smith 6533677ff5aSBarry Smith nontrivial locally owned node - node that is not in the interior (i.e. has more than one 6543677ff5aSBarry Smith local subdomain 6553677ff5aSBarry Smith */ 65624cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag1);CHKERRQ(ierr); 65724cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag2);CHKERRQ(ierr); 65824cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag3);CHKERRQ(ierr); 65989d82c54SBarry Smith 66089d82c54SBarry Smith for (i=0; i<n; i++) { 66189d82c54SBarry Smith if (lindices[i] > max) max = lindices[i]; 66289d82c54SBarry Smith } 66332dcc486SBarry Smith ierr = MPI_Allreduce(&max,&Ng,1,MPIU_INT,MPI_MAX,comm);CHKERRQ(ierr); 66478058e43SBarry Smith Ng++; 66589d82c54SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 66689d82c54SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 667bc8ff85bSBarry Smith scale = Ng/size + 1; 668a2e34c3dSBarry Smith ng = scale; if (rank == size-1) ng = Ng - scale*(size-1); ng = PetscMax(1,ng); 669caba0dd0SBarry Smith rstart = scale*rank; 67089d82c54SBarry Smith 67189d82c54SBarry Smith /* determine ownership ranges of global indices */ 6727c334f02SBarry Smith ierr = PetscMalloc(2*size*sizeof(PetscInt),&nprocs);CHKERRQ(ierr); 67332dcc486SBarry Smith ierr = PetscMemzero(nprocs,2*size*sizeof(PetscInt));CHKERRQ(ierr); 67489d82c54SBarry Smith 67589d82c54SBarry Smith /* determine owners of each local node */ 6767c334f02SBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&owner);CHKERRQ(ierr); 67789d82c54SBarry Smith for (i=0; i<n; i++) { 6783677ff5aSBarry Smith proc = lindices[i]/scale; /* processor that globally owns this index */ 67927c402fcSBarry Smith nprocs[2*proc+1] = 1; /* processor globally owns at least one of ours */ 6803677ff5aSBarry Smith owner[i] = proc; 68127c402fcSBarry Smith nprocs[2*proc]++; /* count of how many that processor globally owns of ours */ 68289d82c54SBarry Smith } 68327c402fcSBarry Smith nsends = 0; for (i=0; i<size; i++) nsends += nprocs[2*i+1]; 6841e2582c4SBarry Smith ierr = PetscInfo1(mapping,"Number of global owners for my local data %d\n",nsends);CHKERRQ(ierr); 68589d82c54SBarry Smith 68689d82c54SBarry Smith /* inform other processors of number of messages and max length*/ 68727c402fcSBarry Smith ierr = PetscMaxSum(comm,nprocs,&nmax,&nrecvs);CHKERRQ(ierr); 6881e2582c4SBarry Smith ierr = PetscInfo1(mapping,"Number of local owners for my global data %d\n",nrecvs);CHKERRQ(ierr); 68989d82c54SBarry Smith 69089d82c54SBarry Smith /* post receives for owned rows */ 69132dcc486SBarry Smith ierr = PetscMalloc((2*nrecvs+1)*(nmax+1)*sizeof(PetscInt),&recvs);CHKERRQ(ierr); 692b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs+1)*sizeof(MPI_Request),&recv_waits);CHKERRQ(ierr); 69389d82c54SBarry Smith for (i=0; i<nrecvs; i++) { 69432dcc486SBarry Smith ierr = MPI_Irecv(recvs+2*nmax*i,2*nmax,MPIU_INT,MPI_ANY_SOURCE,tag1,comm,recv_waits+i);CHKERRQ(ierr); 69589d82c54SBarry Smith } 69689d82c54SBarry Smith 69789d82c54SBarry Smith /* pack messages containing lists of local nodes to owners */ 69832dcc486SBarry Smith ierr = PetscMalloc((2*n+1)*sizeof(PetscInt),&sends);CHKERRQ(ierr); 69932dcc486SBarry Smith ierr = PetscMalloc((size+1)*sizeof(PetscInt),&starts);CHKERRQ(ierr); 70089d82c54SBarry Smith starts[0] = 0; 701f6e5521dSKarl Rupp for (i=1; i<size; i++) starts[i] = starts[i-1] + 2*nprocs[2*i-2]; 70289d82c54SBarry Smith for (i=0; i<n; i++) { 70389d82c54SBarry Smith sends[starts[owner[i]]++] = lindices[i]; 70430dcb7c9SBarry Smith sends[starts[owner[i]]++] = i; 70589d82c54SBarry Smith } 70689d82c54SBarry Smith ierr = PetscFree(owner);CHKERRQ(ierr); 70789d82c54SBarry Smith starts[0] = 0; 708f6e5521dSKarl Rupp for (i=1; i<size; i++) starts[i] = starts[i-1] + 2*nprocs[2*i-2]; 70989d82c54SBarry Smith 71089d82c54SBarry Smith /* send the messages */ 711b0a32e0cSBarry Smith ierr = PetscMalloc((nsends+1)*sizeof(MPI_Request),&send_waits);CHKERRQ(ierr); 71232dcc486SBarry Smith ierr = PetscMalloc((nsends+1)*sizeof(PetscInt),&dest);CHKERRQ(ierr); 71389d82c54SBarry Smith cnt = 0; 71489d82c54SBarry Smith for (i=0; i<size; i++) { 71527c402fcSBarry Smith if (nprocs[2*i]) { 71632dcc486SBarry Smith ierr = MPI_Isend(sends+starts[i],2*nprocs[2*i],MPIU_INT,i,tag1,comm,send_waits+cnt);CHKERRQ(ierr); 71730dcb7c9SBarry Smith dest[cnt] = i; 71889d82c54SBarry Smith cnt++; 71989d82c54SBarry Smith } 72089d82c54SBarry Smith } 72189d82c54SBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 72289d82c54SBarry Smith 72389d82c54SBarry Smith /* wait on receives */ 72497f1f81fSBarry Smith ierr = PetscMalloc((nrecvs+1)*sizeof(PetscMPIInt),&source);CHKERRQ(ierr); 72597f1f81fSBarry Smith ierr = PetscMalloc((nrecvs+1)*sizeof(PetscMPIInt),&len);CHKERRQ(ierr); 72689d82c54SBarry Smith cnt = nrecvs; 72732dcc486SBarry Smith ierr = PetscMalloc((ng+1)*sizeof(PetscInt),&nownedsenders);CHKERRQ(ierr); 72832dcc486SBarry Smith ierr = PetscMemzero(nownedsenders,ng*sizeof(PetscInt));CHKERRQ(ierr); 72989d82c54SBarry Smith while (cnt) { 73089d82c54SBarry Smith ierr = MPI_Waitany(nrecvs,recv_waits,&imdex,&recv_status);CHKERRQ(ierr); 73189d82c54SBarry Smith /* unpack receives into our local space */ 73232dcc486SBarry Smith ierr = MPI_Get_count(&recv_status,MPIU_INT,&len[imdex]);CHKERRQ(ierr); 73389d82c54SBarry Smith source[imdex] = recv_status.MPI_SOURCE; 73430dcb7c9SBarry Smith len[imdex] = len[imdex]/2; 735caba0dd0SBarry Smith /* count how many local owners for each of my global owned indices */ 73630dcb7c9SBarry Smith for (i=0; i<len[imdex]; i++) nownedsenders[recvs[2*imdex*nmax+2*i]-rstart]++; 73789d82c54SBarry Smith cnt--; 73889d82c54SBarry Smith } 73989d82c54SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 74089d82c54SBarry Smith 74130dcb7c9SBarry Smith /* count how many globally owned indices are on an edge multiplied by how many processors own them. */ 742bc8ff85bSBarry Smith nowned = 0; 743bc8ff85bSBarry Smith nownedm = 0; 744bc8ff85bSBarry Smith for (i=0; i<ng; i++) { 745bc8ff85bSBarry Smith if (nownedsenders[i] > 1) {nownedm += nownedsenders[i]; nowned++;} 746bc8ff85bSBarry Smith } 747bc8ff85bSBarry Smith 748bc8ff85bSBarry Smith /* create single array to contain rank of all local owners of each globally owned index */ 74932dcc486SBarry Smith ierr = PetscMalloc((nownedm+1)*sizeof(PetscInt),&ownedsenders);CHKERRQ(ierr); 75032dcc486SBarry Smith ierr = PetscMalloc((ng+1)*sizeof(PetscInt),&starts);CHKERRQ(ierr); 751bc8ff85bSBarry Smith starts[0] = 0; 752bc8ff85bSBarry Smith for (i=1; i<ng; i++) { 753bc8ff85bSBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 754bc8ff85bSBarry Smith else starts[i] = starts[i-1]; 755bc8ff85bSBarry Smith } 756bc8ff85bSBarry Smith 75730dcb7c9SBarry Smith /* for each nontrival globally owned node list all arriving processors */ 758bc8ff85bSBarry Smith for (i=0; i<nrecvs; i++) { 759bc8ff85bSBarry Smith for (j=0; j<len[i]; j++) { 76030dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 761f6e5521dSKarl Rupp if (nownedsenders[node] > 1) ownedsenders[starts[node]++] = source[i]; 762bc8ff85bSBarry Smith } 763bc8ff85bSBarry Smith } 764bc8ff85bSBarry Smith 76507b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 76630dcb7c9SBarry Smith starts[0] = 0; 76730dcb7c9SBarry Smith for (i=1; i<ng; i++) { 76830dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 76930dcb7c9SBarry Smith else starts[i] = starts[i-1]; 77030dcb7c9SBarry Smith } 77130dcb7c9SBarry Smith for (i=0; i<ng; i++) { 77230dcb7c9SBarry Smith if (nownedsenders[i] > 1) { 77330dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] global node %d local owner processors: ",rank,i+rstart);CHKERRQ(ierr); 77430dcb7c9SBarry Smith for (j=0; j<nownedsenders[i]; j++) { 77530dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",ownedsenders[starts[i]+j]);CHKERRQ(ierr); 77630dcb7c9SBarry Smith } 77730dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 77830dcb7c9SBarry Smith } 77930dcb7c9SBarry Smith } 78030dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 78107b52d57SBarry Smith } /* ----------------------------------- */ 78230dcb7c9SBarry Smith 7833677ff5aSBarry Smith /* wait on original sends */ 7843a96401aSBarry Smith if (nsends) { 785b0a32e0cSBarry Smith ierr = PetscMalloc(nsends*sizeof(MPI_Status),&send_status);CHKERRQ(ierr); 7863a96401aSBarry Smith ierr = MPI_Waitall(nsends,send_waits,send_status);CHKERRQ(ierr); 7873a96401aSBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 7883a96401aSBarry Smith } 78989d82c54SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 7903a96401aSBarry Smith ierr = PetscFree(sends);CHKERRQ(ierr); 7913677ff5aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 7923677ff5aSBarry Smith 7933677ff5aSBarry Smith /* pack messages to send back to local owners */ 79430dcb7c9SBarry Smith starts[0] = 0; 79530dcb7c9SBarry Smith for (i=1; i<ng; i++) { 79630dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 79730dcb7c9SBarry Smith else starts[i] = starts[i-1]; 79830dcb7c9SBarry Smith } 79930dcb7c9SBarry Smith nsends2 = nrecvs; 80032dcc486SBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(PetscInt),&nprocs);CHKERRQ(ierr); /* length of each message */ 80130dcb7c9SBarry Smith for (i=0; i<nrecvs; i++) { 80230dcb7c9SBarry Smith nprocs[i] = 1; 80330dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 80430dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 805f6e5521dSKarl Rupp if (nownedsenders[node] > 1) nprocs[i] += 2 + nownedsenders[node]; 80630dcb7c9SBarry Smith } 80730dcb7c9SBarry Smith } 808f6e5521dSKarl Rupp nt = 0; 809f6e5521dSKarl Rupp for (i=0; i<nsends2; i++) nt += nprocs[i]; 810f6e5521dSKarl Rupp 81132dcc486SBarry Smith ierr = PetscMalloc((nt+1)*sizeof(PetscInt),&sends2);CHKERRQ(ierr); 81232dcc486SBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(PetscInt),&starts2);CHKERRQ(ierr); 813f6e5521dSKarl Rupp 814f6e5521dSKarl Rupp starts2[0] = 0; 815f6e5521dSKarl Rupp for (i=1; i<nsends2; i++) starts2[i] = starts2[i-1] + nprocs[i-1]; 81630dcb7c9SBarry Smith /* 81730dcb7c9SBarry Smith Each message is 1 + nprocs[i] long, and consists of 81830dcb7c9SBarry Smith (0) the number of nodes being sent back 81930dcb7c9SBarry Smith (1) the local node number, 82030dcb7c9SBarry Smith (2) the number of processors sharing it, 82130dcb7c9SBarry Smith (3) the processors sharing it 82230dcb7c9SBarry Smith */ 82330dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 82430dcb7c9SBarry Smith cnt = 1; 82530dcb7c9SBarry Smith sends2[starts2[i]] = 0; 82630dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 82730dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 82830dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 82930dcb7c9SBarry Smith sends2[starts2[i]]++; 83030dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = recvs[2*i*nmax+2*j+1]; 83130dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = nownedsenders[node]; 83232dcc486SBarry Smith ierr = PetscMemcpy(&sends2[starts2[i]+cnt],&ownedsenders[starts[node]],nownedsenders[node]*sizeof(PetscInt));CHKERRQ(ierr); 83330dcb7c9SBarry Smith cnt += nownedsenders[node]; 83430dcb7c9SBarry Smith } 83530dcb7c9SBarry Smith } 83630dcb7c9SBarry Smith } 83730dcb7c9SBarry Smith 83830dcb7c9SBarry Smith /* receive the message lengths */ 83930dcb7c9SBarry Smith nrecvs2 = nsends; 84032dcc486SBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(PetscInt),&lens2);CHKERRQ(ierr); 84132dcc486SBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(PetscInt),&starts3);CHKERRQ(ierr); 842d44834fbSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(MPI_Request),&recv_waits);CHKERRQ(ierr); 84330dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 844d44834fbSBarry Smith ierr = MPI_Irecv(&lens2[i],1,MPIU_INT,dest[i],tag2,comm,recv_waits+i);CHKERRQ(ierr); 84530dcb7c9SBarry Smith } 846d44834fbSBarry Smith 8478a8e0b3aSBarry Smith /* send the message lengths */ 8488a8e0b3aSBarry Smith for (i=0; i<nsends2; i++) { 8498a8e0b3aSBarry Smith ierr = MPI_Send(&nprocs[i],1,MPIU_INT,source[i],tag2,comm);CHKERRQ(ierr); 8508a8e0b3aSBarry Smith } 8518a8e0b3aSBarry Smith 852d44834fbSBarry Smith /* wait on receives of lens */ 8530c468ba9SBarry Smith if (nrecvs2) { 8540c468ba9SBarry Smith ierr = PetscMalloc(nrecvs2*sizeof(MPI_Status),&recv_statuses);CHKERRQ(ierr); 855d44834fbSBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 856d44834fbSBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 8570c468ba9SBarry Smith } 858a2ea699eSBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 859d44834fbSBarry Smith 86030dcb7c9SBarry Smith starts3[0] = 0; 861d44834fbSBarry Smith nt = 0; 86230dcb7c9SBarry Smith for (i=0; i<nrecvs2-1; i++) { 86330dcb7c9SBarry Smith starts3[i+1] = starts3[i] + lens2[i]; 864d44834fbSBarry Smith nt += lens2[i]; 86530dcb7c9SBarry Smith } 86676466f69SStefano Zampini if (nrecvs2) nt += lens2[nrecvs2-1]; 867d44834fbSBarry Smith 86832dcc486SBarry Smith ierr = PetscMalloc((nt+1)*sizeof(PetscInt),&recvs2);CHKERRQ(ierr); 869b0a32e0cSBarry Smith ierr = PetscMalloc((nrecvs2+1)*sizeof(MPI_Request),&recv_waits);CHKERRQ(ierr); 87052b72c4aSBarry Smith for (i=0; i<nrecvs2; i++) { 87132dcc486SBarry Smith ierr = MPI_Irecv(recvs2+starts3[i],lens2[i],MPIU_INT,dest[i],tag3,comm,recv_waits+i);CHKERRQ(ierr); 87230dcb7c9SBarry Smith } 87330dcb7c9SBarry Smith 87430dcb7c9SBarry Smith /* send the messages */ 875b0a32e0cSBarry Smith ierr = PetscMalloc((nsends2+1)*sizeof(MPI_Request),&send_waits);CHKERRQ(ierr); 87630dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 87732dcc486SBarry Smith ierr = MPI_Isend(sends2+starts2[i],nprocs[i],MPIU_INT,source[i],tag3,comm,send_waits+i);CHKERRQ(ierr); 87830dcb7c9SBarry Smith } 87930dcb7c9SBarry Smith 88030dcb7c9SBarry Smith /* wait on receives */ 8810c468ba9SBarry Smith if (nrecvs2) { 8820c468ba9SBarry Smith ierr = PetscMalloc(nrecvs2*sizeof(MPI_Status),&recv_statuses);CHKERRQ(ierr); 88330dcb7c9SBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 88430dcb7c9SBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 8850c468ba9SBarry Smith } 88630dcb7c9SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 88730dcb7c9SBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 88830dcb7c9SBarry Smith 88907b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 89030dcb7c9SBarry Smith cnt = 0; 89130dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 89230dcb7c9SBarry Smith nt = recvs2[cnt++]; 89330dcb7c9SBarry Smith for (j=0; j<nt; j++) { 89430dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] local node %d number of subdomains %d: ",rank,recvs2[cnt],recvs2[cnt+1]);CHKERRQ(ierr); 89530dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 89630dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",recvs2[cnt+2+k]);CHKERRQ(ierr); 89730dcb7c9SBarry Smith } 89830dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 89930dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 90030dcb7c9SBarry Smith } 90130dcb7c9SBarry Smith } 90230dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 90307b52d57SBarry Smith } /* ----------------------------------- */ 90430dcb7c9SBarry Smith 90530dcb7c9SBarry Smith /* count number subdomains for each local node */ 90632dcc486SBarry Smith ierr = PetscMalloc(size*sizeof(PetscInt),&nprocs);CHKERRQ(ierr); 90732dcc486SBarry Smith ierr = PetscMemzero(nprocs,size*sizeof(PetscInt));CHKERRQ(ierr); 90830dcb7c9SBarry Smith cnt = 0; 90930dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 91030dcb7c9SBarry Smith nt = recvs2[cnt++]; 91130dcb7c9SBarry Smith for (j=0; j<nt; j++) { 912f6e5521dSKarl Rupp for (k=0; k<recvs2[cnt+1]; k++) nprocs[recvs2[cnt+2+k]]++; 91330dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 91430dcb7c9SBarry Smith } 91530dcb7c9SBarry Smith } 91630dcb7c9SBarry Smith nt = 0; for (i=0; i<size; i++) nt += (nprocs[i] > 0); 91730dcb7c9SBarry Smith *nproc = nt; 91832dcc486SBarry Smith ierr = PetscMalloc((nt+1)*sizeof(PetscInt),procs);CHKERRQ(ierr); 91932dcc486SBarry Smith ierr = PetscMalloc((nt+1)*sizeof(PetscInt),numprocs);CHKERRQ(ierr); 92032dcc486SBarry Smith ierr = PetscMalloc((nt+1)*sizeof(PetscInt*),indices);CHKERRQ(ierr); 9210298fd71SBarry Smith for (i=0;i<nt+1;i++) (*indices)[i]=NULL; 92232dcc486SBarry Smith ierr = PetscMalloc(size*sizeof(PetscInt),&bprocs);CHKERRQ(ierr); 92330dcb7c9SBarry Smith cnt = 0; 92430dcb7c9SBarry Smith for (i=0; i<size; i++) { 92530dcb7c9SBarry Smith if (nprocs[i] > 0) { 92630dcb7c9SBarry Smith bprocs[i] = cnt; 92730dcb7c9SBarry Smith (*procs)[cnt] = i; 92830dcb7c9SBarry Smith (*numprocs)[cnt] = nprocs[i]; 92932dcc486SBarry Smith ierr = PetscMalloc(nprocs[i]*sizeof(PetscInt),&(*indices)[cnt]);CHKERRQ(ierr); 93030dcb7c9SBarry Smith cnt++; 93130dcb7c9SBarry Smith } 93230dcb7c9SBarry Smith } 93330dcb7c9SBarry Smith 93430dcb7c9SBarry Smith /* make the list of subdomains for each nontrivial local node */ 93532dcc486SBarry Smith ierr = PetscMemzero(*numprocs,nt*sizeof(PetscInt));CHKERRQ(ierr); 93630dcb7c9SBarry Smith cnt = 0; 93730dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 93830dcb7c9SBarry Smith nt = recvs2[cnt++]; 93930dcb7c9SBarry Smith for (j=0; j<nt; j++) { 940f6e5521dSKarl Rupp for (k=0; k<recvs2[cnt+1]; k++) (*indices)[bprocs[recvs2[cnt+2+k]]][(*numprocs)[bprocs[recvs2[cnt+2+k]]]++] = recvs2[cnt]; 94130dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 94230dcb7c9SBarry Smith } 94330dcb7c9SBarry Smith } 94430dcb7c9SBarry Smith ierr = PetscFree(bprocs);CHKERRQ(ierr); 94507b52d57SBarry Smith ierr = PetscFree(recvs2);CHKERRQ(ierr); 94630dcb7c9SBarry Smith 94707b52d57SBarry Smith /* sort the node indexing by their global numbers */ 94807b52d57SBarry Smith nt = *nproc; 94907b52d57SBarry Smith for (i=0; i<nt; i++) { 95032dcc486SBarry Smith ierr = PetscMalloc(((*numprocs)[i])*sizeof(PetscInt),&tmp);CHKERRQ(ierr); 951f6e5521dSKarl Rupp for (j=0; j<(*numprocs)[i]; j++) tmp[j] = lindices[(*indices)[i][j]]; 95207b52d57SBarry Smith ierr = PetscSortIntWithArray((*numprocs)[i],tmp,(*indices)[i]);CHKERRQ(ierr); 95307b52d57SBarry Smith ierr = PetscFree(tmp);CHKERRQ(ierr); 95407b52d57SBarry Smith } 95507b52d57SBarry Smith 95607b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 95730dcb7c9SBarry Smith nt = *nproc; 95830dcb7c9SBarry Smith for (i=0; i<nt; i++) { 95930dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] subdomain %d number of indices %d: ",rank,(*procs)[i],(*numprocs)[i]);CHKERRQ(ierr); 96030dcb7c9SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 96130dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%d ",(*indices)[i][j]);CHKERRQ(ierr); 96230dcb7c9SBarry Smith } 96330dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 96430dcb7c9SBarry Smith } 96530dcb7c9SBarry Smith ierr = PetscSynchronizedFlush(comm);CHKERRQ(ierr); 96607b52d57SBarry Smith } /* ----------------------------------- */ 96730dcb7c9SBarry Smith 96830dcb7c9SBarry Smith /* wait on sends */ 96930dcb7c9SBarry Smith if (nsends2) { 970b0a32e0cSBarry Smith ierr = PetscMalloc(nsends2*sizeof(MPI_Status),&send_status);CHKERRQ(ierr); 97130dcb7c9SBarry Smith ierr = MPI_Waitall(nsends2,send_waits,send_status);CHKERRQ(ierr); 97230dcb7c9SBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 97330dcb7c9SBarry Smith } 97430dcb7c9SBarry Smith 97530dcb7c9SBarry Smith ierr = PetscFree(starts3);CHKERRQ(ierr); 97630dcb7c9SBarry Smith ierr = PetscFree(dest);CHKERRQ(ierr); 97730dcb7c9SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 9783677ff5aSBarry Smith 979bc8ff85bSBarry Smith ierr = PetscFree(nownedsenders);CHKERRQ(ierr); 980bc8ff85bSBarry Smith ierr = PetscFree(ownedsenders);CHKERRQ(ierr); 981bc8ff85bSBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 98230dcb7c9SBarry Smith ierr = PetscFree(starts2);CHKERRQ(ierr); 98330dcb7c9SBarry Smith ierr = PetscFree(lens2);CHKERRQ(ierr); 98489d82c54SBarry Smith 98589d82c54SBarry Smith ierr = PetscFree(source);CHKERRQ(ierr); 98697f1f81fSBarry Smith ierr = PetscFree(len);CHKERRQ(ierr); 98789d82c54SBarry Smith ierr = PetscFree(recvs);CHKERRQ(ierr); 9883a96401aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 98930dcb7c9SBarry Smith ierr = PetscFree(sends2);CHKERRQ(ierr); 99024cf384cSBarry Smith 99124cf384cSBarry Smith /* put the information about myself as the first entry in the list */ 99224cf384cSBarry Smith first_procs = (*procs)[0]; 99324cf384cSBarry Smith first_numprocs = (*numprocs)[0]; 99424cf384cSBarry Smith first_indices = (*indices)[0]; 99524cf384cSBarry Smith for (i=0; i<*nproc; i++) { 99624cf384cSBarry Smith if ((*procs)[i] == rank) { 99724cf384cSBarry Smith (*procs)[0] = (*procs)[i]; 99824cf384cSBarry Smith (*numprocs)[0] = (*numprocs)[i]; 99924cf384cSBarry Smith (*indices)[0] = (*indices)[i]; 100024cf384cSBarry Smith (*procs)[i] = first_procs; 100124cf384cSBarry Smith (*numprocs)[i] = first_numprocs; 100224cf384cSBarry Smith (*indices)[i] = first_indices; 100324cf384cSBarry Smith break; 100424cf384cSBarry Smith } 100524cf384cSBarry Smith } 100689d82c54SBarry Smith PetscFunctionReturn(0); 100789d82c54SBarry Smith } 100889d82c54SBarry Smith 10094a2ae208SSatish Balay #undef __FUNCT__ 10104a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingRestoreInfo" 101107b52d57SBarry Smith /*@C 101207b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo - Frees the memory allocated by ISLocalToGlobalMappingGetInfo() 101389d82c54SBarry Smith 101407b52d57SBarry Smith Collective on ISLocalToGlobalMapping 101507b52d57SBarry Smith 101607b52d57SBarry Smith Input Parameters: 101707b52d57SBarry Smith . mapping - the mapping from local to global indexing 101807b52d57SBarry Smith 101907b52d57SBarry Smith Output Parameter: 102007b52d57SBarry Smith + nproc - number of processors that are connected to this one 102107b52d57SBarry Smith . proc - neighboring processors 102207b52d57SBarry Smith . numproc - number of indices for each processor 102307b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 102407b52d57SBarry Smith 102507b52d57SBarry Smith Level: advanced 102607b52d57SBarry Smith 102707b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 102807b52d57SBarry Smith ISLocalToGlobalMappingGetInfo() 102907b52d57SBarry Smith @*/ 10307087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 103107b52d57SBarry Smith { 10326849ba73SBarry Smith PetscErrorCode ierr; 103332dcc486SBarry Smith PetscInt i; 103407b52d57SBarry Smith 103507b52d57SBarry Smith PetscFunctionBegin; 103605b42c5fSBarry Smith ierr = PetscFree(*procs);CHKERRQ(ierr); 103705b42c5fSBarry Smith ierr = PetscFree(*numprocs);CHKERRQ(ierr); 103800ff320aSBarry Smith if (*indices) { 103905b42c5fSBarry Smith ierr = PetscFree((*indices)[0]);CHKERRQ(ierr); 104000ff320aSBarry Smith for (i=1; i<*nproc; i++) { 104105b42c5fSBarry Smith ierr = PetscFree((*indices)[i]);CHKERRQ(ierr); 104207b52d57SBarry Smith } 104307b52d57SBarry Smith ierr = PetscFree(*indices);CHKERRQ(ierr); 104424cf384cSBarry Smith } 104507b52d57SBarry Smith PetscFunctionReturn(0); 104607b52d57SBarry Smith } 104786994e45SJed Brown 104886994e45SJed Brown #undef __FUNCT__ 104986994e45SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingGetIndices" 105086994e45SJed Brown /*@C 105186994e45SJed Brown ISLocalToGlobalMappingGetIndices - Get global indices for every local point 105286994e45SJed Brown 105386994e45SJed Brown Not Collective 105486994e45SJed Brown 105586994e45SJed Brown Input Arguments: 105686994e45SJed Brown . ltog - local to global mapping 105786994e45SJed Brown 105886994e45SJed Brown Output Arguments: 105986994e45SJed Brown . array - array of indices 106086994e45SJed Brown 106186994e45SJed Brown Level: advanced 106286994e45SJed Brown 106386994e45SJed Brown .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingRestoreIndices() 106486994e45SJed Brown @*/ 10657087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingGetIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 106686994e45SJed Brown { 106786994e45SJed Brown PetscFunctionBegin; 106886994e45SJed Brown PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 106986994e45SJed Brown PetscValidPointer(array,2); 107086994e45SJed Brown *array = ltog->indices; 107186994e45SJed Brown PetscFunctionReturn(0); 107286994e45SJed Brown } 107386994e45SJed Brown 107486994e45SJed Brown #undef __FUNCT__ 107586994e45SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingRestoreIndices" 107686994e45SJed Brown /*@C 107786994e45SJed Brown ISLocalToGlobalMappingRestoreIndices - Restore indices obtained with ISLocalToGlobalMappingRestoreIndices() 107886994e45SJed Brown 107986994e45SJed Brown Not Collective 108086994e45SJed Brown 108186994e45SJed Brown Input Arguments: 108286994e45SJed Brown + ltog - local to global mapping 108386994e45SJed Brown - array - array of indices 108486994e45SJed Brown 108586994e45SJed Brown Level: advanced 108686994e45SJed Brown 108786994e45SJed Brown .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingGetIndices() 108886994e45SJed Brown @*/ 10897087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 109086994e45SJed Brown { 109186994e45SJed Brown PetscFunctionBegin; 109286994e45SJed Brown PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 109386994e45SJed Brown PetscValidPointer(array,2); 109486994e45SJed Brown if (*array != ltog->indices) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Trying to return mismatched pointer"); 10950298fd71SBarry Smith *array = NULL; 109686994e45SJed Brown PetscFunctionReturn(0); 109786994e45SJed Brown } 1098f7efa3c7SJed Brown 1099f7efa3c7SJed Brown #undef __FUNCT__ 1100f7efa3c7SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingConcatenate" 1101f7efa3c7SJed Brown /*@C 1102f7efa3c7SJed Brown ISLocalToGlobalMappingConcatenate - Create a new mapping that concatenates a list of mappings 1103f7efa3c7SJed Brown 1104f7efa3c7SJed Brown Not Collective 1105f7efa3c7SJed Brown 1106f7efa3c7SJed Brown Input Arguments: 1107f7efa3c7SJed Brown + comm - communicator for the new mapping, must contain the communicator of every mapping to concatenate 1108f7efa3c7SJed Brown . n - number of mappings to concatenate 1109f7efa3c7SJed Brown - ltogs - local to global mappings 1110f7efa3c7SJed Brown 1111f7efa3c7SJed Brown Output Arguments: 1112f7efa3c7SJed Brown . ltogcat - new mapping 1113f7efa3c7SJed Brown 1114f7efa3c7SJed Brown Level: advanced 1115f7efa3c7SJed Brown 1116f7efa3c7SJed Brown .seealso: ISLocalToGlobalMappingCreate() 1117f7efa3c7SJed Brown @*/ 1118f7efa3c7SJed Brown PetscErrorCode ISLocalToGlobalMappingConcatenate(MPI_Comm comm,PetscInt n,const ISLocalToGlobalMapping ltogs[],ISLocalToGlobalMapping *ltogcat) 1119f7efa3c7SJed Brown { 1120f7efa3c7SJed Brown PetscInt i,cnt,m,*idx; 1121f7efa3c7SJed Brown PetscErrorCode ierr; 1122f7efa3c7SJed Brown 1123f7efa3c7SJed Brown PetscFunctionBegin; 1124f7efa3c7SJed Brown if (n < 0) SETERRQ1(comm,PETSC_ERR_ARG_OUTOFRANGE,"Must have a non-negative number of mappings, given %D",n); 1125f7efa3c7SJed Brown if (n > 0) PetscValidPointer(ltogs,3); 1126f7efa3c7SJed Brown for (i=0; i<n; i++) PetscValidHeaderSpecific(ltogs[i],IS_LTOGM_CLASSID,3); 1127f7efa3c7SJed Brown PetscValidPointer(ltogcat,4); 1128f7efa3c7SJed Brown for (cnt=0,i=0; i<n; i++) { 1129f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetSize(ltogs[i],&m);CHKERRQ(ierr); 1130f7efa3c7SJed Brown cnt += m; 1131f7efa3c7SJed Brown } 1132f7efa3c7SJed Brown ierr = PetscMalloc(cnt*sizeof(PetscInt),&idx);CHKERRQ(ierr); 1133f7efa3c7SJed Brown for (cnt=0,i=0; i<n; i++) { 1134f7efa3c7SJed Brown const PetscInt *subidx; 1135f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetSize(ltogs[i],&m);CHKERRQ(ierr); 1136f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetIndices(ltogs[i],&subidx);CHKERRQ(ierr); 1137f7efa3c7SJed Brown ierr = PetscMemcpy(&idx[cnt],subidx,m*sizeof(PetscInt));CHKERRQ(ierr); 1138f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingRestoreIndices(ltogs[i],&subidx);CHKERRQ(ierr); 1139f7efa3c7SJed Brown cnt += m; 1140f7efa3c7SJed Brown } 1141f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingCreate(comm,cnt,idx,PETSC_OWN_POINTER,ltogcat);CHKERRQ(ierr); 1142f7efa3c7SJed Brown PetscFunctionReturn(0); 1143f7efa3c7SJed Brown } 1144*04a59952SBarry Smith 1145*04a59952SBarry Smith 1146