12362add9SBarry Smith 2af0996ceSBarry Smith #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; 7268a049cSStefano Zampini static PetscErrorCode ISLocalToGlobalMappingGetBlockInfo_Private(ISLocalToGlobalMapping,PetscInt*,PetscInt**,PetscInt**,PetscInt***); 88e58c17dSMatthew Knepley 9186d4ecdSBarry Smith #undef __FUNCT__ 104a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingGetSize" 11565245c5SBarry Smith /*@ 12107e9a97SBarry Smith ISLocalToGlobalMappingGetSize - Gets the local size of a local to global mapping 133b9aefa3SBarry Smith 143b9aefa3SBarry Smith Not Collective 153b9aefa3SBarry Smith 163b9aefa3SBarry Smith Input Parameter: 173b9aefa3SBarry Smith . ltog - local to global mapping 183b9aefa3SBarry Smith 193b9aefa3SBarry Smith Output Parameter: 20107e9a97SBarry Smith . n - the number of entries in the local mapping, ISLocalToGlobalMappingGetIndices() returns an array of this length 213b9aefa3SBarry Smith 223b9aefa3SBarry Smith Level: advanced 233b9aefa3SBarry Smith 24273d9f13SBarry Smith Concepts: mapping^local to global 253b9aefa3SBarry Smith 263b9aefa3SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 273b9aefa3SBarry Smith @*/ 287087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingGetSize(ISLocalToGlobalMapping mapping,PetscInt *n) 293b9aefa3SBarry Smith { 303b9aefa3SBarry Smith PetscFunctionBegin; 310700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 324482741eSBarry Smith PetscValidIntPointer(n,2); 33107e9a97SBarry Smith *n = mapping->bs*mapping->n; 343b9aefa3SBarry Smith PetscFunctionReturn(0); 353b9aefa3SBarry Smith } 363b9aefa3SBarry Smith 374a2ae208SSatish Balay #undef __FUNCT__ 384a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingView" 395a5d4f66SBarry Smith /*@C 405a5d4f66SBarry Smith ISLocalToGlobalMappingView - View a local to global mapping 415a5d4f66SBarry Smith 42b9cd556bSLois Curfman McInnes Not Collective 43b9cd556bSLois Curfman McInnes 445a5d4f66SBarry Smith Input Parameters: 453b9aefa3SBarry Smith + ltog - local to global mapping 463b9aefa3SBarry Smith - viewer - viewer 475a5d4f66SBarry Smith 48a997ad1aSLois Curfman McInnes Level: advanced 49a997ad1aSLois Curfman McInnes 50273d9f13SBarry Smith Concepts: mapping^local to global 515a5d4f66SBarry Smith 525a5d4f66SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 535a5d4f66SBarry Smith @*/ 547087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingView(ISLocalToGlobalMapping mapping,PetscViewer viewer) 555a5d4f66SBarry Smith { 5632dcc486SBarry Smith PetscInt i; 5732dcc486SBarry Smith PetscMPIInt rank; 58ace3abfcSBarry Smith PetscBool iascii; 596849ba73SBarry Smith PetscErrorCode ierr; 605a5d4f66SBarry Smith 615a5d4f66SBarry Smith PetscFunctionBegin; 620700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 633050cee2SBarry Smith if (!viewer) { 64ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mapping),&viewer);CHKERRQ(ierr); 653050cee2SBarry Smith } 660700a824SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 675a5d4f66SBarry Smith 68ce94432eSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mapping),&rank);CHKERRQ(ierr); 69251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 7032077d6dSBarry Smith if (iascii) { 7198c3331eSBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mapping,viewer);CHKERRQ(ierr); 721575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 735a5d4f66SBarry Smith for (i=0; i<mapping->n; i++) { 747904a332SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d] %D %D\n",rank,i,mapping->indices[i]);CHKERRQ(ierr); 756831982aSBarry Smith } 76b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 771575c14dSBarry Smith ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 781575c14dSBarry Smith } 795a5d4f66SBarry Smith PetscFunctionReturn(0); 805a5d4f66SBarry Smith } 815a5d4f66SBarry Smith 824a2ae208SSatish Balay #undef __FUNCT__ 834a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreateIS" 841f428162SBarry Smith /*@ 852bdab257SBarry Smith ISLocalToGlobalMappingCreateIS - Creates a mapping between a local (0 to n) 862bdab257SBarry Smith ordering and a global parallel ordering. 872bdab257SBarry Smith 880f5bd95cSBarry Smith Not collective 89b9cd556bSLois Curfman McInnes 90a997ad1aSLois Curfman McInnes Input Parameter: 918c03b21aSDmitry Karpeev . is - index set containing the global numbers for each local number 922bdab257SBarry Smith 93a997ad1aSLois Curfman McInnes Output Parameter: 942bdab257SBarry Smith . mapping - new mapping data structure 952bdab257SBarry Smith 96f0413b6fSBarry Smith Notes: the block size of the IS determines the block size of the mapping 97a997ad1aSLois Curfman McInnes Level: advanced 98a997ad1aSLois Curfman McInnes 99273d9f13SBarry Smith Concepts: mapping^local to global 1002bdab257SBarry Smith 1012bdab257SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 1022bdab257SBarry Smith @*/ 1037087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingCreateIS(IS is,ISLocalToGlobalMapping *mapping) 1042bdab257SBarry Smith { 1056849ba73SBarry Smith PetscErrorCode ierr; 1063bbf0e92SBarry Smith PetscInt n,bs; 1075d0c19d7SBarry Smith const PetscInt *indices; 1082bdab257SBarry Smith MPI_Comm comm; 1093bbf0e92SBarry Smith PetscBool isblock; 1103a40ed3dSBarry Smith 1113a40ed3dSBarry Smith PetscFunctionBegin; 1120700a824SBarry Smith PetscValidHeaderSpecific(is,IS_CLASSID,1); 1134482741eSBarry Smith PetscValidPointer(mapping,2); 1142bdab257SBarry Smith 1152bdab257SBarry Smith ierr = PetscObjectGetComm((PetscObject)is,&comm);CHKERRQ(ierr); 1163b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 1173bbf0e92SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)is,ISBLOCK,&isblock);CHKERRQ(ierr); 1186006e8d2SBarry Smith if (!isblock) { 119f0413b6fSBarry Smith ierr = ISGetIndices(is,&indices);CHKERRQ(ierr); 120f0413b6fSBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,1,n,indices,PETSC_COPY_VALUES,mapping);CHKERRQ(ierr); 1212bdab257SBarry Smith ierr = ISRestoreIndices(is,&indices);CHKERRQ(ierr); 1226006e8d2SBarry Smith } else { 1236006e8d2SBarry Smith ierr = ISGetBlockSize(is,&bs);CHKERRQ(ierr); 124f0413b6fSBarry Smith ierr = ISBlockGetIndices(is,&indices);CHKERRQ(ierr); 12528bc9809SBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,bs,n/bs,indices,PETSC_COPY_VALUES,mapping);CHKERRQ(ierr); 126f0413b6fSBarry Smith ierr = ISBlockRestoreIndices(is,&indices);CHKERRQ(ierr); 1276006e8d2SBarry Smith } 1283a40ed3dSBarry Smith PetscFunctionReturn(0); 1292bdab257SBarry Smith } 1305a5d4f66SBarry Smith 131a4d96a55SJed Brown #undef __FUNCT__ 132a4d96a55SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingCreateSF" 133a4d96a55SJed Brown /*@C 134a4d96a55SJed Brown ISLocalToGlobalMappingCreateSF - Creates a mapping between a local (0 to n) 135a4d96a55SJed Brown ordering and a global parallel ordering. 136a4d96a55SJed Brown 137a4d96a55SJed Brown Collective 138a4d96a55SJed Brown 139a4d96a55SJed Brown Input Parameter: 140a4d96a55SJed Brown + sf - star forest mapping contiguous local indices to (rank, offset) 141a4d96a55SJed Brown - start - first global index on this process 142a4d96a55SJed Brown 143a4d96a55SJed Brown Output Parameter: 144a4d96a55SJed Brown . mapping - new mapping data structure 145a4d96a55SJed Brown 146a4d96a55SJed Brown Level: advanced 147a4d96a55SJed Brown 148a4d96a55SJed Brown Concepts: mapping^local to global 149a4d96a55SJed Brown 150a4d96a55SJed Brown .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingCreateIS() 151a4d96a55SJed Brown @*/ 152a4d96a55SJed Brown PetscErrorCode ISLocalToGlobalMappingCreateSF(PetscSF sf,PetscInt start,ISLocalToGlobalMapping *mapping) 153a4d96a55SJed Brown { 154a4d96a55SJed Brown PetscErrorCode ierr; 155a4d96a55SJed Brown PetscInt i,maxlocal,nroots,nleaves,*globals,*ltog; 156a4d96a55SJed Brown const PetscInt *ilocal; 157a4d96a55SJed Brown MPI_Comm comm; 158a4d96a55SJed Brown 159a4d96a55SJed Brown PetscFunctionBegin; 160a4d96a55SJed Brown PetscValidHeaderSpecific(sf,PETSCSF_CLASSID,1); 161a4d96a55SJed Brown PetscValidPointer(mapping,3); 162a4d96a55SJed Brown 163a4d96a55SJed Brown ierr = PetscObjectGetComm((PetscObject)sf,&comm);CHKERRQ(ierr); 1640298fd71SBarry Smith ierr = PetscSFGetGraph(sf,&nroots,&nleaves,&ilocal,NULL);CHKERRQ(ierr); 165f6e5521dSKarl Rupp if (ilocal) { 166f6e5521dSKarl Rupp for (i=0,maxlocal=0; i<nleaves; i++) maxlocal = PetscMax(maxlocal,ilocal[i]+1); 167f6e5521dSKarl Rupp } 168a4d96a55SJed Brown else maxlocal = nleaves; 169785e854fSJed Brown ierr = PetscMalloc1(nroots,&globals);CHKERRQ(ierr); 170785e854fSJed Brown ierr = PetscMalloc1(maxlocal,<og);CHKERRQ(ierr); 171a4d96a55SJed Brown for (i=0; i<nroots; i++) globals[i] = start + i; 172a4d96a55SJed Brown for (i=0; i<maxlocal; i++) ltog[i] = -1; 173a4d96a55SJed Brown ierr = PetscSFBcastBegin(sf,MPIU_INT,globals,ltog);CHKERRQ(ierr); 174a4d96a55SJed Brown ierr = PetscSFBcastEnd(sf,MPIU_INT,globals,ltog);CHKERRQ(ierr); 175f0413b6fSBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,1,maxlocal,ltog,PETSC_OWN_POINTER,mapping);CHKERRQ(ierr); 176a4d96a55SJed Brown ierr = PetscFree(globals);CHKERRQ(ierr); 177a4d96a55SJed Brown PetscFunctionReturn(0); 178a4d96a55SJed Brown } 179b46b645bSBarry Smith 1804a2ae208SSatish Balay #undef __FUNCT__ 18163fa5c83Sstefano_zampini #define __FUNCT__ "ISLocalToGlobalMappingSetBlockSize" 18263fa5c83Sstefano_zampini /*@ 18363fa5c83Sstefano_zampini ISLocalToGlobalMappingSetBlockSize - Sets the blocksize of the mapping 18463fa5c83Sstefano_zampini 18563fa5c83Sstefano_zampini Not collective 18663fa5c83Sstefano_zampini 18763fa5c83Sstefano_zampini Input Parameters: 18863fa5c83Sstefano_zampini . mapping - mapping data structure 18963fa5c83Sstefano_zampini . bs - the blocksize 19063fa5c83Sstefano_zampini 19163fa5c83Sstefano_zampini Level: advanced 19263fa5c83Sstefano_zampini 19363fa5c83Sstefano_zampini Concepts: mapping^local to global 19463fa5c83Sstefano_zampini 19563fa5c83Sstefano_zampini .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS() 19663fa5c83Sstefano_zampini @*/ 19763fa5c83Sstefano_zampini PetscErrorCode ISLocalToGlobalMappingSetBlockSize(ISLocalToGlobalMapping mapping,PetscInt bs) 19863fa5c83Sstefano_zampini { 19963fa5c83Sstefano_zampini PetscInt *nid,*oid; 200*c9345713Sstefano_zampini PetscInt i,cn,on,obs,nn,cum; 20163fa5c83Sstefano_zampini PetscErrorCode ierr; 20263fa5c83Sstefano_zampini 20363fa5c83Sstefano_zampini PetscFunctionBegin; 20463fa5c83Sstefano_zampini PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 20563fa5c83Sstefano_zampini if (bs < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid block size %D",bs); 20663fa5c83Sstefano_zampini if (bs == mapping->bs) PetscFunctionReturn(0); 20763fa5c83Sstefano_zampini on = mapping->n; 20863fa5c83Sstefano_zampini obs = mapping->bs; 20963fa5c83Sstefano_zampini oid = mapping->indices; 21063fa5c83Sstefano_zampini nn = (on*obs)/bs; 21163fa5c83Sstefano_zampini if ((on*obs)%bs) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Block size %D is inconsistent with block size %D and number of block indices %D",bs,obs,on); 21263fa5c83Sstefano_zampini ierr = PetscMalloc1(nn,&nid);CHKERRQ(ierr); 213*c9345713Sstefano_zampini for (i=0,cum=0,cn=0;i<on;i++) { 214*c9345713Sstefano_zampini if (oid[i] < 0) cn++; 215*c9345713Sstefano_zampini if (cn == bs || (oid[i] > -1 && !((oid[i]*obs)%bs))) { 21663fa5c83Sstefano_zampini if (cum == nn) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Block sizes %D and %D are incompatible with the block indices",bs,obs); 217*c9345713Sstefano_zampini if (cn && cn != bs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Block sizes %D and %D are incompatible with the block indices",bs,obs); 218*c9345713Sstefano_zampini if (cn) nid[cum++] = -1; 219*c9345713Sstefano_zampini else nid[cum++] = (oid[i]*obs)/bs; 220*c9345713Sstefano_zampini cn = 0; 22163fa5c83Sstefano_zampini } 22263fa5c83Sstefano_zampini } 223*c9345713Sstefano_zampini if (cum != nn || cn) { 22463fa5c83Sstefano_zampini ierr = PetscFree(nid);CHKERRQ(ierr); 225*c9345713Sstefano_zampini SETERRQ5(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Incompatible block sizes %D and %D (new block indices found %D != %D, neg %d)",bs,obs,cum,nn,cn); 22663fa5c83Sstefano_zampini } 22763fa5c83Sstefano_zampini mapping->n = nn; 22863fa5c83Sstefano_zampini mapping->bs = bs; 22963fa5c83Sstefano_zampini ierr = PetscFree(mapping->indices);CHKERRQ(ierr); 23063fa5c83Sstefano_zampini mapping->indices = nid; 231*c9345713Sstefano_zampini ierr = PetscFree(mapping->globals);CHKERRQ(ierr); 232*c9345713Sstefano_zampini mapping->globalstart = 0; 233*c9345713Sstefano_zampini mapping->globalend = 0; 23463fa5c83Sstefano_zampini PetscFunctionReturn(0); 23563fa5c83Sstefano_zampini } 23663fa5c83Sstefano_zampini 23763fa5c83Sstefano_zampini #undef __FUNCT__ 23845b6f7e9SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingGetBlockSize" 23945b6f7e9SBarry Smith /*@ 24045b6f7e9SBarry Smith ISLocalToGlobalMappingGetBlockSize - Gets the blocksize of the mapping 24145b6f7e9SBarry Smith ordering and a global parallel ordering. 24245b6f7e9SBarry Smith 24345b6f7e9SBarry Smith Not Collective 24445b6f7e9SBarry Smith 24545b6f7e9SBarry Smith Input Parameters: 24645b6f7e9SBarry Smith . mapping - mapping data structure 24745b6f7e9SBarry Smith 24845b6f7e9SBarry Smith Output Parameter: 24945b6f7e9SBarry Smith . bs - the blocksize 25045b6f7e9SBarry Smith 25145b6f7e9SBarry Smith Level: advanced 25245b6f7e9SBarry Smith 25345b6f7e9SBarry Smith Concepts: mapping^local to global 25445b6f7e9SBarry Smith 25545b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS() 25645b6f7e9SBarry Smith @*/ 25745b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetBlockSize(ISLocalToGlobalMapping mapping,PetscInt *bs) 25845b6f7e9SBarry Smith { 25945b6f7e9SBarry Smith PetscFunctionBegin; 260cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 26145b6f7e9SBarry Smith *bs = mapping->bs; 26245b6f7e9SBarry Smith PetscFunctionReturn(0); 26345b6f7e9SBarry Smith } 26445b6f7e9SBarry Smith 26545b6f7e9SBarry Smith #undef __FUNCT__ 2664a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreate" 267ba5bb76aSSatish Balay /*@ 26890f02eecSBarry Smith ISLocalToGlobalMappingCreate - Creates a mapping between a local (0 to n) 26990f02eecSBarry Smith ordering and a global parallel ordering. 2702362add9SBarry Smith 27189d82c54SBarry Smith Not Collective, but communicator may have more than one process 272b9cd556bSLois Curfman McInnes 2732362add9SBarry Smith Input Parameters: 27489d82c54SBarry Smith + comm - MPI communicator 275f0413b6fSBarry Smith . bs - the block size 27628bc9809SBarry Smith . n - the number of local elements divided by the block size, or equivalently the number of block indices 27728bc9809SBarry Smith . indices - the global index for each local element, these do not need to be in increasing order (sorted), these values should not be scaled (i.e. multiplied) by the blocksize bs 278d5ad8652SBarry Smith - mode - see PetscCopyMode 2792362add9SBarry Smith 280a997ad1aSLois Curfman McInnes Output Parameter: 28190f02eecSBarry Smith . mapping - new mapping data structure 2822362add9SBarry Smith 283f0413b6fSBarry Smith Notes: There is one integer value in indices per block and it represents the actual indices bs*idx + j, where j=0,..,bs-1 284a997ad1aSLois Curfman McInnes Level: advanced 285a997ad1aSLois Curfman McInnes 286273d9f13SBarry Smith Concepts: mapping^local to global 2872362add9SBarry Smith 288d5ad8652SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS() 2892362add9SBarry Smith @*/ 29060c7cefcSBarry Smith PetscErrorCode ISLocalToGlobalMappingCreate(MPI_Comm comm,PetscInt bs,PetscInt n,const PetscInt indices[],PetscCopyMode mode,ISLocalToGlobalMapping *mapping) 2912362add9SBarry Smith { 2926849ba73SBarry Smith PetscErrorCode ierr; 29332dcc486SBarry Smith PetscInt *in; 294b46b645bSBarry Smith 295b46b645bSBarry Smith PetscFunctionBegin; 29673911063SBarry Smith if (n) PetscValidIntPointer(indices,3); 2974482741eSBarry Smith PetscValidPointer(mapping,4); 298b46b645bSBarry Smith 2990298fd71SBarry Smith *mapping = NULL; 300607a6623SBarry Smith ierr = ISInitializePackage();CHKERRQ(ierr); 3012362add9SBarry Smith 30273107ff1SLisandro Dalcin ierr = PetscHeaderCreate(*mapping,IS_LTOGM_CLASSID,"ISLocalToGlobalMapping","Local to global mapping","IS", 30360c7cefcSBarry Smith comm,ISLocalToGlobalMappingDestroy,ISLocalToGlobalMappingView);CHKERRQ(ierr); 304d4bb536fSBarry Smith (*mapping)->n = n; 305f0413b6fSBarry Smith (*mapping)->bs = bs; 306268a049cSStefano Zampini (*mapping)->info_cached = PETSC_FALSE; 307268a049cSStefano Zampini (*mapping)->info_free = PETSC_FALSE; 308268a049cSStefano Zampini (*mapping)->info_procs = NULL; 309268a049cSStefano Zampini (*mapping)->info_numprocs = NULL; 310268a049cSStefano Zampini (*mapping)->info_indices = NULL; 311d4bb536fSBarry Smith /* 312d4bb536fSBarry Smith Do not create the global to local mapping. This is only created if 313d4bb536fSBarry Smith ISGlobalToLocalMapping() is called 314d4bb536fSBarry Smith */ 315d4bb536fSBarry Smith (*mapping)->globals = 0; 316d5ad8652SBarry Smith if (mode == PETSC_COPY_VALUES) { 317785e854fSJed Brown ierr = PetscMalloc1(n,&in);CHKERRQ(ierr); 318d5ad8652SBarry Smith ierr = PetscMemcpy(in,indices,n*sizeof(PetscInt));CHKERRQ(ierr); 319d5ad8652SBarry Smith (*mapping)->indices = in; 3206389a1a1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)*mapping,n*sizeof(PetscInt));CHKERRQ(ierr); 3216389a1a1SBarry Smith } else if (mode == PETSC_OWN_POINTER) { 3226389a1a1SBarry Smith (*mapping)->indices = (PetscInt*)indices; 3236389a1a1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)*mapping,n*sizeof(PetscInt));CHKERRQ(ierr); 3246389a1a1SBarry Smith } 32560c7cefcSBarry Smith else SETERRQ(comm,PETSC_ERR_SUP,"Cannot currently use PETSC_USE_POINTER"); 326d96308ebSBarry Smith ierr = PetscStrallocpy("basic",&((PetscObject)*mapping)->type_name);CHKERRQ(ierr); 3273a40ed3dSBarry Smith PetscFunctionReturn(0); 3282362add9SBarry Smith } 3292362add9SBarry Smith 3304a2ae208SSatish Balay #undef __FUNCT__ 3314a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingDestroy" 33290f02eecSBarry Smith /*@ 33390f02eecSBarry Smith ISLocalToGlobalMappingDestroy - Destroys a mapping between a local (0 to n) 33490f02eecSBarry Smith ordering and a global parallel ordering. 33590f02eecSBarry Smith 3360f5bd95cSBarry Smith Note Collective 337b9cd556bSLois Curfman McInnes 33890f02eecSBarry Smith Input Parameters: 33990f02eecSBarry Smith . mapping - mapping data structure 34090f02eecSBarry Smith 341a997ad1aSLois Curfman McInnes Level: advanced 342a997ad1aSLois Curfman McInnes 3433acfe500SLois Curfman McInnes .seealso: ISLocalToGlobalMappingCreate() 34490f02eecSBarry Smith @*/ 3456bf464f9SBarry Smith PetscErrorCode ISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping *mapping) 34690f02eecSBarry Smith { 347dfbe8321SBarry Smith PetscErrorCode ierr; 3485fd66863SKarl Rupp 3493a40ed3dSBarry Smith PetscFunctionBegin; 3506bf464f9SBarry Smith if (!*mapping) PetscFunctionReturn(0); 3516bf464f9SBarry Smith PetscValidHeaderSpecific((*mapping),IS_LTOGM_CLASSID,1); 352997056adSBarry Smith if (--((PetscObject)(*mapping))->refct > 0) {*mapping = 0;PetscFunctionReturn(0);} 3536bf464f9SBarry Smith ierr = PetscFree((*mapping)->indices);CHKERRQ(ierr); 3546bf464f9SBarry Smith ierr = PetscFree((*mapping)->globals);CHKERRQ(ierr); 355268a049cSStefano Zampini ierr = PetscFree((*mapping)->info_procs);CHKERRQ(ierr); 356268a049cSStefano Zampini ierr = PetscFree((*mapping)->info_numprocs);CHKERRQ(ierr); 357268a049cSStefano Zampini if ((*mapping)->info_indices) { 358268a049cSStefano Zampini PetscInt i; 359268a049cSStefano Zampini 360268a049cSStefano Zampini ierr = PetscFree(((*mapping)->info_indices)[0]);CHKERRQ(ierr); 361268a049cSStefano Zampini for (i=1; i<(*mapping)->info_nproc; i++) { 362268a049cSStefano Zampini ierr = PetscFree(((*mapping)->info_indices)[i]);CHKERRQ(ierr); 363268a049cSStefano Zampini } 364268a049cSStefano Zampini ierr = PetscFree((*mapping)->info_indices);CHKERRQ(ierr); 365268a049cSStefano Zampini } 366d38fa0fbSBarry Smith ierr = PetscHeaderDestroy(mapping);CHKERRQ(ierr); 367992144d0SBarry Smith *mapping = 0; 3683a40ed3dSBarry Smith PetscFunctionReturn(0); 36990f02eecSBarry Smith } 37090f02eecSBarry Smith 3714a2ae208SSatish Balay #undef __FUNCT__ 3724a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingApplyIS" 37390f02eecSBarry Smith /*@ 3743acfe500SLois Curfman McInnes ISLocalToGlobalMappingApplyIS - Creates from an IS in the local numbering 3753acfe500SLois Curfman McInnes a new index set using the global numbering defined in an ISLocalToGlobalMapping 3763acfe500SLois Curfman McInnes context. 37790f02eecSBarry Smith 378b9cd556bSLois Curfman McInnes Not collective 379b9cd556bSLois Curfman McInnes 38090f02eecSBarry Smith Input Parameters: 381b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 382b9cd556bSLois Curfman McInnes - is - index set in local numbering 38390f02eecSBarry Smith 38490f02eecSBarry Smith Output Parameters: 38590f02eecSBarry Smith . newis - index set in global numbering 38690f02eecSBarry Smith 387a997ad1aSLois Curfman McInnes Level: advanced 388a997ad1aSLois Curfman McInnes 389273d9f13SBarry Smith Concepts: mapping^local to global 3903acfe500SLois Curfman McInnes 39190f02eecSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 392d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy(), ISGlobalToLocalMappingApply() 39390f02eecSBarry Smith @*/ 3947087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping mapping,IS is,IS *newis) 39590f02eecSBarry Smith { 3966849ba73SBarry Smith PetscErrorCode ierr; 397e24637baSBarry Smith PetscInt n,*idxout; 3985d0c19d7SBarry Smith const PetscInt *idxin; 3993a40ed3dSBarry Smith 4003a40ed3dSBarry Smith PetscFunctionBegin; 4010700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 4020700a824SBarry Smith PetscValidHeaderSpecific(is,IS_CLASSID,2); 4034482741eSBarry Smith PetscValidPointer(newis,3); 40490f02eecSBarry Smith 4053b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 40690f02eecSBarry Smith ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 407785e854fSJed Brown ierr = PetscMalloc1(n,&idxout);CHKERRQ(ierr); 408e24637baSBarry Smith ierr = ISLocalToGlobalMappingApply(mapping,n,idxin,idxout);CHKERRQ(ierr); 4093b9aefa3SBarry Smith ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 410543f3098SMatthew G. Knepley ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is),n,idxout,PETSC_OWN_POINTER,newis);CHKERRQ(ierr); 4113a40ed3dSBarry Smith PetscFunctionReturn(0); 41290f02eecSBarry Smith } 41390f02eecSBarry Smith 414afcb2eb5SJed Brown #undef __FUNCT__ 415afcb2eb5SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingApply" 416b89cb25eSSatish Balay /*@ 4173acfe500SLois Curfman McInnes ISLocalToGlobalMappingApply - Takes a list of integers in a local numbering 4183acfe500SLois Curfman McInnes and converts them to the global numbering. 41990f02eecSBarry Smith 420b9cd556bSLois Curfman McInnes Not collective 421b9cd556bSLois Curfman McInnes 422bb25748dSBarry Smith Input Parameters: 423b9cd556bSLois Curfman McInnes + mapping - the local to global mapping context 424bb25748dSBarry Smith . N - number of integers 425b9cd556bSLois Curfman McInnes - in - input indices in local numbering 426bb25748dSBarry Smith 427bb25748dSBarry Smith Output Parameter: 428bb25748dSBarry Smith . out - indices in global numbering 429bb25748dSBarry Smith 430b9cd556bSLois Curfman McInnes Notes: 431b9cd556bSLois Curfman McInnes The in and out array parameters may be identical. 432d4bb536fSBarry Smith 433a997ad1aSLois Curfman McInnes Level: advanced 434a997ad1aSLois Curfman McInnes 43545b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingApplyBlock(), ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 4360752156aSBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 437d4bb536fSBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 438bb25748dSBarry Smith 439273d9f13SBarry Smith Concepts: mapping^local to global 440afcb2eb5SJed Brown @*/ 441afcb2eb5SJed Brown PetscErrorCode ISLocalToGlobalMappingApply(ISLocalToGlobalMapping mapping,PetscInt N,const PetscInt in[],PetscInt out[]) 442afcb2eb5SJed Brown { 443cbc1caf0SMatthew G. Knepley PetscInt i,bs,Nmax; 44445b6f7e9SBarry Smith 44545b6f7e9SBarry Smith PetscFunctionBegin; 446cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 447cbc1caf0SMatthew G. Knepley bs = mapping->bs; 448cbc1caf0SMatthew G. Knepley Nmax = bs*mapping->n; 44945b6f7e9SBarry Smith if (bs == 1) { 450cbc1caf0SMatthew G. Knepley const PetscInt *idx = mapping->indices; 45145b6f7e9SBarry Smith for (i=0; i<N; i++) { 45245b6f7e9SBarry Smith if (in[i] < 0) { 45345b6f7e9SBarry Smith out[i] = in[i]; 45445b6f7e9SBarry Smith continue; 45545b6f7e9SBarry Smith } 456e24637baSBarry Smith if (in[i] >= Nmax) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local index %D too large %D (max) at %D",in[i],Nmax-1,i); 45745b6f7e9SBarry Smith out[i] = idx[in[i]]; 45845b6f7e9SBarry Smith } 45945b6f7e9SBarry Smith } else { 460cbc1caf0SMatthew G. Knepley const PetscInt *idx = mapping->indices; 46145b6f7e9SBarry Smith for (i=0; i<N; i++) { 46245b6f7e9SBarry Smith if (in[i] < 0) { 46345b6f7e9SBarry Smith out[i] = in[i]; 46445b6f7e9SBarry Smith continue; 46545b6f7e9SBarry Smith } 466e24637baSBarry Smith if (in[i] >= Nmax) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local index %D too large %D (max) at %D",in[i],Nmax-1,i); 46745b6f7e9SBarry Smith out[i] = idx[in[i]/bs]*bs + (in[i] % bs); 46845b6f7e9SBarry Smith } 46945b6f7e9SBarry Smith } 47045b6f7e9SBarry Smith PetscFunctionReturn(0); 47145b6f7e9SBarry Smith } 47245b6f7e9SBarry Smith 47345b6f7e9SBarry Smith #undef __FUNCT__ 47445b6f7e9SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingApplyBlock" 47545b6f7e9SBarry Smith /*@ 4766006e8d2SBarry Smith ISLocalToGlobalMappingApplyBlock - Takes a list of integers in a local block numbering and converts them to the global block numbering 47745b6f7e9SBarry Smith 47845b6f7e9SBarry Smith Not collective 47945b6f7e9SBarry Smith 48045b6f7e9SBarry Smith Input Parameters: 48145b6f7e9SBarry Smith + mapping - the local to global mapping context 48245b6f7e9SBarry Smith . N - number of integers 4836006e8d2SBarry Smith - in - input indices in local block numbering 48445b6f7e9SBarry Smith 48545b6f7e9SBarry Smith Output Parameter: 4866006e8d2SBarry Smith . out - indices in global block numbering 48745b6f7e9SBarry Smith 48845b6f7e9SBarry Smith Notes: 48945b6f7e9SBarry Smith The in and out array parameters may be identical. 49045b6f7e9SBarry Smith 4916006e8d2SBarry Smith Example: 4926006e8d2SBarry Smith If the index values are {0,1,6,7} set with a call to ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,2,2,{0,3}) then the mapping applied to 0 4936006e8d2SBarry Smith (the first block) would produce 0 and the mapping applied to 1 (the second block) would produce 3. 4946006e8d2SBarry Smith 49545b6f7e9SBarry Smith Level: advanced 49645b6f7e9SBarry Smith 49745b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 49845b6f7e9SBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 49945b6f7e9SBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 50045b6f7e9SBarry Smith 50145b6f7e9SBarry Smith Concepts: mapping^local to global 50245b6f7e9SBarry Smith @*/ 50345b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingApplyBlock(ISLocalToGlobalMapping mapping,PetscInt N,const PetscInt in[],PetscInt out[]) 50445b6f7e9SBarry Smith { 505cbc1caf0SMatthew G. Knepley 506cbc1caf0SMatthew G. Knepley PetscFunctionBegin; 507cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 508cbc1caf0SMatthew G. Knepley { 509afcb2eb5SJed Brown PetscInt i,Nmax = mapping->n; 510afcb2eb5SJed Brown const PetscInt *idx = mapping->indices; 511d4bb536fSBarry Smith 512afcb2eb5SJed Brown for (i=0; i<N; i++) { 513afcb2eb5SJed Brown if (in[i] < 0) { 514afcb2eb5SJed Brown out[i] = in[i]; 515afcb2eb5SJed Brown continue; 516afcb2eb5SJed Brown } 517e24637baSBarry Smith if (in[i] >= Nmax) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local block index %D too large %D (max) at %D",in[i],Nmax-1,i); 518afcb2eb5SJed Brown out[i] = idx[in[i]]; 519afcb2eb5SJed Brown } 520cbc1caf0SMatthew G. Knepley } 521afcb2eb5SJed Brown PetscFunctionReturn(0); 522afcb2eb5SJed Brown } 523d4bb536fSBarry Smith 524d4bb536fSBarry Smith /* -----------------------------------------------------------------------------------------*/ 525d4bb536fSBarry Smith 5264a2ae208SSatish Balay #undef __FUNCT__ 5274a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingSetUp_Private" 528d4bb536fSBarry Smith /* 529d4bb536fSBarry Smith Creates the global fields in the ISLocalToGlobalMapping structure 530d4bb536fSBarry Smith */ 5316849ba73SBarry Smith static PetscErrorCode ISGlobalToLocalMappingSetUp_Private(ISLocalToGlobalMapping mapping) 532d4bb536fSBarry Smith { 5336849ba73SBarry Smith PetscErrorCode ierr; 53432dcc486SBarry Smith PetscInt i,*idx = mapping->indices,n = mapping->n,end,start,*globals; 535d4bb536fSBarry Smith 5363a40ed3dSBarry Smith PetscFunctionBegin; 537d4bb536fSBarry Smith end = 0; 538ec268f7cSJed Brown start = PETSC_MAX_INT; 539d4bb536fSBarry Smith 540d4bb536fSBarry Smith for (i=0; i<n; i++) { 541d4bb536fSBarry Smith if (idx[i] < 0) continue; 542d4bb536fSBarry Smith if (idx[i] < start) start = idx[i]; 543d4bb536fSBarry Smith if (idx[i] > end) end = idx[i]; 544d4bb536fSBarry Smith } 545d4bb536fSBarry Smith if (start > end) {start = 0; end = -1;} 546d4bb536fSBarry Smith mapping->globalstart = start; 547d4bb536fSBarry Smith mapping->globalend = end; 548d4bb536fSBarry Smith 549854ce69bSBarry Smith ierr = PetscMalloc1(end-start+2,&globals);CHKERRQ(ierr); 550b0a32e0cSBarry Smith mapping->globals = globals; 551f6e5521dSKarl Rupp for (i=0; i<end-start+1; i++) globals[i] = -1; 552d4bb536fSBarry Smith for (i=0; i<n; i++) { 553d4bb536fSBarry Smith if (idx[i] < 0) continue; 554d4bb536fSBarry Smith globals[idx[i] - start] = i; 555d4bb536fSBarry Smith } 556d4bb536fSBarry Smith 5573bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mapping,(end-start+1)*sizeof(PetscInt));CHKERRQ(ierr); 5583a40ed3dSBarry Smith PetscFunctionReturn(0); 559d4bb536fSBarry Smith } 560d4bb536fSBarry Smith 5614a2ae208SSatish Balay #undef __FUNCT__ 5624a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingApply" 563d4bb536fSBarry Smith /*@ 564a997ad1aSLois Curfman McInnes ISGlobalToLocalMappingApply - Provides the local numbering for a list of integers 565a997ad1aSLois Curfman McInnes specified with a global numbering. 566d4bb536fSBarry Smith 567b9cd556bSLois Curfman McInnes Not collective 568b9cd556bSLois Curfman McInnes 569d4bb536fSBarry Smith Input Parameters: 570b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 571d4bb536fSBarry Smith . type - IS_GTOLM_MASK - replaces global indices with no local value with -1 572d4bb536fSBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 573d4bb536fSBarry Smith . n - number of global indices to map 574b9cd556bSLois Curfman McInnes - idx - global indices to map 575d4bb536fSBarry Smith 576d4bb536fSBarry Smith Output Parameters: 577b9cd556bSLois Curfman McInnes + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 578b9cd556bSLois Curfman McInnes - idxout - local index of each global index, one must pass in an array long enough 579e182c471SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApply() with 5800298fd71SBarry Smith idxout == NULL to determine the required length (returned in nout) 581e182c471SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApply() 582e182c471SBarry Smith a second time to set the values. 583d4bb536fSBarry Smith 584b9cd556bSLois Curfman McInnes Notes: 5850298fd71SBarry Smith Either nout or idxout may be NULL. idx and idxout may be identical. 586d4bb536fSBarry Smith 5870f5bd95cSBarry Smith This is not scalable in memory usage. Each processor requires O(Nglobal) size 5880f5bd95cSBarry Smith array to compute these. 5890f5bd95cSBarry Smith 590a997ad1aSLois Curfman McInnes Level: advanced 591a997ad1aSLois Curfman McInnes 59232fd6b96SBarry Smith Developer Note: The manual page states that idx and idxout may be identical but the calling 59332fd6b96SBarry Smith sequence declares idx as const so it cannot be the same as idxout. 59432fd6b96SBarry Smith 595273d9f13SBarry Smith Concepts: mapping^global to local 596d4bb536fSBarry Smith 5979d90f715SBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISGlobalToLocalMappingApplyBlock(), ISLocalToGlobalMappingCreate(), 598d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy() 599d4bb536fSBarry Smith @*/ 6007087cfbeSBarry Smith PetscErrorCode ISGlobalToLocalMappingApply(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, 60132dcc486SBarry Smith PetscInt n,const PetscInt idx[],PetscInt *nout,PetscInt idxout[]) 602d4bb536fSBarry Smith { 6039d90f715SBarry Smith PetscInt i,*globals,nf = 0,tmp,start,end,bs; 6049d90f715SBarry Smith PetscErrorCode ierr; 6059d90f715SBarry Smith 6069d90f715SBarry Smith PetscFunctionBegin; 6079d90f715SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 6089d90f715SBarry Smith if (!mapping->globals) { 6099d90f715SBarry Smith ierr = ISGlobalToLocalMappingSetUp_Private(mapping);CHKERRQ(ierr); 6109d90f715SBarry Smith } 6119d90f715SBarry Smith globals = mapping->globals; 6129d90f715SBarry Smith start = mapping->globalstart; 6139d90f715SBarry Smith end = mapping->globalend; 6149d90f715SBarry Smith bs = mapping->bs; 6159d90f715SBarry Smith 6169d90f715SBarry Smith if (type == IS_GTOLM_MASK) { 6179d90f715SBarry Smith if (idxout) { 6189d90f715SBarry Smith for (i=0; i<n; i++) { 6199d90f715SBarry Smith if (idx[i] < 0) idxout[i] = idx[i]; 6209d90f715SBarry Smith else if (idx[i] < bs*start) idxout[i] = -1; 621663bb84eSBarry Smith else if (idx[i] > bs*(end+1)-1) idxout[i] = -1; 6229d90f715SBarry Smith else idxout[i] = bs*globals[idx[i]/bs - start] + (idx[i] % bs); 6239d90f715SBarry Smith } 6249d90f715SBarry Smith } 6259d90f715SBarry Smith if (nout) *nout = n; 6269d90f715SBarry Smith } else { 6279d90f715SBarry Smith if (idxout) { 6289d90f715SBarry Smith for (i=0; i<n; i++) { 6299d90f715SBarry Smith if (idx[i] < 0) continue; 6309d90f715SBarry Smith if (idx[i] < bs*start) continue; 631663bb84eSBarry Smith if (idx[i] > bs*(end+1)-1) continue; 6329d90f715SBarry Smith tmp = bs*globals[idx[i]/bs - start] + (idx[i] % bs); 6339d90f715SBarry Smith if (tmp < 0) continue; 6349d90f715SBarry Smith idxout[nf++] = tmp; 6359d90f715SBarry Smith } 6369d90f715SBarry Smith } else { 6379d90f715SBarry Smith for (i=0; i<n; i++) { 6389d90f715SBarry Smith if (idx[i] < 0) continue; 6399d90f715SBarry Smith if (idx[i] < bs*start) continue; 640663bb84eSBarry Smith if (idx[i] > bs*(end+1)-1) continue; 6419d90f715SBarry Smith tmp = bs*globals[idx[i]/bs - start] + (idx[i] % bs); 6429d90f715SBarry Smith if (tmp < 0) continue; 6439d90f715SBarry Smith nf++; 6449d90f715SBarry Smith } 6459d90f715SBarry Smith } 6469d90f715SBarry Smith if (nout) *nout = nf; 6479d90f715SBarry Smith } 6489d90f715SBarry Smith PetscFunctionReturn(0); 6499d90f715SBarry Smith } 6509d90f715SBarry Smith 6519d90f715SBarry Smith #undef __FUNCT__ 652d4fe737eSStefano Zampini #define __FUNCT__ "ISGlobalToLocalMappingApplyIS" 653d4fe737eSStefano Zampini /*@ 654d4fe737eSStefano Zampini ISGlobalToLocalMappingApplyIS - Creates from an IS in the global numbering 655d4fe737eSStefano Zampini a new index set using the local numbering defined in an ISLocalToGlobalMapping 656d4fe737eSStefano Zampini context. 657d4fe737eSStefano Zampini 658d4fe737eSStefano Zampini Not collective 659d4fe737eSStefano Zampini 660d4fe737eSStefano Zampini Input Parameters: 661d4fe737eSStefano Zampini + mapping - mapping between local and global numbering 662d4fe737eSStefano Zampini - is - index set in global numbering 663d4fe737eSStefano Zampini 664d4fe737eSStefano Zampini Output Parameters: 665d4fe737eSStefano Zampini . newis - index set in local numbering 666d4fe737eSStefano Zampini 667d4fe737eSStefano Zampini Level: advanced 668d4fe737eSStefano Zampini 669d4fe737eSStefano Zampini Concepts: mapping^local to global 670d4fe737eSStefano Zampini 671d4fe737eSStefano Zampini .seealso: ISGlobalToLocalMappingApply(), ISLocalToGlobalMappingCreate(), 672d4fe737eSStefano Zampini ISLocalToGlobalMappingDestroy() 673d4fe737eSStefano Zampini @*/ 674d4fe737eSStefano Zampini PetscErrorCode ISGlobalToLocalMappingApplyIS(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, IS is,IS *newis) 675d4fe737eSStefano Zampini { 676d4fe737eSStefano Zampini PetscErrorCode ierr; 677d4fe737eSStefano Zampini PetscInt n,nout,*idxout; 678d4fe737eSStefano Zampini const PetscInt *idxin; 679d4fe737eSStefano Zampini 680d4fe737eSStefano Zampini PetscFunctionBegin; 681d4fe737eSStefano Zampini PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 682d4fe737eSStefano Zampini PetscValidHeaderSpecific(is,IS_CLASSID,3); 683d4fe737eSStefano Zampini PetscValidPointer(newis,4); 684d4fe737eSStefano Zampini 685d4fe737eSStefano Zampini ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 686d4fe737eSStefano Zampini ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 687d4fe737eSStefano Zampini if (type == IS_GTOLM_MASK) { 688d4fe737eSStefano Zampini ierr = PetscMalloc1(n,&idxout);CHKERRQ(ierr); 689d4fe737eSStefano Zampini } else { 690d4fe737eSStefano Zampini ierr = ISGlobalToLocalMappingApply(mapping,type,n,idxin,&nout,NULL);CHKERRQ(ierr); 691d4fe737eSStefano Zampini ierr = PetscMalloc1(nout,&idxout);CHKERRQ(ierr); 692d4fe737eSStefano Zampini } 693d4fe737eSStefano Zampini ierr = ISGlobalToLocalMappingApply(mapping,type,n,idxin,&nout,idxout);CHKERRQ(ierr); 694d4fe737eSStefano Zampini ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 695d4fe737eSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is),nout,idxout,PETSC_OWN_POINTER,newis);CHKERRQ(ierr); 696d4fe737eSStefano Zampini PetscFunctionReturn(0); 697d4fe737eSStefano Zampini } 698d4fe737eSStefano Zampini 699d4fe737eSStefano Zampini #undef __FUNCT__ 7009d90f715SBarry Smith #define __FUNCT__ "ISGlobalToLocalMappingApplyBlock" 7019d90f715SBarry Smith /*@ 7029d90f715SBarry Smith ISGlobalToLocalMappingApplyBlock - Provides the local block numbering for a list of integers 7039d90f715SBarry Smith specified with a block global numbering. 7049d90f715SBarry Smith 7059d90f715SBarry Smith Not collective 7069d90f715SBarry Smith 7079d90f715SBarry Smith Input Parameters: 7089d90f715SBarry Smith + mapping - mapping between local and global numbering 7099d90f715SBarry Smith . type - IS_GTOLM_MASK - replaces global indices with no local value with -1 7109d90f715SBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 7119d90f715SBarry Smith . n - number of global indices to map 7129d90f715SBarry Smith - idx - global indices to map 7139d90f715SBarry Smith 7149d90f715SBarry Smith Output Parameters: 7159d90f715SBarry Smith + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 7169d90f715SBarry Smith - idxout - local index of each global index, one must pass in an array long enough 7179d90f715SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApplyBlock() with 7189d90f715SBarry Smith idxout == NULL to determine the required length (returned in nout) 7199d90f715SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApplyBlock() 7209d90f715SBarry Smith a second time to set the values. 7219d90f715SBarry Smith 7229d90f715SBarry Smith Notes: 7239d90f715SBarry Smith Either nout or idxout may be NULL. idx and idxout may be identical. 7249d90f715SBarry Smith 7259d90f715SBarry Smith This is not scalable in memory usage. Each processor requires O(Nglobal) size 7269d90f715SBarry Smith array to compute these. 7279d90f715SBarry Smith 7289d90f715SBarry Smith Level: advanced 7299d90f715SBarry Smith 7309d90f715SBarry Smith Developer Note: The manual page states that idx and idxout may be identical but the calling 7319d90f715SBarry Smith sequence declares idx as const so it cannot be the same as idxout. 7329d90f715SBarry Smith 7339d90f715SBarry Smith Concepts: mapping^global to local 7349d90f715SBarry Smith 7359d90f715SBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISGlobalToLocalMappingApply(), ISLocalToGlobalMappingCreate(), 7369d90f715SBarry Smith ISLocalToGlobalMappingDestroy() 7379d90f715SBarry Smith @*/ 7389d90f715SBarry Smith PetscErrorCode ISGlobalToLocalMappingApplyBlock(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, 7399d90f715SBarry Smith PetscInt n,const PetscInt idx[],PetscInt *nout,PetscInt idxout[]) 7409d90f715SBarry Smith { 74132dcc486SBarry Smith PetscInt i,*globals,nf = 0,tmp,start,end; 7426849ba73SBarry Smith PetscErrorCode ierr; 743d4bb536fSBarry Smith 7443a40ed3dSBarry Smith PetscFunctionBegin; 7450700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 746d4bb536fSBarry Smith if (!mapping->globals) { 747d4bb536fSBarry Smith ierr = ISGlobalToLocalMappingSetUp_Private(mapping);CHKERRQ(ierr); 748d4bb536fSBarry Smith } 749d4bb536fSBarry Smith globals = mapping->globals; 750d4bb536fSBarry Smith start = mapping->globalstart; 751d4bb536fSBarry Smith end = mapping->globalend; 752d4bb536fSBarry Smith 753d4bb536fSBarry Smith if (type == IS_GTOLM_MASK) { 754d4bb536fSBarry Smith if (idxout) { 755d4bb536fSBarry Smith for (i=0; i<n; i++) { 756d4bb536fSBarry Smith if (idx[i] < 0) idxout[i] = idx[i]; 757d4bb536fSBarry Smith else if (idx[i] < start) idxout[i] = -1; 758d4bb536fSBarry Smith else if (idx[i] > end) idxout[i] = -1; 759d4bb536fSBarry Smith else idxout[i] = globals[idx[i] - start]; 760d4bb536fSBarry Smith } 761d4bb536fSBarry Smith } 762d4bb536fSBarry Smith if (nout) *nout = n; 763d4bb536fSBarry Smith } else { 764d4bb536fSBarry Smith if (idxout) { 765d4bb536fSBarry Smith for (i=0; i<n; i++) { 766d4bb536fSBarry Smith if (idx[i] < 0) continue; 767d4bb536fSBarry Smith if (idx[i] < start) continue; 768d4bb536fSBarry Smith if (idx[i] > end) continue; 769d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 770d4bb536fSBarry Smith if (tmp < 0) continue; 771d4bb536fSBarry Smith idxout[nf++] = tmp; 772d4bb536fSBarry Smith } 773d4bb536fSBarry Smith } else { 774d4bb536fSBarry Smith for (i=0; i<n; i++) { 775d4bb536fSBarry Smith if (idx[i] < 0) continue; 776d4bb536fSBarry Smith if (idx[i] < start) continue; 777d4bb536fSBarry Smith if (idx[i] > end) continue; 778d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 779d4bb536fSBarry Smith if (tmp < 0) continue; 780d4bb536fSBarry Smith nf++; 781d4bb536fSBarry Smith } 782d4bb536fSBarry Smith } 783d4bb536fSBarry Smith if (nout) *nout = nf; 784d4bb536fSBarry Smith } 7853a40ed3dSBarry Smith PetscFunctionReturn(0); 786d4bb536fSBarry Smith } 78790f02eecSBarry Smith 7884a2ae208SSatish Balay #undef __FUNCT__ 7896a818285SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingGetBlockInfo" 79089d82c54SBarry Smith /*@C 7916a818285SBarry Smith ISLocalToGlobalMappingGetBlockInfo - Gets the neighbor information for each processor and 79289d82c54SBarry Smith each index shared by more than one processor 79389d82c54SBarry Smith 79489d82c54SBarry Smith Collective on ISLocalToGlobalMapping 79589d82c54SBarry Smith 79689d82c54SBarry Smith Input Parameters: 79789d82c54SBarry Smith . mapping - the mapping from local to global indexing 79889d82c54SBarry Smith 79989d82c54SBarry Smith Output Parameter: 80089d82c54SBarry Smith + nproc - number of processors that are connected to this one 80189d82c54SBarry Smith . proc - neighboring processors 80207b52d57SBarry Smith . numproc - number of indices for each subdomain (processor) 8033463a7baSJed Brown - indices - indices of nodes (in local numbering) shared with neighbors (sorted by global numbering) 80489d82c54SBarry Smith 80589d82c54SBarry Smith Level: advanced 80689d82c54SBarry Smith 807273d9f13SBarry Smith Concepts: mapping^local to global 80889d82c54SBarry Smith 8092cfcea29SBarry Smith Fortran Usage: 8102cfcea29SBarry Smith $ ISLocalToGlobalMpngGetInfoSize(ISLocalToGlobalMapping,PetscInt nproc,PetscInt numprocmax,ierr) followed by 8112cfcea29SBarry Smith $ ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping,PetscInt nproc, PetscInt procs[nproc],PetscInt numprocs[nproc], 8122cfcea29SBarry Smith PetscInt indices[nproc][numprocmax],ierr) 8132cfcea29SBarry Smith There is no ISLocalToGlobalMappingRestoreInfo() in Fortran. You must make sure that procs[], numprocs[] and 8142cfcea29SBarry Smith indices[][] are large enough arrays, either by allocating them dynamically or defining static ones large enough. 8152cfcea29SBarry Smith 8162cfcea29SBarry Smith 81707b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 81807b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo() 81989d82c54SBarry Smith @*/ 8206a818285SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetBlockInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 82189d82c54SBarry Smith { 8226849ba73SBarry Smith PetscErrorCode ierr; 823268a049cSStefano Zampini 824268a049cSStefano Zampini PetscFunctionBegin; 825268a049cSStefano Zampini PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 826268a049cSStefano Zampini if (mapping->info_cached) { 827268a049cSStefano Zampini *nproc = mapping->info_nproc; 828268a049cSStefano Zampini *procs = mapping->info_procs; 829268a049cSStefano Zampini *numprocs = mapping->info_numprocs; 830268a049cSStefano Zampini *indices = mapping->info_indices; 831268a049cSStefano Zampini } else { 832268a049cSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockInfo_Private(mapping,nproc,procs,numprocs,indices);CHKERRQ(ierr); 833268a049cSStefano Zampini } 834268a049cSStefano Zampini PetscFunctionReturn(0); 835268a049cSStefano Zampini } 836268a049cSStefano Zampini 837268a049cSStefano Zampini #undef __FUNCT__ 838268a049cSStefano Zampini #define __FUNCT__ "ISLocalToGlobalMappingGetBlockInfo_Private" 839268a049cSStefano Zampini static PetscErrorCode ISLocalToGlobalMappingGetBlockInfo_Private(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 840268a049cSStefano Zampini { 841268a049cSStefano Zampini PetscErrorCode ierr; 84297f1f81fSBarry Smith PetscMPIInt size,rank,tag1,tag2,tag3,*len,*source,imdex; 84332dcc486SBarry Smith PetscInt i,n = mapping->n,Ng,ng,max = 0,*lindices = mapping->indices; 84432dcc486SBarry Smith PetscInt *nprocs,*owner,nsends,*sends,j,*starts,nmax,nrecvs,*recvs,proc; 84597f1f81fSBarry Smith PetscInt cnt,scale,*ownedsenders,*nownedsenders,rstart,nowned; 84632dcc486SBarry Smith PetscInt node,nownedm,nt,*sends2,nsends2,*starts2,*lens2,*dest,nrecvs2,*starts3,*recvs2,k,*bprocs,*tmp; 84732dcc486SBarry Smith PetscInt first_procs,first_numprocs,*first_indices; 84889d82c54SBarry Smith MPI_Request *recv_waits,*send_waits; 84930dcb7c9SBarry Smith MPI_Status recv_status,*send_status,*recv_statuses; 850ce94432eSBarry Smith MPI_Comm comm; 851ace3abfcSBarry Smith PetscBool debug = PETSC_FALSE; 85289d82c54SBarry Smith 85389d82c54SBarry Smith PetscFunctionBegin; 854ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)mapping,&comm);CHKERRQ(ierr); 85524cf384cSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 85624cf384cSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 85724cf384cSBarry Smith if (size == 1) { 85824cf384cSBarry Smith *nproc = 0; 8590298fd71SBarry Smith *procs = NULL; 86095dccacaSBarry Smith ierr = PetscNew(numprocs);CHKERRQ(ierr); 8611e2105dcSBarry Smith (*numprocs)[0] = 0; 86295dccacaSBarry Smith ierr = PetscNew(indices);CHKERRQ(ierr); 8630298fd71SBarry Smith (*indices)[0] = NULL; 864268a049cSStefano Zampini /* save info for reuse */ 865268a049cSStefano Zampini mapping->info_nproc = *nproc; 866268a049cSStefano Zampini mapping->info_procs = *procs; 867268a049cSStefano Zampini mapping->info_numprocs = *numprocs; 868268a049cSStefano Zampini mapping->info_indices = *indices; 869268a049cSStefano Zampini mapping->info_cached = PETSC_TRUE; 87024cf384cSBarry Smith PetscFunctionReturn(0); 87124cf384cSBarry Smith } 87224cf384cSBarry Smith 873c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject)mapping)->options,NULL,"-islocaltoglobalmappinggetinfo_debug",&debug,NULL);CHKERRQ(ierr); 87407b52d57SBarry Smith 8753677ff5aSBarry Smith /* 8766a818285SBarry Smith Notes on ISLocalToGlobalMappingGetBlockInfo 8773677ff5aSBarry Smith 8783677ff5aSBarry Smith globally owned node - the nodes that have been assigned to this processor in global 8793677ff5aSBarry Smith numbering, just for this routine. 8803677ff5aSBarry Smith 8813677ff5aSBarry Smith nontrivial globally owned node - node assigned to this processor that is on a subdomain 8823677ff5aSBarry Smith boundary (i.e. is has more than one local owner) 8833677ff5aSBarry Smith 8843677ff5aSBarry Smith locally owned node - node that exists on this processors subdomain 8853677ff5aSBarry Smith 8863677ff5aSBarry Smith nontrivial locally owned node - node that is not in the interior (i.e. has more than one 8873677ff5aSBarry Smith local subdomain 8883677ff5aSBarry Smith */ 88924cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag1);CHKERRQ(ierr); 89024cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag2);CHKERRQ(ierr); 89124cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag3);CHKERRQ(ierr); 89289d82c54SBarry Smith 89389d82c54SBarry Smith for (i=0; i<n; i++) { 89489d82c54SBarry Smith if (lindices[i] > max) max = lindices[i]; 89589d82c54SBarry Smith } 896b2566f29SBarry Smith ierr = MPIU_Allreduce(&max,&Ng,1,MPIU_INT,MPI_MAX,comm);CHKERRQ(ierr); 89778058e43SBarry Smith Ng++; 89889d82c54SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 89989d82c54SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 900bc8ff85bSBarry Smith scale = Ng/size + 1; 901a2e34c3dSBarry Smith ng = scale; if (rank == size-1) ng = Ng - scale*(size-1); ng = PetscMax(1,ng); 902caba0dd0SBarry Smith rstart = scale*rank; 90389d82c54SBarry Smith 90489d82c54SBarry Smith /* determine ownership ranges of global indices */ 905785e854fSJed Brown ierr = PetscMalloc1(2*size,&nprocs);CHKERRQ(ierr); 90632dcc486SBarry Smith ierr = PetscMemzero(nprocs,2*size*sizeof(PetscInt));CHKERRQ(ierr); 90789d82c54SBarry Smith 90889d82c54SBarry Smith /* determine owners of each local node */ 909785e854fSJed Brown ierr = PetscMalloc1(n,&owner);CHKERRQ(ierr); 91089d82c54SBarry Smith for (i=0; i<n; i++) { 9113677ff5aSBarry Smith proc = lindices[i]/scale; /* processor that globally owns this index */ 91227c402fcSBarry Smith nprocs[2*proc+1] = 1; /* processor globally owns at least one of ours */ 9133677ff5aSBarry Smith owner[i] = proc; 91427c402fcSBarry Smith nprocs[2*proc]++; /* count of how many that processor globally owns of ours */ 91589d82c54SBarry Smith } 91627c402fcSBarry Smith nsends = 0; for (i=0; i<size; i++) nsends += nprocs[2*i+1]; 9177904a332SBarry Smith ierr = PetscInfo1(mapping,"Number of global owners for my local data %D\n",nsends);CHKERRQ(ierr); 91889d82c54SBarry Smith 91989d82c54SBarry Smith /* inform other processors of number of messages and max length*/ 92027c402fcSBarry Smith ierr = PetscMaxSum(comm,nprocs,&nmax,&nrecvs);CHKERRQ(ierr); 9217904a332SBarry Smith ierr = PetscInfo1(mapping,"Number of local owners for my global data %D\n",nrecvs);CHKERRQ(ierr); 92289d82c54SBarry Smith 92389d82c54SBarry Smith /* post receives for owned rows */ 924785e854fSJed Brown ierr = PetscMalloc1((2*nrecvs+1)*(nmax+1),&recvs);CHKERRQ(ierr); 925854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,&recv_waits);CHKERRQ(ierr); 92689d82c54SBarry Smith for (i=0; i<nrecvs; i++) { 92732dcc486SBarry Smith ierr = MPI_Irecv(recvs+2*nmax*i,2*nmax,MPIU_INT,MPI_ANY_SOURCE,tag1,comm,recv_waits+i);CHKERRQ(ierr); 92889d82c54SBarry Smith } 92989d82c54SBarry Smith 93089d82c54SBarry Smith /* pack messages containing lists of local nodes to owners */ 931854ce69bSBarry Smith ierr = PetscMalloc1(2*n+1,&sends);CHKERRQ(ierr); 932854ce69bSBarry Smith ierr = PetscMalloc1(size+1,&starts);CHKERRQ(ierr); 93389d82c54SBarry Smith starts[0] = 0; 934f6e5521dSKarl Rupp for (i=1; i<size; i++) starts[i] = starts[i-1] + 2*nprocs[2*i-2]; 93589d82c54SBarry Smith for (i=0; i<n; i++) { 93689d82c54SBarry Smith sends[starts[owner[i]]++] = lindices[i]; 93730dcb7c9SBarry Smith sends[starts[owner[i]]++] = i; 93889d82c54SBarry Smith } 93989d82c54SBarry Smith ierr = PetscFree(owner);CHKERRQ(ierr); 94089d82c54SBarry Smith starts[0] = 0; 941f6e5521dSKarl Rupp for (i=1; i<size; i++) starts[i] = starts[i-1] + 2*nprocs[2*i-2]; 94289d82c54SBarry Smith 94389d82c54SBarry Smith /* send the messages */ 944854ce69bSBarry Smith ierr = PetscMalloc1(nsends+1,&send_waits);CHKERRQ(ierr); 945854ce69bSBarry Smith ierr = PetscMalloc1(nsends+1,&dest);CHKERRQ(ierr); 94689d82c54SBarry Smith cnt = 0; 94789d82c54SBarry Smith for (i=0; i<size; i++) { 94827c402fcSBarry Smith if (nprocs[2*i]) { 94932dcc486SBarry Smith ierr = MPI_Isend(sends+starts[i],2*nprocs[2*i],MPIU_INT,i,tag1,comm,send_waits+cnt);CHKERRQ(ierr); 95030dcb7c9SBarry Smith dest[cnt] = i; 95189d82c54SBarry Smith cnt++; 95289d82c54SBarry Smith } 95389d82c54SBarry Smith } 95489d82c54SBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 95589d82c54SBarry Smith 95689d82c54SBarry Smith /* wait on receives */ 957854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,&source);CHKERRQ(ierr); 958854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,&len);CHKERRQ(ierr); 95989d82c54SBarry Smith cnt = nrecvs; 960854ce69bSBarry Smith ierr = PetscMalloc1(ng+1,&nownedsenders);CHKERRQ(ierr); 96132dcc486SBarry Smith ierr = PetscMemzero(nownedsenders,ng*sizeof(PetscInt));CHKERRQ(ierr); 96289d82c54SBarry Smith while (cnt) { 96389d82c54SBarry Smith ierr = MPI_Waitany(nrecvs,recv_waits,&imdex,&recv_status);CHKERRQ(ierr); 96489d82c54SBarry Smith /* unpack receives into our local space */ 96532dcc486SBarry Smith ierr = MPI_Get_count(&recv_status,MPIU_INT,&len[imdex]);CHKERRQ(ierr); 96689d82c54SBarry Smith source[imdex] = recv_status.MPI_SOURCE; 96730dcb7c9SBarry Smith len[imdex] = len[imdex]/2; 968caba0dd0SBarry Smith /* count how many local owners for each of my global owned indices */ 96930dcb7c9SBarry Smith for (i=0; i<len[imdex]; i++) nownedsenders[recvs[2*imdex*nmax+2*i]-rstart]++; 97089d82c54SBarry Smith cnt--; 97189d82c54SBarry Smith } 97289d82c54SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 97389d82c54SBarry Smith 97430dcb7c9SBarry Smith /* count how many globally owned indices are on an edge multiplied by how many processors own them. */ 975bc8ff85bSBarry Smith nowned = 0; 976bc8ff85bSBarry Smith nownedm = 0; 977bc8ff85bSBarry Smith for (i=0; i<ng; i++) { 978bc8ff85bSBarry Smith if (nownedsenders[i] > 1) {nownedm += nownedsenders[i]; nowned++;} 979bc8ff85bSBarry Smith } 980bc8ff85bSBarry Smith 981bc8ff85bSBarry Smith /* create single array to contain rank of all local owners of each globally owned index */ 982854ce69bSBarry Smith ierr = PetscMalloc1(nownedm+1,&ownedsenders);CHKERRQ(ierr); 983854ce69bSBarry Smith ierr = PetscMalloc1(ng+1,&starts);CHKERRQ(ierr); 984bc8ff85bSBarry Smith starts[0] = 0; 985bc8ff85bSBarry Smith for (i=1; i<ng; i++) { 986bc8ff85bSBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 987bc8ff85bSBarry Smith else starts[i] = starts[i-1]; 988bc8ff85bSBarry Smith } 989bc8ff85bSBarry Smith 99030dcb7c9SBarry Smith /* for each nontrival globally owned node list all arriving processors */ 991bc8ff85bSBarry Smith for (i=0; i<nrecvs; i++) { 992bc8ff85bSBarry Smith for (j=0; j<len[i]; j++) { 99330dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 994f6e5521dSKarl Rupp if (nownedsenders[node] > 1) ownedsenders[starts[node]++] = source[i]; 995bc8ff85bSBarry Smith } 996bc8ff85bSBarry Smith } 997bc8ff85bSBarry Smith 99807b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 99930dcb7c9SBarry Smith starts[0] = 0; 100030dcb7c9SBarry Smith for (i=1; i<ng; i++) { 100130dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 100230dcb7c9SBarry Smith else starts[i] = starts[i-1]; 100330dcb7c9SBarry Smith } 100430dcb7c9SBarry Smith for (i=0; i<ng; i++) { 100530dcb7c9SBarry Smith if (nownedsenders[i] > 1) { 10067904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] global node %D local owner processors: ",rank,i+rstart);CHKERRQ(ierr); 100730dcb7c9SBarry Smith for (j=0; j<nownedsenders[i]; j++) { 10087904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%D ",ownedsenders[starts[i]+j]);CHKERRQ(ierr); 100930dcb7c9SBarry Smith } 101030dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 101130dcb7c9SBarry Smith } 101230dcb7c9SBarry Smith } 10130ec8b6e3SBarry Smith ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 101407b52d57SBarry Smith } /* ----------------------------------- */ 101530dcb7c9SBarry Smith 10163677ff5aSBarry Smith /* wait on original sends */ 10173a96401aSBarry Smith if (nsends) { 1018785e854fSJed Brown ierr = PetscMalloc1(nsends,&send_status);CHKERRQ(ierr); 10193a96401aSBarry Smith ierr = MPI_Waitall(nsends,send_waits,send_status);CHKERRQ(ierr); 10203a96401aSBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 10213a96401aSBarry Smith } 102289d82c54SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 10233a96401aSBarry Smith ierr = PetscFree(sends);CHKERRQ(ierr); 10243677ff5aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 10253677ff5aSBarry Smith 10263677ff5aSBarry Smith /* pack messages to send back to local owners */ 102730dcb7c9SBarry Smith starts[0] = 0; 102830dcb7c9SBarry Smith for (i=1; i<ng; i++) { 102930dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 103030dcb7c9SBarry Smith else starts[i] = starts[i-1]; 103130dcb7c9SBarry Smith } 103230dcb7c9SBarry Smith nsends2 = nrecvs; 1033854ce69bSBarry Smith ierr = PetscMalloc1(nsends2+1,&nprocs);CHKERRQ(ierr); /* length of each message */ 103430dcb7c9SBarry Smith for (i=0; i<nrecvs; i++) { 103530dcb7c9SBarry Smith nprocs[i] = 1; 103630dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 103730dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 1038f6e5521dSKarl Rupp if (nownedsenders[node] > 1) nprocs[i] += 2 + nownedsenders[node]; 103930dcb7c9SBarry Smith } 104030dcb7c9SBarry Smith } 1041f6e5521dSKarl Rupp nt = 0; 1042f6e5521dSKarl Rupp for (i=0; i<nsends2; i++) nt += nprocs[i]; 1043f6e5521dSKarl Rupp 1044854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,&sends2);CHKERRQ(ierr); 1045854ce69bSBarry Smith ierr = PetscMalloc1(nsends2+1,&starts2);CHKERRQ(ierr); 1046f6e5521dSKarl Rupp 1047f6e5521dSKarl Rupp starts2[0] = 0; 1048f6e5521dSKarl Rupp for (i=1; i<nsends2; i++) starts2[i] = starts2[i-1] + nprocs[i-1]; 104930dcb7c9SBarry Smith /* 105030dcb7c9SBarry Smith Each message is 1 + nprocs[i] long, and consists of 105130dcb7c9SBarry Smith (0) the number of nodes being sent back 105230dcb7c9SBarry Smith (1) the local node number, 105330dcb7c9SBarry Smith (2) the number of processors sharing it, 105430dcb7c9SBarry Smith (3) the processors sharing it 105530dcb7c9SBarry Smith */ 105630dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 105730dcb7c9SBarry Smith cnt = 1; 105830dcb7c9SBarry Smith sends2[starts2[i]] = 0; 105930dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 106030dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 106130dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 106230dcb7c9SBarry Smith sends2[starts2[i]]++; 106330dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = recvs[2*i*nmax+2*j+1]; 106430dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = nownedsenders[node]; 106532dcc486SBarry Smith ierr = PetscMemcpy(&sends2[starts2[i]+cnt],&ownedsenders[starts[node]],nownedsenders[node]*sizeof(PetscInt));CHKERRQ(ierr); 106630dcb7c9SBarry Smith cnt += nownedsenders[node]; 106730dcb7c9SBarry Smith } 106830dcb7c9SBarry Smith } 106930dcb7c9SBarry Smith } 107030dcb7c9SBarry Smith 107130dcb7c9SBarry Smith /* receive the message lengths */ 107230dcb7c9SBarry Smith nrecvs2 = nsends; 1073854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&lens2);CHKERRQ(ierr); 1074854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&starts3);CHKERRQ(ierr); 1075854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&recv_waits);CHKERRQ(ierr); 107630dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 1077d44834fbSBarry Smith ierr = MPI_Irecv(&lens2[i],1,MPIU_INT,dest[i],tag2,comm,recv_waits+i);CHKERRQ(ierr); 107830dcb7c9SBarry Smith } 1079d44834fbSBarry Smith 10808a8e0b3aSBarry Smith /* send the message lengths */ 10818a8e0b3aSBarry Smith for (i=0; i<nsends2; i++) { 10828a8e0b3aSBarry Smith ierr = MPI_Send(&nprocs[i],1,MPIU_INT,source[i],tag2,comm);CHKERRQ(ierr); 10838a8e0b3aSBarry Smith } 10848a8e0b3aSBarry Smith 1085d44834fbSBarry Smith /* wait on receives of lens */ 10860c468ba9SBarry Smith if (nrecvs2) { 1087785e854fSJed Brown ierr = PetscMalloc1(nrecvs2,&recv_statuses);CHKERRQ(ierr); 1088d44834fbSBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 1089d44834fbSBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 10900c468ba9SBarry Smith } 1091a2ea699eSBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 1092d44834fbSBarry Smith 109330dcb7c9SBarry Smith starts3[0] = 0; 1094d44834fbSBarry Smith nt = 0; 109530dcb7c9SBarry Smith for (i=0; i<nrecvs2-1; i++) { 109630dcb7c9SBarry Smith starts3[i+1] = starts3[i] + lens2[i]; 1097d44834fbSBarry Smith nt += lens2[i]; 109830dcb7c9SBarry Smith } 109976466f69SStefano Zampini if (nrecvs2) nt += lens2[nrecvs2-1]; 1100d44834fbSBarry Smith 1101854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,&recvs2);CHKERRQ(ierr); 1102854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&recv_waits);CHKERRQ(ierr); 110352b72c4aSBarry Smith for (i=0; i<nrecvs2; i++) { 110432dcc486SBarry Smith ierr = MPI_Irecv(recvs2+starts3[i],lens2[i],MPIU_INT,dest[i],tag3,comm,recv_waits+i);CHKERRQ(ierr); 110530dcb7c9SBarry Smith } 110630dcb7c9SBarry Smith 110730dcb7c9SBarry Smith /* send the messages */ 1108854ce69bSBarry Smith ierr = PetscMalloc1(nsends2+1,&send_waits);CHKERRQ(ierr); 110930dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 111032dcc486SBarry Smith ierr = MPI_Isend(sends2+starts2[i],nprocs[i],MPIU_INT,source[i],tag3,comm,send_waits+i);CHKERRQ(ierr); 111130dcb7c9SBarry Smith } 111230dcb7c9SBarry Smith 111330dcb7c9SBarry Smith /* wait on receives */ 11140c468ba9SBarry Smith if (nrecvs2) { 1115785e854fSJed Brown ierr = PetscMalloc1(nrecvs2,&recv_statuses);CHKERRQ(ierr); 111630dcb7c9SBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 111730dcb7c9SBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 11180c468ba9SBarry Smith } 111930dcb7c9SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 112030dcb7c9SBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 112130dcb7c9SBarry Smith 112207b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 112330dcb7c9SBarry Smith cnt = 0; 112430dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 112530dcb7c9SBarry Smith nt = recvs2[cnt++]; 112630dcb7c9SBarry Smith for (j=0; j<nt; j++) { 11277904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] local node %D number of subdomains %D: ",rank,recvs2[cnt],recvs2[cnt+1]);CHKERRQ(ierr); 112830dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 11297904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%D ",recvs2[cnt+2+k]);CHKERRQ(ierr); 113030dcb7c9SBarry Smith } 113130dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 113230dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 113330dcb7c9SBarry Smith } 113430dcb7c9SBarry Smith } 11350ec8b6e3SBarry Smith ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 113607b52d57SBarry Smith } /* ----------------------------------- */ 113730dcb7c9SBarry Smith 113830dcb7c9SBarry Smith /* count number subdomains for each local node */ 1139785e854fSJed Brown ierr = PetscMalloc1(size,&nprocs);CHKERRQ(ierr); 114032dcc486SBarry Smith ierr = PetscMemzero(nprocs,size*sizeof(PetscInt));CHKERRQ(ierr); 114130dcb7c9SBarry Smith cnt = 0; 114230dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 114330dcb7c9SBarry Smith nt = recvs2[cnt++]; 114430dcb7c9SBarry Smith for (j=0; j<nt; j++) { 1145f6e5521dSKarl Rupp for (k=0; k<recvs2[cnt+1]; k++) nprocs[recvs2[cnt+2+k]]++; 114630dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 114730dcb7c9SBarry Smith } 114830dcb7c9SBarry Smith } 114930dcb7c9SBarry Smith nt = 0; for (i=0; i<size; i++) nt += (nprocs[i] > 0); 115030dcb7c9SBarry Smith *nproc = nt; 1151854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,procs);CHKERRQ(ierr); 1152854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,numprocs);CHKERRQ(ierr); 1153854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,indices);CHKERRQ(ierr); 11540298fd71SBarry Smith for (i=0;i<nt+1;i++) (*indices)[i]=NULL; 1155785e854fSJed Brown ierr = PetscMalloc1(size,&bprocs);CHKERRQ(ierr); 115630dcb7c9SBarry Smith cnt = 0; 115730dcb7c9SBarry Smith for (i=0; i<size; i++) { 115830dcb7c9SBarry Smith if (nprocs[i] > 0) { 115930dcb7c9SBarry Smith bprocs[i] = cnt; 116030dcb7c9SBarry Smith (*procs)[cnt] = i; 116130dcb7c9SBarry Smith (*numprocs)[cnt] = nprocs[i]; 1162785e854fSJed Brown ierr = PetscMalloc1(nprocs[i],&(*indices)[cnt]);CHKERRQ(ierr); 116330dcb7c9SBarry Smith cnt++; 116430dcb7c9SBarry Smith } 116530dcb7c9SBarry Smith } 116630dcb7c9SBarry Smith 116730dcb7c9SBarry Smith /* make the list of subdomains for each nontrivial local node */ 116832dcc486SBarry Smith ierr = PetscMemzero(*numprocs,nt*sizeof(PetscInt));CHKERRQ(ierr); 116930dcb7c9SBarry Smith cnt = 0; 117030dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 117130dcb7c9SBarry Smith nt = recvs2[cnt++]; 117230dcb7c9SBarry Smith for (j=0; j<nt; j++) { 1173f6e5521dSKarl Rupp for (k=0; k<recvs2[cnt+1]; k++) (*indices)[bprocs[recvs2[cnt+2+k]]][(*numprocs)[bprocs[recvs2[cnt+2+k]]]++] = recvs2[cnt]; 117430dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 117530dcb7c9SBarry Smith } 117630dcb7c9SBarry Smith } 117730dcb7c9SBarry Smith ierr = PetscFree(bprocs);CHKERRQ(ierr); 117807b52d57SBarry Smith ierr = PetscFree(recvs2);CHKERRQ(ierr); 117930dcb7c9SBarry Smith 118007b52d57SBarry Smith /* sort the node indexing by their global numbers */ 118107b52d57SBarry Smith nt = *nproc; 118207b52d57SBarry Smith for (i=0; i<nt; i++) { 1183854ce69bSBarry Smith ierr = PetscMalloc1((*numprocs)[i],&tmp);CHKERRQ(ierr); 1184f6e5521dSKarl Rupp for (j=0; j<(*numprocs)[i]; j++) tmp[j] = lindices[(*indices)[i][j]]; 118507b52d57SBarry Smith ierr = PetscSortIntWithArray((*numprocs)[i],tmp,(*indices)[i]);CHKERRQ(ierr); 118607b52d57SBarry Smith ierr = PetscFree(tmp);CHKERRQ(ierr); 118707b52d57SBarry Smith } 118807b52d57SBarry Smith 118907b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 119030dcb7c9SBarry Smith nt = *nproc; 119130dcb7c9SBarry Smith for (i=0; i<nt; i++) { 11927904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] subdomain %D number of indices %D: ",rank,(*procs)[i],(*numprocs)[i]);CHKERRQ(ierr); 119330dcb7c9SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 11947904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%D ",(*indices)[i][j]);CHKERRQ(ierr); 119530dcb7c9SBarry Smith } 119630dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 119730dcb7c9SBarry Smith } 11980ec8b6e3SBarry Smith ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 119907b52d57SBarry Smith } /* ----------------------------------- */ 120030dcb7c9SBarry Smith 120130dcb7c9SBarry Smith /* wait on sends */ 120230dcb7c9SBarry Smith if (nsends2) { 1203785e854fSJed Brown ierr = PetscMalloc1(nsends2,&send_status);CHKERRQ(ierr); 120430dcb7c9SBarry Smith ierr = MPI_Waitall(nsends2,send_waits,send_status);CHKERRQ(ierr); 120530dcb7c9SBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 120630dcb7c9SBarry Smith } 120730dcb7c9SBarry Smith 120830dcb7c9SBarry Smith ierr = PetscFree(starts3);CHKERRQ(ierr); 120930dcb7c9SBarry Smith ierr = PetscFree(dest);CHKERRQ(ierr); 121030dcb7c9SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 12113677ff5aSBarry Smith 1212bc8ff85bSBarry Smith ierr = PetscFree(nownedsenders);CHKERRQ(ierr); 1213bc8ff85bSBarry Smith ierr = PetscFree(ownedsenders);CHKERRQ(ierr); 1214bc8ff85bSBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 121530dcb7c9SBarry Smith ierr = PetscFree(starts2);CHKERRQ(ierr); 121630dcb7c9SBarry Smith ierr = PetscFree(lens2);CHKERRQ(ierr); 121789d82c54SBarry Smith 121889d82c54SBarry Smith ierr = PetscFree(source);CHKERRQ(ierr); 121997f1f81fSBarry Smith ierr = PetscFree(len);CHKERRQ(ierr); 122089d82c54SBarry Smith ierr = PetscFree(recvs);CHKERRQ(ierr); 12213a96401aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 122230dcb7c9SBarry Smith ierr = PetscFree(sends2);CHKERRQ(ierr); 122324cf384cSBarry Smith 122424cf384cSBarry Smith /* put the information about myself as the first entry in the list */ 122524cf384cSBarry Smith first_procs = (*procs)[0]; 122624cf384cSBarry Smith first_numprocs = (*numprocs)[0]; 122724cf384cSBarry Smith first_indices = (*indices)[0]; 122824cf384cSBarry Smith for (i=0; i<*nproc; i++) { 122924cf384cSBarry Smith if ((*procs)[i] == rank) { 123024cf384cSBarry Smith (*procs)[0] = (*procs)[i]; 123124cf384cSBarry Smith (*numprocs)[0] = (*numprocs)[i]; 123224cf384cSBarry Smith (*indices)[0] = (*indices)[i]; 123324cf384cSBarry Smith (*procs)[i] = first_procs; 123424cf384cSBarry Smith (*numprocs)[i] = first_numprocs; 123524cf384cSBarry Smith (*indices)[i] = first_indices; 123624cf384cSBarry Smith break; 123724cf384cSBarry Smith } 123824cf384cSBarry Smith } 1239268a049cSStefano Zampini 1240268a049cSStefano Zampini /* save info for reuse */ 1241268a049cSStefano Zampini mapping->info_nproc = *nproc; 1242268a049cSStefano Zampini mapping->info_procs = *procs; 1243268a049cSStefano Zampini mapping->info_numprocs = *numprocs; 1244268a049cSStefano Zampini mapping->info_indices = *indices; 1245268a049cSStefano Zampini mapping->info_cached = PETSC_TRUE; 124689d82c54SBarry Smith PetscFunctionReturn(0); 124789d82c54SBarry Smith } 124889d82c54SBarry Smith 12494a2ae208SSatish Balay #undef __FUNCT__ 12506a818285SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingRestoreBlockInfo" 12516a818285SBarry Smith /*@C 12526a818285SBarry Smith ISLocalToGlobalMappingRestoreBlockInfo - Frees the memory allocated by ISLocalToGlobalMappingGetBlockInfo() 12536a818285SBarry Smith 12546a818285SBarry Smith Collective on ISLocalToGlobalMapping 12556a818285SBarry Smith 12566a818285SBarry Smith Input Parameters: 12576a818285SBarry Smith . mapping - the mapping from local to global indexing 12586a818285SBarry Smith 12596a818285SBarry Smith Output Parameter: 12606a818285SBarry Smith + nproc - number of processors that are connected to this one 12616a818285SBarry Smith . proc - neighboring processors 12626a818285SBarry Smith . numproc - number of indices for each processor 12636a818285SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 12646a818285SBarry Smith 12656a818285SBarry Smith Level: advanced 12666a818285SBarry Smith 12676a818285SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 12686a818285SBarry Smith ISLocalToGlobalMappingGetInfo() 12696a818285SBarry Smith @*/ 12706a818285SBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreBlockInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 12716a818285SBarry Smith { 12726a818285SBarry Smith PetscErrorCode ierr; 12736a818285SBarry Smith 12746a818285SBarry Smith PetscFunctionBegin; 1275cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 1276268a049cSStefano Zampini if (mapping->info_free) { 12776a818285SBarry Smith ierr = PetscFree(*numprocs);CHKERRQ(ierr); 12786a818285SBarry Smith if (*indices) { 1279268a049cSStefano Zampini PetscInt i; 1280268a049cSStefano Zampini 12816a818285SBarry Smith ierr = PetscFree((*indices)[0]);CHKERRQ(ierr); 12826a818285SBarry Smith for (i=1; i<*nproc; i++) { 12836a818285SBarry Smith ierr = PetscFree((*indices)[i]);CHKERRQ(ierr); 12846a818285SBarry Smith } 12856a818285SBarry Smith ierr = PetscFree(*indices);CHKERRQ(ierr); 12866a818285SBarry Smith } 1287268a049cSStefano Zampini } 1288268a049cSStefano Zampini *nproc = 0; 1289268a049cSStefano Zampini *procs = NULL; 1290268a049cSStefano Zampini *numprocs = NULL; 1291268a049cSStefano Zampini *indices = NULL; 12926a818285SBarry Smith PetscFunctionReturn(0); 12936a818285SBarry Smith } 12946a818285SBarry Smith 12956a818285SBarry Smith #undef __FUNCT__ 12966a818285SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingGetInfo" 12976a818285SBarry Smith /*@C 12986a818285SBarry Smith ISLocalToGlobalMappingGetInfo - Gets the neighbor information for each processor and 12996a818285SBarry Smith each index shared by more than one processor 13006a818285SBarry Smith 13016a818285SBarry Smith Collective on ISLocalToGlobalMapping 13026a818285SBarry Smith 13036a818285SBarry Smith Input Parameters: 13046a818285SBarry Smith . mapping - the mapping from local to global indexing 13056a818285SBarry Smith 13066a818285SBarry Smith Output Parameter: 13076a818285SBarry Smith + nproc - number of processors that are connected to this one 13086a818285SBarry Smith . proc - neighboring processors 13096a818285SBarry Smith . numproc - number of indices for each subdomain (processor) 13106a818285SBarry Smith - indices - indices of nodes (in local numbering) shared with neighbors (sorted by global numbering) 13116a818285SBarry Smith 13126a818285SBarry Smith Level: advanced 13136a818285SBarry Smith 13146a818285SBarry Smith Concepts: mapping^local to global 13156a818285SBarry Smith 13166a818285SBarry Smith Fortran Usage: 13176a818285SBarry Smith $ ISLocalToGlobalMpngGetInfoSize(ISLocalToGlobalMapping,PetscInt nproc,PetscInt numprocmax,ierr) followed by 13186a818285SBarry Smith $ ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping,PetscInt nproc, PetscInt procs[nproc],PetscInt numprocs[nproc], 13196a818285SBarry Smith PetscInt indices[nproc][numprocmax],ierr) 13206a818285SBarry Smith There is no ISLocalToGlobalMappingRestoreInfo() in Fortran. You must make sure that procs[], numprocs[] and 13216a818285SBarry Smith indices[][] are large enough arrays, either by allocating them dynamically or defining static ones large enough. 13226a818285SBarry Smith 13236a818285SBarry Smith 13246a818285SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 13256a818285SBarry Smith ISLocalToGlobalMappingRestoreInfo() 13266a818285SBarry Smith @*/ 13276a818285SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 13286a818285SBarry Smith { 13296a818285SBarry Smith PetscErrorCode ierr; 1330268a049cSStefano Zampini PetscInt **bindices = NULL,*bnumprocs = NULL,bs = mapping->bs,i,j,k; 13316a818285SBarry Smith 13326a818285SBarry Smith PetscFunctionBegin; 13336a818285SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 1334268a049cSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockInfo(mapping,nproc,procs,&bnumprocs,&bindices);CHKERRQ(ierr); 1335268a049cSStefano Zampini if (bs > 1) { /* we need to expand the cached info */ 1336732f65e3SBarry Smith ierr = PetscCalloc1(*nproc,&*indices);CHKERRQ(ierr); 1337268a049cSStefano Zampini ierr = PetscCalloc1(*nproc,&*numprocs);CHKERRQ(ierr); 13386a818285SBarry Smith for (i=0; i<*nproc; i++) { 1339268a049cSStefano Zampini ierr = PetscMalloc1(bs*bnumprocs[i],&(*indices)[i]);CHKERRQ(ierr); 1340268a049cSStefano Zampini for (j=0; j<bnumprocs[i]; j++) { 13416a818285SBarry Smith for (k=0; k<bs; k++) { 13426a818285SBarry Smith (*indices)[i][j*bs+k] = bs*bindices[i][j] + k; 13436a818285SBarry Smith } 13446a818285SBarry Smith } 1345268a049cSStefano Zampini (*numprocs)[i] = bnumprocs[i]*bs; 13466a818285SBarry Smith } 1347268a049cSStefano Zampini mapping->info_free = PETSC_TRUE; 1348268a049cSStefano Zampini } else { 1349268a049cSStefano Zampini *numprocs = bnumprocs; 1350268a049cSStefano Zampini *indices = bindices; 13516a818285SBarry Smith } 13526a818285SBarry Smith PetscFunctionReturn(0); 13536a818285SBarry Smith } 13546a818285SBarry Smith 13556a818285SBarry Smith #undef __FUNCT__ 13564a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingRestoreInfo" 135707b52d57SBarry Smith /*@C 135807b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo - Frees the memory allocated by ISLocalToGlobalMappingGetInfo() 135989d82c54SBarry Smith 136007b52d57SBarry Smith Collective on ISLocalToGlobalMapping 136107b52d57SBarry Smith 136207b52d57SBarry Smith Input Parameters: 136307b52d57SBarry Smith . mapping - the mapping from local to global indexing 136407b52d57SBarry Smith 136507b52d57SBarry Smith Output Parameter: 136607b52d57SBarry Smith + nproc - number of processors that are connected to this one 136707b52d57SBarry Smith . proc - neighboring processors 136807b52d57SBarry Smith . numproc - number of indices for each processor 136907b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 137007b52d57SBarry Smith 137107b52d57SBarry Smith Level: advanced 137207b52d57SBarry Smith 137307b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 137407b52d57SBarry Smith ISLocalToGlobalMappingGetInfo() 137507b52d57SBarry Smith @*/ 13767087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 137707b52d57SBarry Smith { 13786849ba73SBarry Smith PetscErrorCode ierr; 137907b52d57SBarry Smith 138007b52d57SBarry Smith PetscFunctionBegin; 13816a818285SBarry Smith ierr = ISLocalToGlobalMappingRestoreBlockInfo(mapping,nproc,procs,numprocs,indices);CHKERRQ(ierr); 138207b52d57SBarry Smith PetscFunctionReturn(0); 138307b52d57SBarry Smith } 138486994e45SJed Brown 138586994e45SJed Brown #undef __FUNCT__ 138686994e45SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingGetIndices" 138786994e45SJed Brown /*@C 1388107e9a97SBarry Smith ISLocalToGlobalMappingGetIndices - Get global indices for every local point that is mapped 138986994e45SJed Brown 139086994e45SJed Brown Not Collective 139186994e45SJed Brown 139286994e45SJed Brown Input Arguments: 139386994e45SJed Brown . ltog - local to global mapping 139486994e45SJed Brown 139586994e45SJed Brown Output Arguments: 1396565245c5SBarry Smith . array - array of indices, the length of this array may be obtained with ISLocalToGlobalMappingGetSize() 139786994e45SJed Brown 139886994e45SJed Brown Level: advanced 139986994e45SJed Brown 1400107e9a97SBarry Smith Notes: ISLocalToGlobalMappingGetSize() returns the length the this array 1401107e9a97SBarry Smith 1402107e9a97SBarry Smith .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingRestoreIndices(), ISLocalToGlobalMappingGetBlockIndices(), ISLocalToGlobalMappingRestoreBlockIndices() 140386994e45SJed Brown @*/ 14047087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingGetIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 140586994e45SJed Brown { 140686994e45SJed Brown PetscFunctionBegin; 140786994e45SJed Brown PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 140886994e45SJed Brown PetscValidPointer(array,2); 140945b6f7e9SBarry Smith if (ltog->bs == 1) { 141086994e45SJed Brown *array = ltog->indices; 141145b6f7e9SBarry Smith } else { 141245b6f7e9SBarry Smith PetscInt *jj,k,i,j,n = ltog->n, bs = ltog->bs; 141345b6f7e9SBarry Smith const PetscInt *ii; 141445b6f7e9SBarry Smith PetscErrorCode ierr; 141545b6f7e9SBarry Smith 141645b6f7e9SBarry Smith ierr = PetscMalloc1(bs*n,&jj);CHKERRQ(ierr); 141745b6f7e9SBarry Smith *array = jj; 141845b6f7e9SBarry Smith k = 0; 141945b6f7e9SBarry Smith ii = ltog->indices; 142045b6f7e9SBarry Smith for (i=0; i<n; i++) 142145b6f7e9SBarry Smith for (j=0; j<bs; j++) 142245b6f7e9SBarry Smith jj[k++] = bs*ii[i] + j; 142345b6f7e9SBarry Smith } 142486994e45SJed Brown PetscFunctionReturn(0); 142586994e45SJed Brown } 142686994e45SJed Brown 142786994e45SJed Brown #undef __FUNCT__ 142886994e45SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingRestoreIndices" 142986994e45SJed Brown /*@C 1430193a2b41SJulian Andrej ISLocalToGlobalMappingRestoreIndices - Restore indices obtained with ISLocalToGlobalMappingGetIndices() 143186994e45SJed Brown 143286994e45SJed Brown Not Collective 143386994e45SJed Brown 143486994e45SJed Brown Input Arguments: 143586994e45SJed Brown + ltog - local to global mapping 143686994e45SJed Brown - array - array of indices 143786994e45SJed Brown 143886994e45SJed Brown Level: advanced 143986994e45SJed Brown 144086994e45SJed Brown .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingGetIndices() 144186994e45SJed Brown @*/ 14427087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 144386994e45SJed Brown { 144486994e45SJed Brown PetscFunctionBegin; 144586994e45SJed Brown PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 144686994e45SJed Brown PetscValidPointer(array,2); 144745b6f7e9SBarry Smith if (ltog->bs == 1 && *array != ltog->indices) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Trying to return mismatched pointer"); 144845b6f7e9SBarry Smith 144945b6f7e9SBarry Smith if (ltog->bs > 1) { 145045b6f7e9SBarry Smith PetscErrorCode ierr; 145145b6f7e9SBarry Smith ierr = PetscFree(*(void**)array);CHKERRQ(ierr); 145245b6f7e9SBarry Smith } 145345b6f7e9SBarry Smith PetscFunctionReturn(0); 145445b6f7e9SBarry Smith } 145545b6f7e9SBarry Smith 145645b6f7e9SBarry Smith #undef __FUNCT__ 145745b6f7e9SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingGetBlockIndices" 145845b6f7e9SBarry Smith /*@C 145945b6f7e9SBarry Smith ISLocalToGlobalMappingGetBlockIndices - Get global indices for every local block 146045b6f7e9SBarry Smith 146145b6f7e9SBarry Smith Not Collective 146245b6f7e9SBarry Smith 146345b6f7e9SBarry Smith Input Arguments: 146445b6f7e9SBarry Smith . ltog - local to global mapping 146545b6f7e9SBarry Smith 146645b6f7e9SBarry Smith Output Arguments: 146745b6f7e9SBarry Smith . array - array of indices 146845b6f7e9SBarry Smith 146945b6f7e9SBarry Smith Level: advanced 147045b6f7e9SBarry Smith 147145b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingRestoreBlockIndices() 147245b6f7e9SBarry Smith @*/ 147345b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetBlockIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 147445b6f7e9SBarry Smith { 147545b6f7e9SBarry Smith PetscFunctionBegin; 147645b6f7e9SBarry Smith PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 147745b6f7e9SBarry Smith PetscValidPointer(array,2); 147845b6f7e9SBarry Smith *array = ltog->indices; 147945b6f7e9SBarry Smith PetscFunctionReturn(0); 148045b6f7e9SBarry Smith } 148145b6f7e9SBarry Smith 148245b6f7e9SBarry Smith #undef __FUNCT__ 148345b6f7e9SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingRestoreBlockIndices" 148445b6f7e9SBarry Smith /*@C 148545b6f7e9SBarry Smith ISLocalToGlobalMappingRestoreBlockIndices - Restore indices obtained with ISLocalToGlobalMappingGetBlockIndices() 148645b6f7e9SBarry Smith 148745b6f7e9SBarry Smith Not Collective 148845b6f7e9SBarry Smith 148945b6f7e9SBarry Smith Input Arguments: 149045b6f7e9SBarry Smith + ltog - local to global mapping 149145b6f7e9SBarry Smith - array - array of indices 149245b6f7e9SBarry Smith 149345b6f7e9SBarry Smith Level: advanced 149445b6f7e9SBarry Smith 149545b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingGetIndices() 149645b6f7e9SBarry Smith @*/ 149745b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreBlockIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 149845b6f7e9SBarry Smith { 149945b6f7e9SBarry Smith PetscFunctionBegin; 150045b6f7e9SBarry Smith PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 150145b6f7e9SBarry Smith PetscValidPointer(array,2); 150286994e45SJed Brown if (*array != ltog->indices) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Trying to return mismatched pointer"); 15030298fd71SBarry Smith *array = NULL; 150486994e45SJed Brown PetscFunctionReturn(0); 150586994e45SJed Brown } 1506f7efa3c7SJed Brown 1507f7efa3c7SJed Brown #undef __FUNCT__ 1508f7efa3c7SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingConcatenate" 1509f7efa3c7SJed Brown /*@C 1510f7efa3c7SJed Brown ISLocalToGlobalMappingConcatenate - Create a new mapping that concatenates a list of mappings 1511f7efa3c7SJed Brown 1512f7efa3c7SJed Brown Not Collective 1513f7efa3c7SJed Brown 1514f7efa3c7SJed Brown Input Arguments: 1515f7efa3c7SJed Brown + comm - communicator for the new mapping, must contain the communicator of every mapping to concatenate 1516f7efa3c7SJed Brown . n - number of mappings to concatenate 1517f7efa3c7SJed Brown - ltogs - local to global mappings 1518f7efa3c7SJed Brown 1519f7efa3c7SJed Brown Output Arguments: 1520f7efa3c7SJed Brown . ltogcat - new mapping 1521f7efa3c7SJed Brown 15229d90f715SBarry Smith Note: this currently always returns a mapping with block size of 1 15239d90f715SBarry Smith 15249d90f715SBarry Smith Developer Note: If all the input mapping have the same block size we could easily handle that as a special case 15259d90f715SBarry Smith 1526f7efa3c7SJed Brown Level: advanced 1527f7efa3c7SJed Brown 1528f7efa3c7SJed Brown .seealso: ISLocalToGlobalMappingCreate() 1529f7efa3c7SJed Brown @*/ 1530f7efa3c7SJed Brown PetscErrorCode ISLocalToGlobalMappingConcatenate(MPI_Comm comm,PetscInt n,const ISLocalToGlobalMapping ltogs[],ISLocalToGlobalMapping *ltogcat) 1531f7efa3c7SJed Brown { 1532f7efa3c7SJed Brown PetscInt i,cnt,m,*idx; 1533f7efa3c7SJed Brown PetscErrorCode ierr; 1534f7efa3c7SJed Brown 1535f7efa3c7SJed Brown PetscFunctionBegin; 1536f7efa3c7SJed Brown if (n < 0) SETERRQ1(comm,PETSC_ERR_ARG_OUTOFRANGE,"Must have a non-negative number of mappings, given %D",n); 1537f7efa3c7SJed Brown if (n > 0) PetscValidPointer(ltogs,3); 1538f7efa3c7SJed Brown for (i=0; i<n; i++) PetscValidHeaderSpecific(ltogs[i],IS_LTOGM_CLASSID,3); 1539f7efa3c7SJed Brown PetscValidPointer(ltogcat,4); 1540f7efa3c7SJed Brown for (cnt=0,i=0; i<n; i++) { 1541f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetSize(ltogs[i],&m);CHKERRQ(ierr); 1542f7efa3c7SJed Brown cnt += m; 1543f7efa3c7SJed Brown } 1544785e854fSJed Brown ierr = PetscMalloc1(cnt,&idx);CHKERRQ(ierr); 1545f7efa3c7SJed Brown for (cnt=0,i=0; i<n; i++) { 1546f7efa3c7SJed Brown const PetscInt *subidx; 1547f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetSize(ltogs[i],&m);CHKERRQ(ierr); 1548f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetIndices(ltogs[i],&subidx);CHKERRQ(ierr); 1549f7efa3c7SJed Brown ierr = PetscMemcpy(&idx[cnt],subidx,m*sizeof(PetscInt));CHKERRQ(ierr); 1550f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingRestoreIndices(ltogs[i],&subidx);CHKERRQ(ierr); 1551f7efa3c7SJed Brown cnt += m; 1552f7efa3c7SJed Brown } 1553f0413b6fSBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,1,cnt,idx,PETSC_OWN_POINTER,ltogcat);CHKERRQ(ierr); 1554f7efa3c7SJed Brown PetscFunctionReturn(0); 1555f7efa3c7SJed Brown } 155604a59952SBarry Smith 155704a59952SBarry Smith 1558