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*8b7cb0e6Sstefano_zampini PetscInt i,cn,on,obs,nn,cum,r,rbs,ri; 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); 212*8b7cb0e6Sstefano_zampini if (bs < obs && obs%bs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Block size %D is inconsistent with block size %D",bs,obs); 213*8b7cb0e6Sstefano_zampini if (bs < obs) { 214*8b7cb0e6Sstefano_zampini r = bs; 215*8b7cb0e6Sstefano_zampini rbs = obs/bs; 216*8b7cb0e6Sstefano_zampini ri = 1; 217*8b7cb0e6Sstefano_zampini } else { 218*8b7cb0e6Sstefano_zampini r = obs; 219*8b7cb0e6Sstefano_zampini rbs = 1; 220*8b7cb0e6Sstefano_zampini ri = bs/obs; 221*8b7cb0e6Sstefano_zampini } 22263fa5c83Sstefano_zampini ierr = PetscMalloc1(nn,&nid);CHKERRQ(ierr); 223c9345713Sstefano_zampini for (i=0,cum=0,cn=0;i<on;i++) { 224*8b7cb0e6Sstefano_zampini if (oid[i] < 0) cn += r; 225*8b7cb0e6Sstefano_zampini if ((cn && !(cn%bs)) || (oid[i] > -1 && !((oid[i]*obs)%bs))) { 22663fa5c83Sstefano_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); 227*8b7cb0e6Sstefano_zampini if (cn && cn%bs) SETERRQ5(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Block sizes %D and %D are incompatible with the block indices (neg = %D, rbs %D, r %D)",bs,obs,cn,rbs,r); 228*8b7cb0e6Sstefano_zampini if (cn) { 229*8b7cb0e6Sstefano_zampini PetscInt j; 230*8b7cb0e6Sstefano_zampini for (j=0;j<rbs;j++) nid[cum++] = -1; 231*8b7cb0e6Sstefano_zampini } else { 232*8b7cb0e6Sstefano_zampini PetscInt j; 233*8b7cb0e6Sstefano_zampini for (j=1;j<ri;j++) { 234*8b7cb0e6Sstefano_zampini if (i+j >= on) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Block sizes %D and %D are incompatible with the block indices: non consecutive indices found",bs,obs); 235*8b7cb0e6Sstefano_zampini if (oid[i] != oid[i+j]-j) SETERRQ6(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Block sizes %D and %D are incompatible with the block indices: non consecutive indices %D %D (%D,%D)",bs,obs,oid[i],oid[i+j],j,ri); 236*8b7cb0e6Sstefano_zampini } 237*8b7cb0e6Sstefano_zampini for (j=0;j<rbs;j++) nid[cum++] = (oid[i]*obs)/bs+j; 238*8b7cb0e6Sstefano_zampini } 239c9345713Sstefano_zampini cn = 0; 24063fa5c83Sstefano_zampini } 24163fa5c83Sstefano_zampini } 242c9345713Sstefano_zampini if (cum != nn || cn) { 24363fa5c83Sstefano_zampini ierr = PetscFree(nid);CHKERRQ(ierr); 244*8b7cb0e6Sstefano_zampini SETERRQ6(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Incompatible block sizes %D and %D (new block indices found %D != %D, neg %D, rbs %D)",bs,obs,cum,nn,cn,rbs); 24563fa5c83Sstefano_zampini } 24663fa5c83Sstefano_zampini mapping->n = nn; 24763fa5c83Sstefano_zampini mapping->bs = bs; 24863fa5c83Sstefano_zampini ierr = PetscFree(mapping->indices);CHKERRQ(ierr); 24963fa5c83Sstefano_zampini mapping->indices = nid; 250c9345713Sstefano_zampini ierr = PetscFree(mapping->globals);CHKERRQ(ierr); 251c9345713Sstefano_zampini mapping->globalstart = 0; 252c9345713Sstefano_zampini mapping->globalend = 0; 25363fa5c83Sstefano_zampini PetscFunctionReturn(0); 25463fa5c83Sstefano_zampini } 25563fa5c83Sstefano_zampini 25663fa5c83Sstefano_zampini #undef __FUNCT__ 25745b6f7e9SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingGetBlockSize" 25845b6f7e9SBarry Smith /*@ 25945b6f7e9SBarry Smith ISLocalToGlobalMappingGetBlockSize - Gets the blocksize of the mapping 26045b6f7e9SBarry Smith ordering and a global parallel ordering. 26145b6f7e9SBarry Smith 26245b6f7e9SBarry Smith Not Collective 26345b6f7e9SBarry Smith 26445b6f7e9SBarry Smith Input Parameters: 26545b6f7e9SBarry Smith . mapping - mapping data structure 26645b6f7e9SBarry Smith 26745b6f7e9SBarry Smith Output Parameter: 26845b6f7e9SBarry Smith . bs - the blocksize 26945b6f7e9SBarry Smith 27045b6f7e9SBarry Smith Level: advanced 27145b6f7e9SBarry Smith 27245b6f7e9SBarry Smith Concepts: mapping^local to global 27345b6f7e9SBarry Smith 27445b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS() 27545b6f7e9SBarry Smith @*/ 27645b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetBlockSize(ISLocalToGlobalMapping mapping,PetscInt *bs) 27745b6f7e9SBarry Smith { 27845b6f7e9SBarry Smith PetscFunctionBegin; 279cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 28045b6f7e9SBarry Smith *bs = mapping->bs; 28145b6f7e9SBarry Smith PetscFunctionReturn(0); 28245b6f7e9SBarry Smith } 28345b6f7e9SBarry Smith 28445b6f7e9SBarry Smith #undef __FUNCT__ 2854a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreate" 286ba5bb76aSSatish Balay /*@ 28790f02eecSBarry Smith ISLocalToGlobalMappingCreate - Creates a mapping between a local (0 to n) 28890f02eecSBarry Smith ordering and a global parallel ordering. 2892362add9SBarry Smith 29089d82c54SBarry Smith Not Collective, but communicator may have more than one process 291b9cd556bSLois Curfman McInnes 2922362add9SBarry Smith Input Parameters: 29389d82c54SBarry Smith + comm - MPI communicator 294f0413b6fSBarry Smith . bs - the block size 29528bc9809SBarry Smith . n - the number of local elements divided by the block size, or equivalently the number of block indices 29628bc9809SBarry 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 297d5ad8652SBarry Smith - mode - see PetscCopyMode 2982362add9SBarry Smith 299a997ad1aSLois Curfman McInnes Output Parameter: 30090f02eecSBarry Smith . mapping - new mapping data structure 3012362add9SBarry Smith 302f0413b6fSBarry 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 303a997ad1aSLois Curfman McInnes Level: advanced 304a997ad1aSLois Curfman McInnes 305273d9f13SBarry Smith Concepts: mapping^local to global 3062362add9SBarry Smith 307d5ad8652SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS() 3082362add9SBarry Smith @*/ 30960c7cefcSBarry Smith PetscErrorCode ISLocalToGlobalMappingCreate(MPI_Comm comm,PetscInt bs,PetscInt n,const PetscInt indices[],PetscCopyMode mode,ISLocalToGlobalMapping *mapping) 3102362add9SBarry Smith { 3116849ba73SBarry Smith PetscErrorCode ierr; 31232dcc486SBarry Smith PetscInt *in; 313b46b645bSBarry Smith 314b46b645bSBarry Smith PetscFunctionBegin; 31573911063SBarry Smith if (n) PetscValidIntPointer(indices,3); 3164482741eSBarry Smith PetscValidPointer(mapping,4); 317b46b645bSBarry Smith 3180298fd71SBarry Smith *mapping = NULL; 319607a6623SBarry Smith ierr = ISInitializePackage();CHKERRQ(ierr); 3202362add9SBarry Smith 32173107ff1SLisandro Dalcin ierr = PetscHeaderCreate(*mapping,IS_LTOGM_CLASSID,"ISLocalToGlobalMapping","Local to global mapping","IS", 32260c7cefcSBarry Smith comm,ISLocalToGlobalMappingDestroy,ISLocalToGlobalMappingView);CHKERRQ(ierr); 323d4bb536fSBarry Smith (*mapping)->n = n; 324f0413b6fSBarry Smith (*mapping)->bs = bs; 325268a049cSStefano Zampini (*mapping)->info_cached = PETSC_FALSE; 326268a049cSStefano Zampini (*mapping)->info_free = PETSC_FALSE; 327268a049cSStefano Zampini (*mapping)->info_procs = NULL; 328268a049cSStefano Zampini (*mapping)->info_numprocs = NULL; 329268a049cSStefano Zampini (*mapping)->info_indices = NULL; 330d4bb536fSBarry Smith /* 331d4bb536fSBarry Smith Do not create the global to local mapping. This is only created if 332d4bb536fSBarry Smith ISGlobalToLocalMapping() is called 333d4bb536fSBarry Smith */ 334d4bb536fSBarry Smith (*mapping)->globals = 0; 335d5ad8652SBarry Smith if (mode == PETSC_COPY_VALUES) { 336785e854fSJed Brown ierr = PetscMalloc1(n,&in);CHKERRQ(ierr); 337d5ad8652SBarry Smith ierr = PetscMemcpy(in,indices,n*sizeof(PetscInt));CHKERRQ(ierr); 338d5ad8652SBarry Smith (*mapping)->indices = in; 3396389a1a1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)*mapping,n*sizeof(PetscInt));CHKERRQ(ierr); 3406389a1a1SBarry Smith } else if (mode == PETSC_OWN_POINTER) { 3416389a1a1SBarry Smith (*mapping)->indices = (PetscInt*)indices; 3426389a1a1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)*mapping,n*sizeof(PetscInt));CHKERRQ(ierr); 3436389a1a1SBarry Smith } 34460c7cefcSBarry Smith else SETERRQ(comm,PETSC_ERR_SUP,"Cannot currently use PETSC_USE_POINTER"); 345d96308ebSBarry Smith ierr = PetscStrallocpy("basic",&((PetscObject)*mapping)->type_name);CHKERRQ(ierr); 3463a40ed3dSBarry Smith PetscFunctionReturn(0); 3472362add9SBarry Smith } 3482362add9SBarry Smith 3494a2ae208SSatish Balay #undef __FUNCT__ 3504a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingDestroy" 35190f02eecSBarry Smith /*@ 35290f02eecSBarry Smith ISLocalToGlobalMappingDestroy - Destroys a mapping between a local (0 to n) 35390f02eecSBarry Smith ordering and a global parallel ordering. 35490f02eecSBarry Smith 3550f5bd95cSBarry Smith Note Collective 356b9cd556bSLois Curfman McInnes 35790f02eecSBarry Smith Input Parameters: 35890f02eecSBarry Smith . mapping - mapping data structure 35990f02eecSBarry Smith 360a997ad1aSLois Curfman McInnes Level: advanced 361a997ad1aSLois Curfman McInnes 3623acfe500SLois Curfman McInnes .seealso: ISLocalToGlobalMappingCreate() 36390f02eecSBarry Smith @*/ 3646bf464f9SBarry Smith PetscErrorCode ISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping *mapping) 36590f02eecSBarry Smith { 366dfbe8321SBarry Smith PetscErrorCode ierr; 3675fd66863SKarl Rupp 3683a40ed3dSBarry Smith PetscFunctionBegin; 3696bf464f9SBarry Smith if (!*mapping) PetscFunctionReturn(0); 3706bf464f9SBarry Smith PetscValidHeaderSpecific((*mapping),IS_LTOGM_CLASSID,1); 371997056adSBarry Smith if (--((PetscObject)(*mapping))->refct > 0) {*mapping = 0;PetscFunctionReturn(0);} 3726bf464f9SBarry Smith ierr = PetscFree((*mapping)->indices);CHKERRQ(ierr); 3736bf464f9SBarry Smith ierr = PetscFree((*mapping)->globals);CHKERRQ(ierr); 374268a049cSStefano Zampini ierr = PetscFree((*mapping)->info_procs);CHKERRQ(ierr); 375268a049cSStefano Zampini ierr = PetscFree((*mapping)->info_numprocs);CHKERRQ(ierr); 376268a049cSStefano Zampini if ((*mapping)->info_indices) { 377268a049cSStefano Zampini PetscInt i; 378268a049cSStefano Zampini 379268a049cSStefano Zampini ierr = PetscFree(((*mapping)->info_indices)[0]);CHKERRQ(ierr); 380268a049cSStefano Zampini for (i=1; i<(*mapping)->info_nproc; i++) { 381268a049cSStefano Zampini ierr = PetscFree(((*mapping)->info_indices)[i]);CHKERRQ(ierr); 382268a049cSStefano Zampini } 383268a049cSStefano Zampini ierr = PetscFree((*mapping)->info_indices);CHKERRQ(ierr); 384268a049cSStefano Zampini } 385d38fa0fbSBarry Smith ierr = PetscHeaderDestroy(mapping);CHKERRQ(ierr); 386992144d0SBarry Smith *mapping = 0; 3873a40ed3dSBarry Smith PetscFunctionReturn(0); 38890f02eecSBarry Smith } 38990f02eecSBarry Smith 3904a2ae208SSatish Balay #undef __FUNCT__ 3914a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingApplyIS" 39290f02eecSBarry Smith /*@ 3933acfe500SLois Curfman McInnes ISLocalToGlobalMappingApplyIS - Creates from an IS in the local numbering 3943acfe500SLois Curfman McInnes a new index set using the global numbering defined in an ISLocalToGlobalMapping 3953acfe500SLois Curfman McInnes context. 39690f02eecSBarry Smith 397b9cd556bSLois Curfman McInnes Not collective 398b9cd556bSLois Curfman McInnes 39990f02eecSBarry Smith Input Parameters: 400b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 401b9cd556bSLois Curfman McInnes - is - index set in local numbering 40290f02eecSBarry Smith 40390f02eecSBarry Smith Output Parameters: 40490f02eecSBarry Smith . newis - index set in global numbering 40590f02eecSBarry Smith 406a997ad1aSLois Curfman McInnes Level: advanced 407a997ad1aSLois Curfman McInnes 408273d9f13SBarry Smith Concepts: mapping^local to global 4093acfe500SLois Curfman McInnes 41090f02eecSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 411d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy(), ISGlobalToLocalMappingApply() 41290f02eecSBarry Smith @*/ 4137087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping mapping,IS is,IS *newis) 41490f02eecSBarry Smith { 4156849ba73SBarry Smith PetscErrorCode ierr; 416e24637baSBarry Smith PetscInt n,*idxout; 4175d0c19d7SBarry Smith const PetscInt *idxin; 4183a40ed3dSBarry Smith 4193a40ed3dSBarry Smith PetscFunctionBegin; 4200700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 4210700a824SBarry Smith PetscValidHeaderSpecific(is,IS_CLASSID,2); 4224482741eSBarry Smith PetscValidPointer(newis,3); 42390f02eecSBarry Smith 4243b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 42590f02eecSBarry Smith ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 426785e854fSJed Brown ierr = PetscMalloc1(n,&idxout);CHKERRQ(ierr); 427e24637baSBarry Smith ierr = ISLocalToGlobalMappingApply(mapping,n,idxin,idxout);CHKERRQ(ierr); 4283b9aefa3SBarry Smith ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 429543f3098SMatthew G. Knepley ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is),n,idxout,PETSC_OWN_POINTER,newis);CHKERRQ(ierr); 4303a40ed3dSBarry Smith PetscFunctionReturn(0); 43190f02eecSBarry Smith } 43290f02eecSBarry Smith 433afcb2eb5SJed Brown #undef __FUNCT__ 434afcb2eb5SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingApply" 435b89cb25eSSatish Balay /*@ 4363acfe500SLois Curfman McInnes ISLocalToGlobalMappingApply - Takes a list of integers in a local numbering 4373acfe500SLois Curfman McInnes and converts them to the global numbering. 43890f02eecSBarry Smith 439b9cd556bSLois Curfman McInnes Not collective 440b9cd556bSLois Curfman McInnes 441bb25748dSBarry Smith Input Parameters: 442b9cd556bSLois Curfman McInnes + mapping - the local to global mapping context 443bb25748dSBarry Smith . N - number of integers 444b9cd556bSLois Curfman McInnes - in - input indices in local numbering 445bb25748dSBarry Smith 446bb25748dSBarry Smith Output Parameter: 447bb25748dSBarry Smith . out - indices in global numbering 448bb25748dSBarry Smith 449b9cd556bSLois Curfman McInnes Notes: 450b9cd556bSLois Curfman McInnes The in and out array parameters may be identical. 451d4bb536fSBarry Smith 452a997ad1aSLois Curfman McInnes Level: advanced 453a997ad1aSLois Curfman McInnes 45445b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingApplyBlock(), ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 4550752156aSBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 456d4bb536fSBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 457bb25748dSBarry Smith 458273d9f13SBarry Smith Concepts: mapping^local to global 459afcb2eb5SJed Brown @*/ 460afcb2eb5SJed Brown PetscErrorCode ISLocalToGlobalMappingApply(ISLocalToGlobalMapping mapping,PetscInt N,const PetscInt in[],PetscInt out[]) 461afcb2eb5SJed Brown { 462cbc1caf0SMatthew G. Knepley PetscInt i,bs,Nmax; 46345b6f7e9SBarry Smith 46445b6f7e9SBarry Smith PetscFunctionBegin; 465cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 466cbc1caf0SMatthew G. Knepley bs = mapping->bs; 467cbc1caf0SMatthew G. Knepley Nmax = bs*mapping->n; 46845b6f7e9SBarry Smith if (bs == 1) { 469cbc1caf0SMatthew G. Knepley const PetscInt *idx = mapping->indices; 47045b6f7e9SBarry Smith for (i=0; i<N; i++) { 47145b6f7e9SBarry Smith if (in[i] < 0) { 47245b6f7e9SBarry Smith out[i] = in[i]; 47345b6f7e9SBarry Smith continue; 47445b6f7e9SBarry Smith } 475e24637baSBarry 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); 47645b6f7e9SBarry Smith out[i] = idx[in[i]]; 47745b6f7e9SBarry Smith } 47845b6f7e9SBarry Smith } else { 479cbc1caf0SMatthew G. Knepley const PetscInt *idx = mapping->indices; 48045b6f7e9SBarry Smith for (i=0; i<N; i++) { 48145b6f7e9SBarry Smith if (in[i] < 0) { 48245b6f7e9SBarry Smith out[i] = in[i]; 48345b6f7e9SBarry Smith continue; 48445b6f7e9SBarry Smith } 485e24637baSBarry 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); 48645b6f7e9SBarry Smith out[i] = idx[in[i]/bs]*bs + (in[i] % bs); 48745b6f7e9SBarry Smith } 48845b6f7e9SBarry Smith } 48945b6f7e9SBarry Smith PetscFunctionReturn(0); 49045b6f7e9SBarry Smith } 49145b6f7e9SBarry Smith 49245b6f7e9SBarry Smith #undef __FUNCT__ 49345b6f7e9SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingApplyBlock" 49445b6f7e9SBarry Smith /*@ 4956006e8d2SBarry Smith ISLocalToGlobalMappingApplyBlock - Takes a list of integers in a local block numbering and converts them to the global block numbering 49645b6f7e9SBarry Smith 49745b6f7e9SBarry Smith Not collective 49845b6f7e9SBarry Smith 49945b6f7e9SBarry Smith Input Parameters: 50045b6f7e9SBarry Smith + mapping - the local to global mapping context 50145b6f7e9SBarry Smith . N - number of integers 5026006e8d2SBarry Smith - in - input indices in local block numbering 50345b6f7e9SBarry Smith 50445b6f7e9SBarry Smith Output Parameter: 5056006e8d2SBarry Smith . out - indices in global block numbering 50645b6f7e9SBarry Smith 50745b6f7e9SBarry Smith Notes: 50845b6f7e9SBarry Smith The in and out array parameters may be identical. 50945b6f7e9SBarry Smith 5106006e8d2SBarry Smith Example: 5116006e8d2SBarry 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 5126006e8d2SBarry Smith (the first block) would produce 0 and the mapping applied to 1 (the second block) would produce 3. 5136006e8d2SBarry Smith 51445b6f7e9SBarry Smith Level: advanced 51545b6f7e9SBarry Smith 51645b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 51745b6f7e9SBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 51845b6f7e9SBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 51945b6f7e9SBarry Smith 52045b6f7e9SBarry Smith Concepts: mapping^local to global 52145b6f7e9SBarry Smith @*/ 52245b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingApplyBlock(ISLocalToGlobalMapping mapping,PetscInt N,const PetscInt in[],PetscInt out[]) 52345b6f7e9SBarry Smith { 524cbc1caf0SMatthew G. Knepley 525cbc1caf0SMatthew G. Knepley PetscFunctionBegin; 526cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 527cbc1caf0SMatthew G. Knepley { 528afcb2eb5SJed Brown PetscInt i,Nmax = mapping->n; 529afcb2eb5SJed Brown const PetscInt *idx = mapping->indices; 530d4bb536fSBarry Smith 531afcb2eb5SJed Brown for (i=0; i<N; i++) { 532afcb2eb5SJed Brown if (in[i] < 0) { 533afcb2eb5SJed Brown out[i] = in[i]; 534afcb2eb5SJed Brown continue; 535afcb2eb5SJed Brown } 536e24637baSBarry 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); 537afcb2eb5SJed Brown out[i] = idx[in[i]]; 538afcb2eb5SJed Brown } 539cbc1caf0SMatthew G. Knepley } 540afcb2eb5SJed Brown PetscFunctionReturn(0); 541afcb2eb5SJed Brown } 542d4bb536fSBarry Smith 543d4bb536fSBarry Smith /* -----------------------------------------------------------------------------------------*/ 544d4bb536fSBarry Smith 5454a2ae208SSatish Balay #undef __FUNCT__ 5464a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingSetUp_Private" 547d4bb536fSBarry Smith /* 548d4bb536fSBarry Smith Creates the global fields in the ISLocalToGlobalMapping structure 549d4bb536fSBarry Smith */ 5506849ba73SBarry Smith static PetscErrorCode ISGlobalToLocalMappingSetUp_Private(ISLocalToGlobalMapping mapping) 551d4bb536fSBarry Smith { 5526849ba73SBarry Smith PetscErrorCode ierr; 55332dcc486SBarry Smith PetscInt i,*idx = mapping->indices,n = mapping->n,end,start,*globals; 554d4bb536fSBarry Smith 5553a40ed3dSBarry Smith PetscFunctionBegin; 556d4bb536fSBarry Smith end = 0; 557ec268f7cSJed Brown start = PETSC_MAX_INT; 558d4bb536fSBarry Smith 559d4bb536fSBarry Smith for (i=0; i<n; i++) { 560d4bb536fSBarry Smith if (idx[i] < 0) continue; 561d4bb536fSBarry Smith if (idx[i] < start) start = idx[i]; 562d4bb536fSBarry Smith if (idx[i] > end) end = idx[i]; 563d4bb536fSBarry Smith } 564d4bb536fSBarry Smith if (start > end) {start = 0; end = -1;} 565d4bb536fSBarry Smith mapping->globalstart = start; 566d4bb536fSBarry Smith mapping->globalend = end; 567d4bb536fSBarry Smith 568854ce69bSBarry Smith ierr = PetscMalloc1(end-start+2,&globals);CHKERRQ(ierr); 569b0a32e0cSBarry Smith mapping->globals = globals; 570f6e5521dSKarl Rupp for (i=0; i<end-start+1; i++) globals[i] = -1; 571d4bb536fSBarry Smith for (i=0; i<n; i++) { 572d4bb536fSBarry Smith if (idx[i] < 0) continue; 573d4bb536fSBarry Smith globals[idx[i] - start] = i; 574d4bb536fSBarry Smith } 575d4bb536fSBarry Smith 5763bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mapping,(end-start+1)*sizeof(PetscInt));CHKERRQ(ierr); 5773a40ed3dSBarry Smith PetscFunctionReturn(0); 578d4bb536fSBarry Smith } 579d4bb536fSBarry Smith 5804a2ae208SSatish Balay #undef __FUNCT__ 5814a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingApply" 582d4bb536fSBarry Smith /*@ 583a997ad1aSLois Curfman McInnes ISGlobalToLocalMappingApply - Provides the local numbering for a list of integers 584a997ad1aSLois Curfman McInnes specified with a global numbering. 585d4bb536fSBarry Smith 586b9cd556bSLois Curfman McInnes Not collective 587b9cd556bSLois Curfman McInnes 588d4bb536fSBarry Smith Input Parameters: 589b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 590d4bb536fSBarry Smith . type - IS_GTOLM_MASK - replaces global indices with no local value with -1 591d4bb536fSBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 592d4bb536fSBarry Smith . n - number of global indices to map 593b9cd556bSLois Curfman McInnes - idx - global indices to map 594d4bb536fSBarry Smith 595d4bb536fSBarry Smith Output Parameters: 596b9cd556bSLois Curfman McInnes + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 597b9cd556bSLois Curfman McInnes - idxout - local index of each global index, one must pass in an array long enough 598e182c471SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApply() with 5990298fd71SBarry Smith idxout == NULL to determine the required length (returned in nout) 600e182c471SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApply() 601e182c471SBarry Smith a second time to set the values. 602d4bb536fSBarry Smith 603b9cd556bSLois Curfman McInnes Notes: 6040298fd71SBarry Smith Either nout or idxout may be NULL. idx and idxout may be identical. 605d4bb536fSBarry Smith 6060f5bd95cSBarry Smith This is not scalable in memory usage. Each processor requires O(Nglobal) size 6070f5bd95cSBarry Smith array to compute these. 6080f5bd95cSBarry Smith 609a997ad1aSLois Curfman McInnes Level: advanced 610a997ad1aSLois Curfman McInnes 61132fd6b96SBarry Smith Developer Note: The manual page states that idx and idxout may be identical but the calling 61232fd6b96SBarry Smith sequence declares idx as const so it cannot be the same as idxout. 61332fd6b96SBarry Smith 614273d9f13SBarry Smith Concepts: mapping^global to local 615d4bb536fSBarry Smith 6169d90f715SBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISGlobalToLocalMappingApplyBlock(), ISLocalToGlobalMappingCreate(), 617d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy() 618d4bb536fSBarry Smith @*/ 6197087cfbeSBarry Smith PetscErrorCode ISGlobalToLocalMappingApply(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, 62032dcc486SBarry Smith PetscInt n,const PetscInt idx[],PetscInt *nout,PetscInt idxout[]) 621d4bb536fSBarry Smith { 6229d90f715SBarry Smith PetscInt i,*globals,nf = 0,tmp,start,end,bs; 6239d90f715SBarry Smith PetscErrorCode ierr; 6249d90f715SBarry Smith 6259d90f715SBarry Smith PetscFunctionBegin; 6269d90f715SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 6279d90f715SBarry Smith if (!mapping->globals) { 6289d90f715SBarry Smith ierr = ISGlobalToLocalMappingSetUp_Private(mapping);CHKERRQ(ierr); 6299d90f715SBarry Smith } 6309d90f715SBarry Smith globals = mapping->globals; 6319d90f715SBarry Smith start = mapping->globalstart; 6329d90f715SBarry Smith end = mapping->globalend; 6339d90f715SBarry Smith bs = mapping->bs; 6349d90f715SBarry Smith 6359d90f715SBarry Smith if (type == IS_GTOLM_MASK) { 6369d90f715SBarry Smith if (idxout) { 6379d90f715SBarry Smith for (i=0; i<n; i++) { 6389d90f715SBarry Smith if (idx[i] < 0) idxout[i] = idx[i]; 6399d90f715SBarry Smith else if (idx[i] < bs*start) idxout[i] = -1; 640663bb84eSBarry Smith else if (idx[i] > bs*(end+1)-1) idxout[i] = -1; 6419d90f715SBarry Smith else idxout[i] = bs*globals[idx[i]/bs - start] + (idx[i] % bs); 6429d90f715SBarry Smith } 6439d90f715SBarry Smith } 6449d90f715SBarry Smith if (nout) *nout = n; 6459d90f715SBarry Smith } else { 6469d90f715SBarry Smith if (idxout) { 6479d90f715SBarry Smith for (i=0; i<n; i++) { 6489d90f715SBarry Smith if (idx[i] < 0) continue; 6499d90f715SBarry Smith if (idx[i] < bs*start) continue; 650663bb84eSBarry Smith if (idx[i] > bs*(end+1)-1) continue; 6519d90f715SBarry Smith tmp = bs*globals[idx[i]/bs - start] + (idx[i] % bs); 6529d90f715SBarry Smith if (tmp < 0) continue; 6539d90f715SBarry Smith idxout[nf++] = tmp; 6549d90f715SBarry Smith } 6559d90f715SBarry Smith } else { 6569d90f715SBarry Smith for (i=0; i<n; i++) { 6579d90f715SBarry Smith if (idx[i] < 0) continue; 6589d90f715SBarry Smith if (idx[i] < bs*start) continue; 659663bb84eSBarry Smith if (idx[i] > bs*(end+1)-1) continue; 6609d90f715SBarry Smith tmp = bs*globals[idx[i]/bs - start] + (idx[i] % bs); 6619d90f715SBarry Smith if (tmp < 0) continue; 6629d90f715SBarry Smith nf++; 6639d90f715SBarry Smith } 6649d90f715SBarry Smith } 6659d90f715SBarry Smith if (nout) *nout = nf; 6669d90f715SBarry Smith } 6679d90f715SBarry Smith PetscFunctionReturn(0); 6689d90f715SBarry Smith } 6699d90f715SBarry Smith 6709d90f715SBarry Smith #undef __FUNCT__ 671d4fe737eSStefano Zampini #define __FUNCT__ "ISGlobalToLocalMappingApplyIS" 672d4fe737eSStefano Zampini /*@ 673d4fe737eSStefano Zampini ISGlobalToLocalMappingApplyIS - Creates from an IS in the global numbering 674d4fe737eSStefano Zampini a new index set using the local numbering defined in an ISLocalToGlobalMapping 675d4fe737eSStefano Zampini context. 676d4fe737eSStefano Zampini 677d4fe737eSStefano Zampini Not collective 678d4fe737eSStefano Zampini 679d4fe737eSStefano Zampini Input Parameters: 680d4fe737eSStefano Zampini + mapping - mapping between local and global numbering 681d4fe737eSStefano Zampini - is - index set in global numbering 682d4fe737eSStefano Zampini 683d4fe737eSStefano Zampini Output Parameters: 684d4fe737eSStefano Zampini . newis - index set in local numbering 685d4fe737eSStefano Zampini 686d4fe737eSStefano Zampini Level: advanced 687d4fe737eSStefano Zampini 688d4fe737eSStefano Zampini Concepts: mapping^local to global 689d4fe737eSStefano Zampini 690d4fe737eSStefano Zampini .seealso: ISGlobalToLocalMappingApply(), ISLocalToGlobalMappingCreate(), 691d4fe737eSStefano Zampini ISLocalToGlobalMappingDestroy() 692d4fe737eSStefano Zampini @*/ 693d4fe737eSStefano Zampini PetscErrorCode ISGlobalToLocalMappingApplyIS(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, IS is,IS *newis) 694d4fe737eSStefano Zampini { 695d4fe737eSStefano Zampini PetscErrorCode ierr; 696d4fe737eSStefano Zampini PetscInt n,nout,*idxout; 697d4fe737eSStefano Zampini const PetscInt *idxin; 698d4fe737eSStefano Zampini 699d4fe737eSStefano Zampini PetscFunctionBegin; 700d4fe737eSStefano Zampini PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 701d4fe737eSStefano Zampini PetscValidHeaderSpecific(is,IS_CLASSID,3); 702d4fe737eSStefano Zampini PetscValidPointer(newis,4); 703d4fe737eSStefano Zampini 704d4fe737eSStefano Zampini ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 705d4fe737eSStefano Zampini ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 706d4fe737eSStefano Zampini if (type == IS_GTOLM_MASK) { 707d4fe737eSStefano Zampini ierr = PetscMalloc1(n,&idxout);CHKERRQ(ierr); 708d4fe737eSStefano Zampini } else { 709d4fe737eSStefano Zampini ierr = ISGlobalToLocalMappingApply(mapping,type,n,idxin,&nout,NULL);CHKERRQ(ierr); 710d4fe737eSStefano Zampini ierr = PetscMalloc1(nout,&idxout);CHKERRQ(ierr); 711d4fe737eSStefano Zampini } 712d4fe737eSStefano Zampini ierr = ISGlobalToLocalMappingApply(mapping,type,n,idxin,&nout,idxout);CHKERRQ(ierr); 713d4fe737eSStefano Zampini ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 714d4fe737eSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is),nout,idxout,PETSC_OWN_POINTER,newis);CHKERRQ(ierr); 715d4fe737eSStefano Zampini PetscFunctionReturn(0); 716d4fe737eSStefano Zampini } 717d4fe737eSStefano Zampini 718d4fe737eSStefano Zampini #undef __FUNCT__ 7199d90f715SBarry Smith #define __FUNCT__ "ISGlobalToLocalMappingApplyBlock" 7209d90f715SBarry Smith /*@ 7219d90f715SBarry Smith ISGlobalToLocalMappingApplyBlock - Provides the local block numbering for a list of integers 7229d90f715SBarry Smith specified with a block global numbering. 7239d90f715SBarry Smith 7249d90f715SBarry Smith Not collective 7259d90f715SBarry Smith 7269d90f715SBarry Smith Input Parameters: 7279d90f715SBarry Smith + mapping - mapping between local and global numbering 7289d90f715SBarry Smith . type - IS_GTOLM_MASK - replaces global indices with no local value with -1 7299d90f715SBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 7309d90f715SBarry Smith . n - number of global indices to map 7319d90f715SBarry Smith - idx - global indices to map 7329d90f715SBarry Smith 7339d90f715SBarry Smith Output Parameters: 7349d90f715SBarry Smith + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 7359d90f715SBarry Smith - idxout - local index of each global index, one must pass in an array long enough 7369d90f715SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApplyBlock() with 7379d90f715SBarry Smith idxout == NULL to determine the required length (returned in nout) 7389d90f715SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApplyBlock() 7399d90f715SBarry Smith a second time to set the values. 7409d90f715SBarry Smith 7419d90f715SBarry Smith Notes: 7429d90f715SBarry Smith Either nout or idxout may be NULL. idx and idxout may be identical. 7439d90f715SBarry Smith 7449d90f715SBarry Smith This is not scalable in memory usage. Each processor requires O(Nglobal) size 7459d90f715SBarry Smith array to compute these. 7469d90f715SBarry Smith 7479d90f715SBarry Smith Level: advanced 7489d90f715SBarry Smith 7499d90f715SBarry Smith Developer Note: The manual page states that idx and idxout may be identical but the calling 7509d90f715SBarry Smith sequence declares idx as const so it cannot be the same as idxout. 7519d90f715SBarry Smith 7529d90f715SBarry Smith Concepts: mapping^global to local 7539d90f715SBarry Smith 7549d90f715SBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISGlobalToLocalMappingApply(), ISLocalToGlobalMappingCreate(), 7559d90f715SBarry Smith ISLocalToGlobalMappingDestroy() 7569d90f715SBarry Smith @*/ 7579d90f715SBarry Smith PetscErrorCode ISGlobalToLocalMappingApplyBlock(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, 7589d90f715SBarry Smith PetscInt n,const PetscInt idx[],PetscInt *nout,PetscInt idxout[]) 7599d90f715SBarry Smith { 76032dcc486SBarry Smith PetscInt i,*globals,nf = 0,tmp,start,end; 7616849ba73SBarry Smith PetscErrorCode ierr; 762d4bb536fSBarry Smith 7633a40ed3dSBarry Smith PetscFunctionBegin; 7640700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 765d4bb536fSBarry Smith if (!mapping->globals) { 766d4bb536fSBarry Smith ierr = ISGlobalToLocalMappingSetUp_Private(mapping);CHKERRQ(ierr); 767d4bb536fSBarry Smith } 768d4bb536fSBarry Smith globals = mapping->globals; 769d4bb536fSBarry Smith start = mapping->globalstart; 770d4bb536fSBarry Smith end = mapping->globalend; 771d4bb536fSBarry Smith 772d4bb536fSBarry Smith if (type == IS_GTOLM_MASK) { 773d4bb536fSBarry Smith if (idxout) { 774d4bb536fSBarry Smith for (i=0; i<n; i++) { 775d4bb536fSBarry Smith if (idx[i] < 0) idxout[i] = idx[i]; 776d4bb536fSBarry Smith else if (idx[i] < start) idxout[i] = -1; 777d4bb536fSBarry Smith else if (idx[i] > end) idxout[i] = -1; 778d4bb536fSBarry Smith else idxout[i] = globals[idx[i] - start]; 779d4bb536fSBarry Smith } 780d4bb536fSBarry Smith } 781d4bb536fSBarry Smith if (nout) *nout = n; 782d4bb536fSBarry Smith } else { 783d4bb536fSBarry Smith if (idxout) { 784d4bb536fSBarry Smith for (i=0; i<n; i++) { 785d4bb536fSBarry Smith if (idx[i] < 0) continue; 786d4bb536fSBarry Smith if (idx[i] < start) continue; 787d4bb536fSBarry Smith if (idx[i] > end) continue; 788d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 789d4bb536fSBarry Smith if (tmp < 0) continue; 790d4bb536fSBarry Smith idxout[nf++] = tmp; 791d4bb536fSBarry Smith } 792d4bb536fSBarry Smith } else { 793d4bb536fSBarry Smith for (i=0; i<n; i++) { 794d4bb536fSBarry Smith if (idx[i] < 0) continue; 795d4bb536fSBarry Smith if (idx[i] < start) continue; 796d4bb536fSBarry Smith if (idx[i] > end) continue; 797d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 798d4bb536fSBarry Smith if (tmp < 0) continue; 799d4bb536fSBarry Smith nf++; 800d4bb536fSBarry Smith } 801d4bb536fSBarry Smith } 802d4bb536fSBarry Smith if (nout) *nout = nf; 803d4bb536fSBarry Smith } 8043a40ed3dSBarry Smith PetscFunctionReturn(0); 805d4bb536fSBarry Smith } 80690f02eecSBarry Smith 8074a2ae208SSatish Balay #undef __FUNCT__ 8086a818285SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingGetBlockInfo" 80989d82c54SBarry Smith /*@C 8106a818285SBarry Smith ISLocalToGlobalMappingGetBlockInfo - Gets the neighbor information for each processor and 81189d82c54SBarry Smith each index shared by more than one processor 81289d82c54SBarry Smith 81389d82c54SBarry Smith Collective on ISLocalToGlobalMapping 81489d82c54SBarry Smith 81589d82c54SBarry Smith Input Parameters: 81689d82c54SBarry Smith . mapping - the mapping from local to global indexing 81789d82c54SBarry Smith 81889d82c54SBarry Smith Output Parameter: 81989d82c54SBarry Smith + nproc - number of processors that are connected to this one 82089d82c54SBarry Smith . proc - neighboring processors 82107b52d57SBarry Smith . numproc - number of indices for each subdomain (processor) 8223463a7baSJed Brown - indices - indices of nodes (in local numbering) shared with neighbors (sorted by global numbering) 82389d82c54SBarry Smith 82489d82c54SBarry Smith Level: advanced 82589d82c54SBarry Smith 826273d9f13SBarry Smith Concepts: mapping^local to global 82789d82c54SBarry Smith 8282cfcea29SBarry Smith Fortran Usage: 8292cfcea29SBarry Smith $ ISLocalToGlobalMpngGetInfoSize(ISLocalToGlobalMapping,PetscInt nproc,PetscInt numprocmax,ierr) followed by 8302cfcea29SBarry Smith $ ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping,PetscInt nproc, PetscInt procs[nproc],PetscInt numprocs[nproc], 8312cfcea29SBarry Smith PetscInt indices[nproc][numprocmax],ierr) 8322cfcea29SBarry Smith There is no ISLocalToGlobalMappingRestoreInfo() in Fortran. You must make sure that procs[], numprocs[] and 8332cfcea29SBarry Smith indices[][] are large enough arrays, either by allocating them dynamically or defining static ones large enough. 8342cfcea29SBarry Smith 8352cfcea29SBarry Smith 83607b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 83707b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo() 83889d82c54SBarry Smith @*/ 8396a818285SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetBlockInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 84089d82c54SBarry Smith { 8416849ba73SBarry Smith PetscErrorCode ierr; 842268a049cSStefano Zampini 843268a049cSStefano Zampini PetscFunctionBegin; 844268a049cSStefano Zampini PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 845268a049cSStefano Zampini if (mapping->info_cached) { 846268a049cSStefano Zampini *nproc = mapping->info_nproc; 847268a049cSStefano Zampini *procs = mapping->info_procs; 848268a049cSStefano Zampini *numprocs = mapping->info_numprocs; 849268a049cSStefano Zampini *indices = mapping->info_indices; 850268a049cSStefano Zampini } else { 851268a049cSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockInfo_Private(mapping,nproc,procs,numprocs,indices);CHKERRQ(ierr); 852268a049cSStefano Zampini } 853268a049cSStefano Zampini PetscFunctionReturn(0); 854268a049cSStefano Zampini } 855268a049cSStefano Zampini 856268a049cSStefano Zampini #undef __FUNCT__ 857268a049cSStefano Zampini #define __FUNCT__ "ISLocalToGlobalMappingGetBlockInfo_Private" 858268a049cSStefano Zampini static PetscErrorCode ISLocalToGlobalMappingGetBlockInfo_Private(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 859268a049cSStefano Zampini { 860268a049cSStefano Zampini PetscErrorCode ierr; 86197f1f81fSBarry Smith PetscMPIInt size,rank,tag1,tag2,tag3,*len,*source,imdex; 86232dcc486SBarry Smith PetscInt i,n = mapping->n,Ng,ng,max = 0,*lindices = mapping->indices; 86332dcc486SBarry Smith PetscInt *nprocs,*owner,nsends,*sends,j,*starts,nmax,nrecvs,*recvs,proc; 86497f1f81fSBarry Smith PetscInt cnt,scale,*ownedsenders,*nownedsenders,rstart,nowned; 86532dcc486SBarry Smith PetscInt node,nownedm,nt,*sends2,nsends2,*starts2,*lens2,*dest,nrecvs2,*starts3,*recvs2,k,*bprocs,*tmp; 86632dcc486SBarry Smith PetscInt first_procs,first_numprocs,*first_indices; 86789d82c54SBarry Smith MPI_Request *recv_waits,*send_waits; 86830dcb7c9SBarry Smith MPI_Status recv_status,*send_status,*recv_statuses; 869ce94432eSBarry Smith MPI_Comm comm; 870ace3abfcSBarry Smith PetscBool debug = PETSC_FALSE; 87189d82c54SBarry Smith 87289d82c54SBarry Smith PetscFunctionBegin; 873ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)mapping,&comm);CHKERRQ(ierr); 87424cf384cSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 87524cf384cSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 87624cf384cSBarry Smith if (size == 1) { 87724cf384cSBarry Smith *nproc = 0; 8780298fd71SBarry Smith *procs = NULL; 87995dccacaSBarry Smith ierr = PetscNew(numprocs);CHKERRQ(ierr); 8801e2105dcSBarry Smith (*numprocs)[0] = 0; 88195dccacaSBarry Smith ierr = PetscNew(indices);CHKERRQ(ierr); 8820298fd71SBarry Smith (*indices)[0] = NULL; 883268a049cSStefano Zampini /* save info for reuse */ 884268a049cSStefano Zampini mapping->info_nproc = *nproc; 885268a049cSStefano Zampini mapping->info_procs = *procs; 886268a049cSStefano Zampini mapping->info_numprocs = *numprocs; 887268a049cSStefano Zampini mapping->info_indices = *indices; 888268a049cSStefano Zampini mapping->info_cached = PETSC_TRUE; 88924cf384cSBarry Smith PetscFunctionReturn(0); 89024cf384cSBarry Smith } 89124cf384cSBarry Smith 892c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject)mapping)->options,NULL,"-islocaltoglobalmappinggetinfo_debug",&debug,NULL);CHKERRQ(ierr); 89307b52d57SBarry Smith 8943677ff5aSBarry Smith /* 8956a818285SBarry Smith Notes on ISLocalToGlobalMappingGetBlockInfo 8963677ff5aSBarry Smith 8973677ff5aSBarry Smith globally owned node - the nodes that have been assigned to this processor in global 8983677ff5aSBarry Smith numbering, just for this routine. 8993677ff5aSBarry Smith 9003677ff5aSBarry Smith nontrivial globally owned node - node assigned to this processor that is on a subdomain 9013677ff5aSBarry Smith boundary (i.e. is has more than one local owner) 9023677ff5aSBarry Smith 9033677ff5aSBarry Smith locally owned node - node that exists on this processors subdomain 9043677ff5aSBarry Smith 9053677ff5aSBarry Smith nontrivial locally owned node - node that is not in the interior (i.e. has more than one 9063677ff5aSBarry Smith local subdomain 9073677ff5aSBarry Smith */ 90824cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag1);CHKERRQ(ierr); 90924cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag2);CHKERRQ(ierr); 91024cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag3);CHKERRQ(ierr); 91189d82c54SBarry Smith 91289d82c54SBarry Smith for (i=0; i<n; i++) { 91389d82c54SBarry Smith if (lindices[i] > max) max = lindices[i]; 91489d82c54SBarry Smith } 915b2566f29SBarry Smith ierr = MPIU_Allreduce(&max,&Ng,1,MPIU_INT,MPI_MAX,comm);CHKERRQ(ierr); 91678058e43SBarry Smith Ng++; 91789d82c54SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 91889d82c54SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 919bc8ff85bSBarry Smith scale = Ng/size + 1; 920a2e34c3dSBarry Smith ng = scale; if (rank == size-1) ng = Ng - scale*(size-1); ng = PetscMax(1,ng); 921caba0dd0SBarry Smith rstart = scale*rank; 92289d82c54SBarry Smith 92389d82c54SBarry Smith /* determine ownership ranges of global indices */ 924785e854fSJed Brown ierr = PetscMalloc1(2*size,&nprocs);CHKERRQ(ierr); 92532dcc486SBarry Smith ierr = PetscMemzero(nprocs,2*size*sizeof(PetscInt));CHKERRQ(ierr); 92689d82c54SBarry Smith 92789d82c54SBarry Smith /* determine owners of each local node */ 928785e854fSJed Brown ierr = PetscMalloc1(n,&owner);CHKERRQ(ierr); 92989d82c54SBarry Smith for (i=0; i<n; i++) { 9303677ff5aSBarry Smith proc = lindices[i]/scale; /* processor that globally owns this index */ 93127c402fcSBarry Smith nprocs[2*proc+1] = 1; /* processor globally owns at least one of ours */ 9323677ff5aSBarry Smith owner[i] = proc; 93327c402fcSBarry Smith nprocs[2*proc]++; /* count of how many that processor globally owns of ours */ 93489d82c54SBarry Smith } 93527c402fcSBarry Smith nsends = 0; for (i=0; i<size; i++) nsends += nprocs[2*i+1]; 9367904a332SBarry Smith ierr = PetscInfo1(mapping,"Number of global owners for my local data %D\n",nsends);CHKERRQ(ierr); 93789d82c54SBarry Smith 93889d82c54SBarry Smith /* inform other processors of number of messages and max length*/ 93927c402fcSBarry Smith ierr = PetscMaxSum(comm,nprocs,&nmax,&nrecvs);CHKERRQ(ierr); 9407904a332SBarry Smith ierr = PetscInfo1(mapping,"Number of local owners for my global data %D\n",nrecvs);CHKERRQ(ierr); 94189d82c54SBarry Smith 94289d82c54SBarry Smith /* post receives for owned rows */ 943785e854fSJed Brown ierr = PetscMalloc1((2*nrecvs+1)*(nmax+1),&recvs);CHKERRQ(ierr); 944854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,&recv_waits);CHKERRQ(ierr); 94589d82c54SBarry Smith for (i=0; i<nrecvs; i++) { 94632dcc486SBarry Smith ierr = MPI_Irecv(recvs+2*nmax*i,2*nmax,MPIU_INT,MPI_ANY_SOURCE,tag1,comm,recv_waits+i);CHKERRQ(ierr); 94789d82c54SBarry Smith } 94889d82c54SBarry Smith 94989d82c54SBarry Smith /* pack messages containing lists of local nodes to owners */ 950854ce69bSBarry Smith ierr = PetscMalloc1(2*n+1,&sends);CHKERRQ(ierr); 951854ce69bSBarry Smith ierr = PetscMalloc1(size+1,&starts);CHKERRQ(ierr); 95289d82c54SBarry Smith starts[0] = 0; 953f6e5521dSKarl Rupp for (i=1; i<size; i++) starts[i] = starts[i-1] + 2*nprocs[2*i-2]; 95489d82c54SBarry Smith for (i=0; i<n; i++) { 95589d82c54SBarry Smith sends[starts[owner[i]]++] = lindices[i]; 95630dcb7c9SBarry Smith sends[starts[owner[i]]++] = i; 95789d82c54SBarry Smith } 95889d82c54SBarry Smith ierr = PetscFree(owner);CHKERRQ(ierr); 95989d82c54SBarry Smith starts[0] = 0; 960f6e5521dSKarl Rupp for (i=1; i<size; i++) starts[i] = starts[i-1] + 2*nprocs[2*i-2]; 96189d82c54SBarry Smith 96289d82c54SBarry Smith /* send the messages */ 963854ce69bSBarry Smith ierr = PetscMalloc1(nsends+1,&send_waits);CHKERRQ(ierr); 964854ce69bSBarry Smith ierr = PetscMalloc1(nsends+1,&dest);CHKERRQ(ierr); 96589d82c54SBarry Smith cnt = 0; 96689d82c54SBarry Smith for (i=0; i<size; i++) { 96727c402fcSBarry Smith if (nprocs[2*i]) { 96832dcc486SBarry Smith ierr = MPI_Isend(sends+starts[i],2*nprocs[2*i],MPIU_INT,i,tag1,comm,send_waits+cnt);CHKERRQ(ierr); 96930dcb7c9SBarry Smith dest[cnt] = i; 97089d82c54SBarry Smith cnt++; 97189d82c54SBarry Smith } 97289d82c54SBarry Smith } 97389d82c54SBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 97489d82c54SBarry Smith 97589d82c54SBarry Smith /* wait on receives */ 976854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,&source);CHKERRQ(ierr); 977854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,&len);CHKERRQ(ierr); 97889d82c54SBarry Smith cnt = nrecvs; 979854ce69bSBarry Smith ierr = PetscMalloc1(ng+1,&nownedsenders);CHKERRQ(ierr); 98032dcc486SBarry Smith ierr = PetscMemzero(nownedsenders,ng*sizeof(PetscInt));CHKERRQ(ierr); 98189d82c54SBarry Smith while (cnt) { 98289d82c54SBarry Smith ierr = MPI_Waitany(nrecvs,recv_waits,&imdex,&recv_status);CHKERRQ(ierr); 98389d82c54SBarry Smith /* unpack receives into our local space */ 98432dcc486SBarry Smith ierr = MPI_Get_count(&recv_status,MPIU_INT,&len[imdex]);CHKERRQ(ierr); 98589d82c54SBarry Smith source[imdex] = recv_status.MPI_SOURCE; 98630dcb7c9SBarry Smith len[imdex] = len[imdex]/2; 987caba0dd0SBarry Smith /* count how many local owners for each of my global owned indices */ 98830dcb7c9SBarry Smith for (i=0; i<len[imdex]; i++) nownedsenders[recvs[2*imdex*nmax+2*i]-rstart]++; 98989d82c54SBarry Smith cnt--; 99089d82c54SBarry Smith } 99189d82c54SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 99289d82c54SBarry Smith 99330dcb7c9SBarry Smith /* count how many globally owned indices are on an edge multiplied by how many processors own them. */ 994bc8ff85bSBarry Smith nowned = 0; 995bc8ff85bSBarry Smith nownedm = 0; 996bc8ff85bSBarry Smith for (i=0; i<ng; i++) { 997bc8ff85bSBarry Smith if (nownedsenders[i] > 1) {nownedm += nownedsenders[i]; nowned++;} 998bc8ff85bSBarry Smith } 999bc8ff85bSBarry Smith 1000bc8ff85bSBarry Smith /* create single array to contain rank of all local owners of each globally owned index */ 1001854ce69bSBarry Smith ierr = PetscMalloc1(nownedm+1,&ownedsenders);CHKERRQ(ierr); 1002854ce69bSBarry Smith ierr = PetscMalloc1(ng+1,&starts);CHKERRQ(ierr); 1003bc8ff85bSBarry Smith starts[0] = 0; 1004bc8ff85bSBarry Smith for (i=1; i<ng; i++) { 1005bc8ff85bSBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 1006bc8ff85bSBarry Smith else starts[i] = starts[i-1]; 1007bc8ff85bSBarry Smith } 1008bc8ff85bSBarry Smith 100930dcb7c9SBarry Smith /* for each nontrival globally owned node list all arriving processors */ 1010bc8ff85bSBarry Smith for (i=0; i<nrecvs; i++) { 1011bc8ff85bSBarry Smith for (j=0; j<len[i]; j++) { 101230dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 1013f6e5521dSKarl Rupp if (nownedsenders[node] > 1) ownedsenders[starts[node]++] = source[i]; 1014bc8ff85bSBarry Smith } 1015bc8ff85bSBarry Smith } 1016bc8ff85bSBarry Smith 101707b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 101830dcb7c9SBarry Smith starts[0] = 0; 101930dcb7c9SBarry Smith for (i=1; i<ng; i++) { 102030dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 102130dcb7c9SBarry Smith else starts[i] = starts[i-1]; 102230dcb7c9SBarry Smith } 102330dcb7c9SBarry Smith for (i=0; i<ng; i++) { 102430dcb7c9SBarry Smith if (nownedsenders[i] > 1) { 10257904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] global node %D local owner processors: ",rank,i+rstart);CHKERRQ(ierr); 102630dcb7c9SBarry Smith for (j=0; j<nownedsenders[i]; j++) { 10277904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%D ",ownedsenders[starts[i]+j]);CHKERRQ(ierr); 102830dcb7c9SBarry Smith } 102930dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 103030dcb7c9SBarry Smith } 103130dcb7c9SBarry Smith } 10320ec8b6e3SBarry Smith ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 103307b52d57SBarry Smith } /* ----------------------------------- */ 103430dcb7c9SBarry Smith 10353677ff5aSBarry Smith /* wait on original sends */ 10363a96401aSBarry Smith if (nsends) { 1037785e854fSJed Brown ierr = PetscMalloc1(nsends,&send_status);CHKERRQ(ierr); 10383a96401aSBarry Smith ierr = MPI_Waitall(nsends,send_waits,send_status);CHKERRQ(ierr); 10393a96401aSBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 10403a96401aSBarry Smith } 104189d82c54SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 10423a96401aSBarry Smith ierr = PetscFree(sends);CHKERRQ(ierr); 10433677ff5aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 10443677ff5aSBarry Smith 10453677ff5aSBarry Smith /* pack messages to send back to local owners */ 104630dcb7c9SBarry Smith starts[0] = 0; 104730dcb7c9SBarry Smith for (i=1; i<ng; i++) { 104830dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 104930dcb7c9SBarry Smith else starts[i] = starts[i-1]; 105030dcb7c9SBarry Smith } 105130dcb7c9SBarry Smith nsends2 = nrecvs; 1052854ce69bSBarry Smith ierr = PetscMalloc1(nsends2+1,&nprocs);CHKERRQ(ierr); /* length of each message */ 105330dcb7c9SBarry Smith for (i=0; i<nrecvs; i++) { 105430dcb7c9SBarry Smith nprocs[i] = 1; 105530dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 105630dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 1057f6e5521dSKarl Rupp if (nownedsenders[node] > 1) nprocs[i] += 2 + nownedsenders[node]; 105830dcb7c9SBarry Smith } 105930dcb7c9SBarry Smith } 1060f6e5521dSKarl Rupp nt = 0; 1061f6e5521dSKarl Rupp for (i=0; i<nsends2; i++) nt += nprocs[i]; 1062f6e5521dSKarl Rupp 1063854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,&sends2);CHKERRQ(ierr); 1064854ce69bSBarry Smith ierr = PetscMalloc1(nsends2+1,&starts2);CHKERRQ(ierr); 1065f6e5521dSKarl Rupp 1066f6e5521dSKarl Rupp starts2[0] = 0; 1067f6e5521dSKarl Rupp for (i=1; i<nsends2; i++) starts2[i] = starts2[i-1] + nprocs[i-1]; 106830dcb7c9SBarry Smith /* 106930dcb7c9SBarry Smith Each message is 1 + nprocs[i] long, and consists of 107030dcb7c9SBarry Smith (0) the number of nodes being sent back 107130dcb7c9SBarry Smith (1) the local node number, 107230dcb7c9SBarry Smith (2) the number of processors sharing it, 107330dcb7c9SBarry Smith (3) the processors sharing it 107430dcb7c9SBarry Smith */ 107530dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 107630dcb7c9SBarry Smith cnt = 1; 107730dcb7c9SBarry Smith sends2[starts2[i]] = 0; 107830dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 107930dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 108030dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 108130dcb7c9SBarry Smith sends2[starts2[i]]++; 108230dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = recvs[2*i*nmax+2*j+1]; 108330dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = nownedsenders[node]; 108432dcc486SBarry Smith ierr = PetscMemcpy(&sends2[starts2[i]+cnt],&ownedsenders[starts[node]],nownedsenders[node]*sizeof(PetscInt));CHKERRQ(ierr); 108530dcb7c9SBarry Smith cnt += nownedsenders[node]; 108630dcb7c9SBarry Smith } 108730dcb7c9SBarry Smith } 108830dcb7c9SBarry Smith } 108930dcb7c9SBarry Smith 109030dcb7c9SBarry Smith /* receive the message lengths */ 109130dcb7c9SBarry Smith nrecvs2 = nsends; 1092854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&lens2);CHKERRQ(ierr); 1093854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&starts3);CHKERRQ(ierr); 1094854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&recv_waits);CHKERRQ(ierr); 109530dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 1096d44834fbSBarry Smith ierr = MPI_Irecv(&lens2[i],1,MPIU_INT,dest[i],tag2,comm,recv_waits+i);CHKERRQ(ierr); 109730dcb7c9SBarry Smith } 1098d44834fbSBarry Smith 10998a8e0b3aSBarry Smith /* send the message lengths */ 11008a8e0b3aSBarry Smith for (i=0; i<nsends2; i++) { 11018a8e0b3aSBarry Smith ierr = MPI_Send(&nprocs[i],1,MPIU_INT,source[i],tag2,comm);CHKERRQ(ierr); 11028a8e0b3aSBarry Smith } 11038a8e0b3aSBarry Smith 1104d44834fbSBarry Smith /* wait on receives of lens */ 11050c468ba9SBarry Smith if (nrecvs2) { 1106785e854fSJed Brown ierr = PetscMalloc1(nrecvs2,&recv_statuses);CHKERRQ(ierr); 1107d44834fbSBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 1108d44834fbSBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 11090c468ba9SBarry Smith } 1110a2ea699eSBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 1111d44834fbSBarry Smith 111230dcb7c9SBarry Smith starts3[0] = 0; 1113d44834fbSBarry Smith nt = 0; 111430dcb7c9SBarry Smith for (i=0; i<nrecvs2-1; i++) { 111530dcb7c9SBarry Smith starts3[i+1] = starts3[i] + lens2[i]; 1116d44834fbSBarry Smith nt += lens2[i]; 111730dcb7c9SBarry Smith } 111876466f69SStefano Zampini if (nrecvs2) nt += lens2[nrecvs2-1]; 1119d44834fbSBarry Smith 1120854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,&recvs2);CHKERRQ(ierr); 1121854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&recv_waits);CHKERRQ(ierr); 112252b72c4aSBarry Smith for (i=0; i<nrecvs2; i++) { 112332dcc486SBarry Smith ierr = MPI_Irecv(recvs2+starts3[i],lens2[i],MPIU_INT,dest[i],tag3,comm,recv_waits+i);CHKERRQ(ierr); 112430dcb7c9SBarry Smith } 112530dcb7c9SBarry Smith 112630dcb7c9SBarry Smith /* send the messages */ 1127854ce69bSBarry Smith ierr = PetscMalloc1(nsends2+1,&send_waits);CHKERRQ(ierr); 112830dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 112932dcc486SBarry Smith ierr = MPI_Isend(sends2+starts2[i],nprocs[i],MPIU_INT,source[i],tag3,comm,send_waits+i);CHKERRQ(ierr); 113030dcb7c9SBarry Smith } 113130dcb7c9SBarry Smith 113230dcb7c9SBarry Smith /* wait on receives */ 11330c468ba9SBarry Smith if (nrecvs2) { 1134785e854fSJed Brown ierr = PetscMalloc1(nrecvs2,&recv_statuses);CHKERRQ(ierr); 113530dcb7c9SBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 113630dcb7c9SBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 11370c468ba9SBarry Smith } 113830dcb7c9SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 113930dcb7c9SBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 114030dcb7c9SBarry Smith 114107b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 114230dcb7c9SBarry Smith cnt = 0; 114330dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 114430dcb7c9SBarry Smith nt = recvs2[cnt++]; 114530dcb7c9SBarry Smith for (j=0; j<nt; j++) { 11467904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] local node %D number of subdomains %D: ",rank,recvs2[cnt],recvs2[cnt+1]);CHKERRQ(ierr); 114730dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 11487904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%D ",recvs2[cnt+2+k]);CHKERRQ(ierr); 114930dcb7c9SBarry Smith } 115030dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 115130dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 115230dcb7c9SBarry Smith } 115330dcb7c9SBarry Smith } 11540ec8b6e3SBarry Smith ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 115507b52d57SBarry Smith } /* ----------------------------------- */ 115630dcb7c9SBarry Smith 115730dcb7c9SBarry Smith /* count number subdomains for each local node */ 1158785e854fSJed Brown ierr = PetscMalloc1(size,&nprocs);CHKERRQ(ierr); 115932dcc486SBarry Smith ierr = PetscMemzero(nprocs,size*sizeof(PetscInt));CHKERRQ(ierr); 116030dcb7c9SBarry Smith cnt = 0; 116130dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 116230dcb7c9SBarry Smith nt = recvs2[cnt++]; 116330dcb7c9SBarry Smith for (j=0; j<nt; j++) { 1164f6e5521dSKarl Rupp for (k=0; k<recvs2[cnt+1]; k++) nprocs[recvs2[cnt+2+k]]++; 116530dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 116630dcb7c9SBarry Smith } 116730dcb7c9SBarry Smith } 116830dcb7c9SBarry Smith nt = 0; for (i=0; i<size; i++) nt += (nprocs[i] > 0); 116930dcb7c9SBarry Smith *nproc = nt; 1170854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,procs);CHKERRQ(ierr); 1171854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,numprocs);CHKERRQ(ierr); 1172854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,indices);CHKERRQ(ierr); 11730298fd71SBarry Smith for (i=0;i<nt+1;i++) (*indices)[i]=NULL; 1174785e854fSJed Brown ierr = PetscMalloc1(size,&bprocs);CHKERRQ(ierr); 117530dcb7c9SBarry Smith cnt = 0; 117630dcb7c9SBarry Smith for (i=0; i<size; i++) { 117730dcb7c9SBarry Smith if (nprocs[i] > 0) { 117830dcb7c9SBarry Smith bprocs[i] = cnt; 117930dcb7c9SBarry Smith (*procs)[cnt] = i; 118030dcb7c9SBarry Smith (*numprocs)[cnt] = nprocs[i]; 1181785e854fSJed Brown ierr = PetscMalloc1(nprocs[i],&(*indices)[cnt]);CHKERRQ(ierr); 118230dcb7c9SBarry Smith cnt++; 118330dcb7c9SBarry Smith } 118430dcb7c9SBarry Smith } 118530dcb7c9SBarry Smith 118630dcb7c9SBarry Smith /* make the list of subdomains for each nontrivial local node */ 118732dcc486SBarry Smith ierr = PetscMemzero(*numprocs,nt*sizeof(PetscInt));CHKERRQ(ierr); 118830dcb7c9SBarry Smith cnt = 0; 118930dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 119030dcb7c9SBarry Smith nt = recvs2[cnt++]; 119130dcb7c9SBarry Smith for (j=0; j<nt; j++) { 1192f6e5521dSKarl Rupp for (k=0; k<recvs2[cnt+1]; k++) (*indices)[bprocs[recvs2[cnt+2+k]]][(*numprocs)[bprocs[recvs2[cnt+2+k]]]++] = recvs2[cnt]; 119330dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 119430dcb7c9SBarry Smith } 119530dcb7c9SBarry Smith } 119630dcb7c9SBarry Smith ierr = PetscFree(bprocs);CHKERRQ(ierr); 119707b52d57SBarry Smith ierr = PetscFree(recvs2);CHKERRQ(ierr); 119830dcb7c9SBarry Smith 119907b52d57SBarry Smith /* sort the node indexing by their global numbers */ 120007b52d57SBarry Smith nt = *nproc; 120107b52d57SBarry Smith for (i=0; i<nt; i++) { 1202854ce69bSBarry Smith ierr = PetscMalloc1((*numprocs)[i],&tmp);CHKERRQ(ierr); 1203f6e5521dSKarl Rupp for (j=0; j<(*numprocs)[i]; j++) tmp[j] = lindices[(*indices)[i][j]]; 120407b52d57SBarry Smith ierr = PetscSortIntWithArray((*numprocs)[i],tmp,(*indices)[i]);CHKERRQ(ierr); 120507b52d57SBarry Smith ierr = PetscFree(tmp);CHKERRQ(ierr); 120607b52d57SBarry Smith } 120707b52d57SBarry Smith 120807b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 120930dcb7c9SBarry Smith nt = *nproc; 121030dcb7c9SBarry Smith for (i=0; i<nt; i++) { 12117904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] subdomain %D number of indices %D: ",rank,(*procs)[i],(*numprocs)[i]);CHKERRQ(ierr); 121230dcb7c9SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 12137904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%D ",(*indices)[i][j]);CHKERRQ(ierr); 121430dcb7c9SBarry Smith } 121530dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 121630dcb7c9SBarry Smith } 12170ec8b6e3SBarry Smith ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 121807b52d57SBarry Smith } /* ----------------------------------- */ 121930dcb7c9SBarry Smith 122030dcb7c9SBarry Smith /* wait on sends */ 122130dcb7c9SBarry Smith if (nsends2) { 1222785e854fSJed Brown ierr = PetscMalloc1(nsends2,&send_status);CHKERRQ(ierr); 122330dcb7c9SBarry Smith ierr = MPI_Waitall(nsends2,send_waits,send_status);CHKERRQ(ierr); 122430dcb7c9SBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 122530dcb7c9SBarry Smith } 122630dcb7c9SBarry Smith 122730dcb7c9SBarry Smith ierr = PetscFree(starts3);CHKERRQ(ierr); 122830dcb7c9SBarry Smith ierr = PetscFree(dest);CHKERRQ(ierr); 122930dcb7c9SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 12303677ff5aSBarry Smith 1231bc8ff85bSBarry Smith ierr = PetscFree(nownedsenders);CHKERRQ(ierr); 1232bc8ff85bSBarry Smith ierr = PetscFree(ownedsenders);CHKERRQ(ierr); 1233bc8ff85bSBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 123430dcb7c9SBarry Smith ierr = PetscFree(starts2);CHKERRQ(ierr); 123530dcb7c9SBarry Smith ierr = PetscFree(lens2);CHKERRQ(ierr); 123689d82c54SBarry Smith 123789d82c54SBarry Smith ierr = PetscFree(source);CHKERRQ(ierr); 123897f1f81fSBarry Smith ierr = PetscFree(len);CHKERRQ(ierr); 123989d82c54SBarry Smith ierr = PetscFree(recvs);CHKERRQ(ierr); 12403a96401aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 124130dcb7c9SBarry Smith ierr = PetscFree(sends2);CHKERRQ(ierr); 124224cf384cSBarry Smith 124324cf384cSBarry Smith /* put the information about myself as the first entry in the list */ 124424cf384cSBarry Smith first_procs = (*procs)[0]; 124524cf384cSBarry Smith first_numprocs = (*numprocs)[0]; 124624cf384cSBarry Smith first_indices = (*indices)[0]; 124724cf384cSBarry Smith for (i=0; i<*nproc; i++) { 124824cf384cSBarry Smith if ((*procs)[i] == rank) { 124924cf384cSBarry Smith (*procs)[0] = (*procs)[i]; 125024cf384cSBarry Smith (*numprocs)[0] = (*numprocs)[i]; 125124cf384cSBarry Smith (*indices)[0] = (*indices)[i]; 125224cf384cSBarry Smith (*procs)[i] = first_procs; 125324cf384cSBarry Smith (*numprocs)[i] = first_numprocs; 125424cf384cSBarry Smith (*indices)[i] = first_indices; 125524cf384cSBarry Smith break; 125624cf384cSBarry Smith } 125724cf384cSBarry Smith } 1258268a049cSStefano Zampini 1259268a049cSStefano Zampini /* save info for reuse */ 1260268a049cSStefano Zampini mapping->info_nproc = *nproc; 1261268a049cSStefano Zampini mapping->info_procs = *procs; 1262268a049cSStefano Zampini mapping->info_numprocs = *numprocs; 1263268a049cSStefano Zampini mapping->info_indices = *indices; 1264268a049cSStefano Zampini mapping->info_cached = PETSC_TRUE; 126589d82c54SBarry Smith PetscFunctionReturn(0); 126689d82c54SBarry Smith } 126789d82c54SBarry Smith 12684a2ae208SSatish Balay #undef __FUNCT__ 12696a818285SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingRestoreBlockInfo" 12706a818285SBarry Smith /*@C 12716a818285SBarry Smith ISLocalToGlobalMappingRestoreBlockInfo - Frees the memory allocated by ISLocalToGlobalMappingGetBlockInfo() 12726a818285SBarry Smith 12736a818285SBarry Smith Collective on ISLocalToGlobalMapping 12746a818285SBarry Smith 12756a818285SBarry Smith Input Parameters: 12766a818285SBarry Smith . mapping - the mapping from local to global indexing 12776a818285SBarry Smith 12786a818285SBarry Smith Output Parameter: 12796a818285SBarry Smith + nproc - number of processors that are connected to this one 12806a818285SBarry Smith . proc - neighboring processors 12816a818285SBarry Smith . numproc - number of indices for each processor 12826a818285SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 12836a818285SBarry Smith 12846a818285SBarry Smith Level: advanced 12856a818285SBarry Smith 12866a818285SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 12876a818285SBarry Smith ISLocalToGlobalMappingGetInfo() 12886a818285SBarry Smith @*/ 12896a818285SBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreBlockInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 12906a818285SBarry Smith { 12916a818285SBarry Smith PetscErrorCode ierr; 12926a818285SBarry Smith 12936a818285SBarry Smith PetscFunctionBegin; 1294cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 1295268a049cSStefano Zampini if (mapping->info_free) { 12966a818285SBarry Smith ierr = PetscFree(*numprocs);CHKERRQ(ierr); 12976a818285SBarry Smith if (*indices) { 1298268a049cSStefano Zampini PetscInt i; 1299268a049cSStefano Zampini 13006a818285SBarry Smith ierr = PetscFree((*indices)[0]);CHKERRQ(ierr); 13016a818285SBarry Smith for (i=1; i<*nproc; i++) { 13026a818285SBarry Smith ierr = PetscFree((*indices)[i]);CHKERRQ(ierr); 13036a818285SBarry Smith } 13046a818285SBarry Smith ierr = PetscFree(*indices);CHKERRQ(ierr); 13056a818285SBarry Smith } 1306268a049cSStefano Zampini } 1307268a049cSStefano Zampini *nproc = 0; 1308268a049cSStefano Zampini *procs = NULL; 1309268a049cSStefano Zampini *numprocs = NULL; 1310268a049cSStefano Zampini *indices = NULL; 13116a818285SBarry Smith PetscFunctionReturn(0); 13126a818285SBarry Smith } 13136a818285SBarry Smith 13146a818285SBarry Smith #undef __FUNCT__ 13156a818285SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingGetInfo" 13166a818285SBarry Smith /*@C 13176a818285SBarry Smith ISLocalToGlobalMappingGetInfo - Gets the neighbor information for each processor and 13186a818285SBarry Smith each index shared by more than one processor 13196a818285SBarry Smith 13206a818285SBarry Smith Collective on ISLocalToGlobalMapping 13216a818285SBarry Smith 13226a818285SBarry Smith Input Parameters: 13236a818285SBarry Smith . mapping - the mapping from local to global indexing 13246a818285SBarry Smith 13256a818285SBarry Smith Output Parameter: 13266a818285SBarry Smith + nproc - number of processors that are connected to this one 13276a818285SBarry Smith . proc - neighboring processors 13286a818285SBarry Smith . numproc - number of indices for each subdomain (processor) 13296a818285SBarry Smith - indices - indices of nodes (in local numbering) shared with neighbors (sorted by global numbering) 13306a818285SBarry Smith 13316a818285SBarry Smith Level: advanced 13326a818285SBarry Smith 13336a818285SBarry Smith Concepts: mapping^local to global 13346a818285SBarry Smith 13356a818285SBarry Smith Fortran Usage: 13366a818285SBarry Smith $ ISLocalToGlobalMpngGetInfoSize(ISLocalToGlobalMapping,PetscInt nproc,PetscInt numprocmax,ierr) followed by 13376a818285SBarry Smith $ ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping,PetscInt nproc, PetscInt procs[nproc],PetscInt numprocs[nproc], 13386a818285SBarry Smith PetscInt indices[nproc][numprocmax],ierr) 13396a818285SBarry Smith There is no ISLocalToGlobalMappingRestoreInfo() in Fortran. You must make sure that procs[], numprocs[] and 13406a818285SBarry Smith indices[][] are large enough arrays, either by allocating them dynamically or defining static ones large enough. 13416a818285SBarry Smith 13426a818285SBarry Smith 13436a818285SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 13446a818285SBarry Smith ISLocalToGlobalMappingRestoreInfo() 13456a818285SBarry Smith @*/ 13466a818285SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 13476a818285SBarry Smith { 13486a818285SBarry Smith PetscErrorCode ierr; 1349268a049cSStefano Zampini PetscInt **bindices = NULL,*bnumprocs = NULL,bs = mapping->bs,i,j,k; 13506a818285SBarry Smith 13516a818285SBarry Smith PetscFunctionBegin; 13526a818285SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 1353268a049cSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockInfo(mapping,nproc,procs,&bnumprocs,&bindices);CHKERRQ(ierr); 1354268a049cSStefano Zampini if (bs > 1) { /* we need to expand the cached info */ 1355732f65e3SBarry Smith ierr = PetscCalloc1(*nproc,&*indices);CHKERRQ(ierr); 1356268a049cSStefano Zampini ierr = PetscCalloc1(*nproc,&*numprocs);CHKERRQ(ierr); 13576a818285SBarry Smith for (i=0; i<*nproc; i++) { 1358268a049cSStefano Zampini ierr = PetscMalloc1(bs*bnumprocs[i],&(*indices)[i]);CHKERRQ(ierr); 1359268a049cSStefano Zampini for (j=0; j<bnumprocs[i]; j++) { 13606a818285SBarry Smith for (k=0; k<bs; k++) { 13616a818285SBarry Smith (*indices)[i][j*bs+k] = bs*bindices[i][j] + k; 13626a818285SBarry Smith } 13636a818285SBarry Smith } 1364268a049cSStefano Zampini (*numprocs)[i] = bnumprocs[i]*bs; 13656a818285SBarry Smith } 1366268a049cSStefano Zampini mapping->info_free = PETSC_TRUE; 1367268a049cSStefano Zampini } else { 1368268a049cSStefano Zampini *numprocs = bnumprocs; 1369268a049cSStefano Zampini *indices = bindices; 13706a818285SBarry Smith } 13716a818285SBarry Smith PetscFunctionReturn(0); 13726a818285SBarry Smith } 13736a818285SBarry Smith 13746a818285SBarry Smith #undef __FUNCT__ 13754a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingRestoreInfo" 137607b52d57SBarry Smith /*@C 137707b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo - Frees the memory allocated by ISLocalToGlobalMappingGetInfo() 137889d82c54SBarry Smith 137907b52d57SBarry Smith Collective on ISLocalToGlobalMapping 138007b52d57SBarry Smith 138107b52d57SBarry Smith Input Parameters: 138207b52d57SBarry Smith . mapping - the mapping from local to global indexing 138307b52d57SBarry Smith 138407b52d57SBarry Smith Output Parameter: 138507b52d57SBarry Smith + nproc - number of processors that are connected to this one 138607b52d57SBarry Smith . proc - neighboring processors 138707b52d57SBarry Smith . numproc - number of indices for each processor 138807b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 138907b52d57SBarry Smith 139007b52d57SBarry Smith Level: advanced 139107b52d57SBarry Smith 139207b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 139307b52d57SBarry Smith ISLocalToGlobalMappingGetInfo() 139407b52d57SBarry Smith @*/ 13957087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 139607b52d57SBarry Smith { 13976849ba73SBarry Smith PetscErrorCode ierr; 139807b52d57SBarry Smith 139907b52d57SBarry Smith PetscFunctionBegin; 14006a818285SBarry Smith ierr = ISLocalToGlobalMappingRestoreBlockInfo(mapping,nproc,procs,numprocs,indices);CHKERRQ(ierr); 140107b52d57SBarry Smith PetscFunctionReturn(0); 140207b52d57SBarry Smith } 140386994e45SJed Brown 140486994e45SJed Brown #undef __FUNCT__ 140586994e45SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingGetIndices" 140686994e45SJed Brown /*@C 1407107e9a97SBarry Smith ISLocalToGlobalMappingGetIndices - Get global indices for every local point that is mapped 140886994e45SJed Brown 140986994e45SJed Brown Not Collective 141086994e45SJed Brown 141186994e45SJed Brown Input Arguments: 141286994e45SJed Brown . ltog - local to global mapping 141386994e45SJed Brown 141486994e45SJed Brown Output Arguments: 1415565245c5SBarry Smith . array - array of indices, the length of this array may be obtained with ISLocalToGlobalMappingGetSize() 141686994e45SJed Brown 141786994e45SJed Brown Level: advanced 141886994e45SJed Brown 1419107e9a97SBarry Smith Notes: ISLocalToGlobalMappingGetSize() returns the length the this array 1420107e9a97SBarry Smith 1421107e9a97SBarry Smith .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingRestoreIndices(), ISLocalToGlobalMappingGetBlockIndices(), ISLocalToGlobalMappingRestoreBlockIndices() 142286994e45SJed Brown @*/ 14237087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingGetIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 142486994e45SJed Brown { 142586994e45SJed Brown PetscFunctionBegin; 142686994e45SJed Brown PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 142786994e45SJed Brown PetscValidPointer(array,2); 142845b6f7e9SBarry Smith if (ltog->bs == 1) { 142986994e45SJed Brown *array = ltog->indices; 143045b6f7e9SBarry Smith } else { 143145b6f7e9SBarry Smith PetscInt *jj,k,i,j,n = ltog->n, bs = ltog->bs; 143245b6f7e9SBarry Smith const PetscInt *ii; 143345b6f7e9SBarry Smith PetscErrorCode ierr; 143445b6f7e9SBarry Smith 143545b6f7e9SBarry Smith ierr = PetscMalloc1(bs*n,&jj);CHKERRQ(ierr); 143645b6f7e9SBarry Smith *array = jj; 143745b6f7e9SBarry Smith k = 0; 143845b6f7e9SBarry Smith ii = ltog->indices; 143945b6f7e9SBarry Smith for (i=0; i<n; i++) 144045b6f7e9SBarry Smith for (j=0; j<bs; j++) 144145b6f7e9SBarry Smith jj[k++] = bs*ii[i] + j; 144245b6f7e9SBarry Smith } 144386994e45SJed Brown PetscFunctionReturn(0); 144486994e45SJed Brown } 144586994e45SJed Brown 144686994e45SJed Brown #undef __FUNCT__ 144786994e45SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingRestoreIndices" 144886994e45SJed Brown /*@C 1449193a2b41SJulian Andrej ISLocalToGlobalMappingRestoreIndices - Restore indices obtained with ISLocalToGlobalMappingGetIndices() 145086994e45SJed Brown 145186994e45SJed Brown Not Collective 145286994e45SJed Brown 145386994e45SJed Brown Input Arguments: 145486994e45SJed Brown + ltog - local to global mapping 145586994e45SJed Brown - array - array of indices 145686994e45SJed Brown 145786994e45SJed Brown Level: advanced 145886994e45SJed Brown 145986994e45SJed Brown .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingGetIndices() 146086994e45SJed Brown @*/ 14617087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 146286994e45SJed Brown { 146386994e45SJed Brown PetscFunctionBegin; 146486994e45SJed Brown PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 146586994e45SJed Brown PetscValidPointer(array,2); 146645b6f7e9SBarry Smith if (ltog->bs == 1 && *array != ltog->indices) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Trying to return mismatched pointer"); 146745b6f7e9SBarry Smith 146845b6f7e9SBarry Smith if (ltog->bs > 1) { 146945b6f7e9SBarry Smith PetscErrorCode ierr; 147045b6f7e9SBarry Smith ierr = PetscFree(*(void**)array);CHKERRQ(ierr); 147145b6f7e9SBarry Smith } 147245b6f7e9SBarry Smith PetscFunctionReturn(0); 147345b6f7e9SBarry Smith } 147445b6f7e9SBarry Smith 147545b6f7e9SBarry Smith #undef __FUNCT__ 147645b6f7e9SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingGetBlockIndices" 147745b6f7e9SBarry Smith /*@C 147845b6f7e9SBarry Smith ISLocalToGlobalMappingGetBlockIndices - Get global indices for every local block 147945b6f7e9SBarry Smith 148045b6f7e9SBarry Smith Not Collective 148145b6f7e9SBarry Smith 148245b6f7e9SBarry Smith Input Arguments: 148345b6f7e9SBarry Smith . ltog - local to global mapping 148445b6f7e9SBarry Smith 148545b6f7e9SBarry Smith Output Arguments: 148645b6f7e9SBarry Smith . array - array of indices 148745b6f7e9SBarry Smith 148845b6f7e9SBarry Smith Level: advanced 148945b6f7e9SBarry Smith 149045b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingRestoreBlockIndices() 149145b6f7e9SBarry Smith @*/ 149245b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetBlockIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 149345b6f7e9SBarry Smith { 149445b6f7e9SBarry Smith PetscFunctionBegin; 149545b6f7e9SBarry Smith PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 149645b6f7e9SBarry Smith PetscValidPointer(array,2); 149745b6f7e9SBarry Smith *array = ltog->indices; 149845b6f7e9SBarry Smith PetscFunctionReturn(0); 149945b6f7e9SBarry Smith } 150045b6f7e9SBarry Smith 150145b6f7e9SBarry Smith #undef __FUNCT__ 150245b6f7e9SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingRestoreBlockIndices" 150345b6f7e9SBarry Smith /*@C 150445b6f7e9SBarry Smith ISLocalToGlobalMappingRestoreBlockIndices - Restore indices obtained with ISLocalToGlobalMappingGetBlockIndices() 150545b6f7e9SBarry Smith 150645b6f7e9SBarry Smith Not Collective 150745b6f7e9SBarry Smith 150845b6f7e9SBarry Smith Input Arguments: 150945b6f7e9SBarry Smith + ltog - local to global mapping 151045b6f7e9SBarry Smith - array - array of indices 151145b6f7e9SBarry Smith 151245b6f7e9SBarry Smith Level: advanced 151345b6f7e9SBarry Smith 151445b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingGetIndices() 151545b6f7e9SBarry Smith @*/ 151645b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreBlockIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 151745b6f7e9SBarry Smith { 151845b6f7e9SBarry Smith PetscFunctionBegin; 151945b6f7e9SBarry Smith PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 152045b6f7e9SBarry Smith PetscValidPointer(array,2); 152186994e45SJed Brown if (*array != ltog->indices) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Trying to return mismatched pointer"); 15220298fd71SBarry Smith *array = NULL; 152386994e45SJed Brown PetscFunctionReturn(0); 152486994e45SJed Brown } 1525f7efa3c7SJed Brown 1526f7efa3c7SJed Brown #undef __FUNCT__ 1527f7efa3c7SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingConcatenate" 1528f7efa3c7SJed Brown /*@C 1529f7efa3c7SJed Brown ISLocalToGlobalMappingConcatenate - Create a new mapping that concatenates a list of mappings 1530f7efa3c7SJed Brown 1531f7efa3c7SJed Brown Not Collective 1532f7efa3c7SJed Brown 1533f7efa3c7SJed Brown Input Arguments: 1534f7efa3c7SJed Brown + comm - communicator for the new mapping, must contain the communicator of every mapping to concatenate 1535f7efa3c7SJed Brown . n - number of mappings to concatenate 1536f7efa3c7SJed Brown - ltogs - local to global mappings 1537f7efa3c7SJed Brown 1538f7efa3c7SJed Brown Output Arguments: 1539f7efa3c7SJed Brown . ltogcat - new mapping 1540f7efa3c7SJed Brown 15419d90f715SBarry Smith Note: this currently always returns a mapping with block size of 1 15429d90f715SBarry Smith 15439d90f715SBarry Smith Developer Note: If all the input mapping have the same block size we could easily handle that as a special case 15449d90f715SBarry Smith 1545f7efa3c7SJed Brown Level: advanced 1546f7efa3c7SJed Brown 1547f7efa3c7SJed Brown .seealso: ISLocalToGlobalMappingCreate() 1548f7efa3c7SJed Brown @*/ 1549f7efa3c7SJed Brown PetscErrorCode ISLocalToGlobalMappingConcatenate(MPI_Comm comm,PetscInt n,const ISLocalToGlobalMapping ltogs[],ISLocalToGlobalMapping *ltogcat) 1550f7efa3c7SJed Brown { 1551f7efa3c7SJed Brown PetscInt i,cnt,m,*idx; 1552f7efa3c7SJed Brown PetscErrorCode ierr; 1553f7efa3c7SJed Brown 1554f7efa3c7SJed Brown PetscFunctionBegin; 1555f7efa3c7SJed Brown if (n < 0) SETERRQ1(comm,PETSC_ERR_ARG_OUTOFRANGE,"Must have a non-negative number of mappings, given %D",n); 1556f7efa3c7SJed Brown if (n > 0) PetscValidPointer(ltogs,3); 1557f7efa3c7SJed Brown for (i=0; i<n; i++) PetscValidHeaderSpecific(ltogs[i],IS_LTOGM_CLASSID,3); 1558f7efa3c7SJed Brown PetscValidPointer(ltogcat,4); 1559f7efa3c7SJed Brown for (cnt=0,i=0; i<n; i++) { 1560f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetSize(ltogs[i],&m);CHKERRQ(ierr); 1561f7efa3c7SJed Brown cnt += m; 1562f7efa3c7SJed Brown } 1563785e854fSJed Brown ierr = PetscMalloc1(cnt,&idx);CHKERRQ(ierr); 1564f7efa3c7SJed Brown for (cnt=0,i=0; i<n; i++) { 1565f7efa3c7SJed Brown const PetscInt *subidx; 1566f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetSize(ltogs[i],&m);CHKERRQ(ierr); 1567f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetIndices(ltogs[i],&subidx);CHKERRQ(ierr); 1568f7efa3c7SJed Brown ierr = PetscMemcpy(&idx[cnt],subidx,m*sizeof(PetscInt));CHKERRQ(ierr); 1569f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingRestoreIndices(ltogs[i],&subidx);CHKERRQ(ierr); 1570f7efa3c7SJed Brown cnt += m; 1571f7efa3c7SJed Brown } 1572f0413b6fSBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,1,cnt,idx,PETSC_OWN_POINTER,ltogcat);CHKERRQ(ierr); 1573f7efa3c7SJed Brown PetscFunctionReturn(0); 1574f7efa3c7SJed Brown } 157504a59952SBarry Smith 157604a59952SBarry Smith 1577