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__ 106658fb44Sstefano_zampini #define __FUNCT__ "ISLocalToGlobalMappingDuplicate" 116658fb44Sstefano_zampini /*@ 126658fb44Sstefano_zampini ISLocalToGlobalMappingDuplicate - Duplicates the local to global mapping object 136658fb44Sstefano_zampini 146658fb44Sstefano_zampini Not Collective 156658fb44Sstefano_zampini 166658fb44Sstefano_zampini Input Parameter: 176658fb44Sstefano_zampini . ltog - local to global mapping 186658fb44Sstefano_zampini 196658fb44Sstefano_zampini Output Parameter: 206658fb44Sstefano_zampini . nltog - the duplicated local to global mapping 216658fb44Sstefano_zampini 226658fb44Sstefano_zampini Level: advanced 236658fb44Sstefano_zampini 246658fb44Sstefano_zampini Concepts: mapping^local to global 256658fb44Sstefano_zampini 266658fb44Sstefano_zampini .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 276658fb44Sstefano_zampini @*/ 286658fb44Sstefano_zampini PetscErrorCode ISLocalToGlobalMappingDuplicate(ISLocalToGlobalMapping ltog,ISLocalToGlobalMapping* nltog) 296658fb44Sstefano_zampini { 306658fb44Sstefano_zampini PetscErrorCode ierr; 316658fb44Sstefano_zampini 326658fb44Sstefano_zampini PetscFunctionBegin; 336658fb44Sstefano_zampini PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 346658fb44Sstefano_zampini ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)ltog),ltog->bs,ltog->n,ltog->indices,PETSC_COPY_VALUES,nltog);CHKERRQ(ierr); 356658fb44Sstefano_zampini PetscFunctionReturn(0); 366658fb44Sstefano_zampini } 376658fb44Sstefano_zampini 386658fb44Sstefano_zampini #undef __FUNCT__ 394a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingGetSize" 40565245c5SBarry Smith /*@ 41107e9a97SBarry Smith ISLocalToGlobalMappingGetSize - Gets the local size of a local to global mapping 423b9aefa3SBarry Smith 433b9aefa3SBarry Smith Not Collective 443b9aefa3SBarry Smith 453b9aefa3SBarry Smith Input Parameter: 463b9aefa3SBarry Smith . ltog - local to global mapping 473b9aefa3SBarry Smith 483b9aefa3SBarry Smith Output Parameter: 49107e9a97SBarry Smith . n - the number of entries in the local mapping, ISLocalToGlobalMappingGetIndices() returns an array of this length 503b9aefa3SBarry Smith 513b9aefa3SBarry Smith Level: advanced 523b9aefa3SBarry Smith 53273d9f13SBarry Smith Concepts: mapping^local to global 543b9aefa3SBarry Smith 553b9aefa3SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 563b9aefa3SBarry Smith @*/ 577087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingGetSize(ISLocalToGlobalMapping mapping,PetscInt *n) 583b9aefa3SBarry Smith { 593b9aefa3SBarry Smith PetscFunctionBegin; 600700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 614482741eSBarry Smith PetscValidIntPointer(n,2); 62107e9a97SBarry Smith *n = mapping->bs*mapping->n; 633b9aefa3SBarry Smith PetscFunctionReturn(0); 643b9aefa3SBarry Smith } 653b9aefa3SBarry Smith 664a2ae208SSatish Balay #undef __FUNCT__ 674a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingView" 685a5d4f66SBarry Smith /*@C 695a5d4f66SBarry Smith ISLocalToGlobalMappingView - View a local to global mapping 705a5d4f66SBarry Smith 71b9cd556bSLois Curfman McInnes Not Collective 72b9cd556bSLois Curfman McInnes 735a5d4f66SBarry Smith Input Parameters: 743b9aefa3SBarry Smith + ltog - local to global mapping 753b9aefa3SBarry Smith - viewer - viewer 765a5d4f66SBarry Smith 77a997ad1aSLois Curfman McInnes Level: advanced 78a997ad1aSLois Curfman McInnes 79273d9f13SBarry Smith Concepts: mapping^local to global 805a5d4f66SBarry Smith 815a5d4f66SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 825a5d4f66SBarry Smith @*/ 837087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingView(ISLocalToGlobalMapping mapping,PetscViewer viewer) 845a5d4f66SBarry Smith { 8532dcc486SBarry Smith PetscInt i; 8632dcc486SBarry Smith PetscMPIInt rank; 87ace3abfcSBarry Smith PetscBool iascii; 886849ba73SBarry Smith PetscErrorCode ierr; 895a5d4f66SBarry Smith 905a5d4f66SBarry Smith PetscFunctionBegin; 910700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 923050cee2SBarry Smith if (!viewer) { 93ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mapping),&viewer);CHKERRQ(ierr); 943050cee2SBarry Smith } 950700a824SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 965a5d4f66SBarry Smith 97ce94432eSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mapping),&rank);CHKERRQ(ierr); 98251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 9932077d6dSBarry Smith if (iascii) { 10098c3331eSBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mapping,viewer);CHKERRQ(ierr); 1011575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 1025a5d4f66SBarry Smith for (i=0; i<mapping->n; i++) { 1037904a332SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d] %D %D\n",rank,i,mapping->indices[i]);CHKERRQ(ierr); 1046831982aSBarry Smith } 105b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1061575c14dSBarry Smith ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 1071575c14dSBarry Smith } 1085a5d4f66SBarry Smith PetscFunctionReturn(0); 1095a5d4f66SBarry Smith } 1105a5d4f66SBarry Smith 1114a2ae208SSatish Balay #undef __FUNCT__ 1124a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreateIS" 1131f428162SBarry Smith /*@ 1142bdab257SBarry Smith ISLocalToGlobalMappingCreateIS - Creates a mapping between a local (0 to n) 1152bdab257SBarry Smith ordering and a global parallel ordering. 1162bdab257SBarry Smith 1170f5bd95cSBarry Smith Not collective 118b9cd556bSLois Curfman McInnes 119a997ad1aSLois Curfman McInnes Input Parameter: 1208c03b21aSDmitry Karpeev . is - index set containing the global numbers for each local number 1212bdab257SBarry Smith 122a997ad1aSLois Curfman McInnes Output Parameter: 1232bdab257SBarry Smith . mapping - new mapping data structure 1242bdab257SBarry Smith 125f0413b6fSBarry Smith Notes: the block size of the IS determines the block size of the mapping 126a997ad1aSLois Curfman McInnes Level: advanced 127a997ad1aSLois Curfman McInnes 128273d9f13SBarry Smith Concepts: mapping^local to global 1292bdab257SBarry Smith 1302bdab257SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate() 1312bdab257SBarry Smith @*/ 1327087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingCreateIS(IS is,ISLocalToGlobalMapping *mapping) 1332bdab257SBarry Smith { 1346849ba73SBarry Smith PetscErrorCode ierr; 1353bbf0e92SBarry Smith PetscInt n,bs; 1365d0c19d7SBarry Smith const PetscInt *indices; 1372bdab257SBarry Smith MPI_Comm comm; 1383bbf0e92SBarry Smith PetscBool isblock; 1393a40ed3dSBarry Smith 1403a40ed3dSBarry Smith PetscFunctionBegin; 1410700a824SBarry Smith PetscValidHeaderSpecific(is,IS_CLASSID,1); 1424482741eSBarry Smith PetscValidPointer(mapping,2); 1432bdab257SBarry Smith 1442bdab257SBarry Smith ierr = PetscObjectGetComm((PetscObject)is,&comm);CHKERRQ(ierr); 1453b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 1463bbf0e92SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)is,ISBLOCK,&isblock);CHKERRQ(ierr); 1476006e8d2SBarry Smith if (!isblock) { 148f0413b6fSBarry Smith ierr = ISGetIndices(is,&indices);CHKERRQ(ierr); 149f0413b6fSBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,1,n,indices,PETSC_COPY_VALUES,mapping);CHKERRQ(ierr); 1502bdab257SBarry Smith ierr = ISRestoreIndices(is,&indices);CHKERRQ(ierr); 1516006e8d2SBarry Smith } else { 1526006e8d2SBarry Smith ierr = ISGetBlockSize(is,&bs);CHKERRQ(ierr); 153f0413b6fSBarry Smith ierr = ISBlockGetIndices(is,&indices);CHKERRQ(ierr); 15428bc9809SBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,bs,n/bs,indices,PETSC_COPY_VALUES,mapping);CHKERRQ(ierr); 155f0413b6fSBarry Smith ierr = ISBlockRestoreIndices(is,&indices);CHKERRQ(ierr); 1566006e8d2SBarry Smith } 1573a40ed3dSBarry Smith PetscFunctionReturn(0); 1582bdab257SBarry Smith } 1595a5d4f66SBarry Smith 160a4d96a55SJed Brown #undef __FUNCT__ 161a4d96a55SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingCreateSF" 162a4d96a55SJed Brown /*@C 163a4d96a55SJed Brown ISLocalToGlobalMappingCreateSF - Creates a mapping between a local (0 to n) 164a4d96a55SJed Brown ordering and a global parallel ordering. 165a4d96a55SJed Brown 166a4d96a55SJed Brown Collective 167a4d96a55SJed Brown 168a4d96a55SJed Brown Input Parameter: 169a4d96a55SJed Brown + sf - star forest mapping contiguous local indices to (rank, offset) 170a4d96a55SJed Brown - start - first global index on this process 171a4d96a55SJed Brown 172a4d96a55SJed Brown Output Parameter: 173a4d96a55SJed Brown . mapping - new mapping data structure 174a4d96a55SJed Brown 175a4d96a55SJed Brown Level: advanced 176a4d96a55SJed Brown 177a4d96a55SJed Brown Concepts: mapping^local to global 178a4d96a55SJed Brown 179a4d96a55SJed Brown .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingCreateIS() 180a4d96a55SJed Brown @*/ 181a4d96a55SJed Brown PetscErrorCode ISLocalToGlobalMappingCreateSF(PetscSF sf,PetscInt start,ISLocalToGlobalMapping *mapping) 182a4d96a55SJed Brown { 183a4d96a55SJed Brown PetscErrorCode ierr; 184a4d96a55SJed Brown PetscInt i,maxlocal,nroots,nleaves,*globals,*ltog; 185a4d96a55SJed Brown const PetscInt *ilocal; 186a4d96a55SJed Brown MPI_Comm comm; 187a4d96a55SJed Brown 188a4d96a55SJed Brown PetscFunctionBegin; 189a4d96a55SJed Brown PetscValidHeaderSpecific(sf,PETSCSF_CLASSID,1); 190a4d96a55SJed Brown PetscValidPointer(mapping,3); 191a4d96a55SJed Brown 192a4d96a55SJed Brown ierr = PetscObjectGetComm((PetscObject)sf,&comm);CHKERRQ(ierr); 1930298fd71SBarry Smith ierr = PetscSFGetGraph(sf,&nroots,&nleaves,&ilocal,NULL);CHKERRQ(ierr); 194f6e5521dSKarl Rupp if (ilocal) { 195f6e5521dSKarl Rupp for (i=0,maxlocal=0; i<nleaves; i++) maxlocal = PetscMax(maxlocal,ilocal[i]+1); 196f6e5521dSKarl Rupp } 197a4d96a55SJed Brown else maxlocal = nleaves; 198785e854fSJed Brown ierr = PetscMalloc1(nroots,&globals);CHKERRQ(ierr); 199785e854fSJed Brown ierr = PetscMalloc1(maxlocal,<og);CHKERRQ(ierr); 200a4d96a55SJed Brown for (i=0; i<nroots; i++) globals[i] = start + i; 201a4d96a55SJed Brown for (i=0; i<maxlocal; i++) ltog[i] = -1; 202a4d96a55SJed Brown ierr = PetscSFBcastBegin(sf,MPIU_INT,globals,ltog);CHKERRQ(ierr); 203a4d96a55SJed Brown ierr = PetscSFBcastEnd(sf,MPIU_INT,globals,ltog);CHKERRQ(ierr); 204f0413b6fSBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,1,maxlocal,ltog,PETSC_OWN_POINTER,mapping);CHKERRQ(ierr); 205a4d96a55SJed Brown ierr = PetscFree(globals);CHKERRQ(ierr); 206a4d96a55SJed Brown PetscFunctionReturn(0); 207a4d96a55SJed Brown } 208b46b645bSBarry Smith 2094a2ae208SSatish Balay #undef __FUNCT__ 21063fa5c83Sstefano_zampini #define __FUNCT__ "ISLocalToGlobalMappingSetBlockSize" 21163fa5c83Sstefano_zampini /*@ 21263fa5c83Sstefano_zampini ISLocalToGlobalMappingSetBlockSize - Sets the blocksize of the mapping 21363fa5c83Sstefano_zampini 21463fa5c83Sstefano_zampini Not collective 21563fa5c83Sstefano_zampini 21663fa5c83Sstefano_zampini Input Parameters: 21763fa5c83Sstefano_zampini . mapping - mapping data structure 21863fa5c83Sstefano_zampini . bs - the blocksize 21963fa5c83Sstefano_zampini 22063fa5c83Sstefano_zampini Level: advanced 22163fa5c83Sstefano_zampini 22263fa5c83Sstefano_zampini Concepts: mapping^local to global 22363fa5c83Sstefano_zampini 22463fa5c83Sstefano_zampini .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS() 22563fa5c83Sstefano_zampini @*/ 22663fa5c83Sstefano_zampini PetscErrorCode ISLocalToGlobalMappingSetBlockSize(ISLocalToGlobalMapping mapping,PetscInt bs) 22763fa5c83Sstefano_zampini { 228*a59f3c4dSstefano_zampini PetscInt *nid; 229*a59f3c4dSstefano_zampini const PetscInt *oid; 230*a59f3c4dSstefano_zampini PetscInt i,cn,on,obs,nn; 23163fa5c83Sstefano_zampini PetscErrorCode ierr; 23263fa5c83Sstefano_zampini 23363fa5c83Sstefano_zampini PetscFunctionBegin; 23463fa5c83Sstefano_zampini PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 23563fa5c83Sstefano_zampini if (bs < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid block size %D",bs); 23663fa5c83Sstefano_zampini if (bs == mapping->bs) PetscFunctionReturn(0); 23763fa5c83Sstefano_zampini on = mapping->n; 23863fa5c83Sstefano_zampini obs = mapping->bs; 23963fa5c83Sstefano_zampini oid = mapping->indices; 24063fa5c83Sstefano_zampini nn = (on*obs)/bs; 24163fa5c83Sstefano_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); 242*a59f3c4dSstefano_zampini 24363fa5c83Sstefano_zampini ierr = PetscMalloc1(nn,&nid);CHKERRQ(ierr); 244*a59f3c4dSstefano_zampini ierr = ISLocalToGlobalMappingGetIndices(mapping,&oid);CHKERRQ(ierr); 245*a59f3c4dSstefano_zampini for (i=0;i<nn;i++) { 246*a59f3c4dSstefano_zampini PetscInt j; 247*a59f3c4dSstefano_zampini for (j=0,cn=0;j<bs-1;j++) { 248*a59f3c4dSstefano_zampini if (oid[i*bs+j] < 0) { cn++; continue; } 249*a59f3c4dSstefano_zampini if (oid[i*bs+j] != oid[i*bs+j+1]-1) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Block sizes %D and %D are incompatible with the block indices: non consecutive indices %D %D",bs,obs,oid[i*bs+j],oid[i*bs+j+1]); 250*a59f3c4dSstefano_zampini } 251*a59f3c4dSstefano_zampini if (oid[i*bs+j] < 0) cn++; 2528b7cb0e6Sstefano_zampini if (cn) { 253*a59f3c4dSstefano_zampini if (cn != bs) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Block sizes %D and %D are incompatible with the block indices: invalid number of negative entries in block %D",bs,obs,cn); 254*a59f3c4dSstefano_zampini nid[i] = -1; 2558b7cb0e6Sstefano_zampini } else { 256*a59f3c4dSstefano_zampini nid[i] = oid[i*bs]/bs; 25763fa5c83Sstefano_zampini } 25863fa5c83Sstefano_zampini } 259*a59f3c4dSstefano_zampini ierr = ISLocalToGlobalMappingRestoreIndices(mapping,&oid);CHKERRQ(ierr); 260*a59f3c4dSstefano_zampini 26163fa5c83Sstefano_zampini mapping->n = nn; 26263fa5c83Sstefano_zampini mapping->bs = bs; 26363fa5c83Sstefano_zampini ierr = PetscFree(mapping->indices);CHKERRQ(ierr); 26463fa5c83Sstefano_zampini mapping->indices = nid; 265c9345713Sstefano_zampini ierr = PetscFree(mapping->globals);CHKERRQ(ierr); 266c9345713Sstefano_zampini mapping->globalstart = 0; 267c9345713Sstefano_zampini mapping->globalend = 0; 26863fa5c83Sstefano_zampini PetscFunctionReturn(0); 26963fa5c83Sstefano_zampini } 27063fa5c83Sstefano_zampini 27163fa5c83Sstefano_zampini #undef __FUNCT__ 27245b6f7e9SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingGetBlockSize" 27345b6f7e9SBarry Smith /*@ 27445b6f7e9SBarry Smith ISLocalToGlobalMappingGetBlockSize - Gets the blocksize of the mapping 27545b6f7e9SBarry Smith ordering and a global parallel ordering. 27645b6f7e9SBarry Smith 27745b6f7e9SBarry Smith Not Collective 27845b6f7e9SBarry Smith 27945b6f7e9SBarry Smith Input Parameters: 28045b6f7e9SBarry Smith . mapping - mapping data structure 28145b6f7e9SBarry Smith 28245b6f7e9SBarry Smith Output Parameter: 28345b6f7e9SBarry Smith . bs - the blocksize 28445b6f7e9SBarry Smith 28545b6f7e9SBarry Smith Level: advanced 28645b6f7e9SBarry Smith 28745b6f7e9SBarry Smith Concepts: mapping^local to global 28845b6f7e9SBarry Smith 28945b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS() 29045b6f7e9SBarry Smith @*/ 29145b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetBlockSize(ISLocalToGlobalMapping mapping,PetscInt *bs) 29245b6f7e9SBarry Smith { 29345b6f7e9SBarry Smith PetscFunctionBegin; 294cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 29545b6f7e9SBarry Smith *bs = mapping->bs; 29645b6f7e9SBarry Smith PetscFunctionReturn(0); 29745b6f7e9SBarry Smith } 29845b6f7e9SBarry Smith 29945b6f7e9SBarry Smith #undef __FUNCT__ 3004a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingCreate" 301ba5bb76aSSatish Balay /*@ 30290f02eecSBarry Smith ISLocalToGlobalMappingCreate - Creates a mapping between a local (0 to n) 30390f02eecSBarry Smith ordering and a global parallel ordering. 3042362add9SBarry Smith 30589d82c54SBarry Smith Not Collective, but communicator may have more than one process 306b9cd556bSLois Curfman McInnes 3072362add9SBarry Smith Input Parameters: 30889d82c54SBarry Smith + comm - MPI communicator 309f0413b6fSBarry Smith . bs - the block size 31028bc9809SBarry Smith . n - the number of local elements divided by the block size, or equivalently the number of block indices 31128bc9809SBarry 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 312d5ad8652SBarry Smith - mode - see PetscCopyMode 3132362add9SBarry Smith 314a997ad1aSLois Curfman McInnes Output Parameter: 31590f02eecSBarry Smith . mapping - new mapping data structure 3162362add9SBarry Smith 317f0413b6fSBarry 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 318a997ad1aSLois Curfman McInnes Level: advanced 319a997ad1aSLois Curfman McInnes 320273d9f13SBarry Smith Concepts: mapping^local to global 3212362add9SBarry Smith 322d5ad8652SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS() 3232362add9SBarry Smith @*/ 32460c7cefcSBarry Smith PetscErrorCode ISLocalToGlobalMappingCreate(MPI_Comm comm,PetscInt bs,PetscInt n,const PetscInt indices[],PetscCopyMode mode,ISLocalToGlobalMapping *mapping) 3252362add9SBarry Smith { 3266849ba73SBarry Smith PetscErrorCode ierr; 32732dcc486SBarry Smith PetscInt *in; 328b46b645bSBarry Smith 329b46b645bSBarry Smith PetscFunctionBegin; 33073911063SBarry Smith if (n) PetscValidIntPointer(indices,3); 3314482741eSBarry Smith PetscValidPointer(mapping,4); 332b46b645bSBarry Smith 3330298fd71SBarry Smith *mapping = NULL; 334607a6623SBarry Smith ierr = ISInitializePackage();CHKERRQ(ierr); 3352362add9SBarry Smith 33673107ff1SLisandro Dalcin ierr = PetscHeaderCreate(*mapping,IS_LTOGM_CLASSID,"ISLocalToGlobalMapping","Local to global mapping","IS", 33760c7cefcSBarry Smith comm,ISLocalToGlobalMappingDestroy,ISLocalToGlobalMappingView);CHKERRQ(ierr); 338d4bb536fSBarry Smith (*mapping)->n = n; 339f0413b6fSBarry Smith (*mapping)->bs = bs; 340268a049cSStefano Zampini (*mapping)->info_cached = PETSC_FALSE; 341268a049cSStefano Zampini (*mapping)->info_free = PETSC_FALSE; 342268a049cSStefano Zampini (*mapping)->info_procs = NULL; 343268a049cSStefano Zampini (*mapping)->info_numprocs = NULL; 344268a049cSStefano Zampini (*mapping)->info_indices = NULL; 345d4bb536fSBarry Smith /* 346d4bb536fSBarry Smith Do not create the global to local mapping. This is only created if 347d4bb536fSBarry Smith ISGlobalToLocalMapping() is called 348d4bb536fSBarry Smith */ 349d4bb536fSBarry Smith (*mapping)->globals = 0; 350d5ad8652SBarry Smith if (mode == PETSC_COPY_VALUES) { 351785e854fSJed Brown ierr = PetscMalloc1(n,&in);CHKERRQ(ierr); 352d5ad8652SBarry Smith ierr = PetscMemcpy(in,indices,n*sizeof(PetscInt));CHKERRQ(ierr); 353d5ad8652SBarry Smith (*mapping)->indices = in; 3546389a1a1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)*mapping,n*sizeof(PetscInt));CHKERRQ(ierr); 3556389a1a1SBarry Smith } else if (mode == PETSC_OWN_POINTER) { 3566389a1a1SBarry Smith (*mapping)->indices = (PetscInt*)indices; 3576389a1a1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)*mapping,n*sizeof(PetscInt));CHKERRQ(ierr); 3586389a1a1SBarry Smith } 35960c7cefcSBarry Smith else SETERRQ(comm,PETSC_ERR_SUP,"Cannot currently use PETSC_USE_POINTER"); 360d96308ebSBarry Smith ierr = PetscStrallocpy("basic",&((PetscObject)*mapping)->type_name);CHKERRQ(ierr); 3613a40ed3dSBarry Smith PetscFunctionReturn(0); 3622362add9SBarry Smith } 3632362add9SBarry Smith 3644a2ae208SSatish Balay #undef __FUNCT__ 3654a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingDestroy" 36690f02eecSBarry Smith /*@ 36790f02eecSBarry Smith ISLocalToGlobalMappingDestroy - Destroys a mapping between a local (0 to n) 36890f02eecSBarry Smith ordering and a global parallel ordering. 36990f02eecSBarry Smith 3700f5bd95cSBarry Smith Note Collective 371b9cd556bSLois Curfman McInnes 37290f02eecSBarry Smith Input Parameters: 37390f02eecSBarry Smith . mapping - mapping data structure 37490f02eecSBarry Smith 375a997ad1aSLois Curfman McInnes Level: advanced 376a997ad1aSLois Curfman McInnes 3773acfe500SLois Curfman McInnes .seealso: ISLocalToGlobalMappingCreate() 37890f02eecSBarry Smith @*/ 3796bf464f9SBarry Smith PetscErrorCode ISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping *mapping) 38090f02eecSBarry Smith { 381dfbe8321SBarry Smith PetscErrorCode ierr; 3825fd66863SKarl Rupp 3833a40ed3dSBarry Smith PetscFunctionBegin; 3846bf464f9SBarry Smith if (!*mapping) PetscFunctionReturn(0); 3856bf464f9SBarry Smith PetscValidHeaderSpecific((*mapping),IS_LTOGM_CLASSID,1); 386997056adSBarry Smith if (--((PetscObject)(*mapping))->refct > 0) {*mapping = 0;PetscFunctionReturn(0);} 3876bf464f9SBarry Smith ierr = PetscFree((*mapping)->indices);CHKERRQ(ierr); 3886bf464f9SBarry Smith ierr = PetscFree((*mapping)->globals);CHKERRQ(ierr); 389268a049cSStefano Zampini ierr = PetscFree((*mapping)->info_procs);CHKERRQ(ierr); 390268a049cSStefano Zampini ierr = PetscFree((*mapping)->info_numprocs);CHKERRQ(ierr); 391268a049cSStefano Zampini if ((*mapping)->info_indices) { 392268a049cSStefano Zampini PetscInt i; 393268a049cSStefano Zampini 394268a049cSStefano Zampini ierr = PetscFree(((*mapping)->info_indices)[0]);CHKERRQ(ierr); 395268a049cSStefano Zampini for (i=1; i<(*mapping)->info_nproc; i++) { 396268a049cSStefano Zampini ierr = PetscFree(((*mapping)->info_indices)[i]);CHKERRQ(ierr); 397268a049cSStefano Zampini } 398268a049cSStefano Zampini ierr = PetscFree((*mapping)->info_indices);CHKERRQ(ierr); 399268a049cSStefano Zampini } 400d38fa0fbSBarry Smith ierr = PetscHeaderDestroy(mapping);CHKERRQ(ierr); 401992144d0SBarry Smith *mapping = 0; 4023a40ed3dSBarry Smith PetscFunctionReturn(0); 40390f02eecSBarry Smith } 40490f02eecSBarry Smith 4054a2ae208SSatish Balay #undef __FUNCT__ 4064a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingApplyIS" 40790f02eecSBarry Smith /*@ 4083acfe500SLois Curfman McInnes ISLocalToGlobalMappingApplyIS - Creates from an IS in the local numbering 4093acfe500SLois Curfman McInnes a new index set using the global numbering defined in an ISLocalToGlobalMapping 4103acfe500SLois Curfman McInnes context. 41190f02eecSBarry Smith 412b9cd556bSLois Curfman McInnes Not collective 413b9cd556bSLois Curfman McInnes 41490f02eecSBarry Smith Input Parameters: 415b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 416b9cd556bSLois Curfman McInnes - is - index set in local numbering 41790f02eecSBarry Smith 41890f02eecSBarry Smith Output Parameters: 41990f02eecSBarry Smith . newis - index set in global numbering 42090f02eecSBarry Smith 421a997ad1aSLois Curfman McInnes Level: advanced 422a997ad1aSLois Curfman McInnes 423273d9f13SBarry Smith Concepts: mapping^local to global 4243acfe500SLois Curfman McInnes 42590f02eecSBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), 426d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy(), ISGlobalToLocalMappingApply() 42790f02eecSBarry Smith @*/ 4287087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping mapping,IS is,IS *newis) 42990f02eecSBarry Smith { 4306849ba73SBarry Smith PetscErrorCode ierr; 431e24637baSBarry Smith PetscInt n,*idxout; 4325d0c19d7SBarry Smith const PetscInt *idxin; 4333a40ed3dSBarry Smith 4343a40ed3dSBarry Smith PetscFunctionBegin; 4350700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 4360700a824SBarry Smith PetscValidHeaderSpecific(is,IS_CLASSID,2); 4374482741eSBarry Smith PetscValidPointer(newis,3); 43890f02eecSBarry Smith 4393b9aefa3SBarry Smith ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 44090f02eecSBarry Smith ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 441785e854fSJed Brown ierr = PetscMalloc1(n,&idxout);CHKERRQ(ierr); 442e24637baSBarry Smith ierr = ISLocalToGlobalMappingApply(mapping,n,idxin,idxout);CHKERRQ(ierr); 4433b9aefa3SBarry Smith ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 444543f3098SMatthew G. Knepley ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is),n,idxout,PETSC_OWN_POINTER,newis);CHKERRQ(ierr); 4453a40ed3dSBarry Smith PetscFunctionReturn(0); 44690f02eecSBarry Smith } 44790f02eecSBarry Smith 448afcb2eb5SJed Brown #undef __FUNCT__ 449afcb2eb5SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingApply" 450b89cb25eSSatish Balay /*@ 4513acfe500SLois Curfman McInnes ISLocalToGlobalMappingApply - Takes a list of integers in a local numbering 4523acfe500SLois Curfman McInnes and converts them to the global numbering. 45390f02eecSBarry Smith 454b9cd556bSLois Curfman McInnes Not collective 455b9cd556bSLois Curfman McInnes 456bb25748dSBarry Smith Input Parameters: 457b9cd556bSLois Curfman McInnes + mapping - the local to global mapping context 458bb25748dSBarry Smith . N - number of integers 459b9cd556bSLois Curfman McInnes - in - input indices in local numbering 460bb25748dSBarry Smith 461bb25748dSBarry Smith Output Parameter: 462bb25748dSBarry Smith . out - indices in global numbering 463bb25748dSBarry Smith 464b9cd556bSLois Curfman McInnes Notes: 465b9cd556bSLois Curfman McInnes The in and out array parameters may be identical. 466d4bb536fSBarry Smith 467a997ad1aSLois Curfman McInnes Level: advanced 468a997ad1aSLois Curfman McInnes 46945b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingApplyBlock(), ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 4700752156aSBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 471d4bb536fSBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 472bb25748dSBarry Smith 473273d9f13SBarry Smith Concepts: mapping^local to global 474afcb2eb5SJed Brown @*/ 475afcb2eb5SJed Brown PetscErrorCode ISLocalToGlobalMappingApply(ISLocalToGlobalMapping mapping,PetscInt N,const PetscInt in[],PetscInt out[]) 476afcb2eb5SJed Brown { 477cbc1caf0SMatthew G. Knepley PetscInt i,bs,Nmax; 47845b6f7e9SBarry Smith 47945b6f7e9SBarry Smith PetscFunctionBegin; 480cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 481cbc1caf0SMatthew G. Knepley bs = mapping->bs; 482cbc1caf0SMatthew G. Knepley Nmax = bs*mapping->n; 48345b6f7e9SBarry Smith if (bs == 1) { 484cbc1caf0SMatthew G. Knepley const PetscInt *idx = mapping->indices; 48545b6f7e9SBarry Smith for (i=0; i<N; i++) { 48645b6f7e9SBarry Smith if (in[i] < 0) { 48745b6f7e9SBarry Smith out[i] = in[i]; 48845b6f7e9SBarry Smith continue; 48945b6f7e9SBarry Smith } 490e24637baSBarry 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); 49145b6f7e9SBarry Smith out[i] = idx[in[i]]; 49245b6f7e9SBarry Smith } 49345b6f7e9SBarry Smith } else { 494cbc1caf0SMatthew G. Knepley const PetscInt *idx = mapping->indices; 49545b6f7e9SBarry Smith for (i=0; i<N; i++) { 49645b6f7e9SBarry Smith if (in[i] < 0) { 49745b6f7e9SBarry Smith out[i] = in[i]; 49845b6f7e9SBarry Smith continue; 49945b6f7e9SBarry Smith } 500e24637baSBarry 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); 50145b6f7e9SBarry Smith out[i] = idx[in[i]/bs]*bs + (in[i] % bs); 50245b6f7e9SBarry Smith } 50345b6f7e9SBarry Smith } 50445b6f7e9SBarry Smith PetscFunctionReturn(0); 50545b6f7e9SBarry Smith } 50645b6f7e9SBarry Smith 50745b6f7e9SBarry Smith #undef __FUNCT__ 50845b6f7e9SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingApplyBlock" 50945b6f7e9SBarry Smith /*@ 5106006e8d2SBarry Smith ISLocalToGlobalMappingApplyBlock - Takes a list of integers in a local block numbering and converts them to the global block numbering 51145b6f7e9SBarry Smith 51245b6f7e9SBarry Smith Not collective 51345b6f7e9SBarry Smith 51445b6f7e9SBarry Smith Input Parameters: 51545b6f7e9SBarry Smith + mapping - the local to global mapping context 51645b6f7e9SBarry Smith . N - number of integers 5176006e8d2SBarry Smith - in - input indices in local block numbering 51845b6f7e9SBarry Smith 51945b6f7e9SBarry Smith Output Parameter: 5206006e8d2SBarry Smith . out - indices in global block numbering 52145b6f7e9SBarry Smith 52245b6f7e9SBarry Smith Notes: 52345b6f7e9SBarry Smith The in and out array parameters may be identical. 52445b6f7e9SBarry Smith 5256006e8d2SBarry Smith Example: 5266006e8d2SBarry 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 5276006e8d2SBarry Smith (the first block) would produce 0 and the mapping applied to 1 (the second block) would produce 3. 5286006e8d2SBarry Smith 52945b6f7e9SBarry Smith Level: advanced 53045b6f7e9SBarry Smith 53145b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(), 53245b6f7e9SBarry Smith ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(), 53345b6f7e9SBarry Smith AOPetscToApplication(), ISGlobalToLocalMappingApply() 53445b6f7e9SBarry Smith 53545b6f7e9SBarry Smith Concepts: mapping^local to global 53645b6f7e9SBarry Smith @*/ 53745b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingApplyBlock(ISLocalToGlobalMapping mapping,PetscInt N,const PetscInt in[],PetscInt out[]) 53845b6f7e9SBarry Smith { 539cbc1caf0SMatthew G. Knepley 540cbc1caf0SMatthew G. Knepley PetscFunctionBegin; 541cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 542cbc1caf0SMatthew G. Knepley { 543afcb2eb5SJed Brown PetscInt i,Nmax = mapping->n; 544afcb2eb5SJed Brown const PetscInt *idx = mapping->indices; 545d4bb536fSBarry Smith 546afcb2eb5SJed Brown for (i=0; i<N; i++) { 547afcb2eb5SJed Brown if (in[i] < 0) { 548afcb2eb5SJed Brown out[i] = in[i]; 549afcb2eb5SJed Brown continue; 550afcb2eb5SJed Brown } 551e24637baSBarry 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); 552afcb2eb5SJed Brown out[i] = idx[in[i]]; 553afcb2eb5SJed Brown } 554cbc1caf0SMatthew G. Knepley } 555afcb2eb5SJed Brown PetscFunctionReturn(0); 556afcb2eb5SJed Brown } 557d4bb536fSBarry Smith 558d4bb536fSBarry Smith /* -----------------------------------------------------------------------------------------*/ 559d4bb536fSBarry Smith 5604a2ae208SSatish Balay #undef __FUNCT__ 5614a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingSetUp_Private" 562d4bb536fSBarry Smith /* 563d4bb536fSBarry Smith Creates the global fields in the ISLocalToGlobalMapping structure 564d4bb536fSBarry Smith */ 5656849ba73SBarry Smith static PetscErrorCode ISGlobalToLocalMappingSetUp_Private(ISLocalToGlobalMapping mapping) 566d4bb536fSBarry Smith { 5676849ba73SBarry Smith PetscErrorCode ierr; 56832dcc486SBarry Smith PetscInt i,*idx = mapping->indices,n = mapping->n,end,start,*globals; 569d4bb536fSBarry Smith 5703a40ed3dSBarry Smith PetscFunctionBegin; 571d4bb536fSBarry Smith end = 0; 572ec268f7cSJed Brown start = PETSC_MAX_INT; 573d4bb536fSBarry Smith 574d4bb536fSBarry Smith for (i=0; i<n; i++) { 575d4bb536fSBarry Smith if (idx[i] < 0) continue; 576d4bb536fSBarry Smith if (idx[i] < start) start = idx[i]; 577d4bb536fSBarry Smith if (idx[i] > end) end = idx[i]; 578d4bb536fSBarry Smith } 579d4bb536fSBarry Smith if (start > end) {start = 0; end = -1;} 580d4bb536fSBarry Smith mapping->globalstart = start; 581d4bb536fSBarry Smith mapping->globalend = end; 582d4bb536fSBarry Smith 583854ce69bSBarry Smith ierr = PetscMalloc1(end-start+2,&globals);CHKERRQ(ierr); 584b0a32e0cSBarry Smith mapping->globals = globals; 585f6e5521dSKarl Rupp for (i=0; i<end-start+1; i++) globals[i] = -1; 586d4bb536fSBarry Smith for (i=0; i<n; i++) { 587d4bb536fSBarry Smith if (idx[i] < 0) continue; 588d4bb536fSBarry Smith globals[idx[i] - start] = i; 589d4bb536fSBarry Smith } 590d4bb536fSBarry Smith 5913bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mapping,(end-start+1)*sizeof(PetscInt));CHKERRQ(ierr); 5923a40ed3dSBarry Smith PetscFunctionReturn(0); 593d4bb536fSBarry Smith } 594d4bb536fSBarry Smith 5954a2ae208SSatish Balay #undef __FUNCT__ 5964a2ae208SSatish Balay #define __FUNCT__ "ISGlobalToLocalMappingApply" 597d4bb536fSBarry Smith /*@ 598a997ad1aSLois Curfman McInnes ISGlobalToLocalMappingApply - Provides the local numbering for a list of integers 599a997ad1aSLois Curfman McInnes specified with a global numbering. 600d4bb536fSBarry Smith 601b9cd556bSLois Curfman McInnes Not collective 602b9cd556bSLois Curfman McInnes 603d4bb536fSBarry Smith Input Parameters: 604b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering 605d4bb536fSBarry Smith . type - IS_GTOLM_MASK - replaces global indices with no local value with -1 606d4bb536fSBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 607d4bb536fSBarry Smith . n - number of global indices to map 608b9cd556bSLois Curfman McInnes - idx - global indices to map 609d4bb536fSBarry Smith 610d4bb536fSBarry Smith Output Parameters: 611b9cd556bSLois Curfman McInnes + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 612b9cd556bSLois Curfman McInnes - idxout - local index of each global index, one must pass in an array long enough 613e182c471SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApply() with 6140298fd71SBarry Smith idxout == NULL to determine the required length (returned in nout) 615e182c471SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApply() 616e182c471SBarry Smith a second time to set the values. 617d4bb536fSBarry Smith 618b9cd556bSLois Curfman McInnes Notes: 6190298fd71SBarry Smith Either nout or idxout may be NULL. idx and idxout may be identical. 620d4bb536fSBarry Smith 6210f5bd95cSBarry Smith This is not scalable in memory usage. Each processor requires O(Nglobal) size 6220f5bd95cSBarry Smith array to compute these. 6230f5bd95cSBarry Smith 624a997ad1aSLois Curfman McInnes Level: advanced 625a997ad1aSLois Curfman McInnes 62632fd6b96SBarry Smith Developer Note: The manual page states that idx and idxout may be identical but the calling 62732fd6b96SBarry Smith sequence declares idx as const so it cannot be the same as idxout. 62832fd6b96SBarry Smith 629273d9f13SBarry Smith Concepts: mapping^global to local 630d4bb536fSBarry Smith 6319d90f715SBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISGlobalToLocalMappingApplyBlock(), ISLocalToGlobalMappingCreate(), 632d4bb536fSBarry Smith ISLocalToGlobalMappingDestroy() 633d4bb536fSBarry Smith @*/ 6347087cfbeSBarry Smith PetscErrorCode ISGlobalToLocalMappingApply(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, 63532dcc486SBarry Smith PetscInt n,const PetscInt idx[],PetscInt *nout,PetscInt idxout[]) 636d4bb536fSBarry Smith { 6379d90f715SBarry Smith PetscInt i,*globals,nf = 0,tmp,start,end,bs; 6389d90f715SBarry Smith PetscErrorCode ierr; 6399d90f715SBarry Smith 6409d90f715SBarry Smith PetscFunctionBegin; 6419d90f715SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 6429d90f715SBarry Smith if (!mapping->globals) { 6439d90f715SBarry Smith ierr = ISGlobalToLocalMappingSetUp_Private(mapping);CHKERRQ(ierr); 6449d90f715SBarry Smith } 6459d90f715SBarry Smith globals = mapping->globals; 6469d90f715SBarry Smith start = mapping->globalstart; 6479d90f715SBarry Smith end = mapping->globalend; 6489d90f715SBarry Smith bs = mapping->bs; 6499d90f715SBarry Smith 6509d90f715SBarry Smith if (type == IS_GTOLM_MASK) { 6519d90f715SBarry Smith if (idxout) { 6529d90f715SBarry Smith for (i=0; i<n; i++) { 6539d90f715SBarry Smith if (idx[i] < 0) idxout[i] = idx[i]; 6549d90f715SBarry Smith else if (idx[i] < bs*start) idxout[i] = -1; 655663bb84eSBarry Smith else if (idx[i] > bs*(end+1)-1) idxout[i] = -1; 6569d90f715SBarry Smith else idxout[i] = bs*globals[idx[i]/bs - start] + (idx[i] % bs); 6579d90f715SBarry Smith } 6589d90f715SBarry Smith } 6599d90f715SBarry Smith if (nout) *nout = n; 6609d90f715SBarry Smith } else { 6619d90f715SBarry Smith if (idxout) { 6629d90f715SBarry Smith for (i=0; i<n; i++) { 6639d90f715SBarry Smith if (idx[i] < 0) continue; 6649d90f715SBarry Smith if (idx[i] < bs*start) continue; 665663bb84eSBarry Smith if (idx[i] > bs*(end+1)-1) continue; 6669d90f715SBarry Smith tmp = bs*globals[idx[i]/bs - start] + (idx[i] % bs); 6679d90f715SBarry Smith if (tmp < 0) continue; 6689d90f715SBarry Smith idxout[nf++] = tmp; 6699d90f715SBarry Smith } 6709d90f715SBarry Smith } else { 6719d90f715SBarry Smith for (i=0; i<n; i++) { 6729d90f715SBarry Smith if (idx[i] < 0) continue; 6739d90f715SBarry Smith if (idx[i] < bs*start) continue; 674663bb84eSBarry Smith if (idx[i] > bs*(end+1)-1) continue; 6759d90f715SBarry Smith tmp = bs*globals[idx[i]/bs - start] + (idx[i] % bs); 6769d90f715SBarry Smith if (tmp < 0) continue; 6779d90f715SBarry Smith nf++; 6789d90f715SBarry Smith } 6799d90f715SBarry Smith } 6809d90f715SBarry Smith if (nout) *nout = nf; 6819d90f715SBarry Smith } 6829d90f715SBarry Smith PetscFunctionReturn(0); 6839d90f715SBarry Smith } 6849d90f715SBarry Smith 6859d90f715SBarry Smith #undef __FUNCT__ 686d4fe737eSStefano Zampini #define __FUNCT__ "ISGlobalToLocalMappingApplyIS" 687d4fe737eSStefano Zampini /*@ 688d4fe737eSStefano Zampini ISGlobalToLocalMappingApplyIS - Creates from an IS in the global numbering 689d4fe737eSStefano Zampini a new index set using the local numbering defined in an ISLocalToGlobalMapping 690d4fe737eSStefano Zampini context. 691d4fe737eSStefano Zampini 692d4fe737eSStefano Zampini Not collective 693d4fe737eSStefano Zampini 694d4fe737eSStefano Zampini Input Parameters: 695d4fe737eSStefano Zampini + mapping - mapping between local and global numbering 696d4fe737eSStefano Zampini - is - index set in global numbering 697d4fe737eSStefano Zampini 698d4fe737eSStefano Zampini Output Parameters: 699d4fe737eSStefano Zampini . newis - index set in local numbering 700d4fe737eSStefano Zampini 701d4fe737eSStefano Zampini Level: advanced 702d4fe737eSStefano Zampini 703d4fe737eSStefano Zampini Concepts: mapping^local to global 704d4fe737eSStefano Zampini 705d4fe737eSStefano Zampini .seealso: ISGlobalToLocalMappingApply(), ISLocalToGlobalMappingCreate(), 706d4fe737eSStefano Zampini ISLocalToGlobalMappingDestroy() 707d4fe737eSStefano Zampini @*/ 708d4fe737eSStefano Zampini PetscErrorCode ISGlobalToLocalMappingApplyIS(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, IS is,IS *newis) 709d4fe737eSStefano Zampini { 710d4fe737eSStefano Zampini PetscErrorCode ierr; 711d4fe737eSStefano Zampini PetscInt n,nout,*idxout; 712d4fe737eSStefano Zampini const PetscInt *idxin; 713d4fe737eSStefano Zampini 714d4fe737eSStefano Zampini PetscFunctionBegin; 715d4fe737eSStefano Zampini PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 716d4fe737eSStefano Zampini PetscValidHeaderSpecific(is,IS_CLASSID,3); 717d4fe737eSStefano Zampini PetscValidPointer(newis,4); 718d4fe737eSStefano Zampini 719d4fe737eSStefano Zampini ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 720d4fe737eSStefano Zampini ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); 721d4fe737eSStefano Zampini if (type == IS_GTOLM_MASK) { 722d4fe737eSStefano Zampini ierr = PetscMalloc1(n,&idxout);CHKERRQ(ierr); 723d4fe737eSStefano Zampini } else { 724d4fe737eSStefano Zampini ierr = ISGlobalToLocalMappingApply(mapping,type,n,idxin,&nout,NULL);CHKERRQ(ierr); 725d4fe737eSStefano Zampini ierr = PetscMalloc1(nout,&idxout);CHKERRQ(ierr); 726d4fe737eSStefano Zampini } 727d4fe737eSStefano Zampini ierr = ISGlobalToLocalMappingApply(mapping,type,n,idxin,&nout,idxout);CHKERRQ(ierr); 728d4fe737eSStefano Zampini ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); 729d4fe737eSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)is),nout,idxout,PETSC_OWN_POINTER,newis);CHKERRQ(ierr); 730d4fe737eSStefano Zampini PetscFunctionReturn(0); 731d4fe737eSStefano Zampini } 732d4fe737eSStefano Zampini 733d4fe737eSStefano Zampini #undef __FUNCT__ 7349d90f715SBarry Smith #define __FUNCT__ "ISGlobalToLocalMappingApplyBlock" 7359d90f715SBarry Smith /*@ 7369d90f715SBarry Smith ISGlobalToLocalMappingApplyBlock - Provides the local block numbering for a list of integers 7379d90f715SBarry Smith specified with a block global numbering. 7389d90f715SBarry Smith 7399d90f715SBarry Smith Not collective 7409d90f715SBarry Smith 7419d90f715SBarry Smith Input Parameters: 7429d90f715SBarry Smith + mapping - mapping between local and global numbering 7439d90f715SBarry Smith . type - IS_GTOLM_MASK - replaces global indices with no local value with -1 7449d90f715SBarry Smith IS_GTOLM_DROP - drops the indices with no local value from the output list 7459d90f715SBarry Smith . n - number of global indices to map 7469d90f715SBarry Smith - idx - global indices to map 7479d90f715SBarry Smith 7489d90f715SBarry Smith Output Parameters: 7499d90f715SBarry Smith + nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n) 7509d90f715SBarry Smith - idxout - local index of each global index, one must pass in an array long enough 7519d90f715SBarry Smith to hold all the indices. You can call ISGlobalToLocalMappingApplyBlock() with 7529d90f715SBarry Smith idxout == NULL to determine the required length (returned in nout) 7539d90f715SBarry Smith and then allocate the required space and call ISGlobalToLocalMappingApplyBlock() 7549d90f715SBarry Smith a second time to set the values. 7559d90f715SBarry Smith 7569d90f715SBarry Smith Notes: 7579d90f715SBarry Smith Either nout or idxout may be NULL. idx and idxout may be identical. 7589d90f715SBarry Smith 7599d90f715SBarry Smith This is not scalable in memory usage. Each processor requires O(Nglobal) size 7609d90f715SBarry Smith array to compute these. 7619d90f715SBarry Smith 7629d90f715SBarry Smith Level: advanced 7639d90f715SBarry Smith 7649d90f715SBarry Smith Developer Note: The manual page states that idx and idxout may be identical but the calling 7659d90f715SBarry Smith sequence declares idx as const so it cannot be the same as idxout. 7669d90f715SBarry Smith 7679d90f715SBarry Smith Concepts: mapping^global to local 7689d90f715SBarry Smith 7699d90f715SBarry Smith .seealso: ISLocalToGlobalMappingApply(), ISGlobalToLocalMappingApply(), ISLocalToGlobalMappingCreate(), 7709d90f715SBarry Smith ISLocalToGlobalMappingDestroy() 7719d90f715SBarry Smith @*/ 7729d90f715SBarry Smith PetscErrorCode ISGlobalToLocalMappingApplyBlock(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingType type, 7739d90f715SBarry Smith PetscInt n,const PetscInt idx[],PetscInt *nout,PetscInt idxout[]) 7749d90f715SBarry Smith { 77532dcc486SBarry Smith PetscInt i,*globals,nf = 0,tmp,start,end; 7766849ba73SBarry Smith PetscErrorCode ierr; 777d4bb536fSBarry Smith 7783a40ed3dSBarry Smith PetscFunctionBegin; 7790700a824SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 780d4bb536fSBarry Smith if (!mapping->globals) { 781d4bb536fSBarry Smith ierr = ISGlobalToLocalMappingSetUp_Private(mapping);CHKERRQ(ierr); 782d4bb536fSBarry Smith } 783d4bb536fSBarry Smith globals = mapping->globals; 784d4bb536fSBarry Smith start = mapping->globalstart; 785d4bb536fSBarry Smith end = mapping->globalend; 786d4bb536fSBarry Smith 787d4bb536fSBarry Smith if (type == IS_GTOLM_MASK) { 788d4bb536fSBarry Smith if (idxout) { 789d4bb536fSBarry Smith for (i=0; i<n; i++) { 790d4bb536fSBarry Smith if (idx[i] < 0) idxout[i] = idx[i]; 791d4bb536fSBarry Smith else if (idx[i] < start) idxout[i] = -1; 792d4bb536fSBarry Smith else if (idx[i] > end) idxout[i] = -1; 793d4bb536fSBarry Smith else idxout[i] = globals[idx[i] - start]; 794d4bb536fSBarry Smith } 795d4bb536fSBarry Smith } 796d4bb536fSBarry Smith if (nout) *nout = n; 797d4bb536fSBarry Smith } else { 798d4bb536fSBarry Smith if (idxout) { 799d4bb536fSBarry Smith for (i=0; i<n; i++) { 800d4bb536fSBarry Smith if (idx[i] < 0) continue; 801d4bb536fSBarry Smith if (idx[i] < start) continue; 802d4bb536fSBarry Smith if (idx[i] > end) continue; 803d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 804d4bb536fSBarry Smith if (tmp < 0) continue; 805d4bb536fSBarry Smith idxout[nf++] = tmp; 806d4bb536fSBarry Smith } 807d4bb536fSBarry Smith } else { 808d4bb536fSBarry Smith for (i=0; i<n; i++) { 809d4bb536fSBarry Smith if (idx[i] < 0) continue; 810d4bb536fSBarry Smith if (idx[i] < start) continue; 811d4bb536fSBarry Smith if (idx[i] > end) continue; 812d4bb536fSBarry Smith tmp = globals[idx[i] - start]; 813d4bb536fSBarry Smith if (tmp < 0) continue; 814d4bb536fSBarry Smith nf++; 815d4bb536fSBarry Smith } 816d4bb536fSBarry Smith } 817d4bb536fSBarry Smith if (nout) *nout = nf; 818d4bb536fSBarry Smith } 8193a40ed3dSBarry Smith PetscFunctionReturn(0); 820d4bb536fSBarry Smith } 82190f02eecSBarry Smith 8224a2ae208SSatish Balay #undef __FUNCT__ 8236a818285SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingGetBlockInfo" 82489d82c54SBarry Smith /*@C 8256a818285SBarry Smith ISLocalToGlobalMappingGetBlockInfo - Gets the neighbor information for each processor and 82689d82c54SBarry Smith each index shared by more than one processor 82789d82c54SBarry Smith 82889d82c54SBarry Smith Collective on ISLocalToGlobalMapping 82989d82c54SBarry Smith 83089d82c54SBarry Smith Input Parameters: 83189d82c54SBarry Smith . mapping - the mapping from local to global indexing 83289d82c54SBarry Smith 83389d82c54SBarry Smith Output Parameter: 83489d82c54SBarry Smith + nproc - number of processors that are connected to this one 83589d82c54SBarry Smith . proc - neighboring processors 83607b52d57SBarry Smith . numproc - number of indices for each subdomain (processor) 8373463a7baSJed Brown - indices - indices of nodes (in local numbering) shared with neighbors (sorted by global numbering) 83889d82c54SBarry Smith 83989d82c54SBarry Smith Level: advanced 84089d82c54SBarry Smith 841273d9f13SBarry Smith Concepts: mapping^local to global 84289d82c54SBarry Smith 8432cfcea29SBarry Smith Fortran Usage: 8442cfcea29SBarry Smith $ ISLocalToGlobalMpngGetInfoSize(ISLocalToGlobalMapping,PetscInt nproc,PetscInt numprocmax,ierr) followed by 8452cfcea29SBarry Smith $ ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping,PetscInt nproc, PetscInt procs[nproc],PetscInt numprocs[nproc], 8462cfcea29SBarry Smith PetscInt indices[nproc][numprocmax],ierr) 8472cfcea29SBarry Smith There is no ISLocalToGlobalMappingRestoreInfo() in Fortran. You must make sure that procs[], numprocs[] and 8482cfcea29SBarry Smith indices[][] are large enough arrays, either by allocating them dynamically or defining static ones large enough. 8492cfcea29SBarry Smith 8502cfcea29SBarry Smith 85107b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 85207b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo() 85389d82c54SBarry Smith @*/ 8546a818285SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetBlockInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 85589d82c54SBarry Smith { 8566849ba73SBarry Smith PetscErrorCode ierr; 857268a049cSStefano Zampini 858268a049cSStefano Zampini PetscFunctionBegin; 859268a049cSStefano Zampini PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 860268a049cSStefano Zampini if (mapping->info_cached) { 861268a049cSStefano Zampini *nproc = mapping->info_nproc; 862268a049cSStefano Zampini *procs = mapping->info_procs; 863268a049cSStefano Zampini *numprocs = mapping->info_numprocs; 864268a049cSStefano Zampini *indices = mapping->info_indices; 865268a049cSStefano Zampini } else { 866268a049cSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockInfo_Private(mapping,nproc,procs,numprocs,indices);CHKERRQ(ierr); 867268a049cSStefano Zampini } 868268a049cSStefano Zampini PetscFunctionReturn(0); 869268a049cSStefano Zampini } 870268a049cSStefano Zampini 871268a049cSStefano Zampini #undef __FUNCT__ 872268a049cSStefano Zampini #define __FUNCT__ "ISLocalToGlobalMappingGetBlockInfo_Private" 873268a049cSStefano Zampini static PetscErrorCode ISLocalToGlobalMappingGetBlockInfo_Private(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 874268a049cSStefano Zampini { 875268a049cSStefano Zampini PetscErrorCode ierr; 87697f1f81fSBarry Smith PetscMPIInt size,rank,tag1,tag2,tag3,*len,*source,imdex; 87732dcc486SBarry Smith PetscInt i,n = mapping->n,Ng,ng,max = 0,*lindices = mapping->indices; 87832dcc486SBarry Smith PetscInt *nprocs,*owner,nsends,*sends,j,*starts,nmax,nrecvs,*recvs,proc; 87997f1f81fSBarry Smith PetscInt cnt,scale,*ownedsenders,*nownedsenders,rstart,nowned; 88032dcc486SBarry Smith PetscInt node,nownedm,nt,*sends2,nsends2,*starts2,*lens2,*dest,nrecvs2,*starts3,*recvs2,k,*bprocs,*tmp; 88132dcc486SBarry Smith PetscInt first_procs,first_numprocs,*first_indices; 88289d82c54SBarry Smith MPI_Request *recv_waits,*send_waits; 88330dcb7c9SBarry Smith MPI_Status recv_status,*send_status,*recv_statuses; 884ce94432eSBarry Smith MPI_Comm comm; 885ace3abfcSBarry Smith PetscBool debug = PETSC_FALSE; 88689d82c54SBarry Smith 88789d82c54SBarry Smith PetscFunctionBegin; 888ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)mapping,&comm);CHKERRQ(ierr); 88924cf384cSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 89024cf384cSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 89124cf384cSBarry Smith if (size == 1) { 89224cf384cSBarry Smith *nproc = 0; 8930298fd71SBarry Smith *procs = NULL; 89495dccacaSBarry Smith ierr = PetscNew(numprocs);CHKERRQ(ierr); 8951e2105dcSBarry Smith (*numprocs)[0] = 0; 89695dccacaSBarry Smith ierr = PetscNew(indices);CHKERRQ(ierr); 8970298fd71SBarry Smith (*indices)[0] = NULL; 898268a049cSStefano Zampini /* save info for reuse */ 899268a049cSStefano Zampini mapping->info_nproc = *nproc; 900268a049cSStefano Zampini mapping->info_procs = *procs; 901268a049cSStefano Zampini mapping->info_numprocs = *numprocs; 902268a049cSStefano Zampini mapping->info_indices = *indices; 903268a049cSStefano Zampini mapping->info_cached = PETSC_TRUE; 90424cf384cSBarry Smith PetscFunctionReturn(0); 90524cf384cSBarry Smith } 90624cf384cSBarry Smith 907c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject)mapping)->options,NULL,"-islocaltoglobalmappinggetinfo_debug",&debug,NULL);CHKERRQ(ierr); 90807b52d57SBarry Smith 9093677ff5aSBarry Smith /* 9106a818285SBarry Smith Notes on ISLocalToGlobalMappingGetBlockInfo 9113677ff5aSBarry Smith 9123677ff5aSBarry Smith globally owned node - the nodes that have been assigned to this processor in global 9133677ff5aSBarry Smith numbering, just for this routine. 9143677ff5aSBarry Smith 9153677ff5aSBarry Smith nontrivial globally owned node - node assigned to this processor that is on a subdomain 9163677ff5aSBarry Smith boundary (i.e. is has more than one local owner) 9173677ff5aSBarry Smith 9183677ff5aSBarry Smith locally owned node - node that exists on this processors subdomain 9193677ff5aSBarry Smith 9203677ff5aSBarry Smith nontrivial locally owned node - node that is not in the interior (i.e. has more than one 9213677ff5aSBarry Smith local subdomain 9223677ff5aSBarry Smith */ 92324cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag1);CHKERRQ(ierr); 92424cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag2);CHKERRQ(ierr); 92524cf384cSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)mapping,&tag3);CHKERRQ(ierr); 92689d82c54SBarry Smith 92789d82c54SBarry Smith for (i=0; i<n; i++) { 92889d82c54SBarry Smith if (lindices[i] > max) max = lindices[i]; 92989d82c54SBarry Smith } 930b2566f29SBarry Smith ierr = MPIU_Allreduce(&max,&Ng,1,MPIU_INT,MPI_MAX,comm);CHKERRQ(ierr); 93178058e43SBarry Smith Ng++; 93289d82c54SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 93389d82c54SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 934bc8ff85bSBarry Smith scale = Ng/size + 1; 935a2e34c3dSBarry Smith ng = scale; if (rank == size-1) ng = Ng - scale*(size-1); ng = PetscMax(1,ng); 936caba0dd0SBarry Smith rstart = scale*rank; 93789d82c54SBarry Smith 93889d82c54SBarry Smith /* determine ownership ranges of global indices */ 939785e854fSJed Brown ierr = PetscMalloc1(2*size,&nprocs);CHKERRQ(ierr); 94032dcc486SBarry Smith ierr = PetscMemzero(nprocs,2*size*sizeof(PetscInt));CHKERRQ(ierr); 94189d82c54SBarry Smith 94289d82c54SBarry Smith /* determine owners of each local node */ 943785e854fSJed Brown ierr = PetscMalloc1(n,&owner);CHKERRQ(ierr); 94489d82c54SBarry Smith for (i=0; i<n; i++) { 9453677ff5aSBarry Smith proc = lindices[i]/scale; /* processor that globally owns this index */ 94627c402fcSBarry Smith nprocs[2*proc+1] = 1; /* processor globally owns at least one of ours */ 9473677ff5aSBarry Smith owner[i] = proc; 94827c402fcSBarry Smith nprocs[2*proc]++; /* count of how many that processor globally owns of ours */ 94989d82c54SBarry Smith } 95027c402fcSBarry Smith nsends = 0; for (i=0; i<size; i++) nsends += nprocs[2*i+1]; 9517904a332SBarry Smith ierr = PetscInfo1(mapping,"Number of global owners for my local data %D\n",nsends);CHKERRQ(ierr); 95289d82c54SBarry Smith 95389d82c54SBarry Smith /* inform other processors of number of messages and max length*/ 95427c402fcSBarry Smith ierr = PetscMaxSum(comm,nprocs,&nmax,&nrecvs);CHKERRQ(ierr); 9557904a332SBarry Smith ierr = PetscInfo1(mapping,"Number of local owners for my global data %D\n",nrecvs);CHKERRQ(ierr); 95689d82c54SBarry Smith 95789d82c54SBarry Smith /* post receives for owned rows */ 958785e854fSJed Brown ierr = PetscMalloc1((2*nrecvs+1)*(nmax+1),&recvs);CHKERRQ(ierr); 959854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,&recv_waits);CHKERRQ(ierr); 96089d82c54SBarry Smith for (i=0; i<nrecvs; i++) { 96132dcc486SBarry Smith ierr = MPI_Irecv(recvs+2*nmax*i,2*nmax,MPIU_INT,MPI_ANY_SOURCE,tag1,comm,recv_waits+i);CHKERRQ(ierr); 96289d82c54SBarry Smith } 96389d82c54SBarry Smith 96489d82c54SBarry Smith /* pack messages containing lists of local nodes to owners */ 965854ce69bSBarry Smith ierr = PetscMalloc1(2*n+1,&sends);CHKERRQ(ierr); 966854ce69bSBarry Smith ierr = PetscMalloc1(size+1,&starts);CHKERRQ(ierr); 96789d82c54SBarry Smith starts[0] = 0; 968f6e5521dSKarl Rupp for (i=1; i<size; i++) starts[i] = starts[i-1] + 2*nprocs[2*i-2]; 96989d82c54SBarry Smith for (i=0; i<n; i++) { 97089d82c54SBarry Smith sends[starts[owner[i]]++] = lindices[i]; 97130dcb7c9SBarry Smith sends[starts[owner[i]]++] = i; 97289d82c54SBarry Smith } 97389d82c54SBarry Smith ierr = PetscFree(owner);CHKERRQ(ierr); 97489d82c54SBarry Smith starts[0] = 0; 975f6e5521dSKarl Rupp for (i=1; i<size; i++) starts[i] = starts[i-1] + 2*nprocs[2*i-2]; 97689d82c54SBarry Smith 97789d82c54SBarry Smith /* send the messages */ 978854ce69bSBarry Smith ierr = PetscMalloc1(nsends+1,&send_waits);CHKERRQ(ierr); 979854ce69bSBarry Smith ierr = PetscMalloc1(nsends+1,&dest);CHKERRQ(ierr); 98089d82c54SBarry Smith cnt = 0; 98189d82c54SBarry Smith for (i=0; i<size; i++) { 98227c402fcSBarry Smith if (nprocs[2*i]) { 98332dcc486SBarry Smith ierr = MPI_Isend(sends+starts[i],2*nprocs[2*i],MPIU_INT,i,tag1,comm,send_waits+cnt);CHKERRQ(ierr); 98430dcb7c9SBarry Smith dest[cnt] = i; 98589d82c54SBarry Smith cnt++; 98689d82c54SBarry Smith } 98789d82c54SBarry Smith } 98889d82c54SBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 98989d82c54SBarry Smith 99089d82c54SBarry Smith /* wait on receives */ 991854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,&source);CHKERRQ(ierr); 992854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,&len);CHKERRQ(ierr); 99389d82c54SBarry Smith cnt = nrecvs; 994854ce69bSBarry Smith ierr = PetscMalloc1(ng+1,&nownedsenders);CHKERRQ(ierr); 99532dcc486SBarry Smith ierr = PetscMemzero(nownedsenders,ng*sizeof(PetscInt));CHKERRQ(ierr); 99689d82c54SBarry Smith while (cnt) { 99789d82c54SBarry Smith ierr = MPI_Waitany(nrecvs,recv_waits,&imdex,&recv_status);CHKERRQ(ierr); 99889d82c54SBarry Smith /* unpack receives into our local space */ 99932dcc486SBarry Smith ierr = MPI_Get_count(&recv_status,MPIU_INT,&len[imdex]);CHKERRQ(ierr); 100089d82c54SBarry Smith source[imdex] = recv_status.MPI_SOURCE; 100130dcb7c9SBarry Smith len[imdex] = len[imdex]/2; 1002caba0dd0SBarry Smith /* count how many local owners for each of my global owned indices */ 100330dcb7c9SBarry Smith for (i=0; i<len[imdex]; i++) nownedsenders[recvs[2*imdex*nmax+2*i]-rstart]++; 100489d82c54SBarry Smith cnt--; 100589d82c54SBarry Smith } 100689d82c54SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 100789d82c54SBarry Smith 100830dcb7c9SBarry Smith /* count how many globally owned indices are on an edge multiplied by how many processors own them. */ 1009bc8ff85bSBarry Smith nowned = 0; 1010bc8ff85bSBarry Smith nownedm = 0; 1011bc8ff85bSBarry Smith for (i=0; i<ng; i++) { 1012bc8ff85bSBarry Smith if (nownedsenders[i] > 1) {nownedm += nownedsenders[i]; nowned++;} 1013bc8ff85bSBarry Smith } 1014bc8ff85bSBarry Smith 1015bc8ff85bSBarry Smith /* create single array to contain rank of all local owners of each globally owned index */ 1016854ce69bSBarry Smith ierr = PetscMalloc1(nownedm+1,&ownedsenders);CHKERRQ(ierr); 1017854ce69bSBarry Smith ierr = PetscMalloc1(ng+1,&starts);CHKERRQ(ierr); 1018bc8ff85bSBarry Smith starts[0] = 0; 1019bc8ff85bSBarry Smith for (i=1; i<ng; i++) { 1020bc8ff85bSBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 1021bc8ff85bSBarry Smith else starts[i] = starts[i-1]; 1022bc8ff85bSBarry Smith } 1023bc8ff85bSBarry Smith 102430dcb7c9SBarry Smith /* for each nontrival globally owned node list all arriving processors */ 1025bc8ff85bSBarry Smith for (i=0; i<nrecvs; i++) { 1026bc8ff85bSBarry Smith for (j=0; j<len[i]; j++) { 102730dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 1028f6e5521dSKarl Rupp if (nownedsenders[node] > 1) ownedsenders[starts[node]++] = source[i]; 1029bc8ff85bSBarry Smith } 1030bc8ff85bSBarry Smith } 1031bc8ff85bSBarry Smith 103207b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 103330dcb7c9SBarry Smith starts[0] = 0; 103430dcb7c9SBarry Smith for (i=1; i<ng; i++) { 103530dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 103630dcb7c9SBarry Smith else starts[i] = starts[i-1]; 103730dcb7c9SBarry Smith } 103830dcb7c9SBarry Smith for (i=0; i<ng; i++) { 103930dcb7c9SBarry Smith if (nownedsenders[i] > 1) { 10407904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] global node %D local owner processors: ",rank,i+rstart);CHKERRQ(ierr); 104130dcb7c9SBarry Smith for (j=0; j<nownedsenders[i]; j++) { 10427904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%D ",ownedsenders[starts[i]+j]);CHKERRQ(ierr); 104330dcb7c9SBarry Smith } 104430dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 104530dcb7c9SBarry Smith } 104630dcb7c9SBarry Smith } 10470ec8b6e3SBarry Smith ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 104807b52d57SBarry Smith } /* ----------------------------------- */ 104930dcb7c9SBarry Smith 10503677ff5aSBarry Smith /* wait on original sends */ 10513a96401aSBarry Smith if (nsends) { 1052785e854fSJed Brown ierr = PetscMalloc1(nsends,&send_status);CHKERRQ(ierr); 10533a96401aSBarry Smith ierr = MPI_Waitall(nsends,send_waits,send_status);CHKERRQ(ierr); 10543a96401aSBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 10553a96401aSBarry Smith } 105689d82c54SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 10573a96401aSBarry Smith ierr = PetscFree(sends);CHKERRQ(ierr); 10583677ff5aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 10593677ff5aSBarry Smith 10603677ff5aSBarry Smith /* pack messages to send back to local owners */ 106130dcb7c9SBarry Smith starts[0] = 0; 106230dcb7c9SBarry Smith for (i=1; i<ng; i++) { 106330dcb7c9SBarry Smith if (nownedsenders[i-1] > 1) starts[i] = starts[i-1] + nownedsenders[i-1]; 106430dcb7c9SBarry Smith else starts[i] = starts[i-1]; 106530dcb7c9SBarry Smith } 106630dcb7c9SBarry Smith nsends2 = nrecvs; 1067854ce69bSBarry Smith ierr = PetscMalloc1(nsends2+1,&nprocs);CHKERRQ(ierr); /* length of each message */ 106830dcb7c9SBarry Smith for (i=0; i<nrecvs; i++) { 106930dcb7c9SBarry Smith nprocs[i] = 1; 107030dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 107130dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 1072f6e5521dSKarl Rupp if (nownedsenders[node] > 1) nprocs[i] += 2 + nownedsenders[node]; 107330dcb7c9SBarry Smith } 107430dcb7c9SBarry Smith } 1075f6e5521dSKarl Rupp nt = 0; 1076f6e5521dSKarl Rupp for (i=0; i<nsends2; i++) nt += nprocs[i]; 1077f6e5521dSKarl Rupp 1078854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,&sends2);CHKERRQ(ierr); 1079854ce69bSBarry Smith ierr = PetscMalloc1(nsends2+1,&starts2);CHKERRQ(ierr); 1080f6e5521dSKarl Rupp 1081f6e5521dSKarl Rupp starts2[0] = 0; 1082f6e5521dSKarl Rupp for (i=1; i<nsends2; i++) starts2[i] = starts2[i-1] + nprocs[i-1]; 108330dcb7c9SBarry Smith /* 108430dcb7c9SBarry Smith Each message is 1 + nprocs[i] long, and consists of 108530dcb7c9SBarry Smith (0) the number of nodes being sent back 108630dcb7c9SBarry Smith (1) the local node number, 108730dcb7c9SBarry Smith (2) the number of processors sharing it, 108830dcb7c9SBarry Smith (3) the processors sharing it 108930dcb7c9SBarry Smith */ 109030dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 109130dcb7c9SBarry Smith cnt = 1; 109230dcb7c9SBarry Smith sends2[starts2[i]] = 0; 109330dcb7c9SBarry Smith for (j=0; j<len[i]; j++) { 109430dcb7c9SBarry Smith node = recvs[2*i*nmax+2*j]-rstart; 109530dcb7c9SBarry Smith if (nownedsenders[node] > 1) { 109630dcb7c9SBarry Smith sends2[starts2[i]]++; 109730dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = recvs[2*i*nmax+2*j+1]; 109830dcb7c9SBarry Smith sends2[starts2[i]+cnt++] = nownedsenders[node]; 109932dcc486SBarry Smith ierr = PetscMemcpy(&sends2[starts2[i]+cnt],&ownedsenders[starts[node]],nownedsenders[node]*sizeof(PetscInt));CHKERRQ(ierr); 110030dcb7c9SBarry Smith cnt += nownedsenders[node]; 110130dcb7c9SBarry Smith } 110230dcb7c9SBarry Smith } 110330dcb7c9SBarry Smith } 110430dcb7c9SBarry Smith 110530dcb7c9SBarry Smith /* receive the message lengths */ 110630dcb7c9SBarry Smith nrecvs2 = nsends; 1107854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&lens2);CHKERRQ(ierr); 1108854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&starts3);CHKERRQ(ierr); 1109854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&recv_waits);CHKERRQ(ierr); 111030dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 1111d44834fbSBarry Smith ierr = MPI_Irecv(&lens2[i],1,MPIU_INT,dest[i],tag2,comm,recv_waits+i);CHKERRQ(ierr); 111230dcb7c9SBarry Smith } 1113d44834fbSBarry Smith 11148a8e0b3aSBarry Smith /* send the message lengths */ 11158a8e0b3aSBarry Smith for (i=0; i<nsends2; i++) { 11168a8e0b3aSBarry Smith ierr = MPI_Send(&nprocs[i],1,MPIU_INT,source[i],tag2,comm);CHKERRQ(ierr); 11178a8e0b3aSBarry Smith } 11188a8e0b3aSBarry Smith 1119d44834fbSBarry Smith /* wait on receives of lens */ 11200c468ba9SBarry Smith if (nrecvs2) { 1121785e854fSJed Brown ierr = PetscMalloc1(nrecvs2,&recv_statuses);CHKERRQ(ierr); 1122d44834fbSBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 1123d44834fbSBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 11240c468ba9SBarry Smith } 1125a2ea699eSBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 1126d44834fbSBarry Smith 112730dcb7c9SBarry Smith starts3[0] = 0; 1128d44834fbSBarry Smith nt = 0; 112930dcb7c9SBarry Smith for (i=0; i<nrecvs2-1; i++) { 113030dcb7c9SBarry Smith starts3[i+1] = starts3[i] + lens2[i]; 1131d44834fbSBarry Smith nt += lens2[i]; 113230dcb7c9SBarry Smith } 113376466f69SStefano Zampini if (nrecvs2) nt += lens2[nrecvs2-1]; 1134d44834fbSBarry Smith 1135854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,&recvs2);CHKERRQ(ierr); 1136854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs2+1,&recv_waits);CHKERRQ(ierr); 113752b72c4aSBarry Smith for (i=0; i<nrecvs2; i++) { 113832dcc486SBarry Smith ierr = MPI_Irecv(recvs2+starts3[i],lens2[i],MPIU_INT,dest[i],tag3,comm,recv_waits+i);CHKERRQ(ierr); 113930dcb7c9SBarry Smith } 114030dcb7c9SBarry Smith 114130dcb7c9SBarry Smith /* send the messages */ 1142854ce69bSBarry Smith ierr = PetscMalloc1(nsends2+1,&send_waits);CHKERRQ(ierr); 114330dcb7c9SBarry Smith for (i=0; i<nsends2; i++) { 114432dcc486SBarry Smith ierr = MPI_Isend(sends2+starts2[i],nprocs[i],MPIU_INT,source[i],tag3,comm,send_waits+i);CHKERRQ(ierr); 114530dcb7c9SBarry Smith } 114630dcb7c9SBarry Smith 114730dcb7c9SBarry Smith /* wait on receives */ 11480c468ba9SBarry Smith if (nrecvs2) { 1149785e854fSJed Brown ierr = PetscMalloc1(nrecvs2,&recv_statuses);CHKERRQ(ierr); 115030dcb7c9SBarry Smith ierr = MPI_Waitall(nrecvs2,recv_waits,recv_statuses);CHKERRQ(ierr); 115130dcb7c9SBarry Smith ierr = PetscFree(recv_statuses);CHKERRQ(ierr); 11520c468ba9SBarry Smith } 115330dcb7c9SBarry Smith ierr = PetscFree(recv_waits);CHKERRQ(ierr); 115430dcb7c9SBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 115530dcb7c9SBarry Smith 115607b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 115730dcb7c9SBarry Smith cnt = 0; 115830dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 115930dcb7c9SBarry Smith nt = recvs2[cnt++]; 116030dcb7c9SBarry Smith for (j=0; j<nt; j++) { 11617904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] local node %D number of subdomains %D: ",rank,recvs2[cnt],recvs2[cnt+1]);CHKERRQ(ierr); 116230dcb7c9SBarry Smith for (k=0; k<recvs2[cnt+1]; k++) { 11637904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%D ",recvs2[cnt+2+k]);CHKERRQ(ierr); 116430dcb7c9SBarry Smith } 116530dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 116630dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 116730dcb7c9SBarry Smith } 116830dcb7c9SBarry Smith } 11690ec8b6e3SBarry Smith ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 117007b52d57SBarry Smith } /* ----------------------------------- */ 117130dcb7c9SBarry Smith 117230dcb7c9SBarry Smith /* count number subdomains for each local node */ 1173785e854fSJed Brown ierr = PetscMalloc1(size,&nprocs);CHKERRQ(ierr); 117432dcc486SBarry Smith ierr = PetscMemzero(nprocs,size*sizeof(PetscInt));CHKERRQ(ierr); 117530dcb7c9SBarry Smith cnt = 0; 117630dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 117730dcb7c9SBarry Smith nt = recvs2[cnt++]; 117830dcb7c9SBarry Smith for (j=0; j<nt; j++) { 1179f6e5521dSKarl Rupp for (k=0; k<recvs2[cnt+1]; k++) nprocs[recvs2[cnt+2+k]]++; 118030dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 118130dcb7c9SBarry Smith } 118230dcb7c9SBarry Smith } 118330dcb7c9SBarry Smith nt = 0; for (i=0; i<size; i++) nt += (nprocs[i] > 0); 118430dcb7c9SBarry Smith *nproc = nt; 1185854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,procs);CHKERRQ(ierr); 1186854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,numprocs);CHKERRQ(ierr); 1187854ce69bSBarry Smith ierr = PetscMalloc1(nt+1,indices);CHKERRQ(ierr); 11880298fd71SBarry Smith for (i=0;i<nt+1;i++) (*indices)[i]=NULL; 1189785e854fSJed Brown ierr = PetscMalloc1(size,&bprocs);CHKERRQ(ierr); 119030dcb7c9SBarry Smith cnt = 0; 119130dcb7c9SBarry Smith for (i=0; i<size; i++) { 119230dcb7c9SBarry Smith if (nprocs[i] > 0) { 119330dcb7c9SBarry Smith bprocs[i] = cnt; 119430dcb7c9SBarry Smith (*procs)[cnt] = i; 119530dcb7c9SBarry Smith (*numprocs)[cnt] = nprocs[i]; 1196785e854fSJed Brown ierr = PetscMalloc1(nprocs[i],&(*indices)[cnt]);CHKERRQ(ierr); 119730dcb7c9SBarry Smith cnt++; 119830dcb7c9SBarry Smith } 119930dcb7c9SBarry Smith } 120030dcb7c9SBarry Smith 120130dcb7c9SBarry Smith /* make the list of subdomains for each nontrivial local node */ 120232dcc486SBarry Smith ierr = PetscMemzero(*numprocs,nt*sizeof(PetscInt));CHKERRQ(ierr); 120330dcb7c9SBarry Smith cnt = 0; 120430dcb7c9SBarry Smith for (i=0; i<nrecvs2; i++) { 120530dcb7c9SBarry Smith nt = recvs2[cnt++]; 120630dcb7c9SBarry Smith for (j=0; j<nt; j++) { 1207f6e5521dSKarl Rupp for (k=0; k<recvs2[cnt+1]; k++) (*indices)[bprocs[recvs2[cnt+2+k]]][(*numprocs)[bprocs[recvs2[cnt+2+k]]]++] = recvs2[cnt]; 120830dcb7c9SBarry Smith cnt += 2 + recvs2[cnt+1]; 120930dcb7c9SBarry Smith } 121030dcb7c9SBarry Smith } 121130dcb7c9SBarry Smith ierr = PetscFree(bprocs);CHKERRQ(ierr); 121207b52d57SBarry Smith ierr = PetscFree(recvs2);CHKERRQ(ierr); 121330dcb7c9SBarry Smith 121407b52d57SBarry Smith /* sort the node indexing by their global numbers */ 121507b52d57SBarry Smith nt = *nproc; 121607b52d57SBarry Smith for (i=0; i<nt; i++) { 1217854ce69bSBarry Smith ierr = PetscMalloc1((*numprocs)[i],&tmp);CHKERRQ(ierr); 1218f6e5521dSKarl Rupp for (j=0; j<(*numprocs)[i]; j++) tmp[j] = lindices[(*indices)[i][j]]; 121907b52d57SBarry Smith ierr = PetscSortIntWithArray((*numprocs)[i],tmp,(*indices)[i]);CHKERRQ(ierr); 122007b52d57SBarry Smith ierr = PetscFree(tmp);CHKERRQ(ierr); 122107b52d57SBarry Smith } 122207b52d57SBarry Smith 122307b52d57SBarry Smith if (debug) { /* ----------------------------------- */ 122430dcb7c9SBarry Smith nt = *nproc; 122530dcb7c9SBarry Smith for (i=0; i<nt; i++) { 12267904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"[%d] subdomain %D number of indices %D: ",rank,(*procs)[i],(*numprocs)[i]);CHKERRQ(ierr); 122730dcb7c9SBarry Smith for (j=0; j<(*numprocs)[i]; j++) { 12287904a332SBarry Smith ierr = PetscSynchronizedPrintf(comm,"%D ",(*indices)[i][j]);CHKERRQ(ierr); 122930dcb7c9SBarry Smith } 123030dcb7c9SBarry Smith ierr = PetscSynchronizedPrintf(comm,"\n");CHKERRQ(ierr); 123130dcb7c9SBarry Smith } 12320ec8b6e3SBarry Smith ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 123307b52d57SBarry Smith } /* ----------------------------------- */ 123430dcb7c9SBarry Smith 123530dcb7c9SBarry Smith /* wait on sends */ 123630dcb7c9SBarry Smith if (nsends2) { 1237785e854fSJed Brown ierr = PetscMalloc1(nsends2,&send_status);CHKERRQ(ierr); 123830dcb7c9SBarry Smith ierr = MPI_Waitall(nsends2,send_waits,send_status);CHKERRQ(ierr); 123930dcb7c9SBarry Smith ierr = PetscFree(send_status);CHKERRQ(ierr); 124030dcb7c9SBarry Smith } 124130dcb7c9SBarry Smith 124230dcb7c9SBarry Smith ierr = PetscFree(starts3);CHKERRQ(ierr); 124330dcb7c9SBarry Smith ierr = PetscFree(dest);CHKERRQ(ierr); 124430dcb7c9SBarry Smith ierr = PetscFree(send_waits);CHKERRQ(ierr); 12453677ff5aSBarry Smith 1246bc8ff85bSBarry Smith ierr = PetscFree(nownedsenders);CHKERRQ(ierr); 1247bc8ff85bSBarry Smith ierr = PetscFree(ownedsenders);CHKERRQ(ierr); 1248bc8ff85bSBarry Smith ierr = PetscFree(starts);CHKERRQ(ierr); 124930dcb7c9SBarry Smith ierr = PetscFree(starts2);CHKERRQ(ierr); 125030dcb7c9SBarry Smith ierr = PetscFree(lens2);CHKERRQ(ierr); 125189d82c54SBarry Smith 125289d82c54SBarry Smith ierr = PetscFree(source);CHKERRQ(ierr); 125397f1f81fSBarry Smith ierr = PetscFree(len);CHKERRQ(ierr); 125489d82c54SBarry Smith ierr = PetscFree(recvs);CHKERRQ(ierr); 12553a96401aSBarry Smith ierr = PetscFree(nprocs);CHKERRQ(ierr); 125630dcb7c9SBarry Smith ierr = PetscFree(sends2);CHKERRQ(ierr); 125724cf384cSBarry Smith 125824cf384cSBarry Smith /* put the information about myself as the first entry in the list */ 125924cf384cSBarry Smith first_procs = (*procs)[0]; 126024cf384cSBarry Smith first_numprocs = (*numprocs)[0]; 126124cf384cSBarry Smith first_indices = (*indices)[0]; 126224cf384cSBarry Smith for (i=0; i<*nproc; i++) { 126324cf384cSBarry Smith if ((*procs)[i] == rank) { 126424cf384cSBarry Smith (*procs)[0] = (*procs)[i]; 126524cf384cSBarry Smith (*numprocs)[0] = (*numprocs)[i]; 126624cf384cSBarry Smith (*indices)[0] = (*indices)[i]; 126724cf384cSBarry Smith (*procs)[i] = first_procs; 126824cf384cSBarry Smith (*numprocs)[i] = first_numprocs; 126924cf384cSBarry Smith (*indices)[i] = first_indices; 127024cf384cSBarry Smith break; 127124cf384cSBarry Smith } 127224cf384cSBarry Smith } 1273268a049cSStefano Zampini 1274268a049cSStefano Zampini /* save info for reuse */ 1275268a049cSStefano Zampini mapping->info_nproc = *nproc; 1276268a049cSStefano Zampini mapping->info_procs = *procs; 1277268a049cSStefano Zampini mapping->info_numprocs = *numprocs; 1278268a049cSStefano Zampini mapping->info_indices = *indices; 1279268a049cSStefano Zampini mapping->info_cached = PETSC_TRUE; 128089d82c54SBarry Smith PetscFunctionReturn(0); 128189d82c54SBarry Smith } 128289d82c54SBarry Smith 12834a2ae208SSatish Balay #undef __FUNCT__ 12846a818285SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingRestoreBlockInfo" 12856a818285SBarry Smith /*@C 12866a818285SBarry Smith ISLocalToGlobalMappingRestoreBlockInfo - Frees the memory allocated by ISLocalToGlobalMappingGetBlockInfo() 12876a818285SBarry Smith 12886a818285SBarry Smith Collective on ISLocalToGlobalMapping 12896a818285SBarry Smith 12906a818285SBarry Smith Input Parameters: 12916a818285SBarry Smith . mapping - the mapping from local to global indexing 12926a818285SBarry Smith 12936a818285SBarry Smith Output Parameter: 12946a818285SBarry Smith + nproc - number of processors that are connected to this one 12956a818285SBarry Smith . proc - neighboring processors 12966a818285SBarry Smith . numproc - number of indices for each processor 12976a818285SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 12986a818285SBarry Smith 12996a818285SBarry Smith Level: advanced 13006a818285SBarry Smith 13016a818285SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 13026a818285SBarry Smith ISLocalToGlobalMappingGetInfo() 13036a818285SBarry Smith @*/ 13046a818285SBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreBlockInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 13056a818285SBarry Smith { 13066a818285SBarry Smith PetscErrorCode ierr; 13076a818285SBarry Smith 13086a818285SBarry Smith PetscFunctionBegin; 1309cbc1caf0SMatthew G. Knepley PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 1310268a049cSStefano Zampini if (mapping->info_free) { 13116a818285SBarry Smith ierr = PetscFree(*numprocs);CHKERRQ(ierr); 13126a818285SBarry Smith if (*indices) { 1313268a049cSStefano Zampini PetscInt i; 1314268a049cSStefano Zampini 13156a818285SBarry Smith ierr = PetscFree((*indices)[0]);CHKERRQ(ierr); 13166a818285SBarry Smith for (i=1; i<*nproc; i++) { 13176a818285SBarry Smith ierr = PetscFree((*indices)[i]);CHKERRQ(ierr); 13186a818285SBarry Smith } 13196a818285SBarry Smith ierr = PetscFree(*indices);CHKERRQ(ierr); 13206a818285SBarry Smith } 1321268a049cSStefano Zampini } 1322268a049cSStefano Zampini *nproc = 0; 1323268a049cSStefano Zampini *procs = NULL; 1324268a049cSStefano Zampini *numprocs = NULL; 1325268a049cSStefano Zampini *indices = NULL; 13266a818285SBarry Smith PetscFunctionReturn(0); 13276a818285SBarry Smith } 13286a818285SBarry Smith 13296a818285SBarry Smith #undef __FUNCT__ 13306a818285SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingGetInfo" 13316a818285SBarry Smith /*@C 13326a818285SBarry Smith ISLocalToGlobalMappingGetInfo - Gets the neighbor information for each processor and 13336a818285SBarry Smith each index shared by more than one processor 13346a818285SBarry Smith 13356a818285SBarry Smith Collective on ISLocalToGlobalMapping 13366a818285SBarry Smith 13376a818285SBarry Smith Input Parameters: 13386a818285SBarry Smith . mapping - the mapping from local to global indexing 13396a818285SBarry Smith 13406a818285SBarry Smith Output Parameter: 13416a818285SBarry Smith + nproc - number of processors that are connected to this one 13426a818285SBarry Smith . proc - neighboring processors 13436a818285SBarry Smith . numproc - number of indices for each subdomain (processor) 13446a818285SBarry Smith - indices - indices of nodes (in local numbering) shared with neighbors (sorted by global numbering) 13456a818285SBarry Smith 13466a818285SBarry Smith Level: advanced 13476a818285SBarry Smith 13486a818285SBarry Smith Concepts: mapping^local to global 13496a818285SBarry Smith 13506a818285SBarry Smith Fortran Usage: 13516a818285SBarry Smith $ ISLocalToGlobalMpngGetInfoSize(ISLocalToGlobalMapping,PetscInt nproc,PetscInt numprocmax,ierr) followed by 13526a818285SBarry Smith $ ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping,PetscInt nproc, PetscInt procs[nproc],PetscInt numprocs[nproc], 13536a818285SBarry Smith PetscInt indices[nproc][numprocmax],ierr) 13546a818285SBarry Smith There is no ISLocalToGlobalMappingRestoreInfo() in Fortran. You must make sure that procs[], numprocs[] and 13556a818285SBarry Smith indices[][] are large enough arrays, either by allocating them dynamically or defining static ones large enough. 13566a818285SBarry Smith 13576a818285SBarry Smith 13586a818285SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 13596a818285SBarry Smith ISLocalToGlobalMappingRestoreInfo() 13606a818285SBarry Smith @*/ 13616a818285SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 13626a818285SBarry Smith { 13636a818285SBarry Smith PetscErrorCode ierr; 1364268a049cSStefano Zampini PetscInt **bindices = NULL,*bnumprocs = NULL,bs = mapping->bs,i,j,k; 13656a818285SBarry Smith 13666a818285SBarry Smith PetscFunctionBegin; 13676a818285SBarry Smith PetscValidHeaderSpecific(mapping,IS_LTOGM_CLASSID,1); 1368268a049cSStefano Zampini ierr = ISLocalToGlobalMappingGetBlockInfo(mapping,nproc,procs,&bnumprocs,&bindices);CHKERRQ(ierr); 1369268a049cSStefano Zampini if (bs > 1) { /* we need to expand the cached info */ 1370732f65e3SBarry Smith ierr = PetscCalloc1(*nproc,&*indices);CHKERRQ(ierr); 1371268a049cSStefano Zampini ierr = PetscCalloc1(*nproc,&*numprocs);CHKERRQ(ierr); 13726a818285SBarry Smith for (i=0; i<*nproc; i++) { 1373268a049cSStefano Zampini ierr = PetscMalloc1(bs*bnumprocs[i],&(*indices)[i]);CHKERRQ(ierr); 1374268a049cSStefano Zampini for (j=0; j<bnumprocs[i]; j++) { 13756a818285SBarry Smith for (k=0; k<bs; k++) { 13766a818285SBarry Smith (*indices)[i][j*bs+k] = bs*bindices[i][j] + k; 13776a818285SBarry Smith } 13786a818285SBarry Smith } 1379268a049cSStefano Zampini (*numprocs)[i] = bnumprocs[i]*bs; 13806a818285SBarry Smith } 1381268a049cSStefano Zampini mapping->info_free = PETSC_TRUE; 1382268a049cSStefano Zampini } else { 1383268a049cSStefano Zampini *numprocs = bnumprocs; 1384268a049cSStefano Zampini *indices = bindices; 13856a818285SBarry Smith } 13866a818285SBarry Smith PetscFunctionReturn(0); 13876a818285SBarry Smith } 13886a818285SBarry Smith 13896a818285SBarry Smith #undef __FUNCT__ 13904a2ae208SSatish Balay #define __FUNCT__ "ISLocalToGlobalMappingRestoreInfo" 139107b52d57SBarry Smith /*@C 139207b52d57SBarry Smith ISLocalToGlobalMappingRestoreInfo - Frees the memory allocated by ISLocalToGlobalMappingGetInfo() 139389d82c54SBarry Smith 139407b52d57SBarry Smith Collective on ISLocalToGlobalMapping 139507b52d57SBarry Smith 139607b52d57SBarry Smith Input Parameters: 139707b52d57SBarry Smith . mapping - the mapping from local to global indexing 139807b52d57SBarry Smith 139907b52d57SBarry Smith Output Parameter: 140007b52d57SBarry Smith + nproc - number of processors that are connected to this one 140107b52d57SBarry Smith . proc - neighboring processors 140207b52d57SBarry Smith . numproc - number of indices for each processor 140307b52d57SBarry Smith - indices - indices of local nodes shared with neighbor (sorted by global numbering) 140407b52d57SBarry Smith 140507b52d57SBarry Smith Level: advanced 140607b52d57SBarry Smith 140707b52d57SBarry Smith .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS(), ISLocalToGlobalMappingCreate(), 140807b52d57SBarry Smith ISLocalToGlobalMappingGetInfo() 140907b52d57SBarry Smith @*/ 14107087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreInfo(ISLocalToGlobalMapping mapping,PetscInt *nproc,PetscInt *procs[],PetscInt *numprocs[],PetscInt **indices[]) 141107b52d57SBarry Smith { 14126849ba73SBarry Smith PetscErrorCode ierr; 141307b52d57SBarry Smith 141407b52d57SBarry Smith PetscFunctionBegin; 14156a818285SBarry Smith ierr = ISLocalToGlobalMappingRestoreBlockInfo(mapping,nproc,procs,numprocs,indices);CHKERRQ(ierr); 141607b52d57SBarry Smith PetscFunctionReturn(0); 141707b52d57SBarry Smith } 141886994e45SJed Brown 141986994e45SJed Brown #undef __FUNCT__ 142086994e45SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingGetIndices" 142186994e45SJed Brown /*@C 1422107e9a97SBarry Smith ISLocalToGlobalMappingGetIndices - Get global indices for every local point that is mapped 142386994e45SJed Brown 142486994e45SJed Brown Not Collective 142586994e45SJed Brown 142686994e45SJed Brown Input Arguments: 142786994e45SJed Brown . ltog - local to global mapping 142886994e45SJed Brown 142986994e45SJed Brown Output Arguments: 1430565245c5SBarry Smith . array - array of indices, the length of this array may be obtained with ISLocalToGlobalMappingGetSize() 143186994e45SJed Brown 143286994e45SJed Brown Level: advanced 143386994e45SJed Brown 1434107e9a97SBarry Smith Notes: ISLocalToGlobalMappingGetSize() returns the length the this array 1435107e9a97SBarry Smith 1436107e9a97SBarry Smith .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingRestoreIndices(), ISLocalToGlobalMappingGetBlockIndices(), ISLocalToGlobalMappingRestoreBlockIndices() 143786994e45SJed Brown @*/ 14387087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingGetIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 143986994e45SJed Brown { 144086994e45SJed Brown PetscFunctionBegin; 144186994e45SJed Brown PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 144286994e45SJed Brown PetscValidPointer(array,2); 144345b6f7e9SBarry Smith if (ltog->bs == 1) { 144486994e45SJed Brown *array = ltog->indices; 144545b6f7e9SBarry Smith } else { 144645b6f7e9SBarry Smith PetscInt *jj,k,i,j,n = ltog->n, bs = ltog->bs; 144745b6f7e9SBarry Smith const PetscInt *ii; 144845b6f7e9SBarry Smith PetscErrorCode ierr; 144945b6f7e9SBarry Smith 145045b6f7e9SBarry Smith ierr = PetscMalloc1(bs*n,&jj);CHKERRQ(ierr); 145145b6f7e9SBarry Smith *array = jj; 145245b6f7e9SBarry Smith k = 0; 145345b6f7e9SBarry Smith ii = ltog->indices; 145445b6f7e9SBarry Smith for (i=0; i<n; i++) 145545b6f7e9SBarry Smith for (j=0; j<bs; j++) 145645b6f7e9SBarry Smith jj[k++] = bs*ii[i] + j; 145745b6f7e9SBarry Smith } 145886994e45SJed Brown PetscFunctionReturn(0); 145986994e45SJed Brown } 146086994e45SJed Brown 146186994e45SJed Brown #undef __FUNCT__ 146286994e45SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingRestoreIndices" 146386994e45SJed Brown /*@C 1464193a2b41SJulian Andrej ISLocalToGlobalMappingRestoreIndices - Restore indices obtained with ISLocalToGlobalMappingGetIndices() 146586994e45SJed Brown 146686994e45SJed Brown Not Collective 146786994e45SJed Brown 146886994e45SJed Brown Input Arguments: 146986994e45SJed Brown + ltog - local to global mapping 147086994e45SJed Brown - array - array of indices 147186994e45SJed Brown 147286994e45SJed Brown Level: advanced 147386994e45SJed Brown 147486994e45SJed Brown .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingGetIndices() 147586994e45SJed Brown @*/ 14767087cfbeSBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 147786994e45SJed Brown { 147886994e45SJed Brown PetscFunctionBegin; 147986994e45SJed Brown PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 148086994e45SJed Brown PetscValidPointer(array,2); 148145b6f7e9SBarry Smith if (ltog->bs == 1 && *array != ltog->indices) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Trying to return mismatched pointer"); 148245b6f7e9SBarry Smith 148345b6f7e9SBarry Smith if (ltog->bs > 1) { 148445b6f7e9SBarry Smith PetscErrorCode ierr; 148545b6f7e9SBarry Smith ierr = PetscFree(*(void**)array);CHKERRQ(ierr); 148645b6f7e9SBarry Smith } 148745b6f7e9SBarry Smith PetscFunctionReturn(0); 148845b6f7e9SBarry Smith } 148945b6f7e9SBarry Smith 149045b6f7e9SBarry Smith #undef __FUNCT__ 149145b6f7e9SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingGetBlockIndices" 149245b6f7e9SBarry Smith /*@C 149345b6f7e9SBarry Smith ISLocalToGlobalMappingGetBlockIndices - Get global indices for every local block 149445b6f7e9SBarry Smith 149545b6f7e9SBarry Smith Not Collective 149645b6f7e9SBarry Smith 149745b6f7e9SBarry Smith Input Arguments: 149845b6f7e9SBarry Smith . ltog - local to global mapping 149945b6f7e9SBarry Smith 150045b6f7e9SBarry Smith Output Arguments: 150145b6f7e9SBarry Smith . array - array of indices 150245b6f7e9SBarry Smith 150345b6f7e9SBarry Smith Level: advanced 150445b6f7e9SBarry Smith 150545b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingRestoreBlockIndices() 150645b6f7e9SBarry Smith @*/ 150745b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetBlockIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 150845b6f7e9SBarry Smith { 150945b6f7e9SBarry Smith PetscFunctionBegin; 151045b6f7e9SBarry Smith PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 151145b6f7e9SBarry Smith PetscValidPointer(array,2); 151245b6f7e9SBarry Smith *array = ltog->indices; 151345b6f7e9SBarry Smith PetscFunctionReturn(0); 151445b6f7e9SBarry Smith } 151545b6f7e9SBarry Smith 151645b6f7e9SBarry Smith #undef __FUNCT__ 151745b6f7e9SBarry Smith #define __FUNCT__ "ISLocalToGlobalMappingRestoreBlockIndices" 151845b6f7e9SBarry Smith /*@C 151945b6f7e9SBarry Smith ISLocalToGlobalMappingRestoreBlockIndices - Restore indices obtained with ISLocalToGlobalMappingGetBlockIndices() 152045b6f7e9SBarry Smith 152145b6f7e9SBarry Smith Not Collective 152245b6f7e9SBarry Smith 152345b6f7e9SBarry Smith Input Arguments: 152445b6f7e9SBarry Smith + ltog - local to global mapping 152545b6f7e9SBarry Smith - array - array of indices 152645b6f7e9SBarry Smith 152745b6f7e9SBarry Smith Level: advanced 152845b6f7e9SBarry Smith 152945b6f7e9SBarry Smith .seealso: ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingGetIndices() 153045b6f7e9SBarry Smith @*/ 153145b6f7e9SBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreBlockIndices(ISLocalToGlobalMapping ltog,const PetscInt **array) 153245b6f7e9SBarry Smith { 153345b6f7e9SBarry Smith PetscFunctionBegin; 153445b6f7e9SBarry Smith PetscValidHeaderSpecific(ltog,IS_LTOGM_CLASSID,1); 153545b6f7e9SBarry Smith PetscValidPointer(array,2); 153686994e45SJed Brown if (*array != ltog->indices) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Trying to return mismatched pointer"); 15370298fd71SBarry Smith *array = NULL; 153886994e45SJed Brown PetscFunctionReturn(0); 153986994e45SJed Brown } 1540f7efa3c7SJed Brown 1541f7efa3c7SJed Brown #undef __FUNCT__ 1542f7efa3c7SJed Brown #define __FUNCT__ "ISLocalToGlobalMappingConcatenate" 1543f7efa3c7SJed Brown /*@C 1544f7efa3c7SJed Brown ISLocalToGlobalMappingConcatenate - Create a new mapping that concatenates a list of mappings 1545f7efa3c7SJed Brown 1546f7efa3c7SJed Brown Not Collective 1547f7efa3c7SJed Brown 1548f7efa3c7SJed Brown Input Arguments: 1549f7efa3c7SJed Brown + comm - communicator for the new mapping, must contain the communicator of every mapping to concatenate 1550f7efa3c7SJed Brown . n - number of mappings to concatenate 1551f7efa3c7SJed Brown - ltogs - local to global mappings 1552f7efa3c7SJed Brown 1553f7efa3c7SJed Brown Output Arguments: 1554f7efa3c7SJed Brown . ltogcat - new mapping 1555f7efa3c7SJed Brown 15569d90f715SBarry Smith Note: this currently always returns a mapping with block size of 1 15579d90f715SBarry Smith 15589d90f715SBarry Smith Developer Note: If all the input mapping have the same block size we could easily handle that as a special case 15599d90f715SBarry Smith 1560f7efa3c7SJed Brown Level: advanced 1561f7efa3c7SJed Brown 1562f7efa3c7SJed Brown .seealso: ISLocalToGlobalMappingCreate() 1563f7efa3c7SJed Brown @*/ 1564f7efa3c7SJed Brown PetscErrorCode ISLocalToGlobalMappingConcatenate(MPI_Comm comm,PetscInt n,const ISLocalToGlobalMapping ltogs[],ISLocalToGlobalMapping *ltogcat) 1565f7efa3c7SJed Brown { 1566f7efa3c7SJed Brown PetscInt i,cnt,m,*idx; 1567f7efa3c7SJed Brown PetscErrorCode ierr; 1568f7efa3c7SJed Brown 1569f7efa3c7SJed Brown PetscFunctionBegin; 1570f7efa3c7SJed Brown if (n < 0) SETERRQ1(comm,PETSC_ERR_ARG_OUTOFRANGE,"Must have a non-negative number of mappings, given %D",n); 1571f7efa3c7SJed Brown if (n > 0) PetscValidPointer(ltogs,3); 1572f7efa3c7SJed Brown for (i=0; i<n; i++) PetscValidHeaderSpecific(ltogs[i],IS_LTOGM_CLASSID,3); 1573f7efa3c7SJed Brown PetscValidPointer(ltogcat,4); 1574f7efa3c7SJed Brown for (cnt=0,i=0; i<n; i++) { 1575f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetSize(ltogs[i],&m);CHKERRQ(ierr); 1576f7efa3c7SJed Brown cnt += m; 1577f7efa3c7SJed Brown } 1578785e854fSJed Brown ierr = PetscMalloc1(cnt,&idx);CHKERRQ(ierr); 1579f7efa3c7SJed Brown for (cnt=0,i=0; i<n; i++) { 1580f7efa3c7SJed Brown const PetscInt *subidx; 1581f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetSize(ltogs[i],&m);CHKERRQ(ierr); 1582f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingGetIndices(ltogs[i],&subidx);CHKERRQ(ierr); 1583f7efa3c7SJed Brown ierr = PetscMemcpy(&idx[cnt],subidx,m*sizeof(PetscInt));CHKERRQ(ierr); 1584f7efa3c7SJed Brown ierr = ISLocalToGlobalMappingRestoreIndices(ltogs[i],&subidx);CHKERRQ(ierr); 1585f7efa3c7SJed Brown cnt += m; 1586f7efa3c7SJed Brown } 1587f0413b6fSBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,1,cnt,idx,PETSC_OWN_POINTER,ltogcat);CHKERRQ(ierr); 1588f7efa3c7SJed Brown PetscFunctionReturn(0); 1589f7efa3c7SJed Brown } 159004a59952SBarry Smith 159104a59952SBarry Smith 1592